foreman_docker 3.0.0 → 3.1.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.
Files changed (79) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +22 -22
  3. data/app/assets/javascripts/foreman_docker/image_step.js +36 -6
  4. data/app/controllers/api/v2/containers_controller.rb +13 -11
  5. data/app/controllers/containers/steps_controller.rb +8 -2
  6. data/app/controllers/containers_controller.rb +4 -3
  7. data/app/controllers/image_search_controller.rb +36 -79
  8. data/app/helpers/container_steps_helper.rb +21 -0
  9. data/app/models/concerns/foreman_docker/parameter_validators.rb +27 -4
  10. data/app/models/container.rb +9 -10
  11. data/app/models/docker_container_wizard_state.rb +2 -0
  12. data/app/models/docker_container_wizard_states/dns.rb +2 -8
  13. data/app/models/docker_container_wizard_states/environment.rb +4 -14
  14. data/app/models/docker_container_wizard_states/environment_variable.rb +2 -2
  15. data/app/models/docker_container_wizard_states/exposed_port.rb +2 -8
  16. data/app/models/docker_container_wizard_states/image.rb +30 -0
  17. data/app/models/docker_container_wizard_states/preliminary.rb +1 -1
  18. data/app/models/docker_parameter.rb +20 -0
  19. data/app/models/docker_registry.rb +6 -4
  20. data/app/models/environment_variable.rb +3 -3
  21. data/app/models/exposed_port.rb +4 -10
  22. data/app/models/foreman_docker/compute_resource_extensions.rb +11 -0
  23. data/app/models/foreman_docker/dns.rb +3 -9
  24. data/app/models/foreman_docker/docker.rb +1 -5
  25. data/app/models/service/containers.rb +15 -11
  26. data/app/models/service/registry_api.rb +87 -15
  27. data/app/services/foreman_docker/image_search.rb +92 -0
  28. data/app/views/containers/index.html.erb +1 -3
  29. data/app/views/containers/show.html.erb +1 -1
  30. data/app/views/containers/steps/_image_hub_tab.html.erb +39 -29
  31. data/app/views/containers/steps/_title.html.erb +1 -1
  32. data/app/views/containers/steps/preliminary.html.erb +1 -1
  33. data/app/views/foreman_docker/common_parameters/_dns_entry.html.erb +1 -1
  34. data/app/views/foreman_docker/common_parameters/_environment_variable.html.erb +1 -1
  35. data/app/views/foreman_docker/common_parameters/_exposed_port.html.erb +1 -1
  36. data/app/views/image_search/_repository_search_results.html.erb +1 -1
  37. data/app/views/registries/index.html.erb +1 -3
  38. data/app/views/registries/new.html.erb +1 -1
  39. data/db/migrate/20160605133025_create_docker_parameters.rb +13 -0
  40. data/db/migrate/20160605134652_move_parameters_to_docker_parameters.rb +27 -0
  41. data/lib/foreman_docker/engine.rb +6 -7
  42. data/lib/foreman_docker/version.rb +1 -1
  43. data/lib/tasks/test.rake +35 -0
  44. data/test/functionals/api/v2/containers_controller_test.rb +21 -0
  45. data/test/functionals/api/v2/registries_controller_test.rb +4 -3
  46. data/test/functionals/containers_controller_test.rb +5 -0
  47. data/test/functionals/containers_steps_controller_test.rb +74 -36
  48. data/test/functionals/image_search_controller_test.rb +166 -12
  49. data/test/integration/container_test.rb +1 -1
  50. data/test/test_plugin_helper.rb +10 -0
  51. data/test/units/container_test.rb +1 -1
  52. data/test/units/containers_service_test.rb +31 -9
  53. data/test/units/docker_container_wizard_states/image_test.rb +84 -0
  54. data/test/units/docker_registry_test.rb +27 -10
  55. data/test/units/foreman_docker/compute_resource_extensions_test.rb +10 -0
  56. data/test/units/image_search_service_test.rb +188 -0
  57. data/test/units/registry_api_test.rb +206 -12
  58. metadata +55 -36
  59. data/lib/foreman_docker/tasks/test.rake +0 -45
  60. data/locale/de/foreman_docker.edit.po +0 -631
  61. data/locale/de/foreman_docker.po.time_stamp +0 -0
  62. data/locale/es/foreman_docker.edit.po +0 -631
  63. data/locale/es/foreman_docker.po.time_stamp +0 -0
  64. data/locale/fr/foreman_docker.edit.po +0 -632
  65. data/locale/fr/foreman_docker.po.time_stamp +0 -0
  66. data/locale/it/foreman_docker.edit.po +0 -630
  67. data/locale/it/foreman_docker.po.time_stamp +0 -0
  68. data/locale/ja/foreman_docker.edit.po +0 -634
  69. data/locale/ja/foreman_docker.po.time_stamp +0 -0
  70. data/locale/ko/foreman_docker.edit.po +0 -629
  71. data/locale/ko/foreman_docker.po.time_stamp +0 -0
  72. data/locale/pt_BR/foreman_docker.edit.po +0 -631
  73. data/locale/pt_BR/foreman_docker.po.time_stamp +0 -0
  74. data/locale/ru/foreman_docker.edit.po +0 -630
  75. data/locale/ru/foreman_docker.po.time_stamp +0 -0
  76. data/locale/zh_CN/foreman_docker.edit.po +0 -628
  77. data/locale/zh_CN/foreman_docker.po.time_stamp +0 -0
  78. data/locale/zh_TW/foreman_docker.edit.po +0 -628
  79. data/locale/zh_TW/foreman_docker.po.time_stamp +0 -0
