Пример #1
0
func Gets(t Fataler, fss ...zx.Tree) {
	for i := 0; i < Repeats; i++ {
		for _, fs := range fss {
			for _, p := range GetFPaths {
				printf("getall %s\n", p)
				dat, err := zx.GetAll(fs, p)
				if err != nil {
					t.Fatalf("get %s: %s", p, err)
				}
				printf("got %d bytes \n\n", len(dat))
				if string(dat) != string(FileData[p]) {
					printf("got <%s>\nexpected<%s>\n",
						string(dat), string(FileData[p]))
					t.Fatalf("%s: bad data", p)
				}
			}

			for _, p := range GetDPaths {
				printf("getall %s\n", p)
				dat, err := zx.GetAll(fs, p)
				if err != nil {
					t.Fatalf("get %s: %s", p, err)
				}
				var d zx.Dir
				ents := []string{}
				for len(dat) > 0 {
					d, dat, err = zx.UnpackDir(dat)
					if err != nil {
						t.Fatalf("dir: %s", err)
					}
					if d["path"] == "/Ctl" || d["path"] == "/Chg" {
						continue
					}
					ents = append(ents, d.TestFmt())
				}
				if strings.Join(GetDOuts[p], "\n") != strings.Join(ents, "\n") {
					t.Fatalf("bad dir data for %s", p)
				}
				printf("got %d ents (ctl, chg excluded)\n", len(ents))
			}
			for _, p := range BadPaths {
				dat, err := zx.GetAll(fs, p)
				if err==nil || len(dat)>0 {
					t.Fatalf("get %s didn't fail", p)
				}
			}
			printf("\n")
		}
	}
}
Пример #2
0
func main() {
	opts := opt.New("[file]")
	c := cmd.AppCtx()
	opts.NewFlag("D", "debug", &c.Debug)
	rdonly := false
	opts.NewFlag("r", "read only", &rdonly)
	opts.NewFlag("e", "do edits for testing", &doedits)
	cmd.UnixIO("err")
	args := opts.Parse()
	var t *ink.Txt
	inkout := cmd.Out("ink")
	if inkout == nil {
		cmd.UnixIO()
	}
	if len(args) == 0 {
		t = ink.NewTxt("1234", "abc")
	} else {
		dat, err := zx.GetAll(cmd.NS(), cmd.AbsPath(args[0]))
		if err != nil {
			cmd.Fatal(err)
		}
		t = ink.NewTxt(args[0]+" Del", string(dat))
	}
	go edit(t)
	if rdonly {
		t.NoEdits()
	}
	ink.UsePort("8182")
	bs := ink.NewButtonSet(&ink.Button{Tag: "One", Name: "one"},
		&ink.Button{Tag: "Two", Name: "two"},
		&ink.Button{Tag: "B", Name: "b", Value: &bold},
		&ink.Button{Tag: "I", Name: "i", Value: &italic})
	rs := ink.NewRadioSet(&style, &ink.Button{Tag: "R", Name: "r"},
		&ink.Button{Tag: "T", Name: "t"})
	go buttons(bs, rs, t)

	pg := ink.NewPg("/", "Example text editing:", bs, rs, t)
	pg.Tag = "Clive's iedit"
	if doedits {
		go edits(t)
	}
	go ink.Serve()
	if inkout != nil {
		// TODO: ctlrs must use unique ids sytem-wide, or
		// controls written won't work because of their ids.
		inkout <- []byte(`<tt>Hi there, this is HTML</tt>`)
		var buf bytes.Buffer
		bs.WriteTo(&buf)
		inkout <- buf.Bytes()
		inkout <- []byte("https://localhost:8182")
	}
	t.Wait()
	for rs := range t.Get(0, -1) {
		cmd.Printf("%s", string(rs))
	}
}
Пример #3
0
// zx.GetAll using the app ns and dot.
func GetAll(path string) ([]byte, error) {
	if len(path) > 0 && path[0] == '#' {
		return nchan.Bytes(Get(path, 0, -1, ""))
	}
	path = app.AbsPath(path)
	_, trs, spaths, err := app.ResolveTree(path)
	if err != nil {
		return nil, err
	}
	return zx.GetAll(trs[0], spaths[0])
}
Пример #4
0
func GetCtl(t Fataler, xfs zx.Fs) {
	fs, ok := xfs.(zx.Getter)
	if !ok {
		t.Fatalf("not a getter")
	}
	dat, err := zx.GetAll(fs, "/Ctl")
	if err != nil {
		t.Fatalf("get /Ctl: %s", err)
	}
	Printf("ctl is:\n%s\n", string(dat))
}
Пример #5
0
func (fs *Cfs) getCtl(off, count int64, pred string, c chan<- []byte, cs *zx.CallStat) (int, error) {
	var buf bytes.Buffer
	fmt.Fprintf(&buf, "%s:\n", fs.Name())

	users := fs.Users()
	for _, k := range users {
		fmt.Fprintf(&buf, "user\t%s\n", k)
	}

	fmt.Fprintf(&buf, "%s", fs.Flags)

	fs.IOstats.Averages()
	fmt.Fprintf(&buf, "%s\n", fs.IOstats.String())

	lctl, _ := zx.GetAll(fs.lfs, "/Ctl")
	if len(lctl) > 0 {
		buf.Write(lctl)
	}

	rctl, _ := zx.GetAll(fs.rfs, "/Ctl")
	if len(rctl) > 0 {
		buf.Write(rctl)
	}
	resp := buf.Bytes()
	o := int(off)
	if o >= len(resp) {
		o = len(resp)
	}
	resp = resp[o:]
	n := int(count)
	if n > len(resp) || n < 0 {
		n = len(resp)
	}
	resp = resp[:n]
	cs.Send(int64(len(resp)))
	c <- resp
	return n, nil
}
Пример #6
0
func EqFiles(t Fataler, path string, fss ...zx.Tree) {
	dirs := []zx.Dir{}
	nerrs := 0
	for _, fs := range fss {
		d, err := zx.Stat(fs, path)
		if err != nil {
			printf("%s: not there: %s\n", fs.Name(), err)
			nerrs++
			continue
		}
		printf("%s: %s\n", fs.Name(), d.LongTestFmt())
		dirs = append(dirs, d)
	}
	if nerrs > 0 {
		if nerrs != len(fss) {
			t.Fatalf("exists only in some")
		}
		return
	}
	for i := 1; i < len(dirs); i++ {
		if dirs[i].TestFmt() != dirs[0].TestFmt() {
			t.Logf("dir%d %s\n", i, dirs[i].TestFmt())
			t.Logf("dir0 %s\n", dirs[0].TestFmt())
			t.Fatalf("dirs do not match")
		}
	}
	if dirs[0]["type"] == "d" {
		return
	}
	datas := [][]byte{}
	for _, fs := range fss {
		dat, err := zx.GetAll(fs, path)
		if err != nil {
			t.Fatalf("%s: %s: %s", fs, path, err)
		}
		datas = append(datas, dat)
	}
	for i := 1; i < len(datas); i++ {
		if bytes.Compare(datas[i], datas[0]) != 0 {
			t.Fatalf("data differs")
		}
	}

}
Пример #7
0
func Puts(t Fataler, fss ...zx.Tree) {
	if len(fss) == 0 {
		t.Fatalf("no fs given")
	}
	fs := fss[0].(zx.RWTree)
	rd, err := zx.Stat(fs, "/")
	if err != nil {
		t.Fatalf("root stat %s", err)
	}
	printf("root %s\n", rd.TestFmt())
	for z := 0; z < Repeats; z++ {
	Loop:
		for nfi, nf := range PutTests {
			dc := make(chan []byte, 1)
			nf.data = make([]byte, 0, 32*1024)
			xd := nf.Dir.Dup()
			printf("put %s %v\n", nf.Path, xd)
			nn := nfi + 1
			if nf.N != 0 {
				nn = 2
			}
			xc := fs.Put(nf.Path, xd, 0, dc, "")
			for i := 0; i < 1000*nn; i++ {
				msg := []byte(fmt.Sprintf("hi %s %d\n", nf.Path, i))
				nf.data = append(nf.data, msg...)
				if ok := dc <- msg; !ok {
					err := cerror(dc)
					if !nf.Fails {
						t.Fatalf("%s: %s\n", nf.Path, err)
					}
					continue Loop
				}
			}
			printf("put %s: sent %d bytes\n", nf.Path, len(nf.data))
			close(dc)
			xd = <-xc
			if nf.Fails {
				if xd!=nil || cerror(xc)==nil {
					t.Fatalf("%s: didn't fail", nf.Path)
				}
				continue
			}
			if xd==nil || cerror(xc)!=nil {
				t.Fatalf("%s: %s\n", nf.Path, cerror(xc))
			}
			got := xd.TestFmt()
			printf("got %s\n", got)
			if nf.Dir["mtime"] != "" {
				got += " mtime " + xd["mtime"]
			}
			if got != nf.Res {
				t.Logf("expected %s\n", nf.Res)
				t.Logf("got %s\n", got)
				t.Fatalf("%s: bad dir output", nf.Path)
			}
			fd, err := zx.Stat(fs, nf.Path)
			if err != nil {
				t.Fatalf("stat: %s", err)
			}
			got = fd.TestFmt()
			if nf.Dir["mtime"] != "" {
				got += " mtime " + fd["mtime"]
			}
			if nf.Dir["X"] != "" {
				got += " X " + fd["X"]
			}
			printf("after put: %s\n", got)
			if nf.Rdir != "" && nf.Rdir != got {
				t.Logf("expected <%s>", nf.Rdir)
				t.Fatalf("got <%s>", got)
			}
			for _, fs := range fss {
				dat, err := zx.GetAll(fs, nf.Path)
				if err != nil {
					t.Fatalf("couldn't get: %s", err)
				}
				if nf.N != 0 && len(dat) != nf.N {
					t.Fatalf("bad output size: %d", len(dat))
				}
				if nf.N != 0 && len(dat) > len(nf.data) {
					dat = dat[:len(nf.data)]
				}
				if nf.N != 0 && len(dat) < len(nf.data) {
					nf.data = nf.data[:len(dat)]
				}
				if string(dat) != string(nf.data) {
					t.Fatalf("bad data %d vs %d bytes", len(dat), len(nf.data))
				}
			}
		}
	}
}


