contained_mr 0.1.2 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +7 -0
- data/Gemfile +7 -6
- data/Gemfile.lock +9 -5
- data/{README.rdoc → README.md} +6 -3
- data/VERSION +1 -1
- data/contained_mr.gemspec +37 -17
- data/lib/contained_mr/job.rb +32 -122
- data/lib/contained_mr/job_logic.rb +126 -0
- data/lib/contained_mr/mock/job.rb +111 -0
- data/lib/contained_mr/mock/runner.rb +86 -0
- data/lib/contained_mr/mock/template.rb +62 -0
- data/lib/contained_mr/mock.rb +3 -0
- data/lib/contained_mr/namespace.rb +24 -0
- data/lib/contained_mr/runner.rb +31 -24
- data/lib/contained_mr/runner_logic.rb +38 -0
- data/lib/contained_mr/template.rb +12 -71
- data/lib/contained_mr/template_logic.rb +91 -0
- data/lib/contained_mr.rb +10 -3
- data/test/concerns/job_state_cases.rb +75 -0
- data/test/helper.rb +1 -0
- data/test/test_cleaner.rb +6 -6
- data/test/test_contained_mr.rb +15 -0
- data/test/test_job.rb +36 -47
- data/test/test_job_logic.rb +52 -0
- data/test/test_mock_job.rb +94 -0
- data/test/test_mock_runner.rb +99 -0
- data/test/test_mock_template.rb +39 -0
- data/test/test_runner.rb +21 -6
- data/test/test_runner_logic.rb +51 -0
- data/test/test_template.rb +15 -28
- data/test/test_template_logic.rb +47 -0
- metadata +52 -21
data/test/test_job.rb
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
require 'helper'
|
2
|
+
require_relative 'concerns/job_state_cases.rb'
|
2
3
|
|
3
4
|
class TestJob < MiniTest::Test
|
4
5
|
def setup
|
5
|
-
@template = ContainedMr
|
6
|
+
@template = ContainedMr.new_template 'contained_mrtests', 'hello',
|
6
7
|
StringIO.new(File.binread('testdata/hello.zip'))
|
7
|
-
@job =
|
8
|
-
|
8
|
+
@job = @template.new_job 'testjob',
|
9
|
+
JSON.load(File.read('testdata/job.hello'))
|
9
10
|
end
|
10
11
|
|
11
12
|
def teardown
|
@@ -13,46 +14,13 @@ class TestJob < MiniTest::Test
|
|
13
14
|
@template.destroy!
|
14
15
|
end
|
15
16
|
|
16
|
-
def test_mapper_container_options
|
17
|
-
@job.build_mapper_image File.read('testdata/input.hello')
|
18
|
-
|
19
|
-
golden = {
|
20
|
-
'name' => 'contained_mrtests_mapper.testjob.2',
|
21
|
-
'Image' => @job.mapper_image_id,
|
22
|
-
'Hostname' => '2.mapper',
|
23
|
-
'Domainname' => '',
|
24
|
-
'Labels' => { 'contained_mr.ctl' => 'contained_mrtests' },
|
25
|
-
'Env' => [ 'ITEM=2', 'ITEMS=3' ],
|
26
|
-
'Ulimits' => [
|
27
|
-
{ 'Name' => 'cpu', 'Hard' => 3, 'Soft' => 3 },
|
28
|
-
{ 'Name' => 'rss', 'Hard' => 1000000, 'Soft' => 1000000 },
|
29
|
-
],
|
30
|
-
'NetworkDisabled' => true, 'ExposedPorts' => {},
|
31
|
-
}
|
32
|
-
assert_equal golden, @job.mapper_container_options(2)
|
33
|
-
end
|
34
|
-
|
35
|
-
def test_reducer_container_options
|
36
|
-
golden = {
|
37
|
-
'name' => 'contained_mrtests_reducer.testjob',
|
38
|
-
'Image' => @job.mapper_image_id,
|
39
|
-
'Hostname' => 'reducer',
|
40
|
-
'Domainname' => '',
|
41
|
-
'Labels' => { 'contained_mr.ctl' => 'contained_mrtests' },
|
42
|
-
'Env' => [ 'ITEMS=3' ],
|
43
|
-
'Ulimits' => [
|
44
|
-
{ 'Name' => 'cpu', 'Hard' => 2, 'Soft' => 2 },
|
45
|
-
{ 'Name' => 'rss', 'Hard' => 100000, 'Soft' => 100000 },
|
46
|
-
],
|
47
|
-
'NetworkDisabled' => true, 'ExposedPorts' => {},
|
48
|
-
}
|
49
|
-
assert_equal golden, @job.reducer_container_options
|
50
|
-
end
|
51
|
-
|
52
17
|
def test_build_mapper_image
|
53
18
|
assert_equal 'contained_mrtests/mapper.testjob', @job.mapper_image_tag
|
54
19
|
|
55
|
-
@job.
|
20
|
+
assert_equal nil, @job.mapper_image_id
|
21
|
+
mapper_return = @job.build_mapper_image File.read('testdata/input.hello')
|
22
|
+
assert_equal mapper_return, @job.mapper_image_id
|
23
|
+
|
56
24
|
image = Docker::Image.get @job.mapper_image_tag
|
57
25
|
assert image, 'Docker::Image'
|
58
26
|
assert_operator image.id, :start_with?, @job.mapper_image_id
|
@@ -63,10 +31,22 @@ class TestJob < MiniTest::Test
|
|
63
31
|
assert_nil @job.reducer_runner, "Reducer started prematurely"
|
64
32
|
end
|
65
33
|
|
34
|
+
def test_created_mapper_image_tags
|
35
|
+
@job.build_mapper_image File.read('testdata/input.hello')
|
36
|
+
|
37
|
+
images = Docker::Image.all
|
38
|
+
image = images.find { |i| i.id.start_with? @job.mapper_image_id }
|
39
|
+
assert image, 'Docker::Image in collection returned by Docker::Image.all'
|
40
|
+
assert image.info['RepoTags'], "Image missing RepoTags: #{image.inspect}"
|
41
|
+
assert_includes image.info['RepoTags'],
|
42
|
+
'contained_mrtests/mapper.testjob:latest'
|
43
|
+
end
|
44
|
+
|
66
45
|
def test_run_mapper_stderr
|
67
46
|
@job.build_mapper_image File.read('testdata/input.hello')
|
68
|
-
@job.run_mapper 2
|
47
|
+
runner = @job.run_mapper 2
|
69
48
|
|
49
|
+
assert_equal runner, @job.mapper_runner(2), 'mapper_runner return'
|
70
50
|
assert_nil @job.mapper_runner(1), 'Mapper 1 started prematurely'
|
71
51
|
assert_nil @job.mapper_runner(3), 'Mapper 3 started prematurely'
|
72
52
|
assert_nil @job.reducer_runner, 'Reducer started prematurely'
|
@@ -106,6 +86,13 @@ class TestJob < MiniTest::Test
|
|
106
86
|
assert_operator image.id, :start_with?, @job.reducer_image_id
|
107
87
|
|
108
88
|
assert_nil @job.reducer_runner, "Reducer started prematurely"
|
89
|
+
|
90
|
+
images = Docker::Image.all
|
91
|
+
image = images.find { |i| i.id.start_with? @job.reducer_image_id }
|
92
|
+
assert image, 'Docker::Image in collection returned by Docker::Image.all'
|
93
|
+
assert image.info['RepoTags'], "Image missing RepoTags: #{image.inspect}"
|
94
|
+
assert_includes image.info['RepoTags'],
|
95
|
+
'contained_mrtests/reducer.testjob:latest'
|
109
96
|
end
|
110
97
|
|
111
98
|
def test_run_reducer
|
@@ -114,7 +101,7 @@ class TestJob < MiniTest::Test
|
|
114
101
|
@job.build_reducer_image
|
115
102
|
reducer = @job.run_reducer
|
116
103
|
|
117
|
-
|
104
|
+
assert_equal reducer, @job.reducer_runner, 'reducer_runner return'
|
118
105
|
assert_equal "3 /\n", reducer.stderr, 'Stderr: $ITEMS + $PWD'
|
119
106
|
|
120
107
|
output_gold = "1\n2\n3\n" +
|
@@ -140,7 +127,7 @@ class TestJob < MiniTest::Test
|
|
140
127
|
1.upto(3) { |i| @job.run_mapper i }
|
141
128
|
@job.build_reducer_image
|
142
129
|
|
143
|
-
@job.destroy!
|
130
|
+
assert_equal @job, @job.destroy!
|
144
131
|
|
145
132
|
assert_raises Docker::Error::NotFoundError do
|
146
133
|
Docker::Image.get @job.mapper_image_tag
|
@@ -155,13 +142,13 @@ class TestJob < MiniTest::Test
|
|
155
142
|
1.upto(3) { |i| @job.run_mapper i }
|
156
143
|
@job.build_reducer_image
|
157
144
|
|
158
|
-
job2 =
|
159
|
-
|
145
|
+
job2 = @template.new_job 'testjob2',
|
146
|
+
JSON.load(File.read('testdata/job.hello'))
|
160
147
|
job2.build_mapper_image File.read('testdata/input.hello')
|
161
148
|
1.upto(3) { |i| job2.run_mapper i }
|
162
149
|
job2.build_reducer_image
|
163
150
|
|
164
|
-
job2.destroy!
|
151
|
+
assert_equal job2, job2.destroy!
|
165
152
|
|
166
153
|
assert_raises Docker::Error::NotFoundError do
|
167
154
|
Docker::Image.get job2.mapper_image_tag
|
@@ -176,7 +163,7 @@ class TestJob < MiniTest::Test
|
|
176
163
|
image = Docker::Image.get @job.reducer_image_tag
|
177
164
|
assert image, "destroy! wiped the other job's reducer image"
|
178
165
|
|
179
|
-
@job.destroy!
|
166
|
+
assert_equal @job, @job.destroy!
|
180
167
|
|
181
168
|
assert_raises Docker::Error::NotFoundError do
|
182
169
|
Docker::Image.get @job.mapper_image_tag
|
@@ -185,4 +172,6 @@ class TestJob < MiniTest::Test
|
|
185
172
|
Docker::Image.get @job.reducer_image_tag
|
186
173
|
end
|
187
174
|
end
|
175
|
+
|
176
|
+
include JobStateCases
|
188
177
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestJobLogic < MiniTest::Test
|
4
|
+
def setup
|
5
|
+
ContainedMr.stubs(:template_class).returns ContainedMr::Mock::Template
|
6
|
+
@template = ContainedMr.new_template 'contained_mrtests', 'hello',
|
7
|
+
StringIO.new(File.binread('testdata/hello.zip'))
|
8
|
+
@job = @template.new_job 'testjob',
|
9
|
+
JSON.load(File.read('testdata/job.hello'))
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_mapper_container_options
|
13
|
+
assert_equal @template, @job.template
|
14
|
+
assert_equal 'contained_mrtests', @job.name_prefix
|
15
|
+
assert_equal 'testjob', @job.id
|
16
|
+
assert_equal 3, @job.item_count
|
17
|
+
|
18
|
+
@job.build_mapper_image File.read('testdata/input.hello')
|
19
|
+
|
20
|
+
golden = {
|
21
|
+
'name' => 'contained_mrtests_mapper.testjob.2',
|
22
|
+
'Image' => @job.mapper_image_id,
|
23
|
+
'Hostname' => '2.mapper',
|
24
|
+
'Domainname' => '',
|
25
|
+
'Labels' => { 'contained_mr.ctl' => 'contained_mrtests' },
|
26
|
+
'Env' => [ 'ITEM=2', 'ITEMS=3' ],
|
27
|
+
'Ulimits' => [
|
28
|
+
{ 'Name' => 'cpu', 'Hard' => 3, 'Soft' => 3 },
|
29
|
+
{ 'Name' => 'rss', 'Hard' => 1000000, 'Soft' => 1000000 },
|
30
|
+
],
|
31
|
+
'NetworkDisabled' => true, 'ExposedPorts' => {},
|
32
|
+
}
|
33
|
+
assert_equal golden, @job.mapper_container_options(2)
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_reducer_container_options
|
37
|
+
golden = {
|
38
|
+
'name' => 'contained_mrtests_reducer.testjob',
|
39
|
+
'Image' => @job.mapper_image_id,
|
40
|
+
'Hostname' => 'reducer',
|
41
|
+
'Domainname' => '',
|
42
|
+
'Labels' => { 'contained_mr.ctl' => 'contained_mrtests' },
|
43
|
+
'Env' => [ 'ITEMS=3' ],
|
44
|
+
'Ulimits' => [
|
45
|
+
{ 'Name' => 'cpu', 'Hard' => 2, 'Soft' => 2 },
|
46
|
+
{ 'Name' => 'rss', 'Hard' => 100000, 'Soft' => 100000 },
|
47
|
+
],
|
48
|
+
'NetworkDisabled' => true, 'ExposedPorts' => {},
|
49
|
+
}
|
50
|
+
assert_equal golden, @job.reducer_container_options
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require_relative 'concerns/job_state_cases.rb'
|
3
|
+
|
4
|
+
class TestMockJob < MiniTest::Test
|
5
|
+
def setup
|
6
|
+
ContainedMr.stubs(:template_class).returns ContainedMr::Mock::Template
|
7
|
+
@template = ContainedMr.new_template 'contained_mrtests', 'hello',
|
8
|
+
StringIO.new(File.binread('testdata/hello.zip'))
|
9
|
+
@job = ContainedMr::Mock::Job.new @template, 'testjob',
|
10
|
+
JSON.load(File.read('testdata/job.hello'))
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_mocking_setup
|
14
|
+
assert_instance_of ContainedMr::Mock::Template, @template
|
15
|
+
assert_instance_of ContainedMr::Mock::Job, @job
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_constructor_readers
|
19
|
+
assert_equal @template, @job.template
|
20
|
+
assert_equal 'contained_mrtests', @job.name_prefix
|
21
|
+
assert_equal 'testjob', @job.id
|
22
|
+
assert_equal 3, @job.item_count
|
23
|
+
|
24
|
+
assert_equal 2.5, @job._json_options['mapper']['wait_time']
|
25
|
+
assert_equal nil, @job._mapper_input
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_build_mapper_image
|
29
|
+
input = File.read('testdata/input.hello')
|
30
|
+
|
31
|
+
assert_equal nil, @job.mapper_image_id
|
32
|
+
assert_equal 'mock-job-mapper-image-id', @job.build_mapper_image(input)
|
33
|
+
assert_equal 'mock-job-mapper-image-id', @job.mapper_image_id
|
34
|
+
|
35
|
+
assert_equal input, @job._mapper_input
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_run_mapper
|
39
|
+
@job.build_mapper_image File.read('testdata/input.hello')
|
40
|
+
|
41
|
+
mock_runner = @job._mock_mapper_runner 2
|
42
|
+
assert_equal nil, @job.mapper_runner(2)
|
43
|
+
assert_equal mock_runner, @job.run_mapper(2)
|
44
|
+
assert_equal mock_runner, @job.mapper_runner(2)
|
45
|
+
|
46
|
+
assert_equal 2.5, mock_runner._time_limit
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_mock_mapper_runner
|
50
|
+
assert_raises ArgumentError do
|
51
|
+
@job._mock_mapper_runner 4
|
52
|
+
end
|
53
|
+
mock_runners = (1..3).map { |i| @job._mock_mapper_runner i }
|
54
|
+
assert_operator mock_runners[0], :!=, mock_runners[1]
|
55
|
+
assert_operator mock_runners[0], :!=, mock_runners[2]
|
56
|
+
assert_operator mock_runners[1], :!=, mock_runners[2]
|
57
|
+
|
58
|
+
@job.build_mapper_image File.read('testdata/input.hello')
|
59
|
+
|
60
|
+
assert_equal mock_runners[0], @job.run_mapper(1)
|
61
|
+
assert_equal mock_runners[1], @job.run_mapper(2)
|
62
|
+
assert_equal mock_runners[2], @job.run_mapper(3)
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_build_reducer_image
|
66
|
+
@job.build_mapper_image File.read('testdata/input.hello')
|
67
|
+
1.upto(3) { |i| @job.run_mapper i }
|
68
|
+
|
69
|
+
assert_equal nil, @job.reducer_image_id
|
70
|
+
assert_equal 'mock-job-reducer-image-id', @job.build_reducer_image
|
71
|
+
assert_equal 'mock-job-reducer-image-id', @job.reducer_image_id
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_run_reducer
|
75
|
+
@job.build_mapper_image File.read('testdata/input.hello')
|
76
|
+
1.upto(3) { |i| @job.run_mapper i }
|
77
|
+
@job.build_reducer_image
|
78
|
+
|
79
|
+
mock_runner = @job._mock_reducer_runner
|
80
|
+
assert_equal nil, @job.reducer_runner
|
81
|
+
assert_equal mock_runner, @job.run_reducer
|
82
|
+
assert_equal mock_runner, @job.reducer_runner
|
83
|
+
|
84
|
+
assert_equal 2, mock_runner._time_limit
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_destroy
|
88
|
+
assert_equal false, @job.destroyed?
|
89
|
+
assert_equal @job, @job.destroy!
|
90
|
+
assert_equal true, @job.destroyed?
|
91
|
+
end
|
92
|
+
|
93
|
+
include JobStateCases
|
94
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestMockRunner < MiniTest::Test
|
4
|
+
def setup
|
5
|
+
@container_options = {
|
6
|
+
'name' => 'contained_mrtests_mapper.testjob.2',
|
7
|
+
'Image' => 'mapperimageid',
|
8
|
+
'Hostname' => '2.mapper',
|
9
|
+
'Domainname' => '',
|
10
|
+
'Labels' => { 'contained_mr.ctl' => 'contained_mrtests' },
|
11
|
+
'Env' => [ 'ITEM=2', 'ITEMS=3' ],
|
12
|
+
'Ulimits' => [
|
13
|
+
{ 'Name' => 'cpu', 'Hard' => 3, 'Soft' => 3 },
|
14
|
+
{ 'Name' => 'rss', 'Hard' => 1000000, 'Soft' => 1000000 },
|
15
|
+
],
|
16
|
+
'NetworkDisabled' => true, 'ExposedPorts' => {},
|
17
|
+
}
|
18
|
+
@runner = ContainedMr::Mock::Runner.new @container_options, 2.5,
|
19
|
+
'/usr/mrd/map-output'
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_constructor_readers
|
23
|
+
assert_equal @container_options, @runner._container_options
|
24
|
+
assert_equal 2.5, @runner._time_limit
|
25
|
+
assert_equal '/usr/mrd/map-output', @runner._output_path
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_perform
|
29
|
+
assert_equal false, @runner.performed?
|
30
|
+
assert_equal @runner, @runner.perform
|
31
|
+
assert_equal true, @runner.performed?
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_destroy
|
35
|
+
assert_equal false, @runner.destroyed?
|
36
|
+
assert_equal @runner, @runner.destroy!
|
37
|
+
assert_equal true, @runner.destroyed?
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_json_file
|
41
|
+
@runner._mock_set status_code: 1, timed_out: true
|
42
|
+
|
43
|
+
golden_json = { ran_for: nil, exit_code: 1, timed_out: true }
|
44
|
+
assert_equal golden_json, @runner.json_file
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_mock_set
|
48
|
+
assert_equal nil, @runner.started_at
|
49
|
+
assert_equal nil, @runner.ended_at
|
50
|
+
assert_equal nil, @runner.status_code
|
51
|
+
assert_equal nil, @runner.timed_out
|
52
|
+
assert_equal nil, @runner.stdout
|
53
|
+
assert_equal nil, @runner.stderr
|
54
|
+
assert_equal nil, @runner.output
|
55
|
+
|
56
|
+
t0 = Time.now
|
57
|
+
t1 = t0 + 42
|
58
|
+
@runner._mock_set started_at: t0, ended_at: t1, status_code: 1,
|
59
|
+
timed_out: false, stdout: 'Hello world!',
|
60
|
+
stderr: 'Nothing to see here', output: 'Ohai'
|
61
|
+
|
62
|
+
assert_equal t0, @runner.started_at
|
63
|
+
assert_equal t1, @runner.ended_at
|
64
|
+
assert_equal 1, @runner.status_code
|
65
|
+
assert_equal false, @runner.timed_out
|
66
|
+
assert_equal 'Hello world!', @runner.stdout
|
67
|
+
assert_equal 'Nothing to see here', @runner.stderr
|
68
|
+
assert_equal 'Ohai', @runner.output
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_ulimit
|
72
|
+
assert_equal 3, @runner._ulimit('cpu')
|
73
|
+
assert_equal 1000000, @runner._ulimit('rss')
|
74
|
+
assert_equal nil, @runner._ulimit('nothing')
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_ulimit_with_mismatched_values
|
78
|
+
@container_options['Ulimits'][0]['Hard'] = 1
|
79
|
+
runner = ContainedMr::Mock::Runner.new @container_options, 2.5,
|
80
|
+
'/usr/mrd/map-output'
|
81
|
+
assert_equal 1000000, runner._ulimit('rss')
|
82
|
+
|
83
|
+
begin
|
84
|
+
runner._ulimit('cpu')
|
85
|
+
flunk 'No exception thrown'
|
86
|
+
rescue RuntimeError => e
|
87
|
+
assert_instance_of RuntimeError, e
|
88
|
+
assert_equal 'Hard/soft ulimit mismatch for cpu', e.message
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_ulimit_with_missing_ulimits_array
|
93
|
+
@container_options.delete 'Ulimits'
|
94
|
+
runner = ContainedMr::Mock::Runner.new @container_options, 2.5,
|
95
|
+
'/usr/mrd/map-output'
|
96
|
+
assert_equal nil, runner._ulimit('cpu')
|
97
|
+
assert_equal nil, runner._ulimit('rss')
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestMockTemplate < MiniTest::Test
|
4
|
+
def setup
|
5
|
+
ContainedMr.stubs(:template_class).returns ContainedMr::Mock::Template
|
6
|
+
@template = ContainedMr.new_template 'contained_mrtests', 'hello',
|
7
|
+
StringIO.new(File.binread('testdata/hello.zip'))
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_mocking_setup
|
11
|
+
assert_instance_of ContainedMr::Mock::Template, @template
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_constructor_readers
|
15
|
+
assert_equal 'contained_mrtests', @template.name_prefix
|
16
|
+
assert_equal 'hello', @template.id
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_image_id
|
20
|
+
assert_equal 'mock-template-image-id', @template.image_id
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_definition
|
24
|
+
assert_equal 3, @template.item_count
|
25
|
+
assert_equal '/usr/mrd/map-output',
|
26
|
+
@template._definition['mapper']['output']
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_zip_contents
|
30
|
+
assert_equal "Hello world!\n", @template._zip_contents['data/hello.txt']
|
31
|
+
assert_equal :directory, @template._zip_contents['data/']
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_destroy
|
35
|
+
assert_equal false, @template.destroyed?
|
36
|
+
@template.destroy!
|
37
|
+
assert_equal true, @template.destroyed?
|
38
|
+
end
|
39
|
+
end
|
data/test/test_runner.rb
CHANGED
@@ -2,10 +2,10 @@ require 'helper'
|
|
2
2
|
|
3
3
|
class TestRunner < MiniTest::Test
|
4
4
|
def setup
|
5
|
-
@template = ContainedMr
|
5
|
+
@template = ContainedMr.new_template 'contained_mrtests', 'hello',
|
6
6
|
StringIO.new(File.binread('testdata/hello.zip'))
|
7
|
-
@job =
|
8
|
-
|
7
|
+
@job = @template.new_job 'testjob',
|
8
|
+
JSON.load(File.read('testdata/job.hello'))
|
9
9
|
@job.build_mapper_image File.read('testdata/input.hello')
|
10
10
|
end
|
11
11
|
|
@@ -17,7 +17,7 @@ class TestRunner < MiniTest::Test
|
|
17
17
|
def test_perform_happy_path
|
18
18
|
runner = ContainedMr::Runner.new @job.mapper_container_options(2), 2.5,
|
19
19
|
@template.mapper_output_path
|
20
|
-
runner.perform
|
20
|
+
assert_equal runner, runner.perform
|
21
21
|
|
22
22
|
assert_equal nil, runner.container_id, 'container still running'
|
23
23
|
assert_operator runner.ended_at - runner.started_at, :<, 1, 'running time'
|
@@ -27,23 +27,30 @@ class TestRunner < MiniTest::Test
|
|
27
27
|
assert_equal "2\nmapper input file\nHello world!\n", runner.stdout,
|
28
28
|
'Stdout: $ITEM + mapper input file + data file'
|
29
29
|
assert_equal "2\n", runner.output, 'Output: ITEM env variable'
|
30
|
+
|
31
|
+
assert_equal runner.ended_at - runner.started_at,
|
32
|
+
runner.json_file[:ran_for]
|
33
|
+
assert_equal 0, runner.json_file[:exit_code]
|
34
|
+
assert_equal false, runner.json_file[:timed_out]
|
30
35
|
end
|
31
36
|
|
32
37
|
def test_perform_exit_code
|
33
38
|
runner = ContainedMr::Runner.new @job.mapper_container_options(3), 2.5,
|
34
39
|
@template.mapper_output_path
|
35
|
-
runner.perform
|
40
|
+
assert_equal runner, runner.perform
|
36
41
|
|
37
42
|
assert_equal nil, runner.container_id, 'container still running'
|
38
43
|
assert_operator runner.ended_at - runner.started_at, :<, 1, 'running time'
|
39
44
|
assert_equal 42, runner.status_code, 'status code'
|
40
45
|
assert_equal false, runner.timed_out, 'timed out'
|
46
|
+
|
47
|
+
assert_equal 42, runner.json_file[:exit_code]
|
41
48
|
end
|
42
49
|
|
43
50
|
def test_perform_timeout
|
44
51
|
runner = ContainedMr::Runner.new @job.mapper_container_options(1), 2.5,
|
45
52
|
@template.mapper_output_path
|
46
|
-
runner.perform
|
53
|
+
assert_equal runner, runner.perform
|
47
54
|
|
48
55
|
assert_equal nil, runner.container_id, 'container still running'
|
49
56
|
assert_equal false, runner.status_code, 'status code'
|
@@ -52,5 +59,13 @@ class TestRunner < MiniTest::Test
|
|
52
59
|
'running time'
|
53
60
|
assert_operator runner.ended_at - runner.started_at, :<, 2.8,
|
54
61
|
'running time'
|
62
|
+
|
63
|
+
assert_equal true, runner.json_file[:timed_out]
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_destroy_without_perform
|
67
|
+
runner = ContainedMr::Runner.new @job.mapper_container_options(2), 2.5,
|
68
|
+
@template.mapper_output_path
|
69
|
+
assert_equal runner, runner.destroy!
|
55
70
|
end
|
56
71
|
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestRunnerLogic < MiniTest::Test
|
4
|
+
def setup
|
5
|
+
@container_options = {
|
6
|
+
'name' => 'contained_mrtests_mapper.testjob.2',
|
7
|
+
'Image' => 'mapperimageid',
|
8
|
+
'Hostname' => '2.mapper',
|
9
|
+
'Domainname' => '',
|
10
|
+
'Labels' => { 'contained_mr.ctl' => 'contained_mrtests' },
|
11
|
+
'Env' => [ 'ITEM=2', 'ITEMS=3' ],
|
12
|
+
'Ulimits' => [
|
13
|
+
{ 'Name' => 'cpu', 'Hard' => 3, 'Soft' => 3 },
|
14
|
+
{ 'Name' => 'rss', 'Hard' => 1000000, 'Soft' => 1000000 },
|
15
|
+
],
|
16
|
+
'NetworkDisabled' => true, 'ExposedPorts' => {},
|
17
|
+
}
|
18
|
+
@runner = ContainedMr::Mock::Runner.new @container_options, 2.5,
|
19
|
+
'/usr/mrd/map-output'
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_ran_for_with_nil_start_end
|
23
|
+
assert_equal nil, @runner.ran_for
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_ran_for_with_nil_end
|
27
|
+
@runner._mock_set started_at: Time.now
|
28
|
+
assert_equal nil, @runner.ran_for
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_ran_for_with_nil_start
|
32
|
+
@runner._mock_set ended_at: Time.now
|
33
|
+
assert_equal nil, @runner.ran_for
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_ran_for_with_start_and_end
|
37
|
+
t0 = Time.now
|
38
|
+
@runner._mock_set started_at: t0, ended_at: t0 + 42
|
39
|
+
assert_equal 42, @runner.ran_for
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_json_file
|
43
|
+
t0 = Time.now
|
44
|
+
t1 = t0 + 42
|
45
|
+
@runner._mock_set started_at: t0, ended_at: t1, status_code: 1,
|
46
|
+
timed_out: false
|
47
|
+
|
48
|
+
golden_json = { ran_for: 42, exit_code: 1, timed_out: false }
|
49
|
+
assert_equal golden_json, @runner.json_file
|
50
|
+
end
|
51
|
+
end
|
data/test/test_template.rb
CHANGED
@@ -2,7 +2,7 @@ require 'helper'
|
|
2
2
|
|
3
3
|
class TestTemplate < MiniTest::Test
|
4
4
|
def setup
|
5
|
-
@template = ContainedMr
|
5
|
+
@template = ContainedMr.new_template 'contained_mrtests', 'hello',
|
6
6
|
StringIO.new(File.binread('testdata/hello.zip'))
|
7
7
|
end
|
8
8
|
|
@@ -11,48 +11,35 @@ class TestTemplate < MiniTest::Test
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def test_image_id_matches_created_image
|
14
|
+
assert_equal 'contained_mrtests', @template.name_prefix
|
15
|
+
assert_equal 'hello', @template.id
|
16
|
+
|
14
17
|
image = Docker::Image.get @template.image_tag
|
15
18
|
assert image, 'Docker::Image'
|
16
19
|
assert_operator image.id, :start_with?, @template.image_id
|
17
20
|
end
|
18
21
|
|
19
|
-
def
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
assert_equal golden, @template.mapper_dockerfile, 'mapper Dockerfile'
|
27
|
-
|
28
|
-
golden = File.read 'testdata/Dockerfile.hello.reducer'
|
29
|
-
golden.sub! 'contained_mrtests/base.hello', @template.image_id
|
30
|
-
assert_equal golden, @template.reducer_dockerfile, 'reducer Dockerfile'
|
31
|
-
end
|
32
|
-
|
33
|
-
def test_paths
|
34
|
-
assert_equal '/usr/mrd/map-output', @template.mapper_output_path
|
35
|
-
assert_equal '/usr/mrd/reduce-output', @template.reducer_output_path
|
36
|
-
end
|
37
|
-
|
38
|
-
def test_envs
|
39
|
-
assert_equal 3, @template.item_count
|
40
|
-
assert_equal ['ITEM=2', 'ITEMS=3'], @template.mapper_env(2)
|
41
|
-
assert_equal ['ITEMS=3'], @template.reducer_env
|
22
|
+
def test_created_image_tags
|
23
|
+
images = Docker::Image.all
|
24
|
+
image = images.find { |i| i.id.start_with? @template.image_id }
|
25
|
+
assert image, 'Docker::Image in collection returned by Docker::Image.all'
|
26
|
+
assert image.info['RepoTags'], "Image missing RepoTags: #{image.inspect}"
|
27
|
+
assert_includes image.info['RepoTags'],
|
28
|
+
'contained_mrtests/base.hello:latest'
|
42
29
|
end
|
43
30
|
|
44
31
|
def test_destroy
|
45
|
-
@template.destroy!
|
32
|
+
assert_equal @template, @template.destroy!
|
46
33
|
assert_raises Docker::Error::NotFoundError do
|
47
34
|
Docker::Image.get @template.image_tag
|
48
35
|
end
|
49
36
|
end
|
50
37
|
|
51
38
|
def test_destory_with_two_templates
|
52
|
-
template2 = ContainedMr
|
39
|
+
template2 = ContainedMr.new_template 'contained_mrtests', 'hello2',
|
53
40
|
StringIO.new(File.binread('testdata/hello.zip'))
|
54
41
|
|
55
|
-
template2.destroy!
|
42
|
+
assert_equal template2, template2.destroy!
|
56
43
|
assert_raises Docker::Error::NotFoundError do
|
57
44
|
Docker::Image.get template2.image_tag
|
58
45
|
end
|
@@ -60,7 +47,7 @@ class TestTemplate < MiniTest::Test
|
|
60
47
|
image = Docker::Image.get @template.image_tag
|
61
48
|
assert image, "destroy! wiped the other template's image"
|
62
49
|
|
63
|
-
@template.destroy!
|
50
|
+
assert_equal @template, @template.destroy!
|
64
51
|
assert_raises Docker::Error::NotFoundError do
|
65
52
|
Docker::Image.get @template.image_tag
|
66
53
|
end
|