capsulecd 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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