contained_mr 0.4.0 → 0.4.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e185d4610f9518f8f95924cd6569f8f62bdd309d
4
- data.tar.gz: 9dc30131aa6475f07b3e5042e43877dbab91d0a3
3
+ metadata.gz: a2802a380e19e314a40493959bace7208a0a8109
4
+ data.tar.gz: fb912e50f9e146624364edda1272faeff971f133
5
5
  SHA512:
6
- metadata.gz: 597919494dce5409863b1ecd5d8ea9b75870f6705d945e74822995501184b6a0138fdd730a6c04e2a0bbe1bb7c85bcb3028f5a1c6291ec2bd0284bc01d06dfc3
7
- data.tar.gz: c0936fd70b787f76aa222186ee6e915b9d400f0abb036af0c09a038c33a6049e4cf11d4435ab3c0dea6291a5fae6feb13a0b7eb6c647e4fa24e4a006f49add3d
6
+ metadata.gz: 82d975a57ef901d4909d8dce6f92d240725fb3ad09d8c3e8f0614c51d98df0cdfbc6c7435bffeb1f734b40025d9487bb89f7e2c40c2e41fb9433d48df2b6238a
7
+ data.tar.gz: 6f034abfe4bf32dd2ab17ac17c89eab1c7b6d3f1cf2e4bd4296288c638421ec89f3d97cf8252836ef88d1473fe8e4bf166399f1cbf6f51a56816d2597db19981
data/README.md CHANGED
@@ -23,7 +23,7 @@ brew cask install virtualbox
23
23
  Create a Docker VM. This is a one-time setup.
24
24
 
25
25
  ```bash
26
- docker-machine create --driver virtualbox dev
26
+ docker-machine create --driver virtualbox --engine-storage-driver overlay dev
27
27
  ```
28
28
 
29
29
  Set up the local environment to point to the Docker daemon in the VM. This must
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.0
1
+ 0.4.1
data/contained_mr.gemspec CHANGED
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: contained_mr 0.4.0 ruby lib
5
+ # stub: contained_mr 0.4.1 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "contained_mr"
9
- s.version = "0.4.0"
9
+ s.version = "0.4.1"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib"]
13
13
  s.authors = ["Victor Costan"]
14
- s.date = "2015-10-17"
14
+ s.date = "2015-10-27"
15
15
  s.description = "Plumbing for running mappers and reducers inside Docker containers"
16
16
  s.email = "victor@costan.us"
