ffi-pcap 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. data/.gitignore +2 -1
  2. data/.pkg_ignore +25 -0
  3. data/.rspec +1 -0
  4. data/.specopts +1 -0
  5. data/.yardopts +1 -0
  6. data/{ChangeLog.rdoc → ChangeLog.md} +15 -5
  7. data/LICENSE.txt +1 -4
  8. data/README.md +92 -0
  9. data/Rakefile +30 -20
  10. data/examples/em_selectable_pcap.rb +38 -0
  11. data/examples/em_timer.rb +26 -0
  12. data/examples/ipfw_divert.rb +28 -8
  13. data/examples/print_bytes.rb +5 -1
  14. data/examples/replay.rb +11 -0
  15. data/examples/selectable_pcap.rb +29 -0
  16. data/ffi-pcap.gemspec +60 -0
  17. data/gemspec.yml +23 -0
  18. data/lib/ffi/pcap.rb +7 -13
  19. data/lib/ffi/pcap/addr.rb +16 -15
  20. data/lib/ffi/pcap/bpf_instruction.rb +25 -0
  21. data/lib/ffi/pcap/bpf_program.rb +85 -0
  22. data/lib/ffi/pcap/bsd.rb +9 -98
  23. data/lib/ffi/pcap/bsd/af.rb +18 -0
  24. data/lib/ffi/pcap/bsd/in6_addr.rb +16 -0
  25. data/lib/ffi/pcap/bsd/in_addr.rb +18 -0
  26. data/lib/ffi/pcap/bsd/sock_addr.rb +19 -0
  27. data/lib/ffi/pcap/bsd/sock_addr_dl.rb +24 -0
  28. data/lib/ffi/pcap/bsd/sock_addr_family.rb +19 -0
  29. data/lib/ffi/pcap/bsd/sock_addr_in.rb +21 -0
  30. data/lib/ffi/pcap/bsd/sock_addr_in6.rb +20 -0
  31. data/lib/ffi/pcap/bsd/typedefs.rb +7 -0
  32. data/lib/ffi/pcap/capture_wrapper.rb +296 -256
  33. data/lib/ffi/pcap/common_wrapper.rb +152 -127
  34. data/lib/ffi/pcap/copy_handler.rb +32 -32
  35. data/lib/ffi/pcap/crt.rb +7 -10
  36. data/lib/ffi/pcap/data_link.rb +178 -153
  37. data/lib/ffi/pcap/dead.rb +42 -29
  38. data/lib/ffi/pcap/dumper.rb +39 -41
  39. data/lib/ffi/pcap/error_buffer.rb +21 -36
  40. data/lib/ffi/pcap/exceptions.rb +21 -15
  41. data/lib/ffi/pcap/file_header.rb +24 -18
  42. data/lib/ffi/pcap/in_addr.rb +4 -4
  43. data/lib/ffi/pcap/interface.rb +22 -20
  44. data/lib/ffi/pcap/live.rb +296 -252
  45. data/lib/ffi/pcap/offline.rb +50 -43
  46. data/lib/ffi/pcap/packet.rb +186 -143
  47. data/lib/ffi/pcap/packet_header.rb +20 -18
  48. data/lib/ffi/pcap/pcap.rb +269 -212
  49. data/lib/ffi/pcap/stat.rb +19 -49
  50. data/lib/ffi/pcap/stat_ex.rb +42 -0
  51. data/lib/ffi/pcap/time_val.rb +52 -38
  52. data/lib/ffi/pcap/typedefs.rb +16 -20
  53. data/spec/data_link_spec.rb +39 -35
  54. data/spec/dead_spec.rb +0 -4
  55. data/spec/error_buffer_spec.rb +7 -9
  56. data/spec/file_header_spec.rb +17 -14
  57. data/spec/live_spec.rb +12 -5
  58. data/spec/offline_spec.rb +10 -11
  59. data/spec/packet_behaviors.rb +20 -6
  60. data/spec/packet_injection_spec.rb +9 -8
  61. data/spec/packet_spec.rb +22 -26
  62. data/spec/pcap_spec.rb +52 -40
  63. data/spec/spec_helper.rb +16 -5
  64. data/spec/wrapper_behaviors.rb +0 -3
  65. data/tasks/doc.rake +69 -0
  66. data/tasks/gem.rake +200 -0
  67. data/tasks/git.rake +40 -0
  68. data/tasks/post_load.rake +34 -0
  69. data/tasks/rubyforge.rake +55 -0
  70. data/tasks/setup.rb +286 -0
  71. data/tasks/spec.rake +54 -0
  72. data/tasks/svn.rake +47 -0
  73. data/tasks/test.rake +40 -0
  74. metadata +142 -92
  75. data/README.rdoc +0 -30
  76. data/VERSION +0 -1
  77. data/lib/ffi/pcap/bpf.rb +0 -106
  78. data/lib/ffi/pcap/version.rb +0 -6
  79. data/tasks/rcov.rb +0 -6
  80. data/tasks/rdoc.rb +0 -17
  81. data/tasks/spec.rb +0 -9
  82. data/tasks/yard.rb +0 -21
