func TestSync0Chgs(t *testing.T) { fstest.ResetTime() fstest.MkTree(t, tdir) defer fstest.RmTree(t, tdir) fstest.ResetTime() fstest.MkTree(t, tdir2) defer fstest.RmTree(t, tdir2) fstest.MkChgs(t, tdir2) fs, err := lfs.New(tdir, tdir, lfs.RW) if err != nil { t.Fatalf("new lfs: %s", err) } fs2, err := lfs.New(tdir2, tdir2, lfs.RW) if err != nil { t.Fatalf("new lfs: %s", err) } Debug = moreverb fs.Dbg = moreverb fs2.Dbg = moreverb fs.SaveAttrs(true) fs2.SaveAttrs(true) db, err := NewDB("tdb", "", fs) if err != nil { t.Fatalf("new: %s", err) } if testing.Verbose() { db.DumpTo(os.Stdout) } db2, err := NewDB("tdb2", "", fs2) if err != nil { t.Fatalf("new: %s", err) } if testing.Verbose() { db2.DumpTo(os.Stdout) } pulls := []chg{ chg{Type: Data, Path: "/a/a1"}, chg{Type: Meta, Path: "/a/a2"}, chg{Type: Add, Path: "/a/n"}, } pushes := []chg{ chg{Type: Add, Path: "/a/b/c"}, } pullc, pushc := Changes(db, db2) ec := make(chan error, 2) go chkcc("pull", pullc, pulls, ec) go chkcc("push", pushc, pushes, ec) if e := <-ec; e != nil { t.Fatal(e) } if e := <-ec; e != nil { t.Fatal(e) } if testing.Verbose() { db.DumpTo(os.Stdout) db2.DumpTo(os.Stdout) } }
func benchfn(b *testing.B, fn func(b *testing.B, t zx.Tree)) { b.StopTimer() fstest.RmTree(b, tdir) fstest.MkTree(b, tdir) defer func() { b.StopTimer() fstest.RmTree(b, tdir) }() rfs, _ := testfs(b) b.StartTimer() fn(b, rfs) }
func benchfn(b *testing.B, fn func(b *testing.B, t zx.Tree)) { b.StopTimer() defer func() { b.StopTimer() fstest.RmTree(b, tdir) }() fstest.RmTree(b, tdir) fstest.MkTree(b, tdir) lfs, err := New(tdir, tdir, RW) if err != nil { b.Fatalf("new: %s", err) } b.StartTimer() fn(b, lfs) }
func TestResolve(t *testing.T) { ns := mkns(t, false) defer fstest.RmTree(t, tdir) ns.Debug = testing.Verbose() ns.DebugFind = testing.Verbose() for _, r := range resolves { _, dirs, paths, err := ns.Resolve(r.Path) printf("sts %v\n", err) if err!=nil && !r.Fails { t.Fatalf("failed with %v", err) } if err==nil && r.Fails { t.Fatal("didn't fail") } if len(dirs) != len(paths) { t.Fatal("wrong lengths") } printf("dirs:\n") for _, d := range dirs { delete(d, "Uid") delete(d, "Gid") delete(d, "Wuid") delete(d, "Sum") printf("\t`%s`,\n", d) } printf("paths:\n") for _, p := range paths { printf("\t`%s`,\n", p) } for i := 0; i<len(r.Dirs) && i<len(dirs); i++ { if r.Dirs[i] != dirs[i].String() { t.Fatalf("bad result [%d]\n\tgot %s\n\twant %s\n", i, dirs[i], r.Dirs[i]) } } if r.Dirs != nil { if len(dirs) > len(r.Dirs) { t.Fatalf("unexpected %s", dirs[len(r.Dirs)]) } if len(dirs) < len(r.Dirs) { t.Fatalf("did expect %s", r.Dirs[len(dirs)]) } } for i := 0; i<len(r.Paths) && i<len(paths); i++ { if r.Paths[i] != paths[i] { t.Fatalf("bad result [%d]\n\tgot %s\n\twant %s\n", i, paths[i], r.Paths[i]) } } if r.Paths != nil { if len(paths) > len(r.Paths) { t.Fatalf("unexpected %s", paths[len(r.Paths)]) } if len(paths) < len(r.Paths) { t.Fatalf("did expect %s", r.Paths[len(paths)]) } } } }
func TestRFind(t *testing.T) { ns := mkrns(t, false) defer fstest.RmTree(t, tdir) ns.Debug = testing.Verbose() ns.DebugFind = testing.Verbose() for _, f := range finds { dc := ns.Find(f.Path, f.Pred, f.Spref, f.Spref, f.Depth) outs := []string{} for d := range dc { printf("got %s err %s\n", d.TestFmt(), d["err"]) if d["err"] != "" { continue } if d["type"] == "c" { // for fuse&cfs d["type"] = "-" } outs = append(outs, d.TestFmt()) } printf("done find %s %s sts %v\n", f.Path, f.Pred, cerror(dc)) for i := 0; i<len(f.Res) && i<len(outs); i++ { if outs[i] != f.Res[i] { t.Fatalf("bad result [%d]\n\tgot %s\n\twant %s\n", i, outs[i], f.Res[i]) } } if f.Res != nil { if len(outs) > len(f.Res) { t.Fatalf("unexpected %s", outs[len(f.Res)]) } if len(outs) < len(f.Res) { t.Fatalf("unexpected %s", f.Res[len(outs)]) } } } }
func testfn(t *testing.T, fns ...func(t fstest.Fataler, fss ...zx.Tree)) { fstest.RmTree(t, tdir) fstest.MkTree(t, tdir) defer fstest.RmTree(t, tdir) lfs, err := New(tdir, tdir, RW) if err != nil { t.Fatalf("new: %s", err) } lfs.SaveAttrs(true) lfs.Dbg = testing.Verbose() xfs, _ := lfs.AuthFor(&auth.Info{Uid: dbg.Usr, SpeaksFor: dbg.Usr, Ok: true}) fs := xfs.(zx.RWTree) for _, fn := range fns { if fn != nil { fn(t, fs) } } }
func TestFinds(t *testing.T) { testfn(t, fstest.Gets) fstest.MkTree(t, tdir) defer fstest.RmTree(t, tdir) lfs, err := New(tdir, tdir, RO) if err != nil { t.Fatalf("new: %s", err) } fstest.Finds(t, lfs) }
func TestCmpNoChg(t *testing.T) { fstest.ResetTime() fstest.MkTree(t, tdir) defer fstest.RmTree(t, tdir) fstest.ResetTime() fstest.MkTree(t, tdir2) defer fstest.RmTree(t, tdir2) fs, err := lfs.New(tdir, tdir, lfs.RW) if err != nil { t.Fatalf("new lfs: %s", err) } fs2, err := lfs.New(tdir2, tdir2, lfs.RW) if err != nil { t.Fatalf("new lfs: %s", err) } Debug = moreverb fs.Dbg = moreverb fs2.Dbg = moreverb fs.SaveAttrs(true) fs2.SaveAttrs(true) db, err := NewDB("tdb", "", fs) if err != nil { t.Fatalf("new: %s", err) } if testing.Verbose() { db.DumpTo(os.Stdout) } db2, err := NewDB("tdb2", "", fs2) if err != nil { t.Fatalf("new: %s", err) } if testing.Verbose() { db2.DumpTo(os.Stdout) } cc := db.ChangesTo(db2) ec := make(chan error, 1) chkcc("chgs", cc, []chg{}, ec) if e := <-ec; e != nil { t.Fatal(e) } }
func TestSendRecv(t *testing.T) { t.Skip("send/recv is broken by now") tdir2 := tdir + "2" fstest.RmTree(t, tdir) fstest.RmTree(t, tdir2) fstest.MkTree(t, tdir) os.Mkdir(tdir+"2", 0755) defer fstest.RmTree(t, tdir) defer fstest.RmTree(t, tdir2) fs, err := New(tdir, tdir, RW) if err != nil { t.Log(err) t.Fail() } fs2, err := New(tdir2, tdir2, RW) if err != nil { t.Fatal(err) } fstest.SendRecv(t, fs, fs2) }
func testfn(t *testing.T, fn func(t fstest.Fataler, fss ...zx.Tree)) { fstest.MkTree(t, tdir) defer fstest.RmTree(t, tdir) lfs, rfs := testfs(t) if testing.Verbose() || showstats { rfs.IOstats = &zx.IOstats{} defer func() { rfs.IOstats.Averages() fmt.Printf("rfs iostats:\n%s\n", rfs.IOstats) }() } fn(t, rfs, lfs) }
func TestNew(t *testing.T) { fstest.ResetTime() fstest.RmTree(t, rdir) fstest.RmTree(t, tdir) fstest.RmTree(t, tdir2) if err := os.Mkdir(rdir, 0755); err != nil && !dbg.IsExists(err) { t.Fatalf("%s: %s", tdir2, err) } defer fstest.RmTree(t, rdir) fstest.MkTree(t, tdir) defer fstest.RmTree(t, tdir) if err := os.Mkdir(tdir2, 0755); err != nil { t.Fatalf("%s: %s", tdir2, err) } defer fstest.RmTree(t, tdir2) r, err := New("testrepl", "", tdir, tdir2) if err != nil { t.Fatalf("new: %s", err) } if err := r.Save(rcfg); err != nil { t.Fatalf("save: %s", err) } nr, err := Load(rcfg) if err != nil { t.Fatalf("load: %s", err) } if testing.Verbose() { nr.DumpTo(os.Stdout) } var b bytes.Buffer nr.DumpTo(&b) out := `testrepl '' /tmp/db_test /tmp/db_test2 testrepl[/tmp/db_test] / d 0755 nemo nemo nemo 6 /1 - 0644 none none none 0 0 /2 - 0644 none none none 31658 4000000000 /a d 0755 none none none 3 /a/a1 - 0644 none none none 10154 1000000000 /a/a2 - 0644 none none none 21418 2000000000 /a/b d 0755 none none none 1 /a/b/c d 0755 none none none 1 /a/b/c/c3 - 0644 none none none 44970 3000000000 /d d 0755 none none none 0 /e d 0755 none none none 1 /e/f d 0755 none none none 0 testrepl[/tmp/db_test2] / d 0755 nemo nemo nemo 1 ` if b.String() != out { t.Fatal("bad repl content") } }
func TestNew(t *testing.T) { fstest.ResetTime() fstest.MkTree(t, tdir) defer fstest.RmTree(t, tdir) fs, err := lfs.New(tdir, tdir, lfs.RW) if err != nil { t.Fatalf("new lfs: %s", err) } fs.SaveAttrs(true) Debug = moreverb fs.Dbg = moreverb db, err := NewDB("tdb", "", fs) if err != nil { t.Fatalf("new: %s", err) } if testing.Verbose() { db.DumpTo(os.Stdout) } var b1 bytes.Buffer db.DumpTo(&b1) c := make(chan []byte, 1000) if err := db.SendTo(c); err != nil { t.Fatalf("recv: %s", err) } close(c) ndb, err := RecvDBFrom(c) if err != nil { t.Fatalf("recv: %s", err) } if testing.Verbose() { ndb.DumpTo(os.Stdout) } var b2 bytes.Buffer db.DumpTo(&b2) if b1.String() != b2.String() { t.Fatal("dbs do not match") } }
func TestNS(t *testing.T) { ns := mkns(t, testing.Verbose()) defer fstest.RmTree(t, tdir) d2 := zx.Dir{"path": "x", "name": "x", "proto": "p2"} err := <-ns.Mount("d", d2, After) if err == nil { t.Fatalf("mount: could mount") } err = <-ns.Unmount("/d", d2) if err != nil { t.Fatalf("unmount dir: %s", err) } printf("ns is `%s`\n", ns) s := ns.String() ns2, err := Parse(s) if err != nil { t.Fatalf("parse: %s", err) } printf("ns2 is `%s`\n", ns2) if ns2.String() != s { t.Fatalf("parsed ns differs") } outs := `path:"/" name:"/" type:"d" mode:"0755" proto:"lfs" spath:"/" tpath:"/tmp/lfs_test" path:"/a/b" name:"b" type:"d" mode:"0755" proto:"lfs" spath:"/" tpath:"/tmp/lfs_test" path:"/d" name:"d" type:"p" mode:"0644" proto:"p1" path:"/d" name:"d" type:"p" mode:"0644" proto:"p2" path:"/d" name:"d" type:"p" mode:"0644" proto:"p2" ` if s != outs { t.Fatalf("bad ns contents") } err = <-ns.Unmount("/a/b", nil) if err != nil { t.Fatalf("unmount dir: %s", err) } printf("ns is `%s`\n", ns) }
func TestFiles(t *testing.T) { fstest.ResetTime() fstest.MkTree(t, tdir) defer fstest.RmTree(t, tdir) fs, err := lfs.New(tdir, tdir, lfs.RW) if err != nil { t.Fatalf("new lfs: %s", err) } Debug = moreverb fs.Dbg = moreverb fs.SaveAttrs(true) db, err := NewDB("tdb", "", fs) if err != nil { t.Fatalf("new: %s", err) } n := 0 for f := range db.Files() { printf("%s\n", f) n++ } if n != 12 { t.Fatalf("got %d and not 12 entries", n) } }
func TestSyncChgs(t *testing.T) { fstest.ResetTime() fstest.RmTree(t, rdir) fstest.RmTree(t, tdir) fstest.RmTree(t, tdir2) defer fstest.RmTree(t, tdir2) defer fstest.RmTree(t, rdir) defer fstest.RmTree(t, tdir) if err := os.Mkdir(rdir, 0755); err != nil && !dbg.IsExists(err) { t.Fatalf("%s: %s", tdir2, err) } fstest.MkTree(t, tdir) if err := os.Mkdir(tdir2, 0755); err != nil { t.Fatalf("%s: %s", tdir2, err) } r, err := New("testrepl", "", tdir, tdir2) if err != nil { t.Fatalf("new: %s", err) } if err := r.Sync(); err != nil { t.Fatalf("sync: %s", err) } if err := r.Save(rcfg); err != nil { t.Fatalf("save: %s", err) } r, err = Load(rcfg) if err != nil { t.Fatalf("load: %s", err) } if testing.Verbose() { r.DumpTo(os.Stdout) } fstest.MkChgs2(t, tdir) fstest.MkChgs(t, tdir2) if err := r.Sync(); err != nil { t.Fatalf("sync: %s", err) } if testing.Verbose() { r.DumpTo(os.Stdout) } if err := r.Sync(); err != nil { t.Fatalf("sync: %s", err) } if err := r.Save(rcfg); err != nil { t.Fatalf("save: %s", err) } if err := r.Sync(); err != nil { t.Fatalf("sync: %s", err) } var b bytes.Buffer r.DumpTo(&b) out := `testrepl '' /tmp/db_test /tmp/db_test2 testrepl[/tmp/db_test] / d 0755 none none none 6 /1 - 0644 none none none 50 13000000000 /2 d 0750 none none none 1 /2/n2 d 0750 none none none 0 /a d 0755 none none none 4 /a/a1 - 0644 none none none 10154 14000000000 /a/a2 - 0750 none none none 21418 2000000000 /a/b d 0755 none none none 0 /a/b/c d GONE none none none 1 /a/n d 0750 none none none 1 /a/n/m d 0750 none none none 1 /a/n/m/m1 - 0640 none none none 11 15000000000 /d d 0755 none none none 0 /e d 0755 none none none 1 /e/f d 0755 none none none 0 testrepl[/tmp/db_test2] / d 0755 none none none 6 /1 - 0644 none none none 50 13000000000 /2 d 0750 none none none 1 /2/n2 d 0750 none none none 0 /a d 0755 none none none 4 /a/a1 - 0644 none none none 10154 14000000000 /a/a2 - 0750 none none none 21418 2000000000 /a/b d 0755 none none none 0 /a/b/c d GONE none none none 1 /a/n d 0750 none none none 1 /a/n/m d 0750 none none none 1 /a/n/m/m1 - 0640 none none none 11 15000000000 /d d 0755 none none none 0 /e d 0755 none none none 1 /e/f d 0755 none none none 0 ` if strings.Replace(b.String(), dbg.Usr, "none", -1) != out { t.Fatal("bad repl") } }
func TestSyncNew(t *testing.T) { fstest.ResetTime() fstest.RmTree(t, rdir) fstest.RmTree(t, tdir) fstest.RmTree(t, tdir2) defer fstest.RmTree(t, tdir2) defer fstest.RmTree(t, rdir) defer fstest.RmTree(t, tdir) if err := os.Mkdir(rdir, 0755); err != nil && !dbg.IsExists(err) { t.Fatalf("%s: %s", tdir2, err) } fstest.MkTree(t, tdir) if err := os.Mkdir(tdir2, 0755); err != nil { t.Fatalf("%s: %s", tdir2, err) } r, err := New("testrepl", "", tdir, tdir2) if err != nil { t.Fatalf("new: %s", err) } if testing.Verbose() { r.DumpTo(os.Stdout) } if err := r.Sync(); err != nil { t.Fatalf("sync: %s", err) } if err := r.Save(rcfg); err != nil { t.Fatalf("save: %s", err) } nr, err := Load(rcfg) if err != nil { t.Fatalf("load: %s", err) } if testing.Verbose() { nr.DumpTo(os.Stdout) } var b bytes.Buffer nr.DumpTo(&b) out := `testrepl '' /tmp/db_test /tmp/db_test2 testrepl[/tmp/db_test] / d 0755 none none none 6 /1 - 0644 none none none 0 0 /2 - 0644 none none none 31658 4000000000 /a d 0755 none none none 3 /a/a1 - 0644 none none none 10154 1000000000 /a/a2 - 0644 none none none 21418 2000000000 /a/b d 0755 none none none 1 /a/b/c d 0755 none none none 1 /a/b/c/c3 - 0644 none none none 44970 3000000000 /d d 0755 none none none 0 /e d 0755 none none none 1 /e/f d 0755 none none none 0 testrepl[/tmp/db_test2] / d 0755 none none none 6 /1 - 0644 none none none 0 0 /2 - 0644 none none none 31658 4000000000 /a d 0755 none none none 3 /a/a1 - 0644 none none none 10154 1000000000 /a/a2 - 0644 none none none 21418 2000000000 /a/b d 0755 none none none 1 /a/b/c d 0755 none none none 1 /a/b/c/c3 - 0644 none none none 44970 3000000000 /d d 0755 none none none 0 /e d 0755 none none none 1 /e/f d 0755 none none none 0 ` if s := strings.Replace(b.String(), dbg.Usr, "none", -1); s != out { printf("<%s>\n", s) t.Fatalf("bad repl dbs") } }
func TestUpdate(t *testing.T) { fstest.ResetTime() fstest.MkTree(t, tdir) defer fstest.RmTree(t, tdir) fstest.ResetTime() fstest.MkTree(t, tdir2) defer fstest.RmTree(t, tdir2) fs, err := lfs.New(tdir, tdir, lfs.RW) if err != nil { t.Fatalf("new lfs: %s", err) } fs2, err := lfs.New(tdir2, tdir2, lfs.RW) if err != nil { t.Fatalf("new lfs: %s", err) } Debug = moreverb fs.Dbg = moreverb fs2.Dbg = moreverb fs.SaveAttrs(true) fs2.SaveAttrs(true) // Initial dbs db, err := NewDB("tdb", "", fs) if err != nil { t.Fatalf("new: %s", err) } if testing.Verbose() { db.DumpTo(os.Stdout) } db2, err := NewDB("tdb2", "", fs2) if err != nil { t.Fatalf("new: %s", err) } if testing.Verbose() { db2.DumpTo(os.Stdout) } // Make changes to db2 and update its db fstest.MkChgs(t, tdir2) ndb2, err := NewDB("tndb2", "", fs2) if err != nil { t.Fatalf("new: %s", err) } cc := db2.ChangesTo(ndb2) ec := make(chan error, 1) go chkcc("upd2", cc, nil, ec) if e := <-ec; e != nil { t.Fatal(e) } if testing.Verbose() { ndb2.DumpTo(os.Stdout) } if err := db2.Update(fs2); err != nil { t.Fatalf("update: %s", err) } var b1, b2 bytes.Buffer ndb2.Name = db2.Name ndb2.DumpTo(&b1) db2.DumpTo(&b2) if b1.String() != b2.String() { t.Fatalf("dbs do not match") } }
func TestSyncChgs(t *testing.T) { fstest.ResetTime() fstest.MkTree(t, tdir) defer fstest.RmTree(t, tdir) fstest.ResetTime() fstest.MkTree(t, tdir2) defer fstest.RmTree(t, tdir2) fs, err := lfs.New(tdir, tdir, lfs.RW) if err != nil { t.Fatalf("new lfs: %s", err) } fs2, err := lfs.New(tdir2, tdir2, lfs.RW) if err != nil { t.Fatalf("new lfs: %s", err) } Debug = moreverb fs.Dbg = moreverb fs2.Dbg = moreverb fs.SaveAttrs(true) fs2.SaveAttrs(true) // Initial dbs db, err := NewDB("tdb", "", fs) if err != nil { t.Fatalf("new: %s", err) } if testing.Verbose() { db.DumpTo(os.Stdout) } db2, err := NewDB("tdb2", "", fs2) if err != nil { t.Fatalf("new: %s", err) } if testing.Verbose() { db2.DumpTo(os.Stdout) } // Make changes to db and update its db fstest.MkChgs2(t, tdir) ndb, err := NewDB("tndb", "", fs) if err != nil { t.Fatalf("new: %s", err) } cc := db.ChangesTo(ndb) ec := make(chan error, 1) go chkcc("upd", cc, nil, ec) if e := <-ec; e != nil { t.Fatal(e) } db = ndb if testing.Verbose() { db.DumpTo(os.Stdout) } // Make changes to db2 and update its db fstest.MkChgs(t, tdir2) ndb2, err := NewDB("tndb2", "", fs2) if err != nil { t.Fatalf("new: %s", err) } cc = db2.ChangesTo(ndb2) ec = make(chan error, 1) go chkcc("upd2", cc, nil, ec) if e := <-ec; e != nil { t.Fatal(e) } db2 = ndb2 if testing.Verbose() { db2.DumpTo(os.Stdout) } // Now sync pulls := []chg{ chg{Type: Data, Path: "/a/a1"}, chg{Type: Meta, Path: "/a/a2"}, chg{Type: Del, Path: "/a/b/c"}, chg{Type: Add, Path: "/a/n"}, } pushes := []chg{ chg{Type: Data, Path: "/1"}, chg{Type: DirFile, Path: "/2"}, } pullc, pushc := Changes(db, db2) ec = make(chan error, 2) go chkcc("pull", pullc, pulls, ec) go chkcc("push", pushc, pushes, ec) if e := <-ec; e != nil { t.Fatal(e) } if e := <-ec; e != nil { t.Fatal(e) } if testing.Verbose() { db.DumpTo(os.Stdout) db2.DumpTo(os.Stdout) } }
func TestApplyChgs(t *testing.T) { fstest.ResetTime() fstest.MkTree(t, tdir) defer fstest.RmTree(t, tdir) fstest.ResetTime() fstest.MkTree(t, tdir2) defer fstest.RmTree(t, tdir2) fs, err := lfs.New(tdir, tdir, lfs.RW) if err != nil { t.Fatalf("new lfs: %s", err) } fs2, err := lfs.New(tdir2, tdir2, lfs.RW) if err != nil { t.Fatalf("new lfs: %s", err) } Debug = moreverb fs.Dbg = moreverb fs2.Dbg = moreverb fs.SaveAttrs(true) fs2.SaveAttrs(true) // Initial dbs db, err := NewDB("tdb", "", fs) if err != nil { t.Fatalf("new: %s", err) } db2, err := NewDB("tdb2", "", fs2) if err != nil { t.Fatalf("new: %s", err) } // Make changes to db and update its db fstest.MkChgs2(t, tdir) ndb, err := NewDB("tndb", "", fs) if err != nil { t.Fatalf("new: %s", err) } cc := db.ChangesTo(ndb) ec := make(chan error, 1) go chkcc("upd", cc, nil, ec) if e := <-ec; e != nil { t.Fatal(e) } db = ndb if testing.Verbose() { db.DumpTo(os.Stdout) } // Make changes to db2 and update its db fstest.MkChgs(t, tdir2) ndb2, err := NewDB("tndb2", "", fs2) if err != nil { t.Fatalf("new: %s", err) } cc = db2.ChangesTo(ndb2) ec = make(chan error, 1) go chkcc("upd2", cc, nil, ec) if e := <-ec; e != nil { t.Fatal(e) } db2 = ndb2 if testing.Verbose() { db2.DumpTo(os.Stdout) } // Now apply changes pullc, pushc := Changes(db, db2) ec = make(chan error, 2) errsc := make(chan error) go func() { for e := range errsc { printf("err %s\n", e) } }() go func() { for c := range pullc { printf("pull %s\n", c) if err := c.Apply(fs, fs2, "", errsc); err != nil { close(pullc, err) ec <- err return } } ec <- nil }() go func() { for c := range pushc { printf("push %s\n", c) if err := c.Apply(fs2, fs, "", errsc); err != nil { close(pushc, err) ec <- err return } } ec <- nil }() if e := <-ec; e != nil { t.Fatal(e) } if e := <-ec; e != nil { t.Fatal(e) } close(errsc) db.Update(fs) db2.Update(fs2) if testing.Verbose() { db.DumpTo(os.Stdout) db2.DumpTo(os.Stdout) } var b, b2 bytes.Buffer db2.Name = db.Name db.DumpTo(&b) db2.DumpTo(&b2) if strings.Replace(b.String(), dbg.Usr, "none", -1) != strings.Replace(b2.String(), dbg.Usr, "none", -1) { t.Fatal("dbs do not match") } }