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.
- checksums.yaml +15 -0
- data/LICENSE +619 -0
- data/README.md +52 -0
- data/Rakefile +30 -0
- data/app/controllers/foreman_deployments/api/v2/base_controller.rb +25 -0
- data/app/controllers/foreman_deployments/api/v2/deployments_controller.rb +102 -0
- data/app/controllers/foreman_deployments/api/v2/stacks_controller.rb +52 -0
- data/app/controllers/foreman_deployments/create_resources_controller.rb +62 -0
- data/app/controllers/foreman_deployments/deployments_controller.rb +5 -0
- data/app/controllers/foreman_deployments/stacks_controller.rb +5 -0
- data/app/lib/foreman_deployments/base_dereference_visitor.rb +55 -0
- data/app/lib/foreman_deployments/config.rb +16 -0
- data/app/lib/foreman_deployments/config/array.rb +91 -0
- data/app/lib/foreman_deployments/config/configurator.rb +23 -0
- data/app/lib/foreman_deployments/config/hash.rb +81 -0
- data/app/lib/foreman_deployments/config/load_visitor.rb +23 -0
- data/app/lib/foreman_deployments/config/merge_visitor.rb +23 -0
- data/app/lib/foreman_deployments/config/save_visitor.rb +23 -0
- data/app/lib/foreman_deployments/inputs/base_input_definition.rb +39 -0
- data/app/lib/foreman_deployments/inputs/value.rb +25 -0
- data/app/lib/foreman_deployments/planner_visitor.rb +26 -0
- data/app/lib/foreman_deployments/registry.rb +67 -0
- data/app/lib/foreman_deployments/stack_definition.rb +37 -0
- data/app/lib/foreman_deployments/stack_parser.rb +121 -0
- data/app/lib/foreman_deployments/task_reference.rb +48 -0
- data/app/lib/foreman_deployments/tasks/base_action.rb +6 -0
- data/app/lib/foreman_deployments/tasks/base_definition.rb +72 -0
- data/app/lib/foreman_deployments/tasks/creation_task_definition.rb +68 -0
- data/app/lib/foreman_deployments/tasks/host_creation_task_definition.rb +44 -0
- data/app/lib/foreman_deployments/tasks/search_task_definition.rb +55 -0
- data/app/lib/foreman_deployments/tasks/stack_deploy_action.rb +10 -0
- data/app/lib/foreman_deployments/tasks/wait_until_built_task_definition.rb +65 -0
- data/app/lib/foreman_deployments/validation/dereference_visitor.rb +18 -0
- data/app/lib/foreman_deployments/validation/remove_ids_visitor.rb +59 -0
- data/app/lib/foreman_deployments/validation/validation_error.rb +12 -0
- data/app/lib/foreman_deployments/validation/validation_result.rb +26 -0
- data/app/lib/foreman_deployments/validation/validation_visitor.rb +20 -0
- data/app/lib/foreman_deployments/validation/validator.rb +29 -0
- data/app/models/foreman_deployments/concerns/belongs_to_single_taxonomy.rb +42 -0
- data/app/models/foreman_deployments/concerns/belongs_to_stack_taxonomy.rb +24 -0
- data/app/models/foreman_deployments/configuration.rb +26 -0
- data/app/models/foreman_deployments/deployment.rb +57 -0
- data/app/models/foreman_deployments/resource_models/create_resource.rb +18 -0
- data/app/models/foreman_deployments/stack.rb +20 -0
- data/app/views/foreman_deployments/api/v2/deployments/base.json.rabl +3 -0
- data/app/views/foreman_deployments/api/v2/deployments/create.json.rabl +3 -0
- data/app/views/foreman_deployments/api/v2/deployments/index.json.rabl +3 -0
- data/app/views/foreman_deployments/api/v2/deployments/main.json.rabl +5 -0
- data/app/views/foreman_deployments/api/v2/deployments/merge_configuration.json.rabl +3 -0
- data/app/views/foreman_deployments/api/v2/deployments/replace_configuration.json.rabl +3 -0
- data/app/views/foreman_deployments/api/v2/deployments/run.json.rabl +3 -0
- data/app/views/foreman_deployments/api/v2/deployments/show.json.rabl +11 -0
- data/app/views/foreman_deployments/api/v2/deployments/update.json.rabl +3 -0
- data/app/views/foreman_deployments/api/v2/stacks/base.json.rabl +3 -0
- data/app/views/foreman_deployments/api/v2/stacks/create.json.rabl +3 -0
- data/app/views/foreman_deployments/api/v2/stacks/index.json.rabl +3 -0
- data/app/views/foreman_deployments/api/v2/stacks/main.json.rabl +3 -0
- data/app/views/foreman_deployments/api/v2/stacks/show.json.rabl +7 -0
- data/app/views/foreman_deployments/api/v2/stacks/update.json.rabl +3 -0
- data/app/views/foreman_deployments/create_resources/new.html.erb +6 -0
- data/config/routes.rb +41 -0
- data/db/migrate/20150623140612_create_stacks.rb +10 -0
- data/db/migrate/20150814092932_create_deployment.rb +20 -0
- data/db/migrate/20150916133305_add_task_to_deployments.rb +5 -0
- data/db/migrate/20150917130618_add_taxonomy_to_deployments.rb +8 -0
- data/db/seeds.d/03-permissions.rb +14 -0
- data/doc/deployment_process.md +112 -0
- data/doc/design/capsule_stack.puml +51 -0
- data/doc/design/complete_stack.puml +17 -0
- data/doc/design/config_resource_overview.puml +15 -0
- data/doc/design/design.md +230 -0
- data/doc/design/diagrams/capsule_stack.png +0 -0
- data/doc/design/diagrams/capsule_stack.svg +1 -0
- data/doc/design/diagrams/complete_stack.png +0 -0
- data/doc/design/diagrams/complete_stack.svg +1 -0
- data/doc/design/diagrams/config_resource_overview.png +0 -0
- data/doc/design/diagrams/config_resource_overview.svg +1 -0
- data/doc/design/diagrams/ordered_resource_overview.png +0 -0
- data/doc/design/diagrams/ordered_resource_overview.svg +1 -0
- data/doc/design/diagrams/overview.png +0 -0
- data/doc/design/diagrams/overview.svg +1 -0
- data/doc/design/diagrams/overview_class.png +0 -0
- data/doc/design/diagrams/overview_class.svg +1 -0
- data/doc/design/diagrams/sat_stack.png +0 -0
- data/doc/design/diagrams/sat_stack.svg +1 -0
- data/doc/design/diagrams/solr_usecase.png +0 -0
- data/doc/design/diagrams/solr_usecase.svg +1 -0
- data/doc/design/examples.md +192 -0
- data/doc/design/generate-diagrams.sh +7 -0
- data/doc/design/implementation.md +128 -0
- data/doc/design/ordered_resource_overview.puml +15 -0
- data/doc/design/overview.puml +42 -0
- data/doc/design/overview_class.puml +64 -0
- data/doc/design/resources.md +134 -0
- data/doc/design/sat_stack.puml +37 -0
- data/doc/design/shared.puml +171 -0
- data/doc/design/solr_usecase.puml +189 -0
- data/doc/design/tasks.md +74 -0
- data/doc/design/user_interfaces.md +189 -0
- data/doc/introduction.md +84 -0
- data/doc/writing_stacks.md +102 -0
- data/lib/foreman_deployments.rb +7 -0
- data/lib/foreman_deployments/engine.rb +94 -0
- data/lib/foreman_deployments/monkey_patches.rb +9 -0
- data/lib/foreman_deployments/version.rb +3 -0
- data/lib/tasks/foreman_deployments_tasks.rake +22 -0
- data/locale/Makefile +62 -0
- data/test/factories/foreman_deployments.rb +70 -0
- data/test/functional/api/v2/deployments_controller_test.rb +318 -0
- data/test/functional/api/v2/stacks_controller_test.rb +140 -0
- data/test/test_plugin_helper.rb +14 -0
- data/test/unit/lib/config/array_test.rb +217 -0
- data/test/unit/lib/config/configurator_test.rb +66 -0
- data/test/unit/lib/config/hash_test.rb +178 -0
- data/test/unit/lib/inputs/value_test.rb +47 -0
- data/test/unit/lib/registry_test.rb +117 -0
- data/test/unit/lib/stack_definition_test.rb +54 -0
- data/test/unit/lib/stack_parser_test.rb +129 -0
- data/test/unit/lib/task_reference_test.rb +63 -0
- data/test/unit/lib/tasks/base_definition_test.rb +137 -0
- data/test/unit/lib/tasks/creation_task_definition_test.rb +57 -0
- data/test/unit/lib/tasks/host_creation_task_definition_test.rb +10 -0
- data/test/unit/lib/tasks/search_task_definition_test.rb +49 -0
- data/test/unit/lib/tasks/stack_deploy_action_test.rb +83 -0
- data/test/unit/lib/tasks/wait_until_built_task_definition_test.rb +71 -0
- data/test/unit/lib/validation/dereference_visitor_test.rb +48 -0
- data/test/unit/lib/validation/remove_ids_visitor_test.rb +90 -0
- data/test/unit/lib/validation/validation_result_test.rb +40 -0
- data/test/unit/lib/validation/validation_visitor_test.rb +67 -0
- data/test/unit/model/configuration_test.rb +88 -0
- data/test/unit/model/deployment_test.rb +159 -0
- data/test/unit/model/stack_test.rb +33 -0
- metadata +241 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class ValueTest < ActiveSupport::TestCase
|
|
4
|
+
setup do
|
|
5
|
+
@input = ForemanDeployments::Inputs::Value.new(
|
|
6
|
+
'description' => 'Some description',
|
|
7
|
+
'default' => 123
|
|
8
|
+
)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
test 'description' do
|
|
12
|
+
assert_equal('Some description', @input.description)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
describe 'configured' do
|
|
16
|
+
test 'configured provides default when no custom value is set' do
|
|
17
|
+
assert_equal(123, @input.configured)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
test 'configured provides custom value if it was set' do
|
|
21
|
+
@input.configure(456)
|
|
22
|
+
assert_equal(456, @input.configured)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
describe 'to_hash' do
|
|
27
|
+
setup do
|
|
28
|
+
@expected = {
|
|
29
|
+
'_type' => 'input',
|
|
30
|
+
'_name' => 'Value',
|
|
31
|
+
'description' => 'Some description',
|
|
32
|
+
'default' => 123,
|
|
33
|
+
'value' => nil
|
|
34
|
+
}
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
test 'contains all the information' do
|
|
38
|
+
assert_equal(@expected, @input.to_hash)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
test 'reflects configuration' do
|
|
42
|
+
@expected['value'] = 456
|
|
43
|
+
@input.configure(456)
|
|
44
|
+
assert_equal(@expected, @input.to_hash)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class RegistryTest < ActiveSupport::TestCase
|
|
4
|
+
class Task < ForemanDeployments::Tasks::BaseDefinition; end
|
|
5
|
+
class Input < ForemanDeployments::Inputs::BaseInputDefinition; end
|
|
6
|
+
|
|
7
|
+
def named(klass, name)
|
|
8
|
+
klass.stubs(:tag_name).returns(name)
|
|
9
|
+
klass
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def task_named(name)
|
|
13
|
+
named(Task, name)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def input_named(name)
|
|
17
|
+
named(Input, name)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
setup do
|
|
21
|
+
@register = ForemanDeployments::Registry.new
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
test 'it does not contain any tasks by default' do
|
|
25
|
+
assert_equal({}, @register.available_tasks)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
test 'it raises exception for invalid type' do
|
|
29
|
+
e = assert_raises ForemanDeployments::Registry::TypeException do
|
|
30
|
+
@register.register('some_type', task_named('task1'))
|
|
31
|
+
end
|
|
32
|
+
assert_match('Type needs to be one of: task, input', e.message)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
test 'it clears registeretd items' do
|
|
36
|
+
@register.register_task(task_named(:task1))
|
|
37
|
+
@register.register_task(task_named(:task2))
|
|
38
|
+
@register.register_input(input_named(:input1))
|
|
39
|
+
@register.clear!
|
|
40
|
+
assert_equal({}, @register.available_tasks)
|
|
41
|
+
assert_equal({}, @register.available_inputs)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
describe 'tasks' do
|
|
45
|
+
test 'it registers a task' do
|
|
46
|
+
@register.register_task(task_named('task1'))
|
|
47
|
+
assert_equal({ 'task1' => 'RegistryTest::Task' }, @register.available_tasks)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
test 'it registers a task with a symbol tag' do
|
|
51
|
+
@register.register_task(task_named(:task1))
|
|
52
|
+
@register.register_task(task_named(:task2))
|
|
53
|
+
assert_equal({ 'task1' => 'RegistryTest::Task', 'task2' => 'RegistryTest::Task' }, @register.available_tasks)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
test 'it does not allow to register a task with empty tag' do
|
|
57
|
+
assert_raises ForemanDeployments::Registry::TypeException do
|
|
58
|
+
@register.register_task(task_named(''))
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
test 'it does not allow to register a task with nil tag' do
|
|
63
|
+
assert_raises ForemanDeployments::Registry::TypeException do
|
|
64
|
+
@register.register_task(task_named(nil))
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
test 'it does not allow to register a task with invalid name' do
|
|
69
|
+
assert_raises ForemanDeployments::Registry::TypeException do
|
|
70
|
+
@register.register_task(task_named('[]'))
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
test 'it does not allow to register a class that is not child of ForemanDeployments::Tasks::BaseDefinition' do
|
|
75
|
+
assert_raises ForemanDeployments::Registry::TypeException do
|
|
76
|
+
@register.register_task(Object)
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
describe 'inputs' do
|
|
82
|
+
test 'it registers an input' do
|
|
83
|
+
@register.register_input(input_named('input1'))
|
|
84
|
+
assert_equal({ 'input1' => 'RegistryTest::Input' }, @register.available_inputs)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
test 'it registers an input with a symbol tag' do
|
|
88
|
+
@register.register_input(input_named(:input1))
|
|
89
|
+
@register.register_input(input_named(:input2))
|
|
90
|
+
assert_equal({ 'input1' => 'RegistryTest::Input', 'input2' => 'RegistryTest::Input' }, @register.available_inputs)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
test 'it does not allow to register an input with empty tag' do
|
|
94
|
+
assert_raises ForemanDeployments::Registry::TypeException do
|
|
95
|
+
@register.register_input(input_named(''))
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
test 'it does not allow to register an input with nil tag' do
|
|
100
|
+
assert_raises ForemanDeployments::Registry::TypeException do
|
|
101
|
+
@register.register_input(input_named(nil))
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
test 'it does not allow to register an input with invalid name' do
|
|
106
|
+
assert_raises ForemanDeployments::Registry::TypeException do
|
|
107
|
+
@register.register_input(input_named('[]'))
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
test 'it does not allow to register a class that is not child of ForemanDeployments::Inputs::BaseInputDefinition' do
|
|
112
|
+
assert_raises ForemanDeployments::Registry::TypeException do
|
|
113
|
+
@register.register_input(Object)
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class StackDefinitionTest < ActiveSupport::TestCase
|
|
4
|
+
setup do
|
|
5
|
+
@tasks = {
|
|
6
|
+
'task1' => ForemanDeployments::Tasks::BaseDefinition.new,
|
|
7
|
+
'task2' => ForemanDeployments::Tasks::BaseDefinition.new
|
|
8
|
+
}
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
describe 'tasks' do
|
|
12
|
+
test 'returns empty hash by default' do
|
|
13
|
+
definition = ForemanDeployments::StackDefinition.new
|
|
14
|
+
assert_equal({}, definition.tasks)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
test 'it returns tasks' do
|
|
18
|
+
definition = ForemanDeployments::StackDefinition.new(@tasks)
|
|
19
|
+
|
|
20
|
+
assert_equal(2, definition.tasks.count)
|
|
21
|
+
assert_equal(@tasks['task1'], definition.tasks['task1'])
|
|
22
|
+
assert_equal(@tasks['task2'], definition.tasks['task2'])
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
test 'it sets ids to tasks' do
|
|
26
|
+
definition = ForemanDeployments::StackDefinition.new(@tasks)
|
|
27
|
+
|
|
28
|
+
assert_equal('task1', definition.tasks['task1'].task_id)
|
|
29
|
+
assert_equal('task2', definition.tasks['task2'].task_id)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
describe 'accept' do
|
|
34
|
+
test 'it calls visit on the visitor with self' do
|
|
35
|
+
definition = ForemanDeployments::StackDefinition.new
|
|
36
|
+
|
|
37
|
+
visitor = mock
|
|
38
|
+
visitor.expects(:visit).with(definition).once
|
|
39
|
+
|
|
40
|
+
definition.accept(visitor)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
test 'it calls accept on all tasks' do
|
|
44
|
+
definition = ForemanDeployments::StackDefinition.new(@tasks)
|
|
45
|
+
|
|
46
|
+
visitor = mock
|
|
47
|
+
visitor.stubs(:visit)
|
|
48
|
+
|
|
49
|
+
definition.tasks['task1'].expects(:accept).with(visitor).once
|
|
50
|
+
definition.tasks['task2'].expects(:accept).with(visitor).once
|
|
51
|
+
definition.accept(visitor)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class StackParserTest < ActiveSupport::TestCase
|
|
4
|
+
class Vulnerable
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
class TestTask < ForemanDeployments::Tasks::BaseDefinition; end
|
|
8
|
+
class TestInput < ForemanDeployments::Inputs::BaseInputDefinition; end
|
|
9
|
+
|
|
10
|
+
def assert_stack_invalid
|
|
11
|
+
e = assert_raises ForemanDeployments::StackParseException do
|
|
12
|
+
yield
|
|
13
|
+
end
|
|
14
|
+
assert_match(/Stack definition is invalid/, e.message)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
setup do
|
|
18
|
+
@registry = ForemanDeployments::Registry.new
|
|
19
|
+
@parser = ForemanDeployments::StackParser.new(@registry)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
test 'it raises exception when the stack is not valid yaml hash' do
|
|
23
|
+
assert_stack_invalid do
|
|
24
|
+
@parser.parse('This is not a valid stack')
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
test 'it raises exception when the input is not string' do
|
|
29
|
+
assert_stack_invalid do
|
|
30
|
+
@parser.parse(123)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
test 'it raises exception when the input is nil' do
|
|
35
|
+
assert_stack_invalid do
|
|
36
|
+
@parser.parse(nil)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
test 'it raises exception when the input is empty string' do
|
|
41
|
+
assert_stack_invalid do
|
|
42
|
+
@parser.parse('')
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
test 'it raises exception when the stack contains references to unknown tasks' do
|
|
47
|
+
stack = [
|
|
48
|
+
'FirstRun: !task:Unknown',
|
|
49
|
+
' parameters:',
|
|
50
|
+
' host_id: 1'
|
|
51
|
+
].join("\n")
|
|
52
|
+
e = assert_raises ForemanDeployments::UnknownTaskException do
|
|
53
|
+
@parser.parse(stack)
|
|
54
|
+
end
|
|
55
|
+
assert_match(/Unknown stack task Unknown/, e.message)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
test 'it does not allow creation of custom objects' do
|
|
59
|
+
stack = [
|
|
60
|
+
'SatelliteStack: !ruby/object:Vulnerable',
|
|
61
|
+
' name: Satellite'
|
|
62
|
+
].join("\n")
|
|
63
|
+
e = assert_raises ForemanDeployments::UnknownYAMLTagException do
|
|
64
|
+
@parser.parse(stack)
|
|
65
|
+
end
|
|
66
|
+
assert_match(/Unknown YAML tag ruby\/object:Vulnerable/, e.message)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
test 'it returns instance of StackDefinition' do
|
|
70
|
+
@registry.register_task(TestTask)
|
|
71
|
+
|
|
72
|
+
stack = [
|
|
73
|
+
'FirstRun: !task:TestTask',
|
|
74
|
+
' parameters:',
|
|
75
|
+
' host_id: 1'
|
|
76
|
+
].join("\n")
|
|
77
|
+
|
|
78
|
+
stack_definition = @parser.parse(stack)
|
|
79
|
+
assert_equal(ForemanDeployments::StackDefinition, stack_definition.class)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
test 'it parses the stack' do
|
|
83
|
+
@registry.register_task(TestTask)
|
|
84
|
+
@registry.register_input(TestInput)
|
|
85
|
+
|
|
86
|
+
stack = [
|
|
87
|
+
'FirstRun: !task:TestTask',
|
|
88
|
+
' parameters:',
|
|
89
|
+
' host_id: 1',
|
|
90
|
+
'SecondRun: !task:TestTask',
|
|
91
|
+
' parameters:',
|
|
92
|
+
' name: !input:TestInput'
|
|
93
|
+
].join("\n")
|
|
94
|
+
|
|
95
|
+
stack_definition = @parser.parse(stack)
|
|
96
|
+
|
|
97
|
+
task_definition = stack_definition.tasks['FirstRun']
|
|
98
|
+
assert_equal(StackParserTest::TestTask, task_definition.class)
|
|
99
|
+
assert_equal('FirstRun', task_definition.task_id)
|
|
100
|
+
assert_equal({ 'parameters' => { 'host_id' => 1 } }, task_definition.parameters)
|
|
101
|
+
|
|
102
|
+
task_definition = stack_definition.tasks['SecondRun']
|
|
103
|
+
assert_equal(StackParserTest::TestTask, task_definition.class)
|
|
104
|
+
assert_equal('SecondRun', task_definition.task_id)
|
|
105
|
+
assert_equal(StackParserTest::TestInput, task_definition.parameters['parameters']['name'].class)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
test 'it parses references in a stack' do
|
|
109
|
+
@registry.register_task(TestTask)
|
|
110
|
+
|
|
111
|
+
stack = [
|
|
112
|
+
'DbServerHost: !task:TestTask',
|
|
113
|
+
'FirstRun: !task:TestTask',
|
|
114
|
+
' parameters:',
|
|
115
|
+
' host_id: !reference',
|
|
116
|
+
" object: 'DbServerHost'",
|
|
117
|
+
" field: 'result.id'"
|
|
118
|
+
].join("\n")
|
|
119
|
+
stack_definition = @parser.parse(stack)
|
|
120
|
+
|
|
121
|
+
assert_equal(StackParserTest::TestTask, stack_definition.tasks['FirstRun'].class)
|
|
122
|
+
|
|
123
|
+
reference = stack_definition.tasks['FirstRun'].parameters['parameters']['host_id']
|
|
124
|
+
assert_equal(ForemanDeployments::TaskReference, reference.class)
|
|
125
|
+
assert_equal('DbServerHost', reference.task_id)
|
|
126
|
+
assert_equal(stack_definition.tasks['DbServerHost'], reference.task)
|
|
127
|
+
assert_equal('result.id', reference.output_key)
|
|
128
|
+
end
|
|
129
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class TaskReferenceTest < ActiveSupport::TestCase
|
|
4
|
+
test 'referenced task can be optionally set in the constructor' do
|
|
5
|
+
task = mock
|
|
6
|
+
ref = ForemanDeployments::TaskReference.new('task', 'resource.id', task)
|
|
7
|
+
assert_equal(task, ref.task)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
describe 'dereference' do
|
|
11
|
+
test 'it dereferences hash' do
|
|
12
|
+
ref = ForemanDeployments::TaskReference.new('task', 'resource.id')
|
|
13
|
+
value = ref.dereference('resource' => { 'id' => 123 })
|
|
14
|
+
assert_equal(123, value)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
test 'it dereferences object' do
|
|
18
|
+
obj = mock
|
|
19
|
+
obj.stubs(:id).returns(123)
|
|
20
|
+
|
|
21
|
+
ref = ForemanDeployments::TaskReference.new('task', 'resource.id')
|
|
22
|
+
value = ref.dereference('resource' => obj)
|
|
23
|
+
assert_equal(123, value)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
test 'it return nil when the key does not exist' do
|
|
27
|
+
ref = ForemanDeployments::TaskReference.new('task', 'resource.unknown')
|
|
28
|
+
value = ref.dereference('resource' => {})
|
|
29
|
+
assert_equal(nil, value)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
test 'it return nil when the method does not exist' do
|
|
33
|
+
ref = ForemanDeployments::TaskReference.new('task', 'resource.unknown')
|
|
34
|
+
value = ref.dereference('resource' => Object.new)
|
|
35
|
+
assert_equal(nil, value)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
test 'it dereferences one item path' do
|
|
39
|
+
obj = mock
|
|
40
|
+
|
|
41
|
+
ref = ForemanDeployments::TaskReference.new('task', 'resource')
|
|
42
|
+
value = ref.dereference('resource' => obj)
|
|
43
|
+
assert_equal(obj, value)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
test 'it dereferences one item path defined by symbol' do
|
|
47
|
+
obj = mock
|
|
48
|
+
|
|
49
|
+
ref = ForemanDeployments::TaskReference.new('task', :resource)
|
|
50
|
+
value = ref.dereference('resource' => obj)
|
|
51
|
+
assert_equal(obj, value)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
test 'accept calls visit on the visitor with self' do
|
|
56
|
+
ref = ForemanDeployments::TaskReference.new('task', 'resource.id')
|
|
57
|
+
|
|
58
|
+
visitor = mock
|
|
59
|
+
visitor.expects(:visit).with(ref).once
|
|
60
|
+
|
|
61
|
+
ref.accept(visitor)
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class BaseDefinitionTest < ActiveSupport::TestCase
|
|
4
|
+
describe 'task_id' do
|
|
5
|
+
test "it's nil by default" do
|
|
6
|
+
assert_equal(nil, ForemanDeployments::Tasks::BaseDefinition.new.task_id)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
test 'it enables setting an id' do
|
|
10
|
+
task = ForemanDeployments::Tasks::BaseDefinition.new
|
|
11
|
+
task.task_id = :some_task
|
|
12
|
+
assert_equal(:some_task, task.task_id)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
test 'it returns parameters' do
|
|
17
|
+
expected_params = {
|
|
18
|
+
'a' => 1,
|
|
19
|
+
'b' => 2
|
|
20
|
+
}
|
|
21
|
+
task = ForemanDeployments::Tasks::BaseDefinition.new(expected_params)
|
|
22
|
+
assert_equal(expected_params, task.parameters)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
describe 'plan' do
|
|
26
|
+
let(:task_params) { { 'params' => true } }
|
|
27
|
+
let(:dynflow_action) { mock }
|
|
28
|
+
let(:parent_task) do
|
|
29
|
+
parent_task = mock
|
|
30
|
+
parent_task.expects(:plan_action).with(dynflow_action, task_params).once.returns(dynflow_action)
|
|
31
|
+
parent_task
|
|
32
|
+
end
|
|
33
|
+
let(:task) do
|
|
34
|
+
task = ForemanDeployments::Tasks::BaseDefinition.new(task_params)
|
|
35
|
+
task.stubs(:dynflow_action).returns(dynflow_action)
|
|
36
|
+
task
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
test 'plans action returned from dynflow_action' do
|
|
40
|
+
task.plan(parent_task)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
test 'plans the action only once' do
|
|
44
|
+
task.plan(parent_task)
|
|
45
|
+
task.plan(parent_task)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
test 'validate raises not implemented exception' do
|
|
50
|
+
assert_raises NotImplementedError do
|
|
51
|
+
ForemanDeployments::Tasks::BaseDefinition.new.validate
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
test 'dynflow_action raises not implemented exception' do
|
|
56
|
+
assert_raises NotImplementedError do
|
|
57
|
+
ForemanDeployments::Tasks::BaseDefinition.new.dynflow_action
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
describe 'configuration' do
|
|
62
|
+
setup do
|
|
63
|
+
@parameters1 = {
|
|
64
|
+
'count' => 1,
|
|
65
|
+
'should_not' => 'be_touched',
|
|
66
|
+
'parameters' => {
|
|
67
|
+
'a' => 1,
|
|
68
|
+
'b' => 2
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
@parameters2 = {
|
|
72
|
+
'count' => 2,
|
|
73
|
+
'parameters' => {
|
|
74
|
+
'a' => 1,
|
|
75
|
+
'c' => 3
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
test 'configure deep merges the parameters' do
|
|
81
|
+
task = ForemanDeployments::Tasks::BaseDefinition.new
|
|
82
|
+
|
|
83
|
+
task.configure(@parameters1)
|
|
84
|
+
task.configure(@parameters2)
|
|
85
|
+
assert_equal(@parameters2, task.configuration)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
test 'merge_configuration deep merges the parameters' do
|
|
89
|
+
task = ForemanDeployments::Tasks::BaseDefinition.new
|
|
90
|
+
|
|
91
|
+
expected_params = {
|
|
92
|
+
'count' => 2,
|
|
93
|
+
'should_not' => 'be_touched',
|
|
94
|
+
'parameters' => {
|
|
95
|
+
'a' => 1,
|
|
96
|
+
'b' => 2,
|
|
97
|
+
'c' => 3
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
task.configure(@parameters1)
|
|
102
|
+
task.merge_configuration(@parameters2)
|
|
103
|
+
assert_equal(expected_params, task.configuration)
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
describe 'accept' do
|
|
108
|
+
test 'it calls visit on the visitor with self' do
|
|
109
|
+
definition = ForemanDeployments::Tasks::BaseDefinition.new
|
|
110
|
+
|
|
111
|
+
visitor = mock
|
|
112
|
+
visitor.expects(:visit).with(definition).once
|
|
113
|
+
|
|
114
|
+
definition.accept(visitor)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
test 'it calls visit on parameters' do
|
|
118
|
+
visitable1 = mock
|
|
119
|
+
visitable2 = mock
|
|
120
|
+
|
|
121
|
+
definition = ForemanDeployments::Tasks::BaseDefinition.new(
|
|
122
|
+
:params => {
|
|
123
|
+
:first => 1,
|
|
124
|
+
:second => visitable1,
|
|
125
|
+
:third => [1, 2, visitable2]
|
|
126
|
+
}
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
visitor = mock
|
|
130
|
+
visitor.expects(:visit).with(definition).once
|
|
131
|
+
visitable1.expects(:accept).with(visitor).once
|
|
132
|
+
visitable2.expects(:accept).with(visitor).once
|
|
133
|
+
|
|
134
|
+
definition.accept(visitor)
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
end
|