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,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