capsulecd 1.0.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 (104) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +2 -0
  3. data/.dockerignore +5 -0
  4. data/.gitignore +95 -0
  5. data/.rspec +3 -0
  6. data/.simplecov +9 -0
  7. data/Dockerfile +16 -0
  8. data/Dockerfile.chef +26 -0
  9. data/Dockerfile.javascript +7 -0
  10. data/Dockerfile.node +7 -0
  11. data/Dockerfile.python +7 -0
  12. data/Dockerfile.ruby +4 -0
  13. data/FEATURES.md +12 -0
  14. data/Gemfile +26 -0
  15. data/LICENSE.md +22 -0
  16. data/README.md +227 -0
  17. data/Rakefile +43 -0
  18. data/bin/capsulecd +4 -0
  19. data/capsulecd.gemspec +27 -0
  20. data/circle.yml +24 -0
  21. data/lib/capsulecd/base/common/git_utils.rb +90 -0
  22. data/lib/capsulecd/base/common/validation_utils.rb +22 -0
  23. data/lib/capsulecd/base/configuration.rb +151 -0
  24. data/lib/capsulecd/base/engine.rb +163 -0
  25. data/lib/capsulecd/base/runner/circleci.rb +37 -0
  26. data/lib/capsulecd/base/runner/default.rb +38 -0
  27. data/lib/capsulecd/base/source/github.rb +183 -0
  28. data/lib/capsulecd/base/transform_engine.rb +62 -0
  29. data/lib/capsulecd/chef/chef_engine.rb +172 -0
  30. data/lib/capsulecd/chef/chef_helper.rb +29 -0
  31. data/lib/capsulecd/cli.rb +64 -0
  32. data/lib/capsulecd/error.rb +51 -0
  33. data/lib/capsulecd/javascript/javascript_engine.rb +213 -0
  34. data/lib/capsulecd/node/node_engine.rb +141 -0
  35. data/lib/capsulecd/python/python_engine.rb +157 -0
  36. data/lib/capsulecd/ruby/ruby_engine.rb +191 -0
  37. data/lib/capsulecd/ruby/ruby_helper.rb +60 -0
  38. data/lib/capsulecd/version.rb +3 -0
  39. data/lib/capsulecd.rb +16 -0
  40. data/logo.svg +1 -0
  41. data/spec/fixtures/chef/cookbook_analogj_test/CHANGELOG.md +3 -0
  42. data/spec/fixtures/chef/cookbook_analogj_test/Gemfile +18 -0
  43. data/spec/fixtures/chef/cookbook_analogj_test/LICENSE +21 -0
  44. data/spec/fixtures/chef/cookbook_analogj_test/README.md +13 -0
  45. data/spec/fixtures/chef/cookbook_analogj_test/Rakefile +1 -0
  46. data/spec/fixtures/chef/cookbook_analogj_test/Thorfile +12 -0
  47. data/spec/fixtures/chef/cookbook_analogj_test/chefignore +94 -0
  48. data/spec/fixtures/chef/cookbook_analogj_test/metadata.rb +5 -0
  49. data/spec/fixtures/chef/cookbook_analogj_test/recipes/default.rb +6 -0
  50. data/spec/fixtures/incorrect_configuration.yml +4 -0
  51. data/spec/fixtures/javascript/javascript_analogj_test/LICENSE +21 -0
  52. data/spec/fixtures/javascript/javascript_analogj_test/README.md +2 -0
  53. data/spec/fixtures/javascript/javascript_analogj_test/package.json +19 -0
  54. data/spec/fixtures/node/npm_analogj_test/LICENSE +21 -0
  55. data/spec/fixtures/node/npm_analogj_test/README.md +2 -0
  56. data/spec/fixtures/node/npm_analogj_test/package.json +19 -0
  57. data/spec/fixtures/python/pip_analogj_test/LICENSE +21 -0
  58. data/spec/fixtures/python/pip_analogj_test/MANIFEST.in +1 -0
  59. data/spec/fixtures/python/pip_analogj_test/README.md +1 -0
  60. data/spec/fixtures/python/pip_analogj_test/VERSION +1 -0
  61. data/spec/fixtures/python/pip_analogj_test/setup.cfg +5 -0
  62. data/spec/fixtures/python/pip_analogj_test/setup.py +80 -0
  63. data/spec/fixtures/python/pip_analogj_test/tox.ini +14 -0
  64. data/spec/fixtures/ruby/gem_analogj_test/Gemfile +4 -0
  65. data/spec/fixtures/ruby/gem_analogj_test/LICENSE.txt +21 -0
  66. data/spec/fixtures/ruby/gem_analogj_test/README.md +41 -0
  67. data/spec/fixtures/ruby/gem_analogj_test/Rakefile +6 -0
  68. data/spec/fixtures/ruby/gem_analogj_test/bin/console +14 -0
  69. data/spec/fixtures/ruby/gem_analogj_test/bin/setup +8 -0
  70. data/spec/fixtures/ruby/gem_analogj_test/gem_analogj_test.gemspec +25 -0
  71. data/spec/fixtures/ruby/gem_analogj_test/lib/gem_analogj_test/version.rb +3 -0
  72. data/spec/fixtures/ruby/gem_analogj_test/lib/gem_analogj_test.rb +5 -0
  73. data/spec/fixtures/ruby/gem_analogj_test/spec/gem_analogj_test_spec.rb +7 -0
  74. data/spec/fixtures/ruby/gem_analogj_test/spec/spec_helper.rb +2 -0
  75. data/spec/fixtures/ruby/gem_analogj_test-0.1.4.gem +0 -0
  76. data/spec/fixtures/sample_chef_configuration.yml +8 -0
  77. data/spec/fixtures/sample_configuration.yml +7 -0
  78. data/spec/fixtures/sample_global_configuration.yml +23 -0
  79. data/spec/fixtures/sample_node_configuration.yml +7 -0
  80. data/spec/fixtures/sample_python_configuration.yml +8 -0
  81. data/spec/fixtures/sample_repo_configuration.yml +22 -0
  82. data/spec/fixtures/sample_ruby_configuration.yml +5 -0
  83. data/spec/fixtures/vcr_cassettes/chef_build_step.yml +636 -0
  84. data/spec/fixtures/vcr_cassettes/gem_build_step.yml +653 -0
  85. data/spec/fixtures/vcr_cassettes/gem_build_step_without_version_rb.yml +653 -0
  86. data/spec/fixtures/vcr_cassettes/integration_chef.yml +1399 -0
  87. data/spec/fixtures/vcr_cassettes/integration_node.yml +1388 -0
  88. data/spec/fixtures/vcr_cassettes/integration_python.yml +1388 -0
  89. data/spec/fixtures/vcr_cassettes/integration_ruby.yml +1377 -0
  90. data/spec/fixtures/vcr_cassettes/node_build_step.yml +647 -0
  91. data/spec/fixtures/vcr_cassettes/pip_build_step.yml +653 -0
  92. data/spec/lib/capsulecd/base/configuration_spec.rb +75 -0
  93. data/spec/lib/capsulecd/base/engine_spec.rb +51 -0
  94. data/spec/lib/capsulecd/base/source/github_spec.rb +253 -0
  95. data/spec/lib/capsulecd/base/transform_engine_spec.rb +55 -0
  96. data/spec/lib/capsulecd/chef/chef_engine_spec.rb +114 -0
  97. data/spec/lib/capsulecd/cli_spec.rb +57 -0
  98. data/spec/lib/capsulecd/node/node_engine_spec.rb +113 -0
  99. data/spec/lib/capsulecd/python/python_engine_spec.rb +118 -0
  100. data/spec/lib/capsulecd/ruby/ruby_engine_spec.rb +128 -0
  101. data/spec/spec_helper.rb +105 -0
  102. data/spec/support/file_system.rb +21 -0
  103. data/spec/support/package_types.rb +11 -0
  104. metadata +281 -0
