recog 3.1.1 → 3.1.2
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.
- 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
|