nucleus 0.2.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +3 -0
  3. data/CHANGELOG.md +9 -0
  4. data/README.md +43 -72
  5. data/lib/nucleus/adapter_resolver.rb +3 -3
  6. data/lib/nucleus/adapters/base_adapter.rb +109 -109
  7. data/lib/nucleus/adapters/v1/cloud_foundry_v2/application.rb +111 -111
  8. data/lib/nucleus/adapters/v1/cloud_foundry_v2/cloud_foundry_v2.rb +141 -141
  9. data/lib/nucleus/adapters/v1/cloud_foundry_v2/data.rb +97 -97
  10. data/lib/nucleus/adapters/v1/cloud_foundry_v2/domains.rb +5 -5
  11. data/lib/nucleus/adapters/v1/cloud_foundry_v2/lifecycle.rb +41 -41
  12. data/lib/nucleus/adapters/v1/cloud_foundry_v2/logs.rb +6 -6
  13. data/lib/nucleus/adapters/v1/cloud_foundry_v2/regions.rb +33 -33
  14. data/lib/nucleus/adapters/v1/cloud_foundry_v2/services.rb +6 -6
  15. data/lib/nucleus/adapters/v1/cloud_foundry_v2/vars.rb +80 -80
  16. data/lib/nucleus/adapters/v1/heroku/app_states.rb +57 -57
  17. data/lib/nucleus/adapters/v1/heroku/data.rb +78 -78
  18. data/lib/nucleus/adapters/v1/heroku/heroku.rb +146 -146
  19. data/lib/nucleus/adapters/v1/heroku/lifecycle.rb +51 -51
  20. data/lib/nucleus/adapters/v1/heroku/logs.rb +2 -2
  21. data/lib/nucleus/adapters/v1/heroku/regions.rb +42 -42
  22. data/lib/nucleus/adapters/v1/heroku/services.rb +168 -168
  23. data/lib/nucleus/adapters/v1/heroku/vars.rb +65 -65
  24. data/lib/nucleus/adapters/v1/openshift_v2/app_states.rb +68 -68
  25. data/lib/nucleus/adapters/v1/openshift_v2/application.rb +1 -1
  26. data/lib/nucleus/adapters/v1/openshift_v2/data.rb +96 -96
  27. data/lib/nucleus/adapters/v1/openshift_v2/lifecycle.rb +60 -60
  28. data/lib/nucleus/adapters/v1/openshift_v2/logs.rb +106 -106
  29. data/lib/nucleus/adapters/v1/openshift_v2/openshift_v2.rb +125 -125
  30. data/lib/nucleus/adapters/v1/openshift_v2/regions.rb +58 -58
  31. data/lib/nucleus/adapters/v1/openshift_v2/services.rb +173 -173
  32. data/lib/nucleus/adapters/v1/openshift_v2/vars.rb +49 -49
  33. data/lib/nucleus/adapters/v1/stub_adapter.rb +464 -464
  34. data/lib/nucleus/core/adapter_extensions/auth/auth_client.rb +44 -44
  35. data/lib/nucleus/core/adapter_extensions/auth/expiring_token_auth_client.rb +53 -53
  36. data/lib/nucleus/core/adapter_extensions/auth/http_basic_auth_client.rb +3 -3
  37. data/lib/nucleus/core/adapter_extensions/auth/o_auth2_auth_client.rb +95 -95
  38. data/lib/nucleus/core/adapter_extensions/auth/token_auth_client.rb +36 -36
  39. data/lib/nucleus/core/adapter_extensions/http_client.rb +5 -5
  40. data/lib/nucleus/core/common/files/archive_extractor.rb +1 -1
  41. data/lib/nucleus/core/common/files/archiver.rb +2 -2
  42. data/lib/nucleus/core/file_handling/file_manager.rb +64 -64
  43. data/lib/nucleus/core/file_handling/git_deployer.rb +133 -133
  44. data/lib/nucleus/core/import/adapter_configuration.rb +53 -53
  45. data/lib/nucleus/scripts/initialize_config_defaults.rb +26 -26
  46. data/lib/nucleus/version.rb +1 -1
  47. data/nucleus.gemspec +2 -2
  48. data/spec/integration/api/auth_spec.rb +3 -3
  49. data/spec/spec_helper.rb +98 -98
  50. data/spec/test_suites.rake +1 -1
  51. data/spec/unit/adapters/git_deployer_spec.rb +262 -262
  52. data/spec/unit/common/helpers/auth_helper_spec.rb +1 -1
  53. data/tasks/evaluation.rake +1 -1
  54. data/wiki/adapter_tests.md +0 -7
  55. data/wiki/implement_new_adapter.md +1 -1
  56. metadata +4 -20
  57. data/config/adapters/cloud_control.yml +0 -32
  58. data/lib/nucleus/adapters/v1/cloud_control/application.rb +0 -108
  59. data/lib/nucleus/adapters/v1/cloud_control/authentication.rb +0 -27
  60. data/lib/nucleus/adapters/v1/cloud_control/buildpacks.rb +0 -23
  61. data/lib/nucleus/adapters/v1/cloud_control/cloud_control.rb +0 -153
  62. data/lib/nucleus/adapters/v1/cloud_control/data.rb +0 -76
  63. data/lib/nucleus/adapters/v1/cloud_control/domains.rb +0 -68
  64. data/lib/nucleus/adapters/v1/cloud_control/lifecycle.rb +0 -27
  65. data/lib/nucleus/adapters/v1/cloud_control/log_poller.rb +0 -71
  66. data/lib/nucleus/adapters/v1/cloud_control/logs.rb +0 -103
  67. data/lib/nucleus/adapters/v1/cloud_control/regions.rb +0 -32
  68. data/lib/nucleus/adapters/v1/cloud_control/scaling.rb +0 -17
  69. data/lib/nucleus/adapters/v1/cloud_control/semantic_errors.rb +0 -31
  70. data/lib/nucleus/adapters/v1/cloud_control/services.rb +0 -162
  71. data/lib/nucleus/adapters/v1/cloud_control/token.rb +0 -17
  72. data/lib/nucleus/adapters/v1/cloud_control/vars.rb +0 -88
