rstyx 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1288 @@
1
+ #!/usr/bin/ruby
2
+ #
3
+ # Copyright (C) 2005 Rafael Sevilla
4
+ # This file is part of RStyx
5
+ #
6
+ # RStyx is free software; you can redistribute it and/or modify
7
+ # it under the terms of the GNU Lesser General Public License as
8
+ # published by the Free Software Foundation; either version 2.1
9
+ # of the License, or (at your option) any later version.
10
+ #
11
+ # RStyx is distributed in the hope that it will be useful, but
12
+ # WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTIBILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Lesser General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Lesser General Public
17
+ # License along with RStyx; if not, write to the Free Software
18
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19
+ # 02111-1307 USA.
20
+ #
21
+ # Unit tests for Styx messages
22
+ #
23
+ # $Id: tc_message.rb,v 1.23 2005/09/28 17:56:58 dido Exp $
24
+ #
25
+ require 'test/unit'
26
+ require 'rstyx/messages'
27
+
28
+ class MessageTest < Test::Unit::TestCase
29
+ ##
30
+ # Test the utility functions provided
31
+ #
32
+ def test_utils
33
+ # Basic test
34
+ pstr = RStyx::Message::Util.strpack("foo")
35
+ assert(pstr == "\003\000foo")
36
+ # Add trailing garbage to the string
37
+ pstr += "some trailing garbage"
38
+ upstr = RStyx::Message::Util.strextract(pstr, 0)
39
+ assert(upstr[0] == "foo")
40
+ # Try packing several strings together
41
+ packstr = RStyx::Message::Util.strpack("foo") +
42
+ RStyx::Message::Util.strpack("bar") +
43
+ RStyx::Message::Util.strpack("baz")
44
+ str, offset = RStyx::Message::Util.strextract(packstr, 0)
45
+ assert(str == "foo")
46
+ str, offset = RStyx::Message::Util.strextract(packstr, offset)
47
+ assert(str == "bar")
48
+ str, offset = RStyx::Message::Util.strextract(packstr, offset)
49
+ assert(str == "baz")
50
+ # Try a long string
51
+ longstr = "alpha bravo charlie delta echo foxtrot golf hotel india juliet kilo lima mama nancy oscar papa quebec romeo sierra tango uniform victor whiskey x-ray yankee zulu"
52
+ pstr = RStyx::Message::Util.strpack(longstr)
53
+ assert(RStyx::Message::Util.strextract(pstr, 0)[0] == longstr)
54
+
55
+ # Test decoding of invalid strings
56
+ invstr ="\003\000fo"
57
+ assert_raise(RStyx::StyxException) { RStyx::Message::Util.strextract(invstr, 0) }
58
+ invstr = "\003"
59
+ assert_raise(RStyx::StyxException) { RStyx::Message::Util.strextract(invstr, 0) }
60
+ end
61
+
62
+ ##
63
+ # Test the Qid class
64
+ #
65
+ def test_qid
66
+ # Generate a distinctive Styx message
67
+ qid = RStyx::Message::Qid.new(0x01,0xdeadbeef,0xfeedfacec0ffeeee)
68
+ bytes = qid.to_bytes
69
+ # Test if the serialized version is as expected
70
+ assert(bytes == "\x01\xef\xbe\xad\xde\xee\xee\xff\xc0\xce\xfa\xed\xfe")
71
+
72
+ # Try to deserialize and check whether the output is as expected
73
+ qqid = RStyx::Message::Qid.decode(bytes)
74
+ assert(qqid.qtype == 0x01)
75
+ assert(qqid.version == 0xdeadbeef)
76
+ assert(qqid.path == 0xfeedfacec0ffeeee)
77
+
78
+ # Test decoding short values
79
+ assert_raise(RStyx::StyxException) { RStyx::Message::Qid.decode("") }
80
+ assert_raise(RStyx::StyxException) { RStyx::Message::Qid.decode(" ") }
81
+
82
+ # Test decoding 13 bytes and with trailing garbage
83
+ assert_nothing_raised { RStyx::Message::Qid.decode(" ") }
84
+ assert_nothing_raised { qqid = RStyx::Message::Qid.decode("\x01\xef\xbe\xad\xde\xee\xee\xff\xc0\xce\xfa\xed\xfesome trailing garbage") }
85
+
86
+ # test if the decoding still works even in the face of trailing garbage
87
+ assert(qqid.qtype == 0x01)
88
+ assert(qqid.version == 0xdeadbeef)
89
+ assert(qqid.path == 0xfeedfacec0ffeeee)
90
+ end
91
+
92
+ ##
93
+ # Test the DirEntry class
94
+ #
95
+ def test_direntry
96
+ # generate a dummy DirEntry for testing
97
+ de = RStyx::Message::DirEntry.new
98
+ de.dtype = 0x1234
99
+ de.dev = 0x567890ab
100
+ de.qid = RStyx::Message::Qid.new(0x01, 0xdeadbeef,0xfeedfacec0ffeeee)
101
+ de.mode = 0x9abcdef0
102
+ de.atime = 0xdeadbeef
103
+ de.mtime = 0xcafebabe
104
+ de.length = 0xfedcba9876543210
105
+ de.name = "foo"
106
+ de.uid = "bar"
107
+ de.gid = "baz"
108
+ de.muid = "quux"
109
+ bytes = de.to_bytes
110
+ expect = "\x3c\x00\x34\x12\xab\x90\x78\x56\x01\xef\xbe\xad\xde\xee\xee\xff\xc0\xce\xfa\xed\xfe\xf0\xde\xbc\x9a\xef\xbe\xad\xde\xbe\xba\xfe\xca\x10\x32\x54\x76\x98\xba\xdc\xfe\x03\x00foo\x03\x00bar\x03\x00baz\x04\x00quux"
111
+ assert(bytes == expect)
112
+
113
+ # Generate a new direntry based on the above string
114
+ de2 = RStyx::Message::DirEntry.decode(expect)
115
+ assert(de2.dtype == 0x1234)
116
+ assert(de2.dev == 0x567890ab)
117
+ assert(de2.qid.qtype == 0x01)
118
+ assert(de2.qid.version == 0xdeadbeef)
119
+ assert(de2.qid.path == 0xfeedfacec0ffeeee)
120
+ assert(de2.mode == 0x9abcdef0)
121
+ assert(de2.atime == 0xdeadbeef)
122
+ assert(de2.mtime == 0xcafebabe)
123
+ assert(de2.length == 0xfedcba9876543210)
124
+ assert(de2.name == "foo")
125
+ assert(de2.uid == "bar")
126
+ assert(de2.gid == "baz")
127
+ assert(de2.muid == "quux")
128
+
129
+ # Test decoding truncated strings
130
+ assert_raise(RStyx::StyxException) { RStyx::Message::DirEntry.decode("") }
131
+ assert_raise(RStyx::StyxException) { RStyx::Message::DirEntry.decode("\x3c\x00\x34\x12\xab\x90\x78\x56\x01\xef\xbe\xad\xde\xee\xee\xff\xc0\xce\xfa\xed\xfe\xf0\xde\xbc\x9a\xef\xbe\xad\xde\xbe\xba\xfe\xca\x10\x32\x54\x76") }
132
+ assert_raise(RStyx::StyxException) { RStyx::Message::DirEntry.decode("\x3c\x00\x34\x12\xab\x90\x78\x56\x01\xef\xbe\xad\xde\xee\xee\xff\xc0\xce\xfa\xed\xfe\xf0\xde\xbc\x9a\xef\xbe\xad\xde\xbe\xba\xfe\xca\x10\x32\x54\x76\x98\xba\xdc\xfe\x03\x00foo\x03\x00bar\x03\x00baz\x04\x00qu") }
133
+
134
+ # Test decoding strings with garbage at the end
135
+ # Generate a new direntry based on the above string
136
+ assert_nothing_raised do
137
+ de2 = RStyx::Message::DirEntry.decode(expect + "trailing garbage")
138
+ end
139
+ assert(de2.dtype == 0x1234)
140
+ assert(de2.dev == 0x567890ab)
141
+ q = RStyx::Message::Qid.new(0x01, 0xdeadbeef,0xfeedfacec0ffeeee)
142
+ assert(de2.qid.qtype == 0x01)
143
+ assert(de2.qid.version == 0xdeadbeef)
144
+ assert(de2.qid.path == 0xfeedfacec0ffeeee)
145
+ assert(de2.mode == 0x9abcdef0)
146
+ assert(de2.atime == 0xdeadbeef)
147
+ assert(de2.mtime == 0xcafebabe)
148
+ assert(de2.length == 0xfedcba9876543210)
149
+ assert(de2.name == "foo")
150
+ assert(de2.uid == "bar")
151
+ assert(de2.gid == "baz")
152
+ assert(de2.muid == "quux")
153
+ end
154
+
155
+ ##
156
+ # Test the Tversion class
157
+ #
158
+ def test_tversion
159
+ tv = RStyx::Message::Tversion.new(0xdeadbeef, "9P2000")
160
+ bytes = tv.to_bytes(0x1234)
161
+ expect = "\x13\x00\x00\x00\x64\x34\x12\xef\xbe\xad\xde\x06\x009P2000"
162
+ assert(expect == bytes)
163
+ # Try to decode the expect string
164
+ tvm = RStyx::Message::StyxMessage.decode(expect)
165
+ assert(tvm.class == RStyx::Message::Tversion)
166
+ assert(tvm.length == 0x13)
167
+ assert(tvm.mtype == RStyx::Message::StyxMessage::TVERSION)
168
+ assert(tvm.tag == 0x1234)
169
+ assert(tvm.msize == 0xdeadbeef)
170
+ assert(tvm.version == "9P2000")
171
+
172
+ # Try to decode short strings
173
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode("\x13\x00\x00\x00\x64\x34\x12\xef\xbe\xad\xde\x06\x009P200") }
174
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode("\x13\x00\x00\x00\x64\x34\x12\xef\xbe\xad") }
175
+
176
+ # Try to decode the expect string with trailing garbage
177
+ tvm = RStyx::Message::StyxMessage.decode(expect + "trailing garbage")
178
+ assert(tvm.class == RStyx::Message::Tversion)
179
+ assert(tvm.length == 0x13)
180
+ assert(tvm.mtype == RStyx::Message::StyxMessage::TVERSION)
181
+ assert(tvm.tag == 0x1234)
182
+ assert(tvm.msize == 0xdeadbeef)
183
+ assert(tvm.version == "9P2000")
184
+
185
+ end
186
+
187
+ ##
188
+ # Test the Rversion class
189
+ #
190
+ def test_rversion
191
+ rv = RStyx::Message::Rversion.new(0xdeadbeef, "9P2000")
192
+ bytes = rv.to_bytes(0x1234)
193
+ expect = "\x13\x00\x00\x00\x65\x34\x12\xef\xbe\xad\xde\x06\x009P2000"
194
+ assert(expect == bytes)
195
+ # Try to decode the expect string
196
+ rvm = RStyx::Message::StyxMessage.decode(expect)
197
+ assert(rvm.class == RStyx::Message::Rversion)
198
+ assert(rvm.length == 0x13)
199
+ assert(rvm.mtype == RStyx::Message::StyxMessage::RVERSION)
200
+ assert(rvm.tag == 0x1234)
201
+ assert(rvm.msize == 0xdeadbeef)
202
+ assert(rvm.version == "9P2000")
203
+
204
+ # Try to decode short strings
205
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode("\x13\x00\x00\x00\x65\x34\x12\xef\xbe\xad\xde\x06\x009P200") }
206
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode("\x13\x00\x00\x00\x65\x34\x12\xef\xbe") }
207
+
208
+ # Try to decode with trailing garbage
209
+ assert_nothing_raised do
210
+ rvm = RStyx::Message::StyxMessage.decode(expect + "trailing garbage")
211
+ end
212
+ assert(rvm.class == RStyx::Message::Rversion)
213
+ assert(rvm.length == 0x13)
214
+ assert(rvm.mtype == RStyx::Message::StyxMessage::RVERSION)
215
+ assert(rvm.tag == 0x1234)
216
+ assert(rvm.msize == 0xdeadbeef)
217
+ assert(rvm.version == "9P2000")
218
+ end
219
+
220
+ ##
221
+ # Test the Tauth class.
222
+ #
223
+ def test_tauth
224
+ ta = RStyx::Message::Tauth.new("foo", 0x9abcdef0, "bar")
225
+ bytes = ta.to_bytes(0x1234)
226
+ expect = "\x66\x34\x12\xf0\xde\xbc\x9a\x03\x00foo\x03\x00bar"
227
+ len = expect.length + 4
228
+ expect = [len].pack("V") + expect
229
+ assert(bytes == expect)
230
+ ta2 = RStyx::Message::StyxMessage.decode(expect)
231
+ assert(ta2.class == RStyx::Message::Tauth)
232
+ assert(ta2.length == len)
233
+ assert(ta2.mtype == RStyx::Message::StyxMessage::TAUTH)
234
+ assert(ta2.tag == 0x1234)
235
+ assert(ta2.afid == 0x9abcdef0)
236
+ assert(ta2.uname == "foo")
237
+ assert(ta2.aname == "bar")
238
+
239
+ # Try to decode short strings
240
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode("\x66\x34\x12\xf0\xde\xbc\x9a\x03\x00foo\x03\x00b") }
241
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode("\x66\x34\x12\xf0\xde\xbc") }
242
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode("\x66\x34") }
243
+
244
+ # decode with trailing garbage
245
+ assert_nothing_raised do
246
+ ta2 = RStyx::Message::StyxMessage.decode(expect + "trailing garbage")
247
+ end
248
+ assert(ta2.class == RStyx::Message::Tauth)
249
+ assert(ta2.length == len)
250
+ assert(ta2.mtype == RStyx::Message::StyxMessage::TAUTH)
251
+ assert(ta2.tag == 0x1234)
252
+ assert(ta2.afid == 0x9abcdef0)
253
+ assert(ta2.uname == "foo")
254
+ assert(ta2.aname == "bar")
255
+ end
256
+
257
+ ##
258
+ # Test the Rauth class.
259
+ #
260
+ def test_rauth
261
+ ra = RStyx::Message::Rauth.new(RStyx::Message::Qid.new(0x01, 0xdeadbeef, 0xfeedfacec0ffeeee))
262
+ bytes = ra.to_bytes(0x1234)
263
+ expect = "\x67\x34\x12\x01\xef\xbe\xad\xde\xee\xee\xff\xc0\xce\xfa\xed\xfe"
264
+ len = expect.length + 4
265
+ expect = [len].pack("V") + expect
266
+ assert(expect == bytes)
267
+ ra2 = RStyx::Message::StyxMessage.decode(expect)
268
+ assert(ra2.class == RStyx::Message::Rauth)
269
+ assert(ra2.length == len)
270
+ assert(ra2.mtype == RStyx::Message::StyxMessage::RAUTH)
271
+ assert(ra2.tag == 0x1234)
272
+ assert(ra2.aqid.qtype == 0x01)
273
+ assert(ra2.aqid.version == 0xdeadbeef)
274
+ assert(ra2.aqid.path == 0xfeedfacec0ffeeee)
275
+ # Try to decode short strings
276
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode("\x67\x34\x12\x01\xef\xbe\xad\xde\xee\xee\xff\xc0\xce\xfa\xed") }
277
+
278
+ # Decode with trailing garbage
279
+ assert_nothing_raised do
280
+ ra2 = RStyx::Message::StyxMessage.decode(expect + "trailing garbage")
281
+ end
282
+ assert(ra2.class == RStyx::Message::Rauth)
283
+ assert(ra2.length == len)
284
+ assert(ra2.mtype == RStyx::Message::StyxMessage::RAUTH)
285
+ assert(ra2.tag == 0x1234)
286
+ assert(ra2.aqid.qtype == 0x01)
287
+ assert(ra2.aqid.version == 0xdeadbeef)
288
+ assert(ra2.aqid.path == 0xfeedfacec0ffeeee)
289
+ end
290
+
291
+ ##
292
+ # Test the Rerror class
293
+ #
294
+ def test_rerror
295
+ rerr = RStyx::Message::Rerror.new("error")
296
+ bytes = rerr.to_bytes(0x1234)
297
+ expect = "\x0e\x00\x00\x00\x6b\x34\x12\x05\x00error"
298
+ assert(bytes == expect)
299
+
300
+ # Try to decode the expect string
301
+ emsg = RStyx::Message::StyxMessage.decode(expect)
302
+ assert(emsg.class == RStyx::Message::Rerror)
303
+ assert(emsg.length == 0x0e)
304
+ assert(emsg.mtype == RStyx::Message::StyxMessage::RERROR)
305
+ assert(emsg.tag == 0x1234)
306
+ assert(emsg.ename == "error")
307
+ assert(emsg.messagebody == "\x05\x00error")
308
+
309
+ # Try to decode short strings
310
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode("") }
311
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode("\x0e\x00\x00") }
312
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode("\x0e\x00\x00\x00\x6b\x34\x12\x05\x00erro") }
313
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode("\x0e\x00\x00\x00\x6b\x34\x12\x05\x00erro") }
314
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode("\x0e\x00\x00\x00\x6b\x34\x12") }
315
+
316
+ # Try to decode strings with trailing garbage
317
+ assert_nothing_raised do
318
+ emsg = RStyx::Message::StyxMessage.decode(expect + "trailing garbage")
319
+ end
320
+ assert(emsg.class == RStyx::Message::Rerror)
321
+ assert(emsg.length == 0x0e)
322
+ assert(emsg.mtype == RStyx::Message::StyxMessage::RERROR)
323
+ assert(emsg.tag == 0x1234)
324
+ assert(emsg.ename == "error")
325
+ assert(emsg.messagebody == "\x05\x00error")
326
+ end
327
+
328
+ ##
329
+ # Test the Tflush class.
330
+ #
331
+ def test_tflush
332
+ tf = RStyx::Message::Tflush.new(0x5678)
333
+ bytes = tf.to_bytes(0x1234)
334
+ expect = "\x6c\x34\x12\x78\x56"
335
+ len = expect.length + 4
336
+ packlen = [len].pack("V")
337
+ expect = packlen + expect
338
+ assert(expect == bytes)
339
+
340
+ # decode expect
341
+ tf2 = RStyx::Message::StyxMessage.decode(expect)
342
+ assert(tf2.class == RStyx::Message::Tflush)
343
+ assert(tf2.length == len)
344
+ assert(tf2.mtype == RStyx::Message::StyxMessage::TFLUSH)
345
+ assert(tf2.tag == 0x1234)
346
+ assert(tf2.oldtag == 0x5678)
347
+
348
+ # try decoding short strings
349
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode(packlen + "\x6c\x34\x12\x78") }
350
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode(packlen + "\x6c\x34\x12") }
351
+
352
+ # decode with trailing garbage
353
+ tf2 = nil
354
+ assert_nothing_raised do
355
+ tf2 = RStyx::Message::StyxMessage.decode(expect + "trailing garbage")
356
+ end
357
+ assert(tf2.class == RStyx::Message::Tflush)
358
+ assert(tf2.length == len)
359
+ assert(tf2.mtype == RStyx::Message::StyxMessage::TFLUSH)
360
+ assert(tf2.tag == 0x1234)
361
+ assert(tf2.oldtag == 0x5678)
362
+ end
363
+
364
+ ##
365
+ # Test the Rflush class.
366
+ #
367
+ def test_rflush
368
+ tf = RStyx::Message::Rflush.new
369
+ bytes = tf.to_bytes(0x1234)
370
+ expect = "\x6d\x34\x12"
371
+ len = expect.length + 4
372
+ packlen = [len].pack("V")
373
+ expect = packlen + expect
374
+ assert(expect == bytes)
375
+
376
+ # decode expect
377
+ rf2 = RStyx::Message::StyxMessage.decode(expect)
378
+ assert(rf2.class == RStyx::Message::Rflush)
379
+ assert(rf2.length == len)
380
+ assert(rf2.mtype == RStyx::Message::StyxMessage::RFLUSH)
381
+ assert(rf2.tag == 0x1234)
382
+
383
+ # try decoding short strings
384
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode(packlen + "\x6d\x34") }
385
+
386
+ # decode with trailing garbage
387
+ rf2 = nil
388
+ assert_nothing_raised do
389
+ rf2 = RStyx::Message::StyxMessage.decode(expect + "trailing garbage")
390
+ end
391
+ assert(rf2.class == RStyx::Message::Rflush)
392
+ assert(rf2.length == len)
393
+ assert(rf2.mtype == RStyx::Message::StyxMessage::RFLUSH)
394
+ assert(rf2.tag == 0x1234)
395
+
396
+ end
397
+
398
+ ##
399
+ # Test the Tattach class.
400
+ #
401
+ def test_tattach
402
+ ta = RStyx::Message::Tattach.new(0x12345678, "foo", 0x9abcdef0, "bar")
403
+ bytes = ta.to_bytes(0x1234)
404
+ expect = "\x68\x34\x12\x78\x56\x34\x12\xf0\xde\xbc\x9a\x03\x00foo\x03\x00bar"
405
+ len = expect.length + 4
406
+ packlen = [len].pack("V")
407
+ expect = packlen + expect
408
+ assert(expect == bytes)
409
+
410
+ # Decode expect string
411
+ ta2 = RStyx::Message::StyxMessage.decode(expect)
412
+ assert(ta2.class == RStyx::Message::Tattach)
413
+ assert(ta2.length == len)
414
+ assert(ta2.mtype == RStyx::Message::StyxMessage::TATTACH)
415
+ assert(ta2.tag == 0x1234)
416
+ assert(ta2.fid == 0x12345678)
417
+ assert(ta2.afid == 0x9abcdef0)
418
+ assert(ta2.uname == "foo")
419
+ assert(ta2.aname == "bar")
420
+
421
+ # Try to decode short strings
422
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode(packlen + "\x68\x34\x12\x78\x56\x34\x12\xf0\xde\xbc\x9a\x03\x00foo\x03\x00ba") }
423
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode(packlen + "\x68\x34\x12\x78\x56\x34\x12\xf0\xde\xbc\x9a\x03\x00fo") }
424
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode(packlen + "\x68\x34\x12\x78\x56\x34\x12\xf0\xde\xbc") }
425
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode(packlen + "\x68\x34\x12\x78\x56\x34\x12\xf0") }
426
+
427
+ # Decode expect string with trailing garbage
428
+ assert_nothing_raised do
429
+ ta2 = RStyx::Message::StyxMessage.decode(expect + "trailing garbage")
430
+ end
431
+ assert(ta2.class == RStyx::Message::Tattach)
432
+ assert(ta2.length == len)
433
+ assert(ta2.mtype == RStyx::Message::StyxMessage::TATTACH)
434
+ assert(ta2.tag == 0x1234)
435
+ assert(ta2.fid == 0x12345678)
436
+ assert(ta2.afid == 0x9abcdef0)
437
+ assert(ta2.uname == "foo")
438
+ assert(ta2.aname == "bar")
439
+ end
440
+
441
+ ##
442
+ # Test the Rattach class.
443
+ #
444
+ def test_rattach
445
+ ra = RStyx::Message::Rattach.new(RStyx::Message::Qid.new(0x01, 0xdeadbeef, 0xfeedfacec0ffeeee))
446
+ bytes = ra.to_bytes(0x1234)
447
+ expect = "\x69\x34\x12\x01\xef\xbe\xad\xde\xee\xee\xff\xc0\xce\xfa\xed\xfe"
448
+ len = expect.length + 4
449
+ packlen = [len].pack("V")
450
+ expect = packlen + expect
451
+ assert(expect == bytes)
452
+ ra2 = RStyx::Message::StyxMessage.decode(expect)
453
+ assert(ra2.class == RStyx::Message::Rattach)
454
+ assert(ra2.length == len)
455
+ assert(ra2.mtype == RStyx::Message::StyxMessage::RATTACH)
456
+ assert(ra2.tag == 0x1234)
457
+ assert(ra2.qid.qtype == 0x01)
458
+ assert(ra2.qid.version == 0xdeadbeef)
459
+ assert(ra2.qid.path == 0xfeedfacec0ffeeee)
460
+
461
+ # Try to decode short strings
462
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode(packlen + "\x69\x34\x12\x01\xef\xbe\xad\xde\xee\xee\xff\xc0\xce\xfa\xed") }
463
+
464
+ # Decode with trailing garbage
465
+ assert_nothing_raised do
466
+ ra2 = RStyx::Message::StyxMessage.decode(expect + "trailing garbage")
467
+ end
468
+ assert(ra2.class == RStyx::Message::Rattach)
469
+ assert(ra2.length == len)
470
+ assert(ra2.mtype == RStyx::Message::StyxMessage::RATTACH)
471
+ assert(ra2.tag == 0x1234)
472
+ assert(ra2.qid.qtype == 0x01)
473
+ assert(ra2.qid.version == 0xdeadbeef)
474
+ assert(ra2.qid.path == 0xfeedfacec0ffeeee)
475
+ end
476
+
477
+ ##
478
+ # Test the Twalk class.
479
+ #
480
+ def test_twalk
481
+ tw = RStyx::Message::Twalk.new(0x12345678, 0x9abcdef0,
482
+ "foo/bar/baz/quux/blargle")
483
+ bytes = tw.to_bytes(0x1234)
484
+ expect = "\x6e\x34\x12\x78\x56\x34\x12\xf0\xde\xbc\x9a\x05\x00\03\x00foo\x03\x00bar\x03\x00baz\x04\x00quux\x07\x00blargle"
485
+ len = expect.length + 4
486
+ packlen = [len].pack("V")
487
+ expect = packlen + expect
488
+ assert(expect == bytes)
489
+ tw2 = RStyx::Message::StyxMessage.decode(expect)
490
+ assert(tw2.class == RStyx::Message::Twalk)
491
+ assert(tw2.length == len)
492
+ assert(tw2.mtype == RStyx::Message::StyxMessage::TWALK)
493
+ assert(tw2.tag == 0x1234)
494
+ assert(tw2.fid == 0x12345678)
495
+ assert(tw2.newfid == 0x9abcdef0)
496
+ assert(tw2.path = "foo/bar/baz/quux/blargle")
497
+
498
+ # Test a long path
499
+ assert_raise(RStyx::StyxException) do
500
+ RStyx::Message::Twalk.new(0x12345678, 0x9abcdef0,
501
+ "1/2/3/4/5/6/7/8/9/10/11/12/13/14/15/16/17")
502
+ end
503
+
504
+ # Test a path not quite so long
505
+ assert_nothing_raised(RStyx::StyxException) do
506
+ RStyx::Message::Twalk.new(0x12345678, 0x9abcdef0,
507
+ "1/2/3/4/5/6/7/8/9/10/11/12/13/14/15/16")
508
+ end
509
+
510
+ # Test short strings
511
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode(packlen + "\x6e\x34\x12\x78\x56\x34\x12\xf0\xde\xbc\x9a\x05\x00\03\x00foo\x03\x00bar\x03\x00baz\x04\x00quux") }
512
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode(packlen + "\x6e\x34\x12\x78\x56\x34\x12\xf0\xde\xbc\x9a") }
513
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode(packlen + "\x6e\x34\x12\x78\x56\x34\x12\xf0\xde") }
514
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode(packlen + "\x6e\x34\x12\x78\x56\x34\x12\xf0") }
515
+
516
+ # trailing garbage test
517
+ assert_nothing_raised do
518
+ tw2 = RStyx::Message::StyxMessage.decode(expect + "trailing garbage")
519
+ end
520
+ assert(tw2.class == RStyx::Message::Twalk)
521
+ assert(tw2.length == len)
522
+ assert(tw2.mtype == RStyx::Message::StyxMessage::TWALK)
523
+ assert(tw2.tag == 0x1234)
524
+ assert(tw2.fid == 0x12345678)
525
+ assert(tw2.newfid == 0x9abcdef0)
526
+ assert(tw2.path = "foo/bar/baz/quux/blargle")
527
+ end
528
+
529
+ ##
530
+ # Test the Rwalk class.
531
+ #
532
+ def test_rwalk
533
+ qidlist = [
534
+ RStyx::Message::Qid.new(0x01,0xdeadbeef,0xfeedfacec0ffeeee),
535
+ RStyx::Message::Qid.new(0x02,0x12345678,0xfedcba9876543210),
536
+ RStyx::Message::Qid.new(0x03,0x87654321,0x0123456789abcdef)
537
+ ]
538
+ rw = RStyx::Message::Rwalk.new(qidlist)
539
+ bytes = rw.to_bytes(0x1234)
540
+ expect = "\x6f\x34\x12\x03\x00\x01\xef\xbe\xad\xde\xee\xee\xff\xc0\xce\xfa\xed\xfe\x02\x78\x56\x34\x12\x10\x32\x54\x76\x98\xba\xdc\xfe\x03\x21\x43\x65\x87\xef\xcd\xab\x89\x67\x45\x23\x01"
541
+ len = expect.length + 4
542
+ packlen = [len].pack("V")
543
+ expect = packlen + expect
544
+ assert(expect == bytes)
545
+ rw2 = RStyx::Message::StyxMessage.decode(expect)
546
+ assert(rw2.class == RStyx::Message::Rwalk)
547
+ assert(rw2.length == len)
548
+ assert(rw2.mtype == RStyx::Message::StyxMessage::RWALK)
549
+ assert(rw2.tag == 0x1234)
550
+ assert(rw2.qids.length == 3)
551
+ qid = rw2.qids[0]
552
+ assert(qid.qtype == 0x01)
553
+ assert(qid.version == 0xdeadbeef)
554
+ assert(qid.path == 0xfeedfacec0ffeeee)
555
+ qid = rw2.qids[1]
556
+ assert(qid.qtype == 0x02)
557
+ assert(qid.version == 0x12345678)
558
+ assert(qid.path == 0xfedcba9876543210)
559
+ qid = rw2.qids[2]
560
+ assert(qid.qtype == 0x03)
561
+ assert(qid.version == 0x87654321)
562
+ assert(qid.path == 0x0123456789abcdef)
563
+
564
+ # Try decoding short strings
565
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode(packlen + "\x6f\x34\x12\x03\x00\x01\xef\xbe\xad\xde\xee\xee\xff\xc0\xce\xfa\xed\xfe\x02\x78\x56\x34\x12\x10\x32\x54\x76\x98\xba\xdc\xfe\x03\x21\x43\x65\x87") }
566
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode(packlen + "\x6f\x34\x12\x03\x00") }
567
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode(packlen + "\x6f\x34\x12\x03") }
568
+
569
+ # Trailing garbage
570
+ assert_nothing_raised do
571
+ rw2 = RStyx::Message::StyxMessage.decode(expect + "trailing garbage")
572
+ end
573
+ assert(rw2.class == RStyx::Message::Rwalk)
574
+ assert(rw2.length == len)
575
+ assert(rw2.mtype == RStyx::Message::StyxMessage::RWALK)
576
+ assert(rw2.tag == 0x1234)
577
+ assert(rw2.qids.length == 3)
578
+ qid = rw2.qids[0]
579
+ assert(qid.qtype == 0x01)
580
+ assert(qid.version == 0xdeadbeef)
581
+ assert(qid.path == 0xfeedfacec0ffeeee)
582
+ qid = rw2.qids[1]
583
+ assert(qid.qtype == 0x02)
584
+ assert(qid.version == 0x12345678)
585
+ assert(qid.path == 0xfedcba9876543210)
586
+ qid = rw2.qids[2]
587
+ assert(qid.qtype == 0x03)
588
+ assert(qid.version == 0x87654321)
589
+ assert(qid.path == 0x0123456789abcdef)
590
+ end
591
+
592
+ ##
593
+ # Test the Topen class.
594
+ #
595
+ def test_topen
596
+ # make sure OTRUNC can only be used with mode OWRITE or ORDWR
597
+ assert_raise(RStyx::StyxException) do
598
+ to = RStyx::Message::Topen.new(0x12345678,
599
+ RStyx::Message::Topen::OREAD |
600
+ RStyx::Message::Topen::OTRUNC)
601
+ end
602
+
603
+ assert_raise(RStyx::StyxException) do
604
+ to = RStyx::Message::Topen.new(0x12345678,
605
+ RStyx::Message::Topen::OEXEC |
606
+ RStyx::Message::Topen::OTRUNC)
607
+ end
608
+
609
+ assert_raise(RStyx::StyxException) do
610
+ to = RStyx::Message::Topen.new(0x12345678, 4)
611
+ end
612
+
613
+ assert_raise(RStyx::StyxException) do
614
+ to = RStyx::Message::Topen.new(0x12345678, 0xff)
615
+ end
616
+
617
+ to = RStyx::Message::Topen.new(0x12345678,
618
+ RStyx::Message::Topen::OWRITE |
619
+ RStyx::Message::Topen::OTRUNC |
620
+ RStyx::Message::Topen::ORCLOSE)
621
+ bytes = to.to_bytes(0x1234)
622
+ expect = "\x70\x34\x12\x78\x56\x34\x12\x51"
623
+ len = expect.length + 4
624
+ packlen = [len].pack("V")
625
+ expect = packlen + expect
626
+ assert(expect == bytes)
627
+
628
+ to2 = RStyx::Message::StyxMessage.decode(expect)
629
+ assert(to2.class == RStyx::Message::Topen)
630
+ assert(to2.length == len)
631
+ assert(to2.mtype == RStyx::Message::StyxMessage::TOPEN)
632
+ assert(to2.tag == 0x1234)
633
+ assert(to2.mode == 0x51)
634
+ assert(to2.fid == 0x12345678)
635
+
636
+ # Try decoding short strings
637
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode(packlen + "\x70\x34\x12\x78\x56\x34\x12") }
638
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode(packlen + "\x70\x34\x12\x78\x56") }
639
+
640
+ # Try decoding invalid values
641
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode(packlen + "\x70\x34\x12\x78\x56\x34\x12\x50") }
642
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode(packlen + "\x70\x34\x12\x78\x56\x34\x12\x53") }
643
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode(packlen + "\x70\x34\x12\x78\x56\x34\x12\xff") }
644
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode(packlen + "\x70\x34\x12\x78\x56\x34\x12\x04") }
645
+
646
+ # Try decoding with trailing garbage
647
+ assert_nothing_raised do
648
+ to2 = RStyx::Message::StyxMessage.decode(expect + "trailing garbage")
649
+ end
650
+ assert(to2.class == RStyx::Message::Topen)
651
+ assert(to2.length == len)
652
+ assert(to2.mtype == RStyx::Message::StyxMessage::TOPEN)
653
+ assert(to2.tag == 0x1234)
654
+ assert(to2.mode == 0x51)
655
+ assert(to2.fid == 0x12345678)
656
+ end
657
+
658
+ ##
659
+ # Test the Ropen class.
660
+ #
661
+ def test_ropen
662
+ ro = RStyx::Message::Ropen.new(RStyx::Message::Qid.new(0x01,0xdeadbeef,0xfeedfacec0ffeeee), 0xfedcba98)
663
+ bytes = ro.to_bytes(0x1234)
664
+ expect = "\x71\x34\x12\x01\xef\xbe\xad\xde\xee\xee\xff\xc0\xce\xfa\xed\xfe\x98\xba\xdc\xfe"
665
+ len = expect.length + 4
666
+ packlen = [len].pack("V")
667
+ expect = packlen + expect
668
+ assert(expect == bytes)
669
+
670
+ # Decode expect
671
+ ro2 = RStyx::Message::StyxMessage.decode(expect)
672
+ assert(ro2.class == RStyx::Message::Ropen)
673
+ assert(ro2.length == len)
674
+ assert(ro2.mtype == RStyx::Message::StyxMessage::ROPEN)
675
+ assert(ro2.tag == 0x1234)
676
+ assert(ro2.qid.qtype == 0x01)
677
+ assert(ro2.qid.version == 0xdeadbeef)
678
+ assert(ro2.qid.path == 0xfeedfacec0ffeeee)
679
+ assert(ro2.iounit == 0xfedcba98)
680
+
681
+ # Try decoding short strings
682
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode(packlen + "\x71\x34\x12\x01\xef\xbe\xad\xde\xee\xee\xff\xc0\xce\xfa\xed\xfe\x98\xba") }
683
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode(packlen + "\x71\x34\x12\x01\xef\xbe\xad\xde\xee\xee\xff\xc0\xce\xfa\xed") }
684
+
685
+ # Decode with trailing garbage
686
+ assert_nothing_raised do
687
+ ro2 = RStyx::Message::StyxMessage.decode(expect + "trailing garbage")
688
+ end
689
+ assert(ro2.class == RStyx::Message::Ropen)
690
+ assert(ro2.length == len)
691
+ assert(ro2.mtype == RStyx::Message::StyxMessage::ROPEN)
692
+ assert(ro2.tag == 0x1234)
693
+ assert(ro2.qid.qtype == 0x01)
694
+ assert(ro2.qid.version == 0xdeadbeef)
695
+ assert(ro2.qid.path == 0xfeedfacec0ffeeee)
696
+ assert(ro2.iounit == 0xfedcba98)
697
+ end
698
+
699
+ ##
700
+ # Test the Tcreate class
701
+ #
702
+ def test_tcreate
703
+ tc = RStyx::Message::Tcreate.new(0x12345678, "foo",
704
+ RStyx::Message::Topen::OWRITE |
705
+ RStyx::Message::Topen::OTRUNC |
706
+ RStyx::Message::Topen::ORCLOSE,
707
+ 0xfedcba98)
708
+ bytes = tc.to_bytes(0x1234)
709
+ expect = "\x72\x34\x12\x78\x56\x34\x12\x03\x00foo\x98\xba\xdc\xfe\x51"
710
+ len = expect.length + 4
711
+ packlen = [len].pack("V")
712
+ expect = packlen + expect
713
+ assert(expect == bytes)
714
+
715
+ # Decode expect
716
+ tc2 = RStyx::Message::StyxMessage.decode(expect)
717
+ assert(tc2.class == RStyx::Message::Tcreate)
718
+ assert(tc2.length == len)
719
+ assert(tc2.mtype == RStyx::Message::StyxMessage::TCREATE)
720
+ assert(tc2.tag == 0x1234)
721
+ assert(tc2.fid == 0x12345678)
722
+ assert(tc2.name == "foo")
723
+ assert(tc2.perm == 0xfedcba98)
724
+ assert(tc2.mode == 0x51)
725
+
726
+ # Try decoding short strings
727
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode(packlen + "\x72\x34\x12\x78\x56\x34\x12\x03\x00foo\x98\xba\xdc\xfe") }
728
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode(packlen + "\x72\x34\x12\x78\x56\x34\x12\x03\x00foo\x98\xba") }
729
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode(packlen + "\x72\x34\x12\x78\x56\x34\x12\x03\x00f") }
730
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode(packlen + "\x72\x34\x12\x78\x56\x34") }
731
+ # Decode with trailing garbage
732
+ tc2 = nil
733
+ assert_nothing_raised do
734
+ tc2 = RStyx::Message::StyxMessage.decode(expect + "trailing garbage")
735
+ end
736
+ assert(tc2.class == RStyx::Message::Tcreate)
737
+ assert(tc2.length == len)
738
+ assert(tc2.mtype == RStyx::Message::StyxMessage::TCREATE)
739
+ assert(tc2.tag == 0x1234)
740
+ assert(tc2.fid == 0x12345678)
741
+ assert(tc2.name == "foo")
742
+ assert(tc2.perm == 0xfedcba98)
743
+ assert(tc2.mode == 0x51)
744
+ end
745
+
746
+ ##
747
+ # Test the Rcreate class.
748
+ #
749
+ def test_rcreate
750
+ rc = RStyx::Message::Rcreate.new(RStyx::Message::Qid.new(0x01,0xdeadbeef,0xfeedfacec0ffeeee), 0xfedcba98)
751
+ bytes = rc.to_bytes(0x1234)
752
+ expect = "\x73\x34\x12\x01\xef\xbe\xad\xde\xee\xee\xff\xc0\xce\xfa\xed\xfe\x98\xba\xdc\xfe"
753
+ len = expect.length + 4
754
+ packlen = [len].pack("V")
755
+ expect = packlen + expect
756
+ assert(expect == bytes)
757
+
758
+ # Decode expect
759
+ rc2 = RStyx::Message::StyxMessage.decode(expect)
760
+ assert(rc2.class == RStyx::Message::Rcreate)
761
+ assert(rc2.length == len)
762
+ assert(rc2.mtype == RStyx::Message::StyxMessage::RCREATE)
763
+ assert(rc2.tag == 0x1234)
764
+ assert(rc2.qid.qtype == 0x01)
765
+ assert(rc2.qid.version == 0xdeadbeef)
766
+ assert(rc2.qid.path == 0xfeedfacec0ffeeee)
767
+ assert(rc2.iounit == 0xfedcba98)
768
+
769
+ # Try decoding short strings
770
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode(packlen + "\x73\x34\x12\x01\xef\xbe\xad\xde\xee\xee\xff\xc0\xce\xfa\xed\xfe\x98\xba") }
771
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode(packlen + "\x73\x34\x12\x01\xef\xbe\xad\xde\xee\xee\xff\xc0\xce\xfa\xed") }
772
+
773
+ # Decode with trailing garbage
774
+ rc2 = nil
775
+ assert_nothing_raised do
776
+ rc2 = RStyx::Message::StyxMessage.decode(expect + "trailing garbage")
777
+ end
778
+ assert(rc2.class == RStyx::Message::Rcreate)
779
+ assert(rc2.length == len)
780
+ assert(rc2.mtype == RStyx::Message::StyxMessage::RCREATE)
781
+ assert(rc2.tag == 0x1234)
782
+ assert(rc2.qid.qtype == 0x01)
783
+ assert(rc2.qid.version == 0xdeadbeef)
784
+ assert(rc2.qid.path == 0xfeedfacec0ffeeee)
785
+ assert(rc2.iounit == 0xfedcba98)
786
+ end
787
+
788
+ ##
789
+ # Test the Tread class.
790
+ #
791
+ def test_tread
792
+ tr = RStyx::Message::Tread.new(0xdeadbeef, 0xfeedfacec0ffeeee, 0xcafebabe)
793
+ bytes = tr.to_bytes(0x1234)
794
+ expect = "\x74\x34\x12\xef\xbe\xad\xde\xee\xee\xff\xc0\xce\xfa\xed\xfe\xbe\xba\xfe\xca"
795
+ len = expect.length + 4
796
+ packlen = [len].pack("V")
797
+ expect = packlen + expect
798
+ assert(expect == bytes)
799
+
800
+ # Decode expect
801
+ tr2 = RStyx::Message::StyxMessage.decode(expect)
802
+ assert(tr2.class == RStyx::Message::Tread)
803
+ assert(tr2.length == len)
804
+ assert(tr2.mtype == RStyx::Message::StyxMessage::TREAD)
805
+ assert(tr2.tag == 0x1234)
806
+ assert(tr2.fid == 0xdeadbeef)
807
+ assert(tr2.offset == 0xfeedfacec0ffeeee)
808
+ assert(tr2.count == 0xcafebabe)
809
+
810
+ # Try decoding short strings
811
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode(packlen + "\x74\x34\x12\xef\xbe\xad\xde\xee\xee\xff\xc0\xce\xfa\xed\xfe\xbe\xba\xfe") }
812
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode(packlen + "\x74\x34\x12\xef\xbe\xad\xde\xee\xee\xff\xc0\xce\xfa\xed") }
813
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode(packlen + "\x74\x34\x12\xef\xbe\xad\xde\xee\xee\xff\xc0\xce") }
814
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode(packlen + "\x74\x34\x12\xef\xbe\xad\xde\xee") }
815
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode(packlen + "\x74\x34\x12\xef\xbe\xad\xde\xee") }
816
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode(packlen + "\x74\x34\x12\xef\xbe\xad") }
817
+
818
+ # Decode with trailing garbage
819
+ tr2 = nil
820
+ assert_nothing_raised do
821
+ tr2 = RStyx::Message::StyxMessage.decode(expect + "trailing garbage")
822
+ end
823
+ assert(tr2.class == RStyx::Message::Tread)
824
+ assert(tr2.length == len)
825
+ assert(tr2.mtype == RStyx::Message::StyxMessage::TREAD)
826
+ assert(tr2.tag == 0x1234)
827
+ assert(tr2.fid == 0xdeadbeef)
828
+ assert(tr2.offset == 0xfeedfacec0ffeeee)
829
+ assert(tr2.count == 0xcafebabe)
830
+ end
831
+
832
+ ##
833
+ # test cases for Rread class
834
+ #
835
+ def test_rread
836
+ data = "alpha bravo charlie delta echo foxtrot golf hotel india juliet kilo lima mama nancy oscar papa quebec romeo sierra tango uniform victor whiskey xray yankee zulu"
837
+ rr = RStyx::Message::Rread.new(data)
838
+ bytes = rr.to_bytes(0x1234)
839
+ expect = "\x75\x34\x12\xa0\x00\x00\x00" + data
840
+ len = expect.length + 4
841
+ packlen = [len].pack("V")
842
+ expect = packlen + expect
843
+ assert(expect == bytes)
844
+
845
+ # Decode expect
846
+ rr2 = RStyx::Message::StyxMessage.decode(expect)
847
+ assert(rr2.class == RStyx::Message::Rread)
848
+ assert(rr2.length == len)
849
+ assert(rr2.mtype == RStyx::Message::StyxMessage::RREAD)
850
+ assert(rr2.tag == 0x1234)
851
+ assert(rr2.count == data.length)
852
+ assert(rr2.data == data)
853
+
854
+ # Try decoding short strings
855
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode(expect.chop) }
856
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode(packlen + "\x75\x34\x12\xa0\x00\x00") }
857
+ # Try decoding empty
858
+ assert_nothing_raised { RStyx::Message::StyxMessage.decode("\x0b\x00\x00\x00\x75\x34\x12\x00\x00\x00\x00") }
859
+
860
+ # Decode with trailing garbage
861
+ rr2 = nil
862
+ assert_nothing_raised do
863
+ rr2 = RStyx::Message::StyxMessage.decode(expect + "trailing garbage")
864
+ end
865
+ assert(rr2.class == RStyx::Message::Rread)
866
+ assert(rr2.length == len)
867
+ assert(rr2.mtype == RStyx::Message::StyxMessage::RREAD)
868
+ assert(rr2.tag == 0x1234)
869
+ assert(rr2.count == data.length)
870
+ assert(rr2.data == data)
871
+ end
872
+
873
+ ##
874
+ # Tests for Twrite class
875
+ #
876
+ def test_twrite
877
+ data = "alpha bravo charlie delta echo foxtrot golf hotel india juliet kilo lima mama nancy oscar papa quebec romeo sierra tango uniform victor whiskey xray yankee zulu"
878
+ tw = RStyx::Message::Twrite.new(0x12345678, 0xfeedfacec0ffeeee, data)
879
+ bytes = tw.to_bytes(0x1234)
880
+ expect = "\x76\x34\x12\x78\x56\x34\x12\xee\xee\xff\xc0\xce\xfa\xed\xfe\xa0\x00\x00\x00" + data
881
+ len = expect.length + 4
882
+ packlen = [len].pack("V")
883
+ expect = packlen + expect
884
+ assert(expect == bytes)
885
+
886
+ # Decode expect
887
+ tw2 = RStyx::Message::StyxMessage.decode(expect)
888
+ assert(tw2.class == RStyx::Message::Twrite)
889
+ assert(tw2.length == len)
890
+ assert(tw2.mtype == RStyx::Message::StyxMessage::TWRITE)
891
+ assert(tw2.tag == 0x1234)
892
+ assert(tw2.fid == 0x12345678)
893
+ assert(tw2.offset == 0xfeedfacec0ffeeee)
894
+ assert(tw2.count == data.length)
895
+ assert(tw2.data == data)
896
+ # Try decoding short strings
897
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode(expect.chop) }
898
+
899
+ # Try decoding empty
900
+ assert_nothing_raised { RStyx::Message::StyxMessage.decode("\x17\x00\x00\x00\x75\x34\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00") }
901
+ # Decode with trailing garbage
902
+ tw2 = nil
903
+ assert_nothing_raised do
904
+ tw2 = RStyx::Message::StyxMessage.decode(expect + "trailing garbage")
905
+ end
906
+ assert(tw2.class == RStyx::Message::Twrite)
907
+ assert(tw2.length == len)
908
+ assert(tw2.mtype == RStyx::Message::StyxMessage::TWRITE)
909
+ assert(tw2.tag == 0x1234)
910
+ assert(tw2.fid == 0x12345678)
911
+ assert(tw2.offset == 0xfeedfacec0ffeeee)
912
+ assert(tw2.count == data.length)
913
+ assert(tw2.data == data)
914
+ end
915
+
916
+ ##
917
+ # Tests for Rwrite class
918
+ def test_rwrite
919
+ rw = RStyx::Message::Rwrite.new(0x12345678)
920
+ bytes = rw.to_bytes(0x1234)
921
+ expect = "\x77\x34\x12\x78\x56\x34\x12"
922
+ len = expect.length + 4
923
+ packlen = [len].pack("V")
924
+ expect = packlen + expect
925
+ assert(expect == bytes)
926
+
927
+ # decode expect
928
+ rw2 = RStyx::Message::StyxMessage.decode(expect)
929
+ assert(rw2.class == RStyx::Message::Rwrite)
930
+ assert(rw2.length == len)
931
+ assert(rw2.mtype == RStyx::Message::StyxMessage::RWRITE)
932
+ assert(rw2.tag == 0x1234)
933
+ assert(rw2.count == 0x12345678)
934
+
935
+ # Try decoding short strings
936
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode(expect.chop) }
937
+ # Decode with trailing garbage
938
+ rw2 = nil
939
+ assert_nothing_raised do
940
+ rw2 = RStyx::Message::StyxMessage.decode(expect)
941
+ end
942
+ assert(rw2.class == RStyx::Message::Rwrite)
943
+ assert(rw2.length == len)
944
+ assert(rw2.mtype == RStyx::Message::StyxMessage::RWRITE)
945
+ assert(rw2.tag == 0x1234)
946
+ assert(rw2.count == 0x12345678)
947
+ end
948
+
949
+ ##
950
+ # Test the Tclunk class.
951
+ #
952
+ def test_tclunk
953
+ tc = RStyx::Message::Tclunk.new(0xdeadbeef)
954
+ bytes = tc.to_bytes(0x1234)
955
+ expect = "\x78\x34\x12\xef\xbe\xad\xde"
956
+ len = expect.length + 4
957
+ packlen = [len].pack("V")
958
+ expect = packlen + expect
959
+ assert(expect == bytes)
960
+
961
+ # decode expect
962
+ tc2 = RStyx::Message::StyxMessage.decode(expect)
963
+ assert(tc2.class == RStyx::Message::Tclunk)
964
+ assert(tc2.length == len)
965
+ assert(tc2.mtype == RStyx::Message::StyxMessage::TCLUNK)
966
+ assert(tc2.tag == 0x1234)
967
+ assert(tc2.fid == 0xdeadbeef)
968
+
969
+ # try decoding short strings
970
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode(packlen + "\x78\x34\x12\xef\xbe\xad") }
971
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode(packlen + "\x78\x34\x12") }
972
+
973
+ # decode with trailing garbage
974
+ tc2 = nil
975
+ assert_nothing_raised do
976
+ tc2 = RStyx::Message::StyxMessage.decode(expect + "trailing garbage")
977
+ end
978
+ assert(tc2.class == RStyx::Message::Tclunk)
979
+ assert(tc2.length == len)
980
+ assert(tc2.mtype == RStyx::Message::StyxMessage::TCLUNK)
981
+ assert(tc2.tag == 0x1234)
982
+ assert(tc2.fid == 0xdeadbeef)
983
+ end
984
+
985
+ ##
986
+ # Test the Rclunk class.
987
+ #
988
+ def test_rclunk
989
+ rc = RStyx::Message::Rclunk.new
990
+ bytes = rc.to_bytes(0x1234)
991
+ expect = "\x79\x34\x12"
992
+ len = expect.length + 4
993
+ packlen = [len].pack("V")
994
+ expect = packlen + expect
995
+ assert(expect == bytes)
996
+
997
+ # decode expect
998
+ rc2 = RStyx::Message::StyxMessage.decode(expect)
999
+ assert(rc2.class == RStyx::Message::Rclunk)
1000
+ assert(rc2.length == len)
1001
+ assert(rc2.mtype == RStyx::Message::StyxMessage::RCLUNK)
1002
+ assert(rc2.tag == 0x1234)
1003
+
1004
+ # try decoding short strings
1005
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode(packlen + "\x79\x34") }
1006
+
1007
+ # decode with trailing garbage
1008
+ rc2 = nil
1009
+ assert_nothing_raised do
1010
+ rc2 = RStyx::Message::StyxMessage.decode(expect + "trailing garbage")
1011
+ end
1012
+ assert(rc2.class == RStyx::Message::Rclunk)
1013
+ assert(rc2.length == len)
1014
+ assert(rc2.mtype == RStyx::Message::StyxMessage::RCLUNK)
1015
+ assert(rc2.tag == 0x1234)
1016
+ end
1017
+
1018
+ ##
1019
+ # Test the Tremove class.
1020
+ #
1021
+ def test_tremove
1022
+ tr = RStyx::Message::Tremove.new(0xdeadbeef)
1023
+ bytes = tr.to_bytes(0x1234)
1024
+ expect = "\x7a\x34\x12\xef\xbe\xad\xde"
1025
+ len = expect.length + 4
1026
+ packlen = [len].pack("V")
1027
+ expect = packlen + expect
1028
+ assert(expect == bytes)
1029
+
1030
+ # decode expect
1031
+ tr2 = RStyx::Message::StyxMessage.decode(expect)
1032
+ assert(tr2.class == RStyx::Message::Tremove)
1033
+ assert(tr2.length == len)
1034
+ assert(tr2.mtype == RStyx::Message::StyxMessage::TREMOVE)
1035
+ assert(tr2.tag == 0x1234)
1036
+ assert(tr2.fid == 0xdeadbeef)
1037
+
1038
+ # try decoding short strings
1039
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode(packlen + "\x7a\x34\x12\xef\xbe\xad") }
1040
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode(packlen + "\x7a\x34\x12") }
1041
+
1042
+ # decode with trailing garbage
1043
+ tr2 = nil
1044
+ assert_nothing_raised do
1045
+ tr2 = RStyx::Message::StyxMessage.decode(expect + "trailing garbage")
1046
+ end
1047
+ assert(tr2.class == RStyx::Message::Tremove)
1048
+ assert(tr2.length == len)
1049
+ assert(tr2.mtype == RStyx::Message::StyxMessage::TREMOVE)
1050
+ assert(tr2.tag == 0x1234)
1051
+ assert(tr2.fid == 0xdeadbeef)
1052
+ end
1053
+
1054
+ ##
1055
+ # Test the Rremove class.
1056
+ #
1057
+ def test_rremove
1058
+ rr = RStyx::Message::Rremove.new
1059
+ bytes = rr.to_bytes(0x1234)
1060
+ expect = "\x7b\x34\x12"
1061
+ len = expect.length + 4
1062
+ packlen = [len].pack("V")
1063
+ expect = packlen + expect
1064
+ assert(expect == bytes)
1065
+
1066
+ # decode expect
1067
+ rr2 = RStyx::Message::StyxMessage.decode(expect)
1068
+ assert(rr2.class == RStyx::Message::Rremove)
1069
+ assert(rr2.length == len)
1070
+ assert(rr2.mtype == RStyx::Message::StyxMessage::RREMOVE)
1071
+ assert(rr2.tag == 0x1234)
1072
+
1073
+ # try decoding short strings
1074
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode(packlen + "\x7b\x34") }
1075
+
1076
+ # decode with trailing garbage
1077
+ rr2 = nil
1078
+ assert_nothing_raised do
1079
+ rr2 = RStyx::Message::StyxMessage.decode(expect + "trailing garbage")
1080
+ end
1081
+ assert(rr2.class == RStyx::Message::Rremove)
1082
+ assert(rr2.length == len)
1083
+ assert(rr2.mtype == RStyx::Message::StyxMessage::RREMOVE)
1084
+ assert(rr2.tag == 0x1234)
1085
+ end
1086
+
1087
+ ##
1088
+ # Test the Tstat class.
1089
+ #
1090
+ def test_tstat
1091
+ ts = RStyx::Message::Tstat.new(0xdeadbeef)
1092
+ bytes = ts.to_bytes(0x1234)
1093
+ expect = "\x7c\x34\x12\xef\xbe\xad\xde"
1094
+ len = expect.length + 4
1095
+ packlen = [len].pack("V")
1096
+ expect = packlen + expect
1097
+ assert(expect == bytes)
1098
+
1099
+ # decode expect
1100
+ ts2 = RStyx::Message::StyxMessage.decode(expect)
1101
+ assert(ts2.class == RStyx::Message::Tstat)
1102
+ assert(ts2.length == len)
1103
+ assert(ts2.mtype == RStyx::Message::StyxMessage::TSTAT)
1104
+ assert(ts2.tag == 0x1234)
1105
+ assert(ts2.fid == 0xdeadbeef)
1106
+
1107
+ # try decoding short strings
1108
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode(packlen + "\x7c\x34\x12\xef\xbe\xad") }
1109
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode(packlen + "\x7c\x34\x12") }
1110
+
1111
+ # decode with trailing garbage
1112
+ ts2 = nil
1113
+ assert_nothing_raised do
1114
+ ts2 = RStyx::Message::StyxMessage.decode(expect + "trailing garbage")
1115
+ end
1116
+ assert(ts2.class == RStyx::Message::Tstat)
1117
+ assert(ts2.length == len)
1118
+ assert(ts2.mtype == RStyx::Message::StyxMessage::TSTAT)
1119
+ assert(ts2.tag == 0x1234)
1120
+ assert(ts2.fid == 0xdeadbeef)
1121
+ end
1122
+
1123
+ ##
1124
+ # Test the Rstat class.
1125
+ #
1126
+ def test_rstat
1127
+ de = RStyx::Message::DirEntry.new
1128
+ de.dtype = 0x1234
1129
+ de.dev = 0x567890ab
1130
+ de.qid = RStyx::Message::Qid.new(0x01, 0xdeadbeef,0xfeedfacec0ffeeee)
1131
+ de.mode = 0x9abcdef0
1132
+ de.atime = 0xdeadbeef
1133
+ de.mtime = 0xcafebabe
1134
+ de.length = 0xfedcba9876543210
1135
+ de.name = "foo"
1136
+ de.uid = "bar"
1137
+ de.gid = "baz"
1138
+ de.muid = "quux"
1139
+ rs = RStyx::Message::Rstat.new(de)
1140
+ bytes = rs.to_bytes(0x1234)
1141
+ expect = "\x7d\x34\x12\x3c\x00\x34\x12\xab\x90\x78\x56\x01\xef\xbe\xad\xde\xee\xee\xff\xc0\xce\xfa\xed\xfe\xf0\xde\xbc\x9a\xef\xbe\xad\xde\xbe\xba\xfe\xca\x10\x32\x54\x76\x98\xba\xdc\xfe\x03\x00foo\x03\x00bar\x03\x00baz\x04\x00quux"
1142
+ len = expect.length + 4
1143
+ packlen = [len].pack("V")
1144
+ expect = packlen + expect
1145
+ assert(expect == bytes)
1146
+
1147
+ # decode expect
1148
+ rs2 = RStyx::Message::StyxMessage.decode(expect)
1149
+ assert(rs2.class == RStyx::Message::Rstat)
1150
+ assert(rs2.length == len)
1151
+ assert(rs2.mtype == RStyx::Message::StyxMessage::RSTAT)
1152
+ assert(rs2.tag == 0x1234)
1153
+ assert(rs2.stat.dtype == 0x1234)
1154
+ assert(rs2.stat.dev == 0x567890ab)
1155
+ assert(rs2.stat.qid.qtype == 0x01)
1156
+ assert(rs2.stat.qid.version == 0xdeadbeef)
1157
+ assert(rs2.stat.qid.path == 0xfeedfacec0ffeeee)
1158
+ assert(rs2.stat.mode == 0x9abcdef0)
1159
+ assert(rs2.stat.atime == 0xdeadbeef)
1160
+ assert(rs2.stat.mtime == 0xcafebabe)
1161
+ assert(rs2.stat.length == 0xfedcba9876543210)
1162
+ assert(rs2.stat.name == "foo")
1163
+ assert(rs2.stat.uid == "bar")
1164
+ assert(rs2.stat.gid == "baz")
1165
+ assert(rs2.stat.muid == "quux")
1166
+
1167
+ # try decoding short strings
1168
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode(expect.chop) }
1169
+
1170
+ # Trailing garbage test
1171
+ rs2 = nil
1172
+ assert_nothing_raised { rs2 = RStyx::Message::StyxMessage.decode(expect + "trailing garbage") }
1173
+ assert(rs2.class == RStyx::Message::Rstat)
1174
+ assert(rs2.length == len)
1175
+ assert(rs2.mtype == RStyx::Message::StyxMessage::RSTAT)
1176
+ assert(rs2.tag == 0x1234)
1177
+ assert(rs2.stat.dtype == 0x1234)
1178
+ assert(rs2.stat.dev == 0x567890ab)
1179
+ assert(rs2.stat.qid.qtype == 0x01)
1180
+ assert(rs2.stat.qid.version == 0xdeadbeef)
1181
+ assert(rs2.stat.qid.path == 0xfeedfacec0ffeeee)
1182
+ assert(rs2.stat.mode == 0x9abcdef0)
1183
+ assert(rs2.stat.atime == 0xdeadbeef)
1184
+ assert(rs2.stat.mtime == 0xcafebabe)
1185
+ assert(rs2.stat.length == 0xfedcba9876543210)
1186
+ assert(rs2.stat.name == "foo")
1187
+ assert(rs2.stat.uid == "bar")
1188
+ assert(rs2.stat.gid == "baz")
1189
+ assert(rs2.stat.muid == "quux")
1190
+ end
1191
+
1192
+ ##
1193
+ # Test the Twstat class.
1194
+ #
1195
+ def test_twstat
1196
+ de = RStyx::Message::DirEntry.new
1197
+ de.dtype = 0x1234
1198
+ de.dev = 0x567890ab
1199
+ de.qid = RStyx::Message::Qid.new(0x01, 0xdeadbeef,0xfeedfacec0ffeeee)
1200
+ de.mode = 0x9abcdef0
1201
+ de.atime = 0xdeadbeef
1202
+ de.mtime = 0xcafebabe
1203
+ de.length = 0xfedcba9876543210
1204
+ de.name = "foo"
1205
+ de.uid = "bar"
1206
+ de.gid = "baz"
1207
+ de.muid = "quux"
1208
+ tw = RStyx::Message::Twstat.new(0x12345678, de)
1209
+ bytes = tw.to_bytes(0x1234)
1210
+ expect = "\x7e\x34\x12\x78\x56\x34\x12\x3c\x00\x34\x12\xab\x90\x78\x56\x01\xef\xbe\xad\xde\xee\xee\xff\xc0\xce\xfa\xed\xfe\xf0\xde\xbc\x9a\xef\xbe\xad\xde\xbe\xba\xfe\xca\x10\x32\x54\x76\x98\xba\xdc\xfe\x03\x00foo\x03\x00bar\x03\x00baz\x04\x00quux"
1211
+ len = expect.length + 4
1212
+ packlen = [len].pack("V")
1213
+ expect = packlen + expect
1214
+ assert(expect == bytes)
1215
+
1216
+ # decode expect
1217
+ tw2 = RStyx::Message::StyxMessage.decode(expect)
1218
+ assert(tw2.class == RStyx::Message::Twstat)
1219
+ assert(tw2.length == len)
1220
+ assert(tw2.mtype == RStyx::Message::StyxMessage::TWSTAT)
1221
+ assert(tw2.tag == 0x1234)
1222
+ assert(tw2.stat.dtype == 0x1234)
1223
+ assert(tw2.stat.dev == 0x567890ab)
1224
+ assert(tw2.stat.qid.qtype == 0x01)
1225
+ assert(tw2.stat.qid.version == 0xdeadbeef)
1226
+ assert(tw2.stat.qid.path == 0xfeedfacec0ffeeee)
1227
+ assert(tw2.stat.mode == 0x9abcdef0)
1228
+ assert(tw2.stat.atime == 0xdeadbeef)
1229
+ assert(tw2.stat.mtime == 0xcafebabe)
1230
+ assert(tw2.stat.length == 0xfedcba9876543210)
1231
+ assert(tw2.stat.name == "foo")
1232
+ assert(tw2.stat.uid == "bar")
1233
+ assert(tw2.stat.gid == "baz")
1234
+ assert(tw2.stat.muid == "quux")
1235
+
1236
+ # try decoding short strings
1237
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode(expect.chop) }
1238
+ # Trailing garbage test
1239
+ tw2 = nil
1240
+ assert_nothing_raised { tw2 = RStyx::Message::StyxMessage.decode(expect + "trailing garbage") }
1241
+ assert(tw2.class == RStyx::Message::Twstat)
1242
+ assert(tw2.length == len)
1243
+ assert(tw2.mtype == RStyx::Message::StyxMessage::TWSTAT)
1244
+ assert(tw2.tag == 0x1234)
1245
+ assert(tw2.stat.dtype == 0x1234)
1246
+ assert(tw2.stat.dev == 0x567890ab)
1247
+ assert(tw2.stat.qid.qtype == 0x01)
1248
+ assert(tw2.stat.qid.version == 0xdeadbeef)
1249
+ assert(tw2.stat.qid.path == 0xfeedfacec0ffeeee)
1250
+ assert(tw2.stat.mode == 0x9abcdef0)
1251
+ assert(tw2.stat.atime == 0xdeadbeef)
1252
+ assert(tw2.stat.mtime == 0xcafebabe)
1253
+ assert(tw2.stat.length == 0xfedcba9876543210)
1254
+ assert(tw2.stat.name == "foo")
1255
+ assert(tw2.stat.uid == "bar")
1256
+ assert(tw2.stat.gid == "baz")
1257
+ assert(tw2.stat.muid == "quux")
1258
+ end
1259
+
1260
+ ##
1261
+ # Test the Rwstat class.
1262
+ #
1263
+ def test_rwstat
1264
+ rw = RStyx::Message::Rwstat.new
1265
+ bytes = rw.to_bytes(0x1234)
1266
+ expect = "\x7f\x34\x12"
1267
+ len = expect.length + 4
1268
+ packlen = [len].pack("V")
1269
+ expect = packlen + expect
1270
+ assert(expect == bytes)
1271
+
1272
+ # decode expect
1273
+ rw2 = RStyx::Message::StyxMessage.decode(expect)
1274
+ assert(rw2.class == RStyx::Message::Rwstat)
1275
+ assert(rw2.length == len)
1276
+ assert(rw2.mtype == RStyx::Message::StyxMessage::RWSTAT)
1277
+ assert(rw2.tag == 0x1234)
1278
+ # try decoding short strings
1279
+ assert_raise(RStyx::StyxException) { RStyx::Message::StyxMessage.decode(expect.chop) }
1280
+ # trailing garbage test
1281
+ assert_nothing_raised { rw2 = RStyx::Message::StyxMessage.decode(expect + "trailing garbage") }
1282
+ assert(rw2.class == RStyx::Message::Rwstat)
1283
+ assert(rw2.length == len)
1284
+ assert(rw2.mtype == RStyx::Message::StyxMessage::RWSTAT)
1285
+ assert(rw2.tag == 0x1234)
1286
+ end
1287
+
1288
+ end