Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ temp/*
gcp/api/v1/osv/**
.hypothesis
go/api-devserver
go/api
esp.log
12 changes: 6 additions & 6 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ Many tests use expected outputs saved directly in the source tree:
### Local API Server Development (Go-native)
- To run the public OSV API server locally using the native Go implementation alongside the ESPv2 proxy (which transcodes HTTP/JSON REST requests to gRPC):
```bash
make run-go-api
make run-api-server
```

---
Expand Down Expand Up @@ -246,11 +246,11 @@ The `osv` folder is a shared Python package. Since the primary API server and so
## GCP Component Architecture (`gcp/`)
Contains deployment setups, workers running in GKE, Cloud Functions, and the user-facing website and API.

### 1. API Server (`gcp/api/`)
- **Status**: **Active (Python)**.
- Serves the public HTTP API for querying vulnerabilities by package or version.
- **Deployment Target**: **Google Cloud Run** (managed via Cloud Deploy pipeline `osv-api`).
- *Note*: Plans exist to migrate this to Go in the near future, but it currently remains in Python.
### 1. API Server (`go/cmd/api/`)
- **Status**: **Active (Go)**.
- Serves the public OSV gRPC API server (transcoded to HTTP/JSON REST via ESPv2).
- **Deployment Target**: **Google Cloud Run** (managed via Cloud Deploy pipeline `osv-api` deploying to `osv-grpc-backend`).
- *Note*: Fully migrated from Python to Go. The legacy Python implementation remains in `gcp/api/` but is retired.

### 2. Website (`gcp/website/`)
- **Status**: **Active**.
Expand Down
29 changes: 19 additions & 10 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,16 @@ go-tests:

api-server-tests:
test -f $(HOME)/.config/gcloud/application_default_credentials.json || (echo "GCP Application Default Credentials not set, try 'gcloud auth application-default login'"; exit 1)
cd go && go build -o ./api ./cmd/api
cd gcp/api && docker build -f Dockerfile.esp -t osv/esp:latest .
cd gcp/api && ./run_tests.sh $(HOME)/.config/gcloud/application_default_credentials.json
cd gcp/api && ./run_tests_e2e.sh $(HOME)/.config/gcloud/application_default_credentials.json
cd gcp/api && OSV_USE_GO_BACKEND=1 ./run_tests.sh $(HOME)/.config/gcloud/application_default_credentials.json
cd gcp/api && OSV_USE_GO_BACKEND=1 ./run_tests_e2e.sh $(HOME)/.config/gcloud/application_default_credentials.json

update-api-snapshots:
test -f $(HOME)/.config/gcloud/application_default_credentials.json || (echo "GCP Application Default Credentials not set, try 'gcloud auth application-default login'"; exit 1)
cd go && go build -o ./api ./cmd/api
cd gcp/api && docker build -f Dockerfile.esp -t osv/esp:latest .
cd gcp/api && UPDATE_SNAPS=true ./run_tests_e2e.sh $(HOME)/.config/gcloud/application_default_credentials.json
cd gcp/api && UPDATE_SNAPS=true OSV_USE_GO_BACKEND=1 ./run_tests_e2e.sh $(HOME)/.config/gcloud/application_default_credentials.json

lint:
GOTOOLCHAIN=go1.26.3 $(run-cmd) tools/lint_and_format.sh
Expand Down Expand Up @@ -103,20 +105,27 @@ run-website-emulator:
cd gcp/website/blog && hugo --buildFuture -d ../dist/static/blog
cd gcp/website && $(install-cmd) && DATASTORE_EMULATOR_PORT=5002 $(run-cmd) python frontend_emulator.py

# Run with `make run-api-server ARGS=--no-backend` to launch esp without backend.
# Run the Go developer server orchestrator (launches both ESPv2 and the Go API server).
# Run with `make run-api-server ARGS=--no-backend` to launch esp without backend.
run-api-server:
test -f $(HOME)/.config/gcloud/application_default_credentials.json || (echo "GCP Application Default Credentials not set, try 'gcloud auth application-default login'"; exit 1)
cd gcp/api && docker build -f Dockerfile.esp -t osv/esp:latest .
cd gcp/api && $(install-cmd) && GOOGLE_CLOUD_PROJECT=oss-vdb OSV_VULNERABILITIES_BUCKET=osv-vulnerabilities $(run-cmd) python test_server.py $(HOME)/.config/gcloud/application_default_credentials.json $(ARGS)

# Run the native Go developer server orchestrator (launches both ESPv2 and the Go API server).
# Run with `run-go-api ARGS=--no-backend` to launch esp without backend.
run-go-api:
test -f $(HOME)/.config/gcloud/application_default_credentials.json || (echo "GCP Application Default Credentials not set, try 'gcloud auth application-default login'"; exit 1)
docker inspect osv/esp:latest >/dev/null 2>&1 || (cd gcp/api && docker build -f Dockerfile.esp -t osv/esp:latest .)
@cd go && go build -o ./api-devserver ./cmd/api-devserver && (GOOGLE_CLOUD_PROJECT=oss-vdb OSV_VULNERABILITIES_BUCKET=osv-vulnerabilities ./api-devserver $(ARGS); EXIT_CODE=$$?; rm -f ./api-devserver; exit $$EXIT_CODE)

# Run the Go developer server orchestrator against the staging/test environment.
run-api-server-test:
test -f $(HOME)/.config/gcloud/application_default_credentials.json || (echo "GCP Application Default Credentials not set, try 'gcloud auth application-default login'"; exit 1)
docker inspect osv/esp:latest >/dev/null 2>&1 || (cd gcp/api && docker build -f Dockerfile.esp -t osv/esp:latest .)
@cd go && go build -o ./api-devserver ./cmd/api-devserver && (GOOGLE_CLOUD_PROJECT=oss-vdb-test OSV_VULNERABILITIES_BUCKET=osv-test-vulnerabilities ./api-devserver $(ARGS); EXIT_CODE=$$?; rm -f ./api-devserver; exit $$EXIT_CODE)

# Legacy Python API server targets
run-python-api-server:
test -f $(HOME)/.config/gcloud/application_default_credentials.json || (echo "GCP Application Default Credentials not set, try 'gcloud auth application-default login'"; exit 1)
cd gcp/api && docker build -f Dockerfile.esp -t osv/esp:latest .
cd gcp/api && $(install-cmd) && GOOGLE_CLOUD_PROJECT=oss-vdb OSV_VULNERABILITIES_BUCKET=osv-vulnerabilities $(run-cmd) python test_server.py $(HOME)/.config/gcloud/application_default_credentials.json $(ARGS)

run-python-api-server-test:
test -f $(HOME)/.config/gcloud/application_default_credentials.json || (echo "GCP Application Default Credentials not set, try 'gcloud auth application-default login'"; exit 1)
cd gcp/api && docker build -f Dockerfile.esp -t osv/esp:latest .
cd gcp/api && $(install-cmd) && GOOGLE_CLOUD_PROJECT=oss-vdb-test OSV_VULNERABILITIES_BUCKET=osv-test-vulnerabilities $(run-cmd) python test_server.py $(HOME)/.config/gcloud/application_default_credentials.json $(ARGS)
Expand Down
24 changes: 14 additions & 10 deletions deployment/build-and-stage.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,20 @@ steps:
args: ['push', '--all-tags', 'gcr.io/oss-vdb/gitter']
waitFor: ['build-gitter', 'cloud-build-queue']

- name: gcr.io/cloud-builders/docker
entrypoint: 'bash'
args: ['-c', 'docker pull gcr.io/oss-vdb/osv-server:latest || exit 0']
id: 'pull-osv-server'
waitFor: ['setup']
- name: gcr.io/cloud-builders/docker
args: ['buildx', 'build', '-t', 'gcr.io/oss-vdb/osv-server:latest', '-t', 'gcr.io/oss-vdb/osv-server:$COMMIT_SHA', '--target', 'api', '--build-context', 'bindings=../bindings', '-f', 'Dockerfile', '--cache-from', 'gcr.io/oss-vdb/osv-server:latest', '--pull', '.']
dir: 'go'
id: 'build-osv-server'
waitFor: ['pull-osv-server', 'build-gitter']
- name: gcr.io/cloud-builders/docker
args: ['push', '--all-tags', 'gcr.io/oss-vdb/osv-server']
waitFor: ['build-osv-server', 'cloud-build-queue']

# Build/push staging-api-test images to gcr.io/oss-vdb-test.
- name: gcr.io/cloud-builders/docker
args: ['build', '-t', 'gcr.io/oss-vdb-test/staging-api-test:latest', '-t', 'gcr.io/oss-vdb-test/staging-api-test:$COMMIT_SHA', '.']
Expand Down Expand Up @@ -352,16 +366,6 @@ steps:
args: ['push', '--all-tags', 'gcr.io/oss-vdb/run_first_package_finder']
waitFor: ['build-first-package-finder', 'cloud-build-queue']


# Build/push api backend
- name: 'gcr.io/cloud-builders/docker'
args: ['build', '-t', 'gcr.io/oss-vdb/osv-server:latest', '-t', 'gcr.io/oss-vdb/osv-server:$COMMIT_SHA', '-f', 'gcp/api/Dockerfile', '.']
id: 'build-osv-server'
waitFor: ['setup']
- name: 'gcr.io/cloud-builders/docker'
args: ['push', '--all-tags', 'gcr.io/oss-vdb/osv-server']
waitFor: ['build-osv-server', 'cloud-build-queue']

# Build/push Debian copyright mirror image
- name: gcr.io/cloud-builders/docker
args: ['build', '-t', 'gcr.io/oss-vdb/debian-copyright-mirror:latest', '-t', 'gcr.io/oss-vdb/debian-copyright-mirror:$COMMIT_SHA', '.']
Expand Down
4 changes: 4 additions & 0 deletions deployment/clouddeploy/osv-api/run-prod.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,12 @@ spec:
containers:
- image: osv-server
env:
- name: GOOGLE_CLOUD_PROJECT
value: oss-vdb
- name: OSV_VULNERABILITIES_BUCKET
value: osv-vulnerabilities
- name: FAILED_TASKS_TOPIC
value: failed-tasks
resources:
limits:
cpu: 2
Expand Down
6 changes: 6 additions & 0 deletions deployment/clouddeploy/osv-api/run-staging.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,14 @@ spec:
containers:
- image: osv-server
env:
- name: GOOGLE_CLOUD_PROJECT
value: oss-vdb-test
- name: OSV_VULNERABILITIES_BUCKET
value: osv-test-vulnerabilities
- name: FAILED_TASKS_TOPIC
value: failed-tasks
- name: OSV_VERBOSE_LOGGING
value: "true"
resources:
limits:
cpu: 2
Expand Down
9 changes: 8 additions & 1 deletion gcp/api/cloudbuild.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,23 @@ steps:
args: ['poetry', 'sync']
waitFor: ['-']

- name: 'gcr.io/oss-vdb/ci'
id: 'build-go-backend'
dir: go
args: ['go', 'build', '-o', 'api', './cmd/api']
waitFor: ['init']

- name: 'gcr.io/oss-vdb/ci'
id: 'api-tests'
dir: gcp/api
#TODO: Update test scripts to support not supplying a credential.
args: ['bash', '-ex', 'run_tests.sh', '/workspace/dummy.json']
waitFor: ['init', 'sync']
waitFor: ['build-go-backend', 'sync']

timeout: 7200s
serviceAccount: 'projects/oss-vdb/serviceAccounts/api-e2e-tester@oss-vdb.iam.gserviceaccount.com'
options:
logging: CLOUD_LOGGING_ONLY
env:
- CLOUDBUILD=1
- OSV_USE_GO_BACKEND=1
40 changes: 20 additions & 20 deletions gcp/api/fixtures/IntegrationTests_api_query_response.txt
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
[ '400:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'{"ecosystem": "crates.io", "name": "crossbeam-utils", "purl": '
'"pkg:cargo/crossbeam-utils"}, "version": "0.8.5"}\n',
'400:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'200:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'{"ecosystem": "crates.io", "name": "crossbeam-utils", "purl": '
'"pkg:cargo/crossbeam-utils"}}\n',
'400:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'{"ecosystem": "crates.io", "name": "crossbeam-utils", "purl": '
'"pkg:cargo/crossbeam-utils@0.8.5"}, "version": "0.8.5"}\n',
'400:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'200:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'{"ecosystem": "crates.io", "name": "crossbeam-utils", "purl": '
'"pkg:cargo/crossbeam-utils@0.8.5"}}\n',
'400:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'{"ecosystem": "crates.io", "name": "crossbeam-utils", "purl": '
'"pkg:pypi/numpy"}, "version": "0.8.5"}\n',
'400:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'200:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'{"ecosystem": "crates.io", "name": "crossbeam-utils", "purl": '
'"pkg:pypi/numpy"}}\n',
'400:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'{"ecosystem": "crates.io", "name": "crossbeam-utils", "purl": '
'"pkg:pypi/numpy@8.24.0"}, "version": "0.8.5"}\n',
'400:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'200:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'{"ecosystem": "crates.io", "name": "crossbeam-utils", "purl": '
'"pkg:pypi/numpy@8.24.0"}}\n',
'400:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
Expand All @@ -30,24 +30,24 @@
'400:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'{"ecosystem": "crates.io", "name": "numpy", "purl": '
'"pkg:cargo/crossbeam-utils"}, "version": "0.8.5"}\n',
'400:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'200:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'{"ecosystem": "crates.io", "name": "numpy", "purl": '
'"pkg:cargo/crossbeam-utils"}}\n',
'400:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'{"ecosystem": "crates.io", "name": "numpy", "purl": '
'"pkg:cargo/crossbeam-utils@0.8.5"}, "version": "0.8.5"}\n',
'400:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'200:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'{"ecosystem": "crates.io", "name": "numpy", "purl": '
'"pkg:cargo/crossbeam-utils@0.8.5"}}\n',
'400:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'{"ecosystem": "crates.io", "name": "numpy", "purl": "pkg:pypi/numpy"}, '
'"version": "0.8.5"}\n',
'400:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'200:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'{"ecosystem": "crates.io", "name": "numpy", "purl": "pkg:pypi/numpy"}}\n',
'400:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'{"ecosystem": "crates.io", "name": "numpy", "purl": '
'"pkg:pypi/numpy@8.24.0"}, "version": "0.8.5"}\n',
'400:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'200:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'{"ecosystem": "crates.io", "name": "numpy", "purl": '
'"pkg:pypi/numpy@8.24.0"}}\n',
'400:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
Expand All @@ -57,22 +57,22 @@
'400:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'{"ecosystem": "crates.io", "purl": "pkg:cargo/crossbeam-utils"}, '
'"version": "0.8.5"}\n',
'400:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'200:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'{"ecosystem": "crates.io", "purl": "pkg:cargo/crossbeam-utils"}}\n',
'400:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'{"ecosystem": "crates.io", "purl": "pkg:cargo/crossbeam-utils@0.8.5"}, '
'"version": "0.8.5"}\n',
'400:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'200:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'{"ecosystem": "crates.io", "purl": "pkg:cargo/crossbeam-utils@0.8.5"}}\n',
'400:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'{"ecosystem": "crates.io", "purl": "pkg:pypi/numpy"}, "version": '
'"0.8.5"}\n',
'400:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'200:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'{"ecosystem": "crates.io", "purl": "pkg:pypi/numpy"}}\n',
'400:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'{"ecosystem": "crates.io", "purl": "pkg:pypi/numpy@8.24.0"}, "version": '
'"0.8.5"}\n',
'400:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'200:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'{"ecosystem": "crates.io", "purl": "pkg:pypi/numpy@8.24.0"}}\n',
'400:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'{"ecosystem": "crates.io"}, "version": "0.8.5"}\n',
Expand All @@ -81,22 +81,22 @@
'400:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'{"name": "crossbeam-utils", "purl": "pkg:cargo/crossbeam-utils"}, '
'"version": "0.8.5"}\n',
'400:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'200:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'{"name": "crossbeam-utils", "purl": "pkg:cargo/crossbeam-utils"}}\n',
'400:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'{"name": "crossbeam-utils", "purl": "pkg:cargo/crossbeam-utils@0.8.5"}, '
'"version": "0.8.5"}\n',
'400:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'200:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'{"name": "crossbeam-utils", "purl": "pkg:cargo/crossbeam-utils@0.8.5"}}\n',
'400:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'{"name": "crossbeam-utils", "purl": "pkg:pypi/numpy"}, "version": '
'"0.8.5"}\n',
'400:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'200:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'{"name": "crossbeam-utils", "purl": "pkg:pypi/numpy"}}\n',
'400:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'{"name": "crossbeam-utils", "purl": "pkg:pypi/numpy@8.24.0"}, "version": '
'"0.8.5"}\n',
'400:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'200:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'{"name": "crossbeam-utils", "purl": "pkg:pypi/numpy@8.24.0"}}\n',
'400:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'{"name": "crossbeam-utils"}, "version": "0.8.5"}\n',
Expand All @@ -105,20 +105,20 @@
'400:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'{"name": "numpy", "purl": "pkg:cargo/crossbeam-utils"}, "version": '
'"0.8.5"}\n',
'400:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'200:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'{"name": "numpy", "purl": "pkg:cargo/crossbeam-utils"}}\n',
'400:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'{"name": "numpy", "purl": "pkg:cargo/crossbeam-utils@0.8.5"}, "version": '
'"0.8.5"}\n',
'400:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'200:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'{"name": "numpy", "purl": "pkg:cargo/crossbeam-utils@0.8.5"}}\n',
'400:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'{"name": "numpy", "purl": "pkg:pypi/numpy"}, "version": "0.8.5"}\n',
'400:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'200:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'{"name": "numpy", "purl": "pkg:pypi/numpy"}}\n',
'400:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'{"name": "numpy", "purl": "pkg:pypi/numpy@8.24.0"}, "version": "0.8.5"}\n',
'400:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'200:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'{"name": "numpy", "purl": "pkg:pypi/numpy@8.24.0"}}\n',
'400:{"commit": "d374094d8c49b6b7d288f307e11217ec5a502391", "package": '
'{"name": "numpy"}, "version": "0.8.5"}\n',
Expand Down
16 changes: 9 additions & 7 deletions gcp/api/integration_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
from osv import tests

_PORT = 8080
_TIMEOUT = 10 # Timeout for HTTP(S) requests
_TIMEOUT = 15 # Timeout for HTTP(S) requests
_LONG_TESTS = os.getenv('LONG_TESTS')
_TEST_DATA_DIR = 'fixtures'
_BASE_QUERY = '/v1/query'
Expand Down Expand Up @@ -399,7 +399,7 @@ def test_query_invalid_ecosystem(self):

self.assert_results_equal({
'code': 3,
'message': 'Invalid ecosystem.'
'message': 'invalid ecosystem'
}, response.json())

def test_query_unknown_purl_invalid_semver(self):
Expand Down Expand Up @@ -492,9 +492,10 @@ def test_query_semver_multiple_package(self):
timeout=_TIMEOUT)

response_json = response.json()
self.assertEqual(2, len(response_json['vulns']))
self.assertCountEqual(['GHSA-6fc8-4gx4-v693', 'GHSA-3h5v-q93c-6h6q'],
[vuln['id'] for vuln in response_json['vulns']])
self.assertEqual(3, len(response_json['vulns']))
self.assertCountEqual(
['GHSA-6fc8-4gx4-v693', 'GHSA-3h5v-q93c-6h6q', 'GHSA-96hv-2xvq-fx4p'],
[vuln['id'] for vuln in response_json['vulns']])

def test_query_purl(self):
"""Test querying by PURL."""
Expand Down Expand Up @@ -694,8 +695,9 @@ def test_get_vuln_by_alias_not_in_db(self):
self.assert_results_equal(
{
'code': 5,
'message': 'Bug not found, but the following aliases were: '
'MAL-2024-2291'
'message':
'Vulnerability not found, but the following aliases were: '
'MAL-2024-2291'
}, response.json())

def test_query_batch(self):
Expand Down
Loading
Loading