@@ -1,26 +1,26 @@
1
- # Check the API versions once and make them available via configatron
2
- nucleus_config.api.versions = Nucleus::VersionDetector.api_versions
3
-
4
- # make sure the key is always set
5
- key_file = nil
6
- if nucleus_config.ssh.key?(:custom_key) && !nucleus_config.ssh.custom_key.nil?
7
- puts "Loading custom SSH key #{nucleus_config.ssh.custom_key}"
8
- # use the custom key file
9
- key_file = nucleus_config.ssh.custom_key
10
-
11
- # fail if file does not exist
12
- unless File.exist?(key_file)
13
- msg = "Could not find the SSH key: '#{key_file}'"
14
- STDERR.puts msg
15
- fail Nucleus::StartupError.new(msg, Nucleus::ExitCodes::INVALID_SSH_KEY_FILE)
16
- end
17
-
18
- if File.read(key_file).include?('ENCRYPTED')
19
- msg = "Provided private key '#{key_file}' must not be protected with a passphrase."
20
- STDERR.puts msg
21
- fail Nucleus::StartupError.new(msg, Nucleus::ExitCodes::INVALID_SSH_KEY_FILE_PROTECTED)
22
- end
23
- end
24
-
25
- # now setup the SSHHandler
26
- nucleus_config.ssh.handler = Nucleus::SSHHandler.new(key_file)
1
+ # Check the API versions once and make them available via configatron
2
+ nucleus_config.api.versions = Nucleus::VersionDetector.api_versions
3
+
4
+ # make sure the key is always set
5
+ key_file = nil
6
+ if nucleus_config.ssh.key?(:custom_key) && !nucleus_config.ssh.custom_key.nil?
7
+ puts "Loading custom SSH key #{nucleus_config.ssh.custom_key}"
8
+ # use the custom key file
9
+ key_file = nucleus_config.ssh.custom_key
10
+
11
+ # fail if file does not exist
12
+ unless File.exist?(key_file)
13
+ msg = "Could not find the SSH key: '#{key_file}'"
14
+ STDERR.puts msg
15
+ raise Nucleus::StartupError.new(msg, Nucleus::ExitCodes::INVALID_SSH_KEY_FILE)
16
+ end
17
+
18
+ if File.read(key_file).include?('ENCRYPTED')
19
+ msg = "Provided private key '#{key_file}' must not be protected with a passphrase."
20
+ STDERR.puts msg
21
+ raise Nucleus::StartupError.new(msg, Nucleus::ExitCodes::INVALID_SSH_KEY_FILE_PROTECTED)
22
+ end
23
+ end
24
+
25
+ # now setup the SSHHandler
26
+ nucleus_config.ssh.handler = Nucleus::SSHHandler.new(key_file)
@@ -1,3 +1,3 @@
1
1
  module Nucleus
2
- VERSION = '0.2.0'.freeze
2
+ VERSION = '0.3.1'.freeze
3
3
  end
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
18
18
 
19
19
  # we ignore the test files and icons as they tremendously increase the gem size (up to 43MB)
20
20
  spec.files = `git ls-files -z --exclude-standard`.split("\x0").reject do |f|
21
- f[%r{^(lib/nucleus_api|spec/adapter|icons)/}]
21
+ f[%r{^(lib/nucleus_api|spec/adapter|icons|docs)/}]
22
22
  end
23
23
  # again only unit and integration, but no adapter test files
24
24
  spec.test_files = spec.files.grep(%r{^(spec)/})
@@ -79,7 +79,7 @@ Gem::Specification.new do |spec|
79
79
  spec.add_development_dependency 'guard-yard'
80
80
  spec.add_development_dependency 'inch', '~> 0.7'
81
81
  spec.add_development_dependency 'rake', '~> 10.4'
82
- spec.add_development_dependency 'rubocop', '~> 0.36.0'
82
+ spec.add_development_dependency 'rubocop', '~> 0.37.2'
83
83
  spec.add_development_dependency 'vcr', '~> 3.0'
84
84
  spec.add_development_dependency 'webmock', '~> 1.20'
85
85
  spec.add_development_dependency 'yard', '~> 0.8'
@@ -31,17 +31,17 @@ describe Nucleus::API::V1::Auth do
31
31
 
32
32
  allow_any_instance_of(Nucleus::Adapters::V1::Heroku).to receive(:applications).and_wrap_original do |m, _|
33
33
  unless m.receiver.send(:headers)['Authorization'] == 'bearer 1234567890'
34
- fail Nucleus::Errors::EndpointAuthenticationError, 'Bad authentication credentials'
34
+ raise Nucleus::Errors::EndpointAuthenticationError, 'Bad authentication credentials'
35
35
  end
36
36
  []
37
37
  end
38
38
  call_count = 0
39
39
  allow_any_instance_of(Nucleus::Adapters::V1::CloudFoundryV2).to receive(:applications).and_wrap_original do |m, _|
40
40
  unless m.receiver.send(:headers)['Authorization'] == 'bearer 0987654321'
41
- fail Nucleus::Errors::EndpointAuthenticationError, 'Bad authentication credentials'
41
+ raise Nucleus::Errors::EndpointAuthenticationError, 'Bad authentication credentials'
42
42
  end
43
43
  call_count += 1
44
- fail Nucleus::Errors::EndpointAuthenticationError, 'Fail 1st attempt' if call_count == 1
44
+ raise Nucleus::Errors::EndpointAuthenticationError, 'Fail 1st attempt' if call_count == 1
45
45
  []
46
46
  end
47
47
  end