@@ -1,6 +1,11 @@
1
1
  require 'test_plugin_helper'
2
2
 
3
3
  class ContainersControllerTest < ActionController::TestCase
4
+ setup do
5
+ stub_image_existance
6
+ stub_registry_api
7
+ end
8
+
4
9
  test 'redirect if Docker provider is not available' do
5
10
  get :index, {}, set_session_user
6
11
  assert_redirected_to new_compute_resource_path
@@ -3,14 +3,16 @@ require 'test_plugin_helper'
3
3
  module Containers
4
4
  class StepsControllerTest < ActionController::TestCase
5
5
  setup do
6
+ stub_image_existance
7
+ stub_registry_api
6
8
  @container = FactoryGirl.create(:container)
9
+ @state = DockerContainerWizardState.create!
7
10
  end
8
11
 
9
12
  test 'wizard finishes with a redirect to the managed container' do
10
- state = DockerContainerWizardState.create!
11
- Service::Containers.any_instance.expects(:start_container!).with(equals(state))
13
+ Service::Containers.any_instance.expects(:start_container!).with(equals(@state))
12
14
  .returns(@container)
13
- put :update, { :wizard_state_id => state.id,
15
+ put :update, { :wizard_state_id => @state.id,
14
16
  :id => :environment,
15
17
  :start_on_create => true,
16
18
  :docker_container_wizard_states_environment => { :tty => false } },
@@ -19,41 +21,68 @@ module Containers
19
21
  assert_redirected_to container_path(:id => @container.id)
20
22
  end
21
23
 
22
- test 'image show doesnot load katello' do
23
- compute_resource = FactoryGirl.create(:docker_cr)
24
- state = DockerContainerWizardState.create!
25
- create_options = { :wizard_state => state,
26
- :compute_resource_id => compute_resource.id
24
+ describe 'on image step' do
25
+ setup do
26
+ @compute_resource = FactoryGirl.create(:docker_cr)
27
+ @create_options = { :wizard_state => @state,
28
+ :compute_resource_id => @compute_resource.id }
29
+ @state.preliminary = DockerContainerWizardStates::Preliminary.create!(@create_options)
30
+ DockerContainerWizardState.expects(:find).at_least_once.returns(@state)
31
+ end
32
+
33
+ test 'image show doesnot load katello' do
34
+ get :show, { :wizard_state_id => @state.id, :id => :image }, set_session_user
35
+ refute @state.image.katello?
36
+ refute response.body.include?("katello") # this is code generated by katello partial
37
+ docker_image = @controller.instance_eval do
38
+ @docker_container_wizard_states_image
39
+ end
40
+ assert_equal @state.image, docker_image
41
+ end
42
+
43
+ describe 'submitting' do
44
+ setup do
45
+ @image_params = {
46
+ docker_container_wizard_states_image: {
47
+ repository_name: 'test',
48
+ tag: 'test'
49
+ }}
50
+ @params = @image_params.merge({
51
+ wizard_state_id: @state.id,
52
+ id: :image,
53
+ })
54
+ end
55
+
56
+ test 'has no errors if the image exists' do
57
+ put :update, @params, set_session_user
58
+ assert_valid @state.image
59
+ assert css_select('#hub_image_search.has-error').size == 0
60
+ end
27
61
 
28
- }
29
- state.preliminary = DockerContainerWizardStates::Preliminary.create!(create_options)
30
- DockerContainerWizardState.expects(:find).at_least_once.returns(state)
31
- get :show, { :wizard_state_id => state.id, :id => :image }, set_session_user
32
- refute state.image.katello?
33
- refute response.body.include?("katello") # this is code generated by katello partial
34
- docker_image = @controller.instance_eval do
35
- @docker_container_wizard_states_image
62
+ test 'shows an error when the image does not exist' do
63
+ stub_image_existance(false)
64
+ put :update, @params, set_session_user
65
+ refute_valid @state.image
66
+ assert_select '#hub_image_search.has-error'
67
+ end
36
68
  end
37
- assert_equal state.image, docker_image
38
69
  end
39
70
 
40
71
  test 'new container respects exposed_ports configuration' do
41
- state = DockerContainerWizardState.create!
42
72
  environment_options = {
43
- :docker_container_wizard_state_id => state.id
73
+ :docker_container_wizard_state_id => @state.id
44
74
  }
45
- state.environment = DockerContainerWizardStates::Environment.create!(environment_options)
46
- state.environment.exposed_ports.create!(:name => '1654', :value => 'tcp')
47
- state.environment.exposed_ports.create!(:name => '1655', :value => 'udp')
48
- get :show, { :wizard_state_id => state.id, :id => :environment }, set_session_user
75
+ @state.environment = DockerContainerWizardStates::Environment.create!(environment_options)
76
+ @state.environment.exposed_ports.create!(:key => '1654', :value => 'tcp')
77
+ @state.environment.exposed_ports.create!(:key => '1655', :value => 'udp')
78
+ get :show, { :wizard_state_id => @state.id, :id => :environment }, set_session_user
49
79
  assert response.body.include?("1654")
50
80
  assert response.body.include?("1655")
51
81
 
52
82
  # Load ExposedPort variables into container
53
- state.environment.exposed_ports.each do |e|
54
- @container.exposed_ports.build :name => e.name,
55
- :value => e.value,
56
- :priority => e.priority
83
+ @state.environment.exposed_ports.each do |e|
84
+ @container.exposed_ports.build :key => e.key,
85
+ :value => e.value
57
86
  end
58
87
  # Check if parametrized value of container matches Docker API's expectations
59
88
  assert @container.parametrize.key? "ExposedPorts"
@@ -62,26 +91,35 @@ module Containers
62
91
  end
63
92
 
64
93
  test 'new container respects dns configuration' do
65
- state = DockerContainerWizardState.create!
66
94
  environment_options = {
67
- :docker_container_wizard_state_id => state.id
95
+ :docker_container_wizard_state_id => @state.id
68
96
  }
69
- state.environment = DockerContainerWizardStates::Environment.create!(environment_options)
70
- state.environment.dns.create!(:name => '18.18.18.18')
71
- state.environment.dns.create!(:name => '19.19.19.19')
72
- get :show, { :wizard_state_id => state.id, :id => :environment }, set_session_user
97
+ @state.environment = DockerContainerWizardStates::Environment.create!(environment_options)
98
+ @state.environment.dns.create!(:key => '18.18.18.18')
99
+ @state.environment.dns.create!(:key => '19.19.19.19')
100
+ get :show, { :wizard_state_id => @state.id, :id => :environment }, set_session_user
73
101
  assert response.body.include?("18.18.18.18")
74
102
  assert response.body.include?("19.19.19.19")
75
103
 
76
104
  # Load Dns variables into container
77
- state.environment.dns.each do |e|
78
- @container.dns.build :name => e.name,
79
- :priority => e.priority
105
+ @state.environment.dns.each do |e|
106
+ @container.dns.build :key => e.key
80
107
  end
81
108
  # Check if parametrized value of container matches Docker API's expectations
82
109
  assert @container.parametrize.key? "HostConfig"
83
110
  assert @container.parametrize["HostConfig"].key? "Dns"
84
111
  assert @container.parametrize["HostConfig"].value? ["18.18.18.18", "19.19.19.19"]
85
112
  end
113
+
114
+ test "does not create a container with 2 exposed ports with the same key" do
115
+ environment_options = {
116
+ :docker_container_wizard_state_id => @state.id
117
+ }
118
+ @state.environment = DockerContainerWizardStates::Environment.new(environment_options)
119
+ @state.environment.exposed_ports.new(:key => '1654', :value => 'tcp')
120
+ @state.environment.exposed_ports.new(:key => '1654', :value => 'udp')
121
+ refute_valid @state
122
+ assert_equal "Please ensure the following parameters are unique", @state.errors[:'environment.exposed_ports'].first
123
+ end
86
124
  end
87
125
  end
@@ -1,27 +1,179 @@
1
1
  require 'test_plugin_helper'
2
2
 
3
3
  class ImageSearchControllerTest < ActionController::TestCase
4
+ let(:docker_image) { 'centos' }
5
+ let(:tags) { ['latest', '5', '4.3'].map { |tag| "#{term}:#{tag}" } }
6
+ let(:term) { docker_image }
7
+
8
+ let(:docker_hub) { Service::RegistryApi.new(url: 'https://nothub.com') }
9
+ let(:compute_resource) { FactoryGirl.create(:docker_cr) }
10
+ let(:registry) { FactoryGirl.create(:docker_registry) }
11
+ let(:image_search_service) { ForemanDocker::ImageSearch.new }
12
+
4
13
  setup do
5
- @container = FactoryGirl.create(:docker_cr)
14
+ Service::RegistryApi.stubs(:docker_hub).returns(docker_hub)
15
+ ComputeResource::ActiveRecord_Relation.any_instance
16
+ .stubs(:find).returns(compute_resource)
17
+ DockerRegistry::ActiveRecord_Relation.any_instance
18
+ .stubs(:find).returns(registry)
19
+ end
20
+
21
+ describe '#auto_complete_repository_name' do
22
+ test 'returns if an image is available' do
23
+ exists = ['true', 'false'].sample
24
+ search_type = ['hub', 'registry'].sample
25
+ subject.instance_variable_set(:@image_search_service, image_search_service)
26
+ image_search_service.expects(:available?).returns(exists)
27
+
28
+ xhr :get, :auto_complete_repository_name,
29
+ { registry: search_type, search: term,
30
+ id: compute_resource }, set_session_user
31
+ assert_equal exists, response.body
32
+ end
33
+
34
+ context 'it is a Docker Hub tab request' do
35
+ let(:search_type) { 'hub' }
36
+
37
+ test 'it queries the compute_resource and Docker Hub' do
38
+ compute_resource.expects(:image).with(term)
39
+ .returns(term)
40
+ compute_resource.expects(:tags_for_local_image)
41
+ .returns(tags)
42
+ docker_hub.expects(:tags).returns([])
43
+
44
+ xhr :get, :auto_complete_repository_name,
45
+ { registry: search_type, search: term,
46
+ id: compute_resource }, set_session_user
47
+ end
48
+ end
49
+
50
+ context 'it is a External Registry tab request' do
51
+ let(:search_type) { 'registry' }
52
+
53
+ test 'it only queries the registry api' do
54
+ compute_resource.expects(:image).with(term).never
55
+ docker_hub.expects(:tags).never
56
+ registry.api.expects(:tags).with(term, nil)
57
+ .returns(['latest'])
58
+
59
+ xhr :get, :auto_complete_repository_name,
60
+ { registry: search_type, registry_id: registry,
61
+ search: term, id: compute_resource }, set_session_user
62
+ end
63
+ end
64
+ end
65
+
66
+ describe '#auto_complete_image_tag' do
67
+ let(:tag_fragment) { 'lat' }
68
+ let(:term) { "#{docker_image}:#{tag_fragment}"}
69
+
70
+ test 'returns an array of { label:, value: } hashes' do
71
+ search_type = ['hub', 'registry'].sample
72
+ subject.instance_variable_set(:@image_search_service, image_search_service)
73
+ image_search_service.expects(:search)
74
+ .with({ term: term, tags: 'true' })
75
+ .returns(tags)
76
+ xhr :get, :auto_complete_image_tag,
77
+ { registry: search_type, search: term,
78
+ id: compute_resource }, set_session_user
79
+ assert_equal tags.first, JSON.parse(response.body).first['value']
80
+ end
81
+
82
+ context 'a Docker Hub tab request' do
83
+ let(:search_type) { 'hub' }
84
+
85
+ test 'it searches Docker Hub and the ComputeResource' do
86
+ compute_resource.expects(:image).with(docker_image)
87
+ .returns(term)
88
+ compute_resource.expects(:tags_for_local_image)
89
+ .returns(tags)
90
+ docker_hub.expects(:tags).returns([])
91
+
92
+ xhr :get, :auto_complete_image_tag,
93
+ { registry: search_type, search: term,
94
+ id: compute_resource }, set_session_user
95
+ end
96
+ end
97
+
98
+ context 'it is a External Registry tab request' do
99
+ let(:search_type) { 'registry' }
100
+
101
+ test 'it only queries the registry api' do
102
+ compute_resource.expects(:image).with(docker_image).never
103
+ docker_hub.expects(:tags).never
104
+ registry.api.expects(:tags).with(docker_image, tag_fragment)
105
+ .returns([])
106
+
107
+ xhr :get, :auto_complete_image_tag,
108
+ { registry: search_type, registry_id: registry,
109
+ search: term, id: compute_resource }, set_session_user
110
+ end
111
+ end
112
+ end
113
+
114
+ describe '#search_repository' do
115
+ test 'returns html with the found images' do
116
+ search_type = ['hub', 'registry'].sample
117
+ subject.instance_variable_set(:@image_search_service, image_search_service)
118
+ image_search_service.expects(:search)
119
+ .with({ term: term, tags: 'false' })
120
+ .returns([{ 'name' => term}])
121
+ xhr :get, :search_repository,
122
+ { registry: search_type, search: term,
123
+ id: compute_resource }, set_session_user
124
+ assert response.body.include?(term)
125
+ end
126
+
127
+ context 'a Docker Hub tab request' do
128
+ let(:search_type) { 'hub' }
129
+
130
+ test 'it searches Docker Hub and the ComputeResource' do
131
+ compute_resource.expects(:local_images)
132
+ .returns([OpenStruct.new(info: { 'RepoTags' => [term] })])
133
+ docker_hub.expects(:search).returns({})
134
+
135
+ xhr :get, :search_repository,
136
+ { registry: search_type, search: term,
137
+ id: compute_resource }, set_session_user
138
+ end
139
+ end
140
+
141
+ context 'it is a External Registry tab request' do
142
+ let(:search_type) { 'registry' }
143
+
144
+ test 'it only queries the registry api' do
145
+ compute_resource.expects(:local_images).with(docker_image).never
146
+ docker_hub.expects(:search).never
147
+ registry.api.expects(:search).with(docker_image)
148
+ .returns({})
149
+
150
+ xhr :get, :search_repository,
151
+ { registry: search_type, registry_id: registry,
152
+ search: term, id: compute_resource }, set_session_user
153
+ end
154
+ end
6
155
  end
7
156
 
8
157
  [Docker::Error::DockerError, Excon::Errors::Error, Errno::ECONNREFUSED].each do |error|
9
158
  test 'auto_complete_repository_name catches exceptions on network errors' do
10
- ForemanDocker::Docker.any_instance.expects(:exist?).raises(error)
11
- get :auto_complete_repository_name, { :search => "test", :id => @container.id },
12
- set_session_user
159
+ ForemanDocker::ImageSearch.any_instance.expects(:available?)
160
+ .raises(error)
161
+ xhr :get, :auto_complete_repository_name,
162
+ { registry: 'hub', search: term, id: compute_resource }, set_session_user
13
163
  assert_response_is_expected
14
164
  end
15
165
 
16
166
  test 'auto_complete_image_tag catch exceptions on network errors' do
17
- ForemanDocker::Docker.any_instance.expects(:tags).raises(error)
18
- get :auto_complete_image_tag, { :search => "test", :id => @container.id }, set_session_user
167
+ ForemanDocker::ImageSearch.any_instance.expects(:search).raises(error)
168
+ xhr :get, :auto_complete_image_tag,
169
+ { registry: 'hub', search: term, id: compute_resource }, set_session_user
19
170
  assert_response_is_expected
20
171
  end
21
172
 
22
173
  test 'search_repository catch exceptions on network errors' do
23
- ForemanDocker::Docker.any_instance.expects(:search).raises(error)
24
- get :search_repository, { :search => "test", :id => @container.id }, set_session_user
174
+ ForemanDocker::ImageSearch.any_instance.expects(:search).raises(error)
175
+ xhr :get, :search_repository,
176
+ { registry: 'hub', search: term, id: compute_resource }, set_session_user
25
177
  assert_response_is_expected
26
178
  end
27
179
  end
@@ -36,8 +188,9 @@ class ImageSearchControllerTest < ActionController::TestCase
36
188
  "name" => repo_full_name,
37
189
  "star_count" => 0
38
190
  }]