@@ -26,10 +26,13 @@ describe Live do
26
26
 
27
27
  it "should provide statistics about packets received/dropped" do
28
28
  i = 0
29
+
29
30
  @pcap.loop {|this,pkt| @pcap.stop if (i += 1) == 10 }
31
+
30
32
  i.should_not == 0
33
+
31
34
  stats = @pcap.stats
32
- Stat.should === stats
35
+ stats.should be_kind_of(Stat)
33
36
  stats.received.should > 0
34
37
  stats.received.should >= 10
35
38
  end
@@ -37,17 +40,20 @@ describe Live do
37
40
  it "should yield packets with a timestamp using loop()" do
38
41
  i = 0
39
42
  @pkt = nil
43
+
40
44
  @pcap.loop(:count => 2) do |this, pkt|
41
45
  this.should == @pcap
42
46
  pkt.should_not be_nil
43
- Packet.should === pkt
47
+ pkt.should be_kind_of(Packet)
48
+
44
49
  (Time.now - pkt.time).should_not > 1000
45
- i+=1
50
+
51
+ i += 1
46
52
  end
53
+
47
54
  i.should == 2
48
55
  end
49
56
 
50
-
51
57
  describe "live packets" do
52
58
  before(:all) do
53
59
  @pcap = Live.new(
@@ -64,7 +70,6 @@ describe Live do
64
70
  end
65
71
 
66
72
  it_should_behave_like "FFI::PCap::Packet populated"
67
-
68
73
  end
69
74
 
70
75
  describe "yielding to a block" do
@@ -78,7 +83,9 @@ describe Live do
78
83
  end
79
84
 
80
85
  start_traffic_generator()
86
+
81
87
  it_should_behave_like "FFI::PCap::CaptureWrapper"
88
+
82
89
  stop_traffic_generator()
83
90
  @pcap.close
84
91
  end
@@ -2,19 +2,17 @@ require 'spec_helper'
2
2
  require 'wrapper_behaviors'
3
3
 
4
4
  describe Offline do
5
- before(:each) do
6
- @pcap = Offline.new(PCAP_TESTFILE)
7
- end
5
+ before(:each) { @pcap = Offline.new(PCAP_TESTFILE) }
8
6
 
9
- after(:each) do
10
- @pcap.close
11
- end
7
+ after(:each) { @pcap.close }
12
8
 
13
9
  it_should_behave_like "FFI::PCap::CaptureWrapper"
14
10
 
15
11
  it "should return a nil from next() at the end of the dump file" do
16
12
  i = 0
17
- @pcap.loop {|this,pkt| i+=1 }
13
+
14
+ @pcap.loop {|this,pkt| i += 1 }
15
+
18
16
  i.should > 0
19
17
  @pcap.next.should be_nil
20
18
  end
@@ -22,11 +20,14 @@ describe Offline do
22
20
  it "should yield packets with a timestamp using loop()" do
23
21
  i = 0
24
22
  @pkt = nil
25
- @pcap.loop(:count => 2) do |this, pkt|
23
+
24
+ @pcap.loop(:count => 2) do |this,pkt|
26
25
  this.should == @pcap
26
+
27
27
  pkt.should_not be_nil
28
- Packet.should === pkt
28
+ pkt.should be_kind_of(Packet)
29
29
  pkt.time.to_i.should > 0
30
+
30
31
  i+=1
31
32
  end
32
33
  i.should == 2
@@ -41,7 +42,6 @@ describe Offline do
41
42
  end
42
43
 
43
44
  describe "yielding to a block" do
44
-
45
45
  # Note we also test all the behaviors here together instead of seperately.
46
46
  Offline.new(PCAP_TESTFILE) do |this|
47
47
  @pcap = this
@@ -55,7 +55,6 @@ describe Offline do
55
55
 
56
56
  @pcap.close
57
57
  end
58
-
59
58
  end
60
59
  end
61
60
 
@@ -1,32 +1,47 @@
1
+ require 'spec_helper'
1
2
 
2
3
  shared_examples_for "FFI::PCap::Packet" do
3
4
  it "should supply a way to get a pointer for the body" do
4
5
  @pkt.body_ptr.should_not be_nil
5
- ::FFI::Pointer.should === @pkt.body_ptr
6
+
7
+ @pkt.body_ptr.should be_kind_of(FFI::Pointer)
6
8
  end
7
9
 
8
10
  it "should supply a way to get a String for the body" do
9
11
  @pkt.body.should_not be_nil
10
- String.should === @pkt.body
12
+
13
+ @pkt.body.should be_kind_of(String)
11
14
  end
12
15
 
13
16
  it "should supply a timestamp as a Time object" do
14
17
  @pkt.time.should_not be_nil
15
- Time.should === @pkt.time
18
+
19
+ @pkt.time.should be_kind_of(Time)
16
20
  end
17
21
 
18
22
  it "should allow time timestamp to be changed" do
19
23
  t = Time.now
20
- lambda {@pkt.time = t}.should_not raise_error(Exception)
21
- @pkt.time.should == t
24
+
25
+ @pkt.time = t
26
+ @pkt.time.to_i.should == t.to_i
22
27
  end
23
28
 
24
29
  it "should return a deep copy of itself with copy()" do
25
30
  cp = @pkt.copy()
31
+
26
32
  cp.object_id.should_not == @pkt.object_id
27
33
  cp.body_ptr.object_id.should_not == @pkt.body_ptr.object_id
28
34
  cp.body.should == @pkt.body
29
35
  end
36
+
37
+ it "should marshal and umarshal" do
38
+ m = Marshal.dump(@pkt)
39
+ unm = Marshal.load(m)
40
+
41
+ unm.should be_kind_of(@pkt.class)
42
+ unm.time.to_i.should == @pkt.time.to_i
43
+ unm.body.should == @pkt.body
44
+ end
30
45
  end
31
46
 
32
47
  shared_examples_for "FFI::PCap::Packet populated" do
@@ -47,7 +62,6 @@ shared_examples_for "FFI::PCap::Packet populated" do
47
62
  it "should have a non-null body pointer" do
48
63
  @pkt.body_ptr.should_not be_null
49
64
  end
50
-
51
65
  end
52
66
 
53
67
  shared_examples_for "FFI::PCap::Packet composed" do
@@ -3,15 +3,15 @@ require 'spec_helper'
3
3
  describe FFI::PCap::Live do
4
4
  describe "packet injection" do
5
5
  before(:all) do
6
- @pcap = FFI::PCap.open_live :device => PCAP_DEV,
7
- :promisc => false,
8
- :timeout => 100,
9
- :snaplen => 8192
6
+ @pcap = FFI::PCap.open_live(
7
+ :device => PCAP_DEV,
8
+ :promisc => false,
9
+ :timeout => 100,
10
+ :snaplen => 8192
11
+ )
10
12
  end
11
13
 
12
- after(:all) do
13
- @pcap.close
14
- end
14
+ after(:all) { @pcap.close }
15
15
 
16
16
  it "should detect when an invalid argument is supplied" do
17
17
  lambda { @pcap.inject(Object.new)}.should raise_error(ArgumentError)
@@ -26,13 +26,14 @@ describe FFI::PCap::Live do
26
26
 
27
27
  it "should allow injection of a String using inject()" do
28
28
  test_data = "A" * 1024
29
+
29
30
  @pcap.inject(test_data).should == test_data.size
30
31
  end
31
32
 
32
33
  it "should allow injection of a Packet using inject()" do
33
34
  test_data = "B" * 512
35
+
34
36
  @pcap.inject(Packet.from_string(test_data)).should == test_data.size
35
37
  end
36
-
37
38
  end
38
39
  end
@@ -5,45 +5,41 @@ describe Packet do
5
5
  describe 'created using new() with a body string and nil header' do
6
6
  before(:all) do
7
7
  @test_body = "\xde\xad\xbe\xef"
8
- @pkt = Packet.new(nil, @test_body)
8
+ @pkt = described_class.new(nil, @test_body)
9
9
  end
10
10
 
11
11
  it_should_behave_like "FFI::PCap::Packet composed"
12
-
13
12
  end
14
13
 
15
14
  describe 'created using new() with a Header and pointer to body' do
16
15
  before(:all) do
17
16
  @test_body = "\xde\xad\xbe\xef\xba\xbe"
18
- l = @test_body.size
19
- body = FFI::MemoryPointer.from_string(@test_body)
20
- @pkt = Packet.new(PacketHeader.new(:caplen => l, :len => l), body)
17
+
18
+ @pkt = described_class.new(
19
+ PacketHeader.new(:caplen => @test_body.size, :len => @test_body.size),
20
+ FFI::MemoryPointer.from_string(@test_body)
21
+ )
21
22
  end
22
23
 
23
24
  it_should_behave_like "FFI::PCap::Packet composed"
24
-
25
25
  end
26
26
 
27
27
  describe 'created with from_string()' do
28
28
  before(:all) do
29
29
  @test_body = "\xde\xad\xbe\xef"
30
- @pkt = Packet.from_string("\xde\xad\xbe\xef")
30
+ @pkt = described_class.from_string("\xde\xad\xbe\xef")
31
31
  end
32
32
 
33
33
  it_should_behave_like "FFI::PCap::Packet composed"
34
-
35
34
  end
36
35
 
37
-
38
36
  describe 'provided by a libpcap savefile using next()' do
39
37
  before(:all) do
40
38
  @pcap = FFI::PCap.open_offline(PCAP_TESTFILE)
41
39
  @pkt = @pcap.next()
42
40
  end
43
41
 
44
- after(:all) do
45
- @pcap.close()
46
- end
42
+ after(:all) { @pcap.close }
47
43
 
48
44
  it_should_behave_like "FFI::PCap::Packet populated"
49
45
  end
@@ -52,60 +48,60 @@ describe Packet do
52
48
  before(:all) do
53
49
  @pcap = FFI::PCap.open_offline(PCAP_TESTFILE)
54
50
  @pkt = nil
51
+
55
52
  # we use copy inside the loop because libpcap's loop() frees or reuses
56
53
  # memory for packets after each call to the handler.
57
- @pcap.loop(:count => 1) {|this,pkt| @pkt = pkt.copy }
54
+ @pcap.loop(:count => 1) { |this,pkt| @pkt = pkt.copy }
58
55
  end
59
56
 
60
- after(:all) do
61
- @pcap.close()
62
- end
57
+ after(:all) { @pcap.close() }
63
58
 
64
59
  it_should_behave_like "FFI::PCap::Packet populated"
65
60
  end
66
61
 
67
-
68
62
  describe "error detection for new()" do
63
+ subject { described_class }
64
+
65
+ let(:buffer) { FFI::MemoryPointer.new(256) }
66
+
69
67
  it "should raise an error when two nil values are supplied" do
70
- lambda { Packet.new(nil,nil)}.should raise_error(Exception)
68
+ lambda { subject.new(nil,nil)}.should raise_error(Exception)
71
69
  end
72
70
 
73
71
  it "should raise an error for an invalid header" do
74
72
  lambda {
75
- Packet.new(Object.new, FFI::MemoryPointer.new(256))
73
+ subject.new(Object.new, buffer)
76
74
  }.should raise_error(Exception)
77
75
  end
78
76
 
79
77
  it "should raise an error for a nil header without a string body" do
80
78
  lambda {
81
- Packet.new(nil, FFI::MemoryPointer.new(256))
79
+ subject.new(nil, buffer)
82
80
  }.should raise_error(Exception)
83
81
  end
84
82
 
85
83
  it "should raise an error for a valid header but an invalid body pointer" do
86
84
  lambda {
87
- Packet.new(PacketHeader.new, "hellotest")
85
+ subject.new(PacketHeader.new, "hellotest")
88
86
  }.should raise_error(Exception)
89
87
  end
90
88
 
91
89
  it "should not raise an error for a PacketHeader and a pointer" do
92
90
  lambda {
93
- Packet.new(PacketHeader.new, FFI::MemoryPointer.new(256))
91
+ subject.new(PacketHeader.new, buffer)
94
92
  }.should_not raise_error(Exception)
95
93
  end
96
94
 
97
95
  it "should not raise an error for a pointer and a pointer" do
98
96
  lambda {
99
- Packet.new(FFI::MemoryPointer.new(20), FFI::MemoryPointer.new(256))
97
+ subject.new(FFI::MemoryPointer.new(20), buffer)
100
98
  }.should_not raise_error(Exception)
101
99
  end
102
100
 
103
101
  it "should not raise an error for a nil and a string" do
104
102
  lambda {
105
- Packet.new(nil, "hellothere")
103
+ subject.new(nil, "hellothere")
106
104
  }.should_not raise_error(Exception)
107
-
108
105
  end
109
-
110
106
  end
111
107
  end
@@ -1,32 +1,31 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe FFI::PCap do
4
- it "should define a VERSION constant" do
5
- FFI::PCap.const_defined?('VERSION').should == true
6
- end
4
+ subject { described_class }
7
5
 
8
6
  it ".lib_version() should expose the libpcap version banner" do
9
- FFI::PCap.lib_version.should_not be_nil
10
- FFI::PCap.lib_version.should_not be_empty
7
+ subject.lib_version.should_not be_nil
8
+ subject.lib_version.should_not be_empty
11
9
  end
12
10
 
13
11
  it ".lib_version_number() should expose the libpcap version number only" do
14
- FFI::PCap.lib_version_number.should_not be_nil
15
- FFI::PCap.lib_version_number.should_not be_empty
16
- FFI::PCap.lib_version_number.should =~ /^\d+\.\d+\.\d+$/
12
+ subject.lib_version_number.should =~ /^\d+\.\d+\.\d+$/
17
13
  end
18
14
 
19
- it ".lookupdev() should return a device deafult device" do
20
- dev = FFI::PCap.lookupdev
15
+ it ".lookupdev() should return a device default device" do
16
+ dev = subject.lookupdev
17
+
21
18
  dev.should_not be_nil
22
19
  dev.should_not be_empty
23
20
  end
24
21
 
25
22
  it ".each_device() should enumerate over all usable interfaces" do
26
23
  i = 0
27
- FFI::PCap.each_device do |dev|
24
+
25
+ subject.each_device do |dev|
28
26
  dev.should_not be_nil
29
- Interface.should === dev
27
+ dev.should be_kind_of(Interface)
28
+
30
29
  [true,false].include?(dev.loopback?).should == true
31
30
  i+=1
32
31
  end
@@ -34,39 +33,44 @@ describe FFI::PCap do
34
33
  end
35
34
 
36
35
  it ".device_names() should return names for all network interfaces" do
37
- devs = FFI::PCap.device_names
38
- Array.should === devs
36
+ devs = subject.device_names
37
+ devs.should be_kind_of(Array)
38
+
39
39
  i = 0
40
+
40
41
  devs.each do |dev|
41
- String.should === dev
42
- dev.should_not be_nil
42
+ dev.should be_kind_of(String)
43
43
  dev.should_not be_empty
44
- i+=1
44
+
45
+ i += 1
45
46
  end
47
+
46
48
  i.should_not == 0
47
49
  devs.include?(PCAP_DEV).should == true
48
50
  end
49
51
 
50
52
  it ".dump_devices() should return name/network pairs for all interfaces" do
51
53
  i = 0
52
- devs = FFI::PCap.dump_devices
53
- Array.should === devs
54
- devs.each do |y|
55
- y.size.should == 2
56
- dev, net = y
57
- String.should === dev
58
- dev.should_not be_nil
54
+
55
+ devs = subject.dump_devices
56
+ devs.should be_kind_of(Array)
57
+
58
+ devs.each do |(dev,net)|
59
+ dev.should be_kind_of(String)
59
60
  dev.should_not be_empty
60
- i+=1
61
+
62
+ i += 1
61
63
  end
64
+
62
65
  i.should_not == 0
66
+
63
67
  devs.select{|dev,net| not net.nil? }.should_not be_empty
64
68
  devs.map{|dev,net| dev}.include?(PCAP_DEV).should == true
65
69
  end
66
70
 
67
71
  it ".open_live() should open a live pcap handler given a chosen device" do
68
72
  lambda {
69
- pcap = FFI::PCap.open_live(:device => PCAP_DEV)
73
+ pcap = subject.open_live(:device => PCAP_DEV)
70
74
  pcap.device.should == PCAP_DEV
71
75
  pcap.close
72
76
  }.should_not raise_error(Exception)
@@ -77,7 +81,7 @@ describe FFI::PCap do
77
81
  # XXX Using Vista and wpcap.dll this breaks on me.
78
82
  # The lookupdev for a default adapter result is '\', which is just
79
83
  # wrong.
80
- pcap = FFI::PCap.open_live()
84
+ pcap = subject.open_live()
81
85
  pcap.should be_ready
82
86
  pcap.close
83
87
  }.should_not raise_error(Exception)