@@ -1,98 +1,98 @@
1
- $LOAD_PATH << File.join(__dir__, '..')
2
-
3
- # figure out where we are being loaded from
4
- if $LOADED_FEATURES.grep(%r{spec\/spec_helper\.rb}).any?
5
- begin
6
- fail 'foo'
7
- rescue => e
8
- puts <<-MSG
9
- ===================================================
10
- It looks like spec_helper.rb has been loaded
11
- multiple times. Normalize the require to:
12
-
13
- require "spec/spec_helper"
14
-
15
- Things like File.join and File.expand_path will
16
- cause it to be loaded multiple times.
17
-
18
- Loaded this time from:
19
-
20
- #{e.backtrace.join("\n ")}
21
- ===================================================
22
- MSG
23
- end
24
- end
25
-
26
- require 'vcr'
27
- require 'factory_girl'
28
- require 'faker'
29
- require 'tmpdir'
30
-
31
- # we need this to detect whether to apply test middleware (tailing hack)
32
- ENV['RACK_ENV'] = 'test'
33
-
34
- if ENV['CODECLIMATE_REPO_TOKEN']
35
- require 'simplecov'
36
- require 'codeclimate-test-reporter'
37
- SimpleCov.add_filter 'vendor'
38
- SimpleCov.formatters = []
39
- # merge results of the last 1 hour
40
- SimpleCov.merge_timeout 3600
41
- SimpleCov.start CodeClimate::TestReporter.configuration.profile
42
- else
43
- require 'simplecov'
44
- # merge results of the last 1 hour
45
- SimpleCov.merge_timeout 3600
46
- SimpleCov.start do
47
- add_filter 'spec/'
48
- add_filter 'lib/nucleus/scripts/'
49
- add_filter 'config/'
50
-
51
- add_group 'Adapters', 'lib/nucleus/adapters'
52
- add_group 'Core', 'lib/nucleus/core'
53
- add_group 'Persistence', 'lib/nucleus/persistence'
54
- add_group 'Lib ext.', 'lib/nucleus/ext'
55
- add_group 'API versions', 'lib/nucleus_api/api/versions'
56
- add_group 'API entities', 'lib/nucleus_api/api/entities'
57
- add_group 'API helpers', 'lib/nucleus_api/api/helpers'
58
- add_group 'API Middleware', 'lib/nucleus_api/rack_middleware'
59
- add_group 'API Models', 'lib/nucleus_api/models'
60
- add_group 'API Lib ext.', 'lib/nucleus_api/ext'
61
- end
62
- end
63
-
64
- # load configuration for integration tests
65
- require 'nucleus/scripts/setup_config'
66
- # disable logging
67
- # TODO: disable logging via proper config option
68
- nucleus_config.logging.level = Logger::Severity::FATAL
69
- # force tmp database
70
- nucleus_config.db.path = File.join(Dir.tmpdir, "#{SecureRandom.uuid}.nucleus.test.store")
71
- nucleus_config.db.delete_on_shutdown = true
72
- nucleus_config.db.override = true
73
-
74
- # require our app
75
- require 'nucleus_api/scripts/load_api'
76
-
77
- # load the certificate to use for the tests only
78
- nucleus_config.ssh.custom_key = File.expand_path(File.join('spec', 'nucleus_git_key.pem'))
79
-
80
- # initialize db, versions and auth strategy
81
- require 'nucleus/scripts/initialize_config_defaults'
82
- # initialize the api config
83
- require 'nucleus_api/scripts/initialize_api_customizations'
84
-
85
- require 'spec/factories/models'
86
-
87
- # require shared examples
88
- require_all 'spec/support'
89
-
90
- RSpec.configure do |config|
91
- config.include FactoryGirl::Syntax::Methods
92
- config.before(:suite) do
93
- Excon.defaults[:mock] = true
94
- end
95
- config.after(:each) do
96
- Excon.stubs.clear
97
- end
98
- end
1
+ $LOAD_PATH << File.join(__dir__, '..')
2
+
3
+ # figure out where we are being loaded from
4
+ if $LOADED_FEATURES.grep(%r{spec\/spec_helper\.rb}).any?
5
+ begin
6
+ raise 'foo'
7
+ rescue => e
8
+ puts <<-MSG
9
+ ===================================================
10
+ It looks like spec_helper.rb has been loaded
11
+ multiple times. Normalize the require to:
12
+
13
+ require "spec/spec_helper"
14
+
15
+ Things like File.join and File.expand_path will
16
+ cause it to be loaded multiple times.
17
+
18
+ Loaded this time from:
19
+
20
+ #{e.backtrace.join("\n ")}
21
+ ===================================================
22
+ MSG
23
+ end
24
+ end
25
+
26
+ require 'vcr'
27
+ require 'factory_girl'
28
+ require 'faker'
29
+ require 'tmpdir'
30
+
31
+ # we need this to detect whether to apply test middleware (tailing hack)
32
+ ENV['RACK_ENV'] = 'test'
33
+
34
+ if ENV['CODECLIMATE_REPO_TOKEN']
35
+ require 'simplecov'
36
+ require 'codeclimate-test-reporter'
37
+ SimpleCov.add_filter 'vendor'
38
+ SimpleCov.formatters = []
39
+ # merge results of the last 1 hour
40
+ SimpleCov.merge_timeout 3600
41
+ SimpleCov.start CodeClimate::TestReporter.configuration.profile
42
+ else
43
+ require 'simplecov'
44
+ # merge results of the last 1 hour
45
+ SimpleCov.merge_timeout 3600
46
+ SimpleCov.start do
47
+ add_filter 'spec/'
48
+ add_filter 'lib/nucleus/scripts/'
49
+ add_filter 'config/'
50
+
51
+ add_group 'Adapters', 'lib/nucleus/adapters'
52
+ add_group 'Core', 'lib/nucleus/core'
53
+ add_group 'Persistence', 'lib/nucleus/persistence'
54
+ add_group 'Lib ext.', 'lib/nucleus/ext'
55
+ add_group 'API versions', 'lib/nucleus_api/api/versions'
56
+ add_group 'API entities', 'lib/nucleus_api/api/entities'
57
+ add_group 'API helpers', 'lib/nucleus_api/api/helpers'
58
+ add_group 'API Middleware', 'lib/nucleus_api/rack_middleware'
59
+ add_group 'API Models', 'lib/nucleus_api/models'
60
+ add_group 'API Lib ext.', 'lib/nucleus_api/ext'
61
+ end
62
+ end
63
+
64
+ # load configuration for integration tests
65
+ require 'nucleus/scripts/setup_config'
66
+ # disable logging
67
+ # TODO: disable logging via proper config option
68
+ nucleus_config.logging.level = Logger::Severity::FATAL
69
+ # force tmp database
70
+ nucleus_config.db.path = File.join(Dir.tmpdir, "#{SecureRandom.uuid}.nucleus.test.store")
71
+ nucleus_config.db.delete_on_shutdown = true
72
+ nucleus_config.db.override = true
73
+
74
+ # require our app
75
+ require 'nucleus_api/scripts/load_api'
76
+
77
+ # load the certificate to use for the tests only
78
+ nucleus_config.ssh.custom_key = File.expand_path(File.join('spec', 'nucleus_git_key.pem'))
79
+
80
+ # initialize db, versions and auth strategy
81
+ require 'nucleus/scripts/initialize_config_defaults'
82
+ # initialize the api config
83
+ require 'nucleus_api/scripts/initialize_api_customizations'
84
+
85
+ require 'spec/factories/models'
86
+
87
+ # require shared examples
88
+ require_all 'spec/support'
89
+
90
+ RSpec.configure do |config|
91
+ config.include FactoryGirl::Syntax::Methods
92
+ config.before(:suite) do
93
+ Excon.defaults[:mock] = true
94
+ end
95
+ config.after(:each) do
96
+ Excon.stubs.clear
97
+ end
98
+ end
@@ -25,7 +25,7 @@ namespace :spec do
25
25
  Rake::Task["spec:suite:#{suite[:id]}"].execute