39
- ForemanDocker::Docker.any_instance.expects(:search).returns(expected).at_least_once
40
- get :search_repository, { :search => "centos", :id => @container.id }, set_session_user
191
+ ForemanDocker::ImageSearch.any_instance.expects(:search).returns(expected).at_least_once
192
+ xhr :get, :search_repository,
193
+ { registry: 'hub', search: 'centos', id: compute_resource }, set_session_user
41
194
  assert_response :success
42
195
  refute response.body.include?(repo_full_name)
43
196
  assert response.body.include?(repository)
@@ -53,8 +206,9 @@ class ImageSearchControllerTest < ActionController::TestCase
53
206
  "name" => repo_full_name,
54
207
  "star_count" => 0
55
208
  }]
56
- ForemanDocker::Docker.any_instance.expects(:search).returns(expected).at_least_once
57
- get :search_repository, { :search => "centos", :id => @container.id }, set_session_user
209
+ ForemanDocker::ImageSearch.any_instance.expects(:search).returns(expected).at_least_once
210
+ xhr :get, :search_repository,
211
+ { registry: 'hub', search: 'centos', id: compute_resource }, set_session_user
58
212
  assert_response :success
59
213
  assert response.body.include?(repo_full_name)
60
214
  assert response.body.include?(repository)