func GetCtl(t Fataler, fss ...zx.Tree) {
	if len(fss) == 0 {
		t.Fatalf("no fs given")
	}
	fs := fss[0].(zx.RWTree)
	vals := []bool{false, true}
	outs := []string{"debug off", "debug on"}
	for i, v := range vals {
		d := fs.(zx.Debugger).Debug()
		*d = v
		printf("get ctl: (debug %v)\n", v)
		dat, err := zx.GetAll(fs, "/Ctl")
		if err != nil {
			t.Fatalf("get /ctl: %s", err)
		}
		ctls := string(dat)
		printf("<%s>\n\n", ctls)
		if !strings.Contains(ctls, outs[i]) {
			t.Fatalf("wrong ctl output")
		}
	}
}

func PutCtl(t Fataler, fss ...zx.Tree) {
	if len(fss) == 0 {
		t.Fatalf("no fs given")
	}
	fs := fss[0].(zx.RWTree)
	vals := []bool{false, true, false, true}
	ins := []string{"nodebug", "debug", "debug off", "debug on"}
	outs := []string{"debug off", "debug on", "debug off", "debug on"}
	for i, v := range vals {
		printf("put ctl: (debug %v)\n", v)
		err := zx.PutAll(fs, "/Ctl", nil, []byte(ins[i]))
		if err != nil {
			t.Fatalf("put /ctl: %s", err)
		}
		printf("get ctl: (debug %v)\n", v)
		dat, err := zx.GetAll(fs, "/Ctl")
		if err != nil {
			t.Fatalf("get /ctl: %s", err)
		}
		ctls := string(dat)
		printf("<%s>\n\n", ctls)
		if !strings.Contains(ctls, outs[i]) {
			t.Fatalf("wrong ctl output")
		}
	}
	err := zx.PutAll(fs, "/Ctl", nil, []byte("bad ctl request"))
	if err == nil {
		t.Fatalf("bad put did not fail")
	}
	printf("put sts %s\n", err)
}


