recog 3.1.1 → 3.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/Gemfile +6 -0
- data/Rakefile +7 -5
- data/lib/recog/db.rb +67 -68
- data/lib/recog/db_manager.rb +22 -21
- data/lib/recog/fingerprint/regexp_factory.rb +10 -13
- data/lib/recog/fingerprint/test.rb +9 -8
- data/lib/recog/fingerprint.rb +252 -262
- data/lib/recog/fingerprint_parse_error.rb +3 -1
- data/lib/recog/formatter.rb +41 -39
- data/lib/recog/match_reporter.rb +82 -83
- data/lib/recog/matcher.rb +37 -40
- data/lib/recog/matcher_factory.rb +7 -6
- data/lib/recog/nizer.rb +218 -224
- data/lib/recog/verifier.rb +30 -28
- data/lib/recog/verify_reporter.rb +69 -73
- data/lib/recog/version.rb +3 -1
- data/lib/recog.rb +2 -0
- data/recog/bin/recog_match +21 -20
- data/recog/xml/apache_modules.xml +2 -0
- data/recog/xml/dhcp_vendor_class.xml +1 -1
- data/recog/xml/favicons.xml +133 -1
- data/recog/xml/ftp_banners.xml +1 -1
- data/recog/xml/html_title.xml +140 -1
- data/recog/xml/http_cookies.xml +20 -2
- data/recog/xml/http_servers.xml +38 -17
- data/recog/xml/http_wwwauth.xml +17 -4
- data/recog/xml/mdns_device-info_txt.xml +49 -15
- data/recog/xml/sip_banners.xml +0 -2
- data/recog/xml/sip_user_agents.xml +1 -1
- data/recog/xml/snmp_sysdescr.xml +1 -2
- data/recog/xml/ssh_banners.xml +8 -0
- data/recog/xml/telnet_banners.xml +3 -2
- data/recog/xml/tls_jarm.xml +1 -1
- data/recog/xml/x11_banners.xml +1 -0
- data/recog/xml/x509_issuers.xml +1 -1
- data/recog/xml/x509_subjects.xml +0 -1
- data/recog.gemspec +14 -13
- data/spec/lib/recog/db_spec.rb +37 -36
- data/spec/lib/recog/fingerprint/regexp_factory_spec.rb +19 -20
- data/spec/lib/recog/fingerprint_spec.rb +44 -42
- data/spec/lib/recog/formatter_spec.rb +20 -18
- data/spec/lib/recog/match_reporter_spec.rb +35 -30
- data/spec/lib/recog/nizer_spec.rb +85 -101
- data/spec/lib/recog/verify_reporter_spec.rb +45 -44
- data/spec/spec_helper.rb +2 -1
- data.tar.gz.sig +1 -3
- metadata +3 -3
- metadata.gz.sig +0 -0
@@ -1,37 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'recog'
|
2
4
|
require 'yaml'
|
3
5
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
NOMATCH_TYPE = {match_key: 'smb.native_os', protocol: 'smb', database_type: 'no_such_987'}
|
6
|
+
VALID_FILTER = { match_key: 'smb.native_os', protocol: 'smb', database_type: 'util.os' }.freeze
|
7
|
+
NOMATCH_MATCH_KEY = { match_key: 'no_such_987', protocol: 'smb', database_type: 'util.os' }.freeze
|
8
|
+
NOMATCH_PROTO = { match_key: 'smb.native_os', protocol: 'no_such_987', database_type: 'util.os' }.freeze
|
9
|
+
NOMATCH_TYPE = { match_key: 'smb.native_os', protocol: 'smb', database_type: 'no_such_987' }.freeze
|
9
10
|
|
10
11
|
describe Recog::Nizer do
|
11
12
|
subject { described_class }
|
12
13
|
|
13
|
-
describe
|
14
|
+
describe '.match' do
|
14
15
|
File.readlines(File.expand_path(File.join('spec', 'data', 'smb_native_os.txt'))).each do |line|
|
15
16
|
data = line.strip
|
16
17
|
context "with smb_native_os:#{data}" do
|
17
18
|
let(:match_result) { subject.match('smb.native_os', data) }
|
18
19
|
|
19
|
-
it
|
20
|
+
it 'returns a hash' do
|
20
21
|
expect(match_result.class).to eq(::Hash)
|
21
22
|
end
|
22
23
|
|
23
|
-
it
|
24
|
+
it 'returns a successful match' do
|
24
25
|
expect(match_result['matched'].to_s).to match(/^[A-Z]/)
|
25
26
|
end
|
26
27
|
|
27
|
-
it
|
28
|
-
if data =~ /^Windows/
|
29
|
-
expect(match_result['os.product']).to match(/^Windows/)
|
30
|
-
end
|
28
|
+
it 'correctly matches service or os' do
|
29
|
+
expect(match_result['os.product']).to match(/^Windows/) if data =~ /^Windows/
|
31
30
|
end
|
32
31
|
|
33
32
|
let(:nomatch_result) { subject.match('smb.native_os', 'no_such_987_76tgklh') }
|
34
|
-
it
|
33
|
+
it 'returns a nil when data cannot be matched' do
|
35
34
|
expect(nomatch_result).to be_nil
|
36
35
|
end
|
37
36
|
|
@@ -43,51 +42,47 @@ describe Recog::Nizer do
|
|
43
42
|
end
|
44
43
|
|
45
44
|
line = 'non-existent'
|
46
|
-
context
|
47
|
-
let(:match_result) {subject.match('smb.native_os', line) }
|
48
|
-
it
|
45
|
+
context 'with non-existent match' do
|
46
|
+
let(:match_result) { subject.match('smb.native_os', line) }
|
47
|
+
it 'returns a nil' do
|
49
48
|
expect(match_result).to be_nil
|
50
49
|
end
|
51
50
|
end
|
52
51
|
end
|
53
52
|
|
54
|
-
describe
|
53
|
+
describe '.match_all_db' do
|
55
54
|
File.readlines(File.expand_path(File.join('spec', 'data', 'smb_native_os.txt'))).each do |line|
|
56
55
|
data = line.strip
|
57
56
|
context "with smb_native_os:#{data}" do
|
58
57
|
let(:match_all_result) { subject.match_all_db(data, VALID_FILTER) }
|
59
58
|
|
60
|
-
it
|
59
|
+
it 'returns an array' do
|
61
60
|
expect(match_all_result.class).to eq(::Array)
|
62
61
|
end
|
63
62
|
|
64
|
-
it
|
63
|
+
it 'returns a successful match' do
|
65
64
|
expect(match_all_result[0]['matched']).to match(/^[A-Z]/)
|
66
65
|
end
|
67
66
|
|
68
|
-
it
|
69
|
-
if data =~ /^Windows/
|
70
|
-
expect(match_all_result[0]['os.product']).to match(/^Windows/)
|
71
|
-
end
|
67
|
+
it 'correctly matches service or os' do
|
68
|
+
expect(match_all_result[0]['os.product']).to match(/^Windows/) if data =~ /^Windows/
|
72
69
|
end
|
73
70
|
|
74
|
-
it
|
71
|
+
it 'correctly matches protocol' do
|
75
72
|
expect(match_all_result[0]['service.protocol']).to eq('smb')
|
76
73
|
end
|
77
74
|
|
78
75
|
let(:no_filter_result) { subject.match_all_db(data) }
|
79
|
-
it
|
76
|
+
it 'returns an array when searching without a filter' do
|
80
77
|
expect(no_filter_result.class).to eq(::Array)
|
81
78
|
end
|
82
79
|
|
83
|
-
it
|
80
|
+
it 'returns a successful match when searching without a filter' do
|
84
81
|
expect(no_filter_result[0]['matched']).to match(/^[A-Z]/)
|
85
82
|
end
|
86
83
|
|
87
|
-
it
|
88
|
-
if data =~ /^Windows/
|
89
|
-
expect(no_filter_result[0]['os.product']).to match(/^Windows/)
|
90
|
-
end
|
84
|
+
it 'correctly matches service or os when searching without a filter' do
|
85
|
+
expect(no_filter_result[0]['os.product']).to match(/^Windows/) if data =~ /^Windows/
|
91
86
|
end
|
92
87
|
|
93
88
|
let(:nomatch_db_result) { subject.match_all_db(data, NOMATCH_MATCH_KEY) }
|
@@ -117,214 +112,203 @@ describe Recog::Nizer do
|
|
117
112
|
end
|
118
113
|
|
119
114
|
line = 'non-existent'
|
120
|
-
context
|
121
|
-
let(:match_result) {subject.match_all_db(line) }
|
122
|
-
it
|
115
|
+
context 'with non-existent match' do
|
116
|
+
let(:match_result) { subject.match_all_db(line) }
|
117
|
+
it 'returns an array' do
|
123
118
|
expect(match_result.class).to eq(::Array)
|
124
119
|
end
|
125
|
-
it
|
120
|
+
it 'returns an empty array' do
|
126
121
|
expect(match_result).to be_empty
|
127
122
|
end
|
128
123
|
end
|
129
124
|
end
|
130
125
|
|
131
|
-
describe
|
126
|
+
describe '.multi_match' do
|
132
127
|
File.readlines(File.expand_path(File.join('spec', 'data', 'smb_native_os.txt'))).each do |line|
|
133
128
|
data = line.strip
|
134
129
|
|
135
130
|
context "with smb_native_os:#{data}" do
|
136
|
-
let(:match_results) {subject.multi_match('smb.native_os', data) }
|
131
|
+
let(:match_results) { subject.multi_match('smb.native_os', data) }
|
137
132
|
|
138
|
-
it
|
133
|
+
it 'returns an array' do
|
139
134
|
expect(match_results.class).to eq(::Array)
|
140
135
|
end
|
141
136
|
|
142
|
-
it
|
137
|
+
it 'returns at least one successful match' do
|
143
138
|
expect(match_results.size).to be > 0
|
144
139
|
end
|
145
140
|
|
146
|
-
it
|
141
|
+
it 'correctly matches service or os' do
|
147
142
|
match_results do |mr|
|
148
|
-
if data =~ /^Windows/
|
149
|
-
expect(mr['os.product']).to match(/^Windows/)
|
150
|
-
end
|
143
|
+
expect(mr['os.product']).to match(/^Windows/) if data =~ /^Windows/
|
151
144
|
end
|
152
145
|
end
|
153
146
|
|
154
147
|
let(:invalid_db_result) { subject.multi_match('no_such_987', data) }
|
155
|
-
it
|
148
|
+
it 'returns an array when passed an invalid match_key' do
|
156
149
|
expect(invalid_db_result.class).to eq(::Array)
|
157
150
|
end
|
158
151
|
|
159
|
-
it
|
152
|
+
it 'returns an empty array when passed an invalid match_key' do
|
160
153
|
expect(invalid_db_result).to be_empty
|
161
154
|
end
|
162
155
|
end
|
163
|
-
|
164
156
|
end
|
165
157
|
|
166
158
|
data = 'Windows Server 2012 R2 Standard 9600'
|
167
|
-
context
|
168
|
-
let(:match_results) {subject.multi_match('smb.native_os', data) }
|
159
|
+
context 'with {data}' do
|
160
|
+
let(:match_results) { subject.multi_match('smb.native_os', data) }
|
169
161
|
|
170
|
-
it
|
162
|
+
it 'returns an array' do
|
171
163
|
expect(match_results.class).to eq(::Array)
|
172
164
|
end
|
173
165
|
|
174
|
-
it
|
166
|
+
it 'returns at least two successful matches' do
|
175
167
|
expect(match_results.size).to be > 1
|
176
168
|
end
|
177
169
|
|
178
|
-
it
|
170
|
+
it 'correctly matches os.product for all matches' do
|
179
171
|
match_results do |mr|
|
180
|
-
if data =~ /^Windows/
|
181
|
-
expect(mr['os.product']).to match(/^Windows/)
|
182
|
-
end
|
172
|
+
expect(mr['os.product']).to match(/^Windows/) if data =~ /^Windows/
|
183
173
|
end
|
184
174
|
end
|
185
175
|
|
186
|
-
it
|
176
|
+
it 'correctly matches protocol for all matches' do
|
187
177
|
match_results do |mr|
|
188
|
-
if data =~ /^Windows/
|
189
|
-
expect(mr['service.protocol']).to eq('smb')
|
190
|
-
end
|
178
|
+
expect(mr['service.protocol']).to eq('smb') if data =~ /^Windows/
|
191
179
|
end
|
192
180
|
end
|
193
181
|
end
|
194
182
|
|
195
183
|
line = 'non-existent'
|
196
|
-
context
|
197
|
-
let(:match_results) {subject.multi_match('smb.native_os', line) }
|
184
|
+
context 'with non-existent match' do
|
185
|
+
let(:match_results) { subject.multi_match('smb.native_os', line) }
|
198
186
|
|
199
|
-
it
|
187
|
+
it 'returns an array' do
|
200
188
|
expect(match_results.class).to eq(::Array)
|
201
189
|
end
|
202
190
|
|
203
|
-
it
|
191
|
+
it 'returns an empty array' do
|
204
192
|
expect(match_results).to be_empty
|
205
193
|
end
|
206
194
|
end
|
207
195
|
end
|
208
196
|
|
209
|
-
describe
|
197
|
+
describe '.best_os_match' do
|
210
198
|
# Demonstrates how this method picks up additional attributes from other members of the winning
|
211
199
|
# os.product match group and applies them to the result.
|
212
|
-
matches1 = YAML.
|
213
|
-
context
|
200
|
+
matches1 = YAML.safe_load(File.read(File.expand_path(File.join('spec', 'data', 'best_os_match_1.yml'))))
|
201
|
+
context 'with best_os_match_1.yml' do
|
214
202
|
let(:result) { subject.best_os_match(matches1) }
|
215
203
|
|
216
|
-
it
|
204
|
+
it 'returns a hash' do
|
217
205
|
expect(result.class).to eq(::Hash)
|
218
206
|
end
|
219
207
|
|
220
|
-
it
|
208
|
+
it 'matches Windows 2008' do
|
221
209
|
expect(result['os.product']).to eq('Windows 2008')
|
222
210
|
end
|
223
211
|
|
224
|
-
it
|
212
|
+
it 'matches Microsoft' do
|
225
213
|
expect(result['os.vendor']).to eq('Microsoft')
|
226
214
|
end
|
227
215
|
|
228
|
-
it
|
216
|
+
it 'matches English' do
|
229
217
|
expect(result['os.language']).to eq('English')
|
230
218
|
end
|
231
219
|
|
232
|
-
it
|
220
|
+
it 'matches service pack 2' do
|
233
221
|
expect(result['os.version']).to eq('Service Pack 2')
|
234
222
|
end
|
235
223
|
end
|
236
224
|
|
237
225
|
# Demonstrates how additive os.certainty values allow a 1.0 certainty rule to be overridden
|
238
226
|
# by multiple lower certainty matches
|
239
|
-
matches2 = YAML.
|
240
|
-
context
|
227
|
+
matches2 = YAML.safe_load(File.read(File.expand_path(File.join('spec', 'data', 'best_os_match_2.yml'))))
|
228
|
+
context 'with best_os_match_2.yml' do
|
241
229
|
let(:result) { subject.best_os_match(matches2) }
|
242
230
|
|
243
|
-
it
|
231
|
+
it 'returns a hash' do
|
244
232
|
expect(result.class).to eq(::Hash)
|
245
233
|
end
|
246
234
|
|
247
|
-
it
|
235
|
+
it 'matches Windows 2012' do
|
248
236
|
expect(result['os.product']).to eq('Windows 2012')
|
249
237
|
end
|
250
238
|
|
251
|
-
it
|
239
|
+
it 'matches Microsoft' do
|
252
240
|
expect(result['os.vendor']).to eq('Microsoft')
|
253
241
|
end
|
254
242
|
|
255
|
-
it
|
243
|
+
it 'matches Arabic' do
|
256
244
|
expect(result['os.language']).to eq('Arabic')
|
257
245
|
end
|
258
246
|
|
259
|
-
it
|
247
|
+
it 'matches service pack 1' do
|
260
248
|
expect(result['os.version']).to eq('Service Pack 1')
|
261
249
|
end
|
262
250
|
end
|
263
|
-
|
264
251
|
end
|
265
252
|
|
266
|
-
describe
|
253
|
+
describe '.best_service_match' do
|
267
254
|
# Demonstrates how this method picks up additional attributes from other members of the winning
|
268
255
|
# service.product match group and applies them to the result.
|
269
|
-
matches1 = YAML.
|
270
|
-
context
|
256
|
+
matches1 = YAML.safe_load(File.read(File.expand_path(File.join('spec', 'data', 'best_service_match_1.yml'))))
|
257
|
+
context 'with best_service_match_1.yml' do
|
271
258
|
let(:result) { subject.best_service_match(matches1) }
|
272
259
|
|
273
|
-
it
|
260
|
+
it 'returns a hash' do
|
274
261
|
expect(result.class).to eq(::Hash)
|
275
262
|
end
|
276
263
|
|
277
|
-
it
|
264
|
+
it 'matches IIS' do
|
278
265
|
expect(result['service.product']).to eq('IIS')
|
279
266
|
end
|
280
267
|
|
281
|
-
it
|
268
|
+
it 'matches Microsoft' do
|
282
269
|
expect(result['service.vendor']).to eq('Microsoft')
|
283
270
|
end
|
284
271
|
|
285
|
-
it
|
272
|
+
it 'matches English' do
|
286
273
|
expect(result['service.language']).to eq('English')
|
287
274
|
end
|
288
275
|
|
289
|
-
it
|
276
|
+
it 'matches version 6.0' do
|
290
277
|
expect(result['service.version'].to_i).to eq(6.0)
|
291
278
|
end
|
292
279
|
end
|
293
|
-
|
294
280
|
end
|
295
281
|
|
296
|
-
|
297
282
|
describe '.load_db' do
|
298
283
|
file_path = File.expand_path(File.join('spec', 'data', 'test_fingerprints.xml'))
|
299
284
|
context "with #{file_path}" do
|
300
285
|
let(:fp_db) { subject.load_db(file_path) }
|
301
|
-
it
|
302
|
-
expect(fp_db).to
|
303
|
-
subject.unload_db
|
286
|
+
it 'loads without error' do
|
287
|
+
expect(fp_db).to be true
|
288
|
+
subject.unload_db
|
304
289
|
end
|
305
290
|
end
|
306
291
|
|
307
|
-
context
|
292
|
+
context 'with no path specified' do
|
308
293
|
let(:fp_db) { subject.load_db }
|
309
|
-
it
|
310
|
-
expect(fp_db).to
|
311
|
-
subject.unload_db
|
294
|
+
it 'loads without error' do
|
295
|
+
expect(fp_db).to be true
|
296
|
+
subject.unload_db
|
312
297
|
end
|
313
298
|
end
|
314
299
|
|
315
|
-
context
|
316
|
-
it
|
300
|
+
context 'with empty file path' do
|
301
|
+
it 'raises an error' do
|
317
302
|
expect { subject.load_db('') }.to raise_error(Errno::ENOENT)
|
318
|
-
subject.unload_db
|
303
|
+
subject.unload_db
|
319
304
|
end
|
320
305
|
end
|
321
306
|
|
322
|
-
context
|
323
|
-
it
|
307
|
+
context 'with invalid file path' do
|
308
|
+
it 'raises an error' do
|
324
309
|
expect { subject.load_db('no_such_987_file_path') }.to raise_error(Errno::ENOENT)
|
325
|
-
subject.unload_db
|
310
|
+
subject.unload_db
|
326
311
|
end
|
327
312
|
end
|
328
313
|
end
|
329
|
-
|
330
314
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'recog/verify_reporter'
|
2
4
|
|
3
5
|
describe Recog::VerifyReporter do
|
@@ -5,142 +7,141 @@ describe Recog::VerifyReporter do
|
|
5
7
|
let(:fingerprint) { double(name: 'a name', tests: tests) }
|
6
8
|
let(:tests) { [double, double, double] }
|
7
9
|
let(:summary_line) do
|
8
|
-
|
10
|
+
'SUMMARY: Test completed with 1 successful, 1 warnings, and 1 failures'
|
9
11
|
end
|
10
|
-
let(:path) {
|
12
|
+
let(:path) { 'fingerprint.xml' }
|
11
13
|
|
12
14
|
subject { Recog::VerifyReporter.new(double(detail: false, quiet: false, warnings: true), formatter) }
|
13
15
|
|
14
16
|
def run_report
|
15
17
|
subject.report(1) do
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
18
|
+
subject.print_name fingerprint
|
19
|
+
subject.success 'passed'
|
20
|
+
subject.warning 'a warning'
|
21
|
+
subject.failure 'a failure'
|
20
22
|
end
|
21
23
|
end
|
22
24
|
|
23
|
-
describe
|
24
|
-
it
|
25
|
+
describe '#report' do
|
26
|
+
it 'prints warnings' do
|
25
27
|
expect(formatter).to receive(:warning_message).with('WARN: a warning')
|
26
28
|
run_report
|
27
29
|
end
|
28
30
|
|
29
|
-
it
|
31
|
+
it 'prints failures' do
|
30
32
|
expect(formatter).to receive(:failure_message).with('FAIL: a failure')
|
31
33
|
run_report
|
32
34
|
end
|
33
35
|
|
34
|
-
it
|
36
|
+
it 'prints summary' do
|
35
37
|
expect(formatter).to receive(:failure_message).with(summary_line)
|
36
38
|
run_report
|
37
39
|
end
|
38
40
|
|
39
|
-
context
|
41
|
+
context 'with detail' do
|
40
42
|
subject { Recog::VerifyReporter.new(double(detail: true, quiet: false, warnings: true), formatter) }
|
41
43
|
|
42
|
-
it
|
44
|
+
it 'prints the fingerprint name' do
|
43
45
|
expect(formatter).to receive(:status_message).with("\na name")
|
44
46
|
run_report
|
45
47
|
end
|
46
48
|
|
47
|
-
it
|
49
|
+
it 'prints successes' do
|
48
50
|
expect(formatter).to receive(:success_message).with(' passed')
|
49
51
|
run_report
|
50
52
|
end
|
51
53
|
|
52
|
-
it
|
54
|
+
it 'prints warnings' do
|
53
55
|
expect(formatter).to receive(:warning_message).with(' WARN: a warning')
|
54
56
|
run_report
|
55
57
|
end
|
56
58
|
|
57
|
-
it
|
59
|
+
it 'prints failures' do
|
58
60
|
expect(formatter).to receive(:failure_message).with(' FAIL: a failure')
|
59
61
|
run_report
|
60
62
|
end
|
61
63
|
|
62
|
-
it
|
64
|
+
it 'prints the fingerprint count' do
|
63
65
|
expect(formatter).to receive(:status_message).with("\nVerified 1 fingerprints:")
|
64
66
|
run_report
|
65
67
|
end
|
66
68
|
|
67
|
-
it
|
69
|
+
it 'prints summary' do
|
68
70
|
expect(formatter).to receive(:failure_message).with(summary_line)
|
69
71
|
run_report
|
70
72
|
end
|
71
73
|
|
72
|
-
context
|
74
|
+
context 'with no fingerprint tests' do
|
73
75
|
let(:tests) { [] }
|
74
76
|
|
75
|
-
it
|
77
|
+
it 'does not print the name' do
|
76
78
|
expect(formatter).not_to receive(:status_message).with("\na name")
|
77
79
|
run_report
|
78
80
|
end
|
79
81
|
end
|
80
82
|
end
|
81
83
|
|
82
|
-
context
|
83
|
-
|
84
|
+
context 'with fingerprint path' do
|
84
85
|
subject { Recog::VerifyReporter.new(double(detail: false, quiet: false, warnings: true), formatter, path) }
|
85
86
|
|
86
|
-
it
|
87
|
+
it 'prints warnings' do
|
87
88
|
expect(formatter).to receive(:warning_message).with("#{path}: WARN: a warning")
|
88
89
|
run_report
|
89
90
|
end
|
90
91
|
|
91
|
-
it
|
92
|
+
it 'prints failures' do
|
92
93
|
expect(formatter).to receive(:failure_message).with("#{path}: FAIL: a failure")
|
93
94
|
run_report
|
94
95
|
end
|
95
96
|
|
96
|
-
it
|
97
|
+
it 'prints summary' do
|
97
98
|
expect(formatter).to receive(:failure_message).with("#{path}: #{summary_line}")
|
98
99
|
run_report
|
99
100
|
end
|
100
101
|
end
|
101
102
|
|
102
|
-
context
|
103
|
+
context 'with fingerprint path and detail' do
|
103
104
|
subject { Recog::VerifyReporter.new(double(detail: true, quiet: false, warnings: true), formatter, path) }
|
104
105
|
|
105
|
-
it
|
106
|
+
it 'prints the fingerprint path' do
|
106
107
|
expect(formatter).to receive(:status_message).with("\n#{path}:\n")
|
107
108
|
run_report
|
108
109
|
end
|
109
110
|
|
110
|
-
it
|
111
|
+
it 'prints the fingerprint name' do
|
111
112
|
expect(formatter).to receive(:status_message).with("\na name")
|
112
113
|
run_report
|
113
114
|
end
|
114
115
|
|
115
|
-
it
|
116
|
+
it 'prints successes' do
|
116
117
|
expect(formatter).to receive(:success_message).with(' passed')
|
117
118
|
run_report
|
118
119
|
end
|
119
120
|
|
120
|
-
it
|
121
|
+
it 'prints warnings' do
|
121
122
|
expect(formatter).to receive(:warning_message).with(' WARN: a warning')
|
122
123
|
run_report
|
123
124
|
end
|
124
125
|
|
125
|
-
it
|
126
|
+
it 'prints failures' do
|
126
127
|
expect(formatter).to receive(:failure_message).with(' FAIL: a failure')
|
127
128
|
run_report
|
128
129
|
end
|
129
130
|
|
130
|
-
it
|
131
|
+
it 'prints the fingerprint count' do
|
131
132
|
expect(formatter).to receive(:status_message).with("\nVerified 1 fingerprints:")
|
132
133
|
run_report
|
133
134
|
end
|
134
135
|
|
135
|
-
it
|
136
|
+
it 'prints summary' do
|
136
137
|
expect(formatter).to receive(:failure_message).with(summary_line)
|
137
138
|
run_report
|
138
139
|
end
|
139
140
|
|
140
|
-
context
|
141
|
+
context 'with no fingerprint tests' do
|
141
142
|
let(:tests) { [] }
|
142
143
|
|
143
|
-
it
|
144
|
+
it 'does not print the name' do
|
144
145
|
expect(formatter).not_to receive(:status_message).with("\na name")
|
145
146
|
run_report
|
146
147
|
end
|
@@ -148,32 +149,32 @@ describe Recog::VerifyReporter do
|
|
148
149
|
end
|
149
150
|
end
|
150
151
|
|
151
|
-
describe
|
152
|
-
context
|
152
|
+
describe '#print_summary' do
|
153
|
+
context 'with success' do
|
153
154
|
before { subject.success 'pass' }
|
154
155
|
|
155
|
-
it
|
156
|
-
msg =
|
156
|
+
it 'prints a successful summary' do
|
157
|
+
msg = 'SUMMARY: Test completed with 1 successful, 0 warnings, and 0 failures'
|
157
158
|
expect(formatter).to receive(:success_message).with(msg)
|
158
159
|
subject.print_summary
|
159
160
|
end
|
160
161
|
end
|
161
162
|
|
162
|
-
context
|
163
|
+
context 'with warnings' do
|
163
164
|
before { subject.warning 'warn' }
|
164
165
|
|
165
|
-
it
|
166
|
-
msg =
|
166
|
+
it 'prints a warning summary' do
|
167
|
+
msg = 'SUMMARY: Test completed with 0 successful, 1 warnings, and 0 failures'
|
167
168
|
expect(formatter).to receive(:warning_message).with(msg)
|
168
169
|
subject.print_summary
|
169
170
|
end
|
170
171
|
end
|
171
172
|
|
172
|
-
context
|
173
|
+
context 'with failures' do
|
173
174
|
before { subject.failure 'fail' }
|
174
175
|
|
175
|
-
it
|
176
|
-
msg =
|
176
|
+
it 'prints a failure summary' do
|
177
|
+
msg = 'SUMMARY: Test completed with 0 successful, 0 warnings, and 1 failures'
|
177
178
|
expect(formatter).to receive(:failure_message).with(msg)
|
178
179
|
subject.print_summary
|
179
180
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
FINGERPRINT_DIR = File.expand_path(File.join('..', 'recog', 'xml'), __dir__)
|
2
4
|
|
3
5
|
# setup code coverage
|
@@ -22,7 +24,6 @@ require 'rspec'
|
|
22
24
|
#
|
23
25
|
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
24
26
|
RSpec.configure do |config|
|
25
|
-
|
26
27
|
# Run specs in random order to surface order dependencies. If you find an
|
27
28
|
# order dependency and want to debug it, you can fix the order by providing
|
28
29
|
# the seed, which is printed after each run.
|
data.tar.gz.sig
CHANGED
@@ -1,3 +1 @@
|
|
1
|
-
|
2
|
-
�0�?�v`Ӵ�C&b��[�#T1E6�������;i�z���a�
|
3
|
-
S�v�=Ԡ^�z;X1�%���dc��p����w��,��GS�Vv����� 6%�z��r�c����V�woVʊ�ǔȳ6�B�l���C���āe�i�@�7�E#'&s���9�H����a+%Y&&$�Mw�AǮk�ip�h����~p�R�Fq<{]F��
|
1
|
+
=&�-,*K��Z�8�k���O�ٱ�N���Y���X��9{��-J�&��Oot ��%�D�!Od�d�,�^�S
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: recog
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.1.
|
4
|
+
version: 3.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rapid7 Research
|
@@ -93,7 +93,7 @@ cert_chain:
|
|
93
93
|
EknWpNgVhohbot1lfVAMmIhdtOVaRVcQQixWPwprDj/ydB8ryDMDosIMcw+fkoXU
|
94
94
|
9GJsSaSRRYQ9UUkVL27b64okU8D48m8=
|
95
95
|
-----END CERTIFICATE-----
|
96
|
-
date: 2023-
|
96
|
+
date: 2023-08-16 00:00:00.000000000 Z
|
97
97
|
dependencies:
|
98
98
|
- !ruby/object:Gem::Dependency
|
99
99
|
name: rspec
|
@@ -293,7 +293,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
293
293
|
requirements:
|
294
294
|
- - ">="
|
295
295
|
- !ruby/object:Gem::Version
|
296
|
-
version: '2.
|
296
|
+
version: '2.5'
|
297
297
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
298
298
|
requirements:
|
299
299
|
- - ">="
|
metadata.gz.sig
CHANGED
Binary file
|