rstyx 0.4.1 → 0.4.2
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/History.txt +5 -0
- data/lib/rstyx/common.rb +4 -4
- data/lib/rstyx/server.rb +11 -9
- data/lib/rstyx/version.rb +2 -2
- data/tests/tc_styxservproto.rb +564 -7
- metadata +2 -2
data/History.txt
CHANGED
data/lib/rstyx/common.rb
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
# Homepage:: http://rstyx.rubyforge.org/
|
6
6
|
# License:: GNU Lesser General Public License / Ruby License
|
7
7
|
#
|
8
|
-
# $Id: common.rb
|
8
|
+
# $Id: common.rb 298 2007-09-21 08:52:12Z dido $
|
9
9
|
#
|
10
10
|
#----------------------------------------------------------------------------
|
11
11
|
#
|
@@ -33,10 +33,10 @@ module RStyx
|
|
33
33
|
ORCLOSE = 0x40
|
34
34
|
|
35
35
|
# Constants related to the file type
|
36
|
-
DMDIR =
|
36
|
+
DMDIR = 0x80000000 # directory
|
37
37
|
DMAPPEND = 0x40000000 # append-only file
|
38
|
-
DMEXCL =
|
39
|
-
DMAUTH =
|
38
|
+
DMEXCL = 0x20000000 # exclusive use file
|
39
|
+
DMAUTH = 0x08000000 # file used for authentication
|
40
40
|
|
41
41
|
# Maximum FID numbers and the NOFID constant.
|
42
42
|
MAX_FID = 0xfffffffe
|
data/lib/rstyx/server.rb
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
# Homepage:: http://rstyx.rubyforge.org/
|
6
6
|
# License:: GNU Lesser General Public License / Ruby License
|
7
7
|
#
|
8
|
-
# $Id: server.rb
|
8
|
+
# $Id: server.rb 302 2007-09-24 03:01:10Z dido $
|
9
9
|
#
|
10
10
|
#----------------------------------------------------------------------------
|
11
11
|
#
|
@@ -364,7 +364,8 @@ module RStyx
|
|
364
364
|
|
365
365
|
# Create the file in the directory, add it to the directory tree,
|
366
366
|
# and associate the new file with the given fid
|
367
|
-
new_file = dir.newfile(msg.name, realperm, isdir, isapponly,
|
367
|
+
new_file = dir.newfile(msg.name, realperm, isdir, isapponly,
|
368
|
+
isexclusive)
|
368
369
|
dir << new_file
|
369
370
|
@session[msg.fid] = new_file
|
370
371
|
new_file.add_client(SFileClient.new(@session, msg.fid, msg.mode))
|
@@ -435,7 +436,7 @@ module RStyx
|
|
435
436
|
sf.synchronize do
|
436
437
|
@session.clunk(msg.fid)
|
437
438
|
parent = sf.parent
|
438
|
-
|
439
|
+
unless @session.writable?(parent)
|
439
440
|
raise StyxException.new("permission denied")
|
440
441
|
end
|
441
442
|
|
@@ -470,7 +471,7 @@ module RStyx
|
|
470
471
|
unless @session.writable?(dir)
|
471
472
|
raise StyxException.new("write permissions required on parent directory to change file name")
|
472
473
|
end
|
473
|
-
|
474
|
+
if dir.has_child?(nstat.name)
|
474
475
|
raise StyxException.new("cannot rename file to the name of an existing file")
|
475
476
|
end
|
476
477
|
sf.can_setname?(nstat.name)
|
@@ -479,10 +480,10 @@ module RStyx
|
|
479
480
|
# Check if we are changing the length of a file
|
480
481
|
if nstat.size != -1
|
481
482
|
# Check if we have write permission on the file
|
482
|
-
|
483
|
+
unless @session.writable?(sf)
|
483
484
|
raise StyxException.new("write permissions required to change file length")
|
484
485
|
end
|
485
|
-
sf.can_setlength?(
|
486
|
+
sf.can_setlength?(nstat.size)
|
486
487
|
end
|
487
488
|
|
488
489
|
# Check if we are changing the mode of a file
|
@@ -493,7 +494,7 @@ module RStyx
|
|
493
494
|
end
|
494
495
|
|
495
496
|
# Can't change the directory bit
|
496
|
-
if ((nstat.mode & DMDIR == DMDIR)
|
497
|
+
if ((nstat.mode & DMDIR == DMDIR) && !sf.directory?)
|
497
498
|
raise StyxException.new("can't change a file to a directory")
|
498
499
|
end
|
499
500
|
sf.can_setmode?(nstat.mode)
|
@@ -547,7 +548,7 @@ module RStyx
|
|
547
548
|
end
|
548
549
|
|
549
550
|
if nstat.size != -1
|
550
|
-
sf.length = nstat.
|
551
|
+
sf.length = nstat.size
|
551
552
|
end
|
552
553
|
|
553
554
|
if nstat.mode != MAXUINT
|
@@ -598,7 +599,7 @@ module RStyx
|
|
598
599
|
# In this case, we can't reply with an error to the client,
|
599
600
|
# since the tag used was invalid! If debug level is high
|
600
601
|
# enough, simply print out an error.
|
601
|
-
@log.error("#{@peername} #{e.to_s} #{msg.to_s}")
|
602
|
+
@log.error("#{@peername} #{e.class.to_s} #{msg.to_s}")
|
602
603
|
rescue FidNotFoundException => e
|
603
604
|
@log.error("#{@peername} unknown fid in message #{msg.to_s}")
|
604
605
|
reply(Message::Rerror.new(:ename => "Unknown fid #{e.fid}"), tag)
|
@@ -607,6 +608,7 @@ module RStyx
|
|
607
608
|
reply(Message::Rerror.new(:ename => "Error: #{e.message}"), tag)
|
608
609
|
rescue Exception => e
|
609
610
|
@log.error("#{@peername} internal error #{e.message} for #{e.to_s} at #{e.backtrace}")
|
611
|
+
reply(Message::Rerror.new(:ename => "Internal RStyx Error: #{e.message}"), tag)
|
610
612
|
end
|
611
613
|
|
612
614
|
end
|
data/lib/rstyx/version.rb
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
# Homepage:: http://rstyx.rubyforge.org/
|
6
6
|
# License:: GNU Lesser General Public License / Ruby License
|
7
7
|
#
|
8
|
-
# $Id: version.rb
|
8
|
+
# $Id: version.rb 303 2007-09-24 03:02:11Z dido $
|
9
9
|
#
|
10
10
|
#----------------------------------------------------------------------------
|
11
11
|
#
|
@@ -29,7 +29,7 @@ module RStyx
|
|
29
29
|
|
30
30
|
MAJOR = 0
|
31
31
|
MINOR = 4
|
32
|
-
TINY =
|
32
|
+
TINY = 2
|
33
33
|
|
34
34
|
# The version of RStyx in use.
|
35
35
|
STRING = [ MAJOR, MINOR, TINY ].join(".")
|
data/tests/tc_styxservproto.rb
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
# Homepage:: http://rstyx.rubyforge.org/
|
6
6
|
# License:: GNU Lesser General Public License / Ruby License
|
7
7
|
#
|
8
|
-
# $Id: tc_styxservproto.rb
|
8
|
+
# $Id: tc_styxservproto.rb 301 2007-09-24 03:00:14Z dido $
|
9
9
|
#
|
10
10
|
#----------------------------------------------------------------------------
|
11
11
|
#
|
@@ -23,7 +23,7 @@
|
|
23
23
|
#
|
24
24
|
require 'test/unit'
|
25
25
|
require 'flexmock'
|
26
|
-
require 'flexmock
|
26
|
+
require 'flexmock'
|
27
27
|
require 'rstyx/server'
|
28
28
|
|
29
29
|
##
|
@@ -62,6 +62,14 @@ module RStyx
|
|
62
62
|
return(@@mock.has_fid?(fid))
|
63
63
|
end
|
64
64
|
|
65
|
+
def add_tag(t)
|
66
|
+
return(@@mock.add_tag(t))
|
67
|
+
end
|
68
|
+
|
69
|
+
def has_tag?(tag)
|
70
|
+
return(@@mock.has_tag?(tag))
|
71
|
+
end
|
72
|
+
|
65
73
|
def execute?(styxfile)
|
66
74
|
return(@@mock.execute?(styxfile))
|
67
75
|
end
|
@@ -90,6 +98,10 @@ module RStyx
|
|
90
98
|
return(@@mock.confirm_open(sf, mode))
|
91
99
|
end
|
92
100
|
|
101
|
+
def user
|
102
|
+
return(@@mock.user)
|
103
|
+
end
|
104
|
+
|
93
105
|
def iounit
|
94
106
|
return(@@mock.iounit)
|
95
107
|
end
|
@@ -135,6 +147,7 @@ class FakeConnection
|
|
135
147
|
end
|
136
148
|
|
137
149
|
class TestStyxServProto < Test::Unit::TestCase
|
150
|
+
include FlexMock::TestCase
|
138
151
|
def test_tversion
|
139
152
|
sessmock1 = flexmock
|
140
153
|
selfmock = flexmock(:get_peername => nil)
|
@@ -153,8 +166,8 @@ class TestStyxServProto < Test::Unit::TestCase
|
|
153
166
|
serv = FakeConnection.new(selfmock, sessmock, nil)
|
154
167
|
resp = serv.tversion(RStyx::Message::Tversion.new(:version => "foo",
|
155
168
|
:msize => 1024))
|
156
|
-
assert_equal(RStyx::Message::
|
157
|
-
assert_equal("
|
169
|
+
assert_equal(RStyx::Message::Rversion, resp.class)
|
170
|
+
assert_equal("unknown", resp.version)
|
158
171
|
end
|
159
172
|
|
160
173
|
def test_tauth
|
@@ -165,7 +178,7 @@ class TestStyxServProto < Test::Unit::TestCase
|
|
165
178
|
:uname => "foo",
|
166
179
|
:aname => "bar"))
|
167
180
|
assert_equal(RStyx::Message::Rerror, resp.class)
|
168
|
-
assert_equal("Authentication methods through auth messages are not
|
181
|
+
assert_equal("Authentication methods through auth messages are not supported.", resp.ename)
|
169
182
|
end
|
170
183
|
|
171
184
|
def test_tattach
|
@@ -443,13 +456,47 @@ class TestStyxServProto < Test::Unit::TestCase
|
|
443
456
|
end
|
444
457
|
end
|
445
458
|
|
446
|
-
# Third,
|
459
|
+
# Third, try to create a file with DMAUTH set.
|
460
|
+
FlexMock.use("sessmock") do |sessmock|
|
461
|
+
FlexMock.use("filemock") do |filemock|
|
462
|
+
sessmock.should_receive(:[]).with(42).returns(filemock)
|
463
|
+
filemock.should_receive(:directory?).returns(true)
|
464
|
+
sessmock.should_receive(:writable?).returns(true)
|
465
|
+
filemock.should_receive(:permissions).returns(0777)
|
466
|
+
serv = FakeConnection.new(selfmock, sessmock, nil)
|
467
|
+
assert_raises(RStyx::StyxException) do
|
468
|
+
resp = serv.tcreate(RStyx::Message::Tcreate.new(:fid => 42,
|
469
|
+
:mode => RStyx::OREAD,
|
470
|
+
:perm => RStyx::DMAUTH | 0644))
|
471
|
+
end
|
472
|
+
end
|
473
|
+
end
|
474
|
+
|
475
|
+
# Fourth, try to create a directory in a mode besides OREAD.
|
476
|
+
FlexMock.use("sessmock") do |sessmock|
|
477
|
+
FlexMock.use("filemock") do |filemock|
|
478
|
+
sessmock.should_receive(:[]).with(42).returns(filemock)
|
479
|
+
filemock.should_receive(:directory?).returns(true)
|
480
|
+
sessmock.should_receive(:writable?).returns(true)
|
481
|
+
filemock.should_receive(:permissions).returns(0777)
|
482
|
+
serv = FakeConnection.new(selfmock, sessmock, nil)
|
483
|
+
assert_raises(RStyx::StyxException) do
|
484
|
+
resp = serv.tcreate(RStyx::Message::Tcreate.new(:fid => 42,
|
485
|
+
:mode => RStyx::OTRUNC,
|
486
|
+
:perm => RStyx::DMDIR | 0755))
|
487
|
+
end
|
488
|
+
end
|
489
|
+
end
|
490
|
+
|
491
|
+
# Finally, successful creation.
|
447
492
|
FlexMock.use("sessmock") do |sessmock|
|
448
493
|
FlexMock.use("filemock") do |filemock|
|
449
494
|
sessmock.should_receive(:[]).with(42).returns(filemock)
|
450
495
|
filemock.should_receive(:directory?).returns(true)
|
451
496
|
sessmock.should_receive(:writable?).returns(true)
|
452
|
-
filemock.should_receive(:
|
497
|
+
filemock.should_receive(:permissions).returns(0777)
|
498
|
+
filemock.should_receive(:newfile).with("foo", 0644, false,
|
499
|
+
false, false).returns(filemock)
|
453
500
|
filemock.should_receive(:<<).with(filemock)
|
454
501
|
sessmock.should_receive(:[]=).with(42, filemock)
|
455
502
|
filemock.should_receive(:add_client)
|
@@ -618,4 +665,514 @@ class TestStyxServProto < Test::Unit::TestCase
|
|
618
665
|
assert_equal(RStyx::Message::Rclunk, resp.class)
|
619
666
|
end
|
620
667
|
|
668
|
+
def test_tremove_permission_denied
|
669
|
+
# Permission denied
|
670
|
+
selfmock = flexmock(:get_peername => nil)
|
671
|
+
sessmock = flexmock
|
672
|
+
filemock = flexmock
|
673
|
+
sessmock.should_receive(:[]).with(42).returns(filemock)
|
674
|
+
filemock.should_receive(:synchronize).with(Proc).returns { |block| block.call }
|
675
|
+
sessmock.should_receive(:clunk).with(Integer).returns do |f|
|
676
|
+
assert_equal(42, f)
|
677
|
+
end
|
678
|
+
filemock.should_receive(:parent).returns(filemock)
|
679
|
+
sessmock.should_receive(:writable?).with(filemock).returns(false)
|
680
|
+
serv = FakeConnection.new(selfmock, sessmock, nil)
|
681
|
+
assert_raises(RStyx::StyxException) do
|
682
|
+
resp = serv.tremove(RStyx::Message::Tremove.new(:fid => 42))
|
683
|
+
end
|
684
|
+
end
|
685
|
+
|
686
|
+
def test_tremove_not_empty
|
687
|
+
# Directory not empty
|
688
|
+
selfmock = flexmock(:get_peername => nil)
|
689
|
+
sessmock = flexmock
|
690
|
+
filemock = flexmock
|
691
|
+
sessmock.should_receive(:[]).with(42).returns(filemock)
|
692
|
+
filemock.should_receive(:synchronize).with(Proc).returns { |block| block.call }
|
693
|
+
sessmock.should_receive(:clunk).with(Integer).returns do |f|
|
694
|
+
assert_equal(42, f)
|
695
|
+
end
|
696
|
+
filemock.should_receive(:parent).returns(filemock)
|
697
|
+
sessmock.should_receive(:writable?).with(filemock).returns(true)
|
698
|
+
filemock.should_receive(:instance_of?).with(RStyx::Server::SDirectory).returns(true)
|
699
|
+
filemock.should_receive(:child_count).returns(42)
|
700
|
+
serv = FakeConnection.new(selfmock, sessmock, nil)
|
701
|
+
assert_raises(RStyx::StyxException) do
|
702
|
+
resp = serv.tremove(RStyx::Message::Tremove.new(:fid => 42))
|
703
|
+
end
|
704
|
+
end
|
705
|
+
|
706
|
+
def test_tremove_success
|
707
|
+
selfmock = flexmock(:get_peername => nil)
|
708
|
+
sessmock = flexmock
|
709
|
+
filemock = flexmock
|
710
|
+
sessmock.should_receive(:[]).with(42).returns(filemock)
|
711
|
+
filemock.should_receive(:synchronize).with(Proc).returns { |block| block.call }
|
712
|
+
sessmock.should_receive(:clunk).with(Integer).returns do |f|
|
713
|
+
assert_equal(42, f)
|
714
|
+
end
|
715
|
+
filemock.should_receive(:parent).returns(filemock)
|
716
|
+
sessmock.should_receive(:writable?).with(filemock).returns(true)
|
717
|
+
filemock.should_receive(:remove)
|
718
|
+
sessmock.should_receive(:user).returns("foo")
|
719
|
+
filemock.should_receive(:set_mtime).with(Time, String).returns { |t,s| assert_equal("foo", s) }
|
720
|
+
serv = FakeConnection.new(selfmock, sessmock, nil)
|
721
|
+
resp = serv.tremove(RStyx::Message::Tremove.new(:fid => 42))
|
722
|
+
assert_equal(RStyx::Message::Rremove, resp.class)
|
723
|
+
end
|
724
|
+
|
725
|
+
def test_tstat
|
726
|
+
selfmock = flexmock(:get_peername => nil)
|
727
|
+
sessmock = flexmock
|
728
|
+
filemock = flexmock
|
729
|
+
filemock.should_receive(:stat)
|
730
|
+
sessmock.should_receive(:[]).with(42).returns(filemock)
|
731
|
+
serv = FakeConnection.new(selfmock, sessmock, nil)
|
732
|
+
resp = serv.tstat(RStyx::Message::Tstat.new(:fid => 42))
|
733
|
+
assert_equal(RStyx::Message::Rstat, resp.class)
|
734
|
+
end
|
735
|
+
|
736
|
+
def test_twstat_name_change_nowrite
|
737
|
+
# Test twstat for name change with no write permissions to
|
738
|
+
# parent directory
|
739
|
+
selfmock = flexmock(:get_peername => nil)
|
740
|
+
sessmock = flexmock
|
741
|
+
filemock = flexmock
|
742
|
+
sessmock.should_receive(:[]).with(42).returns(filemock)
|
743
|
+
filemock.should_receive(:synchronize).with(Proc).returns { |block| block.call }
|
744
|
+
filemock.should_receive(:parent).returns(filemock)
|
745
|
+
sessmock.should_receive(:writable?).with(filemock).returns(false)
|
746
|
+
stat = RStyx::Message::Stat.new
|
747
|
+
stat.name = "foo"
|
748
|
+
serv = FakeConnection.new(selfmock, sessmock, nil)
|
749
|
+
assert_raises(RStyx::StyxException) do
|
750
|
+
resp = serv.twstat(RStyx::Message::Twstat.new(:stat => stat, :fid => 42))
|
751
|
+
end
|
752
|
+
|
753
|
+
end
|
754
|
+
|
755
|
+
def test_twstat_name_change_conflict
|
756
|
+
# Test twstat for name change to a name of a file already
|
757
|
+
# present in the parent directory
|
758
|
+
selfmock = flexmock(:get_peername => nil)
|
759
|
+
sessmock = flexmock
|
760
|
+
filemock = flexmock
|
761
|
+
sessmock.should_receive(:[]).with(42).returns(filemock)
|
762
|
+
filemock.should_receive(:synchronize).with(Proc).returns { |block| block.call }
|
763
|
+
filemock.should_receive(:parent).returns(filemock)
|
764
|
+
sessmock.should_receive(:writable?).with(filemock).returns(true)
|
765
|
+
filemock.should_receive(:has_child?).with("foo").returns(true)
|
766
|
+
stat = RStyx::Message::Stat.new
|
767
|
+
stat.name = "foo"
|
768
|
+
serv = FakeConnection.new(selfmock, sessmock, nil)
|
769
|
+
assert_raises(RStyx::StyxException) do
|
770
|
+
resp = serv.twstat(RStyx::Message::Twstat.new(:stat => stat, :fid => 42))
|
771
|
+
end
|
772
|
+
end
|
773
|
+
|
774
|
+
def test_twstat_name_change_success
|
775
|
+
# test twstat for successful name change
|
776
|
+
selfmock = flexmock(:get_peername => nil)
|
777
|
+
sessmock = flexmock
|
778
|
+
filemock = flexmock
|
779
|
+
sessmock.should_receive(:[]).with(42).returns(filemock)
|
780
|
+
filemock.should_receive(:synchronize).with(Proc).returns { |block| block.call }
|
781
|
+
filemock.should_receive(:parent).returns(filemock)
|
782
|
+
sessmock.should_receive(:writable?).with(filemock).returns(true)
|
783
|
+
filemock.should_receive(:has_child?).with("foo").returns(false)
|
784
|
+
stat = RStyx::Message::Stat.new
|
785
|
+
stat.name = "foo"
|
786
|
+
stat.size = -1
|
787
|
+
stat.mode = RStyx::MAXUINT
|
788
|
+
stat.mtime = RStyx::MAXUINT
|
789
|
+
stat.dtype = 0xffff
|
790
|
+
stat.dev = 0xffffffff
|
791
|
+
stat.qid = RStyx::Message::Qid.new(0xff, 0xffffffff,
|
792
|
+
0xffffffffffffffff)
|
793
|
+
stat.gid = stat.uid = stat.muid = ""
|
794
|
+
stat.atime = 0xffffffff
|
795
|
+
filemock.should_receive(:can_setname?)
|
796
|
+
filemock.should_receive(:name=).with(String).returns { |s| assert_equal("foo", s) }
|
797
|
+
serv = FakeConnection.new(selfmock, sessmock, nil)
|
798
|
+
resp = serv.twstat(RStyx::Message::Twstat.new(:stat => stat, :fid => 42))
|
799
|
+
assert_equal(RStyx::Message::Rwstat, resp.class)
|
800
|
+
end
|
801
|
+
|
802
|
+
def test_twstat_size_noperm
|
803
|
+
# permission denied for file size change
|
804
|
+
# Test twstat for name change with no write permissions to
|
805
|
+
# parent directory
|
806
|
+
selfmock = flexmock(:get_peername => nil)
|
807
|
+
sessmock = flexmock
|
808
|
+
filemock = flexmock
|
809
|
+
sessmock.should_receive(:[]).with(42).returns(filemock)
|
810
|
+
filemock.should_receive(:synchronize).with(Proc).returns { |block| block.call }
|
811
|
+
sessmock.should_receive(:writable?).with(filemock).returns(false)
|
812
|
+
stat = RStyx::Message::Stat.new
|
813
|
+
stat.name = ""
|
814
|
+
stat.size = 42
|
815
|
+
serv = FakeConnection.new(selfmock, sessmock, nil)
|
816
|
+
assert_raises(RStyx::StyxException) do
|
817
|
+
resp = serv.twstat(RStyx::Message::Twstat.new(:stat => stat, :fid => 42))
|
818
|
+
end
|
819
|
+
|
820
|
+
end
|
821
|
+
|
822
|
+
def test_twstat_size_success
|
823
|
+
# test twstat for successful size change
|
824
|
+
selfmock = flexmock(:get_peername => nil)
|
825
|
+
sessmock = flexmock
|
826
|
+
filemock = flexmock
|
827
|
+
sessmock.should_receive(:[]).with(42).returns(filemock)
|
828
|
+
filemock.should_receive(:synchronize).with(Proc).returns { |block| block.call }
|
829
|
+
filemock.should_receive(:synchronize).with(Proc).returns { |block| block.call }
|
830
|
+
sessmock.should_receive(:writable?).with(filemock).returns(true)
|
831
|
+
stat = RStyx::Message::Stat.new
|
832
|
+
stat.name = ""
|
833
|
+
stat.size = 42
|
834
|
+
stat.mode = RStyx::MAXUINT
|
835
|
+
stat.mtime = RStyx::MAXUINT
|
836
|
+
stat.dtype = 0xffff
|
837
|
+
stat.dev = 0xffffffff
|
838
|
+
stat.qid = RStyx::Message::Qid.new(0xff, 0xffffffff,
|
839
|
+
0xffffffffffffffff)
|
840
|
+
stat.gid = stat.uid = stat.muid = ""
|
841
|
+
stat.atime = 0xffffffff
|
842
|
+
filemock.should_receive(:can_setlength?).with(Integer).returns { |s| assert_equal(42, s) }
|
843
|
+
filemock.should_receive(:length=).with(Integer).returns { |s| assert_equal(42, s) }
|
844
|
+
serv = FakeConnection.new(selfmock, sessmock, nil)
|
845
|
+
resp = serv.twstat(RStyx::Message::Twstat.new(:stat => stat, :fid => 42))
|
846
|
+
assert_equal(RStyx::Message::Rwstat, resp.class)
|
847
|
+
end
|
848
|
+
|
849
|
+
def test_twstat_mode_not_owner
|
850
|
+
# test twstat error condition, where mode changer is not the owner of
|
851
|
+
# the file.
|
852
|
+
selfmock = flexmock(:get_peername => nil)
|
853
|
+
sessmock = flexmock
|
854
|
+
filemock = flexmock
|
855
|
+
sessmock.should_receive(:[]).with(42).returns(filemock)
|
856
|
+
filemock.should_receive(:synchronize).with(Proc).returns { |block| block.call }
|
857
|
+
sessmock.should_receive(:user).returns("foo")
|
858
|
+
filemock.should_receive(:uid).returns("bar")
|
859
|
+
stat = RStyx::Message::Stat.new
|
860
|
+
stat.name = ""
|
861
|
+
stat.size = -1
|
862
|
+
stat.mode = 0644
|
863
|
+
serv = FakeConnection.new(selfmock, sessmock, nil)
|
864
|
+
assert_raises(RStyx::StyxException) do
|
865
|
+
resp = serv.twstat(RStyx::Message::Twstat.new(:stat => stat, :fid => 42))
|
866
|
+
end
|
867
|
+
end
|
868
|
+
|
869
|
+
def test_twstat_mode_add_dirbit
|
870
|
+
# test twstat error condition, where the mode of an ordinary file is
|
871
|
+
# to be changed to that of a directory.
|
872
|
+
selfmock = flexmock(:get_peername => nil)
|
873
|
+
sessmock = flexmock
|
874
|
+
filemock = flexmock
|
875
|
+
sessmock.should_receive(:[]).with(42).returns(filemock)
|
876
|
+
filemock.should_receive(:synchronize).with(Proc).returns { |block| block.call }
|
877
|
+
sessmock.should_receive(:user).returns("foo")
|
878
|
+
filemock.should_receive(:uid).returns("foo")
|
879
|
+
filemock.should_receive(:directory?).returns(false)
|
880
|
+
stat = RStyx::Message::Stat.new
|
881
|
+
stat.name = ""
|
882
|
+
stat.size = -1
|
883
|
+
stat.mode = 0644 | RStyx::DMDIR
|
884
|
+
serv = FakeConnection.new(selfmock, sessmock, nil)
|
885
|
+
assert_raises(RStyx::StyxException) do
|
886
|
+
resp = serv.twstat(RStyx::Message::Twstat.new(:stat => stat, :fid => 42))
|
887
|
+
end
|
888
|
+
end
|
889
|
+
|
890
|
+
def test_twstat_mode_success
|
891
|
+
# test twstat for successful mode change
|
892
|
+
selfmock = flexmock(:get_peername => nil)
|
893
|
+
sessmock = flexmock
|
894
|
+
filemock = flexmock
|
895
|
+
sessmock.should_receive(:[]).with(42).returns(filemock)
|
896
|
+
filemock.should_receive(:synchronize).with(Proc).returns { |block| block.call }
|
897
|
+
sessmock.should_receive(:user).returns("foo")
|
898
|
+
filemock.should_receive(:uid).returns("foo")
|
899
|
+
filemock.should_receive(:directory?).returns(false)
|
900
|
+
filemock.should_receive(:can_setmode?)
|
901
|
+
filemock.should_receive(:mode=).with(Integer).returns { |m| assert_equal(0644, m) }
|
902
|
+
stat = RStyx::Message::Stat.new
|
903
|
+
stat.name = ""
|
904
|
+
stat.size = -1
|
905
|
+
stat.mode = 0644
|
906
|
+
stat.mtime = RStyx::MAXUINT
|
907
|
+
stat.dtype = 0xffff
|
908
|
+
stat.dev = 0xffffffff
|
909
|
+
stat.qid = RStyx::Message::Qid.new(0xff, 0xffffffff,
|
910
|
+
0xffffffffffffffff)
|
911
|
+
stat.gid = stat.uid = stat.muid = ""
|
912
|
+
stat.atime = 0xffffffff
|
913
|
+
serv = FakeConnection.new(selfmock, sessmock, nil)
|
914
|
+
resp = serv.twstat(RStyx::Message::Twstat.new(:stat => stat, :fid => 42))
|
915
|
+
end
|
916
|
+
|
917
|
+
def test_twstat_mtime_not_owner
|
918
|
+
# test twstat error condition, where mtime changer is not the owner of
|
919
|
+
# the file.
|
920
|
+
selfmock = flexmock(:get_peername => nil)
|
921
|
+
sessmock = flexmock
|
922
|
+
filemock = flexmock
|
923
|
+
sessmock.should_receive(:[]).with(42).returns(filemock)
|
924
|
+
filemock.should_receive(:synchronize).with(Proc).returns { |block| block.call }
|
925
|
+
sessmock.should_receive(:user).returns("foo")
|
926
|
+
filemock.should_receive(:uid).returns("bar")
|
927
|
+
stat = RStyx::Message::Stat.new
|
928
|
+
stat.name = ""
|
929
|
+
stat.size = -1
|
930
|
+
stat.mode = RStyx::MAXUINT
|
931
|
+
stat.mtime = Time.now.to_i
|
932
|
+
serv = FakeConnection.new(selfmock, sessmock, nil)
|
933
|
+
assert_raises(RStyx::StyxException) do
|
934
|
+
resp = serv.twstat(RStyx::Message::Twstat.new(:stat => stat, :fid => 42))
|
935
|
+
end
|
936
|
+
end
|
937
|
+
|
938
|
+
def test_twstat_mtime_success
|
939
|
+
# test twstat for successful mtime change
|
940
|
+
selfmock = flexmock(:get_peername => nil)
|
941
|
+
sessmock = flexmock
|
942
|
+
filemock = flexmock
|
943
|
+
sessmock.should_receive(:[]).with(42).returns(filemock)
|
944
|
+
filemock.should_receive(:synchronize).with(Proc).returns { |block| block.call }
|
945
|
+
sessmock.should_receive(:user).returns("foo")
|
946
|
+
filemock.should_receive(:uid).returns("foo")
|
947
|
+
filemock.should_receive(:directory?).returns(false)
|
948
|
+
filemock.should_receive(:can_setmtime?)
|
949
|
+
filemock.should_receive(:mtime=).with(Integer).returns { |m| assert_equal(1190545938, m) }
|
950
|
+
stat = RStyx::Message::Stat.new
|
951
|
+
stat.name = ""
|
952
|
+
stat.size = -1
|
953
|
+
stat.mode = RStyx::MAXUINT
|
954
|
+
stat.mtime = 1190545938
|
955
|
+
stat.dtype = 0xffff
|
956
|
+
stat.dev = 0xffffffff
|
957
|
+
stat.qid = RStyx::Message::Qid.new(0xff, 0xffffffff,
|
958
|
+
0xffffffffffffffff)
|
959
|
+
stat.gid = stat.uid = stat.muid = ""
|
960
|
+
stat.atime = 0xffffffff
|
961
|
+
serv = FakeConnection.new(selfmock, sessmock, nil)
|
962
|
+
resp = serv.twstat(RStyx::Message::Twstat.new(:stat => stat, :fid => 42))
|
963
|
+
assert_equal(RStyx::Message::Rwstat, resp.class)
|
964
|
+
end
|
965
|
+
|
966
|
+
def test_twstat_misc_failures
|
967
|
+
# test twstat for miscellaneous failure modes
|
968
|
+
# Try to change group ID (not permitted by an RStyx server)
|
969
|
+
selfmock = flexmock(:get_peername => nil)
|
970
|
+
sessmock = flexmock
|
971
|
+
filemock = flexmock
|
972
|
+
sessmock.should_receive(:[]).with(42).returns(filemock)
|
973
|
+
filemock.should_receive(:synchronize).with(Proc).returns { |block| block.call }
|
974
|
+
stat = RStyx::Message::Stat.new
|
975
|
+
stat.name = ""
|
976
|
+
stat.size = -1
|
977
|
+
stat.mode = RStyx::MAXUINT
|
978
|
+
stat.mtime = RStyx::MAXUINT
|
979
|
+
stat.dtype = 0xfffff
|
980
|
+
stat.dev = 0xffffffff
|
981
|
+
stat.qid = RStyx::Message::Qid.new(0xff, 0xffffffff,
|
982
|
+
0xffffffffffffffff)
|
983
|
+
stat.gid = "foo"
|
984
|
+
stat.uid = stat.muid = ""
|
985
|
+
stat.atime = 0xffffffff
|
986
|
+
serv = FakeConnection.new(selfmock, sessmock, nil)
|
987
|
+
assert_raises(RStyx::StyxException) do
|
988
|
+
resp = serv.twstat(RStyx::Message::Twstat.new(:stat => stat, :fid => 42))
|
989
|
+
end
|
990
|
+
|
991
|
+
# Try changing dtype
|
992
|
+
stat = RStyx::Message::Stat.new
|
993
|
+
stat.name = ""
|
994
|
+
stat.size = -1
|
995
|
+
stat.mode = RStyx::MAXUINT
|
996
|
+
stat.mtime = RStyx::MAXUINT
|
997
|
+
stat.dtype = 0xff00
|
998
|
+
stat.dev = 0xffffffff
|
999
|
+
stat.qid = RStyx::Message::Qid.new(0xff, 0xffffffff,
|
1000
|
+
0xffffffffffffffff)
|
1001
|
+
stat.gid = stat.uid = stat.muid = ""
|
1002
|
+
stat.atime = 0xffffffff
|
1003
|
+
serv = FakeConnection.new(selfmock, sessmock, nil)
|
1004
|
+
assert_raises(RStyx::StyxException) do
|
1005
|
+
resp = serv.twstat(RStyx::Message::Twstat.new(:stat => stat, :fid => 42))
|
1006
|
+
end
|
1007
|
+
|
1008
|
+
# Try changing dev
|
1009
|
+
stat.dtype = 0xffff
|
1010
|
+
stat.dev = 0xdeadbeef
|
1011
|
+
serv = FakeConnection.new(selfmock, sessmock, nil)
|
1012
|
+
assert_raises(RStyx::StyxException) do
|
1013
|
+
resp = serv.twstat(RStyx::Message::Twstat.new(:stat => stat, :fid => 42))
|
1014
|
+
end
|
1015
|
+
|
1016
|
+
# Try changing Qid
|
1017
|
+
stat.dev = 0xffffffff
|
1018
|
+
stat.qid = RStyx::Message::Qid.new(0xfe, 0xf000baaa, 0xdeadbeeff00baaa)
|
1019
|
+
serv = FakeConnection.new(selfmock, sessmock, nil)
|
1020
|
+
assert_raises(RStyx::StyxException) do
|
1021
|
+
resp = serv.twstat(RStyx::Message::Twstat.new(:stat => stat, :fid => 42))
|
1022
|
+
end
|
1023
|
+
|
1024
|
+
# Try changing atime
|
1025
|
+
stat.qid = RStyx::Message::Qid.new(0xff, 0xffffffff,
|
1026
|
+
0xffffffffffffffff)
|
1027
|
+
stat.atime = Time.now.to_i
|
1028
|
+
assert_raises(RStyx::StyxException) do
|
1029
|
+
resp = serv.twstat(RStyx::Message::Twstat.new(:stat => stat, :fid => 42))
|
1030
|
+
end
|
1031
|
+
|
1032
|
+
# try changing uid
|
1033
|
+
stat.atime = 0xffffffff
|
1034
|
+
stat.uid = "foo"
|
1035
|
+
assert_raises(RStyx::StyxException) do
|
1036
|
+
resp = serv.twstat(RStyx::Message::Twstat.new(:stat => stat, :fid => 42))
|
1037
|
+
end
|
1038
|
+
|
1039
|
+
# try changing muid
|
1040
|
+
stat.uid = ""
|
1041
|
+
stat.muid = "foo"
|
1042
|
+
assert_raises(RStyx::StyxException) do
|
1043
|
+
resp = serv.twstat(RStyx::Message::Twstat.new(:stat => stat, :fid => 42))
|
1044
|
+
end
|
1045
|
+
|
1046
|
+
# Try an empty change
|
1047
|
+
stat.muid = ""
|
1048
|
+
resp = serv.twstat(RStyx::Message::Twstat.new(:stat => stat, :fid => 42))
|
1049
|
+
assert_equal(RStyx::Message::Rwstat, resp.class)
|
1050
|
+
end
|
1051
|
+
|
1052
|
+
def test_reply
|
1053
|
+
msg = RStyx::Message::Rversion.new(:version => "9P2000",
|
1054
|
+
:msize => 8216)
|
1055
|
+
selfmock = flexmock(:get_peername => nil)
|
1056
|
+
sessmock = flexmock
|
1057
|
+
sessmock.should_receive(:has_tag?).returns(true)
|
1058
|
+
selfmock.should_receive(:send_data).with(String).returns do |msg|
|
1059
|
+
umsg = RStyx::Message::StyxMessage.from_bytes(msg)
|
1060
|
+
assert_equal(RStyx::Message::Rversion, umsg.class)
|
1061
|
+
assert_equal("9P2000", umsg.version)
|
1062
|
+
assert_equal(8216, umsg.msize)
|
1063
|
+
assert_equal(42, umsg.tag)
|
1064
|
+
end
|
1065
|
+
sessmock.should_receive(:release_tag).with(Integer).returns { |t| assert_equal(42, t) }
|
1066
|
+
serv = FakeConnection.new(selfmock, sessmock, nil)
|
1067
|
+
resp = serv.reply(msg, 42)
|
1068
|
+
end
|
1069
|
+
|
1070
|
+
def test_process_styxmsg_badtag
|
1071
|
+
selfmock = flexmock(:get_peername => nil)
|
1072
|
+
sessmock = flexmock
|
1073
|
+
logmock = flexmock
|
1074
|
+
sessmock.should_receive(:add_tag).with(Integer).returns do |t|
|
1075
|
+
assert_equal(42, t)
|
1076
|
+
raise RStyx::TagInUseException.new(t)
|
1077
|
+
end
|
1078
|
+
logmock.should_receive(:error).with(String).returns do |s|
|
1079
|
+
assert_equal("(unknown peer) RStyx::TagInUseException (Tversion :tag=>\"42\" :msize=>\"8216\" :version=>\"9P2000\")", s)
|
1080
|
+
end
|
1081
|
+
msg = RStyx::Message::Tversion.new(:version => "9P2000",
|
1082
|
+
:msize => 8216,
|
1083
|
+
:tag => 42)
|
1084
|
+
serv = FakeConnection.new(selfmock, sessmock, nil, logmock)
|
1085
|
+
serv.process_styxmsg(msg)
|
1086
|
+
end
|
1087
|
+
|
1088
|
+
def test_process_styxmsg_badfid
|
1089
|
+
selfmock = flexmock(:get_peername => nil)
|
1090
|
+
sessmock = flexmock
|
1091
|
+
sessmock.should_receive(:add_tag).with(Integer).returns do |t|
|
1092
|
+
assert_equal(42, t)
|
1093
|
+
end
|
1094
|
+
sessmock.should_receive(:[]).with(Integer).returns do |t|
|
1095
|
+
assert_equal(42, t)
|
1096
|
+
raise RStyx::FidNotFoundException.new(t)
|
1097
|
+
end
|
1098
|
+
msg = RStyx::Message::Twrite.new(:fid => 42,
|
1099
|
+
:tag => 42)
|
1100
|
+
sessmock.should_receive(:has_tag?).returns(true)
|
1101
|
+
selfmock.should_receive(:send_data).with(String).returns do |msg|
|
1102
|
+
umsg = RStyx::Message::StyxMessage.from_bytes(msg)
|
1103
|
+
assert_equal(RStyx::Message::Rerror, umsg.class)
|
1104
|
+
end
|
1105
|
+
serv = FakeConnection.new(selfmock, sessmock, nil)
|
1106
|
+
sessmock.should_receive(:release_tag).with(Integer).returns { |t| assert_equal(42, t) }
|
1107
|
+
|
1108
|
+
serv.process_styxmsg(msg)
|
1109
|
+
end
|
1110
|
+
|
1111
|
+
def test_process_styxmsg_emptyreply
|
1112
|
+
msgmock = flexmock
|
1113
|
+
selfmock = flexmock(:get_peername => nil)
|
1114
|
+
sessmock = flexmock
|
1115
|
+
sessmock.should_receive(:add_tag).with(42)
|
1116
|
+
sessmock.should_receive(:[]).with(Integer).returns do |t|
|
1117
|
+
assert_equal(42, t)
|
1118
|
+
raise RStyx::FidNotFoundException.new(t)
|
1119
|
+
end
|
1120
|
+
sessmock.should_receive(:has_tag?).returns(true)
|
1121
|
+
selfmock.should_receive(:send_data).with(String).returns do |msg|
|
1122
|
+
umsg = RStyx::Message::StyxMessage.from_bytes(msg)
|
1123
|
+
assert_equal(RStyx::Message::Rerror, umsg.class)
|
1124
|
+
end
|
1125
|
+
selfmock.should_receive(:flexmock).returns(nil)
|
1126
|
+
msgmock.should_receive(:tag).returns(42)
|
1127
|
+
serv = FakeConnection.new(selfmock, sessmock, nil)
|
1128
|
+
sessmock.should_receive(:release_tag).with(Integer).returns { |t| assert_equal(42, t) }
|
1129
|
+
|
1130
|
+
serv.process_styxmsg(msgmock)
|
1131
|
+
end
|
1132
|
+
|
1133
|
+
def test_process_styxmsg_internalerror
|
1134
|
+
msgmock = flexmock
|
1135
|
+
selfmock = flexmock(:get_peername => nil)
|
1136
|
+
sessmock = flexmock
|
1137
|
+
sessmock.should_receive(:add_tag).with(42)
|
1138
|
+
sessmock.should_receive(:[]).with(Integer).returns do |t|
|
1139
|
+
assert_equal(42, t)
|
1140
|
+
raise RStyx::FidNotFoundException.new(t)
|
1141
|
+
end
|
1142
|
+
selfmock.should_receive(:absorber).returns(nil)
|
1143
|
+
sessmock.should_receive(:has_tag?).returns(true)
|
1144
|
+
selfmock.should_receive(:send_data).with(String).returns do |msg|
|
1145
|
+
umsg = RStyx::Message::StyxMessage.from_bytes(msg)
|
1146
|
+
assert_equal(RStyx::Message::Rerror, umsg.class)
|
1147
|
+
end
|
1148
|
+
selfmock.should_receive(:flexmock).returns { raise "error" }
|
1149
|
+
msgmock.should_receive(:tag).returns(42)
|
1150
|
+
serv = FakeConnection.new(selfmock, sessmock, nil)
|
1151
|
+
sessmock.should_receive(:release_tag).with(Integer).returns { |t| assert_equal(42, t) }
|
1152
|
+
|
1153
|
+
serv.process_styxmsg(msgmock)
|
1154
|
+
end
|
1155
|
+
|
1156
|
+
def test_process_styxmsg_success
|
1157
|
+
selfmock = flexmock(:get_peername => nil)
|
1158
|
+
sessmock = flexmock
|
1159
|
+
sessmock.should_receive(:add_tag).with(Integer).returns do |t|
|
1160
|
+
assert_equal(42, t)
|
1161
|
+
end
|
1162
|
+
sessmock.should_receive(:[]).with(Integer).returns do |t|
|
1163
|
+
assert_equal(42, t)
|
1164
|
+
end
|
1165
|
+
msg = RStyx::Message::Tclunk.new(:fid => 42, :tag => 42)
|
1166
|
+
sessmock.should_receive(:clunk).with(42)
|
1167
|
+
sessmock.should_receive(:has_tag?).returns(true)
|
1168
|
+
selfmock.should_receive(:send_data).with(String).returns do |msg|
|
1169
|
+
umsg = RStyx::Message::StyxMessage.from_bytes(msg)
|
1170
|
+
assert_equal(RStyx::Message::Rclunk, umsg.class)
|
1171
|
+
end
|
1172
|
+
serv = FakeConnection.new(selfmock, sessmock, nil)
|
1173
|
+
sessmock.should_receive(:release_tag).with(Integer).returns { |t| assert_equal(42, t) }
|
1174
|
+
|
1175
|
+
serv.process_styxmsg(msg)
|
1176
|
+
end
|
1177
|
+
|
621
1178
|
end
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.4
|
|
3
3
|
specification_version: 1
|
4
4
|
name: rstyx
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.4.
|
7
|
-
date: 2007-09-
|
6
|
+
version: 0.4.2
|
7
|
+
date: 2007-09-24 00:00:00 +08:00
|
8
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
|