func TestTreeSync(t *testing.T) { db, fn := mkrtest(t, rtdir) defer fn() db.Close() db, fn2 := mktest(t, tdir) defer fn2() db.Close() tr, err := New("adb", tdir, "unix!local!9988!/p") if err != nil { t.Fatalf("tree %s", err) } tr.Debug = testing.Verbose() tr.Rdb.Debug = testing.Verbose() defer tr.Close() fstest.MkChgs(t, tdir) fstest.MkChgs2(t, rtdir+"/p") dprintf("\nsync\n") cc, dc := getChgs() err = tr.Sync(cc) if err != nil { t.Fatalf("sync %s", err) } cs := <-dc logChgs(cs) chkFiles(t, tr.Ldb, nil, "") chkFiles(t, tr.Rdb, nil, "") os.RemoveAll(tdir + ".pull") os.Rename(tdir, tdir+".pull") os.RemoveAll(rtdir + ".push") os.Rename(rtdir+"/p", rtdir+".push") }
func TestTreePush(t *testing.T) { db, fn := mkrtest(t, rtdir) defer fn() db.Close() db, fn2 := mktest(t, tdir) defer fn2() db.Close() tr, err := New("adb", tdir, "unix!local!9988!/p") if err != nil { t.Fatalf("tree %s", err) } tr.Debug = testing.Verbose() tr.Rdb.Debug = testing.Verbose() defer tr.Close() fstest.MkChgs(t, tdir) fstest.MkChgs2(t, rtdir+"/p") chkFiles(t, tr.Ldb, fstest.AllFiles, fstest.AllFilesList) chkFiles(t, tr.Rdb, fstest.AllFiles, fstest.AllFilesList) dprintf("\npush\n") cc, dc := getChgs() err = tr.BlindPush(cc) if err != nil { t.Fatalf("push %s", err) } cs := <-dc logChgs(cs) cmpChgs(t, pushcs, cs) chkFiles(t, tr.Ldb, nil, pushldb) chkFiles(t, tr.Rdb, nil, pushrdb) os.RemoveAll(rtdir + ".push") os.Rename(rtdir+"/p", rtdir+".push") }
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 TestTreeSaveLoad(t *testing.T) { db, fn := mkrtest(t, rtdir) defer fn() db.Close() db, fn2 := mktest(t, tdir) defer fn2() db.Close() fstest.MkChgs(t, tdir) fstest.MkChgs2(t, rtdir+"/p") os.Remove(tdir + "repl.ldb") os.Remove(tdir + "repl.rdb") defer os.Remove(tdir + "repl.ldb") defer os.Remove(tdir + "repl.rdb") tr, err := New("adb", tdir, "unix!local!9988!/p") if err != nil { t.Fatalf("tree %s", err) } tr.Debug = testing.Verbose() tr.Rdb.Debug = testing.Verbose() defer tr.Close() dprintf("\ninitial:\n") chkFiles(t, tr.Ldb, nil, "") chkFiles(t, tr.Rdb, nil, "") dprintf("\nsave & load:\n") if err := tr.Save(tdir + "repl"); err != nil { t.Fatalf("save %s", err) } if tr, err = Load(tdir + "repl"); err != nil { t.Fatalf("load %s", err) } chkFiles(t, tr.Ldb, nil, "") chkFiles(t, tr.Rdb, nil, "") // now continue as in the previous test, to check // it all is ok. dprintf("\npullall\n") cc, dc := getChgs() err = tr.PullAll(cc) if err != nil { t.Fatalf("pullall %s", err) } dprintf("\npullall done\n") cs := <-dc logChgs(cs) chkFiles(t, tr.Ldb, nil, pullrdb) chkFiles(t, tr.Rdb, nil, pullrdb) os.RemoveAll(tdir + ".pull") os.Rename(tdir, tdir+".pull") os.RemoveAll(rtdir + ".push") os.Rename(rtdir+"/p", rtdir+".push") }
func TestTreeAllPushChanges(t *testing.T) { db, fn := mkrtest(t, rtdir) defer fn() db.Close() db, fn2 := mktest(t, tdir) defer fn2() db.Close() tr, err := New("adb", tdir, "unix!local!9988!/p") if err != nil { t.Fatalf("tree %s", err) } tr.Debug = testing.Verbose() tr.Rdb.Debug = testing.Verbose() defer tr.Close() dprintf("\ndiffs before making changes\n") cc, err := tr.AllPushChanges() if err != nil { t.Fatalf("sync %s", err) } chgs := []Chg{} for c := range cc { chgs = append(chgs, c) dprintf("chg %s\n", c) } cmpChgs(t, pushdchgs, chgs) dprintf("\ndiffs after making changes\n") fstest.MkChgs(t, tdir) fstest.MkChgs2(t, rtdir+"/p") cc, err = tr.AllPushChanges() if err != nil { t.Fatalf("sync %s", err) } chgs = []Chg{} for c := range cc { chgs = append(chgs, c) dprintf("chg2 %s\n", c) } cmpChgs(t, pushdchgs2, chgs) os.RemoveAll(tdir + ".pull") os.Rename(tdir, tdir+".pull") os.RemoveAll(rtdir + ".push") os.Rename(rtdir+"/p", rtdir+".push") }
func TestTreeChanges(t *testing.T) { db, fn := mkrtest(t, rtdir) defer fn() db.Close() db, fn2 := mktest(t, tdir) defer fn2() db.Close() tr, err := New("adb", tdir, "unix!local!9988!/p") if err != nil { t.Fatalf("tree %s", err) } tr.Debug = testing.Verbose() defer tr.Close() fstest.MkChgs(t, tdir) fstest.MkChgs2(t, rtdir+"/p") dprintf("pull\n") cc, err := tr.PullChanges() if err != nil { t.Fatalf("pull %s", err) } for c := range cc { dprintf("chg %s %s\n", c.At, c) } dprintf("push\n") cc, err = tr.PushChanges() if err != nil { t.Fatalf("push %s", err) } for c := range cc { dprintf("chg %s %s\n", c.At, c) } dprintf("sync\n") cc, err = tr.Changes() if err != nil { t.Fatalf("sync %s", err) } chgs := []Chg{} for c := range cc { chgs = append(chgs, c) dprintf("chg %s %s\n", c.At, c) } cmpChgs(t, schg, chgs) }
func TestDiffs(t *testing.T) { os.Args[0] = "fscmp.test" fstest.Verb = testing.Verbose() fstest.MkTree(t, tdir) fstest.MkChgs(t, tdir) defer os.RemoveAll(tdir) fstest.ResetTime() fstest.MkTree(t, tdir2) fstest.MkChgs2(t, tdir2) defer os.RemoveAll(tdir2) Printf("changes...\n") fs, err := zux.NewZX(tdir) if err != nil { t.Fatal(err) } fs2, err := zux.NewZX(tdir2) if err != nil { t.Fatal(err) } rc := Diff(fs, fs2) out := "" for c := range rc { s := fmt.Sprintf("chg %s %s\n", c.Type, c.D.Fmt()) Printf("%s", s) out += s } xout := `chg data - rw-r--r-- 50 /1 chg dirfile d rwxr-x--- 0 /2 chg data - rw-r--r-- 9.9k /a/a1 chg meta - rw-r--r-- 20.9k /a/a2 chg add d rwxr-xr-x 0 /a/b/c chg add - rw-r--r-- 43.9k /a/b/c/c3 chg del d rwxr-x--- 0 /a/n chg del d rwxr-x--- 0 /a/n/m chg del - rw-r----- 11 /a/n/m/m1 ` if out != xout { t.Fatalf("bad set of changes") } }
func TestCmp(t *testing.T) { db, fn := mktest(t, tdir) defer fn() fstest.MkChgs(t, tdir) dprintf("db after changes\n") ndb := mkdb(t, tdir) chkFiles(t, ndb, fstest.AllChgFiles, fstest.AllChgFilesList) cc := ndb.ChangesFrom(db) chgs := []Chg{} for c := range cc { chgs = append(chgs, c) dprintf("chg %s\n", c) } cmpChgs(t, chg1, chgs) fstest.MkChgs2(t, tdir) dprintf("\ndb after changes2\n") ndb2 := mkdb(t, tdir) chkFiles(t, ndb2, fstest.AllChg2Files, fstest.AllChg2FilesList) dprintf("\nchanges...\n") chgs = []Chg{} cc = ndb2.ChangesFrom(ndb) for c := range cc { chgs = append(chgs, c) dprintf("chg %s\n", c) } cmpChgs(t, chg2, chgs) dprintf("all chgs\n") chgs = []Chg{} cc = ndb2.ChangesFrom(db) for c := range cc { chgs = append(chgs, c) dprintf("chg %s\n", c) } cmpChgs(t, chg3, chgs) }
func TestRzxCmp(t *testing.T) { db, fn := mkrtest(t, rtdir) defer fn() fstest.MkChgs(t, rtdir+"/p") dprintf("db after changes\n") ndb := mkdb(t, "unix!local!9988!/p") chkFiles(t, ndb, fstest.AllChgFiles, fstest.AllChgFilesList) defer ndb.Close() cc := ndb.ChangesFrom(db) chgs := []Chg{} for c := range cc { chgs = append(chgs, c) dprintf("chg %s\n", c) } cmpChgs(t, chg1, chgs) fstest.MkChgs2(t, rtdir+"/p") dprintf("\ndb after changes2\n") ndb2 := mkdb(t, "unix!local!9988!/p") chkFiles(t, ndb2, fstest.AllChg2Files, fstest.AllChg2FilesList) defer ndb2.Close() chgs = []Chg{} cc = ndb2.ChangesFrom(ndb) for c := range cc { chgs = append(chgs, c) dprintf("chg %s\n", c) } cmpChgs(t, chg2, chgs) dprintf("all chgs\n") chgs = []Chg{} cc = ndb2.ChangesFrom(db) for c := range cc { chgs = append(chgs, c) dprintf("chg %s\n", c) } cmpChgs(t, chg3, chgs) }
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") } }
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 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.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") } }