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