@@ -85,7 +89,7 @@ describe FFI::PCap do
85
89
 
86
90
  it ".open_dead() should open a dead pcap handler" do
87
91
  lambda {
88
- pcap = FFI::PCap.open_dead()
92
+ pcap = subject.open_dead()
89
93
  pcap.should be_ready
90
94
  pcap.close
91
95
  }.should_not raise_error(Exception)
@@ -93,7 +97,7 @@ describe FFI::PCap do
93
97
 
94
98
  it ".open_offline() should open a pcap dump file" do
95
99
  lambda {
96
- pcap = FFI::PCap.open_offline(PCAP_TESTFILE)
100
+ pcap = subject.open_offline(PCAP_TESTFILE)
97
101
  pcap.should be_ready
98
102
  pcap.close
99
103
  }.should_not raise_error(Exception)
@@ -101,7 +105,7 @@ describe FFI::PCap do
101
105
 
102
106
  it ".open_file() should work the same as .open_offline()" do
103
107
  lambda {
104
- pcap = FFI::PCap.open_offline(PCAP_TESTFILE)
108
+ pcap = subject.open_offline(PCAP_TESTFILE)
105
109
  pcap.should be_ready
106
110
  pcap.close
107
111
  }.should_not raise_error(Exception)
@@ -109,12 +113,15 @@ describe FFI::PCap do
109
113
 
