summaryrefslogtreecommitdiff
path: root/spec/integration/python/pip_spec.rb
diff options
context:
space:
mode:
Diffstat (limited to 'spec/integration/python/pip_spec.rb')
-rw-r--r--spec/integration/python/pip_spec.rb160
1 files changed, 160 insertions, 0 deletions
diff --git a/spec/integration/python/pip_spec.rb b/spec/integration/python/pip_spec.rb
new file mode 100644
index 0000000..8e3ec3d
--- /dev/null
+++ b/spec/integration/python/pip_spec.rb
@@ -0,0 +1,160 @@
+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).to match_schema(version: '2.0')
+ expect(report[:version]).to start_with('2')
+ expect(report.dependency_names).to include("sentry-sdk")
+ expect(report.licenses_for('sentry-sdk')).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',
+ '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).to match_schema(version: '2.0')
+ expect(report[:version]).to start_with('2')
+ expect(report[:licenses]).not_to be_empty
+ expect(report[:dependencies]).not_to be_empty
+ end
+ end
+
+ [{ version: '2', commit: '04dce91b' }, { version: '3', commit: '48e250a1' }].each do |python|
+ ['1.0', '1.1', '2.0'].each do |report_version|
+ context "when generating a `#{report_version}` report using Python `#{python[:version]}`" do
+ let(:url) { "https://gitlab.com/gitlab-org/security-products/tests/#{language}-#{package_manager}.git" }
+ let(:language) { 'python' }
+ let(:package_manager) { 'pip' }
+ let(:environment) { { 'LM_REPORT_VERSION' => report_version, 'LM_PYTHON_VERSION' => python[:version] } }
+ let(:expected_content) { fixture_file_content("expected/#{language}/#{python[:version]}/#{package_manager}/v#{report_version}.json").chomp }
+
+ it 'matches the expected report' do
+ runner.clone(url, branch: python[:commit])
+ report = runner.scan(env: environment)
+
+ expect(JSON.pretty_generate(report.to_h)).to eq(expected_content)
+ expect(report).to match_schema(version: report_version)
+ end
+ end
+ end
+ end
+
+ context "when scanning projects with a `setup.py` and does not have a `requirements.txt` file" do
+ it 'detects licenses in a simple `setup.py`' do
+ runner.add_file('setup.py', fixture_file_content('python/simple-setup.py'))
+ report = runner.scan
+
+ expect(report).to match_schema(version: '2.0')
+ expect(report[:dependencies]).not_to be_empty
+ expect(report.licenses_for('boto3')).to match_array(['Apache-2.0'])
+ end
+
+ it 'detects licenses in a more complicated `setup.py`' do
+ runner.clone('https://github.com/pypa/sampleproject.git', branch: 'd09af3dbd851d385e56f0aed29875bfa3d3df230')
+ report = runner.scan
+
+ expect(report).to match_schema(version: '2.0')
+ expect(report[:dependencies]).not_to be_empty
+ expect(report.licenses_for('peppercorn')).to match_array(['BSD-2-Clause'])
+ end
+ end
+
+ context "when scanning projects that have a custom index-url" do
+ before do
+ runner.add_file('requirements.txt', 'six')
+ end
+
+ it 'detects the licenses from the custom index' do
+ report = runner.scan(env: { 'PIP_INDEX_URL' => 'https://test.pypi.org/simple/' })
+
+ expect(report).to match_schema(version: '2.0')
+ expect(report.licenses_for('six')).to match_array(["MIT"])
+ end
+ end
+
+ context "when a project uses a custom `SETUP_CMD`" do
+ before do
+ runner.add_file('requirements.txt', 'six==1.14.0')
+ end
+
+ it 'detects the software licenses' do
+ report = runner.scan(env: { 'SETUP_CMD' => 'pip install -r requirements.txt' })
+
+ expect(report).to match_schema(version: '2.0')
+ expect(report.licenses_for('six')).to match_array(["MIT"])
+ expect(report.dependency_names).to contain_exactly('six')
+ end
+ end
+
+ context "when a projects is running in airgap mode" do
+ before do
+ runner.add_file('requirements.txt', '')
+ end
+
+ it 'is able to scan the project' do
+ report = runner.scan(env: {
+ 'PIP_INDEX_URL' => 'https://localhost/simple/'
+ })
+
+ expect(report).to match_schema(version: '2.0')
+ expect(report[:licenses]).to be_empty
+ expect(report[:dependencies]).to be_empty
+ end
+ end
+
+ context "when connecting to a private package repository with self signed certificate" do
+ let(:index_url) { "https://#{private_pypi_host}/simple" }
+ let(:bundle) { fixture_file_content('python/pypi.crt') }
+
+ before do
+ runner.add_file('setup.py') do
+ <<~RAW
+from setuptools import setup, find_packages
+
+setup(
+ name='gitlab-sp-test-python-pip',
+ version='1.2.0',
+ packages=find_packages(),
+ install_requires=['requests'],
+)
+ RAW
+ end
+ end
+
+ it 'downloads the packages and trusts the certificate' do
+ report = runner.scan(env: {
+ 'ADDITIONAL_CA_CERT_BUNDLE' => bundle,
+ 'PIP_INDEX_URL' => index_url
+ })
+
+ expect(report).to match_schema(version: '2.0')
+ expect(report.dependency_names).to include('requests')
+ expect(report.licenses_for('requests')).to match_array(['Apache-2.0'])
+ end
+ end
+end