tlspretense 0.6.1
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/.document +6 -0
- data/.gitignore +7 -0
- data/.rspec +1 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +41 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +231 -0
- data/Rakefile +44 -0
- data/bin/makeder.sh +6 -0
- data/bin/tlspretense +7 -0
- data/bin/view.sh +3 -0
- data/doc/general_setup.rdoc +288 -0
- data/doc/linux_setup.rdoc +64 -0
- data/lib/certmaker.rb +61 -0
- data/lib/certmaker/certificate_factory.rb +106 -0
- data/lib/certmaker/certificate_suite_generator.rb +120 -0
- data/lib/certmaker/ext_core/hash_indifferent_fetch.rb +12 -0
- data/lib/certmaker/runner.rb +27 -0
- data/lib/certmaker/tasks.rb +20 -0
- data/lib/packetthief.rb +167 -0
- data/lib/packetthief/handlers.rb +14 -0
- data/lib/packetthief/handlers/abstract_ssl_handler.rb +249 -0
- data/lib/packetthief/handlers/proxy_redirector.rb +26 -0
- data/lib/packetthief/handlers/ssl_client.rb +87 -0
- data/lib/packetthief/handlers/ssl_server.rb +174 -0
- data/lib/packetthief/handlers/ssl_smart_proxy.rb +143 -0
- data/lib/packetthief/handlers/ssl_transparent_proxy.rb +225 -0
- data/lib/packetthief/handlers/transparent_proxy.rb +183 -0
- data/lib/packetthief/impl.rb +11 -0
- data/lib/packetthief/impl/ipfw.rb +140 -0
- data/lib/packetthief/impl/manual.rb +54 -0
- data/lib/packetthief/impl/netfilter.rb +109 -0
- data/lib/packetthief/impl/pf_divert.rb +168 -0
- data/lib/packetthief/impl/pf_rdr.rb +192 -0
- data/lib/packetthief/logging.rb +49 -0
- data/lib/packetthief/redirect_rule.rb +29 -0
- data/lib/packetthief/util.rb +36 -0
- data/lib/ssl_test.rb +21 -0
- data/lib/ssl_test/app_context.rb +17 -0
- data/lib/ssl_test/certificate_manager.rb +33 -0
- data/lib/ssl_test/config.rb +79 -0
- data/lib/ssl_test/ext_core/io_raw_input.rb +31 -0
- data/lib/ssl_test/input_handler.rb +35 -0
- data/lib/ssl_test/runner.rb +110 -0
- data/lib/ssl_test/runner_options.rb +68 -0
- data/lib/ssl_test/ssl_test_case.rb +46 -0
- data/lib/ssl_test/ssl_test_report.rb +24 -0
- data/lib/ssl_test/ssl_test_result.rb +30 -0
- data/lib/ssl_test/test_listener.rb +140 -0
- data/lib/ssl_test/test_manager.rb +116 -0
- data/lib/tlspretense.rb +13 -0
- data/lib/tlspretense/app.rb +52 -0
- data/lib/tlspretense/init_runner.rb +115 -0
- data/lib/tlspretense/skel/ca/goodcacert.pem +19 -0
- data/lib/tlspretense/skel/ca/goodcakey.pem +27 -0
- data/lib/tlspretense/skel/config.yml +523 -0
- data/lib/tlspretense/version.rb +3 -0
- data/packetthief_examples/em_ssl_test.rb +73 -0
- data/packetthief_examples/redirector.rb +29 -0
- data/packetthief_examples/setup_iptables.sh +24 -0
- data/packetthief_examples/ssl_client_simple.rb +27 -0
- data/packetthief_examples/ssl_server_simple.rb +44 -0
- data/packetthief_examples/ssl_smart_proxy.rb +115 -0
- data/packetthief_examples/ssl_transparent_proxy.rb +97 -0
- data/packetthief_examples/transparent_proxy.rb +56 -0
- data/spec/packetthief/impl/ipfw_spec.rb +98 -0
- data/spec/packetthief/impl/manual_spec.rb +65 -0
- data/spec/packetthief/impl/netfilter_spec.rb +66 -0
- data/spec/packetthief/impl/pf_divert_spec.rb +82 -0
- data/spec/packetthief/impl/pf_rdr_spec.rb +133 -0
- data/spec/packetthief/logging_spec.rb +78 -0
- data/spec/packetthief_spec.rb +47 -0
- data/spec/spec_helper.rb +53 -0
- data/spec/ssl_test/certificate_manager_spec.rb +222 -0
- data/spec/ssl_test/config_spec.rb +76 -0
- data/spec/ssl_test/runner_spec.rb +360 -0
- data/spec/ssl_test/ssl_test_case_spec.rb +113 -0
- data/spec/ssl_test/test_listener_spec.rb +199 -0
- data/spec/ssl_test/test_manager_spec.rb +324 -0
- data/tlspretense.gemspec +35 -0
- metadata +262 -0
@@ -0,0 +1,199 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__),'..','spec_helper'))
|
2
|
+
require 'certmaker'
|
3
|
+
|
4
|
+
# quick and dirty. just create the fields we need.
|
5
|
+
def quickcertmaker(hostname, altnames=nil)
|
6
|
+
cert = OpenSSL::X509::Certificate.new
|
7
|
+
cert.version = 2
|
8
|
+
cert.subject = OpenSSL::X509::Name.parse("C=US, CN=#{hostname}")
|
9
|
+
ef = OpenSSL::X509::ExtensionFactory.new
|
10
|
+
ef.subject_certificate = cert
|
11
|
+
cert.add_extension(ef.create_ext_from_string("subjectAltName = #{altnames}")) if altnames
|
12
|
+
cert
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
module SSLTest
|
17
|
+
describe TestListener do
|
18
|
+
let(:tcpsocket) { double('tcpsocket') }
|
19
|
+
let(:cacert) { double('cacert') }
|
20
|
+
let(:cakey) { double('cakey') }
|
21
|
+
let(:hosttotest) { double('hosttotest') }
|
22
|
+
let(:chaintotest) { [ double('hostcert'), double('intermediatecert'), cacert] }
|
23
|
+
let(:keytotest) { double('keytotest') }
|
24
|
+
|
25
|
+
let(:appcontext) { double('appcontext') }
|
26
|
+
let(:curr_test) { double('curr_test',
|
27
|
+
:id => 'curr_test',
|
28
|
+
:hosttotest => hosttotest,
|
29
|
+
:certchain => chaintotest,
|
30
|
+
:keychain => [keytotest],
|
31
|
+
:cacert => cacert,
|
32
|
+
:cakey => cakey,
|
33
|
+
) }
|
34
|
+
let(:test_manager) { double('test_manager',
|
35
|
+
:paused? => false,
|
36
|
+
:current_test => curr_test,
|
37
|
+
:test_completed => nil,
|
38
|
+
:testing_method => 'senddata',
|
39
|
+
:goodcacert => double('goodcacert'),
|
40
|
+
:goodcakey => double('goodcakey')
|
41
|
+
) }
|
42
|
+
|
43
|
+
# Yes this is bad, but there are too many side effects to calling into
|
44
|
+
# the parent class right now.
|
45
|
+
before(:each) do
|
46
|
+
# PacketThief::Handlers::SSLSmartProxy.any_instance.stub(:initialize)
|
47
|
+
# PacketThief::Handlers::SSLSmartProxy.any_instance.stub(:tls_successful_handshake)
|
48
|
+
# PacketThief::Handlers::SSLSmartProxy.any_instance.stub(:tls_failed_handshake)
|
49
|
+
# PacketThief::Handlers::SSLSmartProxy.any_instance.stub(:unbind)
|
50
|
+
class PacketThief::Handlers::SSLSmartProxy
|
51
|
+
def initialize(socket, certchain, key, logger=nil)
|
52
|
+
end
|
53
|
+
|
54
|
+
def tls_successful_handshake
|
55
|
+
end
|
56
|
+
|
57
|
+
def tls_failed_handshake(e)
|
58
|
+
end
|
59
|
+
|
60
|
+
def unbind
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
subject do
|
66
|
+
_tcpsocket, _appcontext, _testmanager = tcpsocket, appcontext, test_manager
|
67
|
+
TestListener.allocate.instance_eval do
|
68
|
+
initialize(_tcpsocket, _testmanager)
|
69
|
+
self
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe ".cert_matches_host" do
|
74
|
+
context "when the CN in the subject is 'my.hostname.com'" do
|
75
|
+
let(:cert) { quickcertmaker("my.hostname.com") }
|
76
|
+
|
77
|
+
it {TestListener.cert_matches_host(cert, 'my.hostname.com').should == true}
|
78
|
+
it {TestListener.cert_matches_host(cert, 'my.HosTname.Com').should == true}
|
79
|
+
it {TestListener.cert_matches_host(cert, 'my2.hostname.com').should == false}
|
80
|
+
|
81
|
+
context "when another.hostname.com is in the subjectAltName" do
|
82
|
+
let(:cert) { quickcertmaker("my.hostname.com", "DNS:another.hostname.com, DNS:my.hostname.com") }
|
83
|
+
|
84
|
+
it {TestListener.cert_matches_host(cert, 'my.hostname.com').should == true}
|
85
|
+
it {TestListener.cert_matches_host(cert, 'my.HosTname.Com').should == true}
|
86
|
+
it {TestListener.cert_matches_host(cert, 'my2.hostname.com').should == false}
|
87
|
+
it {TestListener.cert_matches_host(cert, 'another.hostname.com').should == true}
|
88
|
+
it {TestListener.cert_matches_host(cert, 'another2.hostname.com').should == false}
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe "#check_for_hosttotest" do
|
94
|
+
context "when the certificate of the destination matches" do
|
95
|
+
before(:each) do
|
96
|
+
TestListener.stub(:cert_matches_host).and_return(true)
|
97
|
+
end
|
98
|
+
|
99
|
+
it "Returns a context where the certificate data matches the hostotest" do
|
100
|
+
@context = OpenSSL::SSL::SSLContext.new
|
101
|
+
@context.cert = double('resigned remote cert', :subject => double('resigned remote cert subject'))
|
102
|
+
@context.key = cakey
|
103
|
+
@context.extra_chain_cert = [cacert]
|
104
|
+
|
105
|
+
@newcontext = subject.check_for_hosttotest(@context)
|
106
|
+
|
107
|
+
@newcontext.cert.should == chaintotest[0]
|
108
|
+
@newcontext.key.should == keytotest
|
109
|
+
@newcontext.extra_chain_cert.should == chaintotest[1..-1]
|
110
|
+
end
|
111
|
+
end
|
112
|
+
context "when the certificate of the destination does not match" do
|
113
|
+
before(:each) do
|
114
|
+
TestListener.stub(:cert_matches_host).and_return(false)
|
115
|
+
end
|
116
|
+
|
117
|
+
it "Returns an unchanged context" do
|
118
|
+
@context = OpenSSL::SSL::SSLContext.new
|
119
|
+
@remotecert = double('resigned remote cert', :subject => double('resigned remote cert subject'))
|
120
|
+
@context.cert = @remotecert
|
121
|
+
@context.key = cakey
|
122
|
+
@context.extra_chain_cert = [cacert]
|
123
|
+
|
124
|
+
@newcontext = subject.check_for_hosttotest(@context)
|
125
|
+
|
126
|
+
@newcontext.cert.should == @remotecert
|
127
|
+
@newcontext.key.should == cakey
|
128
|
+
@newcontext.extra_chain_cert.should == [cacert]
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
context "when the test manager reports that testing is paused" do
|
133
|
+
before(:each) do
|
134
|
+
test_manager.stub(:paused?).and_return(true)
|
135
|
+
end
|
136
|
+
|
137
|
+
it "returns an unchanged context" do
|
138
|
+
@context = OpenSSL::SSL::SSLContext.new
|
139
|
+
@remotecert = double('resigned remote cert', :subject => double('resigned remote cert subject'))
|
140
|
+
@context.cert = @remotecert
|
141
|
+
@context.key = cakey
|
142
|
+
@context.extra_chain_cert = [cacert]
|
143
|
+
|
144
|
+
@newcontext = subject.check_for_hosttotest(@context)
|
145
|
+
|
146
|
+
@newcontext.cert.should == @remotecert
|
147
|
+
@newcontext.key.should == cakey
|
148
|
+
@newcontext.extra_chain_cert.should == [cacert]
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
end
|
153
|
+
|
154
|
+
describe "reporting the result" do
|
155
|
+
context "when a test listener's connection is to the host to test" do
|
156
|
+
before(:each) do
|
157
|
+
TestListener.stub(:cert_matches_host).and_return(true)
|
158
|
+
@ctx = OpenSSL::SSL::SSLContext.new
|
159
|
+
@ctx.cert = double('dest cert', :subject => double('dest cert subject'))
|
160
|
+
subject.check_for_hosttotest(@ctx)
|
161
|
+
end
|
162
|
+
context "when the client connects" do
|
163
|
+
before(:each) do
|
164
|
+
subject.tls_successful_handshake
|
165
|
+
end
|
166
|
+
|
167
|
+
it "calls the test_manager's test_completed callback with :connected when the connection closes" do
|
168
|
+
test_manager.should_receive(:test_completed).with(test_manager.current_test, :connected)
|
169
|
+
|
170
|
+
subject.unbind
|
171
|
+
end
|
172
|
+
end
|
173
|
+
context "when the client rejects" do
|
174
|
+
it "calls the test_manager's test_completed callback with :rejected" do
|
175
|
+
test_manager.should_receive(:test_completed).with(test_manager.current_test, :rejected)
|
176
|
+
|
177
|
+
subject.tls_failed_handshake(double('error'))
|
178
|
+
end
|
179
|
+
end
|
180
|
+
context "when the client sends data" do
|
181
|
+
context "when the testing_method is 'senddata'" do
|
182
|
+
before(:each) do
|
183
|
+
test_manager.stub(:testing_method).and_return('senddata')
|
184
|
+
end
|
185
|
+
it "client_recv calls the test_manager's test_completed callback with :sentdata" do
|
186
|
+
subject.stub(:send_to_dest)
|
187
|
+
|
188
|
+
test_manager.should_receive(:test_completed).with(test_manager.current_test, :sentdata)
|
189
|
+
|
190
|
+
subject.client_recv(double('data'))
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
end
|
199
|
+
end
|
@@ -0,0 +1,324 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__),'..','spec_helper'))
|
2
|
+
|
3
|
+
module SSLTest
|
4
|
+
describe TestManager do
|
5
|
+
|
6
|
+
let(:config) do
|
7
|
+
double("config",
|
8
|
+
:dest_port => 443,
|
9
|
+
:listener_port => 54321,
|
10
|
+
:hosttotest => "my.hostname.com",
|
11
|
+
:packetthief => {
|
12
|
+
:protocol => 'tcp',
|
13
|
+
:dest_port => 443,
|
14
|
+
:in_interface => 'en1'
|
15
|
+
},
|
16
|
+
:testing_method => 'tlshandshake',
|
17
|
+
:pause? => false
|
18
|
+
)
|
19
|
+
end
|
20
|
+
let(:certchain) { double('certchain') }
|
21
|
+
let(:keychain) { [ double('firstkey'), double('secondkey'), double('cakey') ] }
|
22
|
+
let(:goodcacert) { double('goodcacert') }
|
23
|
+
let(:goodcakey) { double('goodcakey') }
|
24
|
+
let(:cert_manager) do
|
25
|
+
@cert_manager = double(
|
26
|
+
"cert_manager",
|
27
|
+
:get_chain => certchain,
|
28
|
+
:get_keychain => keychain,
|
29
|
+
:get_cert => double('cert'),
|
30
|
+
:get_key => double('key')
|
31
|
+
)
|
32
|
+
@cert_manager.stub(:get_cert).with('goodca').and_return(goodcacert)
|
33
|
+
@cert_manager.stub(:get_key).with('goodca').and_return(goodcakey)
|
34
|
+
@cert_manager
|
35
|
+
end
|
36
|
+
let(:logger) { Logger.new(nil) }
|
37
|
+
let(:app_context) { AppContext.new(config, cert_manager, logger) }
|
38
|
+
let(:report) { double('report', :add_result => nil) }
|
39
|
+
let(:listener) { double('listener') }
|
40
|
+
|
41
|
+
let(:foo_test_data) do
|
42
|
+
{
|
43
|
+
'alias' => 'foo',
|
44
|
+
'name' => 'test foo',
|
45
|
+
'certchain' => [ 'a', 'b' ]
|
46
|
+
}
|
47
|
+
end
|
48
|
+
let(:bar_test_data) do
|
49
|
+
{
|
50
|
+
'alias' => 'bar',
|
51
|
+
'name' => 'test bar',
|
52
|
+
'certchain' => [ 'c', 'd' ]
|
53
|
+
}
|
54
|
+
end
|
55
|
+
let(:foo_test) { double('foo test',
|
56
|
+
:expected_result => 'connected',
|
57
|
+
:id => 'foo',
|
58
|
+
:description => 'foo test',
|
59
|
+
) }
|
60
|
+
let(:bar_test) { double('bar test',
|
61
|
+
:expected_result => 'connected',
|
62
|
+
:id => 'bar',
|
63
|
+
:description => 'bar test',
|
64
|
+
) }
|
65
|
+
let(:conf_tests_data) { [ foo_test_data, bar_test_data ] }
|
66
|
+
let(:testlist) { [foo_test, bar_test] }
|
67
|
+
|
68
|
+
subject { TestManager.new(app_context, testlist, report) }
|
69
|
+
|
70
|
+
|
71
|
+
describe "#prepare_next_test" do
|
72
|
+
|
73
|
+
context "when there are 3 tests in the testlist" do
|
74
|
+
let(:testlist) { [ double('test1', :id => 'test1'), double('test2', :id => 'test2'), double('test3', :id => 'test3') ] }
|
75
|
+
it "sets current_test to the first element of remaining_tests" do
|
76
|
+
subject.current_test.should == testlist[0]
|
77
|
+
subject.remaining_tests.should == [testlist[1], testlist[2]]
|
78
|
+
|
79
|
+
subject.prepare_next_test
|
80
|
+
|
81
|
+
subject.current_test.should == testlist[1]
|
82
|
+
subject.remaining_tests.should == [testlist[2]]
|
83
|
+
end
|
84
|
+
|
85
|
+
context "when the application does not want to pause after each test" do
|
86
|
+
before(:each) { config.stub(:pause?).and_return(false) }
|
87
|
+
it "does not set paused to true" do
|
88
|
+
subject.prepare_next_test
|
89
|
+
|
90
|
+
subject.paused?.should == false
|
91
|
+
end
|
92
|
+
end
|
93
|
+
context "when the application wants to pause after each test" do
|
94
|
+
before(:each) { config.stub(:pause?).and_return(true) }
|
95
|
+
|
96
|
+
it "does not set paused to true after initialization" do
|
97
|
+
subject
|
98
|
+
|
99
|
+
subject.paused?.should_not == true
|
100
|
+
end
|
101
|
+
|
102
|
+
it "sets paused to true" do
|
103
|
+
subject.prepare_next_test
|
104
|
+
|
105
|
+
subject.paused?.should == true
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context "when there are no tests remaining" do
|
111
|
+
let(:testlist) { [double('test1', :id => 'test1')] }
|
112
|
+
it "stops testing" do
|
113
|
+
subject.should_receive(:stop_testing)
|
114
|
+
|
115
|
+
subject.prepare_next_test
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
120
|
+
|
121
|
+
describe "#test_completed" do
|
122
|
+
let(:result) { double("result", :description= => nil,
|
123
|
+
:expected_result= => nil, :actual_result= => nil,
|
124
|
+
:start_time= => nil, :stop_time= => nil) }
|
125
|
+
before(:each) do
|
126
|
+
SSLTestResult.stub(:new).and_return(result)
|
127
|
+
end
|
128
|
+
|
129
|
+
context "when the current test is 'foo'" do
|
130
|
+
before(:each) do
|
131
|
+
subject.current_test = foo_test
|
132
|
+
end
|
133
|
+
|
134
|
+
context "when the expected result is a successful connection" do
|
135
|
+
|
136
|
+
context "when the listener reports success" do
|
137
|
+
it "creates a result that reports passing" do
|
138
|
+
|
139
|
+
SSLTestResult.should_receive(:new).with('foo', true).and_return(result)
|
140
|
+
result.should_receive(:description=).with('foo test')
|
141
|
+
result.should_receive(:expected_result=).with('connected')
|
142
|
+
result.should_receive(:actual_result=).with('connected')
|
143
|
+
result.should_receive(:start_time=)
|
144
|
+
result.should_receive(:stop_time=)
|
145
|
+
|
146
|
+
subject.test_completed(subject.current_test, :connected)
|
147
|
+
end
|
148
|
+
it "adds the result to a report" do
|
149
|
+
|
150
|
+
report.should_receive(:add_result).with(result)
|
151
|
+
|
152
|
+
subject.test_completed(subject.current_test, :connected)
|
153
|
+
end
|
154
|
+
|
155
|
+
it "prepares for the next test" do
|
156
|
+
subject.should_receive(:prepare_next_test)
|
157
|
+
|
158
|
+
subject.test_completed(subject.current_test, :connected)
|
159
|
+
end
|
160
|
+
|
161
|
+
end
|
162
|
+
|
163
|
+
context "when the listener reports rejected" do
|
164
|
+
it "creates a result that reports not passing" do
|
165
|
+
SSLTestResult.should_receive(:new).with('foo', false).and_return(result)
|
166
|
+
result.should_receive(:description=).with('foo test')
|
167
|
+
result.should_receive(:expected_result=).with('connected')
|
168
|
+
result.should_receive(:actual_result=).with('rejected')
|
169
|
+
result.should_receive(:start_time=)
|
170
|
+
result.should_receive(:stop_time=)
|
171
|
+
|
172
|
+
subject.test_completed(subject.current_test, :rejected)
|
173
|
+
end
|
174
|
+
it "adds the result to a report" do
|
175
|
+
report.should_receive(:add_result).with(result)
|
176
|
+
|
177
|
+
subject.test_completed(subject.current_test, :rejected)
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
context "when the listener reports a still running test that has stopped" do
|
182
|
+
it "just returns" do
|
183
|
+
SSLTestResult.should_not_receive(:new)
|
184
|
+
|
185
|
+
subject.test_completed(subject.current_test, :running)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
context "when the listener reports connected" do
|
189
|
+
it "creates a result that reports passing" do
|
190
|
+
SSLTestResult.should_receive(:new).with('foo', true).and_return(result)
|
191
|
+
|
192
|
+
subject.test_completed(subject.current_test, :connected)
|
193
|
+
end
|
194
|
+
end
|
195
|
+
context "when the listener reports sentdata" do
|
196
|
+
it "creates a result that reports passing" do
|
197
|
+
SSLTestResult.should_receive(:new).with('foo', true).and_return(result)
|
198
|
+
|
199
|
+
subject.test_completed(subject.current_test, :sentdata)
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
end
|
204
|
+
|
205
|
+
context "when the configuration requires the client to send data for it to consider it to be connected" do
|
206
|
+
before(:each) do
|
207
|
+
config.stub(:testing_method).and_return('senddata')
|
208
|
+
end
|
209
|
+
context "when the expected result is a successful connection" do
|
210
|
+
before(:each) do
|
211
|
+
foo_test.stub(:expected_result).and_return('connected')
|
212
|
+
end
|
213
|
+
|
214
|
+
context "when the listener reports rejected" do
|
215
|
+
it "creates a result that reports not passing" do
|
216
|
+
SSLTestResult.should_receive(:new).with('foo', false).and_return(result)
|
217
|
+
|
218
|
+
subject.test_completed(subject.current_test, :rejected)
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
context "when the listener reports connected" do
|
223
|
+
it "creates a result that reports not passing" do
|
224
|
+
SSLTestResult.should_receive(:new).with('foo', false).and_return(result)
|
225
|
+
|
226
|
+
subject.test_completed(subject.current_test, :connected)
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
context "when the listener reports sentdata" do
|
231
|
+
it "creates a result that reports passing" do
|
232
|
+
SSLTestResult.should_receive(:new).with('foo', true).and_return(result)
|
233
|
+
|
234
|
+
subject.test_completed(subject.current_test, :sentdata)
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
end
|
239
|
+
context "when the expected result is a rejected connection" do
|
240
|
+
before(:each) do
|
241
|
+
foo_test.stub(:expected_result).and_return('rejected')
|
242
|
+
end
|
243
|
+
|
244
|
+
context "when the listener reports rejected" do
|
245
|
+
it "creates a result that reports not passing" do
|
246
|
+
SSLTestResult.should_receive(:new).with('foo', true).and_return(result)
|
247
|
+
|
248
|
+
subject.test_completed(subject.current_test, :rejected)
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
context "when the listener reports connected" do
|
253
|
+
it "creates a result that reports not passing" do
|
254
|
+
SSLTestResult.should_receive(:new).with('foo', true).and_return(result)
|
255
|
+
|
256
|
+
subject.test_completed(subject.current_test, :connected)
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
context "when the listener reports sentdata" do
|
261
|
+
it "creates a result that reports passing" do
|
262
|
+
SSLTestResult.should_receive(:new).with('foo', false).and_return(result)
|
263
|
+
|
264
|
+
subject.test_completed(subject.current_test, :sentdata)
|
265
|
+
end
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
context "when the test passed in is the current_test" do
|
271
|
+
it "progresses to the next test" do
|
272
|
+
subject.should_receive(:prepare_next_test)
|
273
|
+
|
274
|
+
subject.test_completed(subject.current_test, :sentdata)
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
context "when the test passed in to test_completed is 'bar'" do
|
279
|
+
it "does not progress the current test to the next test" do
|
280
|
+
subject.should_not_receive(:prepare_next_test)
|
281
|
+
|
282
|
+
subject.test_completed(bar_test, :sentdata)
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
describe "#unpause" do
|
290
|
+
context "when the manager is paused" do
|
291
|
+
before(:each) do
|
292
|
+
config.stub(:pause?).and_return(true)
|
293
|
+
subject.prepare_next_test
|
294
|
+
end
|
295
|
+
|
296
|
+
it "unpauses the manager" do
|
297
|
+
subject.unpause
|
298
|
+
|
299
|
+
subject.paused?.should == false
|
300
|
+
end
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
describe "#stop_testing" do
|
305
|
+
before(:each) do
|
306
|
+
EM.stub(:stop_event_loop)
|
307
|
+
end
|
308
|
+
context "when the manager is bound to a listener" do
|
309
|
+
before(:each) { subject.listener = listener }
|
310
|
+
it "stops the listener" do
|
311
|
+
listener.should_receive(:stop_server)
|
312
|
+
|
313
|
+
subject.stop_testing
|
314
|
+
end
|
315
|
+
end
|
316
|
+
it "stops event machine" do
|
317
|
+
EM.should_receive(:stop_event_loop)
|
318
|
+
|
319
|
+
subject.stop_testing
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
323
|
+
end
|
324
|
+
end
|