Пример #1
0
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)
	}
}
Пример #2
0
func mklfstrees(t *testing.T) (zx.RWTree, zx.RWTree) {
	fstest.MkTree(t, tdir)
	lfs1, err := lfs.New(tdir, tdir, lfs.RW)
	if err != nil {
		t.Fatalf("lfs: %s", err)
	}
	lfs2, err := lfs.New(tdir, tdir, lfs.RW)
	if err != nil {
		t.Fatalf("lfs: %s", err)
	}
	return lfs1, lfs2
}
Пример #3
0
func TestInitDirs(t *testing.T) {
	os.Args[0] = "mdfs_test"
	os.RemoveAll(tlfsdir)
	defer os.RemoveAll(tlfsdir)
	if err := os.Mkdir(tlfsdir, 0755); err != nil {
		t.Fatalf("lfs: %s", err)
	}
	dfs, err := lfs.New("	cache", tlfsdir, lfs.RW)
	if err != nil {
		t.Fatalf("lfs: %s", err)
	}
	dfs.SaveAttrs(true)
	dfs.Dbg = moreverb && testing.Verbose()
	fs, err := New("example mdfs", dfs)
	if err != nil {
		t.Fatalf("mdfs: %s", err)
	}
	fs.Dbg = testing.Verbose()
	if fs.Dbg {
		defer func() {
			fs.Dbg = false
			dfs.Dbg = false
			fs.Dump(os.Stdout)
			dfs.Dump(os.Stdout)
		}()
	}
	for _, dn := range fstest.Dirs {
		if err := zx.MkdirAll(fs, dn, zx.Dir{"mode": "0755"}); err != nil {
			t.Fatalf("mkdir: %s", err)
		}
	}
}
Пример #4
0
func testfn(t *testing.T, fns ...func(t fstest.Fataler, fss ...zx.Tree)) {
	bufs.Size = 1 * 1024
	os.RemoveAll(tlfsdir)
	defer os.RemoveAll(tlfsdir)
	if err := os.Mkdir(tlfsdir, 0755); err != nil {
		t.Fatalf("lfs: %s", err)
	}
	os.Args[0] = "mdfs_test"
	dfs, err := lfs.New("	cache", tlfsdir, lfs.RW)
	if err != nil {
		t.Fatalf("lfs: %s", err)
	}
	dfs.SaveAttrs(true)
	mfs, err := New("example mfs", dfs)
	if err != nil {
		t.Fatalf("lfs: %s", err)
	}
	xfs, _ := mfs.AuthFor(&auth.Info{Uid: dbg.Usr, SpeaksFor: dbg.Usr, Ok: true})
	fs := xfs.(zx.RWTree)
	fstest.MkZXTree(t, fs)
	mfs.Dbg = testing.Verbose()
	dfs.Dbg = testing.Verbose()
	var fn func(t fstest.Fataler, fss ...zx.Tree)
	if len(fns) > 0 {
		fn = fns[0]
	}
	if fn != nil {
		if mfs.Dbg {
			defer func() {
				mfs.Dump(os.Stdout)
				dfs.Dump(os.Stdout)
			}()
		}
		for _, fn := range fns {
			fn(t, fs)
		}
	} else {
		d1, _ := zx.Stat(mfs, "/")
		printf("mfs st:\t%s\n", d1)
		d1, _ = zx.Stat(dfs, "/")
		printf("lfs st:\t%s\n", d1)
		// recreate, to test a reload
		mfs, err = New("example mfs", dfs)
		if err != nil {
			t.Fatalf("lfs: %s", err)
		}
		mfs.Dbg = testing.Verbose()
		xfs, _ = mfs.AuthFor(&auth.Info{Uid: dbg.Usr, SpeaksFor: dbg.Usr, Ok: true})
		fs = xfs.(zx.RWTree)
		if mfs.Dbg {
			defer func() {
				mfs.Dump(os.Stdout)
				dfs.Dump(os.Stdout)
			}()
		}
	}
	mfs.Dbg = false
	dfs.Dbg = false
	fstest.SameDump(t, mfs, dfs)
}
Пример #5
0
func lfscache(t zx.Tree, fn func()) (zx.Tree, func(), error) {
	m, err := lfs.New("clfs", lfsdir, lfs.RW)
	if err != nil {
		return nil, nil, fmt.Errorf("lfs", err)
	}
	m.SaveAttrs(true)
	m.IOstats = &zx.IOstats{}
	m.Dbg = zdebug
	ncfs.Debug = zdebug
	xfs, err := ncfs.New("cfs", m, t, rflag)
	if err != nil {
		return nil, nil, fmt.Errorf("cfs: %s", err)
	}
	st := &zx.IOstats{}
	xfs.IOstats = st
	if xaddr != "" {
		serve(xfs, xaddr)
	}
	if sflag {
		xfn := func() {
			st.Averages()
			dbg.Warn("%s iostats:\n%s\n", xfs.Name(), st)
			if fn != nil {
				fn()
			}
		}
		return xfs, xfn, nil
	}
	return xfs, fn, nil
}
Пример #6
0
/*
	Import the remote ZX server at the given address.
	This performs authentication if auth.Enabled and honors TLS configuration.
	Addresses of the form "*!*!lfs!tree!/a/b" are understood as a request to build
	a local fs at the given path.
	An address referring to a existing dir path is also used to build a local fs.
*/
func Import(addr string) (zx.RWTree, error) {
	if fi, err := os.Stat(addr); err == nil && fi.IsDir(){
		dir, err := filepath.Abs(addr)
		if err != nil {
			return nil, err
		}
		fs, err := lfs.New(addr, dir, lfs.RW)
		if err == nil {
			fs.SaveAttrs(true)
		}
		return fs, err
	}
	toks := strings.Split(addr, "!")
	if len(toks) < 2 {
		return nil, errors.New("bad address")
	}
	if len(toks) < 3 {
		toks = append(toks, "zx")
		addr = strings.Join(toks, "!")
	}
	if toks[2] == "lfs" {
		p := "/"
		if len(toks) >= 5 {
			p = toks[4]
		}
		fs, err := lfs.New(addr, p, lfs.RW)
		if err == nil {
			fs.SaveAttrs(true)
		}
		return fs, err
	}
	tree := "main"
	if len(toks) >= 4 {
		tree = toks[3]
	}
	c, err := ds.Dial(addr)
	if err != nil {
		return nil, err
	}
	if _, err := auth.AtClient(c, "", "zx"); err!=nil && err!=auth.ErrDisabled {
		err = fmt.Errorf("auth: %s", err)
		close(c.In, err)
		close(c.Out, err)
		return nil, err
	}
	return New(nchan.NewMux(c, true), tree)
}
Пример #7
0
func TestSendRecv(t *testing.T) {
	t.Skip("TODO: this does not work but we are no longer sending trees")
	os.RemoveAll(tlfsdir + "2")
	os.RemoveAll(tlfsdir)
	if err := os.Mkdir(tlfsdir, 0755); err != nil {
		t.Fatalf("lfs: %s", err)
	}
	if err := os.Mkdir(tlfsdir+"2", 0755); err != nil {
		t.Fatalf("lfs: %s", err)
	}
	defer os.RemoveAll(tlfsdir + "2")
	defer os.RemoveAll(tlfsdir)
	os.Args[0] = "mdfs_test"

	dfs1, err := lfs.New("	cache1", tlfsdir, lfs.RW)
	if err != nil {
		t.Fatalf("lfs: %s", err)
	}
	dfs1.SaveAttrs(true)
	fs1, err := New("example mfs1", dfs1)
	if err != nil {
		t.Fatalf("mdfs: %s", err)
	}
	fs1.Dbg = testing.Verbose()

	fstest.MkZXTree(t, fs1)
	dfs2, err := lfs.New("	cache2", tlfsdir+"2", lfs.RW)
	if err != nil {
		t.Fatalf("lfs: %s", err)
	}
	dfs2.SaveAttrs(true)
	fs2, err := New("example mfs2", dfs2)
	if err != nil {
		t.Fatalf("mdfs: %s", err)
	}
	if fs1.Dbg {
		defer fs2.Dump(os.Stdout)
		defer fs1.Dump(os.Stdout)
	}
	fstest.SendRecv(t, fs1, fs2)

}
Пример #8
0
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)
	}
}
Пример #9
0
func main() {
	defer dbg.Exits("")
	os.Args[0] = "zxdump"
	dfltdump := zx.Path(dbg.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", &Verbose)
	opts.NewFlag("D", "debug", &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, or empty if none", &Dump)
	args, err := opts.Parse(os.Args)
	if err != nil {
		dbg.Warn("%s", err)
		opts.Usage()
		dbg.Exits(err)
	}
	if len(Xcludes) == 0 {
		Xcludes = []string{".*", "tmp.*", "*.tmp"}
	}
	Xcludes = append(Xcludes, "tmp")
	if len(args) == 0 {
		dbg.Warn("arguments missing")
		opts.Usage()
		dbg.Exits("usage")
	}
	if Skip && Once {
		dbg.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] = path.Base(al[0])
		}
		t, err := lfs.New(al[0], al[1], lfs.RO)
		if err != nil {
			dbg.Warn("%s: %s", al[0], err)
			continue
		}
		t.ReadAttrs(true)
		nt++
		go dump(Dump, t, ec)
	}
	if nt == 0 {
		dbg.Fatal("no trees to dump")
	}
	for nt > 0 {
		<-ec
		nt--
	}
}
Пример #10
0
// on-disk cache
func dcache() (zx.RWTree, *zx.Flags, error) {
	m, err := lfs.New("clfs", lfscache, lfs.RW)
	if err != nil {
		return nil, nil, fmt.Errorf("lfs", err)
	}
	m.SaveAttrs(true)
	m.IOstats = &zx.IOstats{}
	m.Dbg = lfsdebug
	m.WstatAll = true // cfs must be able to write it all
	return m, m.Flags, nil
}
Пример #11
0
func mklfs(path string) (zx.RWTree, *zx.Flags, *zx.IOstats, error) {
	ronly := rflag && nocache
	fs, err := lfs.New(path, path, ronly)
	if err != nil {
		return nil, nil, nil, fmt.Errorf("lfs: %s", err)
	}
	if sflag {
		fs.IOstats = &zx.IOstats{}
	}
	fs.Dbg = lfsdebug
	fs.SaveAttrs(true)
	return fs, fs.Flags, fs.IOstats, nil
}
Пример #12
0
func ExampleNew() {
	// create a tree using the local directory /tmp/cache for the cache
	dfs, err := lfs.New("cache", "/tmp/cache", lfs.RW)
	if err != nil {
		dbg.Fatal("lfs: %s", err)
	}
	fs, err := New("example mdfs", dfs)
	if err != nil {
		dbg.Fatal("mfds: %s", err)
	}
	dbg.Warn("fs %s ready", fs)
	// Now use it...
}
Пример #13
0
// on-memory medatadata, on-disk data cache
func mdcache() (zx.RWTree, *zx.Flags, error) {
	d, err := lfs.New("mlfs", mlfscache, lfs.RW)
	if err != nil {
		return nil, nil, fmt.Errorf("lfs", err)
	}
	d.SaveAttrs(true)
	d.WstatAll = true // cfs must be able to write it all
	m, err := mdfs.New("mdfs", d)
	if err != nil {
		return nil, nil, fmt.Errorf("mdfs: %s", err)
	}
	m.IOstats = &zx.IOstats{}
	d.Dbg = lfsdebug && false
	m.Dbg = lfsdebug
	m.WstatAll = true // cfs must be able to write it all
	return m, m.Flags, nil
}
Пример #14
0
func testfs(t fstest.Fataler) (*lfs.Lfs, *Rfs) {
	fs, err := lfs.New(tdir, tdir, lfs.RW)
	if err != nil {
		t.Fatalf("new: %s", err)
	}
	c1, c2 := nchan.NewConnPipe(0)
	srv := Serve("srv", c1, nil, RW, fs)
	srv.Debug = testing.Verbose() && moreverb
	rfs, err := New(nchan.NewMux(c2, true), "")
	if err != nil {
		t.Fatalf("%s", err)
	}
	rfs.Tag = "cli"
	rfs.Dbg = testing.Verbose()
	VerbDebug = moreverb
	return fs, rfs
}
Пример #15
0
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")
	}
}
Пример #16
0
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)
	}
}
Пример #17
0
func main() {
	defer dbg.Exits("")
	os.Args[0] = "zx"
	port = "8002"
	opts.NewFlag("p", "port: tcp server port (8002 by default)", &port)
	wport = "9002"
	opts.NewFlag("w", "port: wax http server port", &wport)
	svc = "zx"
	opts.NewFlag("s", "srv: service name (zx by default)", &svc)
	addr = "*!*!zx"
	opts.NewFlag("a", "addr: service address (*!*!zx by default)", &addr)
	opts.NewFlag("v", "report users logged in/out (verbose)", &Verbose)
	opts.NewFlag("D", "debug", &Debug)
	opts.NewFlag("Z", "verbose debug", &Zdebug)
	opts.NewFlag("M", "debug mutexes", &cfs.DebugLocks)
	nopings := false
	opts.NewFlag("k", "do not use zx keep alives", &nopings)
	args, err := opts.Parse(os.Args)
	if err != nil {
		usage(err)
	}
	if len(args) == 0 {
		usage(errors.New("missing arguments"))
	}
	Debug = Debug || Zdebug
	auth.Debug = Debug
	cfs.Debug = Debug
	rfs.Verb = Verbose
	var trs []zx.Tree
	var ros = map[bool]string{false: "rw", true: "ro"}

	for i := 0; i < len(args); i++ {
		al := strings.Split(args[i], "!")
		if len(al) == 1 {
			al = append(al, al[0])
			al[0] = path.Base(al[0])
		}
		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
		}
		t, err := lfs.New(al[0], al[1], ronly && !caching)
		if err != nil {
			dbg.Warn("%s: %s", al[0], err)
			continue
		}
		t.ReadAttrs(true)
		t.SaveAttrs(caching)
		t.IOstats = &zx.IOstats{}
		fp, _ := filepath.Abs(al[1])
		if caching {
			dbg.Warn("%s mfs + lfs %s caching", al[0], ros[ronly])
			cache, err := mfs.New("mfs:" + al[0])
			if err != nil {
				dbg.Warn("%s: mfs: %s", al[0], err)
				continue
			}
			cache.IOstats = &zx.IOstats{}
			cache.Dbg = Zdebug
			cache.WstatAll = true // cfs must be able to write it all
			x, err := cfs.New(al[0], cache, t, ronly)
			if err != nil {
				dbg.Warn("%s: cfs: %s", al[0], err)
				continue
			}
			x.IOstats = &zx.IOstats{}
			zxw[al[0]] = fp
			trs = append(trs, x)

		} else {
			dbg.Warn("%s lfs %s uncached", al[0], ros[ronly])
			zxw[al[0]] = fp
			t.Dbg = Debug
			trs = append(trs, t)
		}
	}
	if len(trs) == 0 {
		dbg.Fatal("no trees to serve")
	}

	ds.DefSvc(svc, port)
	Vprintf("%s: serve %s...\n", os.Args[0], addr)
	cc, _, err := ds.Serve(os.Args[0], addr)
	if err != nil {
		dbg.Fatal("%s: serve: %s", os.Args[0], err)
	}

	go zxwax()
	for c := range cc {
		go func(c nchan.Conn) {
			ai, err := auth.AtServer(c, "", "zx", "finder")
			if err != nil && err != auth.ErrDisabled {
				Vprintf("%s: auth %s: %s\n", os.Args[0], c.Tag, err)
				close(c.In, err)
				close(c.Out, err)
				return
			}
			srv := rfs.Serve("rfs:"+c.Tag, c, ai, rfs.RW, trs...)
			if false {
				srv.Debug = Debug
			}
			srv.Pings = !nopings

		}(*c)
	}
	if err := cerror(cc); err != nil {
		dbg.Fatal("%s: serve: %s", os.Args[0], err)
	}
}
Пример #18
0
func main() {
	defer dbg.Exits("")
	os.Args[0] = "zx"
	port = "8002"
	opts.NewFlag("p", "port: tcp server port", &port)
	wport = "9002"
	opts.NewFlag("w", "port: wax http server port", &wport)
	svc = "zx"
	opts.NewFlag("s", "srv: service name", &svc)
	addr = "*!*!zx"
	opts.NewFlag("a", "addr: service address", &addr)
	opts.NewFlag("D", "debug", &Debug)
	opts.NewFlag("Z", "verbose debug", &Zdebug)
	opts.NewFlag("k", "make cfg entries persist in the ns", &Persist)
	opts.NewFlag("N", "use new cfs", &New)
	args, err := opts.Parse(os.Args)
	if err != nil {
		usage(err)
	}
	if len(args) == 0 {
		usage(nil)
	}
	Debug = Debug || Zdebug
	auth.Debug = Debug
	ncfs.Debug = Debug
	cfs.Debug = Debug
	cfs.Cdebug = Zdebug
	cfs.Zdebug = Zdebug
	rfs.Verb = Verbose
	var trs []zx.Tree
	var ros = map[bool]string{false: "rw", true: "ro"}

	for i := 0; i < len(args); i++ {
		al := strings.Split(args[i], "!")
		if len(al) == 1 {
			al = append(al, al[0])
			al[0] = path.Base(al[0])
		}
		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
		}
		t, err := lfs.New(al[0], al[1], ronly && !caching)
		if err != nil {
			dbg.Warn("%s: %s", al[0], err)
			continue
		}
		t.ReadAttrs(true)
		t.SaveAttrs(caching)
		t.IOstats = &zx.IOstats{}
		fp, _ := filepath.Abs(al[1])
		if New && caching {
			dbg.Warn("%s mfs + lfs %s caching", al[0], ros[ronly])
			cache, err := mfs.New("mfs:" + al[0])
			if err != nil {
				dbg.Warn("%s: mfs: %s", al[0], err)
				continue
			}
			cache.IOstats = &zx.IOstats{}
			cache.Dbg = Zdebug
			x, err := ncfs.New("cfs", cache, t, ronly)
			if err != nil {
				dbg.Warn("%s: cfs: %s", al[0], err)
				continue
			}
			x.IOstats = &zx.IOstats{}
			zxw[al[0]] = fp
			trs = append(trs, x)

		} else if !New && caching {
			dbg.Warn("%s old cfs + lfs %s caching", al[0], ros[ronly])
			x, err := cfs.New("", t, ronly)
			if err != nil {
				dbg.Warn("%s: cfs: %s", al[0], err)
				continue
			}
			x.IOstats = &zx.IOstats{}
			zxw[al[0]] = fp
			trs = append(trs, x)
		} else {
			dbg.Warn("%s lfs %s uncached", al[0], ros[ronly])
			zxw[al[0]] = fp
			t.Dbg = Debug
			trs = append(trs, t)
		}
	}
	if len(trs) == 0 {
		dbg.Fatal("no trees to serve")
	}

	ds.DefSvc(svc, port)
	Vprintf("%s: serve %s...\n", os.Args[0], addr)
	cc, _, err := ds.Serve(os.Args[0], addr)
	if err != nil {
		dbg.Fatal("%s: serve: %s", os.Args[0], err)
	}

	go zxwax()
	for c := range cc {
		go func(c nchan.Conn) {
			ai, err := auth.AtServer(c, "", "zx", "finder")
			if err != nil && err != auth.ErrDisabled {
				Vprintf("%s: auth %s: %s\n", os.Args[0], c.Tag, err)
				close(c.In, err)
				close(c.Out, err)
				return
			}
			srv := rfs.Serve("rfs:"+c.Tag, c, ai, rfs.RW, trs...)
			if false {
				srv.Debug = Debug
			}

		}(*c)
	}
	if err := cerror(cc); err != nil {
		dbg.Fatal("%s: serve: %s", os.Args[0], err)
	}
}
Пример #19
0
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")
	}
}
Пример #20
0
func mkrns(t *testing.T, d bool) *Tree {
	fstest.MkTree(t, tdir)
	lfs1, err := lfs.New(tdir, tdir, lfs.RW)
	if err != nil {
		t.Fatalf("lfs: %s", err)
	}
	hs, hc := fifo.NewChanHandler()
	s := fifo.New("rfs", "rfs", hs)
	if err = s.Serve(); err != nil {
		t.Fatalf("%s", err)
	}
	go func() {
		for c := range hc {
			ai, err := auth.AtServer(*c, "", "zx", "finder")
			if err!=nil && err!=auth.ErrDisabled {
				dbg.Warn("auth %s: %s\n", c.Tag, err)
				close(c.In, err)
				close(c.Out, err)
				return
			}
			rfs.Serve("srv", *c, ai, rfs.RW, lfs1)
		}
	}()
	rfs1, err := rfs.Import("fifo!*!rfs")
	if err != nil {
		t.Fatalf("lfs: %s", err)
	}
	ns := New()

	ns.Debug = d
	ns.DebugFind = d

	root1, err := zx.Stat(lfs1, "/")
	if err != nil {
		t.Fatalf("stat: %s", err)
	}
	err = <-ns.Mount("/", root1, Repl)
	if err != nil {
		t.Fatalf("mount: %s", err)
	}

	root2, err := zx.Stat(rfs1, "/")
	if err != nil {
		t.Fatalf("stat: %s", err)
	}
	err = <-ns.Mount("/a/b", root2, Repl)
	if err != nil {
		t.Fatalf("mount: %s", err)
	}
	d1 := zx.Dir{"path": "x", "name": "x", "proto": "p1"}
	err = <-ns.Mount("/d", d1, Before)
	if err != nil {
		t.Fatalf("mount: %s", err)
	}
	d2 := zx.Dir{"path": "x", "name": "x", "proto": "p2"}
	err = <-ns.Mount("/d", d2, After)
	if err != nil {
		t.Fatalf("mount: %s", err)
	}
	err = <-ns.Mount("/d", d2, After)
	if err != nil {
		t.Fatalf("mount: %s", err)
	}
	printf("ns is `%s`\n", ns)
	return ns
}
Пример #21
0
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)
	}

}
Пример #22
0
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")
	}
}