Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.

dev_test.gno

4.20 Kb · 158 lines
  1package dev
  2
  3import (
  4	"chain/runtime"
  5	"strconv"
  6	"strings"
  7	"testing"
  8
  9	"gno.land/p/nt/testutils/v0"
 10
 11	ninep "gno.land/p/nym-moultest123/x/plan9/ninep/v0"
 12
 13	nsrealm "gno.land/r/nym-moultest123/x/plan9/ns/v0"
 14)
 15
 16func read(t *testing.T, name string) string {
 17	t.Helper()
 18	f, err := tree.Root().Walk(name)
 19	if err != nil {
 20		t.Fatalf("walk %s: %v", name, err)
 21	}
 22	data, err := ninep.ReadAll(f)
 23	if err != nil {
 24		t.Fatalf("read %s: %v", name, err)
 25	}
 26	return data
 27}
 28
 29func TestDevicesFollowTheChain(t *testing.T) {
 30	if got, want := read(t, "sysname"), runtime.ChainID(); got != want {
 31		t.Errorf("sysname: got %q, want %q", got, want)
 32	}
 33	if got, want := read(t, "domain"), runtime.ChainDomain(); got != want {
 34		t.Errorf("domain: got %q, want %q", got, want)
 35	}
 36	if got, want := read(t, "height"), strconv.FormatInt(runtime.ChainHeight(), 10); got != want {
 37		t.Errorf("height: got %q, want %q", got, want)
 38	}
 39
 40	// A device is code, not storage: advance the chain and the file follows.
 41	before := read(t, "height")
 42	testing.SkipHeights(5)
 43	after := read(t, "height")
 44	if before == after {
 45		t.Errorf("height did not move: %q", after)
 46	}
 47	b, _ := strconv.ParseInt(before, 10, 64)
 48	a, _ := strconv.ParseInt(after, 10, 64)
 49	if a-b != 5 {
 50		t.Errorf("height moved by %d, want 5", a-b)
 51	}
 52}
 53
 54func TestRandomIsBlockDeterministic(t *testing.T) {
 55	a := read(t, "random")
 56	if len(a) != 64 {
 57		t.Errorf("a sha256 in hex is 64 characters, got %d", len(a))
 58	}
 59	if a != read(t, "random") {
 60		t.Error("two reads in the same block must agree, or Render is a consensus bug")
 61	}
 62	testing.SkipHeights(1)
 63	if a == read(t, "random") {
 64		t.Error("the value should change with the block")
 65	}
 66}
 67
 68func TestNullAndZero(t *testing.T) {
 69	if got := read(t, "null"); got != "" {
 70		t.Errorf("null: %q", got)
 71	}
 72	f, _ := tree.Root().Walk("zero")
 73	got, _ := f.Read(0, 4)
 74	if got != "\x00\x00\x00\x00" {
 75		t.Errorf("zero: %q", got)
 76	}
 77	// An endless file must not answer an unbounded read with an endless value.
 78	if got, _ := f.Read(0, -1); got != "" {
 79		t.Errorf("unbounded read of /dev/zero: %d bytes", len(got))
 80	}
 81	if got, _ := f.Read(0, 1<<20); len(got) != 4096 {
 82		t.Errorf("a huge read should cap at 4096, got %d", len(got))
 83	}
 84}
 85
 86func TestSessionReportsAPlainKey(t *testing.T) {
 87	got := read(t, "session")
 88	if got != "session no\nscope full\n" {
 89		t.Errorf("a plain key has no session scope: %q", got)
 90	}
 91}
 92
 93func TestDriversListsEveryDevice(t *testing.T) {
 94	got := read(t, "drivers")
 95	ents, err := tree.Root().ReadDir()
 96	if err != nil {
 97		t.Fatalf("readdir: %v", err)
 98	}
 99	for _, e := range ents {
100		if !strings.Contains(got, e.Name+"\t") {
101			t.Errorf("/dev/drivers does not document %q", e.Name)
102		}
103	}
104	if len(ents) != len(docs) {
105		t.Errorf("%d devices but %d documented", len(ents), len(docs))
106	}
107}
108
109func TestTreeIsReadOnly(t *testing.T) {
110	var f ninep.File = tree.Root()
111	if _, ok := f.(ninep.Mutable); ok {
112		t.Error("a device tree handed to other realms must not be Mutable")
113	}
114}
115
116// TestPostedAtDeployTime is the cross-realm claim the whole suite rests on:
117// this realm pushed an interface value into another realm at init, and that
118// realm can call it back later from a read.
119func TestPostedAtDeployTime(t *testing.T) {
120	found := false
121	for _, s := range nsrealm.Services() {
122		if s == "dev" {
123			found = true
124		}
125	}
126	if !found {
127		t.Fatalf("dev is not posted in /srv: %v", nsrealm.Services())
128	}
129}
130
131func TestAFreshNamespaceHasDevBound(cur realm, t *testing.T) {
132	user := testutils.TestAddress("glenda")
133	testing.SetRealm(testing.NewUserRealm(user))
134	nsrealm.Reset(cross(cur))
135	// Touch the namespace so it is built with /dev already bound.
136	nsrealm.Exec(cross(cur), "echo hi > /tmp/hi")
137
138	out, err := nsrealm.Run(user.String(), "ls /dev")
139	if err != nil {
140		t.Fatalf("ls /dev: %v", err)
141	}
142	for _, d := range docs {
143		if !strings.Contains(out, d[0]) {
144			t.Errorf("ls /dev is missing %q: %q", d[0], out)
145		}
146	}
147	got, err := nsrealm.Run(user.String(), "cat /dev/sysname")
148	if err != nil {
149		t.Fatalf("cat: %v", err)
150	}
151	if got != runtime.ChainID() {
152		t.Errorf("reading this realm's device through another realm's namespace: %q", got)
153	}
154	// And the mount table says where it came from.
155	if ns := nsrealm.Namespace(user.String()); !strings.Contains(ns, "bind /srv/dev /dev") {
156		t.Errorf("mount table: %q", ns)
157	}
158}