nucleus 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -0
- data/CHANGELOG.md +18 -4
- data/README.md +28 -40
- data/Rakefile +137 -137
- data/config/nucleus_config.rb +0 -4
- data/lib/nucleus/adapter_resolver.rb +115 -115
- data/lib/nucleus/adapters/buildpack_translator.rb +79 -79
- data/lib/nucleus/adapters/v1/cloud_control/application.rb +108 -108
- data/lib/nucleus/adapters/v1/cloud_control/authentication.rb +27 -27
- data/lib/nucleus/adapters/v1/cloud_control/cloud_control.rb +153 -153
- data/lib/nucleus/adapters/v1/cloud_control/domains.rb +68 -68
- data/lib/nucleus/adapters/v1/cloud_control/logs.rb +103 -103
- data/lib/nucleus/adapters/v1/cloud_control/vars.rb +88 -88
- data/lib/nucleus/adapters/v1/cloud_foundry_v2/domains.rb +149 -149
- data/lib/nucleus/adapters/v1/cloud_foundry_v2/logs.rb +303 -303
- data/lib/nucleus/adapters/v1/cloud_foundry_v2/services.rb +286 -286
- data/lib/nucleus/adapters/v1/heroku/heroku.rb +2 -2
- data/lib/nucleus/adapters/v1/heroku/logs.rb +108 -108
- data/lib/nucleus/core/adapter_authentication_inductor.rb +0 -2
- data/lib/nucleus/core/adapter_extensions/auth/http_basic_auth_client.rb +37 -37
- data/lib/nucleus/core/adapter_extensions/http_client.rb +177 -177
- data/lib/nucleus/core/common/files/archive_extractor.rb +112 -112
- data/lib/nucleus/core/common/files/archiver.rb +91 -91
- data/lib/nucleus/core/common/logging/request_log_formatter.rb +48 -48
- data/lib/nucleus/core/error_messages.rb +127 -127
- data/lib/nucleus/core/models/abstract_model.rb +29 -29
- data/lib/nucleus/scripts/load_dependencies.rb +0 -1
- data/lib/nucleus/scripts/setup_config.rb +28 -28
- data/lib/nucleus/version.rb +3 -3
- data/nucleus.gemspec +10 -12
- data/spec/factories/models.rb +63 -61
- data/spec/integration/api/auth_spec.rb +58 -58
- data/spec/test_suites.rake +31 -31
- data/spec/unit/common/helpers/auth_helper_spec.rb +73 -73
- data/spec/unit/common/oauth2_auth_client_spec.rb +1 -1
- data/tasks/compatibility.rake +113 -113
- data/tasks/evaluation.rake +162 -162
- metadata +16 -30
@@ -1,58 +1,58 @@
|
|
1
|
-
require 'spec/integration/integration_spec_helper'
|
2
|
-
|
3
|
-
describe Nucleus::API::V1::Auth do
|
4
|
-
after { Nucleus::TestDataGenerator.clean }
|
5
|
-
|
6
|
-
let!(:vendor_a) { create(:vendor) }
|
7
|
-
let!(:vendor_b) { create(:vendor) }
|
8
|
-
let!(:provider_a) { create(:provider, vendor: vendor_a.id) }
|
9
|
-
let!(:provider_b) { create(:provider, vendor: vendor_b.id) }
|
10
|
-
let!(:endpoint_a) { create(:endpoint, provider: provider_a.id) }
|
11
|
-
let!(:endpoint_b) { create(:endpoint, provider: provider_b.id) }
|
12
|
-
let!(:adapter_a) { create(:adapter, id: endpoint_a.id, adapter_clazz: Nucleus::Adapters::V1::Heroku) }
|
13
|
-
let!(:adapter_b) { create(:adapter, id: endpoint_b.id, adapter_clazz: Nucleus::Adapters::V1::CloudFoundryV2) }
|
14
|
-
|
15
|
-
# tests case when 'use RequestStore::Middleware' was not applied
|
16
|
-
context 'With alternating endpoint requests' do
|
17
|
-
before do
|
18
|
-
allow_any_instance_of(Nucleus::Adapters::V1::Heroku).to receive(:auth_client) do
|
19
|
-
token_auth = double(Nucleus::Adapters::TokenAuthClient)
|
20
|
-
allow(token_auth).to receive(:authenticate) { token_auth }
|
21
|
-
allow(token_auth).to receive(:auth_header) { { 'Authorization' => 'bearer 1234567890' } }
|
22
|
-
token_auth
|
23
|
-
end
|
24
|
-
allow_any_instance_of(Nucleus::Adapters::V1::CloudFoundryV2).to receive(:auth_client) do
|
25
|
-
oauth = double(Nucleus::Adapters::OAuth2AuthClient)
|
26
|
-
allow(oauth).to receive(:authenticate) { oauth }
|
27
|
-
allow(oauth).to receive(:auth_header) { { 'Authorization' => 'bearer 0987654321' } }
|
28
|
-
allow(oauth).to receive(:refresh) { oauth }
|
29
|
-
oauth
|
30
|
-
end
|
31
|
-
|
32
|
-
allow_any_instance_of(Nucleus::Adapters::V1::Heroku).to receive(:applications).and_wrap_original do |m, _|
|
33
|
-
unless m.receiver.send(:headers)['Authorization'] == 'bearer 1234567890'
|
34
|
-
fail Nucleus::Errors::EndpointAuthenticationError, 'Bad authentication credentials'
|
35
|
-
end
|
36
|
-
[]
|
37
|
-
end
|
38
|
-
call_count = 0
|
39
|
-
allow_any_instance_of(Nucleus::Adapters::V1::CloudFoundryV2).to receive(:applications).and_wrap_original do |m, _|
|
40
|
-
unless m.receiver.send(:headers)['Authorization'] == 'bearer 0987654321'
|
41
|
-
fail Nucleus::Errors::EndpointAuthenticationError, 'Bad authentication credentials'
|
42
|
-
end
|
43
|
-
call_count += 1
|
44
|
-
fail Nucleus::Errors::EndpointAuthenticationError, 'Fail 1st attempt' if call_count == 1
|
45
|
-
[]
|
46
|
-
end
|
47
|
-
end
|
48
|
-
it 'credentials are not re-used for different requests' do
|
49
|
-
headers_a = { 'HTTP_AUTHORIZATION' => 'Basic ' + ['username_a:password_a'].pack('m*').
|
50
|
-
get "/endpoints/#{endpoint_a.id}/applications", headers_a
|
51
|
-
expect(response.status).to eq(200)
|
52
|
-
|
53
|
-
headers_b = { 'HTTP_AUTHORIZATION' => 'Basic ' + ['username_b:password_b'].pack('m*').
|
54
|
-
get "/endpoints/#{endpoint_b.id}/applications", headers_b
|
55
|
-
expect(response.status).to eq(200)
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
1
|
+
require 'spec/integration/integration_spec_helper'
|
2
|
+
|
3
|
+
describe Nucleus::API::V1::Auth do
|
4
|
+
after { Nucleus::TestDataGenerator.clean }
|
5
|
+
|
6
|
+
let!(:vendor_a) { create(:vendor) }
|
7
|
+
let!(:vendor_b) { create(:vendor) }
|
8
|
+
let!(:provider_a) { create(:provider, vendor: vendor_a.id) }
|
9
|
+
let!(:provider_b) { create(:provider, vendor: vendor_b.id) }
|
10
|
+
let!(:endpoint_a) { create(:endpoint, provider: provider_a.id) }
|
11
|
+
let!(:endpoint_b) { create(:endpoint, provider: provider_b.id) }
|
12
|
+
let!(:adapter_a) { create(:adapter, id: endpoint_a.id, adapter_clazz: Nucleus::Adapters::V1::Heroku) }
|
13
|
+
let!(:adapter_b) { create(:adapter, id: endpoint_b.id, adapter_clazz: Nucleus::Adapters::V1::CloudFoundryV2) }
|
14
|
+
|
15
|
+
# tests case when 'use RequestStore::Middleware' was not applied
|
16
|
+
context 'With alternating endpoint requests' do
|
17
|
+
before do
|
18
|
+
allow_any_instance_of(Nucleus::Adapters::V1::Heroku).to receive(:auth_client) do
|
19
|
+
token_auth = double(Nucleus::Adapters::TokenAuthClient)
|
20
|
+
allow(token_auth).to receive(:authenticate) { token_auth }
|
21
|
+
allow(token_auth).to receive(:auth_header) { { 'Authorization' => 'bearer 1234567890' } }
|
22
|
+
token_auth
|
23
|
+
end
|
24
|
+
allow_any_instance_of(Nucleus::Adapters::V1::CloudFoundryV2).to receive(:auth_client) do
|
25
|
+
oauth = double(Nucleus::Adapters::OAuth2AuthClient)
|
26
|
+
allow(oauth).to receive(:authenticate) { oauth }
|
27
|
+
allow(oauth).to receive(:auth_header) { { 'Authorization' => 'bearer 0987654321' } }
|
28
|
+
allow(oauth).to receive(:refresh) { oauth }
|
29
|
+
oauth
|
30
|
+
end
|
31
|
+
|
32
|
+
allow_any_instance_of(Nucleus::Adapters::V1::Heroku).to receive(:applications).and_wrap_original do |m, _|
|
33
|
+
unless m.receiver.send(:headers)['Authorization'] == 'bearer 1234567890'
|
34
|
+
fail Nucleus::Errors::EndpointAuthenticationError, 'Bad authentication credentials'
|
35
|
+
end
|
36
|
+
[]
|
37
|
+
end
|
38
|
+
call_count = 0
|
39
|
+
allow_any_instance_of(Nucleus::Adapters::V1::CloudFoundryV2).to receive(:applications).and_wrap_original do |m, _|
|
40
|
+
unless m.receiver.send(:headers)['Authorization'] == 'bearer 0987654321'
|
41
|
+
fail Nucleus::Errors::EndpointAuthenticationError, 'Bad authentication credentials'
|
42
|
+
end
|
43
|
+
call_count += 1
|
44
|
+
fail Nucleus::Errors::EndpointAuthenticationError, 'Fail 1st attempt' if call_count == 1
|
45
|
+
[]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
it 'credentials are not re-used for different requests' do
|
49
|
+
headers_a = { 'HTTP_AUTHORIZATION' => 'Basic ' + ['username_a:password_a'].pack('m*').delete("\n") }
|
50
|
+
get "/endpoints/#{endpoint_a.id}/applications", headers_a
|
51
|
+
expect(response.status).to eq(200)
|
52
|
+
|
53
|
+
headers_b = { 'HTTP_AUTHORIZATION' => 'Basic ' + ['username_b:password_b'].pack('m*').delete("\n") }
|
54
|
+
get "/endpoints/#{endpoint_b.id}/applications", headers_b
|
55
|
+
expect(response.status).to eq(200)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/spec/test_suites.rake
CHANGED
@@ -1,31 +1,31 @@
|
|
1
|
-
require 'rspec/core/rake_task'
|
2
|
-
|
3
|
-
SPEC_SUITES = [
|
4
|
-
{ id: :unit, title: 'unit tests', pattern: 'spec/unit/**/*_spec.rb' },
|
5
|
-
{ id: :adapters, title: 'adapter tests', pattern: 'spec/adapter/**/*_spec.rb' },
|
6
|
-
{ id: :integration, title: 'integration tests', pattern: 'spec/integration/**/*_spec.rb' }
|
7
|
-
]
|
8
|
-
|
9
|
-
namespace :spec do
|
10
|
-
namespace :suite do
|
11
|
-
SPEC_SUITES.each do |suite|
|
12
|
-
desc "Run all specs in #{suite[:title]} spec suite"
|
13
|
-
RSpec::Core::RakeTask.new(suite[:id]) do |t|
|
14
|
-
t.pattern = suite[:pattern]
|
15
|
-
t.verbose = false
|
16
|
-
t.fail_on_error = false
|
17
|
-
end
|
18
|
-
end
|
19
|
-
desc 'Run all spec suites'
|
20
|
-
task :all do
|
21
|
-
require 'English'
|
22
|
-
failed = []
|
23
|
-
SPEC_SUITES.each do |suite|
|
24
|
-
p "Running spec suite #{suite[:id]} ..."
|
25
|
-
Rake::Task["spec:suite:#{suite[:id]}"].execute
|
26
|
-
failed << suite[:id] unless $CHILD_STATUS.success?
|
27
|
-
end
|
28
|
-
fail "Spec suite#{failed.length > 1 ? 's' : ''} '#{failed.join(', ')}' failed" unless failed.empty?
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
1
|
+
require 'rspec/core/rake_task'
|
2
|
+
|
3
|
+
SPEC_SUITES = [
|
4
|
+
{ id: :unit, title: 'unit tests', pattern: 'spec/unit/**/*_spec.rb' },
|
5
|
+
{ id: :adapters, title: 'adapter tests', pattern: 'spec/adapter/**/*_spec.rb' },
|
6
|
+
{ id: :integration, title: 'integration tests', pattern: 'spec/integration/**/*_spec.rb' }
|
7
|
+
].freeze
|
8
|
+
|
9
|
+
namespace :spec do
|
10
|
+
namespace :suite do
|
11
|
+
SPEC_SUITES.each do |suite|
|
12
|
+
desc "Run all specs in #{suite[:title]} spec suite"
|
13
|
+
RSpec::Core::RakeTask.new(suite[:id]) do |t|
|
14
|
+
t.pattern = suite[:pattern]
|
15
|
+
t.verbose = false
|
16
|
+
t.fail_on_error = false
|
17
|
+
end
|
18
|
+
end
|
19
|
+
desc 'Run all spec suites'
|
20
|
+
task :all do
|
21
|
+
require 'English'
|
22
|
+
failed = []
|
23
|
+
SPEC_SUITES.each do |suite|
|
24
|
+
p "Running spec suite #{suite[:id]} ..."
|
25
|
+
Rake::Task["spec:suite:#{suite[:id]}"].execute
|
26
|
+
failed << suite[:id] unless $CHILD_STATUS.success?
|
27
|
+
end
|
28
|
+
fail "Spec suite#{failed.length > 1 ? 's' : ''} '#{failed.join(', ')}' failed" unless failed.empty?
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -1,73 +1,73 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Nucleus::Adapters::AuthenticationRetryWrapper do
|
4
|
-
let!(:adapter) { double('adapter') }
|
5
|
-
let!(:auth_client) { double('auth_client') }
|
6
|
-
let!(:calculator) { double('calculator') }
|
7
|
-
let!(:user) { 'my fictionary user' }
|
8
|
-
let!(:pass) { 'my fictionary password' }
|
9
|
-
let!(:fake_env) { { 'HTTP_AUTHORIZATION' => 'Basic ' + ["#{user}:#{pass}"].pack('m*').
|
10
|
-
before do
|
11
|
-
cache_key = 'a unique cache key!'
|
12
|
-
cache_dao = double(Nucleus::API::DB::CacheDao)
|
13
|
-
allow(cache_dao).to receive(:get) do |key|
|
14
|
-
key.end_with?('adapter') ? adapter : cache_key
|
15
|
-
end
|
16
|
-
RequestStore.store[:cache_key] = cache_key
|
17
|
-
allow(adapter).to receive(:cache)
|
18
|
-
allow(adapter).to receive(:cache_key)
|
19
|
-
allow(adapter).to receive(:cached) { auth_client }
|
20
|
-
end
|
21
|
-
|
22
|
-
describe '#with_authentication' do
|
23
|
-
context 'when cache is outdated' do
|
24
|
-
before do
|
25
|
-
counted = 0
|
26
|
-
expect = 1
|
27
|
-
allow(calculator).to receive(:calc) do
|
28
|
-
fail(Nucleus::Errors::EndpointAuthenticationError.new('error', auth_client)) if (counted += 1) <= expect
|
29
|
-
1
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
context 'and refresh was ok' do
|
34
|
-
it 'response is returned in repeated call' do
|
35
|
-
expect(auth_client).to receive(:refresh).once
|
36
|
-
expect(calculator).to receive(:calc).exactly(2).times
|
37
|
-
Nucleus::Adapters::AuthenticationRetryWrapper.with_authentication(adapter, fake_env) { calculator.calc }
|
38
|
-
end
|
39
|
-
end
|
40
|
-
context 'and refresh failed' do
|
41
|
-
before do
|
42
|
-
allow(auth_client).to receive(:refresh).and_raise(
|
43
|
-
Nucleus::Errors::EndpointAuthenticationError.new('error', auth_client))
|
44
|
-
end
|
45
|
-
context 'but authentication succeeded' do
|
46
|
-
before { allow(adapter).to receive(:authenticate) { 'authentication result' } }
|
47
|
-
it 'response is returned in repeated call after the authentication' do
|
48
|
-
expect(auth_client).to receive(:authenticate).once
|
49
|
-
expect(calculator).to receive(:calc).exactly(2).times
|
50
|
-
Nucleus::Adapters::AuthenticationRetryWrapper.with_authentication(adapter, fake_env) { calculator.calc }
|
51
|
-
end
|
52
|
-
end
|
53
|
-
context 'and authentication failed' do
|
54
|
-
it 'finally fails' do
|
55
|
-
expect(auth_client).to receive(:authenticate).once.and_raise(Nucleus::Errors::EndpointAuthenticationError,
|
56
|
-
'error')
|
57
|
-
expect(calculator).to receive(:calc).exactly(1).times
|
58
|
-
expect do
|
59
|
-
Nucleus::Adapters::AuthenticationRetryWrapper.with_authentication(adapter, fake_env) { calculator.calc }
|
60
|
-
end.to raise_error(Nucleus::Errors::EndpointAuthenticationError)
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
describe '#re_authenticate' do
|
68
|
-
it 'calls authentication on the adapter' do
|
69
|
-
expect(auth_client).to receive(:authenticate).once.with(user, pass)
|
70
|
-
Nucleus::Adapters::AuthenticationRetryWrapper.re_authenticate(adapter, fake_env)
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Nucleus::Adapters::AuthenticationRetryWrapper do
|
4
|
+
let!(:adapter) { double('adapter') }
|
5
|
+
let!(:auth_client) { double('auth_client') }
|
6
|
+
let!(:calculator) { double('calculator') }
|
7
|
+
let!(:user) { 'my fictionary user' }
|
8
|
+
let!(:pass) { 'my fictionary password' }
|
9
|
+
let!(:fake_env) { { 'HTTP_AUTHORIZATION' => 'Basic ' + ["#{user}:#{pass}"].pack('m*').delete("\n") } }
|
10
|
+
before do
|
11
|
+
cache_key = 'a unique cache key!'
|
12
|
+
cache_dao = double(Nucleus::API::DB::CacheDao)
|
13
|
+
allow(cache_dao).to receive(:get) do |key|
|
14
|
+
key.end_with?('adapter') ? adapter : cache_key
|
15
|
+
end
|
16
|
+
RequestStore.store[:cache_key] = cache_key
|
17
|
+
allow(adapter).to receive(:cache)
|
18
|
+
allow(adapter).to receive(:cache_key)
|
19
|
+
allow(adapter).to receive(:cached) { auth_client }
|
20
|
+
end
|
21
|
+
|
22
|
+
describe '#with_authentication' do
|
23
|
+
context 'when cache is outdated' do
|
24
|
+
before do
|
25
|
+
counted = 0
|
26
|
+
expect = 1
|
27
|
+
allow(calculator).to receive(:calc) do
|
28
|
+
fail(Nucleus::Errors::EndpointAuthenticationError.new('error', auth_client)) if (counted += 1) <= expect
|
29
|
+
1
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'and refresh was ok' do
|
34
|
+
it 'response is returned in repeated call' do
|
35
|
+
expect(auth_client).to receive(:refresh).once
|
36
|
+
expect(calculator).to receive(:calc).exactly(2).times
|
37
|
+
Nucleus::Adapters::AuthenticationRetryWrapper.with_authentication(adapter, fake_env) { calculator.calc }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
context 'and refresh failed' do
|
41
|
+
before do
|
42
|
+
allow(auth_client).to receive(:refresh).and_raise(
|
43
|
+
Nucleus::Errors::EndpointAuthenticationError.new('error', auth_client))
|
44
|
+
end
|
45
|
+
context 'but authentication succeeded' do
|
46
|
+
before { allow(adapter).to receive(:authenticate) { 'authentication result' } }
|
47
|
+
it 'response is returned in repeated call after the authentication' do
|
48
|
+
expect(auth_client).to receive(:authenticate).once
|
49
|
+
expect(calculator).to receive(:calc).exactly(2).times
|
50
|
+
Nucleus::Adapters::AuthenticationRetryWrapper.with_authentication(adapter, fake_env) { calculator.calc }
|
51
|
+
end
|
52
|
+
end
|
53
|
+
context 'and authentication failed' do
|
54
|
+
it 'finally fails' do
|
55
|
+
expect(auth_client).to receive(:authenticate).once.and_raise(Nucleus::Errors::EndpointAuthenticationError,
|
56
|
+
'error')
|
57
|
+
expect(calculator).to receive(:calc).exactly(1).times
|
58
|
+
expect do
|
59
|
+
Nucleus::Adapters::AuthenticationRetryWrapper.with_authentication(adapter, fake_env) { calculator.calc }
|
60
|
+
end.to raise_error(Nucleus::Errors::EndpointAuthenticationError)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe '#re_authenticate' do
|
68
|
+
it 'calls authentication on the adapter' do
|
69
|
+
expect(auth_client).to receive(:authenticate).once.with(user, pass)
|
70
|
+
Nucleus::Adapters::AuthenticationRetryWrapper.re_authenticate(adapter, fake_env)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -6,7 +6,7 @@ describe Nucleus::Adapters::OAuth2AuthClient do
|
|
6
6
|
url = 'theurl'
|
7
7
|
check_certs = false
|
8
8
|
client = Nucleus::Adapters::OAuth2AuthClient.new url, check_certs
|
9
|
-
expect(client.instance_variable_get
|
9
|
+
expect(client.instance_variable_get(:@auth_url)).to be url
|
10
10
|
expect(client.verify_ssl).to be check_certs
|
11
11
|
end
|
12
12
|
end
|
data/tasks/compatibility.rake
CHANGED
@@ -1,113 +1,113 @@
|
|
1
|
-
require 'rspec/core/rake_task'
|
2
|
-
|
3
|
-
namespace :evaluation do
|
4
|
-
namespace :compatibility do
|
5
|
-
task load: :environment do
|
6
|
-
# TODO: choose API version
|
7
|
-
api_version = 'v1'
|
8
|
-
stub = Nucleus::Adapters.const_get(api_version.upcase).const_get('Stub').new 'https://api.example.org'
|
9
|
-
|
10
|
-
adapter_dao = Nucleus::API::DB::AdapterDao.instance(api_version)
|
11
|
-
endpoint_dao = Nucleus::API::DB::EndpointDao.instance(api_version)
|
12
|
-
provider_dao = Nucleus::API::DB::ProviderDao.instance(api_version)
|
13
|
-
vendor_dao = Nucleus::API::DB::VendorDao.instance(api_version)
|
14
|
-
@vendor_results = {}
|
15
|
-
|
16
|
-
adapter_dao.all.each do |adapter_index_entry|
|
17
|
-
vendor_name = vendor_dao.get(provider_dao.get(endpoint_dao.get(adapter_index_entry.id).provider).vendor).name
|
18
|
-
next if @vendor_results.key?(vendor_name)
|
19
|
-
adapter_results = {}
|
20
|
-
adapter = adapter_index_entry.adapter_clazz.new('https://api.example.org', 'http://apps.example.org', true)
|
21
|
-
stub.public_methods(false).each do |method_name|
|
22
|
-
args = []
|
23
|
-
method = stub.method(method_name)
|
24
|
-
method.arity.times { |time| args.push(time) }
|
25
|
-
begin
|
26
|
-
adapter.send(method_name, *args)
|
27
|
-
implemented = true
|
28
|
-
rescue Nucleus::Errors::AdapterMissingImplementationError
|
29
|
-
implemented = false
|
30
|
-
rescue StandardError
|
31
|
-
implemented = true
|
32
|
-
end
|
33
|
-
adapter_results[method_name] = implemented
|
34
|
-
end
|
35
|
-
@vendor_results[vendor_name] = adapter_results
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
task markdown: :load do
|
40
|
-
# table header
|
41
|
-
puts "Method / Vendor|#{@vendor_results.keys.join('|')}"
|
42
|
-
|
43
|
-
# column styles
|
44
|
-
alignment = ':--'
|
45
|
-
@vendor_results.length.times { |_time| alignment << '|:-:' }
|
46
|
-
puts alignment
|
47
|
-
|
48
|
-
lines = []
|
49
|
-
@vendor_results.each do |_vendor, results|
|
50
|
-
results.each_with_index do |(method, supported), line|
|
51
|
-
lines[line] =
|
52
|
-
lines[line] << "|#{supported ? '✓' : '✗'}"
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
lines.each do |line|
|
57
|
-
puts line
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
task :latex, [:save_to] => :load do |_t, args|
|
62
|
-
all_lines = []
|
63
|
-
all_lines << "\\begin{longtable}{|L{7cm}|#{'c|' * @vendor_results.length}}"
|
64
|
-
next_line = ' \\multicolumn{1}{l}{\\Large{\\textbf{Adapter compatibility}}}'
|
65
|
-
@vendor_results.keys.each do |vendor|
|
66
|
-
next_line += " & \\multicolumn{1}{l}{\\turn{60}{#{vendor}}}"
|
67
|
-
end
|
68
|
-
next_line += ' \\\\\\hline'
|
69
|
-
all_lines << next_line
|
70
|
-
all_lines << ' \\endhead'
|
71
|
-
all_lines << ' \\rowcolor{white}'
|
72
|
-
all_lines << ' \\caption{List of methods that are supported by Nucleus per vendor}'\
|
73
|
-
'\\label{table:evaluation_adapter_compatibility}%'
|
74
|
-
all_lines << ' \\endlastfoot'
|
75
|
-
|
76
|
-
lines = []
|
77
|
-
@vendor_results.each do |_vendor, results|
|
78
|
-
results.each_with_index do |(method, supported), line|
|
79
|
-
lines[line] =
|
80
|
-
lines[line] << " & #{supported ? '\\ding{51}' : '\\cellcolor{failedtablebg}\\ding{55}'}"
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
# format and print all lines
|
85
|
-
lines.each_with_index do |line, index|
|
86
|
-
if index != lines.length - 1
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
end
|
93
|
-
|
94
|
-
# print general statistics
|
95
|
-
total_methods = @vendor_results.collect { |_v, tests| tests.length }.uniq.first
|
96
|
-
supported_count = @vendor_results.collect { |_v, tests| tests.find_all { |_m, s| s }.length }
|
97
|
-
all_lines << " Supported methods & #{supported_count.join(' & ')} \\\\\\hline"
|
98
|
-
to_print = supported_count.collect do |supported|
|
99
|
-
"#{format('%g', format('%.1f', (supported / total_methods.to_f * 100)))} \\%"
|
100
|
-
end
|
101
|
-
|
102
|
-
all_lines << " Supported degree & #{to_print.join(' & ')} \\\\\\hline"
|
103
|
-
|
104
|
-
all_lines << '\\end{longtable}'
|
105
|
-
|
106
|
-
# print lines
|
107
|
-
all_lines.each { |line| puts line }
|
108
|
-
|
109
|
-
# and save to file if requested
|
110
|
-
File.open(args.save_to, 'w') { |file| file.write all_lines.join("\n") } if args.save_to
|
111
|
-
end
|
112
|
-
end
|
113
|
-
end
|
1
|
+
require 'rspec/core/rake_task'
|
2
|
+
|
3
|
+
namespace :evaluation do
|
4
|
+
namespace :compatibility do
|
5
|
+
task load: :environment do
|
6
|
+
# TODO: choose API version
|
7
|
+
api_version = 'v1'
|
8
|
+
stub = Nucleus::Adapters.const_get(api_version.upcase).const_get('Stub').new 'https://api.example.org'
|
9
|
+
|
10
|
+
adapter_dao = Nucleus::API::DB::AdapterDao.instance(api_version)
|
11
|
+
endpoint_dao = Nucleus::API::DB::EndpointDao.instance(api_version)
|
12
|
+
provider_dao = Nucleus::API::DB::ProviderDao.instance(api_version)
|
13
|
+
vendor_dao = Nucleus::API::DB::VendorDao.instance(api_version)
|
14
|
+
@vendor_results = {}
|
15
|
+
|
16
|
+
adapter_dao.all.each do |adapter_index_entry|
|
17
|
+
vendor_name = vendor_dao.get(provider_dao.get(endpoint_dao.get(adapter_index_entry.id).provider).vendor).name
|
18
|
+
next if @vendor_results.key?(vendor_name)
|
19
|
+
adapter_results = {}
|
20
|
+
adapter = adapter_index_entry.adapter_clazz.new('https://api.example.org', 'http://apps.example.org', true)
|
21
|
+
stub.public_methods(false).each do |method_name|
|
22
|
+
args = []
|
23
|
+
method = stub.method(method_name)
|
24
|
+
method.arity.times { |time| args.push(time) }
|
25
|
+
begin
|
26
|
+
adapter.send(method_name, *args)
|
27
|
+
implemented = true
|
28
|
+
rescue Nucleus::Errors::AdapterMissingImplementationError
|
29
|
+
implemented = false
|
30
|
+
rescue StandardError
|
31
|
+
implemented = true
|
32
|
+
end
|
33
|
+
adapter_results[method_name] = implemented
|
34
|
+
end
|
35
|
+
@vendor_results[vendor_name] = adapter_results
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
task markdown: :load do
|
40
|
+
# table header
|
41
|
+
puts "Method / Vendor|#{@vendor_results.keys.join('|')}"
|
42
|
+
|
43
|
+
# column styles
|
44
|
+
alignment = ':--'
|
45
|
+
@vendor_results.length.times { |_time| alignment << '|:-:' }
|
46
|
+
puts alignment
|
47
|
+
|
48
|
+
lines = []
|
49
|
+
@vendor_results.each do |_vendor, results|
|
50
|
+
results.each_with_index do |(method, supported), line|
|
51
|
+
lines[line] = method.to_s unless lines[line]
|
52
|
+
lines[line] << "|#{supported ? '✓' : '✗'}"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
lines.each do |line|
|
57
|
+
puts line
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
task :latex, [:save_to] => :load do |_t, args|
|
62
|
+
all_lines = []
|
63
|
+
all_lines << "\\begin{longtable}{|L{7cm}|#{'c|' * @vendor_results.length}}"
|
64
|
+
next_line = ' \\multicolumn{1}{l}{\\Large{\\textbf{Adapter compatibility}}}'
|
65
|
+
@vendor_results.keys.each do |vendor|
|
66
|
+
next_line += " & \\multicolumn{1}{l}{\\turn{60}{#{vendor}}}"
|
67
|
+
end
|
68
|
+
next_line += ' \\\\\\hline'
|
69
|
+
all_lines << next_line
|
70
|
+
all_lines << ' \\endhead'
|
71
|
+
all_lines << ' \\rowcolor{white}'
|
72
|
+
all_lines << ' \\caption{List of methods that are supported by Nucleus per vendor}'\
|
73
|
+
'\\label{table:evaluation_adapter_compatibility}%'
|
74
|
+
all_lines << ' \\endlastfoot'
|
75
|
+
|
76
|
+
lines = []
|
77
|
+
@vendor_results.each do |_vendor, results|
|
78
|
+
results.each_with_index do |(method, supported), line|
|
79
|
+
lines[line] = method.to_s unless lines[line]
|
80
|
+
lines[line] << " & #{supported ? '\\ding{51}' : '\\cellcolor{failedtablebg}\\ding{55}'}"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# format and print all lines
|
85
|
+
lines.each_with_index do |line, index|
|
86
|
+
all_lines << if index != lines.length - 1
|
87
|
+
" #{line.gsub(/_/, '\_')} \\\\\\hline"
|
88
|
+
else
|
89
|
+
# special treatment for the last line
|
90
|
+
" #{line.gsub(/_/, '\_')} \\\\\\hhline{|=|#{'=|' * @vendor_results.length}}"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# print general statistics
|
95
|
+
total_methods = @vendor_results.collect { |_v, tests| tests.length }.uniq.first
|
96
|
+
supported_count = @vendor_results.collect { |_v, tests| tests.find_all { |_m, s| s }.length }
|
97
|
+
all_lines << " Supported methods & #{supported_count.join(' & ')} \\\\\\hline"
|
98
|
+
to_print = supported_count.collect do |supported|
|
99
|
+
"#{format('%g', format('%.1f', (supported / total_methods.to_f * 100)))} \\%"
|
100
|
+
end
|
101
|
+
|
102
|
+
all_lines << " Supported degree & #{to_print.join(' & ')} \\\\\\hline"
|
103
|
+
|
104
|
+
all_lines << '\\end{longtable}'
|
105
|
+
|
106
|
+
# print lines
|
107
|
+
all_lines.each { |line| puts line }
|
108
|
+
|
109
|
+
# and save to file if requested
|
110
|
+
File.open(args.save_to, 'w') { |file| file.write all_lines.join("\n") } if args.save_to
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|