nucleus 0.2.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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