PathrockNetwork Gno Explorer
HomeBlocksTransactionsTokensRealmsPackagesValidatorsAnalytics

PathrockNetwork Gno Explorer — an independent explorer for Gno.land Mainnet (gnoland-1), operated by PathrockNetwork. Not an official Gno.land service.

gnowebarchive RPC

gno.land/p/moul/x/plan9/memfs/v0

Package
Open in gnoweb ↗

Overview

Kind
Pure package
Name
v0
Namespace
moul / x / plan9 / memfs
Files
4 (README)(gnomod.toml)
Exported functions
n/a — not supported for pure packages by the node (vm/qfuncs)
Module
gno.land/p/moul/x/plan9/memfs/v0
gno
0.9

Files (4)

  • README.mdmarkdown
  • gnomod.tomltoml
  • memfs.gnogno
  • memfs_test.gnogno
memfs_test.gnogno
1package memfs23import (4	"testing"56	ninep "gno.land/p/moul/x/plan9/ninep/v0"7)89func TestRootStat(t *testing.T) {10	fs := New("glenda", 100)11	s := fs.Root().Stat()12	if s.Name != "/" {13		t.Errorf("root name: got %q", s.Name)14	}15	if !s.IsDir() {16		t.Error("root should be a directory")17	}18	if s.Length != 0 {19		t.Errorf("a directory reports length 0 in 9P, got %d", s.Length)20	}21	if s.Uid != "glenda" || s.Gid != "glenda" {22		t.Errorf("owner: got %q/%q", s.Uid, s.Gid)23	}24	if s.Mtime != 100 {25		t.Errorf("mtime: got %d, want 100", s.Mtime)26	}27}2829func TestCreateWalkRead(t *testing.T) {30	fs := New("glenda", 1)31	root := fs.RootMutable()3233	f, err := root.Create("greeting", ninep.FilePerm, 2)34	if err != nil {35		t.Fatalf("create: %v", err)36	}37	m := f.(ninep.Mutable)38	n, err := m.Write(0, "hello world", 3)39	if err != nil {40		t.Fatalf("write: %v", err)41	}42	if n != 11 {43		t.Errorf("wrote %d bytes, want 11", n)44	}4546	got, err := root.Walk("greeting")47	if err != nil {48		t.Fatalf("walk: %v", err)49	}50	data, err := ninep.ReadAll(got)51	if err != nil {52		t.Fatalf("read: %v", err)53	}54	if data != "hello world" {55		t.Errorf("read back %q", data)56	}57	if l := got.Stat().Length; l != 11 {58		t.Errorf("length %d, want 11", l)59	}60}6162func TestWalkErrors(t *testing.T) {63	fs := New("glenda", 1)64	root := fs.RootMutable()65	root.Create("file", ninep.FilePerm, 1)6667	if _, err := root.Walk("absent"); err != ninep.ErrNotExist {68		t.Errorf("missing name: got %v, want ErrNotExist", err)69	}70	if _, err := root.Walk("a/b"); err != ninep.ErrBadName {71		t.Errorf("slash in name: got %v, want ErrBadName", err)72	}73	f, _ := root.Walk("file")74	if _, err := f.Walk("x"); err != ninep.ErrNotDir {75		t.Errorf("walk through a file: got %v, want ErrNotDir", err)76	}77	if _, err := f.ReadDir(); err != ninep.ErrNotDir {78		t.Errorf("readdir of a file: got %v, want ErrNotDir", err)79	}80	if _, err := root.Read(0, -1); err != ninep.ErrIsDir {81		t.Errorf("read of a directory: got %v, want ErrIsDir", err)82	}83}8485func TestReadDirIsOrdered(t *testing.T) {86	fs := New("glenda", 1)87	root := fs.RootMutable()88	for _, name := range []string{"zulu", "alpha", "mike", "bravo"} {89		if _, err := root.Create(name, ninep.FilePerm, 1); err != nil {90			t.Fatalf("create %s: %v", name, err)91		}92	}93	ents, err := root.ReadDir()94	if err != nil {95		t.Fatalf("readdir: %v", err)96	}97	want := []string{"alpha", "bravo", "mike", "zulu"}98	if len(ents) != len(want) {99		t.Fatalf("got %d entries, want %d", len(ents), len(want))100	}101	for i, w := range want {102		if ents[i].Name != w {103			t.Errorf("entry %d: got %q, want %q", i, ents[i].Name, w)104		}105	}106}107108func TestCreateDuplicate(t *testing.T) {109	fs := New("glenda", 1)110	root := fs.RootMutable()111	root.Create("x", ninep.FilePerm, 1)112	if _, err := root.Create("x", ninep.FilePerm, 1); err != ninep.ErrExist {113		t.Errorf("got %v, want ErrExist", err)114	}115	if _, err := root.Create("", ninep.FilePerm, 1); err != ninep.ErrBadName {116		t.Errorf("empty name: got %v, want ErrBadName", err)117	}118	if _, err := root.Create("..", ninep.FilePerm, 1); err != ninep.ErrBadName {119		t.Errorf("dotdot: got %v, want ErrBadName", err)120	}121}122123func TestRemove(t *testing.T) {124	fs := New("glenda", 1)125	root := fs.RootMutable()126	root.Create("file", ninep.FilePerm, 1)127	d, _ := root.Create("dir", ninep.DirPerm, 1)128	d.(ninep.Mutable).Create("inner", ninep.FilePerm, 1)129130	if err := root.Remove("absent"); err != ninep.ErrNotExist {131		t.Errorf("remove missing: got %v", err)132	}133	if err := root.Remove("dir"); err != ninep.ErrNotEmpty {134		t.Errorf("remove non-empty dir: got %v, want ErrNotEmpty", err)135	}136	if err := d.(ninep.Mutable).Remove("inner"); err != nil {137		t.Fatalf("remove inner: %v", err)138	}139	if err := root.Remove("dir"); err != nil {140		t.Fatalf("remove emptied dir: %v", err)141	}142	if err := root.Remove("file"); err != nil {143		t.Fatalf("remove file: %v", err)144	}145	ents, _ := root.ReadDir()146	if len(ents) != 0 {147		t.Errorf("root should be empty, has %d entries", len(ents))148	}149}150151func TestWriteOffsets(t *testing.T) {152	tests := []struct {153		name  string154		start string155		off   int64156		data  string157		want  string158	}{159		{"append at end", "abc", 3, "def", "abcdef"},160		{"overwrite middle", "abcdef", 2, "XY", "abXYef"},161		{"overwrite past end", "abc", 2, "XYZ", "abXYZ"},162		{"from zero", "abcdef", 0, "ZZ", "ZZcdef"},163		{"gap is nul filled", "ab", 4, "Z", "ab\x00\x00Z"},164		{"negative offset clamps", "abc", -2, "Z", "Zbc"},165	}166	for _, tt := range tests {167		fs := New("glenda", 1)168		root := fs.RootMutable()169		f, _ := root.Create("f", ninep.FilePerm, 1)170		m := f.(ninep.Mutable)171		m.Write(0, tt.start, 1)172		m.Write(tt.off, tt.data, 2)173		got, _ := ninep.ReadAll(f)174		if got != tt.want {175			t.Errorf("%s: got %q, want %q", tt.name, got, tt.want)176		}177	}178}179180func TestAppendOnlyIgnoresOffset(t *testing.T) {181	fs := New("glenda", 1)182	root := fs.RootMutable()183	f, _ := root.Create("log", ninep.DMAPPEND|0644, 1)184	m := f.(ninep.Mutable)185	m.Write(0, "one\n", 1)186	m.Write(0, "two\n", 2) // offset 0, but append-only pins it to the end187	got, _ := ninep.ReadAll(f)188	if got != "one\ntwo\n" {189		t.Errorf("got %q", got)190	}191}192193func TestTruncate(t *testing.T) {194	fs := New("glenda", 1)195	root := fs.RootMutable()196	f, _ := root.Create("f", ninep.FilePerm, 1)197	m := f.(ninep.Mutable)198	m.Write(0, "abcdef", 1)199200	m.Truncate(3, 2)201	if got, _ := ninep.ReadAll(f); got != "abc" {202		t.Errorf("shrink: got %q", got)203	}204	m.Truncate(5, 3)205	if got, _ := ninep.ReadAll(f); got != "abc\x00\x00" {206		t.Errorf("grow: got %q", got)207	}208	m.Truncate(0, 4)209	if got, _ := ninep.ReadAll(f); got != "" {210		t.Errorf("zero: got %q", got)211	}212}213214func TestQidVersionAndPath(t *testing.T) {215	fs := New("glenda", 1)216	root := fs.RootMutable()217	a, _ := root.Create("a", ninep.FilePerm, 1)218	b, _ := root.Create("b", ninep.FilePerm, 1)219220	if a.Stat().Qid.Path == b.Stat().Qid.Path {221		t.Error("two files share a qid path")222	}223	v0 := a.Stat().Qid.Version224	a.(ninep.Mutable).Write(0, "x", 2)225	if a.Stat().Qid.Version != v0+1 {226		t.Errorf("version did not advance on write: %d -> %d", v0, a.Stat().Qid.Version)227	}228	if a.Stat().Mtime != 2 {229		t.Errorf("mtime: got %d, want 2", a.Stat().Mtime)230	}231}232233func TestMkdirAllAndWriteFile(t *testing.T) {234	fs := New("glenda", 1)235	if _, err := fs.MkdirAll("/usr/glenda/lib", 1); err != nil {236		t.Fatalf("mkdirall: %v", err)237	}238	// idempotent239	if _, err := fs.MkdirAll("/usr/glenda", 1); err != nil {240		t.Fatalf("mkdirall again: %v", err)241	}242	if err := fs.WriteFile("/usr/glenda/lib/profile", "font=pelm\n", 2); err != nil {243		t.Fatalf("writefile: %v", err)244	}245	f, err := ninep.Walk(fs.Root(), ninep.Elems("/usr/glenda/lib/profile"))246	if err != nil {247		t.Fatalf("walk: %v", err)248	}249	if got, _ := ninep.ReadAll(f); got != "font=pelm\n" {250		t.Errorf("got %q", got)251	}252	// rewriting replaces rather than appends253	if err := fs.WriteFile("/usr/glenda/lib/profile", "font=lucida\n", 3); err != nil {254		t.Fatalf("rewrite: %v", err)255	}256	f, _ = ninep.Walk(fs.Root(), ninep.Elems("/usr/glenda/lib/profile"))257	if got, _ := ninep.ReadAll(f); got != "font=lucida\n" {258		t.Errorf("rewrite got %q", got)259	}260}261262func TestMkdirAllThroughAFileFails(t *testing.T) {263	fs := New("glenda", 1)264	fs.WriteFile("/etc", "not a directory", 1)265	if _, err := fs.MkdirAll("/etc/passwd", 2); err != ninep.ErrNotDir {266		t.Errorf("got %v, want ErrNotDir", err)267	}268}269270func TestWalkDepthLimit(t *testing.T) {271	fs := New("glenda", 1)272	elems := []string{}273	for i := 0; i <= ninep.MaxDepth; i++ {274		elems = append(elems, "x")275	}276	if _, err := ninep.Walk(fs.Root(), elems); err != ninep.ErrTooDeep {277		t.Errorf("got %v, want ErrTooDeep", err)278	}279}280

Functions

not supported for pure packages by the node (vm/qfuncs)

Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.