rstyx 0.2.0 → 0.3.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.
- data/COPYING +482 -0
- data/ChangeLog +4 -0
- data/Manifest.txt +17 -0
- data/NEWS +2 -0
- data/README +41 -0
- data/Rakefile +55 -0
- data/examples/readstyxfile.rb +48 -0
- data/lib/rstyx/authmodules.rb +90 -0
- data/lib/rstyx/client.rb +709 -693
- data/lib/rstyx/common.rb +71 -0
- data/lib/rstyx/errors.rb +35 -2
- data/lib/rstyx/messages.rb +377 -1113
- data/lib/rstyx/server.rb +1305 -0
- data/lib/rstyx/version.rb +2 -2
- data/lib/rstyx.rb +11 -4
- data/tests/tc_client.rb +260 -45
- data/tests/tc_message.rb +245 -388
- data/tests/tc_styxservproto.rb +596 -0
- metadata +51 -26
@@ -0,0 +1,596 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
#
|
3
|
+
# Copyright (C) 2006, 2007 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., 51 Franklin St., Fifth Floor, Boston, MA
|
19
|
+
# 02110-1301 USA.
|
20
|
+
#
|
21
|
+
# $Id: tc_styxservproto.rb 222 2007-07-09 08:15:44Z dido $
|
22
|
+
#
|
23
|
+
require 'test/unit'
|
24
|
+
require 'flexmock'
|
25
|
+
require 'rstyx/server'
|
26
|
+
|
27
|
+
##
|
28
|
+
# A simple class that simply accepts any method on itself
|
29
|
+
# and does nothing.
|
30
|
+
#
|
31
|
+
class Absorber
|
32
|
+
def method_missing(name, *args)
|
33
|
+
# do nothing
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
module RStyx
|
38
|
+
module Server
|
39
|
+
# Stub for sessions
|
40
|
+
class Session
|
41
|
+
def initialize
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.mock=(m)
|
45
|
+
@@mock = m
|
46
|
+
end
|
47
|
+
|
48
|
+
def initialize(conn)
|
49
|
+
end
|
50
|
+
|
51
|
+
def reset_session(msize)
|
52
|
+
return(@@mock.reset_session(msize))
|
53
|
+
end
|
54
|
+
|
55
|
+
def version_negotiated?
|
56
|
+
return(@@mock.version_negotiated?)
|
57
|
+
end
|
58
|
+
|
59
|
+
def has_fid?(fid)
|
60
|
+
return(@@mock.has_fid?(fid))
|
61
|
+
end
|
62
|
+
|
63
|
+
def execute?(styxfile)
|
64
|
+
return(@@mock.execute?(styxfile))
|
65
|
+
end
|
66
|
+
|
67
|
+
def writable?(styxfile)
|
68
|
+
return(@@mock.writable?(styxfile))
|
69
|
+
end
|
70
|
+
|
71
|
+
def []=(fid, file)
|
72
|
+
return(@@mock[fid] = file)
|
73
|
+
end
|
74
|
+
|
75
|
+
def [](fid)
|
76
|
+
return(@@mock[fid])
|
77
|
+
end
|
78
|
+
|
79
|
+
def flush_tag(fid)
|
80
|
+
return(@@mock.flush_tag(fid))
|
81
|
+
end
|
82
|
+
|
83
|
+
def release_tag(fid)
|
84
|
+
return(@@mock.release_tag(fid))
|
85
|
+
end
|
86
|
+
|
87
|
+
def confirm_open(sf, mode)
|
88
|
+
return(@@mock.confirm_open(sf, mode))
|
89
|
+
end
|
90
|
+
|
91
|
+
def iounit
|
92
|
+
return(@@mock.iounit)
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
##
|
100
|
+
# Fake connection object mixin used to mix the StyxServerProtocol
|
101
|
+
# module or a copy thereof.
|
102
|
+
#
|
103
|
+
class FakeConnection
|
104
|
+
include RStyx::Server::StyxServerProtocol
|
105
|
+
|
106
|
+
##
|
107
|
+
# Mock objects are required for:
|
108
|
+
#
|
109
|
+
# 1. Methods called to self
|
110
|
+
# 2. Methods called to the session object
|
111
|
+
# 3. Methods called to the root object
|
112
|
+
# 4. (Optionally) Methods called to the logger
|
113
|
+
#
|
114
|
+
def initialize(selfmock, sessionmock, rootmock, log=Absorber.new)
|
115
|
+
@selfmock = selfmock
|
116
|
+
RStyx::Server::Session.mock = sessionmock
|
117
|
+
self.root = rootmock
|
118
|
+
self.log = log
|
119
|
+
post_init
|
120
|
+
end
|
121
|
+
|
122
|
+
def getpeername
|
123
|
+
return(nil)
|
124
|
+
end
|
125
|
+
|
126
|
+
def method_missing(meth, *args)
|
127
|
+
@selfmock.call(meth, *args)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
class TestStyxServProto < Test::Unit::TestCase
|
132
|
+
def test_tversion
|
133
|
+
FlexMock.use("sessmock") do |sessmock|
|
134
|
+
serv = FakeConnection.new(nil, sessmock, nil)
|
135
|
+
sessmock.should_receive(:reset_session).with(Integer).returns do |m|
|
136
|
+
assert_equal(1024, m)
|
137
|
+
end
|
138
|
+
resp = serv.tversion(RStyx::Message::Tversion.new(:version => "9P2000",
|
139
|
+
:msize => 1024))
|
140
|
+
assert_equal(RStyx::Message::Rversion, resp.class)
|
141
|
+
assert_equal("9P2000", resp.version)
|
142
|
+
assert_equal(8216, resp.msize)
|
143
|
+
end
|
144
|
+
|
145
|
+
FlexMock.use("sessmock") do |sessmock|
|
146
|
+
serv = FakeConnection.new(nil, sessmock, nil)
|
147
|
+
resp = serv.tversion(RStyx::Message::Tversion.new(:version => "foo",
|
148
|
+
:msize => 1024))
|
149
|
+
assert_equal(RStyx::Message::Rerror, resp.class)
|
150
|
+
assert_equal("Unsupported protocol version foo (must be 9P2000)", resp.ename)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def test_tauth
|
155
|
+
serv = FakeConnection.new(nil, nil, nil)
|
156
|
+
resp = serv.tauth(RStyx::Message::Tauth.new(:fid => 1,
|
157
|
+
:afid => 2,
|
158
|
+
:uname => "foo",
|
159
|
+
:aname => "bar"))
|
160
|
+
assert_equal(RStyx::Message::Rerror, resp.class)
|
161
|
+
assert_equal("Authentication methods through auth messages are not used.", resp.ename)
|
162
|
+
end
|
163
|
+
|
164
|
+
def test_tattach
|
165
|
+
# Test no version negotiation error
|
166
|
+
FlexMock.use("sessmock") do |sessmock|
|
167
|
+
sessmock.should_receive(:version_negotiated?).returns(false)
|
168
|
+
serv = FakeConnection.new(nil, sessmock, nil)
|
169
|
+
assert_raises(RStyx::StyxException) do
|
170
|
+
serv.tattach(RStyx::Message::Tattach.new(:fid => 1,
|
171
|
+
:afid => 2,
|
172
|
+
:uname => "foo",
|
173
|
+
:aname => "bar"))
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
# Test used fid error
|
178
|
+
FlexMock.use("sessmock") do |sessmock|
|
179
|
+
sessmock.should_receive(:version_negotiated?).returns(true)
|
180
|
+
sessmock.should_receive(:has_fid?).with(1).returns(true)
|
181
|
+
serv = FakeConnection.new(nil, sessmock, nil)
|
182
|
+
assert_raises(RStyx::StyxException) do
|
183
|
+
serv.tattach(RStyx::Message::Tattach.new(:fid => 1,
|
184
|
+
:afid => 2,
|
185
|
+
:uname => "foo",
|
186
|
+
:aname => "bar"))
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
# test successful condition
|
191
|
+
FlexMock.use("sessmock") do |sessmock|
|
192
|
+
FlexMock.use("rootmock") do |rootmock|
|
193
|
+
sessmock.should_receive(:version_negotiated?).returns(true)
|
194
|
+
sessmock.should_receive(:has_fid?).with(1).returns(false)
|
195
|
+
sessmock.should_receive(:[]=).with(1, rootmock)
|
196
|
+
# Return a phony QID with a distinctive pattern
|
197
|
+
rootmock.should_receive(:qid).returns(RStyx::Message::Qid.new(0x12345678, 0x87654321, 0xfeedfacec0ffeee))
|
198
|
+
serv = FakeConnection.new(nil, sessmock, rootmock)
|
199
|
+
resp = serv.tattach(RStyx::Message::Tattach.new(:fid => 1,
|
200
|
+
:afid => 2,
|
201
|
+
:uname => "foo",
|
202
|
+
:aname => "bar"))
|
203
|
+
assert_equal(0x12345678, resp.qid.qtype)
|
204
|
+
assert_equal(0x87654321, resp.qid.version)
|
205
|
+
assert_equal(0xfeedfacec0ffeee, resp.qid.path)
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
def test_tflush
|
211
|
+
FlexMock.use("sessmock") do |sessmock|
|
212
|
+
sessmock.should_receive(:flush_tag).with(100)
|
213
|
+
serv = FakeConnection.new(nil, sessmock, nil)
|
214
|
+
resp = serv.tflush(RStyx::Message::Tflush.new(:oldtag => 100))
|
215
|
+
assert_equal(RStyx::Message::Rflush, resp.class)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
def test_twalk
|
220
|
+
# Test for wnames > MAXWELEM
|
221
|
+
serv = FakeConnection.new(nil, nil, nil)
|
222
|
+
assert_raises(RStyx::StyxException) do
|
223
|
+
serv.twalk(RStyx::Message::Twalk.new(:fid => 1,
|
224
|
+
:newfid => 2,
|
225
|
+
:wnames => ["1", "2", "3",
|
226
|
+
"4", "5", "6",
|
227
|
+
"7", "8", "9",
|
228
|
+
"10,", "11", "12",
|
229
|
+
"13", "14", "15",
|
230
|
+
"16", "17", "18"]))
|
231
|
+
end
|
232
|
+
|
233
|
+
# test for walking to an open fid
|
234
|
+
FlexMock.use("sessmock") do |sessmock|
|
235
|
+
FlexMock.use("filemock") do |filemock|
|
236
|
+
sessmock.should_receive(:[]).with(42).returns(filemock)
|
237
|
+
filemock.should_receive(:client).returns(:pwn3d)
|
238
|
+
serv = FakeConnection.new(nil, sessmock, nil)
|
239
|
+
assert_raises(RStyx::StyxException) do
|
240
|
+
serv.twalk(RStyx::Message::Twalk.new(:fid => 42,
|
241
|
+
:newfid => 43,
|
242
|
+
:wnames => ["1", "2"]))
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
# Test attempting to reassign a fid that is already in use
|
248
|
+
FlexMock.use("sessmock") do |sessmock|
|
249
|
+
FlexMock.use("filemock") do |filemock|
|
250
|
+
sessmock.should_receive(:[]).with(42).returns(filemock)
|
251
|
+
filemock.should_receive(:client).returns(nil)
|
252
|
+
sessmock.should_receive(:has_fid?).with(43).returns(true)
|
253
|
+
serv = FakeConnection.new(nil, sessmock, nil)
|
254
|
+
assert_raises(RStyx::StyxException) do
|
255
|
+
serv.twalk(RStyx::Message::Twalk.new(:fid => 42,
|
256
|
+
:newfid => 43,
|
257
|
+
:wnames => ["1", "2"]))
|
258
|
+
end
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
# Test walking to something which isn't a directory
|
263
|
+
FlexMock.use("sessmock") do |sessmock|
|
264
|
+
FlexMock.use("filemock") do |filemock|
|
265
|
+
sessmock.should_receive(:[]).with(42).returns(filemock)
|
266
|
+
filemock.should_receive(:client).returns(nil)
|
267
|
+
sessmock.should_receive(:has_fid?).with(43).returns(false)
|
268
|
+
filemock.should_receive(:directory?).returns(false)
|
269
|
+
filemock.should_receive(:name).returns("foo")
|
270
|
+
serv = FakeConnection.new(nil, sessmock, nil)
|
271
|
+
assert_raises(RStyx::StyxException) do
|
272
|
+
serv.twalk(RStyx::Message::Twalk.new(:fid => 42,
|
273
|
+
:newfid => 43,
|
274
|
+
:wnames => ["1", "2"]))
|
275
|
+
end
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
# Test for the case where file permissions are violated
|
280
|
+
FlexMock.use("sessmock") do |sessmock|
|
281
|
+
FlexMock.use("filemock") do |filemock|
|
282
|
+
sessmock.should_receive(:[]).with(42).returns(filemock)
|
283
|
+
filemock.should_receive(:client).returns(nil)
|
284
|
+
sessmock.should_receive(:has_fid?).with(43).returns(false)
|
285
|
+
filemock.should_receive(:directory?).returns(true)
|
286
|
+
filemock.should_receive(:name).returns("foo")
|
287
|
+
sessmock.should_receive(:execute?).returns(false)
|
288
|
+
serv = FakeConnection.new(nil, sessmock, nil)
|
289
|
+
assert_raises(RStyx::StyxException) do
|
290
|
+
serv.twalk(RStyx::Message::Twalk.new(:fid => 42,
|
291
|
+
:newfid => 43,
|
292
|
+
:wnames => ["..", "2"]))
|
293
|
+
end
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
# Test for the case where we are unable to walk further than the
|
298
|
+
# first element
|
299
|
+
FlexMock.use("sessmock") do |sessmock|
|
300
|
+
FlexMock.use("filemock") do |filemock|
|
301
|
+
sessmock.should_receive(:[]).with(42).returns(filemock)
|
302
|
+
filemock.should_receive(:client).returns(nil)
|
303
|
+
sessmock.should_receive(:has_fid?).with(43).returns(false)
|
304
|
+
filemock.should_receive(:directory?).returns(true)
|
305
|
+
filemock.should_receive(:name).returns("foo")
|
306
|
+
filemock.should_receive(:atime=)
|
307
|
+
filemock.should_receive(:[]).with("1").returns(nil)
|
308
|
+
serv = FakeConnection.new(nil, sessmock, nil)
|
309
|
+
assert_raises(RStyx::StyxException) do
|
310
|
+
serv.twalk(RStyx::Message::Twalk.new(:fid => 42,
|
311
|
+
:newfid => 43,
|
312
|
+
:wnames => ["1", "2"]))
|
313
|
+
end
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
# Test successful walk without fid assignment
|
318
|
+
FlexMock.use("sessmock") do |sessmock|
|
319
|
+
FlexMock.use("filemock") do |filemock|
|
320
|
+
sessmock.should_receive(:[]).with(42).returns(filemock)
|
321
|
+
filemock.should_receive(:client).returns(nil)
|
322
|
+
sessmock.should_receive(:has_fid?).with(43).returns(false)
|
323
|
+
filemock.should_receive(:directory?).returns(true)
|
324
|
+
filemock.should_receive(:name).returns("foo")
|
325
|
+
filemock.should_receive(:atime=)
|
326
|
+
filemock.should_receive(:[]).with("1").returns(filemock)
|
327
|
+
filemock.should_receive(:[]).with("2").returns(nil)
|
328
|
+
filemock.should_receive(:qid).returns(RStyx::Message::Qid.new(0x12345678, 0x87654321, 0xfeedfacec0ffeee))
|
329
|
+
filemock.should_receive(:refresh)
|
330
|
+
serv = FakeConnection.new(nil, sessmock, nil)
|
331
|
+
resp = serv.twalk(RStyx::Message::Twalk.new(:fid => 42,
|
332
|
+
:newfid => 43,
|
333
|
+
:wnames => ["1", "2"]))
|
334
|
+
assert_equal(RStyx::Message::Rwalk, resp.class)
|
335
|
+
assert_equal(1, resp.qids.length)
|
336
|
+
assert_equal(RStyx::Message::Qid.new(0x12345678,
|
337
|
+
0x87654321,
|
338
|
+
0xfeedfacec0ffeee),
|
339
|
+
resp.qids[0])
|
340
|
+
end
|
341
|
+
end
|
342
|
+
|
343
|
+
# Test successful walk with fid assignment
|
344
|
+
FlexMock.use("sessmock") do |sessmock|
|
345
|
+
FlexMock.use("filemock") do |filemock|
|
346
|
+
sessmock.should_receive(:[]).with(42).returns(filemock)
|
347
|
+
filemock.should_receive(:client).returns(nil)
|
348
|
+
sessmock.should_receive(:has_fid?).with(43).returns(false)
|
349
|
+
filemock.should_receive(:directory?).returns(true)
|
350
|
+
filemock.should_receive(:name).returns("foo")
|
351
|
+
filemock.should_receive(:atime=)
|
352
|
+
filemock.should_receive(:[]).with("1").returns(filemock)
|
353
|
+
filemock.should_receive(:[]).with("2").returns(filemock)
|
354
|
+
qids = [ RStyx::Message::Qid.new(0x12345678,
|
355
|
+
0x87654321,
|
356
|
+
0xfeedfacec0ffeee),
|
357
|
+
RStyx::Message::Qid.new(0x89abcdef,
|
358
|
+
0x01234567,
|
359
|
+
0x0123456789abcdef)
|
360
|
+
]
|
361
|
+
filemock.should_receive(:qid).returns { qids.shift }
|
362
|
+
filemock.should_receive(:refresh)
|
363
|
+
sessmock.should_receive(:[]=).with(42, filemock)
|
364
|
+
serv = FakeConnection.new(nil, sessmock, nil)
|
365
|
+
resp = serv.twalk(RStyx::Message::Twalk.new(:fid => 42,
|
366
|
+
:newfid => 43,
|
367
|
+
:wnames => ["1", "2"]))
|
368
|
+
assert_equal(RStyx::Message::Rwalk, resp.class)
|
369
|
+
assert_equal(2, resp.qids.length)
|
370
|
+
assert_equal(RStyx::Message::Qid.new(0x12345678,
|
371
|
+
0x87654321,
|
372
|
+
0xfeedfacec0ffeee),
|
373
|
+
resp.qids[0])
|
374
|
+
assert_equal(RStyx::Message::Qid.new(0x89abcdef,
|
375
|
+
0x01234567,
|
376
|
+
0x0123456789abcdef),
|
377
|
+
|
378
|
+
resp.qids[1])
|
379
|
+
end
|
380
|
+
end
|
381
|
+
|
382
|
+
|
383
|
+
end
|
384
|
+
|
385
|
+
def test_topen
|
386
|
+
FlexMock.use("sessmock") do |sessmock|
|
387
|
+
FlexMock.use("filemock") do |filemock|
|
388
|
+
sessmock.should_receive(:[]).with(42).returns(filemock)
|
389
|
+
sessmock.should_receive(:confirm_open).with(filemock, RStyx::OTRUNC)
|
390
|
+
filemock.should_receive(:add_client)
|
391
|
+
filemock.should_receive(:set_mtime)
|
392
|
+
sessmock.should_receive(:user)
|
393
|
+
filemock.should_receive(:qid).returns(RStyx::Message::Qid.new(0x12345678, 0x87654321, 0xfeedfacec0ffeee))
|
394
|
+
sessmock.should_receive(:iounit).returns(0xdeadbeef)
|
395
|
+
serv = FakeConnection.new(nil, sessmock, nil)
|
396
|
+
resp = serv.topen(RStyx::Message::Topen.new(:fid => 42,
|
397
|
+
:mode => RStyx::OTRUNC))
|
398
|
+
assert_equal(RStyx::Message::Qid.new(0x12345678, 0x87654321, 0xfeedfacec0ffeee), resp.qid)
|
399
|
+
assert_equal(0xdeadbeef, resp.iounit)
|
400
|
+
end
|
401
|
+
end
|
402
|
+
end
|
403
|
+
|
404
|
+
def test_tcreate
|
405
|
+
# First, test the error condition of trying to create a file
|
406
|
+
# inside a fid representing a file.
|
407
|
+
FlexMock.use("sessmock") do |sessmock|
|
408
|
+
FlexMock.use("filemock") do |filemock|
|
409
|
+
sessmock.should_receive(:[]).with(42).returns(filemock)
|
410
|
+
filemock.should_receive(:directory?).returns(false)
|
411
|
+
serv = FakeConnection.new(nil, sessmock, nil)
|
412
|
+
assert_raises(RStyx::StyxException) do
|
413
|
+
resp = serv.tcreate(RStyx::Message::Tcreate.new(:fid => 42,
|
414
|
+
:mode => RStyx::OTRUNC))
|
415
|
+
end
|
416
|
+
end
|
417
|
+
end
|
418
|
+
|
419
|
+
# Second, test the error condition where we try to create a file
|
420
|
+
# where the connection does not have permission to write.
|
421
|
+
FlexMock.use("sessmock") do |sessmock|
|
422
|
+
FlexMock.use("filemock") do |filemock|
|
423
|
+
sessmock.should_receive(:[]).with(42).returns(filemock)
|
424
|
+
filemock.should_receive(:directory?).returns(true)
|
425
|
+
sessmock.should_receive(:writable?).returns(false)
|
426
|
+
serv = FakeConnection.new(nil, sessmock, nil)
|
427
|
+
assert_raises(RStyx::StyxException) do
|
428
|
+
resp = serv.tcreate(RStyx::Message::Tcreate.new(:fid => 42,
|
429
|
+
:mode => RStyx::OTRUNC))
|
430
|
+
end
|
431
|
+
end
|
432
|
+
end
|
433
|
+
|
434
|
+
# Third, successful creation.
|
435
|
+
FlexMock.use("sessmock") do |sessmock|
|
436
|
+
FlexMock.use("filemock") do |filemock|
|
437
|
+
sessmock.should_receive(:[]).with(42).returns(filemock)
|
438
|
+
filemock.should_receive(:directory?).returns(true)
|
439
|
+
sessmock.should_receive(:writable?).returns(true)
|
440
|
+
filemock.should_receive(:newfile).with("foo", 0644).returns(filemock)
|
441
|
+
filemock.should_receive(:<<).with(filemock)
|
442
|
+
sessmock.should_receive(:[]=).with(42, filemock)
|
443
|
+
filemock.should_receive(:add_client)
|
444
|
+
filemock.should_receive(:qid).returns(RStyx::Message::Qid.new(0x12345678, 0x87654321, 0xfeedfacec0ffeee))
|
445
|
+
sessmock.should_receive(:iounit).returns(0xdeadbeef)
|
446
|
+
serv = FakeConnection.new(nil, sessmock, nil)
|
447
|
+
resp = serv.tcreate(RStyx::Message::Tcreate.new(:fid => 42,
|
448
|
+
:name => "foo",
|
449
|
+
:perm => 0644,
|
450
|
+
:mode =>
|
451
|
+
RStyx::OTRUNC))
|
452
|
+
assert_equal(RStyx::Message::Rcreate, resp.class)
|
453
|
+
assert_equal(RStyx::Message::Qid.new(0x12345678,
|
454
|
+
0x87654321,
|
455
|
+
0xfeedfacec0ffeee), resp.qid)
|
456
|
+
assert_equal(0xdeadbeef, resp.iounit)
|
457
|
+
end
|
458
|
+
end
|
459
|
+
|
460
|
+
end
|
461
|
+
|
462
|
+
def test_tread
|
463
|
+
# Test error condition -- file not open for reading
|
464
|
+
FlexMock.use("sessmock") do |sessmock|
|
465
|
+
FlexMock.use("filemock") do |filemock|
|
466
|
+
sessmock.should_receive(:[]).with(42).returns(filemock)
|
467
|
+
filemock.should_receive(:client).returns(nil)
|
468
|
+
serv = FakeConnection.new(nil, sessmock, nil)
|
469
|
+
assert_raises(RStyx::StyxException) do
|
470
|
+
resp = serv.tread(RStyx::Message::Tread.new(:fid => 42,
|
471
|
+
:offset => 0xfeedfacec0ffeeee,
|
472
|
+
:count => 100))
|
473
|
+
end
|
474
|
+
end
|
475
|
+
end
|
476
|
+
|
477
|
+
# Test trying to read more than the session iounit
|
478
|
+
FlexMock.use("sessmock") do |sessmock|
|
479
|
+
FlexMock.use("filemock") do |filemock|
|
480
|
+
sessmock.should_receive(:[]).with(42).returns(filemock)
|
481
|
+
filemock.should_receive(:client).returns(filemock)
|
482
|
+
filemock.should_receive(:readable?).returns(true)
|
483
|
+
sessmock.should_receive(:iounit).returns(8216)
|
484
|
+
serv = FakeConnection.new(nil, sessmock, nil)
|
485
|
+
assert_raises(RStyx::StyxException) do
|
486
|
+
resp = serv.tread(RStyx::Message::Tread.new(:fid => 42,
|
487
|
+
:offset => 0xfeedfacec0ffeeee,
|
488
|
+
:count => 10000))
|
489
|
+
end
|
490
|
+
end
|
491
|
+
end
|
492
|
+
|
493
|
+
# Test successful read
|
494
|
+
FlexMock.use("sessmock") do |sessmock|
|
495
|
+
FlexMock.use("filemock") do |filemock|
|
496
|
+
sessmock.should_receive(:[]).with(42).returns(filemock)
|
497
|
+
filemock.should_receive(:client).returns(filemock)
|
498
|
+
filemock.should_receive(:readable?).returns(true)
|
499
|
+
sessmock.should_receive(:iounit).returns(8216)
|
500
|
+
filemock.should_receive(:read).returns do |a1,a2,a3|
|
501
|
+
assert_equal(0xfeedfacec0ffeeee, a2)
|
502
|
+
assert_equal(1000, a3)
|
503
|
+
true
|
504
|
+
end
|
505
|
+
serv = FakeConnection.new(nil, sessmock, nil)
|
506
|
+
resp = serv.tread(RStyx::Message::Tread.new(:fid => 42,
|
507
|
+
:offset => 0xfeedfacec0ffeeee,
|
508
|
+
:count => 1000))
|
509
|
+
assert(resp)
|
510
|
+
end
|
511
|
+
end
|
512
|
+
|
513
|
+
end
|
514
|
+
|
515
|
+
def test_twrite
|
516
|
+
# Test error condition -- file not open for writing
|
517
|
+
FlexMock.use("sessmock") do |sessmock|
|
518
|
+
FlexMock.use("filemock") do |filemock|
|
519
|
+
sessmock.should_receive(:[]).with(42).returns(filemock)
|
520
|
+
filemock.should_receive(:client).returns(nil)
|
521
|
+
serv = FakeConnection.new(nil, sessmock, nil)
|
522
|
+
assert_raises(RStyx::StyxException) do
|
523
|
+
resp = serv.twrite(RStyx::Message::Twrite.new(:fid => 42,
|
524
|
+
:offset => 0xfeedfacec0ffeeee,
|
525
|
+
:data => "0" * 1000))
|
526
|
+
end
|
527
|
+
end
|
528
|
+
end
|
529
|
+
|
530
|
+
# Test trying to write more than the session iounit
|
531
|
+
FlexMock.use("sessmock") do |sessmock|
|
532
|
+
FlexMock.use("filemock") do |filemock|
|
533
|
+
sessmock.should_receive(:[]).with(42).returns(filemock)
|
534
|
+
filemock.should_receive(:client).returns(filemock)
|
535
|
+
filemock.should_receive(:writable?).returns(true)
|
536
|
+
sessmock.should_receive(:iounit).returns(8216)
|
537
|
+
serv = FakeConnection.new(nil, sessmock, nil)
|
538
|
+
assert_raises(RStyx::StyxException) do
|
539
|
+
resp = serv.twrite(RStyx::Message::Twrite.new(:fid => 42,
|
540
|
+
:offset => 0xfeedfacec0ffeeee,
|
541
|
+
:data => "0" * 10000))
|
542
|
+
end
|
543
|
+
end
|
544
|
+
end
|
545
|
+
|
546
|
+
# Test successful write
|
547
|
+
FlexMock.use("sessmock") do |sessmock|
|
548
|
+
FlexMock.use("filemock") do |filemock|
|
549
|
+
sessmock.should_receive(:[]).with(42).returns(filemock)
|
550
|
+
filemock.should_receive(:client).returns(filemock)
|
551
|
+
filemock.should_receive(:writable?).returns(true)
|
552
|
+
sessmock.should_receive(:iounit).returns(8216)
|
553
|
+
filemock.should_receive(:write).returns do |a1,a2,a3,a4|
|
554
|
+
assert_equal(0xfeedfacec0ffeeee, a2)
|
555
|
+
assert_equal("0" * 1000, a3)
|
556
|
+
assert(!a4)
|
557
|
+
true
|
558
|
+
end
|
559
|
+
filemock.should_receive(:truncate?).returns(false)
|
560
|
+
filemock.should_receive(:appendonly?).returns(false)
|
561
|
+
filemock.should_receive(:length).returns(42)
|
562
|
+
serv = FakeConnection.new(nil, sessmock, nil)
|
563
|
+
resp = serv.twrite(RStyx::Message::Twrite.new(:fid => 42,
|
564
|
+
:offset => 0xfeedfacec0ffeeee,
|
565
|
+
:data => "0" * 1000))
|
566
|
+
assert(resp)
|
567
|
+
end
|
568
|
+
end
|
569
|
+
|
570
|
+
|
571
|
+
# Test successful write on an append only file
|
572
|
+
FlexMock.use("sessmock") do |sessmock|
|
573
|
+
FlexMock.use("filemock") do |filemock|
|
574
|
+
sessmock.should_receive(:[]).with(42).returns(filemock)
|
575
|
+
filemock.should_receive(:client).returns(filemock)
|
576
|
+
filemock.should_receive(:writable?).returns(true)
|
577
|
+
sessmock.should_receive(:iounit).returns(8216)
|
578
|
+
filemock.should_receive(:write).returns do |a1,a2,a3,a4|
|
579
|
+
assert_equal(42, a2)
|
580
|
+
assert_equal("0" * 1000, a3)
|
581
|
+
assert(!a4)
|
582
|
+
true
|
583
|
+
end
|
584
|
+
filemock.should_receive(:truncate?).returns(false)
|
585
|
+
filemock.should_receive(:appendonly?).returns(true)
|
586
|
+
filemock.should_receive(:length).returns(42)
|
587
|
+
serv = FakeConnection.new(nil, sessmock, nil)
|
588
|
+
resp = serv.twrite(RStyx::Message::Twrite.new(:fid => 42,
|
589
|
+
:offset => 0xfeedfacec0ffeeee,
|
590
|
+
:data => "0" * 1000))
|
591
|
+
assert(resp)
|
592
|
+
end
|
593
|
+
end
|
594
|
+
end
|
595
|
+
|
596
|
+
end
|
metadata
CHANGED
@@ -1,48 +1,73 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.
|
2
|
+
rubygems_version: 0.9.4
|
3
3
|
specification_version: 1
|
4
4
|
name: rstyx
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.
|
7
|
-
date:
|
8
|
-
summary: RStyx is
|
6
|
+
version: 0.3.0
|
7
|
+
date: 2007-08-10 00:00:00 +08:00
|
8
|
+
summary: RStyx is a Ruby implementation of the 9P2000/Styx distributed file protocol used on Plan 9 and Inferno.
|
9
9
|
require_paths:
|
10
|
-
|
10
|
+
- lib
|
11
11
|
email: dido@imperium.ph
|
12
12
|
homepage: http://rubyforge.org/projects/rstyx
|
13
|
-
rubyforge_project:
|
14
|
-
description:
|
15
|
-
autorequire:
|
13
|
+
rubyforge_project: rstyx
|
14
|
+
description: 9P2000/Styx for Ruby
|
15
|
+
autorequire:
|
16
16
|
default_executable:
|
17
17
|
bindir: bin
|
18
18
|
has_rdoc: true
|
19
19
|
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
20
|
requirements:
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
version: 0.0.0
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
25
24
|
version:
|
26
25
|
platform: ruby
|
27
26
|
signing_key:
|
28
27
|
cert_chain:
|
28
|
+
post_install_message:
|
29
29
|
authors:
|
30
|
-
|
30
|
+
- Rafael R. Sevilla
|
31
31
|
files:
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
32
|
+
- COPYING
|
33
|
+
- ChangeLog
|
34
|
+
- Manifest.txt
|
35
|
+
- NEWS
|
36
|
+
- README
|
37
|
+
- Rakefile
|
38
|
+
- examples/readstyxfile.rb
|
39
|
+
- lib/rstyx/authmodules.rb
|
40
|
+
- lib/rstyx/client.rb
|
41
|
+
- lib/rstyx/common.rb
|
42
|
+
- lib/rstyx/errors.rb
|
43
|
+
- lib/rstyx/messages.rb
|
44
|
+
- lib/rstyx/server.rb
|
45
|
+
- lib/rstyx/version.rb
|
46
|
+
- lib/rstyx.rb
|
47
|
+
- tests/tc_client.rb
|
48
|
+
- tests/tc_message.rb
|
49
|
+
test_files:
|
50
|
+
- tests/tc_client.rb
|
51
|
+
- tests/tc_message.rb
|
52
|
+
- tests/tc_styxservproto.rb
|
41
53
|
rdoc_options:
|
42
|
-
|
43
|
-
|
44
|
-
extra_rdoc_files:
|
54
|
+
- --main
|
55
|
+
- README.txt
|
56
|
+
extra_rdoc_files:
|
57
|
+
- Manifest.txt
|
45
58
|
executables: []
|
59
|
+
|
46
60
|
extensions: []
|
61
|
+
|
47
62
|
requirements: []
|
48
|
-
|
63
|
+
|
64
|
+
dependencies:
|
65
|
+
- !ruby/object:Gem::Dependency
|
66
|
+
name: eventmachine
|
67
|
+
version_requirement:
|
68
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
69
|
+
requirements:
|
70
|
+
- - ">"
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: 0.0.0
|
73
|
+
version:
|