Blob


1 package p9pnew
3 import (
4 "bytes"
5 "reflect"
6 "testing"
7 "time"
8 )
10 func TestEncodeDecode(t *testing.T) {
11 for _, testcase := range []struct {
12 description string
13 target interface{}
14 marshaled []byte
15 }{
16 {
17 description: "string",
18 target: "asdf",
19 marshaled: []byte{0x4, 0x0, 0x61, 0x73, 0x64, 0x66},
20 },
21 {
22 description: "[]string",
23 target: []string{"asdf", "qwer", "zxcv"},
24 marshaled: []byte{
25 0x3, 0x0, // len(target)
26 0x4, 0x0, 0x61, 0x73, 0x64, 0x66,
27 0x4, 0x0, 0x71, 0x77, 0x65, 0x72,
28 0x4, 0x0, 0x7a, 0x78, 0x63, 0x76},
29 },
30 // Dir
31 // Qid
32 {
33 description: "Tversion fcall",
34 target: &Fcall{
35 Type: Tversion,
36 Tag: 2255,
37 Message: &MessageTversion{
38 MSize: uint32(1024),
39 Version: "9PTEST",
40 },
41 },
42 marshaled: []byte{
43 0x64, 0xcf, 0x8, 0x0, 0x4, 0x0, 0x0,
44 0x6, 0x0, 0x39, 0x50, 0x54, 0x45, 0x53, 0x54},
45 },
46 {
47 description: "Rversion fcall",
48 target: &Fcall{
49 Type: Rversion,
50 Tag: 2255,
51 Message: &MessageRversion{
52 MSize: uint32(1024),
53 Version: "9PTEST",
54 },
55 },
56 marshaled: []byte{
57 0x65, 0xcf, 0x8, 0x0, 0x4, 0x0, 0x0,
58 0x6, 0x0, 0x39, 0x50, 0x54, 0x45, 0x53, 0x54},
59 },
60 {
61 description: "Twalk fcall",
62 target: &Fcall{
63 Type: Twalk,
64 Tag: 5666,
65 Message: &MessageTwalk{
66 Fid: 1010,
67 Newfid: 1011,
68 Wnames: []string{"a", "b", "c"},
69 },
70 },
71 marshaled: []byte{
72 0x6e, 0x22, 0x16, 0xf2, 0x3, 0x0, 0x0, 0xf3, 0x3, 0x0, 0x0,
73 0x3, 0x0, // len(wnames)
74 0x1, 0x0, 0x61, // "a"
75 0x1, 0x0, 0x62, // "b"
76 0x1, 0x0, 0x63}, // "c"
77 },
78 {
79 description: "Rwalk call",
80 target: &Fcall{
81 Type: Rwalk,
82 Tag: 5556,
83 Message: &MessageRwalk{
84 Qids: []Qid{
85 Qid{
86 Type: QTDIR,
87 Path: 1111,
88 Version: 11112,
89 },
90 Qid{Type: QTFILE,
91 Version: 1112,
92 Path: 11114},
93 },
94 },
95 },
96 marshaled: []byte{
97 0x6f, 0xb4, 0x15,
98 0x2, 0x0,
99 0x80, 0x68, 0x2b, 0x0, 0x0, 0x57, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
100 0x0, 0x58, 0x4, 0x0, 0x0, 0x6a, 0x2b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
101 },
103 description: "Rread fcall",
104 target: &Fcall{
105 Type: Rread,
106 Tag: 5556,
107 Message: &MessageRread{
108 Data: []byte("a lot of byte data"),
109 },
110 },
111 marshaled: []byte{
112 0x75, 0xb4, 0x15,
113 0x12, 0x0, 0x0, 0x0,
114 0x61, 0x20, 0x6c, 0x6f, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x62, 0x79, 0x74, 0x65, 0x20, 0x64, 0x61, 0x74, 0x61},
115 },
117 description: "",
118 target: &Fcall{
119 Type: Rstat,
120 Tag: 5556,
121 Message: &MessageRstat{
122 Stat: Dir{
123 Type: ^uint16(0),
124 Dev: ^uint32(0),
125 Qid: Qid{
126 Type: QTDIR,
127 Version: ^uint32(0),
128 Path: ^uint64(0),
129 },
130 Mode: DMDIR | DMREAD,
131 AccessTime: time.Date(2006, 01, 02, 03, 04, 05, 0, time.UTC),
132 ModTime: time.Date(2006, 01, 02, 03, 04, 05, 0, time.UTC),
133 Length: ^uint64(0),
134 Name: "somedir",
135 UID: "uid",
136 GID: "gid",
137 MUID: "muid",
138 },
139 },
140 },
141 marshaled: []byte{
142 0x7d, 0xb4, 0x15,
143 0x42, 0x0, // TODO(stevvooe): Include Dir size. Not straightforward.
144 0x40, 0x0, // TODO(stevvooe): Include Dir size. Not straightforward.
145 0xff, 0xff, // type
146 0xff, 0xff, 0xff, 0xff, // dev
147 0x80, 0xff, 0xff, 0xff, 0xff, // qid.type, qid.version
148 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // qid.path
149 0x4, 0x0, 0x0, 0x80, // mode
150 0x25, 0x98, 0xb8, 0x43, // atime
151 0x25, 0x98, 0xb8, 0x43, // mtime
152 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // length
153 0x7, 0x0, 0x73, 0x6f, 0x6d, 0x65, 0x64, 0x69, 0x72,
154 0x3, 0x0, 0x75, 0x69, 0x64, // uid
155 0x3, 0x0, 0x67, 0x69, 0x64, // gid
156 0x4, 0x0, 0x6d, 0x75, 0x69, 0x64}, // muid
157 },
158 } {
159 t.Logf("target under test: %v", testcase.target)
160 fatalf := func(format string, args ...interface{}) {
161 t.Fatalf(testcase.description+": "+format, args...)
164 t.Logf("expecting message of %v bytes", len(testcase.marshaled))
166 var b bytes.Buffer
168 enc := &encoder{&b}
169 dec := &decoder{&b}
171 if err := enc.encode(testcase.target); err != nil {
172 fatalf("error writing fcall: %v", err)
175 if !bytes.Equal(b.Bytes(), testcase.marshaled) {
176 fatalf("unexpected bytes for fcall: \n%#v != \n%#v", b.Bytes(), testcase.marshaled)
179 // check that size9p is working correctly
180 if int(size9p(testcase.target)) != len(testcase.marshaled) {
181 fatalf("size not correct: %v != %v", int(size9p(testcase.target)), len(testcase.marshaled))
184 var v interface{}
185 targetType := reflect.TypeOf(testcase.target)
187 if targetType.Kind() == reflect.Ptr {
188 v = reflect.New(targetType.Elem()).Interface()
189 } else {
190 v = reflect.New(targetType).Interface()
193 if err := dec.decode(v); err != nil {
194 fatalf("error reading: %v", err)
197 if targetType.Kind() != reflect.Ptr {
198 v = reflect.Indirect(reflect.ValueOf(v)).Interface()
201 if !reflect.DeepEqual(v, testcase.target) {
202 fatalf("not equal: %v != %v", v, testcase.target)
205 t.Logf("%#v", v)