foreman_deployments 0.0.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.
Files changed (133) hide show
  1. checksums.yaml +15 -0
  2. data/LICENSE +619 -0
  3. data/README.md +52 -0
  4. data/Rakefile +30 -0
  5. data/app/controllers/foreman_deployments/api/v2/base_controller.rb +25 -0
  6. data/app/controllers/foreman_deployments/api/v2/deployments_controller.rb +102 -0
  7. data/app/controllers/foreman_deployments/api/v2/stacks_controller.rb +52 -0
  8. data/app/controllers/foreman_deployments/create_resources_controller.rb +62 -0
  9. data/app/controllers/foreman_deployments/deployments_controller.rb +5 -0
  10. data/app/controllers/foreman_deployments/stacks_controller.rb +5 -0
  11. data/app/lib/foreman_deployments/base_dereference_visitor.rb +55 -0
  12. data/app/lib/foreman_deployments/config.rb +16 -0
  13. data/app/lib/foreman_deployments/config/array.rb +91 -0
  14. data/app/lib/foreman_deployments/config/configurator.rb +23 -0
  15. data/app/lib/foreman_deployments/config/hash.rb +81 -0
  16. data/app/lib/foreman_deployments/config/load_visitor.rb +23 -0
  17. data/app/lib/foreman_deployments/config/merge_visitor.rb +23 -0
  18. data/app/lib/foreman_deployments/config/save_visitor.rb +23 -0
  19. data/app/lib/foreman_deployments/inputs/base_input_definition.rb +39 -0
  20. data/app/lib/foreman_deployments/inputs/value.rb +25 -0
  21. data/app/lib/foreman_deployments/planner_visitor.rb +26 -0
  22. data/app/lib/foreman_deployments/registry.rb +67 -0
  23. data/app/lib/foreman_deployments/stack_definition.rb +37 -0
  24. data/app/lib/foreman_deployments/stack_parser.rb +121 -0
  25. data/app/lib/foreman_deployments/task_reference.rb +48 -0
  26. data/app/lib/foreman_deployments/tasks/base_action.rb +6 -0
  27. data/app/lib/foreman_deployments/tasks/base_definition.rb +72 -0
  28. data/app/lib/foreman_deployments/tasks/creation_task_definition.rb +68 -0
  29. data/app/lib/foreman_deployments/tasks/host_creation_task_definition.rb +44 -0
  30. data/app/lib/foreman_deployments/tasks/search_task_definition.rb +55 -0
  31. data/app/lib/foreman_deployments/tasks/stack_deploy_action.rb +10 -0
  32. data/app/lib/foreman_deployments/tasks/wait_until_built_task_definition.rb +65 -0
  33. data/app/lib/foreman_deployments/validation/dereference_visitor.rb +18 -0
  34. data/app/lib/foreman_deployments/validation/remove_ids_visitor.rb +59 -0
  35. data/app/lib/foreman_deployments/validation/validation_error.rb +12 -0
  36. data/app/lib/foreman_deployments/validation/validation_result.rb +26 -0
  37. data/app/lib/foreman_deployments/validation/validation_visitor.rb +20 -0
  38. data/app/lib/foreman_deployments/validation/validator.rb +29 -0
  39. data/app/models/foreman_deployments/concerns/belongs_to_single_taxonomy.rb +42 -0
  40. data/app/models/foreman_deployments/concerns/belongs_to_stack_taxonomy.rb +24 -0
  41. data/app/models/foreman_deployments/configuration.rb +26 -0
  42. data/app/models/foreman_deployments/deployment.rb +57 -0
  43. data/app/models/foreman_deployments/resource_models/create_resource.rb +18 -0
  44. data/app/models/foreman_deployments/stack.rb +20 -0
  45. data/app/views/foreman_deployments/api/v2/deployments/base.json.rabl +3 -0
  46. data/app/views/foreman_deployments/api/v2/deployments/create.json.rabl +3 -0
  47. data/app/views/foreman_deployments/api/v2/deployments/index.json.rabl +3 -0
  48. data/app/views/foreman_deployments/api/v2/deployments/main.json.rabl +5 -0
  49. data/app/views/foreman_deployments/api/v2/deployments/merge_configuration.json.rabl +3 -0
  50. data/app/views/foreman_deployments/api/v2/deployments/replace_configuration.json.rabl +3 -0
  51. data/app/views/foreman_deployments/api/v2/deployments/run.json.rabl +3 -0
  52. data/app/views/foreman_deployments/api/v2/deployments/show.json.rabl +11 -0
  53. data/app/views/foreman_deployments/api/v2/deployments/update.json.rabl +3 -0
  54. data/app/views/foreman_deployments/api/v2/stacks/base.json.rabl +3 -0
  55. data/app/views/foreman_deployments/api/v2/stacks/create.json.rabl +3 -0
  56. data/app/views/foreman_deployments/api/v2/stacks/index.json.rabl +3 -0
  57. data/app/views/foreman_deployments/api/v2/stacks/main.json.rabl +3 -0
  58. data/app/views/foreman_deployments/api/v2/stacks/show.json.rabl +7 -0
  59. data/app/views/foreman_deployments/api/v2/stacks/update.json.rabl +3 -0
  60. data/app/views/foreman_deployments/create_resources/new.html.erb +6 -0
  61. data/config/routes.rb +41 -0
  62. data/db/migrate/20150623140612_create_stacks.rb +10 -0
  63. data/db/migrate/20150814092932_create_deployment.rb +20 -0
  64. data/db/migrate/20150916133305_add_task_to_deployments.rb +5 -0
  65. data/db/migrate/20150917130618_add_taxonomy_to_deployments.rb +8 -0
  66. data/db/seeds.d/03-permissions.rb +14 -0
  67. data/doc/deployment_process.md +112 -0
  68. data/doc/design/capsule_stack.puml +51 -0
  69. data/doc/design/complete_stack.puml +17 -0
  70. data/doc/design/config_resource_overview.puml +15 -0
  71. data/doc/design/design.md +230 -0
  72. data/doc/design/diagrams/capsule_stack.png +0 -0
  73. data/doc/design/diagrams/capsule_stack.svg +1 -0
  74. data/doc/design/diagrams/complete_stack.png +0 -0
  75. data/doc/design/diagrams/complete_stack.svg +1 -0
  76. data/doc/design/diagrams/config_resource_overview.png +0 -0
  77. data/doc/design/diagrams/config_resource_overview.svg +1 -0
  78. data/doc/design/diagrams/ordered_resource_overview.png +0 -0
  79. data/doc/design/diagrams/ordered_resource_overview.svg +1 -0
  80. data/doc/design/diagrams/overview.png +0 -0
  81. data/doc/design/diagrams/overview.svg +1 -0
  82. data/doc/design/diagrams/overview_class.png +0 -0
  83. data/doc/design/diagrams/overview_class.svg +1 -0
  84. data/doc/design/diagrams/sat_stack.png +0 -0
  85. data/doc/design/diagrams/sat_stack.svg +1 -0
  86. data/doc/design/diagrams/solr_usecase.png +0 -0
  87. data/doc/design/diagrams/solr_usecase.svg +1 -0
  88. data/doc/design/examples.md +192 -0
  89. data/doc/design/generate-diagrams.sh +7 -0
  90. data/doc/design/implementation.md +128 -0
  91. data/doc/design/ordered_resource_overview.puml +15 -0
  92. data/doc/design/overview.puml +42 -0
  93. data/doc/design/overview_class.puml +64 -0
  94. data/doc/design/resources.md +134 -0
  95. data/doc/design/sat_stack.puml +37 -0
  96. data/doc/design/shared.puml +171 -0
  97. data/doc/design/solr_usecase.puml +189 -0
  98. data/doc/design/tasks.md +74 -0
  99. data/doc/design/user_interfaces.md +189 -0
  100. data/doc/introduction.md +84 -0
  101. data/doc/writing_stacks.md +102 -0
  102. data/lib/foreman_deployments.rb +7 -0
  103. data/lib/foreman_deployments/engine.rb +94 -0
  104. data/lib/foreman_deployments/monkey_patches.rb +9 -0
  105. data/lib/foreman_deployments/version.rb +3 -0
  106. data/lib/tasks/foreman_deployments_tasks.rake +22 -0
  107. data/locale/Makefile +62 -0
  108. data/test/factories/foreman_deployments.rb +70 -0
  109. data/test/functional/api/v2/deployments_controller_test.rb +318 -0
  110. data/test/functional/api/v2/stacks_controller_test.rb +140 -0
  111. data/test/test_plugin_helper.rb +14 -0
  112. data/test/unit/lib/config/array_test.rb +217 -0
  113. data/test/unit/lib/config/configurator_test.rb +66 -0
  114. data/test/unit/lib/config/hash_test.rb +178 -0
  115. data/test/unit/lib/inputs/value_test.rb +47 -0
  116. data/test/unit/lib/registry_test.rb +117 -0
  117. data/test/unit/lib/stack_definition_test.rb +54 -0
  118. data/test/unit/lib/stack_parser_test.rb +129 -0
  119. data/test/unit/lib/task_reference_test.rb +63 -0
  120. data/test/unit/lib/tasks/base_definition_test.rb +137 -0
  121. data/test/unit/lib/tasks/creation_task_definition_test.rb +57 -0
  122. data/test/unit/lib/tasks/host_creation_task_definition_test.rb +10 -0
  123. data/test/unit/lib/tasks/search_task_definition_test.rb +49 -0
  124. data/test/unit/lib/tasks/stack_deploy_action_test.rb +83 -0
  125. data/test/unit/lib/tasks/wait_until_built_task_definition_test.rb +71 -0
  126. data/test/unit/lib/validation/dereference_visitor_test.rb +48 -0
  127. data/test/unit/lib/validation/remove_ids_visitor_test.rb +90 -0
  128. data/test/unit/lib/validation/validation_result_test.rb +40 -0
  129. data/test/unit/lib/validation/validation_visitor_test.rb +67 -0
  130. data/test/unit/model/configuration_test.rb +88 -0
  131. data/test/unit/model/deployment_test.rb +159 -0
  132. data/test/unit/model/stack_test.rb +33 -0
  133. metadata +241 -0
