littleneck_clamav 0.0.1 → 0.0.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.
- data/README.md +2 -0
- data/lib/littleneck_clamav.rb +6 -12
- data/lib/littleneck_clamav/clam.rb +36 -36
- data/lib/littleneck_clamav/clamd.rb +11 -5
- data/lib/littleneck_clamav/error.rb +0 -2
- data/lib/littleneck_clamav/result.rb +3 -11
- data/spec/clam_spec.rb +27 -7
- data/spec/clamd_spec.rb +28 -6
- data/spec/littleneck_clamav_spec.rb +38 -51
- data/spec/result_spec.rb +25 -25
- data/spec/spec_helper.rb +6 -5
- data/spec/support/factories.rb +52 -4
- data/spec/support/shared_examples.rb +49 -74
- metadata +22 -6
data/README.md
CHANGED
data/lib/littleneck_clamav.rb
CHANGED
@@ -1,9 +1,8 @@
|
|
1
|
-
require_relative
|
2
|
-
require_relative
|
3
|
-
require_relative
|
1
|
+
require_relative 'littleneck_clamav/clam'
|
2
|
+
require_relative 'littleneck_clamav/clamd'
|
3
|
+
require_relative 'littleneck_clamav/error'
|
4
4
|
|
5
5
|
class LittleneckClamAV
|
6
|
-
|
7
6
|
def engine
|
8
7
|
scanner.engine
|
9
8
|
end
|
@@ -16,23 +15,19 @@ class LittleneckClamAV
|
|
16
15
|
scanner.database_date
|
17
16
|
end
|
18
17
|
|
19
|
-
def available?
|
20
|
-
!!scanner
|
21
|
-
end
|
22
|
-
|
23
18
|
def scan(*args)
|
24
19
|
scanner.scan(*args)
|
25
20
|
end
|
26
21
|
|
27
22
|
def scanner
|
28
23
|
@scanner ||= begin
|
29
|
-
scanner = scanners.find
|
30
|
-
|
24
|
+
scanner = scanners.find(&:available?)
|
25
|
+
fail Error, 'no scanner available, is ClamAV installed?' unless scanner
|
31
26
|
scanner
|
32
27
|
end
|
33
28
|
end
|
34
29
|
|
35
|
-
private
|
30
|
+
private
|
36
31
|
|
37
32
|
def preference
|
38
33
|
[Clamd, Clam]
|
@@ -41,5 +36,4 @@ private
|
|
41
36
|
def scanners
|
42
37
|
@scanners ||= preference.map(&:new)
|
43
38
|
end
|
44
|
-
|
45
39
|
end
|
@@ -1,13 +1,12 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require 'cocaine'
|
2
|
+
require 'English'
|
3
|
+
require 'time'
|
3
4
|
|
4
|
-
require_relative
|
5
|
-
require_relative
|
5
|
+
require_relative 'result'
|
6
|
+
require_relative 'error'
|
6
7
|
|
7
8
|
class LittleneckClamAV
|
8
|
-
|
9
9
|
class Clam
|
10
|
-
|
11
10
|
def engine
|
12
11
|
version[:engine] if available?
|
13
12
|
end
|
@@ -26,56 +25,57 @@ class LittleneckClamAV
|
|
26
25
|
|
27
26
|
def scan(path)
|
28
27
|
check_scan! path
|
29
|
-
opts = { :
|
30
|
-
params = [
|
31
|
-
output = Cocaine::CommandLine.new(
|
32
|
-
parse_result path, output,
|
28
|
+
opts = { swallow_stderr: true, expected_outcodes: [0, 1] }
|
29
|
+
params = ['--no-summary', %("#{path}")].join(' ')
|
30
|
+
output = Cocaine::CommandLine.new(command, params, opts).run
|
31
|
+
parse_result path, output, $CHILD_STATUS.exitstatus
|
33
32
|
end
|
34
33
|
|
35
34
|
def command
|
36
|
-
|
35
|
+
'clamscan'
|
37
36
|
end
|
38
37
|
|
39
|
-
|
38
|
+
private
|
40
39
|
|
41
40
|
def version
|
42
41
|
@version ||= begin
|
43
|
-
opts = { :
|
44
|
-
params =
|
45
|
-
output = Cocaine::CommandLine.new(
|
46
|
-
output
|
47
|
-
engine, db_version, db_date = output.sub(/^ClamAV /,'').split("/",3)
|
48
|
-
success = !!(db_version && db_date)
|
49
|
-
{
|
50
|
-
:output => output,
|
51
|
-
:engine => engine,
|
52
|
-
:database_version => db_version,
|
53
|
-
:database_date => db_date,
|
54
|
-
:success => success
|
55
|
-
}
|
42
|
+
opts = { swallow_stderr: true }
|
43
|
+
params = '--version'
|
44
|
+
output = Cocaine::CommandLine.new(command, params, opts).run.strip
|
45
|
+
parse_output(output)
|
56
46
|
rescue Cocaine::ExitStatusError, Cocaine::CommandNotFoundError => e
|
57
|
-
{:
|
47
|
+
{ error: e.message, success: false }
|
58
48
|
end
|
59
49
|
end
|
60
50
|
|
61
|
-
def
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
51
|
+
def parse_output(output)
|
52
|
+
engine, db_version, db_date = output.sub(/^ClamAV /, '').split('/', 3)
|
53
|
+
success = !(db_version && db_date).nil?
|
54
|
+
{
|
55
|
+
output: output,
|
56
|
+
engine: engine,
|
57
|
+
database_version: db_version,
|
58
|
+
database_date: db_date,
|
59
|
+
success: success
|
60
|
+
}
|
61
|
+
end
|
62
|
+
|
63
|
+
def parse_result(path, output, _code)
|
64
|
+
clean = $CHILD_STATUS.exitstatus == 0
|
65
|
+
description = output.split(':').last.strip
|
66
|
+
description.sub! ' FOUND', ''
|
67
|
+
Result.new path: path, clean: clean, description: description
|
66
68
|
end
|
67
69
|
|
68
70
|
def check_scan!(path)
|
69
|
-
exists = File.
|
71
|
+
exists = File.exist? path
|
70
72
|
if !exists
|
71
|
-
|
73
|
+
fail Error, "the path #{path} does not exist"
|
72
74
|
elsif !available?
|
73
75
|
message = "#{self.class} is not available"
|
74
76
|
message << "because #{version[:message]}" if version[:message]
|
75
|
-
|
77
|
+
fail Error, message
|
76
78
|
end
|
77
79
|
end
|
78
|
-
|
79
80
|
end
|
80
|
-
|
81
81
|
end
|
@@ -1,13 +1,19 @@
|
|
1
|
-
|
1
|
+
require 'English'
|
2
2
|
|
3
|
-
|
3
|
+
require_relative 'clam'
|
4
4
|
|
5
|
+
class LittleneckClamAV
|
5
6
|
class Clamd < Clam
|
6
|
-
|
7
7
|
def command
|
8
|
-
|
8
|
+
'clamdscan'
|
9
9
|
end
|
10
10
|
|
11
|
+
def scan(path)
|
12
|
+
check_scan! path
|
13
|
+
opts = { swallow_stderr: true, expected_outcodes: [0, 1] }
|
14
|
+
params = %(--no-summary -<"#{path}")
|
15
|
+
output = Cocaine::CommandLine.new(command, params, opts).run
|
16
|
+
parse_result path, output, $CHILD_STATUS.exitstatus
|
17
|
+
end
|
11
18
|
end
|
12
|
-
|
13
19
|
end
|
@@ -1,29 +1,21 @@
|
|
1
1
|
class LittleneckClamAV
|
2
|
-
|
3
2
|
class Result
|
4
|
-
|
5
3
|
def initialize(opts)
|
6
4
|
@path = opts[:path]
|
7
5
|
@clean = opts[:clean]
|
8
6
|
@description = opts[:description]
|
9
7
|
end
|
10
8
|
|
11
|
-
|
12
|
-
@path
|
13
|
-
end
|
9
|
+
attr_reader :path
|
14
10
|
|
15
11
|
def clean?
|
16
12
|
@clean
|
17
13
|
end
|
18
14
|
|
19
15
|
def infected?
|
20
|
-
|
21
|
-
end
|
22
|
-
|
23
|
-
def description
|
24
|
-
@description
|
16
|
+
!clean?
|
25
17
|
end
|
26
18
|
|
19
|
+
attr_reader :description
|
27
20
|
end
|
28
|
-
|
29
21
|
end
|
data/spec/clam_spec.rb
CHANGED
@@ -1,15 +1,35 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
|
-
describe LittleneckClamAV::Clam do
|
3
|
+
RSpec.describe LittleneckClamAV::Clam do
|
4
4
|
|
5
|
-
it_behaves_like
|
5
|
+
it_behaves_like 'a scanner'
|
6
6
|
|
7
|
-
describe
|
7
|
+
describe 'instance method' do
|
8
8
|
|
9
|
-
describe
|
9
|
+
describe 'command' do
|
10
10
|
|
11
|
-
it
|
12
|
-
subject.command.
|
11
|
+
it 'should return clamdscan' do
|
12
|
+
expect(subject.command).to eql('clamscan')
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
describe 'scan' do
|
18
|
+
|
19
|
+
it 'should call Cocaine' do
|
20
|
+
file = __FILE__
|
21
|
+
|
22
|
+
allow(subject).to receive(:available?).and_return(true)
|
23
|
+
|
24
|
+
mock_cocaine cmd: subject.command,
|
25
|
+
opts: %(--no-summary "#{file}"),
|
26
|
+
params: {
|
27
|
+
swallow_stderr: true,
|
28
|
+
expected_outcodes: [0, 1]
|
29
|
+
},
|
30
|
+
output: "#{file}: OK"
|
31
|
+
|
32
|
+
subject.scan file
|
13
33
|
end
|
14
34
|
|
15
35
|
end
|
data/spec/clamd_spec.rb
CHANGED
@@ -1,13 +1,35 @@
|
|
1
|
-
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
|
-
|
3
|
+
RSpec.describe LittleneckClamAV::Clamd do
|
4
4
|
|
5
|
-
|
5
|
+
it_behaves_like 'a scanner'
|
6
6
|
|
7
|
-
|
7
|
+
describe 'instance method' do
|
8
8
|
|
9
|
-
|
10
|
-
|
9
|
+
describe 'command' do
|
10
|
+
|
11
|
+
it 'should return clamdscan' do
|
12
|
+
expect(subject.command).to eql('clamdscan')
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
describe 'scan' do
|
18
|
+
|
19
|
+
it 'should call Cocaine' do
|
20
|
+
file = __FILE__
|
21
|
+
|
22
|
+
allow(subject).to receive(:available?).and_return(true)
|
23
|
+
|
24
|
+
mock_cocaine cmd: subject.command,
|
25
|
+
opts: %(--no-summary -<"#{file}"),
|
26
|
+
params: {
|
27
|
+
swallow_stderr: true,
|
28
|
+
expected_outcodes: [0, 1]
|
29
|
+
},
|
30
|
+
output: "#{file}: OK"
|
31
|
+
|
32
|
+
subject.scan file
|
11
33
|
end
|
12
34
|
|
13
35
|
end
|
@@ -1,93 +1,80 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
|
-
describe LittleneckClamAV do
|
3
|
+
RSpec.describe LittleneckClamAV do
|
4
4
|
|
5
|
-
describe
|
5
|
+
describe 'instance method' do
|
6
6
|
|
7
|
-
|
7
|
+
let(:scanner) { double('scanner') }
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
9
|
+
describe 'engine' do
|
10
|
+
|
11
|
+
it 'should call `engine` on the scanner' do
|
12
|
+
expect(scanner).to receive(:engine)
|
13
|
+
allow(subject).to receive(:scanner).and_return(scanner)
|
13
14
|
|
14
15
|
subject.engine
|
15
16
|
end
|
16
17
|
|
17
18
|
end
|
18
19
|
|
19
|
-
describe
|
20
|
+
describe 'database_version' do
|
20
21
|
|
21
|
-
it
|
22
|
-
scanner
|
23
|
-
|
24
|
-
subject.stub( :scanner => scanner )
|
22
|
+
it 'should call `database_version` on the scanner' do
|
23
|
+
expect(scanner).to receive(:database_version)
|
24
|
+
allow(subject).to receive(:scanner).and_return(scanner)
|
25
25
|
|
26
26
|
subject.database_version
|
27
27
|
end
|
28
28
|
|
29
29
|
end
|
30
30
|
|
31
|
-
describe
|
31
|
+
describe 'database_date' do
|
32
32
|
|
33
|
-
it
|
34
|
-
scanner
|
35
|
-
|
36
|
-
subject.stub( :scanner => scanner )
|
33
|
+
it 'should call `database_date` on the scanner' do
|
34
|
+
expect(scanner).to receive(:database_date)
|
35
|
+
allow(subject).to receive(:scanner).and_return(scanner)
|
37
36
|
|
38
37
|
subject.database_date
|
39
38
|
end
|
40
39
|
|
41
40
|
end
|
42
41
|
|
43
|
-
describe
|
44
|
-
|
45
|
-
it "should return true if a scanner is available" do
|
46
|
-
subject.stub( :scanner => Object.new )
|
47
|
-
|
48
|
-
subject.available?.should == true
|
49
|
-
end
|
50
|
-
|
51
|
-
it "should return false if a scanner is not available" do
|
52
|
-
subject.stub( :scanner => nil )
|
53
|
-
|
54
|
-
subject.available?.should == false
|
55
|
-
end
|
56
|
-
|
57
|
-
end
|
58
|
-
|
59
|
-
describe "scan" do
|
42
|
+
describe 'scan' do
|
60
43
|
|
61
|
-
it
|
62
|
-
scanner
|
63
|
-
|
64
|
-
subject.stub( :scanner => scanner )
|
44
|
+
it 'should call `scan` on the scanner' do
|
45
|
+
expect(scanner).to receive(:scan)
|
46
|
+
allow(subject).to receive(:scanner).and_return(scanner)
|
65
47
|
|
66
48
|
subject.scan
|
67
49
|
end
|
68
50
|
|
69
51
|
end
|
70
52
|
|
71
|
-
describe
|
53
|
+
describe 'scanner' do
|
72
54
|
|
73
|
-
it
|
74
|
-
LittleneckClamAV::Clamd.
|
55
|
+
it 'should return Clamd if available' do
|
56
|
+
allow_any_instance_of(LittleneckClamAV::Clamd).to(
|
57
|
+
receive(:available?).and_return(true))
|
75
58
|
|
76
|
-
subject.scanner.
|
59
|
+
expect(subject.scanner).to be_a(LittleneckClamAV::Clamd)
|
77
60
|
end
|
78
61
|
|
79
|
-
it
|
80
|
-
LittleneckClamAV::Clamd.
|
81
|
-
|
62
|
+
it 'should return Clam if Clamd is not available' do
|
63
|
+
allow_any_instance_of(LittleneckClamAV::Clamd).to(
|
64
|
+
receive(:available?).and_return(false))
|
65
|
+
allow_any_instance_of(LittleneckClamAV::Clam).to(
|
66
|
+
receive(:available?).and_return(true))
|
82
67
|
|
83
|
-
subject.scanner.
|
68
|
+
expect(subject.scanner).to be_a(LittleneckClamAV::Clam)
|
84
69
|
end
|
85
70
|
|
86
|
-
it
|
87
|
-
LittleneckClamAV::Clamd.
|
88
|
-
|
71
|
+
it 'should raise an error if neither are available' do
|
72
|
+
allow_any_instance_of(LittleneckClamAV::Clamd).to(
|
73
|
+
receive(:available?).and_return(false))
|
74
|
+
allow_any_instance_of(LittleneckClamAV::Clam).to(
|
75
|
+
receive(:available?).and_return(false))
|
89
76
|
|
90
|
-
|
77
|
+
expect { subject.scanner }.to raise_error(LittleneckClamAV::Error)
|
91
78
|
end
|
92
79
|
|
93
80
|
end
|
data/spec/result_spec.rb
CHANGED
@@ -1,51 +1,51 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
|
-
describe LittleneckClamAV::Result do
|
3
|
+
RSpec.describe LittleneckClamAV::Result do
|
4
4
|
|
5
|
-
describe
|
5
|
+
describe 'instance method' do
|
6
6
|
|
7
|
-
describe
|
7
|
+
describe 'infected?' do
|
8
8
|
|
9
|
-
it
|
10
|
-
result = result_factory :
|
11
|
-
result.infected
|
9
|
+
it 'should return true when infected' do
|
10
|
+
result = result_factory clean: false
|
11
|
+
expect(result.infected?).to be(true)
|
12
12
|
end
|
13
13
|
|
14
|
-
it
|
15
|
-
result = result_factory :
|
16
|
-
result.infected
|
14
|
+
it 'should return false when clean' do
|
15
|
+
result = result_factory clean: true
|
16
|
+
expect(result.infected?).to be(false)
|
17
17
|
end
|
18
18
|
|
19
19
|
end
|
20
20
|
|
21
|
-
describe
|
21
|
+
describe 'clean?' do
|
22
22
|
|
23
|
-
it
|
24
|
-
result = result_factory :
|
25
|
-
result.clean
|
23
|
+
it 'should return true when clean' do
|
24
|
+
result = result_factory clean: true
|
25
|
+
expect(result.clean?).to be(true)
|
26
26
|
end
|
27
27
|
|
28
|
-
it
|
29
|
-
result = result_factory :
|
30
|
-
result.clean
|
28
|
+
it 'should return false when infected' do
|
29
|
+
result = result_factory clean: false
|
30
|
+
expect(result.clean?).to be(false)
|
31
31
|
end
|
32
32
|
|
33
33
|
end
|
34
34
|
|
35
|
-
describe
|
35
|
+
describe 'description' do
|
36
36
|
|
37
|
-
it
|
38
|
-
result = result_factory :
|
39
|
-
result.description.
|
37
|
+
it 'should return the description passed in' do
|
38
|
+
result = result_factory description: 'Hello'
|
39
|
+
expect(result.description).to eql('Hello')
|
40
40
|
end
|
41
41
|
|
42
42
|
end
|
43
43
|
|
44
|
-
describe
|
44
|
+
describe 'path' do
|
45
45
|
|
46
|
-
it
|
47
|
-
result = result_factory :
|
48
|
-
result.path.
|
46
|
+
it 'should return the path passed in' do
|
47
|
+
result = result_factory path: 'foo/bar'
|
48
|
+
expect(result.path).to eql('foo/bar')
|
49
49
|
end
|
50
50
|
|
51
51
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,11 +1,12 @@
|
|
1
|
-
|
1
|
+
$LOAD_PATH.unshift File.join(File.dirname(File.dirname(__FILE__)), 'lib')
|
2
2
|
|
3
|
-
require
|
4
|
-
require "rspec/mocks/any_instance"
|
3
|
+
require 'littleneck_clamav'
|
5
4
|
|
6
|
-
Dir[File.join(File.dirname(__FILE__),'support','*.rb')].each{|f| require f }
|
5
|
+
Dir[File.join(File.dirname(__FILE__), 'support', '*.rb')].each { |f| require f }
|
7
6
|
|
8
7
|
RSpec.configure do |config|
|
9
8
|
config.expect_with :rspec
|
10
|
-
config.mock_with
|
9
|
+
config.mock_with :rspec
|
10
|
+
|
11
|
+
config.disable_monkey_patching!
|
11
12
|
end
|
data/spec/support/factories.rb
CHANGED
@@ -1,9 +1,57 @@
|
|
1
1
|
def result_factory(override = {})
|
2
2
|
options = {
|
3
|
-
:
|
4
|
-
:
|
5
|
-
:
|
6
|
-
}.merge(
|
3
|
+
success: true,
|
4
|
+
path: 'foo.txt',
|
5
|
+
description: 'OK'
|
6
|
+
}.merge(override)
|
7
7
|
|
8
8
|
LittleneckClamAV::Result.new options
|
9
9
|
end
|
10
|
+
|
11
|
+
def mock_cocaine(cocaine_options = {})
|
12
|
+
MockCocaine.new(cocaine_options).mock
|
13
|
+
end
|
14
|
+
|
15
|
+
class MockCocaine
|
16
|
+
include RSpec::Mocks::ExampleMethods
|
17
|
+
|
18
|
+
def initialize(options)
|
19
|
+
@options = defaults.merge(options)
|
20
|
+
end
|
21
|
+
|
22
|
+
def mock
|
23
|
+
build_mock
|
24
|
+
setup_exit_value
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
attr_reader :options
|
30
|
+
|
31
|
+
def defaults
|
32
|
+
{ output: '', exitvalue: 0 }
|
33
|
+
end
|
34
|
+
|
35
|
+
def build_mock
|
36
|
+
basic_mock = expect(Cocaine::CommandLine).to(receive(:new))
|
37
|
+
basic_mock.with(*cocaine_arguments) if any_argument_options?
|
38
|
+
basic_mock.and_return(cocaine_command_double)
|
39
|
+
basic_mock.and_raise(options[:raise]) if options.key?(:raise)
|
40
|
+
end
|
41
|
+
|
42
|
+
def cocaine_command_double
|
43
|
+
double('cocaine command', run: options[:output])
|
44
|
+
end
|
45
|
+
|
46
|
+
def cocaine_arguments
|
47
|
+
[options[:cmd], options[:opts], options[:params]]
|
48
|
+
end
|
49
|
+
|
50
|
+
def any_argument_options?
|
51
|
+
options[:cmd] || options[:opts] || options[:params]
|
52
|
+
end
|
53
|
+
|
54
|
+
def setup_exit_value
|
55
|
+
options[:exitvalue] == 0 ? `true` : `false`
|
56
|
+
end
|
57
|
+
end
|
@@ -1,127 +1,102 @@
|
|
1
|
-
shared_examples_for
|
2
|
-
|
3
|
-
def mock_cocaine(cocaine_options={})
|
4
|
-
options = { :output => "", :exitvalue => 0 }.merge( cocaine_options )
|
5
|
-
mock = Cocaine::CommandLine.should_receive( :new )
|
6
|
-
mock = mock.with(
|
7
|
-
options[:cmd], options[:opts], options[:params]
|
8
|
-
) if options[:cmd] || options[:opts] || options[:params]
|
9
|
-
|
10
|
-
if cocaine_options[:raise]
|
11
|
-
mock.and_raise cocaine_options[:raise]
|
12
|
-
else
|
13
|
-
mock.and_return(
|
14
|
-
double "cocaine command", :run => options[:output]
|
15
|
-
)
|
16
|
-
end
|
17
|
-
|
18
|
-
`true` if options[:exitvalue] == 0
|
19
|
-
`false` if options[:exitvalue] == 1
|
20
|
-
end
|
1
|
+
shared_examples_for 'a scanner' do
|
21
2
|
|
22
|
-
|
3
|
+
describe 'instance method' do
|
23
4
|
|
24
|
-
describe
|
5
|
+
describe 'engine' do
|
25
6
|
|
26
|
-
it
|
27
|
-
mock_cocaine :
|
7
|
+
it 'should call Cocaine with correct parameters' do
|
8
|
+
mock_cocaine cmd: subject.command,
|
9
|
+
opts: '--version',
|
10
|
+
params: { swallow_stderr: true }
|
28
11
|
subject.engine
|
29
12
|
end
|
30
13
|
|
31
|
-
it
|
32
|
-
mock_cocaine :
|
33
|
-
subject.engine.
|
14
|
+
it 'should interpret the return value correctly' do
|
15
|
+
mock_cocaine output: "ClamAV 0.97.5/15306/Tue Aug 28 20:18:12 2012\n"
|
16
|
+
expect(subject.engine).to eql('0.97.5')
|
34
17
|
end
|
35
18
|
|
36
19
|
end
|
37
20
|
|
38
|
-
describe
|
21
|
+
describe 'database_version' do
|
39
22
|
|
40
|
-
it
|
41
|
-
mock_cocaine :
|
23
|
+
it 'should call Cocaine with correct parameters' do
|
24
|
+
mock_cocaine cmd: subject.command,
|
25
|
+
opts: '--version',
|
26
|
+
params: { swallow_stderr: true }
|
42
27
|
subject.database_version
|
43
28
|
end
|
44
29
|
|
45
|
-
it
|
46
|
-
mock_cocaine :
|
47
|
-
subject.database_version.
|
30
|
+
it 'should interpret the return value correctly' do
|
31
|
+
mock_cocaine output: "ClamAV 0.97.5/15306/Tue Aug 28 20:18:12 2012\n"
|
32
|
+
expect(subject.database_version).to eql(15_306)
|
48
33
|
end
|
49
34
|
|
50
35
|
end
|
51
36
|
|
52
|
-
describe
|
37
|
+
describe 'database_version' do
|
53
38
|
|
54
|
-
it
|
55
|
-
mock_cocaine :
|
39
|
+
it 'should call Cocaine with correct parameters' do
|
40
|
+
mock_cocaine cmd: subject.command,
|
41
|
+
opts: '--version',
|
42
|
+
params: { swallow_stderr: true }
|
56
43
|
subject.database_date
|
57
44
|
end
|
58
45
|
|
59
|
-
it
|
60
|
-
mock_cocaine :
|
61
|
-
subject.database_date.
|
46
|
+
it 'should interpret the return value correctly' do
|
47
|
+
mock_cocaine output: "ClamAV 0.97.5/15306/Tue Aug 28 20:18:12 2012\n"
|
48
|
+
expect(subject.database_date).to eql(
|
49
|
+
Time.parse('Tue Aug 28 20:18:12 2012')
|
50
|
+
)
|
62
51
|
end
|
63
52
|
|
64
53
|
end
|
65
54
|
|
66
|
-
describe
|
55
|
+
describe 'available?' do
|
67
56
|
|
68
|
-
it
|
69
|
-
mock_cocaine :
|
57
|
+
it 'should return true when Cocaine returns okay' do
|
58
|
+
mock_cocaine output: "ClamAV 0.97.5/15306/Tue Aug 28 20:18:12 2012\n"
|
70
59
|
|
71
|
-
subject.available
|
60
|
+
expect(subject.available?).to be(true)
|
72
61
|
end
|
73
62
|
|
74
|
-
it
|
75
|
-
mock_cocaine :
|
63
|
+
it 'should return false when command errors' do
|
64
|
+
mock_cocaine raise: Cocaine::ExitStatusError.new('oh noes')
|
76
65
|
|
77
|
-
subject.available
|
66
|
+
expect(subject.available?).to be(false)
|
78
67
|
end
|
79
68
|
|
80
|
-
it
|
81
|
-
mock_cocaine :
|
69
|
+
it 'should return false when command is not found' do
|
70
|
+
mock_cocaine raise: Cocaine::CommandNotFoundError
|
82
71
|
|
83
|
-
subject.available
|
72
|
+
expect(subject.available?).to be(false)
|
84
73
|
end
|
85
74
|
|
86
75
|
end
|
87
76
|
|
88
|
-
describe
|
89
|
-
|
90
|
-
it "should call Cocaine" do
|
91
|
-
file = __FILE__
|
92
|
-
|
93
|
-
subject.stub(:available?).and_return(true)
|
77
|
+
describe 'scan' do
|
94
78
|
|
95
|
-
|
96
|
-
:opts => "--no-summary #{file}",
|
97
|
-
:params => { :swallow_stderr => true, :expected_outcodes => [0, 1] },
|
98
|
-
:output => "#{file}: OK"
|
99
|
-
|
100
|
-
subject.scan file
|
101
|
-
end
|
102
|
-
|
103
|
-
it "should create a Result" do
|
79
|
+
it 'should create a Result' do
|
104
80
|
file = __FILE__
|
105
81
|
|
106
|
-
subject.
|
82
|
+
allow(subject).to receive(:available?).and_return(true)
|
107
83
|
|
108
|
-
mock_cocaine :
|
84
|
+
mock_cocaine output: "#{file}: OK\n"
|
109
85
|
|
110
|
-
LittleneckClamAV::Result.
|
86
|
+
expect(LittleneckClamAV::Result).to receive(:new)
|
87
|
+
.with(path: file, clean: true, description: 'OK')
|
111
88
|
|
112
89
|
subject.scan file
|
113
90
|
end
|
114
91
|
|
115
|
-
it
|
116
|
-
|
92
|
+
it 'should raise an error if the path does not exist' do
|
93
|
+
expect { subject.scan 'foo' }.to raise_error(LittleneckClamAV::Error)
|
117
94
|
end
|
118
95
|
|
119
|
-
it
|
120
|
-
|
121
|
-
|
122
|
-
subject.stub(:available?).and_return(false)
|
96
|
+
it 'should raise an error if it is not available' do
|
97
|
+
allow(subject).to receive(:available?).and_return(false)
|
123
98
|
|
124
|
-
|
99
|
+
expect { subject.scan 'foo' }.to raise_error(LittleneckClamAV::Error)
|
125
100
|
end
|
126
101
|
|
127
102
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: littleneck_clamav
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2014-12-18 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: cocaine
|
@@ -50,7 +50,7 @@ dependencies:
|
|
50
50
|
requirements:
|
51
51
|
- - ~>
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version: '
|
53
|
+
version: '3.1'
|
54
54
|
type: :development
|
55
55
|
prerelease: false
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -58,7 +58,23 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - ~>
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
61
|
+
version: '3.1'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rubocop
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
62
78
|
description:
|
63
79
|
email: theo.c@zepler.net
|
64
80
|
executables: []
|
@@ -95,7 +111,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
95
111
|
version: '0'
|
96
112
|
segments:
|
97
113
|
- 0
|
98
|
-
hash:
|
114
|
+
hash: 2481354664776410882
|
99
115
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
100
116
|
none: false
|
101
117
|
requirements:
|
@@ -104,7 +120,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
104
120
|
version: 1.3.6
|
105
121
|
requirements: []
|
106
122
|
rubyforge_project:
|
107
|
-
rubygems_version: 1.8.
|
123
|
+
rubygems_version: 1.8.23.2
|
108
124
|
signing_key:
|
109
125
|
specification_version: 3
|
110
126
|
summary: A thin wrapper to make it quick and easy to use ClamAV (daemonised or not)
|