@@ -12,7 +12,7 @@ class ContainerIntegrationTest < ActionDispatch::IntegrationTest
12
12
  ComputeResource.any_instance.stubs(:vms).returns([])
13
13
  FactoryGirl.create(:docker_cr)
14
14
  visit containers_path
15
- assert page.has_link? 'New container'
15
+ assert page.has_link? 'Create container'
16
16
  refute_equal current_path, new_compute_resource_path
17
17
  end
18
18
  end
@@ -12,3 +12,13 @@ end
12
12
  # Add plugin to FactoryGirl's paths
13
13
  FactoryGirl.definition_file_paths << File.join(File.dirname(__FILE__), 'factories')
14
14
  FactoryGirl.reload
15
+
16
+ def stub_image_existance(exists = true)
17
+ Docker::Image.any_instance.stubs(:exist?).returns(exists)
18
+ ForemanDocker::ImageSearch.any_instance.stubs(:available?).returns(exists)
19
+ end
20
+
21
+ def stub_registry_api
22
+ Service::RegistryApi.any_instance.stubs(:get).returns({'results' => []})
23
+ Docker::Image.stubs(:all).returns([])
24
+ end
@@ -6,5 +6,5 @@ class ContainerTest < ActiveSupport::TestCase
6
6
  should have_many(:environment_variables)