@@ -0,0 +1,75 @@
1
+ require 'spec_helper'
2
+
3
+ describe CapsuleCD::Configuration do
4
+ describe '::new' do
5
+ describe 'with a sample configuration file' do
6
+ let(:config_file_path) { 'spec/fixtures/sample_configuration.yml' }
7
+ subject { CapsuleCD::Configuration.new(config_file:config_file_path, source: :github, package_type: :node) }
8
+
9
+ it 'should populate github_access_token' do
10
+ expect(subject.source_github_access_token).to eql('sample_test_token')
11
+ end
12
+
13
+ it 'should populate engine_npm_auth_token' do
14
+ expect(subject.npm_auth_token).to eql('sample_auth_token')
15
+ end
16
+
17
+ it 'should use cli specified source' do
18
+ expect(subject.source).to eql(:github)
19
+ end
20
+
21
+ it 'should correctly base64 decode chef supermarket key' do
22
+ expect(subject.chef_supermarket_key).to eql("-----BEGIN RSA PRIVATE KEY-----\nsample_supermarket_key\n-----END RSA PRIVATE KEY-----\n")
23
+ end
24
+
25
+ it 'should have correct defaults' do
26
+ expect(subject.engine_version_bump_type).to eql(:patch)
27
+ expect(subject.chef_supermarket_type).to eql('Other')
28
+ end
29
+ end
30
+
31
+ describe 'with an incorrect configuration file' do
32
+ let(:config_file_path) { 'spec/fixtures/incorrect_configuration.yml' }
33
+ subject { CapsuleCD::Configuration.new(config_file:config_file_path, source: :github, package_type: :node) }
34
+
35
+ it 'should populate github_access_token' do
36
+ expect(subject.source_github_access_token).to eql('sample_test_token')
37
+ end
38
+
39
+ it 'should populate engine_npm_auth_token' do
40
+ expect(subject.npm_auth_token).to eql('sample_auth_token')
41
+ end
42
+
43
+ it 'should use cli specified source' do
44
+ expect(subject.source).to eql(:github)
45
+ end
46
+
47
+ it 'should have a nil chef supermarket key' do
48
+ expect(subject.chef_supermarket_key).to eql(nil)
49
+ end
50
+ end
51
+
52
+ describe 'when overriding sample configuration file' do
53
+ let(:config_file_path) { 'spec/fixtures/sample_configuration.yml' }
54
+
55
+ describe 'with ENV variables' do
56
+ it 'should use CAPSULE_SOURCE_GITHUB_ACCESS_TOKEN instead of config file' do
57
+ allow(ENV).to receive(:each).and_yield('CAPSULE_SOURCE_GITHUB_ACCESS_TOKEN', 'override_test_token')
58
+
59
+ config = CapsuleCD::Configuration.new(config_file: config_file_path, source: :github, package_type: :node)
60
+
61
+ expect(config.source_github_access_token).to eql('override_test_token')
62
+ end
63
+
64
+ it 'should use CAPSULE_ENGINE_VERSION_BUMP_TYPE instead of default and return symbol' do
65
+ allow(ENV).to receive(:each).and_yield('CAPSULE_ENGINE_VERSION_BUMP_TYPE', 'patch')
66
+
67
+ config = CapsuleCD::Configuration.new(config_file: config_file_path, source: :github, package_type: :node)
68
+
69
+ expect(config.engine_version_bump_type).to eql(:patch)
70
+ end
71
+ end
72
+ end
73
+
74
+ end
75
+ end
@@ -0,0 +1,51 @@
1
+ require 'spec_helper'
2
+
3
+ describe CapsuleCD::Engine do
4
+
5
+ describe '::new' do
6
+ describe 'without a source specified' do
7
+ it 'should throw an error' do
8
+ expect{CapsuleCD::Engine.new({})}.to raise_error(CapsuleCD::Error::SourceUnspecifiedError)
9
+ end
10
+ end
11
+ end
12
+
13
+ describe '::bump_version' do
14
+ subject{
15
+ CapsuleCD::Engine.new({:source => :github})
16
+ }
17
+ it 'should default to bumping patch segement' do
18
+ version = SemVer.parse('1.0.2')
19
+ new_version = subject.send(:bump_version, version)
20
+ expect(new_version.to_s).to eql('1.0.3')
21
+ end
22
+
23
+ describe 'when engine_version_bump_type is :minor' do
24
+ subject{
25
+ CapsuleCD::Engine.new({
26
+ :source => :github,
27
+ :engine_version_bump_type => :minor
28
+ })
29
+ }
30
+ it 'should correctly bump minor and clear patch segement' do
31
+ version = SemVer.parse('1.0.2')
32
+ new_version = subject.send(:bump_version, version)
33
+ expect(new_version.to_s).to eql('1.1.0')
34
+ end
35
+ end
36
+
37
+ describe 'when engine_version_bump_type is :major' do
38
+ subject{
39
+ CapsuleCD::Engine.new({
40
+ :source => :github,
41
+ :engine_version_bump_type => :major
42
+ })
43
+ }
44
+ it 'should correctly bump major and clear minor and patch segements' do
45
+ version = SemVer.parse('1.0.2')
46
+ new_version = subject.send(:bump_version, version)
47
+ expect(new_version.to_s).to eql('2.0.0')
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,253 @@
1
+ require 'spec_helper'
2
+ require 'capsulecd/base/source/github'
3
+
4
+ describe CapsuleCD::Source::Github do
5
+ describe '#source_configure' do
6
+
7
+ describe 'when no authentication token is present' do
8
+ let(:test_engine) { Class.new { include CapsuleCD::Source::Github } }
9
+ let(:config) { CapsuleCD::Configuration.new({}) }
10
+ it 'should raise an error' do
11
+ engine = test_engine.new
12
+ engine.instance_variable_set(:@config, config)
13
+ expect { engine.source_configure }.to raise_error(CapsuleCD::Error::SourceAuthenticationFailed)
14
+ end
15
+ end
16
+
17
+ describe 'when authentication token is present' do
18
+ let(:test_engine) { Class.new { include CapsuleCD::Source::Github } }
19
+ let(:config) { CapsuleCD::Configuration.new({:config_file => 'spec/fixtures/sample_configuration.yml'}) }
20
+
21
+ it 'should successfully create an source_client' do
22
+ allow(Dir).to receive(:mktmpdir).and_return('/tmp')
23
+ engine = test_engine.new
24
+ engine.instance_variable_set(:@config, config)
25
+ engine.source_configure
26
+ expect(engine.source_client).to be_a_kind_of Octokit::Client
27
+ end
28
+ end
29
+ end
30
+
31
+ describe '#source_process_push_payload' do
32
+ let(:test_engine) { Class.new { include CapsuleCD::Source::Github } }
33
+ let(:payload) do
34
+ {
35
+ 'head' => {
36
+ 'sha' => '0a5948802a2bba02e019fd13bf3db3c5329faae6',
37
+ 'ref' => 'master',
38
+ 'repo' => {
39
+ 'clone_url' => 'https://github.com/AnalogJ/npm_analogj_test.git',
40
+ 'name' => 'npm_analog_test'
41
+ }
42
+ }
43
+ }
44
+ end
45
+ let(:config) { CapsuleCD::Configuration.new({:config_file => 'spec/fixtures/sample_configuration.yml'}) }
46
+ it 'should clone git repo' do
47
+ engine = test_engine.new
48
+ engine.instance_variable_set(:@config, config)
49
+ engine.instance_variable_set(:@source_git_parent_path, '/tmp')
50
+ allow(CapsuleCD::GitUtils).to receive(:clone).and_return(engine.source_git_parent_path + payload['head']['repo']['name'])
51
+ allow(CapsuleCD::GitUtils).to receive(:checkout).and_return(true)
52
+
53
+ engine.source_process_push_payload(payload)
54
+
55
+ expect(engine.source_git_local_path).to eql(engine.source_git_parent_path + payload['head']['repo']['name'])
56
+ expect(engine.source_git_local_branch).to eql(payload['head']['repo']['branch'])
57
+ expect(engine.source_git_head_info).to be_a(Hash)
58
+ end
59
+
60
+ describe 'with an invalid payload' do
61
+ it 'should raise an error' do
62
+ engine = test_engine.new
63
+ engine.instance_variable_set(:@config, config)
64
+ engine.instance_variable_set(:@source_git_parent_path, '/tmp')
65
+ expect { engine.source_process_push_payload('head' => {}) }.to raise_error(CapsuleCD::Error::SourcePayloadFormatError)
66
+ end
67
+ end
68
+ end
69
+
70
+ describe '#source_process_pull_request_payload' do
71
+ let(:test_engine) { Class.new { include CapsuleCD::Source::Github } }
72
+ let(:source_client_double) { instance_double(Octokit::Client) }
73
+ let(:config) { CapsuleCD::Configuration.new({:config_file => 'spec/fixtures/sample_configuration.yml'}) }
74
+
75
+ describe 'with a closed pull request payload' do
76
+ let(:payload) do
77
+ {
78
+ 'state' => 'closed'
79
+ }
80
+ end
81
+ it 'should raise an error' do
82
+ engine = test_engine.new
83
+ engine.instance_variable_set(:@config, config)
84
+ expect { engine.source_process_pull_request_payload(payload) }.to raise_error(CapsuleCD::Error::SourcePayloadUnsupported)
85
+ end
86
+ end
87
+
88
+ describe 'when the default branch is not the same as the pull request base branch' do
89
+ let(:config) { CapsuleCD::Configuration.new({:config_file => 'spec/fixtures/sample_configuration.yml'}) }
90
+ let(:payload) do
91
+ {
92
+ 'state' => 'open',
93
+ 'base' => {
94
+ 'repo' => {
95
+ 'default_branch' => 'master'
96
+ },
97
+ 'ref' => 'development'
98
+ }
99
+ }
100
+ end
101
+ it 'should raise an error' do
102
+ engine = test_engine.new
103
+ engine.instance_variable_set(:@config, config)
104
+ expect { engine.source_process_pull_request_payload(payload) }.to raise_error(CapsuleCD::Error::SourcePayloadUnsupported)
105
+ end
106
+ end
107
+
108
+ describe 'when the user who opened the PR is not a collaborator' do
109
+ let(:payload) do
110
+ {
111
+ 'state' => 'open',
112
+ 'number' => 8,
113
+ 'base' => {
114
+ 'repo' => {
115
+ 'full_name' => 'AnalogJ/npm_analogj_test',
116
+ 'default_branch' => 'master',
117
+ 'clone_url' => 'https://github.com/AnalogJ/npm_analogj_test.git',
118
+ 'name' => 'npm_analog_test'
119
+ },
120
+ 'sha' => '0a5948802a2bba02e019fd13bf3db3c5329faae6',
121
+ 'ref' => 'master'
122
+ },
123
+ 'user' => {
124
+ 'login' => 'AnalogJ'
125
+ }
126
+ }
127
+ end
128
+
129
+ it 'should raise an error', :skip => true do
130
+ engine = test_engine.new
131
+ engine.instance_variable_set(:@source_client, source_client_double)
132
+ engine.instance_variable_set(:@source_git_parent_path, '/tmp')
133
+
134
+ allow(source_client_double).to receive(:collaborator?).and_return(false)
135
+ allow(source_client_double).to receive(:add_comment).and_return(false)
136
+
137
+ expect { engine.source_process_pull_request_payload(payload) }.to raise_error(CapsuleCD::Error::SourceUnauthorizedUser)
138
+ end
139
+ end
140
+
141
+ describe 'when using a valid payload' do
142
+ let(:payload) do
143
+ {
144
+ 'state' => 'open',
145
+ 'number' => 8,
146
+ 'base' => {
147
+ 'sha' => '0a5948802a2bba02e019fd13bf3db3c5329faae6',
148
+ 'ref' => 'master',
149
+ 'repo' => {
150
+ 'full_name' => 'AnalogJ/npm_analogj_test',
151
+ 'clone_url' => 'https://github.com/AnalogJ/npm_analogj_test.git',
152
+ 'name' => 'npm_analog_test',
153
+ 'default_branch' => 'master'
154
+ }
155
+ },
156
+ 'head' => {
157
+ 'sha' => '0a5948802a2bba02e019fd13bf3db3c5329faae6',
158
+ 'ref' => 'feature',
159
+ 'repo' => {
160
+ 'full_name' => 'AnalogJ/npm_analogj_test',
161
+ 'clone_url' => 'https://github.com/AnalogJ/npm_analogj_test.git',
162
+ 'name' => 'npm_analog_test'
163
+ }
164
+ },
165
+ 'user' => {
166
+ 'login' => 'AnalogJ'
167
+ }
168
+ }
169
+ end
170
+
171
+ it 'should clone merged repo' do
172
+ engine = test_engine.new
173
+ engine.instance_variable_set(:@config, config)
174
+ engine.instance_variable_set(:@source_client, source_client_double)
175
+ engine.instance_variable_set(:@source_git_parent_path, '/tmp')
176
+
177
+ allow(source_client_double).to receive(:collaborator?).and_return(true)
178
+ allow(source_client_double).to receive(:add_comment).and_return(false)
179
+ allow(source_client_double).to receive(:create_status).and_return(false)
180
+ allow(CapsuleCD::GitUtils).to receive(:clone).and_return(engine.source_git_parent_path + payload['head']['repo']['name'])
181
+ allow(CapsuleCD::GitUtils).to receive(:fetch).and_return(true)
182
+ allow(CapsuleCD::GitUtils).to receive(:checkout).and_return(true)
183
+
184
+ engine.source_process_pull_request_payload(payload)
185
+
186
+ expect(engine.source_git_local_branch).to eql('pr_8')
187
+ expect(engine.source_git_local_path).to eql(engine.source_git_parent_path + payload['head']['repo']['name'])
188
+ expect(engine.source_git_head_info).to be_a(Hash)
189
+ expect(engine.source_git_base_info).to be_a(Hash)
190
+ end
191
+ end
192
+ end
193
+
194
+ describe '#source_release' do
195
+ let(:test_engine) { Class.new { include CapsuleCD::Source::Github } }
196
+ let(:source_client_double) { instance_double(Octokit::Client) }
197
+ let(:git_commit_double) { instance_double(Git::Object::Commit) }
198
+
199
+ describe 'when release state is valid' do
200
+ let(:payload) do
201
+ {
202
+ 'state' => 'open',
203
+ 'number' => 8,
204
+ 'base' => {
205
+ 'sha' => '0a5948802a2bba02e019fd13bf3db3c5329faae6',
206
+ 'repo' => {
207
+ 'full_name' => 'AnalogJ/npm_analogj_test',
208
+ 'clone_url' => 'https://github.com/AnalogJ/npm_analogj_test.git',
209
+ 'name' => 'npm_analog_test',
210
+ 'default_branch' => 'master'
211
+ },
212
+ 'ref' => 'master'
213
+ },
214
+ 'head' => {
215
+ 'sha' => '0a5948802a2bba02e019fd13bf3db3c5329faae6',
216
+ 'repo' => {
217
+ 'full_name' => 'AnalogJ/npm_analogj_test',
218
+ 'clone_url' => 'https://github.com/AnalogJ/npm_analogj_test.git',
219
+ 'name' => 'npm_analog_test'
220
+ },
221
+ 'ref' => 'feature'
222
+ },
223
+ 'user' => {
224
+ 'login' => 'AnalogJ'
225
+ }
226
+ }
227
+ end
228
+
229
+ it 'should successfully push changes to github' do
230
+ engine = test_engine.new
231
+ engine.instance_variable_set(:@source_client, source_client_double)
232
+ engine.instance_variable_set(:@source_release_commit, git_commit_double)
233
+ engine.instance_variable_set(:@source_git_local_path, '')
234
+ engine.instance_variable_set(:@source_git_local_branch, '')
235
+ engine.instance_variable_set(:@source_git_base_info, payload['base'])
236
+ engine.instance_variable_set(:@source_git_head_info, payload['head'])
237
+ engine.instance_variable_set(:@source_release_artifacts, [])
238
+ engine.instance_variable_set(:@source_git_parent_path, test_directory)
239
+
240
+ allow(source_client_double).to receive(:create_release).and_return(true)
241
+ allow(source_client_double).to receive(:upload_asset).and_return(false)
242
+ allow(source_client_double).to receive(:create_status).and_return(false)
243
+ allow(git_commit_double).to receive(:sha).and_return('0a5948802a2bba02e019fd13bf3db3c5329faae6')
244
+ allow(git_commit_double).to receive(:name).and_return('test')
245
+ allow(CapsuleCD::GitUtils).to receive(:push).and_return(true)
246
+ allow(CapsuleCD::GitUtils).to receive(:generate_changelog).and_return('')
247
+ allow(FileUtils).to receive(:remove_entry_secure).and_return(true)
248
+
249
+ engine.source_release
250
+ end
251
+ end
252
+ end
253
+ end
@@ -0,0 +1,55 @@
1
+ require 'spec_helper'
2
+
3
+ describe CapsuleCD::TransformEngine do
4
+ before(:each) do
5
+ CapsuleCD.send(:remove_const, 'EngineExtension')
6
+ load 'lib/capsulecd/base/transform_engine.rb'
7
+ end
8
+ describe '::new' do
9
+ describe 'with a global configuration file' do
10
+
11
+ describe 'with an empty engine' do
12
+ before(:each) do
13
+ stub_const 'EmptyEngine', Class.new
14
+ end
15
+
16
+ let(:config_file_path) { 'spec/fixtures/sample_global_configuration.yml' }
17
+ subject { CapsuleCD::TransformEngine.new() }
18
+
19
+ it 'should raise an error if we specify that its a repo configuration' do
20
+ expect{
21
+ subject.transform(nil, config_file_path)
22
+ }.to raise_error(CapsuleCD::Error::EngineTransformUnavailableStep)
23
+ end
24
+
25
+ it 'should register the EngineExtension methods after transform' do
26
+ engine = EmptyEngine.new
27
+ expect(engine.methods - Object.methods).to be_empty
28
+ subject.transform(engine, config_file_path, :global)
29
+ expect((engine.methods - Object.methods).sort).to eql([:post_build_step, :post_source_configure, :pre_source_configure, :source_configure])
30
+ expect(engine.source_configure).to eql('override source_configure')
31
+ end
32
+ end
33
+
34
+ describe 'with an base engine' do
35
+ before(:each) do
36
+ stub_const 'BaseEngine', CapsuleCD::Engine
37
+ end
38
+
39
+ let(:config_file_path) { 'spec/fixtures/sample_global_configuration.yml' }
40
+ subject { CapsuleCD::TransformEngine.new() }
41
+
42
+
43
+ it 'should register the EngineExtension methods after transform, and override any existing methods' do
44
+ engine = BaseEngine.new(source: :github)
45
+ engine.instance_variable_set(:@source_git_local_path, test_directory)
46
+ subject.transform(engine, config_file_path, :global)
47
+ expect(engine.source_configure).to eql('override source_configure')
48
+ expect(engine.post_build_step).to eql('override post_build_step'+test_directory)
49
+ end
50
+ end
51
+
52
+ end
53
+
54
+ end
55
+ end
@@ -0,0 +1,114 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'CapsuleCD::Chef::ChefEngine', :chef do
4
+ describe '#build_step' do
5
+ describe 'when building an empty package' do
6
+ let(:engine) do
7
+ require 'capsulecd/chef/chef_engine'
8
+ CapsuleCD::Chef::ChefEngine.new(source: :github,
9
+ package_type: :chef)
10
+ end
11
+ it 'should raise an error' do
12
+ engine.instance_variable_set(:@source_git_local_path, test_directory )
13
+
14
+ expect { engine.build_step }.to raise_error(CapsuleCD::Error::BuildPackageInvalid)
15
+ end
16
+ end
17
+
18
+ describe 'when building a simple package ' do
19
+ let(:engine) do
20
+ require 'capsulecd/chef/chef_engine'
21
+ CapsuleCD::Chef::ChefEngine.new(source: :github,
22
+ package_type: :chef)
23
+ end
24
+ it 'should create a Rakefile, Berksfile, .gitignore file, file and tests folder' do
25
+ FileUtils.copy_entry('spec/fixtures/chef/cookbook_analogj_test', test_directory)
26
+ engine.instance_variable_set(:@source_git_local_path, test_directory )
27
+
28
+ VCR.use_cassette('chef_build_step',:tag => :chef) do
29
+ engine.build_step
30
+ end
31
+ File.exist?(test_directory+'/Rakefile')
32
+ File.exist?(test_directory+'/Berksfile')
33
+ File.exist?(test_directory+'/.gitignore')
34
+ File.exist?(test_directory+'/Gemfile')
35
+
36
+ end
37
+ end
38
+ end
39
+
40
+ describe '#test_step' do
41
+ let(:engine) do
42
+ require 'capsulecd/chef/chef_engine'
43
+ CapsuleCD::Chef::ChefEngine.new(source: :github,
44
+ package_type: :chef)
45
+ end
46
+ let(:config_double) { CapsuleCD::Configuration.new }
47
+ describe 'when testing chef package' do
48
+ it 'should run install dependencies' do
49
+ FileUtils.copy_entry('spec/fixtures/chef/cookbook_analogj_test', test_directory)
50
+ allow(Open3).to receive(:popen3).and_return(false)
51
+ allow(config_double).to receive(:engine_cmd_test).and_call_original
52
+ allow(config_double).to receive(:engine_disable_test).and_call_original
53
+ engine.instance_variable_set(:@source_git_local_path, test_directory)
54
+ engine.instance_variable_set(:@config, config_double)
55
+
56
+ engine.test_step
57
+ end
58
+ end
59
+ end
60
+
61
+ describe 'integration tests' do
62
+ let(:engine) do
63
+ require 'capsulecd/chef/chef_engine'
64
+ CapsuleCD::Chef::ChefEngine.new(source: :github,
65
+ runner: :default,
66
+ package_type: :chef,
67
+ config_file: 'spec/fixtures/sample_chef_configuration.yml'
68
+ # config_file: 'spec/fixtures/live_chef_configuration.yml'
69
+ )
70
+ end
71
+ let(:git_commit_double) { instance_double(Git::Object::Commit) }
72
+ describe 'when testing chef package' do
73
+ it 'should complete successfully' do
74
+ FileUtils.copy_entry('spec/fixtures/chef/cookbook_analogj_test', test_directory)
75
+
76
+ VCR.use_cassette('integration_chef',:tag => :chef) do
77
+ #set defaults for stubbed classes
78
+ source_git_local_path = test_directory
79
+ allow(File).to receive(:exist?).and_call_original
80
+ allow(File).to receive(:open).and_call_original
81
+ allow(Open3).to receive(:popen3).and_call_original
82
+
83
+ #stub methods in source_process_pull_request_payload
84
+ allow(CapsuleCD::GitUtils).to receive(:clone).and_return(source_git_local_path)
85
+ allow(CapsuleCD::GitUtils).to receive(:fetch).and_return(true)
86
+ allow(CapsuleCD::GitUtils).to receive(:checkout).and_return(true)
87
+
88
+ #stub methods in build_step
89
+ allow(CapsuleCD::GitUtils).to receive(:create_gitignore).with(source_git_local_path, ['ChefCookbook']).and_return(true)
90
+
91
+ #stub methods in package_step
92
+ allow(CapsuleCD::GitUtils).to receive(:commit).and_return(true)
93
+ allow(CapsuleCD::GitUtils).to receive(:tag).with(source_git_local_path,'v0.1.11').and_return(git_commit_double)
94
+ allow(git_commit_double).to receive(:sha).and_return('0a5948802a2bba02e019fd13bf3db3c5329faae6')
95
+ allow(git_commit_double).to receive(:name).and_return('0.1.11')
96
+
97
+ #stub methods in release_step
98
+ allow(Open3).to receive(:popen3).with("knife cookbook site share cookbook_analogj_test Other -c #{File.expand_path('~/knife.rb')}").and_return(true)
99
+ allow(File).to receive(:open).with(File.expand_path('~/knife.rb'), 'w+').and_return(true)
100
+ allow(File).to receive(:open).with(File.expand_path('~/client.pem'), 'w+').and_return(true)
101
+
102
+ #stub methods in source_release
103
+ allow(CapsuleCD::GitUtils).to receive(:push).and_return(true)
104
+ allow(CapsuleCD::GitUtils).to receive(:generate_changelog).and_return('')
105
+
106
+ engine.start
107
+
108
+ end
109
+
110
+ end
111
+ end
112
+ end
113
+
114
+ end
@@ -0,0 +1,57 @@
1
+ require 'spec_helper'
2
+ require 'rspec/support/spec/in_sub_process'
3
+ require 'capsulecd/cli'
4
+ require 'capsulecd/base/engine'
5
+
6
+ describe CapsuleCD::Cli do
7
+ describe '#start' do
8
+ describe 'with default_engine' do
9
+ let(:engine_double) { instance_double(CapsuleCD::Engine, start: true) }
10
+ it 'should call the default start command with the proper options' do
11
+ expect(CapsuleCD::Engine).to receive(:new).with(
12
+ runner: :default, source: :default, package_type: :default, dry_run: false).and_return engine_double
13
+
14
+ CapsuleCD::Cli.start %w(start)
15
+ end
16
+ end
17
+
18
+ describe 'with node_engine', :node do
19
+ require 'capsulecd/node/node_engine'
20
+ let(:engine_double) { instance_double(CapsuleCD::Node::NodeEngine, start: true) }
21
+ it 'should call the node start command with the proper options' do
22
+ expect(CapsuleCD::Node::NodeEngine).to receive(:new).with(
23
+ runner: :default, source: :default, package_type: :node, dry_run: false).and_return engine_double
24
+
25
+ CapsuleCD::Cli.start %w(start --package_type node)
26
+ end
27
+ end
28
+
29
+ describe 'with chef_engine', :chef do
30
+ let(:engine_double) do
31
+ require 'capsulecd/chef/chef_engine'
32
+ instance_double(CapsuleCD::Chef::ChefEngine, start: true)
33
+ end
34
+ it 'should call the chef start command with the proper options' do
35
+ require 'capsulecd/chef/chef_engine'
36
+ expect(CapsuleCD::Chef::ChefEngine).to receive(:new).with(
37
+ runner: :default, source: :default, package_type: :chef, dry_run: false).and_return engine_double
38
+
39
+ CapsuleCD::Cli.start %w(start --package_type chef)
40
+ end
41
+ end
42
+
43
+ describe 'with python_engine', :python do
44
+ let(:engine_double) do
45
+ require 'capsulecd/python/python_engine'
46
+ instance_double(CapsuleCD::Python::PythonEngine, start: true)
47
+ end
48
+ it 'should call the python start command with the proper options' do
49
+ require 'capsulecd/python/python_engine'
50
+ expect(CapsuleCD::Python::PythonEngine).to receive(:new).with(
51
+ runner: :default, source: :default, package_type: :python, dry_run: false).and_return engine_double
52
+
53
+ CapsuleCD::Cli.start %w(start --package_type python)
54
+ end
55
+ end
56
+ end
57
+ end