@@ -0,0 +1,140 @@
1
+ require 'test_plugin_helper'
2
+
3
+ class ForemanDeployments::Api::V2::StacksControllerTest < ActionController::TestCase
4
+ include RegistryStub
5
+
6
+ class FakeTask < ForemanDeployments::Tasks::BaseDefinition
7
+ end
8
+
9
+ setup do
10
+ @definition = [
11
+ 'FirstRun: !task:FakeTask',
12
+ ' parameters:',
13
+ ' host_id: 1'
14
+ ].join("\n")
15
+
16
+ @registry = stub_registry
17
+ @registry.register_task(FakeTask)
18
+ end
19
+
20
+ describe 'importing stack' do
21
+ test 'should import stack' do
22
+ assert_difference('ForemanDeployments::Stack.count', 1) do
23
+ post :create, :stack => { :name => 'Test stack', :definition => @definition }
24
+ end
25
+ assert_response :success
26
+
27
+ parsed_response = JSON.parse(response.body)
28
+ assert_equal('Test stack', parsed_response['name'])
29
+ end
30
+
31
+ test 'should complain on invalid stack' do
32
+ @registry.clear!
33
+ assert_difference('ForemanDeployments::Stack.count', 0) do
34
+ post :create, :stack => { :name => 'Test stack', :definition => @definition }
35
+ end
36
+ assert_response :unprocessable_entity
37
+
38
+ parsed_response = JSON.parse(response.body)
39
+ assert_match('Unknown stack task FakeTask', parsed_response['error']['message'])
40
+ end
41
+ end
42
+
43
+ describe 'updating stacks' do
44
+ setup do
45
+ @updated_definition = [
46
+ 'AnotherRun: !task:FakeTask'
47
+ ].join("\n")
48
+ @stack = ForemanDeployments::Stack.create(:name => 'Test Stack', :definition => @definition)
49
+ end
50
+
51
+ test 'stacks without configuration are editable' do
52
+ put :update, :id => @stack.id, :stack => { :name => 'Updated name', :definition => @updated_definition }
53
+ assert_response :success
54
+
55
+ @stack.reload
56
+ assert_equal('Updated name', @stack.name)
57
+ assert_equal(@updated_definition, @stack.definition)
58
+ end
59
+
60
+ describe 'with saved configuration' do
61
+ setup do
62
+ @stack.configurations.create!
63
+ end
64
+
65
+ test 'it allows to update attributes other than definition' do
66
+ put :update, :id => @stack.id, :stack => { :name => 'Updated name' }
67
+ assert_response :success
68
+
69
+ @stack.reload
70
+ assert_equal('Updated name', @stack.name)
71
+ end
72
+
73
+ test 'it fails if the definition would be updated' do
74
+ put :update, :id => @stack.id, :stack => { :definition => @updated_definition }
75
+ assert_response :unprocessable_entity
76
+
77
+ parsed_response = JSON.parse(response.body)
78
+ assert_match('Can\'t update stack that has been configured', parsed_response['error'])
79
+
80
+ @stack.reload
81
+ assert_equal('Test Stack', @stack.name)
82
+ assert_equal(@definition, @stack.definition)
83
+ end
84
+ end
85
+
86
+ test 'it fails if the new stack definition is invalid' do
87
+ @registry.clear!
88
+
89
+ put :update, :id => @stack.id, :stack => { :definition => @updated_definition }
90
+ assert_response :unprocessable_entity
91
+
92
+ parsed_response = JSON.parse(response.body)
93
+ assert_match('Unknown stack task FakeTask', parsed_response['error']['message'])
94
+
95
+ @stack.reload
96
+ assert_equal('Test Stack', @stack.name)
97
+ assert_equal(@definition, @stack.definition)
98
+ end
99
+ end
100
+
101
+ describe 'listing stacks' do
102
+ setup do
103
+ @stack1 = FactoryGirl.create(:stack,
104
+ :organizations => [taxonomies(:organization1)],
105
+ :locations => [taxonomies(:location1)]
106
+ )
107
+ @stack2 = FactoryGirl.create(:stack,
108
+ :organizations => [taxonomies(:organization1)],
109
+ :locations => [taxonomies(:location2)]
110
+ )
111
+ @stack3 = FactoryGirl.create(:stack,
112
+ :organizations => [taxonomies(:organization2)],
113
+ :locations => [taxonomies(:location2)]
114
+ )
115
+ end
116
+
117
+ test 'it lists available stacks' do
118
+ get :index
119
+ assert_response :success
120
+ end
121
+
122
+ test 'should get stacks for location only' do
123
+ get :index, :location_id => taxonomies(:location2).id
124
+ assert_response :success
125
+ assert_equal [@stack2, @stack3], assigns(:stacks)
126
+ end
127
+
128
+ test 'should get stacks for organization only' do
129
+ get :index, :organization_id => taxonomies(:organization1).id
130
+ assert_response :success
131
+ assert_equal [@stack1, @stack2], assigns(:stacks)
132
+ end
133
+
134
+ test 'should get stacks for both location and organization' do
135
+ get :index, :organization_id => taxonomies(:organization1).id, :location_id => taxonomies(:location1).id
136
+ assert_response :success
137
+ assert_equal [@stack1], assigns(:stacks)
138
+ end
139
+ end
140
+ end
@@ -0,0 +1,14 @@
1
+ # This calls the main test_helper in Foreman-core
2
+ require 'test_helper'
3
+
4
+ module RegistryStub
5
+ def stub_registry
6
+ registry = ForemanDeployments::Registry.new
7
+ ForemanDeployments.stubs(:registry).returns(registry)
8
+ registry
9
+ end
10
+ end
11
+
12
+ # Add plugin to FactoryGirl's paths
13
+ FactoryGirl.definition_file_paths << File.join(File.dirname(__FILE__), 'factories')
14
+ FactoryGirl.reload
@@ -0,0 +1,217 @@
1
+ require 'test_helper'
2
+
3
+ class ArrayTest < ActiveSupport::TestCase
4
+ describe 'merge_configuration' do
5
+ setup do
6
+ @array = ForemanDeployments::Config::Array[nil, nil]
7
+ end
8
+
9
+ test 'can set values to empty slots' do
10
+ @array.merge_configuration([1, 2])
11
+ assert_equal([1, 2], @array.configured)
12
+ end
13
+
14
+ test 'can be configured with shorter array' do
15
+ @array.merge_configuration([1])
16
+ assert_equal([1, nil], @array.configured)
17
+ end
18
+
19
+ test 'can be configured with hash' do
20
+ @array.merge_configuration(1 => :b)
21
+ assert_equal([nil, :b], @array.configured)
22
+ end
23
+
24
+ test 'can be configured with hash using string keys' do
25
+ @array.merge_configuration('1' => :b)
26
+ assert_equal([nil, :b], @array.configured)
27
+ end
28
+
29
+ test 'raises exception when configured with value other than hash or array' do
30
+ e = assert_raises ForemanDeployments::Config::InvalidValueException do
31
+ @array.merge_configuration(1)
32
+ end
33
+ assert_match("Unexpected type 'Fixnum', only hash or array is accepted", e.message)
34
+ assert_equal([nil, nil], @array.configured)
35
+ end
36
+
37
+ test 'raises exception when configured with hash using non-numeric string keys' do
38
+ e = assert_raises ForemanDeployments::Config::InvalidValueException do
39
+ @array.merge_configuration('abc' => :b)
40
+ end
41
+ assert_match("Key 'abc' isn't numeric value", e.message)
42
+ assert_equal([nil, nil], @array.configured)
43
+ end
44
+
45
+ test 'can delete value with setting nil' do
46
+ @array.configure([1, 2])
47
+ @array.merge_configuration(1 => nil)
48
+ assert_equal([1, nil], @array.configured)
49
+ end
50
+
51
+ test 'calls configure on configurable items' do
52
+ configurable = mock
53
+ configurable.expects(:merge_configuration).with(123).once
54
+ array = ForemanDeployments::Config::Array[configurable]
55
+ array.merge_configuration([123])
56
+ end
57
+
58
+ test 'keeps preconfigured values untouched' do
59
+ @array.configure([1, 2])
60
+ assert_equal([nil, nil], @array)
61
+ end
62
+
63
+ test 'raises exception when extra value is added' do
64
+ e = assert_raises ForemanDeployments::Config::InvalidValueException do
65
+ @array.merge_configuration([1, 2, 3])
66
+ end
67
+ assert_match("Can't configure items outside the range", e.message)
68
+ assert_equal([nil, nil], @array.configured)
69
+ end
70
+
71
+ test 'raises exception when a value would be overwritten' do
72
+ array = ForemanDeployments::Config::Array[nil, 1]
73
+ e = assert_raises ForemanDeployments::Config::InvalidValueException do
74
+ array.merge_configuration([1, 2])
75
+ end
76
+ assert_match("You can't override values hardcoded in the stack definition", e.message)
77
+ assert_equal([1, 1], array.configured)
78
+ end
79
+ end
80
+
81
+ describe 'configure' do
82
+ setup do
83
+ @array = ForemanDeployments::Config::Array[nil, nil]
84
+ end
85
+
86
+ test 'can set values to empty slots' do
87
+ @array.configure([1, 2])
88
+ assert_equal([1, 2], @array.configured)
89
+ end
90
+
91
+ test 'overrides the config when called twice' do
92
+ @array.configure([1, 2])
93
+ @array.configure([3])
94
+ assert_equal([3, nil], @array.configured)
95
+ end
96
+
97
+ test 'can be configured with shorter array' do
98
+ @array.configure([1])
99
+ assert_equal([1, nil], @array.configured)
100
+ end
101
+
102
+ test 'can be configured with hash' do
103
+ @array.configure(1 => :b)
104
+ assert_equal([nil, :b], @array.configured)
105
+ end
106
+
107
+ test 'can be configured with hash using string keys' do
108
+ @array.configure('1' => :b)
109
+ assert_equal([nil, :b], @array.configured)
110
+ end
111
+
112
+ test 'raises exception when configured with value other than hash or array' do
113
+ e = assert_raises ForemanDeployments::Config::InvalidValueException do
114
+ @array.configure(1)
115
+ end
116
+ assert_match("Unexpected type 'Fixnum', only hash or array is accepted", e.message)
117
+ assert_equal([nil, nil], @array.configured)
118
+ end
119
+
120
+ test 'raises exception when configured with hash using non-numeric string keys' do
121
+ e = assert_raises ForemanDeployments::Config::InvalidValueException do
122
+ @array.configure('abc' => :b)
123
+ end
124
+ assert_match("Key 'abc' isn't numeric value", e.message)
125
+ assert_equal([nil, nil], @array.configured)
126
+ end
127
+
128
+ test 'calls configure on configurable items' do
129
+ configurable = mock
130
+ configurable.expects(:configure).with(123).once
131
+ array = ForemanDeployments::Config::Array[configurable]
132
+ array.configure([123])
133
+ end
134
+
135
+ test 'keeps preconfigured values untouched' do
136
+ @array.configure([1, 2])
137
+ assert_equal([nil, nil], @array)
138
+ end
139
+
140
+ test 'raises exception when extra value is added' do
141
+ e = assert_raises ForemanDeployments::Config::InvalidValueException do
142
+ @array.configure([1, 2, 3])
143
+ end
144
+ assert_match("Can't configure items outside the range", e.message)
145
+ assert_equal([nil, nil], @array.configured)
146
+ end
147
+
148
+ test 'raises exception when a value would be overwritten' do
149
+ array = ForemanDeployments::Config::Array[nil, 1]
150
+ e = assert_raises ForemanDeployments::Config::InvalidValueException do
151
+ array.configure([1, 2])
152
+ end
153
+ assert_match("You can't override values hardcoded in the stack definition", e.message)
154
+ assert_equal([1, 1], array.configured)
155
+ end
156
+ end
157
+
158
+ describe 'configuration' do
159
+ test 'returns nil by default' do
160
+ array = ForemanDeployments::Config::Array[:a, nil]
161
+ assert_nil(array.configuration)
162
+ end
163
+
164
+ test 'returns nil when the config was erased' do
165
+ array = ForemanDeployments::Config::Array[:a, nil]
166
+ array.configure(1 => 2)
167
+ array.configure(1 => nil)
168
+ assert_nil(array.configuration)
169
+ end
170
+
171
+ test 'returns only configured values' do
172
+ array = ForemanDeployments::Config::Array[nil, :b]
173
+ array.configure([:a])
174
+ assert_equal({ 0 => :a }, array.configuration)
175
+ end
176
+
177
+ test 'returns configured values from inner items' do
178
+ configurable = mock
179
+ configurable.stubs(:configuration).returns(123)
180
+
181
+ array = ForemanDeployments::Config::Array[nil, configurable]
182
+ assert_equal({ 1 => 123 }, array.configuration)
183
+ end
184
+ end
185
+
186
+ describe 'configured' do
187
+ test 'returns preconfigured values mixed with the configuration' do
188
+ array = ForemanDeployments::Config::Array[:a, nil]
189
+ array.configure(1 => :b)
190
+ assert_equal([:a, :b], array.configured)
191
+ end
192
+
193
+ test 'returns values from inner items' do
194
+ configurable = mock
195
+ configurable.stubs(:configured).returns(123)
196
+
197
+ array = ForemanDeployments::Config::Array[:a, configurable]
198
+ assert_equal([:a, 123], array.configured)
199
+ end
200
+ end
201
+
202
+ describe 'transform!' do
203
+ setup do
204
+ @array = ForemanDeployments::Config::Array[1, 2, nil]
205
+ @array.configure(2 => :value)
206
+ @array.transform!(&:to_s)
207
+ end
208
+
209
+ test 'transforms values' do
210
+ assert_equal(['1', '2', ''], @array)
211
+ end
212
+
213
+ test 'keeps the configuration' do
214
+ assert_equal({ 2 => :value }, @array.configuration)
215
+ end
216
+ end
217
+ end
@@ -0,0 +1,66 @@
1
+ require 'test_helper'
2
+
3
+ class ConfiguratorTest < ActiveSupport::TestCase
4
+ class TestTask < ForemanDeployments::Tasks::BaseDefinition; end
5
+
6
+ setup do
7
+ @task1 = TestTask.new
8
+ @task2 = TestTask.new
9
+
10
+ @stack_definition = ForemanDeployments::StackDefinition.new(
11
+ 'task1' => @task1,
12
+ 'task2' => @task2
13
+ )
14
+
15
+ @config = mock
16
+ @config.stubs(:get_config_for).with(@task1).returns('key1' => 'value1')
17
+ @config.stubs(:get_config_for).with(@task2).returns('key2' => 'value2')
18
+
19
+ @config2 = mock
20
+ @config2.stubs(:get_config_for).with(@task1).returns('key2' => 'value2')
21
+ @config2.stubs(:get_config_for).with(@task2).returns('key2' => 'updated_value2', 'key3' => 'value3')
22
+
23
+ @configurator = ForemanDeployments::Config::Configurator.new(@stack_definition)
24
+ end
25
+
26
+ describe 'configure' do
27
+ it 'configures the stack' do
28
+ @configurator.configure(@config)
29
+
30
+ assert_equal({ 'key1' => 'value1' }, @task1.configuration)
31
+ assert_equal({ 'key2' => 'value2' }, @task2.configuration)
32
+ end
33
+
34
+ it 'overwrites the previous config' do
35
+ @task1.configure('key1' => 'previous_value1', 'some_key' => 'value_value')
36
+ @task2.configure('key2' => 'previous_value2', 'some_key' => 'value_value')
37
+
38
+ @configurator.configure(@config)
39
+
40
+ assert_equal({ 'key1' => 'value1' }, @task1.configuration)
41
+ assert_equal({ 'key2' => 'value2' }, @task2.configuration)
42
+ end
43
+ end
44
+
45
+ describe 'merge' do
46
+ it 'loads the config and merges the update' do
47
+ @configurator.merge(@config, @config2)
48
+
49
+ assert_equal({ 'key1' => 'value1', 'key2' => 'value2' }, @task1.configuration)
50
+ assert_equal({ 'key2' => 'updated_value2', 'key3' => 'value3' }, @task2.configuration)
51
+ end
52
+ end
53
+
54
+ describe 'dump' do
55
+ it 'saves the stack configuration' do
56
+ @task1.stubs(:configuration).returns(:a => 1)
57
+ @task2.stubs(:configuration).returns(:b => 2)
58
+
59
+ config = ForemanDeployments::Configuration.new
60
+ @configurator.dump(config)
61
+
62
+ assert_equal({ :a => 1 }, config.get_config_for(@task1))
63
+ assert_equal({ :b => 2 }, config.get_config_for(@task2))
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,178 @@
1
+ require 'test_helper'
2
+
3
+ class HashTest < ActiveSupport::TestCase
4
+ describe 'merge_configuration' do
5
+ test 'can set values' do
6
+ hash = ForemanDeployments::Config::Hash[]
7
+ hash.merge_configuration(:b => 3)
8
+ assert_equal({ 'b' => 3 }, hash.configured)
9
+ end
10
+
11
+ test 'calls configure on configurable items' do
12
+ configurable = mock
13
+ configurable.expects(:merge_configuration).with(123).once
14
+
15
+ hash = ForemanDeployments::Config::Hash[:a => configurable]
16
+ hash.merge_configuration(:a => 123)
17
+ end
18
+
19
+ test 'can delete value with setting nil' do
20
+ hash = ForemanDeployments::Config::Hash[]
21
+ hash.merge_configuration(:b => 2)
22
+ hash.merge_configuration(:b => nil)
23
+ assert_equal({}, hash.configured)
24
+ end
25
+
26
+ test 'keeps preconfigured values untouched' do
27
+ hash = ForemanDeployments::Config::Hash[:a => 1]
28
+ hash.merge_configuration(:b => 2)
29
+ assert_equal({ :a => 1 }, hash)
30
+ end
31
+
32
+ test 'can add additional preconfigured hashses' do
33
+ hash = ForemanDeployments::Config::Hash[]
34
+ hash.merge_configuration(:a => { :b => 1 })
35
+
36
+ assert_equal({}, hash['a'])
37
+ assert_equal(ForemanDeployments::Config::Hash, hash['a'].class)
38
+ end
39
+
40
+ test 'can add additional preconfigured arrays' do
41
+ hash = ForemanDeployments::Config::Hash[]
42
+ hash.merge_configuration(:a => [:b, :c])
43
+
44
+ assert_equal([nil, nil], hash['a'])
45
+ assert_equal(ForemanDeployments::Config::Array, hash['a'].class)
46
+ end
47
+
48
+ test 'raises exception when a value would be overwritten' do
49
+ hash = ForemanDeployments::Config::Hash[:a => 1]
50
+ e = assert_raises ForemanDeployments::Config::InvalidValueException do
51
+ hash.merge_configuration(:a => 2)
52
+ end
53
+ assert_match("You can't override values hardcoded in the stack definition", e.message)
54
+ assert_equal({ 'a' => 1 }, hash.configured)
55
+ end
56
+ end
57
+
58
+ describe 'configure' do
59
+ test 'can set values' do
60
+ hash = ForemanDeployments::Config::Hash[]
61
+ hash.configure(:b => 3)
62
+ assert_equal({ 'b' => 3 }, hash.configured)
63
+ end
64
+
65
+ test 'calls configure on configurable items' do
66
+ configurable = mock
67
+ configurable.expects(:configure).with(123).once
68
+
69
+ hash = ForemanDeployments::Config::Hash[:a => configurable]
70
+ hash.configure(:a => 123)
71
+ end
72
+
73
+ test 'it overwrites previous config' do
74
+ hash = ForemanDeployments::Config::Hash[]
75
+ hash.configure(:b => 2)
76
+ hash.configure(:a => 1)
77
+ assert_equal({ 'a' => 1 }, hash.configured)
78
+ end
79
+
80
+ test 'keeps preconfigured values untouched' do
81
+ hash = ForemanDeployments::Config::Hash[:a => 1]
82
+ hash.configure(:b => 2)
83
+ assert_equal({ :a => 1 }, hash)
84
+ end
85
+
86
+ test 'can add additional preconfigured hashses' do
87
+ hash = ForemanDeployments::Config::Hash[]
88
+ hash.configure(:a => { :b => 1 })
89
+
90
+ assert_equal({}, hash['a'])
91
+ assert_equal(ForemanDeployments::Config::Hash, hash['a'].class)
92
+ end
93
+
94
+ test 'can add additional preconfigured arrays' do
95
+ hash = ForemanDeployments::Config::Hash[]
96
+ hash.configure(:a => [:b, :c])
97
+
98
+ assert_equal([nil, nil], hash['a'])
99
+ assert_equal(ForemanDeployments::Config::Array, hash['a'].class)
100
+ end
101
+
102
+ test 'raises exception when a value would be overwritten' do
103
+ hash = ForemanDeployments::Config::Hash[:a => 1]
104
+ e = assert_raises ForemanDeployments::Config::InvalidValueException do
105
+ hash.configure(:a => 2)
106
+ end
107
+ assert_match("You can't override values hardcoded in the stack definition", e.message)
108
+ assert_equal({ 'a' => 1 }, hash.configured)
109
+ end
110
+ end
111
+
112
+ describe 'configuration' do
113
+ test 'returns nil by default' do
114
+ hash = ForemanDeployments::Config::Hash[:a => 1]
115
+ assert_nil(hash.configuration)
116
+ end
117
+
118
+ test 'returns nil when the config was erased' do
119
+ hash = ForemanDeployments::Config::Hash[:a => 1]
120
+ hash.configure(:b => 2)
121
+ hash.configure(:b => nil)
122
+ assert_nil(hash.configuration)
123
+ end
124
+
125
+ test 'returns only configured values' do
126
+ hash = ForemanDeployments::Config::Hash[:a => 1]
127
+ hash.configure(:b => 2, :c => 3)
128
+ assert_equal({ 'b' => 2, 'c' => 3 }, hash.configuration)
129
+ end
130
+
131
+ test 'returns configured values from inner items' do
132
+ configurable = mock
133
+ configurable.stubs(:configuration).returns(123)
134
+
135
+ hash = ForemanDeployments::Config::Hash[:a => configurable]
136
+ hash.configure(:b => 2)
137
+ assert_equal({ 'a' => 123, 'b' => 2 }, hash.configuration)
138
+ end
139
+ end
140
+
141
+ describe 'configured' do
142
+ test 'returns preconfigured values mixed with the configuration' do
143
+ hash = ForemanDeployments::Config::Hash[:a => 1]
144
+ hash.configure(:b => 2)
145
+ assert_equal({ 'a' => 1, 'b' => 2 }, hash.configured)
146
+ end
147
+
148
+ test 'returns values from inner items' do
149
+ configurable = mock
150
+ configurable.stubs(:configured).returns('c' => 123)
151
+
152
+ hash = ForemanDeployments::Config::Hash[:a => configurable]
153
+ hash.configure(:b => 2)
154
+ assert_equal({ 'a' => { 'c' => 123 }, 'b' => 2 }, hash.configured)
155
+ end
156
+ end
157
+
158
+ describe 'transform!' do
159
+ test 'transforms values' do
160
+ hash = ForemanDeployments::Config::Hash['a' => 1, 'b' => 2]
161
+ hash.transform! { |key, val| [key, val * 2] }
162
+ assert_equal({ 'a' => 2, 'b' => 4 }, hash)
163
+ end
164
+
165
+ test 'enables to change the keys' do
166
+ hash = ForemanDeployments::Config::Hash['a' => 1, 'b' => 2]
167
+ hash.transform! { |key, val| [key * 2, val * 2] }
168
+ assert_equal({ 'aa' => 2, 'bb' => 4 }, hash)
169
+ end
170
+
171
+ test 'keeps the configuration' do
172
+ hash = ForemanDeployments::Config::Hash['a' => 1, 'b' => 2]
173
+ hash.configure('c' => 3)
174
+ hash.transform! { |key, val| [key, val * 2] }
175
+ assert_equal({ 'c' => 3 }, hash.configuration)
176
+ end
177
+ end
178
+ end