func mkrtest(t *testing.T, rtdir string, excl ...string) (*DB, func()) { cmd.UnixIO("in", "out", "err") os.Args[0] = "repl.test" os.Mkdir(rtdir+"/p", 0755) fstest.Verb = testing.Verbose() fstest.MkTree(t, rtdir+"/p") os.Remove("/tmp/clive.9988") fs, err := zux.NewZX(rtdir) if err != nil { os.RemoveAll(rtdir) os.Remove("/tmp/clive.9988") t.Fatal(err) } srv, err := rzx.NewServer("unix!local!9988", auth.TLSserver) if err != nil { os.RemoveAll(rtdir) os.Remove("/tmp/clive.9988") t.Fatal(err) } if err := srv.Serve("main", fs); err != nil { os.RemoveAll(rtdir) os.Remove("/tmp/clive.9988") t.Fatal(err) } db := mkdb(t, "unix!local!9988!/p", excl...) fn := func() { db.Close() os.RemoveAll(rtdir) os.Remove("/tmp/clive.9988") srv.Close() } return db, fn }
func TestExtChanges(t *testing.T) { os.Args[0] = "rzx.test" fstest.Verb = testing.Verbose() ccfg, err := net.TLSCfg("/Users/nemo/.ssh/client") if err != nil { t.Logf("no certs found, no tls conn") } scfg, err := net.TLSCfg("/Users/nemo/.ssh/server") if err != nil || ccfg == nil { ccfg = nil scfg = nil t.Logf("no certs found, no tls conn") } _, _ = scfg, ccfg fstest.MkTree(t, tdir) defer os.RemoveAll(tdir) lfs, err := zux.NewZX(tdir) if err != nil { t.Fatal(err) } defer lfs.Sync() cfs, err := New(lfs) if err != nil { t.Fatal(err) } defer cfs.Close() cfs.Debug = testing.Verbose() lfs.Debug = testing.Verbose() cfs.Flags.Set("rfsdebug", cfs.Debug) cfs.Flags.Set("cachedebug", cfs.Debug) cfs.Flags.Set("verb", cfs.Debug) rc := fscmp.Diff(lfs, cfs) out := "" for c := range rc { s := fmt.Sprintf("pre chg %s %s\n", c.Type, c.D.Fmt()) out += s } if len(out) > 0 { t.Fatalf("had changes") } cfs.Dprintf("%s", out) fstest.MkZXChgs(t, lfs) fstest.MkZXChgs2(t, lfs) cacheTout = time.Millisecond time.Sleep(cacheTout) rc = fscmp.Diff(lfs, cfs) out = "" for c := range rc { s := fmt.Sprintf("post chg %s %s\n", c.Type, c.D.Fmt()) out += s } cfs.Dprintf("%s", out) if len(out) > 0 { t.Fatalf("had missed external changes") } if cfs.Debug { cfs.c.dump() } }
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 main() { cmd.UnixIO() c := cmd.AppCtx() dfltdump := Path(u.Home, "dump") opts.NewFlag("s", "don't dump right now, wait until next at 5am", &Skip) opts.NewFlag("1", "dump once and exit", &Once) opts.NewFlag("v", "verbose", &c.Verb) opts.NewFlag("D", "debug", &c.Debug) opts.NewFlag("x", "expr: files excluded (.*, tmp.* if none given); tmp always excluded.", &Xcludes) Dump = dfltdump opts.NewFlag("d", "dir: where to keep the dump, ~/dump if none", &Dump) args := opts.Parse() if len(Xcludes) == 0 { Xcludes = []string{".*", "tmp.*", "*.tmp"} } Xcludes = append(Xcludes, "tmp") if len(args) == 0 { cmd.Warn("arguments missing") opts.Usage() } if Skip && Once { cmd.Fatal("can't skip the current dump and dump once now") } nt := 0 ec := make(chan bool) for i := 0; i < len(args); i++ { al := strings.SplitN(args[i], "!", 2) if len(al) == 1 { al = append(al, al[0]) al[0] = fpath.Base(al[0]) } t, err := zux.NewZX(al[1]) if err != nil { dbg.Warn("%s: %s", al[0], err) continue } t.Tag = al[0] t.Flags.Set("rdonly", true) nt++ go dump(Dump, t.Tag, t, ec) } if nt == 0 { cmd.Fatal("no trees to dump") } for nt > 0 { <-ec nt-- } }
func runTest(t *testing.T, fn fstest.TestFunc) { os.Args[0] = "rzx.test" fstest.Verb = testing.Verbose() ccfg, err := net.TLSCfg("/Users/nemo/.ssh/client") if err != nil { t.Logf("no certs found, no tls conn") } scfg, err := net.TLSCfg("/Users/nemo/.ssh/server") if err != nil || ccfg == nil { ccfg = nil scfg = nil t.Logf("no certs found, no tls conn") } _, _ = scfg, ccfg fstest.MkTree(t, tdir) defer os.RemoveAll(tdir) lfs, err := zux.NewZX(tdir) if err != nil { t.Fatal(err) } defer lfs.Sync() cfs, err := New(lfs) if err != nil { t.Fatal(err) } defer cfs.Close() cfs.Debug = testing.Verbose() lfs.Debug = testing.Verbose() cfs.Flags.Set("rfsdebug", cfs.Debug) cfs.Flags.Set("cachedebug", cfs.Debug) if fn != nil { fn(t, cfs) } else { d, err := zx.Stat(cfs, "/") if err != nil { t.Fatalf("stat /: %v", err) } t.Logf("/ stat is %s\n", d.TestFmt()) } if cfs.Debug { cfs.c.dump() } }
// Add the given (absolute) paths as valid paths to resolve lfs addresses. // If the path is not ok, it's a panic. // DirFs relies on this to resolve addresses of the form lfs!* // and the longest path added is used. // If fs is not given, a default zux tree is made for it and it's a panic if // we fail to make fs. func AddLfsPath(path string, fs zx.Fs) { path, err := zx.UseAbsPath(path) if err != nil { panic(err) } if fs == nil { fs, err = zux.NewZX(path) if err != nil { panic(err) } } lfslk.Lock() defer lfslk.Unlock() addr := path if ofs, ok := lfs[addr]; ok { if cfs, ok := ofs.(io.Closer); ok { cfs.Close() } } lfs[addr] = fs }
func main() { cmd.UnixIO() opts.AddUsage("\tspec is name | name!file | name!file!flags \n") opts.AddUsage("\tspec flags are ro | rw | ncro | ncrw \n") port = "8002" addr = "*!*!zx" opts.NewFlag("p", "port: tcp server port (8002 by default)", &port) opts.NewFlag("a", "addr: service address (*!*!zx by default)", &addr) opts.NewFlag("s", "use writesync for caches", &wsync) c := cmd.AppCtx() opts.NewFlag("D", "debug", &c.Debug) opts.NewFlag("A", "auth debug", &auth.Debug) opts.NewFlag("v", "report users logged in/out (verbose)", &c.Verb) opts.NewFlag("Z", "verbose debug", &Zdebug) opts.NewFlag("n", "no auth", &noauth) args := opts.Parse() if len(args) == 0 { cmd.Warn("missing arguments") opts.Usage() } c.Debug = c.Debug || Zdebug auth.Debug = c.Debug trs := map[string]zx.Fs{} ros := map[bool]string{false: "rw", true: "ro"} cs := map[bool]string{false: "uncached", true: "cached"} rotrs := map[string]bool{} var mainfs zx.Fs for i := 0; i < len(args); i++ { al := strings.Split(args[i], "!") if len(al) == 1 { al = append(al, al[0]) al[0] = fpath.Base(al[0]) } if _, ok := trs[al[0]]; ok { cmd.Warn("dup tree name %s", al[0]) continue } ronly := false caching := true if len(al) == 3 && strings.Contains(al[2], "ro") { ronly = true } if len(al) == 3 && strings.Contains(al[2], "nc") { caching = false } fp, _ := filepath.Abs(al[1]) t, err := zux.NewZX(fp) if err != nil { cmd.Warn("%s: %s", al[0], err) continue } t.Tag = al[0] cmd.Warn("%s %s %s", al[0], ros[ronly], cs[caching]) var x zx.Fs = t if caching { x, err = zxc.New(t) if err != nil { dbg.Warn("%s: zxc: %s", al[0], err) continue } if Zdebug { x.(*zxc.Fs).Debug = true } if wsync { x.(*zxc.Fs).Flags.Set("writesync", true) } } else if Zdebug { x.(*zux.Fs).Debug = true } trs[t.Tag] = x if i == 0 { mainfs = x } rotrs[t.Tag] = ronly } if len(trs) == 0 { cmd.Fatal("no trees to serve") } if _, ok := trs["main"]; !ok { trs["main"] = mainfs } vprintf("serve %s...", addr) srv, err := rzx.NewServer(addr, auth.TLSserver) if err != nil { cmd.Fatal("serve: %s", err) } if noauth { srv.NoAuth() } if c.Debug { srv.Debug = true } for nm, fs := range trs { if cfs, ok := fs.(*zxc.Fs); ok { cfs.Flags.Add("debug", &srv.Debug) cfs.Flags.Add("zdebug", &cfs.Debug) } else if lfs, ok := fs.(*zux.Fs); ok { lfs.Flags.Add("debug", &srv.Debug) lfs.Flags.Add("zdebug", &lfs.Debug) } if rotrs[nm] { fs = zx.MakeRO(fs) trs[nm] = fs } if err := srv.Serve(nm, fs); err != nil { cmd.Fatal("serve: %s: %s", nm, err) } } if err := srv.Wait(); err != nil { cmd.Fatal("srv: %s", err) } }