func PutsBench(b *testing.B, xfs zx.Tree) {
	fs := xfs.(zx.RWTree)
	b.StopTimer()
	var buf [1024]byte
	copy(buf[0:], "hola")
	<-fs.Remove("/nfb")
	b.StartTimer()
	for bi := 0; bi < b.N; bi++ {
		dc := make(chan []byte)
		xc := fs.Put("/nfb", zx.Dir{"mode": "0644"}, 0, dc, "")
		for i := 0; i < 128; i++ {
			if ok := dc <- buf[:]; !ok {
				b.Fatalf("put failed")
			}
		}
		close(dc)
		if len(<-xc) == 0 {
			b.Fatalf("put failed")
		}
	}
}

var (
	MkdirPaths    = []string{"/nd", "/nd/nd2", "/nd/nd22", "/nd/nd23", "/nd3"}
	BadMkdirPaths = []string{"/", "/nd", "/a"}
)

func Mkdirs(t Fataler, fss ...zx.Tree) {
	if len(fss) == 0 {
		t.Fatalf("no fs given")
	}
	fs := fss[0].(zx.RWTree)
	for i := 0; i < Repeats; i++ {
		for _, p := range MkdirPaths {
			printf("mkdir %s\n", p)
			ec := fs.Mkdir(p, zx.Dir{"mode": "0750"})
			err := <-ec
			if i>0 && err==nil {
				t.Fatalf("could re-mkdir %s", p)
			}
			if i==0 && err!=nil {
				t.Fatalf("%s: %s", p, err)
			}
			for _, fs := range fss {
				d, err := zx.Stat(fs, p)
				if err!=nil || d["type"]!="d" || d["mode"]!="0750" {
					t.Fatalf("mkdir not there %v %v", err, d)
				}
			}
		}
		for _, p := range BadMkdirPaths {
			printf("mkdir %s\n", p)
			ec := fs.Mkdir(p, zx.Dir{"mode": "0750"})
			err := <-ec
			if err == nil {
				t.Fatalf("mkdir %s worked", p)
			}
		}
	}
}

