nucleus 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +3 -0
  3. data/CHANGELOG.md +18 -4
  4. data/README.md +28 -40
  5. data/Rakefile +137 -137
  6. data/config/nucleus_config.rb +0 -4
  7. data/lib/nucleus/adapter_resolver.rb +115 -115
  8. data/lib/nucleus/adapters/buildpack_translator.rb +79 -79
  9. data/lib/nucleus/adapters/v1/cloud_control/application.rb +108 -108
  10. data/lib/nucleus/adapters/v1/cloud_control/authentication.rb +27 -27
  11. data/lib/nucleus/adapters/v1/cloud_control/cloud_control.rb +153 -153
  12. data/lib/nucleus/adapters/v1/cloud_control/domains.rb +68 -68
  13. data/lib/nucleus/adapters/v1/cloud_control/logs.rb +103 -103
  14. data/lib/nucleus/adapters/v1/cloud_control/vars.rb +88 -88
  15. data/lib/nucleus/adapters/v1/cloud_foundry_v2/domains.rb +149 -149
  16. data/lib/nucleus/adapters/v1/cloud_foundry_v2/logs.rb +303 -303
  17. data/lib/nucleus/adapters/v1/cloud_foundry_v2/services.rb +286 -286
  18. data/lib/nucleus/adapters/v1/heroku/heroku.rb +2 -2
  19. data/lib/nucleus/adapters/v1/heroku/logs.rb +108 -108
  20. data/lib/nucleus/core/adapter_authentication_inductor.rb +0 -2
  21. data/lib/nucleus/core/adapter_extensions/auth/http_basic_auth_client.rb +37 -37
  22. data/lib/nucleus/core/adapter_extensions/http_client.rb +177 -177
  23. data/lib/nucleus/core/common/files/archive_extractor.rb +112 -112
  24. data/lib/nucleus/core/common/files/archiver.rb +91 -91
  25. data/lib/nucleus/core/common/logging/request_log_formatter.rb +48 -48
  26. data/lib/nucleus/core/error_messages.rb +127 -127
  27. data/lib/nucleus/core/models/abstract_model.rb +29 -29
  28. data/lib/nucleus/scripts/load_dependencies.rb +0 -1
  29. data/lib/nucleus/scripts/setup_config.rb +28 -28
  30. data/lib/nucleus/version.rb +3 -3
  31. data/nucleus.gemspec +10 -12
  32. data/spec/factories/models.rb +63 -61
  33. data/spec/integration/api/auth_spec.rb +58 -58
  34. data/spec/test_suites.rake +31 -31
  35. data/spec/unit/common/helpers/auth_helper_spec.rb +73 -73
  36. data/spec/unit/common/oauth2_auth_client_spec.rb +1 -1
  37. data/tasks/compatibility.rake +113 -113
  38. data/tasks/evaluation.rake +162 -162
  39. 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*').gsub(/\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*').gsub(/\n/, '') }
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
@@ -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*').gsub(/\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
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 :@auth_url).to be url
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
@@ -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] = "#{method}" unless lines[line]
52
- lines[line] << "|#{supported ? '&#10003;' : '&#10007;'}"
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}" 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
- if index != lines.length - 1
87
- all_lines << " #{line.gsub(/_/, '\_')} \\\\\\hline"
88
- else
89
- # special treatment for the last line
90
- all_lines << " #{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
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 ? '&#10003;' : '&#10007;'}"
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