contained_mr 0.1.2 → 0.2.0
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
- 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
|