// 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) } } }
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) }
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) }
// 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") }
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") } } }
func rcreate(t Fataler, fs zx.RWTree, fname string) { zx.PutAll(fs, fname, zx.Dir{"mode": "0644"}, []byte("hi there")) }
// 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") } }
// 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) } }