var (
	RemovePaths    = []string{"/d", "/e/f", "/e", "/a/a2"}
	BadRemovePaths = []string{"/", "/xxx", "/a"}
)

func Removes(t Fataler, fss ...zx.Tree) {
	if len(fss) == 0 {
		t.Fatalf("no fs given")
	}
	fs := fss[0].(zx.RWTree)
	for i := 0; i < Repeats; i++ {
		for _, p := range RemovePaths {
			printf("remove %s\n", p)
			ec := fs.Remove(p)
			err := <-ec
			if i>0 && err==nil {
				t.Fatalf("could re-remove %s", p)
			}
			if i==0 && err!=nil {
				t.Fatalf("%s: %s", p, err)
			}
			for _, fs := range fss {
				d, err := zx.Stat(fs, p)
				if err==nil || d!=nil {
					t.Fatalf("%s still there", p)
				}
			}
		}
		for _, p := range BadRemovePaths {
			ec := fs.Remove(p)
			err := <-ec
			if err == nil {
				t.Fatalf("remove %s worked", p)
			}
		}
	}
}

func MkdirRemoveBench(b *testing.B, xfs zx.Tree) {
	fs := xfs.(zx.RWTree)
	b.StopTimer()
	<-fs.Remove("/mrb")
	b.StartTimer()
	for bi := 0; bi < b.N; bi++ {
		xc := fs.Mkdir("/mrb", zx.Dir{"mode": "0755"})
		if <-xc != nil {
			b.Fatalf("mkdir failed")
		}
		xc = fs.Remove("/mrb")
		if <-xc != nil {
			b.Fatalf("remove failed")
		}
	}
}

type WstatTest  {
	Path  string
	Dir   zx.Dir
	AppDir bool
	Res   string
	Fails bool
}

var WstatTests = []WstatTest{
	{
		Path: "/d",
		Dir:  zx.Dir{"mode": "0704", "foo": "bar"},
		Res:  `path /d name d type d mode 0704 size 0`,
	},
	{
		Path: "/e/f",
		Dir:  zx.Dir{"mode": "0704", "foo": "bar"},
		Res:  `path /e/f name f type d mode 0704 size 0`,
	},
	{
		Path: "/e",
		Dir:  zx.Dir{"mode": "0704", "foo": "bar"},
		Res:  `path /e name e type d mode 0704 size 1`,
	},
	{
		Path: "/a/a2",
		Dir:  zx.Dir{"mode": "0704", "foo": "bar"},
		Res:  `path /a/a2 name a2 type - mode 0704 size 21418`,
	},
	{
		Path: "/",
		Dir:  zx.Dir{"mode": "0704", "foo": "bar"},
		Res:  `path / name / type d mode 0704 size 0`,
	},
	{
		Path:  "/xxx",
		Dir:   zx.Dir{"mode": "0704", "foo": "bar"},
		Fails: true,
	},
	{
		Path:  "/a/xxx",
		Dir:   zx.Dir{"mode": "0704", "foo": "bar"},
		Fails: true,
	},
	{
		Path:  "/dx",
		Dir:   zx.Dir{"mode": "0704", "foo": "bar"},
		Fails: true,
	},
}

func Wstats(t Fataler, fss ...zx.Tree) {
	if len(fss) == 0 {
		t.Fatalf("no fs given")
	}
	fs := fss[0].(zx.RWTree)
	for i := 0; i < Repeats; i++ {
		for _, f := range WstatTests {
			printf("wstat %s %v\n", f.Path, f.Dir)
			ec := fs.Wstat(f.Path, f.Dir)
			err := <-ec
			if f.Fails {
				if err == nil {
					t.Fatalf("%s didn't fail", f.Path)
				}
				continue
			}
			if !f.Fails && err!=nil {
				t.Fatalf("%s: %s", f.Path, err)
			}
			for _, fs := range fss {
				d, err := zx.Stat(fs, f.Path)
				if err != nil {
					t.Fatalf("stat %s: %s", f.Path, err)
				}
				if d["path"] == "/" {
					d["size"] = "0" // ctl, chg
				}
				if d.TestFmt() != f.Res {
					t.Logf("for %s\n", fs.Name())
					t.Logf("expected %s\n", f.Res)
					t.Logf("got %s\n", d.TestFmt())
					t.Fatalf("stat %s: didn't wstat it", f.Path)
				}
			}
		}
	}
}