7
7
  should have_many(:dns)
8
8
  should have_many(:exposed_ports)
9
- should validate_uniqueness_of(:name)
9
+ should validate_uniqueness_of(:name).scoped_to(:compute_resource_id)
10
10
  end
@@ -1,12 +1,16 @@
1
1
  require 'test_plugin_helper'
2
+ require 'ostruct'
2
3
 
3
4
  class ContainersServiceTest < ActiveSupport::TestCase
4
5
  setup do
6
+ stub_image_existance
7
+ stub_registry_api
8
+
5
9
  @state = DockerContainerWizardState.create! do |s|
6
10
  s.build_preliminary(:compute_resource_id => FactoryGirl.create(:docker_cr).id,
7
11
  :locations => [taxonomies(:location1)],
8
12
  :organizations => [taxonomies(:organization1)])
9
- s.build_image(:repository_name => 'test', :tag => 'test')
13
+ s.build_image(:repository_name => 'test', :tag => 'test', :wizard_state => s)
10
14
  s.build_configuration(:name => 'test', :command => '/bin/bash')
11
15
  s.build_environment(:tty => false)
12
16
  end
@@ -25,14 +29,32 @@ class ContainersServiceTest < ActiveSupport::TestCase
25
29
  assert_equal DockerContainerWizardState.where(:id => @state.id).count, 0
