Permalink
Browse files

Initial rspec specs, starting with Protocols

 * added equality methods to protocol classes to simplify testing
 * refactored build_protocol method
 * a bit of documentation for the protocols helpers
  • Loading branch information...
1 parent 22e4d41 commit e8f7b64189f4f3cdf62f5b013ff9529a7d41d2d2 @johnl committed Feb 21, 2010
Showing with 108 additions and 11 deletions.
  1. +16 −0 Rakefile
  2. +51 −11 lib/netfilter/protocols.rb
  3. +37 −0 spec/protocols_spec.rb
  4. +4 −0 spec/spec.opts
View
@@ -0,0 +1,16 @@
+require 'rubygems'
+require 'spec/rake/spectask'
+
+desc "Run all specs in spec directory"
+Spec::Rake::SpecTask.new do |t|
+ t.spec_opts = ['--options', "\"spec/spec.opts\""]
+ t.spec_files = FileList['spec/*_spec.rb']
+end
+
+require 'rake/rdoctask'
+
+Rake::RDocTask.new('rdoc') do |t|
+ t.rdoc_files.include('README.rdoc', 'lib/**/*.rb')
+ t.main = 'README.rdoc'
+ t.title = "Netfilter.rb Documentation"
+end
View
@@ -9,6 +9,14 @@ class Protocol
def protocol
self.class.const_get(:PROTOCOL)
end
+
+ def ==(b)
+ if b.respond_to? protocol
+ protocol == b.protocol
+ else
+ super
+ end
+ end
end
class ProtocolWithPort < Protocol
@@ -18,7 +26,7 @@ def initialize(port)
@port = port
end
- def to_nfargs
+ def to_nfarg
if port.is_a? Range
"#{port.min}:#{port.max}"
else
@@ -29,6 +37,11 @@ def to_nfargs
def to_nfcmdline(options = {})
"-p #{protocol} #{options[:opt]} #{to_nfarg}"
end
+
+ def ==(b)
+ port_matches = self.port == b.port if b.respond_to? :port
+ port_matches and super
+ end
end
class ProtocolWithMultiport < ProtocolWithPort
@@ -49,6 +62,14 @@ def to_nfarg
def empty?
ports.empty?
end
+
+ def ==(b)
+ if b.respond_to? :ports and b.ports.respond_to? :sort
+ ports_match = self.ports.sort == b.ports.sort
+ end
+ ports_match and super
+ end
+
end
class Udp < ProtocolWithPort
@@ -68,43 +89,62 @@ class MultiportTcp < MultiportUdp
end
class Icmp
- def initialize(type)
- @type = type
+ attr_reader :icmp_type
+ def initialize(icmp_type)
+ @icmp_type = icmp_type
end
def to_s
- "icmp.#{@type}"
+ "icmp.#{icmp_type}"
end
def to_nfcmdline(options = {})
- "-p icmp --icmp-type #{@type}"
+ "-p icmp --icmp-type #{icmp_type}"
+ end
+
+ def ==(b)
+ if b.respond_to? :icmp_type
+ type_matches = self.icmp_type == b.icmp_type
+ end
+ type_matches and super
end
end
+ # Build Tcp or MultiportTcp objects for the given ports
def tcp(*ports)
build_protocols(ports.flatten, Tcp, MultiportTcp)
end
+ # Built Udp or MultiportUdp objects for the given ports
def udp(*ports)
build_protocols(ports.flatten, Udp, MultiportUdp)
end
+ # Build Icmp objects for the given icmp types
def icmp(types)
[types].flatten.collect { |t| Icmp.new(t) }
end
+ # Build IPAddr objects for the given IP addresses. You can
+ # provide IP addresses as multiple strings, or as space separated
+ # strings.
def ip(*ips)
ips.collect { |a| a.split(/ +/).collect { |b| IPAddr.new(b) } }.flatten
end
+ # Return an array of appropriate objects representing the given
+ # ports, removing any duplicates
def build_protocols(ports, protocol, multiport_protocol)
- if ports.size > 1
- multiport = multiport_protocol.new(ports)
- ports -= multiport.ports
+ ports.uniq!
+ single_ports = ports.select { |p| p.respond_to? :to_i }
+ ranges = ports.select { |p| p.respond_to? :begin and p.respond_to? :end }
+ result = []
+ if single_ports.size == 1
+ result << protocol.new(single_ports.first)
+ elsif single_ports.size > 1
+ result << multiport_protocol.new(single_ports)
end
- ports.collect! { |p| protocol.new(p) }
- ports << multiport unless multiport.nil? or multiport.empty?
- ports
+ result += ranges.collect { |p| protocol.new(p) }
end
end
end
View
@@ -0,0 +1,37 @@
+require File.join(File.dirname(__FILE__), '../lib/netfilter')
+include Netfilter
+include Protocols
+
+describe Protocols do
+
+ describe "tcp" do
+ it "should return an array of one Tcp object when given one integer" do
+ tcp(80).size.should == 1
+ tcp(80).first.should be_a_kind_of Tcp
+ end
+
+ it "should return an array of one MultiportTcp object when given two integers" do
+ tcp(80,443).size.should == 1
+ tcp(80,443).first.should be_a_kind_of MultiportTcp
+ end
+
+ it "should return an array of one Tcp object when given a range" do
+ tcp(6667..6669).size.should == 1
+ tcp(6667..6669).first.should be_a_kind_of Tcp
+ end
+
+ it "should return an array of one Tcp object and one MultiportTcp object when given a range and two integers" do
+ result = tcp(6667..6669, 80, 443)
+ result.size.should == 2
+ result.should include Tcp.new(6667..6669)
+ result.should include MultiportTcp.new([80,443])
+ end
+
+ it "should merge all non-contiguous integer arguments into one MultiportTcp" do
+ result = tcp(80, 443, 6667..6669, 81)
+ result.size.should == 2
+ result.should include Tcp.new(6667..6669)
+ result.should include MultiportTcp.new([80,443,81])
+ end
+ end
+end
View
@@ -0,0 +1,4 @@
+--colour
+--format n
+--loadby mtime
+--reverse

0 comments on commit e8f7b64

Please sign in to comment.