17
17
  s.extra_rdoc_files = [
@@ -14,23 +14,32 @@ class ContainedMr::Cleaner
14
14
  end
15
15
 
16
16
  # Removes all images and containers matching this cleaner's name prefix.
17
+ #
18
+ # @return {Array<Docker::Container, Docker::Image>} the removed objects
17
19
  def destroy_all!
18
- destroy_all_containers!
19
- destroy_all_images!
20
+ containers = destroy_all_containers!
21
+ images = destroy_all_images!
22
+ containers + images
20
23
  end
21
24
 
25
+ # @return {Array<Docker::Container>} the removed containers
22
26
  def destroy_all_containers!
23
27
  containers = Docker::Container.all all: true,
24
28
  filters: container_filters.to_json
25
29
  containers.each do |container|
26
- container.delete force: false, volumes: true
30
+ begin
31
+ container.delete force: false, volumes: true
32
+ rescue Docker::Error::NotFoundError
33
+ # Workaround for https://github.com/docker/docker/issues/14474
34
+ end
27
35
  end
28
36
  end
29
- private :destroy_all_containers!
30
37
 
38
+ # @return {Array<Docker::Image>} the removed images
31
39
  def destroy_all_images!
32
40
  tag_prefix = "#{@name_prefix}/"
33
41
  images = Docker::Image.all
42
+ deleted_images = []
34
43
  images.each do |image|
35
44
  next unless image_tags = image.info['RepoTags']
36
45
  image_tags.each do |image_tag|
@@ -38,10 +47,11 @@ class ContainedMr::Cleaner
38
47
  # HACK(pwnall): Trick docker-api into issuing a DELETE request by tag.
39
48
  tag_image = Docker::Image.new Docker.connection, 'id' => image_tag
40
49
  tag_image.delete
50
+ deleted_images << image
41
51
  end
42
52
  end
53
+ deleted_images
43
54
  end
44
- private :destroy_all_images!
45
55
 
46
56
  # @return { Hash<Symbol, Array<String>> } filters used to identify Docker
47
57
  # containers started by this controller
@@ -50,7 +50,11 @@ class ContainedMr::Runner
50
50
  def destroy!(container = nil)
51
51
  unless @container_id.nil?
52
52
  container ||= Docker::Container.get @container_id
53
- container.delete force: true
53
+ begin
54
+ container.delete force: true
55
+ rescue Docker::Error::NotFoundError
56
+ # Workaround for https://github.com/docker/docker/issues/14474
57
+ end
54
58
  @container_id = nil
55
59
  end
56
60
  self
data/test/test_cleaner.rb CHANGED
@@ -7,12 +7,30 @@ class TestCleaner < MiniTest::Test
7
7
  @job = @template.new_job 'testjob',
8
8
  JSON.load(File.read('testdata/job.hello'))
9
9
  @job.build_mapper_image File.read('testdata/input.hello')
10
+ @runner = ContainedMr::Runner.new @job.mapper_container_options(2), 2.5,
11
+ @template.mapper_output_path
12
+ class <<@runner
13
+ def destroy!(*args)
14
+ self
15
+ end
16
+ end
17
+ @runner.perform
10
18
 
11
19
  @cleaner = ContainedMr::Cleaner.new 'contained_mrtests'
12
20
  end
13
21
 
14
- def test_destroy_all
22
+ def teardown
23
+ Docker::Container.any_instance.unstub :delete
15
24
  @cleaner.destroy_all!
25
+ end
26
+
27
+ def test_destroy_all
28
+ objects = @cleaner.destroy_all!
29
+ assert_equal 3, objects.length
30
+ assert_kind_of Docker::Container, objects[0]
31
+ assert_kind_of Docker::Image, objects[1]
32
+ assert_kind_of Docker::Image, objects[2]
33
+
16
34
  assert_raises Docker::Error::NotFoundError do
17
35
  Docker::Image.get @job.mapper_image_tag
18
36
  end
@@ -27,7 +45,24 @@ class TestCleaner < MiniTest::Test
27
45
  job2 = template2.new_job 'testjob2',
28
46
  JSON.load(File.read('testdata/job.hello'))
29
47
  job2.build_mapper_image File.read('testdata/input.hello')
30
- @cleaner.destroy_all!
48
+ runner2 = ContainedMr::Runner.new job2.mapper_container_options(2), 2.5,
49
+ template2.mapper_output_path
50
+ class <<runner2
51
+ def destroy!(*args)
52
+ self
53
+ end
54
+ end
55
+ runner2.perform
56
+
57
+ objects = @cleaner.destroy_all!
58
+ assert_equal 6, objects.length
59
+ assert_kind_of Docker::Container, objects[0]
60
+ assert_kind_of Docker::Container, objects[1]
61
+ assert_kind_of Docker::Image, objects[2]
62
+ assert_kind_of Docker::Image, objects[3]
63
+ assert_kind_of Docker::Image, objects[4]
64
+ assert_kind_of Docker::Image, objects[5]
65
+
31
66
  assert_raises Docker::Error::NotFoundError do
32
67
  Docker::Image.get job2.mapper_image_tag
33
68
  end
@@ -41,4 +76,26 @@ class TestCleaner < MiniTest::Test
41
76
  Docker::Image.get @template.image_tag
42
77
  end
43
78
  end
79
+
80
+ def test_destroy_all_containers_with_duplicates_and_exceptions
81
+ template2 = ContainedMr.new_template 'contained_mrtests', 'hello2',
82
+ StringIO.new(File.binread('testdata/hello.zip'))
83
+ job2 = template2.new_job 'testjob2',
84
+ JSON.load(File.read('testdata/job.hello'))
85
+ job2.build_mapper_image File.read('testdata/input.hello')
86
+ runner2 = ContainedMr::Runner.new job2.mapper_container_options(2), 2.5,
87
+ template2.mapper_output_path
88
+ class <<runner2
89
+ def destroy!(*args)
90
+ self
91
+ end
92
+ end
93
+ runner2.perform
94
+
95
+ Docker::Container.any_instance.expects(:delete).twice.
96
+ raises Docker::Error::NotFoundError
97
+ containers = @cleaner.destroy_all_containers!
98
+ assert_equal 2, containers.length
99
+ containers.each { |c| assert_kind_of Docker::Container, c }
100
+ end
44
101
  end
data/test/test_runner.rb CHANGED
@@ -68,4 +68,39 @@ class TestRunner < MiniTest::Test
68
68
  @template.mapper_output_path
69
69
  assert_equal runner, runner.destroy!
70
70
  end
71
+
72
+ def test_destroy_invalid_container
73
+ runner = ContainedMr::Runner.new @job.mapper_container_options(2), 2.5,
74
+ @template.mapper_output_path
75
+
76
+ # HACK(pwnall): This is a dirty way of getting NotFoundError, which is also
77
+ # what the docker gem throws in docker#14474.
78
+ class <<runner
79
+ alias_method :old_destroy, :destroy!
80
+ def destroy!(container)
81
+ old_container_id = @container_id
82
+ old_destroy container
83
+ if container
84
+ @container_id = old_container_id
85
+ old_destroy container
86
+ end
87
+ end
88
+ end
89
+
90
+ assert_equal runner, runner.perform
91
+
92
+ assert_equal nil, runner.container_id, 'container still running'
93
+ assert_operator runner.ended_at - runner.started_at, :<, 1, 'running time'
94
+ assert_equal 0, runner.status_code, 'status code'
95
+ assert_equal false, runner.timed_out, 'timed out'
96
+ assert_equal "2 3\n", runner.stderr, 'Stderr: $ITEM + $ITEMS'
97
+ assert_equal "2\nmapper input file\nHello world!\n", runner.stdout,
98
+ 'Stdout: $ITEM + mapper input file + data file'
99
+ assert_equal "2\n", runner.output, 'Output: ITEM env variable'
100
+
101
+ assert_equal runner.ended_at - runner.started_at,
102
+ runner.json_file[:ran_for]
103
+ assert_equal 0, runner.json_file[:exit_code]
104
+ assert_equal false, runner.json_file[:timed_out]
105
+ end
71
106
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: contained_mr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Victor Costan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-17 00:00:00.000000000 Z
11
+ date: 2015-10-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: docker-api