var UsrWstatTests = []WstatTest{
	// extra bits in mode
	{
		Path: "/a",
		Dir:  zx.Dir{"mode": "07755"},
		Res: `path /a name a type d mode 0755 size 3 Gid nemo Uid nemo Wuid nemo`,
	},
	// changing size in a dir is ignored if writing existing attributes.
	{
		Path: "/a",
		Dir:  zx.Dir{"size": "5"},
		AppDir: true,
		Res: `path /a name a type d mode 0755 size 3 Gid nemo Uid nemo Wuid nemo`,
	},
	// writing a non  user attribute
	{
		Path: "/a",
		Dir:  zx.Dir{"foo": "bar"},
		Fails: true,
	},
	// writing a ignored non  user attribute
	{
		Path: "/a",
		Dir:  zx.Dir{"mtime": "0", "foo": "bar"},
		Res: `path /a name a type d mode 0755 size 3 Gid nemo Uid nemo Wuid nemo`,
	},
	// Adding a user attribute
	{
		Path: "/a",
		Dir:  zx.Dir{"Dir": "X"},
		Res: `path /a name a type d mode 0755 size 3 Dir X Gid nemo Uid nemo Wuid nemo`,
	},
	// Same, using the previous dir
	{
		Path: "/a",
		Dir:  zx.Dir{"Dir": "X"},
		AppDir: true,
		Res: `path /a name a type d mode 0755 size 3 Dir X Gid nemo Uid nemo Wuid nemo`,
	},
	// Adding a two user attributes
	{
		Path: "/a",
		Dir:  zx.Dir{"Dir": "X", "Abc": "A"},
		Res: `path /a name a type d mode 0755 size 3 Abc A Dir X Gid nemo Uid nemo Wuid nemo`,
	},
	// Removing a non existing user attribute
	{
		Path: "/a",
		Dir:  zx.Dir{"Non": ""},
		Res: `path /a name a type d mode 0755 size 3 Abc A Dir X Gid nemo Uid nemo Wuid nemo`,
	},
	// Rewriting a user attribute
	{
		Path: "/a",
		Dir:  zx.Dir{"Abc": "B"},
		Res: `path /a name a type d mode 0755 size 3 Abc B Dir X Gid nemo Uid nemo Wuid nemo`,
	},
	// Removing a user attribute
	{
		Path: "/a",
		Dir:  zx.Dir{"Abc": ""},
		Res: `path /a name a type d mode 0755 size 3 Dir X Gid nemo Uid nemo Wuid nemo`,
	},
	// Type change
	{
		Path: "/a",
		Dir:  zx.Dir{"type": "x"},
		Fails: true,
	},
	// Removing a sys attribute
	{
		Path: "/a",
		Dir:  zx.Dir{"type": "", "Dir": "X"},
		Fails: true,
	},
	// Trying to change size
	{
		Path: "/a",
		Dir:  zx.Dir{"size": "55"},
		Fails: true,
	},
	// Bad path
	{
		Path: "2",
		Dir:  zx.Dir{"size": "55"},
		Fails: true,
	},
	// Truncating a file
	{
		Path: "/2",
		Dir:  zx.Dir{"size": "55"},
		Res: `path /2 name 2 type - mode 0644 size 55 Gid nemo Uid nemo Wuid nemo`,
	},
}

func UsrWstats(t Fataler, fss ...zx.Tree) {
	if len(fss) == 0 {
		t.Fatalf("no fs given")
	}
	fs := fss[0].(zx.RWTree)
	for i := 0; i < 1; i++ {
		for _, f := range UsrWstatTests {
			d := f.Dir.Dup()
			if f.AppDir {
				od, err := zx.Stat(fs, f.Path)
				if err != nil {
					t.Fatalf("stat %s: %s", f.Path, err)
				}
				for k, v := range d {
					od[k] = v
				}
				d = od
			}
			printf("wstat %s %s\n", f.Path, d.LongTestFmt())
			ec := fs.Wstat(f.Path, d)
			err := <-ec
			if f.Fails {
				if err == nil {
					t.Fatalf("%s didn't fail", f.Path)
				}
				continue
			}
			if !f.Fails && err!=nil {
				t.Fatalf("%s: %s", f.Path, err)
			}
			for _, fs := range fss {
				d, err := zx.Stat(fs, f.Path)
				if err != nil {
					t.Fatalf("stat %s: %s", f.Path, err)
				}
				printf("result %s %s\n", f.Path, d.LongTestFmt())
				if d["foo"] != "" {
					t.Fatalf("could write foo")
				}
				if f.Res == "" {
					continue
				}
				if d["path"] == "/" {
					d["size"] = "0" // ctl, chg
				}
				delete(d, "Sum")
				ds := strings.Replace(d.LongTestFmt(), "nemo", "none", -1)
				ds2 := strings.Replace(f.Res, "nemo", "none", -1)
				if ds != ds2 {
					t.Logf("for fs %s\n", fs.Name())
					t.Logf("expected %s\n", f.Res)
					t.Logf("got %s\n", d.LongTestFmt())
					t.Fatalf("stat %s: didn't wstat it", f.Path)
				}
			}
		}
	}
}

