Skip to content

Commit

Permalink
fix(offline): report all ecosystems without local databases in one si…
Browse files Browse the repository at this point in the history
…ngle line (#1279)

This reduces the amount of noise generated when using `--offline` if a
database is not available for a particular ecosystem. While it was
suggested that we could have some form of general error cache, for now
I've just optimized for this specific case as really it's the one we
expect the most and (in part) I think the nature of Go makes the more
generic improvement a bit too faffy vs the gain.

Resolves #1005
  • Loading branch information
G-Rath authored Sep 30, 2024
1 parent ce76735 commit 866b3e0
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 2 deletions.
42 changes: 42 additions & 0 deletions cmd/osv-scanner/__snapshots__/main_test.snap
Original file line number Diff line number Diff line change
Expand Up @@ -2091,6 +2091,48 @@ databases can only be downloaded when running in offline mode

---

[TestRun_LocalDatabases_AlwaysOffline/#00 - 1]
Scanning dir ./fixtures/locks-requirements
Scanned <rootdir>/fixtures/locks-requirements/my-requirements.txt file and found 1 package
Scanned <rootdir>/fixtures/locks-requirements/requirements-dev.txt file and found 1 package
Scanned <rootdir>/fixtures/locks-requirements/requirements.prod.txt file and found 1 package
Scanned <rootdir>/fixtures/locks-requirements/requirements.txt file and found 3 packages
Scanned <rootdir>/fixtures/locks-requirements/the_requirements_for_test.txt file and found 1 package
Scanning dir ./fixtures/locks-many
Scanned <rootdir>/fixtures/locks-many/Gemfile.lock file and found 1 package
Scanned <rootdir>/fixtures/locks-many/alpine.cdx.xml as CycloneDX SBOM and found 14 packages
Scanned <rootdir>/fixtures/locks-many/composer.lock file and found 1 package
Scanned <rootdir>/fixtures/locks-many/package-lock.json file and found 1 package
Scanned <rootdir>/fixtures/locks-many/yarn.lock file and found 1 package

---

[TestRun_LocalDatabases_AlwaysOffline/#00 - 2]
could not find local databases for ecosystems: Alpine, Packagist, PyPI, RubyGems, npm

---

[TestRun_LocalDatabases_AlwaysOffline/#00 - 3]
Scanning dir ./fixtures/locks-requirements
Scanned <rootdir>/fixtures/locks-requirements/my-requirements.txt file and found 1 package
Scanned <rootdir>/fixtures/locks-requirements/requirements-dev.txt file and found 1 package
Scanned <rootdir>/fixtures/locks-requirements/requirements.prod.txt file and found 1 package
Scanned <rootdir>/fixtures/locks-requirements/requirements.txt file and found 3 packages
Scanned <rootdir>/fixtures/locks-requirements/the_requirements_for_test.txt file and found 1 package
Scanning dir ./fixtures/locks-many
Scanned <rootdir>/fixtures/locks-many/Gemfile.lock file and found 1 package
Scanned <rootdir>/fixtures/locks-many/alpine.cdx.xml as CycloneDX SBOM and found 14 packages
Scanned <rootdir>/fixtures/locks-many/composer.lock file and found 1 package
Scanned <rootdir>/fixtures/locks-many/package-lock.json file and found 1 package
Scanned <rootdir>/fixtures/locks-many/yarn.lock file and found 1 package

---

[TestRun_LocalDatabases_AlwaysOffline/#00 - 4]
could not find local databases for ecosystems: Alpine, Packagist, PyPI, RubyGems, npm

---

[TestRun_LockfileWithExplicitParseAs/#00 - 1]

---
Expand Down
29 changes: 29 additions & 0 deletions cmd/osv-scanner/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,35 @@ func TestRun_LocalDatabases(t *testing.T) {
}
}

func TestRun_LocalDatabases_AlwaysOffline(t *testing.T) {
t.Parallel()

tests := []cliTestCase{
// a bunch of different lockfiles and ecosystem
{
name: "",
args: []string{"", "--config=./fixtures/osv-scanner-empty-config.toml", "--experimental-offline", "./fixtures/locks-requirements", "./fixtures/locks-many"},
exit: 127,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()

testDir := testutility.CreateTestDir(t)
old := tt.args
tt.args = []string{"", "--experimental-local-db-path", testDir}
tt.args = append(tt.args, old[1:]...)

// run each test twice since they should provide the same output,
// and the second run should be fast as the db is already available
testCli(t, tt)
testCli(t, tt)
})
}
}

func TestRun_Licenses(t *testing.T) {
t.Parallel()
tests := []cliTestCase{
Expand Down
21 changes: 19 additions & 2 deletions internal/local/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"fmt"
"os"
"path"
"slices"
"strings"

"github.com/google/osv-scanner/pkg/lockfile"
"github.com/google/osv-scanner/pkg/models"
Expand Down Expand Up @@ -116,6 +118,9 @@ func MakeRequest(r reporter.Reporter, query osv.BatchedQuery, offline bool, loca
return db, nil
}

// slice to track ecosystems that did not have an offline database available
var missingDbs []string

for _, query := range query.Queries {
pkg, err := toPackageDetails(query)

Expand Down Expand Up @@ -143,8 +148,13 @@ func MakeRequest(r reporter.Reporter, query osv.BatchedQuery, offline bool, loca
db, err := loadDBFromCache(pkg.Ecosystem)

if err != nil {
// currently, this will actually only error if the PURL cannot be parses
r.Errorf("could not load db for %s ecosystem: %v\n", pkg.Ecosystem, err)
if errors.Is(err, ErrOfflineDatabaseNotFound) {
missingDbs = append(missingDbs, string(pkg.Ecosystem))
} else {
// the most likely error at this point is that the PURL could not be parsed
r.Errorf("could not load db for %s ecosystem: %v\n", pkg.Ecosystem, err)
}

results = append(results, osv.Response{Vulns: []models.Vulnerability{}})

continue
Expand All @@ -153,5 +163,12 @@ func MakeRequest(r reporter.Reporter, query osv.BatchedQuery, offline bool, loca
results = append(results, osv.Response{Vulns: db.VulnerabilitiesAffectingPackage(pkg)})
}

if len(missingDbs) > 0 {
missingDbs = slices.Compact(missingDbs)
slices.Sort(missingDbs)

r.Errorf("could not find local databases for ecosystems: %s\n", strings.Join(missingDbs, ", "))
}

return &osv.HydratedBatchedResponse{Results: results}, nil
}

0 comments on commit 866b3e0

Please sign in to comment.