From d89872f850332736eb174f2b0ab28692fda6bf46 Mon Sep 17 00:00:00 2001 From: mo khan Date: Thu, 9 Jan 2020 11:26:40 +0000 Subject: Upgrade python from 3.5 to 3.8 --- spec/integration/python/pip_spec.rb | 47 +++++++++++++ spec/integration/ruby/bundler_spec.rb | 88 +++++++++++++++++++++++++ spec/license/management/report/v2_spec.rb | 51 -------------- spec/license/management/repository_spec.rb | 38 ----------- spec/spec_helper.rb | 12 ++++ spec/support/integration_test_helper.rb | 37 +++++++++++ spec/unit/license/management/report/v2_spec.rb | 51 ++++++++++++++ spec/unit/license/management/repository_spec.rb | 38 +++++++++++ 8 files changed, 273 insertions(+), 89 deletions(-) create mode 100644 spec/integration/python/pip_spec.rb create mode 100644 spec/integration/ruby/bundler_spec.rb delete mode 100644 spec/license/management/report/v2_spec.rb delete mode 100644 spec/license/management/repository_spec.rb create mode 100644 spec/support/integration_test_helper.rb create mode 100644 spec/unit/license/management/report/v2_spec.rb create mode 100644 spec/unit/license/management/repository_spec.rb (limited to 'spec') diff --git a/spec/integration/python/pip_spec.rb b/spec/integration/python/pip_spec.rb new file mode 100644 index 0000000..5ff5f60 --- /dev/null +++ b/spec/integration/python/pip_spec.rb @@ -0,0 +1,47 @@ +require 'spec_helper' + +RSpec.describe "pip" do + context "when a project depends on the latest version of pip" do + let(:requirements) { "sentry-sdk>=0.7.7" } + + it 'produces a valid report' do + runner.add_file('requirements.txt', requirements) + + report = runner.scan + + expect(report).not_to be_empty + expect(report[:version]).to start_with('2') + expect(report[:dependencies].map { |x| x[:name] }).to include("sentry-sdk") + expect(report[:dependencies].find { |x| x[:name] == 'sentry-sdk' }[:licenses]).to match_array(["BSD-4-Clause"]) + end + end + + context "when the project has a dependency that depends on a minimum of python 3.6" do + let(:requirements) do + [ + 'boto3', + 'aws-lambda-context>=1.0.0', + 'jsonschema>=3.0.0', + 'python-json-logger>=0.1.10', + 'sentry-sdk>=0.7.7', + 'https://s3-eu-west-1.amazonaws.com/new10-pypi/new10-logging-1.1.4.tar.gz', + 'ptvsd', + 'pylint', + 'flake8', + 'bandit', + 'pydocstyle' + ].join("\n") + end + + it 'produces a valid report' do + runner.add_file('requirements.txt', requirements) + + report = runner.scan + + expect(report).not_to be_empty + expect(report[:version]).to start_with('2') + expect(report[:licenses]).not_to be_empty + expect(report[:dependencies]).not_to be_empty + end + end +end diff --git a/spec/integration/ruby/bundler_spec.rb b/spec/integration/ruby/bundler_spec.rb new file mode 100644 index 0000000..179da2a --- /dev/null +++ b/spec/integration/ruby/bundler_spec.rb @@ -0,0 +1,88 @@ +require 'spec_helper' + +RSpec.describe "bundler" do + context "when the project depends on an older version of ruby specified in a `.ruby-version` file" do + it 'installs the required ruby and produces a valid report' do + runner.add_file('.ruby-version', 'ruby-2.4.9') + runner.add_file('Gemfile') do + <<~RAW +source 'https://rubygems.org' + +gem 'saml-kit' + RAW + end + + report = runner.scan + expect(report).not_to be_empty + expect(report[:licenses]).not_to be_empty + expect(report[:dependencies].map { |x| x[:name] }).to include("saml-kit") + end + end + + context "when a project depends on an older version of bundler" do + it 'produces a valid report' do + runner.add_file('Gemfile') do + <<~RAW +source 'https://rubygems.org' + +gem 'saml-kit' + RAW + end + runner.add_file('Gemfile.lock') do + <<~RAW +GEM + remote: https://rubygems.org/ + specs: + activemodel (6.0.2.1) + activesupport (= 6.0.2.1) + activesupport (6.0.2.1) + concurrent-ruby (~> 1.0, >= 1.0.2) + i18n (>= 0.7, < 2) + minitest (~> 5.1) + tzinfo (~> 1.1) + zeitwerk (~> 2.2) + builder (3.2.4) + concurrent-ruby (1.1.5) + i18n (1.7.1) + concurrent-ruby (~> 1.0) + mini_portile2 (2.4.0) + minitest (5.13.0) + net-hippie (0.2.7) + nokogiri (1.10.7) + mini_portile2 (~> 2.4.0) + saml-kit (1.1.0) + activemodel (>= 4.2.0) + net-hippie (~> 0.1) + xml-kit (>= 0.3.0, < 1.0.0) + thread_safe (0.3.6) + tilt (2.0.10) + tzinfo (1.2.6) + thread_safe (~> 0.1) + xml-kit (0.4.0) + activemodel (>= 4.2.0) + builder (~> 3.2) + nokogiri (~> 1.10) + tilt (>= 1.4.1) + xmldsig (~> 0.6) + xmldsig (0.6.6) + nokogiri (>= 1.6.8, < 2.0.0) + zeitwerk (2.2.2) + +PLATFORMS + ruby + +DEPENDENCIES + saml-kit + +BUNDLED WITH + 1.17.3 + RAW + end + + report = runner.scan + expect(report).not_to be_empty + expect(report[:licenses]).not_to be_empty + expect(report[:dependencies].map { |x| x[:name] }).to include("saml-kit") + end + end +end diff --git a/spec/license/management/report/v2_spec.rb b/spec/license/management/report/v2_spec.rb deleted file mode 100644 index 4da973c..0000000 --- a/spec/license/management/report/v2_spec.rb +++ /dev/null @@ -1,51 +0,0 @@ -RSpec.describe License::Management::Report::V2 do - describe "#to_h" do - { - 'AGPL-1.0' => 'AGPL-1.0', - 'AGPL-3.0' => 'AGPL-3.0', - 'Apache 2.0' => 'Apache-2.0', - 'Artistic-2.0' => 'Artistic-2.0', - 'BSD' => 'BSD-4-Clause', - 'CC0 1.0 Universal' => 'CC0-1.0', - 'CDDL-1.0' => 'CDDL-1.0', - 'CDDL-1.1' => 'CDDL-1.1', - 'EPL-1.0' => 'EPL-1.0', - 'EPL-2.0' => 'EPL-2.0', - 'GPLv2' => 'GPL-2.0', - 'GPLv3' => 'GPL-3.0', - 'ISC' => 'ISC', - 'LGPL' => 'LGPL-3.0-only', - 'LGPL-2.1' => 'LGPL-2.1', - 'MIT' => 'MIT', - 'Mozilla Public License 2.0' => 'MPL-2.0', - 'MS-PL' => 'MS-PL', - 'MS-RL' => 'MS-RL', - 'New BSD' => 'BSD-3-Clause', - 'Python Software Foundation License' => 'Python-2.0', - 'ruby' => 'Ruby', - 'Simplified BSD' => 'BSD-2-Clause', - 'WTFPL' => 'WTFPL', - 'Zlib' => 'Zlib' - }.each do |old_name, spdx_id| - context "when mapping the legacy license name #{old_name}" do - subject { described_class.new([dependency]) } - - let(:license) { LicenseFinder::License.new(short_name: old_name, matcher: LicenseFinder::License::NoneMatcher.new, url: nil) } - let(:dependency) { instance_double(LicenseFinder::Package, name: 'x', summary: '', description: '', homepage: '', licenses: [license]).as_null_object } - let(:result) { subject.to_h } - - specify { expect(result[:version]).to eq('2.0') } - specify { expect(result[:licenses].count).to be(1) } - specify { expect(result[:licenses][0]['id']).to eq(spdx_id) } - end - end - - context "when choosing an appropriate url for a license" do - subject { described_class.new([dependency]) } - let(:license) { LicenseFinder::License.new(short_name: 'MIT', matcher: LicenseFinder::License::NoneMatcher.new, url: nil) } - let(:dependency) { instance_double(LicenseFinder::Package, name: 'x', summary: '', description: '', homepage: '', licenses: [license]).as_null_object } - - specify { expect(subject.to_h[:licenses][0]['url']).to eql('https://opensource.org/licenses/MIT') } - end - end -end diff --git a/spec/license/management/repository_spec.rb b/spec/license/management/repository_spec.rb deleted file mode 100644 index 6ebc09e..0000000 --- a/spec/license/management/repository_spec.rb +++ /dev/null @@ -1,38 +0,0 @@ -RSpec.describe License::Management::Repository do - describe "#item_for" do - let(:spdx_licenses) { JSON.parse(IO.read('spdx-licenses.json'))['licenses'] } - - context "when mapping a license that refers to opensource.org" do - it 'parses the SPDX id from the url' do - spdx_licenses.each do |license| - spdx_id = license['licenseId'] - url = "https://opensource.org/licenses/#{spdx_id}" - license = LicenseFinder::License.new(short_name: url, matcher: LicenseFinder::License::NoneMatcher.new, url: url) - expect(subject.item_for(license)['id']).to eql(spdx_id) - end - end - end - - context "when mapping a license that refers to nuget.org" do - it 'parses the SPDX id from the url' do - spdx_licenses.each do |license| - spdx_id = license['licenseId'] - url = "https://licenses.nuget.org/#{spdx_id}" - license = LicenseFinder::License.new(short_name: url, matcher: LicenseFinder::License::NoneMatcher.new, url: url) - expect(subject.item_for(license)['id']).to eql(spdx_id) - end - end - end - - [ - ['Apache License v2.0', 'Apache-2.0'], - ].each do |short_name, spdx_id| - context "when mapping a `#{short_name}` license" do - let(:license) { LicenseFinder::License.new(short_name: short_name, matcher: LicenseFinder::License::NoneMatcher.new, url: nil) } - let(:dependency) { double(name: 'x', summary: '', description: '', homepage: '', licenses: [license]) } - - it { expect(subject.item_for(license)['id']).to eql(spdx_id) } - end - end - end -end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 2282613..be7673c 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,6 +1,18 @@ require 'license/management' +require 'json' +require 'support/integration_test_helper' RSpec.configure do |config| + config.include IntegrationTestHelper, type: :integration + config.define_derived_metadata(file_path: /\/spec\/integration/) do |metadata| + metadata[:type] = :integration + end + config.before(:suite) do + system('./bin/docker-build') unless ENV['LM_HOME'] + end + config.after(:example, type: :integration) do + runner.cleanup + end config.expect_with :rspec do |expectations| expectations.include_chain_clauses_in_custom_matcher_descriptions = true end diff --git a/spec/support/integration_test_helper.rb b/spec/support/integration_test_helper.rb new file mode 100644 index 0000000..df75176 --- /dev/null +++ b/spec/support/integration_test_helper.rb @@ -0,0 +1,37 @@ +module IntegrationTestHelper + class IntegrationTestRunner + attr_reader :project_path + + def initialize(project_path = Dir.mktmpdir('lm')) + @project_path = project_path + end + + def add_file(name, content = nil) + full_path = "#{project_path}/#{name}" + IO.write(full_path, block_given? ? yield : content) + end + + def scan(env: {}) + return {} unless execute(env, './bin/test-local', project_path) + + report_path = "#{project_path}/gl-license-management-report.json" + return {} unless File.exist?(report_path) + + JSON.parse(IO.read(report_path), symbolize_names: true) + end + + def execute(env = {}, *args) + Bundler.with_clean_env do + system(env, *args) + end + end + + def cleanup + FileUtils.rm_rf(project_path) if Dir.exist?(project_path) + end + end + + def runner(*args) + @runner ||= IntegrationTestRunner.new(*args) + end +end diff --git a/spec/unit/license/management/report/v2_spec.rb b/spec/unit/license/management/report/v2_spec.rb new file mode 100644 index 0000000..4da973c --- /dev/null +++ b/spec/unit/license/management/report/v2_spec.rb @@ -0,0 +1,51 @@ +RSpec.describe License::Management::Report::V2 do + describe "#to_h" do + { + 'AGPL-1.0' => 'AGPL-1.0', + 'AGPL-3.0' => 'AGPL-3.0', + 'Apache 2.0' => 'Apache-2.0', + 'Artistic-2.0' => 'Artistic-2.0', + 'BSD' => 'BSD-4-Clause', + 'CC0 1.0 Universal' => 'CC0-1.0', + 'CDDL-1.0' => 'CDDL-1.0', + 'CDDL-1.1' => 'CDDL-1.1', + 'EPL-1.0' => 'EPL-1.0', + 'EPL-2.0' => 'EPL-2.0', + 'GPLv2' => 'GPL-2.0', + 'GPLv3' => 'GPL-3.0', + 'ISC' => 'ISC', + 'LGPL' => 'LGPL-3.0-only', + 'LGPL-2.1' => 'LGPL-2.1', + 'MIT' => 'MIT', + 'Mozilla Public License 2.0' => 'MPL-2.0', + 'MS-PL' => 'MS-PL', + 'MS-RL' => 'MS-RL', + 'New BSD' => 'BSD-3-Clause', + 'Python Software Foundation License' => 'Python-2.0', + 'ruby' => 'Ruby', + 'Simplified BSD' => 'BSD-2-Clause', + 'WTFPL' => 'WTFPL', + 'Zlib' => 'Zlib' + }.each do |old_name, spdx_id| + context "when mapping the legacy license name #{old_name}" do + subject { described_class.new([dependency]) } + + let(:license) { LicenseFinder::License.new(short_name: old_name, matcher: LicenseFinder::License::NoneMatcher.new, url: nil) } + let(:dependency) { instance_double(LicenseFinder::Package, name: 'x', summary: '', description: '', homepage: '', licenses: [license]).as_null_object } + let(:result) { subject.to_h } + + specify { expect(result[:version]).to eq('2.0') } + specify { expect(result[:licenses].count).to be(1) } + specify { expect(result[:licenses][0]['id']).to eq(spdx_id) } + end + end + + context "when choosing an appropriate url for a license" do + subject { described_class.new([dependency]) } + let(:license) { LicenseFinder::License.new(short_name: 'MIT', matcher: LicenseFinder::License::NoneMatcher.new, url: nil) } + let(:dependency) { instance_double(LicenseFinder::Package, name: 'x', summary: '', description: '', homepage: '', licenses: [license]).as_null_object } + + specify { expect(subject.to_h[:licenses][0]['url']).to eql('https://opensource.org/licenses/MIT') } + end + end +end diff --git a/spec/unit/license/management/repository_spec.rb b/spec/unit/license/management/repository_spec.rb new file mode 100644 index 0000000..6ebc09e --- /dev/null +++ b/spec/unit/license/management/repository_spec.rb @@ -0,0 +1,38 @@ +RSpec.describe License::Management::Repository do + describe "#item_for" do + let(:spdx_licenses) { JSON.parse(IO.read('spdx-licenses.json'))['licenses'] } + + context "when mapping a license that refers to opensource.org" do + it 'parses the SPDX id from the url' do + spdx_licenses.each do |license| + spdx_id = license['licenseId'] + url = "https://opensource.org/licenses/#{spdx_id}" + license = LicenseFinder::License.new(short_name: url, matcher: LicenseFinder::License::NoneMatcher.new, url: url) + expect(subject.item_for(license)['id']).to eql(spdx_id) + end + end + end + + context "when mapping a license that refers to nuget.org" do + it 'parses the SPDX id from the url' do + spdx_licenses.each do |license| + spdx_id = license['licenseId'] + url = "https://licenses.nuget.org/#{spdx_id}" + license = LicenseFinder::License.new(short_name: url, matcher: LicenseFinder::License::NoneMatcher.new, url: url) + expect(subject.item_for(license)['id']).to eql(spdx_id) + end + end + end + + [ + ['Apache License v2.0', 'Apache-2.0'], + ].each do |short_name, spdx_id| + context "when mapping a `#{short_name}` license" do + let(:license) { LicenseFinder::License.new(short_name: short_name, matcher: LicenseFinder::License::NoneMatcher.new, url: nil) } + let(:dependency) { double(name: 'x', summary: '', description: '', homepage: '', licenses: [license]) } + + it { expect(subject.item_for(license)['id']).to eql(spdx_id) } + end + end + end +end -- cgit v1.2.3