func WstatBench(b *testing.B, xfs zx.Tree) {
	fs := xfs.(zx.RWTree)
	for bi := 0; bi < b.N; bi++ {
		xc := <-fs.Wstat("/e", zx.Dir{"mode": "0755"})
		if xc != nil {
			b.Fatalf("wstat failed")
		}
	}
}

var SendOuts = []string{
	`/`,
	`path /1 name 1 type - mode 0644 size 0`,
	`path /2 name 2 type - mode 0644 size 31658`,
	`path /a name a type d mode 0755 size 3`,
	`path /a/a1 name a1 type - mode 0644 size 10154`,
	`path /a/a2 name a2 type - mode 0644 size 21418`,
	`path /a/b name b type d mode 0755 size 1`,
	`path /a/b/c name c type d mode 0755 size 1`,
	`path /a/b/c/c3 name c3 type - mode 0644 size 44970`,
	`path /d name d type d mode 0755 size 0`,
	`path /e name e type d mode 0755 size 1`,
	`path /e/f name f type d mode 0755 size 0`,
}

func SendRecv(t Fataler, sfs, rfs zx.RWTree) {
	dc := make(chan []byte)
	rf, err := zx.Stat(sfs, "/")
	if err!=nil || rf==nil {
		t.Fatalf("stat: %s", err)
	}
	zx.DebugSend = testing.Verbose()
	go func() {
		err := zx.Send(sfs, rf, dc)
		close(dc, err)
	}()
	err = zx.Recv(rfs, dc)
	if cerror(dc) != nil {
		t.Logf("send err %s", cerror(dc))
	}
	if err != nil {
		t.Fatalf("recv: %s", err)
	}
	err = cerror(dc)
	if err != nil {
		t.Fatalf("send: %s", err)
	}
	fc := rfs.Find("/", "", "/", "/", 0)
	tot := 0
	outs := []string{}
	for d := range fc {
		printf("\t`%s`,\n", d.LongTestFmt())
		if d["path"] == "/" {
			outs = append(outs, "/")
			tot++
			continue
		}
		if d["path"] == "/" {
			d["size"] = "0" // get rid of ctl, chg
		}
		if d["path"]=="/Ctl" || d["path"]=="/Chg" {
			continue
		}
		tot++
		outs = append(outs, d.TestFmt())
	}
	if tot != 12 {
		t.Fatalf("bad find tot: got %d", tot)
	}
	if strings.Join(outs, "\n") != strings.Join(SendOuts, "\n") {
		t.Fatalf("bad received tree")
	}
}

