diff --git a/spec/data_link_spec.rb b/spec/data_link_spec.rb index 3ee8e1b..05a302d 100644 --- a/spec/data_link_spec.rb +++ b/spec/data_link_spec.rb @@ -1,65 +1,69 @@ require 'spec_helper' describe DataLink do - before(:all) do - @datalink = DataLink.new(0) - end + subject { described_class.new(0) } it "should map datalink names to datalink layer type values" do - DataLink.name_to_val(:en10mb).should == 1 + described_class.name_to_val(:en10mb).should == 1 end it "should map datalink layer type values to datalink names" do - DataLink.val_to_name(1).should == "EN10MB" + described_class.val_to_name(1).should == "EN10MB" end it "should be initialized from a pcap datalink value" do - @datalink.name.should == 'NULL' + subject.name.should == 'NULL' end - it "should support initialization from a pcap datalink name symbol" do - @datalink = DataLink.new(:null) - DataLink.should === @datalink + it "should have a description" do + subject.description.should_not be_empty end - it "should support initialization from a pcap datalink name string" do - dl = DataLink.new('en10mb') - DataLink.should === dl - end + describe "#initialize" do + it "should support initialization from a pcap datalink name Symbol" do + link = described_class.new(:null) - it "should allow equality comparison against numeric values" do - (@datalink == 0).should == true - (@datalink == 1).should == false - end + link.name.should == 'NULL' + end - it "should allow equality comparison against String names" do - (@datalink == "null").should == true - (@datalink == "en10mb").should == false + it "should support initialization from a pcap datalink name String" do + link = described_class.new('en10mb') + + link.name.should == 'EN10MB' + end end - it "should allow equality comparison against Symbol names" do - (@datalink == :null).should == true - (@datalink == :en10mb).should == false - end + describe "#==" do + it "should allow equality comparison against numeric values" do + (subject == 0).should == true + (subject == 1).should == false + end - it "should allow comparison against another DataLink" do - (@datalink == DataLink.new(0)).should == true - (@datalink == DataLink.new(1)).should == false - end + it "should allow equality comparison against String names" do + (subject == "null").should == true + (subject == "en10mb").should == false + end - it "should still compare correctly against any other object" do - (@datalink == Object.new).should == false - end + it "should allow equality comparison against Symbol names" do + (subject == :null).should == true + (subject == :en10mb).should == false + end - it "should have a description" do - @datalink.description.should_not be_empty + it "should allow comparison against another described_class" do + (subject == described_class.new(0)).should == true + (subject == described_class.new(1)).should == false + end + + it "should still compare correctly against any other object" do + (subject == Object.new).should == false + end end it "should convert to an Integer for the DLT value" do - @datalink.to_i.should == 0 + subject.to_i.should == 0 end it "should convert to a String for the DLT name" do - @datalink.to_s.should == 'NULL' + subject.to_s.should == 'NULL' end end diff --git a/spec/dead_spec.rb b/spec/dead_spec.rb index 3526e7b..9b5a02f 100644 --- a/spec/dead_spec.rb +++ b/spec/dead_spec.rb @@ -26,9 +26,5 @@ @pcap.close end - - end - end - diff --git a/spec/error_buffer_spec.rb b/spec/error_buffer_spec.rb index e388370..c083fa6 100644 --- a/spec/error_buffer_spec.rb +++ b/spec/error_buffer_spec.rb @@ -1,17 +1,17 @@ require 'spec_helper' describe ErrorBuffer do - before(:all) do - @errbuf = ErrorBuffer.create - end + subject { ErrorBuffer.create } - it "should have a size of 256" do - @errbuf.size.should == 256 + it "should have a default size of 256" do + subject.size.should == 256 end it "should return an error message with to_s" do - @errbuf.to_s.should be_empty - FFI::PCap.pcap_open_offline("/this/file/wont/exist/#{rand(0xFFFF)}", @errbuf ) - @errbuf.to_s.should_not be_empty + subject.to_s.should be_empty + + FFI::PCap.pcap_open_offline("/this/file/wont/exist",subject) + + subject.to_s.should_not be_empty end end diff --git a/spec/file_header_spec.rb b/spec/file_header_spec.rb index 1419ee8..620a2d1 100644 --- a/spec/file_header_spec.rb +++ b/spec/file_header_spec.rb @@ -1,28 +1,27 @@ require 'spec_helper' describe FileHeader do - before(:all) do - @file_header = FileHeader.new( :raw => File.read(PCAP_TESTFILE) ) + subject do + described_class.new(:raw => File.read(PCAP_TESTFILE)) end it "should parse a pcap file correctly" do - @file_header.magic.should == 0xa1b2c3d4 - @file_header.version_major.should == 2 - @file_header.version_minor.should == 4 - @file_header.thiszone.should == 0 - @file_header.sigfigs.should == 0 - @file_header.snaplen.should == 96 - @file_header.linktype.should == 1 + subject.magic.should == 0xa1b2c3d4 + subject.version_major.should == 2 + subject.version_minor.should == 4 + subject.thiszone.should == 0 + subject.sigfigs.should == 0 + subject.snaplen.should == 96 + subject.linktype.should == 1 end it "should return a file format version string" do - String.should === @file_header.version - @file_header.version.should == "2.4" + subject.version.should == "2.4" end it "should return a DataLink for the linktype using datalink()" do - DataLink.should === @file_header.datalink - (@file_header.datalink == :en10mb).should == true - end + subject.datalink.should be_kind_of(DataLink) + (subject.datalink == :en10mb).should == true + end end diff --git a/spec/live_spec.rb b/spec/live_spec.rb index 3d80cec..9f9dc0e 100644 --- a/spec/live_spec.rb +++ b/spec/live_spec.rb @@ -26,10 +26,13 @@ it "should provide statistics about packets received/dropped" do i = 0 + @pcap.loop {|this,pkt| @pcap.stop if (i += 1) == 10 } + i.should_not == 0 + stats = @pcap.stats - Stat.should === stats + stats.should be_kind_of(Stat) stats.received.should > 0 stats.received.should >= 10 end @@ -37,17 +40,20 @@ it "should yield packets with a timestamp using loop()" do i = 0 @pkt = nil + @pcap.loop(:count => 2) do |this, pkt| this.should == @pcap pkt.should_not be_nil - Packet.should === pkt + pkt.should be_kind_of(Packet) + (Time.now - pkt.time).should_not > 1000 - i+=1 + + i += 1 end + i.should == 2 end - describe "live packets" do before(:all) do @pcap = Live.new( @@ -64,7 +70,6 @@ end it_should_behave_like "FFI::PCap::Packet populated" - end describe "yielding to a block" do @@ -78,7 +83,9 @@ end start_traffic_generator() + it_should_behave_like "FFI::PCap::CaptureWrapper" + stop_traffic_generator() @pcap.close end diff --git a/spec/offline_spec.rb b/spec/offline_spec.rb index 8d19f32..e141ac5 100644 --- a/spec/offline_spec.rb +++ b/spec/offline_spec.rb @@ -2,19 +2,17 @@ require 'wrapper_behaviors' describe Offline do - before(:each) do - @pcap = Offline.new(PCAP_TESTFILE) - end + before(:each) { @pcap = Offline.new(PCAP_TESTFILE) } - after(:each) do - @pcap.close - end + after(:each) { @pcap.close } it_should_behave_like "FFI::PCap::CaptureWrapper" it "should return a nil from next() at the end of the dump file" do i = 0 - @pcap.loop {|this,pkt| i+=1 } + + @pcap.loop {|this,pkt| i += 1 } + i.should > 0 @pcap.next.should be_nil end @@ -22,11 +20,14 @@ it "should yield packets with a timestamp using loop()" do i = 0 @pkt = nil - @pcap.loop(:count => 2) do |this, pkt| + + @pcap.loop(:count => 2) do |this,pkt| this.should == @pcap + pkt.should_not be_nil - Packet.should === pkt + pkt.should be_kind_of(Packet) pkt.time.to_i.should > 0 + i+=1 end i.should == 2 @@ -41,7 +42,6 @@ end describe "yielding to a block" do - # Note we also test all the behaviors here together instead of seperately. Offline.new(PCAP_TESTFILE) do |this| @pcap = this @@ -55,7 +55,6 @@ @pcap.close end - end end diff --git a/spec/packet_behaviors.rb b/spec/packet_behaviors.rb index 4962084..a0d29f5 100644 --- a/spec/packet_behaviors.rb +++ b/spec/packet_behaviors.rb @@ -1,28 +1,34 @@ +require 'spec_helper' shared_examples_for "FFI::PCap::Packet" do it "should supply a way to get a pointer for the body" do @pkt.body_ptr.should_not be_nil - ::FFI::Pointer.should === @pkt.body_ptr + + @pkt.body_ptr.should be_kind_of(FFI::Pointer) end it "should supply a way to get a String for the body" do @pkt.body.should_not be_nil - String.should === @pkt.body + + @pkt.body.should be_kind_of(String) end it "should supply a timestamp as a Time object" do @pkt.time.should_not be_nil - Time.should === @pkt.time + + @pkt.time.should be_kind_of(Time) end it "should allow time timestamp to be changed" do t = Time.now - lambda {@pkt.time = t}.should_not raise_error(Exception) + + @pkt.time = t @pkt.time.to_i.should == t.to_i end it "should return a deep copy of itself with copy()" do cp = @pkt.copy() + cp.object_id.should_not == @pkt.object_id cp.body_ptr.object_id.should_not == @pkt.body_ptr.object_id cp.body.should == @pkt.body @@ -56,7 +62,6 @@ it "should have a non-null body pointer" do @pkt.body_ptr.should_not be_null end - end shared_examples_for "FFI::PCap::Packet composed" do diff --git a/spec/packet_injection_spec.rb b/spec/packet_injection_spec.rb index 0a9bdb8..e02428e 100644 --- a/spec/packet_injection_spec.rb +++ b/spec/packet_injection_spec.rb @@ -3,15 +3,15 @@ describe FFI::PCap::Live do describe "packet injection" do before(:all) do - @pcap = FFI::PCap.open_live :device => PCAP_DEV, - :promisc => false, - :timeout => 100, - :snaplen => 8192 + @pcap = FFI::PCap.open_live( + :device => PCAP_DEV, + :promisc => false, + :timeout => 100, + :snaplen => 8192 + ) end - after(:all) do - @pcap.close - end + after(:all) { @pcap.close } it "should detect when an invalid argument is supplied" do lambda { @pcap.inject(Object.new)}.should raise_error(ArgumentError) @@ -26,13 +26,14 @@ it "should allow injection of a String using inject()" do test_data = "A" * 1024 + @pcap.inject(test_data).should == test_data.size end it "should allow injection of a Packet using inject()" do test_data = "B" * 512 + @pcap.inject(Packet.from_string(test_data)).should == test_data.size end - end end diff --git a/spec/packet_spec.rb b/spec/packet_spec.rb index 905c2cf..c6609be 100644 --- a/spec/packet_spec.rb +++ b/spec/packet_spec.rb @@ -5,45 +5,41 @@ describe 'created using new() with a body string and nil header' do before(:all) do @test_body = "\xde\xad\xbe\xef" - @pkt = Packet.new(nil, @test_body) + @pkt = described_class.new(nil, @test_body) end it_should_behave_like "FFI::PCap::Packet composed" - end describe 'created using new() with a Header and pointer to body' do before(:all) do @test_body = "\xde\xad\xbe\xef\xba\xbe" - l = @test_body.size - body = FFI::MemoryPointer.from_string(@test_body) - @pkt = Packet.new(PacketHeader.new(:caplen => l, :len => l), body) + + @pkt = described_class.new( + PacketHeader.new(:caplen => @test_body.size, :len => @test_body.size), + FFI::MemoryPointer.from_string(@test_body) + ) end it_should_behave_like "FFI::PCap::Packet composed" - end describe 'created with from_string()' do before(:all) do @test_body = "\xde\xad\xbe\xef" - @pkt = Packet.from_string("\xde\xad\xbe\xef") + @pkt = described_class.from_string("\xde\xad\xbe\xef") end it_should_behave_like "FFI::PCap::Packet composed" - end - describe 'provided by a libpcap savefile using next()' do before(:all) do @pcap = FFI::PCap.open_offline(PCAP_TESTFILE) @pkt = @pcap.next() end - after(:all) do - @pcap.close() - end + after(:all) { @pcap.close } it_should_behave_like "FFI::PCap::Packet populated" end @@ -52,60 +48,60 @@ before(:all) do @pcap = FFI::PCap.open_offline(PCAP_TESTFILE) @pkt = nil + # we use copy inside the loop because libpcap's loop() frees or reuses # memory for packets after each call to the handler. - @pcap.loop(:count => 1) {|this,pkt| @pkt = pkt.copy } + @pcap.loop(:count => 1) { |this,pkt| @pkt = pkt.copy } end - after(:all) do - @pcap.close() - end + after(:all) { @pcap.close() } it_should_behave_like "FFI::PCap::Packet populated" end - describe "error detection for new()" do + subject { described_class } + + let(:buffer) { FFI::MemoryPointer.new(256) } + it "should raise an error when two nil values are supplied" do - lambda { Packet.new(nil,nil)}.should raise_error(Exception) + lambda { subject.new(nil,nil)}.should raise_error(Exception) end it "should raise an error for an invalid header" do lambda { - Packet.new(Object.new, FFI::MemoryPointer.new(256)) + subject.new(Object.new, buffer) }.should raise_error(Exception) end it "should raise an error for a nil header without a string body" do lambda { - Packet.new(nil, FFI::MemoryPointer.new(256)) + subject.new(nil, buffer) }.should raise_error(Exception) end it "should raise an error for a valid header but an invalid body pointer" do lambda { - Packet.new(PacketHeader.new, "hellotest") + subject.new(PacketHeader.new, "hellotest") }.should raise_error(Exception) end it "should not raise an error for a PacketHeader and a pointer" do lambda { - Packet.new(PacketHeader.new, FFI::MemoryPointer.new(256)) + subject.new(PacketHeader.new, buffer) }.should_not raise_error(Exception) end it "should not raise an error for a pointer and a pointer" do lambda { - Packet.new(FFI::MemoryPointer.new(20), FFI::MemoryPointer.new(256)) + subject.new(FFI::MemoryPointer.new(20), buffer) }.should_not raise_error(Exception) end it "should not raise an error for a nil and a string" do lambda { - Packet.new(nil, "hellothere") + subject.new(nil, "hellothere") }.should_not raise_error(Exception) - end - end end diff --git a/spec/pcap_spec.rb b/spec/pcap_spec.rb index 4f62afd..f1cfdc5 100644 --- a/spec/pcap_spec.rb +++ b/spec/pcap_spec.rb @@ -1,28 +1,31 @@ require 'spec_helper' describe FFI::PCap do + subject { described_class } + it ".lib_version() should expose the libpcap version banner" do - FFI::PCap.lib_version.should_not be_nil - FFI::PCap.lib_version.should_not be_empty + subject.lib_version.should_not be_nil + subject.lib_version.should_not be_empty end it ".lib_version_number() should expose the libpcap version number only" do - FFI::PCap.lib_version_number.should_not be_nil - FFI::PCap.lib_version_number.should_not be_empty - FFI::PCap.lib_version_number.should =~ /^\d+\.\d+\.\d+$/ + subject.lib_version_number.should =~ /^\d+\.\d+\.\d+$/ end it ".lookupdev() should return a device default device" do - dev = FFI::PCap.lookupdev + dev = subject.lookupdev + dev.should_not be_nil dev.should_not be_empty end it ".each_device() should enumerate over all usable interfaces" do i = 0 - FFI::PCap.each_device do |dev| + + subject.each_device do |dev| dev.should_not be_nil - Interface.should === dev + dev.should be_kind_of(Interface) + [true,false].include?(dev.loopback?).should == true i+=1 end @@ -30,39 +33,44 @@ end it ".device_names() should return names for all network interfaces" do - devs = FFI::PCap.device_names - Array.should === devs + devs = subject.device_names + devs.should be_kind_of(Array) + i = 0 + devs.each do |dev| - String.should === dev - dev.should_not be_nil + dev.should be_kind_of(String) dev.should_not be_empty - i+=1 + + i += 1 end + i.should_not == 0 devs.include?(PCAP_DEV).should == true end it ".dump_devices() should return name/network pairs for all interfaces" do i = 0 - devs = FFI::PCap.dump_devices - Array.should === devs - devs.each do |y| - y.size.should == 2 - dev, net = y - String.should === dev - dev.should_not be_nil + + devs = subject.dump_devices + devs.should be_kind_of(Array) + + devs.each do |(dev,net)| + dev.should be_kind_of(String) dev.should_not be_empty - i+=1 + + i += 1 end + i.should_not == 0 + devs.select{|dev,net| not net.nil? }.should_not be_empty devs.map{|dev,net| dev}.include?(PCAP_DEV).should == true end it ".open_live() should open a live pcap handler given a chosen device" do lambda { - pcap = FFI::PCap.open_live(:device => PCAP_DEV) + pcap = subject.open_live(:device => PCAP_DEV) pcap.device.should == PCAP_DEV pcap.close }.should_not raise_error(Exception) @@ -73,7 +81,7 @@ # XXX Using Vista and wpcap.dll this breaks on me. # The lookupdev for a default adapter result is '\', which is just # wrong. - pcap = FFI::PCap.open_live() + pcap = subject.open_live() pcap.should be_ready pcap.close }.should_not raise_error(Exception) @@ -81,7 +89,7 @@ it ".open_dead() should open a dead pcap handler" do lambda { - pcap = FFI::PCap.open_dead() + pcap = subject.open_dead() pcap.should be_ready pcap.close }.should_not raise_error(Exception) @@ -89,7 +97,7 @@ it ".open_offline() should open a pcap dump file" do lambda { - pcap = FFI::PCap.open_offline(PCAP_TESTFILE) + pcap = subject.open_offline(PCAP_TESTFILE) pcap.should be_ready pcap.close }.should_not raise_error(Exception) @@ -97,7 +105,7 @@ it ".open_file() should work the same as .open_offline()" do lambda { - pcap = FFI::PCap.open_offline(PCAP_TESTFILE) + pcap = subject.open_offline(PCAP_TESTFILE) pcap.should be_ready pcap.close }.should_not raise_error(Exception) @@ -105,12 +113,15 @@ it ".open_live() should take a block and close the device after calling it" do pcap = nil - ret = FFI::PCap.open_live(:device => PCAP_DEV) {|this| - Live.should === this + + ret = subject.open_live(:device => PCAP_DEV) do |this| + this.should be_kind_of(Live) this.should be_ready this.should_not be_closed + pcap = this - } + end + ret.should be_nil pcap.should_not be_ready pcap.should be_closed @@ -118,12 +129,15 @@ it ".open_dead() should take a block and close the device after calling it" do pcap = nil - ret = FFI::PCap.open_dead() {|this| - Dead.should === this + + ret = subject.open_dead() do |this| + this.should be_kind_of(Dead) this.should be_ready this.should_not be_closed + pcap = this - } + end + ret.should be_nil pcap.should_not be_ready ret.should be_nil @@ -131,15 +145,17 @@ it ".open_file() should take a block and close the device after calling it" do pcap = nil - ret = FFI::PCap.open_file(PCAP_TESTFILE) {|this| - Offline.should === this + + ret = subject.open_file(PCAP_TESTFILE) do |this| + this.should be_kind_of(Offline) this.should be_ready this.should_not be_closed + pcap = this - } + end + ret.should be_nil pcap.should_not be_ready ret.should be_nil end - end diff --git a/spec/wrapper_behaviors.rb b/spec/wrapper_behaviors.rb index 5f1d9c6..a42a306 100644 --- a/spec/wrapper_behaviors.rb +++ b/spec/wrapper_behaviors.rb @@ -67,11 +67,9 @@ @pcap.close }.should_not raise_error(Exception) end - end shared_examples_for "FFI::PCap::CaptureWrapper" do - it "should pass packets to a block using loop()" do i = 0 @pkt = nil @@ -121,4 +119,3 @@ it_should_behave_like "FFI::PCap::CommonWrapper" end -