110
114
  it ".open_live() should take a block and close the device after calling it" do
111
115
  pcap = nil
112
- ret = FFI::PCap.open_live(:device => PCAP_DEV) {|this|
113
- Live.should === this
116
+
117
+ ret = subject.open_live(:device => PCAP_DEV) do |this|
118
+ this.should be_kind_of(Live)
114
119
  this.should be_ready
115
120
  this.should_not be_closed
121
+
116
122
  pcap = this
117
- }
123
+ end
124
+
118
125
  ret.should be_nil
119
126
  pcap.should_not be_ready
120
127
  pcap.should be_closed
@@ -122,12 +129,15 @@ describe FFI::PCap do
122
129
 
123
130
  it ".open_dead() should take a block and close the device after calling it" do
124
131
  pcap = nil
125
- ret = FFI::PCap.open_dead() {|this|
126
- Dead.should === this
132
+
133
+ ret = subject.open_dead() do |this|
134
+ this.should be_kind_of(Dead)
127
135
  this.should be_ready
128
136
  this.should_not be_closed
137
+
129
138
  pcap = this
130
- }
139
+ end
140
+
131
141
  ret.should be_nil
132
142
  pcap.should_not be_ready
133
143
  ret.should be_nil
@@ -135,15 +145,17 @@ describe FFI::PCap do
135
145
 
136
146
  it ".open_file() should take a block and close the device after calling it" do
137
147
  pcap = nil
138
- ret = FFI::PCap.open_file(PCAP_TESTFILE) {|this|
139
- Offline.should === this
148
+
149
+ ret = subject.open_file(PCAP_TESTFILE) do |this|
150
+ this.should be_kind_of(Offline)
140
151
  this.should be_ready
141
152
  this.should_not be_closed
153
+
142
154
  pcap = this
143
- }
155
+ end
156
+
144
157
  ret.should be_nil
145
158
  pcap.should_not be_ready
146
159
  ret.should be_nil
147
160
  end
148
-
149
161
  end