Esempio n. 1
0
// Create a tree with Dirs and Files at tdir at the given zx tree.
func MkZXTree(t Fataler, fs zx.RWTree) {
	for _, dn := range Dirs {
		if err := zx.MkdirAll(fs, dn, zx.Dir{"mode":"0755"}); err != nil {
			t.Fatalf("mkdir: %s", err)
		}
	}
	for i, fn := range Files {
		data := []byte{}
		for k := 0; k < i*1024; k++ {
			txt := fmt.Sprintf("%s %d\n", Files[i], k)
			data = append(data, txt...)
		}
		if err := zx.PutAll(fs, fn, zx.Dir{"mode": "0644"}, data); err != nil {
			t.Fatalf("putall: %s", err)
		}
		FileData[Files[i]] = data
	}
	for _, fn := range Files {
		if err := TouchZX(fs, fn); err != nil {
			t.Fatalf("touch: %s: %s", fn, err)
		}
	}
	for _, dn := range Dirs {
		if err := TouchZX(fs, dn); err != nil {
			t.Fatalf("touch: %s: %s", dn, err)
		}
	}
}
Esempio n. 2
0
func AsAFile(t Fataler, fss ...zx.Tree) {
	if len(fss) == 0 {
		t.Fatalf("no fs given")
	}
	fs := fss[0].(zx.RWTree)
	dat := []byte{}
	if err := zx.PutAll(fs, "/testfile", zx.Dir{"mode": "0640"}, dat); err != nil {
		t.Fatalf("put all: %s", err)
	}
	zxf := NewFakeOSFile(fs, "/testfile")
	rwtest.AsAFile(t, zxf, 1000, 128*1024, 3803)
}
Esempio n. 3
0
func (fs *Cfs) putCtl(dc <-chan []byte) error {
	if !fs.NoPermCheck && !ctldir.CanWrite(fs.ai) {
		return fmt.Errorf("/Ctl: %s", dbg.ErrPerm)
	}
	ctl, err := nchan.String(dc)
	if err != nil {
		return fmt.Errorf("/Ctl: %s", err)
	}
	if strings.HasPrefix(ctl, "pass ") {
		nctl := ctl[5:]
		fs.dprintf("pass ctl <%s>\n", nctl)
		return zx.PutAll(fs.rfs, "/Ctl", nil, []byte(nctl))
	}
	fs.dprintf("ctl <%s>\n", ctl)
	if ctl == "sync" {
		fs.cache.Sync(nil)
		return nil
	}
	return fs.Ctl(ctl)
}
Esempio n. 4
0
// Make some changes in the test zx tree.
//	- Touch /a/a1
//	- Chmod /a/a2
//	- Remove /a/b/c /a/b/c/c3
//	- Create /a/n /a/n/m /a/n/m/m1
func MkZXChgs(t Fataler, fs zx.RWTree) {
	TouchZX(fs, "/a/a1")
	if err := <- fs.Wstat("/a/a2", zx.Dir{"mode": "0750"}); err != nil {
		t.Fatalf("chmod: %s", err)
	}
	if err := <-fs.RemoveAll("/a/b/c"); err != nil {
		t.Fatalf("rm: %s", err)
	}
	<-fs.Mkdir("/a", zx.Dir{"mode": "0750"})
	<-fs.Mkdir("/a/n", zx.Dir{"mode": "0750"})
	if err := <-fs.Mkdir("/a/n/m", zx.Dir{"mode": "0750"}); err != nil {
		t.Fatalf("mkdir: %s", err)
	}
	err := zx.PutAll(fs, "/a/n/m/m1", zx.Dir{"mode": "0640"}, []byte("a new file\n"))
	if err != nil {
		t.Fatalf("new file: %s", err)
	}
	TouchZX(fs, "/a/n/m/m1")
	TouchZX(fs, "/a/n/m")
	TouchZX(fs, "/a/n")
	TouchZX(fs, "/a")
}
Esempio n. 5
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")
		}
	}
}
Esempio n. 6
0
func rcreate(t Fataler, fs zx.RWTree, fname string) {
	zx.PutAll(fs, fname, zx.Dir{"mode": "0644"}, []byte("hi there"))
}
Esempio n. 7
0
// Check perms, uids, and gids for new files and dirs
// including inheriting bits and uids and that we can't change uids that we can't change.
func NewPerms(t Fataler, fss ...zx.Tree) {
	if len(fss) == 0 {
		t.Fatalf("no fs given")
	}
	fs := authfs(t, fss[0].(zx.RWTree))

	// This is a contorted dance to check that we can/can't change uids/gids/wuids
	// depending on the original uids and permissions for non-existing files,
	// existing files, and dirs.
	// It checks also that gids and perms are inherited from the containing dir
	// as they should

	if err := <-fs.Wstat("/d", zx.Dir{"Gid": "katsumoto"}); err == nil {
		t.Fatalf("could wstat gid")
	}
	if err := <-fs.Wstat("/d", zx.Dir{"Gid": "gid1"}); err != nil {
		t.Fatalf("wstat: %s", err)
	}
	if err := <-fs.Wstat("/d", zx.Dir{"Uid": "katsumoto"}); err == nil {
		t.Fatalf("could wstat uid")
	}
	if err := <-fs.Wstat("/d", zx.Dir{"Wuid": "katsumoto"}); err == nil {
		t.Fatalf("could wstat wuid")
	}
	if !stat(t, fs, "/d", "0755 nemo gid1 nemo") {
		t.Fatalf("stat")
	}

	if err := <-fs.Wstat("/d", zx.Dir{"Uid": "gid2"}); err != nil {
		t.Fatalf("wstat: %s", err)
	}
	if !stat(t, fs, "/d", "0755 gid2 gid1 nemo") {
		t.Fatalf("stat")
	}
	if err := <-fs.Wstat("/d", zx.Dir{"Uid": dbg.Usr}); err != nil {
		t.Fatalf("couldn't wstat uid")
	}
	if err := <-fs.Wstat("/d", zx.Dir{"mode": "0750"}); err != nil {
		t.Fatalf("couldn't wstat mode")
	}
	if !stat(t, fs, "/d", "0750 nemo gid1 nemo") {
		t.Fatalf("stat")
	}

	dat := []byte("hi")
	if zx.PutAll(fs, "/d/newauth", zx.Dir{"mode": "0604", "Uid": "katsumoto"}, dat) == nil {
		t.Fatalf("could put uid on create")
	}
	if !nostat(t, fs, "/d/newauth") {
		t.Fatalf("stat")
	}

	if zx.PutAll(fs, "/d/newauth2", zx.Dir{"mode": "0604", "Gid": "katsumoto"}, dat) == nil {
		t.Fatalf("could put gid on create")
	}
	if !nostat(t, fs, "/d/newauth2") {
		t.Fatalf("stat")
	}

	if zx.PutAll(fs, "/d/newauth3", zx.Dir{"mode": "0604", "Wuid": "katsumoto"}, dat) != nil {
		t.Fatalf("put wuid not ignored on create")
	}
	if !stat(t, fs, "/d/newauth3", "0640 nemo gid1 nemo") {
		t.Fatalf("stat")
	}

	if zx.PutAll(fs, "/d/newauth3", zx.Dir{"mode": "0604", "Uid": "katsumoto"}, dat) == nil {
		t.Fatalf("could put uid on existing")
	}
	if !stat(t, fs, "/d/newauth3", "0640 nemo gid1 nemo") {
		t.Fatalf("stat")
	}

	if zx.PutAll(fs, "/d/newauth3", zx.Dir{"mode": "0604", "Gid": "katsumoto"}, dat) == nil {
		t.Fatalf("could put gid on existing")
	}
	if !stat(t, fs, "/d/newauth3", "0640 nemo gid1 nemo") {
		t.Fatalf("stat")
	}

	if zx.PutAll(fs, "/d/newauth3", zx.Dir{"mode": "0604", "Wuid": "katsumoto"}, dat) != nil {
		t.Fatalf("put wuid not ignored on existing")
	}
	if !stat(t, fs, "/d/newauth3", "0640 nemo gid1 nemo") {
		t.Fatalf("stat")
	}

	if zx.PutAll(fs, "/d/newauth4", zx.Dir{"mode": "0604", "Uid": "gid1"}, dat) != nil {
		t.Fatalf("couldn't put uid for gid on create")
	}
	if !stat(t, fs, "/d/newauth4", "0640 gid1 gid1 nemo") {
		t.Fatalf("stat")
	}

	if zx.PutAll(fs, "/d/newauth3", zx.Dir{"mode": "0604", "Uid": "gid1", "Gid": "gid2"}, dat) != nil {
		t.Fatalf("couldn't put uid/gid on existing")
	}
	if !stat(t, fs, "/d/newauth3", "0640 gid1 gid2 nemo") {
		t.Fatalf("stat")
	}

	if <-fs.Mkdir("/d/newd", zx.Dir{"mode": "0755", "Uid": "katsumoto"}) == nil {
		t.Fatalf("could mkdir uid")
	}
	if !nostat(t, fs, "/d/newd") {
		t.Fatalf("stat")
	}

	if <-fs.Mkdir("/d/newd", zx.Dir{"mode": "0705", "Uid": "gid2"}) != nil {
		t.Fatalf("couldn't mkdir uid")
	}
	if !stat(t, fs, "/d/newd", "0750 gid2 gid1 nemo") {
		t.Fatalf("stat")
	}

	if <-fs.Mkdir("/d/newd2", zx.Dir{"mode": "0705", "Gid": "katsumoto"}) == nil {
		t.Fatalf("could mkdir gid")
	}
	if !nostat(t, fs, "/d/newd2") {
		t.Fatalf("stat")
	}

	if <-fs.Mkdir("/d/newd2", zx.Dir{"mode": "0705", "Gid": "gid2"}) != nil {
		t.Fatalf("couldn't mkdir gid")
	}
	if !stat(t, fs, "/d/newd2", "0750 nemo gid2 nemo") {
		t.Fatalf("stat")
	}

	if <-fs.Mkdir("/d/newd3", zx.Dir{"mode": "0705", "Wuid": "katsumoto"}) != nil {
		t.Fatalf("mkdir wuid not ignored")
	}
	if !stat(t, fs, "/d/newd3", "0750 nemo gid1 nemo") {
		t.Fatalf("stat")
	}

	if <-fs.Wstat("/d/newd3", zx.Dir{"mode": "0705"}) != nil {
		t.Fatalf("wstat 755")
	}
	if !stat(t, fs, "/d/newd3", "0705 nemo gid1 nemo") {
		t.Fatalf("stat")
	}

}
Esempio n. 8
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)
	}

}