26
26
  failed << suite[:id] unless $CHILD_STATUS.success?
27
27
  end
28
- fail "Spec suite#{failed.length > 1 ? 's' : ''} '#{failed.join(', ')}' failed" unless failed.empty?
28
+ raise "Spec suite#{failed.length > 1 ? 's' : ''} '#{failed.join(', ')}' failed" unless failed.empty?
29
29
  end
30
30
  end
31
31
  end
@@ -1,262 +1,262 @@
1
- require 'spec/unit/unit_spec_helper'
2
-
3
- describe Nucleus::Adapters::GitDeployer do
4
- let(:repo_name) { 'my_repository' }
5
- let(:repo_url) { 'http://repo.example.org' }
6
- let(:user_email) { 'myuser@example.org' }
7
- let(:repo) { double(Git::Base) }
8
- let(:zip) { 'zip' }
9
- let(:file) { File.join('random', 'file', 'path') }
10
-
11
- it '#deploy fails early with invalid format' do
12
- subject = Nucleus::Adapters::GitDeployer.new(repo_name, repo_url, user_email)
13
- extractor = double(Nucleus::ArchiveExtractor)
14
- expect(Nucleus::ArchiveExtractor).to receive(:new).with(any_args).once { extractor }
15
- # we assume format is supported
16
- expect(extractor).to receive(:supports?).with(kind_of(String)).once { false }
17
- # call should fail
18
- expect { subject.deploy(nil, 'xyz') }.to raise_error(Nucleus::Errors::AdapterRequestError)
19
- end
20
-
21
- describe 'repository actions' do
22
- before do
23
- # every action needs to clone the repository
24
- expect(Git).to receive(:clone).with(repo_url, repo_name, path: kind_of(String)).once { repo }
25
- # verify cleanup is performed for each method call
26
- expect(FileUtils).to receive(:rm_rf).with(File.join(Dir.tmpdir, repo_name)).once
27
- end
28
-
29
- describe '#download' do
30
- let!(:exclude_git) { true }
31
-
32
- context 'with master branch' do
33
- subject { Nucleus::Adapters::GitDeployer.new(repo_name, repo_url, user_email) }
34
- let(:repo_branch) { 'master' }
35
- it 'returns archived repository' do
36
- # verify archiver is called to return the response
37
- archiver = double(Nucleus::Archiver)
38
- expect(Nucleus::Archiver).to receive(:new).with(exclude_git) { archiver }
39
- expect(archiver).to receive(:compress).with(kind_of(String), zip).once { 'response' }
40
-
41
- # execute the call
42
- response = subject.download(zip, exclude_git)
43
- expect(response).to eql('response')
44
- end
45
- end
46
-
47
- context 'with nucleus branch' do
48
- let(:repo_branch) { 'nucleus' }
49
- subject { Nucleus::Adapters::GitDeployer.new(repo_name, repo_url, user_email, repo_branch) }
50
- it 'returns archived repository' do
51
- branch_mock = double(Git::Branch)
52
- expect(repo).to receive(:branch).with(repo_branch).once { branch_mock }
53
- expect(repo).to receive(:checkout).with(branch_mock).once { repo }
54
-
55
- # verify archiver is called to return the response
56
- archiver = double(Nucleus::Archiver)
57
- expect(Nucleus::Archiver).to receive(:new).with(exclude_git) { archiver }
58
- expect(archiver).to receive(:compress).with(kind_of(String), zip).once { 'response' }
59
-
60
- # execute the call
61
- response = subject.download(zip, exclude_git)
62
- expect(response).to eql('response')
63
- end
64
-
65
- it 'returns archived repository even if master did not contain any commit' do
66
- # branch fails for master without commits
67
- expect(repo).to receive(:branch).with(repo_branch).once { fail StandardError, 'No commit for master' }
68
- # then we rely on the fallback, checkout new branch
69
- expect(repo).to receive(:checkout).with(repo_branch, new_branch: true).once { repo }
70
-
71
- # verify archiver is called to return the response
72
- archiver = double(Nucleus::Archiver)
73
- expect(Nucleus::Archiver).to receive(:new).with(exclude_git) { archiver }
74
- expect(archiver).to receive(:compress).with(kind_of(String), zip).once { 'response' }
75
-
76
- # execute the call
77
- response = subject.download(zip, exclude_git)
78
- expect(response).to eql('response')
79
- end
80
- end
81
- end
82
-
83
- describe '#trigger_build' do
84
- # set username and email
85
- before { expect(repo).to receive(:config).with(kind_of(String), kind_of(String)).twice }
86
-
87
- it 'succeeds for master branch' do
88
- subject = Nucleus::Adapters::GitDeployer.new(repo_name, repo_url, user_email)
89
- expect(repo).to receive(:add).with(all: true).once
90
- expect(repo).to receive(:commit).with(kind_of(String)).once
91
- expect(repo).to receive(:repack).with(no_args).once
92
- expect(repo).to receive(:push).with(kind_of(String), 'master', force: true).once
93
-
94
- # there shall be the attempt to write a file to the repository
95
- expect(Nucleus::Adapters::FileManager).to receive(:save_file_from_data).with(any_args).once
96
- # trigger the method
97
- subject.trigger_build
98
- end
99
-
100
- it 'succeeds for nucleus branch' do
101
- subject = Nucleus::Adapters::GitDeployer.new(repo_name, repo_url, user_email, 'nucleus')
102
- expect(repo).to receive(:add).with(all: true).once
103
- expect(repo).to receive(:commit).with(kind_of(String)).once
104
- expect(repo).to receive(:repack).with(no_args).once
105
- expect(repo).to receive(:push).with(kind_of(String), 'nucleus', force: true).once
106
-
107
- branch_mock = double(Git::Branch)
108
- expect(repo).to receive(:branch).with('nucleus').once { branch_mock }
109
- expect(repo).to receive(:checkout).with(branch_mock).once { repo }
110
-
111
- # there shall be the attempt to write a file to the repository
112
- expect(Nucleus::Adapters::FileManager).to receive(:save_file_from_data)
113
- # trigger the method
114
- subject.trigger_build
115
- end
116
- end
117
-
118
- describe '#deploy', memfs: true do
119
- before { expect(repo).to receive(:config).with(kind_of(String), kind_of(String)).twice }
120
- context 'with master branch' do
121
- let(:repo_branch) { 'master' }
122
- subject { Nucleus::Adapters::GitDeployer.new(repo_name, repo_url, user_email) }
123
-
124
- describe 'fails' do
125
- it 'if no files were extracted' do
126
- extractor = double(Nucleus::ArchiveExtractor)
127
- expect(Nucleus::ArchiveExtractor).to receive(:new).once { extractor }
128
- # we assume format is supported
129
- expect(extractor).to receive(:supports?).with(kind_of(String)).once { true }
130
- # assumes number of extracted files
131
- expect(extractor).to receive(:extract).with(file, kind_of(String), zip) { 0 }
132
-
133
- # write files to disk, as the extractor would do
134
- repo_dir = File.join(Dir.tmpdir, repo_name)
135
- git_dir = File.join(repo_dir, '.git')
136
- FileUtils.mkdir_p(git_dir)
137
- FileUtils.touch(File.join(git_dir, 'some_git_file.txt'))
138
-
139
- # make sure files actually exist
140
- expect(File.file?(File.join(git_dir, 'some_git_file.txt'))).to eql(true)
141
- expect(File.directory?(git_dir)).to eql(true)
142
-
143
- # call should fail
144
- expect { subject.deploy(file, zip) }.to raise_error(Nucleus::Errors::AdapterRequestError)
145
- end
146
- end
147
-
148
- it 'succeeds' do
149
- expect(repo).to receive(:add).with(all: true).once
150
- expect(repo).to receive(:commit).with(kind_of(String)).once
151
- expect(repo).to receive(:repack).with(no_args).once
152
- expect(repo).to receive(:push).with(kind_of(String), repo_branch, force: true).once
153
-
154
- extractor = double(Nucleus::ArchiveExtractor)
155
- expect(Nucleus::ArchiveExtractor).to receive(:new).once { extractor }
156
- # we assume format is supported
157
- expect(extractor).to receive(:supports?).with(kind_of(String)).once { true }
158
- # assumes number of extracted files
159
- expect(extractor).to receive(:extract).with(file, kind_of(String), zip) { 9 }
160
-
161
- # write files to disk, as the extractor would do
162
- repo_dir = File.join(Dir.tmpdir, repo_name)
163
- git_dir = File.join(repo_dir, '.git')
164
- other_dir = File.join(repo_dir, 'another_dir')
165
- FileUtils.mkdir_p(git_dir)
166
- FileUtils.mkdir_p(other_dir)
167
- FileUtils.touch(File.join(repo_dir, 'file_1.txt'))
168
- FileUtils.touch(File.join(other_dir, 'file_2.txt'))
169
- FileUtils.touch(File.join(git_dir, 'some_git_file.txt'))
170
-
171
- # make sure files actually exist
172
- expect(File.file?(File.join(repo_dir, 'file_1.txt'))).to eql(true)
173
- expect(File.file?(File.join(other_dir, 'file_2.txt'))).to eql(true)
174
- expect(File.file?(File.join(git_dir, 'some_git_file.txt'))).to eql(true)
175
- expect(File.directory?(git_dir)).to eql(true)
176
- expect(File.directory?(other_dir)).to eql(true)
177
-
178
- # expect(Find).to receive(:find).with(kind_of(String)).once
179
- expect(FileUtils).to receive(:rm_rf).with(other_dir).once.and_call_original
180
- expect(FileUtils).to receive(:rm_f).with(File.join(repo_dir, 'file_1.txt')).once.and_call_original
181
-
182
- sanitizer = double(Nucleus::ApplicationRepoSanitizer)
183
- expect(Nucleus::ApplicationRepoSanitizer).to receive(:new).once { sanitizer }
184
- # we assume format is supported
185
- expect(sanitizer).to receive(:sanitize).with(kind_of(String)).once
186
-
187
- # call should succeed
188
- subject.deploy(file, zip)
189
-
190
- # normal files should be deleted
191
- expect(File.exist?(File.join(repo_dir, 'file_1.txt'))).to eql(false)
192
- expect(File.exist?(File.join(other_dir, 'file_2.txt'))).to eql(false)
193
- expect(File.exist?(other_dir)).to eql(false)
194
-
195
- # whereas git files should still exist
196
- expect(File.exist?(File.join(git_dir, 'some_git_file.txt'))).to eql(true)
197
- expect(File.exist?(git_dir)).to eql(true)
198
- end
199
- end
200
-
201
- context 'with nucleus branch' do
202
- let(:repo_branch) { 'nucleus' }
203
- subject { Nucleus::Adapters::GitDeployer.new(repo_name, repo_url, user_email, repo_branch) }
204
- it 'succeeds' do
205
- expect(repo).to receive(:add).with(all: true).once
206
- expect(repo).to receive(:commit).with(kind_of(String)).once
207
- expect(repo).to receive(:repack).with(no_args).once
208
- expect(repo).to receive(:push).with(kind_of(String), repo_branch, force: true).once
209
-
210
- branch_mock = double(Git::Branch)
211
- expect(repo).to receive(:branch).with(repo_branch).once { branch_mock }
212
- expect(repo).to receive(:checkout).with(branch_mock).once { repo }
213
-
214
- extractor = double(Nucleus::ArchiveExtractor)
215
- expect(Nucleus::ArchiveExtractor).to receive(:new).once { extractor }
216
- # we assume format is supported
217
- expect(extractor).to receive(:supports?).with(kind_of(String)).once { true }
218
- # assumes number of extracted files
219
- expect(extractor).to receive(:extract).with(file, kind_of(String), zip) { 9 }
220
-
221
- # write files to disk, as the extractor would do
222
- repo_dir = File.join(Dir.tmpdir, repo_name)
223
- git_dir = File.join(repo_dir, '.git')
224
- other_dir = File.join(repo_dir, 'another_dir')
225
- FileUtils.mkdir_p(git_dir)
226
- FileUtils.mkdir_p(other_dir)
227
- FileUtils.touch(File.join(repo_dir, 'file_1.txt'))
228
- FileUtils.touch(File.join(other_dir, 'file_2.txt'))
229
- FileUtils.touch(File.join(git_dir, 'some_git_file.txt'))
230
-
231
- # make sure files actually exist
232
- expect(File.file?(File.join(repo_dir, 'file_1.txt'))).to eql(true)
233
- expect(File.file?(File.join(other_dir, 'file_2.txt'))).to eql(true)
234
- expect(File.file?(File.join(git_dir, 'some_git_file.txt'))).to eql(true)
235
- expect(File.directory?(git_dir)).to eql(true)
236
- expect(File.directory?(other_dir)).to eql(true)
237
-
238
- # expect(Find).to receive(:find).with(kind_of(String)).once
239
- expect(FileUtils).to receive(:rm_rf).with(other_dir).once.and_call_original
240
- expect(FileUtils).to receive(:rm_f).with(File.join(repo_dir, 'file_1.txt')).once.and_call_original
241
-
242
- sanitizer = double(Nucleus::ApplicationRepoSanitizer)
243
- expect(Nucleus::ApplicationRepoSanitizer).to receive(:new).once { sanitizer }
244
- # we assume format is supported
245
- expect(sanitizer).to receive(:sanitize).with(kind_of(String)).once
246
-
247
- # call should succeed
248
- subject.deploy(file, zip)
249
-
250
- # normal files should be deleted
251
- expect(File.exist?(File.join(repo_dir, 'file_1.txt'))).to eql(false)
252
- expect(File.exist?(File.join(other_dir, 'file_2.txt'))).to eql(false)
253
- expect(File.exist?(other_dir)).to eql(false)
254
-
255
- # whereas git files should still exist
256
- expect(File.exist?(File.join(git_dir, 'some_git_file.txt'))).to eql(true)
257
- expect(File.exist?(git_dir)).to eql(true)
258
- end
259
- end
260
- end
261
- end
262
- end
1
+ require 'spec/unit/unit_spec_helper'
2
+
3
+ describe Nucleus::Adapters::GitDeployer do
4
+ let(:repo_name) { 'my_repository' }
5
+ let(:repo_url) { 'http://repo.example.org' }
6
+ let(:user_email) { 'myuser@example.org' }
7
+ let(:repo) { double(Git::Base) }
8
+ let(:zip) { 'zip' }
9
+ let(:file) { File.join('random', 'file', 'path') }
10
+
11
+ it '#deploy fails early with invalid format' do
12
+ subject = Nucleus::Adapters::GitDeployer.new(repo_name, repo_url, user_email)
13
+ extractor = double(Nucleus::ArchiveExtractor)
14
+ expect(Nucleus::ArchiveExtractor).to receive(:new).with(any_args).once { extractor }
15
+ # we assume format is supported
16
+ expect(extractor).to receive(:supports?).with(kind_of(String)).once { false }
17
+ # call should fail
18
+ expect { subject.deploy(nil, 'xyz') }.to raise_error(Nucleus::Errors::AdapterRequestError)
19
+ end
20
+
21
+ describe 'repository actions' do
22
+ before do
23
+ # every action needs to clone the repository
24
+ expect(Git).to receive(:clone).with(repo_url, repo_name, path: kind_of(String)).once { repo }
25
+ # verify cleanup is performed for each method call
26
+ expect(FileUtils).to receive(:rm_rf).with(File.join(Dir.tmpdir, repo_name)).once
27
+ end
28
+
29
+ describe '#download' do
30
+ let!(:exclude_git) { true }
31
+
32
+ context 'with master branch' do
33
+ subject { Nucleus::Adapters::GitDeployer.new(repo_name, repo_url, user_email) }
34
+ let(:repo_branch) { 'master' }
35
+ it 'returns archived repository' do
36
+ # verify archiver is called to return the response
37
+ archiver = double(Nucleus::Archiver)
38
+ expect(Nucleus::Archiver).to receive(:new).with(exclude_git) { archiver }
39
+ expect(archiver).to receive(:compress).with(kind_of(String), zip).once { 'response' }
40
+
41
+ # execute the call
42
+ response = subject.download(zip, exclude_git)
43
+ expect(response).to eql('response')
44
+ end
45
+ end
46
+
47
+ context 'with nucleus branch' do
48
+ let(:repo_branch) { 'nucleus' }
49
+ subject { Nucleus::Adapters::GitDeployer.new(repo_name, repo_url, user_email, repo_branch) }
50
+ it 'returns archived repository' do
51
+ branch_mock = double(Git::Branch)
52
+ expect(repo).to receive(:branch).with(repo_branch).once { branch_mock }
53
+ expect(repo).to receive(:checkout).with(branch_mock).once { repo }
54
+
55
+ # verify archiver is called to return the response
56
+ archiver = double(Nucleus::Archiver)
57
+ expect(Nucleus::Archiver).to receive(:new).with(exclude_git) { archiver }
58
+ expect(archiver).to receive(:compress).with(kind_of(String), zip).once { 'response' }
59
+
60
+ # execute the call
61
+ response = subject.download(zip, exclude_git)
62
+ expect(response).to eql('response')
63
+ end
64
+
65
+ it 'returns archived repository even if master did not contain any commit' do
66
+ # branch fails for master without commits
67
+ expect(repo).to receive(:branch).with(repo_branch).once { raise StandardError, 'No commit for master' }
68
+ # then we rely on the fallback, checkout new branch
69
+ expect(repo).to receive(:checkout).with(repo_branch, new_branch: true).once { repo }
70
+
71
+ # verify archiver is called to return the response
72
+ archiver = double(Nucleus::Archiver)
73
+ expect(Nucleus::Archiver).to receive(:new).with(exclude_git) { archiver }
74
+ expect(archiver).to receive(:compress).with(kind_of(String), zip).once { 'response' }
75
+
76
+ # execute the call
77
+ response = subject.download(zip, exclude_git)
78
+ expect(response).to eql('response')
79
+ end
80
+ end
81
+ end
82
+
83
+ describe '#trigger_build' do
84
+ # set username and email
85
+ before { expect(repo).to receive(:config).with(kind_of(String), kind_of(String)).twice }
86
+
87
+ it 'succeeds for master branch' do
88
+ subject = Nucleus::Adapters::GitDeployer.new(repo_name, repo_url, user_email)
89
+ expect(repo).to receive(:add).with(all: true).once
90
+ expect(repo).to receive(:commit).with(kind_of(String)).once
91
+ expect(repo).to receive(:repack).with(no_args).once
92
+ expect(repo).to receive(:push).with(kind_of(String), 'master', force: true).once
93
+
94
+ # there shall be the attempt to write a file to the repository
95
+ expect(Nucleus::Adapters::FileManager).to receive(:save_file_from_data).with(any_args).once
96
+ # trigger the method
97
+ subject.trigger_build
98
+ end
99
+
100
+ it 'succeeds for nucleus branch' do
101
+ subject = Nucleus::Adapters::GitDeployer.new(repo_name, repo_url, user_email, 'nucleus')
102
+ expect(repo).to receive(:add).with(all: true).once
103
+ expect(repo).to receive(:commit).with(kind_of(String)).once
104
+ expect(repo).to receive(:repack).with(no_args).once
105
+ expect(repo).to receive(:push).with(kind_of(String), 'nucleus', force: true).once
106
+
107
+ branch_mock = double(Git::Branch)
108
+ expect(repo).to receive(:branch).with('nucleus').once { branch_mock }
109
+ expect(repo).to receive(:checkout).with(branch_mock).once { repo }
110
+
111
+ # there shall be the attempt to write a file to the repository
112
+ expect(Nucleus::Adapters::FileManager).to receive(:save_file_from_data)
113
+ # trigger the method
114
+ subject.trigger_build
115
+ end
116
+ end
117
+
118
+ describe '#deploy', memfs: true do
119
+ before { expect(repo).to receive(:config).with(kind_of(String), kind_of(String)).twice }
120
+ context 'with master branch' do
121
+ let(:repo_branch) { 'master' }
122
+ subject { Nucleus::Adapters::GitDeployer.new(repo_name, repo_url, user_email) }
123
+
124
+ describe 'fails' do
125
+ it 'if no files were extracted' do
126
+ extractor = double(Nucleus::ArchiveExtractor)
127
+ expect(Nucleus::ArchiveExtractor).to receive(:new).once { extractor }
128
+ # we assume format is supported
129
+ expect(extractor).to receive(:supports?).with(kind_of(String)).once { true }
130
+ # assumes number of extracted files
131
+ expect(extractor).to receive(:extract).with(file, kind_of(String), zip) { 0 }
132
+
133
+ # write files to disk, as the extractor would do
134
+ repo_dir = File.join(Dir.tmpdir, repo_name)
135
+ git_dir = File.join(repo_dir, '.git')
136
+ FileUtils.mkdir_p(git_dir)
137
+ FileUtils.touch(File.join(git_dir, 'some_git_file.txt'))
138
+
139
+ # make sure files actually exist
140
+ expect(File.file?(File.join(git_dir, 'some_git_file.txt'))).to eql(true)
141
+ expect(File.directory?(git_dir)).to eql(true)
142
+
143
+ # call should fail
144
+ expect { subject.deploy(file, zip) }.to raise_error(Nucleus::Errors::AdapterRequestError)
145
+ end
146
+ end
147
+
148
+ it 'succeeds' do
149
+ expect(repo).to receive(:add).with(all: true).once
150
+ expect(repo).to receive(:commit).with(kind_of(String)).once
151
+ expect(repo).to receive(:repack).with(no_args).once
152
+ expect(repo).to receive(:push).with(kind_of(String), repo_branch, force: true).once
153
+
154
+ extractor = double(Nucleus::ArchiveExtractor)
155
+ expect(Nucleus::ArchiveExtractor).to receive(:new).once { extractor }
156
+ # we assume format is supported
157
+ expect(extractor).to receive(:supports?).with(kind_of(String)).once { true }
158
+ # assumes number of extracted files
159
+ expect(extractor).to receive(:extract).with(file, kind_of(String), zip) { 9 }
160
+
161
+ # write files to disk, as the extractor would do
162
+ repo_dir = File.join(Dir.tmpdir, repo_name)
163
+ git_dir = File.join(repo_dir, '.git')
164
+ other_dir = File.join(repo_dir, 'another_dir')
165
+ FileUtils.mkdir_p(git_dir)
166
+ FileUtils.mkdir_p(other_dir)
167
+ FileUtils.touch(File.join(repo_dir, 'file_1.txt'))
168
+ FileUtils.touch(File.join(other_dir, 'file_2.txt'))
169
+ FileUtils.touch(File.join(git_dir, 'some_git_file.txt'))
170
+
171
+ # make sure files actually exist
172
+ expect(File.file?(File.join(repo_dir, 'file_1.txt'))).to eql(true)
173
+ expect(File.file?(File.join(other_dir, 'file_2.txt'))).to eql(true)
174
+ expect(File.file?(File.join(git_dir, 'some_git_file.txt'))).to eql(true)
175
+ expect(File.directory?(git_dir)).to eql(true)
176
+ expect(File.directory?(other_dir)).to eql(true)
177
+
178
+ # expect(Find).to receive(:find).with(kind_of(String)).once
179
+ expect(FileUtils).to receive(:rm_rf).with(other_dir).once.and_call_original
180
+ expect(FileUtils).to receive(:rm_f).with(File.join(repo_dir, 'file_1.txt')).once.and_call_original
181
+
182
+ sanitizer = double(Nucleus::ApplicationRepoSanitizer)
183
+ expect(Nucleus::ApplicationRepoSanitizer).to receive(:new).once { sanitizer }
184
+ # we assume format is supported
185
+ expect(sanitizer).to receive(:sanitize).with(kind_of(String)).once
186
+
187
+ # call should succeed
188
+ subject.deploy(file, zip)
189
+
190
+ # normal files should be deleted
191
+ expect(File.exist?(File.join(repo_dir, 'file_1.txt'))).to eql(false)
192
+ expect(File.exist?(File.join(other_dir, 'file_2.txt'))).to eql(false)
193
+ expect(File.exist?(other_dir)).to eql(false)
194
+
195
+ # whereas git files should still exist
196
+ expect(File.exist?(File.join(git_dir, 'some_git_file.txt'))).to eql(true)
197
+ expect(File.exist?(git_dir)).to eql(true)
198
+ end
199
+ end
200
+
201
+ context 'with nucleus branch' do
202
+ let(:repo_branch) { 'nucleus' }
203
+ subject { Nucleus::Adapters::GitDeployer.new(repo_name, repo_url, user_email, repo_branch) }
204
+ it 'succeeds' do
205
+ expect(repo).to receive(:add).with(all: true).once
206
+ expect(repo).to receive(:commit).with(kind_of(String)).once
207
+ expect(repo).to receive(:repack).with(no_args).once
208
+ expect(repo).to receive(:push).with(kind_of(String), repo_branch, force: true).once
209
+
210
+ branch_mock = double(Git::Branch)
211
+ expect(repo).to receive(:branch).with(repo_branch).once { branch_mock }
212
+ expect(repo).to receive(:checkout).with(branch_mock).once { repo }
213
+
214
+ extractor = double(Nucleus::ArchiveExtractor)
215
+ expect(Nucleus::ArchiveExtractor).to receive(:new).once { extractor }
216
+ # we assume format is supported
217
+ expect(extractor).to receive(:supports?).with(kind_of(String)).once { true }
218
+ # assumes number of extracted files
219
+ expect(extractor).to receive(:extract).with(file, kind_of(String), zip) { 9 }
220
+
221
+ # write files to disk, as the extractor would do
222
+ repo_dir = File.join(Dir.tmpdir, repo_name)
223
+ git_dir = File.join(repo_dir, '.git')
224
+ other_dir = File.join(repo_dir, 'another_dir')
225
+ FileUtils.mkdir_p(git_dir)
226
+ FileUtils.mkdir_p(other_dir)
227
+ FileUtils.touch(File.join(repo_dir, 'file_1.txt'))
228
+ FileUtils.touch(File.join(other_dir, 'file_2.txt'))
229
+ FileUtils.touch(File.join(git_dir, 'some_git_file.txt'))
230
+
231
+ # make sure files actually exist
232
+ expect(File.file?(File.join(repo_dir, 'file_1.txt'))).to eql(true)
233
+ expect(File.file?(File.join(other_dir, 'file_2.txt'))).to eql(true)
234
+ expect(File.file?(File.join(git_dir, 'some_git_file.txt'))).to eql(true)
235
+ expect(File.directory?(git_dir)).to eql(true)
236
+ expect(File.directory?(other_dir)).to eql(true)
237
+
238
+ # expect(Find).to receive(:find).with(kind_of(String)).once
239
+ expect(FileUtils).to receive(:rm_rf).with(other_dir).once.and_call_original
240
+ expect(FileUtils).to receive(:rm_f).with(File.join(repo_dir, 'file_1.txt')).once.and_call_original
241
+
242
+ sanitizer = double(Nucleus::ApplicationRepoSanitizer)
243
+ expect(Nucleus::ApplicationRepoSanitizer).to receive(:new).once { sanitizer }
244
+ # we assume format is supported
245
+ expect(sanitizer).to receive(:sanitize).with(kind_of(String)).once
246
+
247
+ # call should succeed
248
+ subject.deploy(file, zip)
249
+
250
+ # normal files should be deleted
251
+ expect(File.exist?(File.join(repo_dir, 'file_1.txt'))).to eql(false)
252
+ expect(File.exist?(File.join(other_dir, 'file_2.txt'))).to eql(false)
253
+ expect(File.exist?(other_dir)).to eql(false)
254
+
255
+ # whereas git files should still exist
256
+ expect(File.exist?(File.join(git_dir, 'some_git_file.txt'))).to eql(true)
257
+ expect(File.exist?(git_dir)).to eql(true)
258
+ end
259
+ end
260
+ end
261
+ end
262
+ end