26
30
  end
27
31
 
28
- test 'passes errors from compute resource' do
29
- # Since the compute resource will be unreachable, this test will always
30
- # fail at the 'pull_image' step
31
- containers_service = Service::Containers.new
32
- assert_raises(ActiveRecord::Rollback) do
33
- containers_service.create_container_object(@state)
32
+ context 'errors' do
33
+ setup do
34
+ @containers_service = Service::Containers.new
35
+ end
36
+
37
+ test 'from compute resource' do
38
+ # Since the compute resource will be unreachable, this test will always
39
+ # fail at the 'pull_image' step
40
+ assert_raises(ActiveRecord::Rollback) do
41
+ @containers_service.create_container_object(@state)
42
+ end
43
+ assert @containers_service.errors.present?
44
+ assert_match(/No such file or directory.*ENOENT/,
45
+ @containers_service.full_messages.join(' '))
34
46
  end
35
- assert containers_service.errors.present?
36
- end
37
47
 
48
+ test 'from multiple sources' do
49
+ Container.any_instance.expects(:valid?).returns(false)
50
+ Container.any_instance.stubs(:errors).returns(
51
+ OpenStruct.new(:full_messages => ['foo']))
52
+ assert_raises(ActiveRecord::Rollback) do
53
+ @containers_service.create_container_object(@state)
54
+ end
55
+ assert @containers_service.errors.present?
56
+ assert_match(/foo/,
57
+ @containers_service.full_messages.join(' '))
58
+ end
59
+ end
38
60
  end