// Check out if fs.Dump() is the same for all trees
func SameDump(t Fataler, fss ...zx.Tree) {
	old := ""
	oname := ""
	nname := ""
	for _, tfs := range fss {
		var buf bytes.Buffer
		fs, ok := tfs.(zx.Dumper)
		if !ok {
			continue
		}
		fs.Dump(&buf)
		ns := buf.String()
		toks := strings.SplitN(ns, "\n", 2)
		if len(toks) > 1 {
			ns = toks[1]
			nname = toks[0]
		}
		if old == "" {
			old = ns
			oname = nname
		} else if old != ns {
			t.Logf("%s\n<%s>\n", oname, old)
			t.Logf("%s\n<%s>\n", nname, ns)
			i := 0
			for i < len(old) && i < len(ns) {
				if old[i] != ns[i] {
					break
				}
				i++
			}
			t.Logf("suffix1 <%s>\n", old[i:])
			t.Logf("suffix2 <%s>\n", ns[i:])
			t.Fatalf("trees do not match")
		}
	}
}
Пример #8
0
func Gets(t Fataler, xfs zx.Fs) {
	fs, ok := xfs.(zx.Getter)
	if !ok {
		t.Fatalf("not a getter")
	}
	for _, p := range Files {
		data, err := zx.GetAll(fs, p)
		Printf("get all %s: %d bytes sts %v\n", p, len(data), err)
		if err != nil {
			t.Fatalf("get %s: %s", p, err)
		}
		if bytes.Compare(FileData[p], data) != 0 {
			t.Logf("%d get %d data", len(data), len(FileData[p]))
			t.Fatalf("get %s: bad data", p)
		}
	}

	for _, p := range Files {
		data, err := get(fs, p, 1024, 10*1024)
		Printf("get %s 1k 2k: %d bytes sts %v\n", p, len(data), err)
		if err != nil {
			t.Fatalf("get %s: %s", p, err)
		}
		if bytes.Compare(slice(FileData[p], 1024, 10*1024), data) != 0 {
			t.Fatalf("get %s: bad data", p)
		}
	}

	for i, p := range Dirs {
		Printf("get %s\n", p)
		out := ""
		gc := fs.Get(p, 0, -1)
		for b := range gc {
			_, dir, err := zx.UnpackDir(b)
			Printf("%s\n", dir.Fmt())
			if err != nil {
				t.Fatalf("get sts %v", err)
			}
			out += dir.Fmt() + "\n"
		}
		Printf("\n")
		if i > len(dirs) || dirs[i] != out {
			t.Logf("dirs: <%s>\n out <%s>\n", dirs, out)
			t.Fatalf("bad output")
		}
	}

	for i, p := range Dirs {
		Printf("get %s 2 3\n", p)
		out := ""
		gc := fs.Get(p, 2, 3)
		for b := range gc {
			_, dir, err := zx.UnpackDir(b)
			Printf("%s\n", dir.Fmt())
			if err != nil {
				t.Fatalf("get sts %v", err)
			}
			out += dir.Fmt() + "\n"
		}
		Printf("\n")
		if i > len(dirs23) || dirs23[i] != out {
			t.Fatalf("bad dir contents")
		}
		if err := cerror(gc); err != nil {
			t.Fatalf("err %v", err)
		}
	}

	for _, p := range BadPaths[1:] {
		data, err := zx.GetAll(fs, p)
		Printf("get %s: %s\n", p, err)
		if err == nil || len(data) > 0 {
			t.Fatalf("could get")
		}
	}
}
Пример #9
0
func dumpDir(dir, name string, rf zx.File) (string, error) {
	dprintf("dump dir %s %s %s\n", dir, name, rf.D["path"])
	ds := []zx.Dir{}
	istmp := rf.D["name"] == "tmp"
	if !istmp {
		var err error
		ds, err = zx.GetDir(rf.T, rf.D["path"])
		if err != nil {
			dbg.Warn("dumpdir: %s: %s", rf.D["path"], err)
			return "", err
		}
	} else {
		vprintf("%s: temp %s\n", os.Args[0], name)
	}
	dhash := []string{}
	nds := []zx.Dir{}
	for _, d := range ds {
		if d["name"] == "" {
			dbg.Warn("dumpdir: %s: no name", rf.D["path"])
		}
		if d["name"] == "NODUMP" {
			nds = []zx.Dir{}
			dbg.Warn("dumpdir: %s: no dump", rf.D["path"])
			break
		}
		if d["name"] == "FROZEN" {
			vprintf("%s: XXX frozen %s\n", os.Args[0], name)
			/* dir is frozen and the FROZEN contains
			 * the dump path for dir.
			 */
			data, err := zx.GetAll(rf.T, d["path"])
			if err != nil {
				return "", err
			}
			s := string(data)
			if len(strings.Split(s, "/")) != 3 {
				return "", fmt.Errorf("wrong contents in %s", d["path"])
			}
			vprintf("%s: frozen %s\n", os.Args[0], name)
			return strings.TrimSpace(s), nil
		}
		if excluded(d["name"]) {
			dprintf("dump ignored %s\n", d["path"])
			continue
		}
		if t := d["type"]; t != "d" && t != "-" {
			dbg.Warn("dump ignored %s type '%s'\n", d["path"], t)
			continue
		}
		nds = append(nds, d)
	}
	ds = nds
	for _, d := range ds {
		dspath := zx.Path(name, d["name"])
		df, err := zx.Walk(rf.T, rf.D, d["name"])
		if dspath == name {
			panic("zx dump bug")
		}
		if err != nil {
			dbg.Warn("walk: %s: %s", df["path"], err)
			dhash = append(dhash, "")
			dhash = append(dhash, "")
			continue
		}
		var s string
		var e error
		switch d["type"] {
		case "d":
			s, e = dumpDir(dir, dspath, zx.File{rf.T, df})
		case "-":
			s, e = dumpFile(dir, dspath, zx.File{rf.T, df})
		default:
			panic("dump dir type bug")
		}
		if e == nil {
			dhash = append(dhash, d["name"])
			dhash = append(dhash, s)
		} else {
			dbg.Warn("%s: %s", df["path"], e)
		}
		if err == nil && e != nil {
			err = e
			dhash = append(dhash, "")
			dhash = append(dhash, "")
		}
	}
	dval := strings.Join(dhash, "\n")
	h := sha1.New()
	h.Write([]byte(dval))
	sum := h.Sum(nil)
	s := fmt.Sprintf("%02x/%02x/%036x", sum[0], sum[1], sum[2:])
	dprintf("dump dir %s %s\n", name, s)
	dfpath := zx.Path(dir, s)
	fi, _ := os.Stat(dfpath)
	if fi != nil {
		return s, nil
	}
	vprintf("%s: new %s\n", os.Args[0], name)
	return s, newDumpDir(dir, dfpath, rf, ds, dhash)
}
Пример #10
0
func rget(t Fataler, fs zx.RWTree, fname string) {
	zx.GetAll(fs, fname)
}
Пример #11
0
// Check that perms are actually checked in old files and dirs
func RWXPerms(t Fataler, fss ...zx.Tree) {
	if len(fss) == 0 {
		t.Fatalf("no fs given")
	}
	fs := authfs(t, fss[0].(zx.RWTree))

	if <-fs.Mkdir("/chkd", zx.Dir{"mode": "0777", "Gid": "gid1"}) != nil {
		t.Fatalf("couldn't mkdir /chkd gid")
	}
	if <-fs.Mkdir("/chkd/o", zx.Dir{"mode": "0777", "Gid": "gid1"}) != nil {
		t.Fatalf("couldn't mkdir /chkd gid")
	}

	// Check out dirs

	rfn := func(fs zx.RWTree) error {
		_, err := zx.GetDir(fs, "/chkd")
		return err
	}
	out := ugo(t, fs, "/chkd", 4, rfn)
	printf("dir rd ugo: %s\n", out)
	if out != "yyyyynynnnnn" {
		t.Fatalf("dir read perms are %s", out)
	}
	wfn := func(fs zx.RWTree) error {
		err := <-fs.Mkdir("/chkd/x", zx.Dir{"mode": "0777"})
		if err != nil {
			return err
		}
		return <-fs.Remove("/chkd/x")
	}
	out = ugo(t, fs, "/chkd", 2, wfn)
	printf("dir wr ugo: %s\n", out)
	if out != "yyyyynynnnnn" {
		t.Fatalf("dir write perms are %s", out)
	}

	xfn := func(fs zx.RWTree) error {
		_, err := zx.GetDir(fs, "/chkd/o")
		return err
	}
	out = ugo(t, fs, "/chkd", 1, xfn)
	printf("dir ex ugo: %s\n", out)
	if out != "yyyyynynnnnn" {
		t.Fatalf("dir exec perms are %s", out)
	}

	// Check out files
	if err := zx.PutAll(fs, "/chkf", zx.Dir{"mode": "0777"}, []byte("hi")); err != nil {
		t.Fatalf("put: %s", err)
	}
	if err := <-fs.Wstat("/chkf", zx.Dir{"Gid": "gid1"}); err != nil {
		t.Fatalf("wstat: %s", err)
	}
	rfn = func(fs zx.RWTree) error {
		_, err := zx.GetAll(fs, "/chkf")
		return err
	}
	out = ugo(t, fs, "/chkf", 4, rfn)
	printf("file rd ugo: %s\n", out)
	if out != "yyyyynynnnnn" {
		t.Fatalf("file read perms are %s", out)
	}

	wfn = func(fs zx.RWTree) error {
		return zx.PutAll(fs, "/chkf", nil, []byte("there"))
	}
	out = ugo(t, fs, "/chkf", 2, wfn)
	printf("file wr ugo: %s\n", out)
	if out != "yyyyynynnnnn" {
		t.Fatalf("file write perms are %s", out)
	}
	// We can't check out exec perms, because the underlying OS has
	// its own idea of who can exec the file.

	// see who can change modes.
	m := 0
	wfn = func(fs zx.RWTree) error {
		m++
		return <-fs.Wstat("/chkf", zx.Dir{"mode": fmt.Sprintf("0%o", m)})
	}
	out = ugo(t, fs, "/chkf", 2, wfn)
	printf("file wstat ugo: %s\n", out)
	if out != "ynnynnynnynn" {
		t.Fatalf("file wstat perms are %s", out)
	}

}