diff --git a/Makefile b/Makefile index 40140f71e8..6175e86c1b 100644 --- a/Makefile +++ b/Makefile @@ -23,9 +23,7 @@ test: generate # To run it locally you can run the following command: make start-integration-service .PHONY: integration-test integration-test: generate check-env - # "-p 1" because We don't want the tests in internal/testing/backend - # and pkg/assembler/backend running at same time - go test -p 1 -tags=integration ./... + go test -tags=integration ./... # Runs the integration tests locally using docker-compose to start the dependencies and cleans up after itself. .PHONY: integration-test-local diff --git a/cmd/guacone/cmd/gcs_test.go b/cmd/guacone/cmd/gcs_test.go index eb106bd994..c4e9594d15 100644 --- a/cmd/guacone/cmd/gcs_test.go +++ b/cmd/guacone/cmd/gcs_test.go @@ -17,8 +17,6 @@ package cmd import ( "testing" - - "github.com/spf13/cobra" ) func TestValidateGCSFlags(t *testing.T) { @@ -82,18 +80,3 @@ func TestValidateGCSFlags(t *testing.T) { } } - -func TestJsonBz2Ingestion(t *testing.T) { - rootCmd := &cobra.Command{ - Use: "guacone", - Short: "guacone", - } - rootCmd.AddCommand(collectCmd) - rootCmd.AddCommand(filesCmd) - bz2Path := "./../../../internal/testing/testdata/exampledata/busybox-cyclonedx.json.bz2" - rootCmd.SetArgs([]string{"collect", "files", bz2Path}) - err := rootCmd.Execute() - if err != nil { - t.Fatal(err) - } -} diff --git a/go.mod b/go.mod index ad6688591f..2d8d20e07d 100644 --- a/go.mod +++ b/go.mod @@ -269,7 +269,7 @@ require ( deps.dev/api/v3alpha v0.0.0-20240109042716-00b51ef52ece entgo.io/contrib v0.4.5 entgo.io/ent v0.13.0 - github.com/99designs/gqlgen v0.17.41 + github.com/99designs/gqlgen v0.17.43 github.com/CycloneDX/cyclonedx-go v0.8.0 github.com/Khan/genqlient v0.6.0 github.com/Masterminds/semver v1.5.0 @@ -319,7 +319,7 @@ require ( github.com/spf13/viper v1.18.2 github.com/stretchr/testify v1.8.4 github.com/tikv/client-go/v2 v2.0.8-0.20231115083414-7c96dfd783fb - github.com/vektah/gqlparser/v2 v2.5.10 + github.com/vektah/gqlparser/v2 v2.5.11 gocloud.dev v0.36.0 gocloud.dev/pubsub/kafkapubsub v0.36.0 gocloud.dev/pubsub/rabbitpubsub v0.36.0 diff --git a/go.sum b/go.sum index 485c77bd89..23edf2dd24 100644 --- a/go.sum +++ b/go.sum @@ -23,8 +23,8 @@ entgo.io/contrib v0.4.5 h1:BFaOHwFLE8WZjVJadP0XHCIaxgcC1BAtUvAyw7M/GHk= entgo.io/contrib v0.4.5/go.mod h1:wpZyq2DJgthugFvDBlaqMXj9mV4/9ebyGEn7xlTVQqE= entgo.io/ent v0.13.0 h1:DclxWczaCpyiKn6ZWVcJjq1zIKtJ11iNKy+08lNYsJE= entgo.io/ent v0.13.0/go.mod h1:+oU8oGna69xy29O+g+NEz+/TM7yJDhQQGJfuOWq1pT8= -github.com/99designs/gqlgen v0.17.41 h1:C1/zYMhGVP5TWNCNpmZ9Mb6CqT1Vr5SHEWoTOEJ3v3I= -github.com/99designs/gqlgen v0.17.41/go.mod h1:GQ6SyMhwFbgHR0a8r2Wn8fYgEwPxxmndLFPhU63+cJE= +github.com/99designs/gqlgen v0.17.43 h1:I4SYg6ahjowErAQcHFVKy5EcWuwJ3+Xw9z2fLpuFCPo= +github.com/99designs/gqlgen v0.17.43/go.mod h1:lO0Zjy8MkZgBdv4T1U91x09r0e0WFOdhVUutlQs1Rsc= github.com/Azure/azure-amqp-common-go/v3 v3.2.3 h1:uDF62mbd9bypXWi19V1bN5NZEO84JqgmI5G73ibAmrk= github.com/Azure/azure-amqp-common-go/v3 v3.2.3/go.mod h1:7rPmbSfszeovxGfc5fSAXE4ehlXQZHpMja2OtxC2Tas= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.0 h1:fb8kj/Dh4CSwgsOzHeZY4Xh68cFVbzXx+ONXGMY//4w= @@ -759,8 +759,8 @@ github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6Kllzaw github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/vbatts/tar-split v0.11.3 h1:hLFqsOLQ1SsppQNTMpkpPXClLDfC2A3Zgy9OUU+RVck= github.com/vbatts/tar-split v0.11.3/go.mod h1:9QlHN18E+fEH7RdG+QAJJcuya3rqT7eXSTY7wGrAokY= -github.com/vektah/gqlparser/v2 v2.5.10 h1:6zSM4azXC9u4Nxy5YmdmGu4uKamfwsdKTwp5zsEealU= -github.com/vektah/gqlparser/v2 v2.5.10/go.mod h1:1rCcfwB2ekJofmluGWXMSEnPMZgbxzwj6FaZ/4OT8Cc= +github.com/vektah/gqlparser/v2 v2.5.11 h1:JJxLtXIoN7+3x6MBdtIP59TP1RANnY7pXOaDnADQSf8= +github.com/vektah/gqlparser/v2 v2.5.11/go.mod h1:1rCcfwB2ekJofmluGWXMSEnPMZgbxzwj6FaZ/4OT8Cc= github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4= github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU= github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= diff --git a/internal/testing/backend/artifact_test.go b/internal/testing/backend/artifact_test.go index a62d95954e..d819838a54 100644 --- a/internal/testing/backend/artifact_test.go +++ b/internal/testing/backend/artifact_test.go @@ -85,7 +85,7 @@ func TestArtifacts(t *testing.T) { }} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - ingestedArtID, err := b.IngestArtifact(ctx, tt.artifactInput) + ingestedArtID, err := b.IngestArtifact(ctx, &model.IDorArtifactInput{ArtifactInput: tt.artifactInput}) if (err != nil) != tt.wantErr { t.Errorf("arangoClient.IngestArtifact() error = %v, wantErr %v", err, tt.wantErr) return diff --git a/internal/testing/backend/builder_test.go b/internal/testing/backend/builder_test.go index e05ee8b086..a541b1a575 100644 --- a/internal/testing/backend/builder_test.go +++ b/internal/testing/backend/builder_test.go @@ -76,7 +76,7 @@ func TestBuilders(t *testing.T) { }} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - ingestedBuilderID, err := b.IngestBuilder(ctx, tt.builderInput) + ingestedBuilderID, err := b.IngestBuilder(ctx, &model.IDorBuilderInput{BuilderInput: tt.builderInput}) if (err != nil) != tt.wantErr { t.Errorf("arangoClient.IngestBuilder() error = %v, wantErr %v", err, tt.wantErr) return diff --git a/internal/testing/backend/certifyBad_test.go b/internal/testing/backend/certifyBad_test.go index ab037b469c..1732a0b8fd 100644 --- a/internal/testing/backend/certifyBad_test.go +++ b/internal/testing/backend/certifyBad_test.go @@ -201,7 +201,7 @@ func TestCertifyBad(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -227,7 +227,7 @@ func TestCertifyBad(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeAllVersions, @@ -257,7 +257,7 @@ func TestCertifyBad(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -268,7 +268,7 @@ func TestCertifyBad(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -298,7 +298,7 @@ func TestCertifyBad(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -309,7 +309,7 @@ func TestCertifyBad(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -335,7 +335,7 @@ func TestCertifyBad(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -347,7 +347,7 @@ func TestCertifyBad(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -376,7 +376,7 @@ func TestCertifyBad(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P4, + Package: &model.IDorPkgInput{PackageInput: testdata.P4}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeAllVersions, @@ -387,7 +387,7 @@ func TestCertifyBad(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P4, + Package: &model.IDorPkgInput{PackageInput: testdata.P4}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -398,7 +398,7 @@ func TestCertifyBad(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, + Source: &model.IDorSourceInput{SourceInput: testdata.S1}, }, CB: &model.CertifyBadInputSpec{ Justification: "test justification", @@ -433,7 +433,7 @@ func TestCertifyBad(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P4, + Package: &model.IDorPkgInput{PackageInput: testdata.P4}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -458,7 +458,7 @@ func TestCertifyBad(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -469,7 +469,7 @@ func TestCertifyBad(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, + Source: &model.IDorSourceInput{SourceInput: testdata.S1}, }, CB: &model.CertifyBadInputSpec{ Justification: "test justification", @@ -477,7 +477,7 @@ func TestCertifyBad(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S2, + Source: &model.IDorSourceInput{SourceInput: testdata.S2}, }, CB: &model.CertifyBadInputSpec{ Justification: "test justification", @@ -505,7 +505,7 @@ func TestCertifyBad(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S2, + Source: &model.IDorSourceInput{SourceInput: testdata.S2}, }, CB: &model.CertifyBadInputSpec{ Justification: "test justification", @@ -527,7 +527,7 @@ func TestCertifyBad(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A1, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A1}, }, CB: &model.CertifyBadInputSpec{ Justification: "test justification", @@ -535,7 +535,7 @@ func TestCertifyBad(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A2}, }, CB: &model.CertifyBadInputSpec{ Justification: "test justification", @@ -543,7 +543,7 @@ func TestCertifyBad(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, + Source: &model.IDorSourceInput{SourceInput: testdata.S1}, }, CB: &model.CertifyBadInputSpec{ Justification: "test justification", @@ -571,7 +571,7 @@ func TestCertifyBad(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A1, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A1}, }, CB: &model.CertifyBadInputSpec{ Justification: "test justification", @@ -579,7 +579,7 @@ func TestCertifyBad(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A2}, }, CB: &model.CertifyBadInputSpec{ Justification: "test justification", @@ -600,7 +600,7 @@ func TestCertifyBad(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A1, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A1}, }, CB: &model.CertifyBadInputSpec{ Justification: "test justification", @@ -608,7 +608,7 @@ func TestCertifyBad(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A2}, }, CB: &model.CertifyBadInputSpec{ Justification: "test justification", @@ -630,7 +630,7 @@ func TestCertifyBad(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, + Source: &model.IDorSourceInput{SourceInput: testdata.S1}, }, CB: &model.CertifyBadInputSpec{ Justification: "test justification", @@ -638,7 +638,7 @@ func TestCertifyBad(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S2, + Source: &model.IDorSourceInput{SourceInput: testdata.S2}, }, CB: &model.CertifyBadInputSpec{ Justification: "test justification", @@ -669,7 +669,7 @@ func TestCertifyBad(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -680,7 +680,7 @@ func TestCertifyBad(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P2, + Package: &model.IDorPkgInput{PackageInput: testdata.P2}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -691,7 +691,7 @@ func TestCertifyBad(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P2, + Package: &model.IDorPkgInput{PackageInput: testdata.P2}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeAllVersions, @@ -726,7 +726,7 @@ func TestCertifyBad(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A1, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A1}, }, CB: &model.CertifyBadInputSpec{ Justification: "test justification", @@ -734,7 +734,7 @@ func TestCertifyBad(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A2}, }, CB: &model.CertifyBadInputSpec{ Justification: "test justification", @@ -753,7 +753,7 @@ func TestCertifyBad(t *testing.T) { for _, test := range tests { t.Run(test.Name, func(t *testing.T) { for _, p := range test.InPkg { - if pkgIDs, err := b.IngestPackage(ctx, *p); err != nil { + if pkgIDs, err := b.IngestPackage(ctx, model.IDorPkgInput{PackageInput: p}); err != nil { t.Fatalf("Could not ingest package: %v", err) } else { if test.QueryPkgID { @@ -768,7 +768,7 @@ func TestCertifyBad(t *testing.T) { } } for _, s := range test.InSrc { - if srcIDs, err := b.IngestSource(ctx, *s); err != nil { + if srcIDs, err := b.IngestSource(ctx, model.IDorSourceInput{SourceInput: s}); err != nil { t.Fatalf("Could not ingest source: %v", err) } else { if test.QuerySourceID { @@ -783,7 +783,7 @@ func TestCertifyBad(t *testing.T) { } } for _, a := range test.InArt { - if artID, err := b.IngestArtifact(ctx, a); err != nil { + if artID, err := b.IngestArtifact(ctx, &model.IDorArtifactInput{ArtifactInput: a}); err != nil { t.Fatalf("Could not ingest artifact: %v", err) } else { if test.QueryArtID { @@ -852,7 +852,7 @@ func TestIngestCertifyBads(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1}, + Packages: []*model.IDorPkgInput{{PackageInput: testdata.P1}}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -880,7 +880,7 @@ func TestIngestCertifyBads(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1}, + Packages: []*model.IDorPkgInput{{PackageInput: testdata.P1}}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeAllVersions, @@ -912,7 +912,7 @@ func TestIngestCertifyBads(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1, testdata.P1}, + Packages: []*model.IDorPkgInput{{PackageInput: testdata.P1}, {PackageInput: testdata.P1}}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -948,7 +948,7 @@ func TestIngestCertifyBads(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1, testdata.P2}, + Packages: []*model.IDorPkgInput{{PackageInput: testdata.P1}, {PackageInput: testdata.P2}}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -964,7 +964,7 @@ func TestIngestCertifyBads(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{testdata.S1}, + Sources: []*model.IDorSourceInput{&model.IDorSourceInput{SourceInput: testdata.S1}}, }, CB: []*model.CertifyBadInputSpec{ { @@ -998,7 +998,7 @@ func TestIngestCertifyBads(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1}, + Packages: []*model.IDorPkgInput{{PackageInput: testdata.P1}}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -1011,7 +1011,7 @@ func TestIngestCertifyBads(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{testdata.S2, testdata.S2}, + Sources: []*model.IDorSourceInput{{SourceInput: testdata.S2}, {SourceInput: testdata.S2}}, }, CB: []*model.CertifyBadInputSpec{ { @@ -1044,7 +1044,7 @@ func TestIngestCertifyBads(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInputs{ - Artifacts: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, + Artifacts: []*model.IDorArtifactInput{&model.IDorArtifactInput{ArtifactInput: testdata.A1}, &model.IDorArtifactInput{ArtifactInput: testdata.A2}}, }, CB: []*model.CertifyBadInputSpec{ { @@ -1057,7 +1057,7 @@ func TestIngestCertifyBads(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{testdata.S1}, + Sources: []*model.IDorSourceInput{&model.IDorSourceInput{SourceInput: testdata.S1}}, }, CB: []*model.CertifyBadInputSpec{ { @@ -1084,17 +1084,17 @@ func TestIngestCertifyBads(t *testing.T) { for _, test := range tests { t.Run(test.Name, func(t *testing.T) { for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { + if _, err := b.IngestPackage(ctx, model.IDorPkgInput{PackageInput: p}); err != nil { t.Fatalf("Could not ingest package: %v", err) } } for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { + if _, err := b.IngestSource(ctx, model.IDorSourceInput{SourceInput: s}); err != nil { t.Fatalf("Could not ingest source: %v", err) } } for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { + if _, err := b.IngestArtifact(ctx, &model.IDorArtifactInput{ArtifactInput: a}); err != nil { t.Fatalf("Could not ingest artifact: %v", err) } } diff --git a/internal/testing/backend/certifyGood_test.go b/internal/testing/backend/certifyGood_test.go index f6ff0b819e..db42dedd2c 100644 --- a/internal/testing/backend/certifyGood_test.go +++ b/internal/testing/backend/certifyGood_test.go @@ -56,7 +56,7 @@ func TestCertifyGood(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -82,7 +82,7 @@ func TestCertifyGood(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeAllVersions, @@ -112,7 +112,7 @@ func TestCertifyGood(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -123,7 +123,7 @@ func TestCertifyGood(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -153,7 +153,7 @@ func TestCertifyGood(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -164,7 +164,7 @@ func TestCertifyGood(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -190,7 +190,7 @@ func TestCertifyGood(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -202,7 +202,7 @@ func TestCertifyGood(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -232,7 +232,7 @@ func TestCertifyGood(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -243,7 +243,7 @@ func TestCertifyGood(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P2, + Package: &model.IDorPkgInput{PackageInput: testdata.P2}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -254,7 +254,7 @@ func TestCertifyGood(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, + Source: &model.IDorSourceInput{SourceInput: testdata.S1}, }, CG: &model.CertifyGoodInputSpec{ Justification: "test justification", @@ -286,7 +286,7 @@ func TestCertifyGood(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P4, + Package: &model.IDorPkgInput{PackageInput: testdata.P4}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -311,7 +311,7 @@ func TestCertifyGood(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -322,7 +322,7 @@ func TestCertifyGood(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, + Source: &model.IDorSourceInput{SourceInput: testdata.S1}, }, CG: &model.CertifyGoodInputSpec{ Justification: "test justification", @@ -330,7 +330,7 @@ func TestCertifyGood(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S2, + Source: &model.IDorSourceInput{SourceInput: testdata.S2}, }, CG: &model.CertifyGoodInputSpec{ Justification: "test justification", @@ -358,7 +358,7 @@ func TestCertifyGood(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S2, + Source: &model.IDorSourceInput{SourceInput: testdata.S2}, }, CG: &model.CertifyGoodInputSpec{ Justification: "test justification", @@ -380,7 +380,7 @@ func TestCertifyGood(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A1, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A1}, }, CG: &model.CertifyGoodInputSpec{ Justification: "test justification", @@ -388,7 +388,7 @@ func TestCertifyGood(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A2}, }, CG: &model.CertifyGoodInputSpec{ Justification: "test justification", @@ -396,7 +396,7 @@ func TestCertifyGood(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, + Source: &model.IDorSourceInput{SourceInput: testdata.S1}, }, CG: &model.CertifyGoodInputSpec{ Justification: "test justification", @@ -424,7 +424,7 @@ func TestCertifyGood(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A1, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A1}, }, CG: &model.CertifyGoodInputSpec{ Justification: "test justification", @@ -432,7 +432,7 @@ func TestCertifyGood(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A2}, }, CG: &model.CertifyGoodInputSpec{ Justification: "test justification", @@ -453,7 +453,7 @@ func TestCertifyGood(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A1, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A1}, }, CG: &model.CertifyGoodInputSpec{ Justification: "test justification", @@ -461,7 +461,7 @@ func TestCertifyGood(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A2}, }, CG: &model.CertifyGoodInputSpec{ Justification: "test justification", @@ -483,7 +483,7 @@ func TestCertifyGood(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, + Source: &model.IDorSourceInput{SourceInput: testdata.S1}, }, CG: &model.CertifyGoodInputSpec{ Justification: "test justification", @@ -491,7 +491,7 @@ func TestCertifyGood(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S2, + Source: &model.IDorSourceInput{SourceInput: testdata.S2}, }, CG: &model.CertifyGoodInputSpec{ Justification: "test justification", @@ -522,7 +522,7 @@ func TestCertifyGood(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -533,7 +533,7 @@ func TestCertifyGood(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P2, + Package: &model.IDorPkgInput{PackageInput: testdata.P2}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -544,7 +544,7 @@ func TestCertifyGood(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P2, + Package: &model.IDorPkgInput{PackageInput: testdata.P2}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeAllVersions, @@ -579,7 +579,7 @@ func TestCertifyGood(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A1, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A1}, }, CG: &model.CertifyGoodInputSpec{ Justification: "test justification", @@ -587,7 +587,7 @@ func TestCertifyGood(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A2}, }, CG: &model.CertifyGoodInputSpec{ Justification: "test justification", @@ -606,7 +606,7 @@ func TestCertifyGood(t *testing.T) { for _, test := range tests { t.Run(test.Name, func(t *testing.T) { for _, p := range test.InPkg { - if pkgIDs, err := b.IngestPackage(ctx, *p); err != nil { + if pkgIDs, err := b.IngestPackage(ctx, model.IDorPkgInput{PackageInput: p}); err != nil { t.Fatalf("Could not ingest package: %v", err) } else { if test.QueryPkgID { @@ -621,7 +621,7 @@ func TestCertifyGood(t *testing.T) { } } for _, s := range test.InSrc { - if srcIDs, err := b.IngestSource(ctx, *s); err != nil { + if srcIDs, err := b.IngestSource(ctx, model.IDorSourceInput{SourceInput: s}); err != nil { t.Fatalf("Could not ingest source: %v", err) } else { if test.QuerySourceID { @@ -636,7 +636,7 @@ func TestCertifyGood(t *testing.T) { } } for _, a := range test.InArt { - if artID, err := b.IngestArtifact(ctx, a); err != nil { + if artID, err := b.IngestArtifact(ctx, &model.IDorArtifactInput{ArtifactInput: a}); err != nil { t.Fatalf("Could not ingest artifact: %v", err) } else { if test.QueryArtID { @@ -703,7 +703,7 @@ func TestIngestCertifyGoods(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1}, + Packages: []*model.IDorPkgInput{&model.IDorPkgInput{PackageInput: testdata.P1}}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -731,7 +731,7 @@ func TestIngestCertifyGoods(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1}, + Packages: []*model.IDorPkgInput{&model.IDorPkgInput{PackageInput: testdata.P1}}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeAllVersions, @@ -763,7 +763,7 @@ func TestIngestCertifyGoods(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1, testdata.P1}, + Packages: []*model.IDorPkgInput{{PackageInput: testdata.P1}, {PackageInput: testdata.P1}}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -799,7 +799,7 @@ func TestIngestCertifyGoods(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1, testdata.P2}, + Packages: []*model.IDorPkgInput{{PackageInput: testdata.P1}, {PackageInput: testdata.P2}}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -815,7 +815,7 @@ func TestIngestCertifyGoods(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{testdata.S1}, + Sources: []*model.IDorSourceInput{&model.IDorSourceInput{SourceInput: testdata.S1}}, }, CG: []*model.CertifyGoodInputSpec{ { @@ -849,7 +849,7 @@ func TestIngestCertifyGoods(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1}, + Packages: []*model.IDorPkgInput{&model.IDorPkgInput{PackageInput: testdata.P1}}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -862,7 +862,7 @@ func TestIngestCertifyGoods(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{testdata.S2, testdata.S2}, + Sources: []*model.IDorSourceInput{{SourceInput: testdata.S2}, {SourceInput: testdata.S2}}, }, CG: []*model.CertifyGoodInputSpec{ { @@ -895,7 +895,7 @@ func TestIngestCertifyGoods(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInputs{ - Artifacts: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, + Artifacts: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}, {ArtifactInput: testdata.A2}}, }, CG: []*model.CertifyGoodInputSpec{ { @@ -908,7 +908,7 @@ func TestIngestCertifyGoods(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{testdata.S1}, + Sources: []*model.IDorSourceInput{&model.IDorSourceInput{SourceInput: testdata.S1}}, }, CG: []*model.CertifyGoodInputSpec{ { @@ -935,17 +935,17 @@ func TestIngestCertifyGoods(t *testing.T) { for _, test := range tests { t.Run(test.Name, func(t *testing.T) { for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { + if _, err := b.IngestPackage(ctx, model.IDorPkgInput{PackageInput: p}); err != nil { t.Fatalf("Could not ingest package: %v", err) } } for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { + if _, err := b.IngestSource(ctx, model.IDorSourceInput{SourceInput: s}); err != nil { t.Fatalf("Could not ingest source: %v", err) } } for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { + if _, err := b.IngestArtifact(ctx, &model.IDorArtifactInput{ArtifactInput: a}); err != nil { t.Fatalf("Could not ingest artifact: %v", err) } } diff --git a/internal/testing/backend/certifyLegal_test.go b/internal/testing/backend/certifyLegal_test.go index ed240eb852..066aac4d9f 100644 --- a/internal/testing/backend/certifyLegal_test.go +++ b/internal/testing/backend/certifyLegal_test.go @@ -49,8 +49,8 @@ func TestLegal(t *testing.T) { b := setupTest(t) type call struct { PkgSrc model.PackageOrSourceInput - Dec []*model.LicenseInputSpec - Dis []*model.LicenseInputSpec + Dec []*model.IDorLicenseInput + Dis []*model.IDorLicenseInput Legal *model.CertifyLegalInputSpec } tests := []struct { @@ -72,9 +72,9 @@ func TestLegal(t *testing.T) { Calls: []call{ { PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, - Dec: []*model.LicenseInputSpec{testdata.L1}, + Dec: []*model.IDorLicenseInput{{LicenseInput: testdata.L1}}, Legal: &model.CertifyLegalInputSpec{ Justification: "test justification", }, @@ -98,18 +98,18 @@ func TestLegal(t *testing.T) { Calls: []call{ { PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, - Dec: []*model.LicenseInputSpec{testdata.L1}, + Dec: []*model.IDorLicenseInput{{LicenseInput: testdata.L1}}, Legal: &model.CertifyLegalInputSpec{ Justification: "test justification", }, }, { PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, - Dec: []*model.LicenseInputSpec{testdata.L1}, + Dec: []*model.IDorLicenseInput{{LicenseInput: testdata.L1}}, Legal: &model.CertifyLegalInputSpec{ Justification: "test justification", }, @@ -133,18 +133,18 @@ func TestLegal(t *testing.T) { Calls: []call{ { PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, - Dec: []*model.LicenseInputSpec{testdata.L1}, + Dec: []*model.IDorLicenseInput{{LicenseInput: testdata.L1}}, Legal: &model.CertifyLegalInputSpec{ Justification: "test justification", }, }, { PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, - Dec: []*model.LicenseInputSpec{testdata.L1}, + Dec: []*model.IDorLicenseInput{{LicenseInput: testdata.L1}}, Legal: &model.CertifyLegalInputSpec{ Justification: "test justification 2", }, @@ -168,18 +168,18 @@ func TestLegal(t *testing.T) { Calls: []call{ { PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, - Dec: []*model.LicenseInputSpec{testdata.L1}, + Dec: []*model.IDorLicenseInput{{LicenseInput: testdata.L1}}, Legal: &model.CertifyLegalInputSpec{ Justification: "test justification", }, }, { PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, - Dec: []*model.LicenseInputSpec{testdata.L1}, + Dec: []*model.IDorLicenseInput{{LicenseInput: testdata.L1}}, Legal: &model.CertifyLegalInputSpec{ Justification: "test justification 2", }, @@ -202,18 +202,18 @@ func TestLegal(t *testing.T) { Calls: []call{ { PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, - Dec: []*model.LicenseInputSpec{testdata.L1}, + Dec: []*model.IDorLicenseInput{{LicenseInput: testdata.L1}}, Legal: &model.CertifyLegalInputSpec{ Justification: "test justification", }, }, { PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P2, + Package: &model.IDorPkgInput{PackageInput: testdata.P2}, }, - Dec: []*model.LicenseInputSpec{testdata.L1}, + Dec: []*model.IDorLicenseInput{{LicenseInput: testdata.L1}}, Legal: &model.CertifyLegalInputSpec{ Justification: "test justification", }, @@ -241,18 +241,18 @@ func TestLegal(t *testing.T) { Calls: []call{ { PkgSrc: model.PackageOrSourceInput{ - Source: testdata.S1, + Source: &model.IDorSourceInput{SourceInput: testdata.S1}, }, - Dec: []*model.LicenseInputSpec{testdata.L1}, + Dec: []*model.IDorLicenseInput{{LicenseInput: testdata.L1}}, Legal: &model.CertifyLegalInputSpec{ Justification: "test justification", }, }, { PkgSrc: model.PackageOrSourceInput{ - Source: testdata.S2, + Source: &model.IDorSourceInput{SourceInput: testdata.S2}, }, - Dec: []*model.LicenseInputSpec{testdata.L1}, + Dec: []*model.IDorLicenseInput{{LicenseInput: testdata.L1}}, Legal: &model.CertifyLegalInputSpec{ Justification: "test justification", }, @@ -280,18 +280,18 @@ func TestLegal(t *testing.T) { Calls: []call{ { PkgSrc: model.PackageOrSourceInput{ - Source: testdata.S1, + Source: &model.IDorSourceInput{SourceInput: testdata.S1}, }, - Dec: []*model.LicenseInputSpec{testdata.L1, testdata.L2}, + Dec: []*model.IDorLicenseInput{{LicenseInput: testdata.L1}, {LicenseInput: testdata.L2}}, Legal: &model.CertifyLegalInputSpec{ Justification: "test justification", }, }, { PkgSrc: model.PackageOrSourceInput{ - Source: testdata.S1, + Source: &model.IDorSourceInput{SourceInput: testdata.S1}, }, - Dec: []*model.LicenseInputSpec{testdata.L3}, + Dec: []*model.IDorLicenseInput{{LicenseInput: testdata.L3}}, Legal: &model.CertifyLegalInputSpec{ Justification: "test justification", }, @@ -317,18 +317,18 @@ func TestLegal(t *testing.T) { Calls: []call{ { PkgSrc: model.PackageOrSourceInput{ - Source: testdata.S1, + Source: &model.IDorSourceInput{SourceInput: testdata.S1}, }, - Dec: []*model.LicenseInputSpec{testdata.L1, testdata.L4}, + Dec: []*model.IDorLicenseInput{{LicenseInput: testdata.L1}, {LicenseInput: testdata.L4}}, Legal: &model.CertifyLegalInputSpec{ Justification: "test justification", }, }, { PkgSrc: model.PackageOrSourceInput{ - Source: testdata.S1, + Source: &model.IDorSourceInput{SourceInput: testdata.S1}, }, - Dec: []*model.LicenseInputSpec{testdata.L2}, + Dec: []*model.IDorLicenseInput{{LicenseInput: testdata.L2}}, Legal: &model.CertifyLegalInputSpec{ Justification: "test justification", }, @@ -353,7 +353,7 @@ func TestLegal(t *testing.T) { Calls: []call{ { PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Legal: &model.CertifyLegalInputSpec{ DeclaredLicense: "GPL OR MIT", @@ -361,7 +361,7 @@ func TestLegal(t *testing.T) { }, { PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Legal: &model.CertifyLegalInputSpec{ DeclaredLicense: "GPL AND MIT", @@ -384,7 +384,7 @@ func TestLegal(t *testing.T) { Calls: []call{ { PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Legal: &model.CertifyLegalInputSpec{ Attribution: "Copyright Jeff", @@ -392,7 +392,7 @@ func TestLegal(t *testing.T) { }, { PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Legal: &model.CertifyLegalInputSpec{ Attribution: "Copyright Bob", @@ -415,7 +415,7 @@ func TestLegal(t *testing.T) { Calls: []call{ { PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Legal: &model.CertifyLegalInputSpec{ TimeScanned: testdata.T3, @@ -423,7 +423,7 @@ func TestLegal(t *testing.T) { }, { PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Legal: &model.CertifyLegalInputSpec{ TimeScanned: testdata.T2, @@ -447,27 +447,27 @@ func TestLegal(t *testing.T) { Calls: []call{ { PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, - Dec: []*model.LicenseInputSpec{testdata.L1}, + Dec: []*model.IDorLicenseInput{{LicenseInput: testdata.L1}}, Legal: &model.CertifyLegalInputSpec{ Justification: "test justification special", }, }, { PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P2, + Package: &model.IDorPkgInput{PackageInput: testdata.P2}, }, - Dec: []*model.LicenseInputSpec{testdata.L1}, + Dec: []*model.IDorLicenseInput{{LicenseInput: testdata.L1}}, Legal: &model.CertifyLegalInputSpec{ Justification: "test justification special", }, }, { PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P3, + Package: &model.IDorPkgInput{PackageInput: testdata.P3}, }, - Dec: []*model.LicenseInputSpec{testdata.L1}, + Dec: []*model.IDorLicenseInput{{LicenseInput: testdata.L1}}, Legal: &model.CertifyLegalInputSpec{ Justification: "test justification other", }, @@ -519,7 +519,7 @@ func TestLegal(t *testing.T) { // Calls: []call{ // { // PkgSrc: model.PackageOrSourceInput{ - // Package: testdata.P1, + // Package: &model.IDorPkgInput{PackageInput: testdata.P1}, // }, // Dec: []*model.LicenseInputSpec{lNone}, // Legal: &model.CertifyLegalInputSpec{}, @@ -531,17 +531,17 @@ func TestLegal(t *testing.T) { for _, test := range tests { t.Run(test.Name, func(t *testing.T) { for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { + if _, err := b.IngestPackage(ctx, model.IDorPkgInput{PackageInput: p}); err != nil { t.Fatalf("Could not ingest package: %v", err) } } for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { + if _, err := b.IngestSource(ctx, model.IDorSourceInput{SourceInput: s}); err != nil { t.Fatalf("Could not ingest source: %v", err) } } for _, a := range test.InLic { - if _, err := b.IngestLicense(ctx, a); err != nil { + if _, err := b.IngestLicense(ctx, &model.IDorLicenseInput{LicenseInput: a}); err != nil { t.Fatalf("Could not ingest license: %v", err) } } @@ -576,8 +576,8 @@ func TestLegals(t *testing.T) { b := setupTest(t) type call struct { PkgSrc model.PackageOrSourceInputs - Dec [][]*model.LicenseInputSpec - Dis [][]*model.LicenseInputSpec + Dec [][]*model.IDorLicenseInput + Dis [][]*model.IDorLicenseInput Legal []*model.CertifyLegalInputSpec } tests := []struct { @@ -598,10 +598,10 @@ func TestLegals(t *testing.T) { Calls: []call{ { PkgSrc: model.PackageOrSourceInputs{ - Packages: []*model.PkgInputSpec{testdata.P1, testdata.P2}, + Packages: []*model.IDorPkgInput{{PackageInput: testdata.P1}, {PackageInput: testdata.P2}}, }, - Dec: [][]*model.LicenseInputSpec{{testdata.L1}, {testdata.L1}}, - Dis: [][]*model.LicenseInputSpec{{}, {}}, + Dec: [][]*model.IDorLicenseInput{{{LicenseInput: testdata.L1}}, {{LicenseInput: testdata.L1}}}, + Dis: [][]*model.IDorLicenseInput{{}, {}}, Legal: []*model.CertifyLegalInputSpec{ {Justification: "test justification"}, {Justification: "test justification"}, @@ -628,17 +628,17 @@ func TestLegals(t *testing.T) { for _, test := range tests { t.Run(test.Name, func(t *testing.T) { for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { + if _, err := b.IngestPackage(ctx, model.IDorPkgInput{PackageInput: p}); err != nil { t.Fatalf("Could not ingest package: %v", err) } } for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { + if _, err := b.IngestSource(ctx, model.IDorSourceInput{SourceInput: s}); err != nil { t.Fatalf("Could not ingest source: %v", err) } } for _, a := range test.InLic { - if _, err := b.IngestLicense(ctx, a); err != nil { + if _, err := b.IngestLicense(ctx, &model.IDorLicenseInput{LicenseInput: a}); err != nil { t.Fatalf("Could not ingest license: %v", err) } } diff --git a/internal/testing/backend/certifyScorecard_test.go b/internal/testing/backend/certifyScorecard_test.go index 29e874670b..f1dca2d661 100644 --- a/internal/testing/backend/certifyScorecard_test.go +++ b/internal/testing/backend/certifyScorecard_test.go @@ -483,7 +483,7 @@ func TestCertifyScorecard(t *testing.T) { for _, test := range tests { t.Run(test.Name, func(t *testing.T) { for _, s := range test.InSrc { - if srcID, err := b.IngestSource(ctx, *s); err != nil { + if srcID, err := b.IngestSource(ctx, model.IDorSourceInput{SourceInput: s}); err != nil { t.Fatalf("Could not ingest source: %v", err) } else { if test.QuerySourceID { @@ -497,7 +497,7 @@ func TestCertifyScorecard(t *testing.T) { } } for _, o := range test.Calls { - scoreID, err := b.IngestScorecard(ctx, *o.Src, *o.SC) + scoreID, err := b.IngestScorecard(ctx, model.IDorSourceInput{SourceInput: o.Src}, *o.SC) if (err != nil) != test.ExpIngestErr { t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) } @@ -528,7 +528,7 @@ func TestIngestScorecards(t *testing.T) { ctx := context.Background() b := setupTest(t) type call struct { - Src []*model.SourceInputSpec + Src []*model.IDorSourceInput SC []*model.ScorecardInputSpec } tests := []struct { @@ -545,7 +545,7 @@ func TestIngestScorecards(t *testing.T) { InSrc: []*model.SourceInputSpec{testdata.S1}, Calls: []call{ { - Src: []*model.SourceInputSpec{testdata.S1}, + Src: []*model.IDorSourceInput{{SourceInput: testdata.S1}}, SC: []*model.ScorecardInputSpec{ { Origin: "test origin", @@ -571,7 +571,7 @@ func TestIngestScorecards(t *testing.T) { InSrc: []*model.SourceInputSpec{testdata.S1}, Calls: []call{ { - Src: []*model.SourceInputSpec{testdata.S1, testdata.S1}, + Src: []*model.IDorSourceInput{{SourceInput: testdata.S1}, {SourceInput: testdata.S1}}, SC: []*model.ScorecardInputSpec{ { Origin: "test origin", @@ -600,7 +600,7 @@ func TestIngestScorecards(t *testing.T) { InSrc: []*model.SourceInputSpec{testdata.S1}, Calls: []call{ { - Src: []*model.SourceInputSpec{testdata.S1, testdata.S1, testdata.S1}, + Src: []*model.IDorSourceInput{{SourceInput: testdata.S1}, {SourceInput: testdata.S1}, {SourceInput: testdata.S1}}, SC: []*model.ScorecardInputSpec{ { Origin: "test origin one", @@ -643,7 +643,7 @@ func TestIngestScorecards(t *testing.T) { InSrc: []*model.SourceInputSpec{testdata.S1, testdata.S2}, Calls: []call{ { - Src: []*model.SourceInputSpec{testdata.S1, testdata.S2}, + Src: []*model.IDorSourceInput{{SourceInput: testdata.S1}, {SourceInput: testdata.S2}}, SC: []*model.ScorecardInputSpec{ { Origin: "test origin", @@ -696,7 +696,7 @@ func TestIngestScorecards(t *testing.T) { for _, test := range tests { t.Run(test.Name, func(t *testing.T) { for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { + if _, err := b.IngestSource(ctx, model.IDorSourceInput{SourceInput: s}); err != nil { t.Fatalf("Could not ingest source: %v", err) } } diff --git a/internal/testing/backend/certifyVEXStatement_test.go b/internal/testing/backend/certifyVEXStatement_test.go index 25b68cf992..18b0f1fd35 100644 --- a/internal/testing/backend/certifyVEXStatement_test.go +++ b/internal/testing/backend/certifyVEXStatement_test.go @@ -58,7 +58,7 @@ func TestVEX(t *testing.T) { Calls: []call{ { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Vuln: testdata.O1, In: &model.VexStatementInputSpec{ @@ -89,7 +89,7 @@ func TestVEX(t *testing.T) { Calls: []call{ { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Vuln: testdata.O1, In: &model.VexStatementInputSpec{ @@ -99,7 +99,7 @@ func TestVEX(t *testing.T) { }, { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Vuln: testdata.O1, In: &model.VexStatementInputSpec{ @@ -130,7 +130,7 @@ func TestVEX(t *testing.T) { Calls: []call{ { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Vuln: testdata.O1, In: &model.VexStatementInputSpec{ @@ -140,7 +140,7 @@ func TestVEX(t *testing.T) { }, { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Vuln: testdata.O1, In: &model.VexStatementInputSpec{ @@ -172,7 +172,7 @@ func TestVEX(t *testing.T) { Calls: []call{ { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Vuln: testdata.O1, In: &model.VexStatementInputSpec{ @@ -182,7 +182,7 @@ func TestVEX(t *testing.T) { }, { Sub: model.PackageOrArtifactInput{ - Package: testdata.P2, + Package: &model.IDorPkgInput{PackageInput: testdata.P2}, }, Vuln: testdata.O1, In: &model.VexStatementInputSpec{ @@ -192,7 +192,7 @@ func TestVEX(t *testing.T) { }, { Sub: model.PackageOrArtifactInput{ - Artifact: testdata.A1, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A1}, }, Vuln: testdata.O1, In: &model.VexStatementInputSpec{ @@ -237,7 +237,7 @@ func TestVEX(t *testing.T) { Calls: []call{ { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Vuln: testdata.O1, In: &model.VexStatementInputSpec{ @@ -247,7 +247,7 @@ func TestVEX(t *testing.T) { }, { Sub: model.PackageOrArtifactInput{ - Package: testdata.P2, + Package: &model.IDorPkgInput{PackageInput: testdata.P2}, }, Vuln: testdata.O1, In: &model.VexStatementInputSpec{ @@ -257,7 +257,7 @@ func TestVEX(t *testing.T) { }, { Sub: model.PackageOrArtifactInput{ - Artifact: testdata.A1, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A1}, }, Vuln: testdata.O1, In: &model.VexStatementInputSpec{ @@ -287,7 +287,7 @@ func TestVEX(t *testing.T) { Calls: []call{ { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Vuln: testdata.O1, In: &model.VexStatementInputSpec{ @@ -297,7 +297,7 @@ func TestVEX(t *testing.T) { }, { Sub: model.PackageOrArtifactInput{ - Artifact: testdata.A1, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A1}, }, Vuln: testdata.O1, In: &model.VexStatementInputSpec{ @@ -307,7 +307,7 @@ func TestVEX(t *testing.T) { }, { Sub: model.PackageOrArtifactInput{ - Artifact: testdata.A2, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A2}, }, Vuln: testdata.O1, In: &model.VexStatementInputSpec{ @@ -343,7 +343,7 @@ func TestVEX(t *testing.T) { Calls: []call{ { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Vuln: testdata.O1, In: &model.VexStatementInputSpec{ @@ -353,7 +353,7 @@ func TestVEX(t *testing.T) { }, { Sub: model.PackageOrArtifactInput{ - Artifact: testdata.A1, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A1}, }, Vuln: testdata.O1, In: &model.VexStatementInputSpec{ @@ -363,7 +363,7 @@ func TestVEX(t *testing.T) { }, { Sub: model.PackageOrArtifactInput{ - Artifact: testdata.A2, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A2}, }, Vuln: testdata.O1, In: &model.VexStatementInputSpec{ @@ -392,7 +392,7 @@ func TestVEX(t *testing.T) { Calls: []call{ { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Vuln: testdata.O1, In: &model.VexStatementInputSpec{ @@ -402,7 +402,7 @@ func TestVEX(t *testing.T) { }, { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Vuln: testdata.O2, In: &model.VexStatementInputSpec{ @@ -412,7 +412,7 @@ func TestVEX(t *testing.T) { }, { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Vuln: testdata.C1, In: &model.VexStatementInputSpec{ @@ -482,7 +482,7 @@ func TestVEX(t *testing.T) { Calls: []call{ { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Vuln: testdata.O1, In: &model.VexStatementInputSpec{ @@ -492,7 +492,7 @@ func TestVEX(t *testing.T) { }, { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Vuln: testdata.O2, In: &model.VexStatementInputSpec{ @@ -502,7 +502,7 @@ func TestVEX(t *testing.T) { }, { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Vuln: testdata.C1, In: &model.VexStatementInputSpec{ @@ -531,7 +531,7 @@ func TestVEX(t *testing.T) { Calls: []call{ { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Vuln: testdata.C1, In: &model.VexStatementInputSpec{ @@ -542,7 +542,7 @@ func TestVEX(t *testing.T) { }, { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Vuln: testdata.O1, In: &model.VexStatementInputSpec{ @@ -575,7 +575,7 @@ func TestVEX(t *testing.T) { Calls: []call{ { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Vuln: testdata.C1, In: &model.VexStatementInputSpec{ @@ -586,7 +586,7 @@ func TestVEX(t *testing.T) { }, { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Vuln: testdata.O1, In: &model.VexStatementInputSpec{ @@ -619,7 +619,7 @@ func TestVEX(t *testing.T) { Calls: []call{ { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Vuln: testdata.O1, In: &model.VexStatementInputSpec{ @@ -630,7 +630,7 @@ func TestVEX(t *testing.T) { }, { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Vuln: testdata.O1, In: &model.VexStatementInputSpec{ @@ -663,7 +663,7 @@ func TestVEX(t *testing.T) { Calls: []call{ { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Vuln: testdata.O1, In: &model.VexStatementInputSpec{ @@ -673,7 +673,7 @@ func TestVEX(t *testing.T) { }, { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Vuln: testdata.O1, In: &model.VexStatementInputSpec{ @@ -704,7 +704,7 @@ func TestVEX(t *testing.T) { Calls: []call{ { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Vuln: testdata.O1, In: &model.VexStatementInputSpec{ @@ -714,7 +714,7 @@ func TestVEX(t *testing.T) { }, { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Vuln: testdata.O2, In: &model.VexStatementInputSpec{ @@ -743,7 +743,7 @@ func TestVEX(t *testing.T) { Calls: []call{ { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Vuln: testdata.O1, In: &model.VexStatementInputSpec{ @@ -753,7 +753,7 @@ func TestVEX(t *testing.T) { }, { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Vuln: testdata.O2, In: &model.VexStatementInputSpec{ @@ -763,7 +763,7 @@ func TestVEX(t *testing.T) { }, { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Vuln: testdata.C1, In: &model.VexStatementInputSpec{ @@ -786,7 +786,7 @@ func TestVEX(t *testing.T) { Calls: []call{ { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Vuln: testdata.O1, In: &model.VexStatementInputSpec{ @@ -796,7 +796,7 @@ func TestVEX(t *testing.T) { }, { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Vuln: testdata.O2, In: &model.VexStatementInputSpec{ @@ -806,7 +806,7 @@ func TestVEX(t *testing.T) { }, { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Vuln: testdata.C1, In: &model.VexStatementInputSpec{ @@ -843,7 +843,7 @@ func TestVEX(t *testing.T) { for _, test := range tests { t.Run(test.Name, func(t *testing.T) { for _, p := range test.InPkg { - if pkgIDs, err := b.IngestPackage(ctx, *p); err != nil { + if pkgIDs, err := b.IngestPackage(ctx, model.IDorPkgInput{PackageInput: p}); err != nil { t.Fatalf("Could not ingest package: %v", err) } else { if test.QueryPkgID { @@ -858,7 +858,7 @@ func TestVEX(t *testing.T) { } } for _, a := range test.InArt { - if artID, err := b.IngestArtifact(ctx, a); err != nil { + if artID, err := b.IngestArtifact(ctx, &model.IDorArtifactInput{ArtifactInput: a}); err != nil { t.Fatalf("Could not ingest artifact: %a", err) } else { if test.QueryArtID { @@ -873,7 +873,7 @@ func TestVEX(t *testing.T) { } } for _, v := range test.InVuln { - if vulnIDs, err := b.IngestVulnerability(ctx, *v); err != nil { + if vulnIDs, err := b.IngestVulnerability(ctx, model.IDorVulnerabilityInput{VulnerabilityInput: v}); err != nil { t.Fatalf("Could not ingest vulnerability: %v", err) } else { if test.QueryVulnID { @@ -886,7 +886,7 @@ func TestVEX(t *testing.T) { } } for _, o := range test.Calls { - vexID, err := b.IngestVEXStatement(ctx, o.Sub, *o.Vuln, *o.In) + vexID, err := b.IngestVEXStatement(ctx, o.Sub, model.IDorVulnerabilityInput{VulnerabilityInput: o.Vuln}, *o.In) if (err != nil) != test.ExpIngestErr { t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) } @@ -918,7 +918,7 @@ func TestVEXBulkIngest(t *testing.T) { b := setupTest(t) type call struct { Subs model.PackageOrArtifactInputs - Vulns []*model.VulnerabilityInputSpec + Vulns []*model.IDorVulnerabilityInput Vexs []*model.VexStatementInputSpec } tests := []struct { @@ -939,9 +939,9 @@ func TestVEXBulkIngest(t *testing.T) { Calls: []call{ { Subs: model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1}, + Packages: []*model.IDorPkgInput{&model.IDorPkgInput{PackageInput: testdata.P1}}, }, - Vulns: []*model.VulnerabilityInputSpec{testdata.O1}, + Vulns: []*model.IDorVulnerabilityInput{{VulnerabilityInput: testdata.O1}}, Vexs: []*model.VexStatementInputSpec{ { VexJustification: "test justification", @@ -972,9 +972,9 @@ func TestVEXBulkIngest(t *testing.T) { Calls: []call{ { Subs: model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1, testdata.P1}, + Packages: []*model.IDorPkgInput{{PackageInput: testdata.P1}, {PackageInput: testdata.P1}}, }, - Vulns: []*model.VulnerabilityInputSpec{testdata.O1, testdata.O1}, + Vulns: []*model.IDorVulnerabilityInput{{VulnerabilityInput: testdata.O1}, {VulnerabilityInput: testdata.O1}}, Vexs: []*model.VexStatementInputSpec{ { VexJustification: "test justification", @@ -1010,9 +1010,9 @@ func TestVEXBulkIngest(t *testing.T) { Calls: []call{ { Subs: model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1, testdata.P2}, + Packages: []*model.IDorPkgInput{{PackageInput: testdata.P1}, {PackageInput: testdata.P2}}, }, - Vulns: []*model.VulnerabilityInputSpec{testdata.O1, testdata.O1}, + Vulns: []*model.IDorVulnerabilityInput{{VulnerabilityInput: testdata.O1}, {VulnerabilityInput: testdata.O1}}, Vexs: []*model.VexStatementInputSpec{ { VexJustification: "test justification", @@ -1026,9 +1026,9 @@ func TestVEXBulkIngest(t *testing.T) { }, { Subs: model.PackageOrArtifactInputs{ - Artifacts: []*model.ArtifactInputSpec{testdata.A1}, + Artifacts: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}}, }, - Vulns: []*model.VulnerabilityInputSpec{testdata.O1}, + Vulns: []*model.IDorVulnerabilityInput{{VulnerabilityInput: testdata.O1}}, Vexs: []*model.VexStatementInputSpec{ { VexJustification: "test justification", @@ -1063,9 +1063,9 @@ func TestVEXBulkIngest(t *testing.T) { Calls: []call{ { Subs: model.PackageOrArtifactInputs{ - Artifacts: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, + Artifacts: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}, {ArtifactInput: testdata.A2}}, }, - Vulns: []*model.VulnerabilityInputSpec{testdata.O1, testdata.O1}, + Vulns: []*model.IDorVulnerabilityInput{{VulnerabilityInput: testdata.O1}, {VulnerabilityInput: testdata.O1}}, Vexs: []*model.VexStatementInputSpec{ { VexJustification: "test justification", @@ -1104,9 +1104,9 @@ func TestVEXBulkIngest(t *testing.T) { Calls: []call{ { Subs: model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1, testdata.P1, testdata.P1}, + Packages: []*model.IDorPkgInput{{PackageInput: testdata.P1}, {PackageInput: testdata.P1}, {PackageInput: testdata.P1}}, }, - Vulns: []*model.VulnerabilityInputSpec{testdata.O1, testdata.O2, testdata.C1}, + Vulns: []*model.IDorVulnerabilityInput{{VulnerabilityInput: testdata.O1}, {VulnerabilityInput: testdata.O2}, {VulnerabilityInput: testdata.C1}}, Vexs: []*model.VexStatementInputSpec{ { VexJustification: "test justification", @@ -1175,9 +1175,9 @@ func TestVEXBulkIngest(t *testing.T) { Calls: []call{ { Subs: model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1, testdata.P1}, + Packages: []*model.IDorPkgInput{{PackageInput: testdata.P1}, {PackageInput: testdata.P1}}, }, - Vulns: []*model.VulnerabilityInputSpec{testdata.C1, testdata.O1}, + Vulns: []*model.IDorVulnerabilityInput{{VulnerabilityInput: testdata.C1}, {VulnerabilityInput: testdata.O1}}, Vexs: []*model.VexStatementInputSpec{ { VexJustification: "test justification", @@ -1214,9 +1214,9 @@ func TestVEXBulkIngest(t *testing.T) { Calls: []call{ { Subs: model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1, testdata.P1, testdata.P1}, + Packages: []*model.IDorPkgInput{{PackageInput: testdata.P1}, {PackageInput: testdata.P1}, {PackageInput: testdata.P1}}, }, - Vulns: []*model.VulnerabilityInputSpec{testdata.O1, testdata.O2, testdata.C1}, + Vulns: []*model.IDorVulnerabilityInput{{VulnerabilityInput: testdata.O1}, {VulnerabilityInput: testdata.O2}, {VulnerabilityInput: testdata.C1}}, Vexs: []*model.VexStatementInputSpec{ { VexJustification: "test justification", @@ -1260,16 +1260,20 @@ func TestVEXBulkIngest(t *testing.T) { } for _, test := range tests { t.Run(test.Name, func(t *testing.T) { - if _, err := b.IngestPackages(ctx, test.InPkg); err != nil { - t.Fatalf("Could not ingest package: %v", err) + for _, p := range test.InPkg { + if _, err := b.IngestPackage(ctx, model.IDorPkgInput{PackageInput: p}); err != nil { + t.Fatalf("Could not ingest package: %v", err) + } } - - if _, err := b.IngestArtifacts(ctx, test.InArt); err != nil { - t.Fatalf("Could not ingest artifact: %a", err) + for _, a := range test.InArt { + if _, err := b.IngestArtifact(ctx, &model.IDorArtifactInput{ArtifactInput: a}); err != nil { + t.Fatalf("Could not ingest artifact: %a", err) + } } - - if _, err := b.IngestVulnerabilities(ctx, test.InVuln); err != nil { - t.Fatalf("Could not ingest vulnerability: %v", err) + for _, v := range test.InVuln { + if _, err := b.IngestVulnerability(ctx, model.IDorVulnerabilityInput{VulnerabilityInput: v}); err != nil { + t.Fatalf("Could not ingest vulnerability: %v", err) + } } for _, o := range test.Calls { _, err := b.IngestVEXStatements(ctx, o.Subs, o.Vulns, o.Vexs) diff --git a/internal/testing/backend/certifyVuln_test.go b/internal/testing/backend/certifyVuln_test.go index 9bdd592363..a669ca731f 100644 --- a/internal/testing/backend/certifyVuln_test.go +++ b/internal/testing/backend/certifyVuln_test.go @@ -47,7 +47,7 @@ func TestIngestCertifyVulnerability(t *testing.T) { CertifyVuln *model.ScanMetadataInput } tests := []struct { - InPkg []*model.PkgInputSpec + InPkg []*model.IDorPkgInput Name string InVuln []*model.VulnerabilityInputSpec Calls []call @@ -62,7 +62,7 @@ func TestIngestCertifyVulnerability(t *testing.T) { { Name: "HappyPath", InVuln: []*model.VulnerabilityInputSpec{testdata.C1}, - InPkg: []*model.PkgInputSpec{testdata.P2}, + InPkg: []*model.IDorPkgInput{{PackageInput: testdata.P2}}, Calls: []call{ { Pkg: testdata.P2, @@ -96,7 +96,7 @@ func TestIngestCertifyVulnerability(t *testing.T) { { Name: "Certify NoVuln", InVuln: []*model.VulnerabilityInputSpec{testdata.NoVulnInput}, - InPkg: []*model.PkgInputSpec{testdata.P2}, + InPkg: []*model.IDorPkgInput{{PackageInput: testdata.P2}}, Calls: []call{ { Pkg: testdata.P2, @@ -131,7 +131,7 @@ func TestIngestCertifyVulnerability(t *testing.T) { { Name: "Certify OSV", InVuln: []*model.VulnerabilityInputSpec{testdata.O1}, - InPkg: []*model.PkgInputSpec{testdata.P2}, + InPkg: []*model.IDorPkgInput{{PackageInput: testdata.P2}}, Calls: []call{ { Pkg: testdata.P2, @@ -166,7 +166,7 @@ func TestIngestCertifyVulnerability(t *testing.T) { { Name: "Certify GHSA", InVuln: []*model.VulnerabilityInputSpec{testdata.G1}, - InPkg: []*model.PkgInputSpec{testdata.P2}, + InPkg: []*model.IDorPkgInput{{PackageInput: testdata.P2}}, Calls: []call{ { Pkg: testdata.P2, @@ -201,7 +201,7 @@ func TestIngestCertifyVulnerability(t *testing.T) { { Name: "Query on GHSA", InVuln: []*model.VulnerabilityInputSpec{testdata.G1}, - InPkg: []*model.PkgInputSpec{testdata.P2}, + InPkg: []*model.IDorPkgInput{{PackageInput: testdata.P2}}, Calls: []call{ { Pkg: testdata.P2, @@ -236,7 +236,7 @@ func TestIngestCertifyVulnerability(t *testing.T) { { Name: "Query on Vulnerability ID", InVuln: []*model.VulnerabilityInputSpec{testdata.G1}, - InPkg: []*model.PkgInputSpec{testdata.P2}, + InPkg: []*model.IDorPkgInput{{PackageInput: testdata.P2}}, Calls: []call{ { Pkg: testdata.P2, @@ -267,7 +267,7 @@ func TestIngestCertifyVulnerability(t *testing.T) { { Name: "Query ID", InVuln: []*model.VulnerabilityInputSpec{testdata.G1}, - InPkg: []*model.PkgInputSpec{testdata.P2}, + InPkg: []*model.IDorPkgInput{{PackageInput: testdata.P2}}, Calls: []call{ { Pkg: testdata.P2, @@ -298,7 +298,7 @@ func TestIngestCertifyVulnerability(t *testing.T) { { Name: "Query DbURI", InVuln: []*model.VulnerabilityInputSpec{testdata.G1}, - InPkg: []*model.PkgInputSpec{testdata.P2}, + InPkg: []*model.IDorPkgInput{{PackageInput: testdata.P2}}, Calls: []call{ { Pkg: testdata.P2, @@ -339,7 +339,7 @@ func TestIngestCertifyVulnerability(t *testing.T) { { Name: "Query DB Version", InVuln: []*model.VulnerabilityInputSpec{testdata.G1}, - InPkg: []*model.PkgInputSpec{testdata.P2}, + InPkg: []*model.IDorPkgInput{{PackageInput: testdata.P2}}, Calls: []call{ { Pkg: testdata.P2, @@ -380,7 +380,7 @@ func TestIngestCertifyVulnerability(t *testing.T) { { Name: "Query TimeScanned", InVuln: []*model.VulnerabilityInputSpec{testdata.G1}, - InPkg: []*model.PkgInputSpec{testdata.P2}, + InPkg: []*model.IDorPkgInput{{PackageInput: testdata.P2}}, Calls: []call{ { Pkg: testdata.P2, @@ -421,7 +421,7 @@ func TestIngestCertifyVulnerability(t *testing.T) { { Name: "Query ScannerURI", InVuln: []*model.VulnerabilityInputSpec{testdata.G1}, - InPkg: []*model.PkgInputSpec{testdata.P2}, + InPkg: []*model.IDorPkgInput{{PackageInput: testdata.P2}}, Calls: []call{ { Pkg: testdata.P2, @@ -462,7 +462,7 @@ func TestIngestCertifyVulnerability(t *testing.T) { { Name: "Query ScannerVersion", InVuln: []*model.VulnerabilityInputSpec{testdata.G1}, - InPkg: []*model.PkgInputSpec{testdata.P2}, + InPkg: []*model.IDorPkgInput{{PackageInput: testdata.P2}}, Calls: []call{ { Pkg: testdata.P2, @@ -503,7 +503,7 @@ func TestIngestCertifyVulnerability(t *testing.T) { { Name: "Query on Package", InVuln: []*model.VulnerabilityInputSpec{testdata.G1}, - InPkg: []*model.PkgInputSpec{testdata.P3}, + InPkg: []*model.IDorPkgInput{{PackageInput: testdata.P3}}, Calls: []call{ { Pkg: testdata.P3, @@ -539,7 +539,7 @@ func TestIngestCertifyVulnerability(t *testing.T) { { Name: "Query on Package ID", InVuln: []*model.VulnerabilityInputSpec{testdata.G1}, - InPkg: []*model.PkgInputSpec{testdata.P3}, + InPkg: []*model.IDorPkgInput{{PackageInput: testdata.P3}}, Calls: []call{ { Pkg: testdata.P3, @@ -570,7 +570,7 @@ func TestIngestCertifyVulnerability(t *testing.T) { { Name: "Query none", InVuln: []*model.VulnerabilityInputSpec{testdata.G1}, - InPkg: []*model.PkgInputSpec{testdata.P2}, + InPkg: []*model.IDorPkgInput{{PackageInput: testdata.P2}}, Calls: []call{ { Pkg: testdata.P2, @@ -596,7 +596,7 @@ func TestIngestCertifyVulnerability(t *testing.T) { { Name: "Query No Vuln", InVuln: []*model.VulnerabilityInputSpec{testdata.NoVulnInput}, - InPkg: []*model.PkgInputSpec{testdata.P2}, + InPkg: []*model.IDorPkgInput{{PackageInput: testdata.P2}}, Calls: []call{ { Pkg: testdata.P2, @@ -631,7 +631,7 @@ func TestIngestCertifyVulnerability(t *testing.T) { { Name: "Query No Vuln - with novuln boolen", InVuln: []*model.VulnerabilityInputSpec{testdata.NoVulnInput, testdata.C1}, - InPkg: []*model.PkgInputSpec{testdata.P2, testdata.P1}, + InPkg: []*model.IDorPkgInput{{PackageInput: testdata.P2}, {PackageInput: testdata.P1}}, Calls: []call{ { Pkg: testdata.P2, @@ -679,7 +679,7 @@ func TestIngestCertifyVulnerability(t *testing.T) { { Name: "Query only cve (exclude novuln) - with novuln boolen", InVuln: []*model.VulnerabilityInputSpec{testdata.NoVulnInput, testdata.C1}, - InPkg: []*model.PkgInputSpec{testdata.P2, testdata.P1}, + InPkg: []*model.IDorPkgInput{{PackageInput: testdata.P2}, {PackageInput: testdata.P1}}, Calls: []call{ { Pkg: testdata.P2, @@ -736,7 +736,7 @@ func TestIngestCertifyVulnerability(t *testing.T) { { Name: "Query all vulns - with novuln boolean omitted", InVuln: []*model.VulnerabilityInputSpec{testdata.NoVulnInput, testdata.C1, testdata.G1}, - InPkg: []*model.PkgInputSpec{testdata.P2, testdata.P1, testdata.P1}, + InPkg: []*model.IDorPkgInput{{PackageInput: testdata.P2}, {PackageInput: testdata.P1}, {PackageInput: testdata.P1}}, Calls: []call{ { Pkg: testdata.P2, @@ -924,7 +924,7 @@ func TestIngestCertifyVulnerability(t *testing.T) { for _, test := range tests { t.Run(test.Name, func(t *testing.T) { for _, g := range test.InVuln { - if vulnIDs, err := b.IngestVulnerability(ctx, *g); err != nil { + if vulnIDs, err := b.IngestVulnerability(ctx, model.IDorVulnerabilityInput{VulnerabilityInput: g}); err != nil { t.Fatalf("Could not ingest vulnerability: %a", err) } else { if test.QueryVulnID { @@ -949,7 +949,7 @@ func TestIngestCertifyVulnerability(t *testing.T) { } ids := make([]string, len(test.Calls)) for i, o := range test.Calls { - cvID, err := b.IngestCertifyVuln(ctx, *o.Pkg, *o.Vuln, *o.CertifyVuln) + cvID, err := b.IngestCertifyVuln(ctx, model.IDorPkgInput{PackageInput: o.Pkg}, model.IDorVulnerabilityInput{VulnerabilityInput: o.Vuln}, *o.CertifyVuln) if (err != nil) != test.ExpIngestErr { t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) } @@ -989,8 +989,8 @@ func TestIngestCertifyVulns(t *testing.T) { ctx := context.Background() b := setupTest(t) type call struct { - Pkgs []*model.PkgInputSpec - Vulns []*model.VulnerabilityInputSpec + Pkgs []*model.IDorPkgInput + Vulns []*model.IDorVulnerabilityInput CertifyVulns []*model.ScanMetadataInput } tests := []struct { @@ -1009,8 +1009,8 @@ func TestIngestCertifyVulns(t *testing.T) { InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2}, Calls: []call{ { - Pkgs: []*model.PkgInputSpec{testdata.P2, testdata.P1}, - Vulns: []*model.VulnerabilityInputSpec{testdata.C1, testdata.C2}, + Pkgs: []*model.IDorPkgInput{{PackageInput: testdata.P2}, {PackageInput: testdata.P1}}, + Vulns: []*model.IDorVulnerabilityInput{{VulnerabilityInput: testdata.C1}, {VulnerabilityInput: testdata.C2}}, CertifyVulns: []*model.ScanMetadataInput{ { Collector: "test collector", @@ -1063,8 +1063,8 @@ func TestIngestCertifyVulns(t *testing.T) { InPkg: []*model.PkgInputSpec{testdata.P2, testdata.P1}, Calls: []call{ { - Pkgs: []*model.PkgInputSpec{testdata.P2, testdata.P1}, - Vulns: []*model.VulnerabilityInputSpec{testdata.NoVulnInput, testdata.NoVulnInput}, + Pkgs: []*model.IDorPkgInput{{PackageInput: testdata.P2}, {PackageInput: testdata.P1}}, + Vulns: []*model.IDorVulnerabilityInput{{VulnerabilityInput: testdata.NoVulnInput}, {VulnerabilityInput: testdata.NoVulnInput}}, CertifyVulns: []*model.ScanMetadataInput{ { Collector: "test collector", @@ -1117,8 +1117,8 @@ func TestIngestCertifyVulns(t *testing.T) { InPkg: []*model.PkgInputSpec{testdata.P2}, Calls: []call{ { - Pkgs: []*model.PkgInputSpec{testdata.P2}, - Vulns: []*model.VulnerabilityInputSpec{testdata.O1}, + Pkgs: []*model.IDorPkgInput{{PackageInput: testdata.P2}}, + Vulns: []*model.IDorVulnerabilityInput{{VulnerabilityInput: testdata.O1}}, CertifyVulns: []*model.ScanMetadataInput{ { Collector: "test collector", @@ -1154,8 +1154,8 @@ func TestIngestCertifyVulns(t *testing.T) { InPkg: []*model.PkgInputSpec{testdata.P2}, Calls: []call{ { - Pkgs: []*model.PkgInputSpec{testdata.P2}, - Vulns: []*model.VulnerabilityInputSpec{testdata.G1}, + Pkgs: []*model.IDorPkgInput{{PackageInput: testdata.P2}}, + Vulns: []*model.IDorVulnerabilityInput{{VulnerabilityInput: testdata.G1}}, CertifyVulns: []*model.ScanMetadataInput{ { Collector: "test collector", @@ -1191,8 +1191,8 @@ func TestIngestCertifyVulns(t *testing.T) { InPkg: []*model.PkgInputSpec{testdata.P2, testdata.P1}, Calls: []call{ { - Pkgs: []*model.PkgInputSpec{testdata.P2, testdata.P1}, - Vulns: []*model.VulnerabilityInputSpec{testdata.G1, testdata.G2}, + Pkgs: []*model.IDorPkgInput{{PackageInput: testdata.P2}, {PackageInput: testdata.P1}}, + Vulns: []*model.IDorVulnerabilityInput{{VulnerabilityInput: testdata.G1}, {VulnerabilityInput: testdata.G2}}, CertifyVulns: []*model.ScanMetadataInput{ { Collector: "test collector", @@ -1237,8 +1237,8 @@ func TestIngestCertifyVulns(t *testing.T) { InPkg: []*model.PkgInputSpec{testdata.P3, testdata.P4}, Calls: []call{ { - Pkgs: []*model.PkgInputSpec{testdata.P3, testdata.P4}, - Vulns: []*model.VulnerabilityInputSpec{testdata.G1, testdata.G2}, + Pkgs: []*model.IDorPkgInput{{PackageInput: testdata.P3}, {PackageInput: testdata.P4}}, + Vulns: []*model.IDorVulnerabilityInput{{VulnerabilityInput: testdata.G1}, {VulnerabilityInput: testdata.G2}}, CertifyVulns: []*model.ScanMetadataInput{ { Collector: "test collector", @@ -1284,8 +1284,8 @@ func TestIngestCertifyVulns(t *testing.T) { InPkg: []*model.PkgInputSpec{testdata.P2, testdata.P1}, Calls: []call{ { - Pkgs: []*model.PkgInputSpec{testdata.P2, testdata.P1}, - Vulns: []*model.VulnerabilityInputSpec{testdata.G1, testdata.G2}, + Pkgs: []*model.IDorPkgInput{{PackageInput: testdata.P2}, {PackageInput: testdata.P1}}, + Vulns: []*model.IDorVulnerabilityInput{{VulnerabilityInput: testdata.G1}, {VulnerabilityInput: testdata.G2}}, CertifyVulns: []*model.ScanMetadataInput{ { Collector: "test collector", @@ -1321,8 +1321,8 @@ func TestIngestCertifyVulns(t *testing.T) { InPkg: []*model.PkgInputSpec{testdata.P2, testdata.P1}, Calls: []call{ { - Pkgs: []*model.PkgInputSpec{testdata.P2, testdata.P1}, - Vulns: []*model.VulnerabilityInputSpec{testdata.NoVulnInput, testdata.NoVulnInput}, + Pkgs: []*model.IDorPkgInput{{PackageInput: testdata.P2}, {PackageInput: testdata.P1}}, + Vulns: []*model.IDorVulnerabilityInput{{VulnerabilityInput: testdata.NoVulnInput}, {VulnerabilityInput: testdata.NoVulnInput}}, CertifyVulns: []*model.ScanMetadataInput{ { Collector: "test collector", @@ -1372,11 +1372,15 @@ func TestIngestCertifyVulns(t *testing.T) { } for _, test := range tests { t.Run(test.Name, func(t *testing.T) { - if _, err := b.IngestVulnerabilities(ctx, test.InVuln); err != nil { - t.Fatalf("Could not ingest vulnerabilities: %a", err) + for _, v := range test.InVuln { + if _, err := b.IngestVulnerability(ctx, model.IDorVulnerabilityInput{VulnerabilityInput: v}); err != nil { + t.Fatalf("Could not ingest vulnerabilities: %a", err) + } } - if _, err := b.IngestPackages(ctx, test.InPkg); err != nil { - t.Fatalf("Could not ingest packages: %v", err) + for _, p := range test.InPkg { + if _, err := b.IngestPackage(ctx, model.IDorPkgInput{PackageInput: p}); err != nil { + t.Fatalf("Could not ingest packages: %v", err) + } } for _, o := range test.Calls { _, err := b.IngestCertifyVulns(ctx, o.Pkgs, o.Vulns, o.CertifyVulns) diff --git a/internal/testing/backend/hasMetadata_test.go b/internal/testing/backend/hasMetadata_test.go index 9c8b6e8982..cfc05a6b29 100644 --- a/internal/testing/backend/hasMetadata_test.go +++ b/internal/testing/backend/hasMetadata_test.go @@ -57,7 +57,7 @@ func TestHasMetadata(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -92,7 +92,7 @@ func TestHasMetadata(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -127,7 +127,7 @@ func TestHasMetadata(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -154,7 +154,7 @@ func TestHasMetadata(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeAllVersions, @@ -187,7 +187,7 @@ func TestHasMetadata(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P3, + Package: &model.IDorPkgInput{PackageInput: testdata.P3}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -198,7 +198,7 @@ func TestHasMetadata(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P3, + Package: &model.IDorPkgInput{PackageInput: testdata.P3}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -233,7 +233,7 @@ func TestHasMetadata(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -246,7 +246,7 @@ func TestHasMetadata(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -276,7 +276,7 @@ func TestHasMetadata(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -289,7 +289,7 @@ func TestHasMetadata(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -326,7 +326,7 @@ func TestHasMetadata(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -337,7 +337,7 @@ func TestHasMetadata(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -364,7 +364,7 @@ func TestHasMetadata(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -375,7 +375,7 @@ func TestHasMetadata(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P4, + Package: &model.IDorPkgInput{PackageInput: testdata.P4}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -386,7 +386,7 @@ func TestHasMetadata(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, + Source: &model.IDorSourceInput{SourceInput: testdata.S1}, }, HM: &model.HasMetadataInputSpec{ Justification: "test justification", @@ -416,7 +416,7 @@ func TestHasMetadata(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P4, + Package: &model.IDorPkgInput{PackageInput: testdata.P4}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -441,7 +441,7 @@ func TestHasMetadata(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -452,7 +452,7 @@ func TestHasMetadata(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, + Source: &model.IDorSourceInput{SourceInput: testdata.S1}, }, HM: &model.HasMetadataInputSpec{ Justification: "test justification", @@ -460,7 +460,7 @@ func TestHasMetadata(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S2, + Source: &model.IDorSourceInput{SourceInput: testdata.S2}, }, HM: &model.HasMetadataInputSpec{ Justification: "test justification", @@ -488,7 +488,7 @@ func TestHasMetadata(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S2, + Source: &model.IDorSourceInput{SourceInput: testdata.S2}, }, HM: &model.HasMetadataInputSpec{ Justification: "test justification", @@ -510,7 +510,7 @@ func TestHasMetadata(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A1, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A1}, }, HM: &model.HasMetadataInputSpec{ Justification: "test justification", @@ -518,7 +518,7 @@ func TestHasMetadata(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A2}, }, HM: &model.HasMetadataInputSpec{ Justification: "test justification", @@ -526,7 +526,7 @@ func TestHasMetadata(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, + Source: &model.IDorSourceInput{SourceInput: testdata.S1}, }, HM: &model.HasMetadataInputSpec{ Justification: "test justification", @@ -554,7 +554,7 @@ func TestHasMetadata(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A1, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A1}, }, HM: &model.HasMetadataInputSpec{ Justification: "test justification", @@ -562,7 +562,7 @@ func TestHasMetadata(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A2}, }, HM: &model.HasMetadataInputSpec{ Justification: "test justification", @@ -583,7 +583,7 @@ func TestHasMetadata(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A1, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A1}, }, HM: &model.HasMetadataInputSpec{ Justification: "test justification", @@ -591,7 +591,7 @@ func TestHasMetadata(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A2}, }, HM: &model.HasMetadataInputSpec{ Justification: "test justification", @@ -613,7 +613,7 @@ func TestHasMetadata(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, + Source: &model.IDorSourceInput{SourceInput: testdata.S1}, }, HM: &model.HasMetadataInputSpec{ Justification: "test justification", @@ -621,7 +621,7 @@ func TestHasMetadata(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S2, + Source: &model.IDorSourceInput{SourceInput: testdata.S2}, }, HM: &model.HasMetadataInputSpec{ Justification: "test justification", @@ -651,7 +651,7 @@ func TestHasMetadata(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -662,7 +662,7 @@ func TestHasMetadata(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P2, + Package: &model.IDorPkgInput{PackageInput: testdata.P2}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -673,7 +673,7 @@ func TestHasMetadata(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P4, + Package: &model.IDorPkgInput{PackageInput: testdata.P4}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeAllVersions, @@ -708,7 +708,7 @@ func TestHasMetadata(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A1, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A1}, }, HM: &model.HasMetadataInputSpec{ Justification: "test justification", @@ -716,7 +716,7 @@ func TestHasMetadata(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A2}, }, HM: &model.HasMetadataInputSpec{ Justification: "test justification", @@ -735,7 +735,7 @@ func TestHasMetadata(t *testing.T) { for _, test := range tests { t.Run(test.Name, func(t *testing.T) { for _, p := range test.InPkg { - if pkgIDs, err := b.IngestPackage(ctx, *p); err != nil { + if pkgIDs, err := b.IngestPackage(ctx, model.IDorPkgInput{PackageInput: p}); err != nil { t.Fatalf("Could not ingest package: %v", err) } else { if test.QueryPkgID { @@ -750,7 +750,7 @@ func TestHasMetadata(t *testing.T) { } } for _, s := range test.InSrc { - if srcIDs, err := b.IngestSource(ctx, *s); err != nil { + if srcIDs, err := b.IngestSource(ctx, model.IDorSourceInput{SourceInput: s}); err != nil { t.Fatalf("Could not ingest source: %v", err) } else { if test.QuerySourceID { @@ -765,7 +765,7 @@ func TestHasMetadata(t *testing.T) { } } for _, a := range test.InArt { - if artID, err := b.IngestArtifact(ctx, a); err != nil { + if artID, err := b.IngestArtifact(ctx, &model.IDorArtifactInput{ArtifactInput: a}); err != nil { t.Fatalf("Could not ingest artifact: %v", err) } else { if test.QueryArtID { @@ -832,7 +832,7 @@ func TestIngestBulkHasMetadata(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1}, + Packages: []*model.IDorPkgInput{&model.IDorPkgInput{PackageInput: testdata.P1}}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -860,7 +860,7 @@ func TestIngestBulkHasMetadata(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1}, + Packages: []*model.IDorPkgInput{&model.IDorPkgInput{PackageInput: testdata.P1}}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeAllVersions, @@ -892,7 +892,7 @@ func TestIngestBulkHasMetadata(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P3, testdata.P3}, + Packages: []*model.IDorPkgInput{{PackageInput: testdata.P3}, {PackageInput: testdata.P3}}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -933,7 +933,7 @@ func TestIngestBulkHasMetadata(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1, testdata.P4}, + Packages: []*model.IDorPkgInput{{PackageInput: testdata.P1}, {PackageInput: testdata.P4}}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -949,7 +949,7 @@ func TestIngestBulkHasMetadata(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{testdata.S1}, + Sources: []*model.IDorSourceInput{&model.IDorSourceInput{SourceInput: testdata.S1}}, }, HM: []*model.HasMetadataInputSpec{ { @@ -981,7 +981,7 @@ func TestIngestBulkHasMetadata(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1}, + Packages: []*model.IDorPkgInput{&model.IDorPkgInput{PackageInput: testdata.P1}}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -994,7 +994,7 @@ func TestIngestBulkHasMetadata(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{testdata.S2, testdata.S2}, + Sources: []*model.IDorSourceInput{{SourceInput: testdata.S2}, {SourceInput: testdata.S2}}, }, HM: []*model.HasMetadataInputSpec{ { @@ -1027,7 +1027,7 @@ func TestIngestBulkHasMetadata(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInputs{ - Artifacts: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, + Artifacts: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}, {ArtifactInput: testdata.A2}}, }, HM: []*model.HasMetadataInputSpec{ { @@ -1040,7 +1040,7 @@ func TestIngestBulkHasMetadata(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{testdata.S1}, + Sources: []*model.IDorSourceInput{&model.IDorSourceInput{SourceInput: testdata.S1}}, }, HM: []*model.HasMetadataInputSpec{ { @@ -1067,17 +1067,17 @@ func TestIngestBulkHasMetadata(t *testing.T) { for _, test := range tests { t.Run(test.Name, func(t *testing.T) { for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { + if _, err := b.IngestPackage(ctx, model.IDorPkgInput{PackageInput: p}); err != nil { t.Fatalf("Could not ingest package: %v", err) } } for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { + if _, err := b.IngestSource(ctx, model.IDorSourceInput{SourceInput: s}); err != nil { t.Fatalf("Could not ingest source: %v", err) } } for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { + if _, err := b.IngestArtifact(ctx, &model.IDorArtifactInput{ArtifactInput: a}); err != nil { t.Fatalf("Could not ingest artifact: %v", err) } } diff --git a/internal/testing/backend/hasSBOM_test.go b/internal/testing/backend/hasSBOM_test.go index 9b8b21cfd0..5d12a6392b 100644 --- a/internal/testing/backend/hasSBOM_test.go +++ b/internal/testing/backend/hasSBOM_test.go @@ -83,6 +83,8 @@ var includedPackage3 = &model.PkgInputSpec{ var includedPackages = []*model.PkgInputSpec{includedPackage1, includedPackage2, includedPackage3} +var includedIDorPackages = []*model.IDorPkgInput{{PackageInput: includedPackage1}, {PackageInput: includedPackage2}, {PackageInput: includedPackage3}} + var includedArtifact1 = &model.ArtifactInputSpec{ Algorithm: "a1_algorithm", Digest: "a1_digest", @@ -95,9 +97,11 @@ var includedArtifact2 = &model.ArtifactInputSpec{ var includedArtifacts = []*model.ArtifactInputSpec{includedArtifact1, includedArtifact2} +var includedIDorArtifacts = []*model.IDorArtifactInput{{ArtifactInput: includedArtifact1}, {ArtifactInput: includedArtifact2}} + var includedPackageArtifacts = &model.PackageOrArtifactInputs{ - Packages: includedPackages, - Artifacts: includedArtifacts, + Packages: includedIDorPackages, + Artifacts: includedIDorArtifacts, } var includedDependency1 = &model.IsDependencyInputSpec{ @@ -149,11 +153,11 @@ var includedOccurrence = &model.IsOccurrenceInputSpec{ } var includedTestOccurrences = []testOccurrence{{ - Subj: &model.PackageOrSourceInput{Package: includedPackage1}, + Subj: &model.PackageOrSourceInput{Package: &model.IDorPkgInput{PackageInput: includedPackage1}}, Art: includedArtifact1, isOcc: includedOccurrence, }, { - Subj: &model.PackageOrSourceInput{Source: includedSource}, + Subj: &model.PackageOrSourceInput{Source: &model.IDorSourceInput{SourceInput: includedSource}}, Art: includedArtifact1, isOcc: includedOccurrence, }} @@ -333,7 +337,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -344,12 +348,12 @@ func TestHasSBOM(t *testing.T) { Name: "HappyPath", InPkg: []*model.PkgInputSpec{testdata.P1}, PkgArt: &model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1}, + Packages: []*model.IDorPkgInput{&model.IDorPkgInput{PackageInput: testdata.P1}}, }, Calls: []call{ { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, HS: &model.HasSBOMInputSpec{ URI: "test uri", @@ -371,12 +375,12 @@ func TestHasSBOM(t *testing.T) { Name: "Ingest same twice", InPkg: []*model.PkgInputSpec{testdata.P1}, PkgArt: &model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1}, + Packages: []*model.IDorPkgInput{&model.IDorPkgInput{PackageInput: testdata.P1}}, }, Calls: []call{ { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, HS: &model.HasSBOMInputSpec{ URI: "test uri", @@ -384,7 +388,7 @@ func TestHasSBOM(t *testing.T) { }, { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, HS: &model.HasSBOMInputSpec{ URI: "test uri", @@ -406,12 +410,12 @@ func TestHasSBOM(t *testing.T) { Name: "Query on URI", InPkg: []*model.PkgInputSpec{testdata.P1}, PkgArt: &model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1}, + Packages: []*model.IDorPkgInput{&model.IDorPkgInput{PackageInput: testdata.P1}}, }, Calls: []call{ { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, HS: &model.HasSBOMInputSpec{ URI: "test uri one", @@ -419,7 +423,7 @@ func TestHasSBOM(t *testing.T) { }, { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, HS: &model.HasSBOMInputSpec{ URI: "test uri two", @@ -443,7 +447,7 @@ func TestHasSBOM(t *testing.T) { Calls: []call{ { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, HS: &model.HasSBOMInputSpec{ URI: "test uri one", @@ -452,7 +456,7 @@ func TestHasSBOM(t *testing.T) { }, { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, HS: &model.HasSBOMInputSpec{ URI: "test uri two", @@ -477,8 +481,8 @@ func TestHasSBOM(t *testing.T) { InPkg: []*model.PkgInputSpec{testdata.P2, testdata.P4}, InArt: []*model.ArtifactInputSpec{testdata.A1}, PkgArt: &model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P2, testdata.P4}, - Artifacts: []*model.ArtifactInputSpec{testdata.A1}, + Packages: []*model.IDorPkgInput{&model.IDorPkgInput{PackageInput: testdata.P2}, &model.IDorPkgInput{PackageInput: testdata.P4}}, + Artifacts: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}}, }, IsDeps: []testDependency{{ pkg: testdata.P2, @@ -489,14 +493,14 @@ func TestHasSBOM(t *testing.T) { }, }}, IsOccs: []testOccurrence{{ - Subj: &model.PackageOrSourceInput{Package: testdata.P4}, + Subj: &model.PackageOrSourceInput{Package: &model.IDorPkgInput{PackageInput: testdata.P4}}, Art: testdata.A1, isOcc: &model.IsOccurrenceInputSpec{Justification: "test justification"}, }}, Calls: []call{ { Sub: model.PackageOrArtifactInput{ - Package: testdata.P2, + Package: &model.IDorPkgInput{PackageInput: testdata.P2}, }, HS: &model.HasSBOMInputSpec{ URI: "test uri", @@ -504,7 +508,7 @@ func TestHasSBOM(t *testing.T) { }, { Sub: model.PackageOrArtifactInput{ - Package: testdata.P4, + Package: &model.IDorPkgInput{PackageInput: testdata.P4}, }, HS: &model.HasSBOMInputSpec{ URI: "test uri", @@ -512,7 +516,7 @@ func TestHasSBOM(t *testing.T) { }, { Sub: model.PackageOrArtifactInput{ - Artifact: testdata.A1, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A1}, }, HS: &model.HasSBOMInputSpec{ URI: "test uri", @@ -552,7 +556,7 @@ func TestHasSBOM(t *testing.T) { Calls: []call{ { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, HS: &model.HasSBOMInputSpec{ URI: "test uri", @@ -560,7 +564,7 @@ func TestHasSBOM(t *testing.T) { }, { Sub: model.PackageOrArtifactInput{ - Package: testdata.P2, + Package: &model.IDorPkgInput{PackageInput: testdata.P2}, }, HS: &model.HasSBOMInputSpec{ URI: "test uri", @@ -568,7 +572,7 @@ func TestHasSBOM(t *testing.T) { }, { Sub: model.PackageOrArtifactInput{ - Artifact: testdata.A1, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A1}, }, HS: &model.HasSBOMInputSpec{ URI: "test uri", @@ -604,13 +608,13 @@ func TestHasSBOM(t *testing.T) { InPkg: []*model.PkgInputSpec{testdata.P2}, InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, PkgArt: &model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P2}, - Artifacts: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, + Packages: []*model.IDorPkgInput{&model.IDorPkgInput{PackageInput: testdata.P2}}, + Artifacts: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}, {ArtifactInput: testdata.A2}}, }, Calls: []call{ { Sub: model.PackageOrArtifactInput{ - Package: testdata.P2, + Package: &model.IDorPkgInput{PackageInput: testdata.P2}, }, HS: &model.HasSBOMInputSpec{ URI: "test uri", @@ -618,7 +622,7 @@ func TestHasSBOM(t *testing.T) { }, { Sub: model.PackageOrArtifactInput{ - Artifact: testdata.A1, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A1}, }, HS: &model.HasSBOMInputSpec{ URI: "test uri", @@ -626,7 +630,7 @@ func TestHasSBOM(t *testing.T) { }, { Sub: model.PackageOrArtifactInput{ - Artifact: testdata.A2, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A2}, }, HS: &model.HasSBOMInputSpec{ URI: "test uri", @@ -655,7 +659,7 @@ func TestHasSBOM(t *testing.T) { Calls: []call{ { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, HS: &model.HasSBOMInputSpec{ URI: "test uri", @@ -663,7 +667,7 @@ func TestHasSBOM(t *testing.T) { }, { Sub: model.PackageOrArtifactInput{ - Artifact: testdata.A1, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A1}, }, HS: &model.HasSBOMInputSpec{ URI: "test uri", @@ -671,7 +675,7 @@ func TestHasSBOM(t *testing.T) { }, { Sub: model.PackageOrArtifactInput{ - Artifact: testdata.A2, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A2}, }, HS: &model.HasSBOMInputSpec{ URI: "test uri", @@ -695,12 +699,12 @@ func TestHasSBOM(t *testing.T) { Name: "Query on Algorithm", InPkg: []*model.PkgInputSpec{testdata.P1}, PkgArt: &model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1}, + Packages: []*model.IDorPkgInput{&model.IDorPkgInput{PackageInput: testdata.P1}}, }, Calls: []call{ { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, HS: &model.HasSBOMInputSpec{ Algorithm: "QWERasdf", @@ -708,7 +712,7 @@ func TestHasSBOM(t *testing.T) { }, { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, HS: &model.HasSBOMInputSpec{ Algorithm: "QWERasdf two", @@ -730,8 +734,8 @@ func TestHasSBOM(t *testing.T) { Name: "Query on Digest", InPkg: []*model.PkgInputSpec{testdata.P2, testdata.P4}, PkgArt: &model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P2, testdata.P4}, - Artifacts: []*model.ArtifactInputSpec{testdata.A1}, + Packages: []*model.IDorPkgInput{&model.IDorPkgInput{PackageInput: testdata.P2}, &model.IDorPkgInput{PackageInput: testdata.P4}}, + Artifacts: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}}, }, IsDeps: []testDependency{{ pkg: testdata.P2, @@ -742,14 +746,14 @@ func TestHasSBOM(t *testing.T) { }, }}, IsOccs: []testOccurrence{{ - Subj: &model.PackageOrSourceInput{Package: testdata.P4}, + Subj: &model.PackageOrSourceInput{Package: &model.IDorPkgInput{PackageInput: testdata.P4}}, Art: testdata.A1, isOcc: &model.IsOccurrenceInputSpec{Justification: "test justification"}, }}, Calls: []call{ { Sub: model.PackageOrArtifactInput{ - Package: testdata.P2, + Package: &model.IDorPkgInput{PackageInput: testdata.P2}, }, HS: &model.HasSBOMInputSpec{ Digest: "QWERasdf", @@ -757,7 +761,7 @@ func TestHasSBOM(t *testing.T) { }, { Sub: model.PackageOrArtifactInput{ - Package: testdata.P2, + Package: &model.IDorPkgInput{PackageInput: testdata.P2}, }, HS: &model.HasSBOMInputSpec{ Digest: "QWERasdf two", @@ -790,12 +794,12 @@ func TestHasSBOM(t *testing.T) { Name: "Query on DownloadLocation", InPkg: []*model.PkgInputSpec{testdata.P1}, PkgArt: &model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1}, + Packages: []*model.IDorPkgInput{&model.IDorPkgInput{PackageInput: testdata.P1}}, }, Calls: []call{ { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, HS: &model.HasSBOMInputSpec{ DownloadLocation: "location one", @@ -803,7 +807,7 @@ func TestHasSBOM(t *testing.T) { }, { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, HS: &model.HasSBOMInputSpec{ DownloadLocation: "location two", @@ -825,12 +829,12 @@ func TestHasSBOM(t *testing.T) { Name: "Query none", InPkg: []*model.PkgInputSpec{testdata.P1}, PkgArt: &model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1}, + Packages: []*model.IDorPkgInput{&model.IDorPkgInput{PackageInput: testdata.P1}}, }, Calls: []call{ { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, HS: &model.HasSBOMInputSpec{ DownloadLocation: "location one", @@ -838,7 +842,7 @@ func TestHasSBOM(t *testing.T) { }, { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, HS: &model.HasSBOMInputSpec{ DownloadLocation: "location two", @@ -856,7 +860,7 @@ func TestHasSBOM(t *testing.T) { Calls: []call{ { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, HS: &model.HasSBOMInputSpec{ DownloadLocation: "location one", @@ -864,7 +868,7 @@ func TestHasSBOM(t *testing.T) { }, { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, HS: &model.HasSBOMInputSpec{ DownloadLocation: "location two", @@ -872,7 +876,7 @@ func TestHasSBOM(t *testing.T) { }, { Sub: model.PackageOrArtifactInput{ - Package: testdata.P2, + Package: &model.IDorPkgInput{PackageInput: testdata.P2}, }, HS: &model.HasSBOMInputSpec{ DownloadLocation: "location two", @@ -902,12 +906,12 @@ func TestHasSBOM(t *testing.T) { Name: "Query on ID", InPkg: []*model.PkgInputSpec{testdata.P1}, PkgArt: &model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1}, + Packages: []*model.IDorPkgInput{&model.IDorPkgInput{PackageInput: testdata.P1}}, }, Calls: []call{ { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, HS: &model.HasSBOMInputSpec{ DownloadLocation: "location one", @@ -915,7 +919,7 @@ func TestHasSBOM(t *testing.T) { }, { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, HS: &model.HasSBOMInputSpec{ DownloadLocation: "location two", @@ -941,7 +945,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -958,7 +962,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -975,7 +979,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -992,7 +996,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1009,7 +1013,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1026,7 +1030,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1043,7 +1047,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1060,7 +1064,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1077,7 +1081,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1094,7 +1098,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1111,7 +1115,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1128,7 +1132,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1145,7 +1149,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1162,7 +1166,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1180,7 +1184,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1197,7 +1201,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1214,7 +1218,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1231,7 +1235,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1248,7 +1252,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1265,7 +1269,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1283,7 +1287,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1300,7 +1304,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1317,7 +1321,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1334,7 +1338,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1351,7 +1355,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1368,7 +1372,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1385,7 +1389,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1402,7 +1406,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1419,7 +1423,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1436,7 +1440,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1453,7 +1457,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1470,7 +1474,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1487,7 +1491,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1504,7 +1508,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1522,7 +1526,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1539,7 +1543,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1556,7 +1560,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1573,7 +1577,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1590,7 +1594,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1607,7 +1611,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1624,7 +1628,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1641,7 +1645,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1658,7 +1662,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1675,7 +1679,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1692,7 +1696,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1709,7 +1713,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1726,7 +1730,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1743,7 +1747,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1761,7 +1765,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1778,7 +1782,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1795,7 +1799,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1812,7 +1816,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1829,7 +1833,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1846,7 +1850,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1863,7 +1867,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1880,7 +1884,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1901,7 +1905,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1924,7 +1928,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1941,7 +1945,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1958,7 +1962,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1975,7 +1979,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -1992,7 +1996,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -2009,7 +2013,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -2026,7 +2030,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -2044,7 +2048,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -2061,7 +2065,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -2078,7 +2082,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -2095,7 +2099,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -2112,7 +2116,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -2129,7 +2133,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -2146,7 +2150,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -2163,7 +2167,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -2180,7 +2184,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -2197,7 +2201,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -2214,7 +2218,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -2231,7 +2235,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -2248,7 +2252,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -2265,7 +2269,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -2282,7 +2286,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -2299,7 +2303,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -2316,7 +2320,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -2343,7 +2347,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -2365,7 +2369,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -2387,7 +2391,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -2409,7 +2413,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -2431,7 +2435,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -2453,7 +2457,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -2470,7 +2474,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -2493,7 +2497,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -2510,7 +2514,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -2527,7 +2531,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -2544,7 +2548,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -2561,7 +2565,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -2578,7 +2582,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -2595,7 +2599,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -2612,7 +2616,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -2629,7 +2633,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -2646,7 +2650,7 @@ func TestHasSBOM(t *testing.T) { IsOccs: includedTestOccurrences, Calls: []call{{ Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, + Package: &model.IDorPkgInput{PackageInput: includedPackage1}, }, HS: includedHasSBOM, }}, @@ -2657,7 +2661,7 @@ func TestHasSBOM(t *testing.T) { for _, test := range tests { t.Run(test.Name, func(t *testing.T) { for _, p := range test.InPkg { - if pkgIDs, err := b.IngestPackage(ctx, *p); err != nil { + if pkgIDs, err := b.IngestPackage(ctx, model.IDorPkgInput{PackageInput: p}); err != nil { t.Fatalf("Could not ingest package: %v", err) } else { if test.QueryPkgID { @@ -2672,7 +2676,7 @@ func TestHasSBOM(t *testing.T) { } } for _, a := range test.InArt { - if artID, err := b.IngestArtifact(ctx, a); err != nil { + if artID, err := b.IngestArtifact(ctx, &model.IDorArtifactInput{ArtifactInput: a}); err != nil { t.Fatalf("Could not ingest artifact: %v", err) } else { if test.QueryArtID { @@ -2688,7 +2692,7 @@ func TestHasSBOM(t *testing.T) { } includes := model.HasSBOMIncludesInputSpec{} for _, s := range test.InSrc { - if srcIDs, err := b.IngestSource(ctx, *s); err != nil { + if srcIDs, err := b.IngestSource(ctx, model.IDorSourceInput{SourceInput: s}); err != nil { t.Fatalf("Could not ingest source: %v", err) } else { if test.QueryIncludeOccurSrcID { @@ -2737,7 +2741,7 @@ func TestHasSBOM(t *testing.T) { } for _, dep := range test.IsDeps { - if isDep, err := b.IngestDependency(ctx, *dep.pkg, *dep.depPkg, dep.matchType, *dep.isDep); err != nil { + if isDep, err := b.IngestDependency(ctx, model.IDorPkgInput{PackageInput: dep.pkg}, model.IDorPkgInput{PackageInput: dep.depPkg}, dep.matchType, *dep.isDep); err != nil { t.Fatalf("Could not ingest dependency: %v", err) } else { includes.Dependencies = append(includes.Dependencies, isDep) @@ -2748,7 +2752,7 @@ func TestHasSBOM(t *testing.T) { } for _, occ := range test.IsOccs { - if isOcc, err := b.IngestOccurrence(ctx, *occ.Subj, *occ.Art, *occ.isOcc); err != nil { + if isOcc, err := b.IngestOccurrence(ctx, *occ.Subj, model.IDorArtifactInput{ArtifactInput: occ.Art}, *occ.isOcc); err != nil { t.Fatalf("Could not ingest occurrence: %v", err) } else { includes.Occurrences = append(includes.Occurrences, isOcc) @@ -2811,12 +2815,12 @@ func TestIngestHasSBOMs(t *testing.T) { Name: "HappyPath", InPkg: []*model.PkgInputSpec{testdata.P1}, PkgArt: &model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1}, + Packages: []*model.IDorPkgInput{&model.IDorPkgInput{PackageInput: testdata.P1}}, }, Calls: []call{ { Sub: model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1}, + Packages: []*model.IDorPkgInput{&model.IDorPkgInput{PackageInput: testdata.P1}}, }, HS: []*model.HasSBOMInputSpec{ { @@ -2840,12 +2844,12 @@ func TestIngestHasSBOMs(t *testing.T) { Name: "Ingest same twice", InPkg: []*model.PkgInputSpec{testdata.P1}, PkgArt: &model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1}, + Packages: []*model.IDorPkgInput{&model.IDorPkgInput{PackageInput: testdata.P1}}, }, Calls: []call{ { Sub: model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1, testdata.P1}, + Packages: []*model.IDorPkgInput{{PackageInput: testdata.P1}, {PackageInput: testdata.P1}}, }, HS: []*model.HasSBOMInputSpec{ { @@ -2872,12 +2876,12 @@ func TestIngestHasSBOMs(t *testing.T) { Name: "Query on URI", InPkg: []*model.PkgInputSpec{testdata.P1}, PkgArt: &model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1}, + Packages: []*model.IDorPkgInput{&model.IDorPkgInput{PackageInput: testdata.P1}}, }, Calls: []call{ { Sub: model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1, testdata.P1}, + Packages: []*model.IDorPkgInput{{PackageInput: testdata.P1}, {PackageInput: testdata.P1}}, }, HS: []*model.HasSBOMInputSpec{ { @@ -2905,8 +2909,8 @@ func TestIngestHasSBOMs(t *testing.T) { InPkg: []*model.PkgInputSpec{testdata.P2, testdata.P4}, InArt: []*model.ArtifactInputSpec{testdata.A1}, PkgArt: &model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P2, testdata.P4}, - Artifacts: []*model.ArtifactInputSpec{testdata.A1}, + Packages: []*model.IDorPkgInput{&model.IDorPkgInput{PackageInput: testdata.P2}, &model.IDorPkgInput{PackageInput: testdata.P4}}, + Artifacts: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}}, }, IsDeps: []testDependency{{ pkg: testdata.P2, @@ -2917,14 +2921,14 @@ func TestIngestHasSBOMs(t *testing.T) { }, }}, IsOccs: []testOccurrence{{ - Subj: &model.PackageOrSourceInput{Package: testdata.P4}, + Subj: &model.PackageOrSourceInput{Package: &model.IDorPkgInput{PackageInput: testdata.P4}}, Art: testdata.A1, isOcc: &model.IsOccurrenceInputSpec{Justification: "test justification"}, }}, Calls: []call{ { Sub: model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P2, testdata.P4}, + Packages: []*model.IDorPkgInput{&model.IDorPkgInput{PackageInput: testdata.P2}, &model.IDorPkgInput{PackageInput: testdata.P4}}, }, HS: []*model.HasSBOMInputSpec{ { @@ -2937,7 +2941,7 @@ func TestIngestHasSBOMs(t *testing.T) { }, { Sub: model.PackageOrArtifactInputs{ - Artifacts: []*model.ArtifactInputSpec{testdata.A1}, + Artifacts: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}}, }, HS: []*model.HasSBOMInputSpec{ { @@ -2976,18 +2980,18 @@ func TestIngestHasSBOMs(t *testing.T) { InPkg: []*model.PkgInputSpec{testdata.P1}, InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, PkgArt: &model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1}, - Artifacts: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, + Packages: []*model.IDorPkgInput{&model.IDorPkgInput{PackageInput: testdata.P1}}, + Artifacts: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}, {ArtifactInput: testdata.A2}}, }, IsOccs: []testOccurrence{{ - Subj: &model.PackageOrSourceInput{Package: testdata.P1}, + Subj: &model.PackageOrSourceInput{Package: &model.IDorPkgInput{PackageInput: testdata.P1}}, Art: testdata.A2, isOcc: &model.IsOccurrenceInputSpec{Justification: "test justification"}, }}, Calls: []call{ { Sub: model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1}, + Packages: []*model.IDorPkgInput{&model.IDorPkgInput{PackageInput: testdata.P1}}, }, HS: []*model.HasSBOMInputSpec{ { @@ -2997,7 +3001,7 @@ func TestIngestHasSBOMs(t *testing.T) { }, { Sub: model.PackageOrArtifactInputs{ - Artifacts: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, + Artifacts: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}, {ArtifactInput: testdata.A2}}, }, HS: []*model.HasSBOMInputSpec{ { @@ -3033,12 +3037,12 @@ func TestIngestHasSBOMs(t *testing.T) { for _, test := range tests { t.Run(test.Name, func(t *testing.T) { for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { + if _, err := b.IngestPackage(ctx, model.IDorPkgInput{PackageInput: p}); err != nil { t.Fatalf("Could not ingest package: %v", err) } } for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { + if _, err := b.IngestArtifact(ctx, &model.IDorArtifactInput{ArtifactInput: a}); err != nil { t.Fatalf("Could not ingest artifact: %v", err) } } @@ -3059,7 +3063,7 @@ func TestIngestHasSBOMs(t *testing.T) { } for _, dep := range test.IsDeps { - if isDep, err := b.IngestDependency(ctx, *dep.pkg, *dep.depPkg, dep.matchType, *dep.isDep); err != nil { + if isDep, err := b.IngestDependency(ctx, model.IDorPkgInput{PackageInput: dep.pkg}, model.IDorPkgInput{PackageInput: dep.depPkg}, dep.matchType, *dep.isDep); err != nil { t.Fatalf("Could not ingest dependency: %v", err) } else { includes.Dependencies = append(includes.Dependencies, isDep) @@ -3067,7 +3071,7 @@ func TestIngestHasSBOMs(t *testing.T) { } for _, occ := range test.IsOccs { - if isOcc, err := b.IngestOccurrence(ctx, *occ.Subj, *occ.Art, *occ.isOcc); err != nil { + if isOcc, err := b.IngestOccurrence(ctx, *occ.Subj, model.IDorArtifactInput{ArtifactInput: occ.Art}, *occ.isOcc); err != nil { t.Fatalf("Could not ingest occurrence: %v", err) } else { includes.Occurrences = append(includes.Occurrences, isOcc) diff --git a/internal/testing/backend/hasSLSA_test.go b/internal/testing/backend/hasSLSA_test.go index 9577a644c0..4ced3b67e7 100644 --- a/internal/testing/backend/hasSLSA_test.go +++ b/internal/testing/backend/hasSLSA_test.go @@ -61,7 +61,7 @@ func TestHasSLSA(t *testing.T) { } type call struct { Sub *model.ArtifactInputSpec - BF []*model.ArtifactInputSpec + BF []*model.IDorArtifactInput BB *model.BuilderInputSpec SLSA *model.SLSAInputSpec } @@ -101,10 +101,10 @@ func TestHasSLSA(t *testing.T) { Digest: "5a787865sd676dacb0142afa0b83029cd7befd9", Algorithm: "sha1", }, - BF: []*model.ArtifactInputSpec{{ + BF: []*model.IDorArtifactInput{{ArtifactInput: &model.ArtifactInputSpec{ Digest: "0123456789abcdef0000000fedcba9876543210", Algorithm: "sha1", - }}, + }}}, BB: &model.BuilderInputSpec{ URI: "https://github.com/BuildPythonWheel/HubHostedActions@v1", }, @@ -154,7 +154,7 @@ func TestHasSLSA(t *testing.T) { Calls: []call{ { Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, + BF: []*model.IDorArtifactInput{&model.IDorArtifactInput{ArtifactInput: testdata.A2}}, BB: testdata.B1, SLSA: &model.SLSAInputSpec{ BuildType: "test type", @@ -182,7 +182,7 @@ func TestHasSLSA(t *testing.T) { Calls: []call{ { Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, + BF: []*model.IDorArtifactInput{&model.IDorArtifactInput{ArtifactInput: testdata.A2}}, BB: testdata.B1, SLSA: &model.SLSAInputSpec{ BuildType: "test type", @@ -190,7 +190,7 @@ func TestHasSLSA(t *testing.T) { }, { Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, + BF: []*model.IDorArtifactInput{&model.IDorArtifactInput{ArtifactInput: testdata.A2}}, BB: testdata.B1, SLSA: &model.SLSAInputSpec{ BuildType: "test type", @@ -218,7 +218,7 @@ func TestHasSLSA(t *testing.T) { Calls: []call{ { Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, + BF: []*model.IDorArtifactInput{&model.IDorArtifactInput{ArtifactInput: testdata.A2}}, BB: testdata.B1, SLSA: &model.SLSAInputSpec{ BuildType: "test type one", @@ -226,7 +226,7 @@ func TestHasSLSA(t *testing.T) { }, { Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, + BF: []*model.IDorArtifactInput{&model.IDorArtifactInput{ArtifactInput: testdata.A2}}, BB: testdata.B1, SLSA: &model.SLSAInputSpec{ BuildType: "test type two", @@ -254,7 +254,7 @@ func TestHasSLSA(t *testing.T) { Calls: []call{ { Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, + BF: []*model.IDorArtifactInput{&model.IDorArtifactInput{ArtifactInput: testdata.A2}}, BB: testdata.B1, SLSA: &model.SLSAInputSpec{ SlsaVersion: "test type one", @@ -262,7 +262,7 @@ func TestHasSLSA(t *testing.T) { }, { Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, + BF: []*model.IDorArtifactInput{&model.IDorArtifactInput{ArtifactInput: testdata.A2}}, BB: testdata.B1, SLSA: &model.SLSAInputSpec{ SlsaVersion: "test type two", @@ -290,7 +290,7 @@ func TestHasSLSA(t *testing.T) { Calls: []call{ { Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, + BF: []*model.IDorArtifactInput{&model.IDorArtifactInput{ArtifactInput: testdata.A2}}, BB: testdata.B1, SLSA: &model.SLSAInputSpec{ StartedOn: &testTime2, @@ -298,7 +298,7 @@ func TestHasSLSA(t *testing.T) { }, { Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, + BF: []*model.IDorArtifactInput{&model.IDorArtifactInput{ArtifactInput: testdata.A2}}, BB: testdata.B1, SLSA: &model.SLSAInputSpec{ StartedOn: &testTime, @@ -326,7 +326,7 @@ func TestHasSLSA(t *testing.T) { Calls: []call{ { Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, + BF: []*model.IDorArtifactInput{&model.IDorArtifactInput{ArtifactInput: testdata.A2}}, BB: testdata.B1, SLSA: &model.SLSAInputSpec{ FinishedOn: &testTime2, @@ -334,7 +334,7 @@ func TestHasSLSA(t *testing.T) { }, { Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, + BF: []*model.IDorArtifactInput{&model.IDorArtifactInput{ArtifactInput: testdata.A2}}, BB: testdata.B1, SLSA: &model.SLSAInputSpec{ FinishedOn: &testTime, @@ -362,13 +362,13 @@ func TestHasSLSA(t *testing.T) { Calls: []call{ { Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, + BF: []*model.IDorArtifactInput{&model.IDorArtifactInput{ArtifactInput: testdata.A2}}, BB: testdata.B1, SLSA: &model.SLSAInputSpec{}, }, { Sub: testdata.A3, - BF: []*model.ArtifactInputSpec{testdata.A2}, + BF: []*model.IDorArtifactInput{&model.IDorArtifactInput{ArtifactInput: testdata.A2}}, BB: testdata.B1, SLSA: &model.SLSAInputSpec{}, }, @@ -398,13 +398,13 @@ func TestHasSLSA(t *testing.T) { Calls: []call{ { Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, + BF: []*model.IDorArtifactInput{&model.IDorArtifactInput{ArtifactInput: testdata.A2}}, BB: testdata.B1, SLSA: &model.SLSAInputSpec{}, }, { Sub: testdata.A3, - BF: []*model.ArtifactInputSpec{testdata.A2}, + BF: []*model.IDorArtifactInput{&model.IDorArtifactInput{ArtifactInput: testdata.A2}}, BB: testdata.B1, SLSA: &model.SLSAInputSpec{}, }, @@ -427,19 +427,19 @@ func TestHasSLSA(t *testing.T) { Calls: []call{ { Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, + BF: []*model.IDorArtifactInput{{ArtifactInput: testdata.A2}}, BB: testdata.B1, SLSA: &model.SLSAInputSpec{}, }, { Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2, testdata.A3}, + BF: []*model.IDorArtifactInput{{ArtifactInput: testdata.A2}, {ArtifactInput: testdata.A3}}, BB: testdata.B1, SLSA: &model.SLSAInputSpec{}, }, { Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A4}, + BF: []*model.IDorArtifactInput{{ArtifactInput: testdata.A4}}, BB: testdata.B1, SLSA: &model.SLSAInputSpec{}, }, @@ -466,13 +466,13 @@ func TestHasSLSA(t *testing.T) { Calls: []call{ { Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, + BF: []*model.IDorArtifactInput{&model.IDorArtifactInput{ArtifactInput: testdata.A2}}, BB: testdata.B1, SLSA: &model.SLSAInputSpec{}, }, { Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, + BF: []*model.IDorArtifactInput{&model.IDorArtifactInput{ArtifactInput: testdata.A2}}, BB: testdata.B2, SLSA: &model.SLSAInputSpec{}, }, @@ -499,13 +499,13 @@ func TestHasSLSA(t *testing.T) { Calls: []call{ { Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, + BF: []*model.IDorArtifactInput{&model.IDorArtifactInput{ArtifactInput: testdata.A2}}, BB: testdata.B1, SLSA: &model.SLSAInputSpec{}, }, { Sub: testdata.A3, - BF: []*model.ArtifactInputSpec{testdata.A2}, + BF: []*model.IDorArtifactInput{&model.IDorArtifactInput{ArtifactInput: testdata.A2}}, BB: testdata.B2, SLSA: &model.SLSAInputSpec{}, }, @@ -535,13 +535,13 @@ func TestHasSLSA(t *testing.T) { Calls: []call{ { Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, + BF: []*model.IDorArtifactInput{&model.IDorArtifactInput{ArtifactInput: testdata.A2}}, BB: testdata.B1, SLSA: &model.SLSAInputSpec{}, }, { Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, + BF: []*model.IDorArtifactInput{&model.IDorArtifactInput{ArtifactInput: testdata.A2}}, BB: testdata.B2, SLSA: &model.SLSAInputSpec{}, }, @@ -564,13 +564,13 @@ func TestHasSLSA(t *testing.T) { Calls: []call{ { Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, + BF: []*model.IDorArtifactInput{&model.IDorArtifactInput{ArtifactInput: testdata.A2}}, BB: testdata.B1, SLSA: &model.SLSAInputSpec{}, }, { Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, + BF: []*model.IDorArtifactInput{&model.IDorArtifactInput{ArtifactInput: testdata.A2}}, BB: testdata.B2, SLSA: &model.SLSAInputSpec{}, }, @@ -586,7 +586,7 @@ func TestHasSLSA(t *testing.T) { for _, test := range tests { t.Run(test.Name, func(t *testing.T) { for _, a := range test.InArt { - if artID, err := b.IngestArtifact(ctx, a); err != nil { + if artID, err := b.IngestArtifact(ctx, &model.IDorArtifactInput{ArtifactInput: a}); err != nil { t.Fatalf("Could not ingest artifact: %v", err) } else { if test.QuerySubjectID { @@ -599,7 +599,7 @@ func TestHasSLSA(t *testing.T) { } } for _, bld := range test.InBld { - if buildID, err := b.IngestBuilder(ctx, bld); err != nil { + if buildID, err := b.IngestBuilder(ctx, &model.IDorBuilderInput{BuilderInput: bld}); err != nil { t.Fatalf("Could not ingest builder: %v", err) } else { if test.QueryBuilderID { @@ -612,7 +612,7 @@ func TestHasSLSA(t *testing.T) { } } for _, o := range test.Calls { - slsaID, err := b.IngestSLSA(ctx, *o.Sub, o.BF, *o.BB, *o.SLSA) + slsaID, err := b.IngestSLSA(ctx, model.IDorArtifactInput{ArtifactInput: o.Sub}, o.BF, model.IDorBuilderInput{BuilderInput: o.BB}, *o.SLSA) if (err != nil) != test.ExpIngestErr { t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) } @@ -643,9 +643,9 @@ func TestIngestHasSLSAs(t *testing.T) { ctx := context.Background() b := setupTest(t) type call struct { - Sub []*model.ArtifactInputSpec - BF [][]*model.ArtifactInputSpec - BB []*model.BuilderInputSpec + Sub []*model.IDorArtifactInput + BF [][]*model.IDorArtifactInput + BB []*model.IDorBuilderInput SLSA []*model.SLSAInputSpec } tests := []struct { @@ -664,9 +664,9 @@ func TestIngestHasSLSAs(t *testing.T) { InBld: []*model.BuilderInputSpec{testdata.B1}, Calls: []call{ { - Sub: []*model.ArtifactInputSpec{testdata.A1}, - BF: [][]*model.ArtifactInputSpec{{testdata.A2}}, - BB: []*model.BuilderInputSpec{testdata.B1}, + Sub: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}}, + BF: [][]*model.IDorArtifactInput{{{ArtifactInput: testdata.A2}}}, + BB: []*model.IDorBuilderInput{{BuilderInput: testdata.B1}}, SLSA: []*model.SLSAInputSpec{ { BuildType: "test type", @@ -694,9 +694,9 @@ func TestIngestHasSLSAs(t *testing.T) { InBld: []*model.BuilderInputSpec{testdata.B1}, Calls: []call{ { - Sub: []*model.ArtifactInputSpec{testdata.A1, testdata.A1}, - BF: [][]*model.ArtifactInputSpec{{testdata.A2}, {testdata.A2}}, - BB: []*model.BuilderInputSpec{testdata.B1, testdata.B1}, + Sub: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}, {ArtifactInput: testdata.A1}}, + BF: [][]*model.IDorArtifactInput{{{ArtifactInput: testdata.A2}}, {{ArtifactInput: testdata.A2}}}, + BB: []*model.IDorBuilderInput{{BuilderInput: testdata.B1}, {BuilderInput: testdata.B1}}, SLSA: []*model.SLSAInputSpec{ { BuildType: "test type", @@ -727,9 +727,9 @@ func TestIngestHasSLSAs(t *testing.T) { InBld: []*model.BuilderInputSpec{testdata.B1}, Calls: []call{ { - Sub: []*model.ArtifactInputSpec{testdata.A1, testdata.A1}, - BF: [][]*model.ArtifactInputSpec{{testdata.A2}, {testdata.A2}}, - BB: []*model.BuilderInputSpec{testdata.B1, testdata.B1}, + Sub: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}, {ArtifactInput: testdata.A1}}, + BF: [][]*model.IDorArtifactInput{{{ArtifactInput: testdata.A2}}, {{ArtifactInput: testdata.A2}}}, + BB: []*model.IDorBuilderInput{{BuilderInput: testdata.B1}, {BuilderInput: testdata.B1}}, SLSA: []*model.SLSAInputSpec{ { BuildType: "test type one", @@ -760,9 +760,9 @@ func TestIngestHasSLSAs(t *testing.T) { InBld: []*model.BuilderInputSpec{testdata.B1}, Calls: []call{ { - Sub: []*model.ArtifactInputSpec{testdata.A1, testdata.A3}, - BF: [][]*model.ArtifactInputSpec{{testdata.A2}, {testdata.A2}}, - BB: []*model.BuilderInputSpec{testdata.B1, testdata.B1}, + Sub: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}, {ArtifactInput: testdata.A3}}, + BF: [][]*model.IDorArtifactInput{{{ArtifactInput: testdata.A2}}, {{ArtifactInput: testdata.A2}}}, + BB: []*model.IDorBuilderInput{{BuilderInput: testdata.B1}, {BuilderInput: testdata.B1}}, SLSA: []*model.SLSAInputSpec{ {SlsaVersion: "test type one"}, {}, @@ -793,9 +793,9 @@ func TestIngestHasSLSAs(t *testing.T) { InBld: []*model.BuilderInputSpec{testdata.B1}, Calls: []call{ { - Sub: []*model.ArtifactInputSpec{testdata.A1, testdata.A1, testdata.A1}, - BF: [][]*model.ArtifactInputSpec{{testdata.A2}, {testdata.A2, testdata.A3}, {testdata.A4}}, - BB: []*model.BuilderInputSpec{testdata.B1, testdata.B1, testdata.B1}, + Sub: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}, {ArtifactInput: testdata.A1}, {ArtifactInput: testdata.A1}}, + BF: [][]*model.IDorArtifactInput{{{ArtifactInput: testdata.A2}}, {{ArtifactInput: testdata.A2}, {ArtifactInput: testdata.A3}}, {{ArtifactInput: testdata.A4}}}, + BB: []*model.IDorBuilderInput{{BuilderInput: testdata.B1}, {BuilderInput: testdata.B1}, {BuilderInput: testdata.B1}}, SLSA: []*model.SLSAInputSpec{ {}, {}, @@ -822,12 +822,12 @@ func TestIngestHasSLSAs(t *testing.T) { for _, test := range tests { t.Run(test.Name, func(t *testing.T) { for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { + if _, err := b.IngestArtifact(ctx, &model.IDorArtifactInput{ArtifactInput: a}); err != nil { t.Fatalf("Could not ingest artifact: %v", err) } } for _, bld := range test.InBld { - if _, err := b.IngestBuilder(ctx, bld); err != nil { + if _, err := b.IngestBuilder(ctx, &model.IDorBuilderInput{BuilderInput: bld}); err != nil { t.Fatalf("Could not ingest builder: %v", err) } } diff --git a/internal/testing/backend/hasSourceAt_test.go b/internal/testing/backend/hasSourceAt_test.go index d6b109bbea..abed0bdbcd 100644 --- a/internal/testing/backend/hasSourceAt_test.go +++ b/internal/testing/backend/hasSourceAt_test.go @@ -549,7 +549,7 @@ func TestHasSourceAt(t *testing.T) { for _, test := range tests { t.Run(test.Name, func(t *testing.T) { for _, p := range test.InPkg { - if pkgIDs, err := b.IngestPackage(ctx, *p); err != nil { + if pkgIDs, err := b.IngestPackage(ctx, model.IDorPkgInput{PackageInput: p}); err != nil { t.Fatalf("Could not ingest package: %v", err) } else { if test.QueryPkgID { @@ -562,7 +562,7 @@ func TestHasSourceAt(t *testing.T) { } } for _, s := range test.InSrc { - if srcIDs, err := b.IngestSource(ctx, *s); err != nil { + if srcIDs, err := b.IngestSource(ctx, model.IDorSourceInput{SourceInput: s}); err != nil { t.Fatalf("Could not ingest source: %v", err) } else { if test.QuerySourceID { @@ -575,7 +575,7 @@ func TestHasSourceAt(t *testing.T) { } } for _, o := range test.Calls { - hsID, err := b.IngestHasSourceAt(ctx, *o.Pkg, *o.Match, *o.Src, *o.HSA) + hsID, err := b.IngestHasSourceAt(ctx, model.IDorPkgInput{PackageInput: o.Pkg}, *o.Match, model.IDorSourceInput{SourceInput: o.Src}, *o.HSA) if (err != nil) != test.ExpIngestErr { t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) } @@ -606,8 +606,8 @@ func TestIngestHasSourceAts(t *testing.T) { ctx := context.Background() b := setupTest(t) type call struct { - Pkgs []*model.PkgInputSpec - Srcs []*model.SourceInputSpec + Pkgs []*model.IDorPkgInput + Srcs []*model.IDorSourceInput Match *model.MatchFlags HSAs []*model.HasSourceAtInputSpec } @@ -627,8 +627,8 @@ func TestIngestHasSourceAts(t *testing.T) { InSrc: []*model.SourceInputSpec{testdata.S1}, Calls: []call{ { - Pkgs: []*model.PkgInputSpec{testdata.P1}, - Srcs: []*model.SourceInputSpec{testdata.S1}, + Pkgs: []*model.IDorPkgInput{&model.IDorPkgInput{PackageInput: testdata.P1}}, + Srcs: []*model.IDorSourceInput{&model.IDorSourceInput{SourceInput: testdata.S1}}, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, }, @@ -656,8 +656,8 @@ func TestIngestHasSourceAts(t *testing.T) { InSrc: []*model.SourceInputSpec{testdata.S1}, Calls: []call{ { - Pkgs: []*model.PkgInputSpec{testdata.P1}, - Srcs: []*model.SourceInputSpec{testdata.S1}, + Pkgs: []*model.IDorPkgInput{&model.IDorPkgInput{PackageInput: testdata.P1}}, + Srcs: []*model.IDorSourceInput{&model.IDorSourceInput{SourceInput: testdata.S1}}, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeAllVersions, }, @@ -690,8 +690,8 @@ func TestIngestHasSourceAts(t *testing.T) { InSrc: []*model.SourceInputSpec{testdata.S1}, Calls: []call{ { - Pkgs: []*model.PkgInputSpec{testdata.P3, testdata.P1}, - Srcs: []*model.SourceInputSpec{testdata.S1, testdata.S1}, + Pkgs: []*model.IDorPkgInput{{PackageInput: testdata.P3}, {PackageInput: testdata.P3}}, + Srcs: []*model.IDorSourceInput{{SourceInput: testdata.S1}, {SourceInput: testdata.S1}}, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, }, @@ -730,8 +730,8 @@ func TestIngestHasSourceAts(t *testing.T) { InSrc: []*model.SourceInputSpec{testdata.S1}, Calls: []call{ { - Pkgs: []*model.PkgInputSpec{testdata.P1, testdata.P4}, - Srcs: []*model.SourceInputSpec{testdata.S1, testdata.S1}, + Pkgs: []*model.IDorPkgInput{{PackageInput: testdata.P1}, {PackageInput: testdata.P4}}, + Srcs: []*model.IDorSourceInput{{SourceInput: testdata.S1}, {SourceInput: testdata.S1}}, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, }, @@ -766,8 +766,8 @@ func TestIngestHasSourceAts(t *testing.T) { InSrc: []*model.SourceInputSpec{testdata.S1, testdata.S3}, Calls: []call{ { - Pkgs: []*model.PkgInputSpec{testdata.P1, testdata.P1}, - Srcs: []*model.SourceInputSpec{testdata.S1, testdata.S3}, + Pkgs: []*model.IDorPkgInput{{PackageInput: testdata.P1}, {PackageInput: testdata.P1}}, + Srcs: []*model.IDorSourceInput{{SourceInput: testdata.S1}, {SourceInput: testdata.S3}}, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, }, @@ -803,8 +803,8 @@ func TestIngestHasSourceAts(t *testing.T) { InSrc: []*model.SourceInputSpec{testdata.S1}, Calls: []call{ { - Pkgs: []*model.PkgInputSpec{testdata.P1, testdata.P1}, - Srcs: []*model.SourceInputSpec{testdata.S1, testdata.S1}, + Pkgs: []*model.IDorPkgInput{{PackageInput: testdata.P1}, {PackageInput: testdata.P1}}, + Srcs: []*model.IDorSourceInput{{SourceInput: testdata.S1}, {SourceInput: testdata.S1}}, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, }, @@ -833,12 +833,12 @@ func TestIngestHasSourceAts(t *testing.T) { for _, test := range tests { t.Run(test.Name, func(t *testing.T) { for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { + if _, err := b.IngestPackage(ctx, model.IDorPkgInput{PackageInput: p}); err != nil { t.Fatalf("Could not ingest package: %v", err) } } for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { + if _, err := b.IngestSource(ctx, model.IDorSourceInput{SourceInput: s}); err != nil { t.Fatalf("Could not ingest source: %v", err) } } diff --git a/internal/testing/backend/hashEqual_test.go b/internal/testing/backend/hashEqual_test.go index e36607cfbd..853eca4a50 100644 --- a/internal/testing/backend/hashEqual_test.go +++ b/internal/testing/backend/hashEqual_test.go @@ -39,7 +39,7 @@ func TestHashEqual(t *testing.T) { } tests := []struct { Name string - InArt []*model.ArtifactInputSpec + InArt []*model.IDorArtifactInput Calls []call Query *model.HashEqualSpec QueryID bool @@ -50,7 +50,7 @@ func TestHashEqual(t *testing.T) { }{ { Name: "HappyPath", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, + InArt: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}, {ArtifactInput: testdata.A2}}, Calls: []call{ { A1: testdata.A1, @@ -72,7 +72,7 @@ func TestHashEqual(t *testing.T) { }, { Name: "Ingest same, different order", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, + InArt: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}, {ArtifactInput: testdata.A2}}, Calls: []call{ { A1: testdata.A1, @@ -101,7 +101,7 @@ func TestHashEqual(t *testing.T) { }, { Name: "Query on Justification", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, + InArt: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}, {ArtifactInput: testdata.A2}}, Calls: []call{ { A1: testdata.A1, @@ -130,7 +130,7 @@ func TestHashEqual(t *testing.T) { }, { Name: "Query on artifact", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2, testdata.A3}, + InArt: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}, {ArtifactInput: testdata.A2}, {ArtifactInput: testdata.A3}}, Calls: []call{ { A1: testdata.A1, @@ -156,7 +156,7 @@ func TestHashEqual(t *testing.T) { }, { Name: "Query on artifact ID", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2, testdata.A3}, + InArt: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}, {ArtifactInput: testdata.A2}, {ArtifactInput: testdata.A3}}, Calls: []call{ { A1: testdata.A1, @@ -178,7 +178,7 @@ func TestHashEqual(t *testing.T) { }, { Name: "Query on artifact multiple", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2, testdata.A3}, + InArt: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}, {ArtifactInput: testdata.A2}, {ArtifactInput: testdata.A3}}, Calls: []call{ { A1: testdata.A1, @@ -219,7 +219,7 @@ func TestHashEqual(t *testing.T) { }, { Name: "Query on artifact algo", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2, testdata.A3}, + InArt: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}, {ArtifactInput: testdata.A2}, {ArtifactInput: testdata.A3}}, Calls: []call{ { A1: testdata.A1, @@ -257,7 +257,7 @@ func TestHashEqual(t *testing.T) { }, { Name: "Query on artifact algo and hash", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2, testdata.A3}, + InArt: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}, {ArtifactInput: testdata.A2}, {ArtifactInput: testdata.A3}}, Calls: []call{ { A1: testdata.A1, @@ -296,7 +296,7 @@ func TestHashEqual(t *testing.T) { }, { Name: "Query on both artifacts", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2, testdata.A3}, + InArt: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}, {ArtifactInput: testdata.A2}, {ArtifactInput: testdata.A3}}, Calls: []call{ { A1: testdata.A1, @@ -328,7 +328,7 @@ func TestHashEqual(t *testing.T) { }, { Name: "Query on both artifacts, one filter", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2, testdata.A3}, + InArt: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}, {ArtifactInput: testdata.A2}, {ArtifactInput: testdata.A3}}, Calls: []call{ { A1: testdata.A1, @@ -376,7 +376,7 @@ func TestHashEqual(t *testing.T) { }, { Name: "Query none", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2, testdata.A3}, + InArt: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}, {ArtifactInput: testdata.A2}, {ArtifactInput: testdata.A3}}, Calls: []call{ { A1: testdata.A1, @@ -408,7 +408,7 @@ func TestHashEqual(t *testing.T) { }, { Name: "Query on ID", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2, testdata.A3}, + InArt: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}, {ArtifactInput: testdata.A2}, {ArtifactInput: testdata.A3}}, Calls: []call{ { A1: testdata.A1, @@ -453,7 +453,7 @@ func TestHashEqual(t *testing.T) { } } for _, o := range test.Calls { - heID, err := b.IngestHashEqual(ctx, *o.A1, *o.A2, *o.HE) + heID, err := b.IngestHashEqual(ctx, model.IDorArtifactInput{ArtifactInput: o.A1}, model.IDorArtifactInput{ArtifactInput: o.A2}, *o.HE) if (err != nil) != test.ExpIngestErr { t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) } @@ -491,8 +491,8 @@ func TestIngestHashEquals(t *testing.T) { ctx := context.Background() b := setupTest(t) type call struct { - A1 []*model.ArtifactInputSpec - A2 []*model.ArtifactInputSpec + A1 []*model.IDorArtifactInput + A2 []*model.IDorArtifactInput HE []*model.HashEqualInputSpec } tests := []struct { @@ -509,8 +509,8 @@ func TestIngestHashEquals(t *testing.T) { InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, Calls: []call{ { - A1: []*model.ArtifactInputSpec{testdata.A1}, - A2: []*model.ArtifactInputSpec{testdata.A2}, + A1: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}}, + A2: []*model.IDorArtifactInput{{ArtifactInput: testdata.A2}}, HE: []*model.HashEqualInputSpec{ { Justification: "test justification", @@ -533,8 +533,8 @@ func TestIngestHashEquals(t *testing.T) { InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, Calls: []call{ { - A1: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - A2: []*model.ArtifactInputSpec{testdata.A2, testdata.A1}, + A1: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}, {ArtifactInput: testdata.A2}}, + A2: []*model.IDorArtifactInput{{ArtifactInput: testdata.A2}, {ArtifactInput: testdata.A1}}, HE: []*model.HashEqualInputSpec{ { Justification: "test justification", @@ -560,8 +560,8 @@ func TestIngestHashEquals(t *testing.T) { InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, Calls: []call{ { - A1: []*model.ArtifactInputSpec{testdata.A1, testdata.A1}, - A2: []*model.ArtifactInputSpec{testdata.A2, testdata.A2}, + A1: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}, {ArtifactInput: testdata.A1}}, + A2: []*model.IDorArtifactInput{{ArtifactInput: testdata.A2}, {ArtifactInput: testdata.A2}}, HE: []*model.HashEqualInputSpec{ { Justification: "test justification one", @@ -587,8 +587,8 @@ func TestIngestHashEquals(t *testing.T) { InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2, testdata.A3}, Calls: []call{ { - A1: []*model.ArtifactInputSpec{testdata.A1, testdata.A1}, - A2: []*model.ArtifactInputSpec{testdata.A2, testdata.A3}, + A1: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}, {ArtifactInput: testdata.A1}}, + A2: []*model.IDorArtifactInput{{ArtifactInput: testdata.A2}, {ArtifactInput: testdata.A3}}, HE: []*model.HashEqualInputSpec{ {}, {}, @@ -611,8 +611,8 @@ func TestIngestHashEquals(t *testing.T) { InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2, testdata.A3}, Calls: []call{ { - A1: []*model.ArtifactInputSpec{testdata.A1, testdata.A1}, - A2: []*model.ArtifactInputSpec{testdata.A2, testdata.A3}, + A1: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}, {ArtifactInput: testdata.A1}}, + A2: []*model.IDorArtifactInput{{ArtifactInput: testdata.A2}, {ArtifactInput: testdata.A3}}, HE: []*model.HashEqualInputSpec{ {}, {}, @@ -650,8 +650,8 @@ func TestIngestHashEquals(t *testing.T) { InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2, testdata.A3}, Calls: []call{ { - A1: []*model.ArtifactInputSpec{testdata.A1, testdata.A1}, - A2: []*model.ArtifactInputSpec{testdata.A2, testdata.A3}, + A1: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}, {ArtifactInput: testdata.A1}}, + A2: []*model.IDorArtifactInput{{ArtifactInput: testdata.A2}, {ArtifactInput: testdata.A3}}, HE: []*model.HashEqualInputSpec{ {}, {}, @@ -686,8 +686,8 @@ func TestIngestHashEquals(t *testing.T) { InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2, testdata.A3}, Calls: []call{ { - A1: []*model.ArtifactInputSpec{testdata.A1, testdata.A1}, - A2: []*model.ArtifactInputSpec{testdata.A2, testdata.A3}, + A1: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}, {ArtifactInput: testdata.A1}}, + A2: []*model.IDorArtifactInput{{ArtifactInput: testdata.A2}, {ArtifactInput: testdata.A3}}, HE: []*model.HashEqualInputSpec{ {}, {}, @@ -723,8 +723,8 @@ func TestIngestHashEquals(t *testing.T) { InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2, testdata.A3}, Calls: []call{ { - A1: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - A2: []*model.ArtifactInputSpec{testdata.A2, testdata.A3}, + A1: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}, {ArtifactInput: testdata.A2}}, + A2: []*model.IDorArtifactInput{{ArtifactInput: testdata.A2}, {ArtifactInput: testdata.A3}}, HE: []*model.HashEqualInputSpec{ {}, {}, @@ -752,7 +752,7 @@ func TestIngestHashEquals(t *testing.T) { for _, test := range tests { t.Run(test.Name, func(t *testing.T) { for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { + if _, err := b.IngestArtifact(ctx, &model.IDorArtifactInput{ArtifactInput: a}); err != nil { t.Fatalf("Could not ingest artifact: %v", err) } } diff --git a/internal/testing/backend/isDependency_test.go b/internal/testing/backend/isDependency_test.go index ed5bea45ea..9088346424 100644 --- a/internal/testing/backend/isDependency_test.go +++ b/internal/testing/backend/isDependency_test.go @@ -820,7 +820,7 @@ func TestIsDependency(t *testing.T) { for _, test := range tests { t.Run(test.Name, func(t *testing.T) { for _, a := range test.InPkg { - if pkgIDs, err := b.IngestPackage(ctx, *a); err != nil { + if pkgIDs, err := b.IngestPackage(ctx, model.IDorPkgInput{PackageInput: a}); err != nil { t.Fatalf("Could not ingest pkg: %v", err) } else { if test.QueryPkgID { @@ -840,7 +840,7 @@ func TestIsDependency(t *testing.T) { } } for _, o := range test.Calls { - depID, err := b.IngestDependency(ctx, *o.P1, *o.P2, o.MF, *o.ID) + depID, err := b.IngestDependency(ctx, model.IDorPkgInput{PackageInput: o.P1}, model.IDorPkgInput{PackageInput: o.P2}, o.MF, *o.ID) if (err != nil) != test.ExpIngestErr { t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) } @@ -871,8 +871,8 @@ func TestIsDependencies(t *testing.T) { ctx := context.Background() b := setupTest(t) type call struct { - P1s []*model.PkgInputSpec - P2s []*model.PkgInputSpec + P1s []*model.IDorPkgInput + P2s []*model.IDorPkgInput MF model.MatchFlags IDs []*model.IsDependencyInputSpec } @@ -888,8 +888,8 @@ func TestIsDependencies(t *testing.T) { Name: "HappyPath", InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2, testdata.P3, testdata.P4}, Calls: []call{{ - P1s: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - P2s: []*model.PkgInputSpec{testdata.P2, testdata.P4}, + P1s: []*model.IDorPkgInput{{PackageInput: testdata.P1}, {PackageInput: testdata.P2}}, + P2s: []*model.IDorPkgInput{{PackageInput: testdata.P2}, {PackageInput: testdata.P4}}, MF: mAll, IDs: []*model.IsDependencyInputSpec{ { @@ -912,8 +912,8 @@ func TestIsDependencies(t *testing.T) { Name: "HappyPath", InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2, testdata.P3, testdata.P4}, Calls: []call{{ - P1s: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - P2s: []*model.PkgInputSpec{testdata.P2, testdata.P4}, + P1s: []*model.IDorPkgInput{{PackageInput: testdata.P1}, {PackageInput: testdata.P2}}, + P2s: []*model.IDorPkgInput{{PackageInput: testdata.P2}, {PackageInput: testdata.P4}}, MF: mSpecific, IDs: []*model.IsDependencyInputSpec{ { @@ -936,7 +936,7 @@ func TestIsDependencies(t *testing.T) { for _, test := range tests { t.Run(test.Name, func(t *testing.T) { for _, a := range test.InPkg { - if _, err := b.IngestPackage(ctx, *a); err != nil { + if _, err := b.IngestPackage(ctx, model.IDorPkgInput{PackageInput: a}); err != nil { t.Fatalf("Could not ingest pkg: %v", err) } } diff --git a/internal/testing/backend/isOccurrence_test.go b/internal/testing/backend/isOccurrence_test.go index aa5d57e0d3..3c7d6bc4b3 100644 --- a/internal/testing/backend/isOccurrence_test.go +++ b/internal/testing/backend/isOccurrence_test.go @@ -58,7 +58,7 @@ func TestOccurrence(t *testing.T) { Calls: []call{ { PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Artifact: testdata.A1, Occurrence: &model.IsOccurrenceInputSpec{ @@ -84,7 +84,7 @@ func TestOccurrence(t *testing.T) { Calls: []call{ { PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Artifact: testdata.A1, Occurrence: &model.IsOccurrenceInputSpec{ @@ -93,7 +93,7 @@ func TestOccurrence(t *testing.T) { }, { PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Artifact: testdata.A1, Occurrence: &model.IsOccurrenceInputSpec{ @@ -119,7 +119,7 @@ func TestOccurrence(t *testing.T) { Calls: []call{ { PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Artifact: testdata.A1, Occurrence: &model.IsOccurrenceInputSpec{ @@ -128,7 +128,7 @@ func TestOccurrence(t *testing.T) { }, { PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Artifact: testdata.A1, Occurrence: &model.IsOccurrenceInputSpec{ @@ -154,7 +154,7 @@ func TestOccurrence(t *testing.T) { Calls: []call{ { PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Artifact: testdata.A4, Occurrence: &model.IsOccurrenceInputSpec{ @@ -163,7 +163,7 @@ func TestOccurrence(t *testing.T) { }, { PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Artifact: testdata.A2, Occurrence: &model.IsOccurrenceInputSpec{ @@ -192,7 +192,7 @@ func TestOccurrence(t *testing.T) { Calls: []call{ { PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Artifact: testdata.A2, Occurrence: &model.IsOccurrenceInputSpec{ @@ -201,7 +201,7 @@ func TestOccurrence(t *testing.T) { }, { PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Artifact: testdata.A4, Occurrence: &model.IsOccurrenceInputSpec{ @@ -225,7 +225,7 @@ func TestOccurrence(t *testing.T) { Calls: []call{ { PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P4, + Package: &model.IDorPkgInput{PackageInput: testdata.P4}, }, Artifact: testdata.A1, Occurrence: &model.IsOccurrenceInputSpec{ @@ -234,7 +234,7 @@ func TestOccurrence(t *testing.T) { }, { PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P2, + Package: &model.IDorPkgInput{PackageInput: testdata.P2}, }, Artifact: testdata.A1, Occurrence: &model.IsOccurrenceInputSpec{ @@ -264,7 +264,7 @@ func TestOccurrence(t *testing.T) { Calls: []call{ { PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P2, + Package: &model.IDorPkgInput{PackageInput: testdata.P2}, }, Artifact: testdata.A1, Occurrence: &model.IsOccurrenceInputSpec{ @@ -273,7 +273,7 @@ func TestOccurrence(t *testing.T) { }, { PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P4, + Package: &model.IDorPkgInput{PackageInput: testdata.P4}, }, Artifact: testdata.A1, Occurrence: &model.IsOccurrenceInputSpec{ @@ -298,7 +298,7 @@ func TestOccurrence(t *testing.T) { Calls: []call{ { PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Artifact: testdata.A1, Occurrence: &model.IsOccurrenceInputSpec{ @@ -307,7 +307,7 @@ func TestOccurrence(t *testing.T) { }, { PkgSrc: model.PackageOrSourceInput{ - Source: testdata.S1, + Source: &model.IDorSourceInput{SourceInput: testdata.S1}, }, Artifact: testdata.A1, Occurrence: &model.IsOccurrenceInputSpec{ @@ -336,7 +336,7 @@ func TestOccurrence(t *testing.T) { Calls: []call{ { PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Artifact: testdata.A1, Occurrence: &model.IsOccurrenceInputSpec{ @@ -345,7 +345,7 @@ func TestOccurrence(t *testing.T) { }, { PkgSrc: model.PackageOrSourceInput{ - Source: testdata.S1, + Source: &model.IDorSourceInput{SourceInput: testdata.S1}, }, Artifact: testdata.A1, Occurrence: &model.IsOccurrenceInputSpec{ @@ -369,7 +369,7 @@ func TestOccurrence(t *testing.T) { Calls: []call{ { PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Artifact: testdata.A1, Occurrence: &model.IsOccurrenceInputSpec{ @@ -390,7 +390,7 @@ func TestOccurrence(t *testing.T) { Calls: []call{ { PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Artifact: testdata.A1, Occurrence: &model.IsOccurrenceInputSpec{ @@ -414,7 +414,7 @@ func TestOccurrence(t *testing.T) { Calls: []call{ { PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P4, + Package: &model.IDorPkgInput{PackageInput: testdata.P4}, }, Artifact: testdata.A1, Occurrence: &model.IsOccurrenceInputSpec{ @@ -423,7 +423,7 @@ func TestOccurrence(t *testing.T) { }, { PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P4, + Package: &model.IDorPkgInput{PackageInput: testdata.P4}, }, Artifact: testdata.A2, Occurrence: &model.IsOccurrenceInputSpec{ @@ -456,7 +456,7 @@ func TestOccurrence(t *testing.T) { for _, test := range tests { t.Run(test.Name, func(t *testing.T) { for _, p := range test.InPkg { - if pkgIDs, err := b.IngestPackage(ctx, *p); err != nil { + if pkgIDs, err := b.IngestPackage(ctx, model.IDorPkgInput{PackageInput: p}); err != nil { t.Fatalf("Could not ingest package: %v", err) } else { if test.QueryPkgID { @@ -471,7 +471,7 @@ func TestOccurrence(t *testing.T) { } } for _, s := range test.InSrc { - if srcIDs, err := b.IngestSource(ctx, *s); err != nil { + if srcIDs, err := b.IngestSource(ctx, model.IDorSourceInput{SourceInput: s}); err != nil { t.Fatalf("Could not ingest source: %v", err) } else { if test.QuerySourceID { @@ -486,7 +486,7 @@ func TestOccurrence(t *testing.T) { } } for _, a := range test.InArt { - if artID, err := b.IngestArtifact(ctx, a); err != nil { + if artID, err := b.IngestArtifact(ctx, &model.IDorArtifactInput{ArtifactInput: a}); err != nil { t.Fatalf("Could not ingest artifact: %v", err) } else { if test.QueryArtID { @@ -500,7 +500,7 @@ func TestOccurrence(t *testing.T) { } } for _, o := range test.Calls { - ocurID, err := b.IngestOccurrence(ctx, o.PkgSrc, *o.Artifact, *o.Occurrence) + ocurID, err := b.IngestOccurrence(ctx, o.PkgSrc, model.IDorArtifactInput{ArtifactInput: o.Artifact}, *o.Occurrence) if (err != nil) != test.ExpIngestErr { t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) } @@ -532,7 +532,7 @@ func TestIngestOccurrences(t *testing.T) { b := setupTest(t) type call struct { PkgSrcs model.PackageOrSourceInputs - Artifacts []*model.ArtifactInputSpec + Artifacts []*model.IDorArtifactInput Occurrences []*model.IsOccurrenceInputSpec } tests := []struct { @@ -551,9 +551,9 @@ func TestIngestOccurrences(t *testing.T) { Calls: []call{ { PkgSrcs: model.PackageOrSourceInputs{ - Packages: []*model.PkgInputSpec{testdata.P1, testdata.P2}, + Packages: []*model.IDorPkgInput{{PackageInput: testdata.P1}, {PackageInput: testdata.P2}}, }, - Artifacts: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, + Artifacts: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}, {ArtifactInput: testdata.A2}}, Occurrences: []*model.IsOccurrenceInputSpec{{ Justification: "test justification", }, { @@ -575,9 +575,9 @@ func TestIngestOccurrences(t *testing.T) { Calls: []call{ { PkgSrcs: model.PackageOrSourceInputs{ - Sources: []*model.SourceInputSpec{testdata.S1}, + Sources: []*model.IDorSourceInput{&model.IDorSourceInput{SourceInput: testdata.S1}}, }, - Artifacts: []*model.ArtifactInputSpec{testdata.A1}, + Artifacts: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}}, Occurrences: []*model.IsOccurrenceInputSpec{{ Justification: "test justification", }}, @@ -594,17 +594,17 @@ func TestIngestOccurrences(t *testing.T) { for _, test := range tests { t.Run(test.Name, func(t *testing.T) { for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { + if _, err := b.IngestPackage(ctx, model.IDorPkgInput{PackageInput: p}); err != nil { t.Fatalf("Could not ingest package: %v", err) } } for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { + if _, err := b.IngestSource(ctx, model.IDorSourceInput{SourceInput: s}); err != nil { t.Fatalf("Could not ingest source: %v", err) } } for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { + if _, err := b.IngestArtifact(ctx, &model.IDorArtifactInput{ArtifactInput: a}); err != nil { t.Fatalf("Could not ingest artifact: %v", err) } } diff --git a/internal/testing/backend/license_test.go b/internal/testing/backend/license_test.go index c23db078ae..3b5f595348 100644 --- a/internal/testing/backend/license_test.go +++ b/internal/testing/backend/license_test.go @@ -97,7 +97,7 @@ func TestLicenses(t *testing.T) { for _, tt := range tests { t.Run(tt.Name, func(t *testing.T) { for i, ingest := range tt.Ingests { - ingestedLicenseID, err := b.IngestLicense(ctx, ingest) + ingestedLicenseID, err := b.IngestLicense(ctx, &model.IDorLicenseInput{LicenseInput: ingest}) if (err != nil) != tt.ExpIngestErr { t.Errorf("arangoClient.IngestLicense() error = %v, wantErr %v", err, tt.ExpIngestErr) return @@ -129,7 +129,7 @@ func TestLicensesBulk(t *testing.T) { b := setupTest(t) tests := []struct { Name string - Ingests []*model.LicenseInputSpec + Ingests []*model.IDorLicenseInput ExpIngestErr bool Query *model.LicenseSpec Exp []*model.License @@ -137,7 +137,7 @@ func TestLicensesBulk(t *testing.T) { }{ { Name: "Query by Name", - Ingests: []*model.LicenseInputSpec{testdata.L1, testdata.L1, testdata.L2, testdata.L3, testdata.L4}, + Ingests: []*model.IDorLicenseInput{{LicenseInput: testdata.L1}, {LicenseInput: testdata.L1}, {LicenseInput: testdata.L2}, {LicenseInput: testdata.L3}, {LicenseInput: testdata.L4}}, Query: &model.LicenseSpec{ Name: ptrfrom.String("BSD-3-Clause"), }, diff --git a/internal/testing/backend/path_test.go b/internal/testing/backend/path_test.go index c18146e56f..1eac24dcfa 100644 --- a/internal/testing/backend/path_test.go +++ b/internal/testing/backend/path_test.go @@ -169,13 +169,13 @@ func TestPath(t *testing.T) { if tt.certifyVulnTwoPkgsCall != nil { var nonVulnPkgID string for _, p := range tt.inPkg { - pkg, err := b.IngestPackage(ctx, *p) + pkg, err := b.IngestPackage(ctx, model.IDorPkgInput{PackageInput: p}) if err != nil { t.Fatalf("Could not ingest package: %v", err) } nonVulnPkgID = pkg.PackageVersionID } - cvID, err := b.IngestCertifyVuln(ctx, *tt.certifyVulnTwoPkgsCall.Pkg, *tt.certifyVulnTwoPkgsCall.Vuln, *tt.certifyVulnTwoPkgsCall.CertifyVuln) + cvID, err := b.IngestCertifyVuln(ctx, model.IDorPkgInput{PackageInput: tt.certifyVulnTwoPkgsCall.Pkg}, model.IDorVulnerabilityInput{VulnerabilityInput: tt.certifyVulnTwoPkgsCall.Vuln}, *tt.certifyVulnTwoPkgsCall.CertifyVuln) if (err != nil) != tt.wantErr { t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) } @@ -187,20 +187,20 @@ func TestPath(t *testing.T) { } if tt.certifyVulnCall != nil { for _, p := range tt.inPkg { - if pkgIDs, err := b.IngestPackage(ctx, *p); err != nil { + if pkgIDs, err := b.IngestPackage(ctx, model.IDorPkgInput{PackageInput: p}); err != nil { t.Fatalf("Could not ingest package: %v", err) } else { startID = pkgIDs.PackageVersionID } } for _, g := range tt.inVuln { - if vulnIDs, err := b.IngestVulnerability(ctx, *g); err != nil { + if vulnIDs, err := b.IngestVulnerability(ctx, model.IDorVulnerabilityInput{VulnerabilityInput: g}); err != nil { t.Fatalf("Could not ingest vulnerability: %a", err) } else { stopID = vulnIDs.VulnerabilityNodeID } } - _, err := b.IngestCertifyVuln(ctx, *tt.certifyVulnCall.Pkg, *tt.certifyVulnCall.Vuln, *tt.certifyVulnCall.CertifyVuln) + _, err := b.IngestCertifyVuln(ctx, model.IDorPkgInput{PackageInput: tt.certifyVulnCall.Pkg}, model.IDorVulnerabilityInput{VulnerabilityInput: tt.certifyVulnCall.Vuln}, *tt.certifyVulnCall.CertifyVuln) if (err != nil) != tt.wantErr { t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) } @@ -210,11 +210,11 @@ func TestPath(t *testing.T) { } if tt.isDepCall != nil { for _, p := range tt.inPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { + if _, err := b.IngestPackage(ctx, model.IDorPkgInput{PackageInput: p}); err != nil { t.Fatalf("Could not ingest package: %v", err) } } - dID, err := b.IngestDependency(ctx, *tt.isDepCall.P1, *tt.isDepCall.P2, tt.isDepCall.MF, *tt.isDepCall.ID) + dID, err := b.IngestDependency(ctx, model.IDorPkgInput{PackageInput: tt.isDepCall.P1}, model.IDorPkgInput{PackageInput: tt.isDepCall.P2}, tt.isDepCall.MF, *tt.isDepCall.ID) if (err != nil) != tt.wantErr { t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) } @@ -255,8 +255,8 @@ func TestNodes(t *testing.T) { } type certifyLegalCall struct { PkgSrc model.PackageOrSourceInput - Dec []*model.LicenseInputSpec - Dis []*model.LicenseInputSpec + Dec []*model.IDorLicenseInput + Dis []*model.IDorLicenseInput Legal *model.CertifyLegalInputSpec } type scorecardCall struct { @@ -289,7 +289,7 @@ func TestNodes(t *testing.T) { } type hasSlsaCall struct { Sub *model.ArtifactInputSpec - BF []*model.ArtifactInputSpec + BF []*model.IDorArtifactInput BB *model.BuilderInputSpec SLSA *model.SLSAInputSpec } @@ -408,7 +408,7 @@ func TestNodes(t *testing.T) { inPkg: []*model.PkgInputSpec{testdata.P1}, certifyBadCall: &certifyBadCall{ Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -426,7 +426,7 @@ func TestNodes(t *testing.T) { inPkg: []*model.PkgInputSpec{testdata.P1}, certifyGoodCall: &certifyGoodCall{ Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -445,9 +445,9 @@ func TestNodes(t *testing.T) { inLic: []*model.LicenseInputSpec{testdata.L1}, certifyLegalCall: &certifyLegalCall{ PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, - Dec: []*model.LicenseInputSpec{testdata.L1}, + Dec: []*model.IDorLicenseInput{{LicenseInput: testdata.L1}}, Legal: &model.CertifyLegalInputSpec{ Justification: "test justification 2", }, @@ -479,7 +479,7 @@ func TestNodes(t *testing.T) { inVuln: []*model.VulnerabilityInputSpec{testdata.O2}, vexCall: &vexCall{ Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Vuln: testdata.O2, In: &model.VexStatementInputSpec{ @@ -537,7 +537,7 @@ func TestNodes(t *testing.T) { inArt: []*model.ArtifactInputSpec{testdata.A2}, hasMetadataCall: &hasMetadataCall{ Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A2}, }, HM: &model.HasMetadataInputSpec{ Justification: "test justification", @@ -553,7 +553,7 @@ func TestNodes(t *testing.T) { hasSBOMCall: &hasSBOMCall{ Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, HS: &model.HasSBOMInputSpec{ DownloadLocation: "location two", @@ -569,7 +569,7 @@ func TestNodes(t *testing.T) { inBld: []*model.BuilderInputSpec{testdata.B1, testdata.B2}, hasSlsaCall: &hasSlsaCall{ Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, + BF: []*model.IDorArtifactInput{&model.IDorArtifactInput{ArtifactInput: testdata.A2}}, BB: testdata.B2, SLSA: &model.SLSAInputSpec{}, }, @@ -615,7 +615,7 @@ func TestNodes(t *testing.T) { inArt: []*model.ArtifactInputSpec{testdata.A1}, isOcurCall: &isOcurCall{ PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Artifact: testdata.A1, Occurrence: &model.IsOccurrenceInputSpec{ @@ -647,7 +647,7 @@ func TestNodes(t *testing.T) { inArt: []*model.ArtifactInputSpec{testdata.A2}, pointOfContactCall: &pointOfContactCall{ Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A2}, }, POC: &model.PointOfContactInputSpec{ Justification: "test justification", @@ -709,37 +709,37 @@ func TestNodes(t *testing.T) { t.Run(tt.name, func(t *testing.T) { var nodeID string for _, p := range tt.inPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { + if _, err := b.IngestPackage(ctx, model.IDorPkgInput{PackageInput: p}); err != nil { t.Fatalf("Could not ingest package: %v", err) } } for _, s := range tt.inSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { + if _, err := b.IngestSource(ctx, model.IDorSourceInput{SourceInput: s}); err != nil { t.Fatalf("Could not ingest source: %v", err) } } for _, a := range tt.inArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { + if _, err := b.IngestArtifact(ctx, &model.IDorArtifactInput{ArtifactInput: a}); err != nil { t.Fatalf("Could not ingest artifact: %v", err) } } for _, bld := range tt.inBld { - if _, err := b.IngestBuilder(ctx, bld); err != nil { + if _, err := b.IngestBuilder(ctx, &model.IDorBuilderInput{BuilderInput: bld}); err != nil { t.Fatalf("Could not ingest builder: %v", err) } } for _, a := range tt.inLic { - if _, err := b.IngestLicense(ctx, a); err != nil { + if _, err := b.IngestLicense(ctx, &model.IDorLicenseInput{LicenseInput: a}); err != nil { t.Fatalf("Could not ingest license: %v", err) } } for _, g := range tt.inVuln { - if _, err := b.IngestVulnerability(ctx, *g); err != nil { + if _, err := b.IngestVulnerability(ctx, model.IDorVulnerabilityInput{VulnerabilityInput: g}); err != nil { t.Fatalf("Could not ingest vulnerability: %a", err) } } if tt.pkgInput != nil { - ingestedPkg, err := b.IngestPackage(ctx, *tt.pkgInput) + ingestedPkg, err := b.IngestPackage(ctx, model.IDorPkgInput{PackageInput: tt.pkgInput}) if (err != nil) != tt.wantErr { t.Errorf("arangoClient.IngestPackage() error = %v, wantErr %v", err, tt.wantErr) return @@ -747,7 +747,7 @@ func TestNodes(t *testing.T) { nodeID = ingestedPkg.PackageVersionID } if tt.artifactInput != nil { - ingestedArtID, err := b.IngestArtifact(ctx, tt.artifactInput) + ingestedArtID, err := b.IngestArtifact(ctx, &model.IDorArtifactInput{ArtifactInput: tt.artifactInput}) if (err != nil) != tt.wantErr { t.Errorf("arangoClient.IngestArtifact() error = %v, wantErr %v", err, tt.wantErr) return @@ -755,7 +755,7 @@ func TestNodes(t *testing.T) { nodeID = ingestedArtID } if tt.builderInput != nil { - ingestedBuilderID, err := b.IngestBuilder(ctx, tt.builderInput) + ingestedBuilderID, err := b.IngestBuilder(ctx, &model.IDorBuilderInput{BuilderInput: tt.builderInput}) if (err != nil) != tt.wantErr { t.Errorf("arangoClient.IngestBuilder() error = %v, wantErr %v", err, tt.wantErr) return @@ -763,7 +763,7 @@ func TestNodes(t *testing.T) { nodeID = ingestedBuilderID } if tt.srcInput != nil { - ingestedSrc, err := b.IngestSource(ctx, *tt.srcInput) + ingestedSrc, err := b.IngestSource(ctx, model.IDorSourceInput{SourceInput: tt.srcInput}) if (err != nil) != tt.wantErr { t.Errorf("arangoClient.IngestSource() error = %v, wantErr %v", err, tt.wantErr) return @@ -771,14 +771,14 @@ func TestNodes(t *testing.T) { nodeID = ingestedSrc.SourceNameID } if tt.vulnInput != nil { - ingestVuln, err := b.IngestVulnerability(ctx, *tt.vulnInput) + ingestVuln, err := b.IngestVulnerability(ctx, model.IDorVulnerabilityInput{VulnerabilityInput: tt.vulnInput}) if (err != nil) != tt.wantErr { t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.want, err) } nodeID = ingestVuln.VulnerabilityNodeID } if tt.licenseInput != nil { - ingestedLicenseID, err := b.IngestLicense(ctx, tt.licenseInput) + ingestedLicenseID, err := b.IngestLicense(ctx, &model.IDorLicenseInput{LicenseInput: tt.licenseInput}) if (err != nil) != tt.wantErr { t.Errorf("arangoClient.IngestLicense() error = %v, wantErr %v", err, tt.wantErr) return @@ -816,7 +816,7 @@ func TestNodes(t *testing.T) { nodeID = cLID } if tt.scorecardCall != nil { - sID, err := b.IngestScorecard(ctx, *tt.scorecardCall.Src, *tt.scorecardCall.SC) + sID, err := b.IngestScorecard(ctx, model.IDorSourceInput{SourceInput: tt.scorecardCall.Src}, *tt.scorecardCall.SC) if (err != nil) != tt.wantErr { t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) } @@ -826,7 +826,7 @@ func TestNodes(t *testing.T) { nodeID = sID } if tt.vexCall != nil { - vID, err := b.IngestVEXStatement(ctx, tt.vexCall.Sub, *tt.vexCall.Vuln, *tt.vexCall.In) + vID, err := b.IngestVEXStatement(ctx, tt.vexCall.Sub, model.IDorVulnerabilityInput{VulnerabilityInput: tt.vexCall.Vuln}, *tt.vexCall.In) if (err != nil) != tt.wantErr { t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) } @@ -836,7 +836,7 @@ func TestNodes(t *testing.T) { nodeID = vID } if tt.certifyVulnCall != nil { - cvID, err := b.IngestCertifyVuln(ctx, *tt.certifyVulnCall.Pkg, *tt.certifyVulnCall.Vuln, *tt.certifyVulnCall.CertifyVuln) + cvID, err := b.IngestCertifyVuln(ctx, model.IDorPkgInput{PackageInput: tt.certifyVulnCall.Pkg}, model.IDorVulnerabilityInput{VulnerabilityInput: tt.certifyVulnCall.Vuln}, *tt.certifyVulnCall.CertifyVuln) if (err != nil) != tt.wantErr { t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) } @@ -846,7 +846,7 @@ func TestNodes(t *testing.T) { nodeID = cvID } if tt.hashEqualCall != nil { - heID, err := b.IngestHashEqual(ctx, *tt.hashEqualCall.A1, *tt.hashEqualCall.A2, *tt.hashEqualCall.HE) + heID, err := b.IngestHashEqual(ctx, model.IDorArtifactInput{ArtifactInput: tt.hashEqualCall.A1}, model.IDorArtifactInput{ArtifactInput: tt.hashEqualCall.A2}, *tt.hashEqualCall.HE) if (err != nil) != tt.wantErr { t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) } @@ -877,7 +877,7 @@ func TestNodes(t *testing.T) { nodeID = hsID } if tt.hasSlsaCall != nil { - sID, err := b.IngestSLSA(ctx, *tt.hasSlsaCall.Sub, tt.hasSlsaCall.BF, *tt.hasSlsaCall.BB, *tt.hasSlsaCall.SLSA) + sID, err := b.IngestSLSA(ctx, model.IDorArtifactInput{ArtifactInput: tt.hasSlsaCall.Sub}, tt.hasSlsaCall.BF, model.IDorBuilderInput{BuilderInput: tt.hasSlsaCall.BB}, *tt.hasSlsaCall.SLSA) if (err != nil) != tt.wantErr { t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) } @@ -887,7 +887,7 @@ func TestNodes(t *testing.T) { nodeID = sID } if tt.hasSourceAtCall != nil { - hsID, err := b.IngestHasSourceAt(ctx, *tt.hasSourceAtCall.Pkg, *tt.hasSourceAtCall.Match, *tt.hasSourceAtCall.Src, *tt.hasSourceAtCall.HSA) + hsID, err := b.IngestHasSourceAt(ctx, model.IDorPkgInput{PackageInput: tt.hasSourceAtCall.Pkg}, *tt.hasSourceAtCall.Match, model.IDorSourceInput{SourceInput: tt.hasSourceAtCall.Src}, *tt.hasSourceAtCall.HSA) if (err != nil) != tt.wantErr { t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) } @@ -897,7 +897,7 @@ func TestNodes(t *testing.T) { nodeID = hsID } if tt.isDepCall != nil { - dID, err := b.IngestDependency(ctx, *tt.isDepCall.P1, *tt.isDepCall.P2, tt.isDepCall.MF, *tt.isDepCall.ID) + dID, err := b.IngestDependency(ctx, model.IDorPkgInput{PackageInput: tt.isDepCall.P1}, model.IDorPkgInput{PackageInput: tt.isDepCall.P2}, tt.isDepCall.MF, *tt.isDepCall.ID) if (err != nil) != tt.wantErr { t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) } @@ -907,7 +907,7 @@ func TestNodes(t *testing.T) { nodeID = dID } if tt.isOcurCall != nil { - oID, err := b.IngestOccurrence(ctx, tt.isOcurCall.PkgSrc, *tt.isOcurCall.Artifact, *tt.isOcurCall.Occurrence) + oID, err := b.IngestOccurrence(ctx, tt.isOcurCall.PkgSrc, model.IDorArtifactInput{ArtifactInput: tt.isOcurCall.Artifact}, *tt.isOcurCall.Occurrence) if (err != nil) != tt.wantErr { t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) } @@ -917,7 +917,7 @@ func TestNodes(t *testing.T) { nodeID = oID } if tt.pkgEqualCall != nil { - peID, err := b.IngestPkgEqual(ctx, *tt.pkgEqualCall.P1, *tt.pkgEqualCall.P2, *tt.pkgEqualCall.HE) + peID, err := b.IngestPkgEqual(ctx, model.IDorPkgInput{PackageInput: tt.pkgEqualCall.P1}, model.IDorPkgInput{PackageInput: tt.pkgEqualCall.P2}, *tt.pkgEqualCall.HE) if (err != nil) != tt.wantErr { t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) } @@ -937,7 +937,7 @@ func TestNodes(t *testing.T) { nodeID = pocID } if tt.vulnEqualCall != nil { - veID, err := b.IngestVulnEqual(ctx, *tt.vulnEqualCall.Vuln, *tt.vulnEqualCall.OtherVuln, *tt.vulnEqualCall.In) + veID, err := b.IngestVulnEqual(ctx, model.IDorVulnerabilityInput{VulnerabilityInput: tt.vulnEqualCall.Vuln}, model.IDorVulnerabilityInput{VulnerabilityInput: tt.vulnEqualCall.OtherVuln}, *tt.vulnEqualCall.In) if (err != nil) != tt.wantErr { t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) } @@ -947,7 +947,7 @@ func TestNodes(t *testing.T) { nodeID = veID } if tt.vulnMetadataCall != nil { - vmID, err := b.IngestVulnerabilityMetadata(ctx, *tt.vulnMetadataCall.Vuln, *tt.vulnMetadataCall.VulnMetadata) + vmID, err := b.IngestVulnerabilityMetadata(ctx, model.IDorVulnerabilityInput{VulnerabilityInput: tt.vulnMetadataCall.Vuln}, *tt.vulnMetadataCall.VulnMetadata) if (err != nil) != tt.wantErr { t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) } @@ -983,8 +983,8 @@ func TestNeighbors(t *testing.T) { } type certifyLegalCall struct { PkgSrc model.PackageOrSourceInput - Dec []*model.LicenseInputSpec - Dis []*model.LicenseInputSpec + Dec []*model.IDorLicenseInput + Dis []*model.IDorLicenseInput Legal *model.CertifyLegalInputSpec } type scorecardCall struct { @@ -1021,7 +1021,7 @@ func TestNeighbors(t *testing.T) { } type hasSlsaCall struct { Sub *model.ArtifactInputSpec - BF []*model.ArtifactInputSpec + BF []*model.IDorArtifactInput BB *model.BuilderInputSpec SLSA *model.SLSAInputSpec } @@ -1236,7 +1236,7 @@ func TestNeighbors(t *testing.T) { inArt: []*model.ArtifactInputSpec{testdata.A2}, certifyBadCall: &certifyBadCall{ Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A2}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -1255,7 +1255,7 @@ func TestNeighbors(t *testing.T) { inPkg: []*model.PkgInputSpec{testdata.P2}, certifyBadCall: &certifyBadCall{ Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P2, + Package: &model.IDorPkgInput{PackageInput: testdata.P2}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeAllVersions, @@ -1282,7 +1282,7 @@ func TestNeighbors(t *testing.T) { inPkg: []*model.PkgInputSpec{testdata.P2}, certifyBadCall: &certifyBadCall{ Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P2, + Package: &model.IDorPkgInput{PackageInput: testdata.P2}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -1311,7 +1311,7 @@ func TestNeighbors(t *testing.T) { inSrc: []*model.SourceInputSpec{testdata.S1}, certifyBadCall: &certifyBadCall{ Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, + Source: &model.IDorSourceInput{SourceInput: testdata.S1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -1338,7 +1338,7 @@ func TestNeighbors(t *testing.T) { inArt: []*model.ArtifactInputSpec{testdata.A2}, certifyBadCall: &certifyBadCall{ Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A2}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -1354,7 +1354,7 @@ func TestNeighbors(t *testing.T) { inPkg: []*model.PkgInputSpec{testdata.P2}, certifyBadCall: &certifyBadCall{ Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P2, + Package: &model.IDorPkgInput{PackageInput: testdata.P2}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeAllVersions, @@ -1370,7 +1370,7 @@ func TestNeighbors(t *testing.T) { inPkg: []*model.PkgInputSpec{testdata.P2}, certifyBadCall: &certifyBadCall{ Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P2, + Package: &model.IDorPkgInput{PackageInput: testdata.P2}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -1386,7 +1386,7 @@ func TestNeighbors(t *testing.T) { inSrc: []*model.SourceInputSpec{testdata.S1}, certifyBadCall: &certifyBadCall{ Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, + Source: &model.IDorSourceInput{SourceInput: testdata.S1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -1402,7 +1402,7 @@ func TestNeighbors(t *testing.T) { inArt: []*model.ArtifactInputSpec{testdata.A2}, certifyGoodCall: &certifyGoodCall{ Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A2}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -1421,7 +1421,7 @@ func TestNeighbors(t *testing.T) { inPkg: []*model.PkgInputSpec{testdata.P2}, certifyGoodCall: &certifyGoodCall{ Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P2, + Package: &model.IDorPkgInput{PackageInput: testdata.P2}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeAllVersions, @@ -1448,7 +1448,7 @@ func TestNeighbors(t *testing.T) { inPkg: []*model.PkgInputSpec{testdata.P2}, certifyGoodCall: &certifyGoodCall{ Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P2, + Package: &model.IDorPkgInput{PackageInput: testdata.P2}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -1477,7 +1477,7 @@ func TestNeighbors(t *testing.T) { inSrc: []*model.SourceInputSpec{testdata.S1}, certifyGoodCall: &certifyGoodCall{ Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, + Source: &model.IDorSourceInput{SourceInput: testdata.S1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -1504,7 +1504,7 @@ func TestNeighbors(t *testing.T) { inArt: []*model.ArtifactInputSpec{testdata.A2}, certifyGoodCall: &certifyGoodCall{ Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A2}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -1520,7 +1520,7 @@ func TestNeighbors(t *testing.T) { inPkg: []*model.PkgInputSpec{testdata.P2}, certifyGoodCall: &certifyGoodCall{ Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P2, + Package: &model.IDorPkgInput{PackageInput: testdata.P2}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeAllVersions, @@ -1536,7 +1536,7 @@ func TestNeighbors(t *testing.T) { inPkg: []*model.PkgInputSpec{testdata.P2}, certifyGoodCall: &certifyGoodCall{ Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P2, + Package: &model.IDorPkgInput{PackageInput: testdata.P2}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -1552,7 +1552,7 @@ func TestNeighbors(t *testing.T) { inSrc: []*model.SourceInputSpec{testdata.S1}, certifyGoodCall: &certifyGoodCall{ Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, + Source: &model.IDorSourceInput{SourceInput: testdata.S1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -1569,9 +1569,9 @@ func TestNeighbors(t *testing.T) { inLic: []*model.LicenseInputSpec{testdata.L1}, certifyLegalCall: &certifyLegalCall{ PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, - Dec: []*model.LicenseInputSpec{testdata.L1}, + Dec: []*model.IDorLicenseInput{{LicenseInput: testdata.L1}}, Legal: &model.CertifyLegalInputSpec{ Justification: "test justification 2", }, @@ -1598,9 +1598,9 @@ func TestNeighbors(t *testing.T) { inLic: []*model.LicenseInputSpec{testdata.L1}, certifyLegalCall: &certifyLegalCall{ PkgSrc: model.PackageOrSourceInput{ - Source: testdata.S1, + Source: &model.IDorSourceInput{SourceInput: testdata.S1}, }, - Dec: []*model.LicenseInputSpec{testdata.L1}, + Dec: []*model.IDorLicenseInput{{LicenseInput: testdata.L1}}, Legal: &model.CertifyLegalInputSpec{ Justification: "test justification 2", }, @@ -1625,9 +1625,9 @@ func TestNeighbors(t *testing.T) { inLic: []*model.LicenseInputSpec{testdata.L2}, certifyLegalCall: &certifyLegalCall{ PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, - Dec: []*model.LicenseInputSpec{testdata.L2}, + Dec: []*model.IDorLicenseInput{{LicenseInput: testdata.L2}}, Legal: &model.CertifyLegalInputSpec{ Justification: "test justification 2", }, @@ -1645,9 +1645,9 @@ func TestNeighbors(t *testing.T) { inLic: []*model.LicenseInputSpec{testdata.L3}, certifyLegalCall: &certifyLegalCall{ PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, - Dis: []*model.LicenseInputSpec{testdata.L3}, + Dis: []*model.IDorLicenseInput{{LicenseInput: testdata.L3}}, Legal: &model.CertifyLegalInputSpec{ Justification: "test justification 2", }, @@ -1665,9 +1665,9 @@ func TestNeighbors(t *testing.T) { inLic: []*model.LicenseInputSpec{testdata.L1}, certifyLegalCall: &certifyLegalCall{ PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, - Dec: []*model.LicenseInputSpec{testdata.L1}, + Dec: []*model.IDorLicenseInput{{LicenseInput: testdata.L1}}, Legal: &model.CertifyLegalInputSpec{ Justification: "test justification 2", }, @@ -1681,9 +1681,9 @@ func TestNeighbors(t *testing.T) { inLic: []*model.LicenseInputSpec{testdata.L1}, certifyLegalCall: &certifyLegalCall{ PkgSrc: model.PackageOrSourceInput{ - Source: testdata.S1, + Source: &model.IDorSourceInput{SourceInput: testdata.S1}, }, - Dec: []*model.LicenseInputSpec{testdata.L1}, + Dec: []*model.IDorLicenseInput{{LicenseInput: testdata.L1}}, Legal: &model.CertifyLegalInputSpec{ Justification: "test justification 2", }, @@ -1697,9 +1697,9 @@ func TestNeighbors(t *testing.T) { inLic: []*model.LicenseInputSpec{testdata.L2}, certifyLegalCall: &certifyLegalCall{ PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, - Dec: []*model.LicenseInputSpec{testdata.L2}, + Dec: []*model.IDorLicenseInput{{LicenseInput: testdata.L2}}, Legal: &model.CertifyLegalInputSpec{ Justification: "test justification 2", }, @@ -1713,9 +1713,9 @@ func TestNeighbors(t *testing.T) { inLic: []*model.LicenseInputSpec{testdata.L3}, certifyLegalCall: &certifyLegalCall{ PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, - Dis: []*model.LicenseInputSpec{testdata.L3}, + Dis: []*model.IDorLicenseInput{{LicenseInput: testdata.L3}}, Legal: &model.CertifyLegalInputSpec{ Justification: "test justification 2", }, @@ -1766,7 +1766,7 @@ func TestNeighbors(t *testing.T) { inVuln: []*model.VulnerabilityInputSpec{testdata.O2}, vexCall: &vexCall{ Sub: model.PackageOrArtifactInput{ - Artifact: testdata.A2, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A2}, }, Vuln: testdata.O2, In: &model.VexStatementInputSpec{ @@ -1790,7 +1790,7 @@ func TestNeighbors(t *testing.T) { inVuln: []*model.VulnerabilityInputSpec{testdata.O2}, vexCall: &vexCall{ Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Vuln: testdata.O2, In: &model.VexStatementInputSpec{ @@ -1824,7 +1824,7 @@ func TestNeighbors(t *testing.T) { inVuln: []*model.VulnerabilityInputSpec{testdata.G1}, vexCall: &vexCall{ Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Vuln: testdata.G1, In: &model.VexStatementInputSpec{ @@ -1853,7 +1853,7 @@ func TestNeighbors(t *testing.T) { inVuln: []*model.VulnerabilityInputSpec{testdata.O2}, vexCall: &vexCall{ Sub: model.PackageOrArtifactInput{ - Artifact: testdata.A2, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A2}, }, Vuln: testdata.O2, In: &model.VexStatementInputSpec{ @@ -1870,7 +1870,7 @@ func TestNeighbors(t *testing.T) { inVuln: []*model.VulnerabilityInputSpec{testdata.O2}, vexCall: &vexCall{ Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Vuln: testdata.O2, In: &model.VexStatementInputSpec{ @@ -1887,7 +1887,7 @@ func TestNeighbors(t *testing.T) { inVuln: []*model.VulnerabilityInputSpec{testdata.G1}, vexCall: &vexCall{ Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Vuln: testdata.G1, In: &model.VexStatementInputSpec{ @@ -2050,7 +2050,7 @@ func TestNeighbors(t *testing.T) { inArt: []*model.ArtifactInputSpec{testdata.A2}, hasMetadataCall: &hasMetadataCall{ Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A2}, }, HM: &model.HasMetadataInputSpec{ Justification: "test justification", @@ -2066,7 +2066,7 @@ func TestNeighbors(t *testing.T) { inPkg: []*model.PkgInputSpec{testdata.P2}, hasMetadataCall: &hasMetadataCall{ Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P2, + Package: &model.IDorPkgInput{PackageInput: testdata.P2}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeAllVersions, @@ -2093,7 +2093,7 @@ func TestNeighbors(t *testing.T) { inPkg: []*model.PkgInputSpec{testdata.P2}, hasMetadataCall: &hasMetadataCall{ Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P2, + Package: &model.IDorPkgInput{PackageInput: testdata.P2}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -2122,7 +2122,7 @@ func TestNeighbors(t *testing.T) { inSrc: []*model.SourceInputSpec{testdata.S1}, hasMetadataCall: &hasMetadataCall{ Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, + Source: &model.IDorSourceInput{SourceInput: testdata.S1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -2149,7 +2149,7 @@ func TestNeighbors(t *testing.T) { inArt: []*model.ArtifactInputSpec{testdata.A2}, hasMetadataCall: &hasMetadataCall{ Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A2}, }, HM: &model.HasMetadataInputSpec{ Justification: "test justification", @@ -2163,7 +2163,7 @@ func TestNeighbors(t *testing.T) { inPkg: []*model.PkgInputSpec{testdata.P2}, hasMetadataCall: &hasMetadataCall{ Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P2, + Package: &model.IDorPkgInput{PackageInput: testdata.P2}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeAllVersions, @@ -2180,7 +2180,7 @@ func TestNeighbors(t *testing.T) { inPkg: []*model.PkgInputSpec{testdata.P2}, hasMetadataCall: &hasMetadataCall{ Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P2, + Package: &model.IDorPkgInput{PackageInput: testdata.P2}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -2197,7 +2197,7 @@ func TestNeighbors(t *testing.T) { inSrc: []*model.SourceInputSpec{testdata.S1}, hasMetadataCall: &hasMetadataCall{ Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, + Source: &model.IDorSourceInput{SourceInput: testdata.S1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -2214,7 +2214,7 @@ func TestNeighbors(t *testing.T) { inArt: []*model.ArtifactInputSpec{testdata.A2}, hasSBOMCall: &hasSBOMCall{ Sub: model.PackageOrArtifactInput{ - Artifact: testdata.A2, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A2}, }, HS: &model.HasSBOMInputSpec{ DownloadLocation: "location two", @@ -2230,7 +2230,7 @@ func TestNeighbors(t *testing.T) { inPkg: []*model.PkgInputSpec{testdata.P2}, hasSBOMCall: &hasSBOMCall{ Sub: model.PackageOrArtifactInput{ - Package: testdata.P2, + Package: &model.IDorPkgInput{PackageInput: testdata.P2}, }, HS: &model.HasSBOMInputSpec{ DownloadLocation: "location two", @@ -2256,7 +2256,7 @@ func TestNeighbors(t *testing.T) { inPkg: []*model.PkgInputSpec{testdata.P2}, hasSBOMCall: &hasSBOMCall{ Sub: model.PackageOrArtifactInput{ - Package: testdata.P2, + Package: &model.IDorPkgInput{PackageInput: testdata.P2}, }, HS: &model.HasSBOMInputSpec{ DownloadLocation: "location two", @@ -2312,7 +2312,7 @@ func TestNeighbors(t *testing.T) { inArt: []*model.ArtifactInputSpec{testdata.A2}, hasSBOMCall: &hasSBOMCall{ Sub: model.PackageOrArtifactInput{ - Artifact: testdata.A2, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A2}, }, HS: &model.HasSBOMInputSpec{ DownloadLocation: "location two", @@ -2326,7 +2326,7 @@ func TestNeighbors(t *testing.T) { inPkg: []*model.PkgInputSpec{testdata.P2}, hasSBOMCall: &hasSBOMCall{ Sub: model.PackageOrArtifactInput{ - Package: testdata.P2, + Package: &model.IDorPkgInput{PackageInput: testdata.P2}, }, HS: &model.HasSBOMInputSpec{ DownloadLocation: "location two", @@ -2341,7 +2341,7 @@ func TestNeighbors(t *testing.T) { inBld: []*model.BuilderInputSpec{testdata.B1, testdata.B2}, hasSlsaCall: &hasSlsaCall{ Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, + BF: []*model.IDorArtifactInput{&model.IDorArtifactInput{ArtifactInput: testdata.A2}}, BB: testdata.B2, SLSA: &model.SLSAInputSpec{}, }, @@ -2359,7 +2359,7 @@ func TestNeighbors(t *testing.T) { inBld: []*model.BuilderInputSpec{testdata.B1, testdata.B2}, hasSlsaCall: &hasSlsaCall{ Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, + BF: []*model.IDorArtifactInput{&model.IDorArtifactInput{ArtifactInput: testdata.A2}}, BB: testdata.B2, SLSA: &model.SLSAInputSpec{}, }, @@ -2377,7 +2377,7 @@ func TestNeighbors(t *testing.T) { inBld: []*model.BuilderInputSpec{testdata.B1, testdata.B2}, hasSlsaCall: &hasSlsaCall{ Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, + BF: []*model.IDorArtifactInput{&model.IDorArtifactInput{ArtifactInput: testdata.A2}}, BB: testdata.B2, SLSA: &model.SLSAInputSpec{}, }, @@ -2390,7 +2390,7 @@ func TestNeighbors(t *testing.T) { inBld: []*model.BuilderInputSpec{testdata.B1, testdata.B2}, hasSlsaCall: &hasSlsaCall{ Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, + BF: []*model.IDorArtifactInput{&model.IDorArtifactInput{ArtifactInput: testdata.A2}}, BB: testdata.B2, SLSA: &model.SLSAInputSpec{}, }, @@ -2403,7 +2403,7 @@ func TestNeighbors(t *testing.T) { inBld: []*model.BuilderInputSpec{testdata.B1, testdata.B2}, hasSlsaCall: &hasSlsaCall{ Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, + BF: []*model.IDorArtifactInput{&model.IDorArtifactInput{ArtifactInput: testdata.A2}}, BB: testdata.B2, SLSA: &model.SLSAInputSpec{}, }, @@ -2610,7 +2610,7 @@ func TestNeighbors(t *testing.T) { inArt: []*model.ArtifactInputSpec{testdata.A1}, isOcurCall: &isOcurCall{ PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Artifact: testdata.A1, Occurrence: &model.IsOccurrenceInputSpec{ @@ -2629,7 +2629,7 @@ func TestNeighbors(t *testing.T) { inArt: []*model.ArtifactInputSpec{testdata.A1}, isOcurCall: &isOcurCall{ PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Artifact: testdata.A1, Occurrence: &model.IsOccurrenceInputSpec{ @@ -2657,7 +2657,7 @@ func TestNeighbors(t *testing.T) { inArt: []*model.ArtifactInputSpec{testdata.A1}, isOcurCall: &isOcurCall{ PkgSrc: model.PackageOrSourceInput{ - Source: testdata.S1, + Source: &model.IDorSourceInput{SourceInput: testdata.S1}, }, Artifact: testdata.A1, Occurrence: &model.IsOccurrenceInputSpec{ @@ -2684,7 +2684,7 @@ func TestNeighbors(t *testing.T) { inArt: []*model.ArtifactInputSpec{testdata.A1}, isOcurCall: &isOcurCall{ PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Artifact: testdata.A1, Occurrence: &model.IsOccurrenceInputSpec{ @@ -2700,7 +2700,7 @@ func TestNeighbors(t *testing.T) { inArt: []*model.ArtifactInputSpec{testdata.A1}, isOcurCall: &isOcurCall{ PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Artifact: testdata.A1, Occurrence: &model.IsOccurrenceInputSpec{ @@ -2716,7 +2716,7 @@ func TestNeighbors(t *testing.T) { inArt: []*model.ArtifactInputSpec{testdata.A1}, isOcurCall: &isOcurCall{ PkgSrc: model.PackageOrSourceInput{ - Source: testdata.S1, + Source: &model.IDorSourceInput{SourceInput: testdata.S1}, }, Artifact: testdata.A1, Occurrence: &model.IsOccurrenceInputSpec{ @@ -2794,7 +2794,7 @@ func TestNeighbors(t *testing.T) { inArt: []*model.ArtifactInputSpec{testdata.A1}, pointOfContactCall: &pointOfContactCall{ Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A1, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeAllVersions, @@ -2813,7 +2813,7 @@ func TestNeighbors(t *testing.T) { inPkg: []*model.PkgInputSpec{testdata.P2}, pointOfContactCall: &pointOfContactCall{ Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P2, + Package: &model.IDorPkgInput{PackageInput: testdata.P2}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeAllVersions, @@ -2840,7 +2840,7 @@ func TestNeighbors(t *testing.T) { inSrc: []*model.SourceInputSpec{testdata.S1}, pointOfContactCall: &pointOfContactCall{ Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, + Source: &model.IDorSourceInput{SourceInput: testdata.S1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -2867,7 +2867,7 @@ func TestNeighbors(t *testing.T) { inPkg: []*model.PkgInputSpec{testdata.P2}, pointOfContactCall: &pointOfContactCall{ Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P2, + Package: &model.IDorPkgInput{PackageInput: testdata.P2}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -2896,7 +2896,7 @@ func TestNeighbors(t *testing.T) { inArt: []*model.ArtifactInputSpec{testdata.A1}, pointOfContactCall: &pointOfContactCall{ Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A1, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeAllVersions, @@ -2913,7 +2913,7 @@ func TestNeighbors(t *testing.T) { inPkg: []*model.PkgInputSpec{testdata.P2}, pointOfContactCall: &pointOfContactCall{ Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P2, + Package: &model.IDorPkgInput{PackageInput: testdata.P2}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeAllVersions, @@ -2930,7 +2930,7 @@ func TestNeighbors(t *testing.T) { inSrc: []*model.SourceInputSpec{testdata.S1}, pointOfContactCall: &pointOfContactCall{ Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, + Source: &model.IDorSourceInput{SourceInput: testdata.S1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -2947,7 +2947,7 @@ func TestNeighbors(t *testing.T) { inPkg: []*model.PkgInputSpec{testdata.P2}, pointOfContactCall: &pointOfContactCall{ Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P2, + Package: &model.IDorPkgInput{PackageInput: testdata.P2}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -3091,37 +3091,37 @@ func TestNeighbors(t *testing.T) { t.Run(tt.name, func(t *testing.T) { var nodeID string for _, p := range tt.inPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { + if _, err := b.IngestPackage(ctx, model.IDorPkgInput{PackageInput: p}); err != nil { t.Fatalf("Could not ingest package: %v", err) } } for _, s := range tt.inSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { + if _, err := b.IngestSource(ctx, model.IDorSourceInput{SourceInput: s}); err != nil { t.Fatalf("Could not ingest source: %v", err) } } for _, a := range tt.inArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { + if _, err := b.IngestArtifact(ctx, &model.IDorArtifactInput{ArtifactInput: a}); err != nil { t.Fatalf("Could not ingest artifact: %v", err) } } for _, bld := range tt.inBld { - if _, err := b.IngestBuilder(ctx, bld); err != nil { + if _, err := b.IngestBuilder(ctx, &model.IDorBuilderInput{BuilderInput: bld}); err != nil { t.Fatalf("Could not ingest builder: %v", err) } } for _, a := range tt.inLic { - if _, err := b.IngestLicense(ctx, a); err != nil { + if _, err := b.IngestLicense(ctx, &model.IDorLicenseInput{LicenseInput: a}); err != nil { t.Fatalf("Could not ingest license: %v", err) } } for _, g := range tt.inVuln { - if _, err := b.IngestVulnerability(ctx, *g); err != nil { + if _, err := b.IngestVulnerability(ctx, model.IDorVulnerabilityInput{VulnerabilityInput: g}); err != nil { t.Fatalf("Could not ingest vulnerability: %a", err) } } if tt.pkgInput != nil { - ingestedPkg, err := b.IngestPackage(ctx, *tt.pkgInput) + ingestedPkg, err := b.IngestPackage(ctx, model.IDorPkgInput{PackageInput: tt.pkgInput}) if (err != nil) != tt.wantErr { t.Errorf("arangoClient.IngestPackage() error = %v, wantErr %v", err, tt.wantErr) return @@ -3144,7 +3144,7 @@ func TestNeighbors(t *testing.T) { } } if tt.srcInput != nil { - ingestedSrc, err := b.IngestSource(ctx, *tt.srcInput) + ingestedSrc, err := b.IngestSource(ctx, model.IDorSourceInput{SourceInput: tt.srcInput}) if (err != nil) != tt.wantErr { t.Errorf("arangoClient.IngestSource() error = %v, wantErr %v", err, tt.wantErr) return @@ -3163,7 +3163,7 @@ func TestNeighbors(t *testing.T) { } } if tt.vulnInput != nil { - ingestVuln, err := b.IngestVulnerability(ctx, *tt.vulnInput) + ingestVuln, err := b.IngestVulnerability(ctx, model.IDorVulnerabilityInput{VulnerabilityInput: tt.vulnInput}) if (err != nil) != tt.wantErr { t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.want, err) } @@ -3177,7 +3177,7 @@ func TestNeighbors(t *testing.T) { } } if tt.licenseInput != nil { - ingestedLicenseID, err := b.IngestLicense(ctx, tt.licenseInput) + ingestedLicenseID, err := b.IngestLicense(ctx, &model.IDorLicenseInput{LicenseInput: tt.licenseInput}) if (err != nil) != tt.wantErr { t.Errorf("arangoClient.IngestLicense() error = %v, wantErr %v", err, tt.wantErr) return @@ -3283,7 +3283,7 @@ func TestNeighbors(t *testing.T) { } } if tt.scorecardCall != nil { - sID, err := b.IngestScorecard(ctx, *tt.scorecardCall.Src, *tt.scorecardCall.SC) + sID, err := b.IngestScorecard(ctx, model.IDorSourceInput{SourceInput: tt.scorecardCall.Src}, *tt.scorecardCall.SC) if (err != nil) != tt.wantErr { t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) } @@ -3303,7 +3303,7 @@ func TestNeighbors(t *testing.T) { } } if tt.vexCall != nil { - vexID, err := b.IngestVEXStatement(ctx, tt.vexCall.Sub, *tt.vexCall.Vuln, *tt.vexCall.In) + vexID, err := b.IngestVEXStatement(ctx, tt.vexCall.Sub, model.IDorVulnerabilityInput{VulnerabilityInput: tt.vexCall.Vuln}, *tt.vexCall.In) if (err != nil) != tt.wantErr { t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) } @@ -3331,7 +3331,7 @@ func TestNeighbors(t *testing.T) { } } if tt.certifyVulnCall != nil { - cvID, err := b.IngestCertifyVuln(ctx, *tt.certifyVulnCall.Pkg, *tt.certifyVulnCall.Vuln, *tt.certifyVulnCall.CertifyVuln) + cvID, err := b.IngestCertifyVuln(ctx, model.IDorPkgInput{PackageInput: tt.certifyVulnCall.Pkg}, model.IDorVulnerabilityInput{VulnerabilityInput: tt.certifyVulnCall.Vuln}, *tt.certifyVulnCall.CertifyVuln) if (err != nil) != tt.wantErr { t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) } @@ -3355,7 +3355,7 @@ func TestNeighbors(t *testing.T) { } } if tt.hashEqualCall != nil { - heID, err := b.IngestHashEqual(ctx, *tt.hashEqualCall.A1, *tt.hashEqualCall.A2, *tt.hashEqualCall.HE) + heID, err := b.IngestHashEqual(ctx, model.IDorArtifactInput{ArtifactInput: tt.hashEqualCall.A1}, model.IDorArtifactInput{ArtifactInput: tt.hashEqualCall.A2}, *tt.hashEqualCall.HE) if (err != nil) != tt.wantErr { t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) } @@ -3414,7 +3414,7 @@ func TestNeighbors(t *testing.T) { if tt.hasSBOMCall != nil { includes := model.HasSBOMIncludesInputSpec{} for _, s := range tt.hasSBOMCall.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { + if _, err := b.IngestSource(ctx, model.IDorSourceInput{SourceInput: s}); err != nil { t.Fatalf("Could not ingest source: %v", err) } } @@ -3436,7 +3436,7 @@ func TestNeighbors(t *testing.T) { } for _, dep := range tt.hasSBOMCall.IsDeps { - if isDep, err := b.IngestDependency(ctx, *dep.pkg, *dep.depPkg, dep.matchType, *dep.isDep); err != nil { + if isDep, err := b.IngestDependency(ctx, model.IDorPkgInput{PackageInput: dep.pkg}, model.IDorPkgInput{PackageInput: dep.depPkg}, dep.matchType, *dep.isDep); err != nil { t.Fatalf("Could not ingest dependency: %v", err) } else { includes.Dependencies = append(includes.Dependencies, isDep) @@ -3444,7 +3444,7 @@ func TestNeighbors(t *testing.T) { } for _, occ := range tt.hasSBOMCall.IsOccs { - if isOcc, err := b.IngestOccurrence(ctx, *occ.Subj, *occ.Art, *occ.isOcc); err != nil { + if isOcc, err := b.IngestOccurrence(ctx, *occ.Subj, model.IDorArtifactInput{ArtifactInput: occ.Art}, *occ.isOcc); err != nil { t.Fatalf("Could not ingest occurrence: %v", err) } else { includes.Occurrences = append(includes.Occurrences, isOcc) @@ -3474,7 +3474,7 @@ func TestNeighbors(t *testing.T) { } } if tt.hasSlsaCall != nil { - slsaID, err := b.IngestSLSA(ctx, *tt.hasSlsaCall.Sub, tt.hasSlsaCall.BF, *tt.hasSlsaCall.BB, *tt.hasSlsaCall.SLSA) + slsaID, err := b.IngestSLSA(ctx, model.IDorArtifactInput{ArtifactInput: tt.hasSlsaCall.Sub}, tt.hasSlsaCall.BF, model.IDorBuilderInput{BuilderInput: tt.hasSlsaCall.BB}, *tt.hasSlsaCall.SLSA) if (err != nil) != tt.wantErr { t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) } @@ -3498,7 +3498,7 @@ func TestNeighbors(t *testing.T) { } } if tt.hasSourceAtCall != nil { - hsID, err := b.IngestHasSourceAt(ctx, *tt.hasSourceAtCall.Pkg, *tt.hasSourceAtCall.Match, *tt.hasSourceAtCall.Src, *tt.hasSourceAtCall.HSA) + hsID, err := b.IngestHasSourceAt(ctx, model.IDorPkgInput{PackageInput: tt.hasSourceAtCall.Pkg}, *tt.hasSourceAtCall.Match, model.IDorSourceInput{SourceInput: tt.hasSourceAtCall.Src}, *tt.hasSourceAtCall.HSA) if (err != nil) != tt.wantErr { t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) } @@ -3526,7 +3526,7 @@ func TestNeighbors(t *testing.T) { } } if tt.isDepCall != nil { - dID, err := b.IngestDependency(ctx, *tt.isDepCall.P1, *tt.isDepCall.P2, tt.isDepCall.MF, *tt.isDepCall.ID) + dID, err := b.IngestDependency(ctx, model.IDorPkgInput{PackageInput: tt.isDepCall.P1}, model.IDorPkgInput{PackageInput: tt.isDepCall.P2}, tt.isDepCall.MF, *tt.isDepCall.ID) if (err != nil) != tt.wantErr { t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) } @@ -3550,7 +3550,7 @@ func TestNeighbors(t *testing.T) { } } if tt.isOcurCall != nil { - oID, err := b.IngestOccurrence(ctx, tt.isOcurCall.PkgSrc, *tt.isOcurCall.Artifact, *tt.isOcurCall.Occurrence) + oID, err := b.IngestOccurrence(ctx, tt.isOcurCall.PkgSrc, model.IDorArtifactInput{ArtifactInput: tt.isOcurCall.Artifact}, *tt.isOcurCall.Occurrence) if (err != nil) != tt.wantErr { t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) } @@ -3578,7 +3578,7 @@ func TestNeighbors(t *testing.T) { } } if tt.pkgEqualCall != nil { - peID, err := b.IngestPkgEqual(ctx, *tt.pkgEqualCall.P1, *tt.pkgEqualCall.P2, *tt.pkgEqualCall.HE) + peID, err := b.IngestPkgEqual(ctx, model.IDorPkgInput{PackageInput: tt.pkgEqualCall.P1}, model.IDorPkgInput{PackageInput: tt.pkgEqualCall.P2}, *tt.pkgEqualCall.HE) if (err != nil) != tt.wantErr { t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) } @@ -3634,7 +3634,7 @@ func TestNeighbors(t *testing.T) { } } if tt.vulnEqualCall != nil { - veID, err := b.IngestVulnEqual(ctx, *tt.vulnEqualCall.Vuln, *tt.vulnEqualCall.OtherVuln, *tt.vulnEqualCall.In) + veID, err := b.IngestVulnEqual(ctx, model.IDorVulnerabilityInput{VulnerabilityInput: tt.vulnEqualCall.Vuln}, model.IDorVulnerabilityInput{VulnerabilityInput: tt.vulnEqualCall.OtherVuln}, *tt.vulnEqualCall.In) if (err != nil) != tt.wantErr { t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) } @@ -3658,12 +3658,12 @@ func TestNeighbors(t *testing.T) { } } if tt.vulnMetadataCall != nil { - ingestedVuln, err := b.IngestVulnerability(ctx, *tt.inVuln[0]) + ingestedVuln, err := b.IngestVulnerability(ctx, model.IDorVulnerabilityInput{VulnerabilityInput: tt.inVuln[0]}) if err != nil { t.Fatalf("Could not ingest vulnerability: %a", err) } - vulnMetadataID, err := b.IngestVulnerabilityMetadata(ctx, *tt.vulnMetadataCall.Vuln, *tt.vulnMetadataCall.VulnMetadata) + vulnMetadataID, err := b.IngestVulnerabilityMetadata(ctx, model.IDorVulnerabilityInput{VulnerabilityInput: tt.vulnMetadataCall.Vuln}, *tt.vulnMetadataCall.VulnMetadata) if (err != nil) != tt.wantErr { t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) } diff --git a/internal/testing/backend/pkgEqual_test.go b/internal/testing/backend/pkgEqual_test.go index 2a5a588063..267d887dc4 100644 --- a/internal/testing/backend/pkgEqual_test.go +++ b/internal/testing/backend/pkgEqual_test.go @@ -533,14 +533,14 @@ func TestPkgEqual(t *testing.T) { t.Run(test.Name, func(t *testing.T) { var collectedPkgIDs []*model.PackageIDs for _, a := range test.InPkg { - if pkgIDs, err := b.IngestPackage(ctx, *a); err != nil { + if pkgIDs, err := b.IngestPackage(ctx, model.IDorPkgInput{PackageInput: a}); err != nil { t.Fatalf("Could not ingest pkg: %v", err) } else { collectedPkgIDs = append(collectedPkgIDs, pkgIDs) } } for _, o := range test.Calls { - peID, err := b.IngestPkgEqual(ctx, *o.P1, *o.P2, *o.HE) + peID, err := b.IngestPkgEqual(ctx, model.IDorPkgInput{PackageInput: o.P1}, model.IDorPkgInput{PackageInput: o.P2}, *o.HE) if (err != nil) != test.ExpIngestErr { t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) } @@ -591,8 +591,8 @@ func TestIngestPkgEquals(t *testing.T) { ctx := context.Background() b := setupTest(t) type call struct { - P1 []*model.PkgInputSpec - P2 []*model.PkgInputSpec + P1 []*model.IDorPkgInput + P2 []*model.IDorPkgInput PE []*model.PkgEqualInputSpec } tests := []struct { @@ -609,8 +609,8 @@ func TestIngestPkgEquals(t *testing.T) { InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2}, Calls: []call{ { - P1: []*model.PkgInputSpec{testdata.P1, testdata.P1}, - P2: []*model.PkgInputSpec{testdata.P2, testdata.P2}, + P1: []*model.IDorPkgInput{{PackageInput: testdata.P1}, {PackageInput: testdata.P1}}, + P2: []*model.IDorPkgInput{{PackageInput: testdata.P2}, {PackageInput: testdata.P2}}, PE: []*model.PkgEqualInputSpec{ { Justification: "test justification", @@ -636,8 +636,8 @@ func TestIngestPkgEquals(t *testing.T) { InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2}, Calls: []call{ { - P1: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - P2: []*model.PkgInputSpec{testdata.P2, testdata.P1}, + P1: []*model.IDorPkgInput{{PackageInput: testdata.P1}, {PackageInput: testdata.P2}}, + P2: []*model.IDorPkgInput{{PackageInput: testdata.P2}, {PackageInput: testdata.P1}}, PE: []*model.PkgEqualInputSpec{ { Justification: "test justification", @@ -663,8 +663,8 @@ func TestIngestPkgEquals(t *testing.T) { InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2, testdata.P3}, Calls: []call{ { - P1: []*model.PkgInputSpec{testdata.P1, testdata.P1}, - P2: []*model.PkgInputSpec{testdata.P2, testdata.P3}, + P1: []*model.IDorPkgInput{{PackageInput: testdata.P1}, {PackageInput: testdata.P1}}, + P2: []*model.IDorPkgInput{{PackageInput: testdata.P2}, {PackageInput: testdata.P3}}, PE: []*model.PkgEqualInputSpec{ { Justification: "test justification", @@ -694,8 +694,8 @@ func TestIngestPkgEquals(t *testing.T) { InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2, testdata.P3}, Calls: []call{ { - P1: []*model.PkgInputSpec{testdata.P1, testdata.P1}, - P2: []*model.PkgInputSpec{testdata.P2, testdata.P3}, + P1: []*model.IDorPkgInput{{PackageInput: testdata.P1}, {PackageInput: testdata.P1}}, + P2: []*model.IDorPkgInput{{PackageInput: testdata.P2}, {PackageInput: testdata.P3}}, PE: []*model.PkgEqualInputSpec{ { Justification: "test justification", @@ -727,8 +727,8 @@ func TestIngestPkgEquals(t *testing.T) { InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2, testdata.P3}, Calls: []call{ { - P1: []*model.PkgInputSpec{testdata.P1, testdata.P1}, - P2: []*model.PkgInputSpec{testdata.P2, testdata.P3}, + P1: []*model.IDorPkgInput{{PackageInput: testdata.P1}, {PackageInput: testdata.P1}}, + P2: []*model.IDorPkgInput{{PackageInput: testdata.P2}, {PackageInput: testdata.P3}}, PE: []*model.PkgEqualInputSpec{ { Justification: "test justification", @@ -760,9 +760,12 @@ func TestIngestPkgEquals(t *testing.T) { } for _, test := range tests { t.Run(test.Name, func(t *testing.T) { - if _, err := b.IngestPackages(ctx, test.InPkg); err != nil { - t.Fatalf("Could not ingest pkg: %v", err) + for _, p := range test.InPkg { + if _, err := b.IngestPackage(ctx, model.IDorPkgInput{PackageInput: p}); err != nil { + t.Fatalf("Could not ingest pkg: %v", err) + } } + for _, o := range test.Calls { _, err := b.IngestPkgEquals(ctx, o.P1, o.P2, o.PE) if (err != nil) != test.ExpIngestErr { diff --git a/internal/testing/backend/pkg_test.go b/internal/testing/backend/pkg_test.go index ff246e0689..cb404fae42 100644 --- a/internal/testing/backend/pkg_test.go +++ b/internal/testing/backend/pkg_test.go @@ -118,7 +118,7 @@ func TestPackages(t *testing.T) { }} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - ingestedPkgIDs, err := b.IngestPackage(ctx, *tt.pkgInput) + ingestedPkgIDs, err := b.IngestPackage(ctx, model.IDorPkgInput{PackageInput: tt.pkgInput}) if (err != nil) != tt.wantErr { t.Errorf("IngestPackage() error = %v, wantErr %v", err, tt.wantErr) return @@ -143,11 +143,11 @@ func TestIngestPackages(t *testing.T) { b := setupTest(t) tests := []struct { name string - pkgInputs []*model.PkgInputSpec + pkgInputs []*model.IDorPkgInput wantErr bool }{{ name: "tensorflow empty version", - pkgInputs: []*model.PkgInputSpec{testdata.P3, testdata.P4}, + pkgInputs: []*model.IDorPkgInput{{PackageInput: testdata.P3}, {PackageInput: testdata.P4}}, wantErr: false, }} for _, tt := range tests { diff --git a/internal/testing/backend/pointOfContact_test.go b/internal/testing/backend/pointOfContact_test.go index c4a740987d..504c82692b 100644 --- a/internal/testing/backend/pointOfContact_test.go +++ b/internal/testing/backend/pointOfContact_test.go @@ -57,7 +57,7 @@ func TestPointOfContact(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -92,7 +92,7 @@ func TestPointOfContact(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -127,7 +127,7 @@ func TestPointOfContact(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -154,7 +154,7 @@ func TestPointOfContact(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeAllVersions, @@ -187,7 +187,7 @@ func TestPointOfContact(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P3, + Package: &model.IDorPkgInput{PackageInput: testdata.P3}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -198,7 +198,7 @@ func TestPointOfContact(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P3, + Package: &model.IDorPkgInput{PackageInput: testdata.P3}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -233,7 +233,7 @@ func TestPointOfContact(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -246,7 +246,7 @@ func TestPointOfContact(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -276,7 +276,7 @@ func TestPointOfContact(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -289,7 +289,7 @@ func TestPointOfContact(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -326,7 +326,7 @@ func TestPointOfContact(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -337,7 +337,7 @@ func TestPointOfContact(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -364,7 +364,7 @@ func TestPointOfContact(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -375,7 +375,7 @@ func TestPointOfContact(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P4, + Package: &model.IDorPkgInput{PackageInput: testdata.P4}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -386,7 +386,7 @@ func TestPointOfContact(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, + Source: &model.IDorSourceInput{SourceInput: testdata.S1}, }, POC: &model.PointOfContactInputSpec{ Justification: "test justification", @@ -416,7 +416,7 @@ func TestPointOfContact(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P4, + Package: &model.IDorPkgInput{PackageInput: testdata.P4}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -441,7 +441,7 @@ func TestPointOfContact(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -452,7 +452,7 @@ func TestPointOfContact(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, + Source: &model.IDorSourceInput{SourceInput: testdata.S1}, }, POC: &model.PointOfContactInputSpec{ Justification: "test justification", @@ -460,7 +460,7 @@ func TestPointOfContact(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S2, + Source: &model.IDorSourceInput{SourceInput: testdata.S2}, }, POC: &model.PointOfContactInputSpec{ Justification: "test justification", @@ -488,7 +488,7 @@ func TestPointOfContact(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S2, + Source: &model.IDorSourceInput{SourceInput: testdata.S2}, }, POC: &model.PointOfContactInputSpec{ Justification: "test justification", @@ -510,7 +510,7 @@ func TestPointOfContact(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A1, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A1}, }, POC: &model.PointOfContactInputSpec{ Justification: "test justification", @@ -518,7 +518,7 @@ func TestPointOfContact(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A2}, }, POC: &model.PointOfContactInputSpec{ Justification: "test justification", @@ -526,7 +526,7 @@ func TestPointOfContact(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, + Source: &model.IDorSourceInput{SourceInput: testdata.S1}, }, POC: &model.PointOfContactInputSpec{ Justification: "test justification", @@ -554,7 +554,7 @@ func TestPointOfContact(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A1, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A1}, }, POC: &model.PointOfContactInputSpec{ Justification: "test justification", @@ -562,7 +562,7 @@ func TestPointOfContact(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A2}, }, POC: &model.PointOfContactInputSpec{ Justification: "test justification", @@ -583,7 +583,7 @@ func TestPointOfContact(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A1, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A1}, }, POC: &model.PointOfContactInputSpec{ Justification: "test justification", @@ -591,7 +591,7 @@ func TestPointOfContact(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A2}, }, POC: &model.PointOfContactInputSpec{ Justification: "test justification", @@ -613,7 +613,7 @@ func TestPointOfContact(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, + Source: &model.IDorSourceInput{SourceInput: testdata.S1}, }, POC: &model.PointOfContactInputSpec{ Justification: "test justification", @@ -621,7 +621,7 @@ func TestPointOfContact(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S2, + Source: &model.IDorSourceInput{SourceInput: testdata.S2}, }, POC: &model.PointOfContactInputSpec{ Justification: "test justification", @@ -651,7 +651,7 @@ func TestPointOfContact(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -662,7 +662,7 @@ func TestPointOfContact(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P2, + Package: &model.IDorPkgInput{PackageInput: testdata.P2}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -673,7 +673,7 @@ func TestPointOfContact(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P2, + Package: &model.IDorPkgInput{PackageInput: testdata.P2}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeAllVersions, @@ -684,7 +684,7 @@ func TestPointOfContact(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P4, + Package: &model.IDorPkgInput{PackageInput: testdata.P4}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeAllVersions, @@ -719,7 +719,7 @@ func TestPointOfContact(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A1, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A1}, }, POC: &model.PointOfContactInputSpec{ Justification: "test justification", @@ -727,7 +727,7 @@ func TestPointOfContact(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A2}, }, POC: &model.PointOfContactInputSpec{ Justification: "test justification", @@ -746,7 +746,7 @@ func TestPointOfContact(t *testing.T) { for _, test := range tests { t.Run(test.Name, func(t *testing.T) { for _, p := range test.InPkg { - if pkgIDs, err := b.IngestPackage(ctx, *p); err != nil { + if pkgIDs, err := b.IngestPackage(ctx, model.IDorPkgInput{PackageInput: p}); err != nil { t.Fatalf("Could not ingest package: %v", err) } else { if test.QueryPkgID { @@ -761,7 +761,7 @@ func TestPointOfContact(t *testing.T) { } } for _, s := range test.InSrc { - if srcIDs, err := b.IngestSource(ctx, *s); err != nil { + if srcIDs, err := b.IngestSource(ctx, model.IDorSourceInput{SourceInput: s}); err != nil { t.Fatalf("Could not ingest source: %v", err) } else { if test.QuerySourceID { @@ -776,7 +776,7 @@ func TestPointOfContact(t *testing.T) { } } for _, a := range test.InArt { - if artID, err := b.IngestArtifact(ctx, a); err != nil { + if artID, err := b.IngestArtifact(ctx, &model.IDorArtifactInput{ArtifactInput: a}); err != nil { t.Fatalf("Could not ingest artifact: %v", err) } else { if test.QueryArtID { @@ -843,7 +843,7 @@ func TestIngestPointOfContacts(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1}, + Packages: []*model.IDorPkgInput{&model.IDorPkgInput{PackageInput: testdata.P1}}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -871,7 +871,7 @@ func TestIngestPointOfContacts(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1}, + Packages: []*model.IDorPkgInput{&model.IDorPkgInput{PackageInput: testdata.P1}}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeAllVersions, @@ -903,7 +903,7 @@ func TestIngestPointOfContacts(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P3, testdata.P3}, + Packages: []*model.IDorPkgInput{{PackageInput: testdata.P3}, {PackageInput: testdata.P3}}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -944,7 +944,7 @@ func TestIngestPointOfContacts(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1, testdata.P4}, + Packages: []*model.IDorPkgInput{{PackageInput: testdata.P1}, {PackageInput: testdata.P4}}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -960,7 +960,7 @@ func TestIngestPointOfContacts(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{testdata.S1}, + Sources: []*model.IDorSourceInput{&model.IDorSourceInput{SourceInput: testdata.S1}}, }, PC: []*model.PointOfContactInputSpec{ { @@ -992,7 +992,7 @@ func TestIngestPointOfContacts(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1}, + Packages: []*model.IDorPkgInput{&model.IDorPkgInput{PackageInput: testdata.P1}}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -1005,7 +1005,7 @@ func TestIngestPointOfContacts(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{testdata.S2, testdata.S2}, + Sources: []*model.IDorSourceInput{{SourceInput: testdata.S2}, {SourceInput: testdata.S2}}, }, PC: []*model.PointOfContactInputSpec{ { @@ -1038,7 +1038,7 @@ func TestIngestPointOfContacts(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInputs{ - Artifacts: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, + Artifacts: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}, {ArtifactInput: testdata.A2}}, }, PC: []*model.PointOfContactInputSpec{ { @@ -1051,7 +1051,7 @@ func TestIngestPointOfContacts(t *testing.T) { }, { Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{testdata.S1}, + Sources: []*model.IDorSourceInput{&model.IDorSourceInput{SourceInput: testdata.S1}}, }, PC: []*model.PointOfContactInputSpec{ { @@ -1078,17 +1078,17 @@ func TestIngestPointOfContacts(t *testing.T) { for _, test := range tests { t.Run(test.Name, func(t *testing.T) { for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { + if _, err := b.IngestPackage(ctx, model.IDorPkgInput{PackageInput: p}); err != nil { t.Fatalf("Could not ingest package: %v", err) } } for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { + if _, err := b.IngestSource(ctx, model.IDorSourceInput{SourceInput: s}); err != nil { t.Fatalf("Could not ingest source: %v", err) } } for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { + if _, err := b.IngestArtifact(ctx, &model.IDorArtifactInput{ArtifactInput: a}); err != nil { t.Fatalf("Could not ingest artifact: %v", err) } } diff --git a/internal/testing/backend/src_test.go b/internal/testing/backend/src_test.go index a303281b4f..e6406f370b 100644 --- a/internal/testing/backend/src_test.go +++ b/internal/testing/backend/src_test.go @@ -32,11 +32,11 @@ func TestIngestSources(t *testing.T) { b := setupTest(t) tests := []struct { name string - srcInputs []*model.SourceInputSpec + srcInputs []*model.IDorSourceInput wantErr bool }{{ name: "test batch source ingestion", - srcInputs: []*model.SourceInputSpec{testdata.S3, testdata.S4}, + srcInputs: []*model.IDorSourceInput{{SourceInput: testdata.S3}, {SourceInput: testdata.S4}}, wantErr: false, }} for _, tt := range tests { @@ -105,7 +105,7 @@ func TestSources(t *testing.T) { }} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - ingestedSrcIDs, err := b.IngestSource(ctx, *tt.srcInput) + ingestedSrcIDs, err := b.IngestSource(ctx, model.IDorSourceInput{SourceInput: tt.srcInput}) if (err != nil) != tt.wantErr { t.Errorf("IngestSource() error = %v, wantErr %v", err, tt.wantErr) return diff --git a/internal/testing/backend/vulnEqual_test.go b/internal/testing/backend/vulnEqual_test.go index f7b2bb13ee..816f335ef0 100644 --- a/internal/testing/backend/vulnEqual_test.go +++ b/internal/testing/backend/vulnEqual_test.go @@ -567,14 +567,14 @@ func TestVulnEqual(t *testing.T) { t.Run(test.Name, func(t *testing.T) { var collectedVulnIDs []*model.VulnerabilityIDs for _, g := range test.InVuln { - if vulnIDs, err := b.IngestVulnerability(ctx, *g); err != nil { + if vulnIDs, err := b.IngestVulnerability(ctx, model.IDorVulnerabilityInput{VulnerabilityInput: g}); err != nil { t.Fatalf("Could not ingest vulnerability: %a", err) } else { collectedVulnIDs = append(collectedVulnIDs, vulnIDs) } } for _, o := range test.Calls { - veID, err := b.IngestVulnEqual(ctx, *o.Vuln, *o.OtherVuln, *o.In) + veID, err := b.IngestVulnEqual(ctx, model.IDorVulnerabilityInput{VulnerabilityInput: o.Vuln}, model.IDorVulnerabilityInput{VulnerabilityInput: o.OtherVuln}, *o.In) if (err != nil) != test.ExpIngestErr { t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) } @@ -617,8 +617,8 @@ func TestIngestVulnEquals(t *testing.T) { ctx := context.Background() b := setupTest(t) type call struct { - Vulns []*model.VulnerabilityInputSpec - OtherVulns []*model.VulnerabilityInputSpec + Vulns []*model.IDorVulnerabilityInput + OtherVulns []*model.IDorVulnerabilityInput Ins []*model.VulnEqualInputSpec } tests := []struct { @@ -635,8 +635,8 @@ func TestIngestVulnEquals(t *testing.T) { InVuln: []*model.VulnerabilityInputSpec{testdata.O1, testdata.C1, testdata.O1, testdata.C2}, Calls: []call{ { - Vulns: []*model.VulnerabilityInputSpec{testdata.O1, testdata.O1}, - OtherVulns: []*model.VulnerabilityInputSpec{testdata.C1, testdata.C2}, + Vulns: []*model.IDorVulnerabilityInput{{VulnerabilityInput: testdata.O1}, {VulnerabilityInput: testdata.O1}}, + OtherVulns: []*model.IDorVulnerabilityInput{{VulnerabilityInput: testdata.C1}, {VulnerabilityInput: testdata.C2}}, Ins: []*model.VulnEqualInputSpec{ { Justification: "test justification", @@ -684,8 +684,8 @@ func TestIngestVulnEquals(t *testing.T) { InVuln: []*model.VulnerabilityInputSpec{testdata.O1, testdata.C1, testdata.O1, testdata.C1}, Calls: []call{ { - Vulns: []*model.VulnerabilityInputSpec{testdata.O1, testdata.O1}, - OtherVulns: []*model.VulnerabilityInputSpec{testdata.C1, testdata.C1}, + Vulns: []*model.IDorVulnerabilityInput{{VulnerabilityInput: testdata.O1}, {VulnerabilityInput: testdata.O1}}, + OtherVulns: []*model.IDorVulnerabilityInput{{VulnerabilityInput: testdata.C1}, {VulnerabilityInput: testdata.C1}}, Ins: []*model.VulnEqualInputSpec{ { Justification: "test justification", @@ -734,8 +734,8 @@ func TestIngestVulnEquals(t *testing.T) { InVuln: []*model.VulnerabilityInputSpec{testdata.O1, testdata.C1, testdata.O2, testdata.G2}, Calls: []call{ { - Vulns: []*model.VulnerabilityInputSpec{testdata.O1, testdata.O2}, - OtherVulns: []*model.VulnerabilityInputSpec{testdata.C1, testdata.G2}, + Vulns: []*model.IDorVulnerabilityInput{{VulnerabilityInput: testdata.O1}, {VulnerabilityInput: testdata.O2}}, + OtherVulns: []*model.IDorVulnerabilityInput{{VulnerabilityInput: testdata.C1}, {VulnerabilityInput: testdata.G2}}, Ins: []*model.VulnEqualInputSpec{ { Justification: "test justification", @@ -772,9 +772,12 @@ func TestIngestVulnEquals(t *testing.T) { } for _, test := range tests { t.Run(test.Name, func(t *testing.T) { - if _, err := b.IngestVulnerabilities(ctx, test.InVuln); err != nil { - t.Fatalf("Could not ingest vulnerability: %a", err) + for _, v := range test.InVuln { + if _, err := b.IngestVulnerability(ctx, model.IDorVulnerabilityInput{VulnerabilityInput: v}); err != nil { + t.Fatalf("Could not ingest vulnerability: %a", err) + } } + for _, o := range test.Calls { _, err := b.IngestVulnEquals(ctx, o.Vulns, o.OtherVulns, o.Ins) if (err != nil) != test.ExpIngestErr { diff --git a/internal/testing/backend/vulnMetadata_test.go b/internal/testing/backend/vulnMetadata_test.go index 55e8fc8424..4d3ee5353d 100644 --- a/internal/testing/backend/vulnMetadata_test.go +++ b/internal/testing/backend/vulnMetadata_test.go @@ -975,7 +975,7 @@ func TestIngestVulnMetadata(t *testing.T) { for _, test := range tests { t.Run(test.Name, func(t *testing.T) { for _, g := range test.InVuln { - ingestedVuln, err := b.IngestVulnerability(ctx, *g) + ingestedVuln, err := b.IngestVulnerability(ctx, model.IDorVulnerabilityInput{VulnerabilityInput: g}) if err != nil { t.Fatalf("Could not ingest vulnerability: %a", err) } @@ -989,7 +989,7 @@ func TestIngestVulnMetadata(t *testing.T) { } ids := make([]string, len(test.Calls)) for i, o := range test.Calls { - record, err := b.IngestVulnerabilityMetadata(ctx, *o.Vuln, *o.VulnMetadata) + record, err := b.IngestVulnerabilityMetadata(ctx, model.IDorVulnerabilityInput{VulnerabilityInput: o.Vuln}, *o.VulnMetadata) if (err != nil) != test.ExpIngestErr { t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) } @@ -1030,7 +1030,7 @@ func TestIngestVulnMetadatas(t *testing.T) { ctx := context.Background() b := setupTest(t) type call struct { - Vulns []*model.VulnerabilityInputSpec + Vulns []*model.IDorVulnerabilityInput VulnMetadatas []*model.VulnerabilityMetadataInputSpec } @@ -1048,7 +1048,7 @@ func TestIngestVulnMetadatas(t *testing.T) { InVuln: []*model.VulnerabilityInputSpec{testdata.C1, testdata.C2}, Calls: []call{ { - Vulns: []*model.VulnerabilityInputSpec{testdata.C1, testdata.C2}, + Vulns: []*model.IDorVulnerabilityInput{{VulnerabilityInput: testdata.C1}, {VulnerabilityInput: testdata.C2}}, VulnMetadatas: []*model.VulnerabilityMetadataInputSpec{ { ScoreType: model.VulnerabilityScoreTypeCVSSv3, @@ -1102,7 +1102,7 @@ func TestIngestVulnMetadatas(t *testing.T) { InVuln: []*model.VulnerabilityInputSpec{testdata.O1, testdata.O2}, Calls: []call{ { - Vulns: []*model.VulnerabilityInputSpec{testdata.O1, testdata.O2}, + Vulns: []*model.IDorVulnerabilityInput{{VulnerabilityInput: testdata.O1}, {VulnerabilityInput: testdata.O2}}, VulnMetadatas: []*model.VulnerabilityMetadataInputSpec{ { ScoreType: model.VulnerabilityScoreTypeCVSSv3, @@ -1157,7 +1157,7 @@ func TestIngestVulnMetadatas(t *testing.T) { InVuln: []*model.VulnerabilityInputSpec{testdata.G1, testdata.G2}, Calls: []call{ { - Vulns: []*model.VulnerabilityInputSpec{testdata.G1, testdata.G2}, + Vulns: []*model.IDorVulnerabilityInput{{VulnerabilityInput: testdata.G1}, {VulnerabilityInput: testdata.G2}}, VulnMetadatas: []*model.VulnerabilityMetadataInputSpec{ { ScoreType: model.VulnerabilityScoreTypeCVSSv3, @@ -1212,7 +1212,7 @@ func TestIngestVulnMetadatas(t *testing.T) { InVuln: []*model.VulnerabilityInputSpec{testdata.G1, testdata.G2}, Calls: []call{ { - Vulns: []*model.VulnerabilityInputSpec{testdata.G1, testdata.G2}, + Vulns: []*model.IDorVulnerabilityInput{{VulnerabilityInput: testdata.G1}, {VulnerabilityInput: testdata.G2}}, VulnMetadatas: []*model.VulnerabilityMetadataInputSpec{ { ScoreType: model.VulnerabilityScoreTypeCVSSv3, @@ -1255,7 +1255,7 @@ func TestIngestVulnMetadatas(t *testing.T) { InVuln: []*model.VulnerabilityInputSpec{testdata.G1, testdata.G2}, Calls: []call{ { - Vulns: []*model.VulnerabilityInputSpec{testdata.G1, testdata.G2}, + Vulns: []*model.IDorVulnerabilityInput{{VulnerabilityInput: testdata.G1}, {VulnerabilityInput: testdata.G2}}, VulnMetadatas: []*model.VulnerabilityMetadataInputSpec{ { ScoreType: model.VulnerabilityScoreTypeCVSSv3, @@ -1284,8 +1284,10 @@ func TestIngestVulnMetadatas(t *testing.T) { } for _, test := range tests { t.Run(test.Name, func(t *testing.T) { - if _, err := b.IngestVulnerabilities(ctx, test.InVuln); err != nil { - t.Fatalf("Could not ingest vulnerabilities: %a", err) + for _, v := range test.InVuln { + if _, err := b.IngestVulnerability(ctx, model.IDorVulnerabilityInput{VulnerabilityInput: v}); err != nil { + t.Fatalf("Could not ingest vulnerability: %a", err) + } } for _, o := range test.Calls { _, err := b.IngestBulkVulnerabilityMetadata(ctx, o.Vulns, o.VulnMetadatas) diff --git a/internal/testing/backend/vulnerability_test.go b/internal/testing/backend/vulnerability_test.go index aa289740a8..80b0e16db9 100644 --- a/internal/testing/backend/vulnerability_test.go +++ b/internal/testing/backend/vulnerability_test.go @@ -197,7 +197,7 @@ func TestVulnerability(t *testing.T) { for _, test := range tests { t.Run(test.Name, func(t *testing.T) { for _, i := range test.Ingests { - vulnIDs, err := b.IngestVulnerability(ctx, *i) + vulnIDs, err := b.IngestVulnerability(ctx, model.IDorVulnerabilityInput{VulnerabilityInput: i}) if (err != nil) != test.ExpIngestErr { t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) } @@ -229,11 +229,11 @@ func TestIngestVulnerabilities(t *testing.T) { b := setupTest(t) tests := []struct { name string - ingests []*model.VulnerabilityInputSpec + ingests []*model.IDorVulnerabilityInput exp []*model.Vulnerability }{{ name: "Multiple", - ingests: []*model.VulnerabilityInputSpec{testdata.C1, testdata.O1, testdata.G1}, + ingests: []*model.IDorVulnerabilityInput{{VulnerabilityInput: testdata.C1}, {VulnerabilityInput: testdata.O1}, {VulnerabilityInput: testdata.G1}}, }} for _, test := range tests { t.Run(test.name, func(t *testing.T) { diff --git a/internal/testing/cmd/pubsub_test/cmd/files.go b/internal/testing/cmd/pubsub_test/cmd/files.go index 3755b930b9..a081ed003c 100644 --- a/internal/testing/cmd/pubsub_test/cmd/files.go +++ b/internal/testing/cmd/pubsub_test/cmd/files.go @@ -25,8 +25,6 @@ import ( "syscall" "time" - jsoniter "github.com/json-iterator/go" - "github.com/guacsec/guac/pkg/blob" "github.com/guacsec/guac/pkg/emitter" "github.com/guacsec/guac/pkg/handler/collector" @@ -37,8 +35,6 @@ import ( "github.com/spf13/viper" ) -var json = jsoniter.ConfigCompatibleWithStandardLibrary - type options struct { dbAddr string user string diff --git a/internal/testing/mocks/backend.go b/internal/testing/mocks/backend.go index 23cb2d8b34..8023492db4 100644 --- a/internal/testing/mocks/backend.go +++ b/internal/testing/mocks/backend.go @@ -231,7 +231,7 @@ func (mr *MockBackendMockRecorder) HashEqual(ctx, hashEqualSpec interface{}) *go } // IngestArtifact mocks base method. -func (m *MockBackend) IngestArtifact(ctx context.Context, artifact *model.ArtifactInputSpec) (string, error) { +func (m *MockBackend) IngestArtifact(ctx context.Context, artifact *model.IDorArtifactInput) (string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IngestArtifact", ctx, artifact) ret0, _ := ret[0].(string) @@ -246,7 +246,7 @@ func (mr *MockBackendMockRecorder) IngestArtifact(ctx, artifact interface{}) *go } // IngestArtifacts mocks base method. -func (m *MockBackend) IngestArtifacts(ctx context.Context, artifacts []*model.ArtifactInputSpec) ([]string, error) { +func (m *MockBackend) IngestArtifacts(ctx context.Context, artifacts []*model.IDorArtifactInput) ([]string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IngestArtifacts", ctx, artifacts) ret0, _ := ret[0].([]string) @@ -261,7 +261,7 @@ func (mr *MockBackendMockRecorder) IngestArtifacts(ctx, artifacts interface{}) * } // IngestBuilder mocks base method. -func (m *MockBackend) IngestBuilder(ctx context.Context, builder *model.BuilderInputSpec) (string, error) { +func (m *MockBackend) IngestBuilder(ctx context.Context, builder *model.IDorBuilderInput) (string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IngestBuilder", ctx, builder) ret0, _ := ret[0].(string) @@ -276,7 +276,7 @@ func (mr *MockBackendMockRecorder) IngestBuilder(ctx, builder interface{}) *gomo } // IngestBuilders mocks base method. -func (m *MockBackend) IngestBuilders(ctx context.Context, builders []*model.BuilderInputSpec) ([]string, error) { +func (m *MockBackend) IngestBuilders(ctx context.Context, builders []*model.IDorBuilderInput) ([]string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IngestBuilders", ctx, builders) ret0, _ := ret[0].([]string) @@ -306,7 +306,7 @@ func (mr *MockBackendMockRecorder) IngestBulkHasMetadata(ctx, subjects, pkgMatch } // IngestBulkVulnerabilityMetadata mocks base method. -func (m *MockBackend) IngestBulkVulnerabilityMetadata(ctx context.Context, vulnerabilities []*model.VulnerabilityInputSpec, vulnerabilityMetadataList []*model.VulnerabilityMetadataInputSpec) ([]string, error) { +func (m *MockBackend) IngestBulkVulnerabilityMetadata(ctx context.Context, vulnerabilities []*model.IDorVulnerabilityInput, vulnerabilityMetadataList []*model.VulnerabilityMetadataInputSpec) ([]string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IngestBulkVulnerabilityMetadata", ctx, vulnerabilities, vulnerabilityMetadataList) ret0, _ := ret[0].([]string) @@ -381,7 +381,7 @@ func (mr *MockBackendMockRecorder) IngestCertifyGoods(ctx, subjects, pkgMatchTyp } // IngestCertifyLegal mocks base method. -func (m *MockBackend) IngestCertifyLegal(ctx context.Context, subject model.PackageOrSourceInput, declaredLicenses, discoveredLicenses []*model.LicenseInputSpec, certifyLegal *model.CertifyLegalInputSpec) (string, error) { +func (m *MockBackend) IngestCertifyLegal(ctx context.Context, subject model.PackageOrSourceInput, declaredLicenses, discoveredLicenses []*model.IDorLicenseInput, certifyLegal *model.CertifyLegalInputSpec) (string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IngestCertifyLegal", ctx, subject, declaredLicenses, discoveredLicenses, certifyLegal) ret0, _ := ret[0].(string) @@ -396,7 +396,7 @@ func (mr *MockBackendMockRecorder) IngestCertifyLegal(ctx, subject, declaredLice } // IngestCertifyLegals mocks base method. -func (m *MockBackend) IngestCertifyLegals(ctx context.Context, subjects model.PackageOrSourceInputs, declaredLicensesList, discoveredLicensesList [][]*model.LicenseInputSpec, certifyLegals []*model.CertifyLegalInputSpec) ([]string, error) { +func (m *MockBackend) IngestCertifyLegals(ctx context.Context, subjects model.PackageOrSourceInputs, declaredLicensesList, discoveredLicensesList [][]*model.IDorLicenseInput, certifyLegals []*model.CertifyLegalInputSpec) ([]string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IngestCertifyLegals", ctx, subjects, declaredLicensesList, discoveredLicensesList, certifyLegals) ret0, _ := ret[0].([]string) @@ -411,7 +411,7 @@ func (mr *MockBackendMockRecorder) IngestCertifyLegals(ctx, subjects, declaredLi } // IngestCertifyVuln mocks base method. -func (m *MockBackend) IngestCertifyVuln(ctx context.Context, pkg model.PkgInputSpec, vulnerability model.VulnerabilityInputSpec, certifyVuln model.ScanMetadataInput) (string, error) { +func (m *MockBackend) IngestCertifyVuln(ctx context.Context, pkg model.IDorPkgInput, vulnerability model.IDorVulnerabilityInput, certifyVuln model.ScanMetadataInput) (string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IngestCertifyVuln", ctx, pkg, vulnerability, certifyVuln) ret0, _ := ret[0].(string) @@ -426,7 +426,7 @@ func (mr *MockBackendMockRecorder) IngestCertifyVuln(ctx, pkg, vulnerability, ce } // IngestCertifyVulns mocks base method. -func (m *MockBackend) IngestCertifyVulns(ctx context.Context, pkgs []*model.PkgInputSpec, vulnerabilities []*model.VulnerabilityInputSpec, certifyVulns []*model.ScanMetadataInput) ([]string, error) { +func (m *MockBackend) IngestCertifyVulns(ctx context.Context, pkgs []*model.IDorPkgInput, vulnerabilities []*model.IDorVulnerabilityInput, certifyVulns []*model.ScanMetadataInput) ([]string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IngestCertifyVulns", ctx, pkgs, vulnerabilities, certifyVulns) ret0, _ := ret[0].([]string) @@ -441,7 +441,7 @@ func (mr *MockBackendMockRecorder) IngestCertifyVulns(ctx, pkgs, vulnerabilities } // IngestDependencies mocks base method. -func (m *MockBackend) IngestDependencies(ctx context.Context, pkgs, depPkgs []*model.PkgInputSpec, depPkgMatchType model.MatchFlags, dependencies []*model.IsDependencyInputSpec) ([]string, error) { +func (m *MockBackend) IngestDependencies(ctx context.Context, pkgs, depPkgs []*model.IDorPkgInput, depPkgMatchType model.MatchFlags, dependencies []*model.IsDependencyInputSpec) ([]string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IngestDependencies", ctx, pkgs, depPkgs, depPkgMatchType, dependencies) ret0, _ := ret[0].([]string) @@ -456,7 +456,7 @@ func (mr *MockBackendMockRecorder) IngestDependencies(ctx, pkgs, depPkgs, depPkg } // IngestDependency mocks base method. -func (m *MockBackend) IngestDependency(ctx context.Context, pkg, depPkg model.PkgInputSpec, depPkgMatchType model.MatchFlags, dependency model.IsDependencyInputSpec) (string, error) { +func (m *MockBackend) IngestDependency(ctx context.Context, pkg, depPkg model.IDorPkgInput, depPkgMatchType model.MatchFlags, dependency model.IsDependencyInputSpec) (string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IngestDependency", ctx, pkg, depPkg, depPkgMatchType, dependency) ret0, _ := ret[0].(string) @@ -516,7 +516,7 @@ func (mr *MockBackendMockRecorder) IngestHasSbom(ctx, subject, hasSbom, includes } // IngestHasSourceAt mocks base method. -func (m *MockBackend) IngestHasSourceAt(ctx context.Context, pkg model.PkgInputSpec, pkgMatchType model.MatchFlags, source model.SourceInputSpec, hasSourceAt model.HasSourceAtInputSpec) (string, error) { +func (m *MockBackend) IngestHasSourceAt(ctx context.Context, pkg model.IDorPkgInput, pkgMatchType model.MatchFlags, source model.IDorSourceInput, hasSourceAt model.HasSourceAtInputSpec) (string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IngestHasSourceAt", ctx, pkg, pkgMatchType, source, hasSourceAt) ret0, _ := ret[0].(string) @@ -531,7 +531,7 @@ func (mr *MockBackendMockRecorder) IngestHasSourceAt(ctx, pkg, pkgMatchType, sou } // IngestHasSourceAts mocks base method. -func (m *MockBackend) IngestHasSourceAts(ctx context.Context, pkgs []*model.PkgInputSpec, pkgMatchType *model.MatchFlags, sources []*model.SourceInputSpec, hasSourceAts []*model.HasSourceAtInputSpec) ([]string, error) { +func (m *MockBackend) IngestHasSourceAts(ctx context.Context, pkgs []*model.IDorPkgInput, pkgMatchType *model.MatchFlags, sources []*model.IDorSourceInput, hasSourceAts []*model.HasSourceAtInputSpec) ([]string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IngestHasSourceAts", ctx, pkgs, pkgMatchType, sources, hasSourceAts) ret0, _ := ret[0].([]string) @@ -546,7 +546,7 @@ func (mr *MockBackendMockRecorder) IngestHasSourceAts(ctx, pkgs, pkgMatchType, s } // IngestHashEqual mocks base method. -func (m *MockBackend) IngestHashEqual(ctx context.Context, artifact, equalArtifact model.ArtifactInputSpec, hashEqual model.HashEqualInputSpec) (string, error) { +func (m *MockBackend) IngestHashEqual(ctx context.Context, artifact, equalArtifact model.IDorArtifactInput, hashEqual model.HashEqualInputSpec) (string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IngestHashEqual", ctx, artifact, equalArtifact, hashEqual) ret0, _ := ret[0].(string) @@ -561,7 +561,7 @@ func (mr *MockBackendMockRecorder) IngestHashEqual(ctx, artifact, equalArtifact, } // IngestHashEquals mocks base method. -func (m *MockBackend) IngestHashEquals(ctx context.Context, artifacts, otherArtifacts []*model.ArtifactInputSpec, hashEquals []*model.HashEqualInputSpec) ([]string, error) { +func (m *MockBackend) IngestHashEquals(ctx context.Context, artifacts, otherArtifacts []*model.IDorArtifactInput, hashEquals []*model.HashEqualInputSpec) ([]string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IngestHashEquals", ctx, artifacts, otherArtifacts, hashEquals) ret0, _ := ret[0].([]string) @@ -576,7 +576,7 @@ func (mr *MockBackendMockRecorder) IngestHashEquals(ctx, artifacts, otherArtifac } // IngestLicense mocks base method. -func (m *MockBackend) IngestLicense(ctx context.Context, license *model.LicenseInputSpec) (string, error) { +func (m *MockBackend) IngestLicense(ctx context.Context, license *model.IDorLicenseInput) (string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IngestLicense", ctx, license) ret0, _ := ret[0].(string) @@ -591,7 +591,7 @@ func (mr *MockBackendMockRecorder) IngestLicense(ctx, license interface{}) *gomo } // IngestLicenses mocks base method. -func (m *MockBackend) IngestLicenses(ctx context.Context, licenses []*model.LicenseInputSpec) ([]string, error) { +func (m *MockBackend) IngestLicenses(ctx context.Context, licenses []*model.IDorLicenseInput) ([]string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IngestLicenses", ctx, licenses) ret0, _ := ret[0].([]string) @@ -606,7 +606,7 @@ func (mr *MockBackendMockRecorder) IngestLicenses(ctx, licenses interface{}) *go } // IngestOccurrence mocks base method. -func (m *MockBackend) IngestOccurrence(ctx context.Context, subject model.PackageOrSourceInput, artifact model.ArtifactInputSpec, occurrence model.IsOccurrenceInputSpec) (string, error) { +func (m *MockBackend) IngestOccurrence(ctx context.Context, subject model.PackageOrSourceInput, artifact model.IDorArtifactInput, occurrence model.IsOccurrenceInputSpec) (string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IngestOccurrence", ctx, subject, artifact, occurrence) ret0, _ := ret[0].(string) @@ -621,7 +621,7 @@ func (mr *MockBackendMockRecorder) IngestOccurrence(ctx, subject, artifact, occu } // IngestOccurrences mocks base method. -func (m *MockBackend) IngestOccurrences(ctx context.Context, subjects model.PackageOrSourceInputs, artifacts []*model.ArtifactInputSpec, occurrences []*model.IsOccurrenceInputSpec) ([]string, error) { +func (m *MockBackend) IngestOccurrences(ctx context.Context, subjects model.PackageOrSourceInputs, artifacts []*model.IDorArtifactInput, occurrences []*model.IsOccurrenceInputSpec) ([]string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IngestOccurrences", ctx, subjects, artifacts, occurrences) ret0, _ := ret[0].([]string) @@ -636,7 +636,7 @@ func (mr *MockBackendMockRecorder) IngestOccurrences(ctx, subjects, artifacts, o } // IngestPackage mocks base method. -func (m *MockBackend) IngestPackage(ctx context.Context, pkg model.PkgInputSpec) (*model.PackageIDs, error) { +func (m *MockBackend) IngestPackage(ctx context.Context, pkg model.IDorPkgInput) (*model.PackageIDs, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IngestPackage", ctx, pkg) ret0, _ := ret[0].(*model.PackageIDs) @@ -651,7 +651,7 @@ func (mr *MockBackendMockRecorder) IngestPackage(ctx, pkg interface{}) *gomock.C } // IngestPackages mocks base method. -func (m *MockBackend) IngestPackages(ctx context.Context, pkgs []*model.PkgInputSpec) ([]*model.PackageIDs, error) { +func (m *MockBackend) IngestPackages(ctx context.Context, pkgs []*model.IDorPkgInput) ([]*model.PackageIDs, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IngestPackages", ctx, pkgs) ret0, _ := ret[0].([]*model.PackageIDs) @@ -666,7 +666,7 @@ func (mr *MockBackendMockRecorder) IngestPackages(ctx, pkgs interface{}) *gomock } // IngestPkgEqual mocks base method. -func (m *MockBackend) IngestPkgEqual(ctx context.Context, pkg, depPkg model.PkgInputSpec, pkgEqual model.PkgEqualInputSpec) (string, error) { +func (m *MockBackend) IngestPkgEqual(ctx context.Context, pkg, depPkg model.IDorPkgInput, pkgEqual model.PkgEqualInputSpec) (string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IngestPkgEqual", ctx, pkg, depPkg, pkgEqual) ret0, _ := ret[0].(string) @@ -681,7 +681,7 @@ func (mr *MockBackendMockRecorder) IngestPkgEqual(ctx, pkg, depPkg, pkgEqual int } // IngestPkgEquals mocks base method. -func (m *MockBackend) IngestPkgEquals(ctx context.Context, pkgs, otherPackages []*model.PkgInputSpec, pkgEquals []*model.PkgEqualInputSpec) ([]string, error) { +func (m *MockBackend) IngestPkgEquals(ctx context.Context, pkgs, otherPackages []*model.IDorPkgInput, pkgEquals []*model.PkgEqualInputSpec) ([]string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IngestPkgEquals", ctx, pkgs, otherPackages, pkgEquals) ret0, _ := ret[0].([]string) @@ -726,7 +726,7 @@ func (mr *MockBackendMockRecorder) IngestPointOfContacts(ctx, subjects, pkgMatch } // IngestSLSA mocks base method. -func (m *MockBackend) IngestSLSA(ctx context.Context, subject model.ArtifactInputSpec, builtFrom []*model.ArtifactInputSpec, builtBy model.BuilderInputSpec, slsa model.SLSAInputSpec) (string, error) { +func (m *MockBackend) IngestSLSA(ctx context.Context, subject model.IDorArtifactInput, builtFrom []*model.IDorArtifactInput, builtBy model.IDorBuilderInput, slsa model.SLSAInputSpec) (string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IngestSLSA", ctx, subject, builtFrom, builtBy, slsa) ret0, _ := ret[0].(string) @@ -741,7 +741,7 @@ func (mr *MockBackendMockRecorder) IngestSLSA(ctx, subject, builtFrom, builtBy, } // IngestSLSAs mocks base method. -func (m *MockBackend) IngestSLSAs(ctx context.Context, subjects []*model.ArtifactInputSpec, builtFromList [][]*model.ArtifactInputSpec, builtByList []*model.BuilderInputSpec, slsaList []*model.SLSAInputSpec) ([]string, error) { +func (m *MockBackend) IngestSLSAs(ctx context.Context, subjects []*model.IDorArtifactInput, builtFromList [][]*model.IDorArtifactInput, builtByList []*model.IDorBuilderInput, slsaList []*model.SLSAInputSpec) ([]string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IngestSLSAs", ctx, subjects, builtFromList, builtByList, slsaList) ret0, _ := ret[0].([]string) @@ -756,7 +756,7 @@ func (mr *MockBackendMockRecorder) IngestSLSAs(ctx, subjects, builtFromList, bui } // IngestScorecard mocks base method. -func (m *MockBackend) IngestScorecard(ctx context.Context, source model.SourceInputSpec, scorecard model.ScorecardInputSpec) (string, error) { +func (m *MockBackend) IngestScorecard(ctx context.Context, source model.IDorSourceInput, scorecard model.ScorecardInputSpec) (string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IngestScorecard", ctx, source, scorecard) ret0, _ := ret[0].(string) @@ -771,7 +771,7 @@ func (mr *MockBackendMockRecorder) IngestScorecard(ctx, source, scorecard interf } // IngestScorecards mocks base method. -func (m *MockBackend) IngestScorecards(ctx context.Context, sources []*model.SourceInputSpec, scorecards []*model.ScorecardInputSpec) ([]string, error) { +func (m *MockBackend) IngestScorecards(ctx context.Context, sources []*model.IDorSourceInput, scorecards []*model.ScorecardInputSpec) ([]string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IngestScorecards", ctx, sources, scorecards) ret0, _ := ret[0].([]string) @@ -786,7 +786,7 @@ func (mr *MockBackendMockRecorder) IngestScorecards(ctx, sources, scorecards int } // IngestSource mocks base method. -func (m *MockBackend) IngestSource(ctx context.Context, source model.SourceInputSpec) (*model.SourceIDs, error) { +func (m *MockBackend) IngestSource(ctx context.Context, source model.IDorSourceInput) (*model.SourceIDs, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IngestSource", ctx, source) ret0, _ := ret[0].(*model.SourceIDs) @@ -801,7 +801,7 @@ func (mr *MockBackendMockRecorder) IngestSource(ctx, source interface{}) *gomock } // IngestSources mocks base method. -func (m *MockBackend) IngestSources(ctx context.Context, sources []*model.SourceInputSpec) ([]*model.SourceIDs, error) { +func (m *MockBackend) IngestSources(ctx context.Context, sources []*model.IDorSourceInput) ([]*model.SourceIDs, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IngestSources", ctx, sources) ret0, _ := ret[0].([]*model.SourceIDs) @@ -816,7 +816,7 @@ func (mr *MockBackendMockRecorder) IngestSources(ctx, sources interface{}) *gomo } // IngestVEXStatement mocks base method. -func (m *MockBackend) IngestVEXStatement(ctx context.Context, subject model.PackageOrArtifactInput, vulnerability model.VulnerabilityInputSpec, vexStatement model.VexStatementInputSpec) (string, error) { +func (m *MockBackend) IngestVEXStatement(ctx context.Context, subject model.PackageOrArtifactInput, vulnerability model.IDorVulnerabilityInput, vexStatement model.VexStatementInputSpec) (string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IngestVEXStatement", ctx, subject, vulnerability, vexStatement) ret0, _ := ret[0].(string) @@ -831,7 +831,7 @@ func (mr *MockBackendMockRecorder) IngestVEXStatement(ctx, subject, vulnerabilit } // IngestVEXStatements mocks base method. -func (m *MockBackend) IngestVEXStatements(ctx context.Context, subjects model.PackageOrArtifactInputs, vulnerabilities []*model.VulnerabilityInputSpec, vexStatements []*model.VexStatementInputSpec) ([]string, error) { +func (m *MockBackend) IngestVEXStatements(ctx context.Context, subjects model.PackageOrArtifactInputs, vulnerabilities []*model.IDorVulnerabilityInput, vexStatements []*model.VexStatementInputSpec) ([]string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IngestVEXStatements", ctx, subjects, vulnerabilities, vexStatements) ret0, _ := ret[0].([]string) @@ -846,7 +846,7 @@ func (mr *MockBackendMockRecorder) IngestVEXStatements(ctx, subjects, vulnerabil } // IngestVulnEqual mocks base method. -func (m *MockBackend) IngestVulnEqual(ctx context.Context, vulnerability, otherVulnerability model.VulnerabilityInputSpec, vulnEqual model.VulnEqualInputSpec) (string, error) { +func (m *MockBackend) IngestVulnEqual(ctx context.Context, vulnerability, otherVulnerability model.IDorVulnerabilityInput, vulnEqual model.VulnEqualInputSpec) (string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IngestVulnEqual", ctx, vulnerability, otherVulnerability, vulnEqual) ret0, _ := ret[0].(string) @@ -861,7 +861,7 @@ func (mr *MockBackendMockRecorder) IngestVulnEqual(ctx, vulnerability, otherVuln } // IngestVulnEquals mocks base method. -func (m *MockBackend) IngestVulnEquals(ctx context.Context, vulnerabilities, otherVulnerabilities []*model.VulnerabilityInputSpec, vulnEquals []*model.VulnEqualInputSpec) ([]string, error) { +func (m *MockBackend) IngestVulnEquals(ctx context.Context, vulnerabilities, otherVulnerabilities []*model.IDorVulnerabilityInput, vulnEquals []*model.VulnEqualInputSpec) ([]string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IngestVulnEquals", ctx, vulnerabilities, otherVulnerabilities, vulnEquals) ret0, _ := ret[0].([]string) @@ -876,7 +876,7 @@ func (mr *MockBackendMockRecorder) IngestVulnEquals(ctx, vulnerabilities, otherV } // IngestVulnerabilities mocks base method. -func (m *MockBackend) IngestVulnerabilities(ctx context.Context, vulns []*model.VulnerabilityInputSpec) ([]*model.VulnerabilityIDs, error) { +func (m *MockBackend) IngestVulnerabilities(ctx context.Context, vulns []*model.IDorVulnerabilityInput) ([]*model.VulnerabilityIDs, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IngestVulnerabilities", ctx, vulns) ret0, _ := ret[0].([]*model.VulnerabilityIDs) @@ -891,7 +891,7 @@ func (mr *MockBackendMockRecorder) IngestVulnerabilities(ctx, vulns interface{}) } // IngestVulnerability mocks base method. -func (m *MockBackend) IngestVulnerability(ctx context.Context, vuln model.VulnerabilityInputSpec) (*model.VulnerabilityIDs, error) { +func (m *MockBackend) IngestVulnerability(ctx context.Context, vuln model.IDorVulnerabilityInput) (*model.VulnerabilityIDs, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IngestVulnerability", ctx, vuln) ret0, _ := ret[0].(*model.VulnerabilityIDs) @@ -906,7 +906,7 @@ func (mr *MockBackendMockRecorder) IngestVulnerability(ctx, vuln interface{}) *g } // IngestVulnerabilityMetadata mocks base method. -func (m *MockBackend) IngestVulnerabilityMetadata(ctx context.Context, vulnerability model.VulnerabilityInputSpec, vulnerabilityMetadata model.VulnerabilityMetadataInputSpec) (string, error) { +func (m *MockBackend) IngestVulnerabilityMetadata(ctx context.Context, vulnerability model.IDorVulnerabilityInput, vulnerabilityMetadata model.VulnerabilityMetadataInputSpec) (string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IngestVulnerabilityMetadata", ctx, vulnerability, vulnerabilityMetadata) ret0, _ := ret[0].(string) diff --git a/pkg/assembler/assembler.go b/pkg/assembler/assembler.go index 9946b1a3b3..365132af04 100644 --- a/pkg/assembler/assembler.go +++ b/pkg/assembler/assembler.go @@ -17,7 +17,6 @@ package assembler import ( "context" - "strings" "github.com/guacsec/guac/pkg/assembler/clients/generated" "github.com/guacsec/guac/pkg/assembler/helpers" @@ -196,19 +195,19 @@ type CertifyLegalIngest struct { CertifyLegal *generated.CertifyLegalInputSpec `json:"certifyLegal,omitempty"` } -func (i IngestPredicates) GetPackages(ctx context.Context) []*generated.PkgInputSpec { - packageMap := make(map[string]*generated.PkgInputSpec) +func (i IngestPredicates) GetPackages(ctx context.Context) map[string]*generated.IDorPkgInput { + packageMap := make(map[string]*generated.IDorPkgInput) for _, dep := range i.IsDependency { if dep.Pkg != nil { pkgPurl := helpers.PkgInputSpecToPurl(dep.Pkg) if _, ok := packageMap[pkgPurl]; !ok { - packageMap[pkgPurl] = dep.Pkg + packageMap[pkgPurl] = &generated.IDorPkgInput{PackageInput: dep.Pkg} } } if dep.DepPkg != nil { depPkgPurl := helpers.PkgInputSpecToPurl(dep.DepPkg) if _, ok := packageMap[depPkgPurl]; !ok { - packageMap[depPkgPurl] = dep.DepPkg + packageMap[depPkgPurl] = &generated.IDorPkgInput{PackageInput: dep.DepPkg} } } } @@ -216,7 +215,7 @@ func (i IngestPredicates) GetPackages(ctx context.Context) []*generated.PkgInput if occur.Pkg != nil { pkgPurl := helpers.PkgInputSpecToPurl(occur.Pkg) if _, ok := packageMap[pkgPurl]; !ok { - packageMap[pkgPurl] = occur.Pkg + packageMap[pkgPurl] = &generated.IDorPkgInput{PackageInput: occur.Pkg} } } } @@ -224,7 +223,7 @@ func (i IngestPredicates) GetPackages(ctx context.Context) []*generated.PkgInput if vuln.Pkg != nil { pkgPurl := helpers.PkgInputSpecToPurl(vuln.Pkg) if _, ok := packageMap[pkgPurl]; !ok { - packageMap[pkgPurl] = vuln.Pkg + packageMap[pkgPurl] = &generated.IDorPkgInput{PackageInput: vuln.Pkg} } } } @@ -232,7 +231,7 @@ func (i IngestPredicates) GetPackages(ctx context.Context) []*generated.PkgInput if hasSource.Pkg != nil { pkgPurl := helpers.PkgInputSpecToPurl(hasSource.Pkg) if _, ok := packageMap[pkgPurl]; !ok { - packageMap[pkgPurl] = hasSource.Pkg + packageMap[pkgPurl] = &generated.IDorPkgInput{PackageInput: hasSource.Pkg} } } } @@ -240,7 +239,7 @@ func (i IngestPredicates) GetPackages(ctx context.Context) []*generated.PkgInput if bad.Pkg != nil { pkgPurl := helpers.PkgInputSpecToPurl(bad.Pkg) if _, ok := packageMap[pkgPurl]; !ok { - packageMap[pkgPurl] = bad.Pkg + packageMap[pkgPurl] = &generated.IDorPkgInput{PackageInput: bad.Pkg} } } } @@ -248,7 +247,7 @@ func (i IngestPredicates) GetPackages(ctx context.Context) []*generated.PkgInput if good.Pkg != nil { pkgPurl := helpers.PkgInputSpecToPurl(good.Pkg) if _, ok := packageMap[pkgPurl]; !ok { - packageMap[pkgPurl] = good.Pkg + packageMap[pkgPurl] = &generated.IDorPkgInput{PackageInput: good.Pkg} } } } @@ -256,7 +255,7 @@ func (i IngestPredicates) GetPackages(ctx context.Context) []*generated.PkgInput if sbom.Pkg != nil { pkgPurl := helpers.PkgInputSpecToPurl(sbom.Pkg) if _, ok := packageMap[pkgPurl]; !ok { - packageMap[pkgPurl] = sbom.Pkg + packageMap[pkgPurl] = &generated.IDorPkgInput{PackageInput: sbom.Pkg} } } } @@ -264,7 +263,7 @@ func (i IngestPredicates) GetPackages(ctx context.Context) []*generated.PkgInput if v.Pkg != nil { pkgPurl := helpers.PkgInputSpecToPurl(v.Pkg) if _, ok := packageMap[pkgPurl]; !ok { - packageMap[pkgPurl] = v.Pkg + packageMap[pkgPurl] = &generated.IDorPkgInput{PackageInput: v.Pkg} } } } @@ -272,7 +271,7 @@ func (i IngestPredicates) GetPackages(ctx context.Context) []*generated.PkgInput if poc.Pkg != nil { pkgPurl := helpers.PkgInputSpecToPurl(poc.Pkg) if _, ok := packageMap[pkgPurl]; !ok { - packageMap[pkgPurl] = poc.Pkg + packageMap[pkgPurl] = &generated.IDorPkgInput{PackageInput: poc.Pkg} } } } @@ -280,7 +279,7 @@ func (i IngestPredicates) GetPackages(ctx context.Context) []*generated.PkgInput if hm.Pkg != nil { pkgPurl := helpers.PkgInputSpecToPurl(hm.Pkg) if _, ok := packageMap[pkgPurl]; !ok { - packageMap[pkgPurl] = hm.Pkg + packageMap[pkgPurl] = &generated.IDorPkgInput{PackageInput: hm.Pkg} } } } @@ -288,13 +287,13 @@ func (i IngestPredicates) GetPackages(ctx context.Context) []*generated.PkgInput if equal.Pkg != nil { pkgPurl := helpers.PkgInputSpecToPurl(equal.Pkg) if _, ok := packageMap[pkgPurl]; !ok { - packageMap[pkgPurl] = equal.Pkg + packageMap[pkgPurl] = &generated.IDorPkgInput{PackageInput: equal.Pkg} } } if equal.EqualPkg != nil { equalPkgPurl := helpers.PkgInputSpecToPurl(equal.EqualPkg) if _, ok := packageMap[equalPkgPurl]; !ok { - packageMap[equalPkgPurl] = equal.EqualPkg + packageMap[equalPkgPurl] = &generated.IDorPkgInput{PackageInput: equal.EqualPkg} } } } @@ -302,228 +301,207 @@ func (i IngestPredicates) GetPackages(ctx context.Context) []*generated.PkgInput if cl.Pkg != nil { pkgPurl := helpers.PkgInputSpecToPurl(cl.Pkg) if _, ok := packageMap[pkgPurl]; !ok { - packageMap[pkgPurl] = cl.Pkg + packageMap[pkgPurl] = &generated.IDorPkgInput{PackageInput: cl.Pkg} } } } - packages := make([]*generated.PkgInputSpec, 0, len(packageMap)) - for _, pkg := range packageMap { - packages = append(packages, pkg) - } - return packages + return packageMap } -func (i IngestPredicates) GetSources(ctx context.Context) []*generated.SourceInputSpec { - sourceMap := make(map[string]*generated.SourceInputSpec) +func (i IngestPredicates) GetSources(ctx context.Context) map[string]*generated.IDorSourceInput { + sourceMap := make(map[string]*generated.IDorSourceInput) for _, score := range i.CertifyScorecard { if score.Source != nil { - sourceString := concatenateSourceInput(score.Source) + sourceString := helpers.ConcatenateSourceInput(score.Source) if _, ok := sourceMap[sourceString]; !ok { - sourceMap[sourceString] = score.Source + sourceMap[sourceString] = &generated.IDorSourceInput{SourceInput: score.Source} } } } for _, occur := range i.IsOccurrence { if occur.Src != nil { - sourceString := concatenateSourceInput(occur.Src) + sourceString := helpers.ConcatenateSourceInput(occur.Src) if _, ok := sourceMap[sourceString]; !ok { - sourceMap[sourceString] = occur.Src + sourceMap[sourceString] = &generated.IDorSourceInput{SourceInput: occur.Src} } } } for _, hasSource := range i.HasSourceAt { if hasSource.Src != nil { - sourceString := concatenateSourceInput(hasSource.Src) + sourceString := helpers.ConcatenateSourceInput(hasSource.Src) if _, ok := sourceMap[sourceString]; !ok { - sourceMap[sourceString] = hasSource.Src + sourceMap[sourceString] = &generated.IDorSourceInput{SourceInput: hasSource.Src} } } } for _, bad := range i.CertifyBad { if bad.Src != nil { - sourceString := concatenateSourceInput(bad.Src) + sourceString := helpers.ConcatenateSourceInput(bad.Src) if _, ok := sourceMap[sourceString]; !ok { - sourceMap[sourceString] = bad.Src + sourceMap[sourceString] = &generated.IDorSourceInput{SourceInput: bad.Src} } } } for _, good := range i.CertifyGood { if good.Src != nil { - sourceString := concatenateSourceInput(good.Src) + sourceString := helpers.ConcatenateSourceInput(good.Src) if _, ok := sourceMap[sourceString]; !ok { - sourceMap[sourceString] = good.Src + sourceMap[sourceString] = &generated.IDorSourceInput{SourceInput: good.Src} } } } for _, poc := range i.PointOfContact { if poc.Src != nil { - sourceString := concatenateSourceInput(poc.Src) + sourceString := helpers.ConcatenateSourceInput(poc.Src) if _, ok := sourceMap[sourceString]; !ok { - sourceMap[sourceString] = poc.Src + sourceMap[sourceString] = &generated.IDorSourceInput{SourceInput: poc.Src} } } } for _, hm := range i.HasMetadata { if hm.Src != nil { - sourceString := concatenateSourceInput(hm.Src) + sourceString := helpers.ConcatenateSourceInput(hm.Src) if _, ok := sourceMap[sourceString]; !ok { - sourceMap[sourceString] = hm.Src + sourceMap[sourceString] = &generated.IDorSourceInput{SourceInput: hm.Src} } } } for _, cl := range i.CertifyLegal { if cl.Src != nil { - sourceString := concatenateSourceInput(cl.Src) + sourceString := helpers.ConcatenateSourceInput(cl.Src) if _, ok := sourceMap[sourceString]; !ok { - sourceMap[sourceString] = cl.Src + sourceMap[sourceString] = &generated.IDorSourceInput{SourceInput: cl.Src} } } } - sources := make([]*generated.SourceInputSpec, 0, len(sourceMap)) - for _, source := range sourceMap { - sources = append(sources, source) - } - return sources + return sourceMap } -func (i IngestPredicates) GetArtifacts(ctx context.Context) []*generated.ArtifactInputSpec { - artifactMap := make(map[string]*generated.ArtifactInputSpec) +func (i IngestPredicates) GetArtifacts(ctx context.Context) map[string]*generated.IDorArtifactInput { + artifactMap := make(map[string]*generated.IDorArtifactInput) for _, occur := range i.IsOccurrence { if occur.Artifact != nil { - artifactString := occur.Artifact.Algorithm + ":" + occur.Artifact.Digest + artifactString := helpers.ArtifactKey(occur.Artifact) if _, ok := artifactMap[artifactString]; !ok { - artifactMap[artifactString] = occur.Artifact + artifactMap[artifactString] = &generated.IDorArtifactInput{ArtifactInput: occur.Artifact} } } } for _, slsa := range i.HasSlsa { if slsa.Artifact != nil { - artifactString := slsa.Artifact.Algorithm + ":" + slsa.Artifact.Digest + artifactString := helpers.ArtifactKey(slsa.Artifact) if _, ok := artifactMap[artifactString]; !ok { - artifactMap[artifactString] = slsa.Artifact + artifactMap[artifactString] = &generated.IDorArtifactInput{ArtifactInput: slsa.Artifact} } } } for _, sbom := range i.HasSBOM { if sbom.Artifact != nil { - artifactString := sbom.Artifact.Algorithm + ":" + sbom.Artifact.Digest + artifactString := helpers.ArtifactKey(sbom.Artifact) if _, ok := artifactMap[artifactString]; !ok { - artifactMap[artifactString] = sbom.Artifact + artifactMap[artifactString] = &generated.IDorArtifactInput{ArtifactInput: sbom.Artifact} } } } for _, bad := range i.CertifyBad { if bad.Artifact != nil { - artifactString := bad.Artifact.Algorithm + ":" + bad.Artifact.Digest + artifactString := helpers.ArtifactKey(bad.Artifact) if _, ok := artifactMap[artifactString]; !ok { - artifactMap[artifactString] = bad.Artifact + artifactMap[artifactString] = &generated.IDorArtifactInput{ArtifactInput: bad.Artifact} } } } for _, good := range i.CertifyGood { if good.Artifact != nil { - artifactString := good.Artifact.Algorithm + ":" + good.Artifact.Digest + artifactString := helpers.ArtifactKey(good.Artifact) if _, ok := artifactMap[artifactString]; !ok { - artifactMap[artifactString] = good.Artifact + artifactMap[artifactString] = &generated.IDorArtifactInput{ArtifactInput: good.Artifact} } } } for _, v := range i.Vex { if v.Artifact != nil { - artifactString := v.Artifact.Algorithm + ":" + v.Artifact.Digest + artifactString := helpers.ArtifactKey(v.Artifact) if _, ok := artifactMap[artifactString]; !ok { - artifactMap[artifactString] = v.Artifact + artifactMap[artifactString] = &generated.IDorArtifactInput{ArtifactInput: v.Artifact} } } } for _, poc := range i.PointOfContact { if poc.Artifact != nil { - artifactString := poc.Artifact.Algorithm + ":" + poc.Artifact.Digest + artifactString := helpers.ArtifactKey(poc.Artifact) if _, ok := artifactMap[artifactString]; !ok { - artifactMap[artifactString] = poc.Artifact + artifactMap[artifactString] = &generated.IDorArtifactInput{ArtifactInput: poc.Artifact} } } } for _, hm := range i.HasMetadata { if hm.Artifact != nil { - artifactString := hm.Artifact.Algorithm + ":" + hm.Artifact.Digest + artifactString := helpers.ArtifactKey(hm.Artifact) if _, ok := artifactMap[artifactString]; !ok { - artifactMap[artifactString] = hm.Artifact + artifactMap[artifactString] = &generated.IDorArtifactInput{ArtifactInput: hm.Artifact} } } } for _, equal := range i.HashEqual { if equal.Artifact != nil { - artifactString := equal.Artifact.Algorithm + ":" + equal.Artifact.Digest + artifactString := helpers.ArtifactKey(equal.Artifact) if _, ok := artifactMap[artifactString]; !ok { - artifactMap[artifactString] = equal.Artifact + artifactMap[artifactString] = &generated.IDorArtifactInput{ArtifactInput: equal.Artifact} } } if equal.EqualArtifact != nil { - artifactString := equal.EqualArtifact.Algorithm + ":" + equal.EqualArtifact.Digest + artifactString := helpers.ArtifactKey(equal.EqualArtifact) if _, ok := artifactMap[artifactString]; !ok { - artifactMap[artifactString] = equal.EqualArtifact + artifactMap[artifactString] = &generated.IDorArtifactInput{ArtifactInput: equal.EqualArtifact} } } } - artifacts := make([]*generated.ArtifactInputSpec, 0, len(artifactMap)) - for _, art := range artifactMap { - artifacts = append(artifacts, art) - } - return artifacts + return artifactMap } -func (i IngestPredicates) GetMaterials(ctx context.Context) []generated.ArtifactInputSpec { - materialMap := make(map[string]generated.ArtifactInputSpec) +func (i IngestPredicates) GetMaterials(ctx context.Context) map[string]*generated.IDorArtifactInput { + materialMap := make(map[string]*generated.IDorArtifactInput) for _, slsa := range i.HasSlsa { for _, mat := range slsa.Materials { artifactString := mat.Algorithm + ":" + mat.Digest if _, ok := materialMap[artifactString]; !ok { - materialMap[artifactString] = mat + materialMap[artifactString] = &generated.IDorArtifactInput{ArtifactInput: &mat} } } } - materials := make([]generated.ArtifactInputSpec, 0, len(materialMap)) - for _, mat := range materialMap { - materials = append(materials, mat) - } - return materials + return materialMap } -func (i IngestPredicates) GetBuilders(ctx context.Context) []*generated.BuilderInputSpec { - builderMap := make(map[string]*generated.BuilderInputSpec) +func (i IngestPredicates) GetBuilders(ctx context.Context) map[string]*generated.IDorBuilderInput { + builderMap := make(map[string]*generated.IDorBuilderInput) for _, slsa := range i.HasSlsa { if slsa.Builder != nil { if _, ok := builderMap[slsa.Builder.Uri]; !ok { - builderMap[slsa.Builder.Uri] = slsa.Builder + builderMap[slsa.Builder.Uri] = &generated.IDorBuilderInput{BuilderInput: slsa.Builder} } } } - builders := make([]*generated.BuilderInputSpec, 0, len(builderMap)) - - for _, build := range builderMap { - builders = append(builders, build) - } - return builders + return builderMap } -func (i IngestPredicates) GetVulnerabilities(ctx context.Context) []*generated.VulnerabilityInputSpec { - vulnMap := make(map[string]*generated.VulnerabilityInputSpec) +func (i IngestPredicates) GetVulnerabilities(ctx context.Context) map[string]*generated.IDorVulnerabilityInput { + vulnMap := make(map[string]*generated.IDorVulnerabilityInput) for _, v := range i.CertifyVuln { equalVURI := helpers.VulnInputToVURI(v.Vulnerability) if _, ok := vulnMap[equalVURI]; !ok { - vulnMap[equalVURI] = v.Vulnerability + vulnMap[equalVURI] = &generated.IDorVulnerabilityInput{VulnerabilityInput: v.Vulnerability} } } for _, v := range i.VulnMetadata { equalVURI := helpers.VulnInputToVURI(v.Vulnerability) if _, ok := vulnMap[equalVURI]; !ok { - vulnMap[equalVURI] = v.Vulnerability + vulnMap[equalVURI] = &generated.IDorVulnerabilityInput{VulnerabilityInput: v.Vulnerability} } } @@ -531,70 +509,43 @@ func (i IngestPredicates) GetVulnerabilities(ctx context.Context) []*generated.V if v.Vulnerability != nil { equalVURI := helpers.VulnInputToVURI(v.Vulnerability) if _, ok := vulnMap[equalVURI]; !ok { - vulnMap[equalVURI] = v.Vulnerability + vulnMap[equalVURI] = &generated.IDorVulnerabilityInput{VulnerabilityInput: v.Vulnerability} } } if v.EqualVulnerability != nil { equalVURI := helpers.VulnInputToVURI(v.EqualVulnerability) if _, ok := vulnMap[equalVURI]; !ok { - vulnMap[equalVURI] = v.EqualVulnerability + vulnMap[equalVURI] = &generated.IDorVulnerabilityInput{VulnerabilityInput: v.EqualVulnerability} } } } for _, v := range i.Vex { equalVURI := helpers.VulnInputToVURI(v.Vulnerability) if _, ok := vulnMap[equalVURI]; !ok { - vulnMap[equalVURI] = v.Vulnerability + vulnMap[equalVURI] = &generated.IDorVulnerabilityInput{VulnerabilityInput: v.Vulnerability} } } - vulns := make([]*generated.VulnerabilityInputSpec, 0, len(vulnMap)) - for _, vuln := range vulnMap { - vulns = append(vulns, vuln) - } - return vulns + return vulnMap } -func (i IngestPredicates) GetLicenses(ctx context.Context) []generated.LicenseInputSpec { - licenseMap := make(map[string]*generated.LicenseInputSpec) +func (i IngestPredicates) GetLicenses(ctx context.Context) map[string]*generated.IDorLicenseInput { + licenseMap := make(map[string]*generated.IDorLicenseInput) for _, cl := range i.CertifyLegal { for i := range cl.Declared { - k := licenseKey(&cl.Declared[i]) + k := helpers.LicenseKey(&cl.Declared[i]) if _, ok := licenseMap[k]; !ok { - licenseMap[k] = &cl.Declared[i] + licenseMap[k] = &generated.IDorLicenseInput{LicenseInput: &cl.Declared[i]} } } for i := range cl.Discovered { - k := licenseKey(&cl.Discovered[i]) + k := helpers.LicenseKey(&cl.Discovered[i]) if _, ok := licenseMap[k]; !ok { - licenseMap[k] = &cl.Discovered[i] + licenseMap[k] = &generated.IDorLicenseInput{LicenseInput: &cl.Discovered[i]} } } } - licenses := make([]generated.LicenseInputSpec, 0, len(licenseMap)) - for _, license := range licenseMap { - licenses = append(licenses, *license) - } - return licenses -} - -func concatenateSourceInput(source *generated.SourceInputSpec) string { - var sourceElements []string - sourceElements = append(sourceElements, source.Type, source.Namespace, source.Name) - if source.Tag != nil { - sourceElements = append(sourceElements, *source.Tag) - } - if source.Commit != nil { - sourceElements = append(sourceElements, *source.Commit) - } - return strings.Join(sourceElements, "/") -} - -func licenseKey(l *generated.LicenseInputSpec) string { - if l.ListVersion != nil && *l.ListVersion != "" { - return strings.Join([]string{l.Name, *l.ListVersion}, ":") - } - return l.Name + return licenseMap } // AssemblerInput represents the inputs to add to the graph diff --git a/pkg/assembler/assembler_test.go b/pkg/assembler/assembler_test.go index 78facff797..800c795e6a 100644 --- a/pkg/assembler/assembler_test.go +++ b/pkg/assembler/assembler_test.go @@ -81,13 +81,13 @@ func TestIngestPredicates(t *testing.T) { tests := []struct { name string field IngestPredicates - wantPkg []*generated.PkgInputSpec - wantSource []*generated.SourceInputSpec - wantArtifact []*generated.ArtifactInputSpec - wantMaterials []generated.ArtifactInputSpec - wantBuilder []*generated.BuilderInputSpec - wantVuln []*generated.VulnerabilityInputSpec - wantLicense []generated.LicenseInputSpec + wantPkg map[string]*generated.IDorPkgInput + wantSource map[string]*generated.IDorSourceInput + wantArtifact map[string]*generated.IDorArtifactInput + wantMaterials map[string]*generated.IDorArtifactInput + wantBuilder map[string]*generated.IDorBuilderInput + wantVuln map[string]*generated.IDorVulnerabilityInput + wantLicense map[string]*generated.IDorLicenseInput }{{ name: "get nouns", field: IngestPredicates{ @@ -686,124 +686,77 @@ func TestIngestPredicates(t *testing.T) { }, }, }, - wantPkg: []*generated.PkgInputSpec{rootFilePack, maven, openSSL, openSSLWithQualifier, topLevelPack, baselayoutPack, baselayoutdataPack, worldFilePack}, - wantSource: []*generated.SourceInputSpec{k8sSource}, - wantArtifact: []*generated.ArtifactInputSpec{ - { + wantPkg: map[string]*generated.IDorPkgInput{ + "pkg:alpine/alpine-baselayout-data@3.2.0-r22?arch=x86_64&distro=alpine-3.16.2&upstream=alpine-baselayout": {PackageInput: baselayoutdataPack}, + "pkg:alpine/alpine-baselayout@3.2.0-r22?arch=x86_64&distro=alpine-3.16.2&upstream=alpine-baselayout": {PackageInput: baselayoutPack}, + "pkg:conan/openssl.org/openssl2@3.0.3": {PackageInput: openSSL}, + "pkg:conan/openssl.org/openssl@3.0.3?channel=stable&user=bincrafters": {PackageInput: openSSLWithQualifier}, + "pkg:guac/files/sha256%3A575d810a9fae5f2f0671c9b2c0ce973e46c7207fbe5cb8d1b0d1836a6a0470e3?filename=%2Fetc%2Fcrontabs%2Froot": {PackageInput: rootFilePack}, + "pkg:guac/files/sha256%3A713e3907167dce202d7c16034831af3d670191382a3e9026e0ac0a4023013201?filename=%2Fetc%2Fapk%2Fworld": {PackageInput: worldFilePack}, + "pkg:guac/spdx/gcr.io/google-containers/alpine-latest": {PackageInput: topLevelPack}, + "pkg:maven/org.apache.logging.log4j/log4j-core@2.8.1": {PackageInput: maven}}, + wantSource: map[string]*generated.IDorSourceInput{ + "git/github.com/kubernetes/kubernetes/5835544ca568b757a8ecae5c153f317e5736700e": {SourceInput: k8sSource}}, + wantArtifact: map[string]*generated.IDorArtifactInput{ + "sha1:7A8F47318E4676DACB0142AFA0B83029CD7BEFD9": {ArtifactInput: &generated.ArtifactInputSpec{ + Algorithm: "sha1", + Digest: "7A8F47318E4676DACB0142AFA0B83029CD7BEFD9", + }}, + "sha256:1234e40ac7250263c5dbe1cf3138912f3f416140aa248637a60d65fe22c47da4": {ArtifactInput: &generated.ArtifactInputSpec{ Algorithm: "sha256", Digest: "1234e40ac7250263c5dbe1cf3138912f3f416140aa248637a60d65fe22c47da4", - }, - { + }}, + "sha256:575d810a9fae5f2f0671c9b2c0ce973e46c7207fbe5cb8d1b0d1836a6a0470e3": {ArtifactInput: &generated.ArtifactInputSpec{ Algorithm: "sha256", Digest: "575d810a9fae5f2f0671c9b2c0ce973e46c7207fbe5cb8d1b0d1836a6a0470e3", - }, - { + }}, + "sha256:6bbb0da1891646e58eb3e6a63af3a6fc3c8eb5a0d44824cba581d2e14a0450cf": {ArtifactInput: &generated.ArtifactInputSpec{ Algorithm: "sha256", Digest: "6bbb0da1891646e58eb3e6a63af3a6fc3c8eb5a0d44824cba581d2e14a0450cf", - }, - { + }}, + "sha256:713e3907167dce202d7c16034831af3d670191382a3e9026e0ac0a4023013201": {ArtifactInput: &generated.ArtifactInputSpec{ Algorithm: "sha256", Digest: "713e3907167dce202d7c16034831af3d670191382a3e9026e0ac0a4023013201", - }, - { - Algorithm: "sha1", - Digest: "7A8F47318E4676DACB0142AFA0B83029CD7BEFD9", - }, - { + }}, + + "sha256:fe4fe40ac7250263c5dbe1cf3138912f3f416140aa248637a60d65fe22c47da4": {ArtifactInput: &generated.ArtifactInputSpec{ Algorithm: "sha256", Digest: "fe4fe40ac7250263c5dbe1cf3138912f3f416140aa248637a60d65fe22c47da4", - }, + }}, }, - wantMaterials: []generated.ArtifactInputSpec{ - { + wantMaterials: map[string]*generated.IDorArtifactInput{ + "gitCommit:c27d339ee6075c1f744c5d4b200f7901aad2c369": {ArtifactInput: &generated.ArtifactInputSpec{ Algorithm: "gitCommit", Digest: "c27d339ee6075c1f744c5d4b200f7901aad2c369", - }, + }}, }, - wantBuilder: []*generated.BuilderInputSpec{ - { + wantBuilder: map[string]*generated.IDorBuilderInput{ + "https://github.com/slsa-framework/slsa-github-generator/.github/workflows/builder_go_slsa3.yml@refs/tags/v0.0.1": {BuilderInput: &generated.BuilderInputSpec{ Uri: "https://github.com/slsa-framework/slsa-github-generator/.github/workflows/builder_go_slsa3.yml@refs/tags/v0.0.1", - }, + }}, }, - wantVuln: []*generated.VulnerabilityInputSpec{ - { - Type: "osv", - VulnerabilityID: "cve-2018-15710", - }, - { - Type: "osv", - VulnerabilityID: "cve-2023-1944", - }, - { - Type: "osv", - VulnerabilityID: "ghsa-7rjr-3q55-vv33", - }, - { - Type: "osv", - VulnerabilityID: "ghsa-8489-44mv-ggj8", - }, - { - Type: "osv", - VulnerabilityID: "ghsa-fxph-q3j8-mv87", - }, - { - Type: "osv", - VulnerabilityID: "ghsa-jfh8-c2jp-5v3q", - }, - { - Type: "osv", - VulnerabilityID: "ghsa-p6xc-xr62-6r2g", - }, - { - Type: "osv", - VulnerabilityID: "ghsa-vwqq-5vrc-xw9h", - }, - { - Type: "cve", - VulnerabilityID: "cve-2018-43610", - }, - { - Type: "cve", - VulnerabilityID: "cve-2023-1944", - }, - { - Type: "ghsa", - VulnerabilityID: "ghsa-7rjr-3q55-vv33", - }, - { - Type: "ghsa", - VulnerabilityID: "ghsa-8489-44mv-ggj8", - }, - { - Type: "ghsa", - VulnerabilityID: "ghsa-fxph-q3j8-mv87", - }, - { - Type: "ghsa", - VulnerabilityID: "ghsa-h45f-rjvw-2rv2", - }, - { - Type: "ghsa", - VulnerabilityID: "ghsa-jfh8-c2jp-5v3q", - }, - { - Type: "ghsa", - VulnerabilityID: "ghsa-p6xc-xr62-6r2g", - }, + wantVuln: map[string]*generated.IDorVulnerabilityInput{ + "vuln://cve/cve-2018-43610": {VulnerabilityInput: &generated.VulnerabilityInputSpec{Type: "cve", VulnerabilityID: "cve-2018-43610"}}, + "vuln://cve/cve-2023-1944": {VulnerabilityInput: &generated.VulnerabilityInputSpec{Type: "cve", VulnerabilityID: "cve-2023-1944"}}, + "vuln://ghsa/ghsa-7rjr-3q55-vv33": {VulnerabilityInput: &generated.VulnerabilityInputSpec{Type: "ghsa", VulnerabilityID: "ghsa-7rjr-3q55-vv33"}}, + "vuln://ghsa/ghsa-8489-44mv-ggj8": {VulnerabilityInput: &generated.VulnerabilityInputSpec{Type: "ghsa", VulnerabilityID: "ghsa-8489-44mv-ggj8"}}, + "vuln://ghsa/ghsa-fxph-q3j8-mv87": {VulnerabilityInput: &generated.VulnerabilityInputSpec{Type: "ghsa", VulnerabilityID: "ghsa-fxph-q3j8-mv87"}}, + "vuln://ghsa/ghsa-h45f-rjvw-2rv2": {VulnerabilityInput: &generated.VulnerabilityInputSpec{Type: "ghsa", VulnerabilityID: "ghsa-h45f-rjvw-2rv2"}}, + "vuln://ghsa/ghsa-jfh8-c2jp-5v3q": {VulnerabilityInput: &generated.VulnerabilityInputSpec{Type: "ghsa", VulnerabilityID: "ghsa-jfh8-c2jp-5v3q"}}, + "vuln://ghsa/ghsa-p6xc-xr62-6r2g": {VulnerabilityInput: &generated.VulnerabilityInputSpec{Type: "ghsa", VulnerabilityID: "ghsa-p6xc-xr62-6r2g"}}, + "vuln://osv/cve-2018-15710": {VulnerabilityInput: &generated.VulnerabilityInputSpec{Type: "osv", VulnerabilityID: "cve-2018-15710"}}, + "vuln://osv/cve-2023-1944": {VulnerabilityInput: &generated.VulnerabilityInputSpec{Type: "osv", VulnerabilityID: "cve-2023-1944"}}, + "vuln://osv/ghsa-7rjr-3q55-vv33": {VulnerabilityInput: &generated.VulnerabilityInputSpec{Type: "osv", VulnerabilityID: "ghsa-7rjr-3q55-vv33"}}, + "vuln://osv/ghsa-8489-44mv-ggj8": {VulnerabilityInput: &generated.VulnerabilityInputSpec{Type: "osv", VulnerabilityID: "ghsa-8489-44mv-ggj8"}}, + "vuln://osv/ghsa-fxph-q3j8-mv87": {VulnerabilityInput: &generated.VulnerabilityInputSpec{Type: "osv", VulnerabilityID: "ghsa-fxph-q3j8-mv87"}}, + "vuln://osv/ghsa-jfh8-c2jp-5v3q": {VulnerabilityInput: &generated.VulnerabilityInputSpec{Type: "osv", VulnerabilityID: "ghsa-jfh8-c2jp-5v3q"}}, + "vuln://osv/ghsa-p6xc-xr62-6r2g": {VulnerabilityInput: &generated.VulnerabilityInputSpec{Type: "osv", VulnerabilityID: "ghsa-p6xc-xr62-6r2g"}}, + "vuln://osv/ghsa-vwqq-5vrc-xw9h": {VulnerabilityInput: &generated.VulnerabilityInputSpec{Type: "osv", VulnerabilityID: "ghsa-vwqq-5vrc-xw9h"}}, }, - wantLicense: []generated.LicenseInputSpec{ - { - Name: "qwer", - ListVersion: ptrfrom.String("1.2.3"), - }, - { - Name: "asdf", - ListVersion: ptrfrom.String("1.2.3"), - }, - { - Name: "LicenseRef-123", - Inline: ptrfrom.String("This is the license text."), - }, + wantLicense: map[string]*generated.IDorLicenseInput{ + "LicenseRef-123": {LicenseInput: &generated.LicenseInputSpec{Name: "LicenseRef-123", Inline: ptrfrom.String("This is the license text.")}}, + "asdf:1.2.3": {LicenseInput: &generated.LicenseInputSpec{Name: "asdf", ListVersion: ptrfrom.String("1.2.3")}}, + "qwer:1.2.3": {LicenseInput: &generated.LicenseInputSpec{Name: "qwer", ListVersion: ptrfrom.String("1.2.3")}}, }, }} for _, tt := range tests { diff --git a/pkg/assembler/backends/arangodb/artifact.go b/pkg/assembler/backends/arangodb/artifact.go index 820c05eb42..238266f2a2 100644 --- a/pkg/assembler/backends/arangodb/artifact.go +++ b/pkg/assembler/backends/arangodb/artifact.go @@ -117,10 +117,10 @@ func (c *arangoClient) getMaterialsByID(ctx context.Context, artifactIDs []strin } // getMaterials return an slice of artifacts as they are already ingested to be used for hasSLSA -func (c *arangoClient) getMaterials(ctx context.Context, artifactSpec []*model.ArtifactInputSpec) ([]*model.Artifact, error) { +func (c *arangoClient) getMaterials(ctx context.Context, artifactSpec []*model.IDorArtifactInput) ([]*model.Artifact, error) { var listOfValues []map[string]any for i := range artifactSpec { - listOfValues = append(listOfValues, getArtifactQueryValues(artifactSpec[i])) + listOfValues = append(listOfValues, getArtifactQueryValues(artifactSpec[i].ArtifactInput)) } var documents []string @@ -174,10 +174,10 @@ func getArtifactQueryValues(artifact *model.ArtifactInputSpec) map[string]any { return values } -func (c *arangoClient) IngestArtifacts(ctx context.Context, artifacts []*model.ArtifactInputSpec) ([]string, error) { +func (c *arangoClient) IngestArtifacts(ctx context.Context, artifacts []*model.IDorArtifactInput) ([]string, error) { var listOfValues []map[string]any for i := range artifacts { - listOfValues = append(listOfValues, getArtifactQueryValues(artifacts[i])) + listOfValues = append(listOfValues, getArtifactQueryValues(artifacts[i].ArtifactInput)) } var documents []string @@ -228,14 +228,14 @@ RETURN { "id": NEW._id }` return artifactIDs, nil } -func (c *arangoClient) IngestArtifact(ctx context.Context, artifact *model.ArtifactInputSpec) (string, error) { +func (c *arangoClient) IngestArtifact(ctx context.Context, artifact *model.IDorArtifactInput) (string, error) { query := ` UPSERT { algorithm:@algorithm, digest:@digest } INSERT { algorithm:@algorithm, digest:@digest } UPDATE {} IN artifacts OPTIONS { indexHint: "byArtAndDigest" } RETURN { "id": NEW._id }` - cursor, err := executeQueryWithRetry(ctx, c.db, query, getArtifactQueryValues(artifact), "IngestArtifact") + cursor, err := executeQueryWithRetry(ctx, c.db, query, getArtifactQueryValues(artifact.ArtifactInput), "IngestArtifact") if err != nil { return "", fmt.Errorf("failed to ingest artifact: %w", err) } diff --git a/pkg/assembler/backends/arangodb/artifact_test.go b/pkg/assembler/backends/arangodb/artifact_test.go deleted file mode 100644 index 36ff67606d..0000000000 --- a/pkg/assembler/backends/arangodb/artifact_test.go +++ /dev/null @@ -1,330 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build integration - -package arangodb - -import ( - "context" - "slices" - "strings" - "testing" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -func getArangoConfig() *ArangoConfig { - return &ArangoConfig{ - User: "root", - Pass: "test123", - DBAddr: "http://localhost:8529", - TestData: false, - } -} - -func lessArtifact(a, b *model.Artifact) int { - return strings.Compare(a.Digest, b.Digest) -} - -func Test_IngestArtifactIDs(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - c, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - tests := []struct { - name string - artifactInputs []*model.ArtifactInputSpec - wantErr bool - }{{ - name: "sha256", - artifactInputs: []*model.ArtifactInputSpec{{ - Algorithm: "sha256", - Digest: "6bbb0da1891646e58eb3e6a63af3a6fc3c8eb5a0d44824cba581d2e14a0450cf", - }, { - Algorithm: "sha1", - Digest: "7a8f47318e4676dacb0142afa0b83029cd7befd9", - }, { - Algorithm: "sha512", - Digest: "374ab8f711235830769aa5f0b31ce9b72c5670074b34cb302cdafe3b606233ee92ee01e298e5701f15cc7087714cd9abd7ddb838a6e1206b3642de16d9fc9dd7", - }}, - wantErr: false, - }} - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := c.IngestArtifacts(ctx, tt.artifactInputs) - if (err != nil) != tt.wantErr { - t.Errorf("arangoClient.IngestArtifacts() error = %v, wantErr %v", err, tt.wantErr) - return - } - if len(got) != len(tt.artifactInputs) { - t.Errorf("Unexpected number of results. Wanted: %d, got %d", len(tt.artifactInputs), len(got)) - } - }) - } -} - -func Test_IngestArtifactID(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - c, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - tests := []struct { - name string - artifactInput *model.ArtifactInputSpec - wantID bool - wantErr bool - }{{ - name: "sha256", - artifactInput: &model.ArtifactInputSpec{ - Algorithm: "sha256", - Digest: "6bbb0da1891646e58eb3e6a63af3a6fc3c8eb5a0d44824cba581d2e14a0450cf", - }, - wantID: true, - wantErr: false, - }, { - name: "sha1", - artifactInput: &model.ArtifactInputSpec{ - Algorithm: "sha1", - Digest: "7A8F47318E4676DACB0142AFA0B83029CD7BEFD9", - }, - wantID: true, - wantErr: false, - }, { - name: "sha512", - artifactInput: &model.ArtifactInputSpec{ - Algorithm: "sha512", - Digest: "374AB8F711235830769AA5F0B31CE9B72C5670074B34CB302CDAFE3B606233EE92EE01E298E5701F15CC7087714CD9ABD7DDB838A6E1206B3642DE16D9FC9DD7", - }, - wantID: true, - wantErr: false, - }, { - name: "duplicate sha512", - artifactInput: &model.ArtifactInputSpec{ - Algorithm: "sha512", - Digest: "374AB8F711235830769AA5F0B31CE9B72C5670074B34CB302CDAFE3B606233EE92EE01E298E5701F15CC7087714CD9ABD7DDB838A6E1206B3642DE16D9FC9DD7", - }, - wantID: true, - wantErr: false, - }} - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := c.IngestArtifact(ctx, tt.artifactInput) - if (err != nil) != tt.wantErr { - t.Errorf("arangoClient.IngestArtifact() error = %v, wantErr %v", err, tt.wantErr) - return - } - if (got != "") != tt.wantID { - t.Errorf("Unexpected number of results") - return - } - }) - } -} - -func Test_Artifacts(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - c, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - tests := []struct { - name string - artifactInput *model.ArtifactInputSpec - artifactSpec *model.ArtifactSpec - idInFilter bool - want []*model.Artifact - wantErr bool - }{{ - name: "sha256", - artifactInput: &model.ArtifactInputSpec{ - Algorithm: "sha256", - Digest: "6bbb0da1891646e58eb3e6a63af3a6fc3c8eb5a0d44824cba581d2e14a0450cf", - }, - artifactSpec: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha256"), - Digest: ptrfrom.String("6bbb0da1891646e58eb3e6a63af3a6fc3c8eb5a0d44824cba581d2e14a0450cf"), - }, - want: []*model.Artifact{{ - Algorithm: "sha256", - Digest: "6bbb0da1891646e58eb3e6a63af3a6fc3c8eb5a0d44824cba581d2e14a0450cf", - }}, - wantErr: false, - }, { - name: "sha1", - artifactInput: &model.ArtifactInputSpec{ - Algorithm: "sha1", - Digest: "7A8F47318E4676DACB0142AFA0B83029CD7BEFD9", - }, - artifactSpec: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha1"), - Digest: ptrfrom.String("7A8F47318E4676DACB0142AFA0B83029CD7BEFD9"), - }, - want: []*model.Artifact{{ - Algorithm: "sha1", - Digest: "7a8f47318e4676dacb0142afa0b83029cd7befd9", - }}, - wantErr: false, - }, { - name: "sha512", - artifactInput: &model.ArtifactInputSpec{ - Algorithm: "sha512", - Digest: "374AB8F711235830769AA5F0B31CE9B72C5670074B34CB302CDAFE3B606233EE92EE01E298E5701F15CC7087714CD9ABD7DDB838A6E1206B3642DE16D9FC9DD7", - }, - artifactSpec: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha512"), - Digest: ptrfrom.String("374AB8F711235830769AA5F0B31CE9B72C5670074B34CB302CDAFE3B606233EE92EE01E298E5701F15CC7087714CD9ABD7DDB838A6E1206B3642DE16D9FC9DD7"), - }, - idInFilter: true, - want: []*model.Artifact{{ - Algorithm: "sha512", - Digest: "374ab8f711235830769aa5f0b31ce9b72c5670074b34cb302cdafe3b606233ee92ee01e298e5701f15cc7087714cd9abd7ddb838a6e1206b3642de16d9fc9dd7", - }}, - wantErr: false, - }} - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - ingestedArtID, err := c.IngestArtifact(ctx, tt.artifactInput) - if (err != nil) != tt.wantErr { - t.Errorf("arangoClient.IngestArtifact() error = %v, wantErr %v", err, tt.wantErr) - return - } - if tt.idInFilter { - tt.artifactSpec.ID = ptrfrom.String(ingestedArtID) - } - got, err := c.Artifacts(ctx, tt.artifactSpec) - if (err != nil) != tt.wantErr { - t.Errorf("arangoClient.Artifacts() error = %v, wantErr %v", err, tt.wantErr) - return - } - slices.SortFunc(got, lessArtifact) - if diff := cmp.Diff(tt.want, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func Test_buildArtifactResponseByID(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - tests := []struct { - name string - artifactInput *model.ArtifactInputSpec - artifactSpec *model.ArtifactSpec - idInFilter bool - want *model.Artifact - wantErr bool - }{{ - name: "sha256", - artifactInput: &model.ArtifactInputSpec{ - Algorithm: "sha256", - Digest: "6bbb0da1891646e58eb3e6a63af3a6fc3c8eb5a0d44824cba581d2e14a0450cf", - }, - artifactSpec: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha256"), - Digest: ptrfrom.String("6bbb0da1891646e58eb3e6a63af3a6fc3c8eb5a0d44824cba581d2e14a0450cf"), - }, - want: &model.Artifact{ - Algorithm: "sha256", - Digest: "6bbb0da1891646e58eb3e6a63af3a6fc3c8eb5a0d44824cba581d2e14a0450cf", - }, - wantErr: false, - }, { - name: "sha1", - artifactInput: &model.ArtifactInputSpec{ - Algorithm: "sha1", - Digest: "7A8F47318E4676DACB0142AFA0B83029CD7BEFD9", - }, - artifactSpec: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha1"), - Digest: ptrfrom.String("7A8F47318E4676DACB0142AFA0B83029CD7BEFD9"), - }, - want: &model.Artifact{ - Algorithm: "sha1", - Digest: "7a8f47318e4676dacb0142afa0b83029cd7befd9", - }, - wantErr: false, - }, { - name: "sha512", - artifactInput: &model.ArtifactInputSpec{ - Algorithm: "sha512", - Digest: "374AB8F711235830769AA5F0B31CE9B72C5670074B34CB302CDAFE3B606233EE92EE01E298E5701F15CC7087714CD9ABD7DDB838A6E1206B3642DE16D9FC9DD7", - }, - artifactSpec: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha512"), - Digest: ptrfrom.String("374AB8F711235830769AA5F0B31CE9B72C5670074B34CB302CDAFE3B606233EE92EE01E298E5701F15CC7087714CD9ABD7DDB838A6E1206B3642DE16D9FC9DD7"), - }, - idInFilter: true, - want: &model.Artifact{ - Algorithm: "sha512", - Digest: "374ab8f711235830769aa5f0b31ce9b72c5670074b34cb302cdafe3b606233ee92ee01e298e5701f15cc7087714cd9abd7ddb838a6e1206b3642de16d9fc9dd7", - }, - wantErr: false, - }} - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - ingestedArtID, err := b.IngestArtifact(ctx, tt.artifactInput) - if (err != nil) != tt.wantErr { - t.Errorf("arangoClient.IngestArtifact() error = %v, wantErr %v", err, tt.wantErr) - return - } - if tt.idInFilter { - tt.artifactSpec.ID = ptrfrom.String(ingestedArtID) - } - got, err := b.(*arangoClient).buildArtifactResponseByID(ctx, ingestedArtID, tt.artifactSpec) - if (err != nil) != tt.wantErr { - t.Errorf("arangoClient.buildPackageResponseFromID() error = %v, wantErr %v", err, tt.wantErr) - return - } - if diff := cmp.Diff(tt.want, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} diff --git a/pkg/assembler/backends/arangodb/builder.go b/pkg/assembler/backends/arangodb/builder.go index 3885ed2f2d..aa3777819d 100644 --- a/pkg/assembler/backends/arangodb/builder.go +++ b/pkg/assembler/backends/arangodb/builder.go @@ -64,11 +64,11 @@ func getBuilderQueryValues(builder *model.BuilderInputSpec) map[string]any { return values } -func (c *arangoClient) IngestBuilders(ctx context.Context, builders []*model.BuilderInputSpec) ([]string, error) { +func (c *arangoClient) IngestBuilders(ctx context.Context, builders []*model.IDorBuilderInput) ([]string, error) { var listOfValues []map[string]any for i := range builders { - listOfValues = append(listOfValues, getBuilderQueryValues(builders[i])) + listOfValues = append(listOfValues, getBuilderQueryValues(builders[i].BuilderInput)) } var documents []string @@ -118,14 +118,14 @@ RETURN { "id": NEW._id }` return builderIDs, nil } -func (c *arangoClient) IngestBuilder(ctx context.Context, builder *model.BuilderInputSpec) (string, error) { +func (c *arangoClient) IngestBuilder(ctx context.Context, builder *model.IDorBuilderInput) (string, error) { query := ` UPSERT { uri:@uri } INSERT { uri:@uri } UPDATE {} IN builders OPTIONS { indexHint: "byUri" } RETURN { "id": NEW._id }` - cursor, err := executeQueryWithRetry(ctx, c.db, query, getBuilderQueryValues(builder), "IngestBuilder") + cursor, err := executeQueryWithRetry(ctx, c.db, query, getBuilderQueryValues(builder.BuilderInput), "IngestBuilder") if err != nil { return "", fmt.Errorf("failed to ingest builder: %w", err) } diff --git a/pkg/assembler/backends/arangodb/builder_test.go b/pkg/assembler/backends/arangodb/builder_test.go deleted file mode 100644 index ef4464aff0..0000000000 --- a/pkg/assembler/backends/arangodb/builder_test.go +++ /dev/null @@ -1,256 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build integration - -package arangodb - -import ( - "context" - "slices" - "strings" - "testing" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -func Test_IngestBuilder(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - c, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - tests := []struct { - name string - builderInput *model.BuilderInputSpec - wantID bool - wantErr bool - }{{ - name: "HubHostedActions", - builderInput: &model.BuilderInputSpec{ - URI: "https://github.com/CreateFork/HubHostedActions@v1", - }, - wantID: true, - wantErr: false, - }, { - name: "chains", - builderInput: &model.BuilderInputSpec{ - URI: "https://tekton.dev/chains/v2", - }, - wantID: true, - wantErr: false, - }} - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := c.IngestBuilder(ctx, tt.builderInput) - if (err != nil) != tt.wantErr { - t.Errorf("arangoClient.IngestBuilder() error = %v, wantErr %v", err, tt.wantErr) - return - } - if (got != "") != tt.wantID { - t.Errorf("Unexpected number of results") - return - } - }) - } -} - -func lessBuilder(a, b *model.Builder) int { - return strings.Compare(a.URI, b.URI) -} - -func Test_IngestBuilders(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - c, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - tests := []struct { - name string - builderInputs []*model.BuilderInputSpec - wantErr bool - }{{ - name: "HubHostedActions", - builderInputs: []*model.BuilderInputSpec{ - { - URI: "https://github.com/CreateFork/HubHostedActions@v1", - }, - { - URI: "https://tekton.dev/chains/v2", - }, - }, - wantErr: false, - }} - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := c.IngestBuilders(ctx, tt.builderInputs) - if (err != nil) != tt.wantErr { - t.Errorf("arangoClient.IngestBuilders() error = %v, wantErr %v", err, tt.wantErr) - return - } - if len(got) != len(tt.builderInputs) { - t.Errorf("Unexpected number of results. Wanted: %d, got %d", len(tt.builderInputs), len(got)) - } - }) - } -} - -func Test_Builders(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - tests := []struct { - name string - builderInput *model.BuilderInputSpec - builderSpec *model.BuilderSpec - idInFilter bool - want []*model.Builder - wantErr bool - }{{ - name: "HubHostedActions", - builderInput: &model.BuilderInputSpec{ - URI: "https://github.com/CreateFork/HubHostedActions@v1", - }, - builderSpec: &model.BuilderSpec{ - URI: ptrfrom.String("https://github.com/CreateFork/HubHostedActions@v1"), - }, - want: []*model.Builder{{ - URI: "https://github.com/CreateFork/HubHostedActions@v1", - }}, - wantErr: false, - }, { - name: "chains", - builderInput: &model.BuilderInputSpec{ - URI: "https://tekton.dev/chains/v2", - }, - builderSpec: &model.BuilderSpec{ - URI: ptrfrom.String("https://tekton.dev/chains/v2"), - }, - idInFilter: true, - want: []*model.Builder{{ - URI: "https://tekton.dev/chains/v2", - }}, - wantErr: false, - }, { - name: "query all", - builderInput: &model.BuilderInputSpec{ - URI: "https://tekton.dev/chains/v2", - }, - builderSpec: &model.BuilderSpec{}, - want: []*model.Builder{{ - URI: "https://github.com/CreateFork/HubHostedActions@v1", - }, { - URI: "https://tekton.dev/chains/v2", - }}, - wantErr: false, - }} - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - c, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - ingestedBuilderID, err := c.IngestBuilder(ctx, tt.builderInput) - if (err != nil) != tt.wantErr { - t.Errorf("arangoClient.IngestBuilder() error = %v, wantErr %v", err, tt.wantErr) - return - } - if tt.idInFilter { - tt.builderSpec.ID = ptrfrom.String(ingestedBuilderID) - } - got, err := c.Builders(ctx, tt.builderSpec) - if (err != nil) != tt.wantErr { - t.Errorf("demoClient.Builders() error = %v, wantErr %v", err, tt.wantErr) - return - } - slices.SortFunc(got, lessBuilder) - if diff := cmp.Diff(tt.want, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func Test_buildBuilderResponseByID(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - tests := []struct { - name string - builderInput *model.BuilderInputSpec - want *model.Builder - wantErr bool - }{{ - name: "HubHostedActions", - builderInput: &model.BuilderInputSpec{ - URI: "https://github.com/CreateFork/HubHostedActions@v1", - }, - want: &model.Builder{ - URI: "https://github.com/CreateFork/HubHostedActions@v1", - }, - wantErr: false, - }, { - name: "chains", - builderInput: &model.BuilderInputSpec{ - URI: "https://tekton.dev/chains/v2", - }, - want: &model.Builder{ - URI: "https://tekton.dev/chains/v2", - }, - wantErr: false, - }} - - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - ingestedBuilderID, err := b.IngestBuilder(ctx, tt.builderInput) - if (err != nil) != tt.wantErr { - t.Errorf("arangoClient.IngestBuilder() error = %v, wantErr %v", err, tt.wantErr) - return - } - got, err := b.(*arangoClient).buildBuilderResponseByID(ctx, ingestedBuilderID, nil) - if (err != nil) != tt.wantErr { - t.Errorf("arangoClient.buildPackageResponseFromID() error = %v, wantErr %v", err, tt.wantErr) - return - } - if diff := cmp.Diff(tt.want, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} diff --git a/pkg/assembler/backends/arangodb/certifyBad.go b/pkg/assembler/backends/arangodb/certifyBad.go index 1514e44982..f3a1a4bda1 100644 --- a/pkg/assembler/backends/arangodb/certifyBad.go +++ b/pkg/assembler/backends/arangodb/certifyBad.go @@ -341,7 +341,7 @@ func (c *arangoClient) IngestCertifyBad(ctx context.Context, subject model.Packa RETURN { 'certifyBad_id': certifyBad._id }` - cursor, err = executeQueryWithRetry(ctx, c.db, query, getCertifyBadQueryValues(subject.Package, pkgMatchType, nil, nil, &certifyBad), "IngestCertifyBad - PkgVersion") + cursor, err = executeQueryWithRetry(ctx, c.db, query, getCertifyBadQueryValues(subject.Package.PackageInput, pkgMatchType, nil, nil, &certifyBad), "IngestCertifyBad - PkgVersion") if err != nil { return "", fmt.Errorf("failed to ingest package certifyBad: %w", err) } @@ -373,7 +373,7 @@ func (c *arangoClient) IngestCertifyBad(ctx context.Context, subject model.Packa RETURN { 'certifyBad_id': certifyBad._id }` - cursor, err = executeQueryWithRetry(ctx, c.db, query, getCertifyBadQueryValues(subject.Package, pkgMatchType, nil, nil, &certifyBad), "IngestCertifyBad - PkgName") + cursor, err = executeQueryWithRetry(ctx, c.db, query, getCertifyBadQueryValues(subject.Package.PackageInput, pkgMatchType, nil, nil, &certifyBad), "IngestCertifyBad - PkgName") if err != nil { return "", fmt.Errorf("failed to ingest package certifyBad: %w", err) } @@ -398,7 +398,7 @@ func (c *arangoClient) IngestCertifyBad(ctx context.Context, subject model.Packa RETURN { 'certifyBad_id': certifyBad._id }` - cursor, err = executeQueryWithRetry(ctx, c.db, query, getCertifyBadQueryValues(nil, nil, subject.Artifact, nil, &certifyBad), "IngestCertifyBad - artifact") + cursor, err = executeQueryWithRetry(ctx, c.db, query, getCertifyBadQueryValues(nil, nil, subject.Artifact.ArtifactInput, nil, &certifyBad), "IngestCertifyBad - artifact") if err != nil { return "", fmt.Errorf("failed to ingest artifact certifyBad: %w", err) } @@ -430,7 +430,7 @@ func (c *arangoClient) IngestCertifyBad(ctx context.Context, subject model.Packa RETURN { 'certifyBad_id': certifyBad._id }` - cursor, err = executeQueryWithRetry(ctx, c.db, query, getCertifyBadQueryValues(nil, nil, nil, subject.Source, &certifyBad), "IngestCertifyBad - source") + cursor, err = executeQueryWithRetry(ctx, c.db, query, getCertifyBadQueryValues(nil, nil, nil, subject.Source.SourceInput, &certifyBad), "IngestCertifyBad - source") if err != nil { return "", fmt.Errorf("failed to ingest source certifyBad: %w", err) } @@ -457,7 +457,7 @@ func (c *arangoClient) IngestCertifyBads(ctx context.Context, subjects model.Pac var listOfValues []map[string]any for i := range subjects.Packages { - listOfValues = append(listOfValues, getCertifyBadQueryValues(subjects.Packages[i], pkgMatchType, nil, nil, certifyBads[i])) + listOfValues = append(listOfValues, getCertifyBadQueryValues(subjects.Packages[i].PackageInput, pkgMatchType, nil, nil, certifyBads[i])) } var documents []string @@ -557,7 +557,7 @@ func (c *arangoClient) IngestCertifyBads(ctx context.Context, subjects model.Pac var listOfValues []map[string]any for i := range subjects.Artifacts { - listOfValues = append(listOfValues, getCertifyBadQueryValues(nil, nil, subjects.Artifacts[i], nil, certifyBads[i])) + listOfValues = append(listOfValues, getCertifyBadQueryValues(nil, nil, subjects.Artifacts[i].ArtifactInput, nil, certifyBads[i])) } var documents []string @@ -611,7 +611,7 @@ func (c *arangoClient) IngestCertifyBads(ctx context.Context, subjects model.Pac var listOfValues []map[string]any for i := range subjects.Sources { - listOfValues = append(listOfValues, getCertifyBadQueryValues(nil, nil, nil, subjects.Sources[i], certifyBads[i])) + listOfValues = append(listOfValues, getCertifyBadQueryValues(nil, nil, nil, subjects.Sources[i].SourceInput, certifyBads[i])) } var documents []string diff --git a/pkg/assembler/backends/arangodb/certifyBad_test.go b/pkg/assembler/backends/arangodb/certifyBad_test.go deleted file mode 100644 index f40d290948..0000000000 --- a/pkg/assembler/backends/arangodb/certifyBad_test.go +++ /dev/null @@ -1,1238 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build integration - -package arangodb - -import ( - "context" - "strings" - "testing" - "time" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/internal/testing/testdata" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -func TestCertifyBad(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - curTime := time.Now() - timeAfterOneSecond := curTime.Add(time.Second) - type call struct { - Sub model.PackageSourceOrArtifactInput - Match *model.MatchFlags - CB *model.CertifyBadInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - InArt []*model.ArtifactInputSpec - Calls []call - Query *model.CertifyBadSpec - QueryID bool - QueryPkgID bool - QuerySourceID bool - QueryArtID bool - ExpCB []*model.CertifyBad - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{testdata.P1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyBadSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpCB: []*model.CertifyBad{ - { - Subject: testdata.P1out, - Justification: "test justification", - }, - }, - }, - { - Name: "HappyPath All Version", - InPkg: []*model.PkgInputSpec{testdata.P1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyBadSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpCB: []*model.CertifyBad{ - { - Subject: testdata.P1out, - Justification: "test justification", - }, - { - Subject: testdata.P1outName, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest same twice", - InPkg: []*model.PkgInputSpec{testdata.P1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyBadSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpCB: []*model.CertifyBad{ - { - Subject: testdata.P1out, - Justification: "test justification", - }, - { - Subject: testdata.P1outName, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Justification", - InPkg: []*model.PkgInputSpec{testdata.P1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification one", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification two", - }, - }, - }, - Query: &model.CertifyBadSpec{ - Justification: ptrfrom.String("test justification one"), - }, - ExpCB: []*model.CertifyBad{ - { - Subject: testdata.P1out, - Justification: "test justification one", - }, - }, - }, - { - Name: "Query on KnownSince", - InPkg: []*model.PkgInputSpec{testdata.P1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification one", - KnownSince: curTime, - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification two", - KnownSince: timeAfterOneSecond, - }, - }, - }, - Query: &model.CertifyBadSpec{ - Justification: ptrfrom.String("test justification one"), - KnownSince: ptrfrom.Time(curTime), - }, - ExpCB: []*model.CertifyBad{ - { - Subject: testdata.P1out, - Justification: "test justification one", - KnownSince: curTime, - }, - }, - }, - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{testdata.P4}, - InSrc: []*model.SourceInputSpec{testdata.S1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P4, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P4, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyBadSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Package: &model.PkgSpec{ - Type: ptrfrom.String("conan"), - Namespace: ptrfrom.String("openssl.org"), - Name: ptrfrom.String("openssl"), - Version: ptrfrom.String("3.0.3"), - }, - }, - }, - ExpCB: []*model.CertifyBad{ - { - Subject: testdata.P4out, - Justification: "test justification", - }, - { - Subject: testdata.P4outName, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Package version ID", - InPkg: []*model.PkgInputSpec{testdata.P4}, - InSrc: []*model.SourceInputSpec{}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P4, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - }, - QueryPkgID: true, - ExpCB: []*model.CertifyBad{ - { - Subject: testdata.P4out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Source", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InSrc: []*model.SourceInputSpec{testdata.S1, testdata.S2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S2, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyBadSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Source: &model.SourceSpec{ - Name: ptrfrom.String("bobsrepo"), - }, - }, - }, - ExpCB: []*model.CertifyBad{ - { - Subject: testdata.S2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Source ID", - InPkg: []*model.PkgInputSpec{}, - InSrc: []*model.SourceInputSpec{testdata.S2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S2, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - }, - QuerySourceID: true, - ExpCB: []*model.CertifyBad{ - { - Subject: testdata.S2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Artifact", - InSrc: []*model.SourceInputSpec{testdata.S1}, - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A1, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyBadSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha1"), - }, - }, - }, - ExpCB: []*model.CertifyBad{ - { - Subject: testdata.A2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Artifact ID", - InSrc: []*model.SourceInputSpec{}, - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A1, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - }, - QueryArtID: true, - ExpCB: []*model.CertifyBad{ - { - Subject: testdata.A2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query none", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A1, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyBadSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("asdf"), - }, - }, - }, - ExpCB: nil, - }, - { - Name: "Query multiple", - InSrc: []*model.SourceInputSpec{testdata.S1, testdata.S2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S2, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyBadSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Source: &model.SourceSpec{ - Type: ptrfrom.String("git"), - }, - }, - }, - ExpCB: []*model.CertifyBad{ - { - Subject: testdata.S2out, - Justification: "test justification", - }, - { - Subject: testdata.S1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query Packages", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyBadSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Package: &model.PkgSpec{ - Type: ptrfrom.String("pypi"), - Version: ptrfrom.String("2.11.1"), - }, - }, - }, - ExpCB: []*model.CertifyBad{ - { - Subject: testdata.P2out, - Justification: "test justification", - }, - { - Subject: testdata.P1outName, - Justification: "test justification", - }, - }, - }, - { - Name: "Query ID", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A1, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - }, - QueryID: true, - ExpCB: []*model.CertifyBad{ - { - Subject: testdata.A2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query bad ID", - InSrc: []*model.SourceInputSpec{testdata.S1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyBadSpec{ - ID: ptrfrom.String("asdf"), - }, - ExpQueryErr: true, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - for _, p := range test.InPkg { - if pkgIDs, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } else { - if test.QueryPkgID { - test.Query = &model.CertifyBadSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Package: &model.PkgSpec{ - ID: ptrfrom.String(pkgIDs.PackageVersionID), - }, - }, - } - } - } - } - for _, s := range test.InSrc { - if srcIDs, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } else { - if test.QuerySourceID { - test.Query = &model.CertifyBadSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Source: &model.SourceSpec{ - ID: ptrfrom.String(srcIDs.SourceNameID), - }, - }, - } - } - } - } - for _, a := range test.InArt { - if artID, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } else { - if test.QueryArtID { - test.Query = &model.CertifyBadSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - ID: ptrfrom.String(artID), - }, - }, - } - } - } - } - for _, o := range test.Calls { - cbID, err := b.IngestCertifyBad(ctx, o.Sub, o.Match, *o.CB) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - if test.QueryID { - test.Query = &model.CertifyBadSpec{ - ID: ptrfrom.String(cbID), - } - } - } - got, err := b.CertifyBad(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpCB, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func TestIngestCertifyBads(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - type call struct { - Sub model.PackageSourceOrArtifactInputs - Match *model.MatchFlags - CB []*model.CertifyBadInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - InArt []*model.ArtifactInputSpec - Calls []call - Query *model.CertifyBadSpec - ExpCB []*model.CertifyBad - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{testdata.P1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: []*model.CertifyBadInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.CertifyBadSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpCB: []*model.CertifyBad{ - { - Subject: testdata.P1out, - Justification: "test justification", - }, - }, - }, - { - Name: "HappyPath All Version", - InPkg: []*model.PkgInputSpec{testdata.P1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - CB: []*model.CertifyBadInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.CertifyBadSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpCB: []*model.CertifyBad{ - { - Subject: testdata.P1out, - Justification: "test justification", - }, - { - Subject: testdata.P1outName, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest same twice", - InPkg: []*model.PkgInputSpec{testdata.P1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1, testdata.P1}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: []*model.CertifyBadInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.CertifyBadSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpCB: []*model.CertifyBad{ - { - Subject: testdata.P1out, - Justification: "test justification", - }, - { - Subject: testdata.P1outName, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - InSrc: []*model.SourceInputSpec{testdata.S1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: []*model.CertifyBadInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - { - Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{testdata.S1}, - }, - CB: []*model.CertifyBadInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.CertifyBadSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String("2.11.1"), - }, - }, - }, - ExpCB: []*model.CertifyBad{ - { - Subject: testdata.P2out, - Justification: "test justification", - }, - { - Subject: testdata.P1outName, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Source", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InSrc: []*model.SourceInputSpec{testdata.S1, testdata.S2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: []*model.CertifyBadInputSpec{ - { - Justification: "test justification", - }, - }, - }, - { - Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{testdata.S2, testdata.S2}, - }, - CB: []*model.CertifyBadInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.CertifyBadSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Source: &model.SourceSpec{ - Name: ptrfrom.String("bobsrepo"), - }, - }, - }, - ExpCB: []*model.CertifyBad{ - { - Subject: testdata.S2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Artifact", - InSrc: []*model.SourceInputSpec{testdata.S1}, - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Artifacts: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - }, - CB: []*model.CertifyBadInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - { - Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{testdata.S1}, - }, - CB: []*model.CertifyBadInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.CertifyBadSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha1"), - }, - }, - }, - ExpCB: []*model.CertifyBad{ - { - Subject: testdata.A2out, - Justification: "test justification", - }, - }, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - for _, o := range test.Calls { - _, err := b.IngestCertifyBads(ctx, o.Sub, o.Match, o.CB) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.CertifyBad(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpCB, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func Test_buildCertifyBadByID(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - type call struct { - Sub model.PackageSourceOrArtifactInput - Match *model.MatchFlags - CB *model.CertifyBadInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - InArt []*model.ArtifactInputSpec - Call call - Query *model.CertifyBadSpec - ExpCB *model.CertifyBad - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{testdata.P1}, - Call: call{ - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - - Query: &model.CertifyBadSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpCB: &model.CertifyBad{ - Subject: testdata.P1out, - Justification: "test justification", - }, - }, - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{testdata.P4}, - Call: call{ - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P4, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - Query: &model.CertifyBadSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Package: &model.PkgSpec{ - Type: ptrfrom.String("conan"), - Namespace: ptrfrom.String("openssl.org"), - Name: ptrfrom.String("openssl"), - Version: ptrfrom.String("3.0.3"), - }, - }, - }, - ExpCB: &model.CertifyBad{ - Subject: testdata.P4out, - Justification: "test justification", - }, - }, - { - Name: "Query on Source", - InSrc: []*model.SourceInputSpec{testdata.S2}, - Call: call{ - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S2, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - Query: &model.CertifyBadSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Source: &model.SourceSpec{ - Name: ptrfrom.String("bobsrepo"), - }, - }, - }, - ExpCB: &model.CertifyBad{ - Subject: testdata.S2out, - Justification: "test justification", - }, - }, - { - Name: "Query on Artifact", - InArt: []*model.ArtifactInputSpec{testdata.A2}, - Call: call{ - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - Query: &model.CertifyBadSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha1"), - }, - }, - }, - ExpCB: &model.CertifyBad{ - Subject: testdata.A2out, - Justification: "test justification", - }, - }, - { - Name: "Query on Source - no filter", - InSrc: []*model.SourceInputSpec{testdata.S3}, - Call: call{ - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S3, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - Query: &model.CertifyBadSpec{}, - ExpCB: &model.CertifyBad{ - Subject: testdata.S3out, - Justification: "test justification", - }, - }, - { - Name: "Query on Artifact - no filter", - InArt: []*model.ArtifactInputSpec{testdata.A3}, - Call: call{ - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A3, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - Query: &model.CertifyBadSpec{}, - ExpCB: &model.CertifyBad{ - Subject: testdata.A3out, - Justification: "test justification", - }, - }, - { - Name: "Query bad ID", - InSrc: []*model.SourceInputSpec{testdata.S1}, - Call: call{ - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - Query: &model.CertifyBadSpec{ - ID: ptrfrom.String("asdf"), - }, - ExpQueryErr: true, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - cbID, err := b.IngestCertifyBad(ctx, test.Call.Sub, test.Call.Match, *test.Call.CB) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - - got, err := b.(*arangoClient).buildCertifyBadByID(ctx, cbID, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpCB, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} diff --git a/pkg/assembler/backends/arangodb/certifyGood.go b/pkg/assembler/backends/arangodb/certifyGood.go index de09242dee..45208a71fc 100644 --- a/pkg/assembler/backends/arangodb/certifyGood.go +++ b/pkg/assembler/backends/arangodb/certifyGood.go @@ -342,7 +342,7 @@ func (c *arangoClient) IngestCertifyGood(ctx context.Context, subject model.Pack RETURN { 'certifyGood_id': certifyGood._id }` - cursor, err = executeQueryWithRetry(ctx, c.db, query, getCertifyGoodQueryValues(subject.Package, pkgMatchType, nil, nil, &certifyGood), "IngestCertifyGood - PkgVersion") + cursor, err = executeQueryWithRetry(ctx, c.db, query, getCertifyGoodQueryValues(subject.Package.PackageInput, pkgMatchType, nil, nil, &certifyGood), "IngestCertifyGood - PkgVersion") if err != nil { return "", fmt.Errorf("failed to ingest package certifyGood: %w", err) } @@ -374,7 +374,7 @@ func (c *arangoClient) IngestCertifyGood(ctx context.Context, subject model.Pack RETURN { 'certifyGood_id': certifyGood._id }` - cursor, err = executeQueryWithRetry(ctx, c.db, query, getCertifyGoodQueryValues(subject.Package, pkgMatchType, nil, nil, &certifyGood), "IngestCertifyGood - PkgName") + cursor, err = executeQueryWithRetry(ctx, c.db, query, getCertifyGoodQueryValues(subject.Package.PackageInput, pkgMatchType, nil, nil, &certifyGood), "IngestCertifyGood - PkgName") if err != nil { return "", fmt.Errorf("failed to ingest package certifyGood: %w", err) } @@ -400,7 +400,7 @@ func (c *arangoClient) IngestCertifyGood(ctx context.Context, subject model.Pack RETURN { 'certifyGood_id': certifyGood._id }` - cursor, err = executeQueryWithRetry(ctx, c.db, query, getCertifyGoodQueryValues(nil, nil, subject.Artifact, nil, &certifyGood), "IngestCertifyGood - artifact") + cursor, err = executeQueryWithRetry(ctx, c.db, query, getCertifyGoodQueryValues(nil, nil, subject.Artifact.ArtifactInput, nil, &certifyGood), "IngestCertifyGood - artifact") if err != nil { return "", fmt.Errorf("failed to ingest artifact certifyGood: %w", err) } @@ -432,7 +432,7 @@ func (c *arangoClient) IngestCertifyGood(ctx context.Context, subject model.Pack RETURN { 'certifyGood_id': certifyGood._id }` - cursor, err = executeQueryWithRetry(ctx, c.db, query, getCertifyGoodQueryValues(nil, nil, nil, subject.Source, &certifyGood), "IngestCertifyGood - source") + cursor, err = executeQueryWithRetry(ctx, c.db, query, getCertifyGoodQueryValues(nil, nil, nil, subject.Source.SourceInput, &certifyGood), "IngestCertifyGood - source") if err != nil { return "", fmt.Errorf("failed to ingest source certifyGood: %w", err) } @@ -464,7 +464,7 @@ func (c *arangoClient) IngestCertifyGoods(ctx context.Context, subjects model.Pa var listOfValues []map[string]any for i := range subjects.Packages { - listOfValues = append(listOfValues, getCertifyGoodQueryValues(subjects.Packages[i], pkgMatchType, nil, nil, certifyGoods[i])) + listOfValues = append(listOfValues, getCertifyGoodQueryValues(subjects.Packages[i].PackageInput, pkgMatchType, nil, nil, certifyGoods[i])) } var documents []string @@ -567,7 +567,7 @@ func (c *arangoClient) IngestCertifyGoods(ctx context.Context, subjects model.Pa var listOfValues []map[string]any for i := range subjects.Artifacts { - listOfValues = append(listOfValues, getCertifyGoodQueryValues(nil, nil, subjects.Artifacts[i], nil, certifyGoods[i])) + listOfValues = append(listOfValues, getCertifyGoodQueryValues(nil, nil, subjects.Artifacts[i].ArtifactInput, nil, certifyGoods[i])) } var documents []string @@ -626,7 +626,7 @@ func (c *arangoClient) IngestCertifyGoods(ctx context.Context, subjects model.Pa var listOfValues []map[string]any for i := range subjects.Sources { - listOfValues = append(listOfValues, getCertifyGoodQueryValues(nil, nil, nil, subjects.Sources[i], certifyGoods[i])) + listOfValues = append(listOfValues, getCertifyGoodQueryValues(nil, nil, nil, subjects.Sources[i].SourceInput, certifyGoods[i])) } var documents []string diff --git a/pkg/assembler/backends/arangodb/certifyGood_test.go b/pkg/assembler/backends/arangodb/certifyGood_test.go deleted file mode 100644 index 8c7560582a..0000000000 --- a/pkg/assembler/backends/arangodb/certifyGood_test.go +++ /dev/null @@ -1,1235 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build integration - -package arangodb - -import ( - "context" - "strings" - "testing" - "time" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/internal/testing/testdata" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -func TestCertifyGood(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - curTime := time.Now() - timeAfterOneSecond := curTime.Add(time.Second) - type call struct { - Sub model.PackageSourceOrArtifactInput - Match *model.MatchFlags - CG *model.CertifyGoodInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - InArt []*model.ArtifactInputSpec - Calls []call - Query *model.CertifyGoodSpec - QueryID bool - QueryPkgID bool - QuerySourceID bool - QueryArtID bool - ExpCG []*model.CertifyGood - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{testdata.P1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyGoodSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpCG: []*model.CertifyGood{ - { - Subject: testdata.P1out, - Justification: "test justification", - }, - }, - }, - { - Name: "HappyPath All Version", - InPkg: []*model.PkgInputSpec{testdata.P1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyGoodSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpCG: []*model.CertifyGood{ - { - Subject: testdata.P1out, - Justification: "test justification", - }, - { - Subject: testdata.P1outName, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest same twice", - InPkg: []*model.PkgInputSpec{testdata.P1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyGoodSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpCG: []*model.CertifyGood{ - { - Subject: testdata.P1out, - Justification: "test justification", - }, - { - Subject: testdata.P1outName, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Justification", - InPkg: []*model.PkgInputSpec{testdata.P1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification one", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification two", - }, - }, - }, - Query: &model.CertifyGoodSpec{ - Justification: ptrfrom.String("test justification one"), - }, - ExpCG: []*model.CertifyGood{ - { - Subject: testdata.P1out, - Justification: "test justification one", - }, - }, - }, - { - Name: "Query on KnownSince", - InPkg: []*model.PkgInputSpec{testdata.P1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification one", - KnownSince: curTime, - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification two", - KnownSince: timeAfterOneSecond, - }, - }, - }, - Query: &model.CertifyGoodSpec{ - Justification: ptrfrom.String("test justification one"), - KnownSince: ptrfrom.Time(curTime), - }, - ExpCG: []*model.CertifyGood{ - { - Subject: testdata.P1out, - Justification: "test justification one", - KnownSince: curTime, - }, - }, - }, - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - InSrc: []*model.SourceInputSpec{testdata.S1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyGoodSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String("2.11.1"), - }, - }, - }, - ExpCG: []*model.CertifyGood{ - { - Subject: testdata.P2out, - Justification: "test justification", - }, - { - Subject: testdata.P2outName, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Package version ID", - InPkg: []*model.PkgInputSpec{testdata.P4}, - InSrc: []*model.SourceInputSpec{}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P4, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - }, - QueryPkgID: true, - ExpCG: []*model.CertifyGood{ - { - Subject: testdata.P4out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Source", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InSrc: []*model.SourceInputSpec{testdata.S1, testdata.S2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S2, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyGoodSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Source: &model.SourceSpec{ - Name: ptrfrom.String("bobsrepo"), - }, - }, - }, - ExpCG: []*model.CertifyGood{ - { - Subject: testdata.S2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Source ID", - InPkg: []*model.PkgInputSpec{}, - InSrc: []*model.SourceInputSpec{testdata.S2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S2, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - }, - QuerySourceID: true, - ExpCG: []*model.CertifyGood{ - { - Subject: testdata.S2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Artifact", - InSrc: []*model.SourceInputSpec{testdata.S1}, - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A1, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyGoodSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha1"), - }, - }, - }, - ExpCG: []*model.CertifyGood{ - { - Subject: testdata.A2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Artifact ID", - InSrc: []*model.SourceInputSpec{}, - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A1, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - }, - QueryArtID: true, - ExpCG: []*model.CertifyGood{ - { - Subject: testdata.A2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query none", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A1, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyGoodSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("asdf"), - }, - }, - }, - ExpCG: nil, - }, - { - Name: "Query multiple", - InSrc: []*model.SourceInputSpec{testdata.S1, testdata.S2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S2, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyGoodSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Source: &model.SourceSpec{ - Type: ptrfrom.String("git"), - }, - }, - }, - ExpCG: []*model.CertifyGood{ - { - Subject: testdata.S2out, - Justification: "test justification", - }, - { - Subject: testdata.S1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query Packages", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyGoodSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Package: &model.PkgSpec{ - Type: ptrfrom.String("pypi"), - Version: ptrfrom.String("2.11.1"), - }, - }, - }, - ExpCG: []*model.CertifyGood{ - { - Subject: testdata.P2out, - Justification: "test justification", - }, - { - Subject: testdata.P2outName, - Justification: "test justification", - }, - }, - }, - { - Name: "Query ID", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A1, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - }, - QueryID: true, - ExpCG: []*model.CertifyGood{ - { - Subject: testdata.A2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query bad ID", - InSrc: []*model.SourceInputSpec{testdata.S1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyGoodSpec{ - ID: ptrfrom.String("asdf"), - }, - ExpQueryErr: true, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - for _, p := range test.InPkg { - if pkgIDs, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } else { - if test.QueryPkgID { - test.Query = &model.CertifyGoodSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Package: &model.PkgSpec{ - ID: ptrfrom.String(pkgIDs.PackageVersionID), - }, - }, - } - } - } - } - for _, s := range test.InSrc { - if srcIDs, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } else { - if test.QuerySourceID { - test.Query = &model.CertifyGoodSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Source: &model.SourceSpec{ - ID: ptrfrom.String(srcIDs.SourceNameID), - }, - }, - } - } - } - } - for _, a := range test.InArt { - if artID, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } else { - if test.QueryArtID { - test.Query = &model.CertifyGoodSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - ID: ptrfrom.String(artID), - }, - }, - } - } - } - } - for _, o := range test.Calls { - cgID, err := b.IngestCertifyGood(ctx, o.Sub, o.Match, *o.CG) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - if test.QueryID { - test.Query = &model.CertifyGoodSpec{ - ID: ptrfrom.String(cgID), - } - } - } - got, err := b.CertifyGood(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpCG, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func TestIngestCertifyGoods(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - type call struct { - Sub model.PackageSourceOrArtifactInputs - Match *model.MatchFlags - CG []*model.CertifyGoodInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - InArt []*model.ArtifactInputSpec - Calls []call - Query *model.CertifyGoodSpec - ExpCG []*model.CertifyGood - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{testdata.P1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: []*model.CertifyGoodInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.CertifyGoodSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpCG: []*model.CertifyGood{ - { - Subject: testdata.P1out, - Justification: "test justification", - }, - }, - }, - { - Name: "HappyPath All Version", - InPkg: []*model.PkgInputSpec{testdata.P1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - CG: []*model.CertifyGoodInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.CertifyGoodSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpCG: []*model.CertifyGood{ - { - Subject: testdata.P1out, - Justification: "test justification", - }, - { - Subject: testdata.P1outName, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest same twice", - InPkg: []*model.PkgInputSpec{testdata.P1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1, testdata.P1}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: []*model.CertifyGoodInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.CertifyGoodSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpCG: []*model.CertifyGood{ - { - Subject: testdata.P1out, - Justification: "test justification", - }, - { - Subject: testdata.P1outName, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - InSrc: []*model.SourceInputSpec{testdata.S1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: []*model.CertifyGoodInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - { - Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{testdata.S1}, - }, - CG: []*model.CertifyGoodInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.CertifyGoodSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String("2.11.1"), - }, - }, - }, - ExpCG: []*model.CertifyGood{ - { - Subject: testdata.P2out, - Justification: "test justification", - }, - { - Subject: testdata.P2outName, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Source", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InSrc: []*model.SourceInputSpec{testdata.S1, testdata.S2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: []*model.CertifyGoodInputSpec{ - { - Justification: "test justification", - }, - }, - }, - { - Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{testdata.S2, testdata.S2}, - }, - CG: []*model.CertifyGoodInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.CertifyGoodSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Source: &model.SourceSpec{ - Name: ptrfrom.String("bobsrepo"), - }, - }, - }, - ExpCG: []*model.CertifyGood{ - { - Subject: testdata.S2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Artifact", - InSrc: []*model.SourceInputSpec{testdata.S1}, - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Artifacts: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - }, - CG: []*model.CertifyGoodInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - { - Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{testdata.S1}, - }, - CG: []*model.CertifyGoodInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.CertifyGoodSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha1"), - }, - }, - }, - ExpCG: []*model.CertifyGood{ - { - Subject: testdata.A2out, - Justification: "test justification", - }, - }, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - for _, o := range test.Calls { - _, err := b.IngestCertifyGoods(ctx, o.Sub, o.Match, o.CG) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.CertifyGood(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpCG, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func Test_buildCertifyGoodByID(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - type call struct { - Sub model.PackageSourceOrArtifactInput - Match *model.MatchFlags - CG *model.CertifyGoodInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - InArt []*model.ArtifactInputSpec - Call call - Query *model.CertifyGoodSpec - ExpCG *model.CertifyGood - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{testdata.P1}, - Call: call{ - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - - Query: &model.CertifyGoodSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpCG: &model.CertifyGood{ - Subject: testdata.P1out, - Justification: "test justification", - }, - }, - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{testdata.P4}, - Call: call{ - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P4, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - Query: &model.CertifyGoodSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Package: &model.PkgSpec{ - Type: ptrfrom.String("conan"), - Namespace: ptrfrom.String("openssl.org"), - Name: ptrfrom.String("openssl"), - Version: ptrfrom.String("3.0.3"), - }, - }, - }, - ExpCG: &model.CertifyGood{ - Subject: testdata.P4out, - Justification: "test justification", - }, - }, - { - Name: "Query on Source", - InSrc: []*model.SourceInputSpec{testdata.S2}, - Call: call{ - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S2, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - Query: &model.CertifyGoodSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Source: &model.SourceSpec{ - Name: ptrfrom.String("bobsrepo"), - }, - }, - }, - ExpCG: &model.CertifyGood{ - Subject: testdata.S2out, - Justification: "test justification", - }, - }, - { - Name: "Query on Artifact", - InArt: []*model.ArtifactInputSpec{testdata.A2}, - Call: call{ - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - Query: &model.CertifyGoodSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha1"), - }, - }, - }, - ExpCG: &model.CertifyGood{ - Subject: testdata.A2out, - Justification: "test justification", - }, - }, - { - Name: "Query on Source - no filter", - InSrc: []*model.SourceInputSpec{testdata.S3}, - Call: call{ - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S3, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - Query: &model.CertifyGoodSpec{}, - ExpCG: &model.CertifyGood{ - Subject: testdata.S3out, - Justification: "test justification", - }, - }, - { - Name: "Query on Artifact - no filter", - InArt: []*model.ArtifactInputSpec{testdata.A3}, - Call: call{ - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A3, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - Query: &model.CertifyGoodSpec{}, - ExpCG: &model.CertifyGood{ - Subject: testdata.A3out, - Justification: "test justification", - }, - }, - { - Name: "Query bad ID", - InSrc: []*model.SourceInputSpec{testdata.S1}, - Call: call{ - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - Query: &model.CertifyGoodSpec{ - ID: ptrfrom.String("asdf"), - }, - ExpQueryErr: true, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - cgID, err := b.IngestCertifyGood(ctx, test.Call.Sub, test.Call.Match, *test.Call.CG) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - - got, err := b.(*arangoClient).buildCertifyGoodByID(ctx, cgID, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpCG, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} diff --git a/pkg/assembler/backends/arangodb/certifyLegal.go b/pkg/assembler/backends/arangodb/certifyLegal.go index c127c13a51..a81be0e986 100644 --- a/pkg/assembler/backends/arangodb/certifyLegal.go +++ b/pkg/assembler/backends/arangodb/certifyLegal.go @@ -262,8 +262,8 @@ func getCertifyLegalQueryValues(pkg *model.PkgInputSpec, source *model.SourceInp func (c *arangoClient) IngestCertifyLegal( ctx context.Context, subject model.PackageOrSourceInput, - declaredLicenses []*model.LicenseInputSpec, - discoveredLicenses []*model.LicenseInputSpec, + declaredLicenses []*model.IDorLicenseInput, + discoveredLicenses []*model.IDorLicenseInput, certifyLegal *model.CertifyLegalInputSpec) (string, error) { dec, err := c.getLicenses(ctx, declaredLicenses) @@ -333,7 +333,7 @@ LET discoveredLicensesCollection = (FOR disData IN @discoveredLicensesKeyList RETURN { 'certifyLegal_id': certifyLegal._id }` - cursor, err := executeQueryWithRetry(ctx, c.db, query, getCertifyLegalQueryValues(subject.Package, nil, dec, dis, certifyLegal), "IngestCertifyLegal - Pkg") + cursor, err := executeQueryWithRetry(ctx, c.db, query, getCertifyLegalQueryValues(subject.Package.PackageInput, nil, dec, dis, certifyLegal), "IngestCertifyLegal - Pkg") if err != nil { return "", fmt.Errorf("failed to ingest package certifyLegal: %w", err) } @@ -407,7 +407,7 @@ LET discoveredLicensesCollection = (FOR disData IN @discoveredLicensesKeyList RETURN { 'certifyLegal_id': certifyLegal._id }` - cursor, err := executeQueryWithRetry(ctx, c.db, query, getCertifyLegalQueryValues(nil, subject.Source, dec, dis, certifyLegal), "IngestCertifyLegal - source") + cursor, err := executeQueryWithRetry(ctx, c.db, query, getCertifyLegalQueryValues(nil, subject.Source.SourceInput, dec, dis, certifyLegal), "IngestCertifyLegal - source") if err != nil { return "", fmt.Errorf("failed to ingest source certifyLegal: %w", err) } @@ -429,8 +429,8 @@ RETURN { 'certifyLegal_id': certifyLegal._id }` func (c *arangoClient) IngestCertifyLegals( ctx context.Context, subjects model.PackageOrSourceInputs, - declaredLicensesList [][]*model.LicenseInputSpec, - discoveredLicensesList [][]*model.LicenseInputSpec, + declaredLicensesList [][]*model.IDorLicenseInput, + discoveredLicensesList [][]*model.IDorLicenseInput, certifyLegals []*model.CertifyLegalInputSpec) ([]string, error) { if len(subjects.Packages) > 0 { @@ -447,7 +447,7 @@ func (c *arangoClient) IngestCertifyLegals( return nil, fmt.Errorf("failed to get discovered licenses list with error: %w", err) } - listOfValues = append(listOfValues, getCertifyLegalQueryValues(subjects.Packages[i], nil, dec, dis, certifyLegals[i])) + listOfValues = append(listOfValues, getCertifyLegalQueryValues(subjects.Packages[i].PackageInput, nil, dec, dis, certifyLegals[i])) } var documents []string @@ -562,7 +562,7 @@ RETURN { 'certifyLegal_id': certifyLegal._id }` return nil, fmt.Errorf("failed to get discovered licenses list with error: %w", err) } - listOfValues = append(listOfValues, getCertifyLegalQueryValues(nil, subjects.Sources[i], dec, dis, certifyLegals[i])) + listOfValues = append(listOfValues, getCertifyLegalQueryValues(nil, subjects.Sources[i].SourceInput, dec, dis, certifyLegals[i])) } var documents []string diff --git a/pkg/assembler/backends/arangodb/certifyLegal_test.go b/pkg/assembler/backends/arangodb/certifyLegal_test.go deleted file mode 100644 index be7be2adaf..0000000000 --- a/pkg/assembler/backends/arangodb/certifyLegal_test.go +++ /dev/null @@ -1,890 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build integration - -package arangodb - -import ( - "context" - "strings" - "testing" - - "github.com/google/go-cmp/cmp" - - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/internal/testing/testdata" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -// var pNone = &model.PkgInputSpec{ -// Type: "none", -// Name: "none", -// } - -// var sNone = &model.SourceInputSpec{ -// Type: "none", -// Namespace: "github.com/nope", -// Name: "none", -// } - -// var lNone = &model.LicenseInputSpec{ -// Name: "LIC_NONE", -// ListVersion: ptrfrom.String("1.2.3"), -// } - -func TestLegal(t *testing.T) { - type call struct { - PkgSrc model.PackageOrSourceInput - Dec []*model.LicenseInputSpec - Dis []*model.LicenseInputSpec - Legal *model.CertifyLegalInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - InLic []*model.LicenseInputSpec - Calls []call - IDInFilter int - Query *model.CertifyLegalSpec - ExpLegal []*model.CertifyLegal - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InLic: []*model.LicenseInputSpec{testdata.L1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Dec: []*model.LicenseInputSpec{testdata.L1}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyLegalSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpLegal: []*model.CertifyLegal{ - { - Subject: testdata.P1out, - DeclaredLicenses: []*model.License{testdata.L1out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest same twice", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InLic: []*model.LicenseInputSpec{testdata.L1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Dec: []*model.LicenseInputSpec{testdata.L1}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Dec: []*model.LicenseInputSpec{testdata.L1}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyLegalSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpLegal: []*model.CertifyLegal{ - { - Subject: testdata.P1out, - DeclaredLicenses: []*model.License{testdata.L1out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Justification", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InLic: []*model.LicenseInputSpec{testdata.L1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Dec: []*model.LicenseInputSpec{testdata.L1}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Dec: []*model.LicenseInputSpec{testdata.L1}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification 2", - }, - }, - }, - Query: &model.CertifyLegalSpec{ - Justification: ptrfrom.String("test justification 2"), - }, - ExpLegal: []*model.CertifyLegal{ - { - Subject: testdata.P1out, - DeclaredLicenses: []*model.License{testdata.L1out}, - Justification: "test justification 2", - }, - }, - }, - { - Name: "Query on ID", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InLic: []*model.LicenseInputSpec{testdata.L1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Dec: []*model.LicenseInputSpec{testdata.L1}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Dec: []*model.LicenseInputSpec{testdata.L1}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification 2", - }, - }, - }, - IDInFilter: 2, - Query: &model.CertifyLegalSpec{}, - ExpLegal: []*model.CertifyLegal{ - { - Subject: testdata.P1out, - DeclaredLicenses: []*model.License{testdata.L1out}, - Justification: "test justification 2", - }, - }, - }, - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - InLic: []*model.LicenseInputSpec{testdata.L1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Dec: []*model.LicenseInputSpec{testdata.L1}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P2, - }, - Dec: []*model.LicenseInputSpec{testdata.L1}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyLegalSpec{ - Subject: &model.PackageOrSourceSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String("2.11.1"), - }, - }, - }, - ExpLegal: []*model.CertifyLegal{ - { - Subject: testdata.P2out, - DeclaredLicenses: []*model.License{testdata.L1out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Source", - InSrc: []*model.SourceInputSpec{testdata.S1, testdata.S2}, - InLic: []*model.LicenseInputSpec{testdata.L1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Source: testdata.S1, - }, - Dec: []*model.LicenseInputSpec{testdata.L1}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Source: testdata.S2, - }, - Dec: []*model.LicenseInputSpec{testdata.L1}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyLegalSpec{ - Subject: &model.PackageOrSourceSpec{ - Source: &model.SourceSpec{ - Name: ptrfrom.String("myrepo"), - }, - }, - }, - ExpLegal: []*model.CertifyLegal{ - { - Subject: testdata.S1out, - DeclaredLicenses: []*model.License{testdata.L1out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on License", - InSrc: []*model.SourceInputSpec{testdata.S1}, - InLic: []*model.LicenseInputSpec{testdata.L1, testdata.L2, testdata.L3}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Source: testdata.S1, - }, - Dec: []*model.LicenseInputSpec{testdata.L1, testdata.L2}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Source: testdata.S1, - }, - Dec: []*model.LicenseInputSpec{testdata.L3}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyLegalSpec{ - DeclaredLicenses: []*model.LicenseSpec{ - {Name: ptrfrom.String("GPL-2.0-or-later")}, - }, - }, - ExpLegal: []*model.CertifyLegal{ - { - Subject: testdata.S1out, - DeclaredLicenses: []*model.License{testdata.L1out, testdata.L2out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on License inline", - InSrc: []*model.SourceInputSpec{testdata.S1}, - InLic: []*model.LicenseInputSpec{testdata.L1, testdata.L2, testdata.L4}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Source: testdata.S1, - }, - Dec: []*model.LicenseInputSpec{testdata.L1, testdata.L4}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Source: testdata.S1, - }, - Dec: []*model.LicenseInputSpec{testdata.L2}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyLegalSpec{ - DeclaredLicenses: []*model.LicenseSpec{ - {Inline: &testdata.InlineLicense}, - }, - }, - ExpLegal: []*model.CertifyLegal{ - { - Subject: testdata.S1out, - DeclaredLicenses: []*model.License{testdata.L1out, testdata.L4out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on expression", - InPkg: []*model.PkgInputSpec{testdata.P1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Legal: &model.CertifyLegalInputSpec{ - DeclaredLicense: "GPL OR MIT", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Legal: &model.CertifyLegalInputSpec{ - DeclaredLicense: "GPL AND MIT", - }, - }, - }, - Query: &model.CertifyLegalSpec{ - DeclaredLicense: ptrfrom.String("GPL AND MIT"), - }, - ExpLegal: []*model.CertifyLegal{ - { - Subject: testdata.P1out, - DeclaredLicense: "GPL AND MIT", - }, - }, - }, - { - Name: "Query on attribution", - InPkg: []*model.PkgInputSpec{testdata.P1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Legal: &model.CertifyLegalInputSpec{ - Attribution: "Copyright Jeff", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Legal: &model.CertifyLegalInputSpec{ - Attribution: "Copyright Bob", - }, - }, - }, - Query: &model.CertifyLegalSpec{ - Attribution: ptrfrom.String("Copyright Jeff"), - }, - ExpLegal: []*model.CertifyLegal{ - { - Subject: testdata.P1out, - Attribution: "Copyright Jeff", - }, - }, - }, - { - Name: "Query on time", - InPkg: []*model.PkgInputSpec{testdata.P1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Legal: &model.CertifyLegalInputSpec{ - TimeScanned: testdata.T3, - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Legal: &model.CertifyLegalInputSpec{ - TimeScanned: testdata.T2, - }, - }, - }, - Query: &model.CertifyLegalSpec{ - TimeScanned: &testdata.T2, - }, - ExpLegal: []*model.CertifyLegal{ - { - Subject: testdata.P1out, - TimeScanned: testdata.T2, - }, - }, - }, - { - Name: "Query multiple", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2, testdata.P3}, - InLic: []*model.LicenseInputSpec{testdata.L1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Dec: []*model.LicenseInputSpec{testdata.L1}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification special", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P2, - }, - Dec: []*model.LicenseInputSpec{testdata.L1}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification special", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P3, - }, - Dec: []*model.LicenseInputSpec{testdata.L1}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification other", - }, - }, - }, - Query: &model.CertifyLegalSpec{ - Justification: ptrfrom.String("test justification special"), - }, - ExpLegal: []*model.CertifyLegal{ - { - Subject: testdata.P1out, - DeclaredLicenses: []*model.License{testdata.L1out}, - Justification: "test justification special", - }, - { - Subject: testdata.P2out, - DeclaredLicenses: []*model.License{testdata.L1out}, - Justification: "test justification special", - }, - }, - }, - // { - // Name: "Ingest without Package", - // Calls: []call{ - // { - // PkgSrc: model.PackageOrSourceInput{ - // Package: pNone, - // }, - // Legal: &model.CertifyLegalInputSpec{}, - // }, - // }, - // ExpIngestErr: true, - // }, - // { - // Name: "Ingest without Source", - // Calls: []call{ - // { - // PkgSrc: model.PackageOrSourceInput{ - // Source: sNone, - // }, - // Legal: &model.CertifyLegalInputSpec{}, - // }, - // }, - // ExpIngestErr: true, - // }, - // { - // Name: "Ingest without License", - // InPkg: []*model.PkgInputSpec{testdata.P1}, - // Calls: []call{ - // { - // PkgSrc: model.PackageOrSourceInput{ - // Package: testdata.P1, - // }, - // Dec: []*model.LicenseInputSpec{lNone}, - // Legal: &model.CertifyLegalInputSpec{}, - // }, - // }, - // ExpIngestErr: true, - // }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, a := range test.InLic { - if _, err := b.IngestLicense(ctx, a); err != nil { - t.Fatalf("Could not ingest license: %v", err) - } - } - for i, o := range test.Calls { - clID, err := b.IngestCertifyLegal(ctx, o.PkgSrc, o.Dec, o.Dis, o.Legal) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - if (i + 1) == test.IDInFilter { - test.Query.ID = ptrfrom.String(clID) - } - } - got, err := b.CertifyLegal(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpLegal, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func TestLegals(t *testing.T) { - type call struct { - PkgSrc model.PackageOrSourceInputs - Dec [][]*model.LicenseInputSpec - Dis [][]*model.LicenseInputSpec - Legal []*model.CertifyLegalInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - InLic []*model.LicenseInputSpec - Calls []call - Query *model.CertifyLegalSpec - ExpLegal []*model.CertifyLegal - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - InLic: []*model.LicenseInputSpec{testdata.L1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInputs{ - Packages: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - }, - Dec: [][]*model.LicenseInputSpec{{testdata.L1}, {testdata.L1}}, - Dis: [][]*model.LicenseInputSpec{{}, {}}, - Legal: []*model.CertifyLegalInputSpec{ - {Justification: "test justification"}, - {Justification: "test justification"}, - }, - }, - }, - Query: &model.CertifyLegalSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpLegal: []*model.CertifyLegal{ - { - Subject: testdata.P1out, - DeclaredLicenses: []*model.License{testdata.L1out}, - Justification: "test justification", - }, - { - Subject: testdata.P2out, - DeclaredLicenses: []*model.License{testdata.L1out}, - Justification: "test justification", - }, - }, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, a := range test.InLic { - if _, err := b.IngestLicense(ctx, a); err != nil { - t.Fatalf("Could not ingest license: %v", err) - } - } - for _, o := range test.Calls { - _, err := b.IngestCertifyLegals(ctx, o.PkgSrc, o.Dec, o.Dis, o.Legal) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.CertifyLegal(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpLegal, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func Test_buildCertifyLegalByID(t *testing.T) { - type call struct { - PkgSrc model.PackageOrSourceInput - Dec []*model.LicenseInputSpec - Dis []*model.LicenseInputSpec - Legal *model.CertifyLegalInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - InLic []*model.LicenseInputSpec - Calls []call - Query *model.CertifyLegalSpec - ExpLegal *model.CertifyLegal - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "Query on ID", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InLic: []*model.LicenseInputSpec{testdata.L1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Dec: []*model.LicenseInputSpec{testdata.L1}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification 2", - }, - }, - }, - ExpLegal: &model.CertifyLegal{ - Subject: testdata.P1out, - DeclaredLicenses: []*model.License{testdata.L1out}, - Justification: "test justification 2", - }, - }, - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{testdata.P2}, - InLic: []*model.LicenseInputSpec{testdata.L1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P2, - }, - Dec: []*model.LicenseInputSpec{testdata.L1}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyLegalSpec{ - Subject: &model.PackageOrSourceSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String("2.11.1"), - }, - }, - }, - ExpLegal: &model.CertifyLegal{ - Subject: testdata.P2out, - DeclaredLicenses: []*model.License{testdata.L1out}, - Justification: "test justification", - }, - }, - { - Name: "Query on Source", - InSrc: []*model.SourceInputSpec{testdata.S1}, - InLic: []*model.LicenseInputSpec{testdata.L1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Source: testdata.S1, - }, - Dec: []*model.LicenseInputSpec{testdata.L1}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyLegalSpec{ - Subject: &model.PackageOrSourceSpec{ - Source: &model.SourceSpec{ - Name: ptrfrom.String("myrepo"), - }, - }, - }, - ExpLegal: &model.CertifyLegal{ - Subject: testdata.S1out, - DeclaredLicenses: []*model.License{testdata.L1out}, - Justification: "test justification", - }, - }, - { - Name: "Query on License", - InSrc: []*model.SourceInputSpec{testdata.S1}, - InLic: []*model.LicenseInputSpec{testdata.L1, testdata.L2}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Source: testdata.S1, - }, - Dec: []*model.LicenseInputSpec{testdata.L1, testdata.L2}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyLegalSpec{ - DeclaredLicenses: []*model.LicenseSpec{ - {Name: ptrfrom.String("GPL-2.0-or-later")}, - }, - }, - ExpLegal: &model.CertifyLegal{ - Subject: testdata.S1out, - DeclaredLicenses: []*model.License{testdata.L1out, testdata.L2out}, - Justification: "test justification", - }, - }, - { - Name: "Query on License inline", - InSrc: []*model.SourceInputSpec{testdata.S1}, - InLic: []*model.LicenseInputSpec{testdata.L1, testdata.L4}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Source: testdata.S1, - }, - Dec: []*model.LicenseInputSpec{testdata.L1, testdata.L4}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyLegalSpec{ - DeclaredLicenses: []*model.LicenseSpec{ - {Inline: &testdata.InlineLicense}, - }, - }, - ExpLegal: &model.CertifyLegal{ - Subject: testdata.S1out, - DeclaredLicenses: []*model.License{testdata.L1out, testdata.L4out}, - Justification: "test justification", - }, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, a := range test.InLic { - if _, err := b.IngestLicense(ctx, a); err != nil { - t.Fatalf("Could not ingest license: %v", err) - } - } - for _, o := range test.Calls { - clID, err := b.IngestCertifyLegal(ctx, o.PkgSrc, o.Dec, o.Dis, o.Legal) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - got, err := b.(*arangoClient).buildCertifyLegalByID(ctx, clID, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpLegal, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - } - }) - } -} diff --git a/pkg/assembler/backends/arangodb/certifyScorecard.go b/pkg/assembler/backends/arangodb/certifyScorecard.go index 99c129c832..8520297445 100644 --- a/pkg/assembler/backends/arangodb/certifyScorecard.go +++ b/pkg/assembler/backends/arangodb/certifyScorecard.go @@ -179,11 +179,11 @@ func getScorecardValues(src *model.SourceInputSpec, scorecard *model.ScorecardIn // Ingest Scorecards -func (c *arangoClient) IngestScorecards(ctx context.Context, sources []*model.SourceInputSpec, scorecards []*model.ScorecardInputSpec) ([]string, error) { +func (c *arangoClient) IngestScorecards(ctx context.Context, sources []*model.IDorSourceInput, scorecards []*model.ScorecardInputSpec) ([]string, error) { var listOfValues []map[string]any for i := range sources { - listOfValues = append(listOfValues, getScorecardValues(sources[i], scorecards[i])) + listOfValues = append(listOfValues, getScorecardValues(sources[i].SourceInput, scorecards[i])) } var documents []string @@ -255,7 +255,7 @@ func (c *arangoClient) IngestScorecards(ctx context.Context, sources []*model.So // Ingest Scorecard -func (c *arangoClient) IngestScorecard(ctx context.Context, source model.SourceInputSpec, scorecard model.ScorecardInputSpec) (string, error) { +func (c *arangoClient) IngestScorecard(ctx context.Context, source model.IDorSourceInput, scorecard model.ScorecardInputSpec) (string, error) { query := ` LET firstSrc = FIRST( FOR sName in srcNames @@ -282,7 +282,7 @@ func (c *arangoClient) IngestScorecard(ctx context.Context, source model.SourceI RETURN { 'scorecard_id': scorecard._id }` - cursor, err := executeQueryWithRetry(ctx, c.db, query, getScorecardValues(&source, &scorecard), "IngestScorecard") + cursor, err := executeQueryWithRetry(ctx, c.db, query, getScorecardValues(source.SourceInput, &scorecard), "IngestScorecard") if err != nil { return "", fmt.Errorf("failed to ingest source occurrence: %w", err) } diff --git a/pkg/assembler/backends/arangodb/certifyScorecard_test.go b/pkg/assembler/backends/arangodb/certifyScorecard_test.go deleted file mode 100644 index e69ade42d4..0000000000 --- a/pkg/assembler/backends/arangodb/certifyScorecard_test.go +++ /dev/null @@ -1,894 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build integration - -package arangodb - -import ( - "context" - "strings" - "testing" - "time" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/internal/testing/testdata" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -func TestCertifyScorecard(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - testTime := time.Unix(1e9+5, 0) - type call struct { - Src *model.SourceInputSpec - SC *model.ScorecardInputSpec - } - tests := []struct { - Name string - InSrc []*model.SourceInputSpec - Calls []call - Query *model.CertifyScorecardSpec - QueryID bool - QuerySourceID bool - ExpSC []*model.CertifyScorecard - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InSrc: []*model.SourceInputSpec{testdata.S1}, - Calls: []call{ - { - Src: testdata.S1, - SC: &model.ScorecardInputSpec{ - Origin: "test origin", - }, - }, - }, - Query: &model.CertifyScorecardSpec{ - Origin: ptrfrom.String("test origin"), - }, - ExpSC: []*model.CertifyScorecard{ - { - Source: testdata.S1out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - Origin: "test origin", - }, - }, - }, - }, - { - Name: "Ingest same", - InSrc: []*model.SourceInputSpec{testdata.S1}, - Calls: []call{ - { - Src: testdata.S1, - SC: &model.ScorecardInputSpec{ - Origin: "test origin", - }, - }, - { - Src: testdata.S1, - SC: &model.ScorecardInputSpec{ - Origin: "test origin", - }, - }, - }, - Query: &model.CertifyScorecardSpec{ - Origin: ptrfrom.String("test origin"), - }, - ExpSC: []*model.CertifyScorecard{ - { - Source: testdata.S1out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - Origin: "test origin", - }, - }, - }, - }, - { - Name: "Query on Source ID", - InSrc: []*model.SourceInputSpec{testdata.S1, testdata.S2}, - Calls: []call{ - { - Src: testdata.S1, - SC: &model.ScorecardInputSpec{ - Origin: "test origin", - }, - }, - { - Src: testdata.S2, - SC: &model.ScorecardInputSpec{ - Origin: "test origin", - }, - }, - }, - QuerySourceID: true, - ExpSC: []*model.CertifyScorecard{ - { - Source: testdata.S2out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - Origin: "test origin", - }, - }, - }, - }, - { - Name: "Query multiple", - InSrc: []*model.SourceInputSpec{testdata.S1}, - Calls: []call{ - { - Src: testdata.S1, - SC: &model.ScorecardInputSpec{ - Origin: "test origin one", - }, - }, - { - Src: testdata.S1, - SC: &model.ScorecardInputSpec{ - AggregateScore: 4.4, - Origin: "test origin two", - }, - }, - { - Src: testdata.S1, - SC: &model.ScorecardInputSpec{ - AggregateScore: 4.9, - Origin: "test origin two", - }, - }, - }, - Query: &model.CertifyScorecardSpec{ - Origin: ptrfrom.String("test origin two"), - }, - ExpSC: []*model.CertifyScorecard{ - { - Source: testdata.S1out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - AggregateScore: 4.4, - Origin: "test origin two", - }, - }, - { - Source: testdata.S1out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - AggregateScore: 4.9, - Origin: "test origin two", - }, - }, - }, - }, - { - Name: "Query Source", - InSrc: []*model.SourceInputSpec{testdata.S1, testdata.S2}, - Calls: []call{ - { - Src: testdata.S1, - SC: &model.ScorecardInputSpec{ - Origin: "test origin", - }, - }, - { - Src: testdata.S2, - SC: &model.ScorecardInputSpec{ - Origin: "test origin", - }, - }, - }, - Query: &model.CertifyScorecardSpec{ - Source: &model.SourceSpec{ - Namespace: ptrfrom.String("github.com/jeff"), - }, - }, - ExpSC: []*model.CertifyScorecard{ - { - Source: testdata.S1out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - AggregateScore: 4.9, - Origin: "test origin two", - }, - }, - { - Source: testdata.S1out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - AggregateScore: 4.4, - Origin: "test origin two", - }, - }, - { - Source: testdata.S1out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - Origin: "test origin one", - }, - }, - { - Source: testdata.S1out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - Origin: "test origin", - }, - }, - }, - }, - { - Name: "Query Time", - InSrc: []*model.SourceInputSpec{testdata.S1}, - Calls: []call{ - { - Src: testdata.S1, - SC: &model.ScorecardInputSpec{ - AggregateScore: 1.5, - TimeScanned: time.Unix(1e9, 0), - ScorecardVersion: "123", - ScorecardCommit: "abc", - }, - }, - { - Src: testdata.S1, - SC: &model.ScorecardInputSpec{ - AggregateScore: 1.5, - TimeScanned: testTime, - ScorecardVersion: "123", - ScorecardCommit: "abc", - }, - }, - }, - Query: &model.CertifyScorecardSpec{ - TimeScanned: &testTime, - }, - ExpSC: []*model.CertifyScorecard{ - { - Source: testdata.S1out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - AggregateScore: 1.5, - TimeScanned: testTime, - ScorecardVersion: "123", - ScorecardCommit: "abc", - }, - }, - }, - }, - { - Name: "Query Score", - InSrc: []*model.SourceInputSpec{testdata.S1}, - Calls: []call{ - { - Src: testdata.S1, - SC: &model.ScorecardInputSpec{ - AggregateScore: 1.5, - TimeScanned: time.Unix(1e9, 0), - ScorecardVersion: "123", - ScorecardCommit: "abc", - }, - }, - { - Src: testdata.S1, - SC: &model.ScorecardInputSpec{ - AggregateScore: 5.7, - TimeScanned: time.Unix(1e9, 0), - ScorecardVersion: "123", - ScorecardCommit: "abc", - }, - }, - }, - Query: &model.CertifyScorecardSpec{ - AggregateScore: ptrfrom.Float64(57.0 / 10), - }, - ExpSC: []*model.CertifyScorecard{ - { - Source: testdata.S1out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - AggregateScore: 5.7, - TimeScanned: time.Unix(1e9, 0), - ScorecardVersion: "123", - ScorecardCommit: "abc", - }, - }, - }, - }, - { - Name: "Query Checks", - InSrc: []*model.SourceInputSpec{testdata.S1}, - Calls: []call{ - { - Src: testdata.S1, - SC: &model.ScorecardInputSpec{ - Checks: []*model.ScorecardCheckInputSpec{ - { - Check: "check one", - Score: 5, - }, - }, - ScorecardVersion: "123", - }, - }, - { - Src: testdata.S1, - SC: &model.ScorecardInputSpec{ - Checks: []*model.ScorecardCheckInputSpec{ - { - Check: "check one", - Score: 5, - }, - { - Check: "check two", - Score: 6, - }, - }, - ScorecardVersion: "456", - }, - }, - }, - Query: &model.CertifyScorecardSpec{ - Checks: []*model.ScorecardCheckSpec{ - { - Check: "check one", - Score: 5, - }, - }, - }, - ExpSC: []*model.CertifyScorecard{ - { - Source: testdata.S1out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{ - { - Check: "check one", - Score: 5, - }, - }, - ScorecardVersion: "123", - }, - }, - }, - }, - { - Name: "Query None", - InSrc: []*model.SourceInputSpec{testdata.S1}, - Calls: []call{ - { - Src: testdata.S1, - SC: &model.ScorecardInputSpec{ - AggregateScore: 1.5, - TimeScanned: time.Unix(1e9, 0), - ScorecardVersion: "123", - ScorecardCommit: "abc", - }, - }, - { - Src: testdata.S1, - SC: &model.ScorecardInputSpec{ - AggregateScore: 5.7, - TimeScanned: time.Unix(1e9, 0), - ScorecardVersion: "123", - ScorecardCommit: "abc", - }, - }, - }, - Query: &model.CertifyScorecardSpec{ - ScorecardVersion: ptrfrom.String("853"), - }, - ExpSC: nil, - }, - { - Name: "Query commit", - InSrc: []*model.SourceInputSpec{testdata.S1}, - Calls: []call{ - { - Src: testdata.S1, - SC: &model.ScorecardInputSpec{ - AggregateScore: 1.5, - TimeScanned: time.Unix(1e9, 0), - ScorecardVersion: "123", - ScorecardCommit: "abc", - }, - }, - { - Src: testdata.S1, - SC: &model.ScorecardInputSpec{ - AggregateScore: 5.7, - TimeScanned: time.Unix(1e9, 0), - ScorecardVersion: "123", - ScorecardCommit: "abc", - }, - }, - }, - Query: &model.CertifyScorecardSpec{ - ScorecardCommit: ptrfrom.String("abc"), - }, - ExpSC: []*model.CertifyScorecard{ - { - Source: testdata.S1out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - AggregateScore: 1.5, - TimeScanned: time.Unix(1e9, 0), - ScorecardVersion: "123", - ScorecardCommit: "abc", - }, - }, - { - Source: testdata.S1out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - AggregateScore: 1.5, - TimeScanned: testTime, - ScorecardVersion: "123", - ScorecardCommit: "abc", - }, - }, - { - Source: testdata.S1out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - AggregateScore: 5.7, - TimeScanned: time.Unix(1e9, 0), - ScorecardVersion: "123", - ScorecardCommit: "abc", - }, - }, - }, - }, - { - Name: "Query ID", - InSrc: []*model.SourceInputSpec{testdata.S1}, - Calls: []call{ - { - Src: testdata.S1, - SC: &model.ScorecardInputSpec{ - AggregateScore: 1.5, - TimeScanned: time.Unix(1e9, 0), - ScorecardVersion: "123", - ScorecardCommit: "abc", - }, - }, - }, - QueryID: true, - ExpSC: []*model.CertifyScorecard{ - { - Source: testdata.S1out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - AggregateScore: 1.5, - TimeScanned: time.Unix(1e9, 0), - ScorecardVersion: "123", - ScorecardCommit: "abc", - }, - }, - }, - }, - { - Name: "Query bad ID", - InSrc: []*model.SourceInputSpec{testdata.S1}, - Calls: []call{ - { - Src: testdata.S1, - SC: &model.ScorecardInputSpec{ - AggregateScore: 1.5, - TimeScanned: time.Unix(1e9, 0), - ScorecardVersion: "123", - ScorecardCommit: "abc", - }, - }, - }, - Query: &model.CertifyScorecardSpec{ - ID: ptrfrom.String("4294967296"), - }, - ExpQueryErr: true, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - for _, s := range test.InSrc { - if srcID, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } else { - if test.QuerySourceID { - test.Query = &model.CertifyScorecardSpec{ - Source: &model.SourceSpec{ - ID: ptrfrom.String(srcID.SourceNameID), - }, - } - - } - } - } - for _, o := range test.Calls { - scoreID, err := b.IngestScorecard(ctx, *o.Src, *o.SC) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - if test.QueryID { - test.Query = &model.CertifyScorecardSpec{ - ID: ptrfrom.String(scoreID), - } - } - } - got, err := b.Scorecards(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpSC, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func TestIngestScorecards(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - type call struct { - Src []*model.SourceInputSpec - SC []*model.ScorecardInputSpec - } - tests := []struct { - Name string - InSrc []*model.SourceInputSpec - Calls []call - Query *model.CertifyScorecardSpec - ExpSC []*model.CertifyScorecard - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InSrc: []*model.SourceInputSpec{testdata.S1}, - Calls: []call{ - { - Src: []*model.SourceInputSpec{testdata.S1}, - SC: []*model.ScorecardInputSpec{ - { - Origin: "test origin", - }, - }, - }, - }, - Query: &model.CertifyScorecardSpec{ - Origin: ptrfrom.String("test origin"), - }, - ExpSC: []*model.CertifyScorecard{ - { - Source: testdata.S1out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - Origin: "test origin", - }, - }, - }, - }, - { - Name: "Ingest same", - InSrc: []*model.SourceInputSpec{testdata.S1}, - Calls: []call{ - { - Src: []*model.SourceInputSpec{testdata.S1, testdata.S1}, - SC: []*model.ScorecardInputSpec{ - { - Origin: "test origin", - }, - { - Origin: "test origin", - }, - }, - }, - }, - Query: &model.CertifyScorecardSpec{ - Origin: ptrfrom.String("test origin"), - }, - ExpSC: []*model.CertifyScorecard{ - { - Source: testdata.S1out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - Origin: "test origin", - }, - }, - }, - }, - { - Name: "Query multiple", - InSrc: []*model.SourceInputSpec{testdata.S1}, - Calls: []call{ - { - Src: []*model.SourceInputSpec{testdata.S1, testdata.S1, testdata.S1}, - SC: []*model.ScorecardInputSpec{ - { - Origin: "test origin one", - }, - { - AggregateScore: 4.4, - Origin: "test origin two", - }, - { - AggregateScore: 4.9, - Origin: "test origin two", - }, - }, - }, - }, - Query: &model.CertifyScorecardSpec{ - Origin: ptrfrom.String("test origin two"), - }, - ExpSC: []*model.CertifyScorecard{ - { - Source: testdata.S1out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - AggregateScore: 4.4, - Origin: "test origin two", - }, - }, - { - Source: testdata.S1out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - AggregateScore: 4.9, - Origin: "test origin two", - }, - }, - }, - }, - { - Name: "Query Source", - InSrc: []*model.SourceInputSpec{testdata.S1, testdata.S2}, - Calls: []call{ - { - Src: []*model.SourceInputSpec{testdata.S1, testdata.S2}, - SC: []*model.ScorecardInputSpec{ - { - Origin: "test origin", - }, - { - Origin: "test origin", - }, - }, - }, - }, - Query: &model.CertifyScorecardSpec{ - Source: &model.SourceSpec{ - Namespace: ptrfrom.String("github.com/jeff"), - }, - }, - ExpSC: []*model.CertifyScorecard{ - { - Source: testdata.S1out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - AggregateScore: 4.9, - Origin: "test origin two", - }, - }, - { - Source: testdata.S1out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - AggregateScore: 4.4, - Origin: "test origin two", - }, - }, - { - Source: testdata.S1out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - Origin: "test origin one", - }, - }, - { - Source: testdata.S1out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - Origin: "test origin", - }, - }, - }, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, o := range test.Calls { - _, err := b.IngestScorecards(ctx, o.Src, o.SC) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.Scorecards(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpSC, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func Test_buildCertifyScorecardByID(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - type call struct { - Src *model.SourceInputSpec - SC *model.ScorecardInputSpec - } - tests := []struct { - Name string - InSrc []*model.SourceInputSpec - Calls []call - Query *model.CertifyScorecardSpec - ExpSC *model.CertifyScorecard - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "Query Source", - InSrc: []*model.SourceInputSpec{testdata.S2}, - Calls: []call{ - { - Src: testdata.S2, - SC: &model.ScorecardInputSpec{ - Origin: "test origin", - }, - }, - }, - Query: &model.CertifyScorecardSpec{ - Source: &model.SourceSpec{ - Namespace: ptrfrom.String("github.com/bob"), - }, - }, - ExpSC: &model.CertifyScorecard{ - Source: testdata.S2out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - Origin: "test origin", - }, - }, - }, - { - Name: "Query ID", - InSrc: []*model.SourceInputSpec{testdata.S1}, - Calls: []call{ - { - Src: testdata.S1, - SC: &model.ScorecardInputSpec{ - AggregateScore: 1.5, - TimeScanned: time.Unix(1e9, 0), - ScorecardVersion: "123", - ScorecardCommit: "abc", - }, - }, - }, - ExpSC: &model.CertifyScorecard{ - Source: testdata.S1out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - AggregateScore: 1.5, - TimeScanned: time.Unix(1e9, 0), - ScorecardVersion: "123", - ScorecardCommit: "abc", - }, - }, - }, - { - Name: "Query bad ID", - InSrc: []*model.SourceInputSpec{testdata.S1}, - Calls: []call{ - { - Src: testdata.S1, - SC: &model.ScorecardInputSpec{ - AggregateScore: 1.5, - TimeScanned: time.Unix(1e9, 0), - ScorecardVersion: "123", - ScorecardCommit: "abc", - }, - }, - }, - Query: &model.CertifyScorecardSpec{ - ID: ptrfrom.String("4294967296"), - }, - ExpQueryErr: true, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, o := range test.Calls { - scoreID, err := b.IngestScorecard(ctx, *o.Src, *o.SC) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - - got, err := b.(*arangoClient).buildCertifyScorecardByID(ctx, scoreID, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpSC, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - } - }) - } -} diff --git a/pkg/assembler/backends/arangodb/certifyVEXStatement.go b/pkg/assembler/backends/arangodb/certifyVEXStatement.go index 80c74472b7..4df2eb7d86 100644 --- a/pkg/assembler/backends/arangodb/certifyVEXStatement.go +++ b/pkg/assembler/backends/arangodb/certifyVEXStatement.go @@ -259,12 +259,12 @@ func getVEXStatementQueryValues(pkg *model.PkgInputSpec, artifact *model.Artifac return values } -func (c *arangoClient) IngestVEXStatements(ctx context.Context, subjects model.PackageOrArtifactInputs, vulnerabilities []*model.VulnerabilityInputSpec, vexStatements []*model.VexStatementInputSpec) ([]string, error) { +func (c *arangoClient) IngestVEXStatements(ctx context.Context, subjects model.PackageOrArtifactInputs, vulnerabilities []*model.IDorVulnerabilityInput, vexStatements []*model.VexStatementInputSpec) ([]string, error) { if len(subjects.Artifacts) > 0 { var listOfValues []map[string]any for i := range subjects.Artifacts { - listOfValues = append(listOfValues, getVEXStatementQueryValues(nil, subjects.Artifacts[i], vulnerabilities[i], vexStatements[i])) + listOfValues = append(listOfValues, getVEXStatementQueryValues(nil, subjects.Artifacts[i].ArtifactInput, vulnerabilities[i].VulnerabilityInput, vexStatements[i])) } var documents []string @@ -339,7 +339,7 @@ func (c *arangoClient) IngestVEXStatements(ctx context.Context, subjects model.P var listOfValues []map[string]any for i := range subjects.Packages { - listOfValues = append(listOfValues, getVEXStatementQueryValues(subjects.Packages[i], nil, vulnerabilities[i], vexStatements[i])) + listOfValues = append(listOfValues, getVEXStatementQueryValues(subjects.Packages[i].PackageInput, nil, vulnerabilities[i].VulnerabilityInput, vexStatements[i])) } var documents []string @@ -424,7 +424,7 @@ func (c *arangoClient) IngestVEXStatements(ctx context.Context, subjects model.P } } -func (c *arangoClient) IngestVEXStatement(ctx context.Context, subject model.PackageOrArtifactInput, vulnerability model.VulnerabilityInputSpec, vexStatement model.VexStatementInputSpec) (string, error) { +func (c *arangoClient) IngestVEXStatement(ctx context.Context, subject model.PackageOrArtifactInput, vulnerability model.IDorVulnerabilityInput, vexStatement model.VexStatementInputSpec) (string, error) { if subject.Artifact != nil { query := ` LET artifact = FIRST(FOR art IN artifacts FILTER art.algorithm == @art_algorithm FILTER art.digest == @art_digest RETURN art) @@ -453,7 +453,7 @@ func (c *arangoClient) IngestVEXStatement(ctx context.Context, subject model.Pac RETURN { 'certifyVex_id': certifyVex._id }` - cursor, err := executeQueryWithRetry(ctx, c.db, query, getVEXStatementQueryValues(nil, subject.Artifact, &vulnerability, &vexStatement), "IngestVEXStatement - Artifact") + cursor, err := executeQueryWithRetry(ctx, c.db, query, getVEXStatementQueryValues(nil, subject.Artifact.ArtifactInput, vulnerability.VulnerabilityInput, &vexStatement), "IngestVEXStatement - Artifact") if err != nil { return "", fmt.Errorf("failed to ingest VEX: %w", err) } @@ -504,7 +504,7 @@ func (c *arangoClient) IngestVEXStatement(ctx context.Context, subject model.Pac RETURN { 'certifyVex_id': certifyVex._id }` - cursor, err := executeQueryWithRetry(ctx, c.db, query, getVEXStatementQueryValues(subject.Package, nil, &vulnerability, &vexStatement), "IngestVEXStatement - Package") + cursor, err := executeQueryWithRetry(ctx, c.db, query, getVEXStatementQueryValues(subject.Package.PackageInput, nil, vulnerability.VulnerabilityInput, &vexStatement), "IngestVEXStatement - Package") if err != nil { return "", fmt.Errorf("failed to create ingest VEX: %w", err) } diff --git a/pkg/assembler/backends/arangodb/certifyVEXStatement_test.go b/pkg/assembler/backends/arangodb/certifyVEXStatement_test.go deleted file mode 100644 index b36856ee6c..0000000000 --- a/pkg/assembler/backends/arangodb/certifyVEXStatement_test.go +++ /dev/null @@ -1,1549 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build integration - -package arangodb - -import ( - "context" - "strings" - "testing" - "time" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/internal/testing/testdata" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -func TestVEX(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - testTime := time.Unix(1e9+5, 0) - type call struct { - Sub model.PackageOrArtifactInput - Vuln *model.VulnerabilityInputSpec - In *model.VexStatementInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InArt []*model.ArtifactInputSpec - InVuln []*model.VulnerabilityInputSpec - Calls []call - Query *model.CertifyVEXStatementSpec - QueryID bool - QueryPkgID bool - QueryArtID bool - QueryVulnID bool - ExpVEX []*model.CertifyVEXStatement - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InVuln: []*model.VulnerabilityInputSpec{testdata.O1}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, - }, - Vuln: testdata.O1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - VexJustification: (*model.VexJustification)(ptrfrom.String("test justification")), - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: testdata.P1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - { - Name: "Ingest same twice", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InVuln: []*model.VulnerabilityInputSpec{testdata.O1}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, - }, - Vuln: testdata.O1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, - }, - Vuln: testdata.O1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - VexJustification: (*model.VexJustification)(ptrfrom.String("test justification")), - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: testdata.P1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - { - Name: "Query on Justification", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InVuln: []*model.VulnerabilityInputSpec{testdata.O1}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, - }, - Vuln: testdata.O1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, - }, - Vuln: testdata.O1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification 2", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - VexJustification: (*model.VexJustification)(ptrfrom.String("test justification 2")), - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: testdata.P1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - VexJustification: "test justification 2", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - InArt: []*model.ArtifactInputSpec{testdata.A1}, - InVuln: []*model.VulnerabilityInputSpec{testdata.O1}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, - }, - Vuln: testdata.O1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: testdata.P2, - }, - Vuln: testdata.O1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Artifact: testdata.A1, - }, - Vuln: testdata.O1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - Subject: &model.PackageOrArtifactSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String(""), - }, - }, - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: testdata.P1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - VexJustification: "test justification 2", - KnownSince: time.Unix(1e9, 0), - }, - { - Subject: testdata.P1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - { - Name: "Query on Package ID", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - InArt: []*model.ArtifactInputSpec{testdata.A1}, - InVuln: []*model.VulnerabilityInputSpec{testdata.O1}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, - }, - Vuln: testdata.O1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: testdata.P2, - }, - Vuln: testdata.O1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Artifact: testdata.A1, - }, - Vuln: testdata.O1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - QueryPkgID: true, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: testdata.P2out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - { - Name: "Query on Artifact", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - InVuln: []*model.VulnerabilityInputSpec{testdata.O1}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, - }, - Vuln: testdata.O1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Artifact: testdata.A1, - }, - Vuln: testdata.O1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Artifact: testdata.A2, - }, - Vuln: testdata.O1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - Subject: &model.PackageOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha256"), - }, - }, - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: testdata.A1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - { - Name: "Query on Artifact ID", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - InVuln: []*model.VulnerabilityInputSpec{testdata.O1}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, - }, - Vuln: testdata.O1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Artifact: testdata.A1, - }, - Vuln: testdata.O1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Artifact: testdata.A2, - }, - Vuln: testdata.O1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - QueryArtID: true, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: testdata.A2out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - { - Name: "Query on Vuln", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InVuln: []*model.VulnerabilityInputSpec{testdata.O1, testdata.O2, testdata.C1}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, - }, - Vuln: testdata.O1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, - }, - Vuln: testdata.O2, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, - }, - Vuln: testdata.C1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - Vulnerability: &model.VulnerabilitySpec{ - Type: ptrfrom.String("osv"), - VulnerabilityID: ptrfrom.String("cve-2014-8140"), - }, - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: testdata.P1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - { - Subject: testdata.P1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - VexJustification: "test justification 2", - KnownSince: time.Unix(1e9, 0), - }, - { - Subject: testdata.P2out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - { - Subject: testdata.A1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - { - Subject: testdata.A2out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - { - Name: "Query on Vulnerability ID", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InVuln: []*model.VulnerabilityInputSpec{testdata.O1, testdata.O2, testdata.C1}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, - }, - Vuln: testdata.O1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, - }, - Vuln: testdata.O2, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, - }, - Vuln: testdata.C1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - QueryVulnID: true, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: testdata.P1out, - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - { - Name: "Query on Status", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InVuln: []*model.VulnerabilityInputSpec{testdata.C1, testdata.O1}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, - }, - Vuln: testdata.C1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - Status: "status one", - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, - }, - Vuln: testdata.O1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - Status: "status two", - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - Status: (*model.VexStatus)(ptrfrom.String("status one")), - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: testdata.P1out, - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - Status: "status one", - }, - }, - }, - { - Name: "Query on Status Notes", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InVuln: []*model.VulnerabilityInputSpec{testdata.C1, testdata.O1}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, - }, - Vuln: testdata.C1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - StatusNotes: "status one", - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, - }, - Vuln: testdata.O1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - StatusNotes: "status two", - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - StatusNotes: ptrfrom.String("status one"), - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: testdata.P1out, - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - StatusNotes: "status one", - }, - }, - }, - { - Name: "Query on Statement", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InVuln: []*model.VulnerabilityInputSpec{testdata.O1}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, - }, - Vuln: testdata.O1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - Statement: "statement one", - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, - }, - Vuln: testdata.O1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - Statement: "statement two", - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - Statement: ptrfrom.String("statement two"), - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: testdata.P1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - Statement: "statement two", - }, - }, - }, - { - Name: "Query on KnownSince", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InVuln: []*model.VulnerabilityInputSpec{testdata.O1}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, - }, - Vuln: testdata.O1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, - }, - Vuln: testdata.O1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: testTime, - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - KnownSince: &testTime, - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: testdata.P1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - VexJustification: "test justification", - KnownSince: testTime, - }, - }, - }, - { - Name: "Query on ID", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InVuln: []*model.VulnerabilityInputSpec{testdata.O1, testdata.O2}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, - }, - Vuln: testdata.O1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, - }, - Vuln: testdata.O2, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - QueryID: true, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: testdata.P1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O2out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - { - Name: "Query None", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InVuln: []*model.VulnerabilityInputSpec{testdata.O1, testdata.O2, testdata.C1}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, - }, - Vuln: testdata.O1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, - }, - Vuln: testdata.O2, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, - }, - Vuln: testdata.C1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - Vulnerability: &model.VulnerabilitySpec{ - VulnerabilityID: ptrfrom.String("asdf"), - }, - }, - ExpVEX: nil, - }, - { - Name: "Query multiple", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InVuln: []*model.VulnerabilityInputSpec{testdata.O1, testdata.O2, testdata.C1}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, - }, - Vuln: testdata.O1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, - }, - Vuln: testdata.O2, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification two", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, - }, - Vuln: testdata.C1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification two", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - VexJustification: (*model.VexJustification)(ptrfrom.String("test justification two")), - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: testdata.P1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O2out}, - }, - VexJustification: "test justification two", - KnownSince: time.Unix(1e9, 0), - }, - { - Subject: testdata.P1out, - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C1out}, - }, - VexJustification: "test justification two", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - for _, p := range test.InPkg { - if pkgIDs, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } else { - if test.QueryPkgID { - test.Query = &model.CertifyVEXStatementSpec{ - Subject: &model.PackageOrArtifactSpec{ - Package: &model.PkgSpec{ - ID: ptrfrom.String(pkgIDs.PackageVersionID), - }, - }, - } - } - } - } - for _, a := range test.InArt { - if artID, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %a", err) - } else { - if test.QueryArtID { - test.Query = &model.CertifyVEXStatementSpec{ - Subject: &model.PackageOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - ID: ptrfrom.String(artID), - }, - }, - } - } - } - } - for _, v := range test.InVuln { - if vulnIDs, err := b.IngestVulnerability(ctx, *v); err != nil { - t.Fatalf("Could not ingest vulnerability: %v", err) - } else { - if test.QueryVulnID { - test.Query = &model.CertifyVEXStatementSpec{ - Vulnerability: &model.VulnerabilitySpec{ - ID: ptrfrom.String(vulnIDs.VulnerabilityNodeID), - }, - } - } - } - } - for _, o := range test.Calls { - vexID, err := b.IngestVEXStatement(ctx, o.Sub, *o.Vuln, *o.In) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - if test.QueryID { - test.Query = &model.CertifyVEXStatementSpec{ - ID: ptrfrom.String(vexID), - } - } - } - got, err := b.CertifyVEXStatement(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpVEX, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func TestVEXBulkIngest(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - type call struct { - Subs model.PackageOrArtifactInputs - Vulns []*model.VulnerabilityInputSpec - Vexs []*model.VexStatementInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InArt []*model.ArtifactInputSpec - InVuln []*model.VulnerabilityInputSpec - Calls []call - Query *model.CertifyVEXStatementSpec - ExpVEX []*model.CertifyVEXStatement - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InVuln: []*model.VulnerabilityInputSpec{testdata.O1}, - Calls: []call{ - { - Subs: model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1}, - }, - Vulns: []*model.VulnerabilityInputSpec{testdata.O1}, - Vexs: []*model.VexStatementInputSpec{ - { - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - VexJustification: (*model.VexJustification)(ptrfrom.String("test justification")), - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: testdata.P1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - { - Name: "Ingest same twice", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InVuln: []*model.VulnerabilityInputSpec{testdata.O1}, - Calls: []call{ - { - Subs: model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1, testdata.P1}, - }, - Vulns: []*model.VulnerabilityInputSpec{testdata.O1, testdata.O1}, - Vexs: []*model.VexStatementInputSpec{ - { - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - { - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - VexJustification: (*model.VexJustification)(ptrfrom.String("test justification")), - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: testdata.P1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - InArt: []*model.ArtifactInputSpec{testdata.A1}, - InVuln: []*model.VulnerabilityInputSpec{testdata.O1}, - Calls: []call{ - { - Subs: model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - }, - Vulns: []*model.VulnerabilityInputSpec{testdata.O1, testdata.O1}, - Vexs: []*model.VexStatementInputSpec{ - { - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - { - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - { - Subs: model.PackageOrArtifactInputs{ - Artifacts: []*model.ArtifactInputSpec{testdata.A1}, - }, - Vulns: []*model.VulnerabilityInputSpec{testdata.O1}, - Vexs: []*model.VexStatementInputSpec{ - { - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - Subject: &model.PackageOrArtifactSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String(""), - }, - }, - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: testdata.P1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - { - Name: "Query on Artifact", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - InVuln: []*model.VulnerabilityInputSpec{testdata.O1}, - Calls: []call{ - { - Subs: model.PackageOrArtifactInputs{ - Artifacts: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - }, - Vulns: []*model.VulnerabilityInputSpec{testdata.O1, testdata.O1}, - Vexs: []*model.VexStatementInputSpec{ - { - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - { - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - Subject: &model.PackageOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha256"), - }, - }, - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: testdata.A1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - { - Name: "Query on Vuln", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InVuln: []*model.VulnerabilityInputSpec{testdata.O1, testdata.O2, testdata.C1}, - Calls: []call{ - { - Subs: model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1, testdata.P1, testdata.P1}, - }, - Vulns: []*model.VulnerabilityInputSpec{testdata.O1, testdata.O2, testdata.C1}, - Vexs: []*model.VexStatementInputSpec{ - { - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - { - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - { - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - Vulnerability: &model.VulnerabilitySpec{ - Type: ptrfrom.String("osv"), - VulnerabilityID: ptrfrom.String("cve-2014-8140"), - }, - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: testdata.P1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - { - Subject: testdata.P2out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - { - Subject: testdata.A1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - { - Subject: testdata.A2out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - { - Name: "Query on Status", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InVuln: []*model.VulnerabilityInputSpec{testdata.C1, testdata.O1}, - Calls: []call{ - { - Subs: model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1, testdata.P1}, - }, - Vulns: []*model.VulnerabilityInputSpec{testdata.C1, testdata.O1}, - Vexs: []*model.VexStatementInputSpec{ - { - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - Status: "status one", - }, - { - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - Status: (*model.VexStatus)(ptrfrom.String("status one")), - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: testdata.P1out, - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - Status: "status one", - }, - }, - }, - { - Name: "Query multiple", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InVuln: []*model.VulnerabilityInputSpec{testdata.O1, testdata.O2, testdata.C1}, - Calls: []call{ - { - Subs: model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1, testdata.P1, testdata.P1}, - }, - Vulns: []*model.VulnerabilityInputSpec{testdata.O1, testdata.O2, testdata.C1}, - Vexs: []*model.VexStatementInputSpec{ - { - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - { - VexJustification: "test justification two", - KnownSince: time.Unix(1e9, 0), - }, - { - VexJustification: "test justification two", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - VexJustification: (*model.VexJustification)(ptrfrom.String("test justification two")), - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: testdata.P1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O2out}, - }, - VexJustification: "test justification two", - KnownSince: time.Unix(1e9, 0), - }, - { - Subject: testdata.P1out, - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C1out}, - }, - VexJustification: "test justification two", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - if _, err := b.IngestPackages(ctx, test.InPkg); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - - if _, err := b.IngestArtifacts(ctx, test.InArt); err != nil { - t.Fatalf("Could not ingest artifact: %a", err) - } - - if _, err := b.IngestVulnerabilities(ctx, test.InVuln); err != nil { - t.Fatalf("Could not ingest vulnerability: %v", err) - } - for _, o := range test.Calls { - _, err := b.IngestVEXStatements(ctx, o.Subs, o.Vulns, o.Vexs) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.CertifyVEXStatement(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpVEX, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func Test_buildCertifyVexByID(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - type call struct { - Sub model.PackageOrArtifactInput - Vuln *model.VulnerabilityInputSpec - In *model.VexStatementInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InArt []*model.ArtifactInputSpec - InVuln []*model.VulnerabilityInputSpec - Calls []call - Query *model.CertifyVEXStatementSpec - QueryID bool - QueryPkgID bool - QueryArtID bool - QueryVulnID bool - ExpVEX *model.CertifyVEXStatement - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InArt: []*model.ArtifactInputSpec{}, - InVuln: []*model.VulnerabilityInputSpec{testdata.O1}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, - }, - Vuln: testdata.O1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - Subject: &model.PackageOrArtifactSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String(""), - }, - }, - }, - ExpVEX: &model.CertifyVEXStatement{ - Subject: testdata.P1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Name: "Query on Artifact", - InPkg: []*model.PkgInputSpec{}, - InArt: []*model.ArtifactInputSpec{testdata.A1}, - InVuln: []*model.VulnerabilityInputSpec{testdata.O1}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Artifact: testdata.A1, - }, - Vuln: testdata.O1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - Subject: &model.PackageOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha256"), - }, - }, - }, - ExpVEX: &model.CertifyVEXStatement{ - Subject: testdata.A1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Name: "Query on Artifact", - InPkg: []*model.PkgInputSpec{}, - InArt: []*model.ArtifactInputSpec{testdata.A1}, - InVuln: []*model.VulnerabilityInputSpec{testdata.O1}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Artifact: testdata.A1, - }, - Vuln: testdata.O1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - ExpVEX: &model.CertifyVEXStatement{ - Subject: testdata.A1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Name: "Query on Vuln", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InVuln: []*model.VulnerabilityInputSpec{testdata.O1}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, - }, - Vuln: testdata.O1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - Vulnerability: &model.VulnerabilitySpec{ - Type: ptrfrom.String("osv"), - VulnerabilityID: ptrfrom.String("cve-2014-8140"), - }, - }, - ExpVEX: &model.CertifyVEXStatement{ - Subject: testdata.P1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Name: "Query on ID", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InVuln: []*model.VulnerabilityInputSpec{testdata.O2}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, - }, - Vuln: testdata.O2, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - QueryID: true, - ExpVEX: &model.CertifyVEXStatement{ - Subject: testdata.P1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O2out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %a", err) - } - } - for _, v := range test.InVuln { - if _, err := b.IngestVulnerability(ctx, *v); err != nil { - t.Fatalf("Could not ingest vulnerability: %v", err) - } - } - for _, o := range test.Calls { - vexID, err := b.IngestVEXStatement(ctx, o.Sub, *o.Vuln, *o.In) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - got, err := b.(*arangoClient).buildCertifyVexByID(ctx, vexID, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpVEX, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - } - - }) - } -} diff --git a/pkg/assembler/backends/arangodb/certifyVuln.go b/pkg/assembler/backends/arangodb/certifyVuln.go index a43a634df9..ecb6ee1032 100644 --- a/pkg/assembler/backends/arangodb/certifyVuln.go +++ b/pkg/assembler/backends/arangodb/certifyVuln.go @@ -189,11 +189,11 @@ func getCertifyVulnQueryValues(pkg *model.PkgInputSpec, vulnerability *model.Vul return values } -func (c *arangoClient) IngestCertifyVulns(ctx context.Context, pkgs []*model.PkgInputSpec, vulnerabilities []*model.VulnerabilityInputSpec, certifyVulns []*model.ScanMetadataInput) ([]string, error) { +func (c *arangoClient) IngestCertifyVulns(ctx context.Context, pkgs []*model.IDorPkgInput, vulnerabilities []*model.IDorVulnerabilityInput, certifyVulns []*model.ScanMetadataInput) ([]string, error) { var listOfValues []map[string]any for i := range certifyVulns { - listOfValues = append(listOfValues, getCertifyVulnQueryValues(pkgs[i], vulnerabilities[i], certifyVulns[i])) + listOfValues = append(listOfValues, getCertifyVulnQueryValues(pkgs[i].PackageInput, vulnerabilities[i].VulnerabilityInput, certifyVulns[i])) } var documents []string @@ -273,7 +273,7 @@ func (c *arangoClient) IngestCertifyVulns(ctx context.Context, pkgs []*model.Pkg return certifyVulnIDList, nil } -func (c *arangoClient) IngestCertifyVuln(ctx context.Context, pkg model.PkgInputSpec, vulnerability model.VulnerabilityInputSpec, certifyVuln model.ScanMetadataInput) (string, error) { +func (c *arangoClient) IngestCertifyVuln(ctx context.Context, pkg model.IDorPkgInput, vulnerability model.IDorVulnerabilityInput, certifyVuln model.ScanMetadataInput) (string, error) { query := ` LET firstPkg = FIRST( FOR pVersion in pkgVersions @@ -308,7 +308,7 @@ func (c *arangoClient) IngestCertifyVuln(ctx context.Context, pkg model.PkgInput RETURN { 'certifyVuln_id': certifyVuln._id }` - cursor, err := executeQueryWithRetry(ctx, c.db, query, getCertifyVulnQueryValues(&pkg, &vulnerability, &certifyVuln), "IngestCertifyVuln") + cursor, err := executeQueryWithRetry(ctx, c.db, query, getCertifyVulnQueryValues(pkg.PackageInput, vulnerability.VulnerabilityInput, &certifyVuln), "IngestCertifyVuln") if err != nil { return "", fmt.Errorf("failed to ingest certifyVuln: %w", err) } diff --git a/pkg/assembler/backends/arangodb/certifyVuln_test.go b/pkg/assembler/backends/arangodb/certifyVuln_test.go deleted file mode 100644 index 473375f968..0000000000 --- a/pkg/assembler/backends/arangodb/certifyVuln_test.go +++ /dev/null @@ -1,1657 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build integration - -package arangodb - -import ( - "context" - "strconv" - "strings" - "testing" - "time" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/internal/testing/testdata" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -var vmd1 = &model.ScanMetadata{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: testdata.T1, -} - -func TestIngestCertifyVulnerability(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - testTime := time.Unix(1e9+5, 0) - type call struct { - Pkg *model.PkgInputSpec - Vuln *model.VulnerabilityInputSpec - CertifyVuln *model.ScanMetadataInput - } - - tests := []struct { - InPkg []*model.PkgInputSpec - Name string - InVuln []*model.VulnerabilityInputSpec - Calls []call - ExpVuln []*model.CertifyVuln - Query *model.CertifyVulnSpec - QueryID bool - QueryPkgID bool - QueryVulnID bool - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InVuln: []*model.VulnerabilityInputSpec{testdata.C1}, - InPkg: []*model.PkgInputSpec{testdata.P2}, - Calls: []call{ - { - Pkg: testdata.P2, - Vuln: testdata.C1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: testdata.T1, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Collector: ptrfrom.String("test collector"), - }, - ExpVuln: []*model.CertifyVuln{ - { - ID: "1", - Package: testdata.P2out, - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C1out}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Certify NoVuln", - InVuln: []*model.VulnerabilityInputSpec{testdata.NoVulnInput}, - InPkg: []*model.PkgInputSpec{testdata.P2}, - Calls: []call{ - { - Pkg: testdata.P2, - Vuln: testdata.NoVulnInput, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: testdata.T1, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Vulnerability: &model.VulnerabilitySpec{ - Type: ptrfrom.String("noVuln"), - }, - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: testdata.P2out, - Vulnerability: &model.Vulnerability{ - Type: "novuln", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.NoVulnOut}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Certify OSV", - InVuln: []*model.VulnerabilityInputSpec{testdata.O1}, - InPkg: []*model.PkgInputSpec{testdata.P2}, - Calls: []call{ - { - Pkg: testdata.P2, - Vuln: testdata.O1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: testdata.T1, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Vulnerability: &model.VulnerabilitySpec{ - Type: ptrfrom.String("osv"), - }, - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: testdata.P2out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Certify GHSA", - InVuln: []*model.VulnerabilityInputSpec{testdata.G1}, - InPkg: []*model.PkgInputSpec{testdata.P2}, - Calls: []call{ - { - Pkg: testdata.P2, - Vuln: testdata.G1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: testdata.T1, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Vulnerability: &model.VulnerabilitySpec{ - VulnerabilityID: &testdata.G1.VulnerabilityID, - }, - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: testdata.P2out, - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Query on GHSA", - InVuln: []*model.VulnerabilityInputSpec{testdata.G1}, - InPkg: []*model.PkgInputSpec{testdata.P2}, - Calls: []call{ - { - Pkg: testdata.P2, - Vuln: testdata.G1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: testdata.T1, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Vulnerability: &model.VulnerabilitySpec{ - VulnerabilityID: &testdata.G1.VulnerabilityID, - }, - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: testdata.P2out, - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Query on Vulnerability ID", - InVuln: []*model.VulnerabilityInputSpec{testdata.G1}, - InPkg: []*model.PkgInputSpec{testdata.P2}, - Calls: []call{ - { - Pkg: testdata.P2, - Vuln: testdata.G1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: testdata.T1, - }, - }, - }, - QueryVulnID: true, - ExpVuln: []*model.CertifyVuln{ - { - Package: testdata.P2out, - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Query ID", - InVuln: []*model.VulnerabilityInputSpec{testdata.G1}, - InPkg: []*model.PkgInputSpec{testdata.P2}, - Calls: []call{ - { - Pkg: testdata.P2, - Vuln: testdata.G1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: testdata.T1, - }, - }, - }, - QueryID: true, - ExpVuln: []*model.CertifyVuln{ - { - Package: testdata.P2out, - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Query DbURI", - InVuln: []*model.VulnerabilityInputSpec{testdata.G1}, - InPkg: []*model.PkgInputSpec{testdata.P2}, - Calls: []call{ - { - Pkg: testdata.P2, - Vuln: testdata.G1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri 1", - TimeScanned: testdata.T1, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - DbURI: ptrfrom.String("test db uri 1"), - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: testdata.P2out, - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - Metadata: &model.ScanMetadata{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri 1", - TimeScanned: testdata.T1, - }, - }, - }, - }, - { - Name: "Query DB Version", - InVuln: []*model.VulnerabilityInputSpec{testdata.G1}, - InPkg: []*model.PkgInputSpec{testdata.P2}, - Calls: []call{ - { - Pkg: testdata.P2, - Vuln: testdata.G1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.08.01", - DbURI: "test db uri", - TimeScanned: testdata.T1, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - DbVersion: ptrfrom.String("2023.08.01"), - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: testdata.P2out, - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - Metadata: &model.ScanMetadata{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.08.01", - DbURI: "test db uri", - TimeScanned: testdata.T1, - }, - }, - }, - }, - { - Name: "Query TimeScanned", - InVuln: []*model.VulnerabilityInputSpec{testdata.G1}, - InPkg: []*model.PkgInputSpec{testdata.P2}, - Calls: []call{ - { - Pkg: testdata.P2, - Vuln: testdata.G1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.08.01", - DbURI: "test db uri", - TimeScanned: testTime, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - TimeScanned: ptrfrom.Time(testTime), - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: testdata.P2out, - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - Metadata: &model.ScanMetadata{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.08.01", - DbURI: "test db uri", - TimeScanned: testTime, - }, - }, - }, - }, - { - Name: "Query ScannerURI", - InVuln: []*model.VulnerabilityInputSpec{testdata.G1}, - InPkg: []*model.PkgInputSpec{testdata.P2}, - Calls: []call{ - { - Pkg: testdata.P2, - Vuln: testdata.G1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri 1", - DbVersion: "2023.08.01", - DbURI: "test db uri", - TimeScanned: testTime, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - ScannerURI: ptrfrom.String("test scanner uri 1"), - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: testdata.P2out, - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - Metadata: &model.ScanMetadata{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri 1", - DbVersion: "2023.08.01", - DbURI: "test db uri", - TimeScanned: testTime, - }, - }, - }, - }, - { - Name: "Query ScannerVersion", - InVuln: []*model.VulnerabilityInputSpec{testdata.G1}, - InPkg: []*model.PkgInputSpec{testdata.P2}, - Calls: []call{ - { - Pkg: testdata.P2, - Vuln: testdata.G1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.8.0", - ScannerURI: "test scanner uri 1", - DbVersion: "2023.08.01", - DbURI: "test db uri", - TimeScanned: testTime, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - ScannerVersion: ptrfrom.String("v1.8.0"), - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: testdata.P2out, - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - Metadata: &model.ScanMetadata{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.8.0", - ScannerURI: "test scanner uri 1", - DbVersion: "2023.08.01", - DbURI: "test db uri", - TimeScanned: testTime, - }, - }, - }, - }, - { - Name: "Query on Package", - InVuln: []*model.VulnerabilityInputSpec{testdata.G1}, - InPkg: []*model.PkgInputSpec{testdata.P3}, - Calls: []call{ - { - Pkg: testdata.P3, - Vuln: testdata.G1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: testdata.T1, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Package: &model.PkgSpec{ - Name: ptrfrom.String(testdata.P3.Name), - Subpath: ptrfrom.String("saved_model_cli.py"), - }, - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: testdata.P3out, - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Query on Package ID", - InVuln: []*model.VulnerabilityInputSpec{testdata.G1}, - InPkg: []*model.PkgInputSpec{testdata.P3}, - Calls: []call{ - { - Pkg: testdata.P3, - Vuln: testdata.G1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: testdata.T1, - }, - }, - }, - QueryPkgID: true, - ExpVuln: []*model.CertifyVuln{ - { - Package: testdata.P3out, - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Query none", - InVuln: []*model.VulnerabilityInputSpec{testdata.G1}, - InPkg: []*model.PkgInputSpec{testdata.P2}, - Calls: []call{ - { - Pkg: testdata.P2, - Vuln: testdata.G1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: testdata.T1, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Vulnerability: &model.VulnerabilitySpec{ - VulnerabilityID: ptrfrom.String("asdf"), - }, - }, - ExpVuln: nil, - }, - { - Name: "Query No Vuln", - InVuln: []*model.VulnerabilityInputSpec{testdata.NoVulnInput}, - InPkg: []*model.PkgInputSpec{testdata.P2}, - Calls: []call{ - { - Pkg: testdata.P2, - Vuln: testdata.NoVulnInput, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: testdata.T1, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Vulnerability: &model.VulnerabilitySpec{ - Type: ptrfrom.String("noVuln"), - }, - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: testdata.P2out, - Vulnerability: &model.Vulnerability{ - Type: "novuln", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.NoVulnOut}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Query No Vuln - with novuln boolen", - InVuln: []*model.VulnerabilityInputSpec{testdata.NoVulnInput, testdata.C1}, - InPkg: []*model.PkgInputSpec{testdata.P2, testdata.P1}, - Calls: []call{ - { - Pkg: testdata.P2, - Vuln: testdata.NoVulnInput, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: testdata.T1, - }, - }, - { - Pkg: testdata.P1, - Vuln: testdata.C1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: testdata.T1, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Vulnerability: &model.VulnerabilitySpec{ - NoVuln: ptrfrom.Bool(true), - }, - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: testdata.P2out, - Vulnerability: &model.Vulnerability{ - Type: "novuln", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.NoVulnOut}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Query only cve (exclude novuln) - with novuln boolen", - InVuln: []*model.VulnerabilityInputSpec{testdata.NoVulnInput, testdata.C1}, - InPkg: []*model.PkgInputSpec{testdata.P2, testdata.P1}, - Calls: []call{ - { - Pkg: testdata.P2, - Vuln: testdata.NoVulnInput, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: testdata.T1, - }, - }, - { - Pkg: testdata.P1, - Vuln: testdata.C1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: testdata.T1, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Vulnerability: &model.VulnerabilitySpec{ - Type: ptrfrom.String("cve"), - NoVuln: ptrfrom.Bool(false), - }, - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: testdata.P2out, - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C1out}, - }, - Metadata: vmd1, - }, - { - Package: testdata.P1out, - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C1out}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Query all vulns - with novuln boolean omitted", - InVuln: []*model.VulnerabilityInputSpec{testdata.NoVulnInput, testdata.C1, testdata.G1}, - InPkg: []*model.PkgInputSpec{testdata.P2, testdata.P1, testdata.P1}, - Calls: []call{ - { - Pkg: testdata.P2, - Vuln: testdata.NoVulnInput, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: testdata.T1, - }, - }, - { - Pkg: testdata.P1, - Vuln: testdata.C1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: testdata.T1, - }, - }, - { - Pkg: testdata.P1, - Vuln: testdata.G1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: testdata.T1, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Vulnerability: &model.VulnerabilitySpec{}, - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: testdata.P2out, - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C1out}, - }, - Metadata: vmd1, - }, - { - Package: testdata.P2out, - Vulnerability: &model.Vulnerability{ - Type: "novuln", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.NoVulnOut}, - }, - Metadata: vmd1, - }, - { - Package: testdata.P2out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - Metadata: vmd1, - }, - { - Package: testdata.P2out, - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - Metadata: vmd1, - }, - { - Package: testdata.P2out, - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - Metadata: &model.ScanMetadata{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri 1", - TimeScanned: testdata.T1, - }, - }, - { - Package: testdata.P2out, - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - Metadata: &model.ScanMetadata{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.08.01", - DbURI: "test db uri", - TimeScanned: testdata.T1, - }, - }, - { - Package: testdata.P2out, - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - Metadata: &model.ScanMetadata{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.08.01", - DbURI: "test db uri", - TimeScanned: testTime, - }, - }, - { - Package: testdata.P2out, - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - Metadata: &model.ScanMetadata{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri 1", - DbVersion: "2023.08.01", - DbURI: "test db uri", - TimeScanned: testTime, - }, - }, - { - Package: testdata.P2out, - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - Metadata: &model.ScanMetadata{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.8.0", - ScannerURI: "test scanner uri 1", - DbVersion: "2023.08.01", - DbURI: "test db uri", - TimeScanned: testTime, - }, - }, - { - Package: testdata.P3out, - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - Metadata: vmd1, - }, - { - Package: testdata.P1out, - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C1out}, - }, - Metadata: vmd1, - }, - { - Package: testdata.P1out, - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - Metadata: vmd1, - }, - }, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - for _, g := range test.InVuln { - if vulnIDs, err := b.IngestVulnerability(ctx, *g); err != nil { - t.Fatalf("Could not ingest vulnerability: %a", err) - } else { - if test.QueryVulnID { - test.Query = &model.CertifyVulnSpec{ - Vulnerability: &model.VulnerabilitySpec{ - ID: ptrfrom.String(vulnIDs.VulnerabilityNodeID), - }, - } - } - } - } - if pkgIDs, err := b.IngestPackages(ctx, test.InPkg); err != nil { - t.Fatalf("Could not ingest packages: %v", err) - } else { - if test.QueryPkgID { - test.Query = &model.CertifyVulnSpec{ - Package: &model.PkgSpec{ - ID: ptrfrom.String(pkgIDs[0].PackageVersionID), - }, - } - } - } - ids := make([]string, len(test.Calls)) - for i, o := range test.Calls { - cvID, err := b.IngestCertifyVuln(ctx, *o.Pkg, *o.Vuln, *o.CertifyVuln) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - if test.QueryID { - test.Query = &model.CertifyVulnSpec{ - ID: ptrfrom.String(cvID), - } - } - ids[i] = cvID - } - if test.Query != nil { - if test.Query.ID != nil { - idIndex, err := strconv.Atoi(*test.Query.ID) - if err == nil && idIndex > -1 && idIndex < len(ids) { - test.Query.ID = ptrfrom.String(ids[idIndex]) - } - } - } - got, err := b.CertifyVuln(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpVuln, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func TestIngestCertifyVulns(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - type call struct { - Pkgs []*model.PkgInputSpec - Vulns []*model.VulnerabilityInputSpec - CertifyVulns []*model.ScanMetadataInput - } - - tests := []struct { - InPkg []*model.PkgInputSpec - Name string - InVuln []*model.VulnerabilityInputSpec - Calls []call - ExpVuln []*model.CertifyVuln - Query *model.CertifyVulnSpec - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InVuln: []*model.VulnerabilityInputSpec{testdata.C1, testdata.C2}, - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - Calls: []call{ - { - Pkgs: []*model.PkgInputSpec{testdata.P2, testdata.P1}, - Vulns: []*model.VulnerabilityInputSpec{testdata.C1, testdata.C2}, - CertifyVulns: []*model.ScanMetadataInput{ - { - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: testdata.T1, - }, - { - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: testdata.T1, - }, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Collector: ptrfrom.String("test collector"), - }, - ExpVuln: []*model.CertifyVuln{ - { - ID: "1", - Package: testdata.P2out, - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C1out}, - }, - Metadata: vmd1, - }, - { - ID: "10", - Package: testdata.P1out, - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C2out}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Certify NoVuln", - InVuln: []*model.VulnerabilityInputSpec{testdata.NoVulnInput, testdata.NoVulnInput}, - InPkg: []*model.PkgInputSpec{testdata.P2, testdata.P1}, - Calls: []call{ - { - Pkgs: []*model.PkgInputSpec{testdata.P2, testdata.P1}, - Vulns: []*model.VulnerabilityInputSpec{testdata.NoVulnInput, testdata.NoVulnInput}, - CertifyVulns: []*model.ScanMetadataInput{ - { - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: testdata.T1, - }, - { - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: testdata.T1, - }, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Vulnerability: &model.VulnerabilitySpec{ - Type: ptrfrom.String("noVuln"), - }, - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: testdata.P2out, - Vulnerability: &model.Vulnerability{ - Type: "novuln", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.NoVulnOut}, - }, - Metadata: vmd1, - }, - { - Package: testdata.P1out, - Vulnerability: &model.Vulnerability{ - Type: "novuln", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.NoVulnOut}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Certify OSV", - InVuln: []*model.VulnerabilityInputSpec{testdata.O1}, - InPkg: []*model.PkgInputSpec{testdata.P2}, - Calls: []call{ - { - Pkgs: []*model.PkgInputSpec{testdata.P2}, - Vulns: []*model.VulnerabilityInputSpec{testdata.O1}, - CertifyVulns: []*model.ScanMetadataInput{ - { - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: testdata.T1, - }, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Vulnerability: &model.VulnerabilitySpec{ - Type: ptrfrom.String("osv"), - }, - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: testdata.P2out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Certify GHSA", - InVuln: []*model.VulnerabilityInputSpec{testdata.G1}, - InPkg: []*model.PkgInputSpec{testdata.P2}, - Calls: []call{ - { - Pkgs: []*model.PkgInputSpec{testdata.P2}, - Vulns: []*model.VulnerabilityInputSpec{testdata.G1}, - CertifyVulns: []*model.ScanMetadataInput{ - { - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: testdata.T1, - }, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Vulnerability: &model.VulnerabilitySpec{ - Type: ptrfrom.String("ghsa"), - }, - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: testdata.P2out, - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Query on GHSA", - InVuln: []*model.VulnerabilityInputSpec{testdata.G1, testdata.G2}, - InPkg: []*model.PkgInputSpec{testdata.P2, testdata.P1}, - Calls: []call{ - { - Pkgs: []*model.PkgInputSpec{testdata.P2, testdata.P1}, - Vulns: []*model.VulnerabilityInputSpec{testdata.G1, testdata.G2}, - CertifyVulns: []*model.ScanMetadataInput{ - { - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: testdata.T1, - }, - { - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: testdata.T1, - }, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Vulnerability: &model.VulnerabilitySpec{ - VulnerabilityID: &testdata.G1.VulnerabilityID, - }, - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: testdata.P2out, - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Query on Package", - InVuln: []*model.VulnerabilityInputSpec{testdata.G1, testdata.G2}, - InPkg: []*model.PkgInputSpec{testdata.P3, testdata.P4}, - Calls: []call{ - { - Pkgs: []*model.PkgInputSpec{testdata.P3, testdata.P4}, - Vulns: []*model.VulnerabilityInputSpec{testdata.G1, testdata.G2}, - CertifyVulns: []*model.ScanMetadataInput{ - { - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: testdata.T1, - }, - { - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: testdata.T1, - }, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Package: &model.PkgSpec{ - Name: ptrfrom.String(testdata.P3.Name), - Subpath: ptrfrom.String("saved_model_cli.py"), - }, - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: testdata.P3out, - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Query none", - InVuln: []*model.VulnerabilityInputSpec{testdata.G1, testdata.G2}, - InPkg: []*model.PkgInputSpec{testdata.P2, testdata.P1}, - Calls: []call{ - { - Pkgs: []*model.PkgInputSpec{testdata.P2, testdata.P1}, - Vulns: []*model.VulnerabilityInputSpec{testdata.G1, testdata.G2}, - CertifyVulns: []*model.ScanMetadataInput{ - { - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: testdata.T1, - }, - { - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: testdata.T1, - }, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Vulnerability: &model.VulnerabilitySpec{ - VulnerabilityID: ptrfrom.String("asdf"), - }, - }, - ExpVuln: nil, - }, - { - Name: "Query No Vuln", - InVuln: []*model.VulnerabilityInputSpec{testdata.NoVulnInput, testdata.NoVulnInput}, - InPkg: []*model.PkgInputSpec{testdata.P2, testdata.P1}, - Calls: []call{ - { - Pkgs: []*model.PkgInputSpec{testdata.P2, testdata.P1}, - Vulns: []*model.VulnerabilityInputSpec{testdata.NoVulnInput, testdata.NoVulnInput}, - CertifyVulns: []*model.ScanMetadataInput{ - { - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: testdata.T1, - }, - { - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: testdata.T1, - }, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Vulnerability: &model.VulnerabilitySpec{ - Type: ptrfrom.String("noVuln"), - }, - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: testdata.P2out, - Vulnerability: &model.Vulnerability{ - Type: "novuln", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.NoVulnOut}, - }, - Metadata: vmd1, - }, - { - Package: testdata.P1out, - Vulnerability: &model.Vulnerability{ - Type: "novuln", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.NoVulnOut}, - }, - Metadata: vmd1, - }, - }, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - if _, err := b.IngestVulnerabilities(ctx, test.InVuln); err != nil { - t.Fatalf("Could not ingest vulnerabilities: %a", err) - } - if _, err := b.IngestPackages(ctx, test.InPkg); err != nil { - t.Fatalf("Could not ingest packages: %v", err) - } - for _, o := range test.Calls { - _, err := b.IngestCertifyVulns(ctx, o.Pkgs, o.Vulns, o.CertifyVulns) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - - } - got, err := b.CertifyVuln(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpVuln, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func Test_buildCertifyVulnByID(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - type call struct { - Pkg *model.PkgInputSpec - Vuln *model.VulnerabilityInputSpec - CertifyVuln *model.ScanMetadataInput - } - - tests := []struct { - InPkg []*model.PkgInputSpec - Name string - InVuln []*model.VulnerabilityInputSpec - Calls []call - ExpVuln *model.CertifyVuln - Query *model.CertifyVulnSpec - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "Certify NoVuln", - InVuln: []*model.VulnerabilityInputSpec{testdata.NoVulnInput}, - InPkg: []*model.PkgInputSpec{testdata.P2}, - Calls: []call{ - { - Pkg: testdata.P2, - Vuln: testdata.NoVulnInput, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: testdata.T1, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Vulnerability: &model.VulnerabilitySpec{ - Type: ptrfrom.String("noVuln"), - }, - }, - ExpVuln: &model.CertifyVuln{ - - Package: testdata.P2out, - Vulnerability: &model.Vulnerability{ - Type: "novuln", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.NoVulnOut}, - }, - Metadata: vmd1, - }, - }, - { - Name: "Certify OSV", - InVuln: []*model.VulnerabilityInputSpec{testdata.O1}, - InPkg: []*model.PkgInputSpec{testdata.P2}, - Calls: []call{ - { - Pkg: testdata.P2, - Vuln: testdata.O1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: testdata.T1, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Vulnerability: &model.VulnerabilitySpec{ - Type: ptrfrom.String("osv"), - }, - }, - ExpVuln: &model.CertifyVuln{ - Package: testdata.P2out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - Metadata: vmd1, - }, - }, - { - Name: "Certify GHSA", - InVuln: []*model.VulnerabilityInputSpec{testdata.G1}, - InPkg: []*model.PkgInputSpec{testdata.P2}, - Calls: []call{ - { - Pkg: testdata.P2, - Vuln: testdata.G1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: testdata.T1, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Vulnerability: &model.VulnerabilitySpec{ - VulnerabilityID: &testdata.G1.VulnerabilityID, - }, - }, - ExpVuln: &model.CertifyVuln{ - Package: testdata.P2out, - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - Metadata: vmd1, - }, - }, - { - Name: "Query on GHSA", - InVuln: []*model.VulnerabilityInputSpec{testdata.G1}, - InPkg: []*model.PkgInputSpec{testdata.P2}, - Calls: []call{ - { - Pkg: testdata.P2, - Vuln: testdata.G1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: testdata.T1, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Vulnerability: &model.VulnerabilitySpec{ - VulnerabilityID: &testdata.G1.VulnerabilityID, - }, - }, - ExpVuln: &model.CertifyVuln{ - Package: testdata.P2out, - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - Metadata: vmd1, - }, - }, - { - Name: "Query ID", - InVuln: []*model.VulnerabilityInputSpec{testdata.G1}, - InPkg: []*model.PkgInputSpec{testdata.P2}, - Calls: []call{ - { - Pkg: testdata.P2, - Vuln: testdata.G1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: testdata.T1, - }, - }, - }, - ExpVuln: &model.CertifyVuln{ - Package: testdata.P2out, - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - Metadata: vmd1, - }, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - for _, g := range test.InVuln { - if _, err := b.IngestVulnerability(ctx, *g); err != nil { - t.Fatalf("Could not ingest vulnerability: %a", err) - } - } - if _, err := b.IngestPackages(ctx, test.InPkg); err != nil { - t.Fatalf("Could not ingest packages: %v", err) - } - - for _, o := range test.Calls { - cvID, err := b.IngestCertifyVuln(ctx, *o.Pkg, *o.Vuln, *o.CertifyVuln) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - - got, err := b.(*arangoClient).buildCertifyVulnByID(ctx, cvID, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpVuln, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - } - }) - } -} diff --git a/pkg/assembler/backends/arangodb/hasMetadata.go b/pkg/assembler/backends/arangodb/hasMetadata.go index d10bd67f23..dd5d0b3fb7 100644 --- a/pkg/assembler/backends/arangodb/hasMetadata.go +++ b/pkg/assembler/backends/arangodb/hasMetadata.go @@ -363,7 +363,7 @@ func (c *arangoClient) IngestHasMetadata(ctx context.Context, subject model.Pack RETURN { 'hasMetadata_id': hasMetadata._id }` - cursor, err = executeQueryWithRetry(ctx, c.db, query, getHasMetadataQueryValues(subject.Package, pkgMatchType, nil, nil, &hasMetadata), "IngestHasMetadata - PkgVersion") + cursor, err = executeQueryWithRetry(ctx, c.db, query, getHasMetadataQueryValues(subject.Package.PackageInput, pkgMatchType, nil, nil, &hasMetadata), "IngestHasMetadata - PkgVersion") if err != nil { return "", fmt.Errorf("failed to ingest package hasMetadata: %w", err) } @@ -396,7 +396,7 @@ func (c *arangoClient) IngestHasMetadata(ctx context.Context, subject model.Pack RETURN { 'hasMetadata_id': hasMetadata._id }` - cursor, err = executeQueryWithRetry(ctx, c.db, query, getHasMetadataQueryValues(subject.Package, pkgMatchType, nil, nil, &hasMetadata), "IngestHasMetadata - PkgName") + cursor, err = executeQueryWithRetry(ctx, c.db, query, getHasMetadataQueryValues(subject.Package.PackageInput, pkgMatchType, nil, nil, &hasMetadata), "IngestHasMetadata - PkgName") if err != nil { return "", fmt.Errorf("failed to ingest package hasMetadata: %w", err) } @@ -421,7 +421,7 @@ func (c *arangoClient) IngestHasMetadata(ctx context.Context, subject model.Pack RETURN { 'hasMetadata_id': hasMetadata._id }` - cursor, err = executeQueryWithRetry(ctx, c.db, query, getHasMetadataQueryValues(nil, nil, subject.Artifact, nil, &hasMetadata), "IngestHasMetadata - artifact") + cursor, err = executeQueryWithRetry(ctx, c.db, query, getHasMetadataQueryValues(nil, nil, subject.Artifact.ArtifactInput, nil, &hasMetadata), "IngestHasMetadata - artifact") if err != nil { return "", fmt.Errorf("failed to ingest artifact hasMetadata: %w", err) } @@ -453,7 +453,7 @@ func (c *arangoClient) IngestHasMetadata(ctx context.Context, subject model.Pack RETURN { 'hasMetadata_id': hasMetadata._id }` - cursor, err = executeQueryWithRetry(ctx, c.db, query, getHasMetadataQueryValues(nil, nil, nil, subject.Source, &hasMetadata), "IngestHasMetadata - source") + cursor, err = executeQueryWithRetry(ctx, c.db, query, getHasMetadataQueryValues(nil, nil, nil, subject.Source.SourceInput, &hasMetadata), "IngestHasMetadata - source") if err != nil { return "", fmt.Errorf("failed to ingest source hasMetadata: %w", err) } @@ -481,7 +481,7 @@ func (c *arangoClient) IngestBulkHasMetadata(ctx context.Context, subjects model var listOfValues []map[string]any for i := range subjects.Packages { - listOfValues = append(listOfValues, getHasMetadataQueryValues(subjects.Packages[i], pkgMatchType, nil, nil, hasMetadataList[i])) + listOfValues = append(listOfValues, getHasMetadataQueryValues(subjects.Packages[i].PackageInput, pkgMatchType, nil, nil, hasMetadataList[i])) } var documents []string @@ -580,7 +580,7 @@ func (c *arangoClient) IngestBulkHasMetadata(ctx context.Context, subjects model var listOfValues []map[string]any for i := range subjects.Artifacts { - listOfValues = append(listOfValues, getHasMetadataQueryValues(nil, nil, subjects.Artifacts[i], nil, hasMetadataList[i])) + listOfValues = append(listOfValues, getHasMetadataQueryValues(nil, nil, subjects.Artifacts[i].ArtifactInput, nil, hasMetadataList[i])) } var documents []string @@ -634,7 +634,7 @@ func (c *arangoClient) IngestBulkHasMetadata(ctx context.Context, subjects model var listOfValues []map[string]any for i := range subjects.Sources { - listOfValues = append(listOfValues, getHasMetadataQueryValues(nil, nil, nil, subjects.Sources[i], hasMetadataList[i])) + listOfValues = append(listOfValues, getHasMetadataQueryValues(nil, nil, nil, subjects.Sources[i].SourceInput, hasMetadataList[i])) } var documents []string diff --git a/pkg/assembler/backends/arangodb/hasMetadata_test.go b/pkg/assembler/backends/arangodb/hasMetadata_test.go deleted file mode 100644 index 475c34cdec..0000000000 --- a/pkg/assembler/backends/arangodb/hasMetadata_test.go +++ /dev/null @@ -1,1395 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build integration - -package arangodb - -import ( - "context" - "strings" - "testing" - "time" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/internal/testing/testdata" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -func TestHasMetadata(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - type call struct { - Sub model.PackageSourceOrArtifactInput - Match *model.MatchFlags - HM *model.HasMetadataInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - InArt []*model.ArtifactInputSpec - Calls []call - Query *model.HasMetadataSpec - QueryID bool - QueryPkgID bool - QuerySourceID bool - QueryArtID bool - ExpHM []*model.HasMetadata - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{testdata.P1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Key: "key1", - Value: "value1", - Timestamp: time.Unix(1e9, 0), - Justification: "test justification", - }, - }, - }, - Query: &model.HasMetadataSpec{ - Key: ptrfrom.String("key1"), - Value: ptrfrom.String("value1"), - Since: ptrfrom.Time(time.Unix(1e9, 0)), - Justification: ptrfrom.String("test justification"), - }, - ExpHM: []*model.HasMetadata{ - { - Subject: testdata.P1out, - Key: "key1", - Value: "value1", - Timestamp: time.Unix(1e9, 0), - Justification: "test justification", - }, - }, - }, - { - Name: "HappyPath check time since", - InPkg: []*model.PkgInputSpec{testdata.P1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Key: "key1", - Value: "value1", - Timestamp: time.Unix(1e9, 0), - Justification: "test justification", - }, - }, - }, - Query: &model.HasMetadataSpec{ - Key: ptrfrom.String("key1"), - Value: ptrfrom.String("value1"), - Since: ptrfrom.Time(time.Unix(1e8, 0)), - Justification: ptrfrom.String("test justification"), - }, - ExpHM: []*model.HasMetadata{ - { - Subject: testdata.P1out, - Key: "key1", - Value: "value1", - Timestamp: time.Unix(1e9, 0), - Justification: "test justification", - }, - }, - }, - { - Name: "UnhappyPath check time since", - InPkg: []*model.PkgInputSpec{testdata.P1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Key: "key1", - Value: "value1", - Timestamp: time.Unix(1e9, 0), - Justification: "test justification", - }, - }, - }, - Query: &model.HasMetadataSpec{ - Key: ptrfrom.String("key1"), - Value: ptrfrom.String("value1"), - Since: ptrfrom.Time(time.Unix(1e10, 0)), - Justification: ptrfrom.String("test justification"), - }, - ExpHM: nil, - }, - { - Name: "HappyPath All Version", - InPkg: []*model.PkgInputSpec{testdata.P1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.HasMetadataSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHM: []*model.HasMetadata{ - { - Subject: testdata.P1out, - Key: "key1", - Value: "value1", - Timestamp: time.Unix(1e9, 0), - Justification: "test justification", - }, - { - Subject: testdata.P1outName, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest same twice", - InPkg: []*model.PkgInputSpec{testdata.P3}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P3, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P3, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.HasMetadataSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String("2.11.1"), - Subpath: ptrfrom.String("saved_model_cli.py"), - }, - }, - }, - ExpHM: []*model.HasMetadata{ - { - Subject: testdata.P3out, - Justification: "test justification", - }, - { - Subject: testdata.P1outName, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest two different keys - query key", - InPkg: []*model.PkgInputSpec{testdata.P1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Key: "key1", - Value: "value1", - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Key: "key2", - Value: "value2", - Justification: "test justification", - }, - }, - }, - Query: &model.HasMetadataSpec{ - Key: ptrfrom.String("key2"), - }, - ExpHM: []*model.HasMetadata{ - { - Subject: testdata.P1out, - Key: "key2", - Value: "value2", - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest two different keys - query value", - InPkg: []*model.PkgInputSpec{testdata.P1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Key: "key1", - Value: "value1", - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Key: "key2", - Value: "value2", - Justification: "test justification", - }, - }, - }, - Query: &model.HasMetadataSpec{ - Value: ptrfrom.String("value1"), - }, - ExpHM: []*model.HasMetadata{ - { - Subject: testdata.P1out, - Key: "key1", - Value: "value1", - Timestamp: time.Unix(1e9, 0), - Justification: "test justification", - }, - { - Subject: testdata.P1out, - Key: "key1", - Value: "value1", - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Justification", - InPkg: []*model.PkgInputSpec{testdata.P1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification one", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification two", - }, - }, - }, - Query: &model.HasMetadataSpec{ - Justification: ptrfrom.String("test justification one"), - }, - ExpHM: []*model.HasMetadata{ - { - Subject: testdata.P1out, - Justification: "test justification one", - }, - }, - }, - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P4}, - InSrc: []*model.SourceInputSpec{testdata.S1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P4, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.HasMetadataSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Package: &model.PkgSpec{ - Type: ptrfrom.String("conan"), - Namespace: ptrfrom.String("openssl.org"), - Name: ptrfrom.String("openssl"), - }, - }, - }, - ExpHM: []*model.HasMetadata{ - { - Subject: testdata.P4out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Package version ID", - InPkg: []*model.PkgInputSpec{testdata.P4}, - InSrc: []*model.SourceInputSpec{}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P4, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - }, - QueryPkgID: true, - ExpHM: []*model.HasMetadata{ - { - Subject: testdata.P4out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Source", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InSrc: []*model.SourceInputSpec{testdata.S1, testdata.S2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S2, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.HasMetadataSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Source: &model.SourceSpec{ - Name: ptrfrom.String("bobsrepo"), - }, - }, - }, - ExpHM: []*model.HasMetadata{ - { - Subject: testdata.S2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Source ID", - InPkg: []*model.PkgInputSpec{}, - InSrc: []*model.SourceInputSpec{testdata.S2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S2, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - }, - QuerySourceID: true, - ExpHM: []*model.HasMetadata{ - { - Subject: testdata.S2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Artifact", - InSrc: []*model.SourceInputSpec{testdata.S1}, - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A1, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.HasMetadataSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha1"), - }, - }, - }, - ExpHM: []*model.HasMetadata{ - { - Subject: testdata.A2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Artifact ID", - InSrc: []*model.SourceInputSpec{}, - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A1, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - }, - QueryArtID: true, - ExpHM: []*model.HasMetadata{ - { - Subject: testdata.A2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query none", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A1, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.HasMetadataSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("asdf"), - }, - }, - }, - ExpHM: nil, - }, - { - Name: "Query multiple", - InSrc: []*model.SourceInputSpec{testdata.S1, testdata.S2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S2, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.HasMetadataSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Source: &model.SourceSpec{ - Type: ptrfrom.String("git"), - }, - }}, - ExpHM: []*model.HasMetadata{ - { - Subject: testdata.S2out, - Justification: "test justification", - }, - { - Subject: testdata.S1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query Packages", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2, testdata.P4}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P4, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.HasMetadataSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Package: &model.PkgSpec{ - Name: ptrfrom.String("openssl"), - Version: ptrfrom.String("3.0.3"), - }, - }, - }, - ExpHM: []*model.HasMetadata{ - { - Subject: testdata.P4out, - Justification: "test justification", - }, - { - Subject: testdata.P4outName, - Justification: "test justification", - }, - }, - }, - { - Name: "Query ID", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A1, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - }, - QueryID: true, - ExpHM: []*model.HasMetadata{ - { - Subject: testdata.A2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query bad ID", - InSrc: []*model.SourceInputSpec{testdata.S1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.HasMetadataSpec{ - ID: ptrfrom.String("asdf"), - }, - ExpQueryErr: true, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - for _, p := range test.InPkg { - if pkgIDs, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } else { - if test.QueryPkgID { - test.Query = &model.HasMetadataSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Package: &model.PkgSpec{ - ID: ptrfrom.String(pkgIDs.PackageVersionID), - }, - }, - } - } - } - } - for _, s := range test.InSrc { - if srcIDs, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } else { - if test.QuerySourceID { - test.Query = &model.HasMetadataSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Source: &model.SourceSpec{ - ID: ptrfrom.String(srcIDs.SourceNameID), - }, - }, - } - } - } - } - for _, a := range test.InArt { - if artID, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } else { - if test.QueryArtID { - test.Query = &model.HasMetadataSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - ID: ptrfrom.String(artID), - }, - }, - } - } - } - } - for _, o := range test.Calls { - hmID, err := b.IngestHasMetadata(ctx, o.Sub, o.Match, *o.HM) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - if test.QueryID { - test.Query = &model.HasMetadataSpec{ - ID: ptrfrom.String(hmID), - } - } - } - got, err := b.HasMetadata(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpHM, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func TestIngestBulkHasMetadata(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - type call struct { - Sub model.PackageSourceOrArtifactInputs - Match *model.MatchFlags - HM []*model.HasMetadataInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - InArt []*model.ArtifactInputSpec - Calls []call - Query *model.HasMetadataSpec - ExpHM []*model.HasMetadata - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{testdata.P1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: []*model.HasMetadataInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.HasMetadataSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHM: []*model.HasMetadata{ - { - Subject: testdata.P1out, - Justification: "test justification", - }, - }, - }, - { - Name: "HappyPath All Version", - InPkg: []*model.PkgInputSpec{testdata.P1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - HM: []*model.HasMetadataInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.HasMetadataSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHM: []*model.HasMetadata{ - { - Subject: testdata.P1out, - Justification: "test justification", - }, - { - Subject: testdata.P1outName, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest same twice", - InPkg: []*model.PkgInputSpec{testdata.P3}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P3, testdata.P3}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: []*model.HasMetadataInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.HasMetadataSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String("2.11.1"), - Subpath: ptrfrom.String("saved_model_cli.py"), - }, - }, - }, - ExpHM: []*model.HasMetadata{ - { - Subject: testdata.P3out, - Justification: "test justification", - }, - { - Subject: testdata.P1outName, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P4}, - InSrc: []*model.SourceInputSpec{testdata.S1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1, testdata.P4}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: []*model.HasMetadataInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - { - Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{testdata.S1}, - }, - HM: []*model.HasMetadataInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.HasMetadataSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Package: &model.PkgSpec{ - Type: ptrfrom.String("conan"), - Namespace: ptrfrom.String("openssl.org"), - Name: ptrfrom.String("openssl"), - }, - }, - }, - ExpHM: []*model.HasMetadata{ - { - Subject: testdata.P4out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Source", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InSrc: []*model.SourceInputSpec{testdata.S1, testdata.S2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: []*model.HasMetadataInputSpec{ - { - Justification: "test justification", - }, - }, - }, - { - Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{testdata.S2, testdata.S2}, - }, - HM: []*model.HasMetadataInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.HasMetadataSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Source: &model.SourceSpec{ - Name: ptrfrom.String("bobsrepo"), - }, - }, - }, - ExpHM: []*model.HasMetadata{ - { - Subject: testdata.S2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Artifact", - InSrc: []*model.SourceInputSpec{testdata.S1}, - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Artifacts: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - }, - HM: []*model.HasMetadataInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - { - Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{testdata.S1}, - }, - HM: []*model.HasMetadataInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.HasMetadataSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha1"), - }, - }, - }, - ExpHM: []*model.HasMetadata{ - { - Subject: testdata.A2out, - Justification: "test justification", - }, - }, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - for _, o := range test.Calls { - _, err := b.IngestBulkHasMetadata(ctx, o.Sub, o.Match, o.HM) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.HasMetadata(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpHM, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func Test_buildHasMetadataByID(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - type call struct { - Sub model.PackageSourceOrArtifactInput - Match *model.MatchFlags - HM *model.HasMetadataInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - InArt []*model.ArtifactInputSpec - Calls []call - Query *model.HasMetadataSpec - ExpHM *model.HasMetadata - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{testdata.P4}, - InSrc: []*model.SourceInputSpec{}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P4, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.HasMetadataSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Package: &model.PkgSpec{ - Type: ptrfrom.String("conan"), - Namespace: ptrfrom.String("openssl.org"), - Name: ptrfrom.String("openssl"), - }, - }, - }, - ExpHM: &model.HasMetadata{ - Subject: testdata.P4out, - Justification: "test justification", - }, - }, - { - Name: "Query on Package without filter", - InPkg: []*model.PkgInputSpec{testdata.P4}, - InSrc: []*model.SourceInputSpec{}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P4, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - }, - ExpHM: &model.HasMetadata{ - Subject: testdata.P4out, - Justification: "test justification", - }, - }, - { - Name: "Query on Source", - InSrc: []*model.SourceInputSpec{testdata.S2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S2, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.HasMetadataSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Source: &model.SourceSpec{ - Name: ptrfrom.String("bobsrepo"), - }, - }, - }, - ExpHM: &model.HasMetadata{ - Subject: testdata.S2out, - Justification: "test justification", - }, - }, - { - Name: "Query on Source without filter", - InSrc: []*model.SourceInputSpec{testdata.S2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S2, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - }, - ExpHM: &model.HasMetadata{ - - Subject: testdata.S2out, - Justification: "test justification", - }, - }, - { - Name: "Query on Artifact", - InArt: []*model.ArtifactInputSpec{testdata.A2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.HasMetadataSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha1"), - }, - }, - }, - ExpHM: &model.HasMetadata{ - Subject: testdata.A2out, - Justification: "test justification", - }, - }, - { - Name: "Query on Artifact without filter", - InSrc: []*model.SourceInputSpec{}, - InArt: []*model.ArtifactInputSpec{testdata.A2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - }, - ExpHM: &model.HasMetadata{ - Subject: testdata.A2out, - Justification: "test justification", - }, - }, - { - Name: "Query ID", - InArt: []*model.ArtifactInputSpec{testdata.A2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - }, - ExpHM: &model.HasMetadata{ - Subject: testdata.A2out, - Justification: "test justification", - }, - }, - { - Name: "Query bad ID", - InSrc: []*model.SourceInputSpec{testdata.S1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.HasMetadataSpec{ - ID: ptrfrom.String("asdf"), - }, - ExpQueryErr: true, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - for _, o := range test.Calls { - hsID, err := b.IngestHasMetadata(ctx, o.Sub, o.Match, *o.HM) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - got, err := b.(*arangoClient).buildHasMetadataByID(ctx, hsID, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpHM, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - } - - }) - } -} diff --git a/pkg/assembler/backends/arangodb/hasSBOM.go b/pkg/assembler/backends/arangodb/hasSBOM.go index c0dd83cd8a..73cbcfc1dc 100644 --- a/pkg/assembler/backends/arangodb/hasSBOM.go +++ b/pkg/assembler/backends/arangodb/hasSBOM.go @@ -279,7 +279,7 @@ func (c *arangoClient) IngestHasSBOMs(ctx context.Context, subjects model.Packag var listOfValues []map[string]any for i := range subjects.Packages { - listOfValues = append(listOfValues, getHasSBOMQueryValues(subjects.Packages[i], nil, hasSBOMs[i], includes[i])) + listOfValues = append(listOfValues, getHasSBOMQueryValues(subjects.Packages[i].PackageInput, nil, hasSBOMs[i], includes[i])) } var documents []string @@ -358,7 +358,7 @@ func (c *arangoClient) IngestHasSBOMs(ctx context.Context, subjects model.Packag var listOfValues []map[string]any for i := range subjects.Artifacts { - listOfValues = append(listOfValues, getHasSBOMQueryValues(nil, subjects.Artifacts[i], hasSBOMs[i], includes[i])) + listOfValues = append(listOfValues, getHasSBOMQueryValues(nil, subjects.Artifacts[i].ArtifactInput, hasSBOMs[i], includes[i])) } var documents []string @@ -479,7 +479,7 @@ func (c *arangoClient) IngestHasSbom(ctx context.Context, subject model.PackageO RETURN { 'hasSBOM_id': hasSBOM._id }` - cursor, err = executeQueryWithRetry(ctx, c.db, query, getHasSBOMQueryValues(nil, subject.Artifact, &hasSbom, &includes), "IngestHasSbom - Artifact") + cursor, err = executeQueryWithRetry(ctx, c.db, query, getHasSBOMQueryValues(nil, subject.Artifact.ArtifactInput, &hasSbom, &includes), "IngestHasSbom - Artifact") if err != nil { return "", fmt.Errorf("failed to ingest hasSBOM: %w", err) } @@ -537,7 +537,7 @@ func (c *arangoClient) IngestHasSbom(ctx context.Context, subject model.PackageO RETURN { 'hasSBOM_id': hasSBOM._id }` - cursor, err = executeQueryWithRetry(ctx, c.db, query, getHasSBOMQueryValues(subject.Package, nil, &hasSbom, &includes), "IngestHasSbom - Package") + cursor, err = executeQueryWithRetry(ctx, c.db, query, getHasSBOMQueryValues(subject.Package.PackageInput, nil, &hasSbom, &includes), "IngestHasSbom - Package") if err != nil { return "", fmt.Errorf("failed to create ingest hasSBOM: %w", err) } diff --git a/pkg/assembler/backends/arangodb/hasSBOM_test.go b/pkg/assembler/backends/arangodb/hasSBOM_test.go deleted file mode 100644 index 3ddcd8fb34..0000000000 --- a/pkg/assembler/backends/arangodb/hasSBOM_test.go +++ /dev/null @@ -1,3335 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build integration - -package arangodb - -import ( - "context" - "strings" - "testing" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/internal/testing/testdata" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -type testDependency struct { - pkg *model.PkgInputSpec - depPkg *model.PkgInputSpec - matchType model.MatchFlags - isDep *model.IsDependencyInputSpec -} - -type testOccurrence struct { - Subj *model.PackageOrSourceInput - Art *model.ArtifactInputSpec - isOcc *model.IsOccurrenceInputSpec -} - -// Test resources - -var includedPackage1QualifierKey = "p1_key" -var includedPackage1QualifierValue = "p1_value" - -var includedPackage1 = &model.PkgInputSpec{ - Type: "p1_type", - Namespace: ptrfrom.String("p1_namespace"), - Name: "p1_name", - Version: ptrfrom.String("v1.0.0-p1version"), - Qualifiers: []*model.PackageQualifierInputSpec{{ - Key: includedPackage1QualifierKey, - Value: includedPackage1QualifierValue, - }}, - Subpath: ptrfrom.String("p1_subpath"), -} - -var includedPackage2QualifierKey = "p2_key" -var includedPackage2QualifierValue = "p2_value" - -var includedPackage2 = &model.PkgInputSpec{ - Type: "p2_type", - Namespace: ptrfrom.String("p2_namespace"), - Name: "p2_name", - Version: ptrfrom.String("v1.0.0-p2version"), - Qualifiers: []*model.PackageQualifierInputSpec{{ - Key: includedPackage2QualifierKey, - Value: includedPackage2QualifierValue, - }}, - Subpath: ptrfrom.String("p2_subpath"), -} - -var includedPackage3 = &model.PkgInputSpec{ - Type: "p3_type", - Namespace: ptrfrom.String("p3_namespace"), - Name: "p3_name", - Version: ptrfrom.String("v1.0.0-p3version"), - Qualifiers: []*model.PackageQualifierInputSpec{}, - Subpath: ptrfrom.String("p3_subpath"), -} - -var includedPackages = []*model.PkgInputSpec{includedPackage1, includedPackage2, includedPackage3} - -var includedArtifact1 = &model.ArtifactInputSpec{ - Algorithm: "a1_algorithm", - Digest: "a1_digest", -} - -var includedArtifact2 = &model.ArtifactInputSpec{ - Algorithm: "a2_algorithm", - Digest: "a2_digest", -} - -var includedArtifacts = []*model.ArtifactInputSpec{includedArtifact1, includedArtifact2} - -var includedPackageArtifacts = &model.PackageOrArtifactInputs{ - Packages: includedPackages, - Artifacts: includedArtifacts, -} - -var includedDependency1 = &model.IsDependencyInputSpec{ - VersionRange: "dep1_range", - DependencyType: model.DependencyTypeDirect, - Justification: "dep1_justification", - Origin: "dep1_origin", - Collector: "dep1_collector", -} - -var includedDependency2 = &model.IsDependencyInputSpec{ - VersionRange: "dep2_range", - DependencyType: model.DependencyTypeIndirect, - Justification: "dep2_justification", - Origin: "dep2_origin", - Collector: "dep2_collector", -} - -var includedTestDependency1 = &testDependency{ - pkg: includedPackage1, - depPkg: includedPackage2, - matchType: mSpecific, - isDep: includedDependency1, -} - -var includedTestDependency2 = &testDependency{ - pkg: includedPackage1, - depPkg: includedPackage3, - matchType: mSpecific, - isDep: includedDependency2, -} - -var includedTestDependencies = []testDependency{*includedTestDependency1, *includedTestDependency2} - -var includedSource = &model.SourceInputSpec{ - Type: "src_type", - Namespace: "src_namespace", - Name: "src_name", - Tag: ptrfrom.String("src_tag"), - Commit: ptrfrom.String("src_commit"), -} - -var includedSources = []*model.SourceInputSpec{includedSource} - -var includedOccurrence = &model.IsOccurrenceInputSpec{ - Justification: "occ_justification", - Origin: "occ_origin", - Collector: "occ_collector", -} - -var includedTestOccurrences = []testOccurrence{{ - Subj: &model.PackageOrSourceInput{Package: includedPackage1}, - Art: includedArtifact1, - isOcc: includedOccurrence, -}, { - Subj: &model.PackageOrSourceInput{Source: includedSource}, - Art: includedArtifact1, - isOcc: includedOccurrence, -}} - -// var includedHasSBOM = &model.HasSBOMInputSpec{ -// URI: "sbom_URI", -// Algorithm: "sbom_algorithm", -// Digest: "sbom_digest", -// DownloadLocation: "sbom_download_location", -// Origin: "sbom_origin", -// Collector: "sbom_collector", -// } - -var includedTestExpectedPackage1 = &model.Package{ - Type: "p1_type", - Namespaces: []*model.PackageNamespace{{ - Namespace: "p1_namespace", - Names: []*model.PackageName{{ - Name: "p1_name", - Versions: []*model.PackageVersion{{ - Version: "v1.0.0-p1version", - Qualifiers: []*model.PackageQualifier{{ - Key: includedPackage1QualifierKey, - Value: includedPackage1QualifierValue, - }}, - Subpath: "p1_subpath", - }}, - }}, - }}, -} - -var includedTestExpectedPackage2 = &model.Package{ - Type: "p2_type", - Namespaces: []*model.PackageNamespace{{ - Namespace: "p2_namespace", - Names: []*model.PackageName{{ - Name: "p2_name", - Versions: []*model.PackageVersion{{ - Version: "v1.0.0-p2version", - Qualifiers: []*model.PackageQualifier{{ - Key: includedPackage2QualifierKey, - Value: includedPackage2QualifierValue, - }}, - Subpath: "p2_subpath", - }}, - }}, - }}, -} - -var includedTestExpectedPackage3 = &model.Package{ - Type: "p3_type", - Namespaces: []*model.PackageNamespace{{ - Namespace: "p3_namespace", - Names: []*model.PackageName{{ - Name: "p3_name", - Versions: []*model.PackageVersion{{ - Version: "v1.0.0-p3version", - Qualifiers: []*model.PackageQualifier{}, - Subpath: "p3_subpath", - }}, - }}, - }}, -} - -var includedTestExpectedArtifact1 = &model.Artifact{ - Algorithm: "a1_algorithm", - Digest: "a1_digest", -} - -var includedTestExpectedArtifact2 = &model.Artifact{ - Algorithm: "a2_algorithm", - Digest: "a2_digest", -} - -var includedTestExpectedSource = &model.Source{ - Type: "src_type", - Namespaces: []*model.SourceNamespace{{ - Namespace: "src_namespace", - Names: []*model.SourceName{{ - Name: "src_name", - Tag: ptrfrom.String("src_tag"), - Commit: ptrfrom.String("src_commit"), - }}, - }}, -} - -// var includedTestExpectedSBOM = &model.HasSbom{ -// Subject: includedTestExpectedPackage1, -// URI: "sbom_URI", -// Algorithm: "sbom_algorithm", -// Digest: "sbom_digest", -// DownloadLocation: "sbom_download_location", -// Origin: "sbom_origin", -// Collector: "sbom_collector", -// IncludedSoftware: []model.PackageOrArtifact{ -// includedTestExpectedPackage1, -// includedTestExpectedPackage2, -// includedTestExpectedPackage3, -// includedTestExpectedArtifact1, -// includedTestExpectedArtifact2, -// }, -// IncludedDependencies: []*model.IsDependency{{ -// Package: includedTestExpectedPackage1, -// DependencyPackage: includedTestExpectedPackage2, -// VersionRange: "dep1_range", -// DependencyType: model.DependencyTypeDirect, -// Justification: "dep1_justification", -// Origin: "dep1_origin", -// Collector: "dep1_collector", -// }, { -// Package: includedTestExpectedPackage1, -// DependencyPackage: includedTestExpectedPackage3, -// VersionRange: "dep2_range", -// DependencyType: model.DependencyTypeIndirect, -// Justification: "dep2_justification", -// Origin: "dep2_origin", -// Collector: "dep2_collector", -// }}, -// IncludedOccurrences: []*model.IsOccurrence{{ -// Subject: includedTestExpectedPackage1, -// Artifact: includedTestExpectedArtifact1, -// Justification: "occ_justification", -// Origin: "occ_origin", -// Collector: "occ_collector", -// }, { -// Subject: includedTestExpectedSource, -// Artifact: includedTestExpectedArtifact1, -// Justification: "occ_justification", -// Origin: "occ_origin", -// Collector: "occ_collector", -// }}, -// } - -// End of Test resources - -// func TestHasSBOM(t *testing.T) { -// ctx := context.Background() -// arangoArgs := getArangoConfig() -// err := DeleteDatabase(ctx, arangoArgs) -// if err != nil { -// t.Fatalf("error deleting arango database: %v", err) -// } -// b, err := getBackend(ctx, arangoArgs) -// if err != nil { -// t.Fatalf("error creating arango backend: %v", err) -// } -// curTime := time.Now() -// timeAfterOneSecond := curTime.Add(time.Second) -// type call struct { -// Sub model.PackageOrArtifactInput -// HS *model.HasSBOMInputSpec -// Inc *model.HasSBOMIncludesInputSpec -// } -// tests := []struct { -// Name string -// InPkg []*model.PkgInputSpec -// InArt []*model.ArtifactInputSpec -// PkgArt *model.PackageOrArtifactInputs -// InSrc []*model.SourceInputSpec -// IsDeps []testDependency -// IsOccs []testOccurrence -// Calls []call -// Query *model.HasSBOMSpec -// QueryID bool -// QueryPkgID bool -// QueryArtID bool -// QueryIncludePkgID bool -// QueryIncludeArtID bool -// QueryIncludeDepID bool -// QueryIncludeOccurID bool -// QueryIncludeDepMainPkgID bool -// QueryIncludeDepPkgID bool -// QueryIncludeOccurPkgID bool -// QueryIncludeOccurArtID bool -// QueryIncludeOccurSrcID bool -// ExpHS []*model.HasSbom -// ExpIngestErr bool -// ExpQueryErr bool -// }{ -// { -// Name: "Includes - include without filters", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{}}, -// ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, -// }, -// { -// Name: "HappyPath", -// InPkg: []*model.PkgInputSpec{testdata.P1}, -// PkgArt: &model.PackageOrArtifactInputs{ -// Packages: []*model.PkgInputSpec{testdata.P1}, -// }, -// Calls: []call{ -// { -// Sub: model.PackageOrArtifactInput{ -// Package: testdata.P1, -// }, -// HS: &model.HasSBOMInputSpec{ -// URI: "test uri", -// }, -// }, -// }, -// Query: &model.HasSBOMSpec{ -// URI: ptrfrom.String("test uri"), -// }, -// ExpHS: []*model.HasSbom{ -// { -// Subject: testdata.P1out, -// URI: "test uri", -// IncludedSoftware: []model.PackageOrArtifact{testdata.P1out}, -// }, -// }, -// }, -// { -// Name: "Ingest same twice", -// InPkg: []*model.PkgInputSpec{testdata.P1}, -// PkgArt: &model.PackageOrArtifactInputs{ -// Packages: []*model.PkgInputSpec{testdata.P1}, -// }, -// Calls: []call{ -// { -// Sub: model.PackageOrArtifactInput{ -// Package: testdata.P1, -// }, -// HS: &model.HasSBOMInputSpec{ -// URI: "test uri", -// }, -// }, -// { -// Sub: model.PackageOrArtifactInput{ -// Package: testdata.P1, -// }, -// HS: &model.HasSBOMInputSpec{ -// URI: "test uri", -// }, -// }, -// }, -// Query: &model.HasSBOMSpec{ -// URI: ptrfrom.String("test uri"), -// }, -// ExpHS: []*model.HasSbom{ -// { -// Subject: testdata.P1out, -// URI: "test uri", -// IncludedSoftware: []model.PackageOrArtifact{testdata.P1out}, -// }, -// }, -// }, -// { -// Name: "Query on URI", -// InPkg: []*model.PkgInputSpec{testdata.P1}, -// PkgArt: &model.PackageOrArtifactInputs{ -// Packages: []*model.PkgInputSpec{testdata.P1}, -// }, -// Calls: []call{ -// { -// Sub: model.PackageOrArtifactInput{ -// Package: testdata.P1, -// }, -// HS: &model.HasSBOMInputSpec{ -// URI: "test uri one", -// }, -// }, -// { -// Sub: model.PackageOrArtifactInput{ -// Package: testdata.P1, -// }, -// HS: &model.HasSBOMInputSpec{ -// URI: "test uri two", -// }, -// }, -// }, -// Query: &model.HasSBOMSpec{ -// URI: ptrfrom.String("test uri one"), -// }, -// ExpHS: []*model.HasSbom{ -// { -// Subject: testdata.P1out, -// URI: "test uri one", -// IncludedSoftware: []model.PackageOrArtifact{testdata.P1out}, -// }, -// }, -// }, -// { -// Name: "Query on URI and KnownSince", -// InPkg: []*model.PkgInputSpec{testdata.P1}, -// Calls: []call{ -// { -// Sub: model.PackageOrArtifactInput{ -// Package: testdata.P1, -// }, -// HS: &model.HasSBOMInputSpec{ -// URI: "test uri one", -// KnownSince: curTime, -// }, -// }, -// { -// Sub: model.PackageOrArtifactInput{ -// Package: testdata.P1, -// }, -// HS: &model.HasSBOMInputSpec{ -// URI: "test uri two", -// KnownSince: timeAfterOneSecond, -// }, -// }, -// }, -// Query: &model.HasSBOMSpec{ -// URI: ptrfrom.String("test uri one"), -// KnownSince: ptrfrom.Time(curTime), -// }, -// ExpHS: []*model.HasSbom{ -// { -// Subject: testdata.P1out, -// URI: "test uri one", -// KnownSince: curTime, -// }, -// }, -// }, -// { -// Name: "Query on Package", -// InPkg: []*model.PkgInputSpec{testdata.P2, testdata.P4}, -// InArt: []*model.ArtifactInputSpec{testdata.A1}, -// PkgArt: &model.PackageOrArtifactInputs{ -// Packages: []*model.PkgInputSpec{testdata.P2, testdata.P4}, -// Artifacts: []*model.ArtifactInputSpec{testdata.A1}, -// }, -// IsDeps: []testDependency{{ -// pkg: testdata.P2, -// depPkg: testdata.P4, -// matchType: mSpecific, -// isDep: &model.IsDependencyInputSpec{ -// Justification: "test justification", -// }, -// }}, -// IsOccs: []testOccurrence{{ -// Subj: &model.PackageOrSourceInput{Package: testdata.P4}, -// Art: testdata.A1, -// isOcc: &model.IsOccurrenceInputSpec{Justification: "test justification"}, -// }}, -// Calls: []call{ -// { -// Sub: model.PackageOrArtifactInput{ -// Package: testdata.P2, -// }, -// HS: &model.HasSBOMInputSpec{ -// URI: "test uri", -// }, -// }, -// { -// Sub: model.PackageOrArtifactInput{ -// Package: testdata.P4, -// }, -// HS: &model.HasSBOMInputSpec{ -// URI: "test uri", -// }, -// }, -// { -// Sub: model.PackageOrArtifactInput{ -// Artifact: testdata.A1, -// }, -// HS: &model.HasSBOMInputSpec{ -// URI: "test uri", -// }, -// }, -// }, -// Query: &model.HasSBOMSpec{ -// Subject: &model.PackageOrArtifactSpec{ -// Package: &model.PkgSpec{ -// Version: ptrfrom.String("2.11.1"), -// }, -// }, -// }, -// ExpHS: []*model.HasSbom{ -// { -// Subject: testdata.P2out, -// URI: "test uri", -// IncludedSoftware: []model.PackageOrArtifact{testdata.P2out, testdata.P4out, testdata.A1out}, -// IncludedDependencies: []*model.IsDependency{{ -// Package: testdata.P2out, -// DependencyPackage: testdata.P4out, -// Justification: "test justification", -// }}, -// IncludedOccurrences: []*model.IsOccurrence{{ -// Subject: testdata.P4out, -// Artifact: testdata.A1out, -// Justification: "test justification", -// }}, -// }, -// }, -// }, -// { -// Name: "Query on Package ID", -// InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2}, -// InArt: []*model.ArtifactInputSpec{testdata.A1}, -// Calls: []call{ -// { -// Sub: model.PackageOrArtifactInput{ -// Package: testdata.P1, -// }, -// HS: &model.HasSBOMInputSpec{ -// URI: "test uri", -// }, -// }, -// { -// Sub: model.PackageOrArtifactInput{ -// Package: testdata.P2, -// }, -// HS: &model.HasSBOMInputSpec{ -// URI: "test uri", -// }, -// }, -// { -// Sub: model.PackageOrArtifactInput{ -// Artifact: testdata.A1, -// }, -// HS: &model.HasSBOMInputSpec{ -// URI: "test uri", -// }, -// }, -// }, -// QueryPkgID: true, -// ExpHS: []*model.HasSbom{ -// { -// Subject: testdata.P2out, -// URI: "test uri", -// }, -// { -// Subject: testdata.P2out, -// URI: "test uri", -// IncludedSoftware: []model.PackageOrArtifact{testdata.P2out, testdata.P4out, testdata.A1out}, -// IncludedDependencies: []*model.IsDependency{{ -// Package: testdata.P2out, -// DependencyPackage: testdata.P4out, -// Justification: "test justification", -// }}, -// IncludedOccurrences: []*model.IsOccurrence{{ -// Subject: testdata.P4out, -// Artifact: testdata.A1out, -// Justification: "test justification", -// }}, -// }, -// }, -// }, -// { -// Name: "Query on Artifact", -// InPkg: []*model.PkgInputSpec{testdata.P2}, -// InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, -// PkgArt: &model.PackageOrArtifactInputs{ -// Packages: []*model.PkgInputSpec{testdata.P2}, -// Artifacts: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, -// }, -// Calls: []call{ -// { -// Sub: model.PackageOrArtifactInput{ -// Package: testdata.P2, -// }, -// HS: &model.HasSBOMInputSpec{ -// URI: "test uri", -// }, -// }, -// { -// Sub: model.PackageOrArtifactInput{ -// Artifact: testdata.A1, -// }, -// HS: &model.HasSBOMInputSpec{ -// URI: "test uri", -// }, -// }, -// { -// Sub: model.PackageOrArtifactInput{ -// Artifact: testdata.A2, -// }, -// HS: &model.HasSBOMInputSpec{ -// URI: "test uri", -// }, -// }, -// }, -// Query: &model.HasSBOMSpec{ -// Subject: &model.PackageOrArtifactSpec{ -// Artifact: &model.ArtifactSpec{ -// Algorithm: ptrfrom.String("sha1"), -// }, -// }, -// }, -// ExpHS: []*model.HasSbom{ -// { -// Subject: testdata.A2out, -// URI: "test uri", -// IncludedSoftware: []model.PackageOrArtifact{testdata.P2out, testdata.A1out, testdata.A2out}, -// }, -// }, -// }, -// { -// Name: "Query on Artifact ID", -// InPkg: []*model.PkgInputSpec{testdata.P1}, -// InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, -// Calls: []call{ -// { -// Sub: model.PackageOrArtifactInput{ -// Package: testdata.P1, -// }, -// HS: &model.HasSBOMInputSpec{ -// URI: "test uri", -// }, -// }, -// { -// Sub: model.PackageOrArtifactInput{ -// Artifact: testdata.A1, -// }, -// HS: &model.HasSBOMInputSpec{ -// URI: "test uri", -// }, -// }, -// { -// Sub: model.PackageOrArtifactInput{ -// Artifact: testdata.A2, -// }, -// HS: &model.HasSBOMInputSpec{ -// URI: "test uri", -// }, -// }, -// }, -// QueryArtID: true, -// ExpHS: []*model.HasSbom{ -// { -// Subject: testdata.A2out, -// URI: "test uri", -// }, -// { -// Subject: testdata.A2out, -// URI: "test uri", -// IncludedSoftware: []model.PackageOrArtifact{testdata.P2out, testdata.A1out, testdata.A2out}, -// }, -// }, -// }, -// { -// Name: "Query on Algorithm", -// InPkg: []*model.PkgInputSpec{testdata.P1}, -// PkgArt: &model.PackageOrArtifactInputs{ -// Packages: []*model.PkgInputSpec{testdata.P1}, -// }, -// Calls: []call{ -// { -// Sub: model.PackageOrArtifactInput{ -// Package: testdata.P1, -// }, -// HS: &model.HasSBOMInputSpec{ -// Algorithm: "QWERasdf", -// }, -// }, -// { -// Sub: model.PackageOrArtifactInput{ -// Package: testdata.P1, -// }, -// HS: &model.HasSBOMInputSpec{ -// Algorithm: "QWERasdf two", -// }, -// }, -// }, -// Query: &model.HasSBOMSpec{ -// Algorithm: ptrfrom.String("QWERASDF"), -// }, -// ExpHS: []*model.HasSbom{ -// { -// Subject: testdata.P1out, -// Algorithm: "qwerasdf", -// IncludedSoftware: []model.PackageOrArtifact{testdata.P1out}, -// }, -// }, -// }, -// { -// Name: "Query on Digest", -// InPkg: []*model.PkgInputSpec{testdata.P2, testdata.P4}, -// PkgArt: &model.PackageOrArtifactInputs{ -// Packages: []*model.PkgInputSpec{testdata.P2, testdata.P4}, -// Artifacts: []*model.ArtifactInputSpec{testdata.A1}, -// }, -// IsDeps: []testDependency{{ -// pkg: testdata.P2, -// depPkg: testdata.P4, -// matchType: mSpecific, -// isDep: &model.IsDependencyInputSpec{ -// Justification: "test justification", -// }, -// }}, -// IsOccs: []testOccurrence{{ -// Subj: &model.PackageOrSourceInput{Package: testdata.P4}, -// Art: testdata.A1, -// isOcc: &model.IsOccurrenceInputSpec{Justification: "test justification"}, -// }}, -// Calls: []call{ -// { -// Sub: model.PackageOrArtifactInput{ -// Package: testdata.P2, -// }, -// HS: &model.HasSBOMInputSpec{ -// Digest: "QWERasdf", -// }, -// }, -// { -// Sub: model.PackageOrArtifactInput{ -// Package: testdata.P2, -// }, -// HS: &model.HasSBOMInputSpec{ -// Digest: "QWERasdf two", -// }, -// }, -// }, -// Query: &model.HasSBOMSpec{ -// Digest: ptrfrom.String("QWERASDF"), -// }, -// ExpHS: []*model.HasSbom{ -// { -// Subject: testdata.P2out, -// Digest: "qwerasdf", -// IncludedSoftware: []model.PackageOrArtifact{testdata.P2out, testdata.P4out, testdata.A1out}, -// IncludedDependencies: []*model.IsDependency{{ -// Package: testdata.P2out, -// DependencyPackage: testdata.P4out, -// Justification: "test justification", -// }}, -// IncludedOccurrences: []*model.IsOccurrence{{ -// Subject: testdata.P4out, -// Artifact: testdata.A1out, -// Justification: "test justification", -// }}, -// }, -// }, -// }, -// { -// Name: "Query on DownloadLocation", -// InPkg: []*model.PkgInputSpec{testdata.P1}, -// PkgArt: &model.PackageOrArtifactInputs{ -// Packages: []*model.PkgInputSpec{testdata.P1}, -// }, -// Calls: []call{ -// { -// Sub: model.PackageOrArtifactInput{ -// Package: testdata.P1, -// }, -// HS: &model.HasSBOMInputSpec{ -// DownloadLocation: "location one", -// }, -// }, -// { -// Sub: model.PackageOrArtifactInput{ -// Package: testdata.P1, -// }, -// HS: &model.HasSBOMInputSpec{ -// DownloadLocation: "location two", -// }, -// }, -// }, -// Query: &model.HasSBOMSpec{ -// DownloadLocation: ptrfrom.String("location two"), -// }, -// ExpHS: []*model.HasSbom{ -// { -// Subject: testdata.P1out, -// DownloadLocation: "location two", -// IncludedSoftware: []model.PackageOrArtifact{testdata.P1out}, -// }, -// }, -// }, -// { -// Name: "Query none", -// InPkg: []*model.PkgInputSpec{testdata.P1}, -// PkgArt: &model.PackageOrArtifactInputs{ -// Packages: []*model.PkgInputSpec{testdata.P1}, -// }, -// Calls: []call{ -// { -// Sub: model.PackageOrArtifactInput{ -// Package: testdata.P1, -// }, -// HS: &model.HasSBOMInputSpec{ -// DownloadLocation: "location one", -// }, -// }, -// { -// Sub: model.PackageOrArtifactInput{ -// Package: testdata.P1, -// }, -// HS: &model.HasSBOMInputSpec{ -// DownloadLocation: "location two", -// }, -// }, -// }, -// Query: &model.HasSBOMSpec{ -// DownloadLocation: ptrfrom.String("location three"), -// }, -// ExpHS: nil, -// }, -// { -// Name: "Query multiple", -// InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2}, -// Calls: []call{ -// { -// Sub: model.PackageOrArtifactInput{ -// Package: testdata.P1, -// }, -// HS: &model.HasSBOMInputSpec{ -// DownloadLocation: "location one", -// }, -// }, -// { -// Sub: model.PackageOrArtifactInput{ -// Package: testdata.P1, -// }, -// HS: &model.HasSBOMInputSpec{ -// DownloadLocation: "location two", -// }, -// }, -// { -// Sub: model.PackageOrArtifactInput{ -// Package: testdata.P2, -// }, -// HS: &model.HasSBOMInputSpec{ -// DownloadLocation: "location two", -// }, -// }, -// }, -// Query: &model.HasSBOMSpec{ -// DownloadLocation: ptrfrom.String("location two"), -// }, -// ExpHS: []*model.HasSbom{ -// { -// Subject: testdata.P1out, -// DownloadLocation: "location two", -// IncludedSoftware: []model.PackageOrArtifact{testdata.P1out}, -// }, -// { -// Subject: testdata.P1out, -// DownloadLocation: "location two", -// }, -// { -// Subject: testdata.P2out, -// DownloadLocation: "location two", -// }, -// }, -// }, -// { -// Name: "Query on ID", -// InPkg: []*model.PkgInputSpec{testdata.P1}, -// PkgArt: &model.PackageOrArtifactInputs{ -// Packages: []*model.PkgInputSpec{testdata.P1}, -// }, -// Calls: []call{ -// { -// Sub: model.PackageOrArtifactInput{ -// Package: testdata.P1, -// }, -// HS: &model.HasSBOMInputSpec{ -// DownloadLocation: "location one", -// }, -// }, -// { -// Sub: model.PackageOrArtifactInput{ -// Package: testdata.P1, -// }, -// HS: &model.HasSBOMInputSpec{ -// DownloadLocation: "location two", -// }, -// }, -// }, -// QueryID: true, -// ExpHS: []*model.HasSbom{ -// { -// Subject: testdata.P1out, -// DownloadLocation: "location two", -// IncludedSoftware: []model.PackageOrArtifact{testdata.P1out}, -// }, -// }, -// }, -// { -// Name: "Query bad ID", -// InPkg: []*model.PkgInputSpec{testdata.P1}, -// PkgArt: &model.PackageOrArtifactInputs{ -// Packages: []*model.PkgInputSpec{testdata.P1}, -// }, -// Calls: []call{ -// { -// Sub: model.PackageOrArtifactInput{ -// Package: testdata.P1, -// }, -// HS: &model.HasSBOMInputSpec{ -// DownloadLocation: "location one", -// }, -// }, -// { -// Sub: model.PackageOrArtifactInput{ -// Package: testdata.P1, -// }, -// HS: &model.HasSBOMInputSpec{ -// DownloadLocation: "location two", -// }, -// }, -// }, -// Query: &model.HasSBOMSpec{ -// ID: ptrfrom.String("-7"), -// }, -// ExpQueryErr: true, -// }, -// { -// Name: "IncludedSoftware - Valid Included Package ID", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// QueryIncludePkgID: true, -// ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, -// }, -// { -// Name: "IncludedSoftware - Invalid Included Package ID", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Package: &model.PkgSpec{ID: ptrfrom.String("10000")}}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedSoftware - Valid Included Package Namespace", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Package: &model.PkgSpec{Namespace: includedPackage2.Namespace}}}}, -// ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, -// }, -// { -// Name: "IncludedSoftware - Invalid Included Package Namespace", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Package: &model.PkgSpec{Namespace: ptrfrom.String("invalid_namespace")}}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedSoftware - Valid Included Package Name", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Package: &model.PkgSpec{Name: &includedPackage2.Name}}}}, -// ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, -// }, -// { -// Name: "IncludedSoftware - Invalid Included Package Name", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Package: &model.PkgSpec{Name: ptrfrom.String("invalid_name")}}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedSoftware - Valid Included Package Version", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Package: &model.PkgSpec{Version: includedPackage2.Version}}}}, -// ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, -// }, -// { -// Name: "IncludedSoftware - Invalid Included Package Version", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Package: &model.PkgSpec{Version: ptrfrom.String("v1.0.0-invalid-version")}}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedSoftware - Valid Included Package Qualifier", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Package: &model.PkgSpec{Qualifiers: []*model.PackageQualifierSpec{{Key: includedPackage2QualifierKey, Value: ptrfrom.String(includedPackage2QualifierValue)}}}}}}, -// ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, -// }, -// { -// Name: "IncludedSoftware - Invalid Included Package Qualifier Key", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Package: &model.PkgSpec{Qualifiers: []*model.PackageQualifierSpec{{Key: "invalid_qualifier_key", Value: ptrfrom.String(includedPackage2QualifierValue)}}}}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedSoftware - Invalid Subject Package Qualifier Value", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Package: &model.PkgSpec{Qualifiers: []*model.PackageQualifierSpec{{Key: includedPackage2QualifierKey, Value: ptrfrom.String("invalid_qualifier_value")}}}}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedSoftware - Valid Included Package Subpath", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Package: &model.PkgSpec{Subpath: includedPackage2.Subpath}}}}, -// ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, -// }, -// { -// Name: "IncludedSoftware - Invalid Included Package Subpath", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Package: &model.PkgSpec{Subpath: ptrfrom.String("invalid_subpath")}}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedSoftware - Valid Included Artifact ID", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// QueryIncludeArtID: true, -// Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Artifact: &model.ArtifactSpec{ID: ptrfrom.String("13")}}}}, -// ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, -// }, -// { -// Name: "IncludedSoftware - Invalid Included Artifact ID", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Artifact: &model.ArtifactSpec{ID: ptrfrom.String("10000")}}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedSoftware - Valid Included Artifact Algorithm", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Artifact: &model.ArtifactSpec{Algorithm: &includedArtifact1.Algorithm}}}}, -// ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, -// }, -// { -// Name: "IncludedSoftware - Invalid Included Artifact Algorithm", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Artifact: &model.ArtifactSpec{Algorithm: ptrfrom.String("invalid_algorithm")}}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedSoftware - Valid Included Artifact Digest", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Artifact: &model.ArtifactSpec{Digest: &includedArtifact1.Digest}}}}, -// ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, -// }, -// { -// Name: "IncludedSoftware - Invalid Included Artifact Digest", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Artifact: &model.ArtifactSpec{Digest: ptrfrom.String("invalid_digest")}}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedDependencies - Valid Included ID", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// QueryIncludeDepID: true, -// Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{ID: ptrfrom.String("19")}}}, -// ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, -// }, -// { -// Name: "IncludedDependencies - Invalid Included ID", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{ID: ptrfrom.String("10000")}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedDependencies - Valid Included Package ID", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// QueryIncludeDepMainPkgID: true, -// ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, -// }, -// { -// Name: "IncludedDependencies - Invalid Included Package ID", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{ID: ptrfrom.String("10000")}}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedDependencies - Valid Included Package Namespace", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{Namespace: includedPackage1.Namespace}}}}, -// ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, -// }, -// { -// Name: "IncludedDependencies - Invalid Included Package Namespace", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{Namespace: ptrfrom.String("invalid_namespace")}}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedDependencies - Valid Included Package Name", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{Name: &includedPackage1.Name}}}}, -// ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, -// }, -// { -// Name: "IncludedDependencies - Invalid Included Package Name", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{Name: ptrfrom.String("invalid_name")}}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedDependencies - Valid Included Package Version", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{Version: includedPackage1.Version}}}}, -// ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, -// }, -// { -// Name: "IncludedDependencies - Invalid Included Package Version", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{Version: ptrfrom.String("v1.0.0-invalid-version")}}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedDependencies - Valid Included Package Qualifier", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{Qualifiers: []*model.PackageQualifierSpec{{Key: includedPackage1QualifierKey, Value: ptrfrom.String(includedPackage1QualifierValue)}}}}}}, -// ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, -// }, -// { -// Name: "IncludedDependencies - Invalid Included Package Qualifier Key", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{Qualifiers: []*model.PackageQualifierSpec{{Key: "invalid_qualifier_key", Value: ptrfrom.String(includedPackage1QualifierValue)}}}}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedDependencies - Invalid Subject Package Qualifier Value", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{Qualifiers: []*model.PackageQualifierSpec{{Key: includedPackage1QualifierKey, Value: ptrfrom.String("invalid_qualifier_value")}}}}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedDependencies - Valid Included Package Subpath", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{Subpath: includedPackage1.Subpath}}}}, -// ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, -// }, -// { -// Name: "IncludedDependencies - Invalid Included Package Subpath", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{Subpath: ptrfrom.String("invalid_subpath")}}}}, -// ExpHS: nil, -// }, - -// { -// Name: "IncludedDependencies - Valid Included DependencyPackage ID", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// QueryIncludeDepPkgID: true, -// ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, -// }, -// { -// Name: "IncludedDependencies - Invalid Included DependencyPackage ID", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{DependencyPackage: &model.PkgSpec{ID: ptrfrom.String("10000")}}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedDependencies - Valid Included DependencyPackage Namespace", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{DependencyPackage: &model.PkgSpec{Namespace: includedPackage2.Namespace}}}}, -// ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, -// }, -// { -// Name: "IncludedDependencies - Invalid Included DependencyPackage Namespace", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{DependencyPackage: &model.PkgSpec{Namespace: ptrfrom.String("invalid_namespace")}}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedDependencies - Valid Included DependencyPackage Name", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{DependencyPackage: &model.PkgSpec{Name: &includedPackage2.Name}}}}, -// ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, -// }, -// { -// Name: "IncludedDependencies - Invalid Included DependencyPackage Name", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{DependencyPackage: &model.PkgSpec{Name: ptrfrom.String("invalid_name")}}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedDependencies - Valid Included DependencyPackage Version", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{DependencyPackage: &model.PkgSpec{Version: includedPackage2.Version}}}}, -// ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, -// }, -// { -// Name: "IncludedDependencies - Invalid Included DependencyPackage Version", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{DependencyPackage: &model.PkgSpec{Version: ptrfrom.String("v1.0.0-invalid-version")}}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedDependencies - Valid Included DependencyPackage Qualifier", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{DependencyPackage: &model.PkgSpec{Qualifiers: []*model.PackageQualifierSpec{{Key: includedPackage2QualifierKey, Value: ptrfrom.String(includedPackage2QualifierValue)}}}}}}, -// ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, -// }, -// { -// Name: "IncludedDependencies - Invalid Included DependencyPackage Qualifier Key", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{DependencyPackage: &model.PkgSpec{Qualifiers: []*model.PackageQualifierSpec{{Key: "invalid_qualifier_key", Value: ptrfrom.String(includedPackage2QualifierValue)}}}}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedDependencies - Invalid Subject DependencyPackage Qualifier Value", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{DependencyPackage: &model.PkgSpec{Qualifiers: []*model.PackageQualifierSpec{{Key: includedPackage2QualifierKey, Value: ptrfrom.String("invalid_qualifier_value")}}}}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedDependencies - Valid Included DependencyPackage Subpath", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{DependencyPackage: &model.PkgSpec{Subpath: includedPackage2.Subpath}}}}, -// ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, -// }, -// { -// Name: "IncludedDependencies - Invalid Included DependencyPackage Subpath", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{DependencyPackage: &model.PkgSpec{Subpath: ptrfrom.String("invalid_subpath")}}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedDependencies - Valid Included Package ID and DependencyPackage ID", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// QueryIncludeDepMainPkgID: true, -// QueryIncludeDepPkgID: true, -// ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, -// }, -// { -// Name: "IncludedDependencies - Valid Included Package ID and Invalid DependencyPackage ID", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{ID: ptrfrom.String("4")}, DependencyPackage: &model.PkgSpec{ID: ptrfrom.String("10000")}}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedDependencies - Invalid Included Package ID and Valid DependencyPackage ID", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{ID: ptrfrom.String("10000")}, DependencyPackage: &model.PkgSpec{ID: ptrfrom.String("8")}}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedDependencies - Valid Included Package Name and DependencyPackage Name", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{Name: &includedPackage1.Name}, DependencyPackage: &model.PkgSpec{Name: &includedPackage2.Name}}}}, -// ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, -// }, -// { -// Name: "IncludedDependencies - Valid Included Package Name and Invalid DependencyPackage Name", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{Name: &includedPackage1.Name}, DependencyPackage: &model.PkgSpec{Name: ptrfrom.String("invalid_name")}}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedDependencies - Invalid Included Package Name and Valid DependencyPackage Name", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{Name: ptrfrom.String("invalid_name")}, DependencyPackage: &model.PkgSpec{Name: &includedPackage2.Name}}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedDependencies - Valid Included VersionRange", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{VersionRange: &includedDependency1.VersionRange}}}, -// ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, -// }, -// { -// Name: "IncludedDependencies - Invalid Included VersionRange", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{VersionRange: ptrfrom.String("invalid_range")}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedDependencies - Valid Included DependencyType", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{DependencyType: &includedDependency1.DependencyType}}}, -// ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, -// }, -// { -// Name: "IncludedDependencies - Invalid Included DependencyType", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{DependencyType: (*model.DependencyType)(ptrfrom.String(string(model.DependencyTypeUnknown)))}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedDependencies - Valid Included Justification", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Justification: &includedDependency1.Justification}}}, -// ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, -// }, -// { -// Name: "IncludedDependencies - Invalid Included Justification", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Justification: ptrfrom.String("invalid_justification")}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedDependencies - Valid Included Origin", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Origin: &includedDependency1.Origin}}}, -// ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, -// }, -// { -// Name: "IncludedDependencies - Invalid Included Origin", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Origin: ptrfrom.String("invalid_origin")}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedDependencies - Valid Included Collector", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Collector: &includedDependency1.Collector}}}, -// ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, -// }, -// { -// Name: "IncludedDependencies - Invalid Included Collector", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Collector: ptrfrom.String("invalid_collector")}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedOccurrences - Valid Included ID", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// QueryIncludeOccurID: true, -// Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{ID: ptrfrom.String("21")}}}, -// ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, -// }, -// { -// Name: "IncludedOccurrences - Invalid Included ID", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{ID: ptrfrom.String("10000")}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedOccurrences - Valid Included Package ID", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// QueryIncludeOccurPkgID: true, -// ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, -// }, -// { -// Name: "IncludedOccurrences - Invalid Included Package ID", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Package: &model.PkgSpec{ID: ptrfrom.String("10000")}}}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedOccurrences - Valid Included Package Namespace", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Package: &model.PkgSpec{Namespace: includedPackage1.Namespace}}}}}, -// ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, -// }, -// { -// Name: "IncludedOccurrences - Invalid Included Package Namespace", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Package: &model.PkgSpec{Namespace: ptrfrom.String("invalid_namespace")}}}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedOccurrences - Valid Included Package Name", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Package: &model.PkgSpec{Name: ptrfrom.String("p1_name")}}}}}, -// ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, -// }, -// { -// Name: "IncludedOccurrences - Invalid Included Package Name", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Package: &model.PkgSpec{Name: ptrfrom.String("invalid_name")}}}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedOccurrences - Valid Included Package Version", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Package: &model.PkgSpec{Version: includedPackage1.Version}}}}}, -// ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, -// }, -// { -// Name: "IncludedOccurrences - Invalid Included Package Version", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Package: &model.PkgSpec{Version: ptrfrom.String("v1.0.0-invalid-version")}}}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedOccurrences - Valid Included Package Qualifier", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Package: &model.PkgSpec{Qualifiers: []*model.PackageQualifierSpec{{Key: includedPackage1QualifierKey, Value: ptrfrom.String(includedPackage1QualifierValue)}}}}}}}, -// ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, -// }, -// { -// Name: "IncludedOccurrences - Invalid Included Package Qualifier Key", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Package: &model.PkgSpec{Qualifiers: []*model.PackageQualifierSpec{{Key: "invalid_qualifier_key", Value: ptrfrom.String(includedPackage1QualifierValue)}}}}}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedOccurrences - Invalid Subject Package Qualifier Value", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Package: &model.PkgSpec{Qualifiers: []*model.PackageQualifierSpec{{Key: includedPackage1QualifierKey, Value: ptrfrom.String("invalid_qualifier_value")}}}}}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedOccurrences - Valid Included Package Subpath", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Package: &model.PkgSpec{Subpath: includedPackage1.Subpath}}}}}, -// ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, -// }, -// { -// Name: "IncludedOccurrences - Invalid Included Package Subpath", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Package: &model.PkgSpec{Subpath: ptrfrom.String("invalid_subpath")}}}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedOccurrences - Valid Included Source ID", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// QueryIncludeOccurSrcID: true, -// ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, -// }, -// { -// Name: "IncludedOccurrences - Invalid Included Source ID", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Source: &model.SourceSpec{ID: ptrfrom.String("10000")}}}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedOccurrences - Valid Included Source", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// // TODO (knrc) - source currently needs to be an exact match, does this need to change? -// Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Source: &model.SourceSpec{ -// Type: &includedSource.Type, -// Namespace: &includedSource.Namespace, -// Name: &includedSource.Name, -// Tag: includedSource.Tag, -// Commit: includedSource.Commit, -// }}}}}, -// ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, -// }, -// { -// Name: "IncludedOccurrences - Invalid Included Source Type", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Source: &model.SourceSpec{ -// Type: ptrfrom.String("invalid_type"), -// Namespace: &includedSource.Namespace, -// Name: &includedSource.Name, -// Tag: includedSource.Tag, -// Commit: includedSource.Commit, -// }}}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedOccurrences - Invalid Included Source Namespace", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Source: &model.SourceSpec{ -// Type: &includedSource.Type, -// Namespace: ptrfrom.String("invalid_namespace"), -// Name: &includedSource.Name, -// Tag: includedSource.Tag, -// Commit: includedSource.Commit, -// }}}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedOccurrences - Invalid Included Source Name", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Source: &model.SourceSpec{ -// Type: &includedSource.Type, -// Namespace: &includedSource.Namespace, -// Name: ptrfrom.String("invalid_name"), -// Tag: includedSource.Tag, -// Commit: includedSource.Commit, -// }}}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedOccurrences - Invalid Included Source Tag", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Source: &model.SourceSpec{ -// Type: &includedSource.Type, -// Namespace: &includedSource.Namespace, -// Name: &includedSource.Name, -// Tag: ptrfrom.String("invalid_tag"), -// Commit: includedSource.Commit, -// }}}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedOccurrences - Invalid Included Source Commit", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Source: &model.SourceSpec{ -// Type: &includedSource.Type, -// Namespace: &includedSource.Namespace, -// Name: &includedSource.Name, -// Tag: includedSource.Tag, -// Commit: ptrfrom.String("invalid_commit"), -// }}}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedOccurrences - Valid Included Artifact ID", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// QueryIncludeOccurArtID: true, -// ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, -// }, -// { -// Name: "IncludedOccurrences - Invalid Included Artifact ID", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Artifact: &model.ArtifactSpec{ID: ptrfrom.String("10000")}}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedOccurrences - Valid Included Artifact Algorithm", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Artifact: &model.ArtifactSpec{Algorithm: &includedArtifact1.Algorithm}}}}, -// ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, -// }, -// { -// Name: "IncludedOccurrences - Invalid Included Artifact Algorithm", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Artifact: &model.ArtifactSpec{Algorithm: ptrfrom.String("invalid_algorithm")}}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedOccurrences - Valid Included Artifact Digest", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Artifact: &model.ArtifactSpec{Digest: &includedArtifact1.Digest}}}}, -// ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, -// }, -// { -// Name: "IncludedOccurrences - Invalid Included Artifact Digest", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Artifact: &model.ArtifactSpec{Digest: ptrfrom.String("invalid_digest")}}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedOccurrences - Valid Included Justification", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Justification: &includedOccurrence.Justification}}}, -// ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, -// }, -// { -// Name: "IncludedOccurrences - Invalid Included Justification", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Justification: ptrfrom.String("invalid_justification")}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedOccurrences - Valid Included Origin", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Origin: &includedOccurrence.Origin}}}, -// ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, -// }, -// { -// Name: "IncludedOccurrences - Invalid Included Origin", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Origin: ptrfrom.String("invalid_origin")}}}, -// ExpHS: nil, -// }, -// { -// Name: "IncludedOccurrences - Valid Included Collector", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Collector: &includedOccurrence.Collector}}}, -// ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, -// }, -// { -// Name: "IncludedOccurrences - Invalid Included Collector", -// InPkg: includedPackages, -// InArt: includedArtifacts, -// InSrc: includedSources, -// PkgArt: includedPackageArtifacts, -// IsDeps: includedTestDependencies, -// IsOccs: includedTestOccurrences, -// Calls: []call{{ -// Sub: model.PackageOrArtifactInput{ -// Package: includedPackage1, -// }, -// HS: includedHasSBOM, -// }}, -// Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Collector: ptrfrom.String("invalid_collector")}}}, -// ExpHS: nil, -// }, -// } -// ignoreID := cmp.FilterPath(func(p cmp.Path) bool { -// return strings.Compare(".ID", p[len(p)-1].String()) == 0 -// }, cmp.Ignore()) -// for _, test := range tests { -// t.Run(test.Name, func(t *testing.T) { -// for _, p := range test.InPkg { -// if pkgIDs, err := b.IngestPackage(ctx, *p); err != nil { -// t.Fatalf("Could not ingest package: %v", err) -// } else { -// if test.QueryPkgID { -// test.Query = &model.HasSBOMSpec{ -// Subject: &model.PackageOrArtifactSpec{ -// Package: &model.PkgSpec{ -// ID: ptrfrom.String(pkgIDs.PackageVersionID), -// }, -// }, -// } -// } -// } -// } -// for _, a := range test.InArt { -// if artID, err := b.IngestArtifact(ctx, a); err != nil { -// t.Fatalf("Could not ingest artifact: %v", err) -// } else { -// if test.QueryArtID { -// test.Query = &model.HasSBOMSpec{ -// Subject: &model.PackageOrArtifactSpec{ -// Artifact: &model.ArtifactSpec{ -// ID: ptrfrom.String(artID), -// }, -// }, -// } -// } -// } -// } -// includes := model.HasSBOMIncludesInputSpec{} -// for _, s := range test.InSrc { -// if srcIDs, err := b.IngestSource(ctx, *s); err != nil { -// t.Fatalf("Could not ingest source: %v", err) -// } else { -// if test.QueryIncludeOccurSrcID { -// test.Query = &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Source: &model.SourceSpec{ID: ptrfrom.String(srcIDs.SourceNameID)}}}}} -// } -// } -// } -// if test.PkgArt != nil { -// if pkgs, err := b.IngestPackages(ctx, test.PkgArt.Packages); err != nil { -// t.Fatalf("Could not ingest package: %v", err) -// } else { -// if pkgs != nil { -// for _, pkg := range pkgs { -// includes.Software = append(includes.Software, pkg.PackageVersionID) -// } -// if test.QueryIncludePkgID { -// test.Query = &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Package: &model.PkgSpec{ID: ptrfrom.String(pkgs[0].PackageVersionID)}}}} -// } -// if test.QueryIncludeOccurPkgID { -// test.Query = &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Package: &model.PkgSpec{ID: ptrfrom.String(pkgs[0].PackageVersionID)}}}}} -// } -// if test.QueryIncludeDepMainPkgID { -// test.Query = &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{ID: ptrfrom.String(pkgs[0].PackageVersionID)}}}} -// } -// if test.QueryIncludeDepPkgID { -// test.Query = &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{DependencyPackage: &model.PkgSpec{ID: ptrfrom.String(pkgs[len(pkgs)-1].PackageVersionID)}}}} -// } -// if test.QueryIncludeDepMainPkgID && test.QueryIncludeDepPkgID { -// test.Query = &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{ID: ptrfrom.String(pkgs[0].PackageVersionID)}, DependencyPackage: &model.PkgSpec{ID: ptrfrom.String(pkgs[len(pkgs)-1].PackageVersionID)}}}} -// } -// } -// } -// if arts, err := b.IngestArtifacts(ctx, test.PkgArt.Artifacts); err != nil { -// t.Fatalf("Could not ingest artifact: %v", err) -// } else { -// if arts != nil { -// includes.Software = append(includes.Software, arts...) -// if test.QueryIncludeArtID { -// test.Query = &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Artifact: &model.ArtifactSpec{ID: ptrfrom.String(arts[0])}}}} -// } -// if test.QueryIncludeOccurArtID { -// test.Query = &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Artifact: &model.ArtifactSpec{ID: ptrfrom.String(arts[0])}}}} -// } -// } -// } -// } - -// for _, dep := range test.IsDeps { -// if isDep, err := b.IngestDependency(ctx, *dep.pkg, *dep.depPkg, dep.matchType, *dep.isDep); err != nil { -// t.Fatalf("Could not ingest dependency: %v", err) -// } else { -// includes.Dependencies = append(includes.Dependencies, isDep) -// if test.QueryIncludeDepID { -// test.Query = &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{ID: ptrfrom.String(isDep)}}} -// } -// } -// } - -// for _, occ := range test.IsOccs { -// if isOcc, err := b.IngestOccurrence(ctx, *occ.Subj, *occ.Art, *occ.isOcc); err != nil { -// t.Fatalf("Could not ingest occurrence: %v", err) -// } else { -// includes.Occurrences = append(includes.Occurrences, isOcc) -// if test.QueryIncludeOccurID { -// test.Query = &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{ID: ptrfrom.String(isOcc)}}} -// } -// } -// } - -// for _, o := range test.Calls { -// hsID, err := b.IngestHasSbom(ctx, o.Sub, *o.HS, includes) -// if (err != nil) != test.ExpIngestErr { -// t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) -// } -// if err != nil { -// return -// } -// if test.QueryID { -// test.Query = &model.HasSBOMSpec{ -// ID: ptrfrom.String(hsID), -// } -// } -// } -// got, err := b.HasSBOM(ctx, test.Query) -// if (err != nil) != test.ExpQueryErr { -// t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) -// } -// if err != nil { -// return -// } -// if diff := cmp.Diff(test.ExpHS, got, ignoreID); diff != "" { -// t.Errorf("Unexpected results. (-want +got):\n%s", diff) -// } -// }) -// } -// } - -// func TestIngestHasSBOMs(t *testing.T) { -// ctx := context.Background() -// arangoArgs := getArangoConfig() -// err := DeleteDatabase(ctx, arangoArgs) -// if err != nil { -// t.Fatalf("error deleting arango database: %v", err) -// } -// b, err := getBackend(ctx, arangoArgs) -// if err != nil { -// t.Fatalf("error creating arango backend: %v", err) -// } -// type call struct { -// Sub model.PackageOrArtifactInputs -// HS []*model.HasSBOMInputSpec -// Inc []*model.HasSBOMIncludesInputSpec -// } -// tests := []struct { -// Name string -// InPkg []*model.PkgInputSpec -// InArt []*model.ArtifactInputSpec -// PkgArt *model.PackageOrArtifactInputs -// IsDeps []testDependency -// IsOccs []testOccurrence -// Calls []call -// Query *model.HasSBOMSpec -// ExpHS []*model.HasSbom -// ExpIngestErr bool -// ExpQueryErr bool -// }{ -// { -// Name: "HappyPath", -// InPkg: []*model.PkgInputSpec{testdata.P1}, -// PkgArt: &model.PackageOrArtifactInputs{ -// Packages: []*model.PkgInputSpec{testdata.P1}, -// }, -// Calls: []call{ -// { -// Sub: model.PackageOrArtifactInputs{ -// Packages: []*model.PkgInputSpec{testdata.P1}, -// }, -// HS: []*model.HasSBOMInputSpec{ -// { -// URI: "test uri", -// }, -// }, -// }, -// }, -// Query: &model.HasSBOMSpec{ -// URI: ptrfrom.String("test uri"), -// }, -// ExpHS: []*model.HasSbom{ -// { -// Subject: testdata.P1out, -// URI: "test uri", -// IncludedSoftware: []model.PackageOrArtifact{testdata.P1out}, -// }, -// }, -// }, -// { -// Name: "Ingest same twice", -// InPkg: []*model.PkgInputSpec{testdata.P1}, -// PkgArt: &model.PackageOrArtifactInputs{ -// Packages: []*model.PkgInputSpec{testdata.P1}, -// }, -// Calls: []call{ -// { -// Sub: model.PackageOrArtifactInputs{ -// Packages: []*model.PkgInputSpec{testdata.P1, testdata.P1}, -// }, -// HS: []*model.HasSBOMInputSpec{ -// { -// URI: "test uri", -// }, -// { -// URI: "test uri", -// }, -// }, -// }, -// }, -// Query: &model.HasSBOMSpec{ -// URI: ptrfrom.String("test uri"), -// }, -// ExpHS: []*model.HasSbom{ -// { -// Subject: testdata.P1out, -// URI: "test uri", -// IncludedSoftware: []model.PackageOrArtifact{testdata.P1out}, -// }, -// }, -// }, -// { -// Name: "Query on URI", -// InPkg: []*model.PkgInputSpec{testdata.P1}, -// PkgArt: &model.PackageOrArtifactInputs{ -// Packages: []*model.PkgInputSpec{testdata.P1}, -// }, -// Calls: []call{ -// { -// Sub: model.PackageOrArtifactInputs{ -// Packages: []*model.PkgInputSpec{testdata.P1, testdata.P1}, -// }, -// HS: []*model.HasSBOMInputSpec{ -// { -// URI: "test uri one", -// }, -// { -// URI: "test uri two", -// }, -// }, -// }, -// }, -// Query: &model.HasSBOMSpec{ -// URI: ptrfrom.String("test uri one"), -// }, -// ExpHS: []*model.HasSbom{ -// { -// Subject: testdata.P1out, -// URI: "test uri one", -// IncludedSoftware: []model.PackageOrArtifact{testdata.P1out}, -// }, -// }, -// }, -// { -// Name: "Query on Package", -// InPkg: []*model.PkgInputSpec{testdata.P2, testdata.P4}, -// InArt: []*model.ArtifactInputSpec{testdata.A1}, -// PkgArt: &model.PackageOrArtifactInputs{ -// Packages: []*model.PkgInputSpec{testdata.P2, testdata.P4}, -// Artifacts: []*model.ArtifactInputSpec{testdata.A1}, -// }, -// IsDeps: []testDependency{{ -// pkg: testdata.P2, -// depPkg: testdata.P4, -// matchType: mSpecific, -// isDep: &model.IsDependencyInputSpec{ -// Justification: "test justification", -// }, -// }}, -// IsOccs: []testOccurrence{{ -// Subj: &model.PackageOrSourceInput{Package: testdata.P4}, -// Art: testdata.A1, -// isOcc: &model.IsOccurrenceInputSpec{Justification: "test justification"}, -// }}, -// Calls: []call{ -// { -// Sub: model.PackageOrArtifactInputs{ -// Packages: []*model.PkgInputSpec{testdata.P2, testdata.P4}, -// }, -// HS: []*model.HasSBOMInputSpec{ -// { -// URI: "test uri", -// }, -// { -// URI: "test uri", -// }, -// }, -// }, -// { -// Sub: model.PackageOrArtifactInputs{ -// Artifacts: []*model.ArtifactInputSpec{testdata.A1}, -// }, -// HS: []*model.HasSBOMInputSpec{ -// { -// URI: "test uri", -// }, -// }, -// }, -// }, -// Query: &model.HasSBOMSpec{ -// Subject: &model.PackageOrArtifactSpec{ -// Package: &model.PkgSpec{ -// Version: ptrfrom.String("2.11.1"), -// }, -// }, -// }, -// ExpHS: []*model.HasSbom{ -// { -// Subject: testdata.P2out, -// URI: "test uri", -// IncludedSoftware: []model.PackageOrArtifact{testdata.P2out, testdata.P4out, testdata.A1out}, -// IncludedDependencies: []*model.IsDependency{{ -// Package: testdata.P2out, -// DependencyPackage: testdata.P4out, -// Justification: "test justification", -// }}, -// IncludedOccurrences: []*model.IsOccurrence{{ -// Subject: testdata.P4out, -// Artifact: testdata.A1out, -// Justification: "test justification", -// }}, -// }, -// }, -// }, -// { -// Name: "Query on Artifact", -// InPkg: []*model.PkgInputSpec{testdata.P1}, -// InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, -// PkgArt: &model.PackageOrArtifactInputs{ -// Packages: []*model.PkgInputSpec{testdata.P1}, -// Artifacts: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, -// }, -// IsOccs: []testOccurrence{{ -// Subj: &model.PackageOrSourceInput{Package: testdata.P1}, -// Art: testdata.A2, -// isOcc: &model.IsOccurrenceInputSpec{Justification: "test justification"}, -// }}, -// Calls: []call{ -// { -// Sub: model.PackageOrArtifactInputs{ -// Packages: []*model.PkgInputSpec{testdata.P1}, -// }, -// HS: []*model.HasSBOMInputSpec{ -// { -// URI: "test uri", -// }, -// }, -// }, -// { -// Sub: model.PackageOrArtifactInputs{ -// Artifacts: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, -// }, -// HS: []*model.HasSBOMInputSpec{ -// { -// URI: "test uri", -// }, -// { -// URI: "test uri", -// }, -// }, -// }, -// }, -// Query: &model.HasSBOMSpec{ -// Subject: &model.PackageOrArtifactSpec{ -// Artifact: &model.ArtifactSpec{ -// Algorithm: ptrfrom.String("sha1"), -// }, -// }, -// }, -// ExpHS: []*model.HasSbom{ -// { -// Subject: testdata.A2out, -// URI: "test uri", -// IncludedSoftware: []model.PackageOrArtifact{testdata.P1out, testdata.A1out, testdata.A2out}, -// IncludedOccurrences: []*model.IsOccurrence{{ -// Subject: testdata.P1out, -// Artifact: testdata.A2out, -// Justification: "test justification", -// }}, -// }, -// }, -// }, -// } -// ignoreID := cmp.FilterPath(func(p cmp.Path) bool { -// return strings.Compare(".ID", p[len(p)-1].String()) == 0 -// }, cmp.Ignore()) -// for _, test := range tests { -// t.Run(test.Name, func(t *testing.T) { -// for _, p := range test.InPkg { -// if _, err := b.IngestPackage(ctx, *p); err != nil { -// t.Fatalf("Could not ingest package: %v", err) -// } -// } -// for _, a := range test.InArt { -// if _, err := b.IngestArtifact(ctx, a); err != nil { -// t.Fatalf("Could not ingest artifact: %v", err) -// } -// } -// includes := model.HasSBOMIncludesInputSpec{} -// if test.PkgArt != nil { -// if pkgs, err := b.IngestPackages(ctx, test.PkgArt.Packages); err != nil { -// t.Fatalf("Could not ingest package: %v", err) -// } else { -// for _, pkg := range pkgs { -// includes.Software = append(includes.Software, pkg.PackageVersionID) -// } -// } -// if arts, err := b.IngestArtifacts(ctx, test.PkgArt.Artifacts); err != nil { -// t.Fatalf("Could not ingest artifact: %v", err) -// } else { -// includes.Software = append(includes.Software, arts...) -// } -// } - -// for _, dep := range test.IsDeps { -// if isDep, err := b.IngestDependency(ctx, *dep.pkg, *dep.depPkg, dep.matchType, *dep.isDep); err != nil { -// t.Fatalf("Could not ingest dependency: %v", err) -// } else { -// includes.Dependencies = append(includes.Dependencies, isDep) -// } -// } - -// for _, occ := range test.IsOccs { -// if isOcc, err := b.IngestOccurrence(ctx, *occ.Subj, *occ.Art, *occ.isOcc); err != nil { -// t.Fatalf("Could not ingest occurrence: %v", err) -// } else { -// includes.Occurrences = append(includes.Occurrences, isOcc) -// } -// } -// for _, o := range test.Calls { -// var sbomIncludes []*model.HasSBOMIncludesInputSpec -// for count := 0; count < len(o.HS); count++ { -// sbomIncludes = append(sbomIncludes, &includes) -// } -// _, err := b.IngestHasSBOMs(ctx, o.Sub, o.HS, sbomIncludes) -// if (err != nil) != test.ExpIngestErr { -// t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) -// } -// if err != nil { -// return -// } -// } -// got, err := b.HasSBOM(ctx, test.Query) -// if (err != nil) != test.ExpQueryErr { -// t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) -// } -// if err != nil { -// return -// } -// if diff := cmp.Diff(test.ExpHS, got, ignoreID); diff != "" { -// t.Errorf("Unexpected results. (-want +got):\n%s", diff) -// } -// }) -// } -// } - -func Test_buildHasSbomByID(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - type call struct { - Sub model.PackageOrArtifactInput - HS *model.HasSBOMInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InArt []*model.ArtifactInputSpec - Calls []call - Query *model.HasSBOMSpec - ExpHS *model.HasSbom - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{testdata.P2}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: testdata.P2, - }, - HS: &model.HasSBOMInputSpec{ - URI: "test uri", - }, - }, - }, - Query: &model.HasSBOMSpec{ - Subject: &model.PackageOrArtifactSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String("2.11.1"), - }, - }, - }, - ExpHS: &model.HasSbom{ - Subject: testdata.P2out, - URI: "test uri", - }, - }, - { - Name: "Query on Package ID", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - InArt: []*model.ArtifactInputSpec{testdata.A1}, - Calls: []call{ - - { - Sub: model.PackageOrArtifactInput{ - Package: testdata.P2, - }, - HS: &model.HasSBOMInputSpec{ - URI: "test uri", - }, - }, - }, - ExpHS: &model.HasSbom{ - Subject: testdata.P2out, - URI: "test uri", - }, - }, - { - Name: "Query on Artifact", - InArt: []*model.ArtifactInputSpec{testdata.A2}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Artifact: testdata.A2, - }, - HS: &model.HasSBOMInputSpec{ - URI: "test uri", - }, - }, - }, - Query: &model.HasSBOMSpec{ - Subject: &model.PackageOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha1"), - }, - }, - }, - ExpHS: &model.HasSbom{ - Subject: testdata.A2out, - URI: "test uri", - }, - }, - { - Name: "Query on Artifact ID", - InArt: []*model.ArtifactInputSpec{testdata.A2}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Artifact: testdata.A2, - }, - HS: &model.HasSBOMInputSpec{ - URI: "test uri", - }, - }, - }, - ExpHS: &model.HasSbom{ - Subject: testdata.A2out, - URI: "test uri", - }, - }, - { - Name: "Query on ID", - InPkg: []*model.PkgInputSpec{testdata.P1}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, - }, - HS: &model.HasSBOMInputSpec{ - DownloadLocation: "location two", - }, - }, - }, - ExpHS: &model.HasSbom{ - Subject: testdata.P1out, - DownloadLocation: "location two", - }, - }, - { - Name: "Query bad ID", - InPkg: []*model.PkgInputSpec{testdata.P1}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, - }, - HS: &model.HasSBOMInputSpec{ - DownloadLocation: "location one", - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, - }, - HS: &model.HasSBOMInputSpec{ - DownloadLocation: "location two", - }, - }, - }, - Query: &model.HasSBOMSpec{ - ID: ptrfrom.String("-7"), - }, - ExpQueryErr: true, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - for _, o := range test.Calls { - // TODO (knrc) handle includes - hsID, err := b.IngestHasSbom(ctx, o.Sub, *o.HS, model.HasSBOMIncludesInputSpec{}) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - got, err := b.(*arangoClient).buildHasSbomByID(ctx, hsID, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpHS, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - } - }) - } -} diff --git a/pkg/assembler/backends/arangodb/hasSLSA.go b/pkg/assembler/backends/arangodb/hasSLSA.go index 3b13d1ae08..42ac35e06e 100644 --- a/pkg/assembler/backends/arangodb/hasSLSA.go +++ b/pkg/assembler/backends/arangodb/hasSLSA.go @@ -196,7 +196,7 @@ func getSLSAValues(subject model.ArtifactInputSpec, builtFrom []*model.Artifact, return values } -func (c *arangoClient) IngestSLSAs(ctx context.Context, subjects []*model.ArtifactInputSpec, builtFromList [][]*model.ArtifactInputSpec, builtByList []*model.BuilderInputSpec, slsaList []*model.SLSAInputSpec) ([]string, error) { +func (c *arangoClient) IngestSLSAs(ctx context.Context, subjects []*model.IDorArtifactInput, builtFromList [][]*model.IDorArtifactInput, builtByList []*model.IDorBuilderInput, slsaList []*model.SLSAInputSpec) ([]string, error) { builtFromMap := map[string][]*model.Artifact{} var listOfValues []map[string]any @@ -206,8 +206,8 @@ func (c *arangoClient) IngestSLSAs(ctx context.Context, subjects []*model.Artifa if err != nil { return nil, fmt.Errorf("failed to get built from artifact with error: %w", err) } - builtFromMap[artifactKey(subjects[i].Algorithm, subjects[i].Digest)] = materialList - listOfValues = append(listOfValues, getSLSAValues(*subjects[i], materialList, *builtByList[i], *slsaList[i])) + builtFromMap[artifactKey(subjects[i].ArtifactInput.Algorithm, subjects[i].ArtifactInput.Digest)] = materialList + listOfValues = append(listOfValues, getSLSAValues(*subjects[i].ArtifactInput, materialList, *builtByList[i].BuilderInput, *slsaList[i])) } var documents []string @@ -274,7 +274,7 @@ func (c *arangoClient) IngestSLSAs(ctx context.Context, subjects []*model.Artifa return hasSLSAIDList, nil } -func (c *arangoClient) IngestSLSA(ctx context.Context, subject model.ArtifactInputSpec, builtFrom []*model.ArtifactInputSpec, builtBy model.BuilderInputSpec, slsa model.SLSAInputSpec) (string, error) { +func (c *arangoClient) IngestSLSA(ctx context.Context, subject model.IDorArtifactInput, builtFrom []*model.IDorArtifactInput, builtBy model.IDorBuilderInput, slsa model.SLSAInputSpec) (string, error) { // get materials (builtFrom artifacts) as they should already be ingested artifacts, err := c.getMaterials(ctx, builtFrom) if err != nil { @@ -303,13 +303,13 @@ func (c *arangoClient) IngestSLSA(ctx context.Context, subject model.ArtifactInp RETURN { 'hasSLSA_id': hasSLSA._id }` - cursor, err := executeQueryWithRetry(ctx, c.db, query, getSLSAValues(subject, artifacts, builtBy, slsa), "IngestSLSA") + cursor, err := executeQueryWithRetry(ctx, c.db, query, getSLSAValues(*subject.ArtifactInput, artifacts, *builtBy.BuilderInput, slsa), "IngestSLSA") if err != nil { return "", fmt.Errorf("failed to ingest hasSLSA: %w", err) } defer cursor.Close() - hasSLSAList, err := getHasSLSAFromCursor(c, ctx, cursor, map[string][]*model.Artifact{artifactKey(subject.Algorithm, subject.Digest): artifacts}, nil, true) + hasSLSAList, err := getHasSLSAFromCursor(c, ctx, cursor, map[string][]*model.Artifact{artifactKey(subject.ArtifactInput.Algorithm, subject.ArtifactInput.Digest): artifacts}, nil, true) if err != nil { return "", fmt.Errorf("failed to get hasSLSA from arango cursor: %w", err) } diff --git a/pkg/assembler/backends/arangodb/hasSLSA_test.go b/pkg/assembler/backends/arangodb/hasSLSA_test.go deleted file mode 100644 index 22b387d532..0000000000 --- a/pkg/assembler/backends/arangodb/hasSLSA_test.go +++ /dev/null @@ -1,1130 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build integration - -package arangodb - -import ( - "context" - "strings" - "testing" - "time" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/internal/testing/testdata" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -func TestHasSLSA(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - testTime := time.Unix(1e9+5, 0) - testTime2 := time.Unix(1e9, 0) - startTime := time.Now() - finishTime := time.Now().Add(10 * time.Second) - inputPredicate := []*model.SLSAPredicateInputSpec{ - { - Key: "buildDefinition.externalParameters.repository", - Value: "https://github.com/octocat/hello-world", - }, - { - Key: "buildDefinition.externalParameters.ref", - Value: "refs/heads/main", - }, - { - Key: "buildDefinition.resolvedDependencies.uri", - Value: "git+https://github.com/octocat/hello-world@refs/heads/main", - }, - } - - slsaPredicate := []*model.SLSAPredicate{ - { - Key: "buildDefinition.externalParameters.ref", - Value: "refs/heads/main", - }, - { - Key: "buildDefinition.externalParameters.repository", - Value: "https://github.com/octocat/hello-world", - }, - { - Key: "buildDefinition.resolvedDependencies.uri", - Value: "git+https://github.com/octocat/hello-world@refs/heads/main", - }, - } - type call struct { - Sub *model.ArtifactInputSpec - BF []*model.ArtifactInputSpec - BB *model.BuilderInputSpec - SLSA *model.SLSAInputSpec - } - tests := []struct { - Name string - InArt []*model.ArtifactInputSpec - InBld []*model.BuilderInputSpec - Calls []call - Query *model.HasSLSASpec - QueryID bool - QuerySubjectID bool - QueryBuilderID bool - ExpHS []*model.HasSlsa - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "unknown", - InArt: []*model.ArtifactInputSpec{ - { - Digest: "5a787865sd676dacb0142afa0b83029cd7befd9", - Algorithm: "sha1", - }, - { - Digest: "0123456789abcdef0000000fedcba9876543210", - Algorithm: "sha1", - }, - }, - InBld: []*model.BuilderInputSpec{ - { - URI: "https://github.com/BuildPythonWheel/HubHostedActions@v1", - }, - }, - Calls: []call{ - { - Sub: &model.ArtifactInputSpec{ - Digest: "5a787865sd676dacb0142afa0b83029cd7befd9", - Algorithm: "sha1", - }, - BF: []*model.ArtifactInputSpec{{ - Digest: "0123456789abcdef0000000fedcba9876543210", - Algorithm: "sha1", - }}, - BB: &model.BuilderInputSpec{ - URI: "https://github.com/BuildPythonWheel/HubHostedActions@v1", - }, - SLSA: &model.SLSAInputSpec{ - BuildType: "Test:SLSA", - SlsaPredicate: inputPredicate, - SlsaVersion: "v1", - StartedOn: &startTime, - FinishedOn: &finishTime, - Origin: "Demo ingestion", - Collector: "Demo ingestion", - }, - }, - }, - Query: &model.HasSLSASpec{ - BuildType: ptrfrom.String("Test:SLSA"), - }, - ExpHS: []*model.HasSlsa{ - { - Subject: &model.Artifact{ - Digest: "5a787865sd676dacb0142afa0b83029cd7befd9", - Algorithm: "sha1", - }, - Slsa: &model.Slsa{ - BuiltBy: &model.Builder{ - URI: "https://github.com/BuildPythonWheel/HubHostedActions@v1", - }, - BuiltFrom: []*model.Artifact{{ - Digest: "0123456789abcdef0000000fedcba9876543210", - Algorithm: "sha1", - }}, - BuildType: "Test:SLSA", - SlsaPredicate: slsaPredicate, - SlsaVersion: "v1", - StartedOn: &startTime, - FinishedOn: &finishTime, - Origin: "Demo ingestion", - Collector: "Demo ingestion", - }, - }, - }, - }, - { - Name: "HappyPath", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - InBld: []*model.BuilderInputSpec{testdata.B1}, - Calls: []call{ - { - Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, - BB: testdata.B1, - SLSA: &model.SLSAInputSpec{ - BuildType: "test type", - }, - }, - }, - Query: &model.HasSLSASpec{ - BuildType: ptrfrom.String("test type"), - }, - ExpHS: []*model.HasSlsa{ - { - Subject: testdata.A1out, - Slsa: &model.Slsa{ - BuiltBy: testdata.B1out, - BuiltFrom: []*model.Artifact{testdata.A2out}, - BuildType: "test type", - }, - }, - }, - }, - { - Name: "Ingest twice", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - InBld: []*model.BuilderInputSpec{testdata.B1}, - Calls: []call{ - { - Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, - BB: testdata.B1, - SLSA: &model.SLSAInputSpec{ - BuildType: "test type", - }, - }, - { - Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, - BB: testdata.B1, - SLSA: &model.SLSAInputSpec{ - BuildType: "test type", - }, - }, - }, - Query: &model.HasSLSASpec{ - BuildType: ptrfrom.String("test type"), - }, - ExpHS: []*model.HasSlsa{ - { - Subject: testdata.A1out, - Slsa: &model.Slsa{ - BuiltBy: testdata.B1out, - BuiltFrom: []*model.Artifact{testdata.A2out}, - BuildType: "test type", - }, - }, - }, - }, - { - Name: "Query on Build Type", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - InBld: []*model.BuilderInputSpec{testdata.B1}, - Calls: []call{ - { - Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, - BB: testdata.B1, - SLSA: &model.SLSAInputSpec{ - BuildType: "test type one", - }, - }, - { - Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, - BB: testdata.B1, - SLSA: &model.SLSAInputSpec{ - BuildType: "test type two", - }, - }, - }, - Query: &model.HasSLSASpec{ - BuildType: ptrfrom.String("test type one"), - }, - ExpHS: []*model.HasSlsa{ - { - Subject: testdata.A1out, - Slsa: &model.Slsa{ - BuiltBy: testdata.B1out, - BuiltFrom: []*model.Artifact{testdata.A2out}, - BuildType: "test type one", - }, - }, - }, - }, - { - Name: "Query on Version", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - InBld: []*model.BuilderInputSpec{testdata.B1}, - Calls: []call{ - { - Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, - BB: testdata.B1, - SLSA: &model.SLSAInputSpec{ - SlsaVersion: "test type one", - }, - }, - { - Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, - BB: testdata.B1, - SLSA: &model.SLSAInputSpec{ - SlsaVersion: "test type two", - }, - }, - }, - Query: &model.HasSLSASpec{ - SlsaVersion: ptrfrom.String("test type two"), - }, - ExpHS: []*model.HasSlsa{ - { - Subject: testdata.A1out, - Slsa: &model.Slsa{ - BuiltBy: testdata.B1out, - BuiltFrom: []*model.Artifact{testdata.A2out}, - SlsaVersion: "test type two", - }, - }, - }, - }, - { - Name: "Query on Time", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - InBld: []*model.BuilderInputSpec{testdata.B1}, - Calls: []call{ - { - Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, - BB: testdata.B1, - SLSA: &model.SLSAInputSpec{ - StartedOn: &testTime2, - }, - }, - { - Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, - BB: testdata.B1, - SLSA: &model.SLSAInputSpec{ - StartedOn: &testTime, - }, - }, - }, - Query: &model.HasSLSASpec{ - StartedOn: &testTime, - }, - ExpHS: []*model.HasSlsa{ - { - Subject: testdata.A1out, - Slsa: &model.Slsa{ - BuiltBy: testdata.B1out, - BuiltFrom: []*model.Artifact{testdata.A2out}, - StartedOn: &testTime, - }, - }, - }, - }, - { - Name: "Query on Time", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - InBld: []*model.BuilderInputSpec{testdata.B1}, - Calls: []call{ - { - Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, - BB: testdata.B1, - SLSA: &model.SLSAInputSpec{ - FinishedOn: &testTime2, - }, - }, - { - Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, - BB: testdata.B1, - SLSA: &model.SLSAInputSpec{ - FinishedOn: &testTime, - }, - }, - }, - Query: &model.HasSLSASpec{ - FinishedOn: &testTime, - }, - ExpHS: []*model.HasSlsa{ - { - Subject: testdata.A1out, - Slsa: &model.Slsa{ - BuiltBy: testdata.B1out, - BuiltFrom: []*model.Artifact{testdata.A2out}, - FinishedOn: &testTime, - }, - }, - }, - }, - { - Name: "Query on Subject", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2, testdata.A3}, - InBld: []*model.BuilderInputSpec{testdata.B1}, - Calls: []call{ - { - Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, - BB: testdata.B1, - SLSA: &model.SLSAInputSpec{}, - }, - { - Sub: testdata.A3, - BF: []*model.ArtifactInputSpec{testdata.A2}, - BB: testdata.B1, - SLSA: &model.SLSAInputSpec{}, - }, - }, - Query: &model.HasSLSASpec{ - Subject: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha256"), - Digest: ptrfrom.String("6bbb0da1891646e58eb3e6a63af3a6fc3c8eb5a0d44824cba581d2e14a0450cf"), - }, - SlsaVersion: ptrfrom.String("test type one"), - }, - ExpHS: []*model.HasSlsa{ - { - Subject: testdata.A1out, - Slsa: &model.Slsa{ - BuiltBy: testdata.B1out, - BuiltFrom: []*model.Artifact{testdata.A2out}, - SlsaVersion: "test type one", - }, - }, - }, - }, - { - Name: "Query on Subject ID", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2, testdata.A3}, - InBld: []*model.BuilderInputSpec{testdata.B1}, - Calls: []call{ - { - Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, - BB: testdata.B1, - SLSA: &model.SLSAInputSpec{}, - }, - { - Sub: testdata.A3, - BF: []*model.ArtifactInputSpec{testdata.A2}, - BB: testdata.B1, - SLSA: &model.SLSAInputSpec{}, - }, - }, - QuerySubjectID: true, - ExpHS: []*model.HasSlsa{ - { - Subject: testdata.A3out, - Slsa: &model.Slsa{ - BuiltBy: testdata.B1out, - BuiltFrom: []*model.Artifact{testdata.A2out}, - }, - }, - }, - }, - { - Name: "Query on Materials", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2, testdata.A3, testdata.A4}, - InBld: []*model.BuilderInputSpec{testdata.B1}, - Calls: []call{ - { - Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, - BB: testdata.B1, - SLSA: &model.SLSAInputSpec{}, - }, - { - Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2, testdata.A3}, - BB: testdata.B1, - SLSA: &model.SLSAInputSpec{}, - }, - { - Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A4}, - BB: testdata.B1, - SLSA: &model.SLSAInputSpec{}, - }, - }, - Query: &model.HasSLSASpec{ - BuiltFrom: []*model.ArtifactSpec{{ - Digest: ptrfrom.String("5a787865sd676dacb0142afa0b83029cd7befd9"), - }}, - }, - ExpHS: []*model.HasSlsa{ - { - Subject: testdata.A1out, - Slsa: &model.Slsa{ - BuiltBy: testdata.B1out, - BuiltFrom: []*model.Artifact{testdata.A4out}, - }, - }, - }, - }, - { - Name: "Query on Builder", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - InBld: []*model.BuilderInputSpec{testdata.B1, testdata.B2}, - Calls: []call{ - { - Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, - BB: testdata.B1, - SLSA: &model.SLSAInputSpec{}, - }, - { - Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, - BB: testdata.B2, - SLSA: &model.SLSAInputSpec{}, - }, - }, - Query: &model.HasSLSASpec{ - BuiltBy: &model.BuilderSpec{ - URI: ptrfrom.String("qwer"), - }, - }, - ExpHS: []*model.HasSlsa{ - { - Subject: testdata.A1out, - Slsa: &model.Slsa{ - BuiltBy: testdata.B2out, - BuiltFrom: []*model.Artifact{testdata.A2out}, - }, - }, - }, - }, - { - Name: "Query on Builder ID", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2, testdata.A3}, - InBld: []*model.BuilderInputSpec{testdata.B1, testdata.B2}, - Calls: []call{ - { - Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, - BB: testdata.B1, - SLSA: &model.SLSAInputSpec{}, - }, - { - Sub: testdata.A3, - BF: []*model.ArtifactInputSpec{testdata.A2}, - BB: testdata.B2, - SLSA: &model.SLSAInputSpec{}, - }, - }, - QueryBuilderID: true, - ExpHS: []*model.HasSlsa{ - { - Subject: testdata.A1out, - Slsa: &model.Slsa{ - BuiltBy: testdata.B2out, - BuiltFrom: []*model.Artifact{testdata.A2out}, - }, - }, - { - Subject: testdata.A3out, - Slsa: &model.Slsa{ - BuiltBy: testdata.B2out, - BuiltFrom: []*model.Artifact{testdata.A2out}, - }, - }, - }, - }, - { - Name: "Query on ID", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - InBld: []*model.BuilderInputSpec{testdata.B1, testdata.B2}, - Calls: []call{ - { - Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, - BB: testdata.B1, - SLSA: &model.SLSAInputSpec{}, - }, - { - Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, - BB: testdata.B2, - SLSA: &model.SLSAInputSpec{}, - }, - }, - QueryID: true, - ExpHS: []*model.HasSlsa{ - { - Subject: testdata.A1out, - Slsa: &model.Slsa{ - BuiltBy: testdata.B2out, - BuiltFrom: []*model.Artifact{testdata.A2out}, - }, - }, - }, - }, - { - Name: "Query none", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - InBld: []*model.BuilderInputSpec{testdata.B1, testdata.B2}, - Calls: []call{ - { - Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, - BB: testdata.B1, - SLSA: &model.SLSAInputSpec{}, - }, - { - Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, - BB: testdata.B2, - SLSA: &model.SLSAInputSpec{}, - }, - }, - Query: &model.HasSLSASpec{ - BuiltBy: &model.BuilderSpec{ - URI: ptrfrom.String("poiu"), - }, - }, - ExpHS: nil, - }, - { - Name: "Query bad ID", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - InBld: []*model.BuilderInputSpec{testdata.B1, testdata.B2}, - Calls: []call{ - { - Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, - BB: testdata.B1, - SLSA: &model.SLSAInputSpec{}, - }, - { - Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, - BB: testdata.B2, - SLSA: &model.SLSAInputSpec{}, - }, - }, - Query: &model.HasSLSASpec{ - ID: ptrfrom.String("asdf"), - }, - ExpQueryErr: true, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - for _, a := range test.InArt { - if artID, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } else { - if test.QuerySubjectID { - test.Query = &model.HasSLSASpec{ - Subject: &model.ArtifactSpec{ - ID: ptrfrom.String(artID), - }, - } - } - } - } - for _, bld := range test.InBld { - if buildID, err := b.IngestBuilder(ctx, bld); err != nil { - t.Fatalf("Could not ingest builder: %v", err) - } else { - if test.QueryBuilderID { - test.Query = &model.HasSLSASpec{ - BuiltBy: &model.BuilderSpec{ - ID: ptrfrom.String(buildID), - }, - } - } - } - } - for _, o := range test.Calls { - slsaID, err := b.IngestSLSA(ctx, *o.Sub, o.BF, *o.BB, *o.SLSA) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - if test.QueryID { - test.Query = &model.HasSLSASpec{ - ID: ptrfrom.String(slsaID), - } - } - } - got, err := b.HasSlsa(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpHS, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func TestIngestHasSLSAs(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - type call struct { - Sub []*model.ArtifactInputSpec - BF [][]*model.ArtifactInputSpec - BB []*model.BuilderInputSpec - SLSA []*model.SLSAInputSpec - } - tests := []struct { - Name string - InArt []*model.ArtifactInputSpec - InBld []*model.BuilderInputSpec - Calls []call - Query *model.HasSLSASpec - ExpHS []*model.HasSlsa - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - InBld: []*model.BuilderInputSpec{testdata.B1}, - Calls: []call{ - { - Sub: []*model.ArtifactInputSpec{testdata.A1}, - BF: [][]*model.ArtifactInputSpec{{testdata.A2}}, - BB: []*model.BuilderInputSpec{testdata.B1}, - SLSA: []*model.SLSAInputSpec{ - { - BuildType: "test type", - }, - }, - }, - }, - Query: &model.HasSLSASpec{ - BuildType: ptrfrom.String("test type"), - }, - ExpHS: []*model.HasSlsa{ - { - Subject: testdata.A1out, - Slsa: &model.Slsa{ - BuiltBy: testdata.B1out, - BuiltFrom: []*model.Artifact{testdata.A2out}, - BuildType: "test type", - }, - }, - }, - }, - { - Name: "Ingest twice", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - InBld: []*model.BuilderInputSpec{testdata.B1}, - Calls: []call{ - { - Sub: []*model.ArtifactInputSpec{testdata.A1, testdata.A1}, - BF: [][]*model.ArtifactInputSpec{{testdata.A2}, {testdata.A2}}, - BB: []*model.BuilderInputSpec{testdata.B1, testdata.B1}, - SLSA: []*model.SLSAInputSpec{ - { - BuildType: "test type", - }, - { - BuildType: "test type", - }, - }, - }, - }, - Query: &model.HasSLSASpec{ - BuildType: ptrfrom.String("test type"), - }, - ExpHS: []*model.HasSlsa{ - { - Subject: testdata.A1out, - Slsa: &model.Slsa{ - BuiltBy: testdata.B1out, - BuiltFrom: []*model.Artifact{testdata.A2out}, - BuildType: "test type", - }, - }, - }, - }, - { - Name: "Query on Build Type", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - InBld: []*model.BuilderInputSpec{testdata.B1}, - Calls: []call{ - { - Sub: []*model.ArtifactInputSpec{testdata.A1, testdata.A1}, - BF: [][]*model.ArtifactInputSpec{{testdata.A2}, {testdata.A2}}, - BB: []*model.BuilderInputSpec{testdata.B1, testdata.B1}, - SLSA: []*model.SLSAInputSpec{ - { - BuildType: "test type one", - }, - { - BuildType: "test type two", - }, - }, - }, - }, - Query: &model.HasSLSASpec{ - BuildType: ptrfrom.String("test type one"), - }, - ExpHS: []*model.HasSlsa{ - { - Subject: testdata.A1out, - Slsa: &model.Slsa{ - BuiltBy: testdata.B1out, - BuiltFrom: []*model.Artifact{testdata.A2out}, - BuildType: "test type one", - }, - }, - }, - }, - { - Name: "Query on Subject", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2, testdata.A3}, - InBld: []*model.BuilderInputSpec{testdata.B1}, - Calls: []call{ - { - Sub: []*model.ArtifactInputSpec{testdata.A1, testdata.A3}, - BF: [][]*model.ArtifactInputSpec{{testdata.A2}, {testdata.A2}}, - BB: []*model.BuilderInputSpec{testdata.B1, testdata.B1}, - SLSA: []*model.SLSAInputSpec{ - {SlsaVersion: "test type one"}, - {}, - }, - }, - }, - Query: &model.HasSLSASpec{ - Subject: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha256"), - Digest: ptrfrom.String("6bbb0da1891646e58eb3e6a63af3a6fc3c8eb5a0d44824cba581d2e14a0450cf"), - }, - SlsaVersion: ptrfrom.String("test type one"), - }, - ExpHS: []*model.HasSlsa{ - { - Subject: testdata.A1out, - Slsa: &model.Slsa{ - BuiltBy: testdata.B1out, - BuiltFrom: []*model.Artifact{testdata.A2out}, - SlsaVersion: "test type one", - }, - }, - }, - }, - { - Name: "Query on Materials", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2, testdata.A3, testdata.A4}, - InBld: []*model.BuilderInputSpec{testdata.B1}, - Calls: []call{ - { - Sub: []*model.ArtifactInputSpec{testdata.A1, testdata.A1, testdata.A1}, - BF: [][]*model.ArtifactInputSpec{{testdata.A2}, {testdata.A2, testdata.A3}, {testdata.A4}}, - BB: []*model.BuilderInputSpec{testdata.B1, testdata.B1, testdata.B1}, - SLSA: []*model.SLSAInputSpec{ - {}, - {}, - {}, - }, - }, - }, - Query: &model.HasSLSASpec{ - BuiltFrom: []*model.ArtifactSpec{{ - Digest: ptrfrom.String("5a787865sd676dacb0142afa0b83029cd7befd9"), - }}, - }, - ExpHS: []*model.HasSlsa{ - { - Subject: testdata.A1out, - Slsa: &model.Slsa{ - BuiltBy: testdata.B1out, - BuiltFrom: []*model.Artifact{testdata.A4out}, - }, - }, - }, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - for _, bld := range test.InBld { - if _, err := b.IngestBuilder(ctx, bld); err != nil { - t.Fatalf("Could not ingest builder: %v", err) - } - } - for _, o := range test.Calls { - _, err := b.IngestSLSAs(ctx, o.Sub, o.BF, o.BB, o.SLSA) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.HasSlsa(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpHS, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func Test_buildHasSlsaByID(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - type call struct { - Sub *model.ArtifactInputSpec - BF []*model.ArtifactInputSpec - BB *model.BuilderInputSpec - SLSA *model.SLSAInputSpec - } - tests := []struct { - Name string - InArt []*model.ArtifactInputSpec - InBld []*model.BuilderInputSpec - Calls []call - Query *model.HasSLSASpec - ExpHS *model.HasSlsa - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "Query on Subject", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - InBld: []*model.BuilderInputSpec{testdata.B1}, - Calls: []call{ - { - Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, - BB: testdata.B1, - SLSA: &model.SLSAInputSpec{ - BuildType: "test type one", - }, - }, - }, - Query: &model.HasSLSASpec{ - Subject: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha256"), - Digest: ptrfrom.String("6bbb0da1891646e58eb3e6a63af3a6fc3c8eb5a0d44824cba581d2e14a0450cf"), - }, - BuildType: ptrfrom.String("test type one"), - }, - ExpHS: &model.HasSlsa{ - Subject: testdata.A1out, - Slsa: &model.Slsa{ - BuiltBy: testdata.B1out, - BuiltFrom: []*model.Artifact{testdata.A2out}, - BuildType: "test type one", - }, - }, - }, - { - Name: "Query on Subject ID", - InArt: []*model.ArtifactInputSpec{testdata.A2, testdata.A3}, - InBld: []*model.BuilderInputSpec{testdata.B1}, - Calls: []call{ - { - Sub: testdata.A3, - BF: []*model.ArtifactInputSpec{testdata.A2}, - BB: testdata.B1, - SLSA: &model.SLSAInputSpec{}, - }, - }, - ExpHS: &model.HasSlsa{ - Subject: testdata.A3out, - Slsa: &model.Slsa{ - BuiltBy: testdata.B1out, - BuiltFrom: []*model.Artifact{testdata.A2out}, - }, - }, - }, - { - Name: "Query on Materials", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A4}, - InBld: []*model.BuilderInputSpec{testdata.B1}, - Calls: []call{ - { - Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A4}, - BB: testdata.B1, - SLSA: &model.SLSAInputSpec{}, - }, - }, - Query: &model.HasSLSASpec{ - BuiltFrom: []*model.ArtifactSpec{{ - Digest: ptrfrom.String("5a787865sd676dacb0142afa0b83029cd7befd9"), - }}, - }, - ExpHS: &model.HasSlsa{ - Subject: testdata.A1out, - Slsa: &model.Slsa{ - BuiltBy: testdata.B1out, - BuiltFrom: []*model.Artifact{testdata.A4out}, - }, - }, - }, - { - Name: "Query on Builder", - InArt: []*model.ArtifactInputSpec{testdata.A1}, - InBld: []*model.BuilderInputSpec{testdata.B2}, - Calls: []call{ - { - Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, - BB: testdata.B2, - SLSA: &model.SLSAInputSpec{}, - }, - }, - Query: &model.HasSLSASpec{ - BuiltBy: &model.BuilderSpec{ - URI: ptrfrom.String("qwer"), - }, - }, - ExpHS: &model.HasSlsa{ - Subject: testdata.A1out, - Slsa: &model.Slsa{ - BuiltBy: testdata.B2out, - BuiltFrom: []*model.Artifact{testdata.A2out}, - }, - }, - }, - { - Name: "Query on Builder ID", - InArt: []*model.ArtifactInputSpec{testdata.A2, testdata.A3}, - InBld: []*model.BuilderInputSpec{testdata.B2}, - Calls: []call{ - { - Sub: testdata.A3, - BF: []*model.ArtifactInputSpec{testdata.A2}, - BB: testdata.B2, - SLSA: &model.SLSAInputSpec{}, - }, - }, - ExpHS: &model.HasSlsa{ - Subject: testdata.A3out, - Slsa: &model.Slsa{ - BuiltBy: testdata.B2out, - BuiltFrom: []*model.Artifact{testdata.A2out}, - }, - }, - }, - { - Name: "Query on ID", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - InBld: []*model.BuilderInputSpec{testdata.B1, testdata.B2}, - Calls: []call{ - { - Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, - BB: testdata.B2, - SLSA: &model.SLSAInputSpec{}, - }, - }, - ExpHS: &model.HasSlsa{ - Subject: testdata.A1out, - Slsa: &model.Slsa{ - BuiltBy: testdata.B2out, - BuiltFrom: []*model.Artifact{testdata.A2out}, - }, - }, - }, - { - Name: "Query bad ID", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - InBld: []*model.BuilderInputSpec{testdata.B2}, - Calls: []call{ - { - Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, - BB: testdata.B2, - SLSA: &model.SLSAInputSpec{}, - }, - }, - Query: &model.HasSLSASpec{ - ID: ptrfrom.String("asdf"), - }, - ExpQueryErr: true, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - for _, bld := range test.InBld { - if _, err := b.IngestBuilder(ctx, bld); err != nil { - t.Fatalf("Could not ingest builder: %v", err) - } - } - for _, o := range test.Calls { - slsaID, err := b.IngestSLSA(ctx, *o.Sub, o.BF, *o.BB, *o.SLSA) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - got, err := b.(*arangoClient).buildHasSlsaByID(ctx, slsaID, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpHS, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - } - - }) - } -} diff --git a/pkg/assembler/backends/arangodb/hasSourceAt.go b/pkg/assembler/backends/arangodb/hasSourceAt.go index 9bfe1fa802..3af02fad5e 100644 --- a/pkg/assembler/backends/arangodb/hasSourceAt.go +++ b/pkg/assembler/backends/arangodb/hasSourceAt.go @@ -256,7 +256,7 @@ func getHasSourceAtQueryValues(pkg *model.PkgInputSpec, pkgMatchType *model.Matc return values } -func (c *arangoClient) IngestHasSourceAt(ctx context.Context, pkg model.PkgInputSpec, pkgMatchType model.MatchFlags, source model.SourceInputSpec, hasSourceAt model.HasSourceAtInputSpec) (string, error) { +func (c *arangoClient) IngestHasSourceAt(ctx context.Context, pkg model.IDorPkgInput, pkgMatchType model.MatchFlags, source model.IDorSourceInput, hasSourceAt model.HasSourceAtInputSpec) (string, error) { var cursor driver.Cursor var err error if pkgMatchType.Pkg == model.PkgMatchTypeSpecificVersion { @@ -294,7 +294,7 @@ func (c *arangoClient) IngestHasSourceAt(ctx context.Context, pkg model.PkgInput RETURN { 'hasSourceAt_id': hasSourceAt._id }` - cursor, err = executeQueryWithRetry(ctx, c.db, query, getHasSourceAtQueryValues(&pkg, &pkgMatchType, &source, &hasSourceAt), "IngestHasSourceAt - PkgVersion") + cursor, err = executeQueryWithRetry(ctx, c.db, query, getHasSourceAtQueryValues(pkg.PackageInput, &pkgMatchType, source.SourceInput, &hasSourceAt), "IngestHasSourceAt - PkgVersion") if err != nil { return "", fmt.Errorf("failed to ingest package hasSourceAt: %w", err) } @@ -334,7 +334,7 @@ func (c *arangoClient) IngestHasSourceAt(ctx context.Context, pkg model.PkgInput RETURN { 'hasSourceAt_id': hasSourceAt._id }` - cursor, err = executeQueryWithRetry(ctx, c.db, query, getHasSourceAtQueryValues(&pkg, &pkgMatchType, &source, &hasSourceAt), "IngestHasSourceAt - PkgName") + cursor, err = executeQueryWithRetry(ctx, c.db, query, getHasSourceAtQueryValues(pkg.PackageInput, &pkgMatchType, source.SourceInput, &hasSourceAt), "IngestHasSourceAt - PkgName") if err != nil { return "", fmt.Errorf("failed to ingest package hasSourceAt: %w", err) } @@ -352,13 +352,13 @@ func (c *arangoClient) IngestHasSourceAt(ctx context.Context, pkg model.PkgInput } } -func (c *arangoClient) IngestHasSourceAts(ctx context.Context, pkgs []*model.PkgInputSpec, pkgMatchType *model.MatchFlags, sources []*model.SourceInputSpec, hasSourceAts []*model.HasSourceAtInputSpec) ([]string, error) { +func (c *arangoClient) IngestHasSourceAts(ctx context.Context, pkgs []*model.IDorPkgInput, pkgMatchType *model.MatchFlags, sources []*model.IDorSourceInput, hasSourceAts []*model.HasSourceAtInputSpec) ([]string, error) { var cursor driver.Cursor var err error var listOfValues []map[string]any for i := range pkgs { - listOfValues = append(listOfValues, getHasSourceAtQueryValues(pkgs[i], pkgMatchType, sources[i], hasSourceAts[i])) + listOfValues = append(listOfValues, getHasSourceAtQueryValues(pkgs[i].PackageInput, pkgMatchType, sources[i].SourceInput, hasSourceAts[i])) } var documents []string diff --git a/pkg/assembler/backends/arangodb/hasSourceAt_test.go b/pkg/assembler/backends/arangodb/hasSourceAt_test.go deleted file mode 100644 index 8b189df6fa..0000000000 --- a/pkg/assembler/backends/arangodb/hasSourceAt_test.go +++ /dev/null @@ -1,1105 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build integration - -package arangodb - -import ( - "context" - "strings" - "testing" - "time" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/internal/testing/testdata" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -func TestHasSourceAt(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - testTime := time.Unix(1e9+5, 0) - type call struct { - Pkg *model.PkgInputSpec - Src *model.SourceInputSpec - Match *model.MatchFlags - HSA *model.HasSourceAtInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - Calls []call - Query *model.HasSourceAtSpec - QueryID bool - QueryPkgID bool - QuerySourceID bool - ExpHSA []*model.HasSourceAt - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InSrc: []*model.SourceInputSpec{testdata.S1}, - Calls: []call{ - { - Pkg: testdata.P1, - Src: testdata.S1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.HasSourceAtSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHSA: []*model.HasSourceAt{ - { - Package: testdata.P1out, - Source: testdata.S1out, - Justification: "test justification", - }, - }, - }, - { - Name: "HappyPath All Versions", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InSrc: []*model.SourceInputSpec{testdata.S1}, - Calls: []call{ - { - Pkg: testdata.P1, - Src: testdata.S1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - HSA: &model.HasSourceAtInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.HasSourceAtSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHSA: []*model.HasSourceAt{ - { - Package: testdata.P1out, - Source: testdata.S1out, - Justification: "test justification", - }, - { - Package: testdata.P1outName, - Source: testdata.S1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest Same Twice", - InPkg: []*model.PkgInputSpec{testdata.P3}, - InSrc: []*model.SourceInputSpec{testdata.S1}, - Calls: []call{ - { - Pkg: testdata.P3, - Src: testdata.S1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{ - Justification: "test justification", - }, - }, - { - Pkg: testdata.P3, - Src: testdata.S1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.HasSourceAtSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String("2.11.1"), - Subpath: ptrfrom.String("saved_model_cli.py"), - }, - }, - ExpHSA: []*model.HasSourceAt{ - { - Package: testdata.P3out, - Source: testdata.S1out, - Justification: "test justification", - }, - { - Package: testdata.P1outName, - Source: testdata.S1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query On Justification", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InSrc: []*model.SourceInputSpec{testdata.S1}, - Calls: []call{ - { - Pkg: testdata.P1, - Src: testdata.S1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{ - Justification: "test justification one", - }, - }, - { - Pkg: testdata.P1, - Src: testdata.S1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{ - Justification: "test justification two", - }, - }, - }, - Query: &model.HasSourceAtSpec{ - Justification: ptrfrom.String("test justification two"), - }, - ExpHSA: []*model.HasSourceAt{ - { - Package: testdata.P1out, - Source: testdata.S1out, - Justification: "test justification two", - }, - }, - }, - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P4}, - InSrc: []*model.SourceInputSpec{testdata.S1}, - Calls: []call{ - { - Pkg: testdata.P1, - Src: testdata.S1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{}, - }, - { - Pkg: testdata.P4, - Src: testdata.S1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{}, - }, - }, - Query: &model.HasSourceAtSpec{ - Package: &model.PkgSpec{ - Type: ptrfrom.String("conan"), - Namespace: ptrfrom.String("openssl.org"), - Name: ptrfrom.String("openssl"), - }, - }, - ExpHSA: []*model.HasSourceAt{ - { - Package: testdata.P4out, - Source: testdata.S1out, - }, - }, - }, - { - Name: "Query on Package version ID", - InPkg: []*model.PkgInputSpec{testdata.P4}, - InSrc: []*model.SourceInputSpec{testdata.S1}, - Calls: []call{ - { - Pkg: testdata.P4, - Src: testdata.S1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{}, - }, - }, - QueryPkgID: true, - ExpHSA: []*model.HasSourceAt{ - { - Package: testdata.P4out, - Source: testdata.S1out, - }, - }, - }, - { - Name: "Query on Source - tag", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InSrc: []*model.SourceInputSpec{testdata.S1, testdata.S3}, - Calls: []call{ - { - Pkg: testdata.P1, - Src: testdata.S1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{}, - }, - { - Pkg: testdata.P1, - Src: testdata.S3, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{}, - }, - }, - Query: &model.HasSourceAtSpec{ - Source: &model.SourceSpec{ - Type: ptrfrom.String("git"), - Namespace: ptrfrom.String("github.com/jeff"), - Name: ptrfrom.String("myrepo"), - Tag: ptrfrom.String("v1.0"), - }, - }, - ExpHSA: []*model.HasSourceAt{ - { - Package: testdata.P1out, - Source: testdata.S3out, - }, - }, - }, - { - Name: "Query on Source - commit", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InSrc: []*model.SourceInputSpec{testdata.S4, testdata.S3}, - Calls: []call{ - { - Pkg: testdata.P1, - Src: testdata.S4, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{}, - }, - { - Pkg: testdata.P1, - Src: testdata.S3, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{}, - }, - }, - Query: &model.HasSourceAtSpec{ - Source: &model.SourceSpec{ - Type: ptrfrom.String("svn"), - Namespace: ptrfrom.String("github.com/bob"), - Name: ptrfrom.String("bobsrepo"), - Commit: ptrfrom.String("5e7c41f"), - }, - }, - ExpHSA: []*model.HasSourceAt{ - { - Package: testdata.P1out, - Source: testdata.S4out, - }, - }, - }, - { - Name: "Query on Source ID", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InSrc: []*model.SourceInputSpec{testdata.S2}, - Calls: []call{ - { - Pkg: testdata.P1, - Src: testdata.S2, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{}, - }, - }, - QuerySourceID: true, - ExpHSA: []*model.HasSourceAt{ - { - Package: testdata.P1out, - Source: testdata.S2out, - }, - }, - }, - { - Name: "Query on KnownSince", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InSrc: []*model.SourceInputSpec{testdata.S1}, - Calls: []call{ - { - Pkg: testdata.P1, - Src: testdata.S1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{ - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Pkg: testdata.P1, - Src: testdata.S1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{ - KnownSince: testTime, - }, - }, - }, - Query: &model.HasSourceAtSpec{ - KnownSince: &testTime, - }, - ExpHSA: []*model.HasSourceAt{ - { - Package: testdata.P1out, - Source: testdata.S1out, - KnownSince: testTime, - }, - }, - }, - { - Name: "Query Multiple", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - InSrc: []*model.SourceInputSpec{testdata.S1}, - Calls: []call{ - { - Pkg: testdata.P1, - Src: testdata.S1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{ - Justification: "test justification one", - }, - }, - { - Pkg: testdata.P1, - Src: testdata.S1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{ - Justification: "test justification two", - }, - }, - { - Pkg: testdata.P2, - Src: testdata.S1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{ - Justification: "test justification two", - }, - }, - }, - Query: &model.HasSourceAtSpec{ - Justification: ptrfrom.String("test justification two"), - }, - ExpHSA: []*model.HasSourceAt{ - { - Package: testdata.P1out, - Source: testdata.S1out, - Justification: "test justification two", - }, - { - Package: testdata.P2out, - Source: testdata.S1out, - Justification: "test justification two", - }, - }, - }, - { - Name: "Query None", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InSrc: []*model.SourceInputSpec{testdata.S1}, - Calls: []call{ - { - Pkg: testdata.P1, - Src: testdata.S1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{ - Justification: "test justification one", - }, - }, - { - Pkg: testdata.P1, - Src: testdata.S1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{ - Justification: "test justification two", - }, - }, - }, - Query: &model.HasSourceAtSpec{ - Justification: ptrfrom.String("test justification three"), - }, - ExpHSA: nil, - }, - { - Name: "Query ID", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - InSrc: []*model.SourceInputSpec{testdata.S1}, - Calls: []call{ - { - Pkg: testdata.P1, - Src: testdata.S1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{}, - }, - { - Pkg: testdata.P2, - Src: testdata.S1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{}, - }, - }, - QueryID: true, - ExpHSA: []*model.HasSourceAt{ - { - Package: testdata.P2out, - Source: testdata.S1out, - }, - }, - }, - { - Name: "Query Name and Version", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P4}, - InSrc: []*model.SourceInputSpec{testdata.S4}, - Calls: []call{ - { - Pkg: testdata.P1, - Src: testdata.S1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{}, - }, - { - Pkg: testdata.P1, - Src: testdata.S1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - HSA: &model.HasSourceAtInputSpec{}, - }, - { - Pkg: testdata.P4, - Src: testdata.S4, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{}, - }, - }, - Query: &model.HasSourceAtSpec{ - Package: &model.PkgSpec{ - Type: ptrfrom.String("conan"), - Namespace: ptrfrom.String("openssl.org"), - Name: ptrfrom.String("openssl"), - }, - Source: &model.SourceSpec{ - Type: ptrfrom.String("svn"), - Namespace: ptrfrom.String("github.com/bob"), - Name: ptrfrom.String("bobsrepo"), - Commit: ptrfrom.String("5e7c41f"), - }, - }, - ExpHSA: []*model.HasSourceAt{ - { - Package: testdata.P4out, - Source: testdata.S4out, - }, - }, - }, - { - Name: "Query bad ID", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InSrc: []*model.SourceInputSpec{testdata.S1}, - Calls: []call{ - { - Pkg: testdata.P1, - Src: testdata.S1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{}, - }, - }, - Query: &model.HasSourceAtSpec{ - ID: ptrfrom.String("asdf"), - }, - ExpQueryErr: true, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - for _, p := range test.InPkg { - if pkgIDs, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } else { - if test.QueryPkgID { - test.Query = &model.HasSourceAtSpec{ - Package: &model.PkgSpec{ - ID: ptrfrom.String(pkgIDs.PackageVersionID), - }, - } - } - } - } - for _, s := range test.InSrc { - if srcIDs, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } else { - if test.QuerySourceID { - test.Query = &model.HasSourceAtSpec{ - Source: &model.SourceSpec{ - ID: ptrfrom.String(srcIDs.SourceNameID), - }, - } - } - } - } - for _, o := range test.Calls { - hsID, err := b.IngestHasSourceAt(ctx, *o.Pkg, *o.Match, *o.Src, *o.HSA) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - if test.QueryID { - test.Query = &model.HasSourceAtSpec{ - ID: ptrfrom.String(hsID), - } - } - } - got, err := b.HasSourceAt(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpHSA, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func TestIngestHasSourceAts(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - testTime := time.Unix(1e9+5, 0) - type call struct { - Pkgs []*model.PkgInputSpec - Srcs []*model.SourceInputSpec - Match *model.MatchFlags - HSAs []*model.HasSourceAtInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - Calls []call - Query *model.HasSourceAtSpec - ExpHSA []*model.HasSourceAt - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InSrc: []*model.SourceInputSpec{testdata.S1}, - Calls: []call{ - { - Pkgs: []*model.PkgInputSpec{testdata.P1}, - Srcs: []*model.SourceInputSpec{testdata.S1}, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSAs: []*model.HasSourceAtInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.HasSourceAtSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHSA: []*model.HasSourceAt{ - { - Package: testdata.P1out, - Source: testdata.S1out, - Justification: "test justification", - }, - }, - }, - { - Name: "HappyPath All Versions", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InSrc: []*model.SourceInputSpec{testdata.S1}, - Calls: []call{ - { - Pkgs: []*model.PkgInputSpec{testdata.P1}, - Srcs: []*model.SourceInputSpec{testdata.S1}, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - HSAs: []*model.HasSourceAtInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.HasSourceAtSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHSA: []*model.HasSourceAt{ - { - Package: testdata.P1out, - Source: testdata.S1out, - Justification: "test justification", - }, - { - Package: testdata.P1outName, - Source: testdata.S1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest Same Twice", - InPkg: []*model.PkgInputSpec{testdata.P3}, - InSrc: []*model.SourceInputSpec{testdata.S1}, - Calls: []call{ - { - Pkgs: []*model.PkgInputSpec{testdata.P3, testdata.P1}, - Srcs: []*model.SourceInputSpec{testdata.S1, testdata.S1}, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSAs: []*model.HasSourceAtInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.HasSourceAtSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String("2.11.1"), - Subpath: ptrfrom.String("saved_model_cli.py"), - }, - }, - ExpHSA: []*model.HasSourceAt{ - { - Package: testdata.P3out, - Source: testdata.S1out, - Justification: "test justification", - }, - { - Package: testdata.P1outName, - Source: testdata.S1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P4}, - InSrc: []*model.SourceInputSpec{testdata.S1}, - Calls: []call{ - { - Pkgs: []*model.PkgInputSpec{testdata.P1, testdata.P4}, - Srcs: []*model.SourceInputSpec{testdata.S1, testdata.S1}, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSAs: []*model.HasSourceAtInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.HasSourceAtSpec{ - Package: &model.PkgSpec{ - Type: ptrfrom.String("conan"), - Namespace: ptrfrom.String("openssl.org"), - Name: ptrfrom.String("openssl"), - }, - }, - ExpHSA: []*model.HasSourceAt{ - { - Package: testdata.P4out, - Source: testdata.S1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Source", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InSrc: []*model.SourceInputSpec{testdata.S1, testdata.S3}, - Calls: []call{ - { - Pkgs: []*model.PkgInputSpec{testdata.P1, testdata.P1}, - Srcs: []*model.SourceInputSpec{testdata.S1, testdata.S3}, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSAs: []*model.HasSourceAtInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.HasSourceAtSpec{ - Source: &model.SourceSpec{ - Type: ptrfrom.String("git"), - Namespace: ptrfrom.String("github.com/jeff"), - Name: ptrfrom.String("myrepo"), - Tag: ptrfrom.String("v1.0"), - }, - }, - ExpHSA: []*model.HasSourceAt{ - { - Package: testdata.P1out, - Source: testdata.S3out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on KnownSince", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InSrc: []*model.SourceInputSpec{testdata.S1}, - Calls: []call{ - { - Pkgs: []*model.PkgInputSpec{testdata.P1, testdata.P1}, - Srcs: []*model.SourceInputSpec{testdata.S1, testdata.S1}, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSAs: []*model.HasSourceAtInputSpec{ - { - KnownSince: time.Unix(1e9, 0), - }, - { - KnownSince: testTime, - }, - }, - }, - }, - Query: &model.HasSourceAtSpec{ - KnownSince: &testTime, - }, - ExpHSA: []*model.HasSourceAt{ - { - Package: testdata.P1out, - Source: testdata.S1out, - KnownSince: testTime, - }, - }, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, o := range test.Calls { - _, err := b.IngestHasSourceAts(ctx, o.Pkgs, o.Match, o.Srcs, o.HSAs) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.HasSourceAt(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpHSA, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func Test_buildHasSourceAtByID(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - type call struct { - Pkg *model.PkgInputSpec - Src *model.SourceInputSpec - Match *model.MatchFlags - HSA *model.HasSourceAtInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - Calls []call - Query *model.HasSourceAtSpec - ExpHSA *model.HasSourceAt - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{testdata.P4}, - InSrc: []*model.SourceInputSpec{testdata.S1}, - Calls: []call{ - { - Pkg: testdata.P4, - Src: testdata.S1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{}, - }, - }, - Query: &model.HasSourceAtSpec{ - Package: &model.PkgSpec{ - Type: ptrfrom.String("conan"), - Namespace: ptrfrom.String("openssl.org"), - Name: ptrfrom.String("openssl"), - }, - }, - ExpHSA: &model.HasSourceAt{ - Package: testdata.P4out, - Source: testdata.S1out, - }, - }, - { - Name: "Query on Package version ID", - InPkg: []*model.PkgInputSpec{testdata.P4}, - InSrc: []*model.SourceInputSpec{testdata.S1}, - Calls: []call{ - { - Pkg: testdata.P4, - Src: testdata.S1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{}, - }, - }, - ExpHSA: &model.HasSourceAt{ - Package: testdata.P4out, - Source: testdata.S1out, - }, - }, - { - Name: "Query on Source - tag", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InSrc: []*model.SourceInputSpec{testdata.S3}, - Calls: []call{ - { - Pkg: testdata.P1, - Src: testdata.S3, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{}, - }, - }, - Query: &model.HasSourceAtSpec{ - Source: &model.SourceSpec{ - Type: ptrfrom.String("git"), - Namespace: ptrfrom.String("github.com/jeff"), - Name: ptrfrom.String("myrepo"), - Tag: ptrfrom.String("v1.0"), - }, - }, - ExpHSA: &model.HasSourceAt{ - Package: testdata.P1out, - Source: testdata.S3out, - }, - }, - { - Name: "Query on Source ID", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InSrc: []*model.SourceInputSpec{testdata.S2}, - Calls: []call{ - { - Pkg: testdata.P1, - Src: testdata.S2, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{}, - }, - }, - ExpHSA: &model.HasSourceAt{ - Package: testdata.P1out, - Source: testdata.S2out, - }, - }, - { - Name: "Query ID", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - InSrc: []*model.SourceInputSpec{testdata.S1}, - Calls: []call{ - { - Pkg: testdata.P2, - Src: testdata.S1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{}, - }, - }, - ExpHSA: &model.HasSourceAt{ - Package: testdata.P2out, - Source: testdata.S1out, - }, - }, - { - Name: "Query bad ID", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InSrc: []*model.SourceInputSpec{testdata.S1}, - Calls: []call{ - { - Pkg: testdata.P1, - Src: testdata.S1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{}, - }, - }, - Query: &model.HasSourceAtSpec{ - ID: ptrfrom.String("asdf"), - }, - ExpQueryErr: true, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, o := range test.Calls { - hsID, err := b.IngestHasSourceAt(ctx, *o.Pkg, *o.Match, *o.Src, *o.HSA) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - got, err := b.(*arangoClient).buildHasSourceAtByID(ctx, hsID, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpHSA, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - } - }) - } -} diff --git a/pkg/assembler/backends/arangodb/hashEqual.go b/pkg/assembler/backends/arangodb/hashEqual.go index c94b12ef71..7c48633e5a 100644 --- a/pkg/assembler/backends/arangodb/hashEqual.go +++ b/pkg/assembler/backends/arangodb/hashEqual.go @@ -177,11 +177,11 @@ func getHashEqualQueryValues(artifact *model.ArtifactInputSpec, equalArtifact *m return values } -func (c *arangoClient) IngestHashEquals(ctx context.Context, artifacts []*model.ArtifactInputSpec, otherArtifacts []*model.ArtifactInputSpec, hashEquals []*model.HashEqualInputSpec) ([]string, error) { +func (c *arangoClient) IngestHashEquals(ctx context.Context, artifacts []*model.IDorArtifactInput, otherArtifacts []*model.IDorArtifactInput, hashEquals []*model.HashEqualInputSpec) ([]string, error) { var listOfValues []map[string]any for i := range artifacts { - listOfValues = append(listOfValues, getHashEqualQueryValues(artifacts[i], otherArtifacts[i], hashEquals[i])) + listOfValues = append(listOfValues, getHashEqualQueryValues(artifacts[i].ArtifactInput, otherArtifacts[i].ArtifactInput, hashEquals[i])) } var documents []string @@ -245,7 +245,7 @@ func (c *arangoClient) IngestHashEquals(ctx context.Context, artifacts []*model. return hasEqualIDList, nil } -func (c *arangoClient) IngestHashEqual(ctx context.Context, artifact model.ArtifactInputSpec, equalArtifact model.ArtifactInputSpec, hashEqual model.HashEqualInputSpec) (string, error) { +func (c *arangoClient) IngestHashEqual(ctx context.Context, artifact model.IDorArtifactInput, equalArtifact model.IDorArtifactInput, hashEqual model.HashEqualInputSpec) (string, error) { query := ` LET artifact = FIRST(FOR art IN artifacts FILTER art.algorithm == @art_algorithm FILTER art.digest == @art_digest RETURN art) LET equalArtifact = FIRST(FOR art IN artifacts FILTER art.algorithm == @equal_algorithm FILTER art.digest == @equal_digest RETURN art) @@ -264,7 +264,7 @@ INSERT { _key: CONCAT("hashEqualArtEdges", hashEqual._key, equalArtifact._key), RETURN { 'hashEqual_id': hashEqual._id }` - cursor, err := executeQueryWithRetry(ctx, c.db, query, getHashEqualQueryValues(&artifact, &equalArtifact, &hashEqual), "IngestHashEqual") + cursor, err := executeQueryWithRetry(ctx, c.db, query, getHashEqualQueryValues(artifact.ArtifactInput, equalArtifact.ArtifactInput, &hashEqual), "IngestHashEqual") if err != nil { return "", fmt.Errorf("failed to ingest hashEqual: %w", err) } diff --git a/pkg/assembler/backends/arangodb/hashEqual_test.go b/pkg/assembler/backends/arangodb/hashEqual_test.go deleted file mode 100644 index 3e03079fef..0000000000 --- a/pkg/assembler/backends/arangodb/hashEqual_test.go +++ /dev/null @@ -1,932 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build integration - -package arangodb - -import ( - "context" - "slices" - "strings" - "testing" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/internal/testing/testdata" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -func TestHashEqual(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - type call struct { - A1 *model.ArtifactInputSpec - A2 *model.ArtifactInputSpec - HE *model.HashEqualInputSpec - } - tests := []struct { - Name string - InArt []*model.ArtifactInputSpec - Calls []call - Query *model.HashEqualSpec - QueryID bool - QueryArtID bool - ExpHE []*model.HashEqual - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - Calls: []call{ - { - A1: testdata.A1, - A2: testdata.A2, - HE: &model.HashEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.HashEqualSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{testdata.A1out, testdata.A2out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest same, different order", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - Calls: []call{ - { - A1: testdata.A1, - A2: testdata.A2, - HE: &model.HashEqualInputSpec{ - Justification: "test justification", - }, - }, - { - A1: testdata.A2, - A2: testdata.A1, - HE: &model.HashEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.HashEqualSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{testdata.A1out, testdata.A2out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Justification", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - Calls: []call{ - { - A1: testdata.A1, - A2: testdata.A2, - HE: &model.HashEqualInputSpec{ - Justification: "test justification one", - }, - }, - { - A1: testdata.A1, - A2: testdata.A2, - HE: &model.HashEqualInputSpec{ - Justification: "test justification two", - }, - }, - }, - Query: &model.HashEqualSpec{ - Justification: ptrfrom.String("test justification one"), - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{testdata.A1out, testdata.A2out}, - Justification: "test justification one", - }, - }, - }, - { - Name: "Query on artifact", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2, testdata.A3}, - Calls: []call{ - { - A1: testdata.A1, - A2: testdata.A2, - HE: &model.HashEqualInputSpec{}, - }, - { - A1: testdata.A1, - A2: testdata.A3, - HE: &model.HashEqualInputSpec{}, - }, - }, - Query: &model.HashEqualSpec{ - Artifacts: []*model.ArtifactSpec{{ - Digest: ptrfrom.String("374AB8F711235830769AA5F0B31CE9B72C5670074B34CB302CDAFE3B606233EE92EE01E298E5701F15CC7087714CD9ABD7DDB838A6E1206B3642DE16D9FC9DD7"), - }}, - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{testdata.A1out, testdata.A3out}, - }, - }, - }, - { - Name: "Query on artifact ID", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2, testdata.A3}, - Calls: []call{ - { - A1: testdata.A1, - A2: testdata.A2, - HE: &model.HashEqualInputSpec{}, - }, - { - A1: testdata.A1, - A2: testdata.A3, - HE: &model.HashEqualInputSpec{}, - }, - }, - QueryArtID: true, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{testdata.A1out, testdata.A3out}, - }, - }, - }, - { - Name: "Query on artifact multiple", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2, testdata.A3}, - Calls: []call{ - { - A1: testdata.A1, - A2: testdata.A2, - HE: &model.HashEqualInputSpec{}, - }, - { - A1: testdata.A1, - A2: testdata.A3, - HE: &model.HashEqualInputSpec{}, - }, - }, - Query: &model.HashEqualSpec{ - Artifacts: []*model.ArtifactSpec{{ - Digest: ptrfrom.String("6bbb0da1891646e58eb3e6a63af3a6fc3c8eb5a0d44824cba581d2e14a0450cf"), - }}, - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{testdata.A1out, testdata.A2out}, - }, - { - Artifacts: []*model.Artifact{testdata.A1out, testdata.A2out}, - Justification: "test justification two", - }, - { - Artifacts: []*model.Artifact{testdata.A1out, testdata.A2out}, - Justification: "test justification one", - }, - { - Artifacts: []*model.Artifact{testdata.A1out, testdata.A2out}, - Justification: "test justification", - }, - { - Artifacts: []*model.Artifact{testdata.A1out, testdata.A3out}, - }, - }, - }, - { - Name: "Query on artifact algo", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2, testdata.A3}, - Calls: []call{ - { - A1: testdata.A1, - A2: testdata.A2, - HE: &model.HashEqualInputSpec{}, - }, - { - A1: testdata.A1, - A2: testdata.A3, - HE: &model.HashEqualInputSpec{}, - }, - }, - Query: &model.HashEqualSpec{ - Artifacts: []*model.ArtifactSpec{{ - Algorithm: ptrfrom.String("sha1"), - }}, - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{testdata.A1out, testdata.A2out}, - }, - { - Artifacts: []*model.Artifact{testdata.A1out, testdata.A2out}, - Justification: "test justification two", - }, - { - Artifacts: []*model.Artifact{testdata.A1out, testdata.A2out}, - Justification: "test justification one", - }, - { - Artifacts: []*model.Artifact{testdata.A1out, testdata.A2out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on artifact algo and hash", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2, testdata.A3}, - Calls: []call{ - { - A1: testdata.A1, - A2: testdata.A2, - HE: &model.HashEqualInputSpec{}, - }, - { - A1: testdata.A1, - A2: testdata.A3, - HE: &model.HashEqualInputSpec{}, - }, - }, - Query: &model.HashEqualSpec{ - Artifacts: []*model.ArtifactSpec{{ - Algorithm: ptrfrom.String("sha1"), - Digest: ptrfrom.String("7A8F47318E4676DACB0142AFA0B83029CD7BEFD9"), - }}, - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{testdata.A1out, testdata.A2out}, - }, - { - Artifacts: []*model.Artifact{testdata.A1out, testdata.A2out}, - Justification: "test justification two", - }, - { - Artifacts: []*model.Artifact{testdata.A1out, testdata.A2out}, - Justification: "test justification one", - }, - { - Artifacts: []*model.Artifact{testdata.A1out, testdata.A2out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on both artifacts", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2, testdata.A3}, - Calls: []call{ - { - A1: testdata.A1, - A2: testdata.A2, - HE: &model.HashEqualInputSpec{}, - }, - { - A1: testdata.A2, - A2: testdata.A3, - HE: &model.HashEqualInputSpec{}, - }, - }, - Query: &model.HashEqualSpec{ - Artifacts: []*model.ArtifactSpec{ - { - Algorithm: ptrfrom.String("sha1"), - Digest: ptrfrom.String("7A8F47318E4676DACB0142AFA0B83029CD7BEFD9"), - }, - { - Algorithm: ptrfrom.String("sha512"), - }, - }, - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{testdata.A2out, testdata.A3out}, - }, - }, - }, - { - Name: "Query on both artifacts, one filter", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2, testdata.A3}, - Calls: []call{ - { - A1: testdata.A1, - A2: testdata.A2, - HE: &model.HashEqualInputSpec{}, - }, - { - A1: testdata.A2, - A2: testdata.A3, - HE: &model.HashEqualInputSpec{}, - }, - { - A1: testdata.A1, - A2: testdata.A3, - HE: &model.HashEqualInputSpec{}, - }, - }, - Query: &model.HashEqualSpec{ - Artifacts: []*model.ArtifactSpec{ - { - Algorithm: ptrfrom.String("sha1"), - }, - { - Digest: ptrfrom.String("6bbb0da1891646e58eb3e6a63af3a6fc3c8eb5a0d44824cba581d2e14a0450cf"), - }, - }, - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{testdata.A1out, testdata.A2out}, - }, - { - Artifacts: []*model.Artifact{testdata.A1out, testdata.A2out}, - Justification: "test justification two", - }, - { - Artifacts: []*model.Artifact{testdata.A1out, testdata.A2out}, - Justification: "test justification one", - }, - { - Artifacts: []*model.Artifact{testdata.A1out, testdata.A2out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Query none", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2, testdata.A3}, - Calls: []call{ - { - A1: testdata.A1, - A2: testdata.A2, - HE: &model.HashEqualInputSpec{}, - }, - { - A1: testdata.A2, - A2: testdata.A3, - HE: &model.HashEqualInputSpec{}, - }, - { - A1: testdata.A1, - A2: testdata.A3, - HE: &model.HashEqualInputSpec{}, - }, - }, - Query: &model.HashEqualSpec{ - Artifacts: []*model.ArtifactSpec{ - { - Algorithm: ptrfrom.String("gitHash"), - }, - { - Digest: ptrfrom.String("6bbb0da1891646e58eb3e6a63af3a6fc3c8eb5a0d44824cba581d2e14a0450cf"), - }, - }, - }, - ExpHE: nil, - }, - { - Name: "Query on ID", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2, testdata.A3}, - Calls: []call{ - { - A1: testdata.A1, - A2: testdata.A2, - HE: &model.HashEqualInputSpec{}, - }, - { - A1: testdata.A2, - A2: testdata.A3, - HE: &model.HashEqualInputSpec{}, - }, - { - A1: testdata.A1, - A2: testdata.A3, - HE: &model.HashEqualInputSpec{}, - }, - }, - QueryID: true, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{testdata.A1out, testdata.A3out}, - }, - }, - }, - { - Name: "Query bad ID", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2, testdata.A3}, - Calls: []call{ - { - A1: testdata.A1, - A2: testdata.A2, - HE: &model.HashEqualInputSpec{}, - }, - { - A1: testdata.A2, - A2: testdata.A3, - HE: &model.HashEqualInputSpec{}, - }, - { - A1: testdata.A1, - A2: testdata.A3, - HE: &model.HashEqualInputSpec{}, - }, - }, - Query: &model.HashEqualSpec{ - ID: ptrfrom.String("asdf"), - }, - ExpQueryErr: true, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - if artIDs, err := b.IngestArtifacts(ctx, test.InArt); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } else { - if test.QueryArtID { - test.Query = &model.HashEqualSpec{ - Artifacts: []*model.ArtifactSpec{ - { - ID: ptrfrom.String(artIDs[0]), - }, - { - ID: ptrfrom.String(artIDs[2]), - }, - }, - } - } - } - for _, o := range test.Calls { - heID, err := b.IngestHashEqual(ctx, *o.A1, *o.A2, *o.HE) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - if test.QueryID { - test.Query = &model.HashEqualSpec{ - ID: ptrfrom.String(heID), - } - } - } - got, err := b.HashEqual(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - less := func(a, b *model.Artifact) int { return strings.Compare(a.Digest, b.Digest) } - for _, he := range got { - slices.SortFunc(he.Artifacts, less) - } - for _, he := range test.ExpHE { - slices.SortFunc(he.Artifacts, less) - } - if diff := cmp.Diff(test.ExpHE, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func TestIngestHashEquals(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - type call struct { - A1 []*model.ArtifactInputSpec - A2 []*model.ArtifactInputSpec - HE []*model.HashEqualInputSpec - } - tests := []struct { - Name string - InArt []*model.ArtifactInputSpec - Calls []call - Query *model.HashEqualSpec - ExpHE []*model.HashEqual - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - Calls: []call{ - { - A1: []*model.ArtifactInputSpec{testdata.A1}, - A2: []*model.ArtifactInputSpec{testdata.A2}, - HE: []*model.HashEqualInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.HashEqualSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{testdata.A1out, testdata.A2out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest same, different order", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - Calls: []call{ - { - A1: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - A2: []*model.ArtifactInputSpec{testdata.A2, testdata.A1}, - HE: []*model.HashEqualInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.HashEqualSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{testdata.A1out, testdata.A2out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Justification", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - Calls: []call{ - { - A1: []*model.ArtifactInputSpec{testdata.A1, testdata.A1}, - A2: []*model.ArtifactInputSpec{testdata.A2, testdata.A2}, - HE: []*model.HashEqualInputSpec{ - { - Justification: "test justification one", - }, - { - Justification: "test justification two", - }, - }, - }, - }, - Query: &model.HashEqualSpec{ - Justification: ptrfrom.String("test justification one"), - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{testdata.A1out, testdata.A2out}, - Justification: "test justification one", - }, - }, - }, - { - Name: "Query on artifact", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2, testdata.A3}, - Calls: []call{ - { - A1: []*model.ArtifactInputSpec{testdata.A1, testdata.A1}, - A2: []*model.ArtifactInputSpec{testdata.A2, testdata.A3}, - HE: []*model.HashEqualInputSpec{ - {}, - {}, - }, - }, - }, - Query: &model.HashEqualSpec{ - Artifacts: []*model.ArtifactSpec{{ - Digest: ptrfrom.String("374AB8F711235830769AA5F0B31CE9B72C5670074B34CB302CDAFE3B606233EE92EE01E298E5701F15CC7087714CD9ABD7DDB838A6E1206B3642DE16D9FC9DD7"), - }}, - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{testdata.A1out, testdata.A3out}, - }, - }, - }, - { - Name: "Query on artifact multiple", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2, testdata.A3}, - Calls: []call{ - { - A1: []*model.ArtifactInputSpec{testdata.A1, testdata.A1}, - A2: []*model.ArtifactInputSpec{testdata.A2, testdata.A3}, - HE: []*model.HashEqualInputSpec{ - {}, - {}, - }, - }, - }, - Query: &model.HashEqualSpec{ - Artifacts: []*model.ArtifactSpec{{ - Digest: ptrfrom.String("6bbb0da1891646e58eb3e6a63af3a6fc3c8eb5a0d44824cba581d2e14a0450cf"), - }}, - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{testdata.A1out, testdata.A2out}, - }, - { - Artifacts: []*model.Artifact{testdata.A1out, testdata.A2out}, - Justification: "test justification two", - }, - { - Artifacts: []*model.Artifact{testdata.A1out, testdata.A2out}, - Justification: "test justification one", - }, - { - Artifacts: []*model.Artifact{testdata.A1out, testdata.A2out}, - Justification: "test justification", - }, - { - Artifacts: []*model.Artifact{testdata.A1out, testdata.A3out}, - }, - }, - }, - { - Name: "Query on artifact algo", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2, testdata.A3}, - Calls: []call{ - { - A1: []*model.ArtifactInputSpec{testdata.A1, testdata.A1}, - A2: []*model.ArtifactInputSpec{testdata.A2, testdata.A3}, - HE: []*model.HashEqualInputSpec{ - {}, - {}, - }, - }, - }, - Query: &model.HashEqualSpec{ - Artifacts: []*model.ArtifactSpec{{ - Algorithm: ptrfrom.String("sha1"), - }}, - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{testdata.A1out, testdata.A2out}, - }, - { - Artifacts: []*model.Artifact{testdata.A1out, testdata.A2out}, - Justification: "test justification two", - }, - { - Artifacts: []*model.Artifact{testdata.A1out, testdata.A2out}, - Justification: "test justification one", - }, - { - Artifacts: []*model.Artifact{testdata.A1out, testdata.A2out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on artifact algo and hash", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2, testdata.A3}, - Calls: []call{ - { - A1: []*model.ArtifactInputSpec{testdata.A1, testdata.A1}, - A2: []*model.ArtifactInputSpec{testdata.A2, testdata.A3}, - HE: []*model.HashEqualInputSpec{ - {}, - {}, - }, - }, - }, - Query: &model.HashEqualSpec{ - Artifacts: []*model.ArtifactSpec{{ - Algorithm: ptrfrom.String("sha1"), - Digest: ptrfrom.String("7A8F47318E4676DACB0142AFA0B83029CD7BEFD9"), - }}, - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{testdata.A1out, testdata.A2out}, - }, - { - Artifacts: []*model.Artifact{testdata.A1out, testdata.A2out}, - Justification: "test justification two", - }, - { - Artifacts: []*model.Artifact{testdata.A1out, testdata.A2out}, - Justification: "test justification one", - }, - { - Artifacts: []*model.Artifact{testdata.A1out, testdata.A2out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on both artifacts", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2, testdata.A3}, - Calls: []call{ - { - A1: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - A2: []*model.ArtifactInputSpec{testdata.A2, testdata.A3}, - HE: []*model.HashEqualInputSpec{ - {}, - {}, - }, - }, - }, - Query: &model.HashEqualSpec{ - Artifacts: []*model.ArtifactSpec{ - { - Algorithm: ptrfrom.String("sha1"), - Digest: ptrfrom.String("7A8F47318E4676DACB0142AFA0B83029CD7BEFD9"), - }, - { - Algorithm: ptrfrom.String("sha512"), - }, - }, - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{testdata.A2out, testdata.A3out}, - }, - }, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - for _, o := range test.Calls { - _, err := b.IngestHashEquals(ctx, o.A1, o.A2, o.HE) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.HashEqual(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - less := func(a, b *model.Artifact) int { return strings.Compare(a.Digest, b.Digest) } - for _, he := range got { - slices.SortFunc(he.Artifacts, less) - } - for _, he := range test.ExpHE { - slices.SortFunc(he.Artifacts, less) - } - if diff := cmp.Diff(test.ExpHE, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func Test_buildHashEqualByID(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - type call struct { - A1 *model.ArtifactInputSpec - A2 *model.ArtifactInputSpec - HE *model.HashEqualInputSpec - } - tests := []struct { - Name string - InArt []*model.ArtifactInputSpec - Calls []call - Query *model.HashEqualSpec - ExpHE *model.HashEqual - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "Query on ID", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2, testdata.A3}, - Calls: []call{ - { - A1: testdata.A1, - A2: testdata.A3, - HE: &model.HashEqualInputSpec{}, - }, - }, - ExpHE: &model.HashEqual{ - Artifacts: []*model.Artifact{testdata.A3out, testdata.A1out}, - }, - }, - { - Name: "Query bad ID", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2, testdata.A3}, - Calls: []call{ - { - A1: testdata.A1, - A2: testdata.A2, - HE: &model.HashEqualInputSpec{}, - }, - { - A1: testdata.A2, - A2: testdata.A3, - HE: &model.HashEqualInputSpec{}, - }, - { - A1: testdata.A1, - A2: testdata.A3, - HE: &model.HashEqualInputSpec{}, - }, - }, - Query: &model.HashEqualSpec{ - ID: ptrfrom.String("asdf"), - }, - ExpQueryErr: true, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - for _, o := range test.Calls { - heID, err := b.IngestHashEqual(ctx, *o.A1, *o.A2, *o.HE) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - got, err := b.(*arangoClient).buildHashEqualByID(ctx, heID, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpHE, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - } - }) - } -} diff --git a/pkg/assembler/backends/arangodb/isDependency.go b/pkg/assembler/backends/arangodb/isDependency.go index 3223aa61e8..6801b9ebbf 100644 --- a/pkg/assembler/backends/arangodb/isDependency.go +++ b/pkg/assembler/backends/arangodb/isDependency.go @@ -345,13 +345,13 @@ func getDependencyQueryValues(pkg *model.PkgInputSpec, depPkg *model.PkgInputSpe return values } -func (c *arangoClient) IngestDependencies(ctx context.Context, pkgs []*model.PkgInputSpec, depPkgs []*model.PkgInputSpec, depPkgMatchType model.MatchFlags, dependencies []*model.IsDependencyInputSpec) ([]string, error) { +func (c *arangoClient) IngestDependencies(ctx context.Context, pkgs []*model.IDorPkgInput, depPkgs []*model.IDorPkgInput, depPkgMatchType model.MatchFlags, dependencies []*model.IsDependencyInputSpec) ([]string, error) { // TODO(LUMJJB): handle pkgmatchtype var listOfValues []map[string]any for i := range pkgs { - listOfValues = append(listOfValues, getDependencyQueryValues(pkgs[i], depPkgs[i], depPkgMatchType, dependencies[i])) + listOfValues = append(listOfValues, getDependencyQueryValues(pkgs[i].PackageInput, depPkgs[i].PackageInput, depPkgMatchType, dependencies[i])) } var documents []string @@ -469,7 +469,7 @@ func (c *arangoClient) IngestDependencies(ctx context.Context, pkgs []*model.Pkg return isDepIDList, nil } -func (c *arangoClient) IngestDependency(ctx context.Context, pkg model.PkgInputSpec, depPkg model.PkgInputSpec, depPkgMatchType model.MatchFlags, dependency model.IsDependencyInputSpec) (string, error) { +func (c *arangoClient) IngestDependency(ctx context.Context, pkg model.IDorPkgInput, depPkg model.IDorPkgInput, depPkgMatchType model.MatchFlags, dependency model.IsDependencyInputSpec) (string, error) { var query string if depPkgMatchType.Pkg == model.PkgMatchTypeAllVersions { @@ -544,7 +544,7 @@ func (c *arangoClient) IngestDependency(ctx context.Context, pkg model.PkgInputS RETURN { 'isDependency_id': isDependency._id }` } - cursor, err := executeQueryWithRetry(ctx, c.db, query, getDependencyQueryValues(&pkg, &depPkg, depPkgMatchType, &dependency), "IngestDependency") + cursor, err := executeQueryWithRetry(ctx, c.db, query, getDependencyQueryValues(pkg.PackageInput, depPkg.PackageInput, depPkgMatchType, &dependency), "IngestDependency") if err != nil { return "", fmt.Errorf("failed to ingest isDependency: %w", err) } diff --git a/pkg/assembler/backends/arangodb/isDependency_test.go b/pkg/assembler/backends/arangodb/isDependency_test.go deleted file mode 100644 index bbbc20b85d..0000000000 --- a/pkg/assembler/backends/arangodb/isDependency_test.go +++ /dev/null @@ -1,1188 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build integration - -package arangodb - -import ( - "context" - "strings" - "testing" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/internal/testing/testdata" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -var ( - mAll = model.MatchFlags{Pkg: model.PkgMatchTypeAllVersions} - mSpecific = model.MatchFlags{Pkg: model.PkgMatchTypeSpecificVersion} -) - -func TestIsDependency(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - type call struct { - P1 *model.PkgInputSpec - P2 *model.PkgInputSpec - MF model.MatchFlags - ID *model.IsDependencyInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - Calls []call - Query *model.IsDependencySpec - QueryID bool - QueryPkgID bool - QueryDepPkgID bool - ExpID []*model.IsDependency - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - Calls: []call{ - { - P1: testdata.P1, - P2: testdata.P2, - MF: mAll, - ID: &model.IsDependencyInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.IsDependencySpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpID: []*model.IsDependency{ - { - Package: testdata.P1out, - DependencyPackage: testdata.P2outName, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest same", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - Calls: []call{ - { - P1: testdata.P1, - P2: testdata.P2, - MF: mAll, - ID: &model.IsDependencyInputSpec{ - Justification: "test justification", - }, - }, - { - P1: testdata.P1, - P2: testdata.P2, - MF: mAll, - ID: &model.IsDependencyInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.IsDependencySpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpID: []*model.IsDependency{ - { - Package: testdata.P1out, - DependencyPackage: testdata.P2outName, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest same, different version", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2, testdata.P3}, - Calls: []call{ - { - P1: testdata.P1, - P2: testdata.P2, - MF: mAll, - ID: &model.IsDependencyInputSpec{ - Justification: "test justification", - }, - }, - { - P1: testdata.P1, - P2: testdata.P3, - MF: mAll, - ID: &model.IsDependencyInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.IsDependencySpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpID: []*model.IsDependency{ - { - Package: testdata.P1out, - DependencyPackage: testdata.P2outName, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Justification", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - Calls: []call{ - { - P1: testdata.P1, - P2: testdata.P2, - MF: mAll, - ID: &model.IsDependencyInputSpec{ - Justification: "test justification one", - }, - }, - { - P1: testdata.P1, - P2: testdata.P2, - MF: mAll, - ID: &model.IsDependencyInputSpec{ - Justification: "test justification two", - }, - }, - }, - Query: &model.IsDependencySpec{ - Justification: ptrfrom.String("test justification one"), - }, - ExpID: []*model.IsDependency{ - { - Package: testdata.P1out, - DependencyPackage: testdata.P2outName, - Justification: "test justification one", - }, - }, - }, - { - Name: "Query on pkg", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2, testdata.P3}, - Calls: []call{ - { - P1: testdata.P1, - P2: testdata.P2, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - { - P1: testdata.P2, - P2: testdata.P3, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - }, - Query: &model.IsDependencySpec{ - Package: &model.PkgSpec{ - Name: ptrfrom.String("tensorflow"), - Version: ptrfrom.String("2.11.1"), - }, - }, - ExpID: []*model.IsDependency{ - { - Package: testdata.P2out, - DependencyPackage: testdata.P2outName, - }, - }, - }, - { - Name: "Query on dep pkg", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2, testdata.P4}, - Calls: []call{ - { - P1: testdata.P2, - P2: testdata.P4, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - { - P1: testdata.P2, - P2: testdata.P1, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - }, - Query: &model.IsDependencySpec{ - DependencyPackage: &model.PkgSpec{ - Name: ptrfrom.String("openssl"), - }, - }, - ExpID: []*model.IsDependency{ - { - Package: testdata.P2out, - DependencyPackage: testdata.P4outName, - }, - }, - }, - { - Name: "Query on dep pkg - type", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2, testdata.P4}, - Calls: []call{ - { - P1: testdata.P2, - P2: testdata.P4, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - { - P1: testdata.P2, - P2: testdata.P1, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - }, - Query: &model.IsDependencySpec{ - DependencyPackage: &model.PkgSpec{ - Type: ptrfrom.String("conan"), - }, - }, - ExpID: []*model.IsDependency{ - { - Package: testdata.P2out, - DependencyPackage: testdata.P4outName, - }, - }, - }, - { - Name: "Query on dep pkg - namespace", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2, testdata.P4}, - Calls: []call{ - { - P1: testdata.P2, - P2: testdata.P4, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - { - P1: testdata.P2, - P2: testdata.P1, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - }, - Query: &model.IsDependencySpec{ - DependencyPackage: &model.PkgSpec{ - Namespace: ptrfrom.String("openssl.org"), - }, - }, - ExpID: []*model.IsDependency{ - { - Package: testdata.P2out, - DependencyPackage: testdata.P4outName, - }, - }, - }, - { - Name: "Query on dep pkg - version", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2, testdata.P4}, - Calls: []call{ - { - P1: testdata.P2, - P2: testdata.P4, - MF: mSpecific, - ID: &model.IsDependencyInputSpec{}, - }, - { - P1: testdata.P2, - P2: testdata.P1, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - }, - Query: &model.IsDependencySpec{ - DependencyPackage: &model.PkgSpec{ - Version: ptrfrom.String("3.0.3"), - }, - }, - ExpID: []*model.IsDependency{ - { - Package: testdata.P2out, - DependencyPackage: testdata.P4out, - }, - }, - }, - { - Name: "Query on dep pkg - subpath", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2, testdata.P4}, - Calls: []call{ - { - P1: testdata.P2, - P2: testdata.P3, - MF: mSpecific, - ID: &model.IsDependencyInputSpec{}, - }, - { - P1: testdata.P2, - P2: testdata.P1, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - }, - Query: &model.IsDependencySpec{ - DependencyPackage: &model.PkgSpec{ - Subpath: ptrfrom.String("saved_model_cli.py"), - }, - }, - ExpID: []*model.IsDependency{ - { - Package: testdata.P2out, - DependencyPackage: testdata.P3out, - }, - }, - }, - { - Name: "Query on dep pkg - match empty qualifiers", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2, testdata.P4}, - Calls: []call{ - { - P1: testdata.P2, - P2: testdata.P4, - MF: mSpecific, - ID: &model.IsDependencyInputSpec{}, - }, - { - P1: testdata.P2, - P2: testdata.P1, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - }, - Query: &model.IsDependencySpec{ - DependencyPackage: &model.PkgSpec{ - MatchOnlyEmptyQualifiers: ptrfrom.Bool(true), - }, - }, - ExpID: []*model.IsDependency{ - { - Package: testdata.P2out, - DependencyPackage: testdata.P4out, - }, - { - Package: testdata.P2out, - DependencyPackage: testdata.P3out, - }, - }, - }, - { - Name: "Query on dep pkg - match empty qualifiers false", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2, testdata.P5}, - Calls: []call{ - { - P1: testdata.P2, - P2: testdata.P5, - MF: mSpecific, - ID: &model.IsDependencyInputSpec{}, - }, - { - P1: testdata.P2, - P2: testdata.P1, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - }, - Query: &model.IsDependencySpec{ - DependencyPackage: &model.PkgSpec{ - MatchOnlyEmptyQualifiers: ptrfrom.Bool(false), - Qualifiers: []*model.PackageQualifierSpec{ - { - Key: "test", - Value: ptrfrom.String("test"), - }, - }, - }, - }, - ExpID: []*model.IsDependency{ - { - Package: testdata.P2out, - DependencyPackage: testdata.P5out, - }, - }, - }, - { - Name: "Query on dep pkg - match qualifiers", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2, testdata.P5}, - Calls: []call{ - { - P1: testdata.P2, - P2: testdata.P5, - MF: mSpecific, - ID: &model.IsDependencyInputSpec{}, - }, - { - P1: testdata.P2, - P2: testdata.P1, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - }, - Query: &model.IsDependencySpec{ - DependencyPackage: &model.PkgSpec{ - Qualifiers: []*model.PackageQualifierSpec{ - { - Key: "test", - Value: ptrfrom.String("test"), - }, - }, - }, - }, - ExpID: []*model.IsDependency{ - { - Package: testdata.P2out, - DependencyPackage: testdata.P5out, - }, - }, - }, - { - Name: "Query on pkg - match empty qualifiers false", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2, testdata.P5}, - Calls: []call{ - { - P1: testdata.P5, - P2: testdata.P2, - MF: mSpecific, - ID: &model.IsDependencyInputSpec{}, - }, - { - P1: testdata.P2, - P2: testdata.P1, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - }, - Query: &model.IsDependencySpec{ - Package: &model.PkgSpec{ - MatchOnlyEmptyQualifiers: ptrfrom.Bool(false), - Qualifiers: []*model.PackageQualifierSpec{ - { - Key: "test", - Value: ptrfrom.String("test"), - }, - }, - }, - }, - ExpID: []*model.IsDependency{ - { - Package: testdata.P5out, - DependencyPackage: testdata.P2out, - }, - }, - }, - { - Name: "Query on pkg multiple", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2, testdata.P3}, - Calls: []call{ - { - P1: testdata.P1, - P2: testdata.P2, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - { - P1: testdata.P3, - P2: testdata.P2, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - }, - Query: &model.IsDependencySpec{ - Package: &model.PkgSpec{ - Name: ptrfrom.String("tensorflow"), - Subpath: ptrfrom.String("saved_model_cli.py"), - }, - }, - ExpID: []*model.IsDependency{ - { - Package: testdata.P3out, - DependencyPackage: testdata.P1outName, - }, - }, - }, - { - Name: "Query on both pkgs", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2, testdata.P3, testdata.P4}, - Calls: []call{ - { - P1: testdata.P2, - P2: testdata.P1, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - { - P1: testdata.P3, - P2: testdata.P4, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - }, - Query: &model.IsDependencySpec{ - Package: &model.PkgSpec{ - Subpath: ptrfrom.String("saved_model_cli.py"), - }, - DependencyPackage: &model.PkgSpec{ - Name: ptrfrom.String("openssl"), - }, - }, - ExpID: []*model.IsDependency{ - { - Package: testdata.P3out, - DependencyPackage: testdata.P4outName, - }, - }, - }, - { - Name: "Query none", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2, testdata.P3}, - Calls: []call{ - { - P1: testdata.P1, - P2: testdata.P2, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - { - P1: testdata.P2, - P2: testdata.P3, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - { - P1: testdata.P1, - P2: testdata.P3, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - }, - Query: &model.IsDependencySpec{ - Package: &model.PkgSpec{ - Subpath: ptrfrom.String("asdf"), - }, - }, - ExpID: nil, - }, - { - Name: "Query on ID", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2, testdata.P3}, - Calls: []call{ - { - P1: testdata.P1, - P2: testdata.P2, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - { - P1: testdata.P2, - P2: testdata.P3, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - { - P1: testdata.P1, - P2: testdata.P3, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - }, - QueryID: true, - ExpID: []*model.IsDependency{ - { - Package: testdata.P1out, - DependencyPackage: testdata.P2outName, - }, - }, - }, - { - Name: "Query on Range", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - Calls: []call{ - { - P1: testdata.P1, - P2: testdata.P1, - MF: mAll, - ID: &model.IsDependencyInputSpec{ - VersionRange: "1-3", - }, - }, - { - P1: testdata.P2, - P2: testdata.P1, - MF: mAll, - ID: &model.IsDependencyInputSpec{ - VersionRange: "4-5", - }, - }, - }, - Query: &model.IsDependencySpec{ - VersionRange: ptrfrom.String("1-3"), - }, - ExpID: []*model.IsDependency{ - { - Package: testdata.P1out, - DependencyPackage: testdata.P1outName, - VersionRange: "1-3", - }, - }, - }, - { - Name: "Query on DependencyType", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - Calls: []call{ - { - P1: testdata.P1, - P2: testdata.P1, - MF: mAll, - ID: &model.IsDependencyInputSpec{ - DependencyType: model.DependencyTypeDirect, - }, - }, - { - P1: testdata.P2, - P2: testdata.P1, - MF: mAll, - ID: &model.IsDependencyInputSpec{ - DependencyType: model.DependencyTypeIndirect, - }, - }, - }, - Query: &model.IsDependencySpec{ - DependencyType: (*model.DependencyType)(ptrfrom.String(string(model.DependencyTypeIndirect))), - }, - ExpID: []*model.IsDependency{ - { - Package: testdata.P2out, - DependencyPackage: testdata.P1outName, - DependencyType: model.DependencyTypeIndirect, - }, - }, - }, - { - Name: "Query bad ID", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2, testdata.P3}, - Calls: []call{ - { - P1: testdata.P1, - P2: testdata.P2, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - { - P1: testdata.P2, - P2: testdata.P3, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - { - P1: testdata.P1, - P2: testdata.P3, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - }, - Query: &model.IsDependencySpec{ - ID: ptrfrom.String("asdf"), - }, - ExpQueryErr: true, - }, - { - Name: "IsDep from version to version", - InPkg: []*model.PkgInputSpec{testdata.P2, testdata.P3}, - Calls: []call{ - { - P1: testdata.P3, - P2: testdata.P2, - MF: mSpecific, - ID: &model.IsDependencyInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.IsDependencySpec{ - Package: &model.PkgSpec{ - Name: ptrfrom.String("tensorflow"), - Subpath: ptrfrom.String("saved_model_cli.py"), - }, - }, - ExpID: []*model.IsDependency{ - { - Package: testdata.P3out, - DependencyPackage: testdata.P2out, - Justification: "test justification", - }, - { - Package: testdata.P3out, - DependencyPackage: testdata.P4outName, - }, - { - Package: testdata.P3out, - DependencyPackage: testdata.P1outName, - }, - }, - }, - { - Name: "IsDep from version to name", - InPkg: []*model.PkgInputSpec{testdata.P4, testdata.P3}, - Calls: []call{ - { - P1: testdata.P3, - P2: testdata.P4, - MF: mAll, - ID: &model.IsDependencyInputSpec{ - Justification: "test justification name only", - }, - }, - }, - Query: &model.IsDependencySpec{ - DependencyPackage: &model.PkgSpec{ - Name: ptrfrom.String("openssl"), - }, - Justification: ptrfrom.String("test justification name only"), - }, - ExpID: []*model.IsDependency{ - { - Package: testdata.P3out, - DependencyPackage: testdata.P4outName, - Justification: "test justification name only", - }, - }, - }, - { - Name: "IsDep from version to name and version", - InPkg: []*model.PkgInputSpec{testdata.P2, testdata.P3}, - Calls: []call{ - { - P1: testdata.P3, - P2: testdata.P2, - MF: mSpecific, - ID: &model.IsDependencyInputSpec{ - Justification: "test justification return specific", - }, - }, - { - P1: testdata.P3, - P2: testdata.P2, - MF: mAll, - ID: &model.IsDependencyInputSpec{ - Justification: "test justification return specific", - }, - }, - }, - Query: &model.IsDependencySpec{ - Justification: ptrfrom.String("test justification return specific"), - }, - ExpID: []*model.IsDependency{ - { - Package: testdata.P3out, - DependencyPackage: testdata.P2out, - Justification: "test justification return specific", - }, - { - Package: testdata.P3out, - DependencyPackage: testdata.P2outName, - Justification: "test justification return specific", - }, - }, - }, - { - Name: "Query on pkg ID", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2, testdata.P4}, - Calls: []call{ - { - P1: testdata.P1, - P2: testdata.P2, - MF: mSpecific, - ID: &model.IsDependencyInputSpec{}, - }, - { - P1: testdata.P4, - P2: testdata.P2, - MF: mSpecific, - ID: &model.IsDependencyInputSpec{}, - }, - }, - QueryPkgID: true, - ExpID: []*model.IsDependency{ - { - Package: testdata.P4out, - DependencyPackage: testdata.P2out, - }, - }, - }, - { - Name: "Query on dep pkg ID", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2, testdata.P4}, - Calls: []call{ - { - P1: testdata.P2, - P2: testdata.P1, - MF: mSpecific, - ID: &model.IsDependencyInputSpec{}, - }, - { - P1: testdata.P2, - P2: testdata.P4, - MF: mSpecific, - ID: &model.IsDependencyInputSpec{}, - }, - }, - QueryDepPkgID: true, - ExpID: []*model.IsDependency{ - { - Package: testdata.P2out, - DependencyPackage: testdata.P4out, - }, - }, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - for _, a := range test.InPkg { - if pkgIDs, err := b.IngestPackage(ctx, *a); err != nil { - t.Fatalf("Could not ingest pkg: %v", err) - } else { - if test.QueryPkgID { - test.Query = &model.IsDependencySpec{ - Package: &model.PkgSpec{ - ID: ptrfrom.String(pkgIDs.PackageVersionID), - }, - } - } - if test.QueryDepPkgID { - test.Query = &model.IsDependencySpec{ - DependencyPackage: &model.PkgSpec{ - ID: ptrfrom.String(pkgIDs.PackageVersionID), - }, - } - } - } - } - for _, o := range test.Calls { - depID, err := b.IngestDependency(ctx, *o.P1, *o.P2, o.MF, *o.ID) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - if test.QueryID { - test.Query = &model.IsDependencySpec{ - ID: ptrfrom.String(depID), - } - } - } - got, err := b.IsDependency(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpID, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func TestIsDependencies(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - type call struct { - P1s []*model.PkgInputSpec - P2s []*model.PkgInputSpec - MF model.MatchFlags - IDs []*model.IsDependencyInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - Calls []call - ExpID []*model.IsDependency - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2, testdata.P3, testdata.P4}, - Calls: []call{{ - P1s: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - P2s: []*model.PkgInputSpec{testdata.P2, testdata.P4}, - MF: mAll, - IDs: []*model.IsDependencyInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }}, - ExpID: []*model.IsDependency{ - { - Package: testdata.P1out, - DependencyPackage: testdata.P2outName, - Justification: "test justification", - }, - }, - }, - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2, testdata.P3, testdata.P4}, - Calls: []call{{ - P1s: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - P2s: []*model.PkgInputSpec{testdata.P2, testdata.P4}, - MF: mSpecific, - IDs: []*model.IsDependencyInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }}, - ExpID: []*model.IsDependency{ - { - Package: testdata.P1out, - DependencyPackage: testdata.P2out, - Justification: "test justification", - }, - }, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - for _, a := range test.InPkg { - if _, err := b.IngestPackage(ctx, *a); err != nil { - t.Fatalf("Could not ingest pkg: %v", err) - } - } - for _, o := range test.Calls { - depID, err := b.IngestDependencies(ctx, o.P1s, o.P2s, o.MF, o.IDs) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - got, err := b.IsDependency(ctx, &model.IsDependencySpec{ID: ptrfrom.String(depID[0])}) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpID, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - } - }) - } -} - -func Test_buildIsDependencyByID(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - type call struct { - P1 *model.PkgInputSpec - P2 *model.PkgInputSpec - MF model.MatchFlags - ID *model.IsDependencyInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - Calls []call - Query *model.IsDependencySpec - ExpID *model.IsDependency - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "Query on pkg", - InPkg: []*model.PkgInputSpec{testdata.P2, testdata.P3}, - Calls: []call{ - { - P1: testdata.P2, - P2: testdata.P3, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - }, - Query: &model.IsDependencySpec{ - Package: &model.PkgSpec{ - Name: ptrfrom.String("tensorflow"), - Version: ptrfrom.String("2.11.1"), - }, - }, - ExpID: &model.IsDependency{ - Package: testdata.P2out, - DependencyPackage: testdata.P2outName, - }, - }, - { - Name: "Query on dep pkg", - InPkg: []*model.PkgInputSpec{testdata.P2, testdata.P4}, - Calls: []call{ - { - P1: testdata.P2, - P2: testdata.P4, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - }, - Query: &model.IsDependencySpec{ - DependencyPackage: &model.PkgSpec{ - Name: ptrfrom.String("openssl"), - }, - }, - ExpID: &model.IsDependency{ - Package: testdata.P2out, - DependencyPackage: testdata.P4outName, - }, - }, - { - Name: "Query on ID", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - Calls: []call{ - { - P1: testdata.P1, - P2: testdata.P2, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - }, - ExpID: &model.IsDependency{ - Package: testdata.P1out, - DependencyPackage: testdata.P2outName, - }, - }, - { - Name: "Query bad ID", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P3}, - Calls: []call{ - { - P1: testdata.P1, - P2: testdata.P3, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - }, - Query: &model.IsDependencySpec{ - ID: ptrfrom.String("asdf"), - }, - ExpQueryErr: true, - }, - { - Name: "Query on pkg ID", - InPkg: []*model.PkgInputSpec{testdata.P2, testdata.P4}, - Calls: []call{ - { - P1: testdata.P4, - P2: testdata.P2, - MF: mSpecific, - ID: &model.IsDependencyInputSpec{}, - }, - }, - ExpID: &model.IsDependency{ - Package: testdata.P4out, - DependencyPackage: testdata.P2out, - }, - }, - { - Name: "Query on dep pkg ID", - InPkg: []*model.PkgInputSpec{testdata.P2, testdata.P4}, - Calls: []call{ - { - P1: testdata.P2, - P2: testdata.P4, - MF: mSpecific, - ID: &model.IsDependencyInputSpec{}, - }, - }, - ExpID: &model.IsDependency{ - Package: testdata.P2out, - DependencyPackage: testdata.P4out, - }, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - for _, a := range test.InPkg { - if _, err := b.IngestPackage(ctx, *a); err != nil { - t.Fatalf("Could not ingest pkg: %v", err) - } - } - for _, o := range test.Calls { - depID, err := b.IngestDependency(ctx, *o.P1, *o.P2, o.MF, *o.ID) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - got, err := b.(*arangoClient).buildIsDependencyByID(ctx, depID, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpID, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - } - - }) - } -} diff --git a/pkg/assembler/backends/arangodb/isOccurrence.go b/pkg/assembler/backends/arangodb/isOccurrence.go index d7e9904a3e..2380bafbfa 100644 --- a/pkg/assembler/backends/arangodb/isOccurrence.go +++ b/pkg/assembler/backends/arangodb/isOccurrence.go @@ -233,14 +233,14 @@ func getOccurrenceQueryValues(pkg *model.PkgInputSpec, src *model.SourceInputSpe return values } -func (c *arangoClient) IngestOccurrences(ctx context.Context, subjects model.PackageOrSourceInputs, artifacts []*model.ArtifactInputSpec, occurrences []*model.IsOccurrenceInputSpec) ([]string, error) { +func (c *arangoClient) IngestOccurrences(ctx context.Context, subjects model.PackageOrSourceInputs, artifacts []*model.IDorArtifactInput, occurrences []*model.IsOccurrenceInputSpec) ([]string, error) { var cursor driver.Cursor var err error if len(subjects.Packages) > 0 { var listOfValues []map[string]any for i := range subjects.Packages { - listOfValues = append(listOfValues, getOccurrenceQueryValues(subjects.Packages[i], nil, artifacts[i], occurrences[i])) + listOfValues = append(listOfValues, getOccurrenceQueryValues(subjects.Packages[i].PackageInput, nil, artifacts[i].ArtifactInput, occurrences[i])) } var documents []string @@ -303,7 +303,7 @@ func (c *arangoClient) IngestOccurrences(ctx context.Context, subjects model.Pac var listOfValues []map[string]any for i := range subjects.Sources { - listOfValues = append(listOfValues, getOccurrenceQueryValues(nil, subjects.Sources[i], artifacts[i], occurrences[i])) + listOfValues = append(listOfValues, getOccurrenceQueryValues(nil, subjects.Sources[i].SourceInput, artifacts[i].ArtifactInput, occurrences[i])) } var documents []string @@ -377,7 +377,7 @@ func (c *arangoClient) IngestOccurrences(ctx context.Context, subjects model.Pac return isOcurIDList, nil } -func (c *arangoClient) IngestOccurrence(ctx context.Context, subject model.PackageOrSourceInput, artifact model.ArtifactInputSpec, occurrence model.IsOccurrenceInputSpec) (string, error) { +func (c *arangoClient) IngestOccurrence(ctx context.Context, subject model.PackageOrSourceInput, artifact model.IDorArtifactInput, occurrence model.IsOccurrenceInputSpec) (string, error) { var cursor driver.Cursor var err error if subject.Package != nil { @@ -408,7 +408,7 @@ func (c *arangoClient) IngestOccurrence(ctx context.Context, subject model.Packa RETURN { 'isOccurrence_id': isOccurrence._id }` - cursor, err = executeQueryWithRetry(ctx, c.db, query, getOccurrenceQueryValues(subject.Package, nil, &artifact, &occurrence), "IngestOccurrence") + cursor, err = executeQueryWithRetry(ctx, c.db, query, getOccurrenceQueryValues(subject.Package.PackageInput, nil, artifact.ArtifactInput, &occurrence), "IngestOccurrence") if err != nil { return "", fmt.Errorf("failed to ingest package occurrence: %w", err) } @@ -441,7 +441,7 @@ func (c *arangoClient) IngestOccurrence(ctx context.Context, subject model.Packa RETURN { 'isOccurrence_id': isOccurrence._id }` - cursor, err = executeQueryWithRetry(ctx, c.db, query, getOccurrenceQueryValues(nil, subject.Source, &artifact, &occurrence), "IngestOccurrence") + cursor, err = executeQueryWithRetry(ctx, c.db, query, getOccurrenceQueryValues(nil, subject.Source.SourceInput, artifact.ArtifactInput, &occurrence), "IngestOccurrence") if err != nil { return "", fmt.Errorf("failed to ingest source occurrence: %w", err) } diff --git a/pkg/assembler/backends/arangodb/isOccurrence_test.go b/pkg/assembler/backends/arangodb/isOccurrence_test.go deleted file mode 100644 index c601a2b8d2..0000000000 --- a/pkg/assembler/backends/arangodb/isOccurrence_test.go +++ /dev/null @@ -1,932 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build integration - -package arangodb - -import ( - "context" - "strings" - "testing" - - "github.com/google/go-cmp/cmp" - - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/internal/testing/testdata" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -func TestOccurrence(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - type call struct { - PkgSrc model.PackageOrSourceInput - Artifact *model.ArtifactInputSpec - Occurrence *model.IsOccurrenceInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - InArt []*model.ArtifactInputSpec - Calls []call - Query *model.IsOccurrenceSpec - QueryID bool - QueryPkgID bool - QuerySourceID bool - QueryArtID bool - ExpOcc []*model.IsOccurrence - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InArt: []*model.ArtifactInputSpec{testdata.A1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Artifact: testdata.A1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.IsOccurrenceSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpOcc: []*model.IsOccurrence{ - { - Subject: testdata.P1out, - Artifact: testdata.A1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Igest same twice", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InArt: []*model.ArtifactInputSpec{testdata.A1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Artifact: testdata.A1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "test justification", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Artifact: testdata.A1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.IsOccurrenceSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpOcc: []*model.IsOccurrence{ - { - Subject: testdata.P1out, - Artifact: testdata.A1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Justification", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InArt: []*model.ArtifactInputSpec{testdata.A1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Artifact: testdata.A1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "justification one", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Artifact: testdata.A1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "justification two", - }, - }, - }, - Query: &model.IsOccurrenceSpec{ - Justification: ptrfrom.String("justification one"), - }, - ExpOcc: []*model.IsOccurrence{ - { - Subject: testdata.P1out, - Artifact: testdata.A1out, - Justification: "justification one", - }, - }, - }, - { - Name: "Query on Artifact", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InArt: []*model.ArtifactInputSpec{testdata.A4, testdata.A2}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Artifact: testdata.A4, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "justification", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Artifact: testdata.A2, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "justification", - }, - }, - }, - Query: &model.IsOccurrenceSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha1"), - Digest: ptrfrom.String("5a787865sd676dacb0142afa0b83029cd7befd9"), - }, - }, - ExpOcc: []*model.IsOccurrence{ - { - Subject: testdata.P1out, - Artifact: testdata.A4out, - Justification: "justification", - }, - }, - }, - { - Name: "Query on Artifact ID", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InArt: []*model.ArtifactInputSpec{testdata.A2, testdata.A4}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Artifact: testdata.A2, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "justification", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Artifact: testdata.A4, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "justification", - }, - }, - }, - QueryArtID: true, - ExpOcc: []*model.IsOccurrence{ - { - Subject: testdata.P1out, - Artifact: testdata.A4out, - Justification: "justification", - }, - }, - }, - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{testdata.P4, testdata.P2}, - InArt: []*model.ArtifactInputSpec{testdata.A1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P4, - }, - Artifact: testdata.A1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "justification", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P2, - }, - Artifact: testdata.A1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "justification", - }, - }, - }, - Query: &model.IsOccurrenceSpec{ - Subject: &model.PackageOrSourceSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String("3.0.3"), - }, - }, - }, - ExpOcc: []*model.IsOccurrence{ - { - Subject: testdata.P4out, - Artifact: testdata.A1out, - Justification: "justification", - }, - }, - }, - { - Name: "Query on Package ID", - InPkg: []*model.PkgInputSpec{testdata.P2, testdata.P4}, - InArt: []*model.ArtifactInputSpec{testdata.A1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P2, - }, - Artifact: testdata.A1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "justification", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P4, - }, - Artifact: testdata.A1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "justification", - }, - }, - }, - QueryPkgID: true, - ExpOcc: []*model.IsOccurrence{ - { - Subject: testdata.P4out, - Artifact: testdata.A1out, - Justification: "justification", - }, - }, - }, - { - Name: "Query on Source", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InSrc: []*model.SourceInputSpec{testdata.S1}, - InArt: []*model.ArtifactInputSpec{testdata.A1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Artifact: testdata.A1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "justification", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Source: testdata.S1, - }, - Artifact: testdata.A1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "justification", - }, - }, - }, - Query: &model.IsOccurrenceSpec{ - Subject: &model.PackageOrSourceSpec{ - Source: &model.SourceSpec{}, - }, - }, - ExpOcc: []*model.IsOccurrence{ - { - Subject: testdata.S1out, - Artifact: testdata.A1out, - Justification: "justification", - }, - }, - }, - { - Name: "Query on Source ID", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InSrc: []*model.SourceInputSpec{testdata.S1}, - InArt: []*model.ArtifactInputSpec{testdata.A1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Artifact: testdata.A1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "justification", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Source: testdata.S1, - }, - Artifact: testdata.A1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "justification", - }, - }, - }, - QuerySourceID: true, - ExpOcc: []*model.IsOccurrence{ - { - Subject: testdata.S1out, - Artifact: testdata.A1out, - Justification: "justification", - }, - }, - }, - { - Name: "Query none", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InArt: []*model.ArtifactInputSpec{testdata.A1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Artifact: testdata.A1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.IsOccurrenceSpec{ - ID: ptrfrom.String("12345"), - }, - ExpOcc: nil, - ExpQueryErr: true, - }, - { - Name: "Query on ID", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InArt: []*model.ArtifactInputSpec{testdata.A1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Artifact: testdata.A1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "test justification", - }, - }, - }, - QueryID: true, - ExpOcc: []*model.IsOccurrence{ - { - Subject: testdata.P1out, - Artifact: testdata.A1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query multiple", - InPkg: []*model.PkgInputSpec{testdata.P4}, - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P4, - }, - Artifact: testdata.A1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "test justification", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P4, - }, - Artifact: testdata.A2, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.IsOccurrenceSpec{ - Subject: &model.PackageOrSourceSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String("3.0.3"), - }, - }, - Justification: ptrfrom.String("test justification"), - }, - ExpOcc: []*model.IsOccurrence{ - { - Subject: testdata.P4out, - Artifact: testdata.A2out, - Justification: "test justification", - }, - { - Subject: testdata.P4out, - Artifact: testdata.A1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query bad ID", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InArt: []*model.ArtifactInputSpec{testdata.A1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Artifact: testdata.A1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "justification", - }, - }, - }, - Query: &model.IsOccurrenceSpec{ - ID: ptrfrom.String("asdf"), - }, - ExpQueryErr: true, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - for _, p := range test.InPkg { - if pkgIDs, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } else { - if test.QueryPkgID { - test.Query = &model.IsOccurrenceSpec{ - Subject: &model.PackageOrSourceSpec{ - Package: &model.PkgSpec{ - ID: ptrfrom.String(pkgIDs.PackageVersionID), - }, - }, - } - } - } - } - for _, s := range test.InSrc { - if srcIDs, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } else { - if test.QuerySourceID { - test.Query = &model.IsOccurrenceSpec{ - Subject: &model.PackageOrSourceSpec{ - Source: &model.SourceSpec{ - ID: ptrfrom.String(srcIDs.SourceNameID), - }, - }, - } - } - } - } - for _, a := range test.InArt { - if artID, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } else { - if test.QueryArtID { - test.Query = &model.IsOccurrenceSpec{ - Artifact: &model.ArtifactSpec{ - ID: ptrfrom.String(artID), - }, - } - - } - } - } - for _, o := range test.Calls { - ocurID, err := b.IngestOccurrence(ctx, o.PkgSrc, *o.Artifact, *o.Occurrence) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - if test.QueryID { - test.Query = &model.IsOccurrenceSpec{ - ID: ptrfrom.String(ocurID), - } - } - } - got, err := b.IsOccurrence(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpOcc, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func TestIngestOccurrences(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - type call struct { - PkgSrcs model.PackageOrSourceInputs - Artifacts []*model.ArtifactInputSpec - Occurrences []*model.IsOccurrenceInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - InArt []*model.ArtifactInputSpec - Calls []call - ExpOcc []*model.IsOccurrence - ExpIngestErr bool - ExpQueryErr bool - }{{ - Name: "HappyPath - packages", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - Calls: []call{ - { - PkgSrcs: model.PackageOrSourceInputs{ - Packages: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - }, - Artifacts: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - Occurrences: []*model.IsOccurrenceInputSpec{{ - Justification: "test justification", - }, { - Justification: "test justification", - }}, - }, - }, - ExpOcc: []*model.IsOccurrence{ - { - Subject: testdata.P1out, - Artifact: testdata.A1out, - Justification: "test justification", - }, - }, - }, { - Name: "HappyPath - sources", - InSrc: []*model.SourceInputSpec{testdata.S1}, - InArt: []*model.ArtifactInputSpec{testdata.A1}, - Calls: []call{ - { - PkgSrcs: model.PackageOrSourceInputs{ - Sources: []*model.SourceInputSpec{testdata.S1}, - }, - Artifacts: []*model.ArtifactInputSpec{testdata.A1}, - Occurrences: []*model.IsOccurrenceInputSpec{{ - Justification: "test justification", - }}, - }, - }, - ExpOcc: []*model.IsOccurrence{ - { - Subject: testdata.S1out, - Artifact: testdata.A1out, - Justification: "test justification", - }, - }, - }} - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - for _, o := range test.Calls { - ocurID, err := b.IngestOccurrences(ctx, o.PkgSrcs, o.Artifacts, o.Occurrences) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - got, err := b.IsOccurrence(ctx, &model.IsOccurrenceSpec{ID: ptrfrom.String(ocurID[0])}) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpOcc, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - } - }) - } -} - -func Test_buildIsOccurrenceByID(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - type call struct { - PkgSrc model.PackageOrSourceInput - Artifact *model.ArtifactInputSpec - Occurrence *model.IsOccurrenceInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - InArt []*model.ArtifactInputSpec - Calls []call - Query *model.IsOccurrenceSpec - ExpOcc *model.IsOccurrence - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "Query on Artifact", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InArt: []*model.ArtifactInputSpec{testdata.A4}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Artifact: testdata.A4, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "justification", - }, - }, - }, - Query: &model.IsOccurrenceSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha1"), - Digest: ptrfrom.String("5a787865sd676dacb0142afa0b83029cd7befd9"), - }, - }, - ExpOcc: &model.IsOccurrence{ - Subject: testdata.P1out, - Artifact: testdata.A4out, - Justification: "justification", - }, - }, - { - Name: "Query on Artifact ID", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InArt: []*model.ArtifactInputSpec{testdata.A4}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Artifact: testdata.A4, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "justification", - }, - }, - }, - ExpOcc: &model.IsOccurrence{ - Subject: testdata.P1out, - Artifact: testdata.A4out, - Justification: "justification", - }, - }, - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{testdata.P4}, - InArt: []*model.ArtifactInputSpec{testdata.A1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P4, - }, - Artifact: testdata.A1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "justification", - }, - }, - }, - Query: &model.IsOccurrenceSpec{ - Subject: &model.PackageOrSourceSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String("3.0.3"), - }, - }, - }, - ExpOcc: &model.IsOccurrence{ - Subject: testdata.P4out, - Artifact: testdata.A1out, - Justification: "justification", - }, - }, - { - Name: "Query on Package ID", - InPkg: []*model.PkgInputSpec{testdata.P4}, - InArt: []*model.ArtifactInputSpec{testdata.A1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P4, - }, - Artifact: testdata.A1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "justification", - }, - }, - }, - ExpOcc: &model.IsOccurrence{ - Subject: testdata.P4out, - Artifact: testdata.A1out, - Justification: "justification", - }, - }, - { - Name: "Query on Source", - InSrc: []*model.SourceInputSpec{testdata.S1}, - InArt: []*model.ArtifactInputSpec{testdata.A1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Source: testdata.S1, - }, - Artifact: testdata.A1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "justification", - }, - }, - }, - Query: &model.IsOccurrenceSpec{ - Subject: &model.PackageOrSourceSpec{ - Source: &model.SourceSpec{}, - }, - }, - ExpOcc: &model.IsOccurrence{ - Subject: testdata.S1out, - Artifact: testdata.A1out, - Justification: "justification", - }, - }, - { - Name: "Query on Source ID", - InSrc: []*model.SourceInputSpec{testdata.S1}, - InArt: []*model.ArtifactInputSpec{testdata.A1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Source: testdata.S1, - }, - Artifact: testdata.A1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "justification", - }, - }, - }, - ExpOcc: &model.IsOccurrence{ - Subject: testdata.S1out, - Artifact: testdata.A1out, - Justification: "justification", - }, - }, - { - Name: "Query on ID", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InArt: []*model.ArtifactInputSpec{testdata.A1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Artifact: testdata.A1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "test justification", - }, - }, - }, - ExpOcc: &model.IsOccurrence{ - Subject: testdata.P1out, - Artifact: testdata.A1out, - Justification: "test justification", - }, - }, - { - Name: "Query bad ID", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InArt: []*model.ArtifactInputSpec{testdata.A1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Artifact: testdata.A1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "justification", - }, - }, - }, - Query: &model.IsOccurrenceSpec{ - ID: ptrfrom.String("asdf"), - }, - ExpQueryErr: true, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - for _, o := range test.Calls { - ocurID, err := b.IngestOccurrence(ctx, o.PkgSrc, *o.Artifact, *o.Occurrence) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - got, err := b.(*arangoClient).buildIsOccurrenceByID(ctx, ocurID, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpOcc, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - } - - }) - } -} diff --git a/pkg/assembler/backends/arangodb/license.go b/pkg/assembler/backends/arangodb/license.go index aaee0f86fe..b92b7df55a 100644 --- a/pkg/assembler/backends/arangodb/license.go +++ b/pkg/assembler/backends/arangodb/license.go @@ -83,12 +83,12 @@ func nilToEmpty(s *string) string { return *s } -func (c *arangoClient) IngestLicenses(ctx context.Context, licenses []*model.LicenseInputSpec) ([]string, error) { +func (c *arangoClient) IngestLicenses(ctx context.Context, licenses []*model.IDorLicenseInput) ([]string, error) { var listOfValues []map[string]any for i := range licenses { - listOfValues = append(listOfValues, getLicenseQueryValues(licenses[i])) + listOfValues = append(listOfValues, getLicenseQueryValues(licenses[i].LicenseInput)) } var documents []string @@ -139,14 +139,14 @@ RETURN { "id": NEW._id }` return licenseIDs, nil } -func (c *arangoClient) IngestLicense(ctx context.Context, license *model.LicenseInputSpec) (string, error) { +func (c *arangoClient) IngestLicense(ctx context.Context, license *model.IDorLicenseInput) (string, error) { query := ` UPSERT { name:@name, inline:@inline, listversion:@listversion } INSERT { name:@name, inline:@inline, listversion:@listversion } UPDATE {} IN licenses OPTIONS { indexHint: "byNameInlineListVer" } RETURN { "id": NEW._id }` - cursor, err := executeQueryWithRetry(ctx, c.db, query, getLicenseQueryValues(license), "IngestLicense") + cursor, err := executeQueryWithRetry(ctx, c.db, query, getLicenseQueryValues(license.LicenseInput), "IngestLicense") if err != nil { return "", fmt.Errorf("failed to ingest license: %w", err) } @@ -191,10 +191,10 @@ func getLicenses(ctx context.Context, cursor driver.Cursor) ([]*model.License, e return createdLicenses, nil } -func (c *arangoClient) getLicenses(ctx context.Context, licenses []*model.LicenseInputSpec) ([]*model.License, error) { +func (c *arangoClient) getLicenses(ctx context.Context, licenses []*model.IDorLicenseInput) ([]*model.License, error) { var listOfValues []map[string]any for i := range licenses { - listOfValues = append(listOfValues, getLicenseQueryValues(licenses[i])) + listOfValues = append(listOfValues, getLicenseQueryValues(licenses[i].LicenseInput)) } var documents []string diff --git a/pkg/assembler/backends/arangodb/license_test.go b/pkg/assembler/backends/arangodb/license_test.go deleted file mode 100644 index 5d6456cdb6..0000000000 --- a/pkg/assembler/backends/arangodb/license_test.go +++ /dev/null @@ -1,292 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build integration - -package arangodb - -import ( - "context" - "slices" - "strings" - "testing" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/internal/testing/testdata" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -func lessLicense(a, b *model.License) int { - return strings.Compare(a.Name, b.Name) -} - -func Test_Licenses(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - tests := []struct { - Name string - Ingests []*model.LicenseInputSpec - ExpIngestErr bool - IDInFilter int - Query *model.LicenseSpec - Exp []*model.License - ExpQueryErr bool - }{ - { - Name: "HappyPath", - Ingests: []*model.LicenseInputSpec{testdata.L1}, - Query: &model.LicenseSpec{}, - Exp: []*model.License{testdata.L1out}, - }, - { - Name: "Duplicates", - Ingests: []*model.LicenseInputSpec{testdata.L1, testdata.L1, testdata.L1}, - Query: &model.LicenseSpec{}, - Exp: []*model.License{testdata.L1out}, - }, - { - Name: "Multiple", - Ingests: []*model.LicenseInputSpec{testdata.L1, testdata.L2}, - Query: &model.LicenseSpec{}, - Exp: []*model.License{testdata.L1out, testdata.L2out}, - }, - { - Name: "Query by ID", - Ingests: []*model.LicenseInputSpec{testdata.L2, testdata.L3, testdata.L4}, - IDInFilter: 2, - Query: &model.LicenseSpec{}, - Exp: []*model.License{testdata.L3out}, - }, - { - Name: "Query by Name", - Ingests: []*model.LicenseInputSpec{testdata.L1, testdata.L2, testdata.L3, testdata.L4}, - Query: &model.LicenseSpec{ - Name: ptrfrom.String("BSD-3-Clause"), - }, - Exp: []*model.License{testdata.L1out}, - }, - { - Name: "Query by Inline", - Query: &model.LicenseSpec{ - Inline: &testdata.InlineLicense, - }, - Exp: []*model.License{testdata.L4out}, - }, - { - Name: "Query by ListVersion", - Query: &model.LicenseSpec{ - ListVersion: ptrfrom.String("1.23 2020"), - }, - Exp: []*model.License{testdata.L3out}, - }, - { - Name: "Query None", - Query: &model.LicenseSpec{ - ListVersion: ptrfrom.String("foo"), - }, - Exp: nil, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, tt := range tests { - t.Run(tt.Name, func(t *testing.T) { - c, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - for i, ingest := range tt.Ingests { - ingestedLicenseID, err := c.IngestLicense(ctx, ingest) - if (err != nil) != tt.ExpIngestErr { - t.Errorf("arangoClient.IngestLicense() error = %v, wantErr %v", err, tt.ExpIngestErr) - return - } - if err != nil { - return - } - if (i + 1) == tt.IDInFilter { - tt.Query.ID = ptrfrom.String(ingestedLicenseID) - } - } - got, err := c.Licenses(ctx, tt.Query) - if (err != nil) != tt.ExpQueryErr { - t.Errorf("arangoClient.Licenses() error = %v, wantErr %v", err, tt.ExpQueryErr) - return - } - if err != nil { - return - } - slices.SortFunc(got, lessLicense) - if diff := cmp.Diff(tt.Exp, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func Test_LicensesBulk(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - tests := []struct { - Name string - Ingests []*model.LicenseInputSpec - ExpIngestErr bool - Query *model.LicenseSpec - Exp []*model.License - ExpQueryErr bool - }{ - { - Name: "Query by Name", - Ingests: []*model.LicenseInputSpec{testdata.L1, testdata.L1, testdata.L2, testdata.L3, testdata.L4}, - Query: &model.LicenseSpec{ - Name: ptrfrom.String("BSD-3-Clause"), - }, - Exp: []*model.License{testdata.L1out}, - }, - { - Name: "Query by Inline", - Query: &model.LicenseSpec{ - Inline: &testdata.InlineLicense, - }, - Exp: []*model.License{testdata.L4out}, - }, - { - Name: "Query by ListVersion", - Query: &model.LicenseSpec{ - ListVersion: ptrfrom.String("1.23 2020"), - }, - Exp: []*model.License{testdata.L3out}, - }, - { - Name: "Query None", - Query: &model.LicenseSpec{ - ListVersion: ptrfrom.String("foo"), - }, - Exp: nil, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, tt := range tests { - t.Run(tt.Name, func(t *testing.T) { - c, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - _, err = c.IngestLicenses(ctx, tt.Ingests) - if (err != nil) != tt.ExpIngestErr { - t.Errorf("arangoClient.IngestLicenses() error = %v, wantErr %v", err, tt.ExpIngestErr) - return - } - if err != nil { - return - } - got, err := c.Licenses(ctx, tt.Query) - if (err != nil) != tt.ExpQueryErr { - t.Errorf("arangoClient.Licenses() error = %v, wantErr %v", err, tt.ExpQueryErr) - return - } - if err != nil { - return - } - slices.SortFunc(got, lessLicense) - if diff := cmp.Diff(tt.Exp, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func Test_getLicenseByID(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - tests := []struct { - Name string - Ingests []*model.LicenseInputSpec - ExpIngestErr bool - IDInFilter int - Query *model.LicenseSpec - Exp *model.License - ExpQueryErr bool - }{ - { - Name: "HappyPath", - Ingests: []*model.LicenseInputSpec{testdata.L1}, - Query: &model.LicenseSpec{}, - Exp: testdata.L1out, - }, - { - Name: "Query by ID", - Ingests: []*model.LicenseInputSpec{testdata.L4}, - IDInFilter: 2, - Query: &model.LicenseSpec{}, - Exp: testdata.L4out, - }, - { - Name: "Query bad ID", - Query: &model.LicenseSpec{ - ID: ptrfrom.String("foo"), - }, - ExpQueryErr: true, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, tt := range tests { - t.Run(tt.Name, func(t *testing.T) { - c, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - for _, ingest := range tt.Ingests { - ingestedLicenseID, err := c.IngestLicense(ctx, ingest) - if (err != nil) != tt.ExpIngestErr { - t.Errorf("arangoClient.IngestLicense() error = %v, wantErr %v", err, tt.ExpIngestErr) - return - } - if err != nil { - return - } - got, err := c.(*arangoClient).getLicenseByID(ctx, ingestedLicenseID) - if (err != nil) != tt.ExpQueryErr { - t.Errorf("arangoClient.Licenses() error = %v, wantErr %v", err, tt.ExpQueryErr) - return - } - if err != nil { - return - } - if diff := cmp.Diff(tt.Exp, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - } - }) - } -} diff --git a/pkg/assembler/backends/arangodb/path_test.go b/pkg/assembler/backends/arangodb/path_test.go deleted file mode 100644 index 9eaa7b4437..0000000000 --- a/pkg/assembler/backends/arangodb/path_test.go +++ /dev/null @@ -1,3725 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build integration - -package arangodb - -import ( - "context" - "strings" - "testing" - "time" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/testdata" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -func Test_Path(t *testing.T) { - ctx := context.Background() - arangoArg := getArangoConfig() - err := DeleteDatabase(ctx, arangoArg) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArg) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - type certifyVulnCall struct { - Pkg *model.PkgInputSpec - Vuln *model.VulnerabilityInputSpec - CertifyVuln *model.ScanMetadataInput - } - type isDepCall struct { - P1 *model.PkgInputSpec - P2 *model.PkgInputSpec - MF model.MatchFlags - ID *model.IsDependencyInputSpec - } - tests := []struct { - name string - pkgInput *model.PkgInputSpec - vulnInput *model.VulnerabilityInputSpec - inPkg []*model.PkgInputSpec - inVuln []*model.VulnerabilityInputSpec - certifyVulnCall *certifyVulnCall - certifyVulnTwoPkgsCall *certifyVulnCall - isDepCall *isDepCall - edges []model.Edge - want []model.Node - wantErr bool - }{ - { - name: "certifyVuln - edges not provided", - inVuln: []*model.VulnerabilityInputSpec{testdata.G1}, - inPkg: []*model.PkgInputSpec{testdata.P2}, - edges: []model.Edge{}, - certifyVulnCall: &certifyVulnCall{ - Pkg: testdata.P2, - Vuln: testdata.G1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: testdata.T1, - }, - }, - want: []model.Node{ - testdata.P2out, - &model.CertifyVuln{ - Package: testdata.P2out, - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - Metadata: vmd1, - }, - &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - }, - }, - { - name: "certifyVuln - edges not provided", - inVuln: []*model.VulnerabilityInputSpec{testdata.G1}, - inPkg: []*model.PkgInputSpec{testdata.P2}, - edges: []model.Edge{model.EdgePackageCertifyVuln, model.EdgeVulnerabilityCertifyVuln}, - certifyVulnCall: &certifyVulnCall{ - Pkg: testdata.P2, - Vuln: testdata.G1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: testdata.T1, - }, - }, - want: []model.Node{ - testdata.P2out, - &model.CertifyVuln{ - Package: testdata.P2out, - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - Metadata: vmd1, - }, - &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - }, - }, - { - name: "certifyVuln - two packages (one vulnerable)", - inVuln: []*model.VulnerabilityInputSpec{testdata.G1}, - inPkg: []*model.PkgInputSpec{testdata.P2, testdata.P3}, - edges: []model.Edge{model.EdgePackageCertifyVuln, model.EdgeVulnerabilityCertifyVuln}, - certifyVulnTwoPkgsCall: &certifyVulnCall{ - Pkg: testdata.P2, - Vuln: testdata.G1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: testdata.T1, - }, - }, - want: nil, - }, - { - name: "isDependency", - inPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - edges: []model.Edge{model.EdgePackageIsDependency, model.EdgeIsDependencyPackage}, - isDepCall: &isDepCall{ - P1: testdata.P1, - P2: testdata.P2, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - want: []model.Node{ - testdata.P1out, - &model.IsDependency{ - Package: testdata.P1out, - DependencyPackage: testdata.P2outName, - }, - testdata.P2outName, - }, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - var startID string - var stopID string - if tt.certifyVulnTwoPkgsCall != nil { - var nonVulnPkgID string - for _, p := range tt.inPkg { - pkg, err := b.IngestPackage(ctx, *p) - if err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - nonVulnPkgID = pkg.PackageVersionID - } - cvID, err := b.IngestCertifyVuln(ctx, *tt.certifyVulnTwoPkgsCall.Pkg, *tt.certifyVulnTwoPkgsCall.Vuln, *tt.certifyVulnTwoPkgsCall.CertifyVuln) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - startID = cvID - stopID = nonVulnPkgID - } - if tt.certifyVulnCall != nil { - for _, p := range tt.inPkg { - if pkgIDs, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } else { - startID = pkgIDs.PackageVersionID - } - } - for _, g := range tt.inVuln { - if vulnIDs, err := b.IngestVulnerability(ctx, *g); err != nil { - t.Fatalf("Could not ingest vulnerability: %a", err) - } else { - stopID = vulnIDs.VulnerabilityNodeID - } - } - _, err := b.IngestCertifyVuln(ctx, *tt.certifyVulnCall.Pkg, *tt.certifyVulnCall.Vuln, *tt.certifyVulnCall.CertifyVuln) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - } - if tt.isDepCall != nil { - for _, p := range tt.inPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - dID, err := b.IngestDependency(ctx, *tt.isDepCall.P1, *tt.isDepCall.P2, tt.isDepCall.MF, *tt.isDepCall.ID) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - found, err := b.IsDependency(ctx, &model.IsDependencySpec{ID: &dID}) - if err != nil { - t.Fatal() - } - startID = found[0].Package.Namespaces[0].Names[0].Versions[0].ID - stopID = found[0].DependencyPackage.Namespaces[0].Names[0].ID - } - got, err := b.Path(ctx, startID, stopID, 5, tt.edges) - if (err != nil) != tt.wantErr { - t.Errorf("node query error = %v, wantErr %v", err, tt.wantErr) - return - } - if diff := cmp.Diff(tt.want, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func Test_Nodes(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - type certifyBadCall struct { - Sub model.PackageSourceOrArtifactInput - Match *model.MatchFlags - CB *model.CertifyBadInputSpec - } - type certifyGoodCall struct { - Sub model.PackageSourceOrArtifactInput - Match *model.MatchFlags - CG *model.CertifyGoodInputSpec - } - type certifyLegalCall struct { - PkgSrc model.PackageOrSourceInput - Dec []*model.LicenseInputSpec - Dis []*model.LicenseInputSpec - Legal *model.CertifyLegalInputSpec - } - type scorecardCall struct { - Src *model.SourceInputSpec - SC *model.ScorecardInputSpec - } - type vexCall struct { - Sub model.PackageOrArtifactInput - Vuln *model.VulnerabilityInputSpec - In *model.VexStatementInputSpec - } - type certifyVulnCall struct { - Pkg *model.PkgInputSpec - Vuln *model.VulnerabilityInputSpec - CertifyVuln *model.ScanMetadataInput - } - type hashEqualCall struct { - A1 *model.ArtifactInputSpec - A2 *model.ArtifactInputSpec - HE *model.HashEqualInputSpec - } - type hasMetadataCall struct { - Sub model.PackageSourceOrArtifactInput - Match *model.MatchFlags - HM *model.HasMetadataInputSpec - } - type hasSBOMCall struct { - Sub model.PackageOrArtifactInput - HS *model.HasSBOMInputSpec - } - type hasSlsaCall struct { - Sub *model.ArtifactInputSpec - BF []*model.ArtifactInputSpec - BB *model.BuilderInputSpec - SLSA *model.SLSAInputSpec - } - type hasSourceAtCall struct { - Pkg *model.PkgInputSpec - Src *model.SourceInputSpec - Match *model.MatchFlags - HSA *model.HasSourceAtInputSpec - } - type isDepCall struct { - P1 *model.PkgInputSpec - P2 *model.PkgInputSpec - MF model.MatchFlags - ID *model.IsDependencyInputSpec - } - type isOcurCall struct { - PkgSrc model.PackageOrSourceInput - Artifact *model.ArtifactInputSpec - Occurrence *model.IsOccurrenceInputSpec - } - type pkgEqualCall struct { - P1 *model.PkgInputSpec - P2 *model.PkgInputSpec - HE *model.PkgEqualInputSpec - } - type pointOfContactCall struct { - Sub model.PackageSourceOrArtifactInput - Match *model.MatchFlags - POC *model.PointOfContactInputSpec - } - type vulnEqualCall struct { - Vuln *model.VulnerabilityInputSpec - OtherVuln *model.VulnerabilityInputSpec - In *model.VulnEqualInputSpec - } - type vulnMetadataCall struct { - Vuln *model.VulnerabilityInputSpec - VulnMetadata *model.VulnerabilityMetadataInputSpec - } - tests := []struct { - name string - pkgInput *model.PkgInputSpec - artifactInput *model.ArtifactInputSpec - builderInput *model.BuilderInputSpec - srcInput *model.SourceInputSpec - vulnInput *model.VulnerabilityInputSpec - licenseInput *model.LicenseInputSpec - inPkg []*model.PkgInputSpec - inSrc []*model.SourceInputSpec - inArt []*model.ArtifactInputSpec - inVuln []*model.VulnerabilityInputSpec - inBld []*model.BuilderInputSpec - inLic []*model.LicenseInputSpec - certifyBadCall *certifyBadCall - certifyGoodCall *certifyGoodCall - certifyLegalCall *certifyLegalCall - scorecardCall *scorecardCall - vexCall *vexCall - certifyVulnCall *certifyVulnCall - hashEqualCall *hashEqualCall - hasMetadataCall *hasMetadataCall - hasSBOMCall *hasSBOMCall - hasSlsaCall *hasSlsaCall - hasSourceAtCall *hasSourceAtCall - isDepCall *isDepCall - isOcurCall *isOcurCall - pkgEqualCall *pkgEqualCall - pointOfContactCall *pointOfContactCall - vulnEqualCall *vulnEqualCall - vulnMetadataCall *vulnMetadataCall - want []model.Node - wantErr bool - }{{ - name: "package", - pkgInput: testdata.P1, - want: []model.Node{testdata.P1out}, - wantErr: false, - }, { - name: "artifact", - artifactInput: &model.ArtifactInputSpec{ - Algorithm: "sha256", - Digest: "6bbb0da1891646e58eb3e6a63af3a6fc3c8eb5a0d44824cba581d2e14a0450cf", - }, - want: []model.Node{&model.Artifact{ - Algorithm: "sha256", - Digest: "6bbb0da1891646e58eb3e6a63af3a6fc3c8eb5a0d44824cba581d2e14a0450cf", - }}, - wantErr: false, - }, { - name: "builder", - builderInput: &model.BuilderInputSpec{ - URI: "https://github.com/CreateFork/HubHostedActions@v1", - }, - want: []model.Node{&model.Builder{ - URI: "https://github.com/CreateFork/HubHostedActions@v1", - }}, - wantErr: false, - }, { - name: "source", - srcInput: testdata.S1, - want: []model.Node{testdata.S1out}, - wantErr: false, - }, { - name: "vulnerability", - vulnInput: testdata.C1, - want: []model.Node{&model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C1out}, - }}, - }, { - name: "license", - licenseInput: testdata.L1, - want: []model.Node{testdata.L1out}, - }, { - name: "certifyBad", - inPkg: []*model.PkgInputSpec{testdata.P1}, - certifyBadCall: &certifyBadCall{ - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - want: []model.Node{&model.CertifyBad{ - Subject: testdata.P1out, - Justification: "test justification", - }}, - }, { - name: "certifyGood", - inPkg: []*model.PkgInputSpec{testdata.P1}, - certifyGoodCall: &certifyGoodCall{ - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - want: []model.Node{&model.CertifyGood{ - Subject: testdata.P1out, - Justification: "test justification", - }}, - }, { - name: "certifyLegal", - inPkg: []*model.PkgInputSpec{testdata.P1}, - inLic: []*model.LicenseInputSpec{testdata.L1}, - certifyLegalCall: &certifyLegalCall{ - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Dec: []*model.LicenseInputSpec{testdata.L1}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification 2", - }, - }, - want: []model.Node{&model.CertifyLegal{ - Subject: testdata.P1out, - DeclaredLicenses: []*model.License{testdata.L1out}, - Justification: "test justification 2", - }}, - }, { - name: "scorecard", - inSrc: []*model.SourceInputSpec{testdata.S2}, - scorecardCall: &scorecardCall{ - Src: testdata.S2, - SC: &model.ScorecardInputSpec{ - Origin: "test origin", - }, - }, - want: []model.Node{&model.CertifyScorecard{ - Source: testdata.S2out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - Origin: "test origin", - }, - }}, - }, { - name: "vex", - inPkg: []*model.PkgInputSpec{testdata.P1}, - inVuln: []*model.VulnerabilityInputSpec{testdata.O2}, - vexCall: &vexCall{ - Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, - }, - Vuln: testdata.O2, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - want: []model.Node{&model.CertifyVEXStatement{ - Subject: testdata.P1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O2out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }}, - }, { - name: "certifyVuln", - inVuln: []*model.VulnerabilityInputSpec{testdata.G1}, - inPkg: []*model.PkgInputSpec{testdata.P2}, - certifyVulnCall: &certifyVulnCall{ - Pkg: testdata.P2, - Vuln: testdata.G1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: testdata.T1, - }, - }, - want: []model.Node{&model.CertifyVuln{ - Package: testdata.P2out, - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - Metadata: vmd1, - }}, - }, { - name: "hashEqual", - inArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2, testdata.A3}, - hashEqualCall: &hashEqualCall{ - A1: testdata.A1, - A2: testdata.A3, - HE: &model.HashEqualInputSpec{}, - }, - want: []model.Node{&model.HashEqual{ - Artifacts: []*model.Artifact{testdata.A3out, testdata.A1out}, - }}, - }, { - name: "hasMetadata", - inArt: []*model.ArtifactInputSpec{testdata.A2}, - hasMetadataCall: &hasMetadataCall{ - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - want: []model.Node{&model.HasMetadata{ - Subject: testdata.A2out, - Justification: "test justification", - }}, - }, { - name: "hasSBOM", - inPkg: []*model.PkgInputSpec{testdata.P1}, - hasSBOMCall: &hasSBOMCall{ - - Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, - }, - HS: &model.HasSBOMInputSpec{ - DownloadLocation: "location two", - }, - }, - want: []model.Node{&model.HasSbom{ - Subject: testdata.P1out, - DownloadLocation: "location two", - }}, - }, { - name: "hasSLSA", - inArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - inBld: []*model.BuilderInputSpec{testdata.B1, testdata.B2}, - hasSlsaCall: &hasSlsaCall{ - Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, - BB: testdata.B2, - SLSA: &model.SLSAInputSpec{}, - }, - want: []model.Node{&model.HasSlsa{ - Subject: testdata.A1out, - Slsa: &model.Slsa{ - BuiltBy: testdata.B2out, - BuiltFrom: []*model.Artifact{testdata.A2out}, - }, - }}, - }, { - name: "hasSourceAt", - inPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - inSrc: []*model.SourceInputSpec{testdata.S1}, - hasSourceAtCall: &hasSourceAtCall{ - Pkg: testdata.P2, - Src: testdata.S1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{}, - }, - want: []model.Node{&model.HasSourceAt{ - Package: testdata.P2out, - Source: testdata.S1out, - }}, - }, { - name: "isDependency", - inPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - isDepCall: &isDepCall{ - P1: testdata.P1, - P2: testdata.P2, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - want: []model.Node{&model.IsDependency{ - Package: testdata.P1out, - DependencyPackage: testdata.P2outName, - }}, - }, { - name: "isOccurrence", - inPkg: []*model.PkgInputSpec{testdata.P1}, - inArt: []*model.ArtifactInputSpec{testdata.A1}, - isOcurCall: &isOcurCall{ - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Artifact: testdata.A1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "test justification", - }, - }, - want: []model.Node{&model.IsOccurrence{ - Subject: testdata.P1out, - Artifact: testdata.A1out, - Justification: "test justification", - }}, - }, { - name: "pkgEqual", - inPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - pkgEqualCall: &pkgEqualCall{ - P1: testdata.P1, - P2: testdata.P2, - HE: &model.PkgEqualInputSpec{ - Justification: "test justification two", - }, - }, - want: []model.Node{&model.PkgEqual{ - - Packages: []*model.Package{testdata.P1out, testdata.P2out}, - Justification: "test justification two", - }}, - }, { - name: "pointOfContact", - inArt: []*model.ArtifactInputSpec{testdata.A2}, - pointOfContactCall: &pointOfContactCall{ - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, - }, - POC: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - want: []model.Node{&model.PointOfContact{ - Subject: testdata.A2out, - Justification: "test justification", - }}, - }, { - name: "vulnEqual", - inVuln: []*model.VulnerabilityInputSpec{testdata.O1, testdata.G1}, - vulnEqualCall: &vulnEqualCall{ - Vuln: testdata.O1, - OtherVuln: testdata.G1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - want: []model.Node{&model.VulnEqual{ - Vulnerabilities: []*model.Vulnerability{ - { - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - { - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - }, - Justification: "test justification", - }}, - }, { - name: "vulnMetadata", - inVuln: []*model.VulnerabilityInputSpec{testdata.G1}, - vulnMetadataCall: &vulnMetadataCall{ - Vuln: testdata.G1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - want: []model.Node{&model.VulnerabilityMetadata{ - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }}, - }} - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - var nodeID string - for _, p := range tt.inPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, s := range tt.inSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, a := range tt.inArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - for _, bld := range tt.inBld { - if _, err := b.IngestBuilder(ctx, bld); err != nil { - t.Fatalf("Could not ingest builder: %v", err) - } - } - for _, a := range tt.inLic { - if _, err := b.IngestLicense(ctx, a); err != nil { - t.Fatalf("Could not ingest license: %v", err) - } - } - for _, g := range tt.inVuln { - if _, err := b.IngestVulnerability(ctx, *g); err != nil { - t.Fatalf("Could not ingest vulnerability: %a", err) - } - } - if tt.pkgInput != nil { - ingestedPkg, err := b.IngestPackage(ctx, *tt.pkgInput) - if (err != nil) != tt.wantErr { - t.Errorf("arangoClient.IngestPackage() error = %v, wantErr %v", err, tt.wantErr) - return - } - nodeID = ingestedPkg.PackageVersionID - } - if tt.artifactInput != nil { - ingestedArtID, err := b.IngestArtifact(ctx, tt.artifactInput) - if (err != nil) != tt.wantErr { - t.Errorf("arangoClient.IngestArtifact() error = %v, wantErr %v", err, tt.wantErr) - return - } - nodeID = ingestedArtID - } - if tt.builderInput != nil { - ingestedBuilderID, err := b.IngestBuilder(ctx, tt.builderInput) - if (err != nil) != tt.wantErr { - t.Errorf("arangoClient.IngestBuilder() error = %v, wantErr %v", err, tt.wantErr) - return - } - nodeID = ingestedBuilderID - } - if tt.srcInput != nil { - ingestedSrc, err := b.IngestSource(ctx, *tt.srcInput) - if (err != nil) != tt.wantErr { - t.Errorf("arangoClient.IngestSource() error = %v, wantErr %v", err, tt.wantErr) - return - } - nodeID = ingestedSrc.SourceNameID - } - if tt.vulnInput != nil { - ingestVuln, err := b.IngestVulnerability(ctx, *tt.vulnInput) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.want, err) - } - nodeID = ingestVuln.VulnerabilityNodeID - } - if tt.licenseInput != nil { - ingestedLicenseID, err := b.IngestLicense(ctx, tt.licenseInput) - if (err != nil) != tt.wantErr { - t.Errorf("arangoClient.IngestLicense() error = %v, wantErr %v", err, tt.wantErr) - return - } - nodeID = ingestedLicenseID - } - if tt.certifyBadCall != nil { - cbID, err := b.IngestCertifyBad(ctx, tt.certifyBadCall.Sub, tt.certifyBadCall.Match, *tt.certifyBadCall.CB) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - nodeID = cbID - } - if tt.certifyGoodCall != nil { - cgID, err := b.IngestCertifyGood(ctx, tt.certifyGoodCall.Sub, tt.certifyGoodCall.Match, *tt.certifyGoodCall.CG) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - nodeID = cgID - } - if tt.certifyLegalCall != nil { - cLID, err := b.IngestCertifyLegal(ctx, tt.certifyLegalCall.PkgSrc, tt.certifyLegalCall.Dec, tt.certifyLegalCall.Dis, tt.certifyLegalCall.Legal) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - nodeID = cLID - } - if tt.scorecardCall != nil { - sID, err := b.IngestScorecard(ctx, *tt.scorecardCall.Src, *tt.scorecardCall.SC) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - nodeID = sID - } - if tt.vexCall != nil { - vID, err := b.IngestVEXStatement(ctx, tt.vexCall.Sub, *tt.vexCall.Vuln, *tt.vexCall.In) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - nodeID = vID - } - if tt.certifyVulnCall != nil { - cvID, err := b.IngestCertifyVuln(ctx, *tt.certifyVulnCall.Pkg, *tt.certifyVulnCall.Vuln, *tt.certifyVulnCall.CertifyVuln) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - nodeID = cvID - } - if tt.hashEqualCall != nil { - heID, err := b.IngestHashEqual(ctx, *tt.hashEqualCall.A1, *tt.hashEqualCall.A2, *tt.hashEqualCall.HE) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - nodeID = heID - } - if tt.hasMetadataCall != nil { - hmID, err := b.IngestHasMetadata(ctx, tt.hasMetadataCall.Sub, tt.hasMetadataCall.Match, *tt.hasMetadataCall.HM) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - nodeID = hmID - } - if tt.hasSBOMCall != nil { - // TODO (knrc) handle includes - hsID, err := b.IngestHasSbom(ctx, tt.hasSBOMCall.Sub, *tt.hasSBOMCall.HS, model.HasSBOMIncludesInputSpec{}) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - nodeID = hsID - } - if tt.hasSlsaCall != nil { - sID, err := b.IngestSLSA(ctx, *tt.hasSlsaCall.Sub, tt.hasSlsaCall.BF, *tt.hasSlsaCall.BB, *tt.hasSlsaCall.SLSA) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - nodeID = sID - } - if tt.hasSourceAtCall != nil { - hsID, err := b.IngestHasSourceAt(ctx, *tt.hasSourceAtCall.Pkg, *tt.hasSourceAtCall.Match, *tt.hasSourceAtCall.Src, *tt.hasSourceAtCall.HSA) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - nodeID = hsID - } - if tt.isDepCall != nil { - dID, err := b.IngestDependency(ctx, *tt.isDepCall.P1, *tt.isDepCall.P2, tt.isDepCall.MF, *tt.isDepCall.ID) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - nodeID = dID - } - if tt.isOcurCall != nil { - oID, err := b.IngestOccurrence(ctx, tt.isOcurCall.PkgSrc, *tt.isOcurCall.Artifact, *tt.isOcurCall.Occurrence) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - nodeID = oID - } - if tt.pkgEqualCall != nil { - peID, err := b.IngestPkgEqual(ctx, *tt.pkgEqualCall.P1, *tt.pkgEqualCall.P2, *tt.pkgEqualCall.HE) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - nodeID = peID - } - if tt.pointOfContactCall != nil { - pocID, err := b.IngestPointOfContact(ctx, tt.pointOfContactCall.Sub, tt.pointOfContactCall.Match, *tt.pointOfContactCall.POC) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - nodeID = pocID - } - if tt.vulnEqualCall != nil { - veID, err := b.IngestVulnEqual(ctx, *tt.vulnEqualCall.Vuln, *tt.vulnEqualCall.OtherVuln, *tt.vulnEqualCall.In) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - nodeID = veID - } - if tt.vulnMetadataCall != nil { - vmID, err := b.IngestVulnerabilityMetadata(ctx, *tt.vulnMetadataCall.Vuln, *tt.vulnMetadataCall.VulnMetadata) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - nodeID = vmID - } - got, err := b.Nodes(ctx, []string{nodeID}) - if (err != nil) != tt.wantErr { - t.Errorf("node query error = %v, wantErr %v", err, tt.wantErr) - return - } - if diff := cmp.Diff(tt.want, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func Test_Neighbors(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - type certifyBadCall struct { - Sub model.PackageSourceOrArtifactInput - Match *model.MatchFlags - CB *model.CertifyBadInputSpec - } - type certifyGoodCall struct { - Sub model.PackageSourceOrArtifactInput - Match *model.MatchFlags - CG *model.CertifyGoodInputSpec - } - type certifyLegalCall struct { - PkgSrc model.PackageOrSourceInput - Dec []*model.LicenseInputSpec - Dis []*model.LicenseInputSpec - Legal *model.CertifyLegalInputSpec - } - type scorecardCall struct { - Src *model.SourceInputSpec - SC *model.ScorecardInputSpec - } - type vexCall struct { - Sub model.PackageOrArtifactInput - Vuln *model.VulnerabilityInputSpec - In *model.VexStatementInputSpec - } - type certifyVulnCall struct { - Pkg *model.PkgInputSpec - Vuln *model.VulnerabilityInputSpec - CertifyVuln *model.ScanMetadataInput - } - type hashEqualCall struct { - A1 *model.ArtifactInputSpec - A2 *model.ArtifactInputSpec - HE *model.HashEqualInputSpec - } - type hasMetadataCall struct { - Sub model.PackageSourceOrArtifactInput - Match *model.MatchFlags - HM *model.HasMetadataInputSpec - } - type hasSBOMCall struct { - Sub model.PackageOrArtifactInput - HS *model.HasSBOMInputSpec - PkgArt *model.PackageOrArtifactInputs - InSrc []*model.SourceInputSpec - IsDeps []testDependency - IsOccs []testOccurrence - } - type hasSlsaCall struct { - Sub *model.ArtifactInputSpec - BF []*model.ArtifactInputSpec - BB *model.BuilderInputSpec - SLSA *model.SLSAInputSpec - } - type hasSourceAtCall struct { - Pkg *model.PkgInputSpec - Src *model.SourceInputSpec - Match *model.MatchFlags - HSA *model.HasSourceAtInputSpec - } - type isDepCall struct { - P1 *model.PkgInputSpec - P2 *model.PkgInputSpec - MF model.MatchFlags - ID *model.IsDependencyInputSpec - } - type isOcurCall struct { - PkgSrc model.PackageOrSourceInput - Artifact *model.ArtifactInputSpec - Occurrence *model.IsOccurrenceInputSpec - } - type pkgEqualCall struct { - P1 *model.PkgInputSpec - P2 *model.PkgInputSpec - HE *model.PkgEqualInputSpec - } - type pointOfContactCall struct { - Sub model.PackageSourceOrArtifactInput - Match *model.MatchFlags - POC *model.PointOfContactInputSpec - } - type vulnEqualCall struct { - Vuln *model.VulnerabilityInputSpec - OtherVuln *model.VulnerabilityInputSpec - In *model.VulnEqualInputSpec - } - type vulnMetadataCall struct { - Vuln *model.VulnerabilityInputSpec - VulnMetadata *model.VulnerabilityMetadataInputSpec - } - tests := []struct { - name string - pkgInput *model.PkgInputSpec - srcInput *model.SourceInputSpec - vulnInput *model.VulnerabilityInputSpec - licenseInput *model.LicenseInputSpec - inPkg []*model.PkgInputSpec - inSrc []*model.SourceInputSpec - inArt []*model.ArtifactInputSpec - inVuln []*model.VulnerabilityInputSpec - inBld []*model.BuilderInputSpec - inLic []*model.LicenseInputSpec - queryArtifactID bool - queryEqualArtifactID bool - queryBuilderID bool - queryPkgTypeID bool - queryPkgNamespaceID bool - queryPkgNameID bool - queryPkgVersionID bool - queryEqualPkgID bool - querySrcTypeID bool - querySrcNamespaceID bool - querySrcNameID bool - queryVulnTypeID bool - queryVulnID bool - queryEqualVulnID bool - queryDeclaredLicenseID bool - queryDiscoveredLicenseID bool - queryCertifyBadID bool - queryCertifyGoodID bool - queryCertifyLegalID bool - queryScorecardID bool - queryCertifyVexID bool - queryCertifyVulnID bool - queryHashEqualID bool - queryHasMetadataID bool - queryHasSbomID bool - queryHasSlsaID bool - queryHasSourceAtID bool - queryIsDependencyID bool - queryIsOccurrenceID bool - queryPkgEqualID bool - queryPointOfContactID bool - queryVulnEqualID bool - queryVulnMetadataID bool - certifyBadCall *certifyBadCall - certifyGoodCall *certifyGoodCall - certifyLegalCall *certifyLegalCall - scorecardCall *scorecardCall - vexCall *vexCall - certifyVulnCall *certifyVulnCall - hashEqualCall *hashEqualCall - hasMetadataCall *hasMetadataCall - hasSBOMCall *hasSBOMCall - hasSlsaCall *hasSlsaCall - hasSourceAtCall *hasSourceAtCall - isDepCall *isDepCall - isOcurCall *isOcurCall - pkgEqualCall *pkgEqualCall - pointOfContactCall *pointOfContactCall - vulnEqualCall *vulnEqualCall - vulnMetadataCall *vulnMetadataCall - usingOnly []model.Edge - want []model.Node - wantErr bool - }{{ - name: "package - pkgType", - pkgInput: testdata.P1, - queryPkgTypeID: true, - want: []model.Node{&model.Package{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{{ - Names: []*model.PackageName{}, - }}}}, - wantErr: false, - }, { - name: "package - pkgNamespace", - pkgInput: testdata.P1, - queryPkgNamespaceID: true, - want: []model.Node{ - &model.Package{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{{ - Names: []*model.PackageName{{ - Name: "tensorflow", - Versions: []*model.PackageVersion{}, - }}, - }}}, - &model.Package{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{}, - }}, - wantErr: false, - }, { - name: "package - pkgName", - pkgInput: testdata.P1, - queryPkgNameID: true, - want: []model.Node{ - testdata.P1out, - &model.Package{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{{ - Names: []*model.PackageName{}, - }}}}, - wantErr: false, - }, { - name: "package - pkgVersion", - pkgInput: testdata.P1, - queryPkgVersionID: true, - want: []model.Node{&model.Package{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{{ - Names: []*model.PackageName{{ - Name: "tensorflow", - Versions: []*model.PackageVersion{}, - }}, - }}}}, - wantErr: false, - }, { - name: "source - srcType", - srcInput: testdata.S1, - querySrcTypeID: true, - want: []model.Node{&model.Source{ - Type: "git", - Namespaces: []*model.SourceNamespace{{ - Namespace: "github.com/jeff", - Names: []*model.SourceName{}, - }}, - }}, - wantErr: false, - }, { - name: "source - srcNamespace", - srcInput: testdata.S1, - querySrcNamespaceID: true, - want: []model.Node{ - testdata.S1out, - &model.Source{ - Type: "git", - Namespaces: []*model.SourceNamespace{}, - }}, - wantErr: false, - }, { - name: "source - srcName", - srcInput: testdata.S1, - querySrcNameID: true, - want: []model.Node{ - &model.Source{ - Type: "git", - Namespaces: []*model.SourceNamespace{{ - Namespace: "github.com/jeff", - Names: []*model.SourceName{}, - }}, - }}, - wantErr: false, - }, { - name: "vulnerability - type", - vulnInput: testdata.C1, - queryVulnTypeID: true, - want: []model.Node{&model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C1out}, - }}, - }, { - name: "vulnerability - vulnID", - vulnInput: testdata.C1, - queryVulnID: true, - want: []model.Node{&model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{}, - }}, - }, { - name: "certifyBad - Artifact", - inArt: []*model.ArtifactInputSpec{testdata.A2}, - certifyBadCall: &certifyBadCall{ - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - queryArtifactID: true, - want: []model.Node{&model.CertifyBad{ - Subject: testdata.A2out, - Justification: "test justification", - }}, - }, { - name: "certifyBad - PkgName", - inPkg: []*model.PkgInputSpec{testdata.P2}, - certifyBadCall: &certifyBadCall{ - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - queryPkgNameID: true, - want: []model.Node{ - testdata.P2out, - testdata.P1out, - &model.Package{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{{ - Names: []*model.PackageName{}, - }}}, - &model.CertifyBad{ - Subject: testdata.P2outName, - Justification: "test justification", - }}, - }, { - name: "certifyBad - pkgVersion", - inPkg: []*model.PkgInputSpec{testdata.P2}, - certifyBadCall: &certifyBadCall{ - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - queryPkgVersionID: true, - want: []model.Node{ - &model.Package{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{{ - Names: []*model.PackageName{{ - Name: "tensorflow", - Versions: []*model.PackageVersion{}, - }}, - }}, - }, - &model.CertifyBad{ - Subject: testdata.P2out, - Justification: "test justification", - }}, - }, { - name: "certifyBad - srcName", - inSrc: []*model.SourceInputSpec{testdata.S1}, - certifyBadCall: &certifyBadCall{ - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - querySrcNameID: true, - want: []model.Node{ - &model.Source{ - Type: "git", - Namespaces: []*model.SourceNamespace{{ - Namespace: "github.com/jeff", - Names: []*model.SourceName{}, - }}, - }, - &model.CertifyBad{ - Subject: testdata.S1out, - Justification: "test justification", - }}, - }, { - name: "certifyBad - query certifyBadID artifact", - inArt: []*model.ArtifactInputSpec{testdata.A2}, - certifyBadCall: &certifyBadCall{ - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - queryCertifyBadID: true, - want: []model.Node{testdata.A2out}, - }, { - name: "certifyBad - query certifyBadID PkgName", - inPkg: []*model.PkgInputSpec{testdata.P2}, - certifyBadCall: &certifyBadCall{ - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - queryCertifyBadID: true, - want: []model.Node{testdata.P2outName}, - }, { - name: "certifyBad - query certifyBadID pkgVersion", - inPkg: []*model.PkgInputSpec{testdata.P2}, - certifyBadCall: &certifyBadCall{ - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - queryCertifyBadID: true, - want: []model.Node{testdata.P2out}, - }, { - name: "certifyBad - query certifyBadID srcName", - inSrc: []*model.SourceInputSpec{testdata.S1}, - certifyBadCall: &certifyBadCall{ - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - queryCertifyBadID: true, - want: []model.Node{testdata.S1out}, - }, { - name: "certifyGood - artifact", - inArt: []*model.ArtifactInputSpec{testdata.A2}, - certifyGoodCall: &certifyGoodCall{ - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - queryArtifactID: true, - want: []model.Node{&model.CertifyGood{ - Subject: testdata.A2out, - Justification: "test justification", - }}, - }, { - name: "certifyGood - PkgName", - inPkg: []*model.PkgInputSpec{testdata.P2}, - certifyGoodCall: &certifyGoodCall{ - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - queryPkgNameID: true, - want: []model.Node{ - testdata.P2out, - testdata.P1out, - &model.Package{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{{ - Names: []*model.PackageName{}, - }}}, - &model.CertifyGood{ - Subject: testdata.P2outName, - Justification: "test justification", - }}, - }, { - name: "certifyGood - pkgVersion", - inPkg: []*model.PkgInputSpec{testdata.P2}, - certifyGoodCall: &certifyGoodCall{ - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - queryPkgVersionID: true, - want: []model.Node{ - &model.Package{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{{ - Names: []*model.PackageName{{ - Name: "tensorflow", - Versions: []*model.PackageVersion{}, - }}, - }}, - }, - &model.CertifyGood{ - Subject: testdata.P2out, - Justification: "test justification", - }}, - }, { - name: "certifyGood - srcName", - inSrc: []*model.SourceInputSpec{testdata.S1}, - certifyGoodCall: &certifyGoodCall{ - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - querySrcNameID: true, - want: []model.Node{ - &model.Source{ - Type: "git", - Namespaces: []*model.SourceNamespace{{ - Namespace: "github.com/jeff", - Names: []*model.SourceName{}, - }}, - }, - &model.CertifyGood{ - Subject: testdata.S1out, - Justification: "test justification", - }}, - }, { - name: "certifyGood - query certifyGoodID artifact", - inArt: []*model.ArtifactInputSpec{testdata.A2}, - certifyGoodCall: &certifyGoodCall{ - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - queryCertifyGoodID: true, - want: []model.Node{testdata.A2out}, - }, { - name: "certifyGood - query certifyGoodID PkgName", - inPkg: []*model.PkgInputSpec{testdata.P2}, - certifyGoodCall: &certifyGoodCall{ - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - queryCertifyGoodID: true, - want: []model.Node{testdata.P2outName}, - }, { - name: "certifyGood - query certifyGoodID pkgVersion", - inPkg: []*model.PkgInputSpec{testdata.P2}, - certifyGoodCall: &certifyGoodCall{ - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - queryCertifyGoodID: true, - want: []model.Node{testdata.P2out}, - }, { - name: "certifyGood - query certifyGoodID srcName", - inSrc: []*model.SourceInputSpec{testdata.S1}, - certifyGoodCall: &certifyGoodCall{ - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - queryCertifyGoodID: true, - want: []model.Node{testdata.S1out}, - }, { - name: "certifyLegal - pkgVersion", - inPkg: []*model.PkgInputSpec{testdata.P1}, - inLic: []*model.LicenseInputSpec{testdata.L1}, - certifyLegalCall: &certifyLegalCall{ - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Dec: []*model.LicenseInputSpec{testdata.L1}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification 2", - }, - }, - queryPkgVersionID: true, - want: []model.Node{ - &model.Package{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{{ - Names: []*model.PackageName{{ - Name: "tensorflow", - Versions: []*model.PackageVersion{}, - }}, - }}, - }, - &model.CertifyLegal{ - Subject: testdata.P1out, - DeclaredLicenses: []*model.License{testdata.L1out}, - Justification: "test justification 2", - }}, - }, { - name: "certifyLegal - srcName", - inSrc: []*model.SourceInputSpec{testdata.S1}, - inLic: []*model.LicenseInputSpec{testdata.L1}, - certifyLegalCall: &certifyLegalCall{ - PkgSrc: model.PackageOrSourceInput{ - Source: testdata.S1, - }, - Dec: []*model.LicenseInputSpec{testdata.L1}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification 2", - }, - }, - querySrcNameID: true, - want: []model.Node{ - &model.Source{ - Type: "git", - Namespaces: []*model.SourceNamespace{{ - Namespace: "github.com/jeff", - Names: []*model.SourceName{}, - }}, - }, - &model.CertifyLegal{ - Subject: testdata.S1out, - DeclaredLicenses: []*model.License{testdata.L1out}, - Justification: "test justification 2", - }}, - }, { - name: "certifyLegal - Declared License", - inPkg: []*model.PkgInputSpec{testdata.P1}, - inLic: []*model.LicenseInputSpec{testdata.L2}, - certifyLegalCall: &certifyLegalCall{ - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Dec: []*model.LicenseInputSpec{testdata.L2}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification 2", - }, - }, - queryDeclaredLicenseID: true, - want: []model.Node{ - &model.CertifyLegal{ - Subject: testdata.P1out, - DeclaredLicenses: []*model.License{testdata.L2out}, - Justification: "test justification 2", - }}, - }, { - name: "certifyLegal - Discovered License", - inPkg: []*model.PkgInputSpec{testdata.P1}, - inLic: []*model.LicenseInputSpec{testdata.L3}, - certifyLegalCall: &certifyLegalCall{ - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Dis: []*model.LicenseInputSpec{testdata.L3}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification 2", - }, - }, - queryDiscoveredLicenseID: true, - want: []model.Node{ - &model.CertifyLegal{ - Subject: testdata.P1out, - DiscoveredLicenses: []*model.License{testdata.L3out}, - Justification: "test justification 2", - }}, - }, { - name: "certifyLegal - query certifyLegalID pkgVersion", - inPkg: []*model.PkgInputSpec{testdata.P1}, - inLic: []*model.LicenseInputSpec{testdata.L1}, - certifyLegalCall: &certifyLegalCall{ - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Dec: []*model.LicenseInputSpec{testdata.L1}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification 2", - }, - }, - queryCertifyLegalID: true, - usingOnly: []model.Edge{model.EdgeCertifyLegalPackage}, - want: []model.Node{testdata.P1out}, - }, { - name: "certifyLegal - srcName", - inSrc: []*model.SourceInputSpec{testdata.S1}, - inLic: []*model.LicenseInputSpec{testdata.L1}, - certifyLegalCall: &certifyLegalCall{ - PkgSrc: model.PackageOrSourceInput{ - Source: testdata.S1, - }, - Dec: []*model.LicenseInputSpec{testdata.L1}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification 2", - }, - }, - queryCertifyLegalID: true, - usingOnly: []model.Edge{model.EdgeCertifyLegalSource}, - want: []model.Node{testdata.S1out}, - }, { - name: "certifyLegal - Declared License", - inPkg: []*model.PkgInputSpec{testdata.P1}, - inLic: []*model.LicenseInputSpec{testdata.L2}, - certifyLegalCall: &certifyLegalCall{ - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Dec: []*model.LicenseInputSpec{testdata.L2}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification 2", - }, - }, - queryCertifyLegalID: true, - usingOnly: []model.Edge{model.EdgeCertifyLegalLicense}, - want: []model.Node{testdata.L2out}, - }, { - name: "certifyLegal - Discovered License", - inPkg: []*model.PkgInputSpec{testdata.P1}, - inLic: []*model.LicenseInputSpec{testdata.L3}, - certifyLegalCall: &certifyLegalCall{ - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Dis: []*model.LicenseInputSpec{testdata.L3}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification 2", - }, - }, - queryCertifyLegalID: true, - usingOnly: []model.Edge{model.EdgeCertifyLegalLicense}, - want: []model.Node{testdata.L3out}, - }, { - name: "scorecard", - inSrc: []*model.SourceInputSpec{testdata.S2}, - scorecardCall: &scorecardCall{ - Src: testdata.S2, - SC: &model.ScorecardInputSpec{ - Origin: "test origin", - }, - }, - querySrcNameID: true, - want: []model.Node{ - &model.Source{ - Type: "git", - Namespaces: []*model.SourceNamespace{{ - Namespace: "github.com/bob", - Names: []*model.SourceName{}, - }}, - }, - &model.CertifyScorecard{ - Source: testdata.S2out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - Origin: "test origin", - }, - }}, - }, { - name: "scorecard - certifyScoreID", - inSrc: []*model.SourceInputSpec{testdata.S2}, - scorecardCall: &scorecardCall{ - Src: testdata.S2, - SC: &model.ScorecardInputSpec{ - Origin: "test origin", - }, - }, - queryScorecardID: true, - usingOnly: []model.Edge{model.EdgeCertifyScorecardSource}, - want: []model.Node{testdata.S2out}, - }, { - name: "vex - artifact", - inArt: []*model.ArtifactInputSpec{testdata.A2}, - inVuln: []*model.VulnerabilityInputSpec{testdata.O2}, - vexCall: &vexCall{ - Sub: model.PackageOrArtifactInput{ - Artifact: testdata.A2, - }, - Vuln: testdata.O2, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - queryArtifactID: true, - want: []model.Node{&model.CertifyVEXStatement{ - Subject: testdata.A2out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O2out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }}, - }, { - name: "vex - pkgVersion", - inPkg: []*model.PkgInputSpec{testdata.P1}, - inVuln: []*model.VulnerabilityInputSpec{testdata.O2}, - vexCall: &vexCall{ - Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, - }, - Vuln: testdata.O2, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - queryPkgVersionID: true, - want: []model.Node{ - &model.Package{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{{ - Names: []*model.PackageName{{ - Name: "tensorflow", - Versions: []*model.PackageVersion{}, - }}, - }}, - }, - &model.CertifyVEXStatement{ - Subject: testdata.P1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O2out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }}, - }, { - name: "vex - vulnID", - inPkg: []*model.PkgInputSpec{testdata.P1}, - inVuln: []*model.VulnerabilityInputSpec{testdata.G1}, - vexCall: &vexCall{ - Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, - }, - Vuln: testdata.G1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - queryVulnID: true, - want: []model.Node{ - &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{}, - }, - &model.CertifyVEXStatement{ - Subject: testdata.P1out, - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }}, - }, { - name: "vex - certifyVexID - artifact", - inArt: []*model.ArtifactInputSpec{testdata.A2}, - inVuln: []*model.VulnerabilityInputSpec{testdata.O2}, - vexCall: &vexCall{ - Sub: model.PackageOrArtifactInput{ - Artifact: testdata.A2, - }, - Vuln: testdata.O2, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - queryCertifyVexID: true, - usingOnly: []model.Edge{model.EdgeCertifyVexStatementArtifact}, - want: []model.Node{testdata.A2out}, - }, { - name: "vex - certifyVexID - pkgVersion", - inPkg: []*model.PkgInputSpec{testdata.P1}, - inVuln: []*model.VulnerabilityInputSpec{testdata.O2}, - vexCall: &vexCall{ - Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, - }, - Vuln: testdata.O2, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - queryCertifyVexID: true, - usingOnly: []model.Edge{model.EdgeCertifyVexStatementPackage}, - want: []model.Node{testdata.P1out}, - }, { - name: "vex - certifyVexID - vulnID", - inPkg: []*model.PkgInputSpec{testdata.P1}, - inVuln: []*model.VulnerabilityInputSpec{testdata.G1}, - vexCall: &vexCall{ - Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, - }, - Vuln: testdata.G1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - queryCertifyVexID: true, - usingOnly: []model.Edge{model.EdgeCertifyVexStatementVulnerability}, - want: []model.Node{&model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }}, - }, { - name: "certifyVuln - pkgVersion", - inVuln: []*model.VulnerabilityInputSpec{testdata.G1}, - inPkg: []*model.PkgInputSpec{testdata.P2}, - certifyVulnCall: &certifyVulnCall{ - Pkg: testdata.P2, - Vuln: testdata.G1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: testdata.T1, - }, - }, - queryPkgVersionID: true, - want: []model.Node{ - &model.Package{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{{ - Names: []*model.PackageName{{ - Name: "tensorflow", - Versions: []*model.PackageVersion{}, - }}, - }}, - }, - &model.CertifyVuln{ - Package: testdata.P2out, - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - Metadata: vmd1, - }}, - }, { - name: "certifyVuln - vulnID", - inVuln: []*model.VulnerabilityInputSpec{testdata.G1}, - inPkg: []*model.PkgInputSpec{testdata.P2}, - certifyVulnCall: &certifyVulnCall{ - Pkg: testdata.P2, - Vuln: testdata.G1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: testdata.T1, - }, - }, - queryVulnID: true, - want: []model.Node{ - &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{}, - }, - &model.CertifyVuln{ - Package: testdata.P2out, - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - Metadata: vmd1, - }}, - }, { - name: "certifyVuln - certifyVulnID - pkgVersion", - inVuln: []*model.VulnerabilityInputSpec{testdata.G1}, - inPkg: []*model.PkgInputSpec{testdata.P2}, - certifyVulnCall: &certifyVulnCall{ - Pkg: testdata.P2, - Vuln: testdata.G1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: testdata.T1, - }, - }, - queryCertifyVulnID: true, - usingOnly: []model.Edge{model.EdgeCertifyVulnPackage}, - want: []model.Node{testdata.P2out}, - }, { - name: "certifyVuln - vulnID", - inVuln: []*model.VulnerabilityInputSpec{testdata.G1}, - inPkg: []*model.PkgInputSpec{testdata.P2}, - certifyVulnCall: &certifyVulnCall{ - Pkg: testdata.P2, - Vuln: testdata.G1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: testdata.T1, - }, - }, - queryCertifyVulnID: true, - usingOnly: []model.Edge{model.EdgeCertifyVulnVulnerability}, - want: []model.Node{&model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }}, - }, { - name: "hashEqual - artifact", - inArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2, testdata.A3}, - hashEqualCall: &hashEqualCall{ - A1: testdata.A1, - A2: testdata.A3, - HE: &model.HashEqualInputSpec{}, - }, - queryArtifactID: true, - want: []model.Node{&model.HashEqual{ - Artifacts: []*model.Artifact{testdata.A3out, testdata.A1out}, - }}, - }, { - name: "hashEqual - second artifact", - inArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2, testdata.A3}, - hashEqualCall: &hashEqualCall{ - A1: testdata.A1, - A2: testdata.A3, - HE: &model.HashEqualInputSpec{}, - }, - queryEqualArtifactID: true, - want: []model.Node{&model.HashEqual{ - Artifacts: []*model.Artifact{testdata.A3out, testdata.A1out}, - }}, - }, { - name: "hashEqual - hashEqualID", - inArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2, testdata.A3}, - hashEqualCall: &hashEqualCall{ - A1: testdata.A1, - A2: testdata.A3, - HE: &model.HashEqualInputSpec{}, - }, - queryHashEqualID: true, - want: []model.Node{testdata.A3out, testdata.A1out}, - }, { - name: "hasMetadata - artifact", - inArt: []*model.ArtifactInputSpec{testdata.A2}, - hasMetadataCall: &hasMetadataCall{ - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - queryArtifactID: true, - want: []model.Node{&model.HasMetadata{ - Subject: testdata.A2out, - Justification: "test justification", - }}, - }, { - name: "hasMetadata - pkgName", - inPkg: []*model.PkgInputSpec{testdata.P2}, - hasMetadataCall: &hasMetadataCall{ - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - queryPkgNameID: true, - want: []model.Node{ - testdata.P2out, - testdata.P1out, - &model.Package{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{{ - Names: []*model.PackageName{}, - }}}, - &model.HasMetadata{ - Subject: testdata.P2outName, - Justification: "test justification", - }}, - }, { - name: "hasMetadata - pkgVersion", - inPkg: []*model.PkgInputSpec{testdata.P2}, - hasMetadataCall: &hasMetadataCall{ - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - queryPkgVersionID: true, - want: []model.Node{ - &model.Package{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{{ - Names: []*model.PackageName{{ - Name: "tensorflow", - Versions: []*model.PackageVersion{}, - }}, - }}, - }, - &model.HasMetadata{ - Subject: testdata.P2out, - Justification: "test justification", - }}, - }, { - name: "hasMetadata - srcName", - inSrc: []*model.SourceInputSpec{testdata.S1}, - hasMetadataCall: &hasMetadataCall{ - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - querySrcNameID: true, - want: []model.Node{ - &model.Source{ - Type: "git", - Namespaces: []*model.SourceNamespace{{ - Namespace: "github.com/jeff", - Names: []*model.SourceName{}, - }}, - }, - &model.HasMetadata{ - Subject: testdata.S1out, - Justification: "test justification", - }}, - }, { - name: "hasMetadata - hasMetadataID - artifact", - inArt: []*model.ArtifactInputSpec{testdata.A2}, - hasMetadataCall: &hasMetadataCall{ - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - queryHasMetadataID: true, - usingOnly: []model.Edge{model.EdgeHasMetadataArtifact}, - want: []model.Node{testdata.A2out}, - }, { - name: "hasMetadata - hasMetadataID - pkgName", - inPkg: []*model.PkgInputSpec{testdata.P2}, - hasMetadataCall: &hasMetadataCall{ - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - queryHasMetadataID: true, - usingOnly: []model.Edge{model.EdgeHasMetadataPackage}, - want: []model.Node{testdata.P2outName}, - }, { - name: "hasMetadata - hasMetadataID - pkgVersion", - inPkg: []*model.PkgInputSpec{testdata.P2}, - hasMetadataCall: &hasMetadataCall{ - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - queryHasMetadataID: true, - usingOnly: []model.Edge{model.EdgeHasMetadataPackage}, - want: []model.Node{testdata.P2out}, - }, { - name: "hasMetadata - hasMetadataID - srcName", - inSrc: []*model.SourceInputSpec{testdata.S1}, - hasMetadataCall: &hasMetadataCall{ - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - queryHasMetadataID: true, - usingOnly: []model.Edge{model.EdgeHasMetadataSource}, - want: []model.Node{testdata.S1out}, - }, { - name: "hasSBOM - artifact", - inArt: []*model.ArtifactInputSpec{testdata.A2}, - hasSBOMCall: &hasSBOMCall{ - Sub: model.PackageOrArtifactInput{ - Artifact: testdata.A2, - }, - HS: &model.HasSBOMInputSpec{ - DownloadLocation: "location two", - }, - }, - queryArtifactID: true, - want: []model.Node{&model.HasSbom{ - Subject: testdata.A2out, - DownloadLocation: "location two", - }}, - }, { - name: "hasSBOM - pkgVersion", - inPkg: []*model.PkgInputSpec{testdata.P2}, - hasSBOMCall: &hasSBOMCall{ - Sub: model.PackageOrArtifactInput{ - Package: testdata.P2, - }, - HS: &model.HasSBOMInputSpec{ - DownloadLocation: "location two", - }, - }, - queryPkgVersionID: true, - want: []model.Node{ - &model.Package{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{{ - Names: []*model.PackageName{{ - Name: "tensorflow", - Versions: []*model.PackageVersion{}, - }}, - }}, - }, - &model.HasSbom{ - Subject: testdata.P2out, - DownloadLocation: "location two", - }}, - }, { - name: "hasSBOM - Includes", - inPkg: []*model.PkgInputSpec{testdata.P2}, - hasSBOMCall: &hasSBOMCall{ - Sub: model.PackageOrArtifactInput{ - Package: testdata.P2, - }, - HS: &model.HasSBOMInputSpec{ - DownloadLocation: "location two", - }, - PkgArt: includedPackageArtifacts, - InSrc: includedSources, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - }, - queryHasSbomID: true, - want: []model.Node{ - testdata.P2out, - includedTestExpectedArtifact1, - includedTestExpectedArtifact2, - includedTestExpectedPackage1, - includedTestExpectedPackage2, - includedTestExpectedPackage3, - &model.IsDependency{ - Package: includedTestExpectedPackage1, - DependencyPackage: includedTestExpectedPackage2, - VersionRange: "dep1_range", - DependencyType: model.DependencyTypeDirect, - Justification: "dep1_justification", - Origin: "dep1_origin", - Collector: "dep1_collector", - }, - &model.IsDependency{ - Package: includedTestExpectedPackage1, - DependencyPackage: includedTestExpectedPackage3, - VersionRange: "dep2_range", - DependencyType: model.DependencyTypeIndirect, - Justification: "dep2_justification", - Origin: "dep2_origin", - Collector: "dep2_collector", - }, - &model.IsOccurrence{ - Subject: includedTestExpectedPackage1, - Artifact: includedTestExpectedArtifact1, - Justification: "occ_justification", - Origin: "occ_origin", - Collector: "occ_collector", - }, - &model.IsOccurrence{ - Subject: includedTestExpectedSource, - Artifact: includedTestExpectedArtifact1, - Justification: "occ_justification", - Origin: "occ_origin", - Collector: "occ_collector", - }, - }, - }, { - name: "hasSBOM - hasSbomID - artifact", - inArt: []*model.ArtifactInputSpec{testdata.A2}, - hasSBOMCall: &hasSBOMCall{ - Sub: model.PackageOrArtifactInput{ - Artifact: testdata.A2, - }, - HS: &model.HasSBOMInputSpec{ - DownloadLocation: "location two", - }, - }, - queryHasSbomID: true, - usingOnly: []model.Edge{model.EdgeHasSbomArtifact}, - want: []model.Node{testdata.A2out}, - }, { - name: "hasSBOM - hasSbomID - pkgVersion", - inPkg: []*model.PkgInputSpec{testdata.P2}, - hasSBOMCall: &hasSBOMCall{ - Sub: model.PackageOrArtifactInput{ - Package: testdata.P2, - }, - HS: &model.HasSBOMInputSpec{ - DownloadLocation: "location two", - }, - }, - queryHasSbomID: true, - usingOnly: []model.Edge{model.EdgeHasSbomPackage}, - want: []model.Node{testdata.P2out}, - }, { - name: "hasSLSA - builder", - inArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - inBld: []*model.BuilderInputSpec{testdata.B1, testdata.B2}, - hasSlsaCall: &hasSlsaCall{ - Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, - BB: testdata.B2, - SLSA: &model.SLSAInputSpec{}, - }, - queryBuilderID: true, - want: []model.Node{&model.HasSlsa{ - Subject: testdata.A1out, - Slsa: &model.Slsa{ - BuiltBy: testdata.B2out, - BuiltFrom: []*model.Artifact{testdata.A2out}, - }, - }}, - }, { - name: "hasSLSA - subject artifact", - inArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - inBld: []*model.BuilderInputSpec{testdata.B1, testdata.B2}, - hasSlsaCall: &hasSlsaCall{ - Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, - BB: testdata.B2, - SLSA: &model.SLSAInputSpec{}, - }, - queryArtifactID: true, - want: []model.Node{&model.HasSlsa{ - Subject: testdata.A1out, - Slsa: &model.Slsa{ - BuiltBy: testdata.B2out, - BuiltFrom: []*model.Artifact{testdata.A2out}, - }, - }}, - }, { - name: "hasSLSA - hasSlsaID - builder", - inArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - inBld: []*model.BuilderInputSpec{testdata.B1, testdata.B2}, - hasSlsaCall: &hasSlsaCall{ - Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, - BB: testdata.B2, - SLSA: &model.SLSAInputSpec{}, - }, - queryHasSlsaID: true, - usingOnly: []model.Edge{model.EdgeHasSlsaBuiltBy}, - want: []model.Node{testdata.B2out}, - }, { - name: "hasSLSA - hasSlsaID - subject artifact", - inArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - inBld: []*model.BuilderInputSpec{testdata.B1, testdata.B2}, - hasSlsaCall: &hasSlsaCall{ - Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, - BB: testdata.B2, - SLSA: &model.SLSAInputSpec{}, - }, - queryHasSlsaID: true, - usingOnly: []model.Edge{model.EdgeHasSlsaSubject}, - want: []model.Node{testdata.A1out}, - }, { - name: "hasSLSA - hasSlsaID - builtFrom", - inArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - inBld: []*model.BuilderInputSpec{testdata.B1, testdata.B2}, - hasSlsaCall: &hasSlsaCall{ - Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, - BB: testdata.B2, - SLSA: &model.SLSAInputSpec{}, - }, - queryHasSlsaID: true, - usingOnly: []model.Edge{model.EdgeHasSlsaMaterials}, - want: []model.Node{testdata.A2out}, - }, { - name: "hasSourceAt - pkgName", - inPkg: []*model.PkgInputSpec{testdata.P2}, - inSrc: []*model.SourceInputSpec{testdata.S1}, - hasSourceAtCall: &hasSourceAtCall{ - Pkg: testdata.P2, - Src: testdata.S1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - HSA: &model.HasSourceAtInputSpec{}, - }, - queryPkgNameID: true, - want: []model.Node{ - testdata.P2out, - testdata.P1out, - &model.Package{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{{ - Names: []*model.PackageName{}, - }}}, - &model.HasSourceAt{ - Package: testdata.P2outName, - Source: testdata.S1out, - }}, - }, { - name: "hasSourceAt - pkgVersion", - inPkg: []*model.PkgInputSpec{testdata.P2}, - inSrc: []*model.SourceInputSpec{testdata.S1}, - hasSourceAtCall: &hasSourceAtCall{ - Pkg: testdata.P2, - Src: testdata.S1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{}, - }, - queryPkgVersionID: true, - want: []model.Node{ - &model.Package{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{{ - Names: []*model.PackageName{{ - Name: "tensorflow", - Versions: []*model.PackageVersion{}, - }}, - }}}, - &model.HasSourceAt{ - Package: testdata.P2out, - Source: testdata.S1out, - }}, - }, { - name: "hasSourceAt - srcName", - inPkg: []*model.PkgInputSpec{testdata.P2}, - inSrc: []*model.SourceInputSpec{testdata.S1}, - hasSourceAtCall: &hasSourceAtCall{ - Pkg: testdata.P2, - Src: testdata.S1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{}, - }, - querySrcNameID: true, - want: []model.Node{ - &model.Source{ - Type: "git", - Namespaces: []*model.SourceNamespace{{ - Namespace: "github.com/jeff", - Names: []*model.SourceName{}, - }}, - }, - &model.HasSourceAt{ - Package: testdata.P2out, - Source: testdata.S1out, - }, - &model.HasSourceAt{ - Package: testdata.P2outName, - Source: testdata.S1out, - }}, - }, { - name: "hasSourceAt - hasSourceAtID - pkgName", - inPkg: []*model.PkgInputSpec{testdata.P2}, - inSrc: []*model.SourceInputSpec{testdata.S1}, - hasSourceAtCall: &hasSourceAtCall{ - Pkg: testdata.P2, - Src: testdata.S1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - HSA: &model.HasSourceAtInputSpec{}, - }, - queryHasSourceAtID: true, - usingOnly: []model.Edge{model.EdgeHasSourceAtPackage}, - want: []model.Node{testdata.P2outName}, - }, { - name: "hasSourceAt - hasSourceAtID - pkgVersion", - inPkg: []*model.PkgInputSpec{testdata.P2}, - inSrc: []*model.SourceInputSpec{testdata.S1}, - hasSourceAtCall: &hasSourceAtCall{ - Pkg: testdata.P2, - Src: testdata.S1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{}, - }, - queryHasSourceAtID: true, - usingOnly: []model.Edge{model.EdgeHasSourceAtPackage}, - want: []model.Node{testdata.P2out}, - }, { - name: "hasSourceAt - hasSourceAtID - srcName", - inPkg: []*model.PkgInputSpec{testdata.P2}, - inSrc: []*model.SourceInputSpec{testdata.S1}, - hasSourceAtCall: &hasSourceAtCall{ - Pkg: testdata.P2, - Src: testdata.S1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{}, - }, - queryHasSourceAtID: true, - usingOnly: []model.Edge{model.EdgeHasSourceAtSource}, - want: []model.Node{testdata.S1out}, - }, { - name: "isDependency - pkgName", - inPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - isDepCall: &isDepCall{ - P1: testdata.P1, - P2: testdata.P2, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - queryPkgNameID: true, - want: []model.Node{ - testdata.P2out, - testdata.P1out, - &model.Package{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{{ - Names: []*model.PackageName{}, - }}}, - &model.IsDependency{ - Package: testdata.P1out, - DependencyPackage: testdata.P2outName, - }}, - }, { - name: "isDependency - pkgVersion", - inPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - isDepCall: &isDepCall{ - P1: testdata.P1, - P2: testdata.P2, - MF: mSpecific, - ID: &model.IsDependencyInputSpec{}, - }, - queryPkgVersionID: true, - want: []model.Node{ - &model.Package{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{{ - Names: []*model.PackageName{{ - Name: "tensorflow", - Versions: []*model.PackageVersion{}, - }}, - }}}, - &model.IsDependency{ - Package: testdata.P1out, - DependencyPackage: testdata.P2out, - }}, - }, { - name: "isDependency - isDependencyID - pkgName", - inPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - isDepCall: &isDepCall{ - P1: testdata.P1, - P2: testdata.P2, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - queryIsDependencyID: true, - usingOnly: []model.Edge{model.EdgeIsDependencyPackage}, - want: []model.Node{testdata.P1out, testdata.P2outName}, - }, { - name: "isDependency - isDependencyID - pkgVersion", - inPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - isDepCall: &isDepCall{ - P1: testdata.P1, - P2: testdata.P2, - MF: mSpecific, - ID: &model.IsDependencyInputSpec{}, - }, - queryIsDependencyID: true, - usingOnly: []model.Edge{model.EdgeIsDependencyPackage}, - want: []model.Node{testdata.P1out, testdata.P2out}, - }, { - name: "isOccurrence - artifact", - inPkg: []*model.PkgInputSpec{testdata.P1}, - inArt: []*model.ArtifactInputSpec{testdata.A1}, - isOcurCall: &isOcurCall{ - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Artifact: testdata.A1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "test justification", - }, - }, - queryArtifactID: true, - want: []model.Node{&model.IsOccurrence{ - Subject: testdata.P1out, - Artifact: testdata.A1out, - Justification: "test justification", - }}, - }, { - name: "isOccurrence - pkgVersion", - inPkg: []*model.PkgInputSpec{testdata.P1}, - inArt: []*model.ArtifactInputSpec{testdata.A1}, - isOcurCall: &isOcurCall{ - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Artifact: testdata.A1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "test justification", - }, - }, - queryPkgVersionID: true, - want: []model.Node{ - &model.Package{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{{ - Names: []*model.PackageName{{ - Name: "tensorflow", - Versions: []*model.PackageVersion{}, - }}, - }}}, - &model.IsOccurrence{ - Subject: testdata.P1out, - Artifact: testdata.A1out, - Justification: "test justification", - }}, - }, { - name: "isOccurrence - srcName", - inSrc: []*model.SourceInputSpec{testdata.S1}, - inArt: []*model.ArtifactInputSpec{testdata.A1}, - isOcurCall: &isOcurCall{ - PkgSrc: model.PackageOrSourceInput{ - Source: testdata.S1, - }, - Artifact: testdata.A1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "test justification", - }, - }, - querySrcNameID: true, - want: []model.Node{ - &model.Source{ - Type: "git", - Namespaces: []*model.SourceNamespace{{ - Namespace: "github.com/jeff", - Names: []*model.SourceName{}, - }}, - }, - &model.IsOccurrence{ - Subject: testdata.S1out, - Artifact: testdata.A1out, - Justification: "test justification", - }}, - }, { - name: "isOccurrence - isOccurrenceID - artifact", - inPkg: []*model.PkgInputSpec{testdata.P1}, - inArt: []*model.ArtifactInputSpec{testdata.A1}, - isOcurCall: &isOcurCall{ - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Artifact: testdata.A1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "test justification", - }, - }, - queryIsOccurrenceID: true, - usingOnly: []model.Edge{model.EdgeIsOccurrenceArtifact}, - want: []model.Node{testdata.A1out}, - }, { - name: "isOccurrence - isOccurrenceID - pkgVersion", - inPkg: []*model.PkgInputSpec{testdata.P1}, - inArt: []*model.ArtifactInputSpec{testdata.A1}, - isOcurCall: &isOcurCall{ - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Artifact: testdata.A1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "test justification", - }, - }, - queryIsOccurrenceID: true, - usingOnly: []model.Edge{model.EdgeIsOccurrencePackage}, - want: []model.Node{testdata.P1out}, - }, { - name: "isOccurrence - isOccurrenceID - srcName", - inSrc: []*model.SourceInputSpec{testdata.S1}, - inArt: []*model.ArtifactInputSpec{testdata.A1}, - isOcurCall: &isOcurCall{ - PkgSrc: model.PackageOrSourceInput{ - Source: testdata.S1, - }, - Artifact: testdata.A1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "test justification", - }, - }, - queryIsOccurrenceID: true, - usingOnly: []model.Edge{model.EdgeIsOccurrenceSource}, - want: []model.Node{testdata.S1out}, - }, { - name: "pkgEqual", - inPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - pkgEqualCall: &pkgEqualCall{ - P1: testdata.P1, - P2: testdata.P2, - HE: &model.PkgEqualInputSpec{ - Justification: "test justification two", - }, - }, - queryPkgVersionID: true, - want: []model.Node{ - &model.Package{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{{ - Names: []*model.PackageName{{ - Name: "tensorflow", - Versions: []*model.PackageVersion{}, - }}, - }}, - }, - &model.PkgEqual{ - Packages: []*model.Package{testdata.P1out, testdata.P2out}, - Justification: "test justification two", - }}, - }, { - name: "pkgEqual - equal package", - inPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - pkgEqualCall: &pkgEqualCall{ - P1: testdata.P1, - P2: testdata.P2, - HE: &model.PkgEqualInputSpec{ - Justification: "test justification two", - }, - }, - queryEqualPkgID: true, - want: []model.Node{ - &model.Package{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{{ - Names: []*model.PackageName{{ - Name: "tensorflow", - Versions: []*model.PackageVersion{}, - }}, - }}, - }, - &model.PkgEqual{ - Packages: []*model.Package{testdata.P1out, testdata.P2out}, - Justification: "test justification two", - }}, - }, { - name: "pkgEqual - pkgEqualID", - inPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - pkgEqualCall: &pkgEqualCall{ - P1: testdata.P1, - P2: testdata.P2, - HE: &model.PkgEqualInputSpec{ - Justification: "test justification two", - }, - }, - queryPkgEqualID: true, - usingOnly: []model.Edge{model.EdgePkgEqualPackage}, - want: []model.Node{testdata.P1out, testdata.P2out}, - }, { - name: "pointOfContact - artifact", - inArt: []*model.ArtifactInputSpec{testdata.A1}, - pointOfContactCall: &pointOfContactCall{ - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - POC: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - queryArtifactID: true, - want: []model.Node{&model.PointOfContact{ - Subject: testdata.A1out, - Justification: "test justification", - }}, - }, { - name: "pointOfContact - PkgName", - inPkg: []*model.PkgInputSpec{testdata.P2}, - pointOfContactCall: &pointOfContactCall{ - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - POC: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - queryPkgNameID: true, - want: []model.Node{ - testdata.P2out, - testdata.P1out, - &model.Package{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{{ - Names: []*model.PackageName{}, - }}}, - &model.PointOfContact{ - Subject: testdata.P2outName, - Justification: "test justification", - }}, - }, { - name: "pointOfContact - srcName", - inSrc: []*model.SourceInputSpec{testdata.S1}, - pointOfContactCall: &pointOfContactCall{ - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - POC: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - querySrcNameID: true, - want: []model.Node{ - &model.Source{ - Type: "git", - Namespaces: []*model.SourceNamespace{{ - Namespace: "github.com/jeff", - Names: []*model.SourceName{}, - }}, - }, - &model.PointOfContact{ - Subject: testdata.S1out, - Justification: "test justification", - }}, - }, { - name: "pointOfContact - pkgVersion", - inPkg: []*model.PkgInputSpec{testdata.P2}, - pointOfContactCall: &pointOfContactCall{ - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - POC: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - queryPkgVersionID: true, - want: []model.Node{ - &model.Package{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{{ - Names: []*model.PackageName{{ - Name: "tensorflow", - Versions: []*model.PackageVersion{}, - }}, - }}, - }, - &model.PointOfContact{ - Subject: testdata.P2out, - Justification: "test justification", - }}, - }, { - name: "pointOfContact - pointOfContactID - artifact", - inArt: []*model.ArtifactInputSpec{testdata.A1}, - pointOfContactCall: &pointOfContactCall{ - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - POC: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - queryPointOfContactID: true, - usingOnly: []model.Edge{model.EdgePointOfContactArtifact}, - want: []model.Node{testdata.A1out}, - }, { - name: "pointOfContact - pointOfContactID - PkgName", - inPkg: []*model.PkgInputSpec{testdata.P2}, - pointOfContactCall: &pointOfContactCall{ - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - POC: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - queryPointOfContactID: true, - usingOnly: []model.Edge{model.EdgePointOfContactPackage}, - want: []model.Node{testdata.P2outName}, - }, { - name: "pointOfContact - pointOfContactID - srcName", - inSrc: []*model.SourceInputSpec{testdata.S1}, - pointOfContactCall: &pointOfContactCall{ - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - POC: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - queryPointOfContactID: true, - usingOnly: []model.Edge{model.EdgePointOfContactSource}, - want: []model.Node{testdata.S1out}, - }, { - name: "pointOfContact - pointOfContactID - pkgVersion", - inPkg: []*model.PkgInputSpec{testdata.P2}, - pointOfContactCall: &pointOfContactCall{ - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - POC: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - queryPointOfContactID: true, - usingOnly: []model.Edge{model.EdgePointOfContactPackage}, - want: []model.Node{testdata.P2out}, - }, { - name: "vulnEqual - vulnID", - inVuln: []*model.VulnerabilityInputSpec{testdata.O1, testdata.G1}, - vulnEqualCall: &vulnEqualCall{ - Vuln: testdata.O1, - OtherVuln: testdata.G1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - queryVulnID: true, - want: []model.Node{ - &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{}, - }, - &model.VulnEqual{ - Vulnerabilities: []*model.Vulnerability{ - { - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - { - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - }, - Justification: "test justification", - }}, - }, { - name: "vulnEqual - second vulnID", - inVuln: []*model.VulnerabilityInputSpec{testdata.O1, testdata.G1}, - vulnEqualCall: &vulnEqualCall{ - Vuln: testdata.O1, - OtherVuln: testdata.G1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - queryEqualVulnID: true, - want: []model.Node{ - &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{}, - }, - &model.VulnEqual{ - Vulnerabilities: []*model.Vulnerability{ - { - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - { - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - }, - Justification: "test justification", - }}, - }, { - name: "vulnEqual - vulnEqualID", - inVuln: []*model.VulnerabilityInputSpec{testdata.O1, testdata.G1}, - vulnEqualCall: &vulnEqualCall{ - Vuln: testdata.O1, - OtherVuln: testdata.G1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - queryVulnEqualID: true, - usingOnly: []model.Edge{model.EdgeVulnEqualVulnerability}, - want: []model.Node{&model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }}, - }, { - name: "vulnMetadata - vulnID", - inVuln: []*model.VulnerabilityInputSpec{testdata.G1}, - vulnMetadataCall: &vulnMetadataCall{ - Vuln: testdata.G1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - queryVulnID: true, - want: []model.Node{ - &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{}, - }, - &model.VulnerabilityMetadata{ - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }}, - }, { - name: "vulnMetadata - vulnMetadataID", - inVuln: []*model.VulnerabilityInputSpec{testdata.G1}, - vulnMetadataCall: &vulnMetadataCall{ - Vuln: testdata.G1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - queryVulnMetadataID: true, - usingOnly: []model.Edge{model.EdgeVulnMetadataVulnerability}, - want: []model.Node{&model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }}, - }} - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - var nodeID string - for _, p := range tt.inPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, s := range tt.inSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, a := range tt.inArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - for _, bld := range tt.inBld { - if _, err := b.IngestBuilder(ctx, bld); err != nil { - t.Fatalf("Could not ingest builder: %v", err) - } - } - for _, a := range tt.inLic { - if _, err := b.IngestLicense(ctx, a); err != nil { - t.Fatalf("Could not ingest license: %v", err) - } - } - for _, g := range tt.inVuln { - if _, err := b.IngestVulnerability(ctx, *g); err != nil { - t.Fatalf("Could not ingest vulnerability: %a", err) - } - } - if tt.pkgInput != nil { - ingestedPkg, err := b.IngestPackage(ctx, *tt.pkgInput) - if (err != nil) != tt.wantErr { - t.Errorf("arangoClient.IngestPackage() error = %v, wantErr %v", err, tt.wantErr) - return - } - if tt.queryPkgTypeID { - nodeID = ingestedPkg.PackageTypeID - tt.usingOnly = []model.Edge{} - } - if tt.queryPkgNamespaceID { - nodeID = ingestedPkg.PackageNamespaceID - tt.usingOnly = []model.Edge{} - } - if tt.queryPkgNameID { - nodeID = ingestedPkg.PackageNameID - tt.usingOnly = []model.Edge{} - } - if tt.queryPkgVersionID { - nodeID = ingestedPkg.PackageVersionID - tt.usingOnly = []model.Edge{} - } - } - if tt.srcInput != nil { - ingestedSrc, err := b.IngestSource(ctx, *tt.srcInput) - if (err != nil) != tt.wantErr { - t.Errorf("arangoClient.IngestSource() error = %v, wantErr %v", err, tt.wantErr) - return - } - if tt.querySrcTypeID { - nodeID = ingestedSrc.SourceTypeID - tt.usingOnly = []model.Edge{} - } - if tt.querySrcNamespaceID { - nodeID = ingestedSrc.SourceNamespaceID - tt.usingOnly = []model.Edge{} - } - if tt.querySrcNameID { - nodeID = ingestedSrc.SourceNameID - tt.usingOnly = []model.Edge{} - } - } - if tt.vulnInput != nil { - ingestVuln, err := b.IngestVulnerability(ctx, *tt.vulnInput) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.want, err) - } - if tt.queryVulnTypeID { - nodeID = ingestVuln.VulnerabilityTypeID - tt.usingOnly = []model.Edge{} - } - if tt.queryVulnID { - nodeID = ingestVuln.VulnerabilityNodeID - tt.usingOnly = []model.Edge{} - } - } - if tt.licenseInput != nil { - ingestedLicenseID, err := b.IngestLicense(ctx, tt.licenseInput) - if (err != nil) != tt.wantErr { - t.Errorf("arangoClient.IngestLicense() error = %v, wantErr %v", err, tt.wantErr) - return - } - nodeID = ingestedLicenseID - } - if tt.certifyBadCall != nil { - cbID, err := b.IngestCertifyBad(ctx, tt.certifyBadCall.Sub, tt.certifyBadCall.Match, *tt.certifyBadCall.CB) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - found, err := b.CertifyBad(ctx, &model.CertifyBadSpec{ID: &cbID}) - if err != nil { - t.Fatal() - } - if tt.queryArtifactID { - nodeID = found[0].Subject.(*model.Artifact).ID - tt.usingOnly = []model.Edge{model.EdgeArtifactCertifyBad} - } - if tt.queryPkgNameID { - nodeID = found[0].Subject.(*model.Package).Namespaces[0].Names[0].ID - tt.usingOnly = []model.Edge{model.EdgePackageCertifyBad, model.EdgePackageNamePackageNamespace, model.EdgePackageNamePackageVersion} - } - if tt.queryPkgVersionID { - nodeID = found[0].Subject.(*model.Package).Namespaces[0].Names[0].Versions[0].ID - tt.usingOnly = []model.Edge{model.EdgePackageCertifyBad, model.EdgePackageVersionPackageName} - } - if tt.querySrcNameID { - nodeID = found[0].Subject.(*model.Source).Namespaces[0].Names[0].ID - tt.usingOnly = []model.Edge{model.EdgeSourceCertifyBad, model.EdgeSourceNameSourceNamespace} - } - if tt.queryCertifyBadID { - nodeID = cbID - tt.usingOnly = []model.Edge{model.EdgeCertifyBadPackage, model.EdgeCertifyBadArtifact, model.EdgeCertifyBadSource} - } - } - if tt.certifyGoodCall != nil { - cgID, err := b.IngestCertifyGood(ctx, tt.certifyGoodCall.Sub, tt.certifyGoodCall.Match, *tt.certifyGoodCall.CG) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - found, err := b.CertifyGood(ctx, &model.CertifyGoodSpec{ID: &cgID}) - if err != nil { - t.Fatal() - } - if tt.queryArtifactID { - nodeID = found[0].Subject.(*model.Artifact).ID - tt.usingOnly = []model.Edge{model.EdgeArtifactCertifyGood} - } - if tt.queryPkgNameID { - nodeID = found[0].Subject.(*model.Package).Namespaces[0].Names[0].ID - tt.usingOnly = []model.Edge{model.EdgePackageCertifyGood, model.EdgePackageNamePackageNamespace, model.EdgePackageNamePackageVersion} - } - if tt.queryPkgVersionID { - nodeID = found[0].Subject.(*model.Package).Namespaces[0].Names[0].Versions[0].ID - tt.usingOnly = []model.Edge{model.EdgePackageCertifyGood, model.EdgePackageVersionPackageName} - } - if tt.querySrcNameID { - nodeID = found[0].Subject.(*model.Source).Namespaces[0].Names[0].ID - tt.usingOnly = []model.Edge{model.EdgeSourceCertifyGood, model.EdgeSourceNameSourceNamespace} - } - if tt.queryCertifyGoodID { - nodeID = cgID - tt.usingOnly = []model.Edge{model.EdgeCertifyGoodPackage, model.EdgeCertifyGoodArtifact, model.EdgeCertifyGoodSource} - } - } - if tt.certifyLegalCall != nil { - clID, err := b.IngestCertifyLegal(ctx, tt.certifyLegalCall.PkgSrc, tt.certifyLegalCall.Dec, tt.certifyLegalCall.Dis, tt.certifyLegalCall.Legal) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - found, err := b.CertifyLegal(ctx, &model.CertifyLegalSpec{ID: &clID}) - if err != nil { - t.Fatal() - } - if tt.queryPkgVersionID { - nodeID = found[0].Subject.(*model.Package).Namespaces[0].Names[0].Versions[0].ID - tt.usingOnly = []model.Edge{model.EdgePackageCertifyLegal, model.EdgePackageVersionPackageName} - } - if tt.querySrcNameID { - nodeID = found[0].Subject.(*model.Source).Namespaces[0].Names[0].ID - tt.usingOnly = []model.Edge{model.EdgeSourceCertifyLegal, model.EdgeSourceNameSourceNamespace} - } - if tt.queryDeclaredLicenseID { - nodeID = found[0].DeclaredLicenses[0].ID - tt.usingOnly = []model.Edge{model.EdgeLicenseCertifyLegal} - } - if tt.queryDiscoveredLicenseID { - nodeID = found[0].DiscoveredLicenses[0].ID - tt.usingOnly = []model.Edge{model.EdgeLicenseCertifyLegal} - } - if tt.queryCertifyLegalID { - nodeID = clID - } - } - if tt.scorecardCall != nil { - sID, err := b.IngestScorecard(ctx, *tt.scorecardCall.Src, *tt.scorecardCall.SC) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - found, err := b.Scorecards(ctx, &model.CertifyScorecardSpec{ID: &sID}) - if err != nil { - t.Fatal() - } - if tt.querySrcNameID { - nodeID = found[0].Source.Namespaces[0].Names[0].ID - tt.usingOnly = []model.Edge{model.EdgeSourceCertifyScorecard, model.EdgeSourceNameSourceNamespace} - } - if tt.queryScorecardID { - nodeID = sID - } - } - if tt.vexCall != nil { - vexID, err := b.IngestVEXStatement(ctx, tt.vexCall.Sub, *tt.vexCall.Vuln, *tt.vexCall.In) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - found, err := b.CertifyVEXStatement(ctx, &model.CertifyVEXStatementSpec{ID: &vexID}) - if err != nil { - t.Fatal() - } - if tt.queryArtifactID { - nodeID = found[0].Subject.(*model.Artifact).ID - tt.usingOnly = []model.Edge{model.EdgeArtifactCertifyVexStatement} - } - if tt.queryPkgVersionID { - nodeID = found[0].Subject.(*model.Package).Namespaces[0].Names[0].Versions[0].ID - tt.usingOnly = []model.Edge{model.EdgePackageCertifyVexStatement, model.EdgePackageVersionPackageName} - } - if tt.queryVulnID { - nodeID = found[0].Vulnerability.VulnerabilityIDs[0].ID - tt.usingOnly = []model.Edge{model.EdgeVulnerabilityCertifyVexStatement, model.EdgeVulnerabilityIDVulnerabilityType} - } - if tt.queryCertifyVexID { - nodeID = vexID - } - } - if tt.certifyVulnCall != nil { - cvID, err := b.IngestCertifyVuln(ctx, *tt.certifyVulnCall.Pkg, *tt.certifyVulnCall.Vuln, *tt.certifyVulnCall.CertifyVuln) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - found, err := b.CertifyVuln(ctx, &model.CertifyVulnSpec{ID: &cvID}) - if err != nil { - t.Fatal() - } - if tt.queryPkgVersionID { - nodeID = found[0].Package.Namespaces[0].Names[0].Versions[0].ID - tt.usingOnly = []model.Edge{model.EdgePackageCertifyVuln, model.EdgePackageVersionPackageName} - } - if tt.queryVulnID { - nodeID = found[0].Vulnerability.VulnerabilityIDs[0].ID - tt.usingOnly = []model.Edge{model.EdgeVulnerabilityCertifyVuln, model.EdgeVulnerabilityIDVulnerabilityType} - } - if tt.queryCertifyVulnID { - nodeID = cvID - } - } - if tt.hashEqualCall != nil { - heID, err := b.IngestHashEqual(ctx, *tt.hashEqualCall.A1, *tt.hashEqualCall.A2, *tt.hashEqualCall.HE) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - found, err := b.HashEqual(ctx, &model.HashEqualSpec{ID: &heID}) - if err != nil { - t.Fatal() - } - if tt.queryArtifactID { - nodeID = found[0].Artifacts[0].ID - tt.usingOnly = []model.Edge{model.EdgeArtifactHashEqual} - } - if tt.queryEqualArtifactID { - nodeID = found[0].Artifacts[1].ID - tt.usingOnly = []model.Edge{model.EdgeArtifactHashEqual} - } - if tt.queryHashEqualID { - nodeID = heID - tt.usingOnly = []model.Edge{model.EdgeHashEqualArtifact} - } - } - if tt.hasMetadataCall != nil { - hmID, err := b.IngestHasMetadata(ctx, tt.hasMetadataCall.Sub, tt.hasMetadataCall.Match, *tt.hasMetadataCall.HM) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - found, err := b.HasMetadata(ctx, &model.HasMetadataSpec{ID: &hmID}) - if err != nil { - t.Fatal() - } - if tt.queryArtifactID { - nodeID = found[0].Subject.(*model.Artifact).ID - tt.usingOnly = []model.Edge{model.EdgeArtifactHasMetadata} - } - if tt.queryPkgNameID { - nodeID = found[0].Subject.(*model.Package).Namespaces[0].Names[0].ID - tt.usingOnly = []model.Edge{model.EdgePackageHasMetadata, model.EdgePackageNamePackageNamespace, model.EdgePackageNamePackageVersion} - } - if tt.queryPkgVersionID { - nodeID = found[0].Subject.(*model.Package).Namespaces[0].Names[0].Versions[0].ID - tt.usingOnly = []model.Edge{model.EdgePackageHasMetadata, model.EdgePackageVersionPackageName} - } - if tt.querySrcNameID { - nodeID = found[0].Subject.(*model.Source).Namespaces[0].Names[0].ID - tt.usingOnly = []model.Edge{model.EdgeSourceHasMetadata, model.EdgeSourceNameSourceNamespace} - } - if tt.queryHasMetadataID { - nodeID = hmID - } - } - if tt.hasSBOMCall != nil { - includes := model.HasSBOMIncludesInputSpec{} - for _, s := range tt.hasSBOMCall.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - if tt.hasSBOMCall.PkgArt != nil { - if pkgs, err := b.IngestPackages(ctx, tt.hasSBOMCall.PkgArt.Packages); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } else { - for _, pkg := range pkgs { - includes.Software = append(includes.Software, pkg.PackageVersionID) - } - } - if arts, err := b.IngestArtifacts(ctx, tt.hasSBOMCall.PkgArt.Artifacts); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } else { - if arts != nil { - includes.Software = append(includes.Software, arts...) - } - } - } - - for _, dep := range tt.hasSBOMCall.IsDeps { - if isDep, err := b.IngestDependency(ctx, *dep.pkg, *dep.depPkg, dep.matchType, *dep.isDep); err != nil { - t.Fatalf("Could not ingest dependency: %v", err) - } else { - includes.Dependencies = append(includes.Dependencies, isDep) - } - } - - for _, occ := range tt.hasSBOMCall.IsOccs { - if isOcc, err := b.IngestOccurrence(ctx, *occ.Subj, *occ.Art, *occ.isOcc); err != nil { - t.Fatalf("Could not ingest occurrence: %v", err) - } else { - includes.Occurrences = append(includes.Occurrences, isOcc) - } - } - hsID, err := b.IngestHasSbom(ctx, tt.hasSBOMCall.Sub, *tt.hasSBOMCall.HS, includes) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - found, err := b.HasSBOM(ctx, &model.HasSBOMSpec{ID: &hsID}) - if err != nil { - t.Fatal() - } - if tt.queryArtifactID { - nodeID = found[0].Subject.(*model.Artifact).ID - tt.usingOnly = []model.Edge{model.EdgeArtifactHasSbom} - } - if tt.queryPkgVersionID { - nodeID = found[0].Subject.(*model.Package).Namespaces[0].Names[0].Versions[0].ID - tt.usingOnly = []model.Edge{model.EdgePackageHasSbom, model.EdgePackageVersionPackageName} - } - if tt.queryHasSbomID { - nodeID = hsID - } - } - if tt.hasSlsaCall != nil { - slsaID, err := b.IngestSLSA(ctx, *tt.hasSlsaCall.Sub, tt.hasSlsaCall.BF, *tt.hasSlsaCall.BB, *tt.hasSlsaCall.SLSA) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - found, err := b.HasSlsa(ctx, &model.HasSLSASpec{ID: &slsaID}) - if err != nil { - t.Fatal() - } - if tt.queryBuilderID { - nodeID = found[0].Slsa.BuiltBy.ID - tt.usingOnly = []model.Edge{model.EdgeBuilderHasSlsa} - } - if tt.queryArtifactID { - nodeID = found[0].Subject.ID - tt.usingOnly = []model.Edge{model.EdgeArtifactHasSlsa} - } - if tt.queryHasSlsaID { - nodeID = slsaID - } - } - if tt.hasSourceAtCall != nil { - hsID, err := b.IngestHasSourceAt(ctx, *tt.hasSourceAtCall.Pkg, *tt.hasSourceAtCall.Match, *tt.hasSourceAtCall.Src, *tt.hasSourceAtCall.HSA) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - found, err := b.HasSourceAt(ctx, &model.HasSourceAtSpec{ID: &hsID}) - if err != nil { - t.Fatal() - } - if tt.queryPkgNameID { - nodeID = found[0].Package.Namespaces[0].Names[0].ID - tt.usingOnly = []model.Edge{model.EdgePackageHasSourceAt, model.EdgePackageNamePackageNamespace, model.EdgePackageNamePackageVersion} - } - if tt.queryPkgVersionID { - nodeID = found[0].Package.Namespaces[0].Names[0].Versions[0].ID - tt.usingOnly = []model.Edge{model.EdgePackageHasSourceAt, model.EdgePackageVersionPackageName} - } - if tt.querySrcNameID { - nodeID = found[0].Source.Namespaces[0].Names[0].ID - tt.usingOnly = []model.Edge{model.EdgeSourceHasSourceAt, model.EdgeSourceNameSourceNamespace} - } - if tt.queryHasSourceAtID { - nodeID = hsID - } - } - if tt.isDepCall != nil { - dID, err := b.IngestDependency(ctx, *tt.isDepCall.P1, *tt.isDepCall.P2, tt.isDepCall.MF, *tt.isDepCall.ID) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - found, err := b.IsDependency(ctx, &model.IsDependencySpec{ID: &dID}) - if err != nil { - t.Fatal() - } - if tt.queryPkgNameID { - nodeID = found[0].DependencyPackage.Namespaces[0].Names[0].ID - tt.usingOnly = []model.Edge{model.EdgePackageIsDependency, model.EdgePackageNamePackageNamespace, model.EdgePackageNamePackageVersion} - } - if tt.queryPkgVersionID { - nodeID = found[0].DependencyPackage.Namespaces[0].Names[0].Versions[0].ID - tt.usingOnly = []model.Edge{model.EdgePackageIsDependency, model.EdgePackageVersionPackageName} - } - if tt.queryIsDependencyID { - nodeID = dID - } - } - if tt.isOcurCall != nil { - oID, err := b.IngestOccurrence(ctx, tt.isOcurCall.PkgSrc, *tt.isOcurCall.Artifact, *tt.isOcurCall.Occurrence) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - found, err := b.IsOccurrence(ctx, &model.IsOccurrenceSpec{ID: &oID}) - if err != nil { - t.Fatal() - } - if tt.queryArtifactID { - nodeID = found[0].Artifact.ID - tt.usingOnly = []model.Edge{model.EdgeArtifactIsOccurrence} - } - if tt.queryPkgVersionID { - nodeID = found[0].Subject.(*model.Package).Namespaces[0].Names[0].Versions[0].ID - tt.usingOnly = []model.Edge{model.EdgePackageIsOccurrence, model.EdgePackageVersionPackageName} - } - if tt.querySrcNameID { - nodeID = found[0].Subject.(*model.Source).Namespaces[0].Names[0].ID - tt.usingOnly = []model.Edge{model.EdgeSourceIsOccurrence, model.EdgeSourceNameSourceNamespace} - } - if tt.queryIsOccurrenceID { - nodeID = oID - } - } - if tt.pkgEqualCall != nil { - peID, err := b.IngestPkgEqual(ctx, *tt.pkgEqualCall.P1, *tt.pkgEqualCall.P2, *tt.pkgEqualCall.HE) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - found, err := b.PkgEqual(ctx, &model.PkgEqualSpec{ID: &peID}) - if err != nil { - t.Fatal() - } - if tt.queryPkgVersionID { - nodeID = found[0].Packages[0].Namespaces[0].Names[0].Versions[0].ID - tt.usingOnly = []model.Edge{model.EdgePackagePkgEqual, model.EdgePackageVersionPackageName} - } - if tt.queryEqualPkgID { - nodeID = found[0].Packages[1].Namespaces[0].Names[0].Versions[0].ID - tt.usingOnly = []model.Edge{model.EdgePackagePkgEqual, model.EdgePackageVersionPackageName} - } - if tt.queryPkgEqualID { - nodeID = peID - } - } - if tt.pointOfContactCall != nil { - pocID, err := b.IngestPointOfContact(ctx, tt.pointOfContactCall.Sub, tt.pointOfContactCall.Match, *tt.pointOfContactCall.POC) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - found, err := b.PointOfContact(ctx, &model.PointOfContactSpec{ID: &pocID}) - if err != nil { - t.Fatal() - } - if tt.queryArtifactID { - nodeID = found[0].Subject.(*model.Artifact).ID - tt.usingOnly = []model.Edge{model.EdgeArtifactPointOfContact} - } - if tt.queryPkgNameID { - nodeID = found[0].Subject.(*model.Package).Namespaces[0].Names[0].ID - tt.usingOnly = []model.Edge{model.EdgePackagePointOfContact, model.EdgePackageNamePackageNamespace, model.EdgePackageNamePackageVersion} - } - if tt.queryPkgVersionID { - nodeID = found[0].Subject.(*model.Package).Namespaces[0].Names[0].Versions[0].ID - tt.usingOnly = []model.Edge{model.EdgePackagePointOfContact, model.EdgePackageVersionPackageName} - } - if tt.querySrcNameID { - nodeID = found[0].Subject.(*model.Source).Namespaces[0].Names[0].ID - tt.usingOnly = []model.Edge{model.EdgeSourcePointOfContact, model.EdgeSourceNameSourceNamespace} - } - if tt.queryPointOfContactID { - nodeID = pocID - } - } - if tt.vulnEqualCall != nil { - veID, err := b.IngestVulnEqual(ctx, *tt.vulnEqualCall.Vuln, *tt.vulnEqualCall.OtherVuln, *tt.vulnEqualCall.In) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - found, err := b.VulnEqual(ctx, &model.VulnEqualSpec{ID: &veID}) - if err != nil { - t.Fatal() - } - if tt.queryVulnID { - nodeID = found[0].Vulnerabilities[0].VulnerabilityIDs[0].ID - tt.usingOnly = []model.Edge{model.EdgeVulnerabilityVulnEqual, model.EdgeVulnerabilityIDVulnerabilityType} - } - if tt.queryEqualVulnID { - nodeID = found[0].Vulnerabilities[1].VulnerabilityIDs[0].ID - tt.usingOnly = []model.Edge{model.EdgeVulnerabilityVulnEqual, model.EdgeVulnerabilityIDVulnerabilityType} - } - if tt.queryVulnEqualID { - nodeID = veID - } - } - if tt.vulnMetadataCall != nil { - ingestedVuln, err := b.IngestVulnerability(ctx, *tt.inVuln[0]) - if err != nil { - t.Fatalf("Could not ingest vulnerability: %a", err) - } - - vulnMetadataID, err := b.IngestVulnerabilityMetadata(ctx, *tt.vulnMetadataCall.Vuln, *tt.vulnMetadataCall.VulnMetadata) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - if tt.queryVulnID { - nodeID = ingestedVuln.VulnerabilityNodeID - tt.usingOnly = []model.Edge{model.EdgeVulnMetadataVulnerability, model.EdgeVulnerabilityIDVulnerabilityType} - } - if tt.queryVulnMetadataID { - nodeID = vulnMetadataID - } - } - got, err := b.Neighbors(ctx, nodeID, tt.usingOnly) - if (err != nil) != tt.wantErr { - t.Errorf("neighbors query error = %v, wantErr %v", err, tt.wantErr) - return - } - if diff := cmp.Diff(tt.want, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} diff --git a/pkg/assembler/backends/arangodb/pkg.go b/pkg/assembler/backends/arangodb/pkg.go index 3fbefee4f8..04449442b6 100644 --- a/pkg/assembler/backends/arangodb/pkg.go +++ b/pkg/assembler/backends/arangodb/pkg.go @@ -162,10 +162,10 @@ func getPackageQueryValues(pkg *model.PkgInputSpec) map[string]any { return values } -func (c *arangoClient) IngestPackages(ctx context.Context, pkgs []*model.PkgInputSpec) ([]*model.PackageIDs, error) { +func (c *arangoClient) IngestPackages(ctx context.Context, pkgs []*model.IDorPkgInput) ([]*model.PackageIDs, error) { var listOfValues []map[string]any for i := range pkgs { - listOfValues = append(listOfValues, getPackageQueryValues(pkgs[i])) + listOfValues = append(listOfValues, getPackageQueryValues(pkgs[i].PackageInput)) } var documents []string @@ -252,7 +252,7 @@ func (c *arangoClient) IngestPackages(ctx context.Context, pkgs []*model.PkgInpu return getPackageIDs(ctx, cursor) } -func (c *arangoClient) IngestPackage(ctx context.Context, pkg model.PkgInputSpec) (*model.PackageIDs, error) { +func (c *arangoClient) IngestPackage(ctx context.Context, pkg model.IDorPkgInput) (*model.PackageIDs, error) { query := ` LET type = FIRST( UPSERT { type: @pkgType } @@ -305,7 +305,7 @@ func (c *arangoClient) IngestPackage(ctx context.Context, pkg model.PkgInputSpec "version_id": pkgVersionObj._id }` - cursor, err := executeQueryWithRetry(ctx, c.db, query, getPackageQueryValues(&pkg), "IngestPackage") + cursor, err := executeQueryWithRetry(ctx, c.db, query, getPackageQueryValues(pkg.PackageInput), "IngestPackage") if err != nil { return nil, fmt.Errorf("failed to ingest package: %w", err) } diff --git a/pkg/assembler/backends/arangodb/pkgEqual.go b/pkg/assembler/backends/arangodb/pkgEqual.go index eceb182149..9d99d3ce07 100644 --- a/pkg/assembler/backends/arangodb/pkgEqual.go +++ b/pkg/assembler/backends/arangodb/pkgEqual.go @@ -337,11 +337,11 @@ func getPkgEqualQueryValues(currentPkg *model.PkgInputSpec, otherPkg *model.PkgI return values } -func (c *arangoClient) IngestPkgEquals(ctx context.Context, pkgs []*model.PkgInputSpec, otherPackages []*model.PkgInputSpec, pkgEquals []*model.PkgEqualInputSpec) ([]string, error) { +func (c *arangoClient) IngestPkgEquals(ctx context.Context, pkgs []*model.IDorPkgInput, otherPackages []*model.IDorPkgInput, pkgEquals []*model.PkgEqualInputSpec) ([]string, error) { var listOfValues []map[string]any for i := range pkgEquals { - listOfValues = append(listOfValues, getPkgEqualQueryValues(pkgs[i], otherPackages[i], pkgEquals[i])) + listOfValues = append(listOfValues, getPkgEqualQueryValues(pkgs[i].PackageInput, otherPackages[i].PackageInput, pkgEquals[i])) } var documents []string @@ -421,7 +421,7 @@ func (c *arangoClient) IngestPkgEquals(ctx context.Context, pkgs []*model.PkgInp return pkgEqualIDList, nil } -func (c *arangoClient) IngestPkgEqual(ctx context.Context, pkg model.PkgInputSpec, otherPackage model.PkgInputSpec, pkgEqual model.PkgEqualInputSpec) (string, error) { +func (c *arangoClient) IngestPkgEqual(ctx context.Context, pkg model.IDorPkgInput, otherPackage model.IDorPkgInput, pkgEqual model.PkgEqualInputSpec) (string, error) { query := ` LET firstPkg = FIRST( FOR pVersion in pkgVersions @@ -456,7 +456,7 @@ func (c *arangoClient) IngestPkgEqual(ctx context.Context, pkg model.PkgInputSpe RETURN { 'pkgEqual_id': pkgEqual._id }` - cursor, err := executeQueryWithRetry(ctx, c.db, query, getPkgEqualQueryValues(&pkg, &otherPackage, &pkgEqual), "IngestPkgEqual") + cursor, err := executeQueryWithRetry(ctx, c.db, query, getPkgEqualQueryValues(pkg.PackageInput, otherPackage.PackageInput, &pkgEqual), "IngestPkgEqual") if err != nil { return "", fmt.Errorf("failed to ingest pkgEqual: %w", err) } diff --git a/pkg/assembler/backends/arangodb/pkgEqual_test.go b/pkg/assembler/backends/arangodb/pkgEqual_test.go deleted file mode 100644 index 2310356b08..0000000000 --- a/pkg/assembler/backends/arangodb/pkgEqual_test.go +++ /dev/null @@ -1,1143 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build integration - -package arangodb - -import ( - "context" - "fmt" - "strings" - "testing" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/internal/testing/testdata" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -func TestPkgEqual(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - type call struct { - P1 *model.PkgInputSpec - P2 *model.PkgInputSpec - HE *model.PkgEqualInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - Calls []call - Query *model.PkgEqualSpec - ExpHE []*model.PkgEqual - QueryID bool - QueryPkgID bool - QuerySecondaryPkgID bool - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - Calls: []call{ - { - P1: testdata.P1, - P2: testdata.P2, - HE: &model.PkgEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.PkgEqualSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHE: []*model.PkgEqual{ - { - Packages: []*model.Package{testdata.P1out, testdata.P2out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest same, different order", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - Calls: []call{ - { - P1: testdata.P1, - P2: testdata.P2, - HE: &model.PkgEqualInputSpec{ - Justification: "test justification", - }, - }, - { - P1: testdata.P2, - P2: testdata.P1, - HE: &model.PkgEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.PkgEqualSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHE: []*model.PkgEqual{ - { - Packages: []*model.Package{testdata.P1out, testdata.P2out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Justification", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - Calls: []call{ - { - P1: testdata.P1, - P2: testdata.P2, - HE: &model.PkgEqualInputSpec{ - Justification: "test justification one", - }, - }, - { - P1: testdata.P1, - P2: testdata.P2, - HE: &model.PkgEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.PkgEqualSpec{ - Justification: ptrfrom.String("test justification one"), - }, - ExpHE: []*model.PkgEqual{ - { - Packages: []*model.Package{testdata.P1out, testdata.P2out}, - Justification: "test justification one", - }, - }, - }, - { - Name: "Query on pkg ID", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - Calls: []call{ - { - P1: testdata.P1, - P2: testdata.P2, - HE: &model.PkgEqualInputSpec{ - Justification: "test justification one", - }, - }, - { - P1: testdata.P1, - P2: testdata.P2, - HE: &model.PkgEqualInputSpec{ - Justification: "test justification two", - }, - }, - }, - QueryPkgID: true, - ExpHE: []*model.PkgEqual{ - { - Packages: []*model.Package{testdata.P1out, testdata.P2out}, - Justification: "test justification two", - }, - { - Packages: []*model.Package{testdata.P1out, testdata.P2out}, - Justification: "test justification one", - }, - { - Packages: []*model.Package{testdata.P1out, testdata.P2out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on secondary pkg ID", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - Calls: []call{ - { - P1: testdata.P1, - P2: testdata.P2, - HE: &model.PkgEqualInputSpec{ - Justification: "test justification one", - }, - }, - { - P1: testdata.P1, - P2: testdata.P2, - HE: &model.PkgEqualInputSpec{ - Justification: "test justification two", - }, - }, - }, - QuerySecondaryPkgID: true, - ExpHE: []*model.PkgEqual{ - { - Packages: []*model.Package{testdata.P1out, testdata.P2out}, - Justification: "test justification two", - }, - { - Packages: []*model.Package{testdata.P1out, testdata.P2out}, - Justification: "test justification one", - }, - { - Packages: []*model.Package{testdata.P1out, testdata.P2out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on pkg", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2, testdata.P3}, - Calls: []call{ - { - P1: testdata.P1, - P2: testdata.P2, - HE: &model.PkgEqualInputSpec{ - Justification: "test justification", - }, - }, - { - P1: testdata.P1, - P2: testdata.P3, - HE: &model.PkgEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.PkgEqualSpec{ - Packages: []*model.PkgSpec{{ - Type: ptrfrom.String("pypi"), - Name: ptrfrom.String("tensorflow"), - Version: ptrfrom.String("2.11.1"), - Subpath: ptrfrom.String("saved_model_cli.py"), - MatchOnlyEmptyQualifiers: ptrfrom.Bool(true), - }}, - }, - ExpHE: []*model.PkgEqual{ - { - Packages: []*model.Package{testdata.P3out, testdata.P1out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on pkg details", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2, testdata.P3}, - Calls: []call{ - { - P1: testdata.P1, - P2: testdata.P2, - HE: &model.PkgEqualInputSpec{ - Justification: "test justification", - }, - }, - { - P1: testdata.P1, - P2: testdata.P3, - HE: &model.PkgEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.PkgEqualSpec{ - Packages: []*model.PkgSpec{{ - Version: ptrfrom.String("2.11.1"), - Subpath: ptrfrom.String(""), - }}, - Justification: ptrfrom.String("test justification"), - }, - ExpHE: []*model.PkgEqual{ - { - Packages: []*model.Package{testdata.P2out, testdata.P1out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on pkg algo and pkg", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2, testdata.P3}, - Calls: []call{ - { - P1: testdata.P1, - P2: testdata.P2, - HE: &model.PkgEqualInputSpec{ - Justification: "test justification", - }, - }, - { - P1: testdata.P1, - P2: testdata.P3, - HE: &model.PkgEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.PkgEqualSpec{ - Packages: []*model.PkgSpec{{ - Type: ptrfrom.String("pypi"), - Namespace: ptrfrom.String(""), - Name: ptrfrom.String("tensorflow"), - Subpath: ptrfrom.String(""), - Version: ptrfrom.String("2.11.1"), - }}, - }, - ExpHE: []*model.PkgEqual{ - { - Packages: []*model.Package{testdata.P2out, testdata.P1out}, - Justification: "test justification two", - }, - { - Packages: []*model.Package{testdata.P2out, testdata.P1out}, - Justification: "test justification one", - }, - { - Packages: []*model.Package{testdata.P2out, testdata.P1out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on both pkgs", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2, testdata.P3}, - Calls: []call{ - { - P1: testdata.P1, - P2: testdata.P2, - HE: &model.PkgEqualInputSpec{ - Justification: "test justification", - }, - }, - { - P1: testdata.P2, - P2: testdata.P3, - HE: &model.PkgEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.PkgEqualSpec{ - Packages: []*model.PkgSpec{ - { - Subpath: ptrfrom.String("saved_model_cli.py"), - }, - { - Name: ptrfrom.String("tensorflow"), - Version: ptrfrom.String("2.11.1"), - MatchOnlyEmptyQualifiers: ptrfrom.Bool(true), - }, - }, - }, - ExpHE: []*model.PkgEqual{ - { - Packages: []*model.Package{testdata.P3out, testdata.P2out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on both pkgs, one filter", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2, testdata.P3}, - Calls: []call{ - { - P1: testdata.P1, - P2: testdata.P2, - HE: &model.PkgEqualInputSpec{ - Justification: "test justification", - }, - }, - { - P1: testdata.P2, - P2: testdata.P3, - HE: &model.PkgEqualInputSpec{ - Justification: "test justification", - }, - }, - { - P1: testdata.P1, - P2: testdata.P3, - HE: &model.PkgEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.PkgEqualSpec{ - Packages: []*model.PkgSpec{ - { - Version: ptrfrom.String(""), - }, - { - Version: ptrfrom.String("2.11.1"), - Subpath: ptrfrom.String("saved_model_cli.py"), - }, - }, - }, - ExpHE: []*model.PkgEqual{ - { - Packages: []*model.Package{testdata.P1out, testdata.P3out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on both pkgs, match qualifiers", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P5}, - Calls: []call{ - { - P1: testdata.P1, - P2: testdata.P5, - HE: &model.PkgEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.PkgEqualSpec{ - Packages: []*model.PkgSpec{ - { - Version: ptrfrom.String(""), - MatchOnlyEmptyQualifiers: ptrfrom.Bool(true), - }, - { - MatchOnlyEmptyQualifiers: ptrfrom.Bool(false), - Qualifiers: []*model.PackageQualifierSpec{{ - Key: "test", - Value: ptrfrom.String("test"), - }}, - }, - }, - }, - ExpHE: []*model.PkgEqual{ - { - Packages: []*model.Package{testdata.P1out, testdata.P5out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on both pkgs, match qualifiers", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P5}, - Calls: []call{ - { - P1: testdata.P1, - P2: testdata.P5, - HE: &model.PkgEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.PkgEqualSpec{ - Packages: []*model.PkgSpec{ - { - Version: ptrfrom.String(""), - }, - { - Type: ptrfrom.String("conan"), - Namespace: ptrfrom.String("openssl.org"), - Qualifiers: []*model.PackageQualifierSpec{{ - Key: "test", - Value: ptrfrom.String("test"), - }}, - }, - }, - }, - ExpHE: []*model.PkgEqual{ - { - Packages: []*model.Package{testdata.P1out, testdata.P5out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Query none", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2, testdata.P3}, - Calls: []call{ - { - P1: testdata.P1, - P2: testdata.P2, - HE: &model.PkgEqualInputSpec{ - Justification: "test justification", - }, - }, - { - P1: testdata.P2, - P2: testdata.P3, - HE: &model.PkgEqualInputSpec{ - Justification: "test justification", - }, - }, - { - P1: testdata.P1, - P2: testdata.P3, - HE: &model.PkgEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.PkgEqualSpec{ - Packages: []*model.PkgSpec{ - { - Version: ptrfrom.String("1.2.3"), - }, - }, - }, - ExpHE: nil, - }, - { - Name: "Query on ID", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2, testdata.P3}, - Calls: []call{ - { - P1: testdata.P1, - P2: testdata.P2, - HE: &model.PkgEqualInputSpec{ - Justification: "test justification", - }, - }, - { - P1: testdata.P2, - P2: testdata.P3, - HE: &model.PkgEqualInputSpec{ - Justification: "test justification", - }, - }, - { - P1: testdata.P1, - P2: testdata.P3, - HE: &model.PkgEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - QueryID: true, - ExpHE: []*model.PkgEqual{ - { - Packages: []*model.Package{testdata.P1out, testdata.P3out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Query bad ID", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2, testdata.P3}, - Calls: []call{ - { - P1: testdata.P1, - P2: testdata.P2, - HE: &model.PkgEqualInputSpec{ - Justification: "test justification", - }, - }, - { - P1: testdata.P2, - P2: testdata.P3, - HE: &model.PkgEqualInputSpec{ - Justification: "test justification", - }, - }, - { - P1: testdata.P1, - P2: testdata.P3, - HE: &model.PkgEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.PkgEqualSpec{ - ID: ptrfrom.String("asdf"), - }, - ExpQueryErr: true, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - var collectedPkgIDs []*model.PackageIDs - for _, a := range test.InPkg { - if pkgIDs, err := b.IngestPackage(ctx, *a); err != nil { - t.Fatalf("Could not ingest pkg: %v", err) - } else { - collectedPkgIDs = append(collectedPkgIDs, pkgIDs) - } - } - for _, o := range test.Calls { - peID, err := b.IngestPkgEqual(ctx, *o.P1, *o.P2, *o.HE) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - if test.QueryID { - test.Query = &model.PkgEqualSpec{ - ID: ptrfrom.String(peID), - } - } - if test.QueryPkgID { - test.Query = &model.PkgEqualSpec{ - Packages: []*model.PkgSpec{{ - ID: ptrfrom.String(collectedPkgIDs[0].PackageVersionID), - }}, - } - } - if test.QuerySecondaryPkgID { - test.Query = &model.PkgEqualSpec{ - Packages: []*model.PkgSpec{ - { - ID: ptrfrom.String(collectedPkgIDs[0].PackageVersionID), - }, - { - ID: ptrfrom.String(collectedPkgIDs[1].PackageVersionID), - }, - }, - } - } - } - got, err := b.PkgEqual(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpHE, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func TestIngestPkgEquals(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - type call struct { - P1 []*model.PkgInputSpec - P2 []*model.PkgInputSpec - PE []*model.PkgEqualInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - Calls []call - Query *model.PkgEqualSpec - ExpHE []*model.PkgEqual - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - Calls: []call{ - { - P1: []*model.PkgInputSpec{testdata.P1, testdata.P1}, - P2: []*model.PkgInputSpec{testdata.P2, testdata.P2}, - PE: []*model.PkgEqualInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.PkgEqualSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHE: []*model.PkgEqual{ - { - Packages: []*model.Package{testdata.P1out, testdata.P2out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest same, different order", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - Calls: []call{ - { - P1: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - P2: []*model.PkgInputSpec{testdata.P2, testdata.P1}, - PE: []*model.PkgEqualInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.PkgEqualSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHE: []*model.PkgEqual{ - { - Packages: []*model.Package{testdata.P1out, testdata.P2out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on pkg details", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2, testdata.P3}, - Calls: []call{ - { - P1: []*model.PkgInputSpec{testdata.P1, testdata.P1}, - P2: []*model.PkgInputSpec{testdata.P2, testdata.P3}, - PE: []*model.PkgEqualInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.PkgEqualSpec{ - Packages: []*model.PkgSpec{{ - Version: ptrfrom.String("2.11.1"), - Subpath: ptrfrom.String(""), - }}, - Justification: ptrfrom.String("test justification"), - }, - ExpHE: []*model.PkgEqual{ - { - Packages: []*model.Package{testdata.P2out, testdata.P1out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on pkg algo and pkg", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2, testdata.P3}, - Calls: []call{ - { - P1: []*model.PkgInputSpec{testdata.P1, testdata.P1}, - P2: []*model.PkgInputSpec{testdata.P2, testdata.P3}, - PE: []*model.PkgEqualInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.PkgEqualSpec{ - Packages: []*model.PkgSpec{{ - Type: ptrfrom.String("pypi"), - Namespace: ptrfrom.String(""), - Name: ptrfrom.String("tensorflow"), - Subpath: ptrfrom.String(""), - Version: ptrfrom.String("2.11.1"), - }}, - }, - ExpHE: []*model.PkgEqual{ - { - Packages: []*model.Package{testdata.P2out, testdata.P1out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on both pkgs, one filter", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2, testdata.P3}, - Calls: []call{ - { - P1: []*model.PkgInputSpec{testdata.P1, testdata.P1}, - P2: []*model.PkgInputSpec{testdata.P2, testdata.P3}, - PE: []*model.PkgEqualInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.PkgEqualSpec{ - Packages: []*model.PkgSpec{ - { - Version: ptrfrom.String(""), - }, - { - Version: ptrfrom.String("2.11.1"), - Subpath: ptrfrom.String("saved_model_cli.py"), - }, - }, - }, - ExpHE: []*model.PkgEqual{ - { - Packages: []*model.Package{testdata.P1out, testdata.P3out}, - Justification: "test justification", - }, - }, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - if _, err := b.IngestPackages(ctx, test.InPkg); err != nil { - t.Fatalf("Could not ingest pkg: %v", err) - } - for _, o := range test.Calls { - _, err := b.IngestPkgEquals(ctx, o.P1, o.P2, o.PE) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.PkgEqual(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpHE, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func pkg(typ, namespace, name, version, subpath string, qualifiers map[string]string) *model.PkgInputSpec { - var pQualifiers []*model.PackageQualifierInputSpec - for k, v := range qualifiers { - pQualifiers = append(pQualifiers, &model.PackageQualifierInputSpec{ - Key: k, - Value: v, - }) - } - - p := &model.PkgInputSpec{ - Type: typ, - Namespace: &namespace, - Name: name, - Version: &version, - Subpath: &subpath, - Qualifiers: pQualifiers, - } - - return p -} - -func TestPkgInputSpecToPurl(t *testing.T) { - testCases := []struct { - expectedPurlUri string - input *model.PkgInputSpec - }{ - { - // alpine - expectedPurlUri: "pkg:alpm/arch/pacman@6.0.1-1?arch=x86_64", - input: pkg("alpm", "arch", "pacman", "6.0.1-1", "", map[string]string{ - "arch": "x86_64", - }), - }, { - expectedPurlUri: "pkg:apk/alpine/curl@7.83.0-r0?arch=x86", - input: pkg("apk", "alpine", "curl", "7.83.0-r0", "", map[string]string{ - "arch": "x86", - }), - }, { - expectedPurlUri: "pkg:bitbucket/birkenfeld/pygments-main@244fd47e07d1014f0aed9c", - input: pkg("bitbucket", "birkenfeld", "pygments-main", "244fd47e07d1014f0aed9c", "", map[string]string{}), - }, { - expectedPurlUri: "pkg:cocoapods/ShareKit@2.0#Twitter", - input: pkg("cocoapods", "", "ShareKit", "2.0", "Twitter", map[string]string{}), - }, { - expectedPurlUri: "pkg:cargo/rand@0.7.2", - input: pkg("cargo", "", "rand", "0.7.2", "", map[string]string{}), - }, { - expectedPurlUri: "pkg:composer/laravel/laravel@5.5.0", - input: pkg("composer", "laravel", "laravel", "5.5.0", "", map[string]string{}), - }, { - expectedPurlUri: "pkg:conan/openssl.org/openssl@3.0.3?channel=stable&user=bincrafters", - input: pkg("conan", "openssl.org", "openssl", "3.0.3", "", map[string]string{ - "user": "bincrafters", - "channel": "stable", - }), - }, { - expectedPurlUri: "pkg:conda/absl-py@0.4.1?build=py36h06a4308_0&channel=main&subdir=linux-64&type=tar.bz2", - input: pkg("conda", "", "absl-py", "0.4.1", "", map[string]string{ - "build": "py36h06a4308_0", - "channel": "main", - "subdir": "linux-64", - "type": "tar.bz2", - }), - }, { - expectedPurlUri: "pkg:cran/A3@1.0.0", - input: pkg("cran", "", "A3", "1.0.0", "", map[string]string{}), - }, { - expectedPurlUri: "pkg:deb/debian/dpkg@1.19.0.4?arch=amd64&distro=stretch", - input: pkg("deb", "debian", "dpkg", "1.19.0.4", "", map[string]string{ - "arch": "amd64", - "distro": "stretch", - }), - }, { - // The following are for docker PURLs - expectedPurlUri: "pkg:docker/dockerimage@sha256%3A244fd47e07d10?repository_url=gcr.io%2Fcustomer", - input: pkg("docker", "gcr.io/customer", "dockerimage", "sha256:244fd47e07d10", "", map[string]string{}), - }, { - expectedPurlUri: "pkg:docker/debian@dc437cc87d10?repository_url=smartentry", - input: pkg("docker", "smartentry", "debian", "dc437cc87d10", "", map[string]string{}), - }, { - expectedPurlUri: "pkg:docker/cassandra@latest", - input: pkg("docker", "", "cassandra", "latest", "", map[string]string{}), - }, { - expectedPurlUri: "pkg:gem/ruby-advisory-db-check@0.12.4", - input: pkg("gem", "", "ruby-advisory-db-check", "0.12.4", "", map[string]string{}), - }, { - // TODO (Issue #635): url path escapes here? Will this be an issue when searching via purl in osv or deps.dev? - expectedPurlUri: "pkg:generic/openssl@1.1.10g?checksum=sha256%3Ade4d501267da&download_url=https%3A%2F%2Fopenssl.org%2Fsource%2Fopenssl-1.1.0g.tar.gz", - input: pkg("generic", "", "openssl", "1.1.10g", "", map[string]string{ - "download_url": "https://openssl.org/source/openssl-1.1.0g.tar.gz", - "checksum": "sha256:de4d501267da", - }), - }, { - expectedPurlUri: "pkg:generic/bitwarderl?vcs_url=git%2Bhttps%3A%2F%2Fgit.fsfe.org%2Fdxtr%2Fbitwarderl%40cc55108da32", - input: pkg("generic", "", "bitwarderl", "", "", map[string]string{ - "vcs_url": "git+https://git.fsfe.org/dxtr/bitwarderl@cc55108da32", - }), - }, { - expectedPurlUri: "pkg:github/package-url/purl-spec@244fd47e07d1004#everybody/loves/dogs", - input: pkg("github", "package-url", "purl-spec", "244fd47e07d1004", "everybody/loves/dogs", map[string]string{}), - }, { - expectedPurlUri: "pkg:golang/github.com/gorilla/context@234fd47e07d1004f0aed9c#api", - input: pkg("golang", "github.com/gorilla", "context", "234fd47e07d1004f0aed9c", "api", map[string]string{}), - }, { - expectedPurlUri: "pkg:hackage/3d-graphics-examples@0.0.0.2", - input: pkg("hackage", "", "3d-graphics-examples", "0.0.0.2", "", map[string]string{}), - }, { - expectedPurlUri: "pkg:hex/bar@1.2.3?repository_url=https%3A%2F%2Fmyrepo.example.com", - input: pkg("hex", "", "bar", "1.2.3", "", map[string]string{ - "repository_url": "https://myrepo.example.com", - }), - }, { - expectedPurlUri: "pkg:hex/jason@1.1.2", - input: pkg("hex", "", "jason", "1.1.2", "", map[string]string{}), - }, { - expectedPurlUri: "pkg:huggingface/distilbert-base-uncased@043235d6088ecd3dd5fb5ca3592b6913fd516027", - input: pkg("huggingface", "", "distilbert-base-uncased", "043235d6088ecd3dd5fb5ca3592b6913fd516027", "", map[string]string{}), - }, { - expectedPurlUri: "pkg:maven/org.apache.xmlgraphics/batik-anim@1.9.1?classifier=dist&type=zip", - input: pkg("maven", "org.apache.xmlgraphics", "batik-anim", "1.9.1", "", map[string]string{ - "type": "zip", - "classifier": "dist", - }), - }, { - expectedPurlUri: "pkg:mlflow/trafficsigns@10?model_uuid=36233173b22f4c89b451f1228d700d49&repository_url=https%3A%2F%2Fadb-5245952564735461.0.azuredatabricks.net%2Fapi%2F2.0%2Fmlflow&run_id=410a3121-2709-4f88-98dd-dba0ef056b0a", - input: pkg("mlflow", "", "trafficsigns", "10", "", map[string]string{ - "model_uuid": "36233173b22f4c89b451f1228d700d49", - "run_id": "410a3121-2709-4f88-98dd-dba0ef056b0a", - "repository_url": "https://adb-5245952564735461.0.azuredatabricks.net/api/2.0/mlflow", - }), - }, { - expectedPurlUri: "pkg:npm/foobar@12.3.1", - input: pkg("npm", "", "foobar", "12.3.1", "", map[string]string{}), - }, { - expectedPurlUri: "pkg:npm/%40angular/animation@12.3.1", - input: pkg("npm", "@angular", "animation", "12.3.1", "", map[string]string{}), - }, { - expectedPurlUri: "pkg:nuget/EnterpriseLibrary.Common@6.0.1304", - input: pkg("nuget", "", "EnterpriseLibrary.Common", "6.0.1304", "", map[string]string{}), - }, { - expectedPurlUri: "pkg:qpkg/blackberry/com.qnx.sdp@7.0.0.SGA201702151847", - input: pkg("qpkg", "blackberry", "com.qnx.sdp", "7.0.0.SGA201702151847", "", map[string]string{}), - }, { - // Special OCI case - expectedPurlUri: "pkg:oci/debian@sha256%3A244fd47e07d10?arch=amd64&repository_url=docker.io%2Flibrary&tag=latest", - input: pkg("oci", "docker.io/library", "debian", "sha256:244fd47e07d10", "", map[string]string{ - "arch": "amd64", - "tag": "latest", - }), - }, { - expectedPurlUri: "pkg:oci/debian@sha256%3A244fd47e07d10?repository_url=ghcr.io&tag=bullseye", - input: pkg("oci", "ghcr.io", "debian", "sha256:244fd47e07d10", "", map[string]string{ - "tag": "bullseye", - }), - }, { - expectedPurlUri: "pkg:oci/hello-wasm@sha256%3A244fd47e07d10?tag=v1", - input: pkg("oci", "", "hello-wasm", "sha256:244fd47e07d10", "", map[string]string{ - "tag": "v1", - }), - }, { - expectedPurlUri: "pkg:pub/characters@1.2.0", - input: pkg("pub", "", "characters", "1.2.0", "", map[string]string{}), - }, { - expectedPurlUri: "pkg:pypi/django-allauth@12.23", - input: pkg("pypi", "", "django-allauth", "12.23", "", map[string]string{}), - }, { - expectedPurlUri: "pkg:rpm/fedora/curl@7.50.3-1.fc25?arch=i386&distro=fedora-25", - input: pkg("rpm", "fedora", "curl", "7.50.3-1.fc25", "", map[string]string{ - "arch": "i386", - "distro": "fedora-25", - }), - }, { - expectedPurlUri: "pkg:swid/Acme/example.com/Enterprise%2BServer@1.0.0?tag_id=75b8c285-fa7b-485b-b199-4745e3004d0d", - input: pkg("swid", "Acme/example.com", "Enterprise+Server", "1.0.0", "", map[string]string{ - "tag_id": "75b8c285-fa7b-485b-b199-4745e3004d0d", - }), - }, { - expectedPurlUri: "pkg:swift/github.com/RxSwiftCommunity/RxFlow@2.12.4", - input: pkg("swift", "github.com/RxSwiftCommunity", "RxFlow", "2.12.4", "", map[string]string{}), - }, - } - for _, tt := range testCases { - t.Run(fmt.Sprintf("processing %v", tt.expectedPurlUri), func(t *testing.T) { - got := pkgInputSpecToPurl(tt.input) - if got != tt.expectedPurlUri { - t.Errorf("purl mismatch wanted: %s, got: %s", tt.expectedPurlUri, got) - return - } - }) - } -} - -func Test_buildPkgEqualByID(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - type call struct { - P1 *model.PkgInputSpec - P2 *model.PkgInputSpec - HE *model.PkgEqualInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - Calls []call - Query *model.PkgEqualSpec - ExpHE *model.PkgEqual - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "Query on pkg ID", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - Calls: []call{ - { - P1: testdata.P1, - P2: testdata.P2, - HE: &model.PkgEqualInputSpec{ - Justification: "test justification two", - }, - }, - }, - ExpHE: &model.PkgEqual{ - Packages: []*model.Package{testdata.P1out, testdata.P2out}, - Justification: "test justification two", - }, - }, - { - Name: "Query on ID", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P3}, - Calls: []call{ - { - P1: testdata.P1, - P2: testdata.P3, - HE: &model.PkgEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - ExpHE: &model.PkgEqual{ - Packages: []*model.Package{testdata.P1out, testdata.P3out}, - Justification: "test justification", - }, - }, - { - Name: "Query bad ID", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P3}, - Calls: []call{ - { - P1: testdata.P1, - P2: testdata.P3, - HE: &model.PkgEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.PkgEqualSpec{ - ID: ptrfrom.String("asdf"), - }, - ExpQueryErr: true, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - for _, a := range test.InPkg { - if _, err := b.IngestPackage(ctx, *a); err != nil { - t.Fatalf("Could not ingest pkg: %v", err) - } - } - for _, o := range test.Calls { - peID, err := b.IngestPkgEqual(ctx, *o.P1, *o.P2, *o.HE) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - got, err := b.(*arangoClient).buildPkgEqualByID(ctx, peID, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpHE, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - } - - }) - } -} diff --git a/pkg/assembler/backends/arangodb/pkg_test.go b/pkg/assembler/backends/arangodb/pkg_test.go deleted file mode 100644 index 89a9d4bafc..0000000000 --- a/pkg/assembler/backends/arangodb/pkg_test.go +++ /dev/null @@ -1,611 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build integration - -package arangodb - -import ( - "context" - "slices" - "strings" - "testing" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/internal/testing/testdata" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -func Test_Packages(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - tests := []struct { - name string - pkgInput *model.PkgInputSpec - pkgFilter *model.PkgSpec - idInFilter bool - want []*model.Package - wantErr bool - }{{ - name: "tensorflow empty version", - pkgInput: testdata.P1, - pkgFilter: &model.PkgSpec{ - Name: ptrfrom.String("tensorflow"), - }, - idInFilter: false, - want: []*model.Package{testdata.P1out}, - wantErr: false, - }, { - name: "tensorflow empty version, ID search", - pkgInput: testdata.P1, - pkgFilter: &model.PkgSpec{ - Name: ptrfrom.String("tensorflow"), - }, - idInFilter: true, - want: []*model.Package{testdata.P1out}, - wantErr: false, - }, { - name: "tensorflow with version", - pkgInput: testdata.P2, - pkgFilter: &model.PkgSpec{ - Type: ptrfrom.String("pypi"), - Name: ptrfrom.String("tensorflow"), - Version: ptrfrom.String("2.11.1"), - }, - idInFilter: false, - want: []*model.Package{testdata.P2out}, - wantErr: false, - }, { - name: "tensorflow with version and subpath", - pkgInput: testdata.P3, - pkgFilter: &model.PkgSpec{ - Type: ptrfrom.String("pypi"), - Name: ptrfrom.String("tensorflow"), - Subpath: ptrfrom.String("saved_model_cli.py"), - }, - idInFilter: false, - want: []*model.Package{testdata.P3out}, - wantErr: false, - }, { - name: "openssl with version", - pkgInput: testdata.P4, - pkgFilter: &model.PkgSpec{ - Name: ptrfrom.String("openssl"), - Namespace: ptrfrom.String("openssl.org"), - Version: ptrfrom.String("3.0.3"), - }, - idInFilter: false, - want: []*model.Package{testdata.P4out}, - wantErr: false, - }, { - name: "openssl with match empty qualifiers", - pkgInput: testdata.P4, - pkgFilter: &model.PkgSpec{ - Name: ptrfrom.String("openssl"), - Namespace: ptrfrom.String("openssl.org"), - Version: ptrfrom.String("3.0.3"), - MatchOnlyEmptyQualifiers: ptrfrom.Bool(true), - }, - idInFilter: false, - want: []*model.Package{testdata.P4out}, - wantErr: false, - }, { - name: "openssl with qualifier", - pkgInput: testdata.P5, - pkgFilter: &model.PkgSpec{ - Name: ptrfrom.String("openssl"), - Namespace: ptrfrom.String("openssl.org"), - Version: ptrfrom.String("3.0.3"), - Qualifiers: []*model.PackageQualifierSpec{{ - Key: "test", - Value: ptrfrom.String("test"), - }}, - }, - idInFilter: false, - want: []*model.Package{testdata.P5out}, - wantErr: false, - }} - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - ingestedPkgIDs, err := b.IngestPackage(ctx, *tt.pkgInput) - if (err != nil) != tt.wantErr { - t.Errorf("arangoClient.IngestPackage() error = %v, wantErr %v", err, tt.wantErr) - return - } - if tt.idInFilter { - tt.pkgFilter.ID = ptrfrom.String(ingestedPkgIDs.PackageVersionID) - } - got, err := b.Packages(ctx, tt.pkgFilter) - if (err != nil) != tt.wantErr { - t.Errorf("arangoClient.Packages() error = %v, wantErr %v", err, tt.wantErr) - return - } - slices.SortFunc(got, lessPkg) - if diff := cmp.Diff(tt.want, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func Test_PackageTypes(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - tests := []struct { - name string - pkgInput *model.PkgInputSpec - pkgFilter *model.PkgSpec - idInFilter bool - want []*model.Package - wantErr bool - }{{ - name: "tensorflow empty version", - pkgInput: testdata.P1, - pkgFilter: &model.PkgSpec{ - Name: ptrfrom.String("tensorflow"), - }, - idInFilter: false, - want: []*model.Package{{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{}, - }}, - wantErr: false, - }, { - name: "tensorflow empty version, ID search", - pkgInput: testdata.P1, - pkgFilter: &model.PkgSpec{ - Name: ptrfrom.String("tensorflow"), - }, - idInFilter: true, - want: []*model.Package{{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{}, - }}, - wantErr: false, - }, { - name: "tensorflow with version", - pkgInput: testdata.P2, - pkgFilter: &model.PkgSpec{ - Type: ptrfrom.String("pypi"), - Name: ptrfrom.String("tensorflow"), - Version: ptrfrom.String("2.11.1"), - }, - idInFilter: false, - want: []*model.Package{{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{}, - }}, - wantErr: false, - }, { - name: "tensorflow with version and subpath", - pkgInput: testdata.P3, - pkgFilter: &model.PkgSpec{ - Type: ptrfrom.String("pypi"), - Name: ptrfrom.String("tensorflow"), - Subpath: ptrfrom.String("saved_model_cli.py"), - }, - idInFilter: false, - want: []*model.Package{{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{}, - }}, - wantErr: false, - }, { - name: "openssl with version", - pkgInput: testdata.P4, - pkgFilter: &model.PkgSpec{ - Type: ptrfrom.String("conan"), - Name: ptrfrom.String("openssl"), - Version: ptrfrom.String("3.0.3"), - }, - idInFilter: false, - want: []*model.Package{{ - Type: "conan", - Namespaces: []*model.PackageNamespace{}, - }}, - wantErr: false, - }} - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - ingestedPkgIDs, err := b.IngestPackage(ctx, *tt.pkgInput) - if (err != nil) != tt.wantErr { - t.Errorf("arangoClient.IngestPackage() error = %v, wantErr %v", err, tt.wantErr) - return - } - if tt.idInFilter { - tt.pkgFilter.ID = ptrfrom.String(ingestedPkgIDs.PackageVersionID) - } - got, err := b.(*arangoClient).packagesType(ctx, tt.pkgFilter) - if (err != nil) != tt.wantErr { - t.Errorf("arangoClient.packagesType() error = %v, wantErr %v", err, tt.wantErr) - return - } - if diff := cmp.Diff(tt.want, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func Test_PackagesNamespace(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - tests := []struct { - name string - pkgInput *model.PkgInputSpec - pkgFilter *model.PkgSpec - idInFilter bool - want []*model.Package - wantErr bool - }{{ - name: "tensorflow empty version", - pkgInput: testdata.P1, - pkgFilter: &model.PkgSpec{ - Name: ptrfrom.String("tensorflow"), - }, - idInFilter: false, - want: []*model.Package{{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{{Names: []*model.PackageName{}}}, - }}, - wantErr: false, - }, { - name: "tensorflow empty version, ID search", - pkgInput: testdata.P1, - pkgFilter: &model.PkgSpec{ - Name: ptrfrom.String("tensorflow"), - }, - idInFilter: true, - want: []*model.Package{{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{{Names: []*model.PackageName{}}}, - }}, - wantErr: false, - }, { - name: "tensorflow with version", - pkgInput: testdata.P2, - pkgFilter: &model.PkgSpec{ - Type: ptrfrom.String("pypi"), - Name: ptrfrom.String("tensorflow"), - Version: ptrfrom.String("2.11.1"), - }, - idInFilter: false, - want: []*model.Package{{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{{Names: []*model.PackageName{}}}, - }}, - wantErr: false, - }, { - name: "tensorflow with version and subpath", - pkgInput: testdata.P3, - pkgFilter: &model.PkgSpec{ - Type: ptrfrom.String("pypi"), - Name: ptrfrom.String("tensorflow"), - Subpath: ptrfrom.String("saved_model_cli.py"), - }, - idInFilter: false, - want: []*model.Package{{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{{Names: []*model.PackageName{}}}, - }}, - wantErr: false, - }, { - name: "openssl with version", - pkgInput: testdata.P4, - pkgFilter: &model.PkgSpec{ - Type: ptrfrom.String("conan"), - Name: ptrfrom.String("openssl"), - Namespace: ptrfrom.String("openssl.org"), - Version: ptrfrom.String("3.0.3"), - }, - idInFilter: false, - want: []*model.Package{{ - Type: "conan", - Namespaces: []*model.PackageNamespace{{ - Namespace: "openssl.org", - Names: []*model.PackageName{}, - }}, - }}, - wantErr: false, - }} - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - ingestedPkgIDs, err := b.IngestPackage(ctx, *tt.pkgInput) - if (err != nil) != tt.wantErr { - t.Errorf("arangoClient.IngestPackage() error = %v, wantErr %v", err, tt.wantErr) - return - } - if tt.idInFilter { - tt.pkgFilter.ID = ptrfrom.String(ingestedPkgIDs.PackageVersionID) - } - got, err := b.(*arangoClient).packagesNamespace(ctx, tt.pkgFilter) - if (err != nil) != tt.wantErr { - t.Errorf("arangoClient.packagesNamespace() error = %v, wantErr %v", err, tt.wantErr) - return - } - if diff := cmp.Diff(tt.want, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func Test_PackagesName(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - tests := []struct { - name string - pkgInput *model.PkgInputSpec - pkgFilter *model.PkgSpec - idInFilter bool - want []*model.Package - wantErr bool - }{{ - name: "tensorflow empty version", - pkgInput: testdata.P1, - pkgFilter: &model.PkgSpec{ - Name: ptrfrom.String("tensorflow"), - }, - idInFilter: false, - want: []*model.Package{{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{{ - Names: []*model.PackageName{ - {Name: "tensorflow", Versions: []*model.PackageVersion{}}, - }, - }}, - }}, - wantErr: false, - }, { - name: "tensorflow empty version, ID search", - pkgInput: testdata.P1, - pkgFilter: &model.PkgSpec{ - Name: ptrfrom.String("tensorflow"), - }, - idInFilter: true, - want: []*model.Package{{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{{ - Names: []*model.PackageName{ - {Name: "tensorflow", Versions: []*model.PackageVersion{}}, - }, - }}, - }}, - wantErr: false, - }, { - name: "tensorflow with version", - pkgInput: testdata.P2, - pkgFilter: &model.PkgSpec{ - Type: ptrfrom.String("pypi"), - Name: ptrfrom.String("tensorflow"), - Version: ptrfrom.String("2.11.1"), - }, - idInFilter: false, - want: []*model.Package{{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{{ - Names: []*model.PackageName{ - {Name: "tensorflow", Versions: []*model.PackageVersion{}}, - }, - }}, - }}, - wantErr: false, - }, { - name: "tensorflow with version and subpath", - pkgInput: testdata.P3, - pkgFilter: &model.PkgSpec{ - Type: ptrfrom.String("pypi"), - Name: ptrfrom.String("tensorflow"), - Subpath: ptrfrom.String("saved_model_cli.py"), - }, - idInFilter: false, - want: []*model.Package{{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{{ - Names: []*model.PackageName{ - {Name: "tensorflow", Versions: []*model.PackageVersion{}}, - }, - }}, - }}, - wantErr: false, - }, { - name: "openssl with version", - pkgInput: testdata.P4, - pkgFilter: &model.PkgSpec{ - Type: ptrfrom.String("conan"), - Name: ptrfrom.String("openssl"), - Version: ptrfrom.String("3.0.3"), - }, - idInFilter: false, - want: []*model.Package{{ - Type: "conan", - Namespaces: []*model.PackageNamespace{{ - Namespace: "openssl.org", - Names: []*model.PackageName{ - {Name: "openssl", Versions: []*model.PackageVersion{}}, - }, - }}, - }}, - wantErr: false, - }} - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - ingestedPkgIDs, err := b.IngestPackage(ctx, *tt.pkgInput) - if (err != nil) != tt.wantErr { - t.Errorf("arangoClient.IngestPackage() error = %v, wantErr %v", err, tt.wantErr) - return - } - if tt.idInFilter { - tt.pkgFilter.ID = ptrfrom.String(ingestedPkgIDs.PackageVersionID) - } - got, err := b.(*arangoClient).packagesName(ctx, tt.pkgFilter) - if (err != nil) != tt.wantErr { - t.Errorf("arangoClient.packagesName() error = %v, wantErr %v", err, tt.wantErr) - return - } - slices.SortFunc(got, lessPkg) - if diff := cmp.Diff(tt.want, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func lessPkg(a, b *model.Package) int { - return strings.Compare(a.Namespaces[0].Names[0].Name, - b.Namespaces[0].Names[0].Name) -} - -func Test_IngestPackages(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - tests := []struct { - name string - pkgInputs []*model.PkgInputSpec - wantErr bool - }{{ - name: "tensorflow empty version", - pkgInputs: []*model.PkgInputSpec{testdata.P3, testdata.P4}, - wantErr: false, - }} - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := b.IngestPackages(ctx, tt.pkgInputs) - if (err != nil) != tt.wantErr { - t.Errorf("arangoClient.IngestPackages() error = %v, wantErr %v", err, tt.wantErr) - return - } - if len(got) != len(tt.pkgInputs) { - t.Errorf("Unexpected number of results. Wanted: %d, got %d", len(tt.pkgInputs), len(got)) - } - }) - } -} - -func Test_buildPackageResponseFromID(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - tests := []struct { - name string - pkgInput *model.PkgInputSpec - pkgFilter *model.PkgSpec - idInFilter bool - want *model.Package - wantErr bool - }{{ - name: "tensorflow empty version, ID search", - pkgInput: testdata.P3, - pkgFilter: &model.PkgSpec{ - Name: ptrfrom.String("tensorflow"), - Subpath: ptrfrom.String("saved_model_cli.py"), - }, - idInFilter: true, - want: testdata.P3out, - wantErr: false, - }, { - name: "openssl with match empty qualifiers", - pkgInput: testdata.P4, - pkgFilter: &model.PkgSpec{ - Name: ptrfrom.String("openssl"), - Namespace: ptrfrom.String("openssl.org"), - Version: ptrfrom.String("3.0.3"), - MatchOnlyEmptyQualifiers: ptrfrom.Bool(true), - }, - idInFilter: true, - want: testdata.P4out, - wantErr: false, - }} - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - ingestedPkgIDs, err := b.IngestPackage(ctx, *tt.pkgInput) - if (err != nil) != tt.wantErr { - t.Errorf("arangoClient.IngestPackage() error = %v, wantErr %v", err, tt.wantErr) - return - } - got, err := b.(*arangoClient).buildPackageResponseFromID(ctx, ingestedPkgIDs.PackageVersionID, tt.pkgFilter) - if (err != nil) != tt.wantErr { - t.Errorf("arangoClient.buildPackageResponseFromID() error = %v, wantErr %v", err, tt.wantErr) - return - } - if diff := cmp.Diff(tt.want, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} diff --git a/pkg/assembler/backends/arangodb/pointOfContact.go b/pkg/assembler/backends/arangodb/pointOfContact.go index d98502ef2d..38943d079c 100644 --- a/pkg/assembler/backends/arangodb/pointOfContact.go +++ b/pkg/assembler/backends/arangodb/pointOfContact.go @@ -364,7 +364,7 @@ func (c *arangoClient) IngestPointOfContact(ctx context.Context, subject model.P RETURN { 'pointOfContact_id': pointOfContact._id }` - cursor, err = executeQueryWithRetry(ctx, c.db, query, getPointOfContactQueryValues(subject.Package, pkgMatchType, nil, nil, &pointOfContact), "IngestPointOfContact - PkgVersion") + cursor, err = executeQueryWithRetry(ctx, c.db, query, getPointOfContactQueryValues(subject.Package.PackageInput, pkgMatchType, nil, nil, &pointOfContact), "IngestPointOfContact - PkgVersion") if err != nil { return "", fmt.Errorf("failed to ingest package pointOfContact: %w", err) } @@ -396,7 +396,7 @@ func (c *arangoClient) IngestPointOfContact(ctx context.Context, subject model.P RETURN { 'pointOfContact_id': pointOfContact._id }` - cursor, err = executeQueryWithRetry(ctx, c.db, query, getPointOfContactQueryValues(subject.Package, pkgMatchType, nil, nil, &pointOfContact), "IngestPointOfContact - PkgName") + cursor, err = executeQueryWithRetry(ctx, c.db, query, getPointOfContactQueryValues(subject.Package.PackageInput, pkgMatchType, nil, nil, &pointOfContact), "IngestPointOfContact - PkgName") if err != nil { return "", fmt.Errorf("failed to ingest package pointOfContact: %w", err) } @@ -422,7 +422,7 @@ func (c *arangoClient) IngestPointOfContact(ctx context.Context, subject model.P RETURN { 'pointOfContact_id': pointOfContact._id }` - cursor, err = executeQueryWithRetry(ctx, c.db, query, getPointOfContactQueryValues(nil, nil, subject.Artifact, nil, &pointOfContact), "IngestPointOfContact - artifact") + cursor, err = executeQueryWithRetry(ctx, c.db, query, getPointOfContactQueryValues(nil, nil, subject.Artifact.ArtifactInput, nil, &pointOfContact), "IngestPointOfContact - artifact") if err != nil { return "", fmt.Errorf("failed to ingest artifact pointOfContact: %w", err) } @@ -454,7 +454,7 @@ func (c *arangoClient) IngestPointOfContact(ctx context.Context, subject model.P RETURN { 'pointOfContact_id': pointOfContact._id }` - cursor, err = executeQueryWithRetry(ctx, c.db, query, getPointOfContactQueryValues(nil, nil, nil, subject.Source, &pointOfContact), "IngestPointOfContact - source") + cursor, err = executeQueryWithRetry(ctx, c.db, query, getPointOfContactQueryValues(nil, nil, nil, subject.Source.SourceInput, &pointOfContact), "IngestPointOfContact - source") if err != nil { return "", fmt.Errorf("failed to ingest source pointOfContact: %w", err) } @@ -481,7 +481,7 @@ func (c *arangoClient) IngestPointOfContacts(ctx context.Context, subjects model var listOfValues []map[string]any for i := range subjects.Packages { - listOfValues = append(listOfValues, getPointOfContactQueryValues(subjects.Packages[i], pkgMatchType, nil, nil, pointOfContacts[i])) + listOfValues = append(listOfValues, getPointOfContactQueryValues(subjects.Packages[i].PackageInput, pkgMatchType, nil, nil, pointOfContacts[i])) } var documents []string @@ -580,7 +580,7 @@ func (c *arangoClient) IngestPointOfContacts(ctx context.Context, subjects model var listOfValues []map[string]any for i := range subjects.Artifacts { - listOfValues = append(listOfValues, getPointOfContactQueryValues(nil, nil, subjects.Artifacts[i], nil, pointOfContacts[i])) + listOfValues = append(listOfValues, getPointOfContactQueryValues(nil, nil, subjects.Artifacts[i].ArtifactInput, nil, pointOfContacts[i])) } var documents []string @@ -634,7 +634,7 @@ func (c *arangoClient) IngestPointOfContacts(ctx context.Context, subjects model var listOfValues []map[string]any for i := range subjects.Sources { - listOfValues = append(listOfValues, getPointOfContactQueryValues(nil, nil, nil, subjects.Sources[i], pointOfContacts[i])) + listOfValues = append(listOfValues, getPointOfContactQueryValues(nil, nil, nil, subjects.Sources[i].SourceInput, pointOfContacts[i])) } var documents []string diff --git a/pkg/assembler/backends/arangodb/pointOfContact_test.go b/pkg/assembler/backends/arangodb/pointOfContact_test.go deleted file mode 100644 index ea6a0d0c7a..0000000000 --- a/pkg/assembler/backends/arangodb/pointOfContact_test.go +++ /dev/null @@ -1,1403 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build integration - -package arangodb - -import ( - "context" - "strings" - "testing" - "time" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/internal/testing/testdata" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -func TestPointOfContact(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - type call struct { - Sub model.PackageSourceOrArtifactInput - Match *model.MatchFlags - POC *model.PointOfContactInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - InArt []*model.ArtifactInputSpec - Calls []call - Query *model.PointOfContactSpec - QueryID bool - QueryPkgID bool - QuerySourceID bool - QueryArtID bool - ExpPoc []*model.PointOfContact - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{testdata.P1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - POC: &model.PointOfContactInputSpec{ - Email: "a@b.com", - Info: "info1", - Since: time.Unix(1e9, 0), - Justification: "test justification", - }, - }, - }, - Query: &model.PointOfContactSpec{ - Email: ptrfrom.String("a@b.com"), - Info: ptrfrom.String("info1"), - Since: ptrfrom.Time(time.Unix(1e9, 0)), - Justification: ptrfrom.String("test justification"), - }, - ExpPoc: []*model.PointOfContact{ - { - Subject: testdata.P1out, - Email: "a@b.com", - Info: "info1", - Since: time.Unix(1e9, 0), - Justification: "test justification", - }, - }, - }, - { - Name: "HappyPath check time since", - InPkg: []*model.PkgInputSpec{testdata.P1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - POC: &model.PointOfContactInputSpec{ - Email: "a@b.com", - Info: "info1", - Since: time.Unix(1e9, 0), - Justification: "test justification", - }, - }, - }, - Query: &model.PointOfContactSpec{ - Email: ptrfrom.String("a@b.com"), - Info: ptrfrom.String("info1"), - Since: ptrfrom.Time(time.Unix(1e8, 0)), - Justification: ptrfrom.String("test justification"), - }, - ExpPoc: []*model.PointOfContact{ - { - Subject: testdata.P1out, - Email: "a@b.com", - Info: "info1", - Since: time.Unix(1e9, 0), - Justification: "test justification", - }, - }, - }, - { - Name: "UnhappyPath check time since", - InPkg: []*model.PkgInputSpec{testdata.P1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - POC: &model.PointOfContactInputSpec{ - Email: "a@b.com", - Info: "info1", - Since: time.Unix(1e9, 0), - Justification: "test justification", - }, - }, - }, - Query: &model.PointOfContactSpec{ - Email: ptrfrom.String("a@b.com"), - Info: ptrfrom.String("info1"), - Since: ptrfrom.Time(time.Unix(1e10, 0)), - Justification: ptrfrom.String("test justification"), - }, - ExpPoc: nil, - }, - { - Name: "HappyPath All Version", - InPkg: []*model.PkgInputSpec{testdata.P1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - POC: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.PointOfContactSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpPoc: []*model.PointOfContact{ - { - Subject: testdata.P1out, - Email: "a@b.com", - Info: "info1", - Since: time.Unix(1e9, 0), - Justification: "test justification", - }, - { - Subject: testdata.P1outName, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest same twice", - InPkg: []*model.PkgInputSpec{testdata.P3}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P3, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - POC: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P3, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - POC: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.PointOfContactSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String("2.11.1"), - Subpath: ptrfrom.String("saved_model_cli.py"), - }, - }, - }, - ExpPoc: []*model.PointOfContact{ - { - Subject: testdata.P3out, - Justification: "test justification", - }, - { - Subject: testdata.P1outName, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest two different emails - query email", - InPkg: []*model.PkgInputSpec{testdata.P1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - POC: &model.PointOfContactInputSpec{ - Email: "a@b.com", - Info: "info1", - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - POC: &model.PointOfContactInputSpec{ - Email: "x@y.com", - Info: "info2", - Justification: "test justification", - }, - }, - }, - Query: &model.PointOfContactSpec{ - Email: ptrfrom.String("x@y.com"), - }, - ExpPoc: []*model.PointOfContact{ - { - Subject: testdata.P1out, - Email: "x@y.com", - Info: "info2", - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest two different infos - query info", - InPkg: []*model.PkgInputSpec{testdata.P1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - POC: &model.PointOfContactInputSpec{ - Email: "a@b.com", - Info: "info1", - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - POC: &model.PointOfContactInputSpec{ - Email: "x@y.com", - Info: "info2", - Justification: "test justification", - }, - }, - }, - Query: &model.PointOfContactSpec{ - Info: ptrfrom.String("info1"), - }, - ExpPoc: []*model.PointOfContact{ - { - Subject: testdata.P1out, - Email: "a@b.com", - Info: "info1", - Since: time.Unix(1e9, 0), - Justification: "test justification", - }, - { - Subject: testdata.P1out, - Email: "a@b.com", - Info: "info1", - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Justification", - InPkg: []*model.PkgInputSpec{testdata.P1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - POC: &model.PointOfContactInputSpec{ - Justification: "test justification one", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - POC: &model.PointOfContactInputSpec{ - Justification: "test justification two", - }, - }, - }, - Query: &model.PointOfContactSpec{ - Justification: ptrfrom.String("test justification one"), - }, - ExpPoc: []*model.PointOfContact{ - { - Subject: testdata.P1out, - Justification: "test justification one", - }, - }, - }, - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P4}, - InSrc: []*model.SourceInputSpec{testdata.S1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - POC: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P4, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - POC: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, - }, - POC: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.PointOfContactSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Package: &model.PkgSpec{ - Type: ptrfrom.String("conan"), - Namespace: ptrfrom.String("openssl.org"), - Name: ptrfrom.String("openssl"), - }, - }, - }, - ExpPoc: []*model.PointOfContact{ - { - Subject: testdata.P4out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Package version ID", - InPkg: []*model.PkgInputSpec{testdata.P4}, - InSrc: []*model.SourceInputSpec{}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P4, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - POC: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - }, - QueryPkgID: true, - ExpPoc: []*model.PointOfContact{ - { - Subject: testdata.P4out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Source", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InSrc: []*model.SourceInputSpec{testdata.S1, testdata.S2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - POC: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, - }, - POC: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S2, - }, - POC: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.PointOfContactSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Source: &model.SourceSpec{ - Name: ptrfrom.String("bobsrepo"), - }, - }, - }, - ExpPoc: []*model.PointOfContact{ - { - Subject: testdata.S2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Source ID", - InPkg: []*model.PkgInputSpec{}, - InSrc: []*model.SourceInputSpec{testdata.S2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S2, - }, - POC: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - }, - QuerySourceID: true, - ExpPoc: []*model.PointOfContact{ - { - Subject: testdata.S2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Artifact", - InSrc: []*model.SourceInputSpec{testdata.S1}, - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A1, - }, - POC: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, - }, - POC: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, - }, - POC: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.PointOfContactSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha1"), - }, - }, - }, - ExpPoc: []*model.PointOfContact{ - { - Subject: testdata.A2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Artifact ID", - InSrc: []*model.SourceInputSpec{}, - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A1, - }, - POC: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, - }, - POC: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - }, - QueryArtID: true, - ExpPoc: []*model.PointOfContact{ - { - Subject: testdata.A2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query none", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A1, - }, - POC: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, - }, - POC: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.PointOfContactSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("asdf"), - }, - }, - }, - ExpPoc: nil, - }, - { - Name: "Query multiple", - InSrc: []*model.SourceInputSpec{testdata.S1, testdata.S2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, - }, - POC: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S2, - }, - POC: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.PointOfContactSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Source: &model.SourceSpec{ - Type: ptrfrom.String("git"), - }, - }}, - ExpPoc: []*model.PointOfContact{ - { - Subject: testdata.S2out, - Justification: "test justification", - }, - { - Subject: testdata.S1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query Packages", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2, testdata.P4}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - POC: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - POC: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - POC: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P4, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - POC: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.PointOfContactSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Package: &model.PkgSpec{ - Name: ptrfrom.String("openssl"), - Version: ptrfrom.String("3.0.3"), - }, - }, - }, - ExpPoc: []*model.PointOfContact{ - { - Subject: testdata.P4out, - Justification: "test justification", - }, - { - Subject: testdata.P4outName, - Justification: "test justification", - }, - }, - }, - { - Name: "Query ID", - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A1, - }, - POC: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, - }, - POC: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - }, - QueryID: true, - ExpPoc: []*model.PointOfContact{ - { - Subject: testdata.A2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query bad ID", - InSrc: []*model.SourceInputSpec{testdata.S1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, - }, - POC: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.PointOfContactSpec{ - ID: ptrfrom.String("asdf"), - }, - ExpQueryErr: true, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - for _, p := range test.InPkg { - if pkgIDs, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } else { - if test.QueryPkgID { - test.Query = &model.PointOfContactSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Package: &model.PkgSpec{ - ID: ptrfrom.String(pkgIDs.PackageVersionID), - }, - }, - } - } - } - } - for _, s := range test.InSrc { - if srcIDs, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } else { - if test.QuerySourceID { - test.Query = &model.PointOfContactSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Source: &model.SourceSpec{ - ID: ptrfrom.String(srcIDs.SourceNameID), - }, - }, - } - } - } - } - for _, a := range test.InArt { - if artID, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } else { - if test.QueryArtID { - test.Query = &model.PointOfContactSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - ID: ptrfrom.String(artID), - }, - }, - } - } - } - } - for _, o := range test.Calls { - pcID, err := b.IngestPointOfContact(ctx, o.Sub, o.Match, *o.POC) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - if test.QueryID { - test.Query = &model.PointOfContactSpec{ - ID: ptrfrom.String(pcID), - } - } - } - got, err := b.PointOfContact(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpPoc, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func TestIngestPointOfContacts(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - type call struct { - Sub model.PackageSourceOrArtifactInputs - Match *model.MatchFlags - PC []*model.PointOfContactInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - InArt []*model.ArtifactInputSpec - Calls []call - Query *model.PointOfContactSpec - ExpPC []*model.PointOfContact - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{testdata.P1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - PC: []*model.PointOfContactInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.PointOfContactSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpPC: []*model.PointOfContact{ - { - Subject: testdata.P1out, - Justification: "test justification", - }, - }, - }, - { - Name: "HappyPath All Version", - InPkg: []*model.PkgInputSpec{testdata.P1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - PC: []*model.PointOfContactInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.PointOfContactSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpPC: []*model.PointOfContact{ - { - Subject: testdata.P1out, - Justification: "test justification", - }, - { - Subject: testdata.P1outName, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest same twice", - InPkg: []*model.PkgInputSpec{testdata.P3}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P3, testdata.P3}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - PC: []*model.PointOfContactInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.PointOfContactSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String("2.11.1"), - Subpath: ptrfrom.String("saved_model_cli.py"), - }, - }, - }, - ExpPC: []*model.PointOfContact{ - { - Subject: testdata.P3out, - Justification: "test justification", - }, - { - Subject: testdata.P1outName, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P4}, - InSrc: []*model.SourceInputSpec{testdata.S1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1, testdata.P4}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - PC: []*model.PointOfContactInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - { - Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{testdata.S1}, - }, - PC: []*model.PointOfContactInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.PointOfContactSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Package: &model.PkgSpec{ - Type: ptrfrom.String("conan"), - Namespace: ptrfrom.String("openssl.org"), - Name: ptrfrom.String("openssl"), - }, - }, - }, - ExpPC: []*model.PointOfContact{ - { - Subject: testdata.P4out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Source", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InSrc: []*model.SourceInputSpec{testdata.S1, testdata.S2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - PC: []*model.PointOfContactInputSpec{ - { - Justification: "test justification", - }, - }, - }, - { - Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{testdata.S2, testdata.S2}, - }, - PC: []*model.PointOfContactInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.PointOfContactSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Source: &model.SourceSpec{ - Name: ptrfrom.String("bobsrepo"), - }, - }, - }, - ExpPC: []*model.PointOfContact{ - { - Subject: testdata.S2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Artifact", - InSrc: []*model.SourceInputSpec{testdata.S1}, - InArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Artifacts: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - }, - PC: []*model.PointOfContactInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - { - Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{testdata.S1}, - }, - PC: []*model.PointOfContactInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.PointOfContactSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha1"), - }, - }, - }, - ExpPC: []*model.PointOfContact{ - { - Subject: testdata.A2out, - Justification: "test justification", - }, - }, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - for _, o := range test.Calls { - _, err := b.IngestPointOfContacts(ctx, o.Sub, o.Match, o.PC) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.PointOfContact(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpPC, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func Test_buildPointOfContactByID(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - type call struct { - Sub model.PackageSourceOrArtifactInput - Match *model.MatchFlags - POC *model.PointOfContactInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - InArt []*model.ArtifactInputSpec - Calls []call - Query *model.PointOfContactSpec - ExpPoc *model.PointOfContact - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{testdata.P4}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P4, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - POC: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.PointOfContactSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Package: &model.PkgSpec{ - Type: ptrfrom.String("conan"), - Namespace: ptrfrom.String("openssl.org"), - Name: ptrfrom.String("openssl"), - }, - }, - }, - ExpPoc: &model.PointOfContact{ - Subject: testdata.P4out, - Justification: "test justification", - }, - }, - { - Name: "Query on Package version ID", - InPkg: []*model.PkgInputSpec{testdata.P4}, - InSrc: []*model.SourceInputSpec{}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P4, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - POC: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - }, - ExpPoc: &model.PointOfContact{ - Subject: testdata.P4out, - Justification: "test justification", - }, - }, - { - Name: "Query on Source", - InSrc: []*model.SourceInputSpec{testdata.S2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S2, - }, - POC: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.PointOfContactSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Source: &model.SourceSpec{ - Name: ptrfrom.String("bobsrepo"), - }, - }, - }, - ExpPoc: &model.PointOfContact{ - Subject: testdata.S2out, - Justification: "test justification", - }, - }, - { - Name: "Query on Source ID", - InPkg: []*model.PkgInputSpec{}, - InSrc: []*model.SourceInputSpec{testdata.S2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S2, - }, - POC: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - }, - ExpPoc: &model.PointOfContact{ - Subject: testdata.S2out, - Justification: "test justification", - }, - }, - { - Name: "Query on Artifact", - InArt: []*model.ArtifactInputSpec{testdata.A2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, - }, - POC: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.PointOfContactSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha1"), - }, - }, - }, - ExpPoc: &model.PointOfContact{ - Subject: testdata.A2out, - Justification: "test justification", - }, - }, - { - Name: "Query on Artifact ID", - InArt: []*model.ArtifactInputSpec{testdata.A2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, - }, - POC: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - }, - ExpPoc: &model.PointOfContact{ - Subject: testdata.A2out, - Justification: "test justification", - }, - }, - { - Name: "Query ID", - InArt: []*model.ArtifactInputSpec{testdata.A2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, - }, - POC: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - }, - ExpPoc: &model.PointOfContact{ - Subject: testdata.A2out, - Justification: "test justification", - }, - }, - { - Name: "Query bad ID", - InSrc: []*model.SourceInputSpec{testdata.S1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, - }, - POC: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.PointOfContactSpec{ - ID: ptrfrom.String("asdf"), - }, - ExpQueryErr: true, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - for _, o := range test.Calls { - pcID, err := b.IngestPointOfContact(ctx, o.Sub, o.Match, *o.POC) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - got, err := b.(*arangoClient).buildPointOfContactByID(ctx, pcID, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpPoc, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - } - }) - } -} diff --git a/pkg/assembler/backends/arangodb/search_test.go b/pkg/assembler/backends/arangodb/search_test.go deleted file mode 100644 index b253b18cd9..0000000000 --- a/pkg/assembler/backends/arangodb/search_test.go +++ /dev/null @@ -1,73 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build integration - -package arangodb - -import ( - "context" - "strings" - "testing" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -// TODO (pxp928): eventual consistency for search does not allow for the unit test to work - -func Test_arangoClient_FindSoftware(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - tests := []struct { - name string - search string - pkgInput model.PkgInputSpec - srcInput model.SourceInputSpec - artInput model.ArtifactInputSpec - wantPkgSrcArt []model.PackageSourceOrArtifact - wantErr bool - }{{ - // TODO add tests - }} - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - _, err := b.IngestPackage(ctx, tt.pkgInput) - if (err != nil) != tt.wantErr { - t.Errorf("arangoClient.IngestPackage() error = %v, wantErr %v", err, tt.wantErr) - return - } - got, err := b.FindSoftware(ctx, tt.search) - if (err != nil) != tt.wantErr { - t.Errorf("arangoClient.FindSoftware() error = %v, wantErr %v", err, tt.wantErr) - return - } - if diff := cmp.Diff(tt.wantPkgSrcArt, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} diff --git a/pkg/assembler/backends/arangodb/src.go b/pkg/assembler/backends/arangodb/src.go index 68d85fd9f7..6f9a43a435 100644 --- a/pkg/assembler/backends/arangodb/src.go +++ b/pkg/assembler/backends/arangodb/src.go @@ -116,11 +116,11 @@ func getSourceQueryValues(source *model.SourceInputSpec) map[string]any { return values } -func (c *arangoClient) IngestSources(ctx context.Context, sources []*model.SourceInputSpec) ([]*model.SourceIDs, error) { +func (c *arangoClient) IngestSources(ctx context.Context, sources []*model.IDorSourceInput) ([]*model.SourceIDs, error) { var listOfValues []map[string]any for i := range sources { - listOfValues = append(listOfValues, getSourceQueryValues(sources[i])) + listOfValues = append(listOfValues, getSourceQueryValues(sources[i].SourceInput)) } var documents []string @@ -194,7 +194,7 @@ func (c *arangoClient) IngestSources(ctx context.Context, sources []*model.Sourc return getSourceIDs(ctx, cursor) } -func (c *arangoClient) IngestSource(ctx context.Context, source model.SourceInputSpec) (*model.SourceIDs, error) { +func (c *arangoClient) IngestSource(ctx context.Context, source model.IDorSourceInput) (*model.SourceIDs, error) { query := ` LET type = FIRST( UPSERT { type: @srcType } @@ -234,7 +234,7 @@ func (c *arangoClient) IngestSource(ctx context.Context, source model.SourceInpu "name_id": name._id }` - cursor, err := executeQueryWithRetry(ctx, c.db, query, getSourceQueryValues(&source), "IngestSource") + cursor, err := executeQueryWithRetry(ctx, c.db, query, getSourceQueryValues(source.SourceInput), "IngestSource") if err != nil { return nil, fmt.Errorf("failed to ingest source: %w", err) } diff --git a/pkg/assembler/backends/arangodb/src_test.go b/pkg/assembler/backends/arangodb/src_test.go deleted file mode 100644 index 2f61b980f7..0000000000 --- a/pkg/assembler/backends/arangodb/src_test.go +++ /dev/null @@ -1,447 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build integration - -package arangodb - -import ( - "context" - "slices" - "strings" - "testing" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/internal/testing/testdata" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -func lessSource(a, b *model.Source) int { - return strings.Compare(a.Namespaces[0].Namespace, - b.Namespaces[0].Namespace) -} - -func Test_IngestSources(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - tests := []struct { - name string - srcInputs []*model.SourceInputSpec - wantErr bool - }{{ - name: "test batch source ingestion", - srcInputs: []*model.SourceInputSpec{testdata.S3, testdata.S4}, - wantErr: false, - }} - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := b.IngestSources(ctx, tt.srcInputs) - if (err != nil) != tt.wantErr { - t.Errorf("arangoClient.IngestSources() error = %v, wantErr %v", err, tt.wantErr) - return - } - if len(got) != len(tt.srcInputs) { - t.Errorf("Unexpected number of results. Wanted: %d, got %d", len(tt.srcInputs), len(got)) - } - }) - } -} - -func Test_Sources(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - tests := []struct { - name string - srcInput *model.SourceInputSpec - srcFilter *model.SourceSpec - idInFilter bool - want []*model.Source - wantErr bool - }{{ - name: "myrepo with tag", - srcInput: testdata.S1, - srcFilter: &model.SourceSpec{ - Name: ptrfrom.String("myrepo"), - }, - idInFilter: false, - want: []*model.Source{testdata.S1out}, - wantErr: false, - }, { - name: "myrepo with tag, ID search", - srcInput: testdata.S1, - srcFilter: &model.SourceSpec{ - Name: ptrfrom.String("myrepo"), - }, - idInFilter: true, - want: []*model.Source{testdata.S1out}, - wantErr: false, - }, { - name: "bobsrepo with commit", - srcInput: testdata.S4, - srcFilter: &model.SourceSpec{ - Namespace: ptrfrom.String("github.com/bob"), - Commit: ptrfrom.String("5e7c41f"), - }, - idInFilter: false, - want: []*model.Source{testdata.S4out}, - wantErr: false, - }, { - name: "bobsrepo with commit, type search", - srcInput: testdata.S4, - srcFilter: &model.SourceSpec{ - Type: ptrfrom.String("svn"), - Namespace: ptrfrom.String("github.com/bob"), - Commit: ptrfrom.String("5e7c41f"), - }, - idInFilter: false, - want: []*model.Source{testdata.S4out}, - wantErr: false, - }} - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - ingestedSrcIDs, err := b.IngestSource(ctx, *tt.srcInput) - if (err != nil) != tt.wantErr { - t.Errorf("arangoClient.IngestSource() error = %v, wantErr %v", err, tt.wantErr) - return - } - if tt.idInFilter { - tt.srcFilter.ID = ptrfrom.String(ingestedSrcIDs.SourceNameID) - } - got, err := b.Sources(ctx, tt.srcFilter) - if (err != nil) != tt.wantErr { - t.Errorf("arangoClient.Sources() error = %v, wantErr %v", err, tt.wantErr) - return - } - slices.SortFunc(got, lessSource) - if diff := cmp.Diff(tt.want, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func Test_SourceTypes(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - tests := []struct { - name string - srcInput *model.SourceInputSpec - srcFilter *model.SourceSpec - idInFilter bool - want []*model.Source - wantErr bool - }{{ - name: "myrepo with tag", - srcInput: testdata.S1, - srcFilter: &model.SourceSpec{ - Name: ptrfrom.String("myrepo"), - }, - idInFilter: false, - want: []*model.Source{{ - Type: "git", - Namespaces: []*model.SourceNamespace{}, - }}, - wantErr: false, - }, { - name: "myrepo with tag, ID search", - srcInput: testdata.S1, - srcFilter: &model.SourceSpec{ - Name: ptrfrom.String("myrepo"), - }, - idInFilter: true, - want: []*model.Source{{ - Type: "git", - Namespaces: []*model.SourceNamespace{}, - }}, - wantErr: false, - }, { - name: "bobsrepo with commit", - srcInput: testdata.S4, - srcFilter: &model.SourceSpec{ - Namespace: ptrfrom.String("github.com/bob"), - Commit: ptrfrom.String("5e7c41f"), - }, - idInFilter: false, - want: []*model.Source{ - { - Type: "git", - Namespaces: []*model.SourceNamespace{}, - }, { - Type: "svn", - Namespaces: []*model.SourceNamespace{}, - }, - }, - wantErr: false, - }, { - name: "bobsrepo with commit, type search", - srcInput: testdata.S4, - srcFilter: &model.SourceSpec{ - Type: ptrfrom.String("svn"), - Namespace: ptrfrom.String("github.com/bob"), - Commit: ptrfrom.String("5e7c41f"), - }, - idInFilter: false, - want: []*model.Source{{ - Type: "svn", - Namespaces: []*model.SourceNamespace{}, - }}, - wantErr: false, - }} - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - ingestedSrcIDs, err := b.IngestSource(ctx, *tt.srcInput) - if (err != nil) != tt.wantErr { - t.Errorf("arangoClient.IngestSource() error = %v, wantErr %v", err, tt.wantErr) - return - } - if tt.idInFilter { - tt.srcFilter.ID = ptrfrom.String(ingestedSrcIDs.SourceNameID) - } - got, err := b.(*arangoClient).sourcesType(ctx, tt.srcFilter) - if (err != nil) != tt.wantErr { - t.Errorf("arangoClient.Sources() error = %v, wantErr %v", err, tt.wantErr) - return - } - if diff := cmp.Diff(tt.want, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func Test_SourceNamespaces(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - tests := []struct { - name string - srcInput *model.SourceInputSpec - srcFilter *model.SourceSpec - idInFilter bool - want []*model.Source - wantErr bool - }{{ - name: "myrepo with tag", - srcInput: testdata.S1, - srcFilter: &model.SourceSpec{ - Name: ptrfrom.String("myrepo"), - }, - idInFilter: false, - want: []*model.Source{{ - Type: "git", - Namespaces: []*model.SourceNamespace{{ - ID: "srcNamespaces/323102", - Namespace: "github.com/jeff", - Names: []*model.SourceName{}, - }}, - }}, - wantErr: false, - }, { - name: "myrepo with tag, ID search", - srcInput: testdata.S1, - srcFilter: &model.SourceSpec{ - Name: ptrfrom.String("myrepo"), - }, - idInFilter: true, - want: []*model.Source{{ - Type: "git", - Namespaces: []*model.SourceNamespace{{ - Namespace: "github.com/jeff", - Names: []*model.SourceName{}, - }}, - }}, - wantErr: false, - }, { - name: "bobsrepo with commit", - srcInput: testdata.S4, - srcFilter: &model.SourceSpec{ - Namespace: ptrfrom.String("github.com/bob"), - Commit: ptrfrom.String("5e7c41f"), - }, - idInFilter: false, - want: []*model.Source{ - { - Type: "svn", - Namespaces: []*model.SourceNamespace{{ - Namespace: "github.com/bob", - Names: []*model.SourceName{}, - }}, - }, - }, - wantErr: false, - }, { - name: "bobsrepo with commit, type search", - srcInput: testdata.S4, - srcFilter: &model.SourceSpec{ - Type: ptrfrom.String("svn"), - Namespace: ptrfrom.String("github.com/bob"), - Commit: ptrfrom.String("5e7c41f"), - }, - idInFilter: false, - want: []*model.Source{{ - Type: "svn", - Namespaces: []*model.SourceNamespace{{ - Namespace: "github.com/bob", - Names: []*model.SourceName{}, - }}, - }}, - wantErr: false, - }} - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - ingestedSrcIDs, err := b.IngestSource(ctx, *tt.srcInput) - if (err != nil) != tt.wantErr { - t.Errorf("arangoClient.IngestSource() error = %v, wantErr %v", err, tt.wantErr) - return - } - if tt.idInFilter { - tt.srcFilter.ID = ptrfrom.String(ingestedSrcIDs.SourceNameID) - } - got, err := b.(*arangoClient).sourcesNamespace(ctx, tt.srcFilter) - if (err != nil) != tt.wantErr { - t.Errorf("arangoClient.Sources() error = %v, wantErr %v", err, tt.wantErr) - return - } - slices.SortFunc(got, lessSource) - if diff := cmp.Diff(tt.want, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func Test_buildSourceResponseFromID(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - tests := []struct { - name string - srcInput *model.SourceInputSpec - srcFilter *model.SourceSpec - idInFilter bool - want *model.Source - wantErr bool - }{{ - name: "myrepo with tag", - srcInput: testdata.S1, - srcFilter: &model.SourceSpec{ - Name: ptrfrom.String("myrepo"), - }, - idInFilter: false, - want: testdata.S1out, - wantErr: false, - }, { - name: "myrepo with tag, ID search", - srcInput: testdata.S1, - srcFilter: &model.SourceSpec{ - Name: ptrfrom.String("myrepo"), - }, - idInFilter: true, - want: testdata.S1out, - wantErr: false, - }, { - name: "bobsrepo with commit", - srcInput: testdata.S4, - srcFilter: &model.SourceSpec{ - Namespace: ptrfrom.String("github.com/bob"), - Commit: ptrfrom.String("5e7c41f"), - }, - idInFilter: false, - want: testdata.S4out, - wantErr: false, - }, { - name: "bobsrepo with commit, type search", - srcInput: testdata.S4, - srcFilter: &model.SourceSpec{ - Type: ptrfrom.String("svn"), - Namespace: ptrfrom.String("github.com/bob"), - Commit: ptrfrom.String("5e7c41f"), - }, - idInFilter: false, - want: testdata.S4out, - wantErr: false, - }} - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - ingestedSrcIDs, err := b.IngestSource(ctx, *tt.srcInput) - if (err != nil) != tt.wantErr { - t.Errorf("arangoClient.IngestSource() error = %v, wantErr %v", err, tt.wantErr) - return - } - if tt.idInFilter { - tt.srcFilter.ID = ptrfrom.String(ingestedSrcIDs.SourceNameID) - } - got, err := b.(*arangoClient).buildSourceResponseFromID(ctx, ingestedSrcIDs.SourceNameID, tt.srcFilter) - if (err != nil) != tt.wantErr { - t.Errorf("arangoClient.buildSourceResponseFromID() error = %v, wantErr %v", err, tt.wantErr) - return - } - if diff := cmp.Diff(tt.want, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} diff --git a/pkg/assembler/backends/arangodb/vulnEqual.go b/pkg/assembler/backends/arangodb/vulnEqual.go index 80665ed958..a5819845be 100644 --- a/pkg/assembler/backends/arangodb/vulnEqual.go +++ b/pkg/assembler/backends/arangodb/vulnEqual.go @@ -205,11 +205,11 @@ func getVulnEqualQueryValues(vulnerability *model.VulnerabilityInputSpec, otherV } // Ingest IngestVulnEqual -func (c *arangoClient) IngestVulnEquals(ctx context.Context, vulnerabilities []*model.VulnerabilityInputSpec, otherVulnerabilities []*model.VulnerabilityInputSpec, vulnEquals []*model.VulnEqualInputSpec) ([]string, error) { +func (c *arangoClient) IngestVulnEquals(ctx context.Context, vulnerabilities []*model.IDorVulnerabilityInput, otherVulnerabilities []*model.IDorVulnerabilityInput, vulnEquals []*model.VulnEqualInputSpec) ([]string, error) { var listOfValues []map[string]any for i := range vulnEquals { - listOfValues = append(listOfValues, getVulnEqualQueryValues(vulnerabilities[i], otherVulnerabilities[i], vulnEquals[i])) + listOfValues = append(listOfValues, getVulnEqualQueryValues(vulnerabilities[i].VulnerabilityInput, otherVulnerabilities[i].VulnerabilityInput, vulnEquals[i])) } var documents []string @@ -289,7 +289,7 @@ func (c *arangoClient) IngestVulnEquals(ctx context.Context, vulnerabilities []* return vulnEqualIDList, nil } -func (c *arangoClient) IngestVulnEqual(ctx context.Context, vulnerability model.VulnerabilityInputSpec, otherVulnerability model.VulnerabilityInputSpec, vulnEqual model.VulnEqualInputSpec) (string, error) { +func (c *arangoClient) IngestVulnEqual(ctx context.Context, vulnerability model.IDorVulnerabilityInput, otherVulnerability model.IDorVulnerabilityInput, vulnEqual model.VulnEqualInputSpec) (string, error) { query := ` LET firstVuln = FIRST( FOR vVulnID in vulnerabilities @@ -324,7 +324,7 @@ func (c *arangoClient) IngestVulnEqual(ctx context.Context, vulnerability model. RETURN { 'vulnEqual_id': vulnEqual._id }` - cursor, err := executeQueryWithRetry(ctx, c.db, query, getVulnEqualQueryValues(&vulnerability, &otherVulnerability, &vulnEqual), "IngestVulnEqual") + cursor, err := executeQueryWithRetry(ctx, c.db, query, getVulnEqualQueryValues(vulnerability.VulnerabilityInput, otherVulnerability.VulnerabilityInput, &vulnEqual), "IngestVulnEqual") if err != nil { return "", fmt.Errorf("failed to ingest vulnEqual: %w", err) } diff --git a/pkg/assembler/backends/arangodb/vulnEqual_test.go b/pkg/assembler/backends/arangodb/vulnEqual_test.go deleted file mode 100644 index 3ad804893b..0000000000 --- a/pkg/assembler/backends/arangodb/vulnEqual_test.go +++ /dev/null @@ -1,983 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build integration - -package arangodb - -import ( - "context" - "strings" - "testing" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/internal/testing/testdata" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -func TestVulnEqual(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - type call struct { - Vuln *model.VulnerabilityInputSpec - OtherVuln *model.VulnerabilityInputSpec - In *model.VulnEqualInputSpec - } - tests := []struct { - Name string - InVuln []*model.VulnerabilityInputSpec - Calls []call - Query *model.VulnEqualSpec - QueryID bool - QueryVulnID bool - ExpVulnEqual []*model.VulnEqual - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InVuln: []*model.VulnerabilityInputSpec{testdata.O1, testdata.C1}, - Calls: []call{ - { - Vuln: testdata.O1, - OtherVuln: testdata.C1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.VulnEqualSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpVulnEqual: []*model.VulnEqual{ - { - Vulnerabilities: []*model.Vulnerability{ - { - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - { - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C1out}, - }, - }, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest same twice", - InVuln: []*model.VulnerabilityInputSpec{testdata.O1, testdata.C1}, - Calls: []call{ - { - Vuln: testdata.O1, - OtherVuln: testdata.C1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - { - Vuln: testdata.O1, - OtherVuln: testdata.C1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.VulnEqualSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpVulnEqual: []*model.VulnEqual{ - { - Vulnerabilities: []*model.Vulnerability{ - { - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - { - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C1out}, - }, - }, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Justification", - InVuln: []*model.VulnerabilityInputSpec{testdata.O1, testdata.C1}, - Calls: []call{ - { - Vuln: testdata.O1, - OtherVuln: testdata.C1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - { - Vuln: testdata.O1, - OtherVuln: testdata.C1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.VulnEqualSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpVulnEqual: []*model.VulnEqual{ - { - Vulnerabilities: []*model.Vulnerability{ - { - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - { - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C1out}, - }, - }, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on OSV", - InVuln: []*model.VulnerabilityInputSpec{testdata.O1, testdata.O2, testdata.C1}, - Calls: []call{ - { - Vuln: testdata.O1, - OtherVuln: testdata.C1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - { - Vuln: testdata.O2, - OtherVuln: testdata.C1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.VulnEqualSpec{ - Vulnerabilities: []*model.VulnerabilitySpec{ - { - VulnerabilityID: ptrfrom.String("CVE-2022-26499"), - }, - }, - }, - ExpVulnEqual: []*model.VulnEqual{ - { - Vulnerabilities: []*model.Vulnerability{ - { - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O2out}, - }, - { - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C1out}, - }, - }, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on vulnerability IDs", - InVuln: []*model.VulnerabilityInputSpec{testdata.O1, testdata.O2, testdata.C1}, - Calls: []call{ - { - Vuln: testdata.O1, - OtherVuln: testdata.C1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - { - Vuln: testdata.O2, - OtherVuln: testdata.C1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - QueryVulnID: true, - ExpVulnEqual: []*model.VulnEqual{ - { - Vulnerabilities: []*model.Vulnerability{ - { - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O2out}, - }, - { - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C1out}, - }, - }, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on OSV and other vulnerability ID", - InVuln: []*model.VulnerabilityInputSpec{testdata.O1, testdata.O2, testdata.C1}, - Calls: []call{ - { - Vuln: testdata.O1, - OtherVuln: testdata.C1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - { - Vuln: testdata.O2, - OtherVuln: testdata.C1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.VulnEqualSpec{ - Vulnerabilities: []*model.VulnerabilitySpec{ - { - VulnerabilityID: ptrfrom.String("CVE-2022-26499"), - }, - { - VulnerabilityID: ptrfrom.String("CVE-2019-13110"), - }, - }, - }, - ExpVulnEqual: []*model.VulnEqual{ - { - Vulnerabilities: []*model.Vulnerability{ - { - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O2out}, - }, - { - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C1out}, - }, - }, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on OSV and other vulnerability ID", - InVuln: []*model.VulnerabilityInputSpec{testdata.O1, testdata.O2, testdata.C1}, - Calls: []call{ - { - Vuln: testdata.O1, - OtherVuln: testdata.C1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - { - Vuln: testdata.O2, - OtherVuln: testdata.C1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.VulnEqualSpec{ - Vulnerabilities: []*model.VulnerabilitySpec{ - { - VulnerabilityID: ptrfrom.String("CVE-2022-26499"), - }, - { - Type: ptrfrom.String("cve"), - VulnerabilityID: ptrfrom.String("CVE-2019-13110"), - }, - }, - }, - ExpVulnEqual: []*model.VulnEqual{ - { - Vulnerabilities: []*model.Vulnerability{ - { - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O2out}, - }, - { - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C1out}, - }, - }, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on OSV and novuln (return nothing as not valid)", - InVuln: []*model.VulnerabilityInputSpec{testdata.O1, testdata.O2, testdata.C1}, - Calls: []call{ - { - Vuln: testdata.O1, - OtherVuln: testdata.C1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - { - Vuln: testdata.O2, - OtherVuln: testdata.C1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.VulnEqualSpec{ - Vulnerabilities: []*model.VulnerabilitySpec{ - { - VulnerabilityID: ptrfrom.String("CVE-2022-26499"), - }, - { - NoVuln: ptrfrom.Bool(true), - }, - }, - }, - ExpVulnEqual: nil, - }, - { - Name: "Query on GHSA", - InVuln: []*model.VulnerabilityInputSpec{testdata.O1, testdata.C1, testdata.C2, testdata.G1}, - Calls: []call{ - { - Vuln: testdata.O1, - OtherVuln: testdata.C1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - { - Vuln: testdata.O1, - OtherVuln: testdata.C2, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - { - Vuln: testdata.O1, - OtherVuln: testdata.G1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.VulnEqualSpec{ - Vulnerabilities: []*model.VulnerabilitySpec{ - { - Type: ptrfrom.String("ghsa"), - }, - }, - }, - ExpVulnEqual: []*model.VulnEqual{ - { - Vulnerabilities: []*model.Vulnerability{ - { - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - { - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - }, - Justification: "test justification", - }, - }, - }, - { - Name: "Query none", - InVuln: []*model.VulnerabilityInputSpec{testdata.O1, testdata.C1, testdata.C2, testdata.G1}, - Calls: []call{ - { - Vuln: testdata.O1, - OtherVuln: testdata.C1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - { - Vuln: testdata.O1, - OtherVuln: testdata.C2, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - { - Vuln: testdata.O1, - OtherVuln: testdata.G1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.VulnEqualSpec{ - Vulnerabilities: []*model.VulnerabilitySpec{ - { - VulnerabilityID: ptrfrom.String("AEV-2022-26499"), - }, - }, - }, - ExpVulnEqual: nil, - }, - { - Name: "Query multiple", - InVuln: []*model.VulnerabilityInputSpec{testdata.O1, testdata.C1, testdata.C2, testdata.G1}, - Calls: []call{ - { - Vuln: testdata.O1, - OtherVuln: testdata.C1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - { - Vuln: testdata.O1, - OtherVuln: testdata.C2, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - { - Vuln: testdata.O1, - OtherVuln: testdata.G1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.VulnEqualSpec{ - Vulnerabilities: []*model.VulnerabilitySpec{ - { - Type: ptrfrom.String("cve"), - VulnerabilityID: ptrfrom.String("cve-2014-8139"), - }, - }, - }, - ExpVulnEqual: []*model.VulnEqual{ - { - Vulnerabilities: []*model.Vulnerability{ - { - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C2out}, - }, - { - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - }, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on ID", - InVuln: []*model.VulnerabilityInputSpec{testdata.O1, testdata.C1, testdata.C2, testdata.G1}, - Calls: []call{ - { - Vuln: testdata.O1, - OtherVuln: testdata.C1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - { - Vuln: testdata.O1, - OtherVuln: testdata.C2, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - { - Vuln: testdata.O1, - OtherVuln: testdata.G1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - QueryID: true, - ExpVulnEqual: []*model.VulnEqual{ - { - Vulnerabilities: []*model.Vulnerability{ - { - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - { - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - }, - Justification: "test justification", - }, - }, - }, - { - Name: "Query ID not found", - InVuln: []*model.VulnerabilityInputSpec{testdata.O1, testdata.C1, testdata.C2, testdata.G1}, - Calls: []call{ - { - Vuln: testdata.O1, - OtherVuln: testdata.C1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - { - Vuln: testdata.O1, - OtherVuln: testdata.C2, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - { - Vuln: testdata.O1, - OtherVuln: testdata.G1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.VulnEqualSpec{ - ID: ptrfrom.String("123456"), - }, - ExpVulnEqual: nil, - ExpQueryErr: true, - }, - { - Name: "Query Error", - Query: &model.VulnEqualSpec{ - Vulnerabilities: []*model.VulnerabilitySpec{ - { - ID: ptrfrom.String("6"), - }, - }, - }, - ExpQueryErr: false, - }, - { - Name: "Query Bad ID", - Query: &model.VulnEqualSpec{ - ID: ptrfrom.String("-123"), - }, - ExpQueryErr: true, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - var collectedVulnIDs []*model.VulnerabilityIDs - for _, g := range test.InVuln { - if vulnIDs, err := b.IngestVulnerability(ctx, *g); err != nil { - t.Fatalf("Could not ingest vulnerability: %a", err) - } else { - collectedVulnIDs = append(collectedVulnIDs, vulnIDs) - } - } - for _, o := range test.Calls { - veID, err := b.IngestVulnEqual(ctx, *o.Vuln, *o.OtherVuln, *o.In) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - if test.QueryID { - test.Query = &model.VulnEqualSpec{ - ID: ptrfrom.String(veID), - } - } - if test.QueryVulnID { - test.Query = &model.VulnEqualSpec{ - Vulnerabilities: []*model.VulnerabilitySpec{ - { - ID: ptrfrom.String(collectedVulnIDs[1].VulnerabilityNodeID), - }, - { - ID: ptrfrom.String(collectedVulnIDs[2].VulnerabilityNodeID), - }, - }, - } - } - } - got, err := b.VulnEqual(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpVulnEqual, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func TestIngestVulnEquals(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - type call struct { - Vulns []*model.VulnerabilityInputSpec - OtherVulns []*model.VulnerabilityInputSpec - Ins []*model.VulnEqualInputSpec - } - tests := []struct { - Name string - InVuln []*model.VulnerabilityInputSpec - Calls []call - Query *model.VulnEqualSpec - ExpVulnEqual []*model.VulnEqual - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InVuln: []*model.VulnerabilityInputSpec{testdata.O1, testdata.C1, testdata.O1, testdata.C2}, - Calls: []call{ - { - Vulns: []*model.VulnerabilityInputSpec{testdata.O1, testdata.O1}, - OtherVulns: []*model.VulnerabilityInputSpec{testdata.C1, testdata.C2}, - Ins: []*model.VulnEqualInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.VulnEqualSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpVulnEqual: []*model.VulnEqual{ - { - Vulnerabilities: []*model.Vulnerability{ - { - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - { - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C1out}, - }, - }, - Justification: "test justification", - }, - { - Vulnerabilities: []*model.Vulnerability{ - { - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C2out}, - }, - { - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - }, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest same twice", - InVuln: []*model.VulnerabilityInputSpec{testdata.O1, testdata.C1, testdata.O1, testdata.C1}, - Calls: []call{ - { - Vulns: []*model.VulnerabilityInputSpec{testdata.O1, testdata.O1}, - OtherVulns: []*model.VulnerabilityInputSpec{testdata.C1, testdata.C1}, - Ins: []*model.VulnEqualInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.VulnEqualSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpVulnEqual: []*model.VulnEqual{ - { - Vulnerabilities: []*model.Vulnerability{ - { - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - { - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C1out}, - }, - }, - Justification: "test justification", - }, - { - Vulnerabilities: []*model.Vulnerability{ - { - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C2out}, - }, - { - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - }, - Justification: "test justification", - }, - }, - }, - - { - Name: "Query on OSV", - InVuln: []*model.VulnerabilityInputSpec{testdata.O1, testdata.C1, testdata.O2, testdata.G2}, - Calls: []call{ - { - Vulns: []*model.VulnerabilityInputSpec{testdata.O1, testdata.O2}, - OtherVulns: []*model.VulnerabilityInputSpec{testdata.C1, testdata.G2}, - Ins: []*model.VulnEqualInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.VulnEqualSpec{ - Vulnerabilities: []*model.VulnerabilitySpec{ - { - VulnerabilityID: ptrfrom.String("GHSA-xrw3-wqph-3fxg"), - }, - }, - }, - ExpVulnEqual: []*model.VulnEqual{ - { - Vulnerabilities: []*model.Vulnerability{ - { - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G2out}, - }, - { - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O2out}, - }, - }, - Justification: "test justification", - }, - }, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - if _, err := b.IngestVulnerabilities(ctx, test.InVuln); err != nil { - t.Fatalf("Could not ingest vulnerability: %a", err) - } - for _, o := range test.Calls { - _, err := b.IngestVulnEquals(ctx, o.Vulns, o.OtherVulns, o.Ins) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.VulnEqual(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpVulnEqual, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func Test_buildVulnEqualByID(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - type call struct { - Vuln *model.VulnerabilityInputSpec - OtherVuln *model.VulnerabilityInputSpec - In *model.VulnEqualInputSpec - } - tests := []struct { - Name string - InVuln []*model.VulnerabilityInputSpec - Calls []call - Query *model.VulnEqualSpec - ExpVulnEqual *model.VulnEqual - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "Query on vuln Equal ID", - InVuln: []*model.VulnerabilityInputSpec{testdata.O2, testdata.C1}, - Calls: []call{ - { - Vuln: testdata.O2, - OtherVuln: testdata.C1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - ExpVulnEqual: &model.VulnEqual{ - Vulnerabilities: []*model.Vulnerability{ - { - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C1out}, - }, - { - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O2out}, - }, - }, - Justification: "test justification", - }, - }, - { - Name: "Query on ID", - InVuln: []*model.VulnerabilityInputSpec{testdata.O1, testdata.G1}, - Calls: []call{ - { - Vuln: testdata.O1, - OtherVuln: testdata.G1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - ExpVulnEqual: &model.VulnEqual{ - Vulnerabilities: []*model.Vulnerability{ - { - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - { - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - }, - Justification: "test justification", - }, - }, - { - Name: "Query ID not found", - InVuln: []*model.VulnerabilityInputSpec{testdata.O1, testdata.C1, testdata.C2, testdata.G1}, - Calls: []call{ - { - Vuln: testdata.O1, - OtherVuln: testdata.C1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - { - Vuln: testdata.O1, - OtherVuln: testdata.C2, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - { - Vuln: testdata.O1, - OtherVuln: testdata.G1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.VulnEqualSpec{ - ID: ptrfrom.String("123456"), - }, - ExpVulnEqual: nil, - ExpQueryErr: true, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - for _, g := range test.InVuln { - if _, err := b.IngestVulnerability(ctx, *g); err != nil { - t.Fatalf("Could not ingest vulnerability: %a", err) - } - } - for _, o := range test.Calls { - veID, err := b.IngestVulnEqual(ctx, *o.Vuln, *o.OtherVuln, *o.In) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - got, err := b.(*arangoClient).buildVulnEqualByID(ctx, veID, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpVulnEqual, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - } - }) - } -} diff --git a/pkg/assembler/backends/arangodb/vulnMetadata.go b/pkg/assembler/backends/arangodb/vulnMetadata.go index 304333b1a5..77326c1cc1 100644 --- a/pkg/assembler/backends/arangodb/vulnMetadata.go +++ b/pkg/assembler/backends/arangodb/vulnMetadata.go @@ -162,7 +162,7 @@ func getVulnMetadataQueryValues(vulnerability *model.VulnerabilityInputSpec, vul return values } -func (c *arangoClient) IngestVulnerabilityMetadata(ctx context.Context, vulnerability model.VulnerabilityInputSpec, vulnerabilityMetadata model.VulnerabilityMetadataInputSpec) (string, error) { +func (c *arangoClient) IngestVulnerabilityMetadata(ctx context.Context, vulnerability model.IDorVulnerabilityInput, vulnerabilityMetadata model.VulnerabilityMetadataInputSpec) (string, error) { query := ` LET firstVuln = FIRST( FOR vVulnID in vulnerabilities @@ -187,7 +187,7 @@ func (c *arangoClient) IngestVulnerabilityMetadata(ctx context.Context, vulnerab RETURN { 'vulnMetadata_id': vulnMetadata._id }` - cursor, err := executeQueryWithRetry(ctx, c.db, query, getVulnMetadataQueryValues(&vulnerability, vulnerabilityMetadata), "IngestVulnerabilityMetadata") + cursor, err := executeQueryWithRetry(ctx, c.db, query, getVulnMetadataQueryValues(vulnerability.VulnerabilityInput, vulnerabilityMetadata), "IngestVulnerabilityMetadata") if err != nil { return "", fmt.Errorf("failed to ingest VulnerabilityMetadata: %w", err) } @@ -205,11 +205,11 @@ func (c *arangoClient) IngestVulnerabilityMetadata(ctx context.Context, vulnerab } } -func (c *arangoClient) IngestBulkVulnerabilityMetadata(ctx context.Context, vulnerabilities []*model.VulnerabilityInputSpec, vulnerabilityMetadataList []*model.VulnerabilityMetadataInputSpec) ([]string, error) { +func (c *arangoClient) IngestBulkVulnerabilityMetadata(ctx context.Context, vulnerabilities []*model.IDorVulnerabilityInput, vulnerabilityMetadataList []*model.VulnerabilityMetadataInputSpec) ([]string, error) { var listOfValues []map[string]any for i := range vulnerabilityMetadataList { - listOfValues = append(listOfValues, getVulnMetadataQueryValues(vulnerabilities[i], *vulnerabilityMetadataList[i])) + listOfValues = append(listOfValues, getVulnMetadataQueryValues(vulnerabilities[i].VulnerabilityInput, *vulnerabilityMetadataList[i])) } var documents []string diff --git a/pkg/assembler/backends/arangodb/vulnMetadata_test.go b/pkg/assembler/backends/arangodb/vulnMetadata_test.go deleted file mode 100644 index 7e706b63af..0000000000 --- a/pkg/assembler/backends/arangodb/vulnMetadata_test.go +++ /dev/null @@ -1,1488 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build integration - -package arangodb - -import ( - "context" - "strconv" - "strings" - "testing" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/internal/testing/testdata" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -func scoreTypePointer(v model.VulnerabilityScoreType) *model.VulnerabilityScoreType { return &v } - -var greater model.Comparator = model.ComparatorGreater -var greaterEqual model.Comparator = model.ComparatorGreaterEqual -var less model.Comparator = model.ComparatorLess -var lessEqual model.Comparator = model.ComparatorLessEqual -var equal model.Comparator = model.ComparatorEqual - -var cvss2ScoreType model.VulnerabilityScoreType = model.VulnerabilityScoreTypeCVSSv2 - -func TestIngestVulnMetadata(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - type call struct { - Vuln *model.VulnerabilityInputSpec - VulnMetadata *model.VulnerabilityMetadataInputSpec - } - - tests := []struct { - Name string - InVuln []*model.VulnerabilityInputSpec - Calls []call - ExpVuln []*model.VulnerabilityMetadata - Query *model.VulnerabilityMetadataSpec - QueryID bool - QueryVulnID bool - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InVuln: []*model.VulnerabilityInputSpec{testdata.C1}, - Calls: []call{ - { - Vuln: testdata.C1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Collector: ptrfrom.String("test collector"), - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - ID: "1", - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Duplicate", - InVuln: []*model.VulnerabilityInputSpec{testdata.C1, testdata.C1}, - Calls: []call{ - { - Vuln: testdata.C1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - { - Vuln: testdata.C1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Collector: ptrfrom.String("test collector"), - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - ID: "1", - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Certify OSV", - InVuln: []*model.VulnerabilityInputSpec{testdata.O1}, - Calls: []call{ - { - Vuln: testdata.O1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Vulnerability: &model.VulnerabilitySpec{ - Type: ptrfrom.String("osv"), - }, - Collector: ptrfrom.String("test collector"), - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Query on Vulnerability ID", - InVuln: []*model.VulnerabilityInputSpec{testdata.O1}, - Calls: []call{ - { - Vuln: testdata.O1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - QueryVulnID: true, - ExpVuln: []*model.VulnerabilityMetadata{ - { - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Certify GHSA", - InVuln: []*model.VulnerabilityInputSpec{testdata.G1}, - Calls: []call{ - { - Vuln: testdata.G1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeEPSSv1, - ScoreValue: 0.95, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Vulnerability: &model.VulnerabilitySpec{ - Type: ptrfrom.String("ghsa"), - }, - Collector: ptrfrom.String("test collector"), - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - ScoreType: model.VulnerabilityScoreTypeEPSSv1, - ScoreValue: 0.95, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Query on GHSA", - InVuln: []*model.VulnerabilityInputSpec{testdata.G1}, - Calls: []call{ - { - Vuln: testdata.G1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeEPSSv2, - ScoreValue: 0.98, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Vulnerability: &model.VulnerabilitySpec{ - Type: ptrfrom.String("ghsa"), - VulnerabilityID: &testdata.G1.VulnerabilityID, - }, - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - ScoreType: model.VulnerabilityScoreTypeEPSSv2, - ScoreValue: 0.98, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - { - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - ScoreType: model.VulnerabilityScoreTypeEPSSv1, - ScoreValue: 0.95, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Query on ID", - InVuln: []*model.VulnerabilityInputSpec{testdata.G1}, - Calls: []call{ - { - Vuln: testdata.G1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - QueryID: true, - ExpVuln: []*model.VulnerabilityMetadata{ - { - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Query none", - InVuln: []*model.VulnerabilityInputSpec{testdata.G1}, - Calls: []call{ - { - Vuln: testdata.G1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Vulnerability: &model.VulnerabilitySpec{ - VulnerabilityID: ptrfrom.String("asdf"), - }, - }, - ExpVuln: nil, - }, - { - Name: "Query greater than - no score value", - InVuln: []*model.VulnerabilityInputSpec{testdata.C2, testdata.C1}, - Calls: []call{ - { - Vuln: testdata.C2, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - { - Vuln: testdata.C1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Comparator: &greater, - }, - ExpQueryErr: true, - ExpVuln: []*model.VulnerabilityMetadata{}, - }, - { - Name: "Query greater than", - InVuln: []*model.VulnerabilityInputSpec{testdata.C2, testdata.C1}, - Calls: []call{ - { - Vuln: testdata.C2, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - { - Vuln: testdata.C1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Comparator: &greater, - ScoreValue: ptrfrom.Float64(7.0), - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - { - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - { - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - { - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C2out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - { - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Query greater than - specific type", - InVuln: []*model.VulnerabilityInputSpec{testdata.C2, testdata.C1}, - Calls: []call{ - { - Vuln: testdata.C2, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - { - Vuln: testdata.C1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Comparator: &greater, - ScoreValue: ptrfrom.Float64(7.0), - ScoreType: &cvss2ScoreType, - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - { - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - { - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C2out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Query greater than or equal", - InVuln: []*model.VulnerabilityInputSpec{testdata.C2, testdata.C1, testdata.G1}, - Calls: []call{ - { - Vuln: testdata.C2, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - { - Vuln: testdata.C1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - { - Vuln: testdata.G1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 6.3, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Comparator: &greaterEqual, - ScoreValue: ptrfrom.Float64(7.9), - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - { - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - { - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - { - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C2out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - { - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Query less than", - InVuln: []*model.VulnerabilityInputSpec{testdata.C2, testdata.C1, testdata.G1}, - Calls: []call{ - { - Vuln: testdata.C2, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - { - Vuln: testdata.C1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - { - Vuln: testdata.G1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 6.3, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Comparator: &less, - ScoreValue: ptrfrom.Float64(6.5), - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - ScoreType: model.VulnerabilityScoreTypeEPSSv1, - ScoreValue: 0.95, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - { - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - ScoreType: model.VulnerabilityScoreTypeEPSSv2, - ScoreValue: 0.98, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - { - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 6.3, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Query less than or equal", - InVuln: []*model.VulnerabilityInputSpec{testdata.C2, testdata.C1, testdata.G1}, - Calls: []call{ - { - Vuln: testdata.C2, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - { - Vuln: testdata.C1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - { - Vuln: testdata.G1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 6.3, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Comparator: &lessEqual, - ScoreValue: ptrfrom.Float64(7.9), - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - { - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - ScoreType: model.VulnerabilityScoreTypeEPSSv1, - ScoreValue: 0.95, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - { - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - ScoreType: model.VulnerabilityScoreTypeEPSSv2, - ScoreValue: 0.98, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - { - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - { - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 6.3, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Query equal", - InVuln: []*model.VulnerabilityInputSpec{testdata.C2, testdata.C1, testdata.G1}, - Calls: []call{ - { - Vuln: testdata.C2, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - { - Vuln: testdata.C1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - { - Vuln: testdata.G1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 6.3, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Comparator: &equal, - ScoreValue: ptrfrom.Float64(7.9), - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - { - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Query without comparator", - InVuln: []*model.VulnerabilityInputSpec{testdata.C2, testdata.C1, testdata.G1}, - Calls: []call{ - { - Vuln: testdata.C2, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - { - Vuln: testdata.C1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - { - Vuln: testdata.G1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 6.3, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - ScoreValue: ptrfrom.Float64(7.9), - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - { - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Query all vulns - with novuln boolean omitted", - InVuln: []*model.VulnerabilityInputSpec{testdata.C2, testdata.C1, testdata.G1}, - Calls: []call{ - { - Vuln: testdata.C2, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - { - Vuln: testdata.C1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeEPSSv2, - ScoreValue: 0.96, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - { - Vuln: testdata.G1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 2.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Vulnerability: &model.VulnerabilitySpec{ - Type: ptrfrom.String("cve"), - VulnerabilityID: &testdata.C2.VulnerabilityID, - }, - ScoreType: scoreTypePointer(model.VulnerabilityScoreTypeCVSSv2), - ScoreValue: ptrfrom.Float64(8.9), - Timestamp: ptrfrom.Time(testdata.T1), - Collector: ptrfrom.String("test collector"), - Origin: ptrfrom.String("test origin"), - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C2out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - for _, g := range test.InVuln { - ingestedVuln, err := b.IngestVulnerability(ctx, *g) - if err != nil { - t.Fatalf("Could not ingest vulnerability: %a", err) - } - if test.QueryVulnID { - test.Query = &model.VulnerabilityMetadataSpec{ - Vulnerability: &model.VulnerabilitySpec{ - ID: ptrfrom.String(ingestedVuln.VulnerabilityNodeID), - }, - } - } - } - ids := make([]string, len(test.Calls)) - for i, o := range test.Calls { - record, err := b.IngestVulnerabilityMetadata(ctx, *o.Vuln, *o.VulnMetadata) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - if test.QueryID { - test.Query = &model.VulnerabilityMetadataSpec{ - ID: ptrfrom.String(record), - } - } - ids[i] = record - } - if test.Query != nil { - if test.Query.ID != nil { - idIndex, err := strconv.Atoi(*test.Query.ID) - if err == nil && idIndex > -1 && idIndex < len(ids) { - test.Query.ID = ptrfrom.String(ids[idIndex]) - } - } - } - - got, err := b.VulnerabilityMetadata(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpVuln, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func TestIngestVulnMetadatas(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - type call struct { - Vulns []*model.VulnerabilityInputSpec - VulnMetadatas []*model.VulnerabilityMetadataInputSpec - } - - tests := []struct { - Name string - InVuln []*model.VulnerabilityInputSpec - Calls []call - ExpVuln []*model.VulnerabilityMetadata - Query *model.VulnerabilityMetadataSpec - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InVuln: []*model.VulnerabilityInputSpec{testdata.C1, testdata.C2}, - Calls: []call{ - { - Vulns: []*model.VulnerabilityInputSpec{testdata.C1, testdata.C2}, - VulnMetadatas: []*model.VulnerabilityMetadataInputSpec{ - { - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - { - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Collector: ptrfrom.String("test collector"), - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - ID: "1", - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - { - ID: "10", - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C2out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Certify OSV", - InVuln: []*model.VulnerabilityInputSpec{testdata.O1, testdata.O2}, - Calls: []call{ - { - Vulns: []*model.VulnerabilityInputSpec{testdata.O1, testdata.O2}, - VulnMetadatas: []*model.VulnerabilityMetadataInputSpec{ - { - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - { - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Vulnerability: &model.VulnerabilitySpec{ - Type: ptrfrom.String("osv"), - }, - Collector: ptrfrom.String("test collector"), - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O2out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - { - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Certify GHSA", - InVuln: []*model.VulnerabilityInputSpec{testdata.G1, testdata.G2}, - Calls: []call{ - { - Vulns: []*model.VulnerabilityInputSpec{testdata.G1, testdata.G2}, - VulnMetadatas: []*model.VulnerabilityMetadataInputSpec{ - { - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - { - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Vulnerability: &model.VulnerabilitySpec{ - Type: ptrfrom.String("ghsa"), - }, - Collector: ptrfrom.String("test collector"), - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G2out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - { - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Query on GHSA", - InVuln: []*model.VulnerabilityInputSpec{testdata.G1, testdata.G2}, - Calls: []call{ - { - Vulns: []*model.VulnerabilityInputSpec{testdata.G1, testdata.G2}, - VulnMetadatas: []*model.VulnerabilityMetadataInputSpec{ - { - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - { - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Vulnerability: &model.VulnerabilitySpec{ - VulnerabilityID: &testdata.G1.VulnerabilityID, - }, - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Query none", - InVuln: []*model.VulnerabilityInputSpec{testdata.G1, testdata.G2}, - Calls: []call{ - { - Vulns: []*model.VulnerabilityInputSpec{testdata.G1, testdata.G2}, - VulnMetadatas: []*model.VulnerabilityMetadataInputSpec{ - { - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - { - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Vulnerability: &model.VulnerabilitySpec{ - VulnerabilityID: ptrfrom.String("asdf"), - }, - }, - ExpVuln: nil, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - if _, err := b.IngestVulnerabilities(ctx, test.InVuln); err != nil { - t.Fatalf("Could not ingest vulnerabilities: %a", err) - } - for _, o := range test.Calls { - _, err := b.IngestBulkVulnerabilityMetadata(ctx, o.Vulns, o.VulnMetadatas) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - - } - got, err := b.VulnerabilityMetadata(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpVuln, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func Test_buildVulnerabilityMetadataByID(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - type call struct { - Vuln *model.VulnerabilityInputSpec - VulnMetadata *model.VulnerabilityMetadataInputSpec - } - tests := []struct { - Name string - InVuln []*model.VulnerabilityInputSpec - Calls []call - ExpVuln *model.VulnerabilityMetadata - Query *model.VulnerabilityMetadataSpec - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "OSV", - InVuln: []*model.VulnerabilityInputSpec{testdata.O1}, - Calls: []call{ - { - Vuln: testdata.O1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Vulnerability: &model.VulnerabilitySpec{ - Type: ptrfrom.String("osv"), - }, - Collector: ptrfrom.String("test collector"), - }, - ExpVuln: &model.VulnerabilityMetadata{ - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - { - Name: "Certify GHSA", - InVuln: []*model.VulnerabilityInputSpec{testdata.G1}, - Calls: []call{ - { - Vuln: testdata.G1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeEPSSv1, - ScoreValue: 0.95, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Vulnerability: &model.VulnerabilitySpec{ - Type: ptrfrom.String("ghsa"), - }, - Collector: ptrfrom.String("test collector"), - }, - ExpVuln: &model.VulnerabilityMetadata{ - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - ScoreType: model.VulnerabilityScoreTypeEPSSv1, - ScoreValue: 0.95, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - { - Name: "Query on ID", - InVuln: []*model.VulnerabilityInputSpec{testdata.G1}, - Calls: []call{ - { - Vuln: testdata.G1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - ExpVuln: &model.VulnerabilityMetadata{ - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - for _, g := range test.InVuln { - _, err := b.IngestVulnerability(ctx, *g) - if err != nil { - t.Fatalf("Could not ingest vulnerability: %a", err) - } - - } - for _, o := range test.Calls { - record, err := b.IngestVulnerabilityMetadata(ctx, *o.Vuln, *o.VulnMetadata) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - got, err := b.(*arangoClient).buildVulnerabilityMetadataByID(ctx, record, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpVuln, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - } - }) - } -} diff --git a/pkg/assembler/backends/arangodb/vulnerability.go b/pkg/assembler/backends/arangodb/vulnerability.go index 390146e8c2..f63e43b411 100644 --- a/pkg/assembler/backends/arangodb/vulnerability.go +++ b/pkg/assembler/backends/arangodb/vulnerability.go @@ -190,11 +190,11 @@ func getVulnQueryValues(vuln *model.VulnerabilityInputSpec) map[string]any { return values } -func (c *arangoClient) IngestVulnerabilities(ctx context.Context, vulns []*model.VulnerabilityInputSpec) ([]*model.VulnerabilityIDs, error) { +func (c *arangoClient) IngestVulnerabilities(ctx context.Context, vulns []*model.IDorVulnerabilityInput) ([]*model.VulnerabilityIDs, error) { var listOfValues []map[string]any for i := range vulns { - listOfValues = append(listOfValues, getVulnQueryValues(vulns[i])) + listOfValues = append(listOfValues, getVulnQueryValues(vulns[i].VulnerabilityInput)) } var documents []string @@ -257,7 +257,7 @@ func (c *arangoClient) IngestVulnerabilities(ctx context.Context, vulns []*model return getVulnerabilityIDs(ctx, cursor) } -func (c *arangoClient) IngestVulnerability(ctx context.Context, vuln model.VulnerabilityInputSpec) (*model.VulnerabilityIDs, error) { +func (c *arangoClient) IngestVulnerability(ctx context.Context, vuln model.IDorVulnerabilityInput) (*model.VulnerabilityIDs, error) { query := ` LET type = FIRST( UPSERT { type: @vulnType } @@ -284,7 +284,7 @@ func (c *arangoClient) IngestVulnerability(ctx context.Context, vuln model.Vulne "vuln_id": vuln._id }` - cursor, err := executeQueryWithRetry(ctx, c.db, query, getVulnQueryValues(&vuln), "IngestVulnerability") + cursor, err := executeQueryWithRetry(ctx, c.db, query, getVulnQueryValues(vuln.VulnerabilityInput), "IngestVulnerability") if err != nil { return nil, fmt.Errorf("failed to ingest cve: %w", err) } diff --git a/pkg/assembler/backends/arangodb/vulnerability_test.go b/pkg/assembler/backends/arangodb/vulnerability_test.go deleted file mode 100644 index 6f8520ad09..0000000000 --- a/pkg/assembler/backends/arangodb/vulnerability_test.go +++ /dev/null @@ -1,544 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build integration - -package arangodb - -import ( - "context" - "slices" - "strings" - "testing" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/internal/testing/testdata" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -func lessCve(a, b *model.Vulnerability) int { - return strings.Compare(a.VulnerabilityIDs[0].VulnerabilityID, - b.VulnerabilityIDs[0].VulnerabilityID) -} - -func TestVulnerability(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - tests := []struct { - Name string - Ingests []*model.VulnerabilityInputSpec - ExpIngestErr bool - Query *model.VulnerabilitySpec - QueryID bool - Exp []*model.Vulnerability - ExpQueryErr bool - }{ - { - Name: "HappyPath", - Ingests: []*model.VulnerabilityInputSpec{testdata.C1}, - Query: &model.VulnerabilitySpec{}, - Exp: []*model.Vulnerability{ - { - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C1out}, - }, - }, - }, - { - Name: "Multiple", - Ingests: []*model.VulnerabilityInputSpec{testdata.C1, testdata.C2}, - Query: &model.VulnerabilitySpec{}, - Exp: []*model.Vulnerability{ - { - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C2out, testdata.C1out}, - }, - }, - }, - { - Name: "Duplicates", - Ingests: []*model.VulnerabilityInputSpec{testdata.C1, testdata.C1, testdata.C1}, - Query: &model.VulnerabilitySpec{ - VulnerabilityID: ptrfrom.String("cve-2019-13110"), - }, - Exp: []*model.Vulnerability{ - { - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C1out}, - }, - }, - }, - { - Name: "Query by type - cve", - Ingests: []*model.VulnerabilityInputSpec{testdata.C1, testdata.C2, testdata.C3, testdata.G1, testdata.O1}, - Query: &model.VulnerabilitySpec{ - Type: ptrfrom.String("cve"), - }, - Exp: []*model.Vulnerability{ - { - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C3out, testdata.C2out, testdata.C1out}, - }, - }, - }, - { - Name: "Query by type - ghsa", - Ingests: []*model.VulnerabilityInputSpec{testdata.C1, testdata.C2, testdata.C3, testdata.G2, testdata.G3, testdata.O1}, - Query: &model.VulnerabilitySpec{ - Type: ptrfrom.String("ghsa"), - }, - Exp: []*model.Vulnerability{ - { - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G3out, testdata.G2out, testdata.G1out}, - }, - }, - }, - { - Name: "Query by type - osv", - Ingests: []*model.VulnerabilityInputSpec{testdata.C1, testdata.C2, testdata.C3, testdata.G3, testdata.O1, testdata.O2, testdata.O3}, - Query: &model.VulnerabilitySpec{ - Type: ptrfrom.String("osv"), - }, - Exp: []*model.Vulnerability{ - { - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O3out, testdata.O2out, testdata.O1out}, - }, - }, - }, - { - Name: "Query by type - noVuln", - Ingests: []*model.VulnerabilityInputSpec{testdata.NoVulnInput}, - Query: &model.VulnerabilitySpec{ - Type: ptrfrom.String("noVuln"), - }, - Exp: []*model.Vulnerability{ - { - Type: "novuln", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.NoVulnOut}, - }, - }, - }, - { - Name: "Query by type - noVuln with boolean", - Ingests: []*model.VulnerabilityInputSpec{testdata.NoVulnInput}, - Query: &model.VulnerabilitySpec{ - NoVuln: ptrfrom.Bool(true), - }, - Exp: []*model.Vulnerability{ - { - Type: "novuln", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.NoVulnOut}, - }, - }, - }, - { - Name: "Query by vulnID", - Ingests: []*model.VulnerabilityInputSpec{testdata.C1, testdata.C2, testdata.C3}, - Query: &model.VulnerabilitySpec{ - Type: ptrfrom.String("cve"), - VulnerabilityID: ptrfrom.String("CVE-2014-8140"), - }, - Exp: []*model.Vulnerability{ - { - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C3out}, - }, - }, - }, - { - Name: "Query by vulnID - noVuln", - Ingests: []*model.VulnerabilityInputSpec{testdata.C1, testdata.C2, testdata.C3, testdata.NoVulnInput}, - Query: &model.VulnerabilitySpec{ - Type: ptrfrom.String("noVuln"), - }, - Exp: []*model.Vulnerability{ - { - Type: "novuln", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.NoVulnOut}, - }, - }, - }, - { - Name: "Query on ID", - Ingests: []*model.VulnerabilityInputSpec{testdata.C1}, - QueryID: true, - Exp: []*model.Vulnerability{ - { - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C1out}, - }, - }, - }, - { - Name: "Query none", - Ingests: []*model.VulnerabilityInputSpec{testdata.C1, testdata.C2, testdata.C3}, - Query: &model.VulnerabilitySpec{ - Type: ptrfrom.String("5258"), - }, - Exp: nil, - }, - { - Name: "Query none ID", - Ingests: []*model.VulnerabilityInputSpec{testdata.C1, testdata.C2, testdata.C3}, - Query: &model.VulnerabilitySpec{ - ID: ptrfrom.String("12345"), - }, - ExpQueryErr: true, - }, - { - Name: "Query invalid ID", - Ingests: []*model.VulnerabilityInputSpec{testdata.C1, testdata.C2, testdata.C3}, - Query: &model.VulnerabilitySpec{ - ID: ptrfrom.String("asdf"), - }, - ExpQueryErr: true, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - for _, i := range test.Ingests { - vulnIDs, err := b.IngestVulnerability(ctx, *i) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - if test.QueryID { - test.Query = &model.VulnerabilitySpec{ - ID: ptrfrom.String(vulnIDs.VulnerabilityNodeID), - } - } - } - got, err := b.Vulnerabilities(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - slices.SortFunc(got, lessCve) - if diff := cmp.Diff(test.Exp, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func TestVulnerabilityType(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - tests := []struct { - Name string - Ingests []*model.VulnerabilityInputSpec - ExpIngestErr bool - Query *model.VulnerabilitySpec - Exp []*model.Vulnerability - ExpQueryErr bool - }{ - { - Name: "HappyPath", - Ingests: []*model.VulnerabilityInputSpec{testdata.C1}, - Query: &model.VulnerabilitySpec{}, - Exp: []*model.Vulnerability{ - { - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{}, - }, - }, - }, - { - Name: "Multiple", - Ingests: []*model.VulnerabilityInputSpec{testdata.C1, testdata.C2}, - Query: &model.VulnerabilitySpec{}, - Exp: []*model.Vulnerability{ - { - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{}, - }, - }, - }, - { - Name: "Duplicates", - Ingests: []*model.VulnerabilityInputSpec{testdata.C1, testdata.C1, testdata.C1}, - Query: &model.VulnerabilitySpec{ - VulnerabilityID: ptrfrom.String("cve-2019-13110"), - }, - Exp: []*model.Vulnerability{ - { - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{}, - }, - }, - }, - { - Name: "Query by type - cve", - Ingests: []*model.VulnerabilityInputSpec{testdata.C1, testdata.C2, testdata.C3, testdata.G1, testdata.O1}, - Query: &model.VulnerabilitySpec{ - Type: ptrfrom.String("cve"), - }, - Exp: []*model.Vulnerability{ - { - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{}, - }, - }, - }, - { - Name: "Query by type - ghsa", - Ingests: []*model.VulnerabilityInputSpec{testdata.C1, testdata.C2, testdata.C3, testdata.G2, testdata.G3, testdata.O1}, - Query: &model.VulnerabilitySpec{ - Type: ptrfrom.String("ghsa"), - }, - Exp: []*model.Vulnerability{ - { - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{}, - }, - }, - }, - { - Name: "Query by type - osv", - Ingests: []*model.VulnerabilityInputSpec{testdata.C1, testdata.C2, testdata.C3, testdata.G3, testdata.O1, testdata.O2, testdata.O3}, - Query: &model.VulnerabilitySpec{ - Type: ptrfrom.String("osv"), - }, - Exp: []*model.Vulnerability{ - { - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{}, - }, - }, - }, - { - Name: "Query by type - noVuln", - Ingests: []*model.VulnerabilityInputSpec{testdata.NoVulnInput}, - Query: &model.VulnerabilitySpec{ - Type: ptrfrom.String("noVuln"), - }, - Exp: []*model.Vulnerability{ - { - Type: "novuln", - VulnerabilityIDs: []*model.VulnerabilityID{}, - }, - }, - }, - { - Name: "Query by type - noVuln with boolean", - Ingests: []*model.VulnerabilityInputSpec{testdata.NoVulnInput}, - Query: &model.VulnerabilitySpec{ - NoVuln: ptrfrom.Bool(true), - }, - Exp: []*model.Vulnerability{ - { - Type: "novuln", - VulnerabilityIDs: []*model.VulnerabilityID{}, - }, - }, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - for _, i := range test.Ingests { - _, err := b.IngestVulnerability(ctx, *i) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.(*arangoClient).vulnerabilityType(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - slices.SortFunc(got, lessCve) - if diff := cmp.Diff(test.Exp, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func TestIngestVulnerabilities(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - tests := []struct { - name string - ingests []*model.VulnerabilityInputSpec - exp []*model.Vulnerability - }{{ - name: "Multiple", - ingests: []*model.VulnerabilityInputSpec{testdata.C1, testdata.O1, testdata.G1}, - }} - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - got, err := b.IngestVulnerabilities(ctx, test.ingests) - if err != nil { - t.Fatalf("ingest error: %v", err) - return - } - if len(got) != len(test.ingests) { - t.Errorf("Unexpected number of results. Wanted: %d, got %d", len(test.ingests), len(got)) - } - }) - } -} - -func Test_buildVulnResponseByID(t *testing.T) { - ctx := context.Background() - arangoArgs := getArangoConfig() - err := DeleteDatabase(ctx, arangoArgs) - if err != nil { - t.Fatalf("error deleting arango database: %v", err) - } - b, err := getBackend(ctx, arangoArgs) - if err != nil { - t.Fatalf("error creating arango backend: %v", err) - } - tests := []struct { - Name string - Ingest *model.VulnerabilityInputSpec - ExpIngestErr bool - Query *model.VulnerabilitySpec - QueryID bool - Exp *model.Vulnerability - ExpQueryErr bool - }{ - { - Name: "HappyPath", - Ingest: testdata.C1, - Query: &model.VulnerabilitySpec{}, - Exp: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C1out}, - }, - }, - { - Name: "Query by type - noVuln", - Ingest: testdata.NoVulnInput, - Query: &model.VulnerabilitySpec{ - Type: ptrfrom.String("noVuln"), - }, - Exp: &model.Vulnerability{ - Type: "novuln", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.NoVulnOut}, - }, - }, - { - Name: "Query by type - noVuln with boolean", - Ingest: testdata.NoVulnInput, - Query: &model.VulnerabilitySpec{ - NoVuln: ptrfrom.Bool(true), - }, - Exp: &model.Vulnerability{ - Type: "novuln", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.NoVulnOut}, - }, - }, - { - Name: "Query by vulnID", - Ingest: testdata.C3, - Query: &model.VulnerabilitySpec{ - Type: ptrfrom.String("cve"), - VulnerabilityID: ptrfrom.String("CVE-2014-8140"), - }, - Exp: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C3out}, - }, - }, - { - Name: "Query by vulnID - noVuln", - Ingest: testdata.NoVulnInput, - Query: &model.VulnerabilitySpec{ - Type: ptrfrom.String("noVuln"), - }, - Exp: &model.Vulnerability{ - Type: "novuln", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.NoVulnOut}, - }, - }, - { - Name: "Query none ID", - Ingest: testdata.C3, - Query: &model.VulnerabilitySpec{ - ID: ptrfrom.String("12345"), - }, - Exp: nil, - ExpQueryErr: true, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - foundVulnIDs, err := b.IngestVulnerability(ctx, *test.Ingest) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - got, err := b.(*arangoClient).buildVulnResponseByID(ctx, foundVulnIDs.VulnerabilityNodeID, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.Exp, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} diff --git a/pkg/assembler/backends/backends.go b/pkg/assembler/backends/backends.go index 60c4cc16cb..012718f586 100644 --- a/pkg/assembler/backends/backends.go +++ b/pkg/assembler/backends/backends.go @@ -53,54 +53,54 @@ type Backend interface { VulnerabilityMetadata(ctx context.Context, vulnerabilityMetadataSpec *model.VulnerabilityMetadataSpec) ([]*model.VulnerabilityMetadata, error) // Mutations for software trees (read-write queries) - IngestArtifact(ctx context.Context, artifact *model.ArtifactInputSpec) (string, error) - IngestArtifacts(ctx context.Context, artifacts []*model.ArtifactInputSpec) ([]string, error) - IngestBuilder(ctx context.Context, builder *model.BuilderInputSpec) (string, error) - IngestBuilders(ctx context.Context, builders []*model.BuilderInputSpec) ([]string, error) - IngestLicense(ctx context.Context, license *model.LicenseInputSpec) (string, error) - IngestLicenses(ctx context.Context, licenses []*model.LicenseInputSpec) ([]string, error) - IngestPackage(ctx context.Context, pkg model.PkgInputSpec) (*model.PackageIDs, error) - IngestPackages(ctx context.Context, pkgs []*model.PkgInputSpec) ([]*model.PackageIDs, error) - IngestSource(ctx context.Context, source model.SourceInputSpec) (*model.SourceIDs, error) - IngestSources(ctx context.Context, sources []*model.SourceInputSpec) ([]*model.SourceIDs, error) - IngestVulnerability(ctx context.Context, vuln model.VulnerabilityInputSpec) (*model.VulnerabilityIDs, error) - IngestVulnerabilities(ctx context.Context, vulns []*model.VulnerabilityInputSpec) ([]*model.VulnerabilityIDs, error) + IngestArtifact(ctx context.Context, artifact *model.IDorArtifactInput) (string, error) + IngestArtifacts(ctx context.Context, artifacts []*model.IDorArtifactInput) ([]string, error) + IngestBuilder(ctx context.Context, builder *model.IDorBuilderInput) (string, error) + IngestBuilders(ctx context.Context, builders []*model.IDorBuilderInput) ([]string, error) + IngestLicense(ctx context.Context, license *model.IDorLicenseInput) (string, error) + IngestLicenses(ctx context.Context, licenses []*model.IDorLicenseInput) ([]string, error) + IngestPackage(ctx context.Context, pkg model.IDorPkgInput) (*model.PackageIDs, error) + IngestPackages(ctx context.Context, pkgs []*model.IDorPkgInput) ([]*model.PackageIDs, error) + IngestSource(ctx context.Context, source model.IDorSourceInput) (*model.SourceIDs, error) + IngestSources(ctx context.Context, sources []*model.IDorSourceInput) ([]*model.SourceIDs, error) + IngestVulnerability(ctx context.Context, vuln model.IDorVulnerabilityInput) (*model.VulnerabilityIDs, error) + IngestVulnerabilities(ctx context.Context, vulns []*model.IDorVulnerabilityInput) ([]*model.VulnerabilityIDs, error) // Mutations for evidence trees (read-write queries, assume software trees ingested) IngestCertifyBad(ctx context.Context, subject model.PackageSourceOrArtifactInput, pkgMatchType *model.MatchFlags, certifyBad model.CertifyBadInputSpec) (string, error) IngestCertifyBads(ctx context.Context, subjects model.PackageSourceOrArtifactInputs, pkgMatchType *model.MatchFlags, certifyBads []*model.CertifyBadInputSpec) ([]string, error) IngestCertifyGood(ctx context.Context, subject model.PackageSourceOrArtifactInput, pkgMatchType *model.MatchFlags, certifyGood model.CertifyGoodInputSpec) (string, error) IngestCertifyGoods(ctx context.Context, subjects model.PackageSourceOrArtifactInputs, pkgMatchType *model.MatchFlags, certifyGoods []*model.CertifyGoodInputSpec) ([]string, error) - IngestCertifyVuln(ctx context.Context, pkg model.PkgInputSpec, vulnerability model.VulnerabilityInputSpec, certifyVuln model.ScanMetadataInput) (string, error) - IngestCertifyVulns(ctx context.Context, pkgs []*model.PkgInputSpec, vulnerabilities []*model.VulnerabilityInputSpec, certifyVulns []*model.ScanMetadataInput) ([]string, error) - IngestCertifyLegal(ctx context.Context, subject model.PackageOrSourceInput, declaredLicenses []*model.LicenseInputSpec, discoveredLicenses []*model.LicenseInputSpec, certifyLegal *model.CertifyLegalInputSpec) (string, error) - IngestCertifyLegals(ctx context.Context, subjects model.PackageOrSourceInputs, declaredLicensesList [][]*model.LicenseInputSpec, discoveredLicensesList [][]*model.LicenseInputSpec, certifyLegals []*model.CertifyLegalInputSpec) ([]string, error) - IngestDependency(ctx context.Context, pkg model.PkgInputSpec, depPkg model.PkgInputSpec, depPkgMatchType model.MatchFlags, dependency model.IsDependencyInputSpec) (string, error) - IngestDependencies(ctx context.Context, pkgs []*model.PkgInputSpec, depPkgs []*model.PkgInputSpec, depPkgMatchType model.MatchFlags, dependencies []*model.IsDependencyInputSpec) ([]string, error) + IngestCertifyVuln(ctx context.Context, pkg model.IDorPkgInput, vulnerability model.IDorVulnerabilityInput, certifyVuln model.ScanMetadataInput) (string, error) + IngestCertifyVulns(ctx context.Context, pkgs []*model.IDorPkgInput, vulnerabilities []*model.IDorVulnerabilityInput, certifyVulns []*model.ScanMetadataInput) ([]string, error) + IngestCertifyLegal(ctx context.Context, subject model.PackageOrSourceInput, declaredLicenses []*model.IDorLicenseInput, discoveredLicenses []*model.IDorLicenseInput, certifyLegal *model.CertifyLegalInputSpec) (string, error) + IngestCertifyLegals(ctx context.Context, subjects model.PackageOrSourceInputs, declaredLicensesList [][]*model.IDorLicenseInput, discoveredLicensesList [][]*model.IDorLicenseInput, certifyLegals []*model.CertifyLegalInputSpec) ([]string, error) + IngestDependency(ctx context.Context, pkg model.IDorPkgInput, depPkg model.IDorPkgInput, depPkgMatchType model.MatchFlags, dependency model.IsDependencyInputSpec) (string, error) + IngestDependencies(ctx context.Context, pkgs []*model.IDorPkgInput, depPkgs []*model.IDorPkgInput, depPkgMatchType model.MatchFlags, dependencies []*model.IsDependencyInputSpec) ([]string, error) IngestHasSbom(ctx context.Context, subject model.PackageOrArtifactInput, hasSbom model.HasSBOMInputSpec, includes model.HasSBOMIncludesInputSpec) (string, error) IngestHasSBOMs(ctx context.Context, subjects model.PackageOrArtifactInputs, hasSBOMs []*model.HasSBOMInputSpec, includes []*model.HasSBOMIncludesInputSpec) ([]string, error) - IngestHasSourceAt(ctx context.Context, pkg model.PkgInputSpec, pkgMatchType model.MatchFlags, source model.SourceInputSpec, hasSourceAt model.HasSourceAtInputSpec) (string, error) - IngestHasSourceAts(ctx context.Context, pkgs []*model.PkgInputSpec, pkgMatchType *model.MatchFlags, sources []*model.SourceInputSpec, hasSourceAts []*model.HasSourceAtInputSpec) ([]string, error) + IngestHasSourceAt(ctx context.Context, pkg model.IDorPkgInput, pkgMatchType model.MatchFlags, source model.IDorSourceInput, hasSourceAt model.HasSourceAtInputSpec) (string, error) + IngestHasSourceAts(ctx context.Context, pkgs []*model.IDorPkgInput, pkgMatchType *model.MatchFlags, sources []*model.IDorSourceInput, hasSourceAts []*model.HasSourceAtInputSpec) ([]string, error) IngestHasMetadata(ctx context.Context, subject model.PackageSourceOrArtifactInput, pkgMatchType *model.MatchFlags, hasMetadata model.HasMetadataInputSpec) (string, error) IngestBulkHasMetadata(ctx context.Context, subjects model.PackageSourceOrArtifactInputs, pkgMatchType *model.MatchFlags, hasMetadataList []*model.HasMetadataInputSpec) ([]string, error) - IngestHashEqual(ctx context.Context, artifact model.ArtifactInputSpec, equalArtifact model.ArtifactInputSpec, hashEqual model.HashEqualInputSpec) (string, error) - IngestHashEquals(ctx context.Context, artifacts []*model.ArtifactInputSpec, otherArtifacts []*model.ArtifactInputSpec, hashEquals []*model.HashEqualInputSpec) ([]string, error) - IngestOccurrence(ctx context.Context, subject model.PackageOrSourceInput, artifact model.ArtifactInputSpec, occurrence model.IsOccurrenceInputSpec) (string, error) - IngestOccurrences(ctx context.Context, subjects model.PackageOrSourceInputs, artifacts []*model.ArtifactInputSpec, occurrences []*model.IsOccurrenceInputSpec) ([]string, error) - IngestPkgEqual(ctx context.Context, pkg model.PkgInputSpec, depPkg model.PkgInputSpec, pkgEqual model.PkgEqualInputSpec) (string, error) - IngestPkgEquals(ctx context.Context, pkgs []*model.PkgInputSpec, otherPackages []*model.PkgInputSpec, pkgEquals []*model.PkgEqualInputSpec) ([]string, error) + IngestHashEqual(ctx context.Context, artifact model.IDorArtifactInput, equalArtifact model.IDorArtifactInput, hashEqual model.HashEqualInputSpec) (string, error) + IngestHashEquals(ctx context.Context, artifacts []*model.IDorArtifactInput, otherArtifacts []*model.IDorArtifactInput, hashEquals []*model.HashEqualInputSpec) ([]string, error) + IngestOccurrence(ctx context.Context, subject model.PackageOrSourceInput, artifact model.IDorArtifactInput, occurrence model.IsOccurrenceInputSpec) (string, error) + IngestOccurrences(ctx context.Context, subjects model.PackageOrSourceInputs, artifacts []*model.IDorArtifactInput, occurrences []*model.IsOccurrenceInputSpec) ([]string, error) + IngestPkgEqual(ctx context.Context, pkg model.IDorPkgInput, depPkg model.IDorPkgInput, pkgEqual model.PkgEqualInputSpec) (string, error) + IngestPkgEquals(ctx context.Context, pkgs []*model.IDorPkgInput, otherPackages []*model.IDorPkgInput, pkgEquals []*model.PkgEqualInputSpec) ([]string, error) IngestPointOfContact(ctx context.Context, subject model.PackageSourceOrArtifactInput, pkgMatchType *model.MatchFlags, pointOfContact model.PointOfContactInputSpec) (string, error) IngestPointOfContacts(ctx context.Context, subjects model.PackageSourceOrArtifactInputs, pkgMatchType *model.MatchFlags, pointOfContacts []*model.PointOfContactInputSpec) ([]string, error) - IngestSLSA(ctx context.Context, subject model.ArtifactInputSpec, builtFrom []*model.ArtifactInputSpec, builtBy model.BuilderInputSpec, slsa model.SLSAInputSpec) (string, error) - IngestSLSAs(ctx context.Context, subjects []*model.ArtifactInputSpec, builtFromList [][]*model.ArtifactInputSpec, builtByList []*model.BuilderInputSpec, slsaList []*model.SLSAInputSpec) ([]string, error) - IngestScorecard(ctx context.Context, source model.SourceInputSpec, scorecard model.ScorecardInputSpec) (string, error) - IngestScorecards(ctx context.Context, sources []*model.SourceInputSpec, scorecards []*model.ScorecardInputSpec) ([]string, error) - IngestVEXStatement(ctx context.Context, subject model.PackageOrArtifactInput, vulnerability model.VulnerabilityInputSpec, vexStatement model.VexStatementInputSpec) (string, error) - IngestVEXStatements(ctx context.Context, subjects model.PackageOrArtifactInputs, vulnerabilities []*model.VulnerabilityInputSpec, vexStatements []*model.VexStatementInputSpec) ([]string, error) - IngestVulnEqual(ctx context.Context, vulnerability model.VulnerabilityInputSpec, otherVulnerability model.VulnerabilityInputSpec, vulnEqual model.VulnEqualInputSpec) (string, error) - IngestVulnEquals(ctx context.Context, vulnerabilities []*model.VulnerabilityInputSpec, otherVulnerabilities []*model.VulnerabilityInputSpec, vulnEquals []*model.VulnEqualInputSpec) ([]string, error) - IngestVulnerabilityMetadata(ctx context.Context, vulnerability model.VulnerabilityInputSpec, vulnerabilityMetadata model.VulnerabilityMetadataInputSpec) (string, error) - IngestBulkVulnerabilityMetadata(ctx context.Context, vulnerabilities []*model.VulnerabilityInputSpec, vulnerabilityMetadataList []*model.VulnerabilityMetadataInputSpec) ([]string, error) + IngestSLSA(ctx context.Context, subject model.IDorArtifactInput, builtFrom []*model.IDorArtifactInput, builtBy model.IDorBuilderInput, slsa model.SLSAInputSpec) (string, error) + IngestSLSAs(ctx context.Context, subjects []*model.IDorArtifactInput, builtFromList [][]*model.IDorArtifactInput, builtByList []*model.IDorBuilderInput, slsaList []*model.SLSAInputSpec) ([]string, error) + IngestScorecard(ctx context.Context, source model.IDorSourceInput, scorecard model.ScorecardInputSpec) (string, error) + IngestScorecards(ctx context.Context, sources []*model.IDorSourceInput, scorecards []*model.ScorecardInputSpec) ([]string, error) + IngestVEXStatement(ctx context.Context, subject model.PackageOrArtifactInput, vulnerability model.IDorVulnerabilityInput, vexStatement model.VexStatementInputSpec) (string, error) + IngestVEXStatements(ctx context.Context, subjects model.PackageOrArtifactInputs, vulnerabilities []*model.IDorVulnerabilityInput, vexStatements []*model.VexStatementInputSpec) ([]string, error) + IngestVulnEqual(ctx context.Context, vulnerability model.IDorVulnerabilityInput, otherVulnerability model.IDorVulnerabilityInput, vulnEqual model.VulnEqualInputSpec) (string, error) + IngestVulnEquals(ctx context.Context, vulnerabilities []*model.IDorVulnerabilityInput, otherVulnerabilities []*model.IDorVulnerabilityInput, vulnEquals []*model.VulnEqualInputSpec) ([]string, error) + IngestVulnerabilityMetadata(ctx context.Context, vulnerability model.IDorVulnerabilityInput, vulnerabilityMetadata model.VulnerabilityMetadataInputSpec) (string, error) + IngestBulkVulnerabilityMetadata(ctx context.Context, vulnerabilities []*model.IDorVulnerabilityInput, vulnerabilityMetadataList []*model.VulnerabilityMetadataInputSpec) ([]string, error) // Topological queries: queries where node connectivity matters more than node type Neighbors(ctx context.Context, node string, usingOnly []model.Edge) ([]model.Node, error) diff --git a/pkg/assembler/backends/ent/backend/artifact.go b/pkg/assembler/backends/ent/backend/artifact.go index 637a4d6341..8dd211b87d 100644 --- a/pkg/assembler/backends/ent/backend/artifact.go +++ b/pkg/assembler/backends/ent/backend/artifact.go @@ -66,7 +66,7 @@ func toLowerPtr(s *string) *string { return &lower } -func (b *EntBackend) IngestArtifacts(ctx context.Context, artifacts []*model.ArtifactInputSpec) ([]string, error) { +func (b *EntBackend) IngestArtifacts(ctx context.Context, artifacts []*model.IDorArtifactInput) ([]string, error) { funcName := "IngestArtifacts" artsID := make([]string, len(artifacts)) eg, ctx := errgroup.WithContext(ctx) @@ -87,10 +87,10 @@ func (b *EntBackend) IngestArtifacts(ctx context.Context, artifacts []*model.Art return artsID, nil } -func (b *EntBackend) IngestArtifact(ctx context.Context, art *model.ArtifactInputSpec) (string, error) { +func (b *EntBackend) IngestArtifact(ctx context.Context, art *model.IDorArtifactInput) (string, error) { id, err := WithinTX(ctx, b.client, func(ctx context.Context) (*int, error) { client := ent.TxFromContext(ctx) - return upsertArtifact(ctx, client, art) + return upsertArtifact(ctx, client, art.ArtifactInput) }) if err != nil { return "", err diff --git a/pkg/assembler/backends/ent/backend/artifact_test.go b/pkg/assembler/backends/ent/backend/artifact_test.go deleted file mode 100644 index 5f19cf8fb6..0000000000 --- a/pkg/assembler/backends/ent/backend/artifact_test.go +++ /dev/null @@ -1,65 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build integration - -package backend - -import ( - "sort" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -func (s *Suite) Test_IngestArtifacts() { - tests := []struct { - name string - artifactInputs []*model.ArtifactInputSpec - want []string - wantErr bool - }{{ - name: "sha256", - artifactInputs: []*model.ArtifactInputSpec{{ - Algorithm: "sha256", - Digest: "6bbb0da1891646e58eb3e6a63af3a6fc3c8eb5a0d44824cba581d2e14a0450cf", - }, { - Algorithm: "sha1", - Digest: "7a8f47318e4676dacb0142afa0b83029cd7befd9", - }, { - Algorithm: "sha512", - Digest: "374ab8f711235830769aa5f0b31ce9b72c5670074b34cb302cdafe3b606233ee92ee01e298e5701f15cc7087714cd9abd7ddb838a6e1206b3642de16d9fc9dd7", - }}, - want: []string{"1", "2", "3"}, - wantErr: false, - }} - - for _, tt := range tests { - s.Run(tt.name, func() { - be, err := GetBackend(s.Client) - s.NoError(err) - - got, err := be.IngestArtifacts(s.Ctx, tt.artifactInputs) - if (err != nil) != tt.wantErr { - s.T().Errorf("demoClient.IngestArtifacts() error = %v, wantErr %v", err, tt.wantErr) - return - } - sort.Strings(got) - if diff := cmp.Diff(tt.want, got, ignoreID); diff != "" { - s.T().Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} diff --git a/pkg/assembler/backends/ent/backend/builders.go b/pkg/assembler/backends/ent/backend/builders.go index 8a3b93b4d0..9ac7acb262 100644 --- a/pkg/assembler/backends/ent/backend/builders.go +++ b/pkg/assembler/backends/ent/backend/builders.go @@ -58,11 +58,11 @@ func builderInputQueryPredicate(spec model.BuilderInputSpec) predicate.Builder { return builder.URIEqualFold(spec.URI) } -func (b *EntBackend) IngestBuilder(ctx context.Context, build *model.BuilderInputSpec) (string, error) { +func (b *EntBackend) IngestBuilder(ctx context.Context, build *model.IDorBuilderInput) (string, error) { funcName := "IngestBuilder" id, err := WithinTX(ctx, b.client, func(ctx context.Context) (*int, error) { client := ent.TxFromContext(ctx) - return upsertBuilder(ctx, client, build) + return upsertBuilder(ctx, client, build.BuilderInput) }) if err != nil { return "", errors.Wrap(err, funcName) @@ -70,7 +70,7 @@ func (b *EntBackend) IngestBuilder(ctx context.Context, build *model.BuilderInpu return strconv.Itoa(*id), nil } -func (b *EntBackend) IngestBuilders(ctx context.Context, builders []*model.BuilderInputSpec) ([]string, error) { +func (b *EntBackend) IngestBuilders(ctx context.Context, builders []*model.IDorBuilderInput) ([]string, error) { buildersID := make([]string, len(builders)) eg, ctx := errgroup.WithContext(ctx) for i := range builders { diff --git a/pkg/assembler/backends/ent/backend/builders_test.go b/pkg/assembler/backends/ent/backend/builders_test.go deleted file mode 100644 index 1b5e370692..0000000000 --- a/pkg/assembler/backends/ent/backend/builders_test.go +++ /dev/null @@ -1,307 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build integration - -package backend - -import ( - "context" - - "github.com/google/go-cmp/cmp" - - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -func (s *Suite) TestIngestBuilder() { - tests := []struct { - name string - builderInput *model.BuilderInputSpec - want *model.Builder - wantErr bool - }{{ - name: "HubHostedActions", - builderInput: &model.BuilderInputSpec{ - URI: "https://github.com/CreateFork/HubHostedActions@v1", - }, - want: &model.Builder{ - URI: "https://github.com/CreateFork/HubHostedActions@v1", - }, - wantErr: false, - }, { - name: "chains", - builderInput: &model.BuilderInputSpec{ - URI: "https://tekton.dev/chains/v2", - }, - want: &model.Builder{ - URI: "https://tekton.dev/chains/v2", - }, - wantErr: false, - }} - ctx := s.Ctx - for _, tt := range tests { - s.Run(tt.name, func() { - t := s.T() - b, err := GetBackend(s.Client) - if err != nil { - t.Fatalf("GetBackend() error = %v", err) - } - id, err := b.IngestBuilder(ctx, tt.builderInput) - if (err != nil) != tt.wantErr { - t.Errorf("demoClient.IngestBuilder() error = %v, wantErr %v", err, tt.wantErr) - return - } - - got, err := b.Builders(ctx, &model.BuilderSpec{ID: &id}) - if err != nil { - t.Fatalf("Builders() error = %v", err) - } - if diff := cmp.Diff(tt.want, got[0], ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func (s *Suite) TestIngestBuilders() { - tests := []struct { - name string - builderInputs []*model.BuilderInputSpec - want []*model.Builder - wantErr bool - }{{ - name: "HubHostedActions", - builderInputs: []*model.BuilderInputSpec{ - { - URI: "https://github.com/CreateFork/HubHostedActions@v1", - }, - { - URI: "https://tekton.dev/chains/v2", - }}, - want: []*model.Builder{ - { - URI: "https://github.com/CreateFork/HubHostedActions@v1", - }, - { - URI: "https://tekton.dev/chains/v2", - }}, - wantErr: false, - }} - ctx := s.Ctx - for index, tt := range tests { - s.Run(tt.name, func() { - t := s.T() - b, err := GetBackend(s.Client) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - ids, err := b.IngestBuilders(ctx, tt.builderInputs) - if (err != nil) != tt.wantErr { - t.Errorf("demoClient.IngestBuilder() error = %v, wantErr %v", err, tt.wantErr) - return - } - got, err := b.Builders(ctx, &model.BuilderSpec{ID: &ids[index]}) - if err != nil { - t.Fatalf("Builders() error = %v", err) - } - if diff := cmp.Diff(tt.want[index], got[index], ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func (s *Suite) TestBuilders() { - tests := []struct { - name string - builderInput *model.BuilderInputSpec - builderSpec *model.BuilderSpec - idInFilter bool - want []*model.Builder - wantErr bool - }{{ - name: "HubHostedActions", - builderInput: &model.BuilderInputSpec{ - URI: "https://github.com/CreateFork/HubHostedActions@v1", - }, - builderSpec: &model.BuilderSpec{ - URI: ptrfrom.String("https://github.com/CreateFork/HubHostedActions@v1"), - }, - want: []*model.Builder{{ - URI: "https://github.com/CreateFork/HubHostedActions@v1", - }}, - wantErr: false, - }, { - name: "chains", - builderInput: &model.BuilderInputSpec{ - URI: "https://tekton.dev/chains/v2", - }, - builderSpec: &model.BuilderSpec{ - URI: ptrfrom.String("https://tekton.dev/chains/v2"), - }, - idInFilter: true, - want: []*model.Builder{{ - URI: "https://tekton.dev/chains/v2", - }}, - wantErr: false, - }, { - name: "chains", - builderInput: &model.BuilderInputSpec{ - URI: "https://tekton.dev/chains/v2", - }, - builderSpec: &model.BuilderSpec{}, - want: []*model.Builder{{ - URI: "https://tekton.dev/chains/v2", - }}, - wantErr: false, - }} - ctx := s.Ctx - for _, tt := range tests { - s.Run(tt.name, func() { - t := s.T() - b, err := GetBackend(s.Client) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - id, err := b.IngestBuilder(ctx, tt.builderInput) - if (err != nil) != tt.wantErr { - t.Errorf("demoClient.IngestBuilder() error = %v, wantErr %v", err, tt.wantErr) - return - } - if tt.idInFilter { - tt.builderSpec.ID = &id - } - got, err := b.Builders(ctx, tt.builderSpec) - if (err != nil) != tt.wantErr { - t.Errorf("demoClient.Builders() error = %v, wantErr %v", err, tt.wantErr) - return - } - if diff := cmp.Diff(tt.want, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func (s *Suite) TestExactBuilder() { - ctx := context.Background() - tests := []struct { - name string - builderInput *model.BuilderInputSpec - builderSpec *model.BuilderSpec - idInFilter bool - want []*model.Builder - wantErr bool - }{{ - name: "HubHostedActions", - builderInput: &model.BuilderInputSpec{ - URI: "https://github.com/CreateFork/HubHostedActions@v1", - }, - builderSpec: &model.BuilderSpec{ - URI: ptrfrom.String("https://github.com/CreateFork/HubHostedActions@v1"), - }, - want: []*model.Builder{ - { - URI: "https://github.com/CreateFork/HubHostedActions@v1", - }, - }, - wantErr: false, - }, { - name: "chains", - builderInput: &model.BuilderInputSpec{ - URI: "https://tekton.dev/chains/v2", - }, - builderSpec: &model.BuilderSpec{ - URI: ptrfrom.String("https://tekton.dev/chains/v2"), - }, - idInFilter: true, - want: []*model.Builder{ - { - URI: "https://tekton.dev/chains/v2", - }, - }, - wantErr: false, - }} - for _, tt := range tests { - s.Run(tt.name, func() { - t := s.T() - b, err := GetBackend(s.Client) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - id, err := b.IngestBuilder(ctx, tt.builderInput) - if (err != nil) != tt.wantErr { - t.Errorf("demoClient.IngestBuilder() error = %v, wantErr %v", err, tt.wantErr) - return - } - if tt.idInFilter { - tt.builderSpec.ID = &id - } - got, err := b.Builders(ctx, tt.builderSpec) - if (err != nil) != tt.wantErr { - t.Errorf("demoClient.exactBuilder() error = %v, wantErr %v", err, tt.wantErr) - return - } - if diff := cmp.Diff(tt.want, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -// This test is to traverse the other branches of the upsert, not covered by the happy path at the insertion, -// when the create fails due to the presence of the input in the store, and a where query is used in the error branch -func (s *Suite) TestBuildersIngestSameTwice() { - - tests := []struct { - name string - builderInputsSpec []*model.BuilderInputSpec - }{{ - name: "IngestSameTwice", - builderInputsSpec: []*model.BuilderInputSpec{ - { - URI: "https://github.com/CreateFork/HubHostedActions@v1", - }, - { - URI: "https://github.com/CreateFork/HubHostedActions@v1", - }, - }, - }} - - ctx := s.Ctx - for _, tt := range tests { - s.Run(tt.name, func() { - t := s.T() - b, err := GetBackend(s.Client) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - - for _, bIn := range tt.builderInputsSpec { - if _, err := b.IngestBuilder(ctx, bIn); err != nil { - t.Fatalf("Could not ingest builder: %v , err: %v", bIn, err) - } - } - items, err := b.Builders(ctx, &model.BuilderSpec{}) - if err != nil { - t.Fatalf("Error on load Builders %v", err) - } - if len(items) == 2 { - t.Fatalf("Wrong ingestions, ingest same twice found two") - } - }) - } -} diff --git a/pkg/assembler/backends/ent/backend/certify.go b/pkg/assembler/backends/ent/backend/certify.go index a2436762f9..e22860235f 100644 --- a/pkg/assembler/backends/ent/backend/certify.go +++ b/pkg/assembler/backends/ent/backend/certify.go @@ -203,7 +203,7 @@ func upsertCertification[T certificationInputSpec](ctx context.Context, client * switch { case subject.Artifact != nil: - art, err := client.Artifact.Query().Where(artifactQueryInputPredicates(*subject.Artifact)).Only(ctx) + art, err := client.Artifact.Query().Where(artifactQueryInputPredicates(*subject.Artifact.ArtifactInput)).Only(ctx) if err != nil { return nil, err } @@ -218,7 +218,7 @@ func upsertCertification[T certificationInputSpec](ctx context.Context, client * case subject.Package != nil: if pkgMatchType.Pkg == model.PkgMatchTypeSpecificVersion { - pv, err := getPkgVersion(ctx, client.Client(), *subject.Package) + pv, err := getPkgVersion(ctx, client.Client(), *subject.Package.PackageInput) if err != nil { return nil, err } @@ -231,7 +231,7 @@ func upsertCertification[T certificationInputSpec](ctx context.Context, client * sql.IsNull(certification.FieldSourceID), ) } else { - pn, err := getPkgName(ctx, client.Client(), *subject.Package) + pn, err := getPkgName(ctx, client.Client(), *subject.Package.PackageInput) if err != nil { return nil, err } @@ -246,7 +246,7 @@ func upsertCertification[T certificationInputSpec](ctx context.Context, client * } case subject.Source != nil: - srcID, err := getSourceNameID(ctx, client.Client(), *subject.Source) + srcID, err := getSourceNameID(ctx, client.Client(), *subject.Source.SourceInput) if err != nil { return nil, err } diff --git a/pkg/assembler/backends/ent/backend/certifyLegal.go b/pkg/assembler/backends/ent/backend/certifyLegal.go index 4c01cfa749..87bcab9830 100644 --- a/pkg/assembler/backends/ent/backend/certifyLegal.go +++ b/pkg/assembler/backends/ent/backend/certifyLegal.go @@ -69,7 +69,7 @@ func (b *EntBackend) CertifyLegal(ctx context.Context, spec *model.CertifyLegalS return collect(records, toModelCertifyLegal), nil } -func (b *EntBackend) IngestCertifyLegals(ctx context.Context, subjects model.PackageOrSourceInputs, declaredLicensesList [][]*model.LicenseInputSpec, discoveredLicensesList [][]*model.LicenseInputSpec, certifyLegals []*model.CertifyLegalInputSpec) ([]string, error) { +func (b *EntBackend) IngestCertifyLegals(ctx context.Context, subjects model.PackageOrSourceInputs, declaredLicensesList [][]*model.IDorLicenseInput, discoveredLicensesList [][]*model.IDorLicenseInput, certifyLegals []*model.CertifyLegalInputSpec) ([]string, error) { modelCertifyLegals := make([]string, len(certifyLegals)) eg, ctx := errgroup.WithContext(ctx) for i := range certifyLegals { @@ -97,7 +97,7 @@ func (b *EntBackend) IngestCertifyLegals(ctx context.Context, subjects model.Pac return modelCertifyLegals, nil } -func (b *EntBackend) IngestCertifyLegal(ctx context.Context, subject model.PackageOrSourceInput, declaredLicenses []*model.LicenseInputSpec, discoveredLicenses []*model.LicenseInputSpec, spec *model.CertifyLegalInputSpec) (string, error) { +func (b *EntBackend) IngestCertifyLegal(ctx context.Context, subject model.PackageOrSourceInput, declaredLicenses []*model.IDorLicenseInput, discoveredLicenses []*model.IDorLicenseInput, spec *model.CertifyLegalInputSpec) (string, error) { recordID, err := WithinTX(ctx, b.client, func(ctx context.Context) (*int, error) { tx := ent.TxFromContext(ctx) @@ -127,7 +127,7 @@ func (b *EntBackend) IngestCertifyLegal(ctx context.Context, subject model.Packa var conflictWhere *sql.Predicate if subject.Package != nil { - pkgVersion, err := getPkgVersion(ctx, client, *subject.Package) + pkgVersion, err := getPkgVersion(ctx, client, *subject.Package.PackageInput) if err != nil { return nil, errors.Wrap(err, "failed to get package version") } @@ -138,7 +138,7 @@ func (b *EntBackend) IngestCertifyLegal(ctx context.Context, subject model.Packa sql.IsNull(certifylegal.FieldSourceID), ) } else if subject.Source != nil { - srcNameID, err := getSourceNameID(ctx, client, *subject.Source) + srcNameID, err := getSourceNameID(ctx, client, *subject.Source.SourceInput) if err != nil { return nil, errors.Wrap(err, "failed to get source name ID") } @@ -152,7 +152,7 @@ func (b *EntBackend) IngestCertifyLegal(ctx context.Context, subject model.Packa declaredLicenseIDs := make([]int, len(declaredLicenses)) for i := range declaredLicenses { - licenseID, err := getLicenseID(ctx, client, *declaredLicenses[i]) + licenseID, err := getLicenseID(ctx, client, *declaredLicenses[i].LicenseInput) if err != nil { return nil, errors.Wrap(err, "failed to get license ID") } @@ -163,7 +163,7 @@ func (b *EntBackend) IngestCertifyLegal(ctx context.Context, subject model.Packa discoveredLicenseIDs := make([]int, len(discoveredLicenses)) for i := range discoveredLicenses { - licenseID, err := getLicenseID(ctx, client, *discoveredLicenses[i]) + licenseID, err := getLicenseID(ctx, client, *discoveredLicenses[i].LicenseInput) if err != nil { return nil, err } @@ -293,15 +293,15 @@ func certifyLegalQuery(filter model.CertifyLegalSpec) predicate.CertifyLegal { return certifylegal.And(predicates...) } -func certifyLegalInputQuery(subject model.PackageOrSourceInput, declaredLicenses []*model.LicenseInputSpec, discoveredLicenses []*model.LicenseInputSpec, filter model.CertifyLegalInputSpec) predicate.CertifyLegal { +func certifyLegalInputQuery(subject model.PackageOrSourceInput, declaredLicenses []*model.IDorLicenseInput, discoveredLicenses []*model.IDorLicenseInput, filter model.CertifyLegalInputSpec) predicate.CertifyLegal { var subjectSpec *model.PackageOrSourceSpec if subject.Package != nil { subjectSpec = &model.PackageOrSourceSpec{ - Package: helper.ConvertPkgInputSpecToPkgSpec(subject.Package), + Package: helper.ConvertPkgInputSpecToPkgSpec(subject.Package.PackageInput), } } else { subjectSpec = &model.PackageOrSourceSpec{ - Source: helper.ConvertSrcInputSpecToSrcSpec(subject.Source), + Source: helper.ConvertSrcInputSpecToSrcSpec(subject.Source.SourceInput), } } declaredLicenseSpecs := collect(declaredLicenses, helper.ConvertLicenseInputSpecToLicenseSpec) diff --git a/pkg/assembler/backends/ent/backend/certifyLegal_test.go b/pkg/assembler/backends/ent/backend/certifyLegal_test.go deleted file mode 100644 index d5d912d618..0000000000 --- a/pkg/assembler/backends/ent/backend/certifyLegal_test.go +++ /dev/null @@ -1,616 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build integration - -package backend - -import ( - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/internal/testing/testdata" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -func (s *Suite) TestLegal() { - type call struct { - PkgSrc model.PackageOrSourceInput - Dec []*model.LicenseInputSpec - Dis []*model.LicenseInputSpec - Legal *model.CertifyLegalInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - InLic []*model.LicenseInputSpec - Calls []call - Query *model.CertifyLegalSpec - ExpLegal []*model.CertifyLegal - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InLic: []*model.LicenseInputSpec{testdata.L1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Dec: []*model.LicenseInputSpec{testdata.L1}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyLegalSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpLegal: []*model.CertifyLegal{ - { - Subject: testdata.P1out, - DeclaredLicenses: []*model.License{testdata.L1out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest same twice", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InLic: []*model.LicenseInputSpec{testdata.L1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Dec: []*model.LicenseInputSpec{testdata.L1}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Dec: []*model.LicenseInputSpec{testdata.L1}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyLegalSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpLegal: []*model.CertifyLegal{ - { - Subject: testdata.P1out, - DeclaredLicenses: []*model.License{testdata.L1out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Justification", - InPkg: []*model.PkgInputSpec{testdata.P1}, - InLic: []*model.LicenseInputSpec{testdata.L1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Dec: []*model.LicenseInputSpec{testdata.L1}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Dec: []*model.LicenseInputSpec{testdata.L1}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification 2", - }, - }, - }, - Query: &model.CertifyLegalSpec{ - Justification: ptrfrom.String("test justification 2"), - }, - ExpLegal: []*model.CertifyLegal{ - { - Subject: testdata.P1out, - DeclaredLicenses: []*model.License{testdata.L1out}, - Justification: "test justification 2", - }, - }, - }, - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - InLic: []*model.LicenseInputSpec{testdata.L1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Dec: []*model.LicenseInputSpec{testdata.L1}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P2, - }, - Dec: []*model.LicenseInputSpec{testdata.L1}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyLegalSpec{ - Subject: &model.PackageOrSourceSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String(""), - }, - }, - }, - ExpLegal: []*model.CertifyLegal{ - { - Subject: testdata.P1out, - DeclaredLicenses: []*model.License{testdata.L1out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Source", - InSrc: []*model.SourceInputSpec{testdata.S1, testdata.S2}, - InLic: []*model.LicenseInputSpec{testdata.L1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Source: testdata.S1, - }, - Dec: []*model.LicenseInputSpec{testdata.L1}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Source: testdata.S2, - }, - Dec: []*model.LicenseInputSpec{testdata.L1}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyLegalSpec{ - Subject: &model.PackageOrSourceSpec{ - Source: &model.SourceSpec{ - Name: ptrfrom.String("myrepo"), - }, - }, - }, - ExpLegal: []*model.CertifyLegal{ - { - Subject: testdata.S1out, - DeclaredLicenses: []*model.License{testdata.L1out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on License", - InSrc: []*model.SourceInputSpec{testdata.S1}, - InLic: []*model.LicenseInputSpec{testdata.L1, testdata.L2, testdata.L3}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Source: testdata.S1, - }, - Dec: []*model.LicenseInputSpec{testdata.L1, testdata.L2}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Source: testdata.S1, - }, - Dec: []*model.LicenseInputSpec{testdata.L3}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyLegalSpec{ - DeclaredLicenses: []*model.LicenseSpec{ - {Name: ptrfrom.String("GPL-2.0-or-later")}, - }, - }, - ExpLegal: []*model.CertifyLegal{ - { - Subject: testdata.S1out, - DeclaredLicenses: []*model.License{testdata.L1out, testdata.L2out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on License inline", - InSrc: []*model.SourceInputSpec{testdata.S1}, - InLic: []*model.LicenseInputSpec{testdata.L1, testdata.L2, testdata.L4}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Source: testdata.S1, - }, - Dec: []*model.LicenseInputSpec{testdata.L1, testdata.L4}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Source: testdata.S1, - }, - Dec: []*model.LicenseInputSpec{testdata.L2}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyLegalSpec{ - DeclaredLicenses: []*model.LicenseSpec{ - {Inline: &testdata.InlineLicense}, - }, - }, - ExpLegal: []*model.CertifyLegal{ - { - Subject: testdata.S1out, - DeclaredLicenses: []*model.License{testdata.L1out, testdata.L4out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on expression", - InPkg: []*model.PkgInputSpec{testdata.P1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Legal: &model.CertifyLegalInputSpec{ - DeclaredLicense: "GPL OR MIT", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Legal: &model.CertifyLegalInputSpec{ - DeclaredLicense: "GPL AND MIT", - }, - }, - }, - Query: &model.CertifyLegalSpec{ - DeclaredLicense: ptrfrom.String("GPL AND MIT"), - }, - ExpLegal: []*model.CertifyLegal{ - { - Subject: testdata.P1out, - DeclaredLicense: "GPL AND MIT", - }, - }, - }, - { - Name: "Query on attribution", - InPkg: []*model.PkgInputSpec{testdata.P1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Legal: &model.CertifyLegalInputSpec{ - Attribution: "Copyright Jeff", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Legal: &model.CertifyLegalInputSpec{ - Attribution: "Copyright Bob", - }, - }, - }, - Query: &model.CertifyLegalSpec{ - Attribution: ptrfrom.String("Copyright Jeff"), - }, - ExpLegal: []*model.CertifyLegal{ - { - Subject: testdata.P1out, - Attribution: "Copyright Jeff", - }, - }, - }, - { - Name: "Query on time", - InPkg: []*model.PkgInputSpec{testdata.P1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Legal: &model.CertifyLegalInputSpec{ - TimeScanned: testdata.T3, - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Legal: &model.CertifyLegalInputSpec{ - TimeScanned: testdata.T2, - }, - }, - }, - Query: &model.CertifyLegalSpec{ - TimeScanned: &testdata.T2, - }, - ExpLegal: []*model.CertifyLegal{ - { - Subject: testdata.P1out, - TimeScanned: testdata.T2, - }, - }, - }, - { - Name: "Query multiple", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2, testdata.P3}, - InLic: []*model.LicenseInputSpec{testdata.L1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Dec: []*model.LicenseInputSpec{testdata.L1}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P2, - }, - Dec: []*model.LicenseInputSpec{testdata.L1}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P3, - }, - Dec: []*model.LicenseInputSpec{testdata.L1}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification other", - }, - }, - }, - Query: &model.CertifyLegalSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpLegal: []*model.CertifyLegal{ - { - Subject: testdata.P1out, - DeclaredLicenses: []*model.License{testdata.L1out}, - Justification: "test justification", - }, - { - Subject: testdata.P2out, - DeclaredLicenses: []*model.License{testdata.L1out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest without Package", - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Legal: &model.CertifyLegalInputSpec{}, - }, - }, - ExpIngestErr: true, - }, - { - Name: "Ingest without Source", - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Source: testdata.S1, - }, - Legal: &model.CertifyLegalInputSpec{}, - }, - }, - ExpIngestErr: true, - }, - { - Name: "Ingest without License", - InPkg: []*model.PkgInputSpec{testdata.P1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Dec: []*model.LicenseInputSpec{testdata.L1}, - Legal: &model.CertifyLegalInputSpec{}, - }, - }, - ExpIngestErr: true, - }, - } - ctx := s.Ctx - for _, test := range tests { - s.Run(test.Name, func() { - t := s.T() - b, err := GetBackend(s.Client) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, a := range test.InLic { - if _, err := b.IngestLicense(ctx, a); err != nil { - t.Fatalf("Could not ingest license: %v", err) - } - } - for _, o := range test.Calls { - _, err := b.IngestCertifyLegal(ctx, o.PkgSrc, o.Dec, o.Dis, o.Legal) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.CertifyLegal(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpLegal, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func (s *Suite) TestLegals() { - type call struct { - PkgSrc model.PackageOrSourceInputs - Dec [][]*model.LicenseInputSpec - Dis [][]*model.LicenseInputSpec - Legal []*model.CertifyLegalInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - InLic []*model.LicenseInputSpec - Calls []call - Query *model.CertifyLegalSpec - ExpLegal []*model.CertifyLegal - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - InLic: []*model.LicenseInputSpec{testdata.L1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInputs{ - Packages: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - }, - Dec: [][]*model.LicenseInputSpec{{testdata.L1}, {testdata.L1}}, - Dis: [][]*model.LicenseInputSpec{{}, {}}, - Legal: []*model.CertifyLegalInputSpec{ - {Justification: "test justification"}, - {Justification: "test justification"}, - }, - }, - }, - Query: &model.CertifyLegalSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpLegal: []*model.CertifyLegal{ - { - Subject: testdata.P1out, - DeclaredLicenses: []*model.License{testdata.L1out}, - Justification: "test justification", - }, - { - Subject: testdata.P2out, - DeclaredLicenses: []*model.License{testdata.L1out}, - Justification: "test justification", - }, - }, - }, - } - ctx := s.Ctx - for _, test := range tests { - s.Run(test.Name, func() { - t := s.T() - b, err := GetBackend(s.Client) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, a := range test.InLic { - if _, err := b.IngestLicense(ctx, a); err != nil { - t.Fatalf("Could not ingest license: %v", err) - } - } - for _, o := range test.Calls { - _, err := b.IngestCertifyLegals(ctx, o.PkgSrc, o.Dec, o.Dis, o.Legal) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.CertifyLegal(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpLegal, got, IngestPredicatesCmpOpts...); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} diff --git a/pkg/assembler/backends/ent/backend/certifyVEXStatement.go b/pkg/assembler/backends/ent/backend/certifyVEXStatement.go index 5f66f0e9f2..576a6741cc 100644 --- a/pkg/assembler/backends/ent/backend/certifyVEXStatement.go +++ b/pkg/assembler/backends/ent/backend/certifyVEXStatement.go @@ -32,7 +32,7 @@ import ( "golang.org/x/sync/errgroup" ) -func (b *EntBackend) IngestVEXStatement(ctx context.Context, subject model.PackageOrArtifactInput, vulnerability model.VulnerabilityInputSpec, vexStatement model.VexStatementInputSpec) (string, error) { +func (b *EntBackend) IngestVEXStatement(ctx context.Context, subject model.PackageOrArtifactInput, vulnerability model.IDorVulnerabilityInput, vexStatement model.VexStatementInputSpec) (string, error) { funcName := "IngestVEXStatement" recordID, err := WithinTX(ctx, b.client, func(ctx context.Context) (*int, error) { @@ -52,8 +52,8 @@ func (b *EntBackend) IngestVEXStatement(ctx context.Context, subject model.Packa // manage vulnerability vulnID, err := client.VulnerabilityID.Query(). Where( - vulnerabilityid.VulnerabilityIDEqualFold(vulnerability.VulnerabilityID), - vulnerabilityid.HasTypeWith(vulnerabilitytype.TypeEqualFold(vulnerability.Type)), + vulnerabilityid.VulnerabilityIDEqualFold(vulnerability.VulnerabilityInput.VulnerabilityID), + vulnerabilityid.HasTypeWith(vulnerabilitytype.TypeEqualFold(vulnerability.VulnerabilityInput.Type)), ). OnlyID(ctx) if err != nil { @@ -65,7 +65,7 @@ func (b *EntBackend) IngestVEXStatement(ctx context.Context, subject model.Packa // manage package or artifact if subject.Package != nil { - p, err := getPkgVersion(ctx, client.Client(), *subject.Package) + p, err := getPkgVersion(ctx, client.Client(), *subject.Package.PackageInput) if err != nil { return nil, Errorf("%v :: %s", funcName, err) } @@ -77,7 +77,7 @@ func (b *EntBackend) IngestVEXStatement(ctx context.Context, subject model.Packa ) } else if subject.Artifact != nil { artID, err := client.Artifact.Query(). - Where(artifactQueryInputPredicates(*subject.Artifact)). + Where(artifactQueryInputPredicates(*subject.Artifact.ArtifactInput)). OnlyID(ctx) if err != nil { return nil, Errorf("%v :: %s", funcName, err) @@ -113,7 +113,7 @@ func (b *EntBackend) IngestVEXStatement(ctx context.Context, subject model.Packa return nil, errors.Wrap(err, "upsert certify vex statement node") } id, err = client.CertifyVex.Query(). - Where(vexStatementInputPredicate(subject, vulnerability, vexStatement)). + Where(vexStatementInputPredicate(subject, *vulnerability.VulnerabilityInput, vexStatement)). WithPackage(func(q *ent.PackageVersionQuery) { q.WithName(func(q *ent.PackageNameQuery) { q.WithNamespace(func(q *ent.PackageNamespaceQuery) { @@ -139,7 +139,7 @@ func (b *EntBackend) IngestVEXStatement(ctx context.Context, subject model.Packa return nodeID(*recordID), nil } -func (b *EntBackend) IngestVEXStatements(ctx context.Context, subjects model.PackageOrArtifactInputs, vulnerabilities []*model.VulnerabilityInputSpec, vexStatements []*model.VexStatementInputSpec) ([]string, error) { +func (b *EntBackend) IngestVEXStatements(ctx context.Context, subjects model.PackageOrArtifactInputs, vulnerabilities []*model.IDorVulnerabilityInput, vexStatements []*model.VexStatementInputSpec) ([]string, error) { var ids = make([]string, len(vexStatements)) eg, ctx := errgroup.WithContext(ctx) for i := range vexStatements { @@ -258,11 +258,11 @@ func vexStatementInputPredicate(subject model.PackageOrArtifactInput, vulnerabil var sub *model.PackageOrArtifactSpec if subject.Package != nil { sub = &model.PackageOrArtifactSpec{ - Package: helper.ConvertPkgInputSpecToPkgSpec(subject.Package), + Package: helper.ConvertPkgInputSpecToPkgSpec(subject.Package.PackageInput), } } else { sub = &model.PackageOrArtifactSpec{ - Artifact: helper.ConvertArtInputSpecToArtSpec(subject.Artifact), + Artifact: helper.ConvertArtInputSpecToArtSpec(subject.Artifact.ArtifactInput), } } return certifyVexPredicate(model.CertifyVEXStatementSpec{ diff --git a/pkg/assembler/backends/ent/backend/certifyVEXStatement_test.go b/pkg/assembler/backends/ent/backend/certifyVEXStatement_test.go deleted file mode 100644 index 46c49009a3..0000000000 --- a/pkg/assembler/backends/ent/backend/certifyVEXStatement_test.go +++ /dev/null @@ -1,1071 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build integration - -package backend - -import ( - "strconv" - "time" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -func (s *Suite) TestVEX() { - testTime := time.Unix(1e9+5, 0) - type call struct { - Sub model.PackageOrArtifactInput - Vuln *model.VulnerabilityInputSpec - In *model.VexStatementInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InArt []*model.ArtifactInputSpec - InVuln []*model.VulnerabilityInputSpec - Calls []call - Query *model.CertifyVEXStatementSpec - ExpVEX []*model.CertifyVEXStatement - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{p1}, - InVuln: []*model.VulnerabilityInputSpec{o1}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: o1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - VexJustification: (*model.VexJustification)(ptrfrom.String("test justification")), - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: p1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - { - Name: "Ingest same twice", - InPkg: []*model.PkgInputSpec{p1}, - InVuln: []*model.VulnerabilityInputSpec{o1}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: o1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: o1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - VexJustification: (*model.VexJustification)(ptrfrom.String("test justification")), - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: p1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - { - Name: "Query on Justification", - InPkg: []*model.PkgInputSpec{p1}, - InVuln: []*model.VulnerabilityInputSpec{o1}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: o1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: o1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification 2", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - VexJustification: (*model.VexJustification)(ptrfrom.String("test justification 2")), - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: p1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o1out}, - }, - VexJustification: "test justification 2", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{p1, p2}, - InArt: []*model.ArtifactInputSpec{a1}, - InVuln: []*model.VulnerabilityInputSpec{o1}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: o1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: p2, - }, - Vuln: o1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Artifact: a1, - }, - Vuln: o1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - Subject: &model.PackageOrArtifactSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String(""), - }, - }, - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: p1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - { - Name: "Query on Artifact", - InPkg: []*model.PkgInputSpec{p1}, - InArt: []*model.ArtifactInputSpec{a1, a2}, - InVuln: []*model.VulnerabilityInputSpec{o1}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: o1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Artifact: a1, - }, - Vuln: o1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Artifact: a2, - }, - Vuln: o1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - Subject: &model.PackageOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha256"), - }, - }, - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: a1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - { - Name: "Query on Vuln", - InPkg: []*model.PkgInputSpec{p1}, - InVuln: []*model.VulnerabilityInputSpec{o1, o2, c1}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: o1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: o2, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: c1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - Vulnerability: &model.VulnerabilitySpec{ - Type: ptrfrom.String("osv"), - VulnerabilityID: ptrfrom.String("cve-2014-8140"), - }, - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: p1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - { - Name: "Query on Status", - InPkg: []*model.PkgInputSpec{p1}, - InVuln: []*model.VulnerabilityInputSpec{c1, o1}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: c1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - Status: "status one", - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: o1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - Status: "status two", - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - Status: (*model.VexStatus)(ptrfrom.String("status one")), - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: p1out, - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - Status: "status one", - }, - }, - }, - { - Name: "Query on Statement", - InPkg: []*model.PkgInputSpec{p1}, - InVuln: []*model.VulnerabilityInputSpec{o1}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: o1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - Statement: "statement one", - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: o1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - Statement: "statement two", - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - Statement: ptrfrom.String("statement two"), - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: p1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - Statement: "statement two", - }, - }, - }, - { - Name: "Query on KnownSince", - InPkg: []*model.PkgInputSpec{p1}, - InVuln: []*model.VulnerabilityInputSpec{o1}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: o1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: o1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: testTime, - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - KnownSince: &testTime, - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: p1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o1out}, - }, - VexJustification: "test justification", - KnownSince: testTime, - }, - }, - }, - { - Name: "Query on ID", - InPkg: []*model.PkgInputSpec{p1}, - InVuln: []*model.VulnerabilityInputSpec{o1, o2}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: o1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: o2, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - ID: ptrfrom.String("0"), - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: p1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - { - Name: "Query None", - InPkg: []*model.PkgInputSpec{p1}, - InVuln: []*model.VulnerabilityInputSpec{o1, o2, c1}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: o1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: o2, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: c1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - Vulnerability: &model.VulnerabilitySpec{ - VulnerabilityID: ptrfrom.String("asdf"), - }, - }, - ExpVEX: nil, - }, - { - Name: "Query multiple", - InPkg: []*model.PkgInputSpec{p1}, - InVuln: []*model.VulnerabilityInputSpec{o1, o2, c1}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: o1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: o2, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification two", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: c1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification two", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - VexJustification: (*model.VexJustification)(ptrfrom.String("test justification two")), - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: p1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o2out}, - }, - VexJustification: "test justification two", - KnownSince: time.Unix(1e9, 0), - }, - { - Subject: p1out, - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out}, - }, - VexJustification: "test justification two", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - { - Name: "Ingest without sub", - InVuln: []*model.VulnerabilityInputSpec{o1}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: o1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - ExpIngestErr: true, - }, - { - Name: "Ingest without vuln", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: o1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - ExpIngestErr: true, - }, - { - Name: "Query bad id", - InPkg: []*model.PkgInputSpec{p1}, - InVuln: []*model.VulnerabilityInputSpec{o1}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: o1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - ID: ptrfrom.String("asdf"), - }, - ExpQueryErr: true, - }, - } - ctx := s.Ctx - for _, test := range tests { - s.Run(test.Name, func() { - t := s.T() - b, err := GetBackend(s.Client) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %a", err) - } - } - for _, v := range test.InVuln { - if _, err := b.IngestVulnerability(ctx, *v); err != nil { - t.Fatalf("Could not ingest vulnerability: %v", err) - } - } - ids := make([]string, len(test.Calls)) - for i, o := range test.Calls { - v, err := b.IngestVEXStatement(ctx, o.Sub, *o.Vuln, *o.In) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - ids[i] = v - } - - if test.Query.ID != nil { - idIdx, err := strconv.Atoi(*test.Query.ID) - if err == nil { - if idIdx < 0 || idIdx >= len(ids) { - s.T().Fatalf("ID index out of range, want: %d, got: %d. So ID %d will be directly used to query", len(ids), idIdx, idIdx) - } - test.Query.ID = ptrfrom.String(ids[idIdx]) - } - } - - got, err := b.CertifyVEXStatement(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpVEX, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func (s *Suite) TestVEXBulkIngest() { - type call struct { - Subs model.PackageOrArtifactInputs - Vulns []*model.VulnerabilityInputSpec - Vexs []*model.VexStatementInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InArt []*model.ArtifactInputSpec - InVuln []*model.VulnerabilityInputSpec - Calls []call - Query *model.CertifyVEXStatementSpec - ExpVEX []*model.CertifyVEXStatement - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{p1}, - InVuln: []*model.VulnerabilityInputSpec{o1}, - Calls: []call{ - { - Subs: model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - Vulns: []*model.VulnerabilityInputSpec{o1}, - Vexs: []*model.VexStatementInputSpec{ - { - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - VexJustification: (*model.VexJustification)(ptrfrom.String("test justification")), - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: p1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - { - Name: "Ingest same twice", - InPkg: []*model.PkgInputSpec{p1}, - InVuln: []*model.VulnerabilityInputSpec{o1}, - Calls: []call{ - { - Subs: model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1, p1}, - }, - Vulns: []*model.VulnerabilityInputSpec{o1, o1}, - Vexs: []*model.VexStatementInputSpec{ - { - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - { - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - VexJustification: (*model.VexJustification)(ptrfrom.String("test justification")), - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: p1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{p1, p2}, - InArt: []*model.ArtifactInputSpec{a1}, - InVuln: []*model.VulnerabilityInputSpec{o1}, - Calls: []call{ - { - Subs: model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1, p2}, - }, - Vulns: []*model.VulnerabilityInputSpec{o1, o1}, - Vexs: []*model.VexStatementInputSpec{ - { - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - { - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - { - Subs: model.PackageOrArtifactInputs{ - Artifacts: []*model.ArtifactInputSpec{a1}, - }, - Vulns: []*model.VulnerabilityInputSpec{o1}, - Vexs: []*model.VexStatementInputSpec{ - { - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - Subject: &model.PackageOrArtifactSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String(""), - }, - }, - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: p1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - { - Name: "Query on Artifact", - InArt: []*model.ArtifactInputSpec{a1, a2}, - InVuln: []*model.VulnerabilityInputSpec{o1}, - Calls: []call{ - { - Subs: model.PackageOrArtifactInputs{ - Artifacts: []*model.ArtifactInputSpec{a1, a2}, - }, - Vulns: []*model.VulnerabilityInputSpec{o1, o1}, - Vexs: []*model.VexStatementInputSpec{ - { - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - { - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - Subject: &model.PackageOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha256"), - }, - }, - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: a1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - { - Name: "Query on Vuln", - InPkg: []*model.PkgInputSpec{p1}, - InVuln: []*model.VulnerabilityInputSpec{o1, o2, c1}, - Calls: []call{ - { - Subs: model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1, p1, p1}, - }, - Vulns: []*model.VulnerabilityInputSpec{o1, o2, c1}, - Vexs: []*model.VexStatementInputSpec{ - { - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - { - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - { - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - Vulnerability: &model.VulnerabilitySpec{ - Type: ptrfrom.String("osv"), - VulnerabilityID: ptrfrom.String("cve-2014-8140"), - }, - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: p1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - { - Name: "Query on Status", - InPkg: []*model.PkgInputSpec{p1}, - InVuln: []*model.VulnerabilityInputSpec{c1, o1}, - Calls: []call{ - { - Subs: model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1, p1}, - }, - Vulns: []*model.VulnerabilityInputSpec{c1, o1}, - Vexs: []*model.VexStatementInputSpec{ - { - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - Status: "status one", - }, - { - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - Status: (*model.VexStatus)(ptrfrom.String("status one")), - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: p1out, - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - Status: "status one", - }, - }, - }, - { - Name: "Query multiple", - InPkg: []*model.PkgInputSpec{p1}, - InVuln: []*model.VulnerabilityInputSpec{o1, o2, c1}, - Calls: []call{ - { - Subs: model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1, p1, p1}, - }, - Vulns: []*model.VulnerabilityInputSpec{o1, o2, c1}, - Vexs: []*model.VexStatementInputSpec{ - { - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - { - VexJustification: "test justification two", - KnownSince: time.Unix(1e9, 0), - }, - { - VexJustification: "test justification two", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - VexJustification: (*model.VexJustification)(ptrfrom.String("test justification two")), - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: p1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o2out}, - }, - VexJustification: "test justification two", - KnownSince: time.Unix(1e9, 0), - }, - { - Subject: p1out, - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out}, - }, - VexJustification: "test justification two", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - } - ctx := s.Ctx - for _, test := range tests { - s.Run(test.Name, func() { - t := s.T() - b, err := GetBackend(s.Client) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - - if _, err := b.IngestPackages(ctx, test.InPkg); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - - if _, err := b.IngestArtifacts(ctx, test.InArt); err != nil { - t.Fatalf("Could not ingest artifact: %a", err) - } - - if _, err := b.IngestVulnerabilities(ctx, test.InVuln); err != nil { - t.Fatalf("Could not ingest vulnerability: %v", err) - } - for _, o := range test.Calls { - _, err := b.IngestVEXStatements(ctx, o.Subs, o.Vulns, o.Vexs) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.CertifyVEXStatement(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpVEX, got, IngestPredicatesCmpOpts...); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} diff --git a/pkg/assembler/backends/ent/backend/certifyVuln.go b/pkg/assembler/backends/ent/backend/certifyVuln.go index 6940009c1e..61bdf82726 100644 --- a/pkg/assembler/backends/ent/backend/certifyVuln.go +++ b/pkg/assembler/backends/ent/backend/certifyVuln.go @@ -33,7 +33,7 @@ import ( "golang.org/x/sync/errgroup" ) -func (b *EntBackend) IngestCertifyVuln(ctx context.Context, pkg model.PkgInputSpec, spec model.VulnerabilityInputSpec, certifyVuln model.ScanMetadataInput) (string, error) { +func (b *EntBackend) IngestCertifyVuln(ctx context.Context, pkg model.IDorPkgInput, spec model.IDorVulnerabilityInput, certifyVuln model.ScanMetadataInput) (string, error) { record, err := WithinTX(ctx, b.client, func(ctx context.Context) (*int, error) { client := ent.TxFromContext(ctx) @@ -49,14 +49,14 @@ func (b *EntBackend) IngestCertifyVuln(ctx context.Context, pkg model.PkgInputSp certifyvuln.FieldDbVersion, } - vuln, err := getVulnerabilityFromInput(ctx, client.Client(), spec) + vuln, err := getVulnerabilityFromInput(ctx, client.Client(), *spec.VulnerabilityInput) if err != nil { return nil, err } insert.SetVulnerability(vuln) columns = append(columns, certifyvuln.FieldVulnerabilityID) - pv, err := getPkgVersion(ctx, client.Client(), pkg) + pv, err := getPkgVersion(ctx, client.Client(), *pkg.PackageInput) if err != nil { return nil, err } @@ -90,7 +90,7 @@ func (b *EntBackend) IngestCertifyVuln(ctx context.Context, pkg model.PkgInputSp return nodeID(*record), nil } -func (b *EntBackend) IngestCertifyVulns(ctx context.Context, pkgs []*model.PkgInputSpec, vulnerabilities []*model.VulnerabilityInputSpec, certifyVulns []*model.ScanMetadataInput) ([]string, error) { +func (b *EntBackend) IngestCertifyVulns(ctx context.Context, pkgs []*model.IDorPkgInput, vulnerabilities []*model.IDorVulnerabilityInput, certifyVulns []*model.ScanMetadataInput) ([]string, error) { var modelCertifyVulns = make([]string, len(vulnerabilities)) eg, ctx := errgroup.WithContext(ctx) for i := range certifyVulns { diff --git a/pkg/assembler/backends/ent/backend/certifyVuln_test.go b/pkg/assembler/backends/ent/backend/certifyVuln_test.go deleted file mode 100644 index db77a8ffe4..0000000000 --- a/pkg/assembler/backends/ent/backend/certifyVuln_test.go +++ /dev/null @@ -1,1077 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build integration - -package backend - -import ( - "context" - "strconv" - "strings" - "time" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -var t1, _ = time.Parse(time.RFC3339, "2023-01-01T00:00:00Z") - -var vmd1 = &model.ScanMetadata{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, -} - -func (s *Suite) TestIngestCertifyVulnerability() { - type call struct { - Pkg *model.PkgInputSpec - Vuln *model.VulnerabilityInputSpec - CertifyVuln *model.ScanMetadataInput - } - - tests := []struct { - InPkg []*model.PkgInputSpec - Name string - InVuln []*model.VulnerabilityInputSpec - Calls []call - ExpVuln []*model.CertifyVuln - Query *model.CertifyVulnSpec - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InVuln: []*model.VulnerabilityInputSpec{c1}, - InPkg: []*model.PkgInputSpec{p2}, - Calls: []call{ - { - Pkg: p2, - Vuln: c1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Collector: ptrfrom.String("test collector"), - }, - ExpVuln: []*model.CertifyVuln{ - { - ID: "1", - Package: p2out, - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Certify NoVuln", - InVuln: []*model.VulnerabilityInputSpec{noVulnInput}, - InPkg: []*model.PkgInputSpec{p2}, - Calls: []call{ - { - Pkg: p2, - Vuln: noVulnInput, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Collector: ptrfrom.String("test collector"), - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: p2out, - Vulnerability: &model.Vulnerability{ - Type: "novuln", - VulnerabilityIDs: []*model.VulnerabilityID{noVulnOut}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Certify OSV", - InVuln: []*model.VulnerabilityInputSpec{o1}, - InPkg: []*model.PkgInputSpec{p2}, - Calls: []call{ - { - Pkg: p2, - Vuln: o1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Collector: ptrfrom.String("test collector"), - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: p2out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o1out}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Certify GHSA", - InVuln: []*model.VulnerabilityInputSpec{g1}, - InPkg: []*model.PkgInputSpec{p2}, - Calls: []call{ - { - Pkg: p2, - Vuln: g1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Collector: ptrfrom.String("test collector"), - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: p2out, - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{g1out}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Query on GHSA", - InVuln: []*model.VulnerabilityInputSpec{g1}, - InPkg: []*model.PkgInputSpec{p2}, - Calls: []call{ - { - Pkg: p2, - Vuln: g1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Vulnerability: &model.VulnerabilitySpec{ - VulnerabilityID: &g1.VulnerabilityID, - }, - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: p2out, - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{g1out}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Query ID", - InVuln: []*model.VulnerabilityInputSpec{g1}, - InPkg: []*model.PkgInputSpec{p2}, - Calls: []call{ - { - Pkg: p2, - Vuln: g1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - ID: ptrfrom.String("0"), - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: p2out, - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{g1out}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Query on Package", - InVuln: []*model.VulnerabilityInputSpec{g1}, - InPkg: []*model.PkgInputSpec{p2}, - Calls: []call{ - { - Pkg: p2, - Vuln: g1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Package: &model.PkgSpec{ - Name: ptrfrom.String(p2.Name), - }, - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: p2out, - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{g1out}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Query none", - InVuln: []*model.VulnerabilityInputSpec{g1}, - InPkg: []*model.PkgInputSpec{p2}, - Calls: []call{ - { - Pkg: p2, - Vuln: g1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Vulnerability: &model.VulnerabilitySpec{ - VulnerabilityID: ptrfrom.String("asdf"), - }, - }, - ExpVuln: nil, - }, - { - Name: "Query No Vuln", - InVuln: []*model.VulnerabilityInputSpec{noVulnInput}, - InPkg: []*model.PkgInputSpec{p2}, - Calls: []call{ - { - Pkg: p2, - Vuln: noVulnInput, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Vulnerability: &model.VulnerabilitySpec{ - Type: ptrfrom.String("noVuln"), - }, - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: p2out, - Vulnerability: &model.Vulnerability{ - Type: "novuln", - VulnerabilityIDs: []*model.VulnerabilityID{noVulnOut}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Query No Vuln - with novuln boolean", - InVuln: []*model.VulnerabilityInputSpec{noVulnInput, c1}, - InPkg: []*model.PkgInputSpec{p2, p1}, - Calls: []call{ - { - Pkg: p2, - Vuln: noVulnInput, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - { - Pkg: p1, - Vuln: c1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Vulnerability: &model.VulnerabilitySpec{ - NoVuln: ptrfrom.Bool(true), - }, - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: p2out, - Vulnerability: &model.Vulnerability{ - Type: "novuln", - VulnerabilityIDs: []*model.VulnerabilityID{noVulnOut}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Query only cve (exclude novuln) - with novuln boolean", - InVuln: []*model.VulnerabilityInputSpec{noVulnInput, c1}, - InPkg: []*model.PkgInputSpec{p2, p1}, - Calls: []call{ - { - Pkg: p2, - Vuln: noVulnInput, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - { - Pkg: p1, - Vuln: c1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Vulnerability: &model.VulnerabilitySpec{ - NoVuln: ptrfrom.Bool(false), - }, - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: p1out, - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Query all vulns - with novuln boolean omitted", - InVuln: []*model.VulnerabilityInputSpec{noVulnInput, c1, g1}, - InPkg: []*model.PkgInputSpec{p2, p1, p1}, - Calls: []call{ - { - Pkg: p2, - Vuln: noVulnInput, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - { - Pkg: p1, - Vuln: c1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - { - Pkg: p1, - Vuln: g1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Vulnerability: &model.VulnerabilitySpec{}, - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: p2out, - Vulnerability: &model.Vulnerability{ - Type: "novuln", - VulnerabilityIDs: []*model.VulnerabilityID{noVulnOut}, - }, - Metadata: vmd1, - }, - { - Package: p1out, - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out}, - }, - Metadata: vmd1, - }, - { - Package: p1out, - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{g1out}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Ingest without vuln", - InPkg: []*model.PkgInputSpec{p2}, - Calls: []call{ - { - Pkg: p2, - Vuln: &model.VulnerabilityInputSpec{}, - CertifyVuln: &model.ScanMetadataInput{}, - }, - }, - Query: &model.CertifyVulnSpec{}, - ExpIngestErr: true, - }, - { - Name: "Ingest missing pkg", - InPkg: []*model.PkgInputSpec{}, - Calls: []call{ - { - Pkg: p2, - Vuln: &model.VulnerabilityInputSpec{}, - CertifyVuln: &model.ScanMetadataInput{}, - }, - }, - Query: &model.CertifyVulnSpec{}, - ExpIngestErr: true, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, test := range tests { - s.Run(test.Name, func() { - ctx := s.Ctx - t := s.T() - b, err := GetBackend(s.Client) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - - for _, g := range test.InVuln { - if _, err := b.IngestVulnerability(ctx, *g); err != nil { - t.Fatalf("Could not ingest vulnerability: %a", err) - } - } - if _, err := b.IngestPackages(ctx, test.InPkg); err != nil { - t.Fatalf("Could not ingest packages: %v", err) - } - - recordIDs := make([]string, len(test.Calls)) - for i, o := range test.Calls { - record, err := b.IngestCertifyVuln(ctx, *o.Pkg, *o.Vuln, *o.CertifyVuln) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - recordIDs[i] = record - } - - if test.Query.ID != nil { - idIdx, err := strconv.Atoi(*test.Query.ID) - if err == nil { - if idIdx < 0 || idIdx >= len(recordIDs) { - s.T().Logf("ID index out of range, want: %d, got: %d. So ID %d will be directly used to query.", len(recordIDs), idIdx, idIdx) - } else { - realID := recordIDs[idIdx] - test.Query.ID = &realID - } - } - } - - got, err := b.CertifyVuln(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpVuln, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func (s *Suite) TestIngestCertifyVulns() { - type call struct { - Pkgs []*model.PkgInputSpec - Vulns []*model.VulnerabilityInputSpec - CertifyVulns []*model.ScanMetadataInput - } - - tests := []struct { - InPkg []*model.PkgInputSpec - Name string - InVuln []*model.VulnerabilityInputSpec - Calls []call - ExpVuln []*model.CertifyVuln - Query *model.CertifyVulnSpec - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InVuln: []*model.VulnerabilityInputSpec{c1, c2}, - InPkg: []*model.PkgInputSpec{p1, p2}, - Calls: []call{ - { - Pkgs: []*model.PkgInputSpec{p2, p1}, - Vulns: []*model.VulnerabilityInputSpec{c1, c2}, - CertifyVulns: []*model.ScanMetadataInput{ - { - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - { - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Collector: ptrfrom.String("test collector"), - }, - ExpVuln: []*model.CertifyVuln{ - { - ID: "1", - Package: p2out, - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out}, - }, - Metadata: vmd1, - }, - { - ID: "10", - Package: p1out, - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c2out}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Certify NoVuln", - InVuln: []*model.VulnerabilityInputSpec{noVulnInput, noVulnInput}, - InPkg: []*model.PkgInputSpec{p2, p1}, - Calls: []call{ - { - Pkgs: []*model.PkgInputSpec{p2, p1}, - Vulns: []*model.VulnerabilityInputSpec{noVulnInput, noVulnInput}, - CertifyVulns: []*model.ScanMetadataInput{ - { - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - { - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Collector: ptrfrom.String("test collector"), - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: p2out, - Vulnerability: &model.Vulnerability{ - Type: "novuln", - VulnerabilityIDs: []*model.VulnerabilityID{noVulnOut}, - }, - Metadata: vmd1, - }, - { - Package: p1out, - Vulnerability: &model.Vulnerability{ - Type: "novuln", - VulnerabilityIDs: []*model.VulnerabilityID{noVulnOut}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Certify OSV", - InVuln: []*model.VulnerabilityInputSpec{o1}, - InPkg: []*model.PkgInputSpec{p2}, - Calls: []call{ - { - Pkgs: []*model.PkgInputSpec{p2}, - Vulns: []*model.VulnerabilityInputSpec{o1}, - CertifyVulns: []*model.ScanMetadataInput{ - &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Collector: ptrfrom.String("test collector"), - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: p2out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o1out}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Certify GHSA", - InVuln: []*model.VulnerabilityInputSpec{g1}, - InPkg: []*model.PkgInputSpec{p2}, - Calls: []call{ - { - Pkgs: []*model.PkgInputSpec{p2}, - Vulns: []*model.VulnerabilityInputSpec{g1}, - CertifyVulns: []*model.ScanMetadataInput{ - &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Collector: ptrfrom.String("test collector"), - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: p2out, - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{g1out}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Query on GHSA", - InVuln: []*model.VulnerabilityInputSpec{g1, g2}, - InPkg: []*model.PkgInputSpec{p2, p1}, - Calls: []call{ - { - Pkgs: []*model.PkgInputSpec{p2, p1}, - Vulns: []*model.VulnerabilityInputSpec{g1, g2}, - CertifyVulns: []*model.ScanMetadataInput{ - { - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - { - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Vulnerability: &model.VulnerabilitySpec{ - VulnerabilityID: &g1.VulnerabilityID, - }, - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: p2out, - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{g1out}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Query ID", - InVuln: []*model.VulnerabilityInputSpec{g1}, - InPkg: []*model.PkgInputSpec{p2}, - Calls: []call{ - { - Pkgs: []*model.PkgInputSpec{p2}, - Vulns: []*model.VulnerabilityInputSpec{g1}, - CertifyVulns: []*model.ScanMetadataInput{ - &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - ID: ptrfrom.String("0"), - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: p2out, - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{g1out}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Query on Package", - InVuln: []*model.VulnerabilityInputSpec{g1, g2}, - InPkg: []*model.PkgInputSpec{p2, p4}, - Calls: []call{ - { - Pkgs: []*model.PkgInputSpec{p2, p4}, - Vulns: []*model.VulnerabilityInputSpec{g1, g2}, - CertifyVulns: []*model.ScanMetadataInput{ - { - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - { - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Package: &model.PkgSpec{ - Name: ptrfrom.String(p2.Name), - }, - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: p2out, - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{g1out}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Query none", - InVuln: []*model.VulnerabilityInputSpec{g1, g2}, - InPkg: []*model.PkgInputSpec{p2, p1}, - Calls: []call{ - { - Pkgs: []*model.PkgInputSpec{p2, p1}, - Vulns: []*model.VulnerabilityInputSpec{g1, g2}, - CertifyVulns: []*model.ScanMetadataInput{ - { - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - { - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Vulnerability: &model.VulnerabilitySpec{ - VulnerabilityID: ptrfrom.String("asdf"), - }, - }, - ExpVuln: nil, - }, - { - Name: "Query No Vuln", - InVuln: []*model.VulnerabilityInputSpec{noVulnInput, noVulnInput}, - InPkg: []*model.PkgInputSpec{p2, p1}, - Calls: []call{ - { - Pkgs: []*model.PkgInputSpec{p2, p1}, - Vulns: []*model.VulnerabilityInputSpec{noVulnInput, noVulnInput}, - CertifyVulns: []*model.ScanMetadataInput{ - { - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - { - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Vulnerability: &model.VulnerabilitySpec{ - Type: ptrfrom.String("noVuln"), - }, - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: p2out, - Vulnerability: &model.Vulnerability{ - Type: "novuln", - VulnerabilityIDs: []*model.VulnerabilityID{noVulnOut}, - }, - Metadata: vmd1, - }, - { - Package: p1out, - Vulnerability: &model.Vulnerability{ - Type: "novuln", - VulnerabilityIDs: []*model.VulnerabilityID{noVulnOut}, - }, - Metadata: vmd1, - }, - }, - }, - } - ctx := context.Background() - for _, test := range tests { - s.Run(test.Name, func() { - t := s.T() - b, err := GetBackend(s.Client) - if err != nil { - t.Fatalf("GetBackend() error = %v", err) - } - - if _, err := b.IngestVulnerabilities(ctx, test.InVuln); err != nil { - t.Fatalf("Could not ingest vulnerabilities: %a", err) - } - if _, err := b.IngestPackages(ctx, test.InPkg); err != nil { - t.Fatalf("Could not ingest packages: %v", err) - } - - recordIDs := make([]string, len(test.Calls)) - for i, o := range test.Calls { - cvs, err := b.IngestCertifyVulns(ctx, o.Pkgs, o.Vulns, o.CertifyVulns) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - recordIDs[i] = cvs[0] - } - - if test.Query.ID != nil { - idIdx, err := strconv.Atoi(*test.Query.ID) - if err == nil { - if idIdx < 0 || idIdx >= len(recordIDs) { - s.T().Logf("ID index out of range, want: %d, got: %d. So ID %d will be directly used to query.", len(recordIDs), idIdx, idIdx) - } else { - test.Query.ID = &recordIDs[idIdx] - } - } - } - - got, err := b.CertifyVuln(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpVuln, got, IngestPredicatesCmpOpts...); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} diff --git a/pkg/assembler/backends/ent/backend/certify_test.go b/pkg/assembler/backends/ent/backend/certify_test.go deleted file mode 100644 index e245beccb5..0000000000 --- a/pkg/assembler/backends/ent/backend/certify_test.go +++ /dev/null @@ -1,1802 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build integration - -package backend - -import ( - "strconv" - "time" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -func (s *Suite) TestCertifyBad() { - type call struct { - Sub model.PackageSourceOrArtifactInput - Match *model.MatchFlags - CB *model.CertifyBadInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - InArt []*model.ArtifactInputSpec - Calls []call - Query *model.CertifyBadSpec - ExpCB []*model.CertifyBad - ExpIngestErr bool - ExpQueryErr bool - Only bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyBadSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpCB: []*model.CertifyBad{ - { - Subject: p1out, - Justification: "test justification", - }, - }, - }, - { - Name: "HappyPath All Version", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - call{ - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyBadSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpCB: []*model.CertifyBad{ - { - Subject: p1outName, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest same twice", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - call{ - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - call{ - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyBadSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpCB: []*model.CertifyBad{ - { - Subject: p1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Justification", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification one", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - Query: &model.CertifyBadSpec{ - Justification: ptrfrom.String("test justification one"), - KnownSince: ptrfrom.Time(time.Unix(1e9, 0)), - }, - ExpCB: []*model.CertifyBad{ - { - Subject: p1out, - Justification: "test justification one", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - { - Name: "Query on Justification", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - call{ - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification one", - }, - }, - call{ - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification two", - }, - }, - }, - Query: &model.CertifyBadSpec{ - Justification: ptrfrom.String("test justification one"), - }, - ExpCB: []*model.CertifyBad{ - { - Subject: p1out, - Justification: "test justification one", - }, - }, - }, - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{p1, p2}, - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s1, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyBadSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String("2.11.1"), - }, - }, - }, - ExpCB: []*model.CertifyBad{ - { - Subject: p2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Source", - InPkg: []*model.PkgInputSpec{p1}, - InSrc: []*model.SourceInputSpec{s1, s2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s1, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s2, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyBadSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Source: &model.SourceSpec{ - Name: ptrfrom.String("bobsrepo"), - }, - }, - }, - ExpCB: []*model.CertifyBad{ - { - Subject: s2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Artifact", - InSrc: []*model.SourceInputSpec{s1}, - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a1, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a2, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s1, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyBadSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha1"), - }, - }, - }, - ExpCB: []*model.CertifyBad{ - { - Subject: a2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query none", - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a1, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a2, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyBadSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("asdf"), - }, - }, - }, - ExpCB: nil, - }, - { - Name: "Query multiple", - InSrc: []*model.SourceInputSpec{s1, s2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s1, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s2, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyBadSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpCB: []*model.CertifyBad{ - { - Subject: s1out, - Justification: "test justification", - }, - { - Subject: s2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query Packages", - InPkg: []*model.PkgInputSpec{p1, p2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyBadSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String("2.11.1"), - }, - }, - }, - ExpCB: []*model.CertifyBad{ - { - Subject: p2out, - Justification: "test justification", - }, - { - Subject: p1outName, - Justification: "test justification", - }, - }, - }, - { - Name: "Query ID", - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a1, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a2, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyBadSpec{ - ID: ptrfrom.String("0"), - }, - ExpCB: []*model.CertifyBad{ - { - Subject: a1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest without subject", - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a1, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - }, - ExpIngestErr: true, - }, - { - Name: "Query bad ID", - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s1, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyBadSpec{ - ID: ptrfrom.String("asdf"), - }, - ExpQueryErr: true, - }, - } - ctx := s.Ctx - - hasOnly := false - for _, test := range tests { - if test.Only { - hasOnly = true - break - } - } - - for _, test := range tests { - if hasOnly && !test.Only { - continue - } - - s.Run(test.Name, func() { - t := s.T() - b, err := GetBackend(s.Client) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - ids := make([]string, len(test.Calls)) - for i, o := range test.Calls { - v, err := b.IngestCertifyBad(ctx, o.Sub, o.Match, *o.CB) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - ids[i] = v - } - - if test.Query.ID != nil { - idIdx, err := strconv.Atoi(*test.Query.ID) - if err == nil { - if idIdx >= len(ids) { - s.T().Fatalf("ID index out of range, want: %d, got: %d", len(ids), idIdx) - } - test.Query.ID = ptrfrom.String(ids[idIdx]) - } - } - - got, err := b.CertifyBad(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpCB, got, ignoreID, ignoreEmptySlices); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func (s *Suite) TestIngestCertifyBads() { - type call struct { - Sub model.PackageSourceOrArtifactInputs - Match *model.MatchFlags - CB []*model.CertifyBadInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - InArt []*model.ArtifactInputSpec - Calls []call - Query *model.CertifyBadSpec - ExpCB []*model.CertifyBad - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: []*model.CertifyBadInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.CertifyBadSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpCB: []*model.CertifyBad{ - &model.CertifyBad{ - Subject: p1out, - Justification: "test justification", - }, - }, - }, - { - Name: "HappyPath All Version", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - call{ - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - CB: []*model.CertifyBadInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.CertifyBadSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpCB: []*model.CertifyBad{ - &model.CertifyBad{ - Subject: p1outName, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest same twice", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1, p1}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: []*model.CertifyBadInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.CertifyBadSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpCB: []*model.CertifyBad{ - &model.CertifyBad{ - Subject: p1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on KnownSince", - InPkg: []*model.PkgInputSpec{p1, p2}, - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1, p2}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: []*model.CertifyBadInputSpec{ - { - Justification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - { - Justification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - { - Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{s1}, - }, - CB: []*model.CertifyBadInputSpec{ - { - Justification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - }, - Query: &model.CertifyBadSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String("2.11.1"), - }, - }, - KnownSince: ptrfrom.Time(time.Unix(1e9, 0)), - }, - ExpCB: []*model.CertifyBad{ - { - Subject: p2out, - Justification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{p1, p2}, - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1, p2}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: []*model.CertifyBadInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - { - Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{s1}, - }, - CB: []*model.CertifyBadInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.CertifyBadSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String("2.11.1"), - }, - }, - }, - ExpCB: []*model.CertifyBad{ - { - Subject: p2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Source", - InPkg: []*model.PkgInputSpec{p1}, - InSrc: []*model.SourceInputSpec{s1, s2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: []*model.CertifyBadInputSpec{ - { - Justification: "test justification", - }, - }, - }, - { - Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{s2, s2}, - }, - CB: []*model.CertifyBadInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.CertifyBadSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Source: &model.SourceSpec{ - Name: ptrfrom.String("bobsrepo"), - }, - }, - }, - ExpCB: []*model.CertifyBad{ - { - Subject: s2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Artifact", - InSrc: []*model.SourceInputSpec{s1}, - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Artifacts: []*model.ArtifactInputSpec{a1, a2}, - }, - CB: []*model.CertifyBadInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - { - Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{s1}, - }, - CB: []*model.CertifyBadInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.CertifyBadSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha1"), - }, - }, - }, - ExpCB: []*model.CertifyBad{ - { - Subject: a2out, - Justification: "test justification", - }, - }, - }, - } - ctx := s.Ctx - for _, test := range tests { - s.Run(test.Name, func() { - t := s.T() - b, err := GetBackend(s.Client) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - for _, o := range test.Calls { - _, err := b.IngestCertifyBads(ctx, o.Sub, o.Match, o.CB) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.CertifyBad(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpCB, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func (s *Suite) TestCertifyGood() { - type call struct { - Sub model.PackageSourceOrArtifactInput - Match *model.MatchFlags - CG *model.CertifyGoodInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - InArt []*model.ArtifactInputSpec - Calls []call - Query *model.CertifyGoodSpec - ExpCG []*model.CertifyGood - ExpIngestErr bool - ExpQueryErr bool - Only bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyGoodSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpCG: []*model.CertifyGood{ - { - Subject: p1out, - Justification: "test justification", - }, - }, - }, - { - Name: "HappyPath All Version", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - call{ - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyGoodSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpCG: []*model.CertifyGood{ - { - Subject: p1outName, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest same twice", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - call{ - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - call{ - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyGoodSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpCG: []*model.CertifyGood{ - { - Subject: p1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on KnownSince", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification one", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification two", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - Query: &model.CertifyGoodSpec{ - Justification: ptrfrom.String("test justification one"), - KnownSince: ptrfrom.Time(time.Unix(1e9, 0)), - }, - ExpCG: []*model.CertifyGood{ - { - Subject: p1out, - Justification: "test justification one", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - { - Name: "Query on Justification", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - call{ - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification one", - }, - }, - call{ - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification two", - }, - }, - }, - Query: &model.CertifyGoodSpec{ - Justification: ptrfrom.String("test justification one"), - }, - ExpCG: []*model.CertifyGood{ - { - Subject: p1out, - Justification: "test justification one", - }, - }, - }, - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{p1, p2}, - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s1, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyGoodSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String("2.11.1"), - }, - }, - }, - ExpCG: []*model.CertifyGood{ - { - Subject: p2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Source", - InPkg: []*model.PkgInputSpec{p1}, - InSrc: []*model.SourceInputSpec{s1, s2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s1, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s2, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyGoodSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Source: &model.SourceSpec{ - Name: ptrfrom.String("bobsrepo"), - }, - }, - }, - ExpCG: []*model.CertifyGood{ - { - Subject: s2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Artifact", - InSrc: []*model.SourceInputSpec{s1}, - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a1, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a2, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s1, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyGoodSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha1"), - }, - }, - }, - ExpCG: []*model.CertifyGood{ - { - Subject: a2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query none", - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a1, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a2, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyGoodSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("asdf"), - }, - }, - }, - ExpCG: nil, - }, - { - Name: "Query multiple", - InSrc: []*model.SourceInputSpec{s1, s2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s1, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s2, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyGoodSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpCG: []*model.CertifyGood{ - { - Subject: s1out, - Justification: "test justification", - }, - { - Subject: s2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query Packages", - InPkg: []*model.PkgInputSpec{p1, p2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyGoodSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String("2.11.1"), - }, - }, - }, - ExpCG: []*model.CertifyGood{ - { - Subject: p2out, - Justification: "test justification", - }, - { - Subject: p1outName, - Justification: "test justification", - }, - }, - }, - { - Name: "Query ID", - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a1, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a2, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyGoodSpec{ - ID: ptrfrom.String("0"), - }, - ExpCG: []*model.CertifyGood{ - { - Subject: a1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest without subject", - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a1, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - }, - ExpIngestErr: true, - }, - { - Name: "Query good ID", - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s1, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyGoodSpec{ - ID: ptrfrom.String("asdf"), - }, - ExpQueryErr: true, - }, - } - ctx := s.Ctx - hasOnly := false - for _, test := range tests { - if test.Only { - hasOnly = true - break - } - } - - for _, test := range tests { - if hasOnly && !test.Only { - continue - } - - s.Run(test.Name, func() { - t := s.T() - b, err := GetBackend(s.Client) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - ids := make([]string, len(test.Calls)) - for i, o := range test.Calls { - v, err := b.IngestCertifyGood(ctx, o.Sub, o.Match, *o.CG) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - ids[i] = v - } - if test.Query.ID != nil { - idIdx, err := strconv.Atoi(*test.Query.ID) - if err == nil { - if idIdx >= len(ids) { - s.T().Fatalf("ID index out of range, want: %d, got: %d", len(ids), idIdx) - } - test.Query.ID = ptrfrom.String(ids[idIdx]) - } - } - - got, err := b.CertifyGood(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpCG, got, ignoreID, ignoreEmptySlices); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func (s *Suite) TestIngestCertifyGoods() { - type call struct { - Sub model.PackageSourceOrArtifactInputs - Match *model.MatchFlags - CG []*model.CertifyGoodInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - InArt []*model.ArtifactInputSpec - Calls []call - Query *model.CertifyGoodSpec - ExpCG []*model.CertifyGood - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: []*model.CertifyGoodInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.CertifyGoodSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpCG: []*model.CertifyGood{ - { - Subject: p1out, - Justification: "test justification", - }, - }, - }, - { - Name: "HappyPath All Version", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - CG: []*model.CertifyGoodInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.CertifyGoodSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpCG: []*model.CertifyGood{ - { - Subject: p1outName, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest same twice", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1, p1}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: []*model.CertifyGoodInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.CertifyGoodSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpCG: []*model.CertifyGood{ - { - Subject: p1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{p1, p2}, - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1, p2}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: []*model.CertifyGoodInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - { - Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{s1}, - }, - CG: []*model.CertifyGoodInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.CertifyGoodSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String("2.11.1"), - }, - }, - }, - ExpCG: []*model.CertifyGood{ - { - Subject: p2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Source", - InPkg: []*model.PkgInputSpec{p1}, - InSrc: []*model.SourceInputSpec{s1, s2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: []*model.CertifyGoodInputSpec{ - { - Justification: "test justification", - }, - }, - }, - { - Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{s2, s2}, - }, - CG: []*model.CertifyGoodInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.CertifyGoodSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Source: &model.SourceSpec{ - Name: ptrfrom.String("bobsrepo"), - }, - }, - }, - ExpCG: []*model.CertifyGood{ - { - Subject: s2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Artifact", - InSrc: []*model.SourceInputSpec{s1}, - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Artifacts: []*model.ArtifactInputSpec{a1, a2}, - }, - CG: []*model.CertifyGoodInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - { - Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{s1}, - }, - CG: []*model.CertifyGoodInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.CertifyGoodSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha1"), - }, - }, - }, - ExpCG: []*model.CertifyGood{ - { - Subject: a2out, - Justification: "test justification", - }, - }, - }, - } - ctx := s.Ctx - for _, test := range tests { - s.Run(test.Name, func() { - t := s.T() - b, err := GetBackend(s.Client) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - for _, o := range test.Calls { - _, err := b.IngestCertifyGoods(ctx, o.Sub, o.Match, o.CG) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.CertifyGood(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpCG, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} diff --git a/pkg/assembler/backends/ent/backend/dependency.go b/pkg/assembler/backends/ent/backend/dependency.go index 82b7303e66..a2b6b2c0f9 100644 --- a/pkg/assembler/backends/ent/backend/dependency.go +++ b/pkg/assembler/backends/ent/backend/dependency.go @@ -48,7 +48,7 @@ func (b *EntBackend) IsDependency(ctx context.Context, spec *model.IsDependencyS return collect(deps, toModelIsDependencyWithBackrefs), nil } -func (b *EntBackend) IngestDependencies(ctx context.Context, pkgs []*model.PkgInputSpec, depPkgs []*model.PkgInputSpec, depPkgMatchType model.MatchFlags, dependencies []*model.IsDependencyInputSpec) ([]string, error) { +func (b *EntBackend) IngestDependencies(ctx context.Context, pkgs []*model.IDorPkgInput, depPkgs []*model.IDorPkgInput, depPkgMatchType model.MatchFlags, dependencies []*model.IsDependencyInputSpec) ([]string, error) { // TODO: This looks like a good candidate for using BulkCreate() var modelIsDependencies = make([]string, len(dependencies)) @@ -73,12 +73,12 @@ func (b *EntBackend) IngestDependencies(ctx context.Context, pkgs []*model.PkgIn return modelIsDependencies, nil } -func (b *EntBackend) IngestDependency(ctx context.Context, pkg model.PkgInputSpec, depPkg model.PkgInputSpec, depPkgMatchType model.MatchFlags, dep model.IsDependencyInputSpec) (string, error) { +func (b *EntBackend) IngestDependency(ctx context.Context, pkg model.IDorPkgInput, depPkg model.IDorPkgInput, depPkgMatchType model.MatchFlags, dep model.IsDependencyInputSpec) (string, error) { funcName := "IngestDependency" recordID, err := WithinTX(ctx, b.client, func(ctx context.Context) (*int, error) { client := ent.TxFromContext(ctx) - p, err := getPkgVersion(ctx, client.Client(), pkg) + p, err := getPkgVersion(ctx, client.Client(), *pkg.PackageInput) if err != nil { return nil, err } @@ -102,7 +102,7 @@ func (b *EntBackend) IngestDependency(ctx context.Context, pkg model.PkgInputSpe var conflictWhere *sql.Predicate if depPkgMatchType.Pkg == model.PkgMatchTypeAllVersions { - dpn, err := getPkgName(ctx, client.Client(), depPkg) + dpn, err := getPkgName(ctx, client.Client(), *depPkg.PackageInput) if err != nil { return nil, err } @@ -113,7 +113,7 @@ func (b *EntBackend) IngestDependency(ctx context.Context, pkg model.PkgInputSpe sql.IsNull(dependency.FieldDependentPackageVersionID), ) } else { - dpv, err := getPkgVersion(ctx, client.Client(), depPkg) + dpv, err := getPkgVersion(ctx, client.Client(), *depPkg.PackageInput) if err != nil { return nil, err } diff --git a/pkg/assembler/backends/ent/backend/dependency_test.go b/pkg/assembler/backends/ent/backend/dependency_test.go deleted file mode 100644 index 343a06a5d6..0000000000 --- a/pkg/assembler/backends/ent/backend/dependency_test.go +++ /dev/null @@ -1,765 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build integration - -package backend - -import ( - "strconv" - "strings" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -var ( - mAll = model.MatchFlags{Pkg: model.PkgMatchTypeAllVersions} - mSpecific = model.MatchFlags{Pkg: model.PkgMatchTypeSpecificVersion} -) - -func (s *Suite) TestIsDependency() { - type call struct { - P1 *model.PkgInputSpec - P2 *model.PkgInputSpec - MF model.MatchFlags - ID *model.IsDependencyInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - Calls []call - Query *model.IsDependencySpec - ExpID []*model.IsDependency - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{p1, p2}, - Calls: []call{ - { - P1: p1, - P2: p2, - MF: mAll, - ID: &model.IsDependencyInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.IsDependencySpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpID: []*model.IsDependency{ - { - Package: p1out, - DependencyPackage: p2outName, - Justification: "test justification", - DependencyType: model.DependencyTypeUnknown, - }, - }, - }, - { - Name: "Ingest same", - InPkg: []*model.PkgInputSpec{p1, p2}, - Calls: []call{ - { - P1: p1, - P2: p2, - MF: mAll, - ID: &model.IsDependencyInputSpec{ - Justification: "test justification", - }, - }, - { - P1: p1, - P2: p2, - MF: mAll, - ID: &model.IsDependencyInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.IsDependencySpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpID: []*model.IsDependency{ - { - Package: p1out, - DependencyPackage: p2outName, - Justification: "test justification", - DependencyType: model.DependencyTypeUnknown, - }, - }, - }, - { - Name: "Ingest same, different version", - InPkg: []*model.PkgInputSpec{p1, p2, p3}, - Calls: []call{ - { - P1: p1, - P2: p2, - MF: mAll, - ID: &model.IsDependencyInputSpec{ - Justification: "test justification", - }, - }, - { - P1: p1, - P2: p3, - MF: mAll, - ID: &model.IsDependencyInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.IsDependencySpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpID: []*model.IsDependency{ - { - Package: p1out, - DependencyPackage: p2outName, - Justification: "test justification", - DependencyType: model.DependencyTypeUnknown, - }, - }, - }, - { - Name: "Query on Justification", - InPkg: []*model.PkgInputSpec{p1, p2}, - Calls: []call{ - { - P1: p1, - P2: p2, - MF: mAll, - ID: &model.IsDependencyInputSpec{ - Justification: "test justification one", - }, - }, - { - P1: p1, - P2: p2, - MF: mAll, - ID: &model.IsDependencyInputSpec{ - Justification: "test justification two", - }, - }, - }, - Query: &model.IsDependencySpec{ - Justification: ptrfrom.String("test justification one"), - }, - ExpID: []*model.IsDependency{ - { - Package: p1out, - DependencyPackage: p2outName, - Justification: "test justification one", - DependencyType: model.DependencyTypeUnknown, - }, - }, - }, - { - Name: "Query on pkg", - InPkg: []*model.PkgInputSpec{p1, p2, p3}, - Calls: []call{ - { - P1: p1, - P2: p2, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - { - P1: p2, - P2: p3, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - }, - Query: &model.IsDependencySpec{ - Package: &model.PkgSpec{ - ID: ptrfrom.String("0"), - }, - }, - ExpID: []*model.IsDependency{ - { - Package: p1out, - DependencyPackage: p2outName, - DependencyType: model.DependencyTypeUnknown, - }, - }, - }, - { - Name: "Query on dep pkg", - InPkg: []*model.PkgInputSpec{p1, p2, p4}, - Calls: []call{ - { - P1: p2, - P2: p4, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - { - P1: p2, - P2: p1, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - }, - Query: &model.IsDependencySpec{ - DependencyPackage: &model.PkgSpec{ - Name: ptrfrom.String("openssl"), - }, - }, - ExpID: []*model.IsDependency{ - { - Package: p2out, - DependencyPackage: p4outName, - DependencyType: model.DependencyTypeUnknown, - }, - }, - }, - { - Name: "Query on pkg multiple", - InPkg: []*model.PkgInputSpec{p1, p2, p3}, - Calls: []call{ - { - P1: p1, - P2: p2, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - { - P1: p3, - P2: p2, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - }, - Query: &model.IsDependencySpec{ - Package: &model.PkgSpec{ - Type: ptrfrom.String("pypi"), - }, - }, - ExpID: []*model.IsDependency{ - { - Package: p1out, - DependencyPackage: p1outName, - DependencyType: model.DependencyTypeUnknown, - }, - { - Package: p3out, - DependencyPackage: p1outName, - DependencyType: model.DependencyTypeUnknown, - }, - }, - }, - { - Name: "Query on both pkgs", - InPkg: []*model.PkgInputSpec{p1, p2, p3, p4}, - Calls: []call{ - { - P1: p2, - P2: p1, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - { - P1: p3, - P2: p4, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - }, - Query: &model.IsDependencySpec{ - Package: &model.PkgSpec{ - Subpath: ptrfrom.String("saved_model_cli.py"), - }, - DependencyPackage: &model.PkgSpec{ - Name: ptrfrom.String("openssl"), - }, - }, - ExpID: []*model.IsDependency{ - { - Package: p3out, - DependencyPackage: p4outName, - DependencyType: model.DependencyTypeUnknown, - }, - }, - }, - { - Name: "Query none", - InPkg: []*model.PkgInputSpec{p1, p2, p3}, - Calls: []call{ - { - P1: p1, - P2: p2, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - { - P1: p2, - P2: p3, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - { - P1: p1, - P2: p3, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - }, - Query: &model.IsDependencySpec{ - Package: &model.PkgSpec{ - Subpath: ptrfrom.String("asdf"), - }, - }, - ExpID: nil, - }, - { - Name: "Query on ID", - InPkg: []*model.PkgInputSpec{p1, p2, p3}, - Calls: []call{ - { - P1: p1, - P2: p2, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - { - P1: p2, - P2: p3, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - { - P1: p1, - P2: p3, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - }, - Query: &model.IsDependencySpec{ - ID: ptrfrom.String("1"), - }, - ExpID: []*model.IsDependency{ - { - Package: p2out, - DependencyPackage: p1outName, - DependencyType: model.DependencyTypeUnknown, - }, - }, - }, - { - Name: "Query on Range", - InPkg: []*model.PkgInputSpec{p1, p2}, - Calls: []call{ - { - P1: p1, - P2: p1, - MF: mAll, - ID: &model.IsDependencyInputSpec{ - VersionRange: "1-3", - }, - }, - { - P1: p2, - P2: p1, - MF: mAll, - ID: &model.IsDependencyInputSpec{ - VersionRange: "4-5", - }, - }, - }, - Query: &model.IsDependencySpec{ - VersionRange: ptrfrom.String("1-3"), - }, - ExpID: []*model.IsDependency{ - { - Package: p1out, - DependencyPackage: p1outName, - VersionRange: "1-3", - DependencyType: model.DependencyTypeUnknown, - }, - }, - }, - { - Name: "Query on DependencyType", - InPkg: []*model.PkgInputSpec{p1, p2}, - Calls: []call{ - { - P1: p1, - P2: p1, - MF: mAll, - ID: &model.IsDependencyInputSpec{ - DependencyType: model.DependencyTypeDirect, - }, - }, - { - P1: p2, - P2: p1, - MF: mAll, - ID: &model.IsDependencyInputSpec{ - DependencyType: model.DependencyTypeIndirect, - }, - }, - }, - Query: &model.IsDependencySpec{ - DependencyType: (*model.DependencyType)(ptrfrom.String(string(model.DependencyTypeIndirect))), - }, - ExpID: []*model.IsDependency{ - { - Package: p2out, - DependencyPackage: p1outName, - DependencyType: model.DependencyTypeIndirect, - }, - }, - }, - { - Name: "Ingest no P1", - InPkg: []*model.PkgInputSpec{p2}, - Calls: []call{ - { - P1: p1, - P2: p2, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - }, - ExpIngestErr: true, - }, - { - Name: "Ingest no P2", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - P1: p1, - P2: p4, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - }, - ExpIngestErr: true, - }, - { - Name: "Query bad ID", - InPkg: []*model.PkgInputSpec{p1, p2, p3}, - Calls: []call{ - { - P1: p1, - P2: p2, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - { - P1: p2, - P2: p3, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - { - P1: p1, - P2: p3, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - }, - Query: &model.IsDependencySpec{ - ID: ptrfrom.String("asdf"), - }, - ExpQueryErr: true, - }, - { - Name: "IsDep from version to version", - InPkg: []*model.PkgInputSpec{p2, p3}, - Calls: []call{ - { - P1: p3, - P2: p2, - MF: mSpecific, - ID: &model.IsDependencyInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.IsDependencySpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpID: []*model.IsDependency{ - { - Package: p3out, - DependencyPackage: p2out, - Justification: "test justification", - DependencyType: model.DependencyTypeUnknown, - }, - }, - }, - { - Name: "IsDep from version to name", - InPkg: []*model.PkgInputSpec{p2, p3}, - Calls: []call{ - { - P1: p3, - P2: p2, - MF: mAll, - ID: &model.IsDependencyInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.IsDependencySpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpID: []*model.IsDependency{ - { - Package: p3out, - DependencyPackage: p2outName, - Justification: "test justification", - DependencyType: model.DependencyTypeUnknown, - }, - }, - }, - { - Name: "IsDep from version to name and version", - InPkg: []*model.PkgInputSpec{p2, p3}, - Calls: []call{ - { - P1: p3, - P2: p2, - MF: mSpecific, - ID: &model.IsDependencyInputSpec{ - Justification: "test justification", - }, - }, - { - P1: p3, - P2: p2, - MF: mAll, - ID: &model.IsDependencyInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.IsDependencySpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpID: []*model.IsDependency{ - { - Package: p3out, - DependencyPackage: p2out, - Justification: "test justification", - DependencyType: model.DependencyTypeUnknown, - }, - { - Package: p3out, - DependencyPackage: p2outName, - Justification: "test justification", - DependencyType: model.DependencyTypeUnknown, - }, - }, - }, - { - Name: "Ingest DependencyPackage with version and query without version", - InPkg: []*model.PkgInputSpec{p2, p4}, - Calls: []call{ - { - P1: p2, - P2: p4, - MF: mSpecific, - ID: &model.IsDependencyInputSpec{ - Justification: "test justification", - VersionRange: "v3.0.3", - }, - }, - }, - Query: &model.IsDependencySpec{ - Package: &model.PkgSpec{ - Type: ptrfrom.String("pypi"), - Name: ptrfrom.String("tensorflow"), - }, - DependencyPackage: &model.PkgSpec{ - Type: ptrfrom.String("conan"), - Namespace: ptrfrom.String("openssl.org"), - Name: ptrfrom.String("openssl"), - }, - }, - ExpID: []*model.IsDependency{ - { - Package: p2out, - DependencyPackage: p4out, - Justification: "test justification", - DependencyType: model.DependencyTypeUnknown, - VersionRange: "v3.0.3", - }, - }, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - ctx := s.Ctx - for _, test := range tests { - s.Run(test.Name, func() { - b, err := GetBackend(s.Client) - s.Require().NoError(err, "Could not instantiate testing backend") - - pksIDs := make([]string, len(test.InPkg)) - for i, a := range test.InPkg { - if id, err := b.IngestPackage(ctx, *a); err != nil { - s.Require().NoError(err, "Could not ingest pkg") - } else { - pksIDs[i] = id.PackageVersionID - } - } - - depIDs := make([]string, len(test.Calls)) - for i, o := range test.Calls { - - dep, err := b.IngestDependency(ctx, *o.P1, *o.P2, o.MF, *o.ID) - if (err != nil) != test.ExpIngestErr { - s.T().Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - depIDs[i] = dep - } - - if test.Query.ID != nil { - idIdx, err := strconv.Atoi(*test.Query.ID) - if err == nil { - if idIdx < 0 || idIdx >= len(depIDs) { - s.T().Logf("ID index out of range, want: %d, got: %d. So ID %d will be directly used to query.", len(depIDs), idIdx, idIdx) - } else { - test.Query.ID = &depIDs[idIdx] - } - } - } - - if test.Query.Package != nil && test.Query.Package.ID != nil { - idIdx, err := strconv.Atoi(*test.Query.Package.ID) - if err == nil { - if idIdx < 0 || idIdx >= len(pksIDs) { - s.T().Logf("ID index out of range, want: %d, got: %d. So ID %d will be directly used to query.", len(pksIDs), idIdx, idIdx) - } else { - test.Query.Package.ID = &pksIDs[idIdx] - } - } - } - - got, err := b.IsDependency(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - s.T().Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - - if diff := cmp.Diff(test.ExpID, got, ignoreID, ignoreEmptySlices); diff != "" { - s.T().Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func (s *Suite) TestIngestDependencies() { - type call struct { - P1s []*model.PkgInputSpec - P2s []*model.PkgInputSpec - MF model.MatchFlags - IDs []*model.IsDependencyInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - Calls []call - Query *model.IsDependencySpec - ExpID []*model.IsDependency - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{p1, p2, p3, p4}, - Calls: []call{{ - P1s: []*model.PkgInputSpec{p1, p2}, - P2s: []*model.PkgInputSpec{p2, p4}, - MF: mAll, - IDs: []*model.IsDependencyInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }}, - Query: &model.IsDependencySpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpID: []*model.IsDependency{ - { - Package: p1out, - DependencyPackage: p2outName, - Justification: "test justification", - DependencyType: model.DependencyTypeUnknown, - }, - { - Package: p2out, - DependencyPackage: p4outName, - Justification: "test justification", - DependencyType: model.DependencyTypeUnknown, - }, - }, - }, - } - ctx := s.Ctx - for _, test := range tests { - s.Run(test.Name, func() { - b, err := GetBackend(s.Client) - s.Require().NoError(err, "Could not instantiate testing backend") - t := s.T() - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, a := range test.InPkg { - if _, err := b.IngestPackage(ctx, *a); err != nil { - t.Fatalf("Could not ingest pkg: %v", err) - } - } - for _, o := range test.Calls { - _, err := b.IngestDependencies(ctx, o.P1s, o.P2s, o.MF, o.IDs) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - - got, err := b.IsDependency(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpID, got, IngestPredicatesCmpOpts...); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} diff --git a/pkg/assembler/backends/ent/backend/hasMetadata.go b/pkg/assembler/backends/ent/backend/hasMetadata.go index d6142696b7..2d98951c20 100644 --- a/pkg/assembler/backends/ent/backend/hasMetadata.go +++ b/pkg/assembler/backends/ent/backend/hasMetadata.go @@ -136,7 +136,7 @@ func upsertHasMetadata(ctx context.Context, client *ent.Tx, subject model.Packag switch { case subject.Artifact != nil: - art, err := client.Artifact.Query().Where(artifactQueryInputPredicates(*subject.Artifact)).Only(ctx) + art, err := client.Artifact.Query().Where(artifactQueryInputPredicates(*subject.Artifact.ArtifactInput)).Only(ctx) if err != nil { return nil, fmt.Errorf("failed to retrieve subject artifact :: %s", err) } @@ -151,7 +151,7 @@ func upsertHasMetadata(ctx context.Context, client *ent.Tx, subject model.Packag case subject.Package != nil: if pkgMatchType.Pkg == model.PkgMatchTypeSpecificVersion { - pv, err := getPkgVersion(ctx, client.Client(), *subject.Package) + pv, err := getPkgVersion(ctx, client.Client(), *subject.Package.PackageInput) if err != nil { return nil, fmt.Errorf("failed to retrieve subject package version :: %s", err) } @@ -164,7 +164,7 @@ func upsertHasMetadata(ctx context.Context, client *ent.Tx, subject model.Packag sql.IsNull(hasmetadata.FieldSourceID), ) } else { - pn, err := getPkgName(ctx, client.Client(), *subject.Package) + pn, err := getPkgName(ctx, client.Client(), *subject.Package.PackageInput) if err != nil { return nil, fmt.Errorf("failed to retrieve subject package name :: %s", err) } @@ -179,7 +179,7 @@ func upsertHasMetadata(ctx context.Context, client *ent.Tx, subject model.Packag } case subject.Source != nil: - srcID, err := getSourceNameID(ctx, client.Client(), *subject.Source) + srcID, err := getSourceNameID(ctx, client.Client(), *subject.Source.SourceInput) if err != nil { return nil, fmt.Errorf("failed to retrieve subject source :: %s", err) } @@ -247,18 +247,18 @@ func hasMetadataInputPredicate(subject model.PackageSourceOrArtifactInput, pkgMa var subjectSpec *model.PackageSourceOrArtifactSpec if subject.Package != nil { if pkgMatchType != nil && pkgMatchType.Pkg == model.PkgMatchTypeAllVersions { - subject.Package.Version = nil + subject.Package.PackageInput.Version = nil } subjectSpec = &model.PackageSourceOrArtifactSpec{ - Package: helper.ConvertPkgInputSpecToPkgSpec(subject.Package), + Package: helper.ConvertPkgInputSpecToPkgSpec(subject.Package.PackageInput), } } else if subject.Artifact != nil { subjectSpec = &model.PackageSourceOrArtifactSpec{ - Artifact: helper.ConvertArtInputSpecToArtSpec(subject.Artifact), + Artifact: helper.ConvertArtInputSpecToArtSpec(subject.Artifact.ArtifactInput), } } else { subjectSpec = &model.PackageSourceOrArtifactSpec{ - Source: helper.ConvertSrcInputSpecToSrcSpec(subject.Source), + Source: helper.ConvertSrcInputSpecToSrcSpec(subject.Source.SourceInput), } } return hasMetadataPredicate(&model.HasMetadataSpec{ diff --git a/pkg/assembler/backends/ent/backend/hasMetadata_test.go b/pkg/assembler/backends/ent/backend/hasMetadata_test.go deleted file mode 100644 index 23d8696b72..0000000000 --- a/pkg/assembler/backends/ent/backend/hasMetadata_test.go +++ /dev/null @@ -1,1000 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build integration - -package backend - -import ( - "strconv" - "time" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -func (s *Suite) TestHasMetadata() { - type call struct { - Sub model.PackageSourceOrArtifactInput - Match *model.MatchFlags - HM *model.HasMetadataInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - InArt []*model.ArtifactInputSpec - Calls []call - Query *model.HasMetadataSpec - ExpHM []*model.HasMetadata - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Key: "key1", - Value: "value1", - Timestamp: time.Unix(1e9, 0), - Justification: "test justification", - }, - }, - }, - Query: &model.HasMetadataSpec{ - Key: ptrfrom.String("key1"), - Value: ptrfrom.String("value1"), - Since: ptrfrom.Time(time.Unix(1e9, 0)), - Justification: ptrfrom.String("test justification"), - }, - ExpHM: []*model.HasMetadata{ - { - Subject: p1out, - Key: "key1", - Value: "value1", - Timestamp: time.Unix(1e9, 0), - Justification: "test justification", - }, - }, - }, - { - Name: "HappyPath check time since", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Key: "key1", - Value: "value1", - Timestamp: time.Unix(1e9, 0), - Justification: "test justification", - }, - }, - }, - Query: &model.HasMetadataSpec{ - Key: ptrfrom.String("key1"), - Value: ptrfrom.String("value1"), - Since: ptrfrom.Time(time.Unix(1e8, 0)), - Justification: ptrfrom.String("test justification"), - }, - ExpHM: []*model.HasMetadata{ - { - Subject: p1out, - Key: "key1", - Value: "value1", - Timestamp: time.Unix(1e9, 0), - Justification: "test justification", - }, - }, - }, - { - Name: "UnhappyPath check time since", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Key: "key1", - Value: "value1", - Timestamp: time.Unix(1e9, 0), - Justification: "test justification", - }, - }, - }, - Query: &model.HasMetadataSpec{ - Key: ptrfrom.String("key1"), - Value: ptrfrom.String("value1"), - Since: ptrfrom.Time(time.Unix(1e10, 0)), - Justification: ptrfrom.String("test justification"), - }, - ExpHM: nil, - }, - { - Name: "HappyPath All Version", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.HasMetadataSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHM: []*model.HasMetadata{ - { - Subject: p1outName, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest same twice", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.HasMetadataSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHM: []*model.HasMetadata{ - { - Subject: p1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest same twice with version", - InPkg: []*model.PkgInputSpec{p2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.HasMetadataSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHM: []*model.HasMetadata{ - { - Subject: p2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest two different keys", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Key: "key1", - Value: "value1", - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Key: "key2", - Value: "value2", - Justification: "test justification", - }, - }, - }, - Query: &model.HasMetadataSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHM: []*model.HasMetadata{ - { - Subject: p1out, - Key: "key1", - Value: "value1", - Justification: "test justification", - }, - { - Subject: p1out, - Key: "key2", - Value: "value2", - Justification: "test justification", - }, - }, - }, - - { - Name: "Query on Justification", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification one", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification two", - }, - }, - }, - Query: &model.HasMetadataSpec{ - Justification: ptrfrom.String("test justification one"), - }, - ExpHM: []*model.HasMetadata{ - { - Subject: p1out, - Justification: "test justification one", - }, - }, - }, - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{p1, p2}, - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s1, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.HasMetadataSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String("2.11.1"), - }, - }, - }, - ExpHM: []*model.HasMetadata{ - { - Subject: p2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Source", - InPkg: []*model.PkgInputSpec{p1}, - InSrc: []*model.SourceInputSpec{s1, s2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s1, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s2, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.HasMetadataSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Source: &model.SourceSpec{ - Name: ptrfrom.String("bobsrepo"), - }, - }, - }, - ExpHM: []*model.HasMetadata{ - { - Subject: s2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Artifact", - InSrc: []*model.SourceInputSpec{s1}, - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a1, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a2, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s1, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.HasMetadataSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha1"), - }, - }, - }, - ExpHM: []*model.HasMetadata{ - { - Subject: a2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query none", - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a1, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a2, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.HasMetadataSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("asdf"), - }, - }, - }, - ExpHM: nil, - }, - { - Name: "Query multiple", - InSrc: []*model.SourceInputSpec{s1, s2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s1, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s2, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.HasMetadataSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHM: []*model.HasMetadata{ - { - Subject: s1out, - Justification: "test justification", - }, - { - Subject: s2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query Packages", - InPkg: []*model.PkgInputSpec{p1, p2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.HasMetadataSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String("2.11.1"), - }, - }, - }, - ExpHM: []*model.HasMetadata{ - { - Subject: p2out, - Justification: "test justification", - }, - { - Subject: p1outName, - Justification: "test justification", - }, - }, - }, - { - Name: "Query ID", - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a1, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a2, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.HasMetadataSpec{ - ID: ptrfrom.String("0"), - }, - ExpHM: []*model.HasMetadata{ - { - Subject: a1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest without subject", - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a1, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - }, - ExpIngestErr: true, - }, - { - Name: "Query good ID", - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s1, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.HasMetadataSpec{ - ID: ptrfrom.String("asdf"), - }, - ExpQueryErr: true, - }, - } - ctx := s.Ctx - for _, test := range tests { - s.Run(test.Name, func() { - t := s.T() - b, err := GetBackend(s.Client) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - recordIDs := make([]string, len(test.Calls)) - for i, o := range test.Calls { - hm, err := b.IngestHasMetadata(ctx, o.Sub, o.Match, *o.HM) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - recordIDs[i] = hm - } - - if test.Query.ID != nil { - idIdx, err := strconv.Atoi(*test.Query.ID) - if err == nil { - if idIdx < 0 || idIdx >= len(recordIDs) { - s.T().Logf("ID index out of range, want: %d, got: %d. So ID %d will be directly used to query.", len(recordIDs), idIdx, idIdx) - } else { - test.Query.ID = &recordIDs[idIdx] - } - } - } - - got, err := b.HasMetadata(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpHM, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func (s *Suite) TestIngestBulkHasMetadata() { - type call struct { - Sub model.PackageSourceOrArtifactInputs - Match *model.MatchFlags - HM []*model.HasMetadataInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - InArt []*model.ArtifactInputSpec - Calls []call - Query *model.HasMetadataSpec - ExpHM []*model.HasMetadata - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: []*model.HasMetadataInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.HasMetadataSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHM: []*model.HasMetadata{ - { - Subject: p1out, - Justification: "test justification", - }, - }, - }, - { - Name: "HappyPath All Version", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - HM: []*model.HasMetadataInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.HasMetadataSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHM: []*model.HasMetadata{ - { - Subject: p1outName, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest same twice", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1, p1}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: []*model.HasMetadataInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.HasMetadataSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHM: []*model.HasMetadata{ - { - Subject: p1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{p1, p2}, - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1, p2}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: []*model.HasMetadataInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - { - Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{s1}, - }, - HM: []*model.HasMetadataInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.HasMetadataSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String("2.11.1"), - }, - }, - }, - ExpHM: []*model.HasMetadata{ - { - Subject: p2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Source", - InPkg: []*model.PkgInputSpec{p1}, - InSrc: []*model.SourceInputSpec{s1, s2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: []*model.HasMetadataInputSpec{ - { - Justification: "test justification", - }, - }, - }, - { - Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{s2, s2}, - }, - HM: []*model.HasMetadataInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.HasMetadataSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Source: &model.SourceSpec{ - Name: ptrfrom.String("bobsrepo"), - }, - }, - }, - ExpHM: []*model.HasMetadata{ - { - Subject: s2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Artifact", - InSrc: []*model.SourceInputSpec{s1}, - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Artifacts: []*model.ArtifactInputSpec{a1, a2}, - }, - HM: []*model.HasMetadataInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - { - Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{s1}, - }, - HM: []*model.HasMetadataInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.HasMetadataSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha1"), - }, - }, - }, - ExpHM: []*model.HasMetadata{ - { - Subject: a2out, - Justification: "test justification", - }, - }, - }, - } - ctx := s.Ctx - for _, test := range tests { - s.Run(test.Name, func() { - t := s.T() - b, err := GetBackend(s.Client) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - for _, o := range test.Calls { - _, err := b.IngestBulkHasMetadata(ctx, o.Sub, o.Match, o.HM) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.HasMetadata(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpHM, got, IngestPredicatesCmpOpts...); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} diff --git a/pkg/assembler/backends/ent/backend/hashequal.go b/pkg/assembler/backends/ent/backend/hashequal.go index 7a9c7f9f38..300b5ada76 100644 --- a/pkg/assembler/backends/ent/backend/hashequal.go +++ b/pkg/assembler/backends/ent/backend/hashequal.go @@ -50,10 +50,10 @@ func (b *EntBackend) HashEqual(ctx context.Context, spec *model.HashEqualSpec) ( return collect(records, toModelHashEqual), nil } -func (b *EntBackend) IngestHashEqual(ctx context.Context, artifact model.ArtifactInputSpec, equalArtifact model.ArtifactInputSpec, spec model.HashEqualInputSpec) (string, error) { +func (b *EntBackend) IngestHashEqual(ctx context.Context, artifact model.IDorArtifactInput, equalArtifact model.IDorArtifactInput, spec model.HashEqualInputSpec) (string, error) { record, err := WithinTX(ctx, b.client, func(ctx context.Context) (*ent.HashEqual, error) { tx := ent.TxFromContext(ctx) - return upsertHashEqual(ctx, tx, artifact, equalArtifact, spec) + return upsertHashEqual(ctx, tx, *artifact.ArtifactInput, *equalArtifact.ArtifactInput, spec) }) if err != nil { return "", err @@ -63,7 +63,7 @@ func (b *EntBackend) IngestHashEqual(ctx context.Context, artifact model.Artifac return nodeID(record.ID), nil } -func (b *EntBackend) IngestHashEquals(ctx context.Context, artifacts []*model.ArtifactInputSpec, otherArtifacts []*model.ArtifactInputSpec, hashEquals []*model.HashEqualInputSpec) ([]string, error) { +func (b *EntBackend) IngestHashEquals(ctx context.Context, artifacts []*model.IDorArtifactInput, otherArtifacts []*model.IDorArtifactInput, hashEquals []*model.HashEqualInputSpec) ([]string, error) { var result []string for i := range hashEquals { he, err := b.IngestHashEqual(ctx, *artifacts[i], *otherArtifacts[i], *hashEquals[i]) diff --git a/pkg/assembler/backends/ent/backend/hashequal_test.go b/pkg/assembler/backends/ent/backend/hashequal_test.go deleted file mode 100644 index df156314bd..0000000000 --- a/pkg/assembler/backends/ent/backend/hashequal_test.go +++ /dev/null @@ -1,803 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build integration - -package backend - -import ( - "slices" - "strconv" - "strings" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -func (s *Suite) TestHashEqual() { - type call struct { - A1 *model.ArtifactInputSpec - A2 *model.ArtifactInputSpec - HE *model.HashEqualInputSpec - } - tests := []struct { - Name string - InArt []*model.ArtifactInputSpec - Calls []call - Query *model.HashEqualSpec - ExpHE []*model.HashEqual - ExpIngestErr bool - ExpQueryErr bool - Only bool - }{ - { - Name: "HappyPath", - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - A1: a1, - A2: a2, - HE: &model.HashEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.HashEqualSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{a1out, a2out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest same, different order", - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - A1: a1, - A2: a2, - HE: &model.HashEqualInputSpec{ - Justification: "test justification", - }, - }, - { - A1: a2, - A2: a1, - HE: &model.HashEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.HashEqualSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{a1out, a2out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Justification", - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - A1: a1, - A2: a2, - HE: &model.HashEqualInputSpec{ - Justification: "test justification one", - }, - }, - { - A1: a1, - A2: a2, - HE: &model.HashEqualInputSpec{ - Justification: "test justification two", - }, - }, - }, - Query: &model.HashEqualSpec{ - Justification: ptrfrom.String("test justification one"), - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{a1out, a2out}, - Justification: "test justification one", - }, - }, - }, - { - Name: "Query on artifact", - InArt: []*model.ArtifactInputSpec{a1, a2, a3}, - Calls: []call{ - { - A1: a1, - A2: a2, - HE: &model.HashEqualInputSpec{}, - }, - { - A1: a1, - A2: a3, - HE: &model.HashEqualInputSpec{}, - }, - }, - Query: &model.HashEqualSpec{ - Artifacts: []*model.ArtifactSpec{{ - ID: ptrfrom.String("2"), - }}, - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{a1out, a3out}, - }, - }, - }, - { - Name: "Query on artifact multiple", - InArt: []*model.ArtifactInputSpec{a1, a2, a3}, - Calls: []call{ - { - A1: a1, - A2: a2, - HE: &model.HashEqualInputSpec{}, - }, - { - A1: a1, - A2: a3, - HE: &model.HashEqualInputSpec{}, - }, - }, - Query: &model.HashEqualSpec{ - Artifacts: []*model.ArtifactSpec{{ - ID: ptrfrom.String("0"), - }}, - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{a1out, a2out}, - }, - { - Artifacts: []*model.Artifact{a1out, a3out}, - }, - }, - }, - { - Name: "Query on artifact algo", - InArt: []*model.ArtifactInputSpec{a1, a2, a3}, - Calls: []call{ - { - A1: a1, - A2: a2, - HE: &model.HashEqualInputSpec{}, - }, - { - A1: a1, - A2: a3, - HE: &model.HashEqualInputSpec{}, - }, - }, - Query: &model.HashEqualSpec{ - Artifacts: []*model.ArtifactSpec{{ - Algorithm: ptrfrom.String("sha1"), - }}, - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{a1out, a2out}, - }, - }, - }, - { - Name: "Query on artifact algo and hash", - InArt: []*model.ArtifactInputSpec{a1, a2, a3}, - Calls: []call{ - { - A1: a1, - A2: a2, - HE: &model.HashEqualInputSpec{}, - }, - { - A1: a1, - A2: a3, - HE: &model.HashEqualInputSpec{}, - }, - }, - Query: &model.HashEqualSpec{ - Artifacts: []*model.ArtifactSpec{{ - Algorithm: ptrfrom.String("sha1"), - Digest: ptrfrom.String("7A8F47318E4676DACB0142AFA0B83029CD7BEFD9"), - }}, - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{a1out, a2out}, - }, - }, - }, - { - Name: "Query on both artifacts", - InArt: []*model.ArtifactInputSpec{a1, a2, a3}, - Calls: []call{ - { - A1: a1, - A2: a2, - HE: &model.HashEqualInputSpec{}, - }, - { - A1: a2, - A2: a3, - HE: &model.HashEqualInputSpec{}, - }, - }, - Query: &model.HashEqualSpec{ - Artifacts: []*model.ArtifactSpec{ - { - Algorithm: ptrfrom.String("sha1"), - Digest: ptrfrom.String("7A8F47318E4676DACB0142AFA0B83029CD7BEFD9"), - }, - { - ID: ptrfrom.String("2"), - }, - }, - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{a2out, a3out}, - }, - }, - }, - { - Name: "Query on both artifacts, one filter", - InArt: []*model.ArtifactInputSpec{a1, a2, a3}, - Calls: []call{ - { - A1: a1, - A2: a2, - HE: &model.HashEqualInputSpec{}, - }, - { - A1: a2, - A2: a3, - HE: &model.HashEqualInputSpec{}, - }, - { - A1: a1, - A2: a3, - HE: &model.HashEqualInputSpec{}, - }, - }, - Query: &model.HashEqualSpec{ - Artifacts: []*model.ArtifactSpec{ - { - Algorithm: ptrfrom.String("sha1"), - }, - { - Digest: ptrfrom.String("6bbb0da1891646e58eb3e6a63af3a6fc3c8eb5a0d44824cba581d2e14a0450cf"), - }, - }, - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{a1out, a2out}, - }, - }, - }, - { - Name: "Query none", - InArt: []*model.ArtifactInputSpec{a1, a2, a3}, - Calls: []call{ - { - A1: a1, - A2: a2, - HE: &model.HashEqualInputSpec{}, - }, - { - A1: a2, - A2: a3, - HE: &model.HashEqualInputSpec{}, - }, - { - A1: a1, - A2: a3, - HE: &model.HashEqualInputSpec{}, - }, - }, - Query: &model.HashEqualSpec{ - Artifacts: []*model.ArtifactSpec{ - { - Algorithm: ptrfrom.String("gitHash"), - }, - { - Digest: ptrfrom.String("6bbb0da1891646e58eb3e6a63af3a6fc3c8eb5a0d44824cba581d2e14a0450cf"), - }, - }, - }, - ExpHE: nil, - }, - { - Name: "Query on ID", - InArt: []*model.ArtifactInputSpec{a1, a2, a3}, - Calls: []call{ - { - A1: a1, - A2: a2, - HE: &model.HashEqualInputSpec{}, - }, - { - A1: a2, - A2: a3, - HE: &model.HashEqualInputSpec{}, - }, - { - A1: a1, - A2: a3, - HE: &model.HashEqualInputSpec{}, - }, - }, - Query: &model.HashEqualSpec{ - ID: ptrfrom.String("1"), - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{a3out, a2out}, - }, - }, - }, - { - Name: "Ingest no A1", - InArt: []*model.ArtifactInputSpec{a2}, - Calls: []call{ - { - A1: a1, - A2: a2, - HE: &model.HashEqualInputSpec{}, - }, - }, - ExpIngestErr: true, - }, - { - Name: "Ingest no A2", - InArt: []*model.ArtifactInputSpec{a1}, - Calls: []call{ - { - A1: a1, - A2: a2, - HE: &model.HashEqualInputSpec{}, - }, - }, - ExpIngestErr: true, - }, - // FIXME: (ivanvanderbyl) This test doesn't make sense in a SQL context because an invalid Digest is equivalent to finding zero records. - // { - // Name: "Query three", - // InArt: []*model.ArtifactInputSpec{a1, a2, a3}, - // Calls: []call{ - // { - // A1: a1, - // A2: a2, - // HE: &model.HashEqualInputSpec{}, - // }, - // { - // A1: a2, - // A2: a3, - // HE: &model.HashEqualInputSpec{}, - // }, - // { - // A1: a1, - // A2: a3, - // HE: &model.HashEqualInputSpec{}, - // }, - // }, - // Query: &model.HashEqualSpec{ - // Artifacts: []*model.ArtifactSpec{ - // { - // Algorithm: ptrfrom.String("gitHash"), - // }, - // { - // Digest: ptrfrom.String("6bbb0da1891646e58eb3e6a63af3a6fc3c8eb5a0d44824cba581d2e14a0450cf"), - // }, - // { - // Digest: ptrfrom.String("asdf"), - // }, - // }, - // }, - // ExpQueryErr: true, - // }, - { - Name: "Query bad ID", - InArt: []*model.ArtifactInputSpec{a1, a2, a3}, - Calls: []call{ - { - A1: a1, - A2: a2, - HE: &model.HashEqualInputSpec{}, - }, - { - A1: a2, - A2: a3, - HE: &model.HashEqualInputSpec{}, - }, - { - A1: a1, - A2: a3, - HE: &model.HashEqualInputSpec{}, - }, - }, - Query: &model.HashEqualSpec{ - ID: ptrfrom.String("asdf"), - }, - ExpQueryErr: true, - }, - } - - ctx := s.Ctx - hasOnly := false - for _, t := range tests { - if t.Only { - hasOnly = true - break - } - } - - for _, test := range tests { - if hasOnly && !test.Only { - continue - } - s.Run(test.Name, func() { - t := s.T() - b, err := GetBackend(s.Client) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - artifactIDs := make([]string, len(test.InArt)) - for i, a := range test.InArt { - if v, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } else { - artifactIDs[i] = v - } - } - - if test.Query != nil { - for i, aq := range test.Query.Artifacts { - if aq.ID == nil { - continue - } - idIdx, err := strconv.Atoi(*aq.ID) - if err == nil { - if idIdx >= len(artifactIDs) { - s.T().Fatalf("ID index out of range, want: %d, got: %d", len(artifactIDs), idIdx) - } - - realID := artifactIDs[idIdx] - test.Query.Artifacts[i].ID = &realID - } - } - } - - ids := make([]string, len(test.Calls)) - for i, o := range test.Calls { - v, err := b.IngestHashEqual(ctx, *o.A1, *o.A2, *o.HE) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - ids[i] = v - } - - if test.Query != nil && test.Query.ID != nil { - idIdx, err := strconv.Atoi(*test.Query.ID) - if err == nil { - if idIdx >= len(ids) { - s.T().Fatalf("ID index out of range, want: %d, got: %d", len(ids), idIdx) - } - test.Query.ID = &ids[idIdx] - } - } - - got, err := b.HashEqual(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - less := func(a, b *model.Artifact) int { return strings.Compare(a.Digest, b.Digest) } - for _, he := range got { - slices.SortFunc(he.Artifacts, less) - } - for _, he := range test.ExpHE { - slices.SortFunc(he.Artifacts, less) - } - if diff := cmp.Diff(test.ExpHE, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func (s *Suite) TestIngestHashEquals() { - type call struct { - A1 []*model.ArtifactInputSpec - A2 []*model.ArtifactInputSpec - HE []*model.HashEqualInputSpec - } - tests := []struct { - Name string - InArt []*model.ArtifactInputSpec - Calls []call - Query *model.HashEqualSpec - ExpHE []*model.HashEqual - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - A1: []*model.ArtifactInputSpec{a1}, - A2: []*model.ArtifactInputSpec{a2}, - HE: []*model.HashEqualInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.HashEqualSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{a1out, a2out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest same, different order", - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - A1: []*model.ArtifactInputSpec{a1, a2}, - A2: []*model.ArtifactInputSpec{a2, a1}, - HE: []*model.HashEqualInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.HashEqualSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{a1out, a2out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Justification", - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - A1: []*model.ArtifactInputSpec{a1, a1}, - A2: []*model.ArtifactInputSpec{a2, a2}, - HE: []*model.HashEqualInputSpec{ - { - Justification: "test justification one", - }, - { - Justification: "test justification two", - }, - }, - }, - }, - Query: &model.HashEqualSpec{ - Justification: ptrfrom.String("test justification one"), - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{a1out, a2out}, - Justification: "test justification one", - }, - }, - }, - { - Name: "Query on artifact", - InArt: []*model.ArtifactInputSpec{a1, a2, a3}, - Calls: []call{ - { - A1: []*model.ArtifactInputSpec{a1, a1}, - A2: []*model.ArtifactInputSpec{a2, a3}, - HE: []*model.HashEqualInputSpec{ - {}, - {}, - }, - }, - }, - Query: &model.HashEqualSpec{ - Artifacts: []*model.ArtifactSpec{{ - ID: ptrfrom.String("3"), - }}, - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{a1out, a3out}, - }, - }, - }, - { - Name: "Query on artifact multiple", - InArt: []*model.ArtifactInputSpec{a1, a2, a3}, - Calls: []call{ - { - A1: []*model.ArtifactInputSpec{a1, a1}, - A2: []*model.ArtifactInputSpec{a2, a3}, - HE: []*model.HashEqualInputSpec{ - {}, - {}, - }, - }, - }, - Query: &model.HashEqualSpec{ - Artifacts: []*model.ArtifactSpec{{ - ID: ptrfrom.String("1"), - }}, - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{a1out, a2out}, - }, - { - Artifacts: []*model.Artifact{a1out, a3out}, - }, - }, - }, - { - Name: "Query on artifact algo", - InArt: []*model.ArtifactInputSpec{a1, a2, a3}, - Calls: []call{ - { - A1: []*model.ArtifactInputSpec{a1, a1}, - A2: []*model.ArtifactInputSpec{a2, a3}, - HE: []*model.HashEqualInputSpec{ - {}, - {}, - }, - }, - }, - Query: &model.HashEqualSpec{ - Artifacts: []*model.ArtifactSpec{{ - Algorithm: ptrfrom.String("sha1"), - }}, - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{a1out, a2out}, - }, - }, - }, - { - Name: "Query on artifact algo and hash", - InArt: []*model.ArtifactInputSpec{a1, a2, a3}, - Calls: []call{ - { - A1: []*model.ArtifactInputSpec{a1, a1}, - A2: []*model.ArtifactInputSpec{a2, a3}, - HE: []*model.HashEqualInputSpec{ - {}, - {}, - }, - }, - }, - Query: &model.HashEqualSpec{ - Artifacts: []*model.ArtifactSpec{{ - Algorithm: ptrfrom.String("sha1"), - Digest: ptrfrom.String("7A8F47318E4676DACB0142AFA0B83029CD7BEFD9"), - }}, - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{a1out, a2out}, - }, - }, - }, - { - Name: "Query on both artifacts", - InArt: []*model.ArtifactInputSpec{a1, a2, a3}, - Calls: []call{ - { - A1: []*model.ArtifactInputSpec{a1, a2}, - A2: []*model.ArtifactInputSpec{a2, a3}, - HE: []*model.HashEqualInputSpec{ - {}, - {}, - }, - }, - }, - Query: &model.HashEqualSpec{ - Artifacts: []*model.ArtifactSpec{ - { - Algorithm: ptrfrom.String("sha1"), - Digest: ptrfrom.String("7A8F47318E4676DACB0142AFA0B83029CD7BEFD9"), - }, - { - ID: ptrfrom.String("3"), - }, - }, - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{a2out, a3out}, - }, - }, - }, - } - ctx := s.Ctx - for _, test := range tests { - s.Run(test.Name, func() { - t := s.T() - b, err := GetBackend(s.Client) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - for _, o := range test.Calls { - _, err := b.IngestHashEquals(ctx, o.A1, o.A2, o.HE) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.HashEqual(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - less := func(a, b *model.Artifact) int { return strings.Compare(a.Digest, b.Digest) } - for _, he := range got { - slices.SortFunc(he.Artifacts, less) - } - for _, he := range test.ExpHE { - slices.SortFunc(he.Artifacts, less) - } - if diff := cmp.Diff(test.ExpHE, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} diff --git a/pkg/assembler/backends/ent/backend/helpers_test.go b/pkg/assembler/backends/ent/backend/helpers_test.go index 8fda15303b..e884a1e486 100644 --- a/pkg/assembler/backends/ent/backend/helpers_test.go +++ b/pkg/assembler/backends/ent/backend/helpers_test.go @@ -13,15 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -//go:build integration - package backend import ( - "reflect" - "strconv" "strings" - "testing" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" @@ -29,22 +24,10 @@ import ( "github.com/guacsec/guac/pkg/assembler/helpers" ) -func ptr[T any](s T) *T { - return &s -} - var ignoreID = cmp.FilterPath(func(p cmp.Path) bool { return strings.Compare(".ID", p[len(p)-1].String()) == 0 }, cmp.Ignore()) -var ignoreEmptySlices = cmp.FilterValues(func(x, y interface{}) bool { - xv, yv := reflect.ValueOf(x), reflect.ValueOf(y) - if xv.Kind() == reflect.Slice && yv.Kind() == reflect.Slice { - return xv.Len() == 0 && yv.Len() == 0 - } - return false -}, cmp.Ignore()) - var IngestPredicatesCmpOpts = []cmp.Option{ ignoreID, cmpopts.EquateEmpty(), @@ -133,14 +116,3 @@ func certifyLegalLess(e1, e2 *model.CertifyLegal) bool { } return false } - -func rewriteID(t *testing.T, queryID *string, realIDs []string) { - idIdx, err := strconv.Atoi(*queryID) - if err == nil { - if idIdx >= len(realIDs) { - t.Logf("ID index out of range, want: %d, got: %d. So ID %d will be directly used to query.", len(realIDs), idIdx, idIdx) - } else { - *queryID = realIDs[idIdx] - } - } -} diff --git a/pkg/assembler/backends/ent/backend/license.go b/pkg/assembler/backends/ent/backend/license.go index 095c3f35ab..1394d692a1 100644 --- a/pkg/assembler/backends/ent/backend/license.go +++ b/pkg/assembler/backends/ent/backend/license.go @@ -28,7 +28,7 @@ import ( "github.com/vektah/gqlparser/v2/gqlerror" ) -func (b *EntBackend) IngestLicenses(ctx context.Context, licenses []*model.LicenseInputSpec) ([]string, error) { +func (b *EntBackend) IngestLicenses(ctx context.Context, licenses []*model.IDorLicenseInput) ([]string, error) { var modelLicenses []string for i, license := range licenses { modelLicense, err := b.IngestLicense(ctx, license) @@ -40,10 +40,10 @@ func (b *EntBackend) IngestLicenses(ctx context.Context, licenses []*model.Licen return modelLicenses, nil } -func (b *EntBackend) IngestLicense(ctx context.Context, license *model.LicenseInputSpec) (string, error) { +func (b *EntBackend) IngestLicense(ctx context.Context, license *model.IDorLicenseInput) (string, error) { record, err := WithinTX(ctx, b.client, func(ctx context.Context) (*int, error) { client := ent.TxFromContext(ctx) - licenseID, err := upsertLicense(ctx, client, *license) + licenseID, err := upsertLicense(ctx, client, *license.LicenseInput) if err != nil { return nil, err } diff --git a/pkg/assembler/backends/ent/backend/license_test.go b/pkg/assembler/backends/ent/backend/license_test.go deleted file mode 100644 index e5401aa34c..0000000000 --- a/pkg/assembler/backends/ent/backend/license_test.go +++ /dev/null @@ -1,181 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build integration - -package backend - -import ( - "slices" - "strconv" - "strings" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/internal/testing/testdata" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -func (s *Suite) TestLicense() { - tests := []struct { - Name string - Ingests []*model.LicenseInputSpec - ExpIngestErr bool - Query *model.LicenseSpec - Exp []*model.License - ExpQueryErr bool - }{ - { - Name: "HappyPath", - Ingests: []*model.LicenseInputSpec{testdata.L1}, - Query: &model.LicenseSpec{}, - Exp: []*model.License{testdata.L1out}, - }, - { - Name: "Multiple", - Ingests: []*model.LicenseInputSpec{testdata.L1, testdata.L2}, - Query: &model.LicenseSpec{}, - Exp: []*model.License{testdata.L1out, testdata.L2out}, - }, - { - Name: "Duplicates", - Ingests: []*model.LicenseInputSpec{testdata.L1, testdata.L1, testdata.L1}, - Query: &model.LicenseSpec{}, - Exp: []*model.License{testdata.L1out}, - }, - { - Name: "Query by Name", - Ingests: []*model.LicenseInputSpec{testdata.L1, testdata.L2, testdata.L3}, - Query: &model.LicenseSpec{ - Name: ptrfrom.String("BSD-3-Clause"), - }, - Exp: []*model.License{testdata.L1out}, - }, - { - Name: "Query by Inline", - Ingests: []*model.LicenseInputSpec{testdata.L2, testdata.L3, testdata.L4}, - Query: &model.LicenseSpec{ - Inline: &testdata.InlineLicense, - }, - Exp: []*model.License{testdata.L4out}, - }, - { - Name: "Query by ListVersion", - Ingests: []*model.LicenseInputSpec{testdata.L2, testdata.L3, testdata.L4}, - Query: &model.LicenseSpec{ - ListVersion: ptrfrom.String("1.23 2020"), - }, - Exp: []*model.License{testdata.L3out}, - }, - { - Name: "Query by ID", - Ingests: []*model.LicenseInputSpec{testdata.L2, testdata.L3, testdata.L4}, - Query: &model.LicenseSpec{ - ID: ptrfrom.String("1"), - }, - Exp: []*model.License{testdata.L3out}, - }, - { - Name: "Query None", - Ingests: []*model.LicenseInputSpec{testdata.L2, testdata.L3, testdata.L4}, - Query: &model.LicenseSpec{ - ListVersion: ptrfrom.String("foo"), - }, - Exp: nil, - }, - { - Name: "Query invalid ID", - Ingests: []*model.LicenseInputSpec{testdata.L1, testdata.L2, testdata.L3}, - Query: &model.LicenseSpec{ - ID: ptrfrom.String("asdf"), - }, - ExpQueryErr: true, - }, - } - ctx := s.Ctx - for _, test := range tests { - s.Run(test.Name, func() { - t := s.T() - b, err := GetBackend(s.Client) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - recordIDs := make([]string, len(test.Ingests)) - for x, i := range test.Ingests { - lic, err := b.IngestLicense(ctx, i) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - recordIDs[x] = lic - } - - if test.Query.ID != nil { - idIdx, err := strconv.Atoi(*test.Query.ID) - if err == nil { - if idIdx >= len(recordIDs) { - s.T().Logf("ID index out of range, want: %d, got: %d. So ID %d will be directly used to query.", len(recordIDs), idIdx, idIdx) - } else { - realID := recordIDs[idIdx] - test.Query.ID = &realID - } - } - } - - got, err := b.Licenses(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - slices.SortFunc(got, lessLic) - if diff := cmp.Diff(test.Exp, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func lessLic(a, b *model.License) int { - return strings.Compare(a.Name, b.Name) -} - -func (s *Suite) TestIngestLicenses() { - tests := []struct { - name string - ingests []*model.LicenseInputSpec - }{ - { - name: "Multiple", - ingests: []*model.LicenseInputSpec{testdata.L1, testdata.L2, testdata.L3, testdata.L4}, - }, - } - ctx := s.Ctx - for _, test := range tests { - s.Run(test.name, func() { - t := s.T() - b, err := GetBackend(s.Client) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - if _, err := b.IngestLicenses(ctx, test.ingests); err != nil { - t.Fatalf("ingest error: %v", err) - } - }) - } -} diff --git a/pkg/assembler/backends/ent/backend/neighbors_test.go b/pkg/assembler/backends/ent/backend/neighbors_test.go deleted file mode 100644 index 368af0fca5..0000000000 --- a/pkg/assembler/backends/ent/backend/neighbors_test.go +++ /dev/null @@ -1,138 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build integration - -package backend - -import ( - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -func (s *Suite) TestNode() { - ctx := s.Ctx - tests := []struct { - Name string - InArt []*model.ArtifactInputSpec - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - InBld []*model.BuilderInputSpec - Expected []interface{} - Only bool - }{ - { - Name: "Ingest Artifact", - InArt: []*model.ArtifactInputSpec{a1}, - InPkg: []*model.PkgInputSpec{p4}, - InSrc: []*model.SourceInputSpec{s1}, - InBld: []*model.BuilderInputSpec{b1}, - Expected: []interface{}{ - a1out, - p4out, - s1out, - b1out, - }, - }, - } - hasOnly := false - for _, t := range tests { - if t.Only { - hasOnly = true - break - } - } - - for _, test := range tests { - if hasOnly && !test.Only { - continue - } - - s.Run(test.Name, func() { - b, err := GetBackend(s.Client) - s.Require().NoError(err, "Could not instantiate testing backend") - - ids := make([]string, 0, len(test.Expected)) - for _, inA := range test.InArt { - if a, err := b.IngestArtifact(ctx, inA); err != nil { - s.T().Fatalf("Could not ingest artifact: %v", err) - } else { - ids = append(ids, a) - } - } - - for _, inP := range test.InPkg { - if id, err := b.IngestPackage(ctx, *inP); err != nil { - s.T().Fatalf("Could not ingest package: %v", err) - } else { - ids = append(ids, id.PackageVersionID) - } - } - - for _, inSrc := range test.InSrc { - if id, err := b.IngestSource(ctx, *inSrc); err != nil { - s.T().Fatalf("Could not ingest source: %v", err) - } else { - ids = append(ids, id.SourceNameID) - } - } - - for _, inBLD := range test.InBld { - if id, err := b.IngestBuilder(ctx, inBLD); err != nil { - s.T().Fatalf("Could not ingest builder: %v", err) - } else { - ids = append(ids, id) - } - } - - for i, id := range ids { - n, err := b.Node(s.Ctx, id) - s.Require().NoError(err) - if diff := cmp.Diff(test.Expected[i], n, ignoreID, ignoreEmptySlices); diff != "" { - s.T().Errorf("Unexpected results. (-want +got):\n%s", diff) - } - } - }) - } -} - -func (s *Suite) TestNodes() { - s.Run("HappyPath", func() { - be, err := GetBackend(s.Client) - s.Require().NoError(err) - - v, err := be.IngestArtifact(s.Ctx, a1) - s.Require().NoError(err) - - id, err := be.IngestPackage(s.Ctx, *p4) - s.Require().NoError(err) - - pkgs, err := be.Packages(s.Ctx, &model.PkgSpec{ID: &id.PackageVersionID}) - s.Require().NoError(err) - p := pkgs[0] - - nodes, err := be.Nodes(s.Ctx, []string{v, p.ID, p.Namespaces[0].Names[0].Versions[0].ID}) - s.Require().NoError(err) - if diff := cmp.Diff(a1out, nodes[0], ignoreID, ignoreEmptySlices); diff != "" { - s.T().Errorf("Unexpected results. (-want +got):\n%s", diff) - } - if diff := cmp.Diff(p4outNamespace, nodes[1], ignoreID, ignoreEmptySlices); diff != "" { - s.T().Errorf("Unexpected results. (-want +got):\n%s", diff) - } - if diff := cmp.Diff(p4out, nodes[2], ignoreID, ignoreEmptySlices); diff != "" { - s.T().Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) -} diff --git a/pkg/assembler/backends/ent/backend/occurrence.go b/pkg/assembler/backends/ent/backend/occurrence.go index f3470f5a59..184b44e2f9 100644 --- a/pkg/assembler/backends/ent/backend/occurrence.go +++ b/pkg/assembler/backends/ent/backend/occurrence.go @@ -63,7 +63,7 @@ func (b *EntBackend) IsOccurrence(ctx context.Context, query *model.IsOccurrence return models, nil } -func (b *EntBackend) IngestOccurrences(ctx context.Context, subjects model.PackageOrSourceInputs, artifacts []*model.ArtifactInputSpec, occurrences []*model.IsOccurrenceInputSpec) ([]string, error) { +func (b *EntBackend) IngestOccurrences(ctx context.Context, subjects model.PackageOrSourceInputs, artifacts []*model.IDorArtifactInput, occurrences []*model.IsOccurrenceInputSpec) ([]string, error) { models := make([]string, len(occurrences)) eg, ctx := errgroup.WithContext(ctx) for i := range occurrences { @@ -92,7 +92,7 @@ func (b *EntBackend) IngestOccurrences(ctx context.Context, subjects model.Packa func (b *EntBackend) IngestOccurrence(ctx context.Context, subject model.PackageOrSourceInput, - art model.ArtifactInputSpec, + art model.IDorArtifactInput, spec model.IsOccurrenceInputSpec, ) (string, error) { funcName := "IngestOccurrence" @@ -104,7 +104,7 @@ func (b *EntBackend) IngestOccurrence(ctx context.Context, artRecord, err := client.Artifact.Query(). Order(ent.Asc(artifact.FieldID)). // is order important here? - Where(artifactQueryInputPredicates(art)). + Where(artifactQueryInputPredicates(*art.ArtifactInput)). Only(ctx) // should already be ingested if err != nil { return nil, err @@ -126,7 +126,7 @@ func (b *EntBackend) IngestOccurrence(ctx context.Context, var conflictWhere *sql.Predicate if subject.Package != nil { - pkgVersion, err := getPkgVersion(ctx, client, *subject.Package) + pkgVersion, err := getPkgVersion(ctx, client, *subject.Package.PackageInput) if err != nil { return nil, errors.Wrap(err, "failed to get package version") } @@ -137,7 +137,7 @@ func (b *EntBackend) IngestOccurrence(ctx context.Context, sql.IsNull(occurrence.FieldSourceID), ) } else if subject.Source != nil { - srcNameID, err := upsertSource(ctx, tx, *subject.Source) + srcNameID, err := upsertSource(ctx, tx, *subject.Source.SourceInput) if err != nil { return nil, err } diff --git a/pkg/assembler/backends/ent/backend/occurrence_test.go b/pkg/assembler/backends/ent/backend/occurrence_test.go deleted file mode 100644 index 74d68ca621..0000000000 --- a/pkg/assembler/backends/ent/backend/occurrence_test.go +++ /dev/null @@ -1,668 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build integration - -package backend - -import ( - "github.com/google/go-cmp/cmp" - - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -var a1 = &model.ArtifactInputSpec{ - Algorithm: "sha256", - Digest: "6bbb0da1891646e58eb3e6a63af3a6fc3c8eb5a0d44824cba581d2e14a0450cf", -} -var a1out = &model.Artifact{ - Algorithm: "sha256", - Digest: "6bbb0da1891646e58eb3e6a63af3a6fc3c8eb5a0d44824cba581d2e14a0450cf", -} - -var a2 = &model.ArtifactInputSpec{ - Algorithm: "sha1", - Digest: "7A8F47318E4676DACB0142AFA0B83029CD7BEFD9", -} -var a2out = &model.Artifact{ - Algorithm: "sha1", - Digest: "7a8f47318e4676dacb0142afa0b83029cd7befd9", -} - -var a3 = &model.ArtifactInputSpec{ - Algorithm: "sha512", - Digest: "374AB8F711235830769AA5F0B31CE9B72C5670074B34CB302CDAFE3B606233EE92EE01E298E5701F15CC7087714CD9ABD7DDB838A6E1206B3642DE16D9FC9DD7", -} -var a3out = &model.Artifact{ - Algorithm: "sha512", - Digest: "374ab8f711235830769aa5f0b31ce9b72c5670074b34cb302cdafe3b606233ee92ee01e298e5701f15cc7087714cd9abd7ddb838a6e1206b3642de16d9fc9dd7", -} - -var a4 = &model.ArtifactInputSpec{ - Algorithm: "sha1", - Digest: "5a787865sd676dacb0142afa0b83029cd7befd9", -} - -var p1 = &model.PkgInputSpec{ - Type: "pypi", - Name: "tensorflow", -} -var p1out = &model.Package{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{{ - Names: []*model.PackageName{{ - Name: "tensorflow", - Versions: []*model.PackageVersion{{ - Version: "", - Qualifiers: []*model.PackageQualifier{}, - }}, - }}, - }}, -} -var p1outName = &model.Package{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{{ - Names: []*model.PackageName{{ - Name: "tensorflow", - Versions: []*model.PackageVersion{}, - }}, - }}, -} - -var p2 = &model.PkgInputSpec{ - Type: "pypi", - Name: "tensorflow", - Version: ptrfrom.String("2.11.1"), -} -var p2out = &model.Package{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{{ - Names: []*model.PackageName{{ - Name: "tensorflow", - Versions: []*model.PackageVersion{{ - Version: "2.11.1", - Qualifiers: []*model.PackageQualifier{}, - }}, - }}, - }}, -} - -var p2outName = &model.Package{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{{ - Names: []*model.PackageName{{ - Name: "tensorflow", - Versions: []*model.PackageVersion{}, - }}, - }}, -} - -var p3 = &model.PkgInputSpec{ - Type: "pypi", - Name: "tensorflow", - Version: ptrfrom.String("2.11.1"), - Subpath: ptrfrom.String("saved_model_cli.py"), -} -var p3out = &model.Package{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{{ - Names: []*model.PackageName{{ - Name: "tensorflow", - Versions: []*model.PackageVersion{{ - Version: "2.11.1", - Subpath: "saved_model_cli.py", - Qualifiers: []*model.PackageQualifier{}, - }}, - }}, - }}, -} - -var p4 = &model.PkgInputSpec{ - Type: "conan", - Namespace: ptrfrom.String("openssl.org"), - Name: "openssl", - Version: ptrfrom.String("3.0.3"), -} -var p4out = &model.Package{ - Type: "conan", - Namespaces: []*model.PackageNamespace{{ - Namespace: "openssl.org", - Names: []*model.PackageName{{ - Name: "openssl", - Versions: []*model.PackageVersion{{ - Version: "3.0.3", - Qualifiers: []*model.PackageQualifier{}, - }}, - }}, - }}, -} - -var p4outName = &model.Package{ - Type: "conan", - Namespaces: []*model.PackageNamespace{{ - Namespace: "openssl.org", - Names: []*model.PackageName{{ - Name: "openssl", - Versions: []*model.PackageVersion{}, - }}, - }}, -} - -var p4outNamespace = &model.Package{ - Type: "conan", - Namespaces: []*model.PackageNamespace{{ - Namespace: "openssl.org", - }}, -} - -var s1 = &model.SourceInputSpec{ - Type: "git", - Namespace: "github.com/jeff", - Name: "myrepo", -} -var s1out = &model.Source{ - Type: "git", - Namespaces: []*model.SourceNamespace{{ - Namespace: "github.com/jeff", - Names: []*model.SourceName{{ - Name: "myrepo", - }}, - }}, -} - -var s2 = &model.SourceInputSpec{ - Type: "git", - Namespace: "github.com/bob", - Name: "bobsrepo", - Commit: ptrfrom.String("5e7c41f"), -} -var s2out = &model.Source{ - Type: "git", - Namespaces: []*model.SourceNamespace{{ - Namespace: "github.com/bob", - Names: []*model.SourceName{{ - Name: "bobsrepo", - Commit: ptrfrom.String("5e7c41f"), - }}, - }}, -} - -func (s *Suite) TestOccurrenceHappyPath() { - s.Run("HappyPath", func() { - b, err := GetBackend(s.Client) - s.Require().NoError(err) - - _, err = b.IngestPackage(s.Ctx, *p1) - s.Require().NoError(err) - - _, err = b.IngestArtifact(s.Ctx, a1) - s.Require().NoError(err) - - occ, err := b.IngestOccurrence(s.Ctx, - model.PackageOrSourceInput{ - Package: p1, - }, - *a1, - model.IsOccurrenceInputSpec{ - Justification: "test justification", - }, - ) - s.Require().NoError(err) - s.Require().NotNil(occ) - }) -} - -func (s *Suite) TestOccurrence() { - type call struct { - PkgSrc model.PackageOrSourceInput - Artifact *model.ArtifactInputSpec - Occurrence *model.IsOccurrenceInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - InArt []*model.ArtifactInputSpec - Calls []call - Query *model.IsOccurrenceSpec - ExpOcc []*model.IsOccurrence - ExpIngestErr bool - ExpQueryErr bool - Only bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{p1}, - InArt: []*model.ArtifactInputSpec{a1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: p1, - }, - Artifact: a1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.IsOccurrenceSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpOcc: []*model.IsOccurrence{ - { - Subject: p1out, - Artifact: a1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Igest same twice", - InPkg: []*model.PkgInputSpec{p1}, - InArt: []*model.ArtifactInputSpec{a1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: p1, - }, - Artifact: a1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "test justification", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Package: p1, - }, - Artifact: a1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.IsOccurrenceSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpOcc: []*model.IsOccurrence{ - { - Subject: p1out, - Artifact: a1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Justification", - InPkg: []*model.PkgInputSpec{p1}, - InArt: []*model.ArtifactInputSpec{a1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{Package: p1}, - Artifact: a1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "justification one", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{Package: p1}, - Artifact: a1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "justification two", - }, - }, - }, - Query: &model.IsOccurrenceSpec{ - Justification: ptrfrom.String("justification one"), - }, - ExpOcc: []*model.IsOccurrence{ - { - Subject: p1out, - Artifact: a1out, - Justification: "justification one", - }, - }, - }, - { - Name: "Query on Artifact", - InPkg: []*model.PkgInputSpec{p1}, - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: p1, - }, - Artifact: a1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "justification", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Package: p1, - }, - Artifact: a2, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "justification", - }, - }, - }, - Query: &model.IsOccurrenceSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha256"), - }, - }, - ExpOcc: []*model.IsOccurrence{ - { - Subject: p1out, - Artifact: a1out, - Justification: "justification", - }, - }, - }, - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{p1, p2}, - InArt: []*model.ArtifactInputSpec{a1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: p1, - }, - Artifact: a1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "justification", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Package: p2, - }, - Artifact: a1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "justification", - }, - }, - }, - Query: &model.IsOccurrenceSpec{ - Subject: &model.PackageOrSourceSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String(""), - }, - }, - }, - ExpOcc: []*model.IsOccurrence{ - { - Subject: p1out, - Artifact: a1out, - Justification: "justification", - }, - }, - }, - { - Name: "Query on Source", - InPkg: []*model.PkgInputSpec{p1}, - InSrc: []*model.SourceInputSpec{s1}, - InArt: []*model.ArtifactInputSpec{a1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: p1, - }, - Artifact: a1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "justification", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Source: s1, - }, - Artifact: a1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "justification", - }, - }, - }, - Query: &model.IsOccurrenceSpec{ - Subject: &model.PackageOrSourceSpec{ - Source: &model.SourceSpec{}, - }, - }, - ExpOcc: []*model.IsOccurrence{ - { - Subject: s1out, - Artifact: a1out, - Justification: "justification", - }, - }, - }, - { - Name: "Query none", - InPkg: []*model.PkgInputSpec{p1}, - InArt: []*model.ArtifactInputSpec{a1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: p1, - }, - Artifact: a1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.IsOccurrenceSpec{ - ID: ptrfrom.String("12345"), - }, - ExpOcc: nil, - }, - { - Name: "Query multiple", - InPkg: []*model.PkgInputSpec{p1}, - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: p1, - }, - Artifact: a1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "test justification", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Package: p1, - }, - Artifact: a2, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.IsOccurrenceSpec{}, - ExpOcc: []*model.IsOccurrence{ - { - Subject: p1out, - Artifact: a1out, - Justification: "test justification", - }, - { - Subject: p1out, - Artifact: a2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query bad ID", - InPkg: []*model.PkgInputSpec{p1}, - InArt: []*model.ArtifactInputSpec{a1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: p1, - }, - Artifact: a1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "justification", - }, - }, - }, - Query: &model.IsOccurrenceSpec{ - ID: ptrfrom.String("asdf"), - }, - ExpQueryErr: true, - }, - } - - ctx := s.Ctx - - hasOnly := false - for _, t := range tests { - if t.Only { - hasOnly = true - break - } - } - - for _, test := range tests { - if hasOnly && !test.Only { - continue - } - - s.Run(test.Name, func() { - b, err := GetBackend(s.Client) - s.Require().NoError(err, "Could not instantiate testing backend") - - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - s.T().Fatalf("Could not ingest artifact: %v", err) - } - } - - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - s.T().Fatalf("Could not ingest package: %v", err) - } - } - - for _, src := range test.InSrc { - if _, err := b.IngestSource(ctx, *src); err != nil { - s.T().Fatalf("Could not ingest source: %v", err) - } - } - - for _, o := range test.Calls { - _, err := b.IngestOccurrence(ctx, o.PkgSrc, *o.Artifact, *o.Occurrence) - if test.ExpIngestErr { - s.Require().Error(err, "Expected ingest error") - } else { - s.Require().NoError(err, "Unexpected ingest error") - } - } - got, err := b.IsOccurrence(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - s.T().Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpOcc, got, ignoreID, ignoreEmptySlices); diff != "" { - s.T().Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func (s *Suite) TestIngestOccurrences() { - type call struct { - PkgSrcs model.PackageOrSourceInputs - Artifacts []*model.ArtifactInputSpec - Occurrences []*model.IsOccurrenceInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - InArt []*model.ArtifactInputSpec - Calls []call - ExpIngestErr bool - }{{ - Name: "HappyPath - packages", - InPkg: []*model.PkgInputSpec{p1, p2}, - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - call{ - PkgSrcs: model.PackageOrSourceInputs{ - Packages: []*model.PkgInputSpec{p1, p2}, - }, - Artifacts: []*model.ArtifactInputSpec{a1, a2}, - Occurrences: []*model.IsOccurrenceInputSpec{{ - Justification: "test justification", - }, { - Justification: "test justification", - }}, - }, - }, - }, { - Name: "HappyPath - sources", - InSrc: []*model.SourceInputSpec{s1}, - InArt: []*model.ArtifactInputSpec{a1}, - Calls: []call{ - call{ - PkgSrcs: model.PackageOrSourceInputs{ - Sources: []*model.SourceInputSpec{s1}, - }, - Artifacts: []*model.ArtifactInputSpec{a1}, - Occurrences: []*model.IsOccurrenceInputSpec{{ - Justification: "test justification", - }}, - }, - }, - }} - ctx := s.Ctx - for _, test := range tests { - s.Run(test.Name, func() { - t := s.T() - b, err := GetBackend(s.Client) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - for _, o := range test.Calls { - _, err := b.IngestOccurrences(ctx, o.PkgSrcs, o.Artifacts, o.Occurrences) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - } - }) - } -} diff --git a/pkg/assembler/backends/ent/backend/package.go b/pkg/assembler/backends/ent/backend/package.go index c1e3b139b0..a9e8f71586 100644 --- a/pkg/assembler/backends/ent/backend/package.go +++ b/pkg/assembler/backends/ent/backend/package.go @@ -94,7 +94,7 @@ func (b *EntBackend) Packages(ctx context.Context, pkgSpec *model.PkgSpec) ([]*m return collect(pkgs, toModelPackage), nil } -func (b *EntBackend) IngestPackages(ctx context.Context, pkgs []*model.PkgInputSpec) ([]*model.PackageIDs, error) { +func (b *EntBackend) IngestPackages(ctx context.Context, pkgs []*model.IDorPkgInput) ([]*model.PackageIDs, error) { // FIXME: (ivanvanderbyl) This will be suboptimal because we can't batch insert relations with upserts. See Readme. pkgsID := make([]*model.PackageIDs, len(pkgs)) eg, ctx := errgroup.WithContext(ctx) @@ -115,9 +115,9 @@ func (b *EntBackend) IngestPackages(ctx context.Context, pkgs []*model.PkgInputS return pkgsID, nil } -func (b *EntBackend) IngestPackage(ctx context.Context, pkg model.PkgInputSpec) (*model.PackageIDs, error) { +func (b *EntBackend) IngestPackage(ctx context.Context, pkg model.IDorPkgInput) (*model.PackageIDs, error) { pkgVersionID, err := WithinTX(ctx, b.client, func(ctx context.Context) (*model.PackageIDs, error) { - p, err := upsertPackage(ctx, ent.TxFromContext(ctx), pkg) + p, err := upsertPackage(ctx, ent.TxFromContext(ctx), *pkg.PackageInput) if err != nil { return nil, errors.Wrap(err, "failed to upsert package") } diff --git a/pkg/assembler/backends/ent/backend/package_test.go b/pkg/assembler/backends/ent/backend/package_test.go deleted file mode 100644 index fbed988f97..0000000000 --- a/pkg/assembler/backends/ent/backend/package_test.go +++ /dev/null @@ -1,433 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build integration - -package backend - -import ( - "context" - "testing" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/pkg/assembler/backends/ent" - "github.com/guacsec/guac/pkg/assembler/backends/ent/packageversion" - "github.com/guacsec/guac/pkg/assembler/graphql/model" - "github.com/stretchr/testify/assert" -) - -func TestHashPackageVersions(t *testing.T) { - tests := []struct { - name string - pkg model.PkgInputSpec - expected string - }{ - { - name: "With empty qualifiers", - pkg: model.PkgInputSpec{Version: ptr("1.0.0"), Subpath: ptr("subpath"), Qualifiers: []*model.PackageQualifierInputSpec{}}, - expected: "2f2b07de87ca7c566f419c7dd81afbc7be0d1bfe", - }, - { - name: "With nil qualifiers", - pkg: model.PkgInputSpec{Version: ptr("1.0.0"), Subpath: ptr("subpath"), Qualifiers: nil}, - expected: "2f2b07de87ca7c566f419c7dd81afbc7be0d1bfe", - }, - { - name: "With qualifiers", - pkg: model.PkgInputSpec{Version: ptr("1.0.0"), Subpath: ptr("subpath"), Qualifiers: []*model.PackageQualifierInputSpec{ - {Key: "arch", Value: "arm64"}, - {Key: "tag", Value: "foo"}, - }}, - expected: "38315cfad2f3b9a267ad75a564dda639f1e1c768", - }, - { - name: "With qualifiers reverse order", - pkg: model.PkgInputSpec{Version: ptr("1.0.0"), Subpath: ptr("subpath"), Qualifiers: []*model.PackageQualifierInputSpec{ - {Key: "tag", Value: "foo"}, - {Key: "arch", Value: "arm64"}, - }}, - expected: "38315cfad2f3b9a267ad75a564dda639f1e1c768", - }, - } - - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - result := versionHashFromInputSpec(test.pkg) - assert.Equal(t, test.expected, result) - }) - } -} - -func (s *Suite) Test_get_package_helpers() { - p1Spec := model.PkgInputSpec{ - Type: "apk", - Namespace: ptr("test"), - Name: "alpine", - Version: ptr("1.0.0"), - Subpath: ptr("subpath"), - Qualifiers: []*model.PackageQualifierInputSpec{ - {Key: "arch", Value: "arm64"}, - {Key: "a", Value: "b"}, - }, - } - - s.Run("HappyPath", func() { - ingestP2(s) - ingestP1(s) - }) - - s.Run("getPkgName", func() { - ingestP2(s) - ingestP1(s) - pkgName, err := getPkgName(s.Ctx, s.Client, model.PkgInputSpec{ - Type: "apk", - Namespace: ptr("test"), - Name: "alpine", - }) - s.Require().NoError(err) - s.Require().NotNil(pkgName) - s.Equal("alpine", pkgName.Name) - }) - - s.Run("getPkgVersion", func() { - ingestP2(s) - ingestP1(s) - pkgVersion, err := getPkgVersion(s.Ctx, s.Client, p1Spec) - s.Require().NoError(err) - s.Require().NotNil(pkgVersion) - }) - - s.Run("pkgTreeFromVersion", func() { - ingestP2(s) - ingestP1(s) - pkgVersion, err := getPkgVersion(s.Ctx, s.Client, p1Spec) - s.Require().NoError(err) - pkgTree, err := pkgTreeFromVersion(s.Ctx, pkgVersion) - s.Require().NoError(err) - s.Require().NotNil(pkgTree) - if s.Len(pkgTree.Edges.Namespaces, 1) { - if s.Len(pkgTree.Edges.Namespaces[0].Edges.Names, 1) { - if s.Len(pkgTree.Edges.Namespaces[0].Edges.Names[0].Edges.Versions, 1) { - s.Equal("1.0.0", pkgTree.Edges.Namespaces[0].Edges.Names[0].Edges.Versions[0].Version) - } - } - } - }) -} - -func ingestP2(s *Suite) { - p2Spec := model.PkgInputSpec{ - Type: "apk", - Namespace: ptr("test"), - Name: "alpine", - Version: ptr("1.0.0"), - Subpath: ptr("subpath"), - } - - _, err := WithinTX(s.Ctx, s.Client, func(ctx context.Context) (*model.PackageIDs, error) { - return upsertPackage(s.Ctx, ent.TxFromContext(ctx), p2Spec) - }) - s.Require().NoError(err) -} - -func (s *Suite) TestEmptyQualifiersPredicate() { - spec := model.PkgInputSpec{ - Type: "apk", - Namespace: ptr("test"), - Name: "alpine", - Version: ptr("1.0.0"), - Subpath: ptr("subpath"), - Qualifiers: []*model.PackageQualifierInputSpec{ - {Key: "arch", Value: "arm64"}, - {Key: "a", Value: "b"}, - }, - } - - s.Run("HappyPath", func() { - ingestP1(s) - }) - s.Run("Ingest twice", func() { - ingestP1(s) - // Ingest twice to ensure upserts are working - pkg, err := WithinTX(s.Ctx, s.Client, func(ctx context.Context) (*model.PackageIDs, error) { - return upsertPackage(s.Ctx, ent.TxFromContext(ctx), spec) - }) - s.Require().NoError(err) - s.Require().NotNil(pkg) - }) - - s.Run("Empty keys", func() { - ingestP1(s) - s.Empty(s.Client.PackageVersion.Query().Where(packageversion.QualifiersIsEmpty()).AllX(s.Ctx)) - }) - - s.Run("No Qualifiers", func() { - ingestP1(s) - spec.Qualifiers = nil - pkg, err := WithinTX(s.Ctx, s.Client, func(ctx context.Context) (*model.PackageIDs, error) { - return upsertPackage(s.Ctx, ent.TxFromContext(ctx), spec) - }) - s.Require().NoError(err) - s.Require().NotNil(pkg) - - s.Len(s.Client.PackageVersion.Query().Where(packageversion.QualifiersIsEmpty()).AllX(s.Ctx), 1) - }) - - s.Run("Single key", func() { - ingestP1(s) - versions := s.Client.PackageVersion.Query().Where(packageversion.QualifiersWithKeys("arch", "a")).AllX(s.Ctx) - s.NotEmpty(versions) - }) - - s.Run("Multiple keys", func() { - ingestP1(s) - versions := s.Client.PackageVersion.Query().Where(packageversion.QualifiersContains("arch", "arm64")).AllX(s.Ctx) - s.NotEmpty(versions) - }) - - s.Run("Using spec - Null value", func() { - ingestP1(s) - versions := s.Client.PackageVersion.Query().Where( - packageversion.QualifiersMatch([]*model.PackageQualifierSpec{{Key: "arch"}}, false), - ).AllX(s.Ctx) - s.NotEmpty(versions) - }) - - s.Run("Using spec - Multiple", func() { - ingestP1(s) - versions := s.Client.PackageVersion.Query().Where( - packageversion.QualifiersMatch([]*model.PackageQualifierSpec{ - {Key: "arch"}, - {Key: "a", Value: ptr("b")}, - }, false), - ).AllX(s.Ctx) - s.NotEmpty(versions) - }) - -} - -func ingestP1(s *Suite) { - p1Spec := model.PkgInputSpec{ - Type: "apk", - Namespace: ptr("test"), - Name: "alpine", - Version: ptr("1.0.0"), - Subpath: ptr("subpath"), - Qualifiers: []*model.PackageQualifierInputSpec{ - {Key: "arch", Value: "arm64"}, - {Key: "a", Value: "b"}, - }, - } - pkg, err := WithinTX(s.Ctx, s.Client, func(ctx context.Context) (*model.PackageIDs, error) { - return upsertPackage(s.Ctx, ent.TxFromContext(ctx), p1Spec) - }) - s.Require().NoError(err) - s.Require().NotNil(pkg) -} - -func (s *Suite) Test_IngestPackages() { - ctx := s.Ctx - tests := []struct { - name string - pkgInputs []*model.PkgInputSpec - want []*model.Package - wantErr bool - }{{ - name: "tensorflow empty version", - pkgInputs: []*model.PkgInputSpec{p1, p2, p3, p4}, - want: []*model.Package{p1out, p2out, p3out, p4out}, - wantErr: false, - }} - for _, tt := range tests { - s.Run(tt.name, func() { - c, err := GetBackend(s.Client) - s.NoError(err) - - got, err := c.IngestPackages(ctx, tt.pkgInputs) - if (err != nil) != tt.wantErr { - s.T().Errorf("demoClient.IngestPackages() error = %v, wantErr %v", err, tt.wantErr) - return - } - - // Here we check if all parameters are present and if they are alla different each other see https://github.com/guacsec/guac/pull/1330 - if len(got) != 4 || (got[0] == got[1] || got[1] == got[2] || got[2] == got[3]) { - diff := cmp.Diff(tt.want, got, ignoreID) - s.T().Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func (s *Suite) Test_Packages() { - ctx := s.Ctx - tests := []struct { - name string - pkgInput *model.PkgInputSpec - pkgFilter *model.PkgSpec - idInFilter bool - want []*model.Package - wantErr bool - }{ - { - name: "tensorflow empty version", - pkgInput: p1, - pkgFilter: &model.PkgSpec{ - Name: ptrfrom.String("tensorflow"), - }, - want: []*model.Package{p1out}, - }, - { - name: "tensorflow empty version, ID search", - pkgInput: p1, - pkgFilter: &model.PkgSpec{ - Name: ptrfrom.String("tensorflow"), - }, - idInFilter: true, - want: []*model.Package{p1out}, - }, - { - name: "tensorflow with version", - pkgInput: p2, - pkgFilter: &model.PkgSpec{ - Type: ptrfrom.String("pypi"), - Name: ptrfrom.String("tensorflow"), - }, - want: []*model.Package{p2out}, - }, - { - name: "tensorflow with version and subpath", - pkgInput: p3, - pkgFilter: &model.PkgSpec{ - Type: ptrfrom.String("pypi"), - Name: ptrfrom.String("tensorflow"), - Subpath: ptrfrom.String("saved_model_cli.py"), - }, - want: []*model.Package{p3out}, - }, - { - name: "tensorflow with version and subpath but query without subpath", - pkgInput: p3, - pkgFilter: &model.PkgSpec{ - Type: ptrfrom.String("pypi"), - Name: ptrfrom.String("tensorflow"), - }, - want: []*model.Package{p3out}, - }, - { - name: "tensorflow without subpath", - pkgInput: p2, - pkgFilter: &model.PkgSpec{ - Type: ptrfrom.String("pypi"), - Name: ptrfrom.String("tensorflow"), - Subpath: ptrfrom.String(""), - }, - want: []*model.Package{p2out}, - }, - { - name: "openssl with version", - pkgInput: p4, - pkgFilter: &model.PkgSpec{ - Name: ptrfrom.String("openssl"), - Version: ptrfrom.String("3.0.3"), - }, - want: []*model.Package{p4out}, - }} - - for _, tt := range tests { - s.Run(tt.name, func() { - t := s.T() - be, err := GetBackend(s.Client) - s.NoError(err) - ingestedPkgID, err := be.IngestPackage(ctx, *tt.pkgInput) - if (err != nil) != tt.wantErr { - t.Errorf("demoClient.IngestPackage() error = %v, wantErr %v", err, tt.wantErr) - return - } - - if tt.idInFilter && ingestedPkgID.PackageVersionID != "" { - tt.pkgFilter.ID = &ingestedPkgID.PackageVersionID - } - got, err := be.Packages(ctx, tt.pkgFilter) - if (err != nil) != tt.wantErr { - t.Errorf("demoClient.Packages() error = %v, wantErr %v", err, tt.wantErr) - return - } - if diff := cmp.Diff(tt.want, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -// This test is to traverse the other branches of the upsert, not covered by the happy path at the insertion, -// when the create fails due to the presence of the input in the store, and a where query is used in the error branch -func (s *Suite) TestPackagesIngestSameTwice() { - - tests := []struct { - name string - pkgInputsSpec []model.PkgInputSpec - }{{ - name: "IngestSameTwice", - pkgInputsSpec: []model.PkgInputSpec{ - { - Type: "apk", - Namespace: ptr("test"), - Name: "alpine", - Version: ptr("1.0.0"), - Subpath: ptr("subpath"), - Qualifiers: []*model.PackageQualifierInputSpec{ - {Key: "arch", Value: "amd64"}, - {Key: "ac", Value: "dc"}, - }, - }, - { - Type: "apk", - Namespace: ptr("test"), - Name: "alpine", - Version: ptr("1.0.0"), - Subpath: ptr("subpath"), - Qualifiers: []*model.PackageQualifierInputSpec{ - {Key: "arch", Value: "amd64"}, - {Key: "ac", Value: "dc"}, - }, - }, - }, - }} - - ctx := s.Ctx - for _, tt := range tests { - s.Run(tt.name, func() { - t := s.T() - b, err := GetBackend(s.Client) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - - for _, bIn := range tt.pkgInputsSpec { - if _, err := b.IngestPackage(ctx, bIn); err != nil { - t.Fatalf("Could not ingest package: %v , err: %v", bIn, err) - } - } - items, err := b.Packages(ctx, &model.PkgSpec{}) - if err != nil { - t.Fatalf("Error on load Packages %v", err) - } - if len(items) == 2 { - t.Fatalf("Wrong ingestions, ingest same twice found two") - } - }) - } -} diff --git a/pkg/assembler/backends/ent/backend/pkgequal.go b/pkg/assembler/backends/ent/backend/pkgequal.go index d5ffc56f2d..781dfb3143 100644 --- a/pkg/assembler/backends/ent/backend/pkgequal.go +++ b/pkg/assembler/backends/ent/backend/pkgequal.go @@ -45,9 +45,9 @@ func (b *EntBackend) PkgEqual(ctx context.Context, spec *model.PkgEqualSpec) ([] return collect(records, toModelPkgEqual), nil } -func (b *EntBackend) IngestPkgEqual(ctx context.Context, pkg model.PkgInputSpec, depPkg model.PkgInputSpec, pkgEqual model.PkgEqualInputSpec) (string, error) { +func (b *EntBackend) IngestPkgEqual(ctx context.Context, pkg model.IDorPkgInput, depPkg model.IDorPkgInput, pkgEqual model.PkgEqualInputSpec) (string, error) { id, err := WithinTX(ctx, b.client, func(ctx context.Context) (*int, error) { - return upsertPackageEqual(ctx, ent.TxFromContext(ctx), pkg, depPkg, pkgEqual) + return upsertPackageEqual(ctx, ent.TxFromContext(ctx), *pkg.PackageInput, *depPkg.PackageInput, pkgEqual) }) if err != nil { return "", err @@ -56,7 +56,7 @@ func (b *EntBackend) IngestPkgEqual(ctx context.Context, pkg model.PkgInputSpec, return strconv.Itoa(*id), nil } -func (b *EntBackend) IngestPkgEquals(ctx context.Context, pkgs []*model.PkgInputSpec, otherPackages []*model.PkgInputSpec, pkgEquals []*model.PkgEqualInputSpec) ([]string, error) { +func (b *EntBackend) IngestPkgEquals(ctx context.Context, pkgs []*model.IDorPkgInput, otherPackages []*model.IDorPkgInput, pkgEquals []*model.PkgEqualInputSpec) ([]string, error) { var ids []string for i, pkgEqual := range pkgEquals { id, err := b.IngestPkgEqual(ctx, *pkgs[i], *otherPackages[i], *pkgEqual) diff --git a/pkg/assembler/backends/ent/backend/pkgequal_test.go b/pkg/assembler/backends/ent/backend/pkgequal_test.go deleted file mode 100644 index e1298a9c1b..0000000000 --- a/pkg/assembler/backends/ent/backend/pkgequal_test.go +++ /dev/null @@ -1,874 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build integration - -package backend - -import ( - "slices" - "strconv" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/pkg/assembler/graphql/model" - jsoniter "github.com/json-iterator/go" -) - -var json = jsoniter.ConfigCompatibleWithStandardLibrary - -func (s *Suite) TestPkgEqual() { - type call struct { - P1 *model.PkgInputSpec - P2 *model.PkgInputSpec - PkgEqual *model.PkgEqualInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - Calls []call - Query *model.PkgEqualSpec - ExpPkgEqual []*model.PkgEqual - ExpInserts int - ExpIngestErr bool - ExpQueryErr bool - Only bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{p1, p2}, - Calls: []call{ - { - P1: p1, - P2: p2, - PkgEqual: &model.PkgEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.PkgEqualSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpPkgEqual: []*model.PkgEqual{ - { - Packages: []*model.Package{p1out, p2out}, - Justification: "test justification", - }, - }, - }, - { - // Only: true, - Name: "Ingest same, different order", - InPkg: []*model.PkgInputSpec{p1, p2}, - ExpInserts: 1, - Calls: []call{ - { - P1: p1, - P2: p2, - PkgEqual: &model.PkgEqualInputSpec{ - Justification: "test justification", - }, - }, - { - P1: p2, - P2: p1, - PkgEqual: &model.PkgEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.PkgEqualSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpPkgEqual: []*model.PkgEqual{ - { - Packages: []*model.Package{p1out, p2out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Justification", - // Only: true, - InPkg: []*model.PkgInputSpec{p1, p2}, - ExpInserts: 2, - Calls: []call{ - { - P1: p1, - P2: p2, - PkgEqual: &model.PkgEqualInputSpec{ - Justification: "test justification one", - }, - }, - { - P1: p1, - P2: p2, - PkgEqual: &model.PkgEqualInputSpec{ - Justification: "test justification two", - }, - }, - }, - Query: &model.PkgEqualSpec{ - Justification: ptrfrom.String("test justification two"), - }, - ExpPkgEqual: []*model.PkgEqual{ - { - Packages: []*model.Package{p1out, p2out}, - Justification: "test justification two", - }, - }, - }, - { - Name: "Query on pkg", - InPkg: []*model.PkgInputSpec{p1, p2, p3}, - Calls: []call{ - { - P1: p1, - P2: p2, - PkgEqual: &model.PkgEqualInputSpec{}, - }, - { - P1: p1, - P2: p3, - PkgEqual: &model.PkgEqualInputSpec{}, - }, - }, - Query: &model.PkgEqualSpec{ - Packages: []*model.PkgSpec{{ - ID: ptrfrom.String("2"), // index of p3 - }}, - }, - ExpPkgEqual: []*model.PkgEqual{ - { - Packages: []*model.Package{p1out, p3out}, - }, - }, - }, - { - Name: "Query on pkg multiple", - InPkg: []*model.PkgInputSpec{p1, p2, p3}, - Calls: []call{ - { - P1: p1, - P2: p2, - PkgEqual: &model.PkgEqualInputSpec{}, - }, - { - P1: p1, - P2: p3, - PkgEqual: &model.PkgEqualInputSpec{}, - }, - }, - Query: &model.PkgEqualSpec{ - Packages: []*model.PkgSpec{{ - ID: ptrfrom.String("0"), - }}, - }, - ExpPkgEqual: []*model.PkgEqual{ - { - Packages: []*model.Package{p1out, p2out}, - }, - { - Packages: []*model.Package{p1out, p3out}, - }, - }, - }, - { - Name: "Query on pkg details", - InPkg: []*model.PkgInputSpec{p1, p2, p3}, - Calls: []call{ - { - P1: p1, - P2: p2, - PkgEqual: &model.PkgEqualInputSpec{}, - }, - { - P1: p1, - P2: p3, - PkgEqual: &model.PkgEqualInputSpec{}, - }, - }, - Query: &model.PkgEqualSpec{ - Packages: []*model.PkgSpec{{ - Version: ptrfrom.String("2.11.1"), - Subpath: ptrfrom.String(""), - }}, - }, - ExpPkgEqual: []*model.PkgEqual{ - { - Packages: []*model.Package{p1out, p2out}, - }, - }, - }, - { - Name: "Query on pkg algo and pkg", - InPkg: []*model.PkgInputSpec{p1, p2, p3}, - Calls: []call{ - { - P1: p1, - P2: p2, - PkgEqual: &model.PkgEqualInputSpec{ - Justification: "test justification", - }, - }, - { - P1: p1, - P2: p3, - PkgEqual: &model.PkgEqualInputSpec{}, - }, - }, - Query: &model.PkgEqualSpec{ - Packages: []*model.PkgSpec{{ - Type: ptrfrom.String("pypi"), - Namespace: ptrfrom.String(""), - Name: ptrfrom.String("tensorflow"), - Version: ptrfrom.String("2.11.1"), - Subpath: ptrfrom.String(""), - }}, - }, - ExpPkgEqual: []*model.PkgEqual{ - { - Justification: "test justification", - Packages: []*model.Package{p1out, p2out}, - }, - }, - }, - { - // Only: true, - Name: "Query on both pkgs", - InPkg: []*model.PkgInputSpec{p1, p2, p3}, - Calls: []call{ - { - P1: p1, - P2: p2, - PkgEqual: &model.PkgEqualInputSpec{}, - }, - { - P1: p2, - P2: p3, - PkgEqual: &model.PkgEqualInputSpec{}, - }, - }, - Query: &model.PkgEqualSpec{ - Packages: []*model.PkgSpec{ - { - Subpath: ptrfrom.String("saved_model_cli.py"), - }, - { - ID: ptrfrom.String("1"), - }, - }, - }, - ExpPkgEqual: []*model.PkgEqual{ - { - Packages: []*model.Package{p2out, p3out}, - }, - }, - }, - { - Name: "Query on both pkgs, one filter", - InPkg: []*model.PkgInputSpec{p1, p2, p3}, - Calls: []call{ - { - P1: p1, - P2: p2, - PkgEqual: &model.PkgEqualInputSpec{}, - }, - { - P1: p2, - P2: p3, - PkgEqual: &model.PkgEqualInputSpec{}, - }, - { - P1: p1, - P2: p3, - PkgEqual: &model.PkgEqualInputSpec{}, - }, - }, - Query: &model.PkgEqualSpec{ - Packages: []*model.PkgSpec{ - { - Version: ptrfrom.String(""), - }, - { - Version: ptrfrom.String("2.11.1"), - Subpath: ptrfrom.String("saved_model_cli.py"), - }, - }, - }, - ExpPkgEqual: []*model.PkgEqual{ - { - Packages: []*model.Package{p1out, p3out}, - }, - }, - }, - { - Name: "Query none", - InPkg: []*model.PkgInputSpec{p1, p2, p3}, - Calls: []call{ - { - P1: p1, - P2: p2, - PkgEqual: &model.PkgEqualInputSpec{}, - }, - { - P1: p2, - P2: p3, - PkgEqual: &model.PkgEqualInputSpec{}, - }, - { - P1: p1, - P2: p3, - PkgEqual: &model.PkgEqualInputSpec{}, - }, - }, - Query: &model.PkgEqualSpec{ - Packages: []*model.PkgSpec{ - { - Version: ptrfrom.String("1.2.3"), - }, - }, - }, - ExpPkgEqual: nil, - }, - { - Name: "Query on ID", - InPkg: []*model.PkgInputSpec{p1, p2, p3}, - Calls: []call{ - { - P1: p1, - P2: p2, - PkgEqual: &model.PkgEqualInputSpec{}, - }, - { - P1: p2, - P2: p3, - PkgEqual: &model.PkgEqualInputSpec{}, - }, - { - P1: p1, - P2: p3, - PkgEqual: &model.PkgEqualInputSpec{}, - }, - }, - Query: &model.PkgEqualSpec{ - ID: ptrfrom.String("1"), - }, - ExpPkgEqual: []*model.PkgEqual{ - { - Packages: []*model.Package{p2out, p3out}, - }, - }, - }, - { - Name: "Ingest no P1", - InPkg: []*model.PkgInputSpec{p2}, - Calls: []call{ - { - P1: p1, - P2: p2, - PkgEqual: &model.PkgEqualInputSpec{}, - }, - }, - ExpIngestErr: true, - }, - { - Name: "Ingest no P2", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - P1: p1, - P2: p2, - PkgEqual: &model.PkgEqualInputSpec{}, - }, - }, - ExpIngestErr: true, - }, - // { - // Name: "Query three", - // InPkg: []*model.PkgInputSpec{p1, p2, p3}, - // Calls: []call{ - // { - // P1: p1, - // P2: p2, - // PkgEqual: &model.PkgEqualInputSpec{}, - // }, - // { - // P1: p2, - // P2: p3, - // PkgEqual: &model.PkgEqualInputSpec{}, - // }, - // { - // P1: p1, - // P2: p3, - // PkgEqual: &model.PkgEqualInputSpec{}, - // }, - // }, - // Query: &model.PkgEqualSpec{ - // Packages: []*model.PkgSpec{ - // { - // Name: ptrfrom.String("somename"), - // }, - // { - // Version: ptrfrom.String("1.2.3"), - // }, - // { - // Type: ptrfrom.String("asdf"), - // }, - // }, - // }, - // ExpQueryErr: true, - // }, - { - Name: "Query bad ID", - InPkg: []*model.PkgInputSpec{p1, p2, p3}, - Calls: []call{ - { - P1: p1, - P2: p2, - PkgEqual: &model.PkgEqualInputSpec{}, - }, - { - P1: p2, - P2: p3, - PkgEqual: &model.PkgEqualInputSpec{}, - }, - { - P1: p1, - P2: p3, - PkgEqual: &model.PkgEqualInputSpec{}, - }, - }, - Query: &model.PkgEqualSpec{ - ID: ptrfrom.String("asdf"), - }, - ExpQueryErr: true, - }, - } - - ctx := s.Ctx - hasOnly := false - for _, t := range tests { - if t.Only { - hasOnly = true - break - } - } - - for _, test := range tests { - if hasOnly && !test.Only { - continue - } - s.Run(test.Name, func() { - t := s.T() - b, err := GetBackend(s.Client) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - pkgIDs := make([]string, len(test.InPkg)) - for i, a := range test.InPkg { - if id, err := b.IngestPackage(ctx, *a); err != nil { - t.Fatalf("Could not ingest pkg: %v", err) - } else { - pkgs, err := b.Packages(ctx, &model.PkgSpec{ID: &id.PackageVersionID}) - if err != nil { - t.Fatalf("Package not found with ID %v error: %v", id, err) - } - if len(pkgs) > 0 { - pkgIDs[i] = pkgs[0].Namespaces[0].Names[0].Versions[0].ID - } else { - t.Fatalf("Package not found with ID %v", id) - } - } - } - - if test.Query != nil { - for i, pkg := range test.Query.Packages { - if pkg.ID == nil { - continue - } - idIdx, err := strconv.Atoi(*pkg.ID) - if err == nil { - if idIdx >= len(pkgIDs) { - s.T().Fatalf("ID index out of range, want: %d, got: %d", len(pkgIDs), idIdx) - } - test.Query.Packages[i].ID = &pkgIDs[idIdx] - } - } - } - - ids := make([]string, len(test.Calls)) - for i, o := range test.Calls { - id, err := b.IngestPkgEqual(ctx, *o.P1, *o.P2, *o.PkgEqual) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - - ids[i] = id - } - afterCount := s.Client.PkgEqual.Query().CountX(ctx) - - if test.ExpInserts > 0 { - if want, got := test.ExpInserts, afterCount; want != got { - t.Errorf("unexpected number of inserts, want: %d, got: %d", want, got) - } - } - - if test.Query != nil && test.Query.ID != nil { - idIdx, err := strconv.Atoi(*test.Query.ID) - if err == nil { - if idIdx >= len(ids) { - s.T().Fatalf("ID index out of range, want: %d, got: %d", len(ids), idIdx) - } - test.Query.ID = &ids[idIdx] - } - } - - got, err := b.PkgEqual(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - - if diff := cmp.Diff(test.ExpPkgEqual, got, ignoreID, ignoreEmptySlices); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func (s *Suite) TestIngestPkgEquals() { - type call struct { - P1 []*model.PkgInputSpec - P2 []*model.PkgInputSpec - PE []*model.PkgEqualInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - Calls []call - Query *model.PkgEqualSpec - ExpHE []*model.PkgEqual - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{p1, p2}, - Calls: []call{ - { - P1: []*model.PkgInputSpec{p1, p1}, - P2: []*model.PkgInputSpec{p2, p2}, - PE: []*model.PkgEqualInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.PkgEqualSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHE: []*model.PkgEqual{ - { - Packages: []*model.Package{p1out, p2out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest same, different order", - InPkg: []*model.PkgInputSpec{p1, p2}, - Calls: []call{ - { - P1: []*model.PkgInputSpec{p1, p2}, - P2: []*model.PkgInputSpec{p2, p1}, - PE: []*model.PkgEqualInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.PkgEqualSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHE: []*model.PkgEqual{ - { - Packages: []*model.Package{p1out, p2out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on pkg details", - InPkg: []*model.PkgInputSpec{p1, p2, p3}, - Calls: []call{ - { - P1: []*model.PkgInputSpec{p1, p1}, - P2: []*model.PkgInputSpec{p2, p3}, - PE: []*model.PkgEqualInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.PkgEqualSpec{ - Packages: []*model.PkgSpec{{ - Version: ptrfrom.String("2.11.1"), - Subpath: ptrfrom.String(""), - }}, - }, - ExpHE: []*model.PkgEqual{ - { - Packages: []*model.Package{p1out, p2out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on pkg algo and pkg", - InPkg: []*model.PkgInputSpec{p1, p2, p3}, - Calls: []call{ - { - P1: []*model.PkgInputSpec{p1, p1}, - P2: []*model.PkgInputSpec{p2, p3}, - PE: []*model.PkgEqualInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.PkgEqualSpec{ - Packages: []*model.PkgSpec{{ - Type: ptrfrom.String("pypi"), - Namespace: ptrfrom.String(""), - Name: ptrfrom.String("tensorflow"), - Version: ptrfrom.String("2.11.1"), - Subpath: ptrfrom.String(""), - }}, - }, - ExpHE: []*model.PkgEqual{ - { - Packages: []*model.Package{p1out, p2out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on both pkgs, one filter", - InPkg: []*model.PkgInputSpec{p1, p2, p3}, - Calls: []call{ - { - P1: []*model.PkgInputSpec{p1, p1}, - P2: []*model.PkgInputSpec{p2, p3}, - PE: []*model.PkgEqualInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.PkgEqualSpec{ - Packages: []*model.PkgSpec{ - { - Version: ptrfrom.String(""), - }, - { - Version: ptrfrom.String("2.11.1"), - Subpath: ptrfrom.String("saved_model_cli.py"), - }, - }, - }, - ExpHE: []*model.PkgEqual{ - { - Packages: []*model.Package{p1out, p3out}, - Justification: "test justification", - }, - }, - }, - } - ctx := s.Ctx - for _, test := range tests { - s.Run(test.Name, func() { - t := s.T() - b, err := GetBackend(s.Client) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - - if _, err := b.IngestPackages(ctx, test.InPkg); err != nil { - t.Fatalf("Could not ingest pkg: %v", err) - } - for _, o := range test.Calls { - _, err := b.IngestPkgEquals(ctx, o.P1, o.P2, o.PE) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.PkgEqual(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpHE, got, IngestPredicatesCmpOpts...); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func (s *Suite) TestPkgEqualNeighbors() { - s.T().Skip() - - type call struct { - P1 *model.PkgInputSpec - P2 *model.PkgInputSpec - HE *model.PkgEqualInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - Calls []call - ExpNeighbors map[string][]string - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{p1, p2}, - Calls: []call{ - { - P1: p1, - P2: p2, - HE: &model.PkgEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - ExpNeighbors: map[string][]string{ - "5": {"2", "7"}, // p1 - "6": {"2", "7"}, // p2 - "7": {"2", "2"}, // pkgequal - }, - }, - { - Name: "Multiple", - InPkg: []*model.PkgInputSpec{p1, p2, p3}, - Calls: []call{ - { - P1: p1, - P2: p2, - HE: &model.PkgEqualInputSpec{ - Justification: "test justification", - }, - }, - { - P1: p1, - P2: p3, - HE: &model.PkgEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - ExpNeighbors: map[string][]string{ - "5": {"2", "8", "9"}, // p1 - "6": {"2", "8"}, // p2 - "7": {"2", "9"}, // p3 - "8": {"2", "2"}, // pkgequal 1 - "9": {"2", "2"}, // pkgequal 2 - }, - }, - } - ctx := s.Ctx - for _, test := range tests { - s.Run(test.Name, func() { - t := s.T() - b, err := GetBackend(s.Client) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, a := range test.InPkg { - if _, err := b.IngestPackage(ctx, *a); err != nil { - t.Fatalf("Could not ingest pkg: %v", err) - } - } - for _, o := range test.Calls { - if _, err := b.IngestPkgEqual(ctx, *o.P1, *o.P2, *o.HE); err != nil { - t.Fatalf("Could not ingest PkgEqual: %v", err) - } - } - for q, r := range test.ExpNeighbors { - got, err := b.Neighbors(ctx, q, nil) - if err != nil { - t.Fatalf("Could not query neighbors: %s", err) - } - gotIDs := convNodes(got) - slices.Sort(r) - slices.Sort(gotIDs) - if diff := cmp.Diff(r, gotIDs); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - } - }) - } -} - -func convNode(n model.Node) hasID { - // All nodes have a json "id" - // Only getting top-level id however - var h hasID - b, _ := json.Marshal(n) - _ = json.Unmarshal(b, &h) - return h -} - -func convNodes(ns []model.Node) []string { - var ids []string - for _, n := range ns { - h := convNode(n) - ids = append(ids, h.ID) - } - return ids -} - -type hasID struct { - ID string `json:"id"` -} diff --git a/pkg/assembler/backends/ent/backend/pointOfContact.go b/pkg/assembler/backends/ent/backend/pointOfContact.go index 92daa3381d..3830296dc1 100644 --- a/pkg/assembler/backends/ent/backend/pointOfContact.go +++ b/pkg/assembler/backends/ent/backend/pointOfContact.go @@ -126,7 +126,7 @@ func upsertPointOfContact(ctx context.Context, client *ent.Tx, subject model.Pac switch { case subject.Artifact != nil: - art, err := client.Artifact.Query().Where(artifactQueryInputPredicates(*subject.Artifact)).Only(ctx) + art, err := client.Artifact.Query().Where(artifactQueryInputPredicates(*subject.Artifact.ArtifactInput)).Only(ctx) if err != nil { return nil, fmt.Errorf("failed to retrieve subject artifact :: %s", err) } @@ -141,7 +141,7 @@ func upsertPointOfContact(ctx context.Context, client *ent.Tx, subject model.Pac case subject.Package != nil: if pkgMatchType.Pkg == model.PkgMatchTypeSpecificVersion { - pv, err := getPkgVersion(ctx, client.Client(), *subject.Package) + pv, err := getPkgVersion(ctx, client.Client(), *subject.Package.PackageInput) if err != nil { return nil, fmt.Errorf("failed to retrieve subject package version :: %s", err) } @@ -154,7 +154,7 @@ func upsertPointOfContact(ctx context.Context, client *ent.Tx, subject model.Pac sql.IsNull(pointofcontact.FieldSourceID), ) } else { - pn, err := getPkgName(ctx, client.Client(), *subject.Package) + pn, err := getPkgName(ctx, client.Client(), *subject.Package.PackageInput) if err != nil { return nil, fmt.Errorf("failed to retrieve subject package name :: %s", err) } @@ -169,7 +169,7 @@ func upsertPointOfContact(ctx context.Context, client *ent.Tx, subject model.Pac } case subject.Source != nil: - srcID, err := getSourceNameID(ctx, client.Client(), *subject.Source) + srcID, err := getSourceNameID(ctx, client.Client(), *subject.Source.SourceInput) if err != nil { return nil, fmt.Errorf("failed to retrieve subject source :: %s", err) } @@ -237,18 +237,18 @@ func pointOfContactInputPredicate(subject model.PackageSourceOrArtifactInput, pk var subjectSpec *model.PackageSourceOrArtifactSpec if subject.Package != nil { if pkgMatchType != nil && pkgMatchType.Pkg == model.PkgMatchTypeAllVersions { - subject.Package.Version = nil + subject.Package.PackageInput.Version = nil } subjectSpec = &model.PackageSourceOrArtifactSpec{ - Package: helper.ConvertPkgInputSpecToPkgSpec(subject.Package), + Package: helper.ConvertPkgInputSpecToPkgSpec(subject.Package.PackageInput), } } else if subject.Artifact != nil { subjectSpec = &model.PackageSourceOrArtifactSpec{ - Artifact: helper.ConvertArtInputSpecToArtSpec(subject.Artifact), + Artifact: helper.ConvertArtInputSpecToArtSpec(subject.Artifact.ArtifactInput), } } else { subjectSpec = &model.PackageSourceOrArtifactSpec{ - Source: helper.ConvertSrcInputSpecToSrcSpec(subject.Source), + Source: helper.ConvertSrcInputSpecToSrcSpec(subject.Source.SourceInput), } } return pointOfContactPredicate(&model.PointOfContactSpec{ diff --git a/pkg/assembler/backends/ent/backend/pointOfContact_test.go b/pkg/assembler/backends/ent/backend/pointOfContact_test.go deleted file mode 100644 index 9fce01888f..0000000000 --- a/pkg/assembler/backends/ent/backend/pointOfContact_test.go +++ /dev/null @@ -1,970 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build integration - -package backend - -import ( - "strconv" - "time" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -func (s *Suite) TestPointOfContact() { - type call struct { - Sub model.PackageSourceOrArtifactInput - Match *model.MatchFlags - HM *model.PointOfContactInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - InArt []*model.ArtifactInputSpec - Calls []call - Query *model.PointOfContactSpec - ExpHM []*model.PointOfContact - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.PointOfContactInputSpec{ - Email: "a@b.com", - Info: "info1", - Since: time.Unix(1e9, 0), - Justification: "test justification", - }, - }, - }, - Query: &model.PointOfContactSpec{ - Email: ptrfrom.String("a@b.com"), - Info: ptrfrom.String("info1"), - Since: ptrfrom.Time(time.Unix(1e9, 0)), - Justification: ptrfrom.String("test justification"), - }, - ExpHM: []*model.PointOfContact{ - { - Subject: p1out, - Email: "a@b.com", - Info: "info1", - Since: time.Unix(1e9, 0), - Justification: "test justification", - }, - }, - }, - { - Name: "HappyPath check time since", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.PointOfContactInputSpec{ - Email: "a@b.com", - Info: "info1", - Since: time.Unix(1e9, 0), - Justification: "test justification", - }, - }, - }, - Query: &model.PointOfContactSpec{ - Email: ptrfrom.String("a@b.com"), - Info: ptrfrom.String("info1"), - Since: ptrfrom.Time(time.Unix(1e8, 0)), - Justification: ptrfrom.String("test justification"), - }, - ExpHM: []*model.PointOfContact{ - { - Subject: p1out, - Email: "a@b.com", - Info: "info1", - Since: time.Unix(1e9, 0), - Justification: "test justification", - }, - }, - }, - { - Name: "UnhappyPath check time since", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.PointOfContactInputSpec{ - Email: "a@b.com", - Info: "info1", - Since: time.Unix(1e9, 0), - Justification: "test justification", - }, - }, - }, - Query: &model.PointOfContactSpec{ - Email: ptrfrom.String("a@b.com"), - Info: ptrfrom.String("info1"), - Since: ptrfrom.Time(time.Unix(1e10, 0)), - Justification: ptrfrom.String("test justification"), - }, - ExpHM: nil, - }, - { - Name: "HappyPath All Version", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.PointOfContactSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHM: []*model.PointOfContact{ - { - Subject: p1outName, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest same twice", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.PointOfContactSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHM: []*model.PointOfContact{ - { - Subject: p1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest two different keys", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.PointOfContactInputSpec{ - Email: "a@b.com", - Info: "info1", - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.PointOfContactInputSpec{ - Email: "x@y.com", - Info: "info2", - Justification: "test justification", - }, - }, - }, - Query: &model.PointOfContactSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHM: []*model.PointOfContact{ - { - Subject: p1out, - Email: "a@b.com", - Info: "info1", - Justification: "test justification", - }, - { - Subject: p1out, - Email: "x@y.com", - Info: "info2", - Justification: "test justification", - }, - }, - }, - - { - Name: "Query on Justification", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification one", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification two", - }, - }, - }, - Query: &model.PointOfContactSpec{ - Justification: ptrfrom.String("test justification one"), - }, - ExpHM: []*model.PointOfContact{ - { - Subject: p1out, - Justification: "test justification one", - }, - }, - }, - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{p1, p2}, - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s1, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.PointOfContactSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String("2.11.1"), - }, - }, - }, - ExpHM: []*model.PointOfContact{ - { - Subject: p2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Source", - InPkg: []*model.PkgInputSpec{p1}, - InSrc: []*model.SourceInputSpec{s1, s2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s1, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s2, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.PointOfContactSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Source: &model.SourceSpec{ - Name: ptrfrom.String("bobsrepo"), - }, - }, - }, - ExpHM: []*model.PointOfContact{ - { - Subject: s2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Artifact", - InSrc: []*model.SourceInputSpec{s1}, - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a1, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a2, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s1, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.PointOfContactSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha1"), - }, - }, - }, - ExpHM: []*model.PointOfContact{ - { - Subject: a2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query none", - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a1, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a2, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.PointOfContactSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("asdf"), - }, - }, - }, - ExpHM: nil, - }, - { - Name: "Query multiple", - InSrc: []*model.SourceInputSpec{s1, s2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s1, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s2, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.PointOfContactSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHM: []*model.PointOfContact{ - { - Subject: s1out, - Justification: "test justification", - }, - { - Subject: s2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query Packages", - InPkg: []*model.PkgInputSpec{p1, p2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.PointOfContactSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String("2.11.1"), - }, - }, - }, - ExpHM: []*model.PointOfContact{ - { - Subject: p2out, - Justification: "test justification", - }, - { - Subject: p1outName, - Justification: "test justification", - }, - }, - }, - { - Name: "Query ID", - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a1, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a2, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.PointOfContactSpec{ - ID: ptrfrom.String("0"), - }, - ExpHM: []*model.PointOfContact{ - { - Subject: a1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest without subject", - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a1, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - }, - ExpIngestErr: true, - }, - { - Name: "Query good ID", - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s1, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.PointOfContactSpec{ - ID: ptrfrom.String("asdf"), - }, - ExpQueryErr: true, - }, - } - ctx := s.Ctx - for _, test := range tests { - s.Run(test.Name, func() { - t := s.T() - b, err := GetBackend(s.Client) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - recordIDs := make([]string, len(test.Calls)) - for i, o := range test.Calls { - poc, err := b.IngestPointOfContact(ctx, o.Sub, o.Match, *o.HM) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - recordIDs[i] = poc - } - - if test.Query.ID != nil { - idIdx, err := strconv.Atoi(*test.Query.ID) - if err == nil { - if idIdx < 0 || idIdx >= len(recordIDs) { - s.T().Logf("ID index out of range, want: %d, got: %d. So ID %d will be directly used to query.", len(recordIDs), idIdx, idIdx) - } else { - test.Query.ID = &recordIDs[idIdx] - } - } - } - - got, err := b.PointOfContact(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpHM, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func (s *Suite) TestIngestPointOfContacts() { - type call struct { - Sub model.PackageSourceOrArtifactInputs - Match *model.MatchFlags - PC []*model.PointOfContactInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - InArt []*model.ArtifactInputSpec - Calls []call - Query *model.PointOfContactSpec - ExpPC []*model.PointOfContact - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - PC: []*model.PointOfContactInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.PointOfContactSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpPC: []*model.PointOfContact{ - { - Subject: p1out, - Justification: "test justification", - }, - }, - }, - { - Name: "HappyPath All Version", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - PC: []*model.PointOfContactInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.PointOfContactSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpPC: []*model.PointOfContact{ - { - Subject: p1outName, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest same twice", - InPkg: []*model.PkgInputSpec{p3}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p3, p3}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - PC: []*model.PointOfContactInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.PointOfContactSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String("2.11.1"), - Subpath: ptrfrom.String("saved_model_cli.py"), - }, - }, - }, - ExpPC: []*model.PointOfContact{ - { - Subject: p3out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{p1, p4}, - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1, p4}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - PC: []*model.PointOfContactInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - { - Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{s1}, - }, - PC: []*model.PointOfContactInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.PointOfContactSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Package: &model.PkgSpec{ - Type: ptrfrom.String("conan"), - Namespace: ptrfrom.String("openssl.org"), - Name: ptrfrom.String("openssl"), - }, - }, - }, - ExpPC: []*model.PointOfContact{ - { - Subject: p4out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Source", - InPkg: []*model.PkgInputSpec{p1}, - InSrc: []*model.SourceInputSpec{s1, s2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - PC: []*model.PointOfContactInputSpec{ - { - Justification: "test justification", - }, - }, - }, - { - Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{s2, s2}, - }, - PC: []*model.PointOfContactInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.PointOfContactSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Source: &model.SourceSpec{ - Name: ptrfrom.String("bobsrepo"), - }, - }, - }, - ExpPC: []*model.PointOfContact{ - { - Subject: s2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Artifact", - InSrc: []*model.SourceInputSpec{s1}, - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Artifacts: []*model.ArtifactInputSpec{a1, a2}, - }, - PC: []*model.PointOfContactInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - { - Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{s1}, - }, - PC: []*model.PointOfContactInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.PointOfContactSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha1"), - }, - }, - }, - ExpPC: []*model.PointOfContact{ - { - Subject: a2out, - Justification: "test justification", - }, - }, - }, - } - ctx := s.Ctx - for _, test := range tests { - s.Run(test.Name, func() { - t := s.T() - b, err := GetBackend(s.Client) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - for _, o := range test.Calls { - _, err := b.IngestPointOfContacts(ctx, o.Sub, o.Match, o.PC) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.PointOfContact(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpPC, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} diff --git a/pkg/assembler/backends/ent/backend/query_helpers.go b/pkg/assembler/backends/ent/backend/query_helpers.go index 82f85b5226..01b24d7b3b 100644 --- a/pkg/assembler/backends/ent/backend/query_helpers.go +++ b/pkg/assembler/backends/ent/backend/query_helpers.go @@ -15,15 +15,6 @@ package backend -import ( - "context" - - "github.com/guacsec/guac/pkg/assembler/backends/ent" - "github.com/guacsec/guac/pkg/assembler/backends/ent/packagename" - "github.com/guacsec/guac/pkg/assembler/backends/ent/packagenamespace" - "github.com/guacsec/guac/pkg/assembler/backends/ent/packageversion" -) - //func getArtifact(ctx context.Context, client *ent.Client, artin *model.ArtifactInputSpec) (*ent.Artifact, error) { // return client.Artifact.Query(). // Where(artifact.Algorithm(artin.Algorithm), artifact.Digest(artin.Digest)). @@ -34,52 +25,52 @@ import ( // rebuild the full top level tree object with just the nested objects that are // part of the path to that node -func pkgTreeFromVersion(ctx context.Context, pv *ent.PackageVersion) (*ent.PackageType, error) { - // pv.QueryName().QueryNamespace().QueryPackage().Query +// func pkgTreeFromVersion(ctx context.Context, pv *ent.PackageVersion) (*ent.PackageType, error) { +// // pv.QueryName().QueryNamespace().QueryPackage().Query - // eagerLoadedVersion, err := pv. - // QueryName(). - // WithNamespace(). - // QueryNamespace(). - // WithPackage(). - // QueryPackage(). - // WithNamespaces(func(q *ent.PackageNamespaceQuery) { - // q.WithNames(func(q *ent.PackageNameQuery) { - // q.WithVersions() - // }) - // }). - // Only(ctx) - // if err != nil { - // return nil, err - // } +// // eagerLoadedVersion, err := pv. +// // QueryName(). +// // WithNamespace(). +// // QueryNamespace(). +// // WithPackage(). +// // QueryPackage(). +// // WithNamespaces(func(q *ent.PackageNamespaceQuery) { +// // q.WithNames(func(q *ent.PackageNameQuery) { +// // q.WithVersions() +// // }) +// // }). +// // Only(ctx) +// // if err != nil { +// // return nil, err +// // } - // return eagerLoadedVersion, nil +// // return eagerLoadedVersion, nil - n, err := pv.QueryName().Only(ctx) - if err != nil { - return nil, err - } - ns, err := n.QueryNamespace().Only(ctx) - if err != nil { - return nil, err - } +// n, err := pv.QueryName().Only(ctx) +// if err != nil { +// return nil, err +// } +// ns, err := n.QueryNamespace().Only(ctx) +// if err != nil { +// return nil, err +// } - q := ns.QueryPackage() - buildPackageTreeQuery(q, ns.Namespace, n.Name, pv) - return q.Only(ctx) -} +// q := ns.QueryPackage() +// buildPackageTreeQuery(q, ns.Namespace, n.Name, pv) +// return q.Only(ctx) +// } -func buildPackageTreeQuery(q *ent.PackageTypeQuery, ns, packageName string, pv *ent.PackageVersion) { - q.WithNamespaces(func(q *ent.PackageNamespaceQuery) { - q.Where(packagenamespace.Namespace(ns)) - q.WithNames(func(q *ent.PackageNameQuery) { - q.Where(packagename.Name(packageName)) - q.WithVersions(func(q *ent.PackageVersionQuery) { - q.Where(packageversion.Hash(hashPackageVersion(pv.Version, pv.Subpath, pv.Qualifiers))) - }) - }) - }) -} +// func buildPackageTreeQuery(q *ent.PackageTypeQuery, ns, packageName string, pv *ent.PackageVersion) { +// q.WithNamespaces(func(q *ent.PackageNamespaceQuery) { +// q.Where(packagenamespace.Namespace(ns)) +// q.WithNames(func(q *ent.PackageNameQuery) { +// q.Where(packagename.Name(packageName)) +// q.WithVersions(func(q *ent.PackageVersionQuery) { +// q.Where(packageversion.Hash(hashPackageVersion(pv.Version, pv.Subpath, pv.Qualifiers))) +// }) +// }) +// }) +// } //func pkgTreeFromName(ctx context.Context, pn *ent.PackageName) (*ent.PackageType, error) { // ns, err := pn.QueryNamespace().Only(ctx) diff --git a/pkg/assembler/backends/ent/backend/sbom.go b/pkg/assembler/backends/ent/backend/sbom.go index e8856bdf0b..5fadbfec2b 100644 --- a/pkg/assembler/backends/ent/backend/sbom.go +++ b/pkg/assembler/backends/ent/backend/sbom.go @@ -125,7 +125,7 @@ func (b *EntBackend) IngestHasSbom(ctx context.Context, subject model.PackageOrA if subject.Package != nil { var err error - p, err := getPkgVersion(ctx, client.Client(), *subject.Package) + p, err := getPkgVersion(ctx, client.Client(), *subject.Package.PackageInput) if err != nil { return nil, Errorf("%v :: %s", funcName, err) } @@ -138,7 +138,7 @@ func (b *EntBackend) IngestHasSbom(ctx context.Context, subject model.PackageOrA } else if subject.Artifact != nil { var err error art, err := client.Artifact.Query(). - Where(artifactQueryInputPredicates(*subject.Artifact)). + Where(artifactQueryInputPredicates(*subject.Artifact.ArtifactInput)). Only(ctx) if err != nil { return nil, Errorf("%v :: %s", funcName, err) diff --git a/pkg/assembler/backends/ent/backend/sbom_test.go b/pkg/assembler/backends/ent/backend/sbom_test.go deleted file mode 100644 index 6051514366..0000000000 --- a/pkg/assembler/backends/ent/backend/sbom_test.go +++ /dev/null @@ -1,3016 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build integration - -package backend - -import ( - "strconv" - "time" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -type testDependency struct { - pkg *model.PkgInputSpec - depPkg *model.PkgInputSpec - matchType model.MatchFlags - isDep *model.IsDependencyInputSpec -} - -type testOccurrence struct { - Subj *model.PackageOrSourceInput - Art *model.ArtifactInputSpec - isOcc *model.IsOccurrenceInputSpec -} - -// Test resources - -var includedPackage1QualifierKey = "p1_key" -var includedPackage1QualifierValue = "p1_value" - -var includedPackage1 = &model.PkgInputSpec{ - Type: "p1_type", - Namespace: ptrfrom.String("p1_namespace"), - Name: "p1_name", - Version: ptrfrom.String("v1.0.0-p1version"), - Qualifiers: []*model.PackageQualifierInputSpec{{ - Key: includedPackage1QualifierKey, - Value: includedPackage1QualifierValue, - }}, - Subpath: ptrfrom.String("p1_subpath"), -} - -var includedPackage2QualifierKey = "p2_key" -var includedPackage2QualifierValue = "p2_value" - -var includedPackage2 = &model.PkgInputSpec{ - Type: "p2_type", - Namespace: ptrfrom.String("p2_namespace"), - Name: "p2_name", - Version: ptrfrom.String("v1.0.0-p2version"), - Qualifiers: []*model.PackageQualifierInputSpec{{ - Key: includedPackage2QualifierKey, - Value: includedPackage2QualifierValue, - }}, - Subpath: ptrfrom.String("p2_subpath"), -} - -var includedPackage3 = &model.PkgInputSpec{ - Type: "p3_type", - Namespace: ptrfrom.String("p3_namespace"), - Name: "p3_name", - Version: ptrfrom.String("v1.0.0-p3version"), - Qualifiers: []*model.PackageQualifierInputSpec{}, - Subpath: ptrfrom.String("p3_subpath"), -} - -var includedPackages = []*model.PkgInputSpec{includedPackage1, includedPackage2, includedPackage3} - -var includedArtifact1 = &model.ArtifactInputSpec{ - Algorithm: "a1_algorithm", - Digest: "a1_digest", -} - -var includedArtifact2 = &model.ArtifactInputSpec{ - Algorithm: "a2_algorithm", - Digest: "a2_digest", -} - -var includedArtifacts = []*model.ArtifactInputSpec{includedArtifact1, includedArtifact2} - -var includedPackageArtifacts = &model.PackageOrArtifactInputs{ - Packages: includedPackages, - Artifacts: includedArtifacts, -} - -var includedDependency1 = &model.IsDependencyInputSpec{ - VersionRange: "dep1_range", - DependencyType: model.DependencyTypeDirect, - Justification: "dep1_justification", - Origin: "dep1_origin", - Collector: "dep1_collector", -} - -var includedDependency2 = &model.IsDependencyInputSpec{ - VersionRange: "dep2_range", - DependencyType: model.DependencyTypeIndirect, - Justification: "dep2_justification", - Origin: "dep2_origin", - Collector: "dep2_collector", -} - -var includedTestDependency1 = &testDependency{ - pkg: includedPackage1, - depPkg: includedPackage2, - matchType: mSpecific, - isDep: includedDependency1, -} - -var includedTestDependency2 = &testDependency{ - pkg: includedPackage1, - depPkg: includedPackage3, - matchType: mSpecific, - isDep: includedDependency2, -} - -var includedTestDependencies = []testDependency{*includedTestDependency1, *includedTestDependency2} - -var includedSource = &model.SourceInputSpec{ - Type: "src_type", - Namespace: "src_namespace", - Name: "src_name", - Tag: ptrfrom.String("src_tag"), - Commit: ptrfrom.String("src_commit"), -} - -var includedSources = []*model.SourceInputSpec{includedSource} - -var includedOccurrence = &model.IsOccurrenceInputSpec{ - Justification: "occ_justification", - Origin: "occ_origin", - Collector: "occ_collector", -} - -var includedTestOccurrences = []testOccurrence{{ - Subj: &model.PackageOrSourceInput{Package: includedPackage1}, - Art: includedArtifact1, - isOcc: includedOccurrence, -}, { - Subj: &model.PackageOrSourceInput{Source: includedSource}, - Art: includedArtifact1, - isOcc: includedOccurrence, -}} - -var includedHasSBOM = &model.HasSBOMInputSpec{ - URI: "sbom_URI", - Algorithm: "sbom_algorithm", - Digest: "sbom_digest", - DownloadLocation: "sbom_download_location", - Origin: "sbom_origin", - Collector: "sbom_collector", -} - -var includedTestExpectedPackage1 = &model.Package{ - Type: "p1_type", - Namespaces: []*model.PackageNamespace{{ - Namespace: "p1_namespace", - Names: []*model.PackageName{{ - Name: "p1_name", - Versions: []*model.PackageVersion{{ - Version: "v1.0.0-p1version", - Qualifiers: []*model.PackageQualifier{{ - Key: includedPackage1QualifierKey, - Value: includedPackage1QualifierValue, - }}, - Subpath: "p1_subpath", - }}, - }}, - }}, -} - -var includedTestExpectedPackage2 = &model.Package{ - Type: "p2_type", - Namespaces: []*model.PackageNamespace{{ - Namespace: "p2_namespace", - Names: []*model.PackageName{{ - Name: "p2_name", - Versions: []*model.PackageVersion{{ - Version: "v1.0.0-p2version", - Qualifiers: []*model.PackageQualifier{{ - Key: includedPackage2QualifierKey, - Value: includedPackage2QualifierValue, - }}, - Subpath: "p2_subpath", - }}, - }}, - }}, -} - -var includedTestExpectedPackage3 = &model.Package{ - Type: "p3_type", - Namespaces: []*model.PackageNamespace{{ - Namespace: "p3_namespace", - Names: []*model.PackageName{{ - Name: "p3_name", - Versions: []*model.PackageVersion{{ - Version: "v1.0.0-p3version", - Qualifiers: []*model.PackageQualifier{}, - Subpath: "p3_subpath", - }}, - }}, - }}, -} - -var includedTestExpectedArtifact1 = &model.Artifact{ - Algorithm: "a1_algorithm", - Digest: "a1_digest", -} - -var includedTestExpectedArtifact2 = &model.Artifact{ - Algorithm: "a2_algorithm", - Digest: "a2_digest", -} - -var includedTestExpectedSource = &model.Source{ - Type: "src_type", - Namespaces: []*model.SourceNamespace{{ - Namespace: "src_namespace", - Names: []*model.SourceName{{ - Name: "src_name", - Tag: ptrfrom.String("src_tag"), - Commit: ptrfrom.String("src_commit"), - }}, - }}, -} - -var includedTestExpectedSBOM = &model.HasSbom{ - Subject: includedTestExpectedPackage1, - URI: "sbom_URI", - Algorithm: "sbom_algorithm", - Digest: "sbom_digest", - DownloadLocation: "sbom_download_location", - Origin: "sbom_origin", - Collector: "sbom_collector", - IncludedSoftware: []model.PackageOrArtifact{ - includedTestExpectedPackage1, - includedTestExpectedPackage2, - includedTestExpectedPackage3, - includedTestExpectedArtifact1, - includedTestExpectedArtifact2, - }, - IncludedDependencies: []*model.IsDependency{{ - Package: includedTestExpectedPackage1, - DependencyPackage: includedTestExpectedPackage2, - VersionRange: "dep1_range", - DependencyType: model.DependencyTypeDirect, - Justification: "dep1_justification", - Origin: "dep1_origin", - Collector: "dep1_collector", - }, { - Package: includedTestExpectedPackage1, - DependencyPackage: includedTestExpectedPackage3, - VersionRange: "dep2_range", - DependencyType: model.DependencyTypeIndirect, - Justification: "dep2_justification", - Origin: "dep2_origin", - Collector: "dep2_collector", - }}, - IncludedOccurrences: []*model.IsOccurrence{{ - Subject: includedTestExpectedPackage1, - Artifact: includedTestExpectedArtifact1, - Justification: "occ_justification", - Origin: "occ_origin", - Collector: "occ_collector", - }, { - Subject: includedTestExpectedSource, - Artifact: includedTestExpectedArtifact1, - Justification: "occ_justification", - Origin: "occ_origin", - Collector: "occ_collector", - }}, -} - -// End of Test resources - -func (s *Suite) TestHasSBOM() { - curTime := time.Now().UTC() - timeAfterOneSecond := time.UnixMicro(curTime.UnixMicro()).Add(time.Second) - type call struct { - Sub model.PackageOrArtifactInput - HS *model.HasSBOMInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InArt []*model.ArtifactInputSpec - PkgArt *model.PackageOrArtifactInputs - InSrc []*model.SourceInputSpec - IsDeps []testDependency - IsOccs []testOccurrence - Calls []call - Query *model.HasSBOMSpec - ExpHS []*model.HasSbom - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{p1}, - PkgArt: &model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - HS: &model.HasSBOMInputSpec{ - URI: "test uri", - }, - }, - }, - Query: &model.HasSBOMSpec{ - URI: ptrfrom.String("test uri"), - }, - ExpHS: []*model.HasSbom{ - { - Subject: p1out, - URI: "test uri", - IncludedSoftware: []model.PackageOrArtifact{p1out}, - }, - }, - }, - { - Name: "Ingest same twice", - InPkg: []*model.PkgInputSpec{p1}, - PkgArt: &model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - HS: &model.HasSBOMInputSpec{ - URI: "test uri", - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - HS: &model.HasSBOMInputSpec{ - URI: "test uri", - }, - }, - }, - Query: &model.HasSBOMSpec{ - URI: ptrfrom.String("test uri"), - }, - ExpHS: []*model.HasSbom{ - { - Subject: p1out, - URI: "test uri", - IncludedSoftware: []model.PackageOrArtifact{p1out}, - }, - }, - }, - { - Name: "Query on URI", - InPkg: []*model.PkgInputSpec{p1}, - PkgArt: &model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - HS: &model.HasSBOMInputSpec{ - URI: "test uri one", - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - HS: &model.HasSBOMInputSpec{ - URI: "test uri two", - }, - }, - }, - Query: &model.HasSBOMSpec{ - URI: ptrfrom.String("test uri one"), - }, - ExpHS: []*model.HasSbom{ - { - Subject: p1out, - URI: "test uri one", - IncludedSoftware: []model.PackageOrArtifact{p1out}, - }, - }, - }, - { - Name: "Query on KnownSince", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - HS: &model.HasSBOMInputSpec{ - KnownSince: timeAfterOneSecond, - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - HS: &model.HasSBOMInputSpec{ - KnownSince: curTime, - }, - }, - }, - Query: &model.HasSBOMSpec{ - KnownSince: &timeAfterOneSecond, - }, - ExpHS: []*model.HasSbom{ - { - Subject: p1out, - KnownSince: timeAfterOneSecond, - }, - }, - }, - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{p2, p4}, - InArt: []*model.ArtifactInputSpec{a1}, - PkgArt: &model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p2, p4}, - Artifacts: []*model.ArtifactInputSpec{a1}, - }, - IsDeps: []testDependency{{ - pkg: p2, - depPkg: p4, - matchType: mSpecific, - isDep: &model.IsDependencyInputSpec{ - Justification: "test justification", - }, - }}, - IsOccs: []testOccurrence{{ - Subj: &model.PackageOrSourceInput{Package: p4}, - Art: a1, - isOcc: &model.IsOccurrenceInputSpec{Justification: "test justification"}, - }}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p2, - }, - HS: &model.HasSBOMInputSpec{ - URI: "test uri", - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: p4, - }, - HS: &model.HasSBOMInputSpec{ - URI: "test uri", - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Artifact: a1, - }, - HS: &model.HasSBOMInputSpec{ - URI: "test uri", - }, - }, - }, - Query: &model.HasSBOMSpec{ - Subject: &model.PackageOrArtifactSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String("2.11.1"), - }, - }, - }, - ExpHS: []*model.HasSbom{ - { - Subject: p2out, - URI: "test uri", - IncludedSoftware: []model.PackageOrArtifact{p2out, p4out, a1out}, - IncludedDependencies: []*model.IsDependency{{ - Package: p2out, - DependencyPackage: p4out, - Justification: "test justification", - DependencyType: model.DependencyTypeUnknown, - }}, - IncludedOccurrences: []*model.IsOccurrence{{ - Subject: p4out, - Artifact: a1out, - Justification: "test justification", - }}, - }, - }, - }, - { - Name: "Query on Artifact", - InPkg: []*model.PkgInputSpec{p2}, - InArt: []*model.ArtifactInputSpec{a1, a2}, - PkgArt: &model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p2}, - Artifacts: []*model.ArtifactInputSpec{a1, a2}, - }, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p2, - }, - HS: &model.HasSBOMInputSpec{ - URI: "test uri", - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Artifact: a1, - }, - HS: &model.HasSBOMInputSpec{ - URI: "test uri", - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Artifact: a2, - }, - HS: &model.HasSBOMInputSpec{ - URI: "test uri", - }, - }, - }, - Query: &model.HasSBOMSpec{ - Subject: &model.PackageOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha1"), - }, - }, - }, - ExpHS: []*model.HasSbom{ - { - Subject: a2out, - URI: "test uri", - IncludedSoftware: []model.PackageOrArtifact{p2out, a1out, a2out}, - }, - }, - }, - { - Name: "Query on Algorithm", - InPkg: []*model.PkgInputSpec{p1}, - PkgArt: &model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - HS: &model.HasSBOMInputSpec{ - Algorithm: "QWERasdf", - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - HS: &model.HasSBOMInputSpec{ - Algorithm: "QWERasdf two", - }, - }, - }, - Query: &model.HasSBOMSpec{ - Algorithm: ptrfrom.String("QWERASDF"), - }, - ExpHS: []*model.HasSbom{ - { - Subject: p1out, - Algorithm: "qwerasdf", - IncludedSoftware: []model.PackageOrArtifact{p1out}, - }, - }, - }, - { - Name: "Query on Digest", - InPkg: []*model.PkgInputSpec{p2, p4}, - PkgArt: &model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p2, p4}, - Artifacts: []*model.ArtifactInputSpec{a1}, - }, - IsDeps: []testDependency{{ - pkg: p2, - depPkg: p4, - matchType: mSpecific, - isDep: &model.IsDependencyInputSpec{ - Justification: "test justification", - }, - }}, - IsOccs: []testOccurrence{{ - Subj: &model.PackageOrSourceInput{Package: p4}, - Art: a1, - isOcc: &model.IsOccurrenceInputSpec{Justification: "test justification"}, - }}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p2, - }, - HS: &model.HasSBOMInputSpec{ - Digest: "QWERasdf", - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: p2, - }, - HS: &model.HasSBOMInputSpec{ - Digest: "QWERasdf two", - }, - }, - }, - Query: &model.HasSBOMSpec{ - Digest: ptrfrom.String("QWERASDF"), - }, - ExpHS: []*model.HasSbom{ - { - Subject: p2out, - Digest: "qwerasdf", - IncludedSoftware: []model.PackageOrArtifact{p2out, p4out, a1out}, - IncludedDependencies: []*model.IsDependency{{ - Package: p2out, - DependencyPackage: p4out, - Justification: "test justification", - DependencyType: model.DependencyTypeUnknown, - }}, - IncludedOccurrences: []*model.IsOccurrence{{ - Subject: p4out, - Artifact: a1out, - Justification: "test justification", - }}, - }, - }, - }, - { - Name: "Query on DownloadLocation", - InPkg: []*model.PkgInputSpec{p1}, - PkgArt: &model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - HS: &model.HasSBOMInputSpec{ - DownloadLocation: "location one", - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - HS: &model.HasSBOMInputSpec{ - DownloadLocation: "location two", - }, - }, - }, - Query: &model.HasSBOMSpec{ - DownloadLocation: ptrfrom.String("location two"), - }, - ExpHS: []*model.HasSbom{ - { - Subject: p1out, - DownloadLocation: "location two", - IncludedSoftware: []model.PackageOrArtifact{p1out}, - }, - }, - }, - { - Name: "Query none", - InPkg: []*model.PkgInputSpec{p1}, - PkgArt: &model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - HS: &model.HasSBOMInputSpec{ - DownloadLocation: "location one", - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - HS: &model.HasSBOMInputSpec{ - DownloadLocation: "location two", - }, - }, - }, - Query: &model.HasSBOMSpec{ - DownloadLocation: ptrfrom.String("location three"), - }, - ExpHS: nil, - }, - { - Name: "Query multiple", - InPkg: []*model.PkgInputSpec{p1, p2}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - HS: &model.HasSBOMInputSpec{ - DownloadLocation: "location one", - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - HS: &model.HasSBOMInputSpec{ - DownloadLocation: "location two", - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: p2, - }, - HS: &model.HasSBOMInputSpec{ - DownloadLocation: "location two", - }, - }, - }, - Query: &model.HasSBOMSpec{ - DownloadLocation: ptrfrom.String("location two"), - }, - ExpHS: []*model.HasSbom{ - { - Subject: p2out, - DownloadLocation: "location two", - }, - { - Subject: p1out, - DownloadLocation: "location two", - }, - }, - }, - { - Name: "Query on ID", - InPkg: []*model.PkgInputSpec{p1}, - PkgArt: &model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - HS: &model.HasSBOMInputSpec{ - DownloadLocation: "location one", - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - HS: &model.HasSBOMInputSpec{ - DownloadLocation: "location two", - }, - }, - }, - Query: &model.HasSBOMSpec{ - ID: ptrfrom.String("1"), - }, - ExpHS: []*model.HasSbom{ - { - Subject: p1out, - DownloadLocation: "location two", - IncludedSoftware: []model.PackageOrArtifact{p1out}, - }, - }, - }, - { - Name: "Ingest without subject", - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - HS: &model.HasSBOMInputSpec{ - DownloadLocation: "location one", - }, - }, - }, - ExpIngestErr: true, - }, - { - Name: "Query without hasSBOMSpec", - InPkg: []*model.PkgInputSpec{p1}, - PkgArt: &model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - HS: &model.HasSBOMInputSpec{ - DownloadLocation: "location one", - }, - }, - }, - Query: &model.HasSBOMSpec{}, - ExpHS: []*model.HasSbom{ - { - Subject: p1out, - DownloadLocation: "location one", - IncludedSoftware: []model.PackageOrArtifact{p1out}, - }, - }, - }, - { - Name: "Includeds - include without filters", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedSoftware - Valid Included Package ID", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Package: &model.PkgSpec{ID: ptrfrom.String("0")}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedSoftware - Invalid Included Package ID", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Package: &model.PkgSpec{ID: ptrfrom.String("10000")}}}}, - ExpHS: nil, - }, - { - Name: "IncludedSoftware - Valid Included Package Namespace", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Package: &model.PkgSpec{Namespace: includedPackage2.Namespace}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedSoftware - Invalid Included Package Namespace", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Package: &model.PkgSpec{Namespace: ptrfrom.String("invalid_namespace")}}}}, - ExpHS: nil, - }, - { - Name: "IncludedSoftware - Valid Included Package Name", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Package: &model.PkgSpec{Name: &includedPackage2.Name}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedSoftware - Invalid Included Package Name", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Package: &model.PkgSpec{Name: ptrfrom.String("invalid_name")}}}}, - ExpHS: nil, - }, - { - Name: "IncludedSoftware - Valid Included Package Version", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Package: &model.PkgSpec{Version: includedPackage2.Version}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedSoftware - Invalid Included Package Version", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Package: &model.PkgSpec{Version: ptrfrom.String("v1.0.0-invalid-version")}}}}, - ExpHS: nil, - }, - { - Name: "IncludedSoftware - Valid Included Package Qualifier", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Package: &model.PkgSpec{Qualifiers: []*model.PackageQualifierSpec{{Key: includedPackage2QualifierKey, Value: ptrfrom.String(includedPackage2QualifierValue)}}}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedSoftware - Invalid Included Package Qualifier Key", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Package: &model.PkgSpec{Qualifiers: []*model.PackageQualifierSpec{{Key: "invalid_qualifier_key", Value: ptrfrom.String(includedPackage2QualifierValue)}}}}}}, - ExpHS: nil, - }, - { - Name: "IncludedSoftware - Invalid Subject Package Qualifier Value", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Package: &model.PkgSpec{Qualifiers: []*model.PackageQualifierSpec{{Key: includedPackage2QualifierKey, Value: ptrfrom.String("invalid_qualifier_value")}}}}}}, - ExpHS: nil, - }, - { - Name: "IncludedSoftware - Valid Included Package Subpath", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Package: &model.PkgSpec{Subpath: includedPackage2.Subpath}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedSoftware - Invalid Included Package Subpath", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Package: &model.PkgSpec{Subpath: ptrfrom.String("invalid_subpath")}}}}, - ExpHS: nil, - }, - { - Name: "IncludedSoftware - Valid Included Artifact ID", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Artifact: &model.ArtifactSpec{ID: ptrfrom.String("0")}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedSoftware - Invalid Included Artifact ID", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Artifact: &model.ArtifactSpec{ID: ptrfrom.String("10000")}}}}, - ExpHS: nil, - }, - { - Name: "IncludedSoftware - Valid Included Artifact Algorithm", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Artifact: &model.ArtifactSpec{Algorithm: &includedArtifact1.Algorithm}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedSoftware - Invalid Included Artifact Algorithm", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Artifact: &model.ArtifactSpec{Algorithm: ptrfrom.String("invalid_algorithm")}}}}, - ExpHS: nil, - }, - { - Name: "IncludedSoftware - Valid Included Artifact Digest", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Artifact: &model.ArtifactSpec{Digest: &includedArtifact1.Digest}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedSoftware - Invalid Included Artifact Digest", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Artifact: &model.ArtifactSpec{Digest: ptrfrom.String("invalid_digest")}}}}, - ExpHS: nil, - }, - { - Name: "IncludedDependencies - Valid Included ID", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{ID: ptrfrom.String("0")}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedDependencies - Invalid Included ID", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{ID: ptrfrom.String("10000")}}}, - ExpHS: nil, - }, - { - Name: "IncludedDependencies - Valid Included Package ID", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{ID: ptrfrom.String("0")}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedDependencies - Invalid Included Package ID", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{ID: ptrfrom.String("10000")}}}}, - ExpHS: nil, - }, - { - Name: "IncludedDependencies - Valid Included Package Namespace", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{Namespace: includedPackage1.Namespace}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedDependencies - Invalid Included Package Namespace", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{Namespace: ptrfrom.String("invalid_namespace")}}}}, - ExpHS: nil, - }, - { - Name: "IncludedDependencies - Valid Included Package Name", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{Name: &includedPackage1.Name}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedDependencies - Invalid Included Package Name", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{Name: ptrfrom.String("invalid_name")}}}}, - ExpHS: nil, - }, - { - Name: "IncludedDependencies - Valid Included Package Version", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{Version: includedPackage1.Version}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedDependencies - Invalid Included Package Version", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{Version: ptrfrom.String("v1.0.0-invalid-version")}}}}, - ExpHS: nil, - }, - { - Name: "IncludedDependencies - Valid Included Package Qualifier", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{Qualifiers: []*model.PackageQualifierSpec{{Key: includedPackage1QualifierKey, Value: ptrfrom.String(includedPackage1QualifierValue)}}}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedDependencies - Invalid Included Package Qualifier Key", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{Qualifiers: []*model.PackageQualifierSpec{{Key: "invalid_qualifier_key", Value: ptrfrom.String(includedPackage1QualifierValue)}}}}}}, - ExpHS: nil, - }, - { - Name: "IncludedDependencies - Invalid Subject Package Qualifier Value", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{Qualifiers: []*model.PackageQualifierSpec{{Key: includedPackage1QualifierKey, Value: ptrfrom.String("invalid_qualifier_value")}}}}}}, - ExpHS: nil, - }, - { - Name: "IncludedDependencies - Valid Included Package Subpath", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{Subpath: includedPackage1.Subpath}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedDependencies - Invalid Included Package Subpath", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{Subpath: ptrfrom.String("invalid_subpath")}}}}, - ExpHS: nil, - }, - - { - Name: "IncludedDependencies - Valid Included DependencyPackage ID", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{DependencyPackage: &model.PkgSpec{ID: ptrfrom.String("1")}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedDependencies - Invalid Included DependencyPackage ID", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{DependencyPackage: &model.PkgSpec{ID: ptrfrom.String("10000")}}}}, - ExpHS: nil, - }, - { - Name: "IncludedDependencies - Valid Included DependencyPackage Namespace", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{DependencyPackage: &model.PkgSpec{Namespace: includedPackage2.Namespace}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedDependencies - Invalid Included DependencyPackage Namespace", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{DependencyPackage: &model.PkgSpec{Namespace: ptrfrom.String("invalid_namespace")}}}}, - ExpHS: nil, - }, - { - Name: "IncludedDependencies - Valid Included DependencyPackage Name", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{DependencyPackage: &model.PkgSpec{Name: &includedPackage2.Name}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedDependencies - Invalid Included DependencyPackage Name", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{DependencyPackage: &model.PkgSpec{Name: ptrfrom.String("invalid_name")}}}}, - ExpHS: nil, - }, - { - Name: "IncludedDependencies - Valid Included DependencyPackage Version", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{DependencyPackage: &model.PkgSpec{Version: includedPackage2.Version}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedDependencies - Invalid Included DependencyPackage Version", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{DependencyPackage: &model.PkgSpec{Version: ptrfrom.String("v1.0.0-invalid-version")}}}}, - ExpHS: nil, - }, - { - Name: "IncludedDependencies - Valid Included DependencyPackage Qualifier", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{DependencyPackage: &model.PkgSpec{Qualifiers: []*model.PackageQualifierSpec{{Key: includedPackage2QualifierKey, Value: ptrfrom.String(includedPackage2QualifierValue)}}}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedDependencies - Invalid Included DependencyPackage Qualifier Key", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{DependencyPackage: &model.PkgSpec{Qualifiers: []*model.PackageQualifierSpec{{Key: "invalid_qualifier_key", Value: ptrfrom.String(includedPackage2QualifierValue)}}}}}}, - ExpHS: nil, - }, - { - Name: "IncludedDependencies - Invalid Subject DependencyPackage Qualifier Value", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{DependencyPackage: &model.PkgSpec{Qualifiers: []*model.PackageQualifierSpec{{Key: includedPackage2QualifierKey, Value: ptrfrom.String("invalid_qualifier_value")}}}}}}, - ExpHS: nil, - }, - { - Name: "IncludedDependencies - Valid Included DependencyPackage Subpath", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{DependencyPackage: &model.PkgSpec{Subpath: includedPackage2.Subpath}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedDependencies - Invalid Included DependencyPackage Subpath", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{DependencyPackage: &model.PkgSpec{Subpath: ptrfrom.String("invalid_subpath")}}}}, - ExpHS: nil, - }, - { - Name: "IncludedDependencies - Valid Included Package ID and DependencyPackage ID", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{ID: ptrfrom.String("0")}, DependencyPackage: &model.PkgSpec{ID: ptrfrom.String("1")}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedDependencies - Valid Included Package ID and Invalid DependencyPackage ID", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{ID: ptrfrom.String("4")}, DependencyPackage: &model.PkgSpec{ID: ptrfrom.String("10000")}}}}, - ExpHS: nil, - }, - { - Name: "IncludedDependencies - Invalid Included Package ID and Valid DependencyPackage ID", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{ID: ptrfrom.String("10000")}, DependencyPackage: &model.PkgSpec{ID: ptrfrom.String("8")}}}}, - ExpHS: nil, - }, - { - Name: "IncludedDependencies - Valid Included Package Name and DependencyPackage Name", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{Name: &includedPackage1.Name}, DependencyPackage: &model.PkgSpec{Name: &includedPackage2.Name}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedDependencies - Valid Included Package Name and Invalid DependencyPackage Name", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{Name: &includedPackage1.Name}, DependencyPackage: &model.PkgSpec{Name: ptrfrom.String("invalid_name")}}}}, - ExpHS: nil, - }, - { - Name: "IncludedDependencies - Invalid Included Package Name and Valid DependencyPackage Name", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{Name: ptrfrom.String("invalid_name")}, DependencyPackage: &model.PkgSpec{Name: &includedPackage2.Name}}}}, - ExpHS: nil, - }, - { - Name: "IncludedDependencies - Valid Included VersionRange", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{VersionRange: &includedDependency1.VersionRange}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedDependencies - Invalid Included VersionRange", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{VersionRange: ptrfrom.String("invalid_range")}}}, - ExpHS: nil, - }, - { - Name: "IncludedDependencies - Valid Included DependencyType", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{DependencyType: &includedDependency1.DependencyType}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedDependencies - Invalid Included DependencyType", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{DependencyType: (*model.DependencyType)(ptrfrom.String(string(model.DependencyTypeUnknown)))}}}, - ExpHS: nil, - }, - { - Name: "IncludedDependencies - Valid Included Justification", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Justification: &includedDependency1.Justification}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedDependencies - Invalid Included Justification", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Justification: ptrfrom.String("invalid_justification")}}}, - ExpHS: nil, - }, - { - Name: "IncludedDependencies - Valid Included Origin", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Origin: &includedDependency1.Origin}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedDependencies - Invalid Included Origin", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Origin: ptrfrom.String("invalid_origin")}}}, - ExpHS: nil, - }, - { - Name: "IncludedDependencies - Valid Included Collector", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Collector: &includedDependency1.Collector}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedDependencies - Invalid Included Collector", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Collector: ptrfrom.String("invalid_collector")}}}, - ExpHS: nil, - }, - { - Name: "IncludedOccurrences - Valid Included ID", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{ID: ptrfrom.String("0")}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedOccurrences - Invalid Included ID", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{ID: ptrfrom.String("10000")}}}, - ExpHS: nil, - }, - { - Name: "IncludedOccurrences - Valid Included Package ID", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Package: &model.PkgSpec{ID: ptrfrom.String("0")}}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedOccurrences - Invalid Included Package ID", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Package: &model.PkgSpec{ID: ptrfrom.String("10000")}}}}}, - ExpHS: nil, - }, - { - Name: "IncludedOccurrences - Valid Included Package Namespace", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Package: &model.PkgSpec{Namespace: includedPackage1.Namespace}}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedOccurrences - Invalid Included Package Namespace", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Package: &model.PkgSpec{Namespace: ptrfrom.String("invalid_namespace")}}}}}, - ExpHS: nil, - }, - { - Name: "IncludedOccurrences - Valid Included Package Name", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Package: &model.PkgSpec{Name: ptrfrom.String("p1_name")}}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedOccurrences - Invalid Included Package Name", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Package: &model.PkgSpec{Name: ptrfrom.String("invalid_name")}}}}}, - ExpHS: nil, - }, - { - Name: "IncludedOccurrences - Valid Included Package Version", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Package: &model.PkgSpec{Version: includedPackage1.Version}}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedOccurrences - Invalid Included Package Version", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Package: &model.PkgSpec{Version: ptrfrom.String("v1.0.0-invalid-version")}}}}}, - ExpHS: nil, - }, - { - Name: "IncludedOccurrences - Valid Included Package Qualifier", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Package: &model.PkgSpec{Qualifiers: []*model.PackageQualifierSpec{{Key: includedPackage1QualifierKey, Value: ptrfrom.String(includedPackage1QualifierValue)}}}}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedOccurrences - Invalid Included Package Qualifier Key", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Package: &model.PkgSpec{Qualifiers: []*model.PackageQualifierSpec{{Key: "invalid_qualifier_key", Value: ptrfrom.String(includedPackage1QualifierValue)}}}}}}}, - ExpHS: nil, - }, - { - Name: "IncludedOccurrences - Invalid Subject Package Qualifier Value", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Package: &model.PkgSpec{Qualifiers: []*model.PackageQualifierSpec{{Key: includedPackage1QualifierKey, Value: ptrfrom.String("invalid_qualifier_value")}}}}}}}, - ExpHS: nil, - }, - { - Name: "IncludedOccurrences - Valid Included Package Subpath", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Package: &model.PkgSpec{Subpath: includedPackage1.Subpath}}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedOccurrences - Invalid Included Package Subpath", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Package: &model.PkgSpec{Subpath: ptrfrom.String("invalid_subpath")}}}}}, - ExpHS: nil, - }, - { - Name: "IncludedOccurrences - Valid Included Source ID", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Source: &model.SourceSpec{ID: ptrfrom.String("0")}}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedOccurrences - Invalid Included Source ID", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Source: &model.SourceSpec{ID: ptrfrom.String("10000")}}}}}, - ExpHS: nil, - }, - { - Name: "IncludedOccurrences - Valid Included Source", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - // TODO (knrc) - source currently needs to be an exact match, does this need to change? - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Source: &model.SourceSpec{ - Type: &includedSource.Type, - Namespace: &includedSource.Namespace, - Name: &includedSource.Name, - Tag: includedSource.Tag, - Commit: includedSource.Commit, - }}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedOccurrences - Invalid Included Source Type", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Source: &model.SourceSpec{ - Type: ptrfrom.String("invalid_type"), - Namespace: &includedSource.Namespace, - Name: &includedSource.Name, - Tag: includedSource.Tag, - Commit: includedSource.Commit, - }}}}}, - ExpHS: nil, - }, - { - Name: "IncludedOccurrences - Invalid Included Source Namespace", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Source: &model.SourceSpec{ - Type: &includedSource.Type, - Namespace: ptrfrom.String("invalid_namespace"), - Name: &includedSource.Name, - Tag: includedSource.Tag, - Commit: includedSource.Commit, - }}}}}, - ExpHS: nil, - }, - { - Name: "IncludedOccurrences - Invalid Included Source Name", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Source: &model.SourceSpec{ - Type: &includedSource.Type, - Namespace: &includedSource.Namespace, - Name: ptrfrom.String("invalid_name"), - Tag: includedSource.Tag, - Commit: includedSource.Commit, - }}}}}, - ExpHS: nil, - }, - { - Name: "IncludedOccurrences - Invalid Included Source Tag", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Source: &model.SourceSpec{ - Type: &includedSource.Type, - Namespace: &includedSource.Namespace, - Name: &includedSource.Name, - Tag: ptrfrom.String("invalid_tag"), - Commit: includedSource.Commit, - }}}}}, - ExpHS: nil, - }, - { - Name: "IncludedOccurrences - Invalid Included Source Commit", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Source: &model.SourceSpec{ - Type: &includedSource.Type, - Namespace: &includedSource.Namespace, - Name: &includedSource.Name, - Tag: includedSource.Tag, - Commit: ptrfrom.String("invalid_commit"), - }}}}}, - ExpHS: nil, - }, - { - Name: "IncludedOccurrences - Valid Included Artifact ID", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Artifact: &model.ArtifactSpec{ID: ptrfrom.String("0")}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedOccurrences - Invalid Included Artifact ID", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Artifact: &model.ArtifactSpec{ID: ptrfrom.String("10000")}}}}, - ExpHS: nil, - }, - { - Name: "IncludedOccurrences - Valid Included Artifact Algorithm", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Artifact: &model.ArtifactSpec{Algorithm: &includedArtifact1.Algorithm}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedOccurrences - Invalid Included Artifact Algorithm", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Artifact: &model.ArtifactSpec{Algorithm: ptrfrom.String("invalid_algorithm")}}}}, - ExpHS: nil, - }, - { - Name: "IncludedOccurrences - Valid Included Artifact Digest", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Artifact: &model.ArtifactSpec{Digest: &includedArtifact1.Digest}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedOccurrences - Invalid Included Artifact Digest", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Artifact: &model.ArtifactSpec{Digest: ptrfrom.String("invalid_digest")}}}}, - ExpHS: nil, - }, - { - Name: "IncludedOccurrences - Valid Included Justification", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Justification: &includedOccurrence.Justification}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedOccurrences - Invalid Included Justification", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Justification: ptrfrom.String("invalid_justification")}}}, - ExpHS: nil, - }, - { - Name: "IncludedOccurrences - Valid Included Origin", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Origin: &includedOccurrence.Origin}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedOccurrences - Invalid Included Origin", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Origin: ptrfrom.String("invalid_origin")}}}, - ExpHS: nil, - }, - { - Name: "IncludedOccurrences - Valid Included Collector", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Collector: &includedOccurrence.Collector}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedOccurrences - Invalid Included Collector", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Collector: ptrfrom.String("invalid_collector")}}}, - ExpHS: nil, - }, - } - ctx := s.Ctx - for _, test := range tests { - s.Run(test.Name, func() { - b, err := GetBackend(s.Client) - if err != nil { - s.T().Fatalf("Could not instantiate testing backend: %v", err) - } - var pkgIDs []string - for _, p := range test.InPkg { - if pkg, err := b.IngestPackage(ctx, *p); err != nil { - s.T().Fatalf("Could not ingest package: %v", err) - } else { - pkgIDs = append(pkgIDs, pkg.PackageVersionID) - } - } - var artifactIDs []string - for _, a := range test.InArt { - if art, err := b.IngestArtifact(ctx, a); err != nil { - s.T().Fatalf("Could not ingest artifact: %v", err) - } else { - artifactIDs = append(artifactIDs, art) - } - } - var srcIDs []string - for _, src := range test.InSrc { - if source, err := b.IngestSource(ctx, *src); err != nil { - s.T().Fatalf("Could not ingest source: %v", err) - } else { - srcIDs = append(srcIDs, source.SourceNameID) - } - } - - includes := model.HasSBOMIncludesInputSpec{} - - if test.PkgArt != nil { - if pkgs, err := b.IngestPackages(ctx, test.PkgArt.Packages); err != nil { - s.T().Fatalf("Could not ingest package: %v", err) - } else { - for _, pkg := range pkgs { - includes.Software = append(includes.Software, pkg.PackageVersionID) - } - } - if arts, err := b.IngestArtifacts(ctx, test.PkgArt.Artifacts); err != nil { - s.T().Fatalf("Could not ingest artifact: %v", err) - } else { - includes.Software = append(includes.Software, arts...) - } - } - - var depIDs []string - for _, dep := range test.IsDeps { - if isDep, err := b.IngestDependency(ctx, *dep.pkg, *dep.depPkg, dep.matchType, *dep.isDep); err != nil { - s.T().Fatalf("Could not ingest dependency: %v", err) - } else { - includes.Dependencies = append(includes.Dependencies, isDep) - depIDs = append(depIDs, isDep) - } - } - - var occIDs []string - for _, occ := range test.IsOccs { - if isOcc, err := b.IngestOccurrence(ctx, *occ.Subj, *occ.Art, *occ.isOcc); err != nil { - s.T().Fatalf("Could not ingest occurrence: %v", err) - } else { - includes.Occurrences = append(includes.Occurrences, isOcc) - occIDs = append(occIDs, isOcc) - } - } - - hasSbomIDs := make([]string, len(test.Calls)) - for i, o := range test.Calls { - id, err := b.IngestHasSbom(ctx, o.Sub, *o.HS, includes) - if (err != nil) != test.ExpIngestErr { - s.T().Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - hasSbomIDs[i] = id - } - - // Queries IDs translation into real ones - if test.Query.ID != nil { - idIdx, err := strconv.Atoi(*test.Query.ID) - if err == nil { - if idIdx >= len(hasSbomIDs) { - s.T().Fatalf("ID index out of range, want: %d, got: %d", len(hasSbomIDs), idIdx) - } - - realID := hasSbomIDs[idIdx] - test.Query.ID = &realID - } - } - for _, includedSw := range test.Query.IncludedSoftware { - if includedSw.Package != nil && includedSw.Package.ID != nil { - rewriteID(s.T(), includedSw.Package.ID, pkgIDs) - } else if includedSw.Artifact != nil && includedSw.Artifact.ID != nil { - rewriteID(s.T(), includedSw.Artifact.ID, artifactIDs) - } - } - for _, includedDep := range test.Query.IncludedDependencies { - if includedDep.ID != nil { - rewriteID(s.T(), includedDep.ID, depIDs) - } - if includedDep.Package != nil && includedDep.Package.ID != nil { - rewriteID(s.T(), includedDep.Package.ID, pkgIDs) - } - if includedDep.DependencyPackage != nil && includedDep.DependencyPackage.ID != nil { - rewriteID(s.T(), includedDep.DependencyPackage.ID, pkgIDs) - } - } - for _, includedOcc := range test.Query.IncludedOccurrences { - if includedOcc.ID != nil { - rewriteID(s.T(), includedOcc.ID, occIDs) - } - if includedOcc.Subject != nil { - if includedOcc.Subject.Package != nil && includedOcc.Subject.Package.ID != nil { - rewriteID(s.T(), includedOcc.Subject.Package.ID, pkgIDs) - } else if includedOcc.Subject.Source != nil && includedOcc.Subject.Source.ID != nil { - rewriteID(s.T(), includedOcc.Subject.Source.ID, srcIDs) - } - } - if includedOcc.Artifact != nil && includedOcc.Artifact.ID != nil { - rewriteID(s.T(), includedOcc.Artifact.ID, artifactIDs) - } - } - - got, err := b.HasSBOM(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - s.T().Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpHS, got, IngestPredicatesCmpOpts...); diff != "" { - s.T().Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func (s *Suite) TestIngestHasSBOMs() { - type call struct { - Sub model.PackageOrArtifactInputs - HS []*model.HasSBOMInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InArt []*model.ArtifactInputSpec - PkgArt *model.PackageOrArtifactInputs - IsDeps []testDependency - IsOccs []testOccurrence - Calls []call - Query *model.HasSBOMSpec - ExpHS []*model.HasSbom - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{p1}, - PkgArt: &model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - Calls: []call{ - { - Sub: model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - HS: []*model.HasSBOMInputSpec{ - { - URI: "test uri", - }, - }, - }, - }, - Query: &model.HasSBOMSpec{ - URI: ptrfrom.String("test uri"), - }, - ExpHS: []*model.HasSbom{ - { - Subject: p1out, - URI: "test uri", - IncludedSoftware: []model.PackageOrArtifact{p1out}, - }, - }, - }, - { - Name: "Ingest same twice", - InPkg: []*model.PkgInputSpec{p1}, - PkgArt: &model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - Calls: []call{ - { - Sub: model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1, p1}, - }, - HS: []*model.HasSBOMInputSpec{ - { - URI: "test uri", - }, - { - URI: "test uri", - }, - }, - }, - }, - Query: &model.HasSBOMSpec{ - URI: ptrfrom.String("test uri"), - }, - ExpHS: []*model.HasSbom{ - { - Subject: p1out, - URI: "test uri", - IncludedSoftware: []model.PackageOrArtifact{p1out}, - }, - }, - }, - { - Name: "Query on URI", - InPkg: []*model.PkgInputSpec{p1}, - PkgArt: &model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - Calls: []call{ - { - Sub: model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1, p1}, - }, - HS: []*model.HasSBOMInputSpec{ - { - URI: "test uri one", - }, - { - URI: "test uri two", - }, - }, - }, - }, - Query: &model.HasSBOMSpec{ - URI: ptrfrom.String("test uri one"), - }, - ExpHS: []*model.HasSbom{ - { - Subject: p1out, - URI: "test uri one", - IncludedSoftware: []model.PackageOrArtifact{p1out}, - }, - }, - }, - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{p2, p4}, - InArt: []*model.ArtifactInputSpec{a1}, - PkgArt: &model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p2, p4}, - Artifacts: []*model.ArtifactInputSpec{a1}, - }, - IsDeps: []testDependency{{ - pkg: p2, - depPkg: p4, - matchType: mSpecific, - isDep: &model.IsDependencyInputSpec{ - Justification: "test justification", - }, - }}, - IsOccs: []testOccurrence{{ - Subj: &model.PackageOrSourceInput{Package: p4}, - Art: a1, - isOcc: &model.IsOccurrenceInputSpec{Justification: "test justification"}, - }}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p2, p4}, - }, - HS: []*model.HasSBOMInputSpec{ - { - URI: "test uri", - }, - { - URI: "test uri", - }, - }, - }, - { - Sub: model.PackageOrArtifactInputs{ - Artifacts: []*model.ArtifactInputSpec{a1}, - }, - HS: []*model.HasSBOMInputSpec{ - { - URI: "test uri", - }, - }, - }, - }, - Query: &model.HasSBOMSpec{ - Subject: &model.PackageOrArtifactSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String("2.11.1"), - }, - }, - }, - ExpHS: []*model.HasSbom{ - { - Subject: p2out, - URI: "test uri", - IncludedSoftware: []model.PackageOrArtifact{p2out, p4out, a1out}, - IncludedDependencies: []*model.IsDependency{{ - Package: p2out, - DependencyPackage: p4out, - Justification: "test justification", - DependencyType: model.DependencyTypeUnknown, - }}, - IncludedOccurrences: []*model.IsOccurrence{{ - Subject: p4out, - Artifact: a1out, - Justification: "test justification", - }}, - }, - }, - }, - { - Name: "Query on Artifact", - InPkg: []*model.PkgInputSpec{p1}, - InArt: []*model.ArtifactInputSpec{a1, a2}, - PkgArt: &model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - Artifacts: []*model.ArtifactInputSpec{a1, a2}, - }, - IsOccs: []testOccurrence{{ - Subj: &model.PackageOrSourceInput{Package: p1}, - Art: a2, - isOcc: &model.IsOccurrenceInputSpec{Justification: "test justification"}, - }}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - HS: []*model.HasSBOMInputSpec{ - { - URI: "test uri", - }, - }, - }, - { - Sub: model.PackageOrArtifactInputs{ - Artifacts: []*model.ArtifactInputSpec{a1, a2}, - }, - HS: []*model.HasSBOMInputSpec{ - { - URI: "test uri", - }, - { - URI: "test uri", - }, - }, - }, - }, - Query: &model.HasSBOMSpec{ - Subject: &model.PackageOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha1"), - }, - }, - }, - ExpHS: []*model.HasSbom{ - { - Subject: a2out, - URI: "test uri", - IncludedSoftware: []model.PackageOrArtifact{p1out, a1out, a2out}, - IncludedOccurrences: []*model.IsOccurrence{{ - Subject: p1out, - Artifact: a2out, - Justification: "test justification", - }}, - }, - }, - }, - } - ctx := s.Ctx - for _, test := range tests { - s.Run(test.Name, func() { - b, err := GetBackend(s.Client) - if err != nil { - s.T().Fatalf("Could not instantiate testing backend: %v", err) - } - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - s.T().Fatalf("Could not ingest package: %v", err) - } - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - s.T().Fatalf("Could not ingest artifact: %v", err) - } - } - includes := model.HasSBOMIncludesInputSpec{} - if test.PkgArt != nil { - if pkgs, err := b.IngestPackages(ctx, test.PkgArt.Packages); err != nil { - s.T().Fatalf("Could not ingest package: %v", err) - } else { - for _, pkg := range pkgs { - includes.Software = append(includes.Software, pkg.PackageVersionID) - } - } - if arts, err := b.IngestArtifacts(ctx, test.PkgArt.Artifacts); err != nil { - s.T().Fatalf("Could not ingest artifact: %v", err) - } else { - includes.Software = append(includes.Software, arts...) - } - } - - for _, dep := range test.IsDeps { - if isDep, err := b.IngestDependency(ctx, *dep.pkg, *dep.depPkg, dep.matchType, *dep.isDep); err != nil { - s.T().Fatalf("Could not ingest dependency: %v", err) - } else { - includes.Dependencies = append(includes.Dependencies, isDep) - } - } - - for _, occ := range test.IsOccs { - if isOcc, err := b.IngestOccurrence(ctx, *occ.Subj, *occ.Art, *occ.isOcc); err != nil { - s.T().Fatalf("Could not ingest occurrence: %v", err) - } else { - includes.Occurrences = append(includes.Occurrences, isOcc) - } - } - for _, o := range test.Calls { - var sbomIncludes []*model.HasSBOMIncludesInputSpec - for count := 0; count < len(o.HS); count++ { - sbomIncludes = append(sbomIncludes, &includes) - } - _, err := b.IngestHasSBOMs(ctx, o.Sub, o.HS, sbomIncludes) - if (err != nil) != test.ExpIngestErr { - s.T().Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.HasSBOM(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - s.T().Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpHS, got, IngestPredicatesCmpOpts...); diff != "" { - s.T().Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} diff --git a/pkg/assembler/backends/ent/backend/scorecard.go b/pkg/assembler/backends/ent/backend/scorecard.go index 7b4fb8deff..7e275930ef 100644 --- a/pkg/assembler/backends/ent/backend/scorecard.go +++ b/pkg/assembler/backends/ent/backend/scorecard.go @@ -89,9 +89,9 @@ func (b *EntBackend) Scorecards(ctx context.Context, filter *model.CertifyScorec // Mutations for evidence trees (read-write queries, assume software trees ingested) // IngestScorecard takes a scorecard and a source and creates a certifyScorecard -func (b *EntBackend) IngestScorecard(ctx context.Context, source model.SourceInputSpec, scorecard model.ScorecardInputSpec) (string, error) { +func (b *EntBackend) IngestScorecard(ctx context.Context, source model.IDorSourceInput, scorecard model.ScorecardInputSpec) (string, error) { cscID, err := WithinTX(ctx, b.client, func(ctx context.Context) (*int, error) { - return upsertScorecard(ctx, ent.TxFromContext(ctx), source, scorecard) + return upsertScorecard(ctx, ent.TxFromContext(ctx), *source.SourceInput, scorecard) }) if err != nil { return "", err @@ -99,7 +99,7 @@ func (b *EntBackend) IngestScorecard(ctx context.Context, source model.SourceInp return strconv.Itoa(*cscID), nil } -func (b *EntBackend) IngestScorecards(ctx context.Context, sources []*model.SourceInputSpec, scorecards []*model.ScorecardInputSpec) ([]string, error) { +func (b *EntBackend) IngestScorecards(ctx context.Context, sources []*model.IDorSourceInput, scorecards []*model.ScorecardInputSpec) ([]string, error) { var modelScorecardIDs []string for i, sc := range scorecards { modelScorecardID, err := b.IngestScorecard(ctx, *sources[i], *sc) diff --git a/pkg/assembler/backends/ent/backend/scorecard_test.go b/pkg/assembler/backends/ent/backend/scorecard_test.go deleted file mode 100644 index 3f596fb274..0000000000 --- a/pkg/assembler/backends/ent/backend/scorecard_test.go +++ /dev/null @@ -1,632 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build integration - -package backend - -import ( - "time" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -func (s *Suite) TestCertifyScorecard() { - testTime := time.Unix(1e9+5, 0) - type call struct { - Src *model.SourceInputSpec - SC *model.ScorecardInputSpec - } - tests := []struct { - Name string - InSrc []*model.SourceInputSpec - Calls []call - Query *model.CertifyScorecardSpec - ExpSC []*model.CertifyScorecard - ExpIngestErr bool - ExpQueryErr bool - Only bool - }{ - { - Name: "HappyPath", - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Src: s1, - SC: &model.ScorecardInputSpec{ - Origin: "test origin", - }, - }, - }, - Query: &model.CertifyScorecardSpec{ - Origin: ptrfrom.String("test origin"), - }, - ExpSC: []*model.CertifyScorecard{ - { - Source: s1out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - Origin: "test origin", - }, - }, - }, - }, - { - Name: "Ingest same", - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Src: s1, - SC: &model.ScorecardInputSpec{ - Origin: "test origin", - }, - }, - { - Src: s1, - SC: &model.ScorecardInputSpec{ - Origin: "test origin", - }, - }, - }, - Query: &model.CertifyScorecardSpec{ - Origin: ptrfrom.String("test origin"), - }, - ExpSC: []*model.CertifyScorecard{ - { - Source: s1out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - Origin: "test origin", - }, - }, - }, - }, - { - Name: "Query multiple", - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Src: s1, - SC: &model.ScorecardInputSpec{ - Origin: "test origin one", - }, - }, - { - Src: s1, - SC: &model.ScorecardInputSpec{ - AggregateScore: 4.4, - Origin: "test origin two", - }, - }, - { - Src: s1, - SC: &model.ScorecardInputSpec{ - AggregateScore: 4.9, - Origin: "test origin two", - }, - }, - }, - Query: &model.CertifyScorecardSpec{ - Origin: ptrfrom.String("test origin two"), - }, - ExpSC: []*model.CertifyScorecard{ - { - Source: s1out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - AggregateScore: 4.4, - Origin: "test origin two", - }, - }, - { - Source: s1out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - AggregateScore: 4.9, - Origin: "test origin two", - }, - }, - }, - }, - { - Name: "Query Source", - Only: true, - InSrc: []*model.SourceInputSpec{s1, s2}, - Calls: []call{ - { - Src: s1, - SC: &model.ScorecardInputSpec{ - Origin: "test origin", - }, - }, - { - Src: s2, - SC: &model.ScorecardInputSpec{ - Origin: "test origin", - }, - }, - }, - Query: &model.CertifyScorecardSpec{ - Source: &model.SourceSpec{ - Namespace: ptrfrom.String("github.com/jeff"), - }, - }, - ExpSC: []*model.CertifyScorecard{ - { - Source: s1out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - Origin: "test origin", - }, - }, - }, - }, - { - Name: "Query Time", - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Src: s1, - SC: &model.ScorecardInputSpec{ - AggregateScore: 1.5, - TimeScanned: time.Unix(1e9, 0), - ScorecardVersion: "123", - ScorecardCommit: "abc", - }, - }, - { - Src: s1, - SC: &model.ScorecardInputSpec{ - AggregateScore: 1.5, - TimeScanned: testTime, - ScorecardVersion: "123", - ScorecardCommit: "abc", - }, - }, - }, - Query: &model.CertifyScorecardSpec{ - TimeScanned: &testTime, - }, - ExpSC: []*model.CertifyScorecard{ - { - Source: s1out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - AggregateScore: 1.5, - TimeScanned: testTime, - ScorecardVersion: "123", - ScorecardCommit: "abc", - }, - }, - }, - }, - { - Name: "Query Score", - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Src: s1, - SC: &model.ScorecardInputSpec{ - AggregateScore: 1.5, - TimeScanned: time.Unix(1e9, 0), - ScorecardVersion: "123", - ScorecardCommit: "abc", - }, - }, - { - Src: s1, - SC: &model.ScorecardInputSpec{ - AggregateScore: 5.7, - TimeScanned: time.Unix(1e9, 0), - ScorecardVersion: "123", - ScorecardCommit: "abc", - }, - }, - }, - Query: &model.CertifyScorecardSpec{ - AggregateScore: ptrfrom.Float64(57.0 / 10), - }, - ExpSC: []*model.CertifyScorecard{ - { - Source: s1out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - AggregateScore: 5.7, - TimeScanned: time.Unix(1e9, 0), - ScorecardVersion: "123", - ScorecardCommit: "abc", - }, - }, - }, - }, - { - Name: "Query Checks", - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Src: s1, - SC: &model.ScorecardInputSpec{ - Checks: []*model.ScorecardCheckInputSpec{ - { - Check: "check one", - Score: 5, - }, - }, - ScorecardVersion: "123", - }, - }, - { - Src: s1, - SC: &model.ScorecardInputSpec{ - Checks: []*model.ScorecardCheckInputSpec{ - { - Check: "check one", - Score: 5, - }, - { - Check: "check two", - Score: 6, - }, - }, - ScorecardVersion: "456", - }, - }, - }, - Query: &model.CertifyScorecardSpec{ - Checks: []*model.ScorecardCheckSpec{ - { - Check: "check one", - Score: 5, - }, - }, - }, - ExpSC: []*model.CertifyScorecard{ - { - Source: s1out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{ - { - Check: "check one", - Score: 5, - }, - }, - ScorecardVersion: "123", - }, - }, - }, - }, - { - Name: "Query None", - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Src: s1, - SC: &model.ScorecardInputSpec{ - AggregateScore: 1.5, - TimeScanned: time.Unix(1e9, 0), - ScorecardVersion: "123", - ScorecardCommit: "abc", - }, - }, - { - Src: s1, - SC: &model.ScorecardInputSpec{ - AggregateScore: 5.7, - TimeScanned: time.Unix(1e9, 0), - ScorecardVersion: "123", - ScorecardCommit: "abc", - }, - }, - }, - Query: &model.CertifyScorecardSpec{ - ScorecardVersion: ptrfrom.String("456"), - }, - ExpSC: nil, - }, - { - Name: "Query ID", - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Src: s1, - SC: &model.ScorecardInputSpec{ - AggregateScore: 1.5, - TimeScanned: time.Unix(1e9, 0), - ScorecardVersion: "123", - ScorecardCommit: "abc", - }, - }, - }, - Query: &model.CertifyScorecardSpec{ - ID: ptrfrom.String("5"), - }, - ExpSC: []*model.CertifyScorecard{ - { - Source: s1out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - AggregateScore: 1.5, - TimeScanned: time.Unix(1e9, 0), - ScorecardVersion: "123", - ScorecardCommit: "abc", - }, - }, - }, - }, - { - Name: "Ingest error", - Calls: []call{ - { - Src: s1, - SC: &model.ScorecardInputSpec{ - AggregateScore: 1.5, - TimeScanned: time.Unix(1e9, 0), - ScorecardVersion: "123", - ScorecardCommit: "abc", - }, - }, - }, - ExpIngestErr: true, - }, - { - Name: "Query bad ID", - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Src: s1, - SC: &model.ScorecardInputSpec{ - AggregateScore: 1.5, - TimeScanned: time.Unix(1e9, 0), - ScorecardVersion: "123", - ScorecardCommit: "abc", - }, - }, - }, - Query: &model.CertifyScorecardSpec{ - ID: ptrfrom.String("4294967296"), - }, - ExpQueryErr: true, - }, - } - - ctx := s.Ctx - hasOnly := false - for _, t := range tests { - if t.Only { - hasOnly = true - break - } - } - - for _, test := range tests { - if hasOnly && !test.Only { - continue - } - s.Run(test.Name, func() { - t := s.T() - b, err := GetBackend(s.Client) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, o := range test.Calls { - _, err := b.IngestScorecard(ctx, *o.Src, *o.SC) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.Scorecards(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpSC, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func (s *Suite) TestIngestScorecards() { - type call struct { - Src []*model.SourceInputSpec - SC []*model.ScorecardInputSpec - } - tests := []struct { - Name string - InSrc []*model.SourceInputSpec - Calls []call - Query *model.CertifyScorecardSpec - ExpSC []*model.CertifyScorecard - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Src: []*model.SourceInputSpec{s1}, - SC: []*model.ScorecardInputSpec{ - { - Origin: "test origin", - }, - }, - }, - }, - Query: &model.CertifyScorecardSpec{ - Origin: ptrfrom.String("test origin"), - }, - ExpSC: []*model.CertifyScorecard{ - { - Source: s1out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - Origin: "test origin", - }, - }, - }, - }, - // TODO: Determine why this test fails? - // { - // Name: "Ingest same", - // InSrc: []*model.SourceInputSpec{s1}, - // Calls: []call{ - // { - // Src: []*model.SourceInputSpec{s1, s1}, - // SC: []*model.ScorecardInputSpec{ - // { - // Origin: "test origin", - // }, - // { - // Origin: "test origin", - // }, - // }, - // }, - // }, - // Query: &model.CertifyScorecardSpec{ - // Origin: ptrfrom.String("test origin"), - // }, - // ExpSC: []*model.CertifyScorecard{ - // { - // Source: s1out, - // Scorecard: &model.Scorecard{ - // Checks: []*model.ScorecardCheck{}, - // Origin: "test origin", - // }, - // }, - // }, - // }, - { - Name: "Query multiple", - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Src: []*model.SourceInputSpec{s1, s1, s1}, - SC: []*model.ScorecardInputSpec{ - { - Origin: "test origin one", - }, - { - AggregateScore: 4.4, - Origin: "test origin two", - }, - { - AggregateScore: 4.9, - Origin: "test origin two", - }, - }, - }, - }, - Query: &model.CertifyScorecardSpec{ - Origin: ptrfrom.String("test origin two"), - }, - ExpSC: []*model.CertifyScorecard{ - { - Source: s1out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - AggregateScore: 4.4, - Origin: "test origin two", - }, - }, - { - Source: s1out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - AggregateScore: 4.9, - Origin: "test origin two", - }, - }, - }, - }, - { - Name: "Query Source", - InSrc: []*model.SourceInputSpec{s1, s2}, - Calls: []call{ - { - Src: []*model.SourceInputSpec{s1, s2}, - SC: []*model.ScorecardInputSpec{ - { - Origin: "test origin", - }, - { - Origin: "test origin", - }, - }, - }, - }, - Query: &model.CertifyScorecardSpec{ - Source: &model.SourceSpec{ - Namespace: ptrfrom.String("github.com/jeff"), - }, - }, - ExpSC: []*model.CertifyScorecard{ - { - Source: s1out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - Origin: "test origin", - }, - }, - }, - }, - } - ctx := s.Ctx - for _, test := range tests { - s.Run(test.Name, func() { - t := s.T() - b, err := GetBackend(s.Client) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, o := range test.Calls { - _, err := b.IngestScorecards(ctx, o.Src, o.SC) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.Scorecards(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpSC, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} diff --git a/pkg/assembler/backends/ent/backend/search_test.go b/pkg/assembler/backends/ent/backend/search_test.go deleted file mode 100644 index 58565f98ca..0000000000 --- a/pkg/assembler/backends/ent/backend/search_test.go +++ /dev/null @@ -1,80 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build integration - -package backend - -import ( - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -func (s *Suite) Test_FindSoftware() { - s.Run("HappyPath", func() { - b, err := GetBackend(s.Client) - s.NoError(err) - - for _, p := range []*model.PkgInputSpec{p1, p2, p3} { - if _, err := b.IngestPackage(s.Ctx, *p); err != nil { - s.NoError(err) - } - } - - for _, src := range []*model.SourceInputSpec{s1, s2} { - if _, err := b.IngestSource(s.Ctx, *src); err != nil { - s.NoError(err) - } - } - - for _, art := range []*model.ArtifactInputSpec{a1} { - if _, err := b.IngestArtifact(s.Ctx, art); err != nil { - s.NoError(err) - } - } - - // Find a package - results, err := b.FindSoftware(s.Ctx, "tensor") - s.NoError(err) - - if diff := cmp.Diff([]model.PackageSourceOrArtifact{p1out, p2out, p3out}, results, ignoreID, ignoreEmptySlices); diff != "" { - s.T().Errorf("Unexpected results. (-want +got):\n%s", diff) - } - - // Find a source - results, err = b.FindSoftware(s.Ctx, "bobs") - s.NoError(err) - - if diff := cmp.Diff([]model.PackageSourceOrArtifact{s2out}, results, ignoreID, ignoreEmptySlices); diff != "" { - s.T().Errorf("Unexpected results. (-want +got):\n%s", diff) - } - - // Find an artifact - results, err = b.FindSoftware(s.Ctx, "6bbb0da") - s.NoError(err) - - if diff := cmp.Diff([]model.PackageSourceOrArtifact{a1out}, results, ignoreID, ignoreEmptySlices); diff != "" { - s.T().Errorf("Unexpected results. (-want +got):\n%s", diff) - } - - // Find with empty query - results, err = b.FindSoftware(s.Ctx, "") - s.NoError(err) - - if diff := cmp.Diff([]model.PackageSourceOrArtifact{}, results, ignoreID, ignoreEmptySlices); diff != "" { - s.T().Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) -} diff --git a/pkg/assembler/backends/ent/backend/slsa.go b/pkg/assembler/backends/ent/backend/slsa.go index 20928541a3..a56b60c047 100644 --- a/pkg/assembler/backends/ent/backend/slsa.go +++ b/pkg/assembler/backends/ent/backend/slsa.go @@ -68,9 +68,14 @@ func (b *EntBackend) HasSlsa(ctx context.Context, spec *model.HasSLSASpec) ([]*m return collect(records, toModelHasSLSA), nil } -func (b *EntBackend) IngestSLSA(ctx context.Context, subject model.ArtifactInputSpec, builtFrom []*model.ArtifactInputSpec, builtBy model.BuilderInputSpec, slsa model.SLSAInputSpec) (string, error) { +func (b *EntBackend) IngestSLSA(ctx context.Context, subject model.IDorArtifactInput, builtFrom []*model.IDorArtifactInput, builtBy model.IDorBuilderInput, slsa model.SLSAInputSpec) (string, error) { + var builtFromInput []*model.ArtifactInputSpec + for _, bf := range builtFrom { + builtFromInput = append(builtFromInput, bf.ArtifactInput) + } + att, err := WithinTX(ctx, b.client, func(ctx context.Context) (*ent.SLSAAttestation, error) { - return upsertSLSA(ctx, ent.TxFromContext(ctx), subject, builtFrom, builtBy, slsa) + return upsertSLSA(ctx, ent.TxFromContext(ctx), *subject.ArtifactInput, builtFromInput, *builtBy.BuilderInput, slsa) }) if err != nil { return "", err @@ -80,7 +85,7 @@ func (b *EntBackend) IngestSLSA(ctx context.Context, subject model.ArtifactInput return nodeID(att.ID), nil } -func (b *EntBackend) IngestSLSAs(ctx context.Context, subjects []*model.ArtifactInputSpec, builtFromList [][]*model.ArtifactInputSpec, builtByList []*model.BuilderInputSpec, slsaList []*model.SLSAInputSpec) ([]string, error) { +func (b *EntBackend) IngestSLSAs(ctx context.Context, subjects []*model.IDorArtifactInput, builtFromList [][]*model.IDorArtifactInput, builtByList []*model.IDorBuilderInput, slsaList []*model.SLSAInputSpec) ([]string, error) { var modelHasSlsas []string for i, slsa := range slsaList { modelHasSlsa, err := b.IngestSLSA(ctx, *subjects[i], builtFromList[i], *builtByList[i], *slsa) diff --git a/pkg/assembler/backends/ent/backend/slsa_test.go b/pkg/assembler/backends/ent/backend/slsa_test.go deleted file mode 100644 index 3b37f0361f..0000000000 --- a/pkg/assembler/backends/ent/backend/slsa_test.go +++ /dev/null @@ -1,780 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build integration - -package backend - -import ( - "strconv" - "time" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -var b1 = &model.BuilderInputSpec{ - URI: "asdf", -} -var b1out = &model.Builder{ - URI: "asdf", -} - -var b2 = &model.BuilderInputSpec{ - URI: "qwer", -} - -func (s *Suite) TestHasSLSA() { - testTime := time.Unix(1e9+5, 0) - testTime2 := time.Unix(1e9, 0) - type call struct { - Sub *model.ArtifactInputSpec - BuiltFrom []*model.ArtifactInputSpec - Builder *model.BuilderInputSpec - SLSA *model.SLSAInputSpec - } - tests := []struct { - Name string - InArt []*model.ArtifactInputSpec - InBld []*model.BuilderInputSpec - Calls []call - Query *model.HasSLSASpec - ExpHS []*model.HasSlsa - ExpIngestErr bool - ExpQueryErr bool - Only bool - }{ - { - Name: "HappyPath", - InArt: []*model.ArtifactInputSpec{a1, a2}, - InBld: []*model.BuilderInputSpec{b1}, - Calls: []call{ - { - Sub: a1, - BuiltFrom: []*model.ArtifactInputSpec{a2}, - Builder: b1, - SLSA: &model.SLSAInputSpec{ - BuildType: "test type", - }, - }, - }, - Query: &model.HasSLSASpec{ - BuildType: ptrfrom.String("test type"), - }, - ExpHS: []*model.HasSlsa{ - { - Subject: a1out, - Slsa: &model.Slsa{ - BuiltBy: b1out, - BuiltFrom: []*model.Artifact{a2out}, - BuildType: "test type", - }, - }, - }, - }, - { - Name: "Ingest twice", - InArt: []*model.ArtifactInputSpec{a1, a2}, - InBld: []*model.BuilderInputSpec{b1}, - Calls: []call{ - { - Sub: a1, - BuiltFrom: []*model.ArtifactInputSpec{a2}, - Builder: b1, - SLSA: &model.SLSAInputSpec{ - BuildType: "test type", - }, - }, - { - Sub: a1, - BuiltFrom: []*model.ArtifactInputSpec{a2}, - Builder: b1, - SLSA: &model.SLSAInputSpec{ - BuildType: "test type", - }, - }, - }, - Query: &model.HasSLSASpec{ - BuildType: ptrfrom.String("test type"), - }, - ExpHS: []*model.HasSlsa{ - { - Subject: a1out, - Slsa: &model.Slsa{ - BuiltBy: b1out, - BuiltFrom: []*model.Artifact{a2out}, - BuildType: "test type", - }, - }, - }, - }, - { - Name: "Query on Build Type", - InArt: []*model.ArtifactInputSpec{a1, a2}, - InBld: []*model.BuilderInputSpec{b1}, - Calls: []call{ - { - Sub: a1, - BuiltFrom: []*model.ArtifactInputSpec{a2}, - Builder: b1, - SLSA: &model.SLSAInputSpec{ - BuildType: "test type one", - }, - }, - { - Sub: a1, - BuiltFrom: []*model.ArtifactInputSpec{a2}, - Builder: b1, - SLSA: &model.SLSAInputSpec{ - BuildType: "test type two", - }, - }, - }, - Query: &model.HasSLSASpec{ - BuildType: ptrfrom.String("test type one"), - }, - ExpHS: []*model.HasSlsa{ - { - Subject: a1out, - Slsa: &model.Slsa{ - BuiltBy: b1out, - BuiltFrom: []*model.Artifact{a2out}, - BuildType: "test type one", - }, - }, - }, - }, - { - Name: "Query on Version", - InArt: []*model.ArtifactInputSpec{a1, a2}, - InBld: []*model.BuilderInputSpec{b1}, - Calls: []call{ - { - Sub: a1, - BuiltFrom: []*model.ArtifactInputSpec{a2}, - Builder: b1, - SLSA: &model.SLSAInputSpec{ - SlsaVersion: "test type two", - }, - }, - { - Sub: a1, - BuiltFrom: []*model.ArtifactInputSpec{a2}, - Builder: b1, - SLSA: &model.SLSAInputSpec{ - SlsaVersion: "test type one", - }, - }, - }, - Query: &model.HasSLSASpec{ - SlsaVersion: ptrfrom.String("test type two"), - }, - ExpHS: []*model.HasSlsa{ - { - Subject: a1out, - Slsa: &model.Slsa{ - BuiltBy: b1out, - BuiltFrom: []*model.Artifact{a2out}, - SlsaVersion: "test type two", - }, - }, - }, - }, - { - Name: "Query on Time", - InArt: []*model.ArtifactInputSpec{a1, a2}, - InBld: []*model.BuilderInputSpec{b1}, - Calls: []call{ - { - Sub: a1, - BuiltFrom: []*model.ArtifactInputSpec{a2}, - Builder: b1, - SLSA: &model.SLSAInputSpec{ - StartedOn: &testTime2, - }, - }, - { - Sub: a1, - BuiltFrom: []*model.ArtifactInputSpec{a2}, - Builder: b1, - SLSA: &model.SLSAInputSpec{ - StartedOn: &testTime, - }, - }, - }, - Query: &model.HasSLSASpec{ - StartedOn: &testTime, - }, - ExpHS: []*model.HasSlsa{ - { - Subject: a1out, - Slsa: &model.Slsa{ - BuiltBy: b1out, - BuiltFrom: []*model.Artifact{a2out}, - StartedOn: &testTime, - }, - }, - }, - }, - { - Name: "Query on Subject", - InArt: []*model.ArtifactInputSpec{a1, a2, a3}, - InBld: []*model.BuilderInputSpec{b1}, - Calls: []call{ - { - Sub: a1, - BuiltFrom: []*model.ArtifactInputSpec{a2}, - Builder: b1, - SLSA: &model.SLSAInputSpec{}, - }, - { - Sub: a3, - BuiltFrom: []*model.ArtifactInputSpec{a2}, - Builder: b1, - SLSA: &model.SLSAInputSpec{}, - }, - }, - Query: &model.HasSLSASpec{ - Subject: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha256"), - }, - }, - ExpHS: []*model.HasSlsa{ - { - Subject: a1out, - Slsa: &model.Slsa{ - BuiltBy: b1out, - BuiltFrom: []*model.Artifact{a2out}, - }, - }, - }, - }, - { - Name: "Query on Materials", - InArt: []*model.ArtifactInputSpec{a1, a2, a3, a4}, - InBld: []*model.BuilderInputSpec{b1}, - Calls: []call{ - { - Sub: a1, - BuiltFrom: []*model.ArtifactInputSpec{a2}, - Builder: b1, - SLSA: &model.SLSAInputSpec{}, - }, - { - Sub: a1, - BuiltFrom: []*model.ArtifactInputSpec{a2, a3}, - Builder: b1, - SLSA: &model.SLSAInputSpec{}, - }, - { - Sub: a1, - BuiltFrom: []*model.ArtifactInputSpec{a4}, - Builder: b1, - SLSA: &model.SLSAInputSpec{}, - }, - }, - Query: &model.HasSLSASpec{ - BuiltFrom: []*model.ArtifactSpec{{ - Digest: ptrfrom.String("7A8F47318E4676DACB0142AFA0B83029CD7BEFD9"), - }}, - }, - ExpHS: []*model.HasSlsa{ - { - Subject: a1out, - Slsa: &model.Slsa{ - BuiltBy: b1out, - BuiltFrom: []*model.Artifact{a2out}, - }, - }, - { - Subject: a1out, - Slsa: &model.Slsa{ - BuiltBy: b1out, - BuiltFrom: []*model.Artifact{a2out, a3out}, - }, - }, - }, - }, - { - Name: "Query on Builder", - InArt: []*model.ArtifactInputSpec{a1, a2}, - InBld: []*model.BuilderInputSpec{b1, b2}, - Calls: []call{ - { - Sub: a1, - BuiltFrom: []*model.ArtifactInputSpec{a2}, - Builder: b1, - SLSA: &model.SLSAInputSpec{}, - }, - { - Sub: a1, - BuiltFrom: []*model.ArtifactInputSpec{a2}, - Builder: b2, - SLSA: &model.SLSAInputSpec{}, - }, - }, - Query: &model.HasSLSASpec{ - BuiltBy: &model.BuilderSpec{ - URI: ptrfrom.String("asdf"), - }, - }, - ExpHS: []*model.HasSlsa{ - { - Subject: a1out, - Slsa: &model.Slsa{ - BuiltBy: b1out, - BuiltFrom: []*model.Artifact{a2out}, - }, - }, - }, - }, - { - Name: "Query on ID", - InArt: []*model.ArtifactInputSpec{a1, a2}, - InBld: []*model.BuilderInputSpec{b1, b2}, - Calls: []call{ - { - Sub: a1, - BuiltFrom: []*model.ArtifactInputSpec{a2}, - Builder: b1, - SLSA: &model.SLSAInputSpec{}, - }, - { - Sub: a1, - BuiltFrom: []*model.ArtifactInputSpec{a2}, - Builder: b2, - SLSA: &model.SLSAInputSpec{}, - }, - }, - Query: &model.HasSLSASpec{ - ID: ptrfrom.String("0"), - }, - ExpHS: []*model.HasSlsa{ - { - Subject: a1out, - Slsa: &model.Slsa{ - BuiltBy: b1out, - BuiltFrom: []*model.Artifact{a2out}, - }, - }, - }, - }, - { - Name: "Query none", - InArt: []*model.ArtifactInputSpec{a1, a2}, - InBld: []*model.BuilderInputSpec{b1, b2}, - Calls: []call{ - { - Sub: a1, - BuiltFrom: []*model.ArtifactInputSpec{a2}, - Builder: b1, - SLSA: &model.SLSAInputSpec{}, - }, - { - Sub: a1, - BuiltFrom: []*model.ArtifactInputSpec{a2}, - Builder: b2, - SLSA: &model.SLSAInputSpec{}, - }, - }, - Query: &model.HasSLSASpec{ - BuiltBy: &model.BuilderSpec{ - URI: ptrfrom.String("poiu"), - }, - }, - ExpHS: nil, - }, - { - Name: "Ingest no Materials 1", - InArt: []*model.ArtifactInputSpec{a1}, - InBld: []*model.BuilderInputSpec{b1}, - Calls: []call{ - { - Sub: a1, - BuiltFrom: nil, - Builder: b2, - SLSA: &model.SLSAInputSpec{}, - }, - }, - ExpIngestErr: true, - }, - { - Name: "Ingest no Materials 2", - InArt: []*model.ArtifactInputSpec{a1}, - InBld: []*model.BuilderInputSpec{b1}, - Calls: []call{ - { - Sub: a1, - BuiltFrom: []*model.ArtifactInputSpec{}, - Builder: b2, - SLSA: &model.SLSAInputSpec{}, - }, - }, - ExpIngestErr: true, - }, - { - Name: "Ingest no Sub", - InArt: []*model.ArtifactInputSpec{a2}, - InBld: []*model.BuilderInputSpec{b2}, - Calls: []call{ - { - Sub: a1, - BuiltFrom: []*model.ArtifactInputSpec{a2}, - Builder: b2, - SLSA: &model.SLSAInputSpec{}, - }, - }, - ExpIngestErr: true, - }, - { - Name: "Ingest no matrials found", - InArt: []*model.ArtifactInputSpec{a1}, - InBld: []*model.BuilderInputSpec{b2}, - Calls: []call{ - { - Sub: a1, - BuiltFrom: []*model.ArtifactInputSpec{a2}, - Builder: b2, - SLSA: &model.SLSAInputSpec{}, - }, - }, - ExpIngestErr: true, - }, - { - Name: "Ingest no builder found", - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - Sub: a1, - BuiltFrom: []*model.ArtifactInputSpec{a2}, - Builder: b2, - SLSA: &model.SLSAInputSpec{}, - }, - }, - ExpIngestErr: true, - }, - { - Name: "Query bad ID", - InArt: []*model.ArtifactInputSpec{a1, a2}, - InBld: []*model.BuilderInputSpec{b1, b2}, - Calls: []call{ - { - Sub: a1, - BuiltFrom: []*model.ArtifactInputSpec{a2}, - Builder: b1, - SLSA: &model.SLSAInputSpec{}, - }, - { - Sub: a1, - BuiltFrom: []*model.ArtifactInputSpec{a2}, - Builder: b2, - SLSA: &model.SLSAInputSpec{}, - }, - }, - Query: &model.HasSLSASpec{ - ID: ptrfrom.Any("asdf"), - }, - ExpQueryErr: true, - }, - } - - ctx := s.Ctx - hasOnly := false - for _, t := range tests { - if t.Only { - hasOnly = true - break - } - } - - for _, test := range tests { - if hasOnly && !test.Only { - continue - } - s.Run(test.Name, func() { - t := s.T() - b, err := GetBackend(s.Client) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - for _, bld := range test.InBld { - if _, err := b.IngestBuilder(ctx, bld); err != nil { - t.Fatalf("Could not ingest builder: %v", err) - } - } - - ids := make([]string, len(test.Calls)) - for i, o := range test.Calls { - v, err := b.IngestSLSA(ctx, *o.Sub, o.BuiltFrom, *o.Builder, *o.SLSA) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - ids[i] = v - } - if test.Query != nil && test.Query.ID != nil { - idIdx, err := strconv.Atoi(*test.Query.ID) - if err == nil { - if idIdx >= len(ids) { - s.T().Fatalf("ID index out of range, want: %d, got: %d", len(ids), idIdx) - } - test.Query.ID = &ids[idIdx] - } - } - - got, err := b.HasSlsa(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpHS, got, ignoreID, ignoreEmptySlices); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func (s *Suite) TestIngestHasSLSAs() { - type call struct { - Sub []*model.ArtifactInputSpec - BF [][]*model.ArtifactInputSpec - BB []*model.BuilderInputSpec - SLSA []*model.SLSAInputSpec - } - tests := []struct { - Name string - InArt []*model.ArtifactInputSpec - InBld []*model.BuilderInputSpec - Calls []call - Query *model.HasSLSASpec - ExpHS []*model.HasSlsa - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InArt: []*model.ArtifactInputSpec{a1, a2}, - InBld: []*model.BuilderInputSpec{b1}, - Calls: []call{ - { - Sub: []*model.ArtifactInputSpec{a1}, - BF: [][]*model.ArtifactInputSpec{[]*model.ArtifactInputSpec{a2}}, - BB: []*model.BuilderInputSpec{b1}, - SLSA: []*model.SLSAInputSpec{ - { - BuildType: "test type", - }, - }, - }, - }, - Query: &model.HasSLSASpec{ - BuildType: ptrfrom.String("test type"), - }, - ExpHS: []*model.HasSlsa{ - { - Subject: a1out, - Slsa: &model.Slsa{ - BuiltBy: b1out, - BuiltFrom: []*model.Artifact{a2out}, - BuildType: "test type", - }, - }, - }, - }, - { - Name: "Ingest twice", - InArt: []*model.ArtifactInputSpec{a1, a2}, - InBld: []*model.BuilderInputSpec{b1}, - Calls: []call{ - { - Sub: []*model.ArtifactInputSpec{a1, a1}, - BF: [][]*model.ArtifactInputSpec{[]*model.ArtifactInputSpec{a2}, []*model.ArtifactInputSpec{a2}}, - BB: []*model.BuilderInputSpec{b1, b1}, - SLSA: []*model.SLSAInputSpec{ - { - BuildType: "test type", - }, - { - BuildType: "test type", - }, - }, - }, - }, - Query: &model.HasSLSASpec{ - BuildType: ptrfrom.String("test type"), - }, - ExpHS: []*model.HasSlsa{ - { - Subject: a1out, - Slsa: &model.Slsa{ - BuiltBy: b1out, - BuiltFrom: []*model.Artifact{a2out}, - BuildType: "test type", - }, - }, - }, - }, - { - Name: "Query on Build Type", - InArt: []*model.ArtifactInputSpec{a1, a2}, - InBld: []*model.BuilderInputSpec{b1}, - Calls: []call{ - { - Sub: []*model.ArtifactInputSpec{a1, a1}, - BF: [][]*model.ArtifactInputSpec{[]*model.ArtifactInputSpec{a2}, []*model.ArtifactInputSpec{a2}}, - BB: []*model.BuilderInputSpec{b1, b1}, - SLSA: []*model.SLSAInputSpec{ - { - BuildType: "test type one", - }, - { - BuildType: "test type two", - }, - }, - }, - }, - Query: &model.HasSLSASpec{ - BuildType: ptrfrom.String("test type one"), - }, - ExpHS: []*model.HasSlsa{ - { - Subject: a1out, - Slsa: &model.Slsa{ - BuiltBy: b1out, - BuiltFrom: []*model.Artifact{a2out}, - BuildType: "test type one", - }, - }, - }, - }, - { - Name: "Query on Subject", - InArt: []*model.ArtifactInputSpec{a1, a2, a3}, - InBld: []*model.BuilderInputSpec{b1}, - Calls: []call{ - { - Sub: []*model.ArtifactInputSpec{a1, a3}, - BF: [][]*model.ArtifactInputSpec{[]*model.ArtifactInputSpec{a2}, []*model.ArtifactInputSpec{a2}}, - BB: []*model.BuilderInputSpec{b1, b1}, - SLSA: []*model.SLSAInputSpec{ - {}, - {}, - }, - }, - }, - Query: &model.HasSLSASpec{ - Subject: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha256"), - }, - }, - ExpHS: []*model.HasSlsa{ - { - Subject: a1out, - Slsa: &model.Slsa{ - BuiltBy: b1out, - BuiltFrom: []*model.Artifact{a2out}, - }, - }, - }, - }, - { - Name: "Query on Materials", - InArt: []*model.ArtifactInputSpec{a1, a2, a3, a4}, - InBld: []*model.BuilderInputSpec{b1}, - Calls: []call{ - { - Sub: []*model.ArtifactInputSpec{a1, a1, a1}, - BF: [][]*model.ArtifactInputSpec{[]*model.ArtifactInputSpec{a2}, []*model.ArtifactInputSpec{a2, a3}, []*model.ArtifactInputSpec{a4}}, - BB: []*model.BuilderInputSpec{b1, b1, b1}, - SLSA: []*model.SLSAInputSpec{ - {}, - {}, - {}, - }, - }, - }, - Query: &model.HasSLSASpec{ - BuiltFrom: []*model.ArtifactSpec{{ - Digest: ptrfrom.String("7A8F47318E4676DACB0142AFA0B83029CD7BEFD9"), - }}, - }, - ExpHS: []*model.HasSlsa{ - { - Subject: a1out, - Slsa: &model.Slsa{ - BuiltBy: b1out, - BuiltFrom: []*model.Artifact{a2out}, - }, - }, - { - Subject: a1out, - Slsa: &model.Slsa{ - BuiltBy: b1out, - BuiltFrom: []*model.Artifact{a2out, a3out}, - }, - }, - }, - }, - } - ctx := s.Ctx - for _, test := range tests { - s.Run(test.Name, func() { - t := s.T() - b, err := GetBackend(s.Client) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - for _, bld := range test.InBld { - if _, err := b.IngestBuilder(ctx, bld); err != nil { - t.Fatalf("Could not ingest builder: %v", err) - } - } - for _, o := range test.Calls { - _, err := b.IngestSLSAs(ctx, o.Sub, o.BF, o.BB, o.SLSA) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.HasSlsa(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpHS, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} diff --git a/pkg/assembler/backends/ent/backend/software_test.go b/pkg/assembler/backends/ent/backend/software_test.go deleted file mode 100644 index 8f658416b8..0000000000 --- a/pkg/assembler/backends/ent/backend/software_test.go +++ /dev/null @@ -1,177 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build integration - -package backend - -// Usually this would be part of ent, but the import cycle doesn't allow for it. - -import ( - "testing" - - "github.com/guacsec/guac/pkg/assembler/backends/ent/testutils" - "github.com/guacsec/guac/pkg/assembler/graphql/model" - "github.com/stretchr/testify/suite" -) - -type Suite struct { - testutils.Suite -} - -func TestEntBackendSuite(t *testing.T) { - suite.Run(t, new(Suite)) -} - -func (s *Suite) TestCreateSoftwareTree() { - s.Run("HappyPath", func() { - be, err := GetBackend(s.Client) - s.NoError(err) - - // pkg:apk/alpine/apk@2.12.9-r3?arch=x86 - id, err2 := be.IngestPackage(s.Ctx, model.PkgInputSpec{ - Type: "apk", - Namespace: ptr("alpine"), - Name: "apk", - Version: ptr("2.12.9-r3"), - Subpath: nil, - Qualifiers: []*model.PackageQualifierInputSpec{ - {Key: "arch", Value: "x86"}, - }, - }) - s.NoError(err2) - pkgs, err3 := be.Packages(s.Ctx, &model.PkgSpec{ID: &id.PackageVersionID}) - s.NoError(err3) - pkg := pkgs[0] - s.NoError(err3) - s.NotNil(pkg) - s.Equal("apk", pkg.Type) - - if s.Len(pkg.Namespaces, 1) { - s.Equal("alpine", pkg.Namespaces[0].Namespace) - - if s.Len(pkg.Namespaces[0].Names, 1) { - s.Equal("apk", pkg.Namespaces[0].Names[0].Name) - - if s.Len(pkg.Namespaces[0].Names[0].Versions, 1) { - s.Equal("2.12.9-r3", pkg.Namespaces[0].Names[0].Versions[0].Version) - } - } - } - - // Ingest a second time should only create a new version - id, err2 = be.IngestPackage(s.Ctx, model.PkgInputSpec{ - Type: "apk", - Namespace: ptr("alpine"), - Name: "apk", - Version: ptr("2.12.10"), - Subpath: nil, - Qualifiers: []*model.PackageQualifierInputSpec{ - {Key: "arch", Value: "x86"}, - }, - }) - // Ensure that we don't get a duplicate row error - s.NoError(err2) - - pkgs, err = be.Packages(s.Ctx, &model.PkgSpec{ID: &id.PackageVersionID}) - s.NoError(err) - pkg = pkgs[0] - s.NotNil(pkg) - - if s.Len(pkg.Namespaces, 1) { - s.Equal("alpine", pkg.Namespaces[0].Namespace) - - if s.Len(pkg.Namespaces[0].Names, 1) { - s.Equal("apk", pkg.Namespaces[0].Names[0].Name) - - if s.Len(pkg.Namespaces[0].Names[0].Versions, 1) { - s.Equal("2.12.10", pkg.Namespaces[0].Names[0].Versions[0].Version) - } - } - } - }) -} - -func (s *Suite) TestVersionUpsertsWithQualifiers() { - s.Run("HappyPath", func() { - be, err := GetBackend(s.Client) - s.NoError(err) - - // pkg:apk/alpine/apk@2.12.9-r3?arch=x86 - id, err2 := be.IngestPackage(s.Ctx, model.PkgInputSpec{ - Type: "apk", - Namespace: ptr("alpine"), - Name: "apk", - Version: ptr("2.12.9-r3"), - Subpath: nil, - Qualifiers: []*model.PackageQualifierInputSpec{{Key: "arch", Value: "x86"}}, - }) - s.NoError(err2) - pkgs, err3 := be.Packages(s.Ctx, &model.PkgSpec{ID: &id.PackageVersionID}) - pkg1 := pkgs[0] - s.NoError(err3) - s.NotNil(pkg1) - s.Equal("", pkg1.Namespaces[0].Names[0].Versions[0].Subpath) - - // pkg:apk/alpine/apk@2.12.9-r3?arch=arm64 - spec2 := model.PkgInputSpec{ - Type: "apk", - Namespace: ptr("alpine"), - Name: "apk", - Version: ptr("2.12.9-r3"), - Subpath: nil, - Qualifiers: []*model.PackageQualifierInputSpec{{Key: "arch", Value: "arm64"}}, - } - - id2, err4 := be.IngestPackage(s.Ctx, spec2) - s.NoError(err4) - pkgs, err3 = be.Packages(s.Ctx, &model.PkgSpec{ID: &id2.PackageVersionID}) - s.NoError(err3) - pkg2 := pkgs[0] - s.NotNil(pkg2) - }) -} - -func (s *Suite) TestIngestOccurrence_Package() { - s.Run("HappyPath", func() { - be, err := GetBackend(s.Client) - s.NoError(err) - - _, err = be.IngestPackage(s.Ctx, *p1) - s.NoError(err) - - _, err = be.IngestArtifact(s.Ctx, &model.ArtifactInputSpec{ - Algorithm: "sha256", Digest: "6bbb0da1891646e58eb3e6a63af3a6fc3c8eb5a0d44824cba581d2e14a0450cf", - }) - s.NoError(err) - - // pkg:apk/alpine/apk@2.12.9-r3?arch=x86 - oc, err := be.IngestOccurrence(s.Ctx, - model.PackageOrSourceInput{ - Package: p1, - }, - model.ArtifactInputSpec{ - Algorithm: "sha256", Digest: "6bbb0da1891646e58eb3e6a63af3a6fc3c8eb5a0d44824cba581d2e14a0450cf", - }, - model.IsOccurrenceInputSpec{ - Justification: "this artifact is an occurrence of this openssl", - Origin: "Demo ingestion", - Collector: "Demo ingestion", - }, - ) - s.NoError(err) - s.NotNil(oc) - }) -} diff --git a/pkg/assembler/backends/ent/backend/source.go b/pkg/assembler/backends/ent/backend/source.go index 1a1289a094..bc0c25142b 100644 --- a/pkg/assembler/backends/ent/backend/source.go +++ b/pkg/assembler/backends/ent/backend/source.go @@ -69,9 +69,9 @@ func (b *EntBackend) HasSourceAt(ctx context.Context, filter *model.HasSourceAtS return collect(records, toModelHasSourceAt), nil } -func (b *EntBackend) IngestHasSourceAt(ctx context.Context, pkg model.PkgInputSpec, pkgMatchType model.MatchFlags, source model.SourceInputSpec, hasSourceAt model.HasSourceAtInputSpec) (string, error) { +func (b *EntBackend) IngestHasSourceAt(ctx context.Context, pkg model.IDorPkgInput, pkgMatchType model.MatchFlags, source model.IDorSourceInput, hasSourceAt model.HasSourceAtInputSpec) (string, error) { record, err := WithinTX(ctx, b.client, func(ctx context.Context) (*ent.HasSourceAt, error) { - return upsertHasSourceAt(ctx, ent.TxFromContext(ctx), pkg, pkgMatchType, source, hasSourceAt) + return upsertHasSourceAt(ctx, ent.TxFromContext(ctx), *pkg.PackageInput, pkgMatchType, *source.SourceInput, hasSourceAt) }) if err != nil { return "", err @@ -81,7 +81,7 @@ func (b *EntBackend) IngestHasSourceAt(ctx context.Context, pkg model.PkgInputSp return nodeID(record.ID), nil } -func (b *EntBackend) IngestHasSourceAts(ctx context.Context, pkgs []*model.PkgInputSpec, pkgMatchType *model.MatchFlags, sources []*model.SourceInputSpec, hasSourceAts []*model.HasSourceAtInputSpec) ([]string, error) { +func (b *EntBackend) IngestHasSourceAts(ctx context.Context, pkgs []*model.IDorPkgInput, pkgMatchType *model.MatchFlags, sources []*model.IDorSourceInput, hasSourceAts []*model.HasSourceAtInputSpec) ([]string, error) { var result []string for i := range hasSourceAts { hsa, err := b.IngestHasSourceAt(ctx, *pkgs[i], *pkgMatchType, *sources[i], *hasSourceAts[i]) @@ -161,7 +161,7 @@ func (b *EntBackend) Sources(ctx context.Context, filter *model.SourceSpec) ([]* return collect(records, toModelSourceName), nil } -func (b *EntBackend) IngestSources(ctx context.Context, sources []*model.SourceInputSpec) ([]*model.SourceIDs, error) { +func (b *EntBackend) IngestSources(ctx context.Context, sources []*model.IDorSourceInput) ([]*model.SourceIDs, error) { ids := make([]*model.SourceIDs, len(sources)) eg, ctx := errgroup.WithContext(ctx) for i := range sources { @@ -181,9 +181,9 @@ func (b *EntBackend) IngestSources(ctx context.Context, sources []*model.SourceI return ids, nil } -func (b *EntBackend) IngestSource(ctx context.Context, source model.SourceInputSpec) (*model.SourceIDs, error) { +func (b *EntBackend) IngestSource(ctx context.Context, source model.IDorSourceInput) (*model.SourceIDs, error) { sourceNameID, err := WithinTX(ctx, b.client, func(ctx context.Context) (*model.SourceIDs, error) { - return upsertSource(ctx, ent.TxFromContext(ctx), source) + return upsertSource(ctx, ent.TxFromContext(ctx), *source.SourceInput) }) if err != nil { return nil, err diff --git a/pkg/assembler/backends/ent/backend/source_test.go b/pkg/assembler/backends/ent/backend/source_test.go deleted file mode 100644 index b32aa9e69a..0000000000 --- a/pkg/assembler/backends/ent/backend/source_test.go +++ /dev/null @@ -1,962 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build integration - -package backend - -import ( - "strconv" - "time" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -func (s *Suite) TestSources() { - ctx := s.Ctx - tests := []struct { - name string - srcInput []*model.SourceInputSpec - srcFilter *model.SourceSpec - idInFilter bool - want []*model.Source - wantErr bool - expInserts int - }{ - { - name: "myrepo with tag", - srcInput: []*model.SourceInputSpec{s1}, - srcFilter: &model.SourceSpec{ - Name: ptrfrom.String("myrepo"), - }, - idInFilter: false, - want: []*model.Source{s1out}, - wantErr: false, - expInserts: 1, - }, - { - name: "myrepo with tag, ID search", - srcInput: []*model.SourceInputSpec{s1}, - srcFilter: &model.SourceSpec{ - Name: ptrfrom.String("myrepo"), - }, - idInFilter: true, - want: []*model.Source{s1out}, - wantErr: false, - expInserts: 1, - }, - { - name: "bobsrepo with commit", - srcInput: []*model.SourceInputSpec{s2}, - srcFilter: &model.SourceSpec{ - Namespace: ptrfrom.String("github.com/bob"), - Commit: ptrfrom.String("5e7c41f"), - }, - want: []*model.Source{s2out}, - expInserts: 1, - }, - { - name: "ingest same twice", - srcInput: []*model.SourceInputSpec{s1, s1}, - srcFilter: &model.SourceSpec{ - Name: ptrfrom.String("myrepo"), - }, - want: []*model.Source{s1out}, - expInserts: 1, - }, - { - name: "bobsrepo with commit, type search", - srcInput: []*model.SourceInputSpec{s2}, - srcFilter: &model.SourceSpec{ - Type: ptrfrom.String("git"), - Namespace: ptrfrom.String("github.com/bob"), - Commit: ptrfrom.String("5e7c41f"), - }, - idInFilter: false, - want: []*model.Source{s2out}, - wantErr: false, - expInserts: 1, - }, - } - - for _, tt := range tests { - s.Run(tt.name, func() { - t := s.T() - be, err := GetBackend(s.Client) - if err != nil { - t.Fatalf("GetBackend() error = %v", err) - } - ids, err := be.IngestSources(ctx, tt.srcInput) - if (err != nil) != tt.wantErr { - t.Errorf("demoClient.IngestSource() error = %v, wantErr %v", err, tt.wantErr) - return - } - - if count := s.Client.SourceName.Query().CountX(ctx); count != tt.expInserts { - t.Errorf("Expected %d inserts, got %d", tt.expInserts, count) - } - - if tt.idInFilter { - tt.srcFilter.ID = &ids[0].SourceNameID - } - got, err := be.Sources(ctx, tt.srcFilter) - if (err != nil) != tt.wantErr { - t.Errorf("demoClient.Sources() error = %v, wantErr %v", err, tt.wantErr) - return - } - if diff := cmp.Diff(tt.want, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func (s *Suite) TestHasSourceAt() { - testTime := time.Unix(1e9+5, 0) - type call struct { - Pkg *model.PkgInputSpec - Src *model.SourceInputSpec - Match *model.MatchFlags - HSA *model.HasSourceAtInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - Calls []call - Query *model.HasSourceAtSpec - ExpHSA []*model.HasSourceAt - ExpIngestErr bool - ExpQueryErr bool - Only bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{p1}, - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Pkg: p1, - Src: s1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.HasSourceAtSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHSA: []*model.HasSourceAt{ - { - Package: p1out, - Source: s1out, - Justification: "test justification", - }, - }, - }, - { - Name: "HappyPath All Versions", - InPkg: []*model.PkgInputSpec{p1}, - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Pkg: p1, - Src: s1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - HSA: &model.HasSourceAtInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.HasSourceAtSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHSA: []*model.HasSourceAt{ - { - Package: p1outName, - Source: s1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest Same Twice", - InPkg: []*model.PkgInputSpec{p1}, - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Pkg: p1, - Src: s1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{ - Justification: "test justification", - }, - }, - { - Pkg: p1, - Src: s1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.HasSourceAtSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHSA: []*model.HasSourceAt{ - { - Package: p1out, - Source: s1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query On Justification", - InPkg: []*model.PkgInputSpec{p1}, - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Pkg: p1, - Src: s1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{ - Justification: "test justification one", - }, - }, - { - Pkg: p1, - Src: s1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{ - Justification: "test justification two", - }, - }, - }, - Query: &model.HasSourceAtSpec{ - Justification: ptrfrom.String("test justification two"), - }, - ExpHSA: []*model.HasSourceAt{ - { - Package: p1out, - Source: s1out, - Justification: "test justification two", - }, - }, - }, - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{p1, p2}, - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Pkg: p1, - Src: s1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{}, - }, - { - Pkg: p2, - Src: s1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{}, - }, - }, - Query: &model.HasSourceAtSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String("2.11.1"), - }, - }, - ExpHSA: []*model.HasSourceAt{ - { - Package: p2out, - Source: s1out, - }, - }, - }, - { - Name: "Query on Source", - InPkg: []*model.PkgInputSpec{p1}, - InSrc: []*model.SourceInputSpec{s1, s2}, - Calls: []call{ - { - Pkg: p1, - Src: s1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{}, - }, - { - Pkg: p1, - Src: s2, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{}, - }, - }, - Query: &model.HasSourceAtSpec{ - Source: &model.SourceSpec{ - Name: ptrfrom.String("myrepo"), - }, - }, - ExpHSA: []*model.HasSourceAt{ - { - Package: p1out, - Source: s1out, - }, - }, - }, - { - Name: "Query on KnownSince", - InPkg: []*model.PkgInputSpec{p1}, - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Pkg: p1, - Src: s1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{ - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Pkg: p1, - Src: s1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{ - KnownSince: testTime, - }, - }, - }, - Query: &model.HasSourceAtSpec{ - KnownSince: &testTime, - }, - ExpHSA: []*model.HasSourceAt{ - { - Package: p1out, - Source: s1out, - KnownSince: testTime, - }, - }, - }, - { - Name: "Query Multiple", - InPkg: []*model.PkgInputSpec{p1, p2}, - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Pkg: p1, - Src: s1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{ - Justification: "test justification one", - }, - }, - { - Pkg: p1, - Src: s1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{ - Justification: "test justification two", - }, - }, - { - Pkg: p2, - Src: s1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{ - Justification: "test justification two", - }, - }, - }, - Query: &model.HasSourceAtSpec{ - Justification: ptrfrom.String("test justification two"), - }, - ExpHSA: []*model.HasSourceAt{ - { - Package: p1out, - Source: s1out, - Justification: "test justification two", - }, - { - Package: p2out, - Source: s1out, - Justification: "test justification two", - }, - }, - }, - { - Name: "Query None", - InPkg: []*model.PkgInputSpec{p1}, - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Pkg: p1, - Src: s1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{ - Justification: "test justification one", - }, - }, - { - Pkg: p1, - Src: s1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{ - Justification: "test justification two", - }, - }, - }, - Query: &model.HasSourceAtSpec{ - Justification: ptrfrom.String("test justification three"), - }, - ExpHSA: nil, - }, - { - Name: "Query ID", - InPkg: []*model.PkgInputSpec{p1}, - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Pkg: p1, - Src: s1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{ - Justification: "test justification one", - }, - }, - { - Pkg: p1, - Src: s1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{ - Justification: "test justification two", - }, - }, - }, - Query: &model.HasSourceAtSpec{ - ID: ptrfrom.String("1"), - }, - ExpHSA: []*model.HasSourceAt{ - { - Package: p1out, - Source: s1out, - Justification: "test justification two", - }, - }, - }, - { - Name: "Query Name and Version", - InPkg: []*model.PkgInputSpec{p1, p2}, - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Pkg: p1, - Src: s1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{}, - }, - { - Pkg: p1, - Src: s1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - HSA: &model.HasSourceAtInputSpec{}, - }, - { - Pkg: p2, - Src: s1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{}, - }, - }, - Query: &model.HasSourceAtSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String(""), - }, - }, - ExpHSA: []*model.HasSourceAt{ - { - Package: p1out, - Source: s1out, - }, - { - Package: p1outName, - Source: s1out, - }, - }, - }, - { - Name: "Ingest no pkg", - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Pkg: p1, - Src: s1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{}, - }, - }, - ExpIngestErr: true, - }, - { - Name: "Ingest no src", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Pkg: p1, - Src: s1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{}, - }, - }, - ExpIngestErr: true, - }, - { - Name: "Query bad ID", - InPkg: []*model.PkgInputSpec{p1}, - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Pkg: p1, - Src: s1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{}, - }, - }, - Query: &model.HasSourceAtSpec{ - ID: ptrfrom.String("asdf"), - }, - ExpQueryErr: true, - }, - } - - hasOnly := false - for _, test := range tests { - if test.Only { - hasOnly = true - break - } - } - - ctx := s.Ctx - for _, test := range tests { - if hasOnly && !test.Only { - continue - } - - s.Run(test.Name, func() { - t := s.T() - b, err := GetBackend(s.Client) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - - _, err = b.IngestSources(ctx, test.InSrc) - s.NoError(err, "Could not ingest sources") - - ids := make([]string, len(test.Calls)) - for i, o := range test.Calls { - v, err := b.IngestHasSourceAt(ctx, *o.Pkg, *o.Match, *o.Src, *o.HSA) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - ids[i] = v - } - - if test.Query.ID != nil { - idIdx, err := strconv.Atoi(*test.Query.ID) - if err == nil { - if idIdx >= len(ids) { - s.T().Fatalf("ID index out of range, want: %d, got: %d", len(ids), idIdx) - } - test.Query.ID = ptrfrom.String(ids[idIdx]) - } - } - - got, err := b.HasSourceAt(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpHSA, got, ignoreID, ignoreEmptySlices); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func (s *Suite) TestIngestHasSourceAts() { - testTime := time.Unix(1e9+5, 0) - type call struct { - Pkgs []*model.PkgInputSpec - Srcs []*model.SourceInputSpec - Match *model.MatchFlags - HSAs []*model.HasSourceAtInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - Calls []call - Query *model.HasSourceAtSpec - ExpHSA []*model.HasSourceAt - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{p1}, - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Pkgs: []*model.PkgInputSpec{p1}, - Srcs: []*model.SourceInputSpec{s1}, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSAs: []*model.HasSourceAtInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.HasSourceAtSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHSA: []*model.HasSourceAt{ - { - Package: p1out, - Source: s1out, - Justification: "test justification", - }, - }, - }, - { - Name: "HappyPath All Versions", - InPkg: []*model.PkgInputSpec{p1}, - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Pkgs: []*model.PkgInputSpec{p1}, - Srcs: []*model.SourceInputSpec{s1}, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - HSAs: []*model.HasSourceAtInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.HasSourceAtSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHSA: []*model.HasSourceAt{ - { - Package: p1outName, - Source: s1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest Same Twice", - InPkg: []*model.PkgInputSpec{p1}, - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Pkgs: []*model.PkgInputSpec{p1, p1}, - Srcs: []*model.SourceInputSpec{s1, s1}, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSAs: []*model.HasSourceAtInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.HasSourceAtSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHSA: []*model.HasSourceAt{ - { - Package: p1out, - Source: s1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{p1, p2}, - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Pkgs: []*model.PkgInputSpec{p1, p2}, - Srcs: []*model.SourceInputSpec{s1, s1}, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSAs: []*model.HasSourceAtInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.HasSourceAtSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String("2.11.1"), - }, - }, - ExpHSA: []*model.HasSourceAt{ - { - Package: p2out, - Source: s1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Source", - InPkg: []*model.PkgInputSpec{p1}, - InSrc: []*model.SourceInputSpec{s1, s2}, - Calls: []call{ - { - Pkgs: []*model.PkgInputSpec{p1, p1}, - Srcs: []*model.SourceInputSpec{s1, s2}, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSAs: []*model.HasSourceAtInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.HasSourceAtSpec{ - Source: &model.SourceSpec{ - Name: ptrfrom.String("myrepo"), - }, - }, - ExpHSA: []*model.HasSourceAt{ - { - Package: p1out, - Source: s1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on KnownSince", - InPkg: []*model.PkgInputSpec{p1}, - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Pkgs: []*model.PkgInputSpec{p1, p1}, - Srcs: []*model.SourceInputSpec{s1, s1}, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSAs: []*model.HasSourceAtInputSpec{ - { - KnownSince: time.Unix(1e9, 0), - }, - { - KnownSince: testTime, - }, - }, - }, - }, - Query: &model.HasSourceAtSpec{ - KnownSince: &testTime, - }, - ExpHSA: []*model.HasSourceAt{ - { - Package: p1out, - Source: s1out, - KnownSince: testTime, - }, - }, - }, - } - ctx := s.Ctx - for _, test := range tests { - s.Run(test.Name, func() { - t := s.T() - b, err := GetBackend(s.Client) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, o := range test.Calls { - _, err := b.IngestHasSourceAts(ctx, o.Pkgs, o.Match, o.Srcs, o.HSAs) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.HasSourceAt(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpHSA, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -// This test is to traverse the other branches of the upsert, not covered by the happy path at the insertion, -// when the create fails due to the presence of the input in the store, and a where query is used in the error branch -func (s *Suite) TestSourcesIngestSameTwice() { - - tests := []struct { - name string - sourceInputsSpec []model.SourceInputSpec - }{{ - name: "IngestSameTwice", - sourceInputsSpec: []model.SourceInputSpec{ - { - Type: "git", - Namespace: "github.com/jeff", - Name: "myrepo", - Tag: ptr("nightly"), - Commit: ptr("012345678"), - }, - { - Type: "git", - Namespace: "github.com/jeff", - Name: "myrepo", - Tag: ptr("nightly"), - Commit: ptr("012345678"), - }, - }, - }} - - ctx := s.Ctx - for _, tt := range tests { - s.Run(tt.name, func() { - t := s.T() - b, err := GetBackend(s.Client) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - - for _, bIn := range tt.sourceInputsSpec { - if _, err := b.IngestSource(ctx, bIn); err != nil { - t.Fatalf("Could not ingest source: %v , err: %v", bIn, err) - } - } - items, err := b.Sources(ctx, &model.SourceSpec{}) - if err != nil { - t.Fatalf("Error on load Sources %v", err) - } - if len(items) == 2 { - t.Fatalf("Wrong ingestions, ingest same twice found two") - } - }) - } -} diff --git a/pkg/assembler/backends/ent/backend/vex_test.go b/pkg/assembler/backends/ent/backend/vex_test.go deleted file mode 100644 index 4eb85ef895..0000000000 --- a/pkg/assembler/backends/ent/backend/vex_test.go +++ /dev/null @@ -1,1032 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build integration - -package backend - -// func (s *Suite) TestVEX() { -// testTime := time.Unix(1e9+5, 0) -// type call struct { -// Sub model.PackageOrArtifactInput -// Vuln model.VulnerabilityInputSpec -// In *model.VexStatementInputSpec -// } -// tests := []struct { -// Name string -// InPkg []*model.PkgInputSpec -// InArt []*model.ArtifactInputSpec -// InOsv []*model.OSVInputSpec -// InCve []*model.CVEInputSpec -// InGhsa []*model.GHSAInputSpec -// Calls []call -// Query *model.CertifyVEXStatementSpec -// ExpVEX []*model.CertifyVEXStatement -// ExpIngestErr bool -// ExpQueryErr bool -// }{ -// { -// Name: "HappyPath", -// InPkg: []*model.PkgInputSpec{p1}, -// InOsv: []*model.OSVInputSpec{o1}, -// Calls: []call{ -// call{ -// Sub: model.PackageOrArtifactInput{ -// Package: p1, -// }, -// Vuln: model.VulnerabilityInput{ -// Osv: o1, -// }, -// In: &model.VexStatementInputSpec{ -// VexJustification: "test justification", -// KnownSince: time.Unix(1e9, 0), -// }, -// }, -// }, -// Query: &model.CertifyVEXStatementSpec{ -// VexJustification: (*model.VexJustification)(ptrfrom.String("test justification")), -// }, -// ExpVEX: []*model.CertifyVEXStatement{ -// &model.CertifyVEXStatement{ -// Subject: p1out, -// Vulnerability: o1out, -// VexJustification: "test justification", -// KnownSince: time.Unix(1e9, 0), -// }, -// }, -// }, -// { -// Name: "Ingest same twice", -// InPkg: []*model.PkgInputSpec{p1}, -// InOsv: []*model.OSVInputSpec{o1}, -// Calls: []call{ -// call{ -// Sub: model.PackageOrArtifactInput{ -// Package: p1, -// }, -// Vuln: model.VulnerabilityInput{ -// Osv: o1, -// }, -// In: &model.VexStatementInputSpec{ -// VexJustification: "test justification", -// KnownSince: time.Unix(1e9, 0), -// }, -// }, -// call{ -// Sub: model.PackageOrArtifactInput{ -// Package: p1, -// }, -// Vuln: model.VulnerabilityInput{ -// Osv: o1, -// }, -// In: &model.VexStatementInputSpec{ -// VexJustification: "test justification", -// KnownSince: time.Unix(1e9, 0), -// }, -// }, -// }, -// Query: &model.CertifyVEXStatementSpec{ -// VexJustification: (*model.VexJustification)(ptrfrom.String("test justification")), -// }, -// ExpVEX: []*model.CertifyVEXStatement{ -// &model.CertifyVEXStatement{ -// Subject: p1out, -// Vulnerability: o1out, -// VexJustification: "test justification", -// KnownSince: time.Unix(1e9, 0), -// }, -// }, -// }, -// { -// Name: "Query on Justification", -// InPkg: []*model.PkgInputSpec{p1}, -// InOsv: []*model.OSVInputSpec{o1}, -// Calls: []call{ -// call{ -// Sub: model.PackageOrArtifactInput{ -// Package: p1, -// }, -// Vuln: model.VulnerabilityInput{ -// Osv: o1, -// }, -// In: &model.VexStatementInputSpec{ -// VexJustification: "test justification", -// KnownSince: time.Unix(1e9, 0), -// }, -// }, -// call{ -// Sub: model.PackageOrArtifactInput{ -// Package: p1, -// }, -// Vuln: model.VulnerabilityInput{ -// Osv: o1, -// }, -// In: &model.VexStatementInputSpec{ -// VexJustification: "test justification 2", -// KnownSince: time.Unix(1e9, 0), -// }, -// }, -// }, -// Query: &model.CertifyVEXStatementSpec{ -// VexJustification: (*model.VexJustification)(ptrfrom.String("test justification 2")), -// }, -// ExpVEX: []*model.CertifyVEXStatement{ -// &model.CertifyVEXStatement{ -// Subject: p1out, -// Vulnerability: o1out, -// VexJustification: "test justification 2", -// KnownSince: time.Unix(1e9, 0), -// }, -// }, -// }, -// { -// Name: "Query on Package", -// InPkg: []*model.PkgInputSpec{p1, p2}, -// InArt: []*model.ArtifactInputSpec{a1}, -// InOsv: []*model.OSVInputSpec{o1}, -// Calls: []call{ -// call{ -// Sub: model.PackageOrArtifactInput{ -// Package: p1, -// }, -// Vuln: model.VulnerabilityInput{ -// Osv: o1, -// }, -// In: &model.VexStatementInputSpec{ -// VexJustification: "test justification", -// KnownSince: time.Unix(1e9, 0), -// }, -// }, -// call{ -// Sub: model.PackageOrArtifactInput{ -// Package: p2, -// }, -// Vuln: model.VulnerabilityInput{ -// Osv: o1, -// }, -// In: &model.VexStatementInputSpec{ -// VexJustification: "test justification", -// KnownSince: time.Unix(1e9, 0), -// }, -// }, -// call{ -// Sub: model.PackageOrArtifactInput{ -// Artifact: a1, -// }, -// Vuln: model.VulnerabilityInput{ -// Osv: o1, -// }, -// In: &model.VexStatementInputSpec{ -// VexJustification: "test justification", -// KnownSince: time.Unix(1e9, 0), -// }, -// }, -// }, -// Query: &model.CertifyVEXStatementSpec{ -// Subject: &model.PackageOrArtifactSpec{ -// Package: &model.PkgSpec{ -// Version: ptrfrom.String(""), -// }, -// }, -// }, -// ExpVEX: []*model.CertifyVEXStatement{ -// &model.CertifyVEXStatement{ -// Subject: p1out, -// Vulnerability: o1out, -// VexJustification: "test justification", -// KnownSince: time.Unix(1e9, 0), -// }, -// }, -// }, -// { -// Name: "Query on Artifact", -// InPkg: []*model.PkgInputSpec{p1}, -// InArt: []*model.ArtifactInputSpec{a1, a2}, -// InOsv: []*model.OSVInputSpec{o1}, -// Calls: []call{ -// call{ -// Sub: model.PackageOrArtifactInput{ -// Package: p1, -// }, -// Vuln: model.VulnerabilityInput{ -// Osv: o1, -// }, -// In: &model.VexStatementInputSpec{ -// VexJustification: "test justification", -// KnownSince: time.Unix(1e9, 0), -// }, -// }, -// call{ -// Sub: model.PackageOrArtifactInput{ -// Artifact: a1, -// }, -// Vuln: model.VulnerabilityInput{ -// Osv: o1, -// }, -// In: &model.VexStatementInputSpec{ -// VexJustification: "test justification", -// KnownSince: time.Unix(1e9, 0), -// }, -// }, -// call{ -// Sub: model.PackageOrArtifactInput{ -// Artifact: a2, -// }, -// Vuln: model.VulnerabilityInput{ -// Osv: o1, -// }, -// In: &model.VexStatementInputSpec{ -// VexJustification: "test justification", -// KnownSince: time.Unix(1e9, 0), -// }, -// }, -// }, -// Query: &model.CertifyVEXStatementSpec{ -// Subject: &model.PackageOrArtifactSpec{ -// Artifact: &model.ArtifactSpec{ -// Algorithm: ptrfrom.String("sha256"), -// }, -// }, -// }, -// ExpVEX: []*model.CertifyVEXStatement{ -// &model.CertifyVEXStatement{ -// Subject: a1out, -// Vulnerability: o1out, -// VexJustification: "test justification", -// KnownSince: time.Unix(1e9, 0), -// }, -// }, -// }, -// { -// Name: "Query on Vuln", -// InPkg: []*model.PkgInputSpec{p1}, -// InOsv: []*model.OSVInputSpec{o1, o2}, -// InCve: []*model.CVEInputSpec{c1}, -// Calls: []call{ -// call{ -// Sub: model.PackageOrArtifactInput{ -// Package: p1, -// }, -// Vuln: model.VulnerabilityInput{ -// Osv: o1, -// }, -// In: &model.VexStatementInputSpec{ -// VexJustification: "test justification", -// KnownSince: time.Unix(1e9, 0), -// }, -// }, -// call{ -// Sub: model.PackageOrArtifactInput{ -// Package: p1, -// }, -// Vuln: model.VulnerabilityInput{ -// Osv: o2, -// }, -// In: &model.VexStatementInputSpec{ -// VexJustification: "test justification", -// KnownSince: time.Unix(1e9, 0), -// }, -// }, -// call{ -// Sub: model.PackageOrArtifactInput{ -// Package: p1, -// }, -// Vuln: model.VulnerabilityInput{ -// Cve: c1, -// }, -// In: &model.VexStatementInputSpec{ -// VexJustification: "test justification", -// KnownSince: time.Unix(1e9, 0), -// }, -// }, -// }, -// Query: &model.CertifyVEXStatementSpec{ -// Vulnerability: &model.VulnerabilitySpec{ -// Osv: &model.OSVSpec{ -// OsvID: ptrfrom.String("CVE-2014-8140"), -// }, -// }, -// }, -// ExpVEX: []*model.CertifyVEXStatement{ -// &model.CertifyVEXStatement{ -// Subject: p1out, -// Vulnerability: o1out, -// VexJustification: "test justification", -// KnownSince: time.Unix(1e9, 0), -// }, -// }, -// }, -// { -// Name: "Query on Status", -// InPkg: []*model.PkgInputSpec{p1}, -// InOsv: []*model.OSVInputSpec{o1}, -// Calls: []call{ -// call{ -// Sub: model.PackageOrArtifactInput{ -// Package: p1, -// }, -// Vuln: model.VulnerabilityInput{ -// Osv: o1, -// }, -// In: &model.VexStatementInputSpec{ -// VexJustification: "test justification", -// KnownSince: time.Unix(1e9, 0), -// Status: "status one", -// }, -// }, -// call{ -// Sub: model.PackageOrArtifactInput{ -// Package: p1, -// }, -// Vuln: model.VulnerabilityInput{ -// Osv: o1, -// }, -// In: &model.VexStatementInputSpec{ -// VexJustification: "test justification", -// KnownSince: time.Unix(1e9, 0), -// Status: "status two", -// }, -// }, -// }, -// Query: &model.CertifyVEXStatementSpec{ -// Status: (*model.VexStatus)(ptrfrom.String("status one")), -// }, -// ExpVEX: []*model.CertifyVEXStatement{ -// &model.CertifyVEXStatement{ -// Subject: p1out, -// Vulnerability: o1out, -// VexJustification: "test justification", -// KnownSince: time.Unix(1e9, 0), -// Status: "status one", -// }, -// }, -// }, -// { -// Name: "Query on Statement", -// InPkg: []*model.PkgInputSpec{p1}, -// InOsv: []*model.OSVInputSpec{o1}, -// Calls: []call{ -// call{ -// Sub: model.PackageOrArtifactInput{ -// Package: p1, -// }, -// Vuln: model.VulnerabilityInput{ -// Osv: o1, -// }, -// In: &model.VexStatementInputSpec{ -// VexJustification: "test justification", -// KnownSince: time.Unix(1e9, 0), -// Statement: "statement one", -// }, -// }, -// call{ -// Sub: model.PackageOrArtifactInput{ -// Package: p1, -// }, -// Vuln: model.VulnerabilityInput{ -// Osv: o1, -// }, -// In: &model.VexStatementInputSpec{ -// VexJustification: "test justification", -// KnownSince: time.Unix(1e9, 0), -// Statement: "statement two", -// }, -// }, -// }, -// Query: &model.CertifyVEXStatementSpec{ -// Statement: ptrfrom.String("statement two"), -// }, -// ExpVEX: []*model.CertifyVEXStatement{ -// &model.CertifyVEXStatement{ -// Subject: p1out, -// Vulnerability: o1out, -// VexJustification: "test justification", -// KnownSince: time.Unix(1e9, 0), -// Statement: "statement two", -// }, -// }, -// }, -// { -// Name: "Query on KnownSince", -// InPkg: []*model.PkgInputSpec{p1}, -// InOsv: []*model.OSVInputSpec{o1}, -// Calls: []call{ -// call{ -// Sub: model.PackageOrArtifactInput{ -// Package: p1, -// }, -// Vuln: model.VulnerabilityInput{ -// Osv: o1, -// }, -// In: &model.VexStatementInputSpec{ -// VexJustification: "test justification", -// KnownSince: time.Unix(1e9, 0), -// }, -// }, -// call{ -// Sub: model.PackageOrArtifactInput{ -// Package: p1, -// }, -// Vuln: model.VulnerabilityInput{ -// Osv: o1, -// }, -// In: &model.VexStatementInputSpec{ -// VexJustification: "test justification", -// KnownSince: testTime, -// }, -// }, -// }, -// Query: &model.CertifyVEXStatementSpec{ -// KnownSince: &testTime, -// }, -// ExpVEX: []*model.CertifyVEXStatement{ -// &model.CertifyVEXStatement{ -// Subject: p1out, -// Vulnerability: o1out, -// VexJustification: "test justification", -// KnownSince: testTime, -// }, -// }, -// }, -// { -// Name: "Query on ID", -// InPkg: []*model.PkgInputSpec{p1}, -// InOsv: []*model.OSVInputSpec{o1, o2}, -// Calls: []call{ -// call{ -// Sub: model.PackageOrArtifactInput{ -// Package: p1, -// }, -// Vuln: model.VulnerabilityInput{ -// Osv: o1, -// }, -// In: &model.VexStatementInputSpec{ -// VexJustification: "test justification", -// KnownSince: time.Unix(1e9, 0), -// }, -// }, -// call{ -// Sub: model.PackageOrArtifactInput{ -// Package: p1, -// }, -// Vuln: model.VulnerabilityInput{ -// Osv: o2, -// }, -// In: &model.VexStatementInputSpec{ -// VexJustification: "test justification", -// KnownSince: time.Unix(1e9, 0), -// }, -// }, -// }, -// Query: &model.CertifyVEXStatementSpec{ -// //ID: ptrfrom.String("17179869184"), -// ID: ptrfrom.String("0"), -// }, -// ExpVEX: []*model.CertifyVEXStatement{ -// &model.CertifyVEXStatement{ -// Subject: p1out, -// Vulnerability: o1out, -// VexJustification: "test justification", -// KnownSince: time.Unix(1e9, 0), -// }, -// }, -// }, -// { -// Name: "Query None", -// InPkg: []*model.PkgInputSpec{p1}, -// InOsv: []*model.OSVInputSpec{o1, o2}, -// InCve: []*model.CVEInputSpec{c1}, -// Calls: []call{ -// call{ -// Sub: model.PackageOrArtifactInput{ -// Package: p1, -// }, -// Vuln: model.VulnerabilityInput{ -// Osv: o1, -// }, -// In: &model.VexStatementInputSpec{ -// VexJustification: "test justification", -// KnownSince: time.Unix(1e9, 0), -// }, -// }, -// call{ -// Sub: model.PackageOrArtifactInput{ -// Package: p1, -// }, -// Vuln: model.VulnerabilityInput{ -// Osv: o2, -// }, -// In: &model.VexStatementInputSpec{ -// VexJustification: "test justification", -// KnownSince: time.Unix(1e9, 0), -// }, -// }, -// call{ -// Sub: model.PackageOrArtifactInput{ -// Package: p1, -// }, -// Vuln: model.VulnerabilityInput{ -// Cve: c1, -// }, -// In: &model.VexStatementInputSpec{ -// VexJustification: "test justification", -// KnownSince: time.Unix(1e9, 0), -// }, -// }, -// }, -// Query: &model.CertifyVEXStatementSpec{ -// Vulnerability: &model.VulnerabilitySpec{ -// Osv: &model.OSVSpec{ -// OsvID: ptrfrom.String("asdf"), -// }, -// }, -// }, -// ExpVEX: nil, -// }, -// { -// Name: "Query multiple", -// InPkg: []*model.PkgInputSpec{p1}, -// InOsv: []*model.OSVInputSpec{o1, o2}, -// InCve: []*model.CVEInputSpec{c1}, -// Calls: []call{ -// call{ -// Sub: model.PackageOrArtifactInput{ -// Package: p1, -// }, -// Vuln: model.VulnerabilityInput{ -// Osv: o1, -// }, -// In: &model.VexStatementInputSpec{ -// VexJustification: "test justification", -// KnownSince: time.Unix(1e9, 0), -// }, -// }, -// call{ -// Sub: model.PackageOrArtifactInput{ -// Package: p1, -// }, -// Vuln: model.VulnerabilityInput{ -// Osv: o2, -// }, -// In: &model.VexStatementInputSpec{ -// VexJustification: "test justification two", -// KnownSince: time.Unix(1e9, 0), -// }, -// }, -// call{ -// Sub: model.PackageOrArtifactInput{ -// Package: p1, -// }, -// Vuln: model.VulnerabilityInput{ -// Cve: c1, -// }, -// In: &model.VexStatementInputSpec{ -// VexJustification: "test justification two", -// KnownSince: time.Unix(1e9, 0), -// }, -// }, -// }, -// Query: &model.CertifyVEXStatementSpec{ -// VexJustification: (*model.VexJustification)(ptrfrom.String("test justification two")), -// }, -// ExpVEX: []*model.CertifyVEXStatement{ -// &model.CertifyVEXStatement{ -// Subject: p1out, -// Vulnerability: o2out, -// VexJustification: "test justification two", -// KnownSince: time.Unix(1e9, 0), -// }, -// &model.CertifyVEXStatement{ -// Subject: p1out, -// Vulnerability: c1out, -// VexJustification: "test justification two", -// KnownSince: time.Unix(1e9, 0), -// }, -// }, -// }, -// { -// Name: "Ingest noVuln", -// InPkg: []*model.PkgInputSpec{p1}, -// Calls: []call{ -// call{ -// Sub: model.PackageOrArtifactInput{ -// Package: p1, -// }, -// Vuln: model.VulnerabilityInput{ -// NoVuln: ptrfrom.Bool(true), -// }, -// In: &model.VexStatementInputSpec{ -// VexJustification: "test justification", -// KnownSince: time.Unix(1e9, 0), -// }, -// }, -// }, -// ExpIngestErr: true, -// }, -// { -// Name: "Ingest without sub", -// InOsv: []*model.OSVInputSpec{o1}, -// Calls: []call{ -// call{ -// Sub: model.PackageOrArtifactInput{ -// Package: p1, -// }, -// Vuln: model.VulnerabilityInput{ -// Osv: o1, -// }, -// In: &model.VexStatementInputSpec{ -// VexJustification: "test justification", -// KnownSince: time.Unix(1e9, 0), -// }, -// }, -// }, -// ExpIngestErr: true, -// }, -// { -// Name: "Ingest without vuln", -// InPkg: []*model.PkgInputSpec{p1}, -// Calls: []call{ -// call{ -// Sub: model.PackageOrArtifactInput{ -// Package: p1, -// }, -// Vuln: model.VulnerabilityInput{ -// Osv: o1, -// }, -// In: &model.VexStatementInputSpec{ -// VexJustification: "test justification", -// KnownSince: time.Unix(1e9, 0), -// }, -// }, -// }, -// ExpIngestErr: true, -// }, -// { -// Name: "Ingest double sub", -// InPkg: []*model.PkgInputSpec{p1}, -// InArt: []*model.ArtifactInputSpec{a1}, -// InOsv: []*model.OSVInputSpec{o1}, -// Calls: []call{ -// call{ -// Sub: model.PackageOrArtifactInput{ -// Package: p1, -// Artifact: a1, -// }, -// Vuln: model.VulnerabilityInput{ -// Osv: o1, -// }, -// In: &model.VexStatementInputSpec{ -// VexJustification: "test justification", -// KnownSince: time.Unix(1e9, 0), -// }, -// }, -// }, -// ExpIngestErr: true, -// }, -// { -// Name: "Ingest double vuln", -// InPkg: []*model.PkgInputSpec{p1}, -// InOsv: []*model.OSVInputSpec{o1}, -// InCve: []*model.CVEInputSpec{c1}, -// Calls: []call{ -// call{ -// Sub: model.PackageOrArtifactInput{ -// Package: p1, -// }, -// Vuln: model.VulnerabilityInput{ -// Osv: o1, -// Cve: c1, -// }, -// In: &model.VexStatementInputSpec{ -// VexJustification: "test justification", -// KnownSince: time.Unix(1e9, 0), -// }, -// }, -// }, -// ExpIngestErr: true, -// }, -// { -// Name: "Query double sub", -// InPkg: []*model.PkgInputSpec{p1}, -// InOsv: []*model.OSVInputSpec{o1}, -// Calls: []call{ -// call{ -// Sub: model.PackageOrArtifactInput{ -// Package: p1, -// }, -// Vuln: model.VulnerabilityInput{ -// Osv: o1, -// }, -// In: &model.VexStatementInputSpec{ -// VexJustification: "test justification", -// KnownSince: time.Unix(1e9, 0), -// }, -// }, -// }, -// Query: &model.CertifyVEXStatementSpec{ -// Subject: &model.PackageOrArtifactSpec{ -// Package: &model.PkgSpec{ -// Version: ptrfrom.String(""), -// }, -// Artifact: &model.ArtifactSpec{ -// Algorithm: ptrfrom.String("sha256"), -// }, -// }, -// }, -// ExpQueryErr: true, -// }, -// { -// Name: "Query double vuln", -// InPkg: []*model.PkgInputSpec{p1}, -// InOsv: []*model.OSVInputSpec{o1}, -// Calls: []call{ -// call{ -// Sub: model.PackageOrArtifactInput{ -// Package: p1, -// }, -// Vuln: model.VulnerabilityInput{ -// Osv: o1, -// }, -// In: &model.VexStatementInputSpec{ -// VexJustification: "test justification", -// KnownSince: time.Unix(1e9, 0), -// }, -// }, -// }, -// Query: &model.CertifyVEXStatementSpec{ -// Vulnerability: &model.VulnerabilitySpec{ -// Osv: &model.OSVSpec{ -// OsvID: ptrfrom.String("asdf"), -// }, -// Cve: &model.CVESpec{ -// CveID: ptrfrom.String("asdf"), -// }, -// }, -// }, -// ExpQueryErr: true, -// }, -// { -// Name: "Query no vuln", -// InPkg: []*model.PkgInputSpec{p1}, -// InOsv: []*model.OSVInputSpec{o1}, -// Calls: []call{ -// call{ -// Sub: model.PackageOrArtifactInput{ -// Package: p1, -// }, -// Vuln: model.VulnerabilityInput{ -// Osv: o1, -// }, -// In: &model.VexStatementInputSpec{ -// VexJustification: "test justification", -// KnownSince: time.Unix(1e9, 0), -// }, -// }, -// }, -// Query: &model.CertifyVEXStatementSpec{ -// Vulnerability: &model.VulnerabilitySpec{ -// NoVuln: ptrfrom.Bool(true), -// }, -// }, -// ExpQueryErr: true, -// }, -// { -// Name: "Query bad id", -// InPkg: []*model.PkgInputSpec{p1}, -// InOsv: []*model.OSVInputSpec{o1}, -// Calls: []call{ -// call{ -// Sub: model.PackageOrArtifactInput{ -// Package: p1, -// }, -// Vuln: model.VulnerabilityInput{ -// Osv: o1, -// }, -// In: &model.VexStatementInputSpec{ -// VexJustification: "test justification", -// KnownSince: time.Unix(1e9, 0), -// }, -// }, -// }, -// Query: &model.CertifyVEXStatementSpec{ -// ID: ptrfrom.String("asdf"), -// }, -// ExpQueryErr: true, -// }, -// } -// ignoreID := cmp.FilterPath(func(p cmp.Path) bool { -// return strings.Compare(".ID", p[len(p)-1].String()) == 0 -// }, cmp.Ignore()) -// ctx := s.Ctx -// for _, test := range tests { -// s.Run(test.Name, func() { -// t := s.T() -// b, err := GetBackend(s.Client) -// if err != nil { -// t.Fatalf("Could not instantiate testing backend: %v", err) -// } -// for _, p := range test.InPkg { -// if _, err := b.IngestPackage(ctx, *p); err != nil { -// t.Fatalf("Could not ingest package: %v", err) -// } -// } -// for _, a := range test.InArt { -// if _, err := b.IngestArtifact(ctx, a); err != nil { -// t.Fatalf("Could not ingest artifact: %a", err) -// } -// } -// for _, o := range test.InOsv { -// if _, err := b.IngestOsv(ctx, o); err != nil { -// t.Fatalf("Could not ingest osv: %v", err) -// } -// } -// for _, c := range test.InCve { -// if _, err := b.IngestCve(ctx, c); err != nil { -// t.Fatalf("Could not ingest cve: %v", err) -// } -// } -// for _, g := range test.InGhsa { -// if _, err := b.IngestGhsa(ctx, g); err != nil { -// t.Fatalf("Could not ingest ghsa: %a", err) -// } -// } -// ids := make([]string, len(test.Calls)) -// for i, o := range test.Calls { -// v, err := b.IngestVEXStatement(ctx, o.Sub, o.Vuln, *o.In) -// if (err != nil) != test.ExpIngestErr { -// t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) -// } -// if err != nil { -// return -// } -// ids[i] = v.ID -// } - -// if test.Query.ID != nil { -// idIdx, err := strconv.Atoi(*test.Query.ID) -// if err == nil { -// if idIdx >= len(ids) { -// s.T().Fatalf("ID index out of range, want: %d, got: %d", len(ids), idIdx) -// } -// test.Query.ID = ptrfrom.String(ids[idIdx]) -// } -// } - -// got, err := b.CertifyVEXStatement(ctx, test.Query) -// if (err != nil) != test.ExpQueryErr { -// t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) -// } -// if err != nil { -// return -// } -// if diff := cmp.Diff(test.ExpVEX, got, ignoreID); diff != "" { -// t.Errorf("Unexpected results. (-want +got):\n%s", diff) -// } -// }) -// } -// } - -//func (s *Suite) TestVEXNeighbors() { -// type call struct { -// Sub model.PackageOrArtifactInput -// Vuln model.VulnerabilityInput -// In *model.VexStatementInputSpec -// } -// tests := []struct { -// Name string -// InPkg []*model.PkgInputSpec -// InArt []*model.ArtifactInputSpec -// InOsv []*model.OSVInputSpec -// InCve []*model.CVEInputSpec -// InGhsa []*model.GHSAInputSpec -// Calls []call -// ExpNeighbors map[string][]string -// }{ -// { -// Name: "HappyPath", -// InPkg: []*model.PkgInputSpec{p1}, -// InOsv: []*model.OSVInputSpec{o1}, -// Calls: []call{ -// call{ -// Sub: model.PackageOrArtifactInput{ -// Package: p1, -// }, -// Vuln: model.VulnerabilityInput{ -// Osv: o1, -// }, -// In: &model.VexStatementInputSpec{ -// VexJustification: "test justification", -// KnownSince: time.Unix(1e9, 0), -// }, -// }, -// }, -// ExpNeighbors: map[string][]string{ -// "5": []string{"2", "7"}, // pkg version -> pkg name, vex -// "6": []string{"7"}, // Vuln -> vex -// "7": []string{"2", "6"}, // Vex -> pkg version, vuln -// }, -// }, -// { -// Name: "Two vex on same package", -// InPkg: []*model.PkgInputSpec{p1}, -// InOsv: []*model.OSVInputSpec{o1, o2}, -// Calls: []call{ -// call{ -// Sub: model.PackageOrArtifactInput{ -// Package: p1, -// }, -// Vuln: model.VulnerabilityInput{ -// Osv: o1, -// }, -// In: &model.VexStatementInputSpec{ -// VexJustification: "test justification", -// KnownSince: time.Unix(1e9, 0), -// }, -// }, -// call{ -// Sub: model.PackageOrArtifactInput{ -// Package: p1, -// }, -// Vuln: model.VulnerabilityInput{ -// Osv: o2, -// }, -// In: &model.VexStatementInputSpec{ -// VexJustification: "test justification", -// KnownSince: time.Unix(1e9, 0), -// }, -// }, -// }, -// ExpNeighbors: map[string][]string{ -// "5": []string{"2", "8", "9"}, // pkg version -> pkg name, vex1, vex2 -// "6": []string{"8"}, // Vuln1 -> vex1 -// "7": []string{"9"}, // Vuln2 -> vex2 -// "8": []string{"2", "6"}, // Vex1 -> pkg version, vuln1 -// "9": []string{"2", "7"}, // Vex2 -> pkg version, vuln2 -// }, -// }, -// } -// ctx := s.Ctx -// for _, test := range tests { -// s.Run(test.Name, func() { -// t := s.T() -// b, err := GetBackend(s.Client) -// if err != nil { -// t.Fatalf("Could not instantiate testing backend: %v", err) -// } -// for _, p := range test.InPkg { -// if _, err := b.IngestPackage(ctx, *p); err != nil { -// t.Fatalf("Could not ingest package: %v", err) -// } -// } -// for _, a := range test.InArt { -// if _, err := b.IngestArtifact(ctx, a); err != nil { -// t.Fatalf("Could not ingest artifact: %a", err) -// } -// } -// for _, o := range test.InOsv { -// if _, err := b.IngestOsv(ctx, o); err != nil { -// t.Fatalf("Could not ingest osv: %v", err) -// } -// } -// for _, c := range test.InCve { -// if _, err := b.IngestCve(ctx, c); err != nil { -// t.Fatalf("Could not ingest cve: %v", err) -// } -// } -// for _, g := range test.InGhsa { -// if _, err := b.IngestGhsa(ctx, g); err != nil { -// t.Fatalf("Could not ingest ghsa: %a", err) -// } -// } -// for _, o := range test.Calls { -// if _, err := b.IngestVEXStatement(ctx, o.Sub, o.Vuln, *o.In); err != nil { -// t.Fatalf("Could not ingest VEXStatement") -// } -// } -// for q, r := range test.ExpNeighbors { -// got, err := b.Neighbors(ctx, q, nil) -// if err != nil { -// t.Fatalf("Could not query neighbors: %s", err) -// } -// gotIDs := convNodes(got) -// slices.Sort(r) -// slices.Sort(gotIDs) -// if diff := cmp.Diff(r, gotIDs); diff != "" { -// t.Errorf("Unexpected results. (-want +got):\n%s", diff) -// } -// } -// }) -// } -//} diff --git a/pkg/assembler/backends/ent/backend/vulnEqual.go b/pkg/assembler/backends/ent/backend/vulnEqual.go index 54c83b0ae9..e3c9740016 100644 --- a/pkg/assembler/backends/ent/backend/vulnEqual.go +++ b/pkg/assembler/backends/ent/backend/vulnEqual.go @@ -61,7 +61,7 @@ func (b *EntBackend) VulnEqual(ctx context.Context, filter *model.VulnEqualSpec) return collect(results, toModelVulnEqual), nil } -func (b *EntBackend) IngestVulnEquals(ctx context.Context, vulnerabilities []*model.VulnerabilityInputSpec, otherVulnerabilities []*model.VulnerabilityInputSpec, vulnEquals []*model.VulnEqualInputSpec) ([]string, error) { +func (b *EntBackend) IngestVulnEquals(ctx context.Context, vulnerabilities []*model.IDorVulnerabilityInput, otherVulnerabilities []*model.IDorVulnerabilityInput, vulnEquals []*model.VulnEqualInputSpec) ([]string, error) { var ids []string for i, vulnEqual := range vulnEquals { ve, err := b.IngestVulnEqual(ctx, *vulnerabilities[i], *otherVulnerabilities[i], *vulnEqual) @@ -73,11 +73,11 @@ func (b *EntBackend) IngestVulnEquals(ctx context.Context, vulnerabilities []*mo return ids, nil } -func (b *EntBackend) IngestVulnEqual(ctx context.Context, vulnerability model.VulnerabilityInputSpec, otherVulnerability model.VulnerabilityInputSpec, vulnEqual model.VulnEqualInputSpec) (string, error) { +func (b *EntBackend) IngestVulnEqual(ctx context.Context, vulnerability model.IDorVulnerabilityInput, otherVulnerability model.IDorVulnerabilityInput, vulnEqual model.VulnEqualInputSpec) (string, error) { id, err := WithinTX(ctx, b.client, func(ctx context.Context) (*int, error) { tx := ent.TxFromContext(ctx) - return upsertVulnEquals(ctx, tx, vulnerability, otherVulnerability, vulnEqual) + return upsertVulnEquals(ctx, tx, *vulnerability.VulnerabilityInput, *otherVulnerability.VulnerabilityInput, vulnEqual) }) if err != nil { diff --git a/pkg/assembler/backends/ent/backend/vulnEqual_test.go b/pkg/assembler/backends/ent/backend/vulnEqual_test.go deleted file mode 100644 index f985d17c85..0000000000 --- a/pkg/assembler/backends/ent/backend/vulnEqual_test.go +++ /dev/null @@ -1,658 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build integration - -package backend - -import ( - "context" - "strconv" - "strings" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/internal/testing/testdata" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -func (s *Suite) TestVulnEqual() { - type call struct { - Vuln *model.VulnerabilityInputSpec - OtherVuln *model.VulnerabilityInputSpec - In *model.VulnEqualInputSpec - } - tests := []struct { - Name string - InVuln []*model.VulnerabilityInputSpec - Calls []call - Query *model.VulnEqualSpec - ExpVulnEqual []*model.VulnEqual - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InVuln: []*model.VulnerabilityInputSpec{testdata.O1, testdata.C1}, - Calls: []call{ - call{ - Vuln: testdata.O1, - OtherVuln: testdata.C1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.VulnEqualSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpVulnEqual: []*model.VulnEqual{ - &model.VulnEqual{ - Vulnerabilities: []*model.Vulnerability{ - &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C1out}, - }, - }, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest same twice", - InVuln: []*model.VulnerabilityInputSpec{testdata.O1, testdata.C1}, - Calls: []call{ - call{ - Vuln: testdata.O1, - OtherVuln: testdata.C1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - call{ - Vuln: testdata.O1, - OtherVuln: testdata.C1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.VulnEqualSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpVulnEqual: []*model.VulnEqual{ - &model.VulnEqual{ - Vulnerabilities: []*model.Vulnerability{ - &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C1out}, - }, - }, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Justification", - InVuln: []*model.VulnerabilityInputSpec{testdata.O1, testdata.C1}, - Calls: []call{ - call{ - Vuln: testdata.O1, - OtherVuln: testdata.C1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - call{ - Vuln: testdata.O1, - OtherVuln: testdata.C1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.VulnEqualSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpVulnEqual: []*model.VulnEqual{ - &model.VulnEqual{ - Vulnerabilities: []*model.Vulnerability{ - &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C1out}, - }, - }, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on OSV", - InVuln: []*model.VulnerabilityInputSpec{testdata.O1, testdata.O2, testdata.C1}, - Calls: []call{ - call{ - Vuln: testdata.O1, - OtherVuln: testdata.C1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - call{ - Vuln: testdata.O2, - OtherVuln: testdata.C1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.VulnEqualSpec{ - Vulnerabilities: []*model.VulnerabilitySpec{ - { - VulnerabilityID: ptrfrom.String("CVE-2022-26499"), - }, - }, - }, - ExpVulnEqual: []*model.VulnEqual{ - &model.VulnEqual{ - Vulnerabilities: []*model.Vulnerability{ - &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O2out}, - }, - &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C1out}, - }, - }, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on GHSA", - InVuln: []*model.VulnerabilityInputSpec{testdata.O1, testdata.C1, testdata.C2, testdata.G1}, - Calls: []call{ - call{ - Vuln: testdata.O1, - OtherVuln: testdata.C1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - call{ - Vuln: testdata.O1, - OtherVuln: testdata.C2, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - call{ - Vuln: testdata.O1, - OtherVuln: testdata.G1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.VulnEqualSpec{ - Vulnerabilities: []*model.VulnerabilitySpec{ - { - Type: ptrfrom.String("ghsa"), - }, - }, - }, - ExpVulnEqual: []*model.VulnEqual{ - &model.VulnEqual{ - Vulnerabilities: []*model.Vulnerability{ - &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - }, - Justification: "test justification", - }, - }, - }, - { - Name: "Query none", - InVuln: []*model.VulnerabilityInputSpec{testdata.O1, testdata.C1, testdata.C2, testdata.G1}, - Calls: []call{ - call{ - Vuln: testdata.O1, - OtherVuln: testdata.C1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - call{ - Vuln: testdata.O1, - OtherVuln: testdata.C2, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - call{ - Vuln: testdata.O1, - OtherVuln: testdata.G1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.VulnEqualSpec{ - Vulnerabilities: []*model.VulnerabilitySpec{ - { - VulnerabilityID: ptrfrom.String("AEV-2022-26499"), - }, - }, - }, - ExpVulnEqual: nil, - }, - { - Name: "Query multiple", - InVuln: []*model.VulnerabilityInputSpec{testdata.O1, testdata.C1, testdata.C2, testdata.G1}, - Calls: []call{ - call{ - Vuln: testdata.O1, - OtherVuln: testdata.C1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - call{ - Vuln: testdata.O1, - OtherVuln: testdata.C2, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - call{ - Vuln: testdata.O1, - OtherVuln: testdata.G1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.VulnEqualSpec{ - Vulnerabilities: []*model.VulnerabilitySpec{ - { - Type: ptrfrom.String("cve"), - }, - }, - }, - ExpVulnEqual: []*model.VulnEqual{ - &model.VulnEqual{ - Vulnerabilities: []*model.Vulnerability{ - &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C1out}, - }, - }, - Justification: "test justification", - }, - &model.VulnEqual{ - Vulnerabilities: []*model.Vulnerability{ - &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C2out}, - }, - }, - Justification: "test justification", - }, - }, - }, - { - Name: "Query ID", - InVuln: []*model.VulnerabilityInputSpec{testdata.O1, testdata.C1, testdata.C2, testdata.G1}, - Calls: []call{ - call{ - Vuln: testdata.O1, - OtherVuln: testdata.C1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - call{ - Vuln: testdata.O1, - OtherVuln: testdata.C2, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - call{ - Vuln: testdata.O1, - OtherVuln: testdata.G1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.VulnEqualSpec{ - ID: ptrfrom.String("0"), - }, - ExpVulnEqual: []*model.VulnEqual{ - &model.VulnEqual{ - Vulnerabilities: []*model.Vulnerability{ - &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C1out}, - }, - }, - Justification: "test justification", - }, - }, - }, - { - Name: "Query ID not found", - InVuln: []*model.VulnerabilityInputSpec{testdata.O1, testdata.C1, testdata.C2, testdata.G1}, - Calls: []call{ - call{ - Vuln: testdata.O1, - OtherVuln: testdata.C1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - call{ - Vuln: testdata.O1, - OtherVuln: testdata.C2, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - call{ - Vuln: testdata.O1, - OtherVuln: testdata.G1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.VulnEqualSpec{ - ID: ptrfrom.String("123456"), - }, - ExpVulnEqual: nil, - }, - { - Name: "Query Error", - Query: &model.VulnEqualSpec{ - Vulnerabilities: []*model.VulnerabilitySpec{ - { - ID: ptrfrom.String("6"), - }, - }, - }, - ExpQueryErr: false, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - ctx := context.Background() - for _, test := range tests { - s.Run(test.Name, func() { - t := s.T() - b, err := GetBackend(s.Client) - if err != nil { - t.Fatalf("GetBackend() error = %v", err) - } - - for _, g := range test.InVuln { - if _, err := b.IngestVulnerability(ctx, *g); err != nil { - t.Fatalf("Could not ingest vulnerability: %a", err) - } - } - recordIDs := make([]string, len(test.Calls)) - for i, o := range test.Calls { - ve, err := b.IngestVulnEqual(ctx, *o.Vuln, *o.OtherVuln, *o.In) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - recordIDs[i] = ve - } - - if test.Query.ID != nil { - idIdx, err := strconv.Atoi(*test.Query.ID) - if err == nil { - if idIdx < 0 || idIdx >= len(recordIDs) { - s.T().Logf("ID index out of range, want: %d, got: %d. So ID %d will be directly used to query.", len(recordIDs), idIdx, idIdx) - } else { - test.Query.ID = &recordIDs[idIdx] - } - } - } - - got, err := b.VulnEqual(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpVulnEqual, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func (s *Suite) TestIngestVulnEquals() { - type call struct { - Vulns []*model.VulnerabilityInputSpec - OtherVulns []*model.VulnerabilityInputSpec - Ins []*model.VulnEqualInputSpec - } - tests := []struct { - Name string - InVuln []*model.VulnerabilityInputSpec - Calls []call - Query *model.VulnEqualSpec - ExpVulnEqual []*model.VulnEqual - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InVuln: []*model.VulnerabilityInputSpec{o1, c1, o1, c2}, - Calls: []call{ - call{ - Vulns: []*model.VulnerabilityInputSpec{o1, o1}, - OtherVulns: []*model.VulnerabilityInputSpec{c1, c2}, - Ins: []*model.VulnEqualInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.VulnEqualSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpVulnEqual: []*model.VulnEqual{ - &model.VulnEqual{ - Vulnerabilities: []*model.Vulnerability{ - &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o1out}, - }, - &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out}, - }, - }, - Justification: "test justification", - }, - &model.VulnEqual{ - Vulnerabilities: []*model.Vulnerability{ - &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o1out}, - }, - &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c2out}, - }, - }, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest same twice", - InVuln: []*model.VulnerabilityInputSpec{o1, c1, o1, c1}, - Calls: []call{ - call{ - Vulns: []*model.VulnerabilityInputSpec{o1, o1}, - OtherVulns: []*model.VulnerabilityInputSpec{c1, c1}, - Ins: []*model.VulnEqualInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.VulnEqualSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpVulnEqual: []*model.VulnEqual{ - &model.VulnEqual{ - Vulnerabilities: []*model.Vulnerability{ - &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o1out}, - }, - &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out}, - }, - }, - Justification: "test justification", - }, - }, - }, - - { - Name: "Query on OSV", - InVuln: []*model.VulnerabilityInputSpec{o1, c1, o2, g2}, - Calls: []call{ - call{ - Vulns: []*model.VulnerabilityInputSpec{o1, o2}, - OtherVulns: []*model.VulnerabilityInputSpec{c1, g2}, - Ins: []*model.VulnEqualInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.VulnEqualSpec{ - Vulnerabilities: []*model.VulnerabilitySpec{ - { - VulnerabilityID: ptrfrom.String("GHSA-xrw3-wqph-3fxg"), - }, - }, - }, - ExpVulnEqual: []*model.VulnEqual{ - &model.VulnEqual{ - Vulnerabilities: []*model.Vulnerability{ - &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o2out}, - }, - &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{g2out}, - }, - }, - Justification: "test justification", - }, - }, - }, - } - ctx := context.Background() - for _, test := range tests { - s.Run(test.Name, func() { - t := s.T() - b, err := GetBackend(s.Client) - if err != nil { - t.Fatalf("GetBackend() error = %v", err) - } - - if _, err := b.IngestVulnerabilities(ctx, test.InVuln); err != nil { - t.Fatalf("Could not ingest vulnerability: %a", err) - } - for _, o := range test.Calls { - _, err := b.IngestVulnEquals(ctx, o.Vulns, o.OtherVulns, o.Ins) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.VulnEqual(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpVulnEqual, got, IngestPredicatesCmpOpts...); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} diff --git a/pkg/assembler/backends/ent/backend/vulnMetadata.go b/pkg/assembler/backends/ent/backend/vulnMetadata.go index 5ec9980fb3..19135e1755 100644 --- a/pkg/assembler/backends/ent/backend/vulnMetadata.go +++ b/pkg/assembler/backends/ent/backend/vulnMetadata.go @@ -50,9 +50,9 @@ func (b *EntBackend) VulnerabilityMetadata(ctx context.Context, filter *model.Vu return collect(records, toModelVulnerabilityMetadata), nil } -func (b *EntBackend) IngestVulnerabilityMetadata(ctx context.Context, vulnerability model.VulnerabilityInputSpec, vulnerabilityMetadata model.VulnerabilityMetadataInputSpec) (string, error) { +func (b *EntBackend) IngestVulnerabilityMetadata(ctx context.Context, vulnerability model.IDorVulnerabilityInput, vulnerabilityMetadata model.VulnerabilityMetadataInputSpec) (string, error) { recordID, err := WithinTX(ctx, b.client, func(ctx context.Context) (*int, error) { - return upsertVulnerabilityMetadata(ctx, ent.TxFromContext(ctx), vulnerability, vulnerabilityMetadata) + return upsertVulnerabilityMetadata(ctx, ent.TxFromContext(ctx), *vulnerability.VulnerabilityInput, vulnerabilityMetadata) }) if err != nil { return "", fmt.Errorf("failed to execute IngestVulnerabilityMetadata :: %s", err) @@ -61,7 +61,7 @@ func (b *EntBackend) IngestVulnerabilityMetadata(ctx context.Context, vulnerabil return strconv.Itoa(*recordID), nil } -func (b *EntBackend) IngestBulkVulnerabilityMetadata(ctx context.Context, vulnerabilities []*model.VulnerabilityInputSpec, vulnerabilityMetadataList []*model.VulnerabilityMetadataInputSpec) ([]string, error) { +func (b *EntBackend) IngestBulkVulnerabilityMetadata(ctx context.Context, vulnerabilities []*model.IDorVulnerabilityInput, vulnerabilityMetadataList []*model.VulnerabilityMetadataInputSpec) ([]string, error) { var results []string for i := range vulnerabilityMetadataList { hm, err := b.IngestVulnerabilityMetadata(ctx, *vulnerabilities[i], *vulnerabilityMetadataList[i]) diff --git a/pkg/assembler/backends/ent/backend/vulnMetadata_test.go b/pkg/assembler/backends/ent/backend/vulnMetadata_test.go deleted file mode 100644 index 13c7947c1b..0000000000 --- a/pkg/assembler/backends/ent/backend/vulnMetadata_test.go +++ /dev/null @@ -1,1082 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build integration - -package backend - -import ( - "strconv" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -var ( - greater model.Comparator = model.ComparatorGreater - greaterEqual model.Comparator = model.ComparatorGreaterEqual - less model.Comparator = model.ComparatorLess - lessEqual model.Comparator = model.ComparatorLessEqual - equal model.Comparator = model.ComparatorEqual -) - -var cvss2ScoreType model.VulnerabilityScoreType = model.VulnerabilityScoreTypeCVSSv2 - -func (s *Suite) TestIngestVulnMetadata() { - type call struct { - Vuln *model.VulnerabilityInputSpec - VulnMetadata *model.VulnerabilityMetadataInputSpec - } - - tests := []struct { - Name string - InVuln []*model.VulnerabilityInputSpec - Calls []call - ExpVuln []*model.VulnerabilityMetadata - Query *model.VulnerabilityMetadataSpec - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InVuln: []*model.VulnerabilityInputSpec{c1}, - Calls: []call{ - { - Vuln: c1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Collector: ptrfrom.String("test collector"), - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - ID: "1", - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Duplicate", - InVuln: []*model.VulnerabilityInputSpec{c1, c1}, - Calls: []call{ - { - Vuln: c1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - { - Vuln: c1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Collector: ptrfrom.String("test collector"), - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - ID: "1", - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Certify OSV", - InVuln: []*model.VulnerabilityInputSpec{o1}, - Calls: []call{ - { - Vuln: o1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Collector: ptrfrom.String("test collector"), - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Certify GHSA", - InVuln: []*model.VulnerabilityInputSpec{g1}, - Calls: []call{ - { - Vuln: g1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeEPSSv1, - ScoreValue: 0.95, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Collector: ptrfrom.String("test collector"), - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{g1out}, - }, - ScoreType: model.VulnerabilityScoreTypeEPSSv1, - ScoreValue: 0.95, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Query on GHSA", - InVuln: []*model.VulnerabilityInputSpec{g1}, - Calls: []call{ - { - Vuln: g1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeEPSSv2, - ScoreValue: 0.98, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Vulnerability: &model.VulnerabilitySpec{ - Type: ptrfrom.String("ghsa"), - VulnerabilityID: &g1.VulnerabilityID, - }, - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{g1out}, - }, - ScoreType: model.VulnerabilityScoreTypeEPSSv2, - ScoreValue: 0.98, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Query ID", - InVuln: []*model.VulnerabilityInputSpec{g1}, - Calls: []call{ - { - Vuln: g1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - ID: ptrfrom.String("0"), - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{g1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Query none", - InVuln: []*model.VulnerabilityInputSpec{g1}, - Calls: []call{ - { - Vuln: g1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Vulnerability: &model.VulnerabilitySpec{ - VulnerabilityID: ptrfrom.String("asdf"), - }, - }, - ExpVuln: nil, - }, - { - Name: "Query greater than", - InVuln: []*model.VulnerabilityInputSpec{c2, c1}, - Calls: []call{ - { - Vuln: c2, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - { - Vuln: c1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Comparator: &greater, - ScoreValue: ptrfrom.Float64(7.0), - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c2out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - { - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Query greater than - specific type", - InVuln: []*model.VulnerabilityInputSpec{c2, c1}, - Calls: []call{ - { - Vuln: c2, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - { - Vuln: c1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Comparator: &greater, - ScoreValue: ptrfrom.Float64(7.0), - ScoreType: &cvss2ScoreType, - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c2out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Query greater than or equal", - InVuln: []*model.VulnerabilityInputSpec{c2, c1, g1}, - Calls: []call{ - { - Vuln: c2, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - { - Vuln: c1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - { - Vuln: g1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 6.3, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Comparator: &greaterEqual, - ScoreValue: ptrfrom.Float64(7.9), - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c2out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - { - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Query less than", - InVuln: []*model.VulnerabilityInputSpec{c2, c1, g1}, - Calls: []call{ - { - Vuln: c2, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - { - Vuln: c1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - { - Vuln: g1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 6.3, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Comparator: &less, - ScoreValue: ptrfrom.Float64(6.5), - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{g1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 6.3, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Query less than or equal", - InVuln: []*model.VulnerabilityInputSpec{c2, c1, g1}, - Calls: []call{ - { - Vuln: c2, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - { - Vuln: c1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - { - Vuln: g1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 6.3, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Comparator: &lessEqual, - ScoreValue: ptrfrom.Float64(7.9), - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - { - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{g1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 6.3, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Query equal", - InVuln: []*model.VulnerabilityInputSpec{c2, c1, g1}, - Calls: []call{ - { - Vuln: c2, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - { - Vuln: c1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - { - Vuln: g1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 6.3, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Comparator: &equal, - ScoreValue: ptrfrom.Float64(7.9), - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Query without comparator", - InVuln: []*model.VulnerabilityInputSpec{c2, c1, g1}, - Calls: []call{ - { - Vuln: c2, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - { - Vuln: c1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - { - Vuln: g1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 6.3, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - ScoreValue: ptrfrom.Float64(7.9), - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Query all vulns - with novuln boolean omitted", - InVuln: []*model.VulnerabilityInputSpec{c2, c1, g1}, - Calls: []call{ - { - Vuln: c2, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - { - Vuln: c1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeEPSSv2, - ScoreValue: 0.96, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - { - Vuln: g1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 2.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Vulnerability: &model.VulnerabilitySpec{}, - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c2out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - { - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out}, - }, - ScoreType: model.VulnerabilityScoreTypeEPSSv2, - ScoreValue: 0.96, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - { - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{g1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 2.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Ingest without vuln", - Calls: []call{ - { - Vuln: &model.VulnerabilityInputSpec{}, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{}, - }, - }, - Query: &model.VulnerabilityMetadataSpec{}, - ExpIngestErr: true, - }, - } - ctx := s.Ctx - for _, test := range tests { - s.Run(test.Name, func() { - t := s.T() - b, err := GetBackend(s.Client) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, g := range test.InVuln { - if _, err := b.IngestVulnerability(ctx, *g); err != nil { - t.Fatalf("Could not ingest vulnerability: %a", err) - } - } - - ids := make([]string, len(test.Calls)) - for i, o := range test.Calls { - record, err := b.IngestVulnerabilityMetadata(ctx, *o.Vuln, *o.VulnMetadata) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - ids[i] = record - } - - if test.Query != nil { - if test.Query.ID != nil { - idIndex, err := strconv.Atoi(*test.Query.ID) - if err == nil && idIndex > -1 && idIndex < len(ids) { - test.Query.ID = ptrfrom.String(ids[idIndex]) - } - } - } - - got, err := b.VulnerabilityMetadata(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpVuln, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func (s *Suite) TestIngestVulnMetadatas() { - type call struct { - Vulns []*model.VulnerabilityInputSpec - VulnMetadatas []*model.VulnerabilityMetadataInputSpec - } - - tests := []struct { - Name string - InVuln []*model.VulnerabilityInputSpec - Calls []call - ExpVuln []*model.VulnerabilityMetadata - Query *model.VulnerabilityMetadataSpec - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InVuln: []*model.VulnerabilityInputSpec{c1, c2}, - Calls: []call{ - { - Vulns: []*model.VulnerabilityInputSpec{c1, c2}, - VulnMetadatas: []*model.VulnerabilityMetadataInputSpec{ - { - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - { - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Collector: ptrfrom.String("test collector"), - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - ID: "1", - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - { - ID: "10", - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c2out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Certify OSV", - InVuln: []*model.VulnerabilityInputSpec{o1, o2}, - Calls: []call{ - { - Vulns: []*model.VulnerabilityInputSpec{o1, o2}, - VulnMetadatas: []*model.VulnerabilityMetadataInputSpec{ - { - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - { - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Collector: ptrfrom.String("test collector"), - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - { - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o2out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Certify GHSA", - InVuln: []*model.VulnerabilityInputSpec{g1, g2}, - Calls: []call{ - { - Vulns: []*model.VulnerabilityInputSpec{g1, g2}, - VulnMetadatas: []*model.VulnerabilityMetadataInputSpec{ - { - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - { - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Collector: ptrfrom.String("test collector"), - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{g1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - { - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{g2out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Query on GHSA", - InVuln: []*model.VulnerabilityInputSpec{g1, g2}, - Calls: []call{ - { - Vulns: []*model.VulnerabilityInputSpec{g1, g2}, - VulnMetadatas: []*model.VulnerabilityMetadataInputSpec{ - { - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - { - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Vulnerability: &model.VulnerabilitySpec{ - VulnerabilityID: &g1.VulnerabilityID, - }, - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{g1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Query none", - InVuln: []*model.VulnerabilityInputSpec{g1, g2}, - Calls: []call{ - { - Vulns: []*model.VulnerabilityInputSpec{g1, g2}, - VulnMetadatas: []*model.VulnerabilityMetadataInputSpec{ - { - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - { - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Vulnerability: &model.VulnerabilitySpec{ - VulnerabilityID: ptrfrom.String("asdf"), - }, - }, - ExpVuln: nil, - }, - } - ctx := s.Ctx - for _, test := range tests { - s.Run(test.Name, func() { - t := s.T() - b, err := GetBackend(s.Client) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - if _, err := b.IngestVulnerabilities(ctx, test.InVuln); err != nil { - t.Fatalf("Could not ingest vulnerabilities: %a", err) - } - for _, o := range test.Calls { - _, err := b.IngestBulkVulnerabilityMetadata(ctx, o.Vulns, o.VulnMetadatas) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - - } - got, err := b.VulnerabilityMetadata(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpVuln, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} diff --git a/pkg/assembler/backends/ent/backend/vulnerability.go b/pkg/assembler/backends/ent/backend/vulnerability.go index 7265738ddb..be91b1a4b6 100644 --- a/pkg/assembler/backends/ent/backend/vulnerability.go +++ b/pkg/assembler/backends/ent/backend/vulnerability.go @@ -32,9 +32,9 @@ import ( const NoVuln = "novuln" -func (b *EntBackend) IngestVulnerability(ctx context.Context, vuln model.VulnerabilityInputSpec) (*model.VulnerabilityIDs, error) { +func (b *EntBackend) IngestVulnerability(ctx context.Context, vuln model.IDorVulnerabilityInput) (*model.VulnerabilityIDs, error) { id, err := WithinTX(ctx, b.client, func(ctx context.Context) (*model.VulnerabilityIDs, error) { - return upsertVulnerability(ctx, ent.TxFromContext(ctx), vuln) + return upsertVulnerability(ctx, ent.TxFromContext(ctx), *vuln.VulnerabilityInput) }) if err != nil { return nil, err @@ -43,7 +43,7 @@ func (b *EntBackend) IngestVulnerability(ctx context.Context, vuln model.Vulnera return id, nil } -func (b *EntBackend) IngestVulnerabilities(ctx context.Context, vulns []*model.VulnerabilityInputSpec) ([]*model.VulnerabilityIDs, error) { +func (b *EntBackend) IngestVulnerabilities(ctx context.Context, vulns []*model.IDorVulnerabilityInput) ([]*model.VulnerabilityIDs, error) { ids := make([]*model.VulnerabilityIDs, len(vulns)) for i, vul := range vulns { id, err := b.IngestVulnerability(ctx, *vul) diff --git a/pkg/assembler/backends/ent/backend/vulnerability_test.go b/pkg/assembler/backends/ent/backend/vulnerability_test.go deleted file mode 100644 index 4338eb45fc..0000000000 --- a/pkg/assembler/backends/ent/backend/vulnerability_test.go +++ /dev/null @@ -1,416 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build integration - -package backend - -import ( - "slices" - "strconv" - "strings" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -var c1 = &model.VulnerabilityInputSpec{ - Type: "cve", - VulnerabilityID: "CVE-2019-13110", -} - -var c1out = &model.VulnerabilityID{ - VulnerabilityID: "cve-2019-13110", -} - -var c2 = &model.VulnerabilityInputSpec{ - Type: "cve", - VulnerabilityID: "CVE-2014-8139", -} - -var c2out = &model.VulnerabilityID{ - VulnerabilityID: "cve-2014-8139", -} - -var c3 = &model.VulnerabilityInputSpec{ - Type: "CVE", - VulnerabilityID: "cVe-2014-8140", -} - -var c3out = &model.VulnerabilityID{ - VulnerabilityID: "cve-2014-8140", -} - -var g1 = &model.VulnerabilityInputSpec{ - Type: "GHSA", - VulnerabilityID: "GHSA-h45f-rjvw-2rv2", -} - -var g1out = &model.VulnerabilityID{ - VulnerabilityID: "ghsa-h45f-rjvw-2rv2", -} - -var g2 = &model.VulnerabilityInputSpec{ - Type: "ghsa", - VulnerabilityID: "GHSA-xrw3-wqph-3fxg", -} - -var g2out = &model.VulnerabilityID{ - VulnerabilityID: "ghsa-xrw3-wqph-3fxg", -} - -var g3 = &model.VulnerabilityInputSpec{ - Type: "ghsa", - VulnerabilityID: "GHSA-8v4j-7jgf-5rg9", -} - -var g3out = &model.VulnerabilityID{ - VulnerabilityID: "ghsa-8v4j-7jgf-5rg9", -} - -var o1 = &model.VulnerabilityInputSpec{ - Type: "OSV", - VulnerabilityID: "CVE-2014-8140", -} - -var o1out = &model.VulnerabilityID{ - VulnerabilityID: "cve-2014-8140", -} - -var o2 = &model.VulnerabilityInputSpec{ - Type: "osv", - VulnerabilityID: "CVE-2022-26499", -} - -var o2out = &model.VulnerabilityID{ - VulnerabilityID: "cve-2022-26499", -} - -var o3 = &model.VulnerabilityInputSpec{ - Type: "osv", - VulnerabilityID: "GHSA-h45f-rjvw-2rv2", -} - -var o3out = &model.VulnerabilityID{ - VulnerabilityID: "ghsa-h45f-rjvw-2rv2", -} - -var noVulnInput = &model.VulnerabilityInputSpec{ - Type: "noVuln", - VulnerabilityID: "", -} - -var noVulnOut = &model.VulnerabilityID{ - VulnerabilityID: "", -} - -func lessCve(a, b *model.Vulnerability) int { - return strings.Compare(a.VulnerabilityIDs[0].VulnerabilityID, - b.VulnerabilityIDs[0].VulnerabilityID) -} - -func (s *Suite) TestVulnerability() { - tests := []struct { - Name string - Ingests []*model.VulnerabilityInputSpec - ExpIngestErr bool - Query *model.VulnerabilitySpec - Exp []*model.Vulnerability - ExpQueryErr bool - }{ - { - Name: "HappyPath", - Ingests: []*model.VulnerabilityInputSpec{c1}, - Query: &model.VulnerabilitySpec{}, - Exp: []*model.Vulnerability{ - { - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out}, - }, - }, - }, - { - Name: "Multiple", - Ingests: []*model.VulnerabilityInputSpec{c1, c2}, - Query: &model.VulnerabilitySpec{}, - Exp: []*model.Vulnerability{ - { - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out, c2out}, - }, - }, - }, - { - Name: "Duplicates", - Ingests: []*model.VulnerabilityInputSpec{c1, c1, c1}, - Query: &model.VulnerabilitySpec{}, - Exp: []*model.Vulnerability{ - { - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out}, - }, - }, - }, - { - Name: "Query by type - cve", - Ingests: []*model.VulnerabilityInputSpec{c1, c2, c3, g1, o1}, - Query: &model.VulnerabilitySpec{ - Type: ptrfrom.String("cve"), - }, - Exp: []*model.Vulnerability{ - { - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out, c2out, c3out}, - }, - }, - }, - { - Name: "Query by type - ghsa", - Ingests: []*model.VulnerabilityInputSpec{c1, c2, c3, g2, g3, o1}, - Query: &model.VulnerabilitySpec{ - Type: ptrfrom.String("ghsa"), - }, - Exp: []*model.Vulnerability{ - { - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{g2out, g3out}, - }, - }, - }, - { - Name: "Query by type - osv", - Ingests: []*model.VulnerabilityInputSpec{c1, c2, c3, g3, o1, o2, o3}, - Query: &model.VulnerabilitySpec{ - Type: ptrfrom.String("osv"), - }, - Exp: []*model.Vulnerability{ - { - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o1out, o2out, o3out}, - }, - }, - }, - { - Name: "Query by type - noVuln", - Ingests: []*model.VulnerabilityInputSpec{noVulnInput}, - Query: &model.VulnerabilitySpec{ - Type: ptrfrom.String("noVuln"), - }, - Exp: []*model.Vulnerability{ - { - Type: "novuln", - VulnerabilityIDs: []*model.VulnerabilityID{noVulnOut}, - }, - }, - }, - { - Name: "Query by type - noVuln with boolean", - Ingests: []*model.VulnerabilityInputSpec{noVulnInput}, - Query: &model.VulnerabilitySpec{ - NoVuln: ptrfrom.Bool(true), - }, - Exp: []*model.Vulnerability{ - { - Type: "novuln", - VulnerabilityIDs: []*model.VulnerabilityID{noVulnOut}, - }, - }, - }, - { - Name: "Query by vulnID", - Ingests: []*model.VulnerabilityInputSpec{c1, c2, c3}, - Query: &model.VulnerabilitySpec{ - VulnerabilityID: ptrfrom.String("CVE-2014-8140"), - }, - Exp: []*model.Vulnerability{ - { - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c3out}, - }, - }, - }, - { - Name: "Query by vulnID - noVuln", - Ingests: []*model.VulnerabilityInputSpec{c1, c2, c3, noVulnInput}, - Query: &model.VulnerabilitySpec{ - Type: ptrfrom.String("noVuln"), - }, - Exp: []*model.Vulnerability{ - { - Type: "novuln", - VulnerabilityIDs: []*model.VulnerabilityID{noVulnOut}, - }, - }, - }, - { - Name: "Query by ID", - Ingests: []*model.VulnerabilityInputSpec{c1}, - Query: &model.VulnerabilitySpec{}, - Exp: []*model.Vulnerability{ - { - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out}, - }, - }, - }, - { - Name: "Query none", - Ingests: []*model.VulnerabilityInputSpec{c1, c2, c3}, - Query: &model.VulnerabilitySpec{ - Type: ptrfrom.String("ghsa"), - }, - Exp: []*model.Vulnerability{}, - }, - { - Name: "Query none ID", - Ingests: []*model.VulnerabilityInputSpec{c1, c2, c3}, - Query: &model.VulnerabilitySpec{ - ID: ptrfrom.String("12345"), - }, - Exp: nil, - }, - { - Name: "Query invalid ID", - Ingests: []*model.VulnerabilityInputSpec{c1, c2, c3}, - Query: &model.VulnerabilitySpec{ - ID: ptrfrom.String("asdf"), - }, - ExpQueryErr: true, - }, - } - - for _, test := range tests { - s.Run(test.Name, func() { - ctx := s.Ctx - t := s.T() - b, err := GetBackend(s.Client) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - - recordIDs := make([]string, len(test.Ingests)) - for i, inputSpec := range test.Ingests { - vulnID, err := b.IngestVulnerability(ctx, *inputSpec) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - recordIDs[i] = vulnID.VulnerabilityNodeID - } - - if test.Query.ID != nil { - idIdx, err := strconv.Atoi(*test.Query.ID) - if err == nil { - if idIdx >= len(recordIDs) { - s.T().Logf("ID index out of range, want: %d, got: %d. So ID %d will be directly used to query.", len(recordIDs), idIdx, idIdx) - } else { - realID := recordIDs[idIdx] - test.Query.ID = &realID - } - } - } - got, err := b.Vulnerabilities(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - slices.SortFunc(got, lessCve) - if diff := cmp.Diff(test.Exp, got, ignoreID, ignoreEmptySlices); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func (s *Suite) TestIngestVulnerabilities() { - tests := []struct { - name string - ingests []*model.VulnerabilityInputSpec - exp []*model.VulnerabilityIDs - }{{ - name: "Multiple", - ingests: []*model.VulnerabilityInputSpec{c1, c2, c3}, - exp: make([]*model.VulnerabilityIDs, 3), - }} - for _, test := range tests { - s.Run(test.name, func() { - ctx := s.Ctx - t := s.T() - b, err := GetBackend(s.Client) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - vulID, err := b.IngestVulnerabilities(ctx, test.ingests) - if err != nil { - t.Fatalf("ingest error: %v", err) - return - } - if diff := cmp.Diff(len(test.exp), len(vulID)); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -// This test is to traverse the other branches of the upsert, not covered by the happy path at the insertion, -// when the create fails due to the presence of the input in the store, and a where query is used in the error branch -func (s *Suite) TestVulnerabiltiesIngestSameTwice() { - - tests := []struct { - name string - vulnerabilityInputsSpec []*model.VulnerabilityInputSpec - }{{ - name: "IngestSameTwice", - vulnerabilityInputsSpec: []*model.VulnerabilityInputSpec{ - { - Type: "CVE", - VulnerabilityID: "CVE-2019-13110", - }, - { - Type: "CVE", - VulnerabilityID: "CVE-2019-13110", - }, - }, - }} - - ctx := s.Ctx - for _, tt := range tests { - s.Run(tt.name, func() { - t := s.T() - b, err := GetBackend(s.Client) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - - for _, bIn := range tt.vulnerabilityInputsSpec { - if _, err := b.IngestVulnerability(ctx, *bIn); err != nil { - t.Fatalf("Could not ingest vulnerabilty: %v err: %v", bIn, err) - } - } - items, err := b.Vulnerabilities(ctx, &model.VulnerabilitySpec{}) - if err != nil { - t.Fatalf("Error on load Vulnerabilities %v", err) - } - if len(items) == 2 { - t.Fatalf("Wrong ingestions, ingest same twice found two") - } - }) - } -} diff --git a/pkg/assembler/backends/helper/conversion.go b/pkg/assembler/backends/helper/conversion.go index bc2676484f..d846098e32 100644 --- a/pkg/assembler/backends/helper/conversion.go +++ b/pkg/assembler/backends/helper/conversion.go @@ -95,11 +95,11 @@ func ConvertBuilderInputSpecToBuilderSpec(input *model.BuilderInputSpec) *model. return &output } -func ConvertLicenseInputSpecToLicenseSpec(licenseInput *model.LicenseInputSpec) *model.LicenseSpec { +func ConvertLicenseInputSpecToLicenseSpec(licenseInput *model.IDorLicenseInput) *model.LicenseSpec { return &model.LicenseSpec{ - Name: &licenseInput.Name, - Inline: licenseInput.Inline, - ListVersion: licenseInput.ListVersion, + Name: &licenseInput.LicenseInput.Name, + Inline: licenseInput.LicenseInput.Inline, + ListVersion: licenseInput.LicenseInput.ListVersion, } } diff --git a/pkg/assembler/backends/keyvalue/artifact.go b/pkg/assembler/backends/keyvalue/artifact.go index 13c14c2f33..484b77fe5e 100644 --- a/pkg/assembler/backends/keyvalue/artifact.go +++ b/pkg/assembler/backends/keyvalue/artifact.go @@ -141,7 +141,7 @@ func (c *demoClient) artifactModelByID(ctx context.Context, id string) (*model.A // Ingest Artifacts -func (c *demoClient) IngestArtifacts(ctx context.Context, artifacts []*model.ArtifactInputSpec) ([]string, error) { +func (c *demoClient) IngestArtifacts(ctx context.Context, artifacts []*model.IDorArtifactInput) ([]string, error) { var modelArtifacts []string for _, art := range artifacts { modelArt, err := c.IngestArtifact(ctx, art) @@ -153,13 +153,13 @@ func (c *demoClient) IngestArtifacts(ctx context.Context, artifacts []*model.Art return modelArtifacts, nil } -func (c *demoClient) IngestArtifact(ctx context.Context, artifact *model.ArtifactInputSpec) (string, error) { +func (c *demoClient) IngestArtifact(ctx context.Context, artifact *model.IDorArtifactInput) (string, error) { return c.ingestArtifact(ctx, artifact, true) } -func (c *demoClient) ingestArtifact(ctx context.Context, artifact *model.ArtifactInputSpec, readOnly bool) (string, error) { - algorithm := strings.ToLower(artifact.Algorithm) - digest := strings.ToLower(artifact.Digest) +func (c *demoClient) ingestArtifact(ctx context.Context, artifact *model.IDorArtifactInput, readOnly bool) (string, error) { + algorithm := strings.ToLower(artifact.ArtifactInput.Algorithm) + digest := strings.ToLower(artifact.ArtifactInput.Digest) inA := &artStruct{ Algorithm: algorithm, @@ -305,3 +305,20 @@ func (c *demoClient) buildArtifactResponse(ctx context.Context, ID string, filte return art, nil } + +// returnFoundArtifact return the node by first searching via ID. If the ID is not specified, it defaults to searching via inputspec +func (c *demoClient) returnFoundArtifact(ctx context.Context, artIDorInput *model.IDorArtifactInput) (*artStruct, error) { + if artIDorInput.ArtifactID != nil { + foundArtStruct, err := byIDkv[*artStruct](ctx, *artIDorInput.ArtifactID, c) + if err != nil { + return nil, gqlerror.Errorf("failed to return artStruct node by ID with error: %v", err) + } + return foundArtStruct, nil + } else { + foundArtStruct, err := c.artifactByInput(ctx, artIDorInput.ArtifactInput) + if err != nil { + return nil, gqlerror.Errorf("failed to artifactByInput with error: %v", err) + } + return foundArtStruct, nil + } +} diff --git a/pkg/assembler/backends/keyvalue/artifact_test.go b/pkg/assembler/backends/keyvalue/artifact_test.go deleted file mode 100644 index f1ab97e7b7..0000000000 --- a/pkg/assembler/backends/keyvalue/artifact_test.go +++ /dev/null @@ -1,493 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package keyvalue - -import ( - "context" - "reflect" - "strings" - "testing" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -func Test_artifactStruct_ID(t *testing.T) { - tests := []struct { - name string - id string - want string - }{{ - name: "getID", - id: "643", - want: "643", - }} - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - b := &artStruct{ - ThisID: tt.id, - } - if got := b.ID(); got != tt.want { - t.Errorf("builderStruct.ID() = %v, want %v", got, tt.want) - } - }) - } -} - -func Test_artifactStruct_Neighbors(t *testing.T) { - type fields struct { - id string - algorithm string - digest string - hashEquals []string - occurrences []string - hasSLSAs []string - vexLinks []string - badLinks []string - goodLinks []string - } - tests := []struct { - name string - fields fields - allowedEdges edgeMap - want []string - }{{ - name: "hashEquals", - fields: fields{ - hashEquals: []string{"343", "546"}, - }, - allowedEdges: edgeMap{model.EdgeArtifactHashEqual: true}, - want: []string{"343", "546"}, - }, { - name: "occurrences", - fields: fields{ - occurrences: []string{"2324", "1234"}, - }, - allowedEdges: edgeMap{model.EdgeArtifactIsOccurrence: true}, - want: []string{"2324", "1234"}, - }, { - name: "hasSLSAs", - fields: fields{ - hasSLSAs: []string{"445", "1232244"}, - }, - allowedEdges: edgeMap{model.EdgeArtifactHasSlsa: true}, - want: []string{"445", "1232244"}, - }, { - name: "vexLinks", - fields: fields{ - vexLinks: []string{"987", "9876"}, - }, - allowedEdges: edgeMap{model.EdgeArtifactCertifyVexStatement: true}, - want: []string{"987", "9876"}, - }, { - name: "badLinks", - fields: fields{ - badLinks: []string{"5322", "544"}, - }, - allowedEdges: edgeMap{model.EdgeArtifactCertifyBad: true}, - want: []string{"5322", "544"}, - }, { - name: "goodLinks", - fields: fields{ - goodLinks: []string{"25468", "1458"}, - }, - allowedEdges: edgeMap{model.EdgeArtifactCertifyGood: true}, - want: []string{"25468", "1458"}, - }} - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - a := &artStruct{ - ThisID: tt.fields.id, - Algorithm: tt.fields.algorithm, - Digest: tt.fields.digest, - HashEquals: tt.fields.hashEquals, - Occurrences: tt.fields.occurrences, - HasSLSAs: tt.fields.hasSLSAs, - VexLinks: tt.fields.vexLinks, - BadLinks: tt.fields.badLinks, - GoodLinks: tt.fields.goodLinks, - } - if got := a.Neighbors(tt.allowedEdges); !reflect.DeepEqual(got, tt.want) { - t.Errorf("builderStruct.Neighbors() = %v, want %v", got, tt.want) - } - }) - } -} - -func Test_artifactStruct_BuildModelNode(t *testing.T) { - type fields struct { - id string - algorithm string - digest string - } - tests := []struct { - name string - fields fields - want model.Node - wantErr bool - }{{ - name: "sha256", - fields: fields{ - id: "43", - algorithm: strings.ToLower("sha256"), - digest: strings.ToLower("6bbb0da1891646e58eb3e6a63af3a6fc3c8eb5a0d44824cba581d2e14a0450cf"), - }, - want: &model.Artifact{ - ID: "43", - Algorithm: strings.ToLower("sha256"), - Digest: strings.ToLower("6bbb0da1891646e58eb3e6a63af3a6fc3c8eb5a0d44824cba581d2e14a0450cf"), - }, - wantErr: false, - }, { - name: "sha1", - fields: fields{ - id: "53", - algorithm: strings.ToLower("sha1"), - digest: strings.ToLower("7A8F47318E4676DACB0142AFA0B83029CD7BEFD9"), - }, - want: &model.Artifact{ - ID: "53", - Algorithm: strings.ToLower("sha1"), - Digest: strings.ToLower("7a8f47318e4676dacb0142afa0b83029cd7befd9"), - }, - wantErr: false, - }, { - name: "sha512", - fields: fields{ - id: "63", - algorithm: strings.ToLower("sha512"), - digest: strings.ToLower("374AB8F711235830769AA5F0B31CE9B72C5670074B34CB302CDAFE3B606233EE92EE01E298E5701F15CC7087714CD9ABD7DDB838A6E1206B3642DE16D9FC9DD7"), - }, - want: &model.Artifact{ - ID: "63", - Algorithm: strings.ToLower("sha512"), - Digest: strings.ToLower("374ab8f711235830769aa5f0b31ce9b72c5670074b34cb302cdafe3b606233ee92ee01e298e5701f15cc7087714cd9abd7ddb838a6e1206b3642de16d9fc9dd7"), - }, - wantErr: false, - }} - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - c, _ := getBackend(context.Background(), nil) - a := &artStruct{ - ThisID: tt.fields.id, - Algorithm: tt.fields.algorithm, - Digest: tt.fields.digest, - } - b := c.(*demoClient) - got, err := a.BuildModelNode(context.Background(), b) - if (err != nil) != tt.wantErr { - t.Errorf("artStruct.BuildModelNode() error = %v, wantErr %v", err, tt.wantErr) - return - } - if diff := cmp.Diff(tt.want, got); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func Test_demoClient_IngestArtifacts(t *testing.T) { - ctx := context.Background() - tests := []struct { - name string - artifactInputs []*model.ArtifactInputSpec - wantErr bool - }{{ - name: "sha256", - artifactInputs: []*model.ArtifactInputSpec{{ - Algorithm: "sha256", - Digest: "6bbb0da1891646e58eb3e6a63af3a6fc3c8eb5a0d44824cba581d2e14a0450cf", - }, { - Algorithm: "sha1", - Digest: "7a8f47318e4676dacb0142afa0b83029cd7befd9", - }, { - Algorithm: "sha512", - Digest: "374ab8f711235830769aa5f0b31ce9b72c5670074b34cb302cdafe3b606233ee92ee01e298e5701f15cc7087714cd9abd7ddb838a6e1206b3642de16d9fc9dd7", - }}, - wantErr: false, - }} - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - c, _ := getBackend(ctx, nil) - _, err := c.IngestArtifacts(ctx, tt.artifactInputs) - if (err != nil) != tt.wantErr { - t.Errorf("demoClient.IngestArtifact() error = %v, wantErr %v", err, tt.wantErr) - return - } - }) - } -} - -func Test_demoClient_IngestArtifact(t *testing.T) { - ctx := context.Background() - tests := []struct { - name string - artifactInput *model.ArtifactInputSpec - wantErr bool - }{{ - name: "sha256", - artifactInput: &model.ArtifactInputSpec{ - Algorithm: "sha256", - Digest: "6bbb0da1891646e58eb3e6a63af3a6fc3c8eb5a0d44824cba581d2e14a0450cf", - }, - wantErr: false, - }, { - name: "sha1", - artifactInput: &model.ArtifactInputSpec{ - Algorithm: "sha1", - Digest: "7A8F47318E4676DACB0142AFA0B83029CD7BEFD9", - }, - wantErr: false, - }, { - name: "sha512", - artifactInput: &model.ArtifactInputSpec{ - Algorithm: "sha512", - Digest: "374AB8F711235830769AA5F0B31CE9B72C5670074B34CB302CDAFE3B606233EE92EE01E298E5701F15CC7087714CD9ABD7DDB838A6E1206B3642DE16D9FC9DD7", - }, - wantErr: false, - }} - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - c, _ := getBackend(ctx, nil) - - _, err := c.IngestArtifact(ctx, tt.artifactInput) - if (err != nil) != tt.wantErr { - t.Errorf("demoClient.IngestArtifact() error = %v, wantErr %v", err, tt.wantErr) - return - } - }) - } -} - -func Test_demoClient_Artifacts(t *testing.T) { - ctx := context.Background() - tests := []struct { - name string - artifactInput *model.ArtifactInputSpec - artifactSpec *model.ArtifactSpec - idInFilter bool - want []*model.Artifact - wantErr bool - }{{ - name: "sha256", - artifactInput: &model.ArtifactInputSpec{ - Algorithm: "sha256", - Digest: "6bbb0da1891646e58eb3e6a63af3a6fc3c8eb5a0d44824cba581d2e14a0450cf", - }, - artifactSpec: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha256"), - Digest: ptrfrom.String("6bbb0da1891646e58eb3e6a63af3a6fc3c8eb5a0d44824cba581d2e14a0450cf"), - }, - want: []*model.Artifact{{ - Algorithm: "sha256", - Digest: "6bbb0da1891646e58eb3e6a63af3a6fc3c8eb5a0d44824cba581d2e14a0450cf", - }}, - wantErr: false, - }, { - name: "sha1", - artifactInput: &model.ArtifactInputSpec{ - Algorithm: "sha1", - Digest: "7A8F47318E4676DACB0142AFA0B83029CD7BEFD9", - }, - artifactSpec: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha1"), - Digest: ptrfrom.String("7A8F47318E4676DACB0142AFA0B83029CD7BEFD9"), - }, - want: []*model.Artifact{{ - Algorithm: "sha1", - Digest: "7a8f47318e4676dacb0142afa0b83029cd7befd9", - }}, - wantErr: false, - }, { - name: "sha512", - artifactInput: &model.ArtifactInputSpec{ - Algorithm: "sha512", - Digest: "374AB8F711235830769AA5F0B31CE9B72C5670074B34CB302CDAFE3B606233EE92EE01E298E5701F15CC7087714CD9ABD7DDB838A6E1206B3642DE16D9FC9DD7", - }, - artifactSpec: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha512"), - Digest: ptrfrom.String("374AB8F711235830769AA5F0B31CE9B72C5670074B34CB302CDAFE3B606233EE92EE01E298E5701F15CC7087714CD9ABD7DDB838A6E1206B3642DE16D9FC9DD7"), - }, - idInFilter: true, - want: []*model.Artifact{{ - Algorithm: "sha512", - Digest: "374ab8f711235830769aa5f0b31ce9b72c5670074b34cb302cdafe3b606233ee92ee01e298e5701f15cc7087714cd9abd7ddb838a6e1206b3642de16d9fc9dd7", - }}, - wantErr: false, - }} - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - c, _ := getBackend(ctx, nil) - ingestedArt, err := c.IngestArtifact(ctx, tt.artifactInput) - if (err != nil) != tt.wantErr { - t.Errorf("demoClient.IngestArtifact() error = %v, wantErr %v", err, tt.wantErr) - return - } - if tt.idInFilter { - tt.artifactSpec.ID = &ingestedArt - } - got, err := c.Artifacts(ctx, tt.artifactSpec) - if (err != nil) != tt.wantErr { - t.Errorf("demoClient.Artifacts() error = %v, wantErr %v", err, tt.wantErr) - return - } - if diff := cmp.Diff(tt.want, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func Test_demoClient_buildArtifactResponse(t *testing.T) { - ctx := context.Background() - tests := []struct { - name string - artifactInput *model.ArtifactInputSpec - artifactSpec *model.ArtifactSpec - idInFilter bool - want *model.Artifact - wantErr bool - }{{ - name: "sha256", - artifactInput: &model.ArtifactInputSpec{ - Algorithm: "sha256", - Digest: "6bbb0da1891646e58eb3e6a63af3a6fc3c8eb5a0d44824cba581d2e14a0450cf", - }, - artifactSpec: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha256"), - Digest: ptrfrom.String("6bbb0da1891646e58eb3e6a63af3a6fc3c8eb5a0d44824cba581d2e14a0450cf"), - }, - want: &model.Artifact{ - Algorithm: "sha256", - Digest: "6bbb0da1891646e58eb3e6a63af3a6fc3c8eb5a0d44824cba581d2e14a0450cf", - }, - wantErr: false, - }, { - name: "sha1", - artifactInput: &model.ArtifactInputSpec{ - Algorithm: "sha1", - Digest: "7A8F47318E4676DACB0142AFA0B83029CD7BEFD9", - }, - artifactSpec: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha1"), - Digest: ptrfrom.String("7A8F47318E4676DACB0142AFA0B83029CD7BEFD9"), - }, - want: &model.Artifact{ - Algorithm: "sha1", - Digest: "7a8f47318e4676dacb0142afa0b83029cd7befd9", - }, - wantErr: false, - }, { - name: "sha512", - artifactInput: &model.ArtifactInputSpec{ - Algorithm: "sha512", - Digest: "374AB8F711235830769AA5F0B31CE9B72C5670074B34CB302CDAFE3B606233EE92EE01E298E5701F15CC7087714CD9ABD7DDB838A6E1206B3642DE16D9FC9DD7", - }, - artifactSpec: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha512"), - Digest: ptrfrom.String("374AB8F711235830769AA5F0B31CE9B72C5670074B34CB302CDAFE3B606233EE92EE01E298E5701F15CC7087714CD9ABD7DDB838A6E1206B3642DE16D9FC9DD7"), - }, - idInFilter: true, - want: &model.Artifact{ - Algorithm: "sha512", - Digest: "374ab8f711235830769aa5f0b31ce9b72c5670074b34cb302cdafe3b606233ee92ee01e298e5701f15cc7087714cd9abd7ddb838a6e1206b3642de16d9fc9dd7", - }, - wantErr: false, - }} - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - c, _ := getBackend(ctx, nil) - art, err := c.IngestArtifact(ctx, tt.artifactInput) - if (err != nil) != tt.wantErr { - t.Errorf("demoClient.IngestArtifact() error = %v, wantErr %v", err, tt.wantErr) - return - } - if tt.idInFilter { - tt.artifactSpec.ID = &art - } - b := c.(*demoClient) - got, err := b.buildArtifactResponse(context.Background(), art, tt.artifactSpec) - if (err != nil) != tt.wantErr { - t.Errorf("demoClient.Artifacts() error = %v, wantErr %v", err, tt.wantErr) - return - } - if diff := cmp.Diff(tt.want, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func Test_demoClient_getArtifactIDFromInput(t *testing.T) { - ctx := context.Background() - tests := []struct { - name string - artifactInput *model.ArtifactInputSpec - wantErr bool - }{{ - name: "sha256", - artifactInput: &model.ArtifactInputSpec{ - Algorithm: "sha256", - Digest: "6bbb0da1891646e58eb3e6a63af3a6fc3c8eb5a0d44824cba581d2e14a0450cf", - }, - wantErr: false, - }, { - name: "sha1", - artifactInput: &model.ArtifactInputSpec{ - Algorithm: "sha1", - Digest: "7A8F47318E4676DACB0142AFA0B83029CD7BEFD9", - }, - wantErr: false, - }, { - name: "sha512", - artifactInput: &model.ArtifactInputSpec{ - Algorithm: "sha512", - Digest: "374AB8F711235830769AA5F0B31CE9B72C5670074B34CB302CDAFE3B606233EE92EE01E298E5701F15CC7087714CD9ABD7DDB838A6E1206B3642DE16D9FC9DD7", - }, - wantErr: false, - }} - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - c, _ := getBackend(ctx, nil) - art, err := c.IngestArtifact(ctx, tt.artifactInput) - if (err != nil) != tt.wantErr { - t.Errorf("demoClient.IngestArtifact() error = %v, wantErr %v", err, tt.wantErr) - return - } - b := c.(*demoClient) - got, err := b.artifactByInput(context.Background(), tt.artifactInput) - if (err != nil) != tt.wantErr { - t.Errorf("demoClient.Artifacts() error = %v, wantErr %v", err, tt.wantErr) - return - } - if diff := cmp.Diff(art, got.ThisID, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} diff --git a/pkg/assembler/backends/keyvalue/builder.go b/pkg/assembler/backends/keyvalue/builder.go index ab6db539b2..eece28bd06 100644 --- a/pkg/assembler/backends/keyvalue/builder.go +++ b/pkg/assembler/backends/keyvalue/builder.go @@ -62,7 +62,7 @@ func (c *demoClient) builderByInput(ctx context.Context, b *model.BuilderInputSp // Ingest Builders -func (c *demoClient) IngestBuilders(ctx context.Context, builders []*model.BuilderInputSpec) ([]string, error) { +func (c *demoClient) IngestBuilders(ctx context.Context, builders []*model.IDorBuilderInput) ([]string, error) { var modelBuilders []string for _, build := range builders { modelBuild, err := c.IngestBuilder(ctx, build) @@ -76,13 +76,13 @@ func (c *demoClient) IngestBuilders(ctx context.Context, builders []*model.Build // Ingest Builder -func (c *demoClient) IngestBuilder(ctx context.Context, builder *model.BuilderInputSpec) (string, error) { +func (c *demoClient) IngestBuilder(ctx context.Context, builder *model.IDorBuilderInput) (string, error) { return c.ingestBuilder(ctx, builder, true) } -func (c *demoClient) ingestBuilder(ctx context.Context, builder *model.BuilderInputSpec, readOnly bool) (string, error) { +func (c *demoClient) ingestBuilder(ctx context.Context, builder *model.IDorBuilderInput, readOnly bool) (string, error) { in := &builderStruct{ - URI: builder.URI, + URI: builder.BuilderInput.URI, } lock(&c.m, readOnly) @@ -179,3 +179,20 @@ func (c *demoClient) exactBuilder(ctx context.Context, filter *model.BuilderSpec } return nil, nil } + +// returnFoundBuilder return the node by first searching via ID. If the ID is not specified, it defaults to searching via inputspec +func (c *demoClient) returnFoundBuilder(ctx context.Context, buildIDorInput *model.IDorBuilderInput) (*builderStruct, error) { + if buildIDorInput.BuilderID != nil { + builderStruct, err := byIDkv[*builderStruct](ctx, *buildIDorInput.BuilderID, c) + if err != nil { + return nil, gqlerror.Errorf("failed to return builderStruct node by ID with error: %v", err) + } + return builderStruct, nil + } else { + builderStruct, err := c.builderByInput(ctx, buildIDorInput.BuilderInput) + if err != nil { + return nil, gqlerror.Errorf("failed to builderByInput with error: %v", err) + } + return builderStruct, nil + } +} diff --git a/pkg/assembler/backends/keyvalue/builder_test.go b/pkg/assembler/backends/keyvalue/builder_test.go deleted file mode 100644 index a3691b4d27..0000000000 --- a/pkg/assembler/backends/keyvalue/builder_test.go +++ /dev/null @@ -1,332 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package keyvalue - -import ( - "context" - "reflect" - "strings" - "testing" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -func Test_builderStruct_ID(t *testing.T) { - tests := []struct { - name string - id string - want string - }{{ - name: "getID", - id: "643", - want: "643", - }} - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - b := &builderStruct{ - ThisID: tt.id, - } - if got := b.ID(); got != tt.want { - t.Errorf("builderStruct.ID() = %v, want %v", got, tt.want) - } - }) - } -} - -func Test_builderStruct_Neighbors(t *testing.T) { - type fields struct { - id string - uri string - hasSLSAs []string - } - tests := []struct { - name string - fields fields - allowedEdges edgeMap - want []string - }{{ - name: "hasSLSAs", - fields: fields{ - hasSLSAs: []string{"445", "1232244"}, - }, - allowedEdges: edgeMap{model.EdgeBuilderHasSlsa: true}, - want: []string{"445", "1232244"}, - }} - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - b := &builderStruct{ - ThisID: tt.fields.id, - URI: tt.fields.uri, - HasSLSAs: tt.fields.hasSLSAs, - } - if got := b.Neighbors(tt.allowedEdges); !reflect.DeepEqual(got, tt.want) { - t.Errorf("builderStruct.Neighbors() = %v, want %v", got, tt.want) - } - }) - } -} - -func Test_builderStruct_BuildModelNode(t *testing.T) { - type fields struct { - id string - uri string - } - tests := []struct { - name string - fields fields - want model.Node - wantErr bool - }{{ - name: "HubHostedActions", - fields: fields{ - id: "43", - uri: "https://github.com/CreateFork/HubHostedActions@v1", - }, - want: &model.Builder{ - ID: "43", - URI: "https://github.com/CreateFork/HubHostedActions@v1", - }, - wantErr: false, - }, { - name: "chains", - fields: fields{ - id: "53", - uri: "https://tekton.dev/chains/v2", - }, - want: &model.Builder{ - ID: "53", - URI: "https://tekton.dev/chains/v2", - }, - wantErr: false, - }} - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - c, _ := getBackend(context.Background(), nil) - b := &builderStruct{ - ThisID: tt.fields.id, - URI: tt.fields.uri, - } - dc := c.(*demoClient) - got, err := b.BuildModelNode(context.Background(), dc) - if (err != nil) != tt.wantErr { - t.Errorf("builderStruct.BuildModelNode() error = %v, wantErr %v", err, tt.wantErr) - return - } - if diff := cmp.Diff(tt.want, got); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func Test_demoClient_IngestBuilder(t *testing.T) { - ctx := context.Background() - tests := []struct { - name string - builderInput *model.BuilderInputSpec - wantErr bool - }{ - { - name: "HubHostedActions", - builderInput: &model.BuilderInputSpec{ - URI: "https://github.com/CreateFork/HubHostedActions@v1", - }, - wantErr: false, - }, - { - name: "chains", - builderInput: &model.BuilderInputSpec{ - URI: "https://tekton.dev/chains/v2", - }, - wantErr: false, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - c, _ := getBackend(ctx, nil) - _, err := c.IngestBuilder(ctx, tt.builderInput) - if (err != nil) != tt.wantErr { - t.Errorf("demoClient.IngestBuilder() error = %v, wantErr %v", err, tt.wantErr) - } - }) - } -} - -func Test_demoClient_IngestBuilders(t *testing.T) { - ctx := context.Background() - tests := []struct { - name string - builderInputs []*model.BuilderInputSpec - wantErr bool - }{ - { - name: "HubHostedActions", - builderInputs: []*model.BuilderInputSpec{ - { - URI: "https://github.com/CreateFork/HubHostedActions@v1", - }, - { - URI: "https://tekton.dev/chains/v2", - }, - }, - wantErr: false, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - c, _ := getBackend(ctx, nil) - _, err := c.IngestBuilders(ctx, tt.builderInputs) - if (err != nil) != tt.wantErr { - t.Errorf("demoClient.IngestBuilder() error = %v, wantErr %v", err, tt.wantErr) - } - }) - } -} - -func Test_demoClient_Builders(t *testing.T) { - ctx := context.Background() - tests := []struct { - name string - builderInput *model.BuilderInputSpec - builderSpec *model.BuilderSpec - idInFilter bool - want []*model.Builder - wantErr bool - }{{ - name: "HubHostedActions", - builderInput: &model.BuilderInputSpec{ - URI: "https://github.com/CreateFork/HubHostedActions@v1", - }, - builderSpec: &model.BuilderSpec{ - URI: ptrfrom.String("https://github.com/CreateFork/HubHostedActions@v1"), - }, - want: []*model.Builder{{ - URI: "https://github.com/CreateFork/HubHostedActions@v1", - }}, - wantErr: false, - }, { - name: "chains", - builderInput: &model.BuilderInputSpec{ - URI: "https://tekton.dev/chains/v2", - }, - builderSpec: &model.BuilderSpec{ - URI: ptrfrom.String("https://tekton.dev/chains/v2"), - }, - idInFilter: true, - want: []*model.Builder{{ - URI: "https://tekton.dev/chains/v2", - }}, - wantErr: false, - }, { - name: "chains", - builderInput: &model.BuilderInputSpec{ - URI: "https://tekton.dev/chains/v2", - }, - builderSpec: &model.BuilderSpec{}, - want: []*model.Builder{{ - URI: "https://tekton.dev/chains/v2", - }}, - wantErr: false, - }} - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - c, _ := getBackend(ctx, nil) - ingestedBuilder, err := c.IngestBuilder(ctx, tt.builderInput) - if (err != nil) != tt.wantErr { - t.Errorf("demoClient.IngestBuilder() error = %v, wantErr %v", err, tt.wantErr) - return - } - if tt.idInFilter { - tt.builderSpec.ID = &ingestedBuilder - } - got, err := c.Builders(ctx, tt.builderSpec) - if (err != nil) != tt.wantErr { - t.Errorf("demoClient.Builders() error = %v, wantErr %v", err, tt.wantErr) - return - } - if diff := cmp.Diff(tt.want, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func Test_demoClient_exactBuilder(t *testing.T) { - ctx := context.Background() - tests := []struct { - name string - builderInput *model.BuilderInputSpec - builderSpec *model.BuilderSpec - idInFilter bool - want *builderStruct - wantErr bool - }{{ - name: "HubHostedActions", - builderInput: &model.BuilderInputSpec{ - URI: "https://github.com/CreateFork/HubHostedActions@v1", - }, - builderSpec: &model.BuilderSpec{ - URI: ptrfrom.String("https://github.com/CreateFork/HubHostedActions@v1"), - }, - want: &builderStruct{ - URI: "https://github.com/CreateFork/HubHostedActions@v1", - }, - wantErr: false, - }, { - name: "chains", - builderInput: &model.BuilderInputSpec{ - URI: "https://tekton.dev/chains/v2", - }, - builderSpec: &model.BuilderSpec{ - URI: ptrfrom.String("https://tekton.dev/chains/v2"), - }, - idInFilter: true, - want: &builderStruct{ - URI: "https://tekton.dev/chains/v2", - }, - wantErr: false, - }} - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - c, _ := getBackend(ctx, nil) - ingestedBuilder, err := c.IngestBuilder(ctx, tt.builderInput) - if (err != nil) != tt.wantErr { - t.Errorf("demoClient.IngestBuilder() error = %v, wantErr %v", err, tt.wantErr) - return - } - if tt.idInFilter { - tt.builderSpec.ID = &ingestedBuilder - } - dc := c.(*demoClient) - got, err := dc.exactBuilder(ctx, tt.builderSpec) - if (err != nil) != tt.wantErr { - t.Errorf("demoClient.exactBuilder() error = %v, wantErr %v", err, tt.wantErr) - return - } - tt.want.ThisID = ingestedBuilder - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("demoClient.exactBuilder() = %v, want %v", got, tt.want) - } - }) - } -} diff --git a/pkg/assembler/backends/keyvalue/certifyBad.go b/pkg/assembler/backends/keyvalue/certifyBad.go index f467e1a36a..64258da70f 100644 --- a/pkg/assembler/backends/keyvalue/certifyBad.go +++ b/pkg/assembler/backends/keyvalue/certifyBad.go @@ -120,31 +120,30 @@ func (c *demoClient) ingestCertifyBad(ctx context.Context, subject model.Package lock(&c.m, readOnly) defer unlock(&c.m, readOnly) - var foundPkgNameorVersionNode pkgNameOrVersion + var foundPkgNameOrVersionNode pkgNameOrVersion var foundArtStruct *artStruct var foundSrcName *srcNameNode if subject.Package != nil { var err error - foundPkgNameorVersionNode, err = c.getPackageNameOrVerFromInput(ctx, *subject.Package, *pkgMatchType) + in.PackageID, foundPkgNameOrVersionNode, err = c.returnFoundPkgBasedOnMatchType(ctx, subject.Package, pkgMatchType) if err != nil { return "", gqlerror.Errorf("%v :: %s", funcName, err) } - in.PackageID = foundPkgNameorVersionNode.ID() } else if subject.Artifact != nil { var err error - foundArtStruct, err = c.artifactByInput(ctx, subject.Artifact) + foundArtStruct, err = c.returnFoundArtifact(ctx, subject.Artifact) if err != nil { return "", gqlerror.Errorf("%v :: %s", funcName, err) } - in.ArtifactID = foundArtStruct.ThisID + in.ArtifactID = foundArtStruct.ID() } else { var err error - foundSrcName, err = c.getSourceNameFromInput(ctx, *subject.Source) + foundSrcName, err = c.returnFoundSource(ctx, subject.Source) if err != nil { return "", gqlerror.Errorf("%v :: %s", funcName, err) } - in.SourceID = foundSrcName.ThisID + in.SourceID = foundSrcName.ID() } out, err := byKeykv[*badLink](ctx, cbCol, in.Key(), c) @@ -166,8 +165,8 @@ func (c *demoClient) ingestCertifyBad(ctx context.Context, subject model.Package if err := c.addToIndex(ctx, cbCol, in); err != nil { return "", err } - if foundPkgNameorVersionNode != nil { - if err := foundPkgNameorVersionNode.setCertifyBadLinks(ctx, in.ThisID, c); err != nil { + if foundPkgNameOrVersionNode != nil { + if err := foundPkgNameOrVersionNode.setCertifyBadLinks(ctx, in.ThisID, c); err != nil { return "", err } } else if foundArtStruct != nil { diff --git a/pkg/assembler/backends/keyvalue/certifyBad_test.go b/pkg/assembler/backends/keyvalue/certifyBad_test.go deleted file mode 100644 index 31acb7cb6b..0000000000 --- a/pkg/assembler/backends/keyvalue/certifyBad_test.go +++ /dev/null @@ -1,986 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package keyvalue_test - -import ( - "context" - "slices" - "strings" - "testing" - "time" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/internal/testing/stablememmap" - "github.com/guacsec/guac/pkg/assembler/backends" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -func TestCertifyBad(t *testing.T) { - curTime := time.Now() - timeAfterOneSecond := curTime.Add(time.Second) - type call struct { - Sub model.PackageSourceOrArtifactInput - Match *model.MatchFlags - CB *model.CertifyBadInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - InArt []*model.ArtifactInputSpec - Calls []call - Query *model.CertifyBadSpec - ExpCB []*model.CertifyBad - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyBadSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpCB: []*model.CertifyBad{ - { - Subject: p1out, - Justification: "test justification", - }, - }, - }, - { - Name: "HappyPath All Version", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyBadSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpCB: []*model.CertifyBad{ - { - Subject: p1outName, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest same twice", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyBadSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpCB: []*model.CertifyBad{ - { - Subject: p1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Justification", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification one", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification two", - }, - }, - }, - Query: &model.CertifyBadSpec{ - Justification: ptrfrom.String("test justification one"), - }, - ExpCB: []*model.CertifyBad{ - { - Subject: p1out, - Justification: "test justification one", - }, - }, - }, - { - Name: "Query on KnownSince", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: &model.CertifyBadInputSpec{ - KnownSince: timeAfterOneSecond, - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: &model.CertifyBadInputSpec{ - KnownSince: curTime, - }, - }, - }, - Query: &model.CertifyBadSpec{ - KnownSince: &timeAfterOneSecond, - }, - ExpCB: []*model.CertifyBad{ - { - Subject: p1out, - KnownSince: timeAfterOneSecond, - }, - }, - }, - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{p1, p2}, - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s1, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyBadSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String("2.11.1"), - }, - }, - }, - ExpCB: []*model.CertifyBad{ - { - Subject: p2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Source", - InPkg: []*model.PkgInputSpec{p1}, - InSrc: []*model.SourceInputSpec{s1, s2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s1, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s2, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyBadSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Source: &model.SourceSpec{ - Name: ptrfrom.String("bobsrepo"), - }, - }, - }, - ExpCB: []*model.CertifyBad{ - { - Subject: s2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Artifact", - InSrc: []*model.SourceInputSpec{s1}, - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a1, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a2, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s1, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyBadSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha1"), - }, - }, - }, - ExpCB: []*model.CertifyBad{ - { - Subject: a2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query none", - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a1, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a2, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyBadSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("asdf"), - }, - }, - }, - ExpCB: nil, - }, - { - Name: "Query multiple", - InSrc: []*model.SourceInputSpec{s1, s2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s1, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s2, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyBadSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpCB: []*model.CertifyBad{ - { - Subject: s2out, - Justification: "test justification", - }, - { - Subject: s1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query Packages", - InPkg: []*model.PkgInputSpec{p1, p2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyBadSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String("2.11.1"), - }, - }, - }, - ExpCB: []*model.CertifyBad{ - { - Subject: p2out, - Justification: "test justification", - }, - { - Subject: p1outName, - Justification: "test justification", - }, - }, - }, - { - Name: "Query ID", - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a1, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a2, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyBadSpec{ - ID: ptrfrom.String("3"), - }, - ExpCB: []*model.CertifyBad{ - { - Subject: a1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest without subject", - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a1, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - }, - ExpIngestErr: true, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - ctx := context.Background() - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - for _, o := range test.Calls { - _, err := b.IngestCertifyBad(ctx, o.Sub, o.Match, *o.CB) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.CertifyBad(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpCB, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func TestIngestCertifyBads(t *testing.T) { - type call struct { - Sub model.PackageSourceOrArtifactInputs - Match *model.MatchFlags - CB []*model.CertifyBadInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - InArt []*model.ArtifactInputSpec - Calls []call - Query *model.CertifyBadSpec - ExpCB []*model.CertifyBad - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: []*model.CertifyBadInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.CertifyBadSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpCB: []*model.CertifyBad{ - { - Subject: p1out, - Justification: "test justification", - }, - }, - }, - { - Name: "HappyPath All Version", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - CB: []*model.CertifyBadInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.CertifyBadSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpCB: []*model.CertifyBad{ - { - Subject: p1outName, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest same twice", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1, p1}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: []*model.CertifyBadInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.CertifyBadSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpCB: []*model.CertifyBad{ - { - Subject: p1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{p1, p2}, - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1, p2}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: []*model.CertifyBadInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - { - Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{s1}, - }, - CB: []*model.CertifyBadInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.CertifyBadSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String("2.11.1"), - }, - }, - }, - ExpCB: []*model.CertifyBad{ - { - Subject: p2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Source", - InPkg: []*model.PkgInputSpec{p1}, - InSrc: []*model.SourceInputSpec{s1, s2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: []*model.CertifyBadInputSpec{ - { - Justification: "test justification", - }, - }, - }, - { - Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{s2, s2}, - }, - CB: []*model.CertifyBadInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.CertifyBadSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Source: &model.SourceSpec{ - Name: ptrfrom.String("bobsrepo"), - }, - }, - }, - ExpCB: []*model.CertifyBad{ - { - Subject: s2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Artifact", - InSrc: []*model.SourceInputSpec{s1}, - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Artifacts: []*model.ArtifactInputSpec{a1, a2}, - }, - CB: []*model.CertifyBadInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - { - Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{s1}, - }, - CB: []*model.CertifyBadInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.CertifyBadSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha1"), - }, - }, - }, - ExpCB: []*model.CertifyBad{ - { - Subject: a2out, - Justification: "test justification", - }, - }, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - ctx := context.Background() - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - for _, o := range test.Calls { - _, err := b.IngestCertifyBads(ctx, o.Sub, o.Match, o.CB) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.CertifyBad(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpCB, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func TestCertifyBadNeighbors(t *testing.T) { - type call struct { - Sub model.PackageSourceOrArtifactInput - Match *model.MatchFlags - CB *model.CertifyBadInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - InArt []*model.ArtifactInputSpec - Calls []call - ExpNeighbors map[string][]string - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - }, - ExpNeighbors: map[string][]string{ - "4": {"1", "5"}, // pkg version - "5": {"1"}, // certify bad - }, - }, - { - Name: "Pkg Name Src and Artifact", - InPkg: []*model.PkgInputSpec{p1}, - InSrc: []*model.SourceInputSpec{s1}, - InArt: []*model.ArtifactInputSpec{a1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s1, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a1, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - }, - ExpNeighbors: map[string][]string{ - "1": {"1"}, - "2": {"1", "1"}, - "3": {"1", "1", "9"}, // pkg name - "4": {"1"}, // pkg version - "5": {"5"}, - "6": {"5", "5"}, - "7": {"5", "10"}, // src name - "8": {"11"}, // art - "9": {"1"}, // cb 1 -> pkg name - "10": {"5"}, // cb 2 -> src name - "11": {"8"}, // cb 3 -> art - }, - }, - } - ctx := context.Background() - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - for _, o := range test.Calls { - if _, err := b.IngestCertifyBad(ctx, o.Sub, o.Match, *o.CB); err != nil { - t.Fatalf("Could not ingest CertifyBad: %v", err) - } - } - for q, r := range test.ExpNeighbors { - got, err := b.Neighbors(ctx, q, nil) - if err != nil { - t.Fatalf("Could not query neighbors: %s", err) - } - gotIDs := convNodes(got) - slices.Sort(r) - slices.Sort(gotIDs) - if diff := cmp.Diff(r, gotIDs); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - } - }) - } -} diff --git a/pkg/assembler/backends/keyvalue/certifyGood.go b/pkg/assembler/backends/keyvalue/certifyGood.go index 2776f1ecb1..e12c7ae2d6 100644 --- a/pkg/assembler/backends/keyvalue/certifyGood.go +++ b/pkg/assembler/backends/keyvalue/certifyGood.go @@ -119,31 +119,30 @@ func (c *demoClient) ingestCertifyGood(ctx context.Context, subject model.Packag lock(&c.m, readOnly) defer unlock(&c.m, readOnly) - var foundPkgNameorVersionNode pkgNameOrVersion - var foundArtStrct *artStruct + var foundPkgNameOrVersionNode pkgNameOrVersion + var foundArtStruct *artStruct var foundSrcName *srcNameNode if subject.Package != nil { var err error - foundPkgNameorVersionNode, err = c.getPackageNameOrVerFromInput(ctx, *subject.Package, *pkgMatchType) + in.PackageID, foundPkgNameOrVersionNode, err = c.returnFoundPkgBasedOnMatchType(ctx, subject.Package, pkgMatchType) if err != nil { return "", gqlerror.Errorf("%v :: %s", funcName, err) } - in.PackageID = foundPkgNameorVersionNode.ID() } else if subject.Artifact != nil { var err error - foundArtStrct, err = c.artifactByInput(ctx, subject.Artifact) + foundArtStruct, err = c.returnFoundArtifact(ctx, subject.Artifact) if err != nil { return "", gqlerror.Errorf("%v :: %s", funcName, err) } - in.ArtifactID = foundArtStrct.ThisID + in.ArtifactID = foundArtStruct.ID() } else { var err error - foundSrcName, err = c.getSourceNameFromInput(ctx, *subject.Source) + foundSrcName, err = c.returnFoundSource(ctx, subject.Source) if err != nil { return "", gqlerror.Errorf("%v :: %s", funcName, err) } - in.SourceID = foundSrcName.ThisID + in.SourceID = foundSrcName.ID() } out, err := byKeykv[*goodLink](ctx, cgCol, in.Key(), c) @@ -165,12 +164,12 @@ func (c *demoClient) ingestCertifyGood(ctx context.Context, subject model.Packag if err := c.addToIndex(ctx, cgCol, in); err != nil { return "", err } - if foundPkgNameorVersionNode != nil { - if err := foundPkgNameorVersionNode.setCertifyGoodLinks(ctx, in.ThisID, c); err != nil { + if foundPkgNameOrVersionNode != nil { + if err := foundPkgNameOrVersionNode.setCertifyGoodLinks(ctx, in.ThisID, c); err != nil { return "", err } - } else if foundArtStrct != nil { - if err := foundArtStrct.setCertifyGoodLinks(ctx, in.ThisID, c); err != nil { + } else if foundArtStruct != nil { + if err := foundArtStruct.setCertifyGoodLinks(ctx, in.ThisID, c); err != nil { return "", err } } else { diff --git a/pkg/assembler/backends/keyvalue/certifyGood_test.go b/pkg/assembler/backends/keyvalue/certifyGood_test.go deleted file mode 100644 index 0877b75891..0000000000 --- a/pkg/assembler/backends/keyvalue/certifyGood_test.go +++ /dev/null @@ -1,986 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package keyvalue_test - -import ( - "context" - "slices" - "strings" - "testing" - "time" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/internal/testing/stablememmap" - "github.com/guacsec/guac/pkg/assembler/backends" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -func TestCertifyGood(t *testing.T) { - curTime := time.Now() - timeAfterOneSecond := curTime.Add(time.Second) - type call struct { - Sub model.PackageSourceOrArtifactInput - Match *model.MatchFlags - CG *model.CertifyGoodInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - InArt []*model.ArtifactInputSpec - Calls []call - Query *model.CertifyGoodSpec - ExpCG []*model.CertifyGood - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyGoodSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpCG: []*model.CertifyGood{ - { - Subject: p1out, - Justification: "test justification", - }, - }, - }, - { - Name: "HappyPath All Version", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyGoodSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpCG: []*model.CertifyGood{ - { - Subject: p1outName, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest same twice", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyGoodSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpCG: []*model.CertifyGood{ - { - Subject: p1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Justification", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification one", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification two", - }, - }, - }, - Query: &model.CertifyGoodSpec{ - Justification: ptrfrom.String("test justification one"), - }, - ExpCG: []*model.CertifyGood{ - { - Subject: p1out, - Justification: "test justification one", - }, - }, - }, - { - Name: "Query on KnownSince", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: &model.CertifyGoodInputSpec{ - KnownSince: timeAfterOneSecond, - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: &model.CertifyGoodInputSpec{ - KnownSince: curTime, - }, - }, - }, - Query: &model.CertifyGoodSpec{ - KnownSince: &timeAfterOneSecond, - }, - ExpCG: []*model.CertifyGood{ - { - Subject: p1out, - KnownSince: timeAfterOneSecond, - }, - }, - }, - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{p1, p2}, - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s1, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyGoodSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String("2.11.1"), - }, - }, - }, - ExpCG: []*model.CertifyGood{ - { - Subject: p2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Source", - InPkg: []*model.PkgInputSpec{p1}, - InSrc: []*model.SourceInputSpec{s1, s2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s1, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s2, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyGoodSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Source: &model.SourceSpec{ - Name: ptrfrom.String("bobsrepo"), - }, - }, - }, - ExpCG: []*model.CertifyGood{ - { - Subject: s2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Artifact", - InSrc: []*model.SourceInputSpec{s1}, - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a1, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a2, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s1, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyGoodSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha1"), - }, - }, - }, - ExpCG: []*model.CertifyGood{ - { - Subject: a2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query none", - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a1, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a2, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyGoodSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("asdf"), - }, - }, - }, - ExpCG: nil, - }, - { - Name: "Query multiple", - InSrc: []*model.SourceInputSpec{s1, s2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s1, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s2, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyGoodSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpCG: []*model.CertifyGood{ - { - Subject: s2out, - Justification: "test justification", - }, - { - Subject: s1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query Packages", - InPkg: []*model.PkgInputSpec{p1, p2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyGoodSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String("2.11.1"), - }, - }, - }, - ExpCG: []*model.CertifyGood{ - { - Subject: p2out, - Justification: "test justification", - }, - { - Subject: p1outName, - Justification: "test justification", - }, - }, - }, - { - Name: "Query ID", - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a1, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a2, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyGoodSpec{ - ID: ptrfrom.String("3"), - }, - ExpCG: []*model.CertifyGood{ - { - Subject: a1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest without subject", - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a1, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - }, - ExpIngestErr: true, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - ctx := context.Background() - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - for _, o := range test.Calls { - _, err := b.IngestCertifyGood(ctx, o.Sub, o.Match, *o.CG) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.CertifyGood(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpCG, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func TestIngestCertifyGoods(t *testing.T) { - type call struct { - Sub model.PackageSourceOrArtifactInputs - Match *model.MatchFlags - CG []*model.CertifyGoodInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - InArt []*model.ArtifactInputSpec - Calls []call - Query *model.CertifyGoodSpec - ExpCG []*model.CertifyGood - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: []*model.CertifyGoodInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.CertifyGoodSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpCG: []*model.CertifyGood{ - { - Subject: p1out, - Justification: "test justification", - }, - }, - }, - { - Name: "HappyPath All Version", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - CG: []*model.CertifyGoodInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.CertifyGoodSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpCG: []*model.CertifyGood{ - { - Subject: p1outName, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest same twice", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1, p1}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: []*model.CertifyGoodInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.CertifyGoodSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpCG: []*model.CertifyGood{ - { - Subject: p1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{p1, p2}, - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1, p2}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: []*model.CertifyGoodInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - { - Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{s1}, - }, - CG: []*model.CertifyGoodInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.CertifyGoodSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String("2.11.1"), - }, - }, - }, - ExpCG: []*model.CertifyGood{ - { - Subject: p2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Source", - InPkg: []*model.PkgInputSpec{p1}, - InSrc: []*model.SourceInputSpec{s1, s2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: []*model.CertifyGoodInputSpec{ - { - Justification: "test justification", - }, - }, - }, - { - Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{s2, s2}, - }, - CG: []*model.CertifyGoodInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.CertifyGoodSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Source: &model.SourceSpec{ - Name: ptrfrom.String("bobsrepo"), - }, - }, - }, - ExpCG: []*model.CertifyGood{ - { - Subject: s2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Artifact", - InSrc: []*model.SourceInputSpec{s1}, - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Artifacts: []*model.ArtifactInputSpec{a1, a2}, - }, - CG: []*model.CertifyGoodInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - { - Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{s1}, - }, - CG: []*model.CertifyGoodInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.CertifyGoodSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha1"), - }, - }, - }, - ExpCG: []*model.CertifyGood{ - { - Subject: a2out, - Justification: "test justification", - }, - }, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - ctx := context.Background() - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - for _, o := range test.Calls { - _, err := b.IngestCertifyGoods(ctx, o.Sub, o.Match, o.CG) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.CertifyGood(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpCG, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func TestCertifyGoodNeighbors(t *testing.T) { - type call struct { - Sub model.PackageSourceOrArtifactInput - Match *model.MatchFlags - CG *model.CertifyGoodInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - InArt []*model.ArtifactInputSpec - Calls []call - ExpNeighbors map[string][]string - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - }, - ExpNeighbors: map[string][]string{ - "4": {"1", "5"}, // pkg version - "5": {"1"}, // certify good - }, - }, - { - Name: "Pkg Name Src and Artifact", - InPkg: []*model.PkgInputSpec{p1}, - InSrc: []*model.SourceInputSpec{s1}, - InArt: []*model.ArtifactInputSpec{a1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s1, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a1, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - }, - ExpNeighbors: map[string][]string{ - "1": {"1"}, - "2": {"1", "1"}, - "3": {"1", "1", "9"}, // pkg name - "4": {"1"}, // pkg version - "5": {"5"}, - "6": {"5", "5"}, - "7": {"5", "10"}, // src name - "8": {"11"}, // art - "9": {"1"}, // cb 1 -> pkg name - "10": {"5"}, // cb 2 -> src name - "11": {"8"}, // cb 3 -> art - }, - }, - } - ctx := context.Background() - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - for _, o := range test.Calls { - if _, err := b.IngestCertifyGood(ctx, o.Sub, o.Match, *o.CG); err != nil { - t.Fatalf("Could not ingest CertifyGood: %v", err) - } - } - for q, r := range test.ExpNeighbors { - got, err := b.Neighbors(ctx, q, nil) - if err != nil { - t.Fatalf("Could not query neighbors: %s", err) - } - gotIDs := convNodes(got) - slices.Sort(r) - slices.Sort(gotIDs) - if diff := cmp.Diff(r, gotIDs); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - } - }) - } -} diff --git a/pkg/assembler/backends/keyvalue/certifyLegal.go b/pkg/assembler/backends/keyvalue/certifyLegal.go index 2a36a32428..0dfc8770f3 100644 --- a/pkg/assembler/backends/keyvalue/certifyLegal.go +++ b/pkg/assembler/backends/keyvalue/certifyLegal.go @@ -81,7 +81,7 @@ func (n *certifyLegalStruct) BuildModelNode(ctx context.Context, c *demoClient) return c.convLegal(ctx, n) } -func (c *demoClient) IngestCertifyLegals(ctx context.Context, subjects model.PackageOrSourceInputs, declaredLicensesList [][]*model.LicenseInputSpec, discoveredLicensesList [][]*model.LicenseInputSpec, certifyLegals []*model.CertifyLegalInputSpec) ([]string, error) { +func (c *demoClient) IngestCertifyLegals(ctx context.Context, subjects model.PackageOrSourceInputs, declaredLicensesList [][]*model.IDorLicenseInput, discoveredLicensesList [][]*model.IDorLicenseInput, certifyLegals []*model.CertifyLegalInputSpec) ([]string, error) { var rv []string for i, v := range certifyLegals { @@ -105,11 +105,11 @@ func (c *demoClient) IngestCertifyLegals(ctx context.Context, subjects model.Pac return rv, nil } -func (c *demoClient) IngestCertifyLegal(ctx context.Context, subject model.PackageOrSourceInput, declaredLicenses []*model.LicenseInputSpec, discoveredLicenses []*model.LicenseInputSpec, certifyLegal *model.CertifyLegalInputSpec) (string, error) { +func (c *demoClient) IngestCertifyLegal(ctx context.Context, subject model.PackageOrSourceInput, declaredLicenses []*model.IDorLicenseInput, discoveredLicenses []*model.IDorLicenseInput, certifyLegal *model.CertifyLegalInputSpec) (string, error) { return c.ingestCertifyLegal(ctx, subject, declaredLicenses, discoveredLicenses, certifyLegal, true) } -func (c *demoClient) ingestCertifyLegal(ctx context.Context, subject model.PackageOrSourceInput, declaredLicenses []*model.LicenseInputSpec, discoveredLicenses []*model.LicenseInputSpec, certifyLegal *model.CertifyLegalInputSpec, readOnly bool) (string, error) { +func (c *demoClient) ingestCertifyLegal(ctx context.Context, subject model.PackageOrSourceInput, declaredLicenses []*model.IDorLicenseInput, discoveredLicenses []*model.IDorLicenseInput, certifyLegal *model.CertifyLegalInputSpec, readOnly bool) (string, error) { funcName := "IngestCertifyLegal" in := &certifyLegalStruct{ @@ -127,9 +127,9 @@ func (c *demoClient) ingestCertifyLegal(ctx context.Context, subject model.Packa var dec []string for _, lis := range declaredLicenses { - l, err := c.licenseByInput(ctx, lis) + l, err := c.returnFoundLicense(ctx, lis) if err != nil { - return "", gqlerror.Errorf("%v :: License not found %q %v", funcName, lis.Name, err) + return "", gqlerror.Errorf("%v :: License not found %q %v", funcName, lis.LicenseInput.Name, err) } dec = append(dec, l.ThisID) } @@ -138,9 +138,9 @@ func (c *demoClient) ingestCertifyLegal(ctx context.Context, subject model.Packa var dis []string for _, lis := range discoveredLicenses { - l, err := c.licenseByInput(ctx, lis) + l, err := c.returnFoundLicense(ctx, lis) if err != nil { - return "", gqlerror.Errorf("%v :: License not found %q %v", funcName, lis.Name, err) + return "", gqlerror.Errorf("%v :: License not found %q %v", funcName, lis.LicenseInput.Name, err) } dis = append(dis, l.ThisID) } @@ -150,21 +150,21 @@ func (c *demoClient) ingestCertifyLegal(ctx context.Context, subject model.Packa var pkg *pkgVersion if subject.Package != nil { var err error - pkg, err = c.getPackageVerFromInput(ctx, *subject.Package) + pkg, err = c.returnFoundPkgVersion(ctx, subject.Package) if err != nil { return "", gqlerror.Errorf("%v :: %s", funcName, err) } - in.Pkg = pkg.ThisID + in.Pkg = pkg.ID() } var src *srcNameNode if subject.Source != nil { var err error - src, err = c.getSourceNameFromInput(ctx, *subject.Source) + src, err = c.returnFoundSource(ctx, subject.Source) if err != nil { - return "", gqlerror.Errorf("%v :: %v", funcName, err) + return "", gqlerror.Errorf("%v :: %s", funcName, err) } - in.Source = src.ThisID + in.Source = src.ID() } out, err := byKeykv[*certifyLegalStruct](ctx, clCol, in.Key(), c) diff --git a/pkg/assembler/backends/keyvalue/certifyLegal_test.go b/pkg/assembler/backends/keyvalue/certifyLegal_test.go deleted file mode 100644 index dc335e7db2..0000000000 --- a/pkg/assembler/backends/keyvalue/certifyLegal_test.go +++ /dev/null @@ -1,750 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package keyvalue_test - -import ( - "context" - "slices" - "strings" - "testing" - "time" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/internal/testing/stablememmap" - "github.com/guacsec/guac/pkg/assembler/backends" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -var ( - t2 = time.Unix(1e9, 0) - t3 = time.Unix(1e9+5, 0) -) - -func TestLegal(t *testing.T) { - type call struct { - PkgSrc model.PackageOrSourceInput - Dec []*model.LicenseInputSpec - Dis []*model.LicenseInputSpec - Legal *model.CertifyLegalInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - InLic []*model.LicenseInputSpec - Calls []call - Query *model.CertifyLegalSpec - ExpLegal []*model.CertifyLegal - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{p1}, - InLic: []*model.LicenseInputSpec{l1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: p1, - }, - Dec: []*model.LicenseInputSpec{l1}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyLegalSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpLegal: []*model.CertifyLegal{ - { - Subject: p1out, - DeclaredLicenses: []*model.License{l1out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest same twice", - InPkg: []*model.PkgInputSpec{p1}, - InLic: []*model.LicenseInputSpec{l1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: p1, - }, - Dec: []*model.LicenseInputSpec{l1}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Package: p1, - }, - Dec: []*model.LicenseInputSpec{l1}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyLegalSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpLegal: []*model.CertifyLegal{ - { - Subject: p1out, - DeclaredLicenses: []*model.License{l1out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Justification", - InPkg: []*model.PkgInputSpec{p1}, - InLic: []*model.LicenseInputSpec{l1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: p1, - }, - Dec: []*model.LicenseInputSpec{l1}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Package: p1, - }, - Dec: []*model.LicenseInputSpec{l1}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification 2", - }, - }, - }, - Query: &model.CertifyLegalSpec{ - Justification: ptrfrom.String("test justification 2"), - }, - ExpLegal: []*model.CertifyLegal{ - { - Subject: p1out, - DeclaredLicenses: []*model.License{l1out}, - Justification: "test justification 2", - }, - }, - }, - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{p1, p2}, - InLic: []*model.LicenseInputSpec{l1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: p1, - }, - Dec: []*model.LicenseInputSpec{l1}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Package: p2, - }, - Dec: []*model.LicenseInputSpec{l1}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyLegalSpec{ - Subject: &model.PackageOrSourceSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String(""), - }, - }, - }, - ExpLegal: []*model.CertifyLegal{ - { - Subject: p1out, - DeclaredLicenses: []*model.License{l1out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Source", - InSrc: []*model.SourceInputSpec{s1, s2}, - InLic: []*model.LicenseInputSpec{l1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Source: s1, - }, - Dec: []*model.LicenseInputSpec{l1}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Source: s2, - }, - Dec: []*model.LicenseInputSpec{l1}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyLegalSpec{ - Subject: &model.PackageOrSourceSpec{ - Source: &model.SourceSpec{ - Name: ptrfrom.String("myrepo"), - }, - }, - }, - ExpLegal: []*model.CertifyLegal{ - { - Subject: s1out, - DeclaredLicenses: []*model.License{l1out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on License", - InSrc: []*model.SourceInputSpec{s1}, - InLic: []*model.LicenseInputSpec{l1, l2, l3}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Source: s1, - }, - Dec: []*model.LicenseInputSpec{l1, l2}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Source: s1, - }, - Dec: []*model.LicenseInputSpec{l3}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyLegalSpec{ - DeclaredLicenses: []*model.LicenseSpec{ - {Name: ptrfrom.String("GPL-2.0-or-later")}, - }, - }, - ExpLegal: []*model.CertifyLegal{ - { - Subject: s1out, - DeclaredLicenses: []*model.License{l1out, l2out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on License inline", - InSrc: []*model.SourceInputSpec{s1}, - InLic: []*model.LicenseInputSpec{l1, l2, l4}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Source: s1, - }, - Dec: []*model.LicenseInputSpec{l1, l4}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Source: s1, - }, - Dec: []*model.LicenseInputSpec{l2}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.CertifyLegalSpec{ - DeclaredLicenses: []*model.LicenseSpec{ - {Inline: &inlineLicense}, - }, - }, - ExpLegal: []*model.CertifyLegal{ - { - Subject: s1out, - DeclaredLicenses: []*model.License{l1out, l4out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on expression", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: p1, - }, - Legal: &model.CertifyLegalInputSpec{ - DeclaredLicense: "GPL OR MIT", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Package: p1, - }, - Legal: &model.CertifyLegalInputSpec{ - DeclaredLicense: "GPL AND MIT", - }, - }, - }, - Query: &model.CertifyLegalSpec{ - DeclaredLicense: ptrfrom.String("GPL AND MIT"), - }, - ExpLegal: []*model.CertifyLegal{ - { - Subject: p1out, - DeclaredLicense: "GPL AND MIT", - }, - }, - }, - { - Name: "Query on attribution", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: p1, - }, - Legal: &model.CertifyLegalInputSpec{ - Attribution: "Copyright Jeff", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Package: p1, - }, - Legal: &model.CertifyLegalInputSpec{ - Attribution: "Copyright Bob", - }, - }, - }, - Query: &model.CertifyLegalSpec{ - Attribution: ptrfrom.String("Copyright Jeff"), - }, - ExpLegal: []*model.CertifyLegal{ - { - Subject: p1out, - Attribution: "Copyright Jeff", - }, - }, - }, - { - Name: "Query on time", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: p1, - }, - Legal: &model.CertifyLegalInputSpec{ - TimeScanned: t3, - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Package: p1, - }, - Legal: &model.CertifyLegalInputSpec{ - TimeScanned: t2, - }, - }, - }, - Query: &model.CertifyLegalSpec{ - TimeScanned: &t2, - }, - ExpLegal: []*model.CertifyLegal{ - { - Subject: p1out, - TimeScanned: t2, - }, - }, - }, - { - Name: "Query multiple", - InPkg: []*model.PkgInputSpec{p1, p2, p3}, - InLic: []*model.LicenseInputSpec{l1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: p1, - }, - Dec: []*model.LicenseInputSpec{l1}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Package: p2, - }, - Dec: []*model.LicenseInputSpec{l1}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Package: p3, - }, - Dec: []*model.LicenseInputSpec{l1}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification other", - }, - }, - }, - Query: &model.CertifyLegalSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpLegal: []*model.CertifyLegal{ - { - Subject: p2out, - DeclaredLicenses: []*model.License{l1out}, - Justification: "test justification", - }, - { - Subject: p1out, - DeclaredLicenses: []*model.License{l1out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest without Package", - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: p1, - }, - Legal: &model.CertifyLegalInputSpec{}, - }, - }, - ExpIngestErr: true, - }, - { - Name: "Ingest without Source", - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Source: s1, - }, - Legal: &model.CertifyLegalInputSpec{}, - }, - }, - ExpIngestErr: true, - }, - { - Name: "Ingest without License", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: p1, - }, - Dec: []*model.LicenseInputSpec{l1}, - Legal: &model.CertifyLegalInputSpec{}, - }, - }, - ExpIngestErr: true, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - ctx := context.Background() - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, a := range test.InLic { - if _, err := b.IngestLicense(ctx, a); err != nil { - t.Fatalf("Could not ingest license: %v", err) - } - } - for _, o := range test.Calls { - _, err := b.IngestCertifyLegal(ctx, o.PkgSrc, o.Dec, o.Dis, o.Legal) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.CertifyLegal(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpLegal, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func TestLegals(t *testing.T) { - type call struct { - PkgSrc model.PackageOrSourceInputs - Dec [][]*model.LicenseInputSpec - Dis [][]*model.LicenseInputSpec - Legal []*model.CertifyLegalInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - InLic []*model.LicenseInputSpec - Calls []call - Query *model.CertifyLegalSpec - ExpLegal []*model.CertifyLegal - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{p1, p2}, - InLic: []*model.LicenseInputSpec{l1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInputs{ - Packages: []*model.PkgInputSpec{p1, p2}, - }, - Dec: [][]*model.LicenseInputSpec{{l1}, {l1}}, - Dis: [][]*model.LicenseInputSpec{{}, {}}, - Legal: []*model.CertifyLegalInputSpec{ - {Justification: "test justification"}, - {Justification: "test justification"}, - }, - }, - }, - Query: &model.CertifyLegalSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpLegal: []*model.CertifyLegal{ - { - Subject: p2out, - DeclaredLicenses: []*model.License{l1out}, - Justification: "test justification", - }, - { - Subject: p1out, - DeclaredLicenses: []*model.License{l1out}, - Justification: "test justification", - }, - }, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - ctx := context.Background() - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, a := range test.InLic { - if _, err := b.IngestLicense(ctx, a); err != nil { - t.Fatalf("Could not ingest license: %v", err) - } - } - for _, o := range test.Calls { - _, err := b.IngestCertifyLegals(ctx, o.PkgSrc, o.Dec, o.Dis, o.Legal) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.CertifyLegal(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpLegal, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func TestLegalNeighbors(t *testing.T) { - type call struct { - PkgSrc model.PackageOrSourceInput - Dec []*model.LicenseInputSpec - Dis []*model.LicenseInputSpec - Legal *model.CertifyLegalInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - InLic []*model.LicenseInputSpec - Calls []call - ExpNeighbors map[string][]string - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{p1}, - InLic: []*model.LicenseInputSpec{l1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: p1, - }, - Dec: []*model.LicenseInputSpec{l1}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification", - }, - }, - }, - ExpNeighbors: map[string][]string{ - "1": {"1"}, - "2": {"1", "1"}, - "3": {"1", "1"}, - "4": {"1", "6"}, // pkg version - "5": {"6"}, // license - "6": {"1", "5"}, // certifyLegal - }, - }, - { - Name: "Two Certify Legals", - InPkg: []*model.PkgInputSpec{p1, p2}, - InLic: []*model.LicenseInputSpec{l1, l2, l3}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: p1, - }, - Dec: []*model.LicenseInputSpec{l1, l2}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Package: p2, - }, - Dec: []*model.LicenseInputSpec{l1, l3}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification", - }, - }, - }, - ExpNeighbors: map[string][]string{ - "4": {"1", "9"}, // pkg version 1 - "5": {"1", "10"}, // pkg version 2 - "6": {"9", "10"}, // license 1 - "7": {"9"}, // license 2 - "8": {"10"}, // license 2 - "9": {"1", "6", "7"}, // certLegal 1 - "10": {"1", "6", "8"}, // certLegal 2 - }, - }, - } - ctx := context.Background() - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, a := range test.InLic { - if _, err := b.IngestLicense(ctx, a); err != nil { - t.Fatalf("Could not ingest license: %v", err) - } - } - for _, o := range test.Calls { - if _, err := b.IngestCertifyLegal(ctx, o.PkgSrc, o.Dec, o.Dis, o.Legal); err != nil { - t.Fatalf("Could not ingest CertifyLegal: %s", err) - } - } - for q, r := range test.ExpNeighbors { - got, err := b.Neighbors(ctx, q, nil) - if err != nil { - t.Fatalf("Could not query neighbors: %s", err) - } - gotIDs := convNodes(got) - slices.Sort(r) - slices.Sort(gotIDs) - if diff := cmp.Diff(r, gotIDs); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - } - }) - } -} diff --git a/pkg/assembler/backends/keyvalue/certifyScorecard.go b/pkg/assembler/backends/keyvalue/certifyScorecard.go index 4f5794d018..a9c877772b 100644 --- a/pkg/assembler/backends/keyvalue/certifyScorecard.go +++ b/pkg/assembler/backends/keyvalue/certifyScorecard.go @@ -69,7 +69,7 @@ func (n *scorecardLink) BuildModelNode(ctx context.Context, c *demoClient) (mode // Ingest Scorecards -func (c *demoClient) IngestScorecards(ctx context.Context, sources []*model.SourceInputSpec, scorecards []*model.ScorecardInputSpec) ([]string, error) { +func (c *demoClient) IngestScorecards(ctx context.Context, sources []*model.IDorSourceInput, scorecards []*model.ScorecardInputSpec) ([]string, error) { var modelCertifyScorecards []string for i := range scorecards { scorecard, err := c.IngestScorecard(ctx, *sources[i], *scorecards[i]) @@ -82,11 +82,11 @@ func (c *demoClient) IngestScorecards(ctx context.Context, sources []*model.Sour } // Ingest CertifyScorecard -func (c *demoClient) IngestScorecard(ctx context.Context, source model.SourceInputSpec, scorecard model.ScorecardInputSpec) (string, error) { +func (c *demoClient) IngestScorecard(ctx context.Context, source model.IDorSourceInput, scorecard model.ScorecardInputSpec) (string, error) { return c.certifyScorecard(ctx, source, scorecard, true) } -func (c *demoClient) certifyScorecard(ctx context.Context, source model.SourceInputSpec, scorecard model.ScorecardInputSpec, readOnly bool) (string, error) { +func (c *demoClient) certifyScorecard(ctx context.Context, source model.IDorSourceInput, scorecard model.ScorecardInputSpec, readOnly bool) (string, error) { funcName := "CertifyScorecard" checksMap := getChecksFromInput(scorecard.Checks) @@ -103,11 +103,11 @@ func (c *demoClient) certifyScorecard(ctx context.Context, source model.SourceIn lock(&c.m, readOnly) defer unlock(&c.m, readOnly) - srcName, err := c.getSourceNameFromInput(ctx, source) + srcName, err := c.returnFoundSource(ctx, &source) if err != nil { return "", gqlerror.Errorf("%v :: %s", funcName, err) } - in.SourceID = srcName.ThisID + in.SourceID = srcName.ID() out, err := byKeykv[*scorecardLink](ctx, cscCol, in.Key(), c) if err == nil { diff --git a/pkg/assembler/backends/keyvalue/certifyScorecard_test.go b/pkg/assembler/backends/keyvalue/certifyScorecard_test.go deleted file mode 100644 index febc7f755b..0000000000 --- a/pkg/assembler/backends/keyvalue/certifyScorecard_test.go +++ /dev/null @@ -1,702 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package keyvalue_test - -import ( - "context" - "slices" - "strings" - "testing" - "time" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/internal/testing/stablememmap" - "github.com/guacsec/guac/pkg/assembler/backends" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -func TestCertifyScorecard(t *testing.T) { - testTime := time.Unix(1e9+5, 0) - type call struct { - Src *model.SourceInputSpec - SC *model.ScorecardInputSpec - } - tests := []struct { - Name string - InSrc []*model.SourceInputSpec - Calls []call - Query *model.CertifyScorecardSpec - ExpSC []*model.CertifyScorecard - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Src: s1, - SC: &model.ScorecardInputSpec{ - Origin: "test origin", - }, - }, - }, - Query: &model.CertifyScorecardSpec{ - Origin: ptrfrom.String("test origin"), - }, - ExpSC: []*model.CertifyScorecard{ - { - Source: s1out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - Origin: "test origin", - }, - }, - }, - }, - { - Name: "Ingest same", - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Src: s1, - SC: &model.ScorecardInputSpec{ - Origin: "test origin", - }, - }, - { - Src: s1, - SC: &model.ScorecardInputSpec{ - Origin: "test origin", - }, - }, - }, - Query: &model.CertifyScorecardSpec{ - Origin: ptrfrom.String("test origin"), - }, - ExpSC: []*model.CertifyScorecard{ - { - Source: s1out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - Origin: "test origin", - }, - }, - }, - }, - { - Name: "Query multiple", - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Src: s1, - SC: &model.ScorecardInputSpec{ - Origin: "test origin one", - }, - }, - { - Src: s1, - SC: &model.ScorecardInputSpec{ - AggregateScore: 4.4, - Origin: "test origin two", - }, - }, - { - Src: s1, - SC: &model.ScorecardInputSpec{ - AggregateScore: 4.9, - Origin: "test origin two", - }, - }, - }, - Query: &model.CertifyScorecardSpec{ - Origin: ptrfrom.String("test origin two"), - }, - ExpSC: []*model.CertifyScorecard{ - { - Source: s1out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - AggregateScore: 4.4, - Origin: "test origin two", - }, - }, - { - Source: s1out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - AggregateScore: 4.9, - Origin: "test origin two", - }, - }, - }, - }, - { - Name: "Query Source", - InSrc: []*model.SourceInputSpec{s1, s2}, - Calls: []call{ - { - Src: s1, - SC: &model.ScorecardInputSpec{ - Origin: "test origin", - }, - }, - { - Src: s2, - SC: &model.ScorecardInputSpec{ - Origin: "test origin", - }, - }, - }, - Query: &model.CertifyScorecardSpec{ - Source: &model.SourceSpec{ - Namespace: ptrfrom.String("github.com/jeff"), - }, - }, - ExpSC: []*model.CertifyScorecard{ - { - Source: s1out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - Origin: "test origin", - }, - }, - }, - }, - { - Name: "Query Time", - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Src: s1, - SC: &model.ScorecardInputSpec{ - AggregateScore: 1.5, - TimeScanned: time.Unix(1e9, 0), - ScorecardVersion: "123", - ScorecardCommit: "abc", - }, - }, - { - Src: s1, - SC: &model.ScorecardInputSpec{ - AggregateScore: 1.5, - TimeScanned: testTime, - ScorecardVersion: "123", - ScorecardCommit: "abc", - }, - }, - }, - Query: &model.CertifyScorecardSpec{ - TimeScanned: &testTime, - }, - ExpSC: []*model.CertifyScorecard{ - { - Source: s1out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - AggregateScore: 1.5, - TimeScanned: testTime, - ScorecardVersion: "123", - ScorecardCommit: "abc", - }, - }, - }, - }, - { - Name: "Query Score", - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Src: s1, - SC: &model.ScorecardInputSpec{ - AggregateScore: 1.5, - TimeScanned: time.Unix(1e9, 0), - ScorecardVersion: "123", - ScorecardCommit: "abc", - }, - }, - { - Src: s1, - SC: &model.ScorecardInputSpec{ - AggregateScore: 5.7, - TimeScanned: time.Unix(1e9, 0), - ScorecardVersion: "123", - ScorecardCommit: "abc", - }, - }, - }, - Query: &model.CertifyScorecardSpec{ - AggregateScore: ptrfrom.Float64(57.0 / 10), - }, - ExpSC: []*model.CertifyScorecard{ - { - Source: s1out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - AggregateScore: 5.7, - TimeScanned: time.Unix(1e9, 0), - ScorecardVersion: "123", - ScorecardCommit: "abc", - }, - }, - }, - }, - { - Name: "Query Checks", - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Src: s1, - SC: &model.ScorecardInputSpec{ - Checks: []*model.ScorecardCheckInputSpec{ - { - Check: "check one", - Score: 5, - }, - }, - ScorecardVersion: "123", - }, - }, - { - Src: s1, - SC: &model.ScorecardInputSpec{ - Checks: []*model.ScorecardCheckInputSpec{ - { - Check: "check one", - Score: 5, - }, - { - Check: "check two", - Score: 6, - }, - }, - ScorecardVersion: "456", - }, - }, - }, - Query: &model.CertifyScorecardSpec{ - Checks: []*model.ScorecardCheckSpec{ - { - Check: "check one", - Score: 5, - }, - }, - }, - ExpSC: []*model.CertifyScorecard{ - { - Source: s1out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{ - { - Check: "check one", - Score: 5, - }, - }, - ScorecardVersion: "123", - }, - }, - }, - }, - { - Name: "Query None", - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Src: s1, - SC: &model.ScorecardInputSpec{ - AggregateScore: 1.5, - TimeScanned: time.Unix(1e9, 0), - ScorecardVersion: "123", - ScorecardCommit: "abc", - }, - }, - { - Src: s1, - SC: &model.ScorecardInputSpec{ - AggregateScore: 5.7, - TimeScanned: time.Unix(1e9, 0), - ScorecardVersion: "123", - ScorecardCommit: "abc", - }, - }, - }, - Query: &model.CertifyScorecardSpec{ - ScorecardVersion: ptrfrom.String("456"), - }, - ExpSC: nil, - }, - { - Name: "Query ID", - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Src: s1, - SC: &model.ScorecardInputSpec{ - AggregateScore: 1.5, - TimeScanned: time.Unix(1e9, 0), - ScorecardVersion: "123", - ScorecardCommit: "abc", - }, - }, - }, - Query: &model.CertifyScorecardSpec{ - ID: ptrfrom.String("4"), - }, - ExpSC: []*model.CertifyScorecard{ - { - Source: s1out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - AggregateScore: 1.5, - TimeScanned: time.Unix(1e9, 0), - ScorecardVersion: "123", - ScorecardCommit: "abc", - }, - }, - }, - }, - { - Name: "Ingest error", - Calls: []call{ - { - Src: s1, - SC: &model.ScorecardInputSpec{ - AggregateScore: 1.5, - TimeScanned: time.Unix(1e9, 0), - ScorecardVersion: "123", - ScorecardCommit: "abc", - }, - }, - }, - ExpIngestErr: true, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - ctx := context.Background() - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, o := range test.Calls { - _, err := b.IngestScorecard(ctx, *o.Src, *o.SC) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.Scorecards(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpSC, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func TestIngestScorecards(t *testing.T) { - type call struct { - Src []*model.SourceInputSpec - SC []*model.ScorecardInputSpec - } - tests := []struct { - Name string - InSrc []*model.SourceInputSpec - Calls []call - Query *model.CertifyScorecardSpec - ExpSC []*model.CertifyScorecard - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Src: []*model.SourceInputSpec{s1}, - SC: []*model.ScorecardInputSpec{ - { - Origin: "test origin", - }, - }, - }, - }, - Query: &model.CertifyScorecardSpec{ - Origin: ptrfrom.String("test origin"), - }, - ExpSC: []*model.CertifyScorecard{ - { - Source: s1out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - Origin: "test origin", - }, - }, - }, - }, - { - Name: "Ingest same", - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Src: []*model.SourceInputSpec{s1, s1}, - SC: []*model.ScorecardInputSpec{ - { - Origin: "test origin", - }, - { - Origin: "test origin", - }, - }, - }, - }, - Query: &model.CertifyScorecardSpec{ - Origin: ptrfrom.String("test origin"), - }, - ExpSC: []*model.CertifyScorecard{ - { - Source: s1out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - Origin: "test origin", - }, - }, - }, - }, - { - Name: "Query multiple", - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Src: []*model.SourceInputSpec{s1, s1, s1}, - SC: []*model.ScorecardInputSpec{ - { - Origin: "test origin one", - }, - { - AggregateScore: 4.4, - Origin: "test origin two", - }, - { - AggregateScore: 4.9, - Origin: "test origin two", - }, - }, - }, - }, - Query: &model.CertifyScorecardSpec{ - Origin: ptrfrom.String("test origin two"), - }, - ExpSC: []*model.CertifyScorecard{ - { - Source: s1out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - AggregateScore: 4.4, - Origin: "test origin two", - }, - }, - { - Source: s1out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - AggregateScore: 4.9, - Origin: "test origin two", - }, - }, - }, - }, - { - Name: "Query Source", - InSrc: []*model.SourceInputSpec{s1, s2}, - Calls: []call{ - { - Src: []*model.SourceInputSpec{s1, s2}, - SC: []*model.ScorecardInputSpec{ - { - Origin: "test origin", - }, - { - Origin: "test origin", - }, - }, - }, - }, - Query: &model.CertifyScorecardSpec{ - Source: &model.SourceSpec{ - Namespace: ptrfrom.String("github.com/jeff"), - }, - }, - ExpSC: []*model.CertifyScorecard{ - { - Source: s1out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - Origin: "test origin", - }, - }, - }, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - ctx := context.Background() - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, o := range test.Calls { - _, err := b.IngestScorecards(ctx, o.Src, o.SC) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.Scorecards(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpSC, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func TestCertifyScorecardNeighbors(t *testing.T) { - type call struct { - Src *model.SourceInputSpec - SC *model.ScorecardInputSpec - } - tests := []struct { - Name string - InSrc []*model.SourceInputSpec - Calls []call - ExpNeighbors map[string][]string - }{ - { - Name: "HappyPath", - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Src: s1, - SC: &model.ScorecardInputSpec{ - Origin: "test origin", - }, - }, - }, - ExpNeighbors: map[string][]string{ - "3": {"1", "4"}, // src name - "4": {"1"}, // SC - }, - }, - { - Name: "Multiple", - InSrc: []*model.SourceInputSpec{s1, s2}, - Calls: []call{ - { - Src: s1, - SC: &model.ScorecardInputSpec{ - Origin: "test origin", - }, - }, - { - Src: s2, - SC: &model.ScorecardInputSpec{ - Origin: "test origin", - }, - }, - { - Src: s2, - SC: &model.ScorecardInputSpec{ - Origin: "test origin two", - }, - }, - }, - ExpNeighbors: map[string][]string{ - // test sources are all type git, id:2 - "3": {"1", "6"}, // src name 1 -> src namespace, SC1 - "5": {"1", "7", "8"}, // src name 2 -> src namespace, SC2, SC3 - "6": {"1"}, // SC 1 - "7": {"1"}, // SC 2 - "8": {"1"}, // SC 3 - }, - }, - } - ctx := context.Background() - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, o := range test.Calls { - if _, err := b.IngestScorecard(ctx, *o.Src, *o.SC); err != nil { - t.Fatalf("Could not ingest CertifyScorecard: %v", err) - } - } - for q, r := range test.ExpNeighbors { - got, err := b.Neighbors(ctx, q, nil) - if err != nil { - t.Fatalf("Could not query neighbors: %s", err) - } - gotIDs := convNodes(got) - slices.Sort(r) - slices.Sort(gotIDs) - if diff := cmp.Diff(r, gotIDs); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - } - }) - } -} diff --git a/pkg/assembler/backends/keyvalue/certifyVEXStatement.go b/pkg/assembler/backends/keyvalue/certifyVEXStatement.go index d71991384d..dc50efad28 100644 --- a/pkg/assembler/backends/keyvalue/certifyVEXStatement.go +++ b/pkg/assembler/backends/keyvalue/certifyVEXStatement.go @@ -80,7 +80,7 @@ func (n *vexLink) BuildModelNode(ctx context.Context, c *demoClient) (model.Node // Ingest CertifyVex -func (c *demoClient) IngestVEXStatements(ctx context.Context, subjects model.PackageOrArtifactInputs, vulnerabilities []*model.VulnerabilityInputSpec, vexStatements []*model.VexStatementInputSpec) ([]string, error) { +func (c *demoClient) IngestVEXStatements(ctx context.Context, subjects model.PackageOrArtifactInputs, vulnerabilities []*model.IDorVulnerabilityInput, vexStatements []*model.VexStatementInputSpec) ([]string, error) { var modelVexStatementIDs []string for i := range vexStatements { @@ -104,11 +104,11 @@ func (c *demoClient) IngestVEXStatements(ctx context.Context, subjects model.Pac return modelVexStatementIDs, nil } -func (c *demoClient) IngestVEXStatement(ctx context.Context, subject model.PackageOrArtifactInput, vulnerability model.VulnerabilityInputSpec, vexStatement model.VexStatementInputSpec) (string, error) { +func (c *demoClient) IngestVEXStatement(ctx context.Context, subject model.PackageOrArtifactInput, vulnerability model.IDorVulnerabilityInput, vexStatement model.VexStatementInputSpec) (string, error) { return c.ingestVEXStatement(ctx, subject, vulnerability, vexStatement, true) } -func (c *demoClient) ingestVEXStatement(ctx context.Context, subject model.PackageOrArtifactInput, vulnerability model.VulnerabilityInputSpec, vexStatement model.VexStatementInputSpec, readOnly bool) (string, error) { +func (c *demoClient) ingestVEXStatement(ctx context.Context, subject model.PackageOrArtifactInput, vulnerability model.IDorVulnerabilityInput, vexStatement model.VexStatementInputSpec, readOnly bool) (string, error) { funcName := "IngestVEXStatement" in := &vexLink{ @@ -125,28 +125,28 @@ func (c *demoClient) ingestVEXStatement(ctx context.Context, subject model.Packa defer unlock(&c.m, readOnly) var foundPkgVersionNode *pkgVersion - var foundArtStrct *artStruct + var foundArtStruct *artStruct if subject.Package != nil { var err error - foundPkgVersionNode, err = c.getPackageVerFromInput(ctx, *subject.Package) + foundPkgVersionNode, err = c.returnFoundPkgVersion(ctx, subject.Package) if err != nil { return "", gqlerror.Errorf("%v :: %s", funcName, err) } - in.PackageID = foundPkgVersionNode.ThisID + in.PackageID = foundPkgVersionNode.ID() } else { var err error - foundArtStrct, err = c.artifactByInput(ctx, subject.Artifact) + foundArtStruct, err = c.returnFoundArtifact(ctx, subject.Artifact) if err != nil { return "", gqlerror.Errorf("%v :: %s", funcName, err) } - in.ArtifactID = foundArtStrct.ThisID + in.ArtifactID = foundArtStruct.ID() } - foundVulnNode, err := c.getVulnerabilityFromInput(ctx, vulnerability) + foundVulnNode, err := c.returnFoundVulnerability(ctx, &vulnerability) if err != nil { return "", gqlerror.Errorf("%v :: %s", funcName, err) } - in.VulnerabilityID = foundVulnNode.ThisID + in.VulnerabilityID = foundVulnNode.ID() out, err := byKeykv[*vexLink](ctx, cVEXCol, in.Key(), c) if err == nil { @@ -173,7 +173,7 @@ func (c *demoClient) ingestVEXStatement(ctx context.Context, subject model.Packa return "", err } } else { - if err := foundArtStrct.setVexLinks(ctx, in.ThisID, c); err != nil { + if err := foundArtStruct.setVexLinks(ctx, in.ThisID, c); err != nil { return "", err } } diff --git a/pkg/assembler/backends/keyvalue/certifyVEXStatement_test.go b/pkg/assembler/backends/keyvalue/certifyVEXStatement_test.go deleted file mode 100644 index 40eef9b336..0000000000 --- a/pkg/assembler/backends/keyvalue/certifyVEXStatement_test.go +++ /dev/null @@ -1,1161 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package keyvalue_test - -import ( - "context" - "slices" - "strings" - "testing" - "time" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/internal/testing/stablememmap" - "github.com/guacsec/guac/pkg/assembler/backends" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -func TestVEX(t *testing.T) { - testTime := time.Unix(1e9+5, 0) - type call struct { - Sub model.PackageOrArtifactInput - Vuln *model.VulnerabilityInputSpec - In *model.VexStatementInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InArt []*model.ArtifactInputSpec - InVuln []*model.VulnerabilityInputSpec - Calls []call - Query *model.CertifyVEXStatementSpec - ExpVEX []*model.CertifyVEXStatement - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{p1}, - InVuln: []*model.VulnerabilityInputSpec{o1}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: o1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - VexJustification: (*model.VexJustification)(ptrfrom.String("test justification")), - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: p1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - { - Name: "Ingest same twice", - InPkg: []*model.PkgInputSpec{p1}, - InVuln: []*model.VulnerabilityInputSpec{o1}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: o1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: o1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - VexJustification: (*model.VexJustification)(ptrfrom.String("test justification")), - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: p1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - { - Name: "Query on Justification", - InPkg: []*model.PkgInputSpec{p1}, - InVuln: []*model.VulnerabilityInputSpec{o1}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: o1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: o1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification 2", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - VexJustification: (*model.VexJustification)(ptrfrom.String("test justification 2")), - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: p1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o1out}, - }, - VexJustification: "test justification 2", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{p1, p2}, - InArt: []*model.ArtifactInputSpec{a1}, - InVuln: []*model.VulnerabilityInputSpec{o1}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: o1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: p2, - }, - Vuln: o1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Artifact: a1, - }, - Vuln: o1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - Subject: &model.PackageOrArtifactSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String(""), - }, - }, - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: p1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - { - Name: "Query on Artifact", - InPkg: []*model.PkgInputSpec{p1}, - InArt: []*model.ArtifactInputSpec{a1, a2}, - InVuln: []*model.VulnerabilityInputSpec{o1}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: o1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Artifact: a1, - }, - Vuln: o1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Artifact: a2, - }, - Vuln: o1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - Subject: &model.PackageOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha256"), - }, - }, - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: a1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - { - Name: "Query on Vuln", - InPkg: []*model.PkgInputSpec{p1}, - InVuln: []*model.VulnerabilityInputSpec{o1, o2, c1}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: o1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: o2, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: c1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - Vulnerability: &model.VulnerabilitySpec{ - Type: ptrfrom.String("osv"), - VulnerabilityID: ptrfrom.String("cve-2014-8140"), - }, - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: p1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - { - Name: "Query on Status", - InPkg: []*model.PkgInputSpec{p1}, - InVuln: []*model.VulnerabilityInputSpec{c1, o1}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: c1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - Status: "status one", - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: o1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - Status: "status two", - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - Status: (*model.VexStatus)(ptrfrom.String("status one")), - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: p1out, - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - Status: "status one", - }, - }, - }, - { - Name: "Query on Statement", - InPkg: []*model.PkgInputSpec{p1}, - InVuln: []*model.VulnerabilityInputSpec{o1}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: o1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - Statement: "statement one", - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: o1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - Statement: "statement two", - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - Statement: ptrfrom.String("statement two"), - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: p1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - Statement: "statement two", - }, - }, - }, - { - Name: "Query on KnownSince", - InPkg: []*model.PkgInputSpec{p1}, - InVuln: []*model.VulnerabilityInputSpec{o1}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: o1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: o1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: testTime, - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - KnownSince: &testTime, - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: p1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o1out}, - }, - VexJustification: "test justification", - KnownSince: testTime, - }, - }, - }, - { - Name: "Query on ID", - InPkg: []*model.PkgInputSpec{p1}, - InVuln: []*model.VulnerabilityInputSpec{o1, o2}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: o1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: o2, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - ID: ptrfrom.String("8"), - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: p1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - { - Name: "Query None", - InPkg: []*model.PkgInputSpec{p1}, - InVuln: []*model.VulnerabilityInputSpec{o1, o2, c1}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: o1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: o2, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: c1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - Vulnerability: &model.VulnerabilitySpec{ - VulnerabilityID: ptrfrom.String("asdf"), - }, - }, - ExpVEX: nil, - }, - { - Name: "Query multiple", - InPkg: []*model.PkgInputSpec{p1}, - InVuln: []*model.VulnerabilityInputSpec{o1, o2, c1}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: o1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: o2, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification two", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: c1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification two", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - VexJustification: (*model.VexJustification)(ptrfrom.String("test justification two")), - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: p1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o2out}, - }, - VexJustification: "test justification two", - KnownSince: time.Unix(1e9, 0), - }, - { - Subject: p1out, - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out}, - }, - VexJustification: "test justification two", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - { - Name: "Ingest without sub", - InVuln: []*model.VulnerabilityInputSpec{o1}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: o1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - ExpIngestErr: true, - }, - { - Name: "Ingest without vuln", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: o1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - ExpIngestErr: true, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - ctx := context.Background() - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %a", err) - } - } - for _, v := range test.InVuln { - if _, err := b.IngestVulnerability(ctx, *v); err != nil { - t.Fatalf("Could not ingest vulnerability: %v", err) - } - } - for _, o := range test.Calls { - _, err := b.IngestVEXStatement(ctx, o.Sub, *o.Vuln, *o.In) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.CertifyVEXStatement(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpVEX, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func TestVEXBulkIngest(t *testing.T) { - type call struct { - Subs model.PackageOrArtifactInputs - Vulns []*model.VulnerabilityInputSpec - Vexs []*model.VexStatementInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InArt []*model.ArtifactInputSpec - InVuln []*model.VulnerabilityInputSpec - Calls []call - Query *model.CertifyVEXStatementSpec - ExpVEX []*model.CertifyVEXStatement - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{p1}, - InVuln: []*model.VulnerabilityInputSpec{o1}, - Calls: []call{ - { - Subs: model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - Vulns: []*model.VulnerabilityInputSpec{o1}, - Vexs: []*model.VexStatementInputSpec{ - { - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - VexJustification: (*model.VexJustification)(ptrfrom.String("test justification")), - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: p1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - { - Name: "Ingest same twice", - InPkg: []*model.PkgInputSpec{p1}, - InVuln: []*model.VulnerabilityInputSpec{o1}, - Calls: []call{ - { - Subs: model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1, p1}, - }, - Vulns: []*model.VulnerabilityInputSpec{o1, o1}, - Vexs: []*model.VexStatementInputSpec{ - { - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - { - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - VexJustification: (*model.VexJustification)(ptrfrom.String("test justification")), - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: p1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{p1, p2}, - InArt: []*model.ArtifactInputSpec{a1}, - InVuln: []*model.VulnerabilityInputSpec{o1}, - Calls: []call{ - { - Subs: model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1, p2}, - }, - Vulns: []*model.VulnerabilityInputSpec{o1, o1}, - Vexs: []*model.VexStatementInputSpec{ - { - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - { - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - { - Subs: model.PackageOrArtifactInputs{ - Artifacts: []*model.ArtifactInputSpec{a1}, - }, - Vulns: []*model.VulnerabilityInputSpec{o1}, - Vexs: []*model.VexStatementInputSpec{ - { - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - Subject: &model.PackageOrArtifactSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String(""), - }, - }, - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: p1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - { - Name: "Query on Artifact", - InArt: []*model.ArtifactInputSpec{a1, a2}, - InVuln: []*model.VulnerabilityInputSpec{o1}, - Calls: []call{ - { - Subs: model.PackageOrArtifactInputs{ - Artifacts: []*model.ArtifactInputSpec{a1, a2}, - }, - Vulns: []*model.VulnerabilityInputSpec{o1, o1}, - Vexs: []*model.VexStatementInputSpec{ - { - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - { - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - Subject: &model.PackageOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha256"), - }, - }, - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: a1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - { - Name: "Query on Vuln", - InPkg: []*model.PkgInputSpec{p1}, - InVuln: []*model.VulnerabilityInputSpec{o1, o2, c1}, - Calls: []call{ - { - Subs: model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1, p1, p1}, - }, - Vulns: []*model.VulnerabilityInputSpec{o1, o2, c1}, - Vexs: []*model.VexStatementInputSpec{ - { - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - { - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - { - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - Vulnerability: &model.VulnerabilitySpec{ - Type: ptrfrom.String("osv"), - VulnerabilityID: ptrfrom.String("cve-2014-8140"), - }, - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: p1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - { - Name: "Query on Status", - InPkg: []*model.PkgInputSpec{p1}, - InVuln: []*model.VulnerabilityInputSpec{c1, o1}, - Calls: []call{ - { - Subs: model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1, p1}, - }, - Vulns: []*model.VulnerabilityInputSpec{c1, o1}, - Vexs: []*model.VexStatementInputSpec{ - { - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - Status: "status one", - }, - { - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - Status: (*model.VexStatus)(ptrfrom.String("status one")), - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: p1out, - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - Status: "status one", - }, - }, - }, - { - Name: "Query multiple", - InPkg: []*model.PkgInputSpec{p1}, - InVuln: []*model.VulnerabilityInputSpec{o1, o2, c1}, - Calls: []call{ - { - Subs: model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1, p1, p1}, - }, - Vulns: []*model.VulnerabilityInputSpec{o1, o2, c1}, - Vexs: []*model.VexStatementInputSpec{ - { - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - { - VexJustification: "test justification two", - KnownSince: time.Unix(1e9, 0), - }, - { - VexJustification: "test justification two", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - }, - Query: &model.CertifyVEXStatementSpec{ - VexJustification: (*model.VexJustification)(ptrfrom.String("test justification two")), - }, - ExpVEX: []*model.CertifyVEXStatement{ - { - Subject: p1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o2out}, - }, - VexJustification: "test justification two", - KnownSince: time.Unix(1e9, 0), - }, - { - Subject: p1out, - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out}, - }, - VexJustification: "test justification two", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - ctx := context.Background() - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - - if _, err := b.IngestPackages(ctx, test.InPkg); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - - if _, err := b.IngestArtifacts(ctx, test.InArt); err != nil { - t.Fatalf("Could not ingest artifact: %a", err) - } - - if _, err := b.IngestVulnerabilities(ctx, test.InVuln); err != nil { - t.Fatalf("Could not ingest vulnerability: %v", err) - } - for _, o := range test.Calls { - _, err := b.IngestVEXStatements(ctx, o.Subs, o.Vulns, o.Vexs) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.CertifyVEXStatement(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpVEX, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func TestVEXNeighbors(t *testing.T) { - type call struct { - Sub model.PackageOrArtifactInput - Vuln *model.VulnerabilityInputSpec - In *model.VexStatementInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InArt []*model.ArtifactInputSpec - InVuln []*model.VulnerabilityInputSpec - Calls []call - ExpNeighbors map[string][]string - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{p1}, - InVuln: []*model.VulnerabilityInputSpec{o1}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: o1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - ExpNeighbors: map[string][]string{ - "4": {"1", "7"}, // pkg version -> pkg name, vex - "6": {"5", "7"}, // vuln -> vuln type, vex - "7": {"1", "5"}, // Vex -> pkg version, vuln - }, - }, - { - Name: "Two vex on same package", - InPkg: []*model.PkgInputSpec{p1}, - InVuln: []*model.VulnerabilityInputSpec{o1, o2}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: o1, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - Vuln: o2, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - }, - ExpNeighbors: map[string][]string{ - "4": {"1", "8", "9"}, // pkg version -> pkg name, vex1, vex2 - "6": {"5", "8"}, // Vuln1 -> vulnType, vex1 - "7": {"5", "9"}, // Vuln2 -> vulnType, vex2 - "8": {"1", "5"}, // Vex1 -> pkg version, vuln1 - "9": {"1", "5"}, // Vex2 -> pkg version, vuln2 - }, - }, - } - ctx := context.Background() - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %a", err) - } - } - for _, v := range test.InVuln { - if _, err := b.IngestVulnerability(ctx, *v); err != nil { - t.Fatalf("Could not ingest vulnerability: %v", err) - } - } - for _, o := range test.Calls { - if _, err := b.IngestVEXStatement(ctx, o.Sub, *o.Vuln, *o.In); err != nil { - t.Fatalf("Could not ingest VEXStatement") - } - } - for q, r := range test.ExpNeighbors { - got, err := b.Neighbors(ctx, q, nil) - if err != nil { - t.Fatalf("Could not query neighbors: %s", err) - } - gotIDs := convNodes(got) - slices.Sort(r) - slices.Sort(gotIDs) - if diff := cmp.Diff(r, gotIDs); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - } - }) - } -} diff --git a/pkg/assembler/backends/keyvalue/certifyVuln.go b/pkg/assembler/backends/keyvalue/certifyVuln.go index 21bde56be4..9186a96cd1 100644 --- a/pkg/assembler/backends/keyvalue/certifyVuln.go +++ b/pkg/assembler/backends/keyvalue/certifyVuln.go @@ -74,7 +74,7 @@ func (n *certifyVulnerabilityLink) BuildModelNode(ctx context.Context, c *demoCl } // Ingest CertifyVuln -func (c *demoClient) IngestCertifyVulns(ctx context.Context, pkgs []*model.PkgInputSpec, vulnerabilities []*model.VulnerabilityInputSpec, certifyVulns []*model.ScanMetadataInput) ([]string, error) { +func (c *demoClient) IngestCertifyVulns(ctx context.Context, pkgs []*model.IDorPkgInput, vulnerabilities []*model.IDorVulnerabilityInput, certifyVulns []*model.ScanMetadataInput) ([]string, error) { var modelCertifyVulnList []string for i := range certifyVulns { certifyVuln, err := c.IngestCertifyVuln(ctx, *pkgs[i], *vulnerabilities[i], *certifyVulns[i]) @@ -86,11 +86,11 @@ func (c *demoClient) IngestCertifyVulns(ctx context.Context, pkgs []*model.PkgIn return modelCertifyVulnList, nil } -func (c *demoClient) IngestCertifyVuln(ctx context.Context, pkg model.PkgInputSpec, vulnerability model.VulnerabilityInputSpec, certifyVuln model.ScanMetadataInput) (string, error) { +func (c *demoClient) IngestCertifyVuln(ctx context.Context, pkg model.IDorPkgInput, vulnerability model.IDorVulnerabilityInput, certifyVuln model.ScanMetadataInput) (string, error) { return c.ingestVulnerability(ctx, pkg, vulnerability, certifyVuln, true) } -func (c *demoClient) ingestVulnerability(ctx context.Context, packageArg model.PkgInputSpec, vulnerability model.VulnerabilityInputSpec, certifyVuln model.ScanMetadataInput, readOnly bool) (string, error) { +func (c *demoClient) ingestVulnerability(ctx context.Context, packageArg model.IDorPkgInput, vulnerability model.IDorVulnerabilityInput, certifyVuln model.ScanMetadataInput, readOnly bool) (string, error) { funcName := "IngestVulnerability" in := &certifyVulnerabilityLink{ @@ -106,17 +106,17 @@ func (c *demoClient) ingestVulnerability(ctx context.Context, packageArg model.P lock(&c.m, readOnly) defer unlock(&c.m, readOnly) - foundPackage, err := c.getPackageVerFromInput(ctx, packageArg) + foundPackage, err := c.returnFoundPkgVersion(ctx, &packageArg) if err != nil { return "", gqlerror.Errorf("%v :: %s", funcName, err) } - in.PackageID = foundPackage.ThisID + in.PackageID = foundPackage.ID() - foundVulnNode, err := c.getVulnerabilityFromInput(ctx, vulnerability) + foundVulnNode, err := c.returnFoundVulnerability(ctx, &vulnerability) if err != nil { return "", gqlerror.Errorf("%v :: %s", funcName, err) } - in.VulnerabilityID = foundVulnNode.ThisID + in.VulnerabilityID = foundVulnNode.ID() out, err := byKeykv[*certifyVulnerabilityLink](ctx, cVulnCol, in.Key(), c) if err == nil { diff --git a/pkg/assembler/backends/keyvalue/certifyVuln_test.go b/pkg/assembler/backends/keyvalue/certifyVuln_test.go deleted file mode 100644 index b3b61cc7e1..0000000000 --- a/pkg/assembler/backends/keyvalue/certifyVuln_test.go +++ /dev/null @@ -1,1222 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package keyvalue_test - -import ( - "context" - "slices" - "strconv" - "strings" - "testing" - "time" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/internal/testing/stablememmap" - "github.com/guacsec/guac/pkg/assembler/backends" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -var t1, _ = time.Parse(time.RFC3339, "2023-01-01T00:00:00Z") - -var vmd1 = &model.ScanMetadata{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, -} - -func TestIngestCertifyVulnerability(t *testing.T) { - type call struct { - Pkg *model.PkgInputSpec - Vuln *model.VulnerabilityInputSpec - CertifyVuln *model.ScanMetadataInput - } - - tests := []struct { - InPkg []*model.PkgInputSpec - Name string - InVuln []*model.VulnerabilityInputSpec - Calls []call - ExpVuln []*model.CertifyVuln - Query *model.CertifyVulnSpec - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InVuln: []*model.VulnerabilityInputSpec{c1}, - InPkg: []*model.PkgInputSpec{p2}, - Calls: []call{ - { - Pkg: p2, - Vuln: c1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Collector: ptrfrom.String("test collector"), - }, - ExpVuln: []*model.CertifyVuln{ - { - ID: "1", - Package: p2out, - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Certify NoVuln", - InVuln: []*model.VulnerabilityInputSpec{noVulnInput}, - InPkg: []*model.PkgInputSpec{p2}, - Calls: []call{ - { - Pkg: p2, - Vuln: noVulnInput, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Collector: ptrfrom.String("test collector"), - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: p2out, - Vulnerability: &model.Vulnerability{ - Type: "novuln", - VulnerabilityIDs: []*model.VulnerabilityID{noVulnOut}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Certify OSV", - InVuln: []*model.VulnerabilityInputSpec{o1}, - InPkg: []*model.PkgInputSpec{p2}, - Calls: []call{ - { - Pkg: p2, - Vuln: o1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Collector: ptrfrom.String("test collector"), - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: p2out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o1out}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Certify GHSA", - InVuln: []*model.VulnerabilityInputSpec{g1}, - InPkg: []*model.PkgInputSpec{p2}, - Calls: []call{ - { - Pkg: p2, - Vuln: g1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Collector: ptrfrom.String("test collector"), - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: p2out, - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{g1out}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Query on GHSA", - InVuln: []*model.VulnerabilityInputSpec{g1}, - InPkg: []*model.PkgInputSpec{p2}, - Calls: []call{ - { - Pkg: p2, - Vuln: g1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Vulnerability: &model.VulnerabilitySpec{ - VulnerabilityID: &g1.VulnerabilityID, - }, - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: p2out, - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{g1out}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Query ID", - InVuln: []*model.VulnerabilityInputSpec{g1}, - InPkg: []*model.PkgInputSpec{p2}, - Calls: []call{ - { - Pkg: p2, - Vuln: g1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - ID: ptrfrom.String("7"), - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: p2out, - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{g1out}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Query on Package", - InVuln: []*model.VulnerabilityInputSpec{g1}, - InPkg: []*model.PkgInputSpec{p2}, - Calls: []call{ - { - Pkg: p2, - Vuln: g1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Package: &model.PkgSpec{ - Name: ptrfrom.String(p2.Name), - }, - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: p2out, - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{g1out}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Query none", - InVuln: []*model.VulnerabilityInputSpec{g1}, - InPkg: []*model.PkgInputSpec{p2}, - Calls: []call{ - { - Pkg: p2, - Vuln: g1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Vulnerability: &model.VulnerabilitySpec{ - VulnerabilityID: ptrfrom.String("asdf"), - }, - }, - ExpVuln: nil, - }, - { - Name: "Query No Vuln", - InVuln: []*model.VulnerabilityInputSpec{noVulnInput}, - InPkg: []*model.PkgInputSpec{p2}, - Calls: []call{ - { - Pkg: p2, - Vuln: noVulnInput, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Vulnerability: &model.VulnerabilitySpec{ - Type: ptrfrom.String("noVuln"), - }, - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: p2out, - Vulnerability: &model.Vulnerability{ - Type: "novuln", - VulnerabilityIDs: []*model.VulnerabilityID{noVulnOut}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Query No Vuln - with novuln boolen", - InVuln: []*model.VulnerabilityInputSpec{noVulnInput, c1}, - InPkg: []*model.PkgInputSpec{p2, p1}, - Calls: []call{ - { - Pkg: p2, - Vuln: noVulnInput, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - { - Pkg: p1, - Vuln: c1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Vulnerability: &model.VulnerabilitySpec{ - NoVuln: ptrfrom.Bool(true), - }, - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: p2out, - Vulnerability: &model.Vulnerability{ - Type: "novuln", - VulnerabilityIDs: []*model.VulnerabilityID{noVulnOut}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Query only cve (exclude novuln) - with novuln boolen", - InVuln: []*model.VulnerabilityInputSpec{noVulnInput, c1}, - InPkg: []*model.PkgInputSpec{p2, p1}, - Calls: []call{ - { - Pkg: p2, - Vuln: noVulnInput, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - { - Pkg: p1, - Vuln: c1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Vulnerability: &model.VulnerabilitySpec{ - NoVuln: ptrfrom.Bool(false), - }, - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: p1out, - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Query all vulns - with novuln boolean omitted", - InVuln: []*model.VulnerabilityInputSpec{noVulnInput, c1, g1}, - InPkg: []*model.PkgInputSpec{p2, p1, p1}, - Calls: []call{ - { - Pkg: p2, - Vuln: noVulnInput, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - { - Pkg: p1, - Vuln: c1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - { - Pkg: p1, - Vuln: g1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Vulnerability: &model.VulnerabilitySpec{}, - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: p1out, - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out}, - }, - Metadata: vmd1, - }, - { - Package: p1out, - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{g1out}, - }, - Metadata: vmd1, - }, - { - Package: p2out, - Vulnerability: &model.Vulnerability{ - Type: "novuln", - VulnerabilityIDs: []*model.VulnerabilityID{noVulnOut}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Query No Vuln - with novuln boolen false but type set to novuln", - InVuln: []*model.VulnerabilityInputSpec{noVulnInput, c1}, - InPkg: []*model.PkgInputSpec{p2, p1}, - Calls: []call{ - { - Pkg: p2, - Vuln: noVulnInput, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - { - Pkg: p1, - Vuln: c1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Vulnerability: &model.VulnerabilitySpec{ - NoVuln: ptrfrom.Bool(false), - Type: ptrfrom.String("novuln"), - }, - }, - ExpVuln: []*model.CertifyVuln{}, - ExpQueryErr: true, - }, - { - Name: "Ingest without vuln", - InPkg: []*model.PkgInputSpec{p2}, - Calls: []call{ - { - Pkg: p2, - Vuln: &model.VulnerabilityInputSpec{}, - CertifyVuln: &model.ScanMetadataInput{}, - }, - }, - Query: &model.CertifyVulnSpec{}, - ExpIngestErr: true, - }, - { - Name: "Ingest missing pkg", - InPkg: []*model.PkgInputSpec{}, - Calls: []call{ - { - Pkg: p2, - Vuln: &model.VulnerabilityInputSpec{}, - CertifyVuln: &model.ScanMetadataInput{}, - }, - }, - Query: &model.CertifyVulnSpec{}, - ExpIngestErr: true, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - ctx := context.Background() - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, g := range test.InVuln { - if _, err := b.IngestVulnerability(ctx, *g); err != nil { - t.Fatalf("Could not ingest vulnerability: %a", err) - } - } - if _, err := b.IngestPackages(ctx, test.InPkg); err != nil { - t.Fatalf("Could not ingest packages: %v", err) - } - - ids := make([]string, len(test.Calls)) - for i, o := range test.Calls { - record, err := b.IngestCertifyVuln(ctx, *o.Pkg, *o.Vuln, *o.CertifyVuln) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - ids[i] = record - } - if test.Query != nil { - if test.Query.ID != nil { - idIndex, err := strconv.Atoi(*test.Query.ID) - if err == nil && idIndex > -1 && idIndex < len(ids) { - test.Query.ID = ptrfrom.String(ids[idIndex]) - } - } - } - - got, err := b.CertifyVuln(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpVuln, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func TestIngestCertifyVulns(t *testing.T) { - type call struct { - Pkgs []*model.PkgInputSpec - Vulns []*model.VulnerabilityInputSpec - CertifyVulns []*model.ScanMetadataInput - } - - tests := []struct { - InPkg []*model.PkgInputSpec - Name string - InVuln []*model.VulnerabilityInputSpec - Calls []call - ExpVuln []*model.CertifyVuln - Query *model.CertifyVulnSpec - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InVuln: []*model.VulnerabilityInputSpec{c1, c2}, - InPkg: []*model.PkgInputSpec{p1, p2}, - Calls: []call{ - { - Pkgs: []*model.PkgInputSpec{p2, p1}, - Vulns: []*model.VulnerabilityInputSpec{c1, c2}, - CertifyVulns: []*model.ScanMetadataInput{ - { - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - { - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Collector: ptrfrom.String("test collector"), - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: p2out, - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out}, - }, - Metadata: vmd1, - }, - { - Package: p1out, - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c2out}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Certify NoVuln", - InVuln: []*model.VulnerabilityInputSpec{noVulnInput, noVulnInput}, - InPkg: []*model.PkgInputSpec{p2, p1}, - Calls: []call{ - { - Pkgs: []*model.PkgInputSpec{p2, p1}, - Vulns: []*model.VulnerabilityInputSpec{noVulnInput, noVulnInput}, - CertifyVulns: []*model.ScanMetadataInput{ - { - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - { - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Collector: ptrfrom.String("test collector"), - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: p2out, - Vulnerability: &model.Vulnerability{ - Type: "novuln", - VulnerabilityIDs: []*model.VulnerabilityID{noVulnOut}, - }, - Metadata: vmd1, - }, - { - Package: p1out, - Vulnerability: &model.Vulnerability{ - Type: "novuln", - VulnerabilityIDs: []*model.VulnerabilityID{noVulnOut}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Certify OSV", - InVuln: []*model.VulnerabilityInputSpec{o1}, - InPkg: []*model.PkgInputSpec{p2}, - Calls: []call{ - { - Pkgs: []*model.PkgInputSpec{p2}, - Vulns: []*model.VulnerabilityInputSpec{o1}, - CertifyVulns: []*model.ScanMetadataInput{ - { - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Collector: ptrfrom.String("test collector"), - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: p2out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o1out}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Certify GHSA", - InVuln: []*model.VulnerabilityInputSpec{g1}, - InPkg: []*model.PkgInputSpec{p2}, - Calls: []call{ - { - Pkgs: []*model.PkgInputSpec{p2}, - Vulns: []*model.VulnerabilityInputSpec{g1}, - CertifyVulns: []*model.ScanMetadataInput{ - { - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Collector: ptrfrom.String("test collector"), - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: p2out, - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{g1out}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Query on GHSA", - InVuln: []*model.VulnerabilityInputSpec{g1, g2}, - InPkg: []*model.PkgInputSpec{p2, p1}, - Calls: []call{ - { - Pkgs: []*model.PkgInputSpec{p2, p1}, - Vulns: []*model.VulnerabilityInputSpec{g1, g2}, - CertifyVulns: []*model.ScanMetadataInput{ - { - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - { - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Vulnerability: &model.VulnerabilitySpec{ - VulnerabilityID: &g1.VulnerabilityID, - }, - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: p2out, - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{g1out}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Query ID", - InVuln: []*model.VulnerabilityInputSpec{g1}, - InPkg: []*model.PkgInputSpec{p2}, - Calls: []call{ - { - Pkgs: []*model.PkgInputSpec{p2}, - Vulns: []*model.VulnerabilityInputSpec{g1}, - CertifyVulns: []*model.ScanMetadataInput{ - { - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - ID: ptrfrom.String("7"), - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: p2out, - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{g1out}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Query on Package", - InVuln: []*model.VulnerabilityInputSpec{g1, g2}, - InPkg: []*model.PkgInputSpec{p2, p4}, - Calls: []call{ - { - Pkgs: []*model.PkgInputSpec{p2, p4}, - Vulns: []*model.VulnerabilityInputSpec{g1, g2}, - CertifyVulns: []*model.ScanMetadataInput{ - { - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - { - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Package: &model.PkgSpec{ - Name: ptrfrom.String(p2.Name), - }, - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: p2out, - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{g1out}, - }, - Metadata: vmd1, - }, - }, - }, - { - Name: "Query none", - InVuln: []*model.VulnerabilityInputSpec{g1, g2}, - InPkg: []*model.PkgInputSpec{p2, p1}, - Calls: []call{ - { - Pkgs: []*model.PkgInputSpec{p2, p1}, - Vulns: []*model.VulnerabilityInputSpec{g1, g2}, - CertifyVulns: []*model.ScanMetadataInput{ - { - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - { - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Vulnerability: &model.VulnerabilitySpec{ - VulnerabilityID: ptrfrom.String("asdf"), - }, - }, - ExpVuln: nil, - }, - { - Name: "Query No Vuln", - InVuln: []*model.VulnerabilityInputSpec{noVulnInput, noVulnInput}, - InPkg: []*model.PkgInputSpec{p2, p1}, - Calls: []call{ - { - Pkgs: []*model.PkgInputSpec{p2, p1}, - Vulns: []*model.VulnerabilityInputSpec{noVulnInput, noVulnInput}, - CertifyVulns: []*model.ScanMetadataInput{ - { - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - { - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - }, - }, - Query: &model.CertifyVulnSpec{ - Vulnerability: &model.VulnerabilitySpec{ - Type: ptrfrom.String("noVuln"), - }, - }, - ExpVuln: []*model.CertifyVuln{ - { - Package: p2out, - Vulnerability: &model.Vulnerability{ - Type: "novuln", - VulnerabilityIDs: []*model.VulnerabilityID{noVulnOut}, - }, - Metadata: vmd1, - }, - { - Package: p1out, - Vulnerability: &model.Vulnerability{ - Type: "novuln", - VulnerabilityIDs: []*model.VulnerabilityID{noVulnOut}, - }, - Metadata: vmd1, - }, - }, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - ctx := context.Background() - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - - if _, err := b.IngestVulnerabilities(ctx, test.InVuln); err != nil { - t.Fatalf("Could not ingest vulnerabilities: %a", err) - } - if _, err := b.IngestPackages(ctx, test.InPkg); err != nil { - t.Fatalf("Could not ingest packages: %v", err) - } - - for _, o := range test.Calls { - _, err := b.IngestCertifyVulns(ctx, o.Pkgs, o.Vulns, o.CertifyVulns) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - - } - - got, err := b.CertifyVuln(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpVuln, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func TestCertifyVulnNeighbors(t *testing.T) { - type call struct { - Pkg *model.PkgInputSpec - Vuln *model.VulnerabilityInputSpec - CertifyVuln *model.ScanMetadataInput - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InVuln []*model.VulnerabilityInputSpec - Calls []call - ExpNeighbors map[string][]string - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{p1}, - InVuln: []*model.VulnerabilityInputSpec{o1}, - Calls: []call{ - { - Pkg: p1, - Vuln: o1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - }, - ExpNeighbors: map[string][]string{ - "4": {"1", "7"}, // pkg version -> pkg name, vex - "6": {"5", "7"}, // Vuln -> vex - "7": {"1", "5"}, // Vex -> pkg version, vuln - }, - }, - { - Name: "Two vex on same package", - InPkg: []*model.PkgInputSpec{p1}, - InVuln: []*model.VulnerabilityInputSpec{o1, o2}, - Calls: []call{ - { - Pkg: p1, - Vuln: o1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - { - Pkg: p1, - Vuln: o2, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: t1, - }, - }, - }, - ExpNeighbors: map[string][]string{ - "4": {"1", "8", "9"}, // pkg version -> pkg name, certVuln1, certVuln2 - "6": {"5", "8"}, // Vuln1 -> vunType, certVuln1 - "7": {"5", "9"}, // Vuln2 -> vunType, certVuln2 - "8": {"1", "5"}, // certVuln1 -> pkg version, vuln1 - "9": {"1", "5"}, // certVuln2 -> pkg version, vuln2 - }, - }, - } - ctx := context.Background() - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, o := range test.InVuln { - if _, err := b.IngestVulnerability(ctx, *o); err != nil { - t.Fatalf("Could not ingest osv: %v", err) - } - } - for _, o := range test.Calls { - if _, err := b.IngestCertifyVuln(ctx, *o.Pkg, *o.Vuln, *o.CertifyVuln); err != nil { - t.Fatalf("Could not ingest certifyVuln") - } - } - for q, r := range test.ExpNeighbors { - got, err := b.Neighbors(ctx, q, nil) - if err != nil { - t.Fatalf("Could not query neighbors: %s", err) - } - gotIDs := convNodes(got) - slices.Sort(r) - slices.Sort(gotIDs) - if diff := cmp.Diff(r, gotIDs); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - } - }) - } -} diff --git a/pkg/assembler/backends/keyvalue/hasMetadata.go b/pkg/assembler/backends/keyvalue/hasMetadata.go index 49ff0acdd9..a5ad5048a2 100644 --- a/pkg/assembler/backends/keyvalue/hasMetadata.go +++ b/pkg/assembler/backends/keyvalue/hasMetadata.go @@ -124,30 +124,29 @@ func (c *demoClient) ingestHasMetadata(ctx context.Context, subject model.Packag lock(&c.m, readOnly) defer unlock(&c.m, readOnly) - var foundPkgNameorVersionNode pkgNameOrVersion - var foundArtStrct *artStruct + var foundPkgNameOrVersionNode pkgNameOrVersion + var foundArtStruct *artStruct var srcName *srcNameNode if subject.Package != nil { var err error - foundPkgNameorVersionNode, err = c.getPackageNameOrVerFromInput(ctx, *subject.Package, *pkgMatchType) + in.PackageID, foundPkgNameOrVersionNode, err = c.returnFoundPkgBasedOnMatchType(ctx, subject.Package, pkgMatchType) if err != nil { return "", gqlerror.Errorf("%v :: %s", funcName, err) } - in.PackageID = foundPkgNameorVersionNode.ID() } else if subject.Artifact != nil { var err error - foundArtStrct, err = c.artifactByInput(ctx, subject.Artifact) + foundArtStruct, err = c.returnFoundArtifact(ctx, subject.Artifact) if err != nil { return "", gqlerror.Errorf("%v :: %s", funcName, err) } - in.ArtifactID = foundArtStrct.ThisID + in.ArtifactID = foundArtStruct.ID() } else { var err error - srcName, err = c.getSourceNameFromInput(ctx, *subject.Source) + srcName, err = c.returnFoundSource(ctx, subject.Source) if err != nil { return "", gqlerror.Errorf("%v :: %s", funcName, err) } - in.SourceID = srcName.ThisID + in.SourceID = srcName.ID() } out, err := byKeykv[*hasMetadataLink](ctx, hasMDCol, in.Key(), c) @@ -171,13 +170,13 @@ func (c *demoClient) ingestHasMetadata(ctx context.Context, subject model.Packag } // set the backlinks - if foundPkgNameorVersionNode != nil { - if err := foundPkgNameorVersionNode.setHasMetadataLinks(ctx, in.ThisID, c); err != nil { + if foundPkgNameOrVersionNode != nil { + if err := foundPkgNameOrVersionNode.setHasMetadataLinks(ctx, in.ThisID, c); err != nil { return "", err } } - if foundArtStrct != nil { - if err := foundArtStrct.setHasMetadataLinks(ctx, in.ThisID, c); err != nil { + if foundArtStruct != nil { + if err := foundArtStruct.setHasMetadataLinks(ctx, in.ThisID, c); err != nil { return "", err } } diff --git a/pkg/assembler/backends/keyvalue/hasMetadata_test.go b/pkg/assembler/backends/keyvalue/hasMetadata_test.go deleted file mode 100644 index a6fdb14233..0000000000 --- a/pkg/assembler/backends/keyvalue/hasMetadata_test.go +++ /dev/null @@ -1,1068 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package keyvalue_test - -import ( - "context" - "slices" - "strings" - "testing" - "time" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/internal/testing/stablememmap" - "github.com/guacsec/guac/pkg/assembler/backends" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -func TestHasMetadata(t *testing.T) { - type call struct { - Sub model.PackageSourceOrArtifactInput - Match *model.MatchFlags - HM *model.HasMetadataInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - InArt []*model.ArtifactInputSpec - Calls []call - Query *model.HasMetadataSpec - ExpHM []*model.HasMetadata - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Key: "key1", - Value: "value1", - Timestamp: time.Unix(1e9, 0), - Justification: "test justification", - }, - }, - }, - Query: &model.HasMetadataSpec{ - Key: ptrfrom.String("key1"), - Value: ptrfrom.String("value1"), - Since: ptrfrom.Time(time.Unix(1e9, 0)), - Justification: ptrfrom.String("test justification"), - }, - ExpHM: []*model.HasMetadata{ - { - Subject: p1out, - Key: "key1", - Value: "value1", - Timestamp: time.Unix(1e9, 0), - Justification: "test justification", - }, - }, - }, - { - Name: "HappyPath check time since", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Key: "key1", - Value: "value1", - Timestamp: time.Unix(1e9, 0), - Justification: "test justification", - }, - }, - }, - Query: &model.HasMetadataSpec{ - Key: ptrfrom.String("key1"), - Value: ptrfrom.String("value1"), - Since: ptrfrom.Time(time.Unix(1e8, 0)), - Justification: ptrfrom.String("test justification"), - }, - ExpHM: []*model.HasMetadata{ - { - Subject: p1out, - Key: "key1", - Value: "value1", - Timestamp: time.Unix(1e9, 0), - Justification: "test justification", - }, - }, - }, - { - Name: "UnhappyPath check time since", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Key: "key1", - Value: "value1", - Timestamp: time.Unix(1e9, 0), - Justification: "test justification", - }, - }, - }, - Query: &model.HasMetadataSpec{ - Key: ptrfrom.String("key1"), - Value: ptrfrom.String("value1"), - Since: ptrfrom.Time(time.Unix(1e10, 0)), - Justification: ptrfrom.String("test justification"), - }, - ExpHM: nil, - }, - { - Name: "HappyPath All Version", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.HasMetadataSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHM: []*model.HasMetadata{ - { - Subject: p1outName, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest same twice", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.HasMetadataSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHM: []*model.HasMetadata{ - { - Subject: p1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest two different keys", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Key: "key1", - Value: "value1", - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Key: "key2", - Value: "value2", - Justification: "test justification", - }, - }, - }, - Query: &model.HasMetadataSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHM: []*model.HasMetadata{ - { - Subject: p1out, - Key: "key2", - Value: "value2", - Justification: "test justification", - }, - { - Subject: p1out, - Key: "key1", - Value: "value1", - Justification: "test justification", - }, - }, - }, - - { - Name: "Query on Justification", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification one", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification two", - }, - }, - }, - Query: &model.HasMetadataSpec{ - Justification: ptrfrom.String("test justification one"), - }, - ExpHM: []*model.HasMetadata{ - { - Subject: p1out, - Justification: "test justification one", - }, - }, - }, - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{p1, p2}, - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s1, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.HasMetadataSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String("2.11.1"), - }, - }, - }, - ExpHM: []*model.HasMetadata{ - { - Subject: p2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Source", - InPkg: []*model.PkgInputSpec{p1}, - InSrc: []*model.SourceInputSpec{s1, s2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s1, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s2, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.HasMetadataSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Source: &model.SourceSpec{ - Name: ptrfrom.String("bobsrepo"), - }, - }, - }, - ExpHM: []*model.HasMetadata{ - { - Subject: s2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Artifact", - InSrc: []*model.SourceInputSpec{s1}, - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a1, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a2, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s1, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.HasMetadataSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha1"), - }, - }, - }, - ExpHM: []*model.HasMetadata{ - { - Subject: a2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query none", - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a1, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a2, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.HasMetadataSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("asdf"), - }, - }, - }, - ExpHM: nil, - }, - { - Name: "Query multiple", - InSrc: []*model.SourceInputSpec{s1, s2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s1, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s2, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.HasMetadataSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHM: []*model.HasMetadata{ - { - Subject: s1out, - Justification: "test justification", - }, - { - Subject: s2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query Packages", - InPkg: []*model.PkgInputSpec{p1, p2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.HasMetadataSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String("2.11.1"), - }, - }, - }, - ExpHM: []*model.HasMetadata{ - { - Subject: p2out, - Justification: "test justification", - }, - { - Subject: p1outName, - Justification: "test justification", - }, - }, - }, - { - Name: "Query ID", - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a1, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a2, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.HasMetadataSpec{ - ID: ptrfrom.String("3"), - }, - ExpHM: []*model.HasMetadata{ - { - Subject: a1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest without subject", - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a1, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - }, - ExpIngestErr: true, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - ctx := context.Background() - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - for _, o := range test.Calls { - _, err := b.IngestHasMetadata(ctx, o.Sub, o.Match, *o.HM) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.HasMetadata(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpHM, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func TestIngestBulkHasMetadata(t *testing.T) { - type call struct { - Sub model.PackageSourceOrArtifactInputs - Match *model.MatchFlags - HM []*model.HasMetadataInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - InArt []*model.ArtifactInputSpec - Calls []call - Query *model.HasMetadataSpec - ExpHM []*model.HasMetadata - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: []*model.HasMetadataInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.HasMetadataSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHM: []*model.HasMetadata{ - { - Subject: p1out, - Justification: "test justification", - }, - }, - }, - { - Name: "HappyPath All Version", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - HM: []*model.HasMetadataInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.HasMetadataSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHM: []*model.HasMetadata{ - { - Subject: p1outName, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest same twice", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1, p1}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: []*model.HasMetadataInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.HasMetadataSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHM: []*model.HasMetadata{ - { - Subject: p1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{p1, p2}, - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1, p2}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: []*model.HasMetadataInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - { - Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{s1}, - }, - HM: []*model.HasMetadataInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.HasMetadataSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String("2.11.1"), - }, - }, - }, - ExpHM: []*model.HasMetadata{ - { - Subject: p2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Source", - InPkg: []*model.PkgInputSpec{p1}, - InSrc: []*model.SourceInputSpec{s1, s2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: []*model.HasMetadataInputSpec{ - { - Justification: "test justification", - }, - }, - }, - { - Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{s2, s2}, - }, - HM: []*model.HasMetadataInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.HasMetadataSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Source: &model.SourceSpec{ - Name: ptrfrom.String("bobsrepo"), - }, - }, - }, - ExpHM: []*model.HasMetadata{ - { - Subject: s2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Artifact", - InSrc: []*model.SourceInputSpec{s1}, - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Artifacts: []*model.ArtifactInputSpec{a1, a2}, - }, - HM: []*model.HasMetadataInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - { - Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{s1}, - }, - HM: []*model.HasMetadataInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.HasMetadataSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha1"), - }, - }, - }, - ExpHM: []*model.HasMetadata{ - { - Subject: a2out, - Justification: "test justification", - }, - }, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - ctx := context.Background() - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - for _, o := range test.Calls { - _, err := b.IngestBulkHasMetadata(ctx, o.Sub, o.Match, o.HM) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.HasMetadata(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpHM, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func TestHasMetadataNeighbors(t *testing.T) { - type call struct { - Sub model.PackageSourceOrArtifactInput - Match *model.MatchFlags - HM *model.HasMetadataInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - InArt []*model.ArtifactInputSpec - Calls []call - ExpNeighbors map[string][]string - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - }, - ExpNeighbors: map[string][]string{ - "4": {"1", "5"}, // pkg version - "5": {"1"}, // certify good - }, - }, - { - Name: "Pkg Name Src and Artifact", - InPkg: []*model.PkgInputSpec{p1}, - InSrc: []*model.SourceInputSpec{s1}, - InArt: []*model.ArtifactInputSpec{a1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s1, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a1, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - }, - ExpNeighbors: map[string][]string{ - "1": {"1"}, - "2": {"1", "1"}, - "3": {"1", "1", "9"}, // pkg name - "4": {"1"}, // pkg version - "5": {"5"}, - "6": {"5", "5"}, - "7": {"5", "10"}, // src name - "8": {"11"}, // art - "9": {"1"}, // cb 1 -> pkg name - "10": {"5"}, // cb 2 -> src name - "11": {"8"}, // cb 3 -> art - }, - }, - } - ctx := context.Background() - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - for _, o := range test.Calls { - if _, err := b.IngestHasMetadata(ctx, o.Sub, o.Match, *o.HM); err != nil { - t.Fatalf("Could not ingest HasMetadata: %v", err) - } - } - for q, r := range test.ExpNeighbors { - got, err := b.Neighbors(ctx, q, nil) - if err != nil { - t.Fatalf("Could not query neighbors: %s", err) - } - gotIDs := convNodes(got) - slices.Sort(r) - slices.Sort(gotIDs) - if diff := cmp.Diff(r, gotIDs); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - } - }) - } -} diff --git a/pkg/assembler/backends/keyvalue/hasSBOM.go b/pkg/assembler/backends/keyvalue/hasSBOM.go index cabd890f82..4458d7c7d4 100644 --- a/pkg/assembler/backends/keyvalue/hasSBOM.go +++ b/pkg/assembler/backends/keyvalue/hasSBOM.go @@ -178,18 +178,18 @@ func (c *demoClient) ingestHasSbom(ctx context.Context, subject model.PackageOrA if subject.Package != nil { var err error - pkg, err = c.getPackageVerFromInput(ctx, *subject.Package) + pkg, err = c.returnFoundPkgVersion(ctx, subject.Package) if err != nil { return "", gqlerror.Errorf("%v :: %s", funcName, err) } - in.Pkg = pkg.ThisID + in.Pkg = pkg.ID() } else { var err error - art, err = c.artifactByInput(ctx, subject.Artifact) + art, err = c.returnFoundArtifact(ctx, subject.Artifact) if err != nil { return "", gqlerror.Errorf("%v :: %s", funcName, err) } - in.Artifact = art.ThisID + in.Artifact = art.ID() } out, err := byKeykv[*hasSBOMStruct](ctx, hasSBOMCol, in.Key(), c) diff --git a/pkg/assembler/backends/keyvalue/hasSBOM_test.go b/pkg/assembler/backends/keyvalue/hasSBOM_test.go deleted file mode 100644 index d7a7584833..0000000000 --- a/pkg/assembler/backends/keyvalue/hasSBOM_test.go +++ /dev/null @@ -1,3202 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package keyvalue_test - -import ( - "context" - "fmt" - "reflect" - "slices" - "strings" - "testing" - "time" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/internal/testing/stablememmap" - "github.com/guacsec/guac/pkg/assembler/backends" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -type testDependency struct { - pkg *model.PkgInputSpec - depPkg *model.PkgInputSpec - matchType model.MatchFlags - isDep *model.IsDependencyInputSpec -} - -type testOccurrence struct { - Subj *model.PackageOrSourceInput - Art *model.ArtifactInputSpec - isOcc *model.IsOccurrenceInputSpec -} - -// Test resources - -var includedPackage1QualifierKey = "p1_key" -var includedPackage1QualifierValue = "p1_value" - -var includedPackage1 = &model.PkgInputSpec{ - Type: "p1_type", - Namespace: ptrfrom.String("p1_namespace"), - Name: "p1_name", - Version: ptrfrom.String("v1.0.0-p1version"), - Qualifiers: []*model.PackageQualifierInputSpec{{ - Key: includedPackage1QualifierKey, - Value: includedPackage1QualifierValue, - }}, - Subpath: ptrfrom.String("p1_subpath"), -} - -var includedPackage2QualifierKey = "p2_key" -var includedPackage2QualifierValue = "p2_value" - -var includedPackage2 = &model.PkgInputSpec{ - Type: "p2_type", - Namespace: ptrfrom.String("p2_namespace"), - Name: "p2_name", - Version: ptrfrom.String("v1.0.0-p2version"), - Qualifiers: []*model.PackageQualifierInputSpec{{ - Key: includedPackage2QualifierKey, - Value: includedPackage2QualifierValue, - }}, - Subpath: ptrfrom.String("p2_subpath"), -} - -var includedPackage3 = &model.PkgInputSpec{ - Type: "p3_type", - Namespace: ptrfrom.String("p3_namespace"), - Name: "p3_name", - Version: ptrfrom.String("v1.0.0-p3version"), - Qualifiers: []*model.PackageQualifierInputSpec{}, - Subpath: ptrfrom.String("p3_subpath"), -} - -var includedPackages = []*model.PkgInputSpec{includedPackage1, includedPackage2, includedPackage3} - -var includedArtifact1 = &model.ArtifactInputSpec{ - Algorithm: "a1_algorithm", - Digest: "a1_digest", -} - -var includedArtifact2 = &model.ArtifactInputSpec{ - Algorithm: "a2_algorithm", - Digest: "a2_digest", -} - -var includedArtifacts = []*model.ArtifactInputSpec{includedArtifact1, includedArtifact2} - -var includedPackageArtifacts = &model.PackageOrArtifactInputs{ - Packages: includedPackages, - Artifacts: includedArtifacts, -} - -var includedDependency1 = &model.IsDependencyInputSpec{ - VersionRange: "dep1_range", - DependencyType: model.DependencyTypeDirect, - Justification: "dep1_justification", - Origin: "dep1_origin", - Collector: "dep1_collector", -} - -var includedDependency2 = &model.IsDependencyInputSpec{ - VersionRange: "dep2_range", - DependencyType: model.DependencyTypeIndirect, - Justification: "dep2_justification", - Origin: "dep2_origin", - Collector: "dep2_collector", -} - -var includedTestDependency1 = &testDependency{ - pkg: includedPackage1, - depPkg: includedPackage2, - matchType: mSpecific, - isDep: includedDependency1, -} - -var includedTestDependency2 = &testDependency{ - pkg: includedPackage1, - depPkg: includedPackage3, - matchType: mSpecific, - isDep: includedDependency2, -} - -var includedTestDependencies = []testDependency{*includedTestDependency1, *includedTestDependency2} - -var includedSource = &model.SourceInputSpec{ - Type: "src_type", - Namespace: "src_namespace", - Name: "src_name", - Tag: ptrfrom.String("src_tag"), - Commit: ptrfrom.String("src_commit"), -} - -var includedSources = []*model.SourceInputSpec{includedSource} - -var includedOccurrence = &model.IsOccurrenceInputSpec{ - Justification: "occ_justification", - Origin: "occ_origin", - Collector: "occ_collector", -} - -var includedTestOccurrences = []testOccurrence{{ - Subj: &model.PackageOrSourceInput{Package: includedPackage1}, - Art: includedArtifact1, - isOcc: includedOccurrence, -}, { - Subj: &model.PackageOrSourceInput{Source: includedSource}, - Art: includedArtifact1, - isOcc: includedOccurrence, -}} - -var includedHasSBOM = &model.HasSBOMInputSpec{ - URI: "sbom_URI", - Algorithm: "sbom_algorithm", - Digest: "sbom_digest", - DownloadLocation: "sbom_download_location", - Origin: "sbom_origin", - Collector: "sbom_collector", -} - -var includedTestExpectedPackage1 = &model.Package{ - Type: "p1_type", - Namespaces: []*model.PackageNamespace{{ - Namespace: "p1_namespace", - Names: []*model.PackageName{{ - Name: "p1_name", - Versions: []*model.PackageVersion{{ - Version: "v1.0.0-p1version", - Qualifiers: []*model.PackageQualifier{{ - Key: includedPackage1QualifierKey, - Value: includedPackage1QualifierValue, - }}, - Subpath: "p1_subpath", - }}, - }}, - }}, -} - -var includedTestExpectedPackage2 = &model.Package{ - Type: "p2_type", - Namespaces: []*model.PackageNamespace{{ - Namespace: "p2_namespace", - Names: []*model.PackageName{{ - Name: "p2_name", - Versions: []*model.PackageVersion{{ - Version: "v1.0.0-p2version", - Qualifiers: []*model.PackageQualifier{{ - Key: includedPackage2QualifierKey, - Value: includedPackage2QualifierValue, - }}, - Subpath: "p2_subpath", - }}, - }}, - }}, -} - -var includedTestExpectedPackage3 = &model.Package{ - Type: "p3_type", - Namespaces: []*model.PackageNamespace{{ - Namespace: "p3_namespace", - Names: []*model.PackageName{{ - Name: "p3_name", - Versions: []*model.PackageVersion{{ - Version: "v1.0.0-p3version", - Qualifiers: []*model.PackageQualifier{}, - Subpath: "p3_subpath", - }}, - }}, - }}, -} - -var includedTestExpectedArtifact1 = &model.Artifact{ - Algorithm: "a1_algorithm", - Digest: "a1_digest", -} - -var includedTestExpectedArtifact2 = &model.Artifact{ - Algorithm: "a2_algorithm", - Digest: "a2_digest", -} - -var includedTestExpectedSource = &model.Source{ - Type: "src_type", - Namespaces: []*model.SourceNamespace{{ - Namespace: "src_namespace", - Names: []*model.SourceName{{ - Name: "src_name", - Tag: ptrfrom.String("src_tag"), - Commit: ptrfrom.String("src_commit"), - }}, - }}, -} - -var includedTestExpectedSBOM = &model.HasSbom{ - Subject: includedTestExpectedPackage1, - URI: "sbom_URI", - Algorithm: "sbom_algorithm", - Digest: "sbom_digest", - DownloadLocation: "sbom_download_location", - Origin: "sbom_origin", - Collector: "sbom_collector", - IncludedSoftware: []model.PackageOrArtifact{ - includedTestExpectedPackage3, - includedTestExpectedArtifact1, - includedTestExpectedArtifact2, - includedTestExpectedPackage1, - includedTestExpectedPackage2, - }, - IncludedDependencies: []*model.IsDependency{{ - Package: includedTestExpectedPackage1, - DependencyPackage: includedTestExpectedPackage2, - VersionRange: "dep1_range", - DependencyType: model.DependencyTypeDirect, - Justification: "dep1_justification", - Origin: "dep1_origin", - Collector: "dep1_collector", - }, { - Package: includedTestExpectedPackage1, - DependencyPackage: includedTestExpectedPackage3, - VersionRange: "dep2_range", - DependencyType: model.DependencyTypeIndirect, - Justification: "dep2_justification", - Origin: "dep2_origin", - Collector: "dep2_collector", - }}, - IncludedOccurrences: []*model.IsOccurrence{{ - Subject: includedTestExpectedPackage1, - Artifact: includedTestExpectedArtifact1, - Justification: "occ_justification", - Origin: "occ_origin", - Collector: "occ_collector", - }, { - Subject: includedTestExpectedSource, - Artifact: includedTestExpectedArtifact1, - Justification: "occ_justification", - Origin: "occ_origin", - Collector: "occ_collector", - }}, -} - -// End of Test resources - -func getNodeIds(nodes []model.Node) ([]string, error) { - var ids []string - for _, node := range nodes { - var id *string - switch typed := node.(type) { - case *model.Package: - switch len(typed.Namespaces) { - case 0: - id = &typed.ID - case 1: - namespace := typed.Namespaces[0] - switch len(namespace.Names) { - case 0: - id = &namespace.ID - case 1: - name := namespace.Names[0] - switch len(name.Versions) { - case 0: - id = &name.ID - case 1: - version := name.Versions[0] - id = &version.ID - } - } - } - case *model.Artifact: - id = &typed.ID - case *model.HasSbom: - id = &typed.ID - case *model.IsDependency: - id = &typed.ID - case *model.IsOccurrence: - id = &typed.ID - } - if id == nil { - return nil, fmt.Errorf("Could not idenitfy correct id for node: %v", reflect.TypeOf(node)) - } else { - ids = append(ids, *id) - } - } - return ids, nil -} - -func TestHasSBOM(t *testing.T) { - curTime := time.Now() - timeAfterOneSecond := curTime.Add(time.Second) - type call struct { - Sub model.PackageOrArtifactInput - HS *model.HasSBOMInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InArt []*model.ArtifactInputSpec - PkgArt *model.PackageOrArtifactInputs - InSrc []*model.SourceInputSpec - IsDeps []testDependency - IsOccs []testOccurrence - Calls []call - Query *model.HasSBOMSpec - ExpHS []*model.HasSbom - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{p1}, - PkgArt: &model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - HS: &model.HasSBOMInputSpec{ - URI: "test uri", - }, - }, - }, - Query: &model.HasSBOMSpec{ - URI: ptrfrom.String("test uri"), - }, - ExpHS: []*model.HasSbom{ - { - Subject: p1out, - URI: "test uri", - IncludedSoftware: []model.PackageOrArtifact{p1out}, - }, - }, - }, - { - Name: "Ingest same twice", - InPkg: []*model.PkgInputSpec{p1}, - PkgArt: &model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - HS: &model.HasSBOMInputSpec{ - URI: "test uri", - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - HS: &model.HasSBOMInputSpec{ - URI: "test uri", - }, - }, - }, - Query: &model.HasSBOMSpec{ - URI: ptrfrom.String("test uri"), - }, - ExpHS: []*model.HasSbom{ - { - Subject: p1out, - URI: "test uri", - IncludedSoftware: []model.PackageOrArtifact{p1out}, - }, - }, - }, - { - Name: "Query on URI", - InPkg: []*model.PkgInputSpec{p1}, - PkgArt: &model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - HS: &model.HasSBOMInputSpec{ - URI: "test uri one", - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - HS: &model.HasSBOMInputSpec{ - URI: "test uri two", - }, - }, - }, - Query: &model.HasSBOMSpec{ - URI: ptrfrom.String("test uri one"), - }, - ExpHS: []*model.HasSbom{ - { - Subject: p1out, - URI: "test uri one", - IncludedSoftware: []model.PackageOrArtifact{p1out}, - }, - }, - }, - { - Name: "Query on KnownSince", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - HS: &model.HasSBOMInputSpec{ - KnownSince: timeAfterOneSecond, - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - HS: &model.HasSBOMInputSpec{ - KnownSince: curTime, - }, - }, - }, - Query: &model.HasSBOMSpec{ - KnownSince: &timeAfterOneSecond, - }, - ExpHS: []*model.HasSbom{ - { - Subject: p1out, - KnownSince: timeAfterOneSecond, - }, - }, - }, - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{p2, p4}, - InArt: []*model.ArtifactInputSpec{a1}, - PkgArt: &model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p2, p4}, - Artifacts: []*model.ArtifactInputSpec{a1}, - }, - IsDeps: []testDependency{{ - pkg: p2, - depPkg: p4, - matchType: mSpecific, - isDep: &model.IsDependencyInputSpec{ - Justification: "test justification", - }, - }}, - IsOccs: []testOccurrence{{ - Subj: &model.PackageOrSourceInput{Package: p4}, - Art: a1, - isOcc: &model.IsOccurrenceInputSpec{Justification: "test justification"}, - }}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p2, - }, - HS: &model.HasSBOMInputSpec{ - URI: "test uri", - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: p4, - }, - HS: &model.HasSBOMInputSpec{ - URI: "test uri", - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Artifact: a1, - }, - HS: &model.HasSBOMInputSpec{ - URI: "test uri", - }, - }, - }, - Query: &model.HasSBOMSpec{ - Subject: &model.PackageOrArtifactSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String("2.11.1"), - }, - }, - }, - ExpHS: []*model.HasSbom{ - { - Subject: p2out, - URI: "test uri", - IncludedSoftware: []model.PackageOrArtifact{p2out, p4out, a1out}, - IncludedDependencies: []*model.IsDependency{{ - Package: p2out, - DependencyPackage: p4out, - Justification: "test justification", - DependencyType: model.DependencyTypeUnknown, - }}, - IncludedOccurrences: []*model.IsOccurrence{{ - Subject: p4out, - Artifact: a1out, - Justification: "test justification", - }}, - }, - }, - }, - { - Name: "Query on Artifact", - InPkg: []*model.PkgInputSpec{p2}, - InArt: []*model.ArtifactInputSpec{a1, a2}, - PkgArt: &model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p2}, - Artifacts: []*model.ArtifactInputSpec{a1, a2}, - }, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p2, - }, - HS: &model.HasSBOMInputSpec{ - URI: "test uri", - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Artifact: a1, - }, - HS: &model.HasSBOMInputSpec{ - URI: "test uri", - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Artifact: a2, - }, - HS: &model.HasSBOMInputSpec{ - URI: "test uri", - }, - }, - }, - Query: &model.HasSBOMSpec{ - Subject: &model.PackageOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha1"), - }, - }, - }, - ExpHS: []*model.HasSbom{ - { - Subject: a2out, - URI: "test uri", - IncludedSoftware: []model.PackageOrArtifact{p2out, a1out, a2out}, - }, - }, - }, - { - Name: "Query on Algorithm", - InPkg: []*model.PkgInputSpec{p1}, - PkgArt: &model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - HS: &model.HasSBOMInputSpec{ - Algorithm: "QWERasdf", - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - HS: &model.HasSBOMInputSpec{ - Algorithm: "QWERasdf two", - }, - }, - }, - Query: &model.HasSBOMSpec{ - Algorithm: ptrfrom.String("QWERASDF"), - }, - ExpHS: []*model.HasSbom{ - { - Subject: p1out, - Algorithm: "qwerasdf", - IncludedSoftware: []model.PackageOrArtifact{p1out}, - }, - }, - }, - { - Name: "Query on Digest", - InPkg: []*model.PkgInputSpec{p2, p4}, - PkgArt: &model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p2, p4}, - Artifacts: []*model.ArtifactInputSpec{a1}, - }, - IsDeps: []testDependency{{ - pkg: p2, - depPkg: p4, - matchType: mSpecific, - isDep: &model.IsDependencyInputSpec{ - Justification: "test justification", - }, - }}, - IsOccs: []testOccurrence{{ - Subj: &model.PackageOrSourceInput{Package: p4}, - Art: a1, - isOcc: &model.IsOccurrenceInputSpec{Justification: "test justification"}, - }}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p2, - }, - HS: &model.HasSBOMInputSpec{ - Digest: "QWERasdf", - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: p2, - }, - HS: &model.HasSBOMInputSpec{ - Digest: "QWERasdf two", - }, - }, - }, - Query: &model.HasSBOMSpec{ - Digest: ptrfrom.String("QWERASDF"), - }, - ExpHS: []*model.HasSbom{ - { - Subject: p2out, - Digest: "qwerasdf", - IncludedSoftware: []model.PackageOrArtifact{p2out, p4out, a1out}, - IncludedDependencies: []*model.IsDependency{{ - Package: p2out, - DependencyPackage: p4out, - Justification: "test justification", - DependencyType: model.DependencyTypeUnknown, - }}, - IncludedOccurrences: []*model.IsOccurrence{{ - Subject: p4out, - Artifact: a1out, - Justification: "test justification", - }}, - }, - }, - }, - { - Name: "Query on DownloadLocation", - InPkg: []*model.PkgInputSpec{p1}, - PkgArt: &model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - HS: &model.HasSBOMInputSpec{ - DownloadLocation: "location one", - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - HS: &model.HasSBOMInputSpec{ - DownloadLocation: "location two", - }, - }, - }, - Query: &model.HasSBOMSpec{ - DownloadLocation: ptrfrom.String("location two"), - }, - ExpHS: []*model.HasSbom{ - { - Subject: p1out, - DownloadLocation: "location two", - IncludedSoftware: []model.PackageOrArtifact{p1out}, - }, - }, - }, - { - Name: "Query none", - InPkg: []*model.PkgInputSpec{p1}, - PkgArt: &model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - HS: &model.HasSBOMInputSpec{ - DownloadLocation: "location one", - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - HS: &model.HasSBOMInputSpec{ - DownloadLocation: "location two", - }, - }, - }, - Query: &model.HasSBOMSpec{ - DownloadLocation: ptrfrom.String("location three"), - }, - ExpHS: nil, - }, - { - Name: "Query multiple", - InPkg: []*model.PkgInputSpec{p1, p2}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - HS: &model.HasSBOMInputSpec{ - DownloadLocation: "location one", - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - HS: &model.HasSBOMInputSpec{ - DownloadLocation: "location two", - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: p2, - }, - HS: &model.HasSBOMInputSpec{ - DownloadLocation: "location two", - }, - }, - }, - Query: &model.HasSBOMSpec{ - DownloadLocation: ptrfrom.String("location two"), - }, - ExpHS: []*model.HasSbom{ - { - Subject: p2out, - DownloadLocation: "location two", - }, - { - Subject: p1out, - DownloadLocation: "location two", - }, - }, - }, - { - Name: "Query on ID", - InPkg: []*model.PkgInputSpec{p1}, - PkgArt: &model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - HS: &model.HasSBOMInputSpec{ - DownloadLocation: "location one", - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - HS: &model.HasSBOMInputSpec{ - DownloadLocation: "location two", - }, - }, - }, - Query: &model.HasSBOMSpec{ - ID: ptrfrom.String("6"), - }, - ExpHS: []*model.HasSbom{ - { - Subject: p1out, - DownloadLocation: "location two", - IncludedSoftware: []model.PackageOrArtifact{p1out}, - }, - }, - }, - { - Name: "Ingest without subject", - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - HS: &model.HasSBOMInputSpec{ - DownloadLocation: "location one", - }, - }, - }, - ExpIngestErr: true, - }, - { - Name: "Query without hasSBOMSpec", - InPkg: []*model.PkgInputSpec{p1}, - PkgArt: &model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - HS: &model.HasSBOMInputSpec{ - DownloadLocation: "location one", - }, - }, - }, - Query: nil, - ExpHS: []*model.HasSbom{ - { - Subject: p1out, - DownloadLocation: "location one", - IncludedSoftware: []model.PackageOrArtifact{p1out}, - }, - }, - }, - { - Name: "Includeds - include without filters", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedSoftware - Valid Included Package ID", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Package: &model.PkgSpec{ID: ptrfrom.String("8")}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedSoftware - Invalid Included Package ID", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Package: &model.PkgSpec{ID: ptrfrom.String("10000")}}}}, - ExpHS: nil, - }, - { - Name: "IncludedSoftware - Valid Included Package Namespace", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Package: &model.PkgSpec{Namespace: includedPackage2.Namespace}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedSoftware - Invalid Included Package Namespace", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Package: &model.PkgSpec{Namespace: ptrfrom.String("invalid_namespace")}}}}, - ExpHS: nil, - }, - { - Name: "IncludedSoftware - Valid Included Package Name", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Package: &model.PkgSpec{Name: &includedPackage2.Name}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedSoftware - Invalid Included Package Name", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Package: &model.PkgSpec{Name: ptrfrom.String("invalid_name")}}}}, - ExpHS: nil, - }, - { - Name: "IncludedSoftware - Valid Included Package Version", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Package: &model.PkgSpec{Version: includedPackage2.Version}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedSoftware - Invalid Included Package Version", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Package: &model.PkgSpec{Version: ptrfrom.String("v1.0.0-invalid-version")}}}}, - ExpHS: nil, - }, - { - Name: "IncludedSoftware - Valid Included Package Qualifier", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Package: &model.PkgSpec{Qualifiers: []*model.PackageQualifierSpec{{Key: includedPackage2QualifierKey, Value: ptrfrom.String(includedPackage2QualifierValue)}}}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedSoftware - Invalid Included Package Qualifier Key", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Package: &model.PkgSpec{Qualifiers: []*model.PackageQualifierSpec{{Key: "invalid_qualifier_key", Value: ptrfrom.String(includedPackage2QualifierValue)}}}}}}, - ExpHS: nil, - }, - { - Name: "IncludedSoftware - Invalid Subject Package Qualifier Value", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Package: &model.PkgSpec{Qualifiers: []*model.PackageQualifierSpec{{Key: includedPackage2QualifierKey, Value: ptrfrom.String("invalid_qualifier_value")}}}}}}, - ExpHS: nil, - }, - { - Name: "IncludedSoftware - Valid Included Package Subpath", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Package: &model.PkgSpec{Subpath: includedPackage2.Subpath}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedSoftware - Invalid Included Package Subpath", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Package: &model.PkgSpec{Subpath: ptrfrom.String("invalid_subpath")}}}}, - ExpHS: nil, - }, - { - Name: "IncludedSoftware - Valid Included Artifact ID", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Artifact: &model.ArtifactSpec{ID: ptrfrom.String("13")}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedSoftware - Invalid Included Artifact ID", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Artifact: &model.ArtifactSpec{ID: ptrfrom.String("10000")}}}}, - ExpHS: nil, - }, - { - Name: "IncludedSoftware - Valid Included Artifact Algorithm", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Artifact: &model.ArtifactSpec{Algorithm: &includedArtifact1.Algorithm}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedSoftware - Invalid Included Artifact Algorithm", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Artifact: &model.ArtifactSpec{Algorithm: ptrfrom.String("invalid_algorithm")}}}}, - ExpHS: nil, - }, - { - Name: "IncludedSoftware - Valid Included Artifact Digest", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Artifact: &model.ArtifactSpec{Digest: &includedArtifact1.Digest}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedSoftware - Invalid Included Artifact Digest", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedSoftware: []*model.PackageOrArtifactSpec{{Artifact: &model.ArtifactSpec{Digest: ptrfrom.String("invalid_digest")}}}}, - ExpHS: nil, - }, - { - Name: "IncludedDependencies - Valid Included ID", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{ID: ptrfrom.String("19")}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedDependencies - Invalid Included ID", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{ID: ptrfrom.String("10000")}}}, - ExpHS: nil, - }, - { - Name: "IncludedDependencies - Valid Included Package ID", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{ID: ptrfrom.String("4")}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedDependencies - Invalid Included Package ID", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{ID: ptrfrom.String("10000")}}}}, - ExpHS: nil, - }, - { - Name: "IncludedDependencies - Valid Included Package Namespace", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{Namespace: includedPackage1.Namespace}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedDependencies - Invalid Included Package Namespace", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{Namespace: ptrfrom.String("invalid_namespace")}}}}, - ExpHS: nil, - }, - { - Name: "IncludedDependencies - Valid Included Package Name", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{Name: &includedPackage1.Name}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedDependencies - Invalid Included Package Name", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{Name: ptrfrom.String("invalid_name")}}}}, - ExpHS: nil, - }, - { - Name: "IncludedDependencies - Valid Included Package Version", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{Version: includedPackage1.Version}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedDependencies - Invalid Included Package Version", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{Version: ptrfrom.String("v1.0.0-invalid-version")}}}}, - ExpHS: nil, - }, - { - Name: "IncludedDependencies - Valid Included Package Qualifier", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{Qualifiers: []*model.PackageQualifierSpec{{Key: includedPackage1QualifierKey, Value: ptrfrom.String(includedPackage1QualifierValue)}}}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedDependencies - Invalid Included Package Qualifier Key", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{Qualifiers: []*model.PackageQualifierSpec{{Key: "invalid_qualifier_key", Value: ptrfrom.String(includedPackage1QualifierValue)}}}}}}, - ExpHS: nil, - }, - { - Name: "IncludedDependencies - Invalid Subject Package Qualifier Value", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{Qualifiers: []*model.PackageQualifierSpec{{Key: includedPackage1QualifierKey, Value: ptrfrom.String("invalid_qualifier_value")}}}}}}, - ExpHS: nil, - }, - { - Name: "IncludedDependencies - Valid Included Package Subpath", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{Subpath: includedPackage1.Subpath}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedDependencies - Invalid Included Package Subpath", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{Subpath: ptrfrom.String("invalid_subpath")}}}}, - ExpHS: nil, - }, - - { - Name: "IncludedDependencies - Valid Included DependencyPackage ID", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{DependencyPackage: &model.PkgSpec{ID: ptrfrom.String("8")}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedDependencies - Invalid Included DependencyPackage ID", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{DependencyPackage: &model.PkgSpec{ID: ptrfrom.String("10000")}}}}, - ExpHS: nil, - }, - { - Name: "IncludedDependencies - Valid Included DependencyPackage Namespace", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{DependencyPackage: &model.PkgSpec{Namespace: includedPackage2.Namespace}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedDependencies - Invalid Included DependencyPackage Namespace", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{DependencyPackage: &model.PkgSpec{Namespace: ptrfrom.String("invalid_namespace")}}}}, - ExpHS: nil, - }, - { - Name: "IncludedDependencies - Valid Included DependencyPackage Name", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{DependencyPackage: &model.PkgSpec{Name: &includedPackage2.Name}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedDependencies - Invalid Included DependencyPackage Name", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{DependencyPackage: &model.PkgSpec{Name: ptrfrom.String("invalid_name")}}}}, - ExpHS: nil, - }, - { - Name: "IncludedDependencies - Valid Included DependencyPackage Version", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{DependencyPackage: &model.PkgSpec{Version: includedPackage2.Version}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedDependencies - Invalid Included DependencyPackage Version", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{DependencyPackage: &model.PkgSpec{Version: ptrfrom.String("v1.0.0-invalid-version")}}}}, - ExpHS: nil, - }, - { - Name: "IncludedDependencies - Valid Included DependencyPackage Qualifier", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{DependencyPackage: &model.PkgSpec{Qualifiers: []*model.PackageQualifierSpec{{Key: includedPackage2QualifierKey, Value: ptrfrom.String(includedPackage2QualifierValue)}}}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedDependencies - Invalid Included DependencyPackage Qualifier Key", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{DependencyPackage: &model.PkgSpec{Qualifiers: []*model.PackageQualifierSpec{{Key: "invalid_qualifier_key", Value: ptrfrom.String(includedPackage2QualifierValue)}}}}}}, - ExpHS: nil, - }, - { - Name: "IncludedDependencies - Invalid Subject DependencyPackage Qualifier Value", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{DependencyPackage: &model.PkgSpec{Qualifiers: []*model.PackageQualifierSpec{{Key: includedPackage2QualifierKey, Value: ptrfrom.String("invalid_qualifier_value")}}}}}}, - ExpHS: nil, - }, - { - Name: "IncludedDependencies - Valid Included DependencyPackage Subpath", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{DependencyPackage: &model.PkgSpec{Subpath: includedPackage2.Subpath}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedDependencies - Invalid Included DependencyPackage Subpath", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{DependencyPackage: &model.PkgSpec{Subpath: ptrfrom.String("invalid_subpath")}}}}, - ExpHS: nil, - }, - { - Name: "IncludedDependencies - Valid Included Package ID and DependencyPackage ID", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{ID: ptrfrom.String("4")}, DependencyPackage: &model.PkgSpec{ID: ptrfrom.String("8")}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedDependencies - Valid Included Package ID and Invalid DependencyPackage ID", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{ID: ptrfrom.String("4")}, DependencyPackage: &model.PkgSpec{ID: ptrfrom.String("10000")}}}}, - ExpHS: nil, - }, - { - Name: "IncludedDependencies - Invalid Included Package ID and Valid DependencyPackage ID", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{ID: ptrfrom.String("10000")}, DependencyPackage: &model.PkgSpec{ID: ptrfrom.String("8")}}}}, - ExpHS: nil, - }, - { - Name: "IncludedDependencies - Valid Included Package Name and DependencyPackage Name", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{Name: &includedPackage1.Name}, DependencyPackage: &model.PkgSpec{Name: &includedPackage2.Name}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedDependencies - Valid Included Package Name and Invalid DependencyPackage Name", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{Name: &includedPackage1.Name}, DependencyPackage: &model.PkgSpec{Name: ptrfrom.String("invalid_name")}}}}, - ExpHS: nil, - }, - { - Name: "IncludedDependencies - Invalid Included Package Name and Valid DependencyPackage Name", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Package: &model.PkgSpec{Name: ptrfrom.String("invalid_name")}, DependencyPackage: &model.PkgSpec{Name: &includedPackage2.Name}}}}, - ExpHS: nil, - }, - { - Name: "IncludedDependencies - Valid Included VersionRange", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{VersionRange: &includedDependency1.VersionRange}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedDependencies - Invalid Included VersionRange", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{VersionRange: ptrfrom.String("invalid_range")}}}, - ExpHS: nil, - }, - { - Name: "IncludedDependencies - Valid Included DependencyType", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{DependencyType: &includedDependency1.DependencyType}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedDependencies - Invalid Included DependencyType", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{DependencyType: (*model.DependencyType)(ptrfrom.String(string(model.DependencyTypeUnknown)))}}}, - ExpHS: nil, - }, - { - Name: "IncludedDependencies - Valid Included Justification", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Justification: &includedDependency1.Justification}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedDependencies - Invalid Included Justification", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Justification: ptrfrom.String("invalid_justification")}}}, - ExpHS: nil, - }, - { - Name: "IncludedDependencies - Valid Included Origin", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Origin: &includedDependency1.Origin}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedDependencies - Invalid Included Origin", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Origin: ptrfrom.String("invalid_origin")}}}, - ExpHS: nil, - }, - { - Name: "IncludedDependencies - Valid Included Collector", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Collector: &includedDependency1.Collector}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedDependencies - Invalid Included Collector", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedDependencies: []*model.IsDependencySpec{{Collector: ptrfrom.String("invalid_collector")}}}, - ExpHS: nil, - }, - { - Name: "IncludedOccurrences - Valid Included ID", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{ID: ptrfrom.String("21")}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedOccurrences - Invalid Included ID", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{ID: ptrfrom.String("10000")}}}, - ExpHS: nil, - }, - { - Name: "IncludedOccurrences - Valid Included Package ID", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Package: &model.PkgSpec{ID: ptrfrom.String("4")}}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedOccurrences - Invalid Included Package ID", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Package: &model.PkgSpec{ID: ptrfrom.String("10000")}}}}}, - ExpHS: nil, - }, - { - Name: "IncludedOccurrences - Valid Included Package Namespace", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Package: &model.PkgSpec{Namespace: includedPackage1.Namespace}}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedOccurrences - Invalid Included Package Namespace", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Package: &model.PkgSpec{Namespace: ptrfrom.String("invalid_namespace")}}}}}, - ExpHS: nil, - }, - { - Name: "IncludedOccurrences - Valid Included Package Name", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Package: &model.PkgSpec{Name: ptrfrom.String("p1_name")}}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedOccurrences - Invalid Included Package Name", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Package: &model.PkgSpec{Name: ptrfrom.String("invalid_name")}}}}}, - ExpHS: nil, - }, - { - Name: "IncludedOccurrences - Valid Included Package Version", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Package: &model.PkgSpec{Version: includedPackage1.Version}}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedOccurrences - Invalid Included Package Version", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Package: &model.PkgSpec{Version: ptrfrom.String("v1.0.0-invalid-version")}}}}}, - ExpHS: nil, - }, - { - Name: "IncludedOccurrences - Valid Included Package Qualifier", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Package: &model.PkgSpec{Qualifiers: []*model.PackageQualifierSpec{{Key: includedPackage1QualifierKey, Value: ptrfrom.String(includedPackage1QualifierValue)}}}}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedOccurrences - Invalid Included Package Qualifier Key", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Package: &model.PkgSpec{Qualifiers: []*model.PackageQualifierSpec{{Key: "invalid_qualifier_key", Value: ptrfrom.String(includedPackage1QualifierValue)}}}}}}}, - ExpHS: nil, - }, - { - Name: "IncludedOccurrences - Invalid Subject Package Qualifier Value", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Package: &model.PkgSpec{Qualifiers: []*model.PackageQualifierSpec{{Key: includedPackage1QualifierKey, Value: ptrfrom.String("invalid_qualifier_value")}}}}}}}, - ExpHS: nil, - }, - { - Name: "IncludedOccurrences - Valid Included Package Subpath", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Package: &model.PkgSpec{Subpath: includedPackage1.Subpath}}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedOccurrences - Invalid Included Package Subpath", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Package: &model.PkgSpec{Subpath: ptrfrom.String("invalid_subpath")}}}}}, - ExpHS: nil, - }, - { - Name: "IncludedOccurrences - Valid Included Source ID", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Source: &model.SourceSpec{ID: ptrfrom.String("17")}}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedOccurrences - Invalid Included Source ID", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Source: &model.SourceSpec{ID: ptrfrom.String("10000")}}}}}, - ExpHS: nil, - }, - { - Name: "IncludedOccurrences - Valid Included Source", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - // TODO (knrc) - source currently needs to be an exact match, does this need to change? - Query: &model.HasSBOMSpec{ - IncludedOccurrences: []*model.IsOccurrenceSpec{ - { - Subject: &model.PackageOrSourceSpec{ - Source: &model.SourceSpec{ - Type: &includedSource.Type, - Namespace: &includedSource.Namespace, - Name: &includedSource.Name, - Tag: includedSource.Tag, - Commit: includedSource.Commit, - }, - }, - }, - }, - }, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedOccurrences - Invalid Included Source Type", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Source: &model.SourceSpec{ - Type: ptrfrom.String("invalid_type"), - Namespace: &includedSource.Namespace, - Name: &includedSource.Name, - Tag: includedSource.Tag, - Commit: includedSource.Commit, - }}}}}, - ExpHS: nil, - }, - { - Name: "IncludedOccurrences - Invalid Included Source Namespace", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Source: &model.SourceSpec{ - Type: &includedSource.Type, - Namespace: ptrfrom.String("invalid_namespace"), - Name: &includedSource.Name, - Tag: includedSource.Tag, - Commit: includedSource.Commit, - }}}}}, - ExpHS: nil, - }, - { - Name: "IncludedOccurrences - Invalid Included Source Name", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Source: &model.SourceSpec{ - Type: &includedSource.Type, - Namespace: &includedSource.Namespace, - Name: ptrfrom.String("invalid_name"), - Tag: includedSource.Tag, - Commit: includedSource.Commit, - }}}}}, - ExpHS: nil, - }, - { - Name: "IncludedOccurrences - Invalid Included Source Tag", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Source: &model.SourceSpec{ - Type: &includedSource.Type, - Namespace: &includedSource.Namespace, - Name: &includedSource.Name, - Tag: ptrfrom.String("invalid_tag"), - Commit: includedSource.Commit, - }}}}}, - ExpHS: nil, - }, - { - Name: "IncludedOccurrences - Invalid Included Source Commit", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Subject: &model.PackageOrSourceSpec{Source: &model.SourceSpec{ - Type: &includedSource.Type, - Namespace: &includedSource.Namespace, - Name: &includedSource.Name, - Tag: includedSource.Tag, - Commit: ptrfrom.String("invalid_commit"), - }}}}}, - ExpHS: nil, - }, - { - Name: "IncludedOccurrences - Valid Included Artifact ID", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Artifact: &model.ArtifactSpec{ID: ptrfrom.String("13")}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedOccurrences - Invalid Included Artifact ID", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Artifact: &model.ArtifactSpec{ID: ptrfrom.String("10000")}}}}, - ExpHS: nil, - }, - { - Name: "IncludedOccurrences - Valid Included Artifact Algorithm", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Artifact: &model.ArtifactSpec{Algorithm: &includedArtifact1.Algorithm}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedOccurrences - Invalid Included Artifact Algorithm", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Artifact: &model.ArtifactSpec{Algorithm: ptrfrom.String("invalid_algorithm")}}}}, - ExpHS: nil, - }, - { - Name: "IncludedOccurrences - Valid Included Artifact Digest", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Artifact: &model.ArtifactSpec{Digest: &includedArtifact1.Digest}}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedOccurrences - Invalid Included Artifact Digest", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Artifact: &model.ArtifactSpec{Digest: ptrfrom.String("invalid_digest")}}}}, - ExpHS: nil, - }, - { - Name: "IncludedOccurrences - Valid Included Justification", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Justification: &includedOccurrence.Justification}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedOccurrences - Invalid Included Justification", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Justification: ptrfrom.String("invalid_justification")}}}, - ExpHS: nil, - }, - { - Name: "IncludedOccurrences - Valid Included Origin", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Origin: &includedOccurrence.Origin}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedOccurrences - Invalid Included Origin", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Origin: ptrfrom.String("invalid_origin")}}}, - ExpHS: nil, - }, - { - Name: "IncludedOccurrences - Valid Included Collector", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Collector: &includedOccurrence.Collector}}}, - ExpHS: []*model.HasSbom{includedTestExpectedSBOM}, - }, - { - Name: "IncludedOccurrences - Invalid Included Collector", - InPkg: includedPackages, - InArt: includedArtifacts, - InSrc: includedSources, - PkgArt: includedPackageArtifacts, - IsDeps: includedTestDependencies, - IsOccs: includedTestOccurrences, - Calls: []call{{ - Sub: model.PackageOrArtifactInput{ - Package: includedPackage1, - }, - HS: includedHasSBOM, - }}, - Query: &model.HasSBOMSpec{IncludedOccurrences: []*model.IsOccurrenceSpec{{Collector: ptrfrom.String("invalid_collector")}}}, - ExpHS: nil, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - ctx := context.Background() - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - includes := model.HasSBOMIncludesInputSpec{} - if test.PkgArt != nil { - if pkgs, err := b.IngestPackages(ctx, test.PkgArt.Packages); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } else { - for _, pkg := range pkgs { - includes.Software = append(includes.Software, pkg.PackageVersionID) - } - } - if arts, err := b.IngestArtifacts(ctx, test.PkgArt.Artifacts); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } else { - includes.Software = append(includes.Software, arts...) - } - } - - for _, dep := range test.IsDeps { - if isDep, err := b.IngestDependency(ctx, *dep.pkg, *dep.depPkg, dep.matchType, *dep.isDep); err != nil { - t.Fatalf("Could not ingest dependency: %v", err) - } else { - includes.Dependencies = append(includes.Dependencies, isDep) - } - } - - for _, occ := range test.IsOccs { - if isOcc, err := b.IngestOccurrence(ctx, *occ.Subj, *occ.Art, *occ.isOcc); err != nil { - t.Fatalf("Could not ingest occurrence: %v", err) - } else { - includes.Occurrences = append(includes.Occurrences, isOcc) - } - } - for _, o := range test.Calls { - _, err := b.IngestHasSbom(ctx, o.Sub, *o.HS, includes) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.HasSBOM(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpHS, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func TestIngestHasSBOMs(t *testing.T) { - type call struct { - Sub model.PackageOrArtifactInputs - HS []*model.HasSBOMInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InArt []*model.ArtifactInputSpec - PkgArt *model.PackageOrArtifactInputs - IsDeps []testDependency - IsOccs []testOccurrence - Calls []call - Query *model.HasSBOMSpec - ExpHS []*model.HasSbom - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{p1}, - PkgArt: &model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - Calls: []call{ - { - Sub: model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - HS: []*model.HasSBOMInputSpec{ - { - URI: "test uri", - }, - }, - }, - }, - Query: &model.HasSBOMSpec{ - URI: ptrfrom.String("test uri"), - }, - ExpHS: []*model.HasSbom{ - { - Subject: p1out, - URI: "test uri", - IncludedSoftware: []model.PackageOrArtifact{p1out}, - }, - }, - }, - { - Name: "Ingest same twice", - InPkg: []*model.PkgInputSpec{p1}, - PkgArt: &model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - Calls: []call{ - { - Sub: model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1, p1}, - }, - HS: []*model.HasSBOMInputSpec{ - { - URI: "test uri", - }, - { - URI: "test uri", - }, - }, - }, - }, - Query: &model.HasSBOMSpec{ - URI: ptrfrom.String("test uri"), - }, - ExpHS: []*model.HasSbom{ - { - Subject: p1out, - URI: "test uri", - IncludedSoftware: []model.PackageOrArtifact{p1out}, - }, - }, - }, - { - Name: "Query on URI", - InPkg: []*model.PkgInputSpec{p1}, - PkgArt: &model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - Calls: []call{ - { - Sub: model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1, p1}, - }, - HS: []*model.HasSBOMInputSpec{ - { - URI: "test uri one", - }, - { - URI: "test uri two", - }, - }, - }, - }, - Query: &model.HasSBOMSpec{ - URI: ptrfrom.String("test uri one"), - }, - ExpHS: []*model.HasSbom{ - { - Subject: p1out, - URI: "test uri one", - IncludedSoftware: []model.PackageOrArtifact{p1out}, - }, - }, - }, - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{p2, p4}, - InArt: []*model.ArtifactInputSpec{a1}, - PkgArt: &model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p2, p4}, - Artifacts: []*model.ArtifactInputSpec{a1}, - }, - IsDeps: []testDependency{{ - pkg: p2, - depPkg: p4, - matchType: mSpecific, - isDep: &model.IsDependencyInputSpec{ - Justification: "test justification", - }, - }}, - IsOccs: []testOccurrence{{ - Subj: &model.PackageOrSourceInput{Package: p4}, - Art: a1, - isOcc: &model.IsOccurrenceInputSpec{Justification: "test justification"}, - }}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p2, p4}, - }, - HS: []*model.HasSBOMInputSpec{ - { - URI: "test uri", - }, - { - URI: "test uri", - }, - }, - }, - { - Sub: model.PackageOrArtifactInputs{ - Artifacts: []*model.ArtifactInputSpec{a1}, - }, - HS: []*model.HasSBOMInputSpec{ - { - URI: "test uri", - }, - }, - }, - }, - Query: &model.HasSBOMSpec{ - Subject: &model.PackageOrArtifactSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String("2.11.1"), - }, - }, - }, - ExpHS: []*model.HasSbom{ - { - Subject: p2out, - URI: "test uri", - IncludedSoftware: []model.PackageOrArtifact{p2out, p4out, a1out}, - IncludedDependencies: []*model.IsDependency{{ - Package: p2out, - DependencyPackage: p4out, - Justification: "test justification", - DependencyType: model.DependencyTypeUnknown, - }}, - IncludedOccurrences: []*model.IsOccurrence{{ - Subject: p4out, - Artifact: a1out, - Justification: "test justification", - }}, - }, - }, - }, - { - Name: "Query on Artifact", - InPkg: []*model.PkgInputSpec{p1}, - InArt: []*model.ArtifactInputSpec{a1, a2}, - PkgArt: &model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - Artifacts: []*model.ArtifactInputSpec{a1, a2}, - }, - IsOccs: []testOccurrence{{ - Subj: &model.PackageOrSourceInput{Package: p1}, - Art: a2, - isOcc: &model.IsOccurrenceInputSpec{Justification: "test justification"}, - }}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - HS: []*model.HasSBOMInputSpec{ - { - URI: "test uri", - }, - }, - }, - { - Sub: model.PackageOrArtifactInputs{ - Artifacts: []*model.ArtifactInputSpec{a1, a2}, - }, - HS: []*model.HasSBOMInputSpec{ - { - URI: "test uri", - }, - { - URI: "test uri", - }, - }, - }, - }, - Query: &model.HasSBOMSpec{ - Subject: &model.PackageOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha1"), - }, - }, - }, - ExpHS: []*model.HasSbom{ - { - Subject: a2out, - URI: "test uri", - IncludedSoftware: []model.PackageOrArtifact{p1out, a1out, a2out}, - IncludedOccurrences: []*model.IsOccurrence{{ - Subject: p1out, - Artifact: a2out, - Justification: "test justification", - }}, - }, - }, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - ctx := context.Background() - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - includes := model.HasSBOMIncludesInputSpec{} - if test.PkgArt != nil { - if pkgs, err := b.IngestPackages(ctx, test.PkgArt.Packages); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } else { - for _, pkg := range pkgs { - includes.Software = append(includes.Software, pkg.PackageVersionID) - } - } - if arts, err := b.IngestArtifacts(ctx, test.PkgArt.Artifacts); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } else { - includes.Software = append(includes.Software, arts...) - } - } - - for _, dep := range test.IsDeps { - if isDep, err := b.IngestDependency(ctx, *dep.pkg, *dep.depPkg, dep.matchType, *dep.isDep); err != nil { - t.Fatalf("Could not ingest dependency: %v", err) - } else { - includes.Dependencies = append(includes.Dependencies, isDep) - } - } - - for _, occ := range test.IsOccs { - if isOcc, err := b.IngestOccurrence(ctx, *occ.Subj, *occ.Art, *occ.isOcc); err != nil { - t.Fatalf("Could not ingest occurrence: %v", err) - } else { - includes.Occurrences = append(includes.Occurrences, isOcc) - } - } - for _, o := range test.Calls { - var sbomIncludes []*model.HasSBOMIncludesInputSpec - for count := 0; count < len(o.HS); count++ { - sbomIncludes = append(sbomIncludes, &includes) - } - _, err := b.IngestHasSBOMs(ctx, o.Sub, o.HS, sbomIncludes) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.HasSBOM(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpHS, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func TestHasSBOMNeighbors(t *testing.T) { - type call struct { - Sub model.PackageOrArtifactInput - HS *model.HasSBOMInputSpec - } - - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InArt []*model.ArtifactInputSpec - PkgArt *model.PackageOrArtifactInputs - IsDeps []testDependency - IsOccs []testOccurrence - Calls []call - ExpNeighbors map[string][]string - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{p2, p4}, - PkgArt: &model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p2, p4}, - Artifacts: []*model.ArtifactInputSpec{a1}, - }, - IsDeps: []testDependency{{ - pkg: p2, - depPkg: p4, - matchType: mSpecific, - isDep: &model.IsDependencyInputSpec{ - Justification: "test justification", - }, - }}, - IsOccs: []testOccurrence{{ - Subj: &model.PackageOrSourceInput{Package: p4}, - Art: a1, - isOcc: &model.IsOccurrenceInputSpec{Justification: "test justification"}, - }}, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p2, - }, - HS: &model.HasSBOMInputSpec{ - URI: "test uri", - }, - }, - }, - /* - * 1 - p2 Package - * 2 - p2 PackageNamespace - * 3 - p2 PackageName - * 4 - p2 PackageVersion - * 5 - p4 Package - * 6 - p4 PackageNamespace - * 7 - p4 PackageName - * 8 - p4 PackageVersion - * 9 - a1 Artifact - * 10 - IsDependency - * 11 - IsOccurrence - * 12 - HasSBOM - */ - ExpNeighbors: map[string][]string{ - "4": {"3", "10", "12"}, // p2 PackageVersion -> p2 PackageName, IsDependency, HasSBOM - "8": {"7", "10", "11"}, // p4 PackageVersion -> P4 PackageName, IsDependency, IsOccurrence - "9": {"11"}, // a1 Artifact -> IsOccurrence - "10": {"4", "8"}, // IsDependency -> p2 PackageVersion, p4 PackageVersion - "11": {"8", "9"}, // IsOccurrence -> p4 PackageVersion, a1 Artifact - "12": {"4", "8", "9", "10", "11"}, // HasSBOM -> p2 PackageVersion, p4 PackageVersion, a1 Artifact, IsDependency, IsOccurrence - }, - }, - { - Name: "Pkg and Artifact", - InPkg: []*model.PkgInputSpec{p1}, - InArt: []*model.ArtifactInputSpec{a1}, - PkgArt: &model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - Artifacts: []*model.ArtifactInputSpec{a1}, - }, - Calls: []call{ - { - Sub: model.PackageOrArtifactInput{ - Package: p1, - }, - HS: &model.HasSBOMInputSpec{ - URI: "test uri", - }, - }, - { - Sub: model.PackageOrArtifactInput{ - Artifact: a1, - }, - HS: &model.HasSBOMInputSpec{ - URI: "test uri", - }, - }, - }, - /* - * 1 - p1 Package - * 2 - p1 PackageNamespace - * 3 - p1 PackageName - * 4 - p1 PackageVersion - * 5 - a1 Artifact - * 6 - HasSBOM - * 7 - HasSBOM - */ - ExpNeighbors: map[string][]string{ - "4": {"3", "6"}, // p1 PackageVersion -> p1 PackageName, p1 HasSBOM - "5": {"7"}, // artifact -> a1 HasSBOM - "6": {"4", "5"}, // p1 HasSBOM -> p1 PackageVersion, a1 Artifact - "7": {"4", "5"}, // p2 HasSBOM -> p1 PackageVersion, a1 Artifact - }, - }, - } - ctx := context.Background() - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - - includes := model.HasSBOMIncludesInputSpec{} - if test.PkgArt != nil { - if pkgs, err := b.IngestPackages(ctx, test.PkgArt.Packages); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } else { - for _, pkg := range pkgs { - includes.Software = append(includes.Software, pkg.PackageVersionID) - } - } - if arts, err := b.IngestArtifacts(ctx, test.PkgArt.Artifacts); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } else { - includes.Software = append(includes.Software, arts...) - } - } - - for _, dep := range test.IsDeps { - if isDep, err := b.IngestDependency(ctx, *dep.pkg, *dep.depPkg, dep.matchType, *dep.isDep); err != nil { - t.Fatalf("Could not ingest dependency: %v", err) - } else { - includes.Dependencies = append(includes.Dependencies, isDep) - } - } - - for _, occ := range test.IsOccs { - if isOcc, err := b.IngestOccurrence(ctx, *occ.Subj, *occ.Art, *occ.isOcc); err != nil { - t.Fatalf("Could not ingest occurrence: %v", err) - } else { - includes.Occurrences = append(includes.Occurrences, isOcc) - } - } - - for _, o := range test.Calls { - if _, err := b.IngestHasSbom(ctx, o.Sub, *o.HS, includes); err != nil { - t.Fatalf("Could not ingest HasSBOM: %v", err) - } - } - for q, r := range test.ExpNeighbors { - got, err := b.Neighbors(ctx, q, nil) - if err != nil { - t.Fatalf("Could not query neighbors: %s", err) - } - gotIDs, err := getNodeIds(got) - if err != nil { - t.Fatalf("Could not retrieve neighbor ids: %s", err) - } - slices.Sort(r) - slices.Sort(gotIDs) - if diff := cmp.Diff(r, gotIDs); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - } - }) - } -} diff --git a/pkg/assembler/backends/keyvalue/hasSLSA.go b/pkg/assembler/backends/keyvalue/hasSLSA.go index ba6966c261..b2dbead993 100644 --- a/pkg/assembler/backends/keyvalue/hasSLSA.go +++ b/pkg/assembler/backends/keyvalue/hasSLSA.go @@ -189,7 +189,7 @@ func matchSLSAPreds(haves []*model.SLSAPredicate, wants []*model.SLSAPredicateSp // Ingest HasSlsa -func (c *demoClient) IngestSLSAs(ctx context.Context, subjects []*model.ArtifactInputSpec, builtFromList [][]*model.ArtifactInputSpec, builtByList []*model.BuilderInputSpec, slsaList []*model.SLSAInputSpec) ([]string, error) { +func (c *demoClient) IngestSLSAs(ctx context.Context, subjects []*model.IDorArtifactInput, builtFromList [][]*model.IDorArtifactInput, builtByList []*model.IDorBuilderInput, slsaList []*model.SLSAInputSpec) ([]string, error) { var modelHasSLSAList []string for i := range subjects { hasSLSA, err := c.IngestSLSA(ctx, *subjects[i], builtFromList[i], *builtByList[i], *slsaList[i]) @@ -202,15 +202,15 @@ func (c *demoClient) IngestSLSAs(ctx context.Context, subjects []*model.Artifact } func (c *demoClient) IngestSLSA(ctx context.Context, - subject model.ArtifactInputSpec, builtFrom []*model.ArtifactInputSpec, - builtBy model.BuilderInputSpec, slsa model.SLSAInputSpec, + subject model.IDorArtifactInput, builtFrom []*model.IDorArtifactInput, + builtBy model.IDorBuilderInput, slsa model.SLSAInputSpec, ) (string, error) { return c.ingestSLSA(ctx, subject, builtFrom, builtBy, slsa, true) } func (c *demoClient) ingestSLSA(ctx context.Context, - subject model.ArtifactInputSpec, builtFrom []*model.ArtifactInputSpec, - builtBy model.BuilderInputSpec, slsa model.SLSAInputSpec, readOnly bool) ( + subject model.IDorArtifactInput, builtFrom []*model.IDorArtifactInput, + builtBy model.IDorBuilderInput, slsa model.SLSAInputSpec, readOnly bool) ( string, error, ) { preds := convSLSAP(slsa.SlsaPredicate) @@ -233,7 +233,7 @@ func (c *demoClient) ingestSLSA(ctx context.Context, lock(&c.m, readOnly) defer unlock(&c.m, readOnly) - s, err := c.artifactByInput(ctx, &subject) + s, err := c.returnFoundArtifact(ctx, &subject) if err != nil { return "", gqlerror.Errorf("IngestSLSA :: Subject artifact not found") } @@ -242,7 +242,7 @@ func (c *demoClient) ingestSLSA(ctx context.Context, var bfs []*artStruct var bfIDs []string for i, a := range builtFrom { - b, err := c.artifactByInput(ctx, a) + b, err := c.returnFoundArtifact(ctx, a) if err != nil { return "", gqlerror.Errorf("IngestSLSA :: BuiltFrom %d artifact not found", i) } @@ -252,7 +252,7 @@ func (c *demoClient) ingestSLSA(ctx context.Context, slices.Sort(bfIDs) in.BuiltFrom = bfIDs - b, err := c.builderByInput(ctx, &builtBy) + b, err := c.returnFoundBuilder(ctx, &builtBy) if err != nil { return "", gqlerror.Errorf("IngestSLSA :: Builder not found") } diff --git a/pkg/assembler/backends/keyvalue/hasSLSA_test.go b/pkg/assembler/backends/keyvalue/hasSLSA_test.go deleted file mode 100644 index b2cc7fcfd5..0000000000 --- a/pkg/assembler/backends/keyvalue/hasSLSA_test.go +++ /dev/null @@ -1,848 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package keyvalue_test - -import ( - "context" - "slices" - "strings" - "testing" - "time" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/internal/testing/stablememmap" - "github.com/guacsec/guac/pkg/assembler/backends" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -var b1 = &model.BuilderInputSpec{ - URI: "asdf", -} - -var b1out = &model.Builder{ - URI: "asdf", -} - -var b2 = &model.BuilderInputSpec{ - URI: "qwer", -} - -func TestHasSLSA(t *testing.T) { - testTime := time.Unix(1e9+5, 0) - testTime2 := time.Unix(1e9, 0) - type call struct { - Sub *model.ArtifactInputSpec - BF []*model.ArtifactInputSpec - BB *model.BuilderInputSpec - SLSA *model.SLSAInputSpec - } - tests := []struct { - Name string - InArt []*model.ArtifactInputSpec - InBld []*model.BuilderInputSpec - Calls []call - Query *model.HasSLSASpec - ExpHS []*model.HasSlsa - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InArt: []*model.ArtifactInputSpec{a1, a2}, - InBld: []*model.BuilderInputSpec{b1}, - Calls: []call{ - { - Sub: a1, - BF: []*model.ArtifactInputSpec{a2}, - BB: b1, - SLSA: &model.SLSAInputSpec{ - BuildType: "test type", - }, - }, - }, - Query: &model.HasSLSASpec{ - BuildType: ptrfrom.String("test type"), - }, - ExpHS: []*model.HasSlsa{ - { - Subject: a1out, - Slsa: &model.Slsa{ - BuiltBy: b1out, - BuiltFrom: []*model.Artifact{a2out}, - BuildType: "test type", - }, - }, - }, - }, - { - Name: "Ingest twice", - InArt: []*model.ArtifactInputSpec{a1, a2}, - InBld: []*model.BuilderInputSpec{b1}, - Calls: []call{ - { - Sub: a1, - BF: []*model.ArtifactInputSpec{a2}, - BB: b1, - SLSA: &model.SLSAInputSpec{ - BuildType: "test type", - }, - }, - { - Sub: a1, - BF: []*model.ArtifactInputSpec{a2}, - BB: b1, - SLSA: &model.SLSAInputSpec{ - BuildType: "test type", - }, - }, - }, - Query: &model.HasSLSASpec{ - BuildType: ptrfrom.String("test type"), - }, - ExpHS: []*model.HasSlsa{ - { - Subject: a1out, - Slsa: &model.Slsa{ - BuiltBy: b1out, - BuiltFrom: []*model.Artifact{a2out}, - BuildType: "test type", - }, - }, - }, - }, - { - Name: "Query on Build Type", - InArt: []*model.ArtifactInputSpec{a1, a2}, - InBld: []*model.BuilderInputSpec{b1}, - Calls: []call{ - { - Sub: a1, - BF: []*model.ArtifactInputSpec{a2}, - BB: b1, - SLSA: &model.SLSAInputSpec{ - BuildType: "test type one", - }, - }, - { - Sub: a1, - BF: []*model.ArtifactInputSpec{a2}, - BB: b1, - SLSA: &model.SLSAInputSpec{ - BuildType: "test type two", - }, - }, - }, - Query: &model.HasSLSASpec{ - BuildType: ptrfrom.String("test type one"), - }, - ExpHS: []*model.HasSlsa{ - { - Subject: a1out, - Slsa: &model.Slsa{ - BuiltBy: b1out, - BuiltFrom: []*model.Artifact{a2out}, - BuildType: "test type one", - }, - }, - }, - }, - { - Name: "Query on Version", - InArt: []*model.ArtifactInputSpec{a1, a2}, - InBld: []*model.BuilderInputSpec{b1}, - Calls: []call{ - { - Sub: a1, - BF: []*model.ArtifactInputSpec{a2}, - BB: b1, - SLSA: &model.SLSAInputSpec{ - SlsaVersion: "test type one", - }, - }, - { - Sub: a1, - BF: []*model.ArtifactInputSpec{a2}, - BB: b1, - SLSA: &model.SLSAInputSpec{ - SlsaVersion: "test type two", - }, - }, - }, - Query: &model.HasSLSASpec{ - SlsaVersion: ptrfrom.String("test type two"), - }, - ExpHS: []*model.HasSlsa{ - { - Subject: a1out, - Slsa: &model.Slsa{ - BuiltBy: b1out, - BuiltFrom: []*model.Artifact{a2out}, - SlsaVersion: "test type two", - }, - }, - }, - }, - { - Name: "Query on Time", - InArt: []*model.ArtifactInputSpec{a1, a2}, - InBld: []*model.BuilderInputSpec{b1}, - Calls: []call{ - { - Sub: a1, - BF: []*model.ArtifactInputSpec{a2}, - BB: b1, - SLSA: &model.SLSAInputSpec{ - StartedOn: &testTime2, - }, - }, - { - Sub: a1, - BF: []*model.ArtifactInputSpec{a2}, - BB: b1, - SLSA: &model.SLSAInputSpec{ - StartedOn: &testTime, - }, - }, - }, - Query: &model.HasSLSASpec{ - StartedOn: &testTime, - }, - ExpHS: []*model.HasSlsa{ - { - Subject: a1out, - Slsa: &model.Slsa{ - BuiltBy: b1out, - BuiltFrom: []*model.Artifact{a2out}, - StartedOn: &testTime, - }, - }, - }, - }, - { - Name: "Query on Subject", - InArt: []*model.ArtifactInputSpec{a1, a2, a3}, - InBld: []*model.BuilderInputSpec{b1}, - Calls: []call{ - { - Sub: a1, - BF: []*model.ArtifactInputSpec{a2}, - BB: b1, - SLSA: &model.SLSAInputSpec{}, - }, - { - Sub: a3, - BF: []*model.ArtifactInputSpec{a2}, - BB: b1, - SLSA: &model.SLSAInputSpec{}, - }, - }, - Query: &model.HasSLSASpec{ - Subject: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha256"), - }, - }, - ExpHS: []*model.HasSlsa{ - { - Subject: a1out, - Slsa: &model.Slsa{ - BuiltBy: b1out, - BuiltFrom: []*model.Artifact{a2out}, - }, - }, - }, - }, - { - Name: "Query on Materials", - InArt: []*model.ArtifactInputSpec{a1, a2, a3, a4}, - InBld: []*model.BuilderInputSpec{b1}, - Calls: []call{ - { - Sub: a1, - BF: []*model.ArtifactInputSpec{a2}, - BB: b1, - SLSA: &model.SLSAInputSpec{}, - }, - { - Sub: a1, - BF: []*model.ArtifactInputSpec{a2, a3}, - BB: b1, - SLSA: &model.SLSAInputSpec{}, - }, - { - Sub: a1, - BF: []*model.ArtifactInputSpec{a4}, - BB: b1, - SLSA: &model.SLSAInputSpec{}, - }, - }, - Query: &model.HasSLSASpec{ - BuiltFrom: []*model.ArtifactSpec{{ - Digest: ptrfrom.String("7A8F47318E4676DACB0142AFA0B83029CD7BEFD9"), - }}, - }, - ExpHS: []*model.HasSlsa{ - { - Subject: a1out, - Slsa: &model.Slsa{ - BuiltBy: b1out, - BuiltFrom: []*model.Artifact{a2out}, - }, - }, - { - Subject: a1out, - Slsa: &model.Slsa{ - BuiltBy: b1out, - BuiltFrom: []*model.Artifact{a2out, a3out}, - }, - }, - }, - }, - { - Name: "Query on Builder", - InArt: []*model.ArtifactInputSpec{a1, a2}, - InBld: []*model.BuilderInputSpec{b1, b2}, - Calls: []call{ - { - Sub: a1, - BF: []*model.ArtifactInputSpec{a2}, - BB: b1, - SLSA: &model.SLSAInputSpec{}, - }, - { - Sub: a1, - BF: []*model.ArtifactInputSpec{a2}, - BB: b2, - SLSA: &model.SLSAInputSpec{}, - }, - }, - Query: &model.HasSLSASpec{ - BuiltBy: &model.BuilderSpec{ - URI: ptrfrom.String("asdf"), - }, - }, - ExpHS: []*model.HasSlsa{ - { - Subject: a1out, - Slsa: &model.Slsa{ - BuiltBy: b1out, - BuiltFrom: []*model.Artifact{a2out}, - }, - }, - }, - }, - { - Name: "Query on ID", - InArt: []*model.ArtifactInputSpec{a1, a2}, - InBld: []*model.BuilderInputSpec{b1, b2}, - Calls: []call{ - { - Sub: a1, - BF: []*model.ArtifactInputSpec{a2}, - BB: b1, - SLSA: &model.SLSAInputSpec{}, - }, - { - Sub: a1, - BF: []*model.ArtifactInputSpec{a2}, - BB: b2, - SLSA: &model.SLSAInputSpec{}, - }, - }, - Query: &model.HasSLSASpec{ - ID: ptrfrom.String("5"), - }, - ExpHS: []*model.HasSlsa{ - { - Subject: a1out, - Slsa: &model.Slsa{ - BuiltBy: b1out, - BuiltFrom: []*model.Artifact{a2out}, - }, - }, - }, - }, - { - Name: "Query none", - InArt: []*model.ArtifactInputSpec{a1, a2}, - InBld: []*model.BuilderInputSpec{b1, b2}, - Calls: []call{ - { - Sub: a1, - BF: []*model.ArtifactInputSpec{a2}, - BB: b1, - SLSA: &model.SLSAInputSpec{}, - }, - { - Sub: a1, - BF: []*model.ArtifactInputSpec{a2}, - BB: b2, - SLSA: &model.SLSAInputSpec{}, - }, - }, - Query: &model.HasSLSASpec{ - BuiltBy: &model.BuilderSpec{ - URI: ptrfrom.String("poiu"), - }, - }, - ExpHS: nil, - }, - { - Name: "Ingest no Materials 1", - InArt: []*model.ArtifactInputSpec{a1}, - InBld: []*model.BuilderInputSpec{b1}, - Calls: []call{ - { - Sub: a1, - BF: nil, - BB: b2, - SLSA: &model.SLSAInputSpec{}, - }, - }, - ExpIngestErr: true, - }, - { - Name: "Ingest no Materials 2", - InArt: []*model.ArtifactInputSpec{a1}, - InBld: []*model.BuilderInputSpec{b1}, - Calls: []call{ - { - Sub: a1, - BF: []*model.ArtifactInputSpec{}, - BB: b2, - SLSA: &model.SLSAInputSpec{}, - }, - }, - ExpIngestErr: true, - }, - { - Name: "Ingest no Sub", - InArt: []*model.ArtifactInputSpec{a2}, - InBld: []*model.BuilderInputSpec{b2}, - Calls: []call{ - { - Sub: a1, - BF: []*model.ArtifactInputSpec{a2}, - BB: b2, - SLSA: &model.SLSAInputSpec{}, - }, - }, - ExpIngestErr: true, - }, - { - Name: "Ingest no matrials found", - InArt: []*model.ArtifactInputSpec{a1}, - InBld: []*model.BuilderInputSpec{b2}, - Calls: []call{ - { - Sub: a1, - BF: []*model.ArtifactInputSpec{a2}, - BB: b2, - SLSA: &model.SLSAInputSpec{}, - }, - }, - ExpIngestErr: true, - }, - { - Name: "Ingest no builder found", - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - Sub: a1, - BF: []*model.ArtifactInputSpec{a2}, - BB: b2, - SLSA: &model.SLSAInputSpec{}, - }, - }, - ExpIngestErr: true, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - ctx := context.Background() - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - for _, bld := range test.InBld { - if _, err := b.IngestBuilder(ctx, bld); err != nil { - t.Fatalf("Could not ingest builder: %v", err) - } - } - for _, o := range test.Calls { - _, err := b.IngestSLSA(ctx, *o.Sub, o.BF, *o.BB, *o.SLSA) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.HasSlsa(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpHS, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func TestIngestHasSLSAs(t *testing.T) { - type call struct { - Sub []*model.ArtifactInputSpec - BF [][]*model.ArtifactInputSpec - BB []*model.BuilderInputSpec - SLSA []*model.SLSAInputSpec - } - tests := []struct { - Name string - InArt []*model.ArtifactInputSpec - InBld []*model.BuilderInputSpec - Calls []call - Query *model.HasSLSASpec - ExpHS []*model.HasSlsa - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InArt: []*model.ArtifactInputSpec{a1, a2}, - InBld: []*model.BuilderInputSpec{b1}, - Calls: []call{ - { - Sub: []*model.ArtifactInputSpec{a1}, - BF: [][]*model.ArtifactInputSpec{{a2}}, - BB: []*model.BuilderInputSpec{b1}, - SLSA: []*model.SLSAInputSpec{ - { - BuildType: "test type", - }, - }, - }, - }, - Query: &model.HasSLSASpec{ - BuildType: ptrfrom.String("test type"), - }, - ExpHS: []*model.HasSlsa{ - { - Subject: a1out, - Slsa: &model.Slsa{ - BuiltBy: b1out, - BuiltFrom: []*model.Artifact{a2out}, - BuildType: "test type", - }, - }, - }, - }, - { - Name: "Ingest twice", - InArt: []*model.ArtifactInputSpec{a1, a2}, - InBld: []*model.BuilderInputSpec{b1}, - Calls: []call{ - { - Sub: []*model.ArtifactInputSpec{a1, a1}, - BF: [][]*model.ArtifactInputSpec{{a2}, {a2}}, - BB: []*model.BuilderInputSpec{b1, b1}, - SLSA: []*model.SLSAInputSpec{ - { - BuildType: "test type", - }, - { - BuildType: "test type", - }, - }, - }, - }, - Query: &model.HasSLSASpec{ - BuildType: ptrfrom.String("test type"), - }, - ExpHS: []*model.HasSlsa{ - { - Subject: a1out, - Slsa: &model.Slsa{ - BuiltBy: b1out, - BuiltFrom: []*model.Artifact{a2out}, - BuildType: "test type", - }, - }, - }, - }, - { - Name: "Query on Build Type", - InArt: []*model.ArtifactInputSpec{a1, a2}, - InBld: []*model.BuilderInputSpec{b1}, - Calls: []call{ - { - Sub: []*model.ArtifactInputSpec{a1, a1}, - BF: [][]*model.ArtifactInputSpec{{a2}, {a2}}, - BB: []*model.BuilderInputSpec{b1, b1}, - SLSA: []*model.SLSAInputSpec{ - { - BuildType: "test type one", - }, - { - BuildType: "test type two", - }, - }, - }, - }, - Query: &model.HasSLSASpec{ - BuildType: ptrfrom.String("test type one"), - }, - ExpHS: []*model.HasSlsa{ - { - Subject: a1out, - Slsa: &model.Slsa{ - BuiltBy: b1out, - BuiltFrom: []*model.Artifact{a2out}, - BuildType: "test type one", - }, - }, - }, - }, - { - Name: "Query on Subject", - InArt: []*model.ArtifactInputSpec{a1, a2, a3}, - InBld: []*model.BuilderInputSpec{b1}, - Calls: []call{ - { - Sub: []*model.ArtifactInputSpec{a1, a3}, - BF: [][]*model.ArtifactInputSpec{{a2}, {a2}}, - BB: []*model.BuilderInputSpec{b1, b1}, - SLSA: []*model.SLSAInputSpec{ - {}, - {}, - }, - }, - }, - Query: &model.HasSLSASpec{ - Subject: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha256"), - }, - }, - ExpHS: []*model.HasSlsa{ - { - Subject: a1out, - Slsa: &model.Slsa{ - BuiltBy: b1out, - BuiltFrom: []*model.Artifact{a2out}, - }, - }, - }, - }, - { - Name: "Query on Materials", - InArt: []*model.ArtifactInputSpec{a1, a2, a3, a4}, - InBld: []*model.BuilderInputSpec{b1}, - Calls: []call{ - { - Sub: []*model.ArtifactInputSpec{a1, a1, a1}, - BF: [][]*model.ArtifactInputSpec{{a2}, {a2, a3}, {a4}}, - BB: []*model.BuilderInputSpec{b1, b1, b1}, - SLSA: []*model.SLSAInputSpec{ - {}, - {}, - {}, - }, - }, - }, - Query: &model.HasSLSASpec{ - BuiltFrom: []*model.ArtifactSpec{{ - Digest: ptrfrom.String("7A8F47318E4676DACB0142AFA0B83029CD7BEFD9"), - }}, - }, - ExpHS: []*model.HasSlsa{ - { - Subject: a1out, - Slsa: &model.Slsa{ - BuiltBy: b1out, - BuiltFrom: []*model.Artifact{a2out}, - }, - }, - { - Subject: a1out, - Slsa: &model.Slsa{ - BuiltBy: b1out, - BuiltFrom: []*model.Artifact{a2out, a3out}, - }, - }, - }, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - ctx := context.Background() - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - for _, bld := range test.InBld { - if _, err := b.IngestBuilder(ctx, bld); err != nil { - t.Fatalf("Could not ingest builder: %v", err) - } - } - for _, o := range test.Calls { - _, err := b.IngestSLSAs(ctx, o.Sub, o.BF, o.BB, o.SLSA) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.HasSlsa(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpHS, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func TestHasSLSANeighbors(t *testing.T) { - type call struct { - Sub *model.ArtifactInputSpec - BF []*model.ArtifactInputSpec - BB *model.BuilderInputSpec - SLSA *model.SLSAInputSpec - } - tests := []struct { - Name string - InArt []*model.ArtifactInputSpec - InBld []*model.BuilderInputSpec - Calls []call - ExpNeighbors map[string][]string - }{ - { - Name: "HappyPath", - InArt: []*model.ArtifactInputSpec{a1, a2}, - InBld: []*model.BuilderInputSpec{b1}, - Calls: []call{ - { - Sub: a1, - BF: []*model.ArtifactInputSpec{a2}, - BB: b1, - SLSA: &model.SLSAInputSpec{ - BuildType: "test type", - }, - }, - }, - ExpNeighbors: map[string][]string{ - "1": {"4"}, // a1 - "2": {"4"}, // a2 - "3": {"4"}, // b1 - "4": {"1", "2", "3"}, // hasSBOM - }, - }, - { - Name: "Multiple", - InArt: []*model.ArtifactInputSpec{a1, a2, a3, a4}, - InBld: []*model.BuilderInputSpec{b1}, - Calls: []call{ - { - Sub: a1, - BF: []*model.ArtifactInputSpec{a2}, - BB: b1, - SLSA: &model.SLSAInputSpec{ - BuildType: "test type", - }, - }, - { - Sub: a3, - BF: []*model.ArtifactInputSpec{a4}, - BB: b1, - SLSA: &model.SLSAInputSpec{ - BuildType: "test type", - }, - }, - }, - ExpNeighbors: map[string][]string{ - "1": {"6"}, // a1 - "2": {"6"}, // a2 - "3": {"7"}, // a3 - "4": {"7"}, // a4 - "5": {"6", "7"}, // b1 - "6": {"1", "2", "5"}, // hasSBOM 1 - "7": {"3", "4", "5"}, // hasSBOM 2 - }, - }, - } - ctx := context.Background() - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - for _, bld := range test.InBld { - if _, err := b.IngestBuilder(ctx, bld); err != nil { - t.Fatalf("Could not ingest builder: %v", err) - } - } - for _, o := range test.Calls { - if _, err := b.IngestSLSA(ctx, *o.Sub, o.BF, *o.BB, *o.SLSA); err != nil { - t.Fatalf("Could not ingest HasSLSA: %v", err) - } - } - for q, r := range test.ExpNeighbors { - got, err := b.Neighbors(ctx, q, nil) - if err != nil { - t.Fatalf("Could not query neighbors: %s", err) - } - gotIDs := convNodes(got) - slices.Sort(r) - slices.Sort(gotIDs) - if diff := cmp.Diff(r, gotIDs); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - } - }) - } -} diff --git a/pkg/assembler/backends/keyvalue/hasSourceAt.go b/pkg/assembler/backends/keyvalue/hasSourceAt.go index ea4b13decc..2a32c75f7c 100644 --- a/pkg/assembler/backends/keyvalue/hasSourceAt.go +++ b/pkg/assembler/backends/keyvalue/hasSourceAt.go @@ -67,7 +67,7 @@ func (n *srcMapLink) BuildModelNode(ctx context.Context, c *demoClient) (model.N // Ingest HasSourceAt -func (c *demoClient) IngestHasSourceAts(ctx context.Context, pkgs []*model.PkgInputSpec, pkgMatchType *model.MatchFlags, sources []*model.SourceInputSpec, hasSourceAts []*model.HasSourceAtInputSpec) ([]string, error) { +func (c *demoClient) IngestHasSourceAts(ctx context.Context, pkgs []*model.IDorPkgInput, pkgMatchType *model.MatchFlags, sources []*model.IDorSourceInput, hasSourceAts []*model.HasSourceAtInputSpec) ([]string, error) { var modelHasMetadataIDs []string for i := range hasSourceAts { @@ -80,11 +80,11 @@ func (c *demoClient) IngestHasSourceAts(ctx context.Context, pkgs []*model.PkgIn return modelHasMetadataIDs, nil } -func (c *demoClient) IngestHasSourceAt(ctx context.Context, packageArg model.PkgInputSpec, pkgMatchType model.MatchFlags, source model.SourceInputSpec, hasSourceAt model.HasSourceAtInputSpec) (string, error) { +func (c *demoClient) IngestHasSourceAt(ctx context.Context, packageArg model.IDorPkgInput, pkgMatchType model.MatchFlags, source model.IDorSourceInput, hasSourceAt model.HasSourceAtInputSpec) (string, error) { return c.ingestHasSourceAt(ctx, packageArg, pkgMatchType, source, hasSourceAt, true) } -func (c *demoClient) ingestHasSourceAt(ctx context.Context, packageArg model.PkgInputSpec, pkgMatchType model.MatchFlags, source model.SourceInputSpec, hasSourceAt model.HasSourceAtInputSpec, readOnly bool) (string, error) { +func (c *demoClient) ingestHasSourceAt(ctx context.Context, packageArg model.IDorPkgInput, pkgMatchType model.MatchFlags, source model.IDorSourceInput, hasSourceAt model.HasSourceAtInputSpec, readOnly bool) (string, error) { funcName := "IngestHasSourceAt" in := &srcMapLink{ @@ -97,17 +97,18 @@ func (c *demoClient) ingestHasSourceAt(ctx context.Context, packageArg model.Pkg lock(&c.m, readOnly) defer unlock(&c.m, readOnly) - srcName, err := c.getSourceNameFromInput(ctx, source) + var pkgNameOrVersionNode pkgNameOrVersion + var err error + in.PackageID, pkgNameOrVersionNode, err = c.returnFoundPkgBasedOnMatchType(ctx, &packageArg, &pkgMatchType) if err != nil { return "", gqlerror.Errorf("%v :: %s", funcName, err) } - in.SourceID = srcName.ThisID - pkgNameOrVersionNode, err := c.getPackageNameOrVerFromInput(ctx, packageArg, pkgMatchType) + srcName, err := c.returnFoundSource(ctx, &source) if err != nil { return "", gqlerror.Errorf("%v :: %s", funcName, err) } - in.PackageID = pkgNameOrVersionNode.ID() + in.SourceID = srcName.ThisID out, err := byKeykv[*srcMapLink](ctx, hsaCol, in.Key(), c) if err == nil { diff --git a/pkg/assembler/backends/keyvalue/hasSourceAt_test.go b/pkg/assembler/backends/keyvalue/hasSourceAt_test.go deleted file mode 100644 index 438af80d20..0000000000 --- a/pkg/assembler/backends/keyvalue/hasSourceAt_test.go +++ /dev/null @@ -1,883 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package keyvalue_test - -import ( - "context" - "slices" - "strings" - "testing" - "time" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/internal/testing/stablememmap" - "github.com/guacsec/guac/pkg/assembler/backends" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -func TestHasSourceAt(t *testing.T) { - testTime := time.Unix(1e9+5, 0) - type call struct { - Pkg *model.PkgInputSpec - Src *model.SourceInputSpec - Match *model.MatchFlags - HSA *model.HasSourceAtInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - Calls []call - Query *model.HasSourceAtSpec - ExpHSA []*model.HasSourceAt - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{p1}, - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Pkg: p1, - Src: s1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.HasSourceAtSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHSA: []*model.HasSourceAt{ - { - Package: p1out, - Source: s1out, - Justification: "test justification", - }, - }, - }, - { - Name: "HappyPath All Versions", - InPkg: []*model.PkgInputSpec{p1}, - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Pkg: p1, - Src: s1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - HSA: &model.HasSourceAtInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.HasSourceAtSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHSA: []*model.HasSourceAt{ - { - Package: p1outName, - Source: s1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest Same Twice", - InPkg: []*model.PkgInputSpec{p1}, - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Pkg: p1, - Src: s1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{ - Justification: "test justification", - }, - }, - { - Pkg: p1, - Src: s1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.HasSourceAtSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHSA: []*model.HasSourceAt{ - { - Package: p1out, - Source: s1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query On Justification", - InPkg: []*model.PkgInputSpec{p1}, - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Pkg: p1, - Src: s1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{ - Justification: "test justification one", - }, - }, - { - Pkg: p1, - Src: s1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{ - Justification: "test justification two", - }, - }, - }, - Query: &model.HasSourceAtSpec{ - Justification: ptrfrom.String("test justification two"), - }, - ExpHSA: []*model.HasSourceAt{ - { - Package: p1out, - Source: s1out, - Justification: "test justification two", - }, - }, - }, - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{p1, p2}, - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Pkg: p1, - Src: s1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{}, - }, - { - Pkg: p2, - Src: s1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{}, - }, - }, - Query: &model.HasSourceAtSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String("2.11.1"), - }, - }, - ExpHSA: []*model.HasSourceAt{ - { - Package: p2out, - Source: s1out, - }, - }, - }, - { - Name: "Query on Source", - InPkg: []*model.PkgInputSpec{p1}, - InSrc: []*model.SourceInputSpec{s1, s2}, - Calls: []call{ - { - Pkg: p1, - Src: s1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{}, - }, - { - Pkg: p1, - Src: s2, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{}, - }, - }, - Query: &model.HasSourceAtSpec{ - Source: &model.SourceSpec{ - Name: ptrfrom.String("myrepo"), - }, - }, - ExpHSA: []*model.HasSourceAt{ - { - Package: p1out, - Source: s1out, - }, - }, - }, - { - Name: "Query on KnownSince", - InPkg: []*model.PkgInputSpec{p1}, - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Pkg: p1, - Src: s1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{ - KnownSince: time.Unix(1e9, 0), - }, - }, - { - Pkg: p1, - Src: s1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{ - KnownSince: testTime, - }, - }, - }, - Query: &model.HasSourceAtSpec{ - KnownSince: &testTime, - }, - ExpHSA: []*model.HasSourceAt{ - { - Package: p1out, - Source: s1out, - KnownSince: testTime, - }, - }, - }, - { - Name: "Query Multiple", - InPkg: []*model.PkgInputSpec{p1, p2}, - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Pkg: p1, - Src: s1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{ - Justification: "test justification one", - }, - }, - { - Pkg: p1, - Src: s1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{ - Justification: "test justification two", - }, - }, - { - Pkg: p2, - Src: s1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{ - Justification: "test justification two", - }, - }, - }, - Query: &model.HasSourceAtSpec{ - Justification: ptrfrom.String("test justification two"), - }, - ExpHSA: []*model.HasSourceAt{ - { - Package: p1out, - Source: s1out, - Justification: "test justification two", - }, - { - Package: p2out, - Source: s1out, - Justification: "test justification two", - }, - }, - }, - { - Name: "Query None", - InPkg: []*model.PkgInputSpec{p1}, - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Pkg: p1, - Src: s1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{ - Justification: "test justification one", - }, - }, - { - Pkg: p1, - Src: s1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{ - Justification: "test justification two", - }, - }, - }, - Query: &model.HasSourceAtSpec{ - Justification: ptrfrom.String("test justification three"), - }, - ExpHSA: nil, - }, - { - Name: "Query ID", - InPkg: []*model.PkgInputSpec{p1}, - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Pkg: p1, - Src: s1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{ - Justification: "test justification one", - }, - }, - { - Pkg: p1, - Src: s1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{ - Justification: "test justification two", - }, - }, - }, - Query: &model.HasSourceAtSpec{ - ID: ptrfrom.String("9"), - }, - ExpHSA: []*model.HasSourceAt{ - { - Package: p1out, - Source: s1out, - Justification: "test justification two", - }, - }, - }, - { - Name: "Query Name and Version", - InPkg: []*model.PkgInputSpec{p1, p2}, - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Pkg: p1, - Src: s1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{}, - }, - { - Pkg: p1, - Src: s1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - HSA: &model.HasSourceAtInputSpec{}, - }, - { - Pkg: p2, - Src: s1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{}, - }, - }, - Query: &model.HasSourceAtSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String(""), - }, - }, - ExpHSA: []*model.HasSourceAt{ - { - Package: p1out, - Source: s1out, - }, - { - Package: p1outName, - Source: s1out, - }, - }, - }, - { - Name: "Ingest no pkg", - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Pkg: p1, - Src: s1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{}, - }, - }, - ExpIngestErr: true, - }, - { - Name: "Ingest no src", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Pkg: p1, - Src: s1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{}, - }, - }, - ExpIngestErr: true, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - ctx := context.Background() - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, o := range test.Calls { - _, err := b.IngestHasSourceAt(ctx, *o.Pkg, *o.Match, *o.Src, *o.HSA) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.HasSourceAt(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpHSA, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func TestIngestHasSourceAts(t *testing.T) { - testTime := time.Unix(1e9+5, 0) - type call struct { - Pkgs []*model.PkgInputSpec - Srcs []*model.SourceInputSpec - Match *model.MatchFlags - HSAs []*model.HasSourceAtInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - Calls []call - Query *model.HasSourceAtSpec - ExpHSA []*model.HasSourceAt - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{p1}, - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Pkgs: []*model.PkgInputSpec{p1}, - Srcs: []*model.SourceInputSpec{s1}, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSAs: []*model.HasSourceAtInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.HasSourceAtSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHSA: []*model.HasSourceAt{ - { - Package: p1out, - Source: s1out, - Justification: "test justification", - }, - }, - }, - { - Name: "HappyPath All Versions", - InPkg: []*model.PkgInputSpec{p1}, - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Pkgs: []*model.PkgInputSpec{p1}, - Srcs: []*model.SourceInputSpec{s1}, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - HSAs: []*model.HasSourceAtInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.HasSourceAtSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHSA: []*model.HasSourceAt{ - { - Package: p1outName, - Source: s1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest Same Twice", - InPkg: []*model.PkgInputSpec{p1}, - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Pkgs: []*model.PkgInputSpec{p1, p1}, - Srcs: []*model.SourceInputSpec{s1, s1}, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSAs: []*model.HasSourceAtInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.HasSourceAtSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHSA: []*model.HasSourceAt{ - { - Package: p1out, - Source: s1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{p1, p2}, - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Pkgs: []*model.PkgInputSpec{p1, p2}, - Srcs: []*model.SourceInputSpec{s1, s1}, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSAs: []*model.HasSourceAtInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.HasSourceAtSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String("2.11.1"), - }, - }, - ExpHSA: []*model.HasSourceAt{ - { - Package: p2out, - Source: s1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Source", - InPkg: []*model.PkgInputSpec{p1}, - InSrc: []*model.SourceInputSpec{s1, s2}, - Calls: []call{ - { - Pkgs: []*model.PkgInputSpec{p1, p1}, - Srcs: []*model.SourceInputSpec{s1, s2}, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSAs: []*model.HasSourceAtInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.HasSourceAtSpec{ - Source: &model.SourceSpec{ - Name: ptrfrom.String("myrepo"), - }, - }, - ExpHSA: []*model.HasSourceAt{ - { - Package: p1out, - Source: s1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on KnownSince", - InPkg: []*model.PkgInputSpec{p1}, - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Pkgs: []*model.PkgInputSpec{p1, p1}, - Srcs: []*model.SourceInputSpec{s1, s1}, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSAs: []*model.HasSourceAtInputSpec{ - { - KnownSince: time.Unix(1e9, 0), - }, - { - KnownSince: testTime, - }, - }, - }, - }, - Query: &model.HasSourceAtSpec{ - KnownSince: &testTime, - }, - ExpHSA: []*model.HasSourceAt{ - { - Package: p1out, - Source: s1out, - KnownSince: testTime, - }, - }, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - ctx := context.Background() - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, o := range test.Calls { - _, err := b.IngestHasSourceAts(ctx, o.Pkgs, o.Match, o.Srcs, o.HSAs) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.HasSourceAt(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpHSA, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func TestHasSourceAtNeighbors(t *testing.T) { - type call struct { - Pkg *model.PkgInputSpec - Src *model.SourceInputSpec - Match *model.MatchFlags - HSA *model.HasSourceAtInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - Calls []call - ExpNeighbors map[string][]string - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{p1}, - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Pkg: p1, - Src: s1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{ - Justification: "test justification", - }, - }, - }, - ExpNeighbors: map[string][]string{ - "4": {"1", "8"}, // Package Version - "7": {"5", "8"}, // Source Name - "8": {"1", "5"}, // HSA - }, - }, - { - Name: "Package Name and Version", - InPkg: []*model.PkgInputSpec{p1}, - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Pkg: p1, - Src: s1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{ - Justification: "test justification", - }, - }, - { - Pkg: p1, - Src: s1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - HSA: &model.HasSourceAtInputSpec{}, - }, - }, - ExpNeighbors: map[string][]string{ - "3": {"1", "1", "9"}, // Package Name - "4": {"1", "8"}, // Package Version - "7": {"5", "8", "9"}, // Source Name - "8": {"1", "5"}, // HSA -> Version - "9": {"1", "5"}, // HSA -> Name - }, - }, - } - ctx := context.Background() - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, o := range test.Calls { - if _, err := b.IngestHasSourceAt(ctx, *o.Pkg, *o.Match, *o.Src, *o.HSA); err != nil { - t.Fatalf("Could not ingest HasSourceAt: %v", err) - } - } - for q, r := range test.ExpNeighbors { - got, err := b.Neighbors(ctx, q, nil) - if err != nil { - t.Fatalf("Could not query neighbors: %s", err) - } - gotIDs := convNodes(got) - slices.Sort(r) - slices.Sort(gotIDs) - if diff := cmp.Diff(r, gotIDs); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - } - }) - } -} diff --git a/pkg/assembler/backends/keyvalue/hashEqual.go b/pkg/assembler/backends/keyvalue/hashEqual.go index 1382ad948e..4a99ba50c6 100644 --- a/pkg/assembler/backends/keyvalue/hashEqual.go +++ b/pkg/assembler/backends/keyvalue/hashEqual.go @@ -60,7 +60,7 @@ func (n *hashEqualStruct) BuildModelNode(ctx context.Context, c *demoClient) (mo // Ingest HashEqual -func (c *demoClient) IngestHashEquals(ctx context.Context, artifacts []*model.ArtifactInputSpec, otherArtifacts []*model.ArtifactInputSpec, hashEquals []*model.HashEqualInputSpec) ([]string, error) { +func (c *demoClient) IngestHashEquals(ctx context.Context, artifacts []*model.IDorArtifactInput, otherArtifacts []*model.IDorArtifactInput, hashEquals []*model.HashEqualInputSpec) ([]string, error) { var modelHashEquals []string for i := range hashEquals { hashEqual, err := c.IngestHashEqual(ctx, *artifacts[i], *otherArtifacts[i], *hashEquals[i]) @@ -72,11 +72,11 @@ func (c *demoClient) IngestHashEquals(ctx context.Context, artifacts []*model.Ar return modelHashEquals, nil } -func (c *demoClient) IngestHashEqual(ctx context.Context, artifact model.ArtifactInputSpec, equalArtifact model.ArtifactInputSpec, hashEqual model.HashEqualInputSpec) (string, error) { +func (c *demoClient) IngestHashEqual(ctx context.Context, artifact model.IDorArtifactInput, equalArtifact model.IDorArtifactInput, hashEqual model.HashEqualInputSpec) (string, error) { return c.ingestHashEqual(ctx, artifact, equalArtifact, hashEqual, true) } -func (c *demoClient) ingestHashEqual(ctx context.Context, artifact model.ArtifactInputSpec, equalArtifact model.ArtifactInputSpec, hashEqual model.HashEqualInputSpec, readOnly bool) (string, error) { +func (c *demoClient) ingestHashEqual(ctx context.Context, artifact model.IDorArtifactInput, equalArtifact model.IDorArtifactInput, hashEqual model.HashEqualInputSpec, readOnly bool) (string, error) { in := &hashEqualStruct{ Justification: hashEqual.Justification, Origin: hashEqual.Origin, @@ -86,11 +86,11 @@ func (c *demoClient) ingestHashEqual(ctx context.Context, artifact model.Artifac lock(&c.m, readOnly) defer unlock(&c.m, readOnly) - aInt1, err := c.artifactByInput(ctx, &artifact) + aInt1, err := c.returnFoundArtifact(ctx, &artifact) if err != nil { return "", gqlerror.Errorf("IngestHashEqual :: Artifact not found") } - aInt2, err := c.artifactByInput(ctx, &equalArtifact) + aInt2, err := c.returnFoundArtifact(ctx, &equalArtifact) if err != nil { return "", gqlerror.Errorf("IngestHashEqual :: Artifact not found") } diff --git a/pkg/assembler/backends/keyvalue/hashEqual_test.go b/pkg/assembler/backends/keyvalue/hashEqual_test.go deleted file mode 100644 index 5c77b50bef..0000000000 --- a/pkg/assembler/backends/keyvalue/hashEqual_test.go +++ /dev/null @@ -1,794 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package keyvalue_test - -import ( - "context" - "slices" - "strings" - "testing" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/internal/testing/stablememmap" - "github.com/guacsec/guac/pkg/assembler/backends" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -func TestHashEqual(t *testing.T) { - type call struct { - A1 *model.ArtifactInputSpec - A2 *model.ArtifactInputSpec - HE *model.HashEqualInputSpec - } - tests := []struct { - Name string - InArt []*model.ArtifactInputSpec - Calls []call - Query *model.HashEqualSpec - ExpHE []*model.HashEqual - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - A1: a1, - A2: a2, - HE: &model.HashEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.HashEqualSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{a1out, a2out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest same, different order", - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - A1: a1, - A2: a2, - HE: &model.HashEqualInputSpec{ - Justification: "test justification", - }, - }, - { - A1: a2, - A2: a1, - HE: &model.HashEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.HashEqualSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{a1out, a2out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Justification", - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - A1: a1, - A2: a2, - HE: &model.HashEqualInputSpec{ - Justification: "test justification one", - }, - }, - { - A1: a1, - A2: a2, - HE: &model.HashEqualInputSpec{ - Justification: "test justification two", - }, - }, - }, - Query: &model.HashEqualSpec{ - Justification: ptrfrom.String("test justification one"), - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{a1out, a2out}, - Justification: "test justification one", - }, - }, - }, - { - Name: "Query on artifact", - InArt: []*model.ArtifactInputSpec{a1, a2, a3}, - Calls: []call{ - { - A1: a1, - A2: a2, - HE: &model.HashEqualInputSpec{}, - }, - { - A1: a1, - A2: a3, - HE: &model.HashEqualInputSpec{}, - }, - }, - Query: &model.HashEqualSpec{ - Artifacts: []*model.ArtifactSpec{{ - ID: ptrfrom.String("3"), - }}, - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{a1out, a3out}, - }, - }, - }, - { - Name: "Query on artifact multiple", - InArt: []*model.ArtifactInputSpec{a1, a2, a3}, - Calls: []call{ - { - A1: a1, - A2: a2, - HE: &model.HashEqualInputSpec{}, - }, - { - A1: a1, - A2: a3, - HE: &model.HashEqualInputSpec{}, - }, - }, - Query: &model.HashEqualSpec{ - Artifacts: []*model.ArtifactSpec{{ - ID: ptrfrom.String("1"), - }}, - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{a1out, a2out}, - }, - { - Artifacts: []*model.Artifact{a1out, a3out}, - }, - }, - }, - { - Name: "Query on artifact algo", - InArt: []*model.ArtifactInputSpec{a1, a2, a3}, - Calls: []call{ - { - A1: a1, - A2: a2, - HE: &model.HashEqualInputSpec{}, - }, - { - A1: a1, - A2: a3, - HE: &model.HashEqualInputSpec{}, - }, - }, - Query: &model.HashEqualSpec{ - Artifacts: []*model.ArtifactSpec{{ - Algorithm: ptrfrom.String("sha1"), - }}, - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{a1out, a2out}, - }, - }, - }, - { - Name: "Query on artifact algo and hash", - InArt: []*model.ArtifactInputSpec{a1, a2, a3}, - Calls: []call{ - { - A1: a1, - A2: a2, - HE: &model.HashEqualInputSpec{}, - }, - { - A1: a1, - A2: a3, - HE: &model.HashEqualInputSpec{}, - }, - }, - Query: &model.HashEqualSpec{ - Artifacts: []*model.ArtifactSpec{{ - Algorithm: ptrfrom.String("sha1"), - Digest: ptrfrom.String("7A8F47318E4676DACB0142AFA0B83029CD7BEFD9"), - }}, - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{a1out, a2out}, - }, - }, - }, - { - Name: "Query on both artifacts", - InArt: []*model.ArtifactInputSpec{a1, a2, a3}, - Calls: []call{ - { - A1: a1, - A2: a2, - HE: &model.HashEqualInputSpec{}, - }, - { - A1: a2, - A2: a3, - HE: &model.HashEqualInputSpec{}, - }, - }, - Query: &model.HashEqualSpec{ - Artifacts: []*model.ArtifactSpec{ - { - Algorithm: ptrfrom.String("sha1"), - Digest: ptrfrom.String("7A8F47318E4676DACB0142AFA0B83029CD7BEFD9"), - }, - { - ID: ptrfrom.String("3"), - }, - }, - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{a2out, a3out}, - }, - }, - }, - { - Name: "Query on both artifacts, one filter", - InArt: []*model.ArtifactInputSpec{a1, a2, a3}, - Calls: []call{ - { - A1: a1, - A2: a2, - HE: &model.HashEqualInputSpec{}, - }, - { - A1: a2, - A2: a3, - HE: &model.HashEqualInputSpec{}, - }, - { - A1: a1, - A2: a3, - HE: &model.HashEqualInputSpec{}, - }, - }, - Query: &model.HashEqualSpec{ - Artifacts: []*model.ArtifactSpec{ - { - Algorithm: ptrfrom.String("sha1"), - }, - { - Digest: ptrfrom.String("6bbb0da1891646e58eb3e6a63af3a6fc3c8eb5a0d44824cba581d2e14a0450cf"), - }, - }, - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{a1out, a2out}, - }, - }, - }, - { - Name: "Query none", - InArt: []*model.ArtifactInputSpec{a1, a2, a3}, - Calls: []call{ - { - A1: a1, - A2: a2, - HE: &model.HashEqualInputSpec{}, - }, - { - A1: a2, - A2: a3, - HE: &model.HashEqualInputSpec{}, - }, - { - A1: a1, - A2: a3, - HE: &model.HashEqualInputSpec{}, - }, - }, - Query: &model.HashEqualSpec{ - Artifacts: []*model.ArtifactSpec{ - { - Algorithm: ptrfrom.String("gitHash"), - }, - { - Digest: ptrfrom.String("6bbb0da1891646e58eb3e6a63af3a6fc3c8eb5a0d44824cba581d2e14a0450cf"), - }, - }, - }, - ExpHE: nil, - }, - { - Name: "Query on ID", - InArt: []*model.ArtifactInputSpec{a1, a2, a3}, - Calls: []call{ - { - A1: a1, - A2: a2, - HE: &model.HashEqualInputSpec{}, - }, - { - A1: a2, - A2: a3, - HE: &model.HashEqualInputSpec{}, - }, - { - A1: a1, - A2: a3, - HE: &model.HashEqualInputSpec{}, - }, - }, - Query: &model.HashEqualSpec{ - ID: ptrfrom.String("5"), - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{a3out, a2out}, - }, - }, - }, - { - Name: "Ingest no A1", - InArt: []*model.ArtifactInputSpec{a2}, - Calls: []call{ - { - A1: a1, - A2: a2, - HE: &model.HashEqualInputSpec{}, - }, - }, - ExpIngestErr: true, - }, - { - Name: "Ingest no A2", - InArt: []*model.ArtifactInputSpec{a1}, - Calls: []call{ - { - A1: a1, - A2: a2, - HE: &model.HashEqualInputSpec{}, - }, - }, - ExpIngestErr: true, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - ctx := context.Background() - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - for _, o := range test.Calls { - _, err := b.IngestHashEqual(ctx, *o.A1, *o.A2, *o.HE) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.HashEqual(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - less := func(a, b *model.Artifact) int { return strings.Compare(a.Digest, b.Digest) } - for _, he := range got { - slices.SortFunc(he.Artifacts, less) - } - for _, he := range test.ExpHE { - slices.SortFunc(he.Artifacts, less) - } - if diff := cmp.Diff(test.ExpHE, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func TestIngestHashEquals(t *testing.T) { - type call struct { - A1 []*model.ArtifactInputSpec - A2 []*model.ArtifactInputSpec - HE []*model.HashEqualInputSpec - } - tests := []struct { - Name string - InArt []*model.ArtifactInputSpec - Calls []call - Query *model.HashEqualSpec - ExpHE []*model.HashEqual - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - A1: []*model.ArtifactInputSpec{a1}, - A2: []*model.ArtifactInputSpec{a2}, - HE: []*model.HashEqualInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.HashEqualSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{a1out, a2out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest same, different order", - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - A1: []*model.ArtifactInputSpec{a1, a2}, - A2: []*model.ArtifactInputSpec{a2, a1}, - HE: []*model.HashEqualInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.HashEqualSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{a1out, a2out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Justification", - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - A1: []*model.ArtifactInputSpec{a1, a1}, - A2: []*model.ArtifactInputSpec{a2, a2}, - HE: []*model.HashEqualInputSpec{ - { - Justification: "test justification one", - }, - { - Justification: "test justification two", - }, - }, - }, - }, - Query: &model.HashEqualSpec{ - Justification: ptrfrom.String("test justification one"), - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{a1out, a2out}, - Justification: "test justification one", - }, - }, - }, - { - Name: "Query on artifact", - InArt: []*model.ArtifactInputSpec{a1, a2, a3}, - Calls: []call{ - { - A1: []*model.ArtifactInputSpec{a1, a1}, - A2: []*model.ArtifactInputSpec{a2, a3}, - HE: []*model.HashEqualInputSpec{ - {}, - {}, - }, - }, - }, - Query: &model.HashEqualSpec{ - Artifacts: []*model.ArtifactSpec{{ - ID: ptrfrom.String("3"), - }}, - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{a1out, a3out}, - }, - }, - }, - { - Name: "Query on artifact multiple", - InArt: []*model.ArtifactInputSpec{a1, a2, a3}, - Calls: []call{ - { - A1: []*model.ArtifactInputSpec{a1, a1}, - A2: []*model.ArtifactInputSpec{a2, a3}, - HE: []*model.HashEqualInputSpec{ - {}, - {}, - }, - }, - }, - Query: &model.HashEqualSpec{ - Artifacts: []*model.ArtifactSpec{{ - ID: ptrfrom.String("1"), - }}, - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{a1out, a2out}, - }, - { - Artifacts: []*model.Artifact{a1out, a3out}, - }, - }, - }, - { - Name: "Query on artifact algo", - InArt: []*model.ArtifactInputSpec{a1, a2, a3}, - Calls: []call{ - { - A1: []*model.ArtifactInputSpec{a1, a1}, - A2: []*model.ArtifactInputSpec{a2, a3}, - HE: []*model.HashEqualInputSpec{ - {}, - {}, - }, - }, - }, - Query: &model.HashEqualSpec{ - Artifacts: []*model.ArtifactSpec{{ - Algorithm: ptrfrom.String("sha1"), - }}, - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{a1out, a2out}, - }, - }, - }, - { - Name: "Query on artifact algo and hash", - InArt: []*model.ArtifactInputSpec{a1, a2, a3}, - Calls: []call{ - { - A1: []*model.ArtifactInputSpec{a1, a1}, - A2: []*model.ArtifactInputSpec{a2, a3}, - HE: []*model.HashEqualInputSpec{ - {}, - {}, - }, - }, - }, - Query: &model.HashEqualSpec{ - Artifacts: []*model.ArtifactSpec{{ - Algorithm: ptrfrom.String("sha1"), - Digest: ptrfrom.String("7A8F47318E4676DACB0142AFA0B83029CD7BEFD9"), - }}, - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{a1out, a2out}, - }, - }, - }, - { - Name: "Query on both artifacts", - InArt: []*model.ArtifactInputSpec{a1, a2, a3}, - Calls: []call{ - { - A1: []*model.ArtifactInputSpec{a1, a2}, - A2: []*model.ArtifactInputSpec{a2, a3}, - HE: []*model.HashEqualInputSpec{ - {}, - {}, - }, - }, - }, - Query: &model.HashEqualSpec{ - Artifacts: []*model.ArtifactSpec{ - { - Algorithm: ptrfrom.String("sha1"), - Digest: ptrfrom.String("7A8F47318E4676DACB0142AFA0B83029CD7BEFD9"), - }, - { - ID: ptrfrom.String("3"), - }, - }, - }, - ExpHE: []*model.HashEqual{ - { - Artifacts: []*model.Artifact{a2out, a3out}, - }, - }, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - ctx := context.Background() - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - for _, o := range test.Calls { - _, err := b.IngestHashEquals(ctx, o.A1, o.A2, o.HE) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.HashEqual(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - less := func(a, b *model.Artifact) int { return strings.Compare(a.Digest, b.Digest) } - for _, he := range got { - slices.SortFunc(he.Artifacts, less) - } - for _, he := range test.ExpHE { - slices.SortFunc(he.Artifacts, less) - } - if diff := cmp.Diff(test.ExpHE, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func TestHashEqualNeighbors(t *testing.T) { - type call struct { - A1 *model.ArtifactInputSpec - A2 *model.ArtifactInputSpec - HE *model.HashEqualInputSpec - } - tests := []struct { - Name string - InArt []*model.ArtifactInputSpec - Calls []call - ExpNeighbors map[string][]string - }{ - { - Name: "HappyPath", - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - A1: a1, - A2: a2, - HE: &model.HashEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - ExpNeighbors: map[string][]string{ - "1": {"3"}, // a1 - "2": {"3"}, // a2 - "3": {"1", "2"}, // hashequal - }, - }, - { - Name: "Multiple", - InArt: []*model.ArtifactInputSpec{a1, a2, a3}, - Calls: []call{ - { - A1: a1, - A2: a2, - HE: &model.HashEqualInputSpec{ - Justification: "test justification", - }, - }, - { - A1: a1, - A2: a3, - HE: &model.HashEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - ExpNeighbors: map[string][]string{ - "1": {"4", "5"}, // a1 - "2": {"4"}, // a2 - "3": {"5"}, // a3 - "4": {"1", "2"}, // hashequal 1 - "5": {"1", "3"}, // hashequal 2 - }, - }, - } - ctx := context.Background() - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - for _, o := range test.Calls { - if _, err := b.IngestHashEqual(ctx, *o.A1, *o.A2, *o.HE); err != nil { - t.Fatalf("Could not ingest HashEqual: %v", err) - } - } - for q, r := range test.ExpNeighbors { - got, err := b.Neighbors(ctx, q, nil) - if err != nil { - t.Fatalf("Could not query neighbors: %s", err) - } - gotIDs := convNodes(got) - slices.Sort(r) - slices.Sort(gotIDs) - if diff := cmp.Diff(r, gotIDs); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - } - }) - } -} diff --git a/pkg/assembler/backends/keyvalue/isDependency.go b/pkg/assembler/backends/keyvalue/isDependency.go index 26b65224ce..9adae0e68b 100644 --- a/pkg/assembler/backends/keyvalue/isDependency.go +++ b/pkg/assembler/backends/keyvalue/isDependency.go @@ -65,7 +65,7 @@ func (n *isDependencyLink) BuildModelNode(ctx context.Context, c *demoClient) (m // Ingest IngestDependencies -func (c *demoClient) IngestDependencies(ctx context.Context, pkgs []*model.PkgInputSpec, depPkgs []*model.PkgInputSpec, depPkgMatchType model.MatchFlags, dependencies []*model.IsDependencyInputSpec) ([]string, error) { +func (c *demoClient) IngestDependencies(ctx context.Context, pkgs []*model.IDorPkgInput, depPkgs []*model.IDorPkgInput, depPkgMatchType model.MatchFlags, dependencies []*model.IsDependencyInputSpec) ([]string, error) { // TODO(LUMJJB): match flags var modelIsDependencies []string @@ -80,11 +80,11 @@ func (c *demoClient) IngestDependencies(ctx context.Context, pkgs []*model.PkgIn } // Ingest IsDependency -func (c *demoClient) IngestDependency(ctx context.Context, packageArg model.PkgInputSpec, dependentPackageArg model.PkgInputSpec, depPkgMatchType model.MatchFlags, dependency model.IsDependencyInputSpec) (string, error) { +func (c *demoClient) IngestDependency(ctx context.Context, packageArg model.IDorPkgInput, dependentPackageArg model.IDorPkgInput, depPkgMatchType model.MatchFlags, dependency model.IsDependencyInputSpec) (string, error) { return c.ingestDependency(ctx, packageArg, dependentPackageArg, depPkgMatchType, dependency, true) } -func (c *demoClient) ingestDependency(ctx context.Context, packageArg model.PkgInputSpec, dependentPackageArg model.PkgInputSpec, depPkgMatchType model.MatchFlags, dependency model.IsDependencyInputSpec, readOnly bool) (string, error) { +func (c *demoClient) ingestDependency(ctx context.Context, packageArg model.IDorPkgInput, dependentPackageArg model.IDorPkgInput, depPkgMatchType model.MatchFlags, dependency model.IsDependencyInputSpec, readOnly bool) (string, error) { funcName := "IngestDependency" inLink := &isDependencyLink{ @@ -99,20 +99,18 @@ func (c *demoClient) ingestDependency(ctx context.Context, packageArg model.PkgI lock(&c.m, readOnly) defer unlock(&c.m, readOnly) - // for IsDependency the dependent package will return the ID at the - // packageName node. VersionRange will be used to specify the versions are - // the attestation relates to - foundPkgVersion, err := c.getPackageVerFromInput(ctx, packageArg) + var depPkg pkgNameOrVersion + var err error + inLink.DepPackageID, depPkg, err = c.returnFoundPkgBasedOnMatchType(ctx, &dependentPackageArg, &depPkgMatchType) if err != nil { return "", gqlerror.Errorf("%v :: %s", funcName, err) } - inLink.PackageID = foundPkgVersion.ThisID - depPkg, err := c.getPackageNameOrVerFromInput(ctx, dependentPackageArg, depPkgMatchType) + foundPkgVersion, err := c.returnFoundPkgVersion(ctx, &packageArg) if err != nil { return "", gqlerror.Errorf("%v :: %s", funcName, err) } - inLink.DepPackageID = depPkg.ID() + inLink.PackageID = foundPkgVersion.ID() outLink, err := byKeykv[*isDependencyLink](ctx, isDepCol, inLink.Key(), c) if err == nil { diff --git a/pkg/assembler/backends/keyvalue/isDependency_test.go b/pkg/assembler/backends/keyvalue/isDependency_test.go deleted file mode 100644 index de2268c89e..0000000000 --- a/pkg/assembler/backends/keyvalue/isDependency_test.go +++ /dev/null @@ -1,128 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package keyvalue_test - -import ( - "context" - "slices" - "testing" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/stablememmap" - "github.com/guacsec/guac/pkg/assembler/backends" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -var ( - mAll = model.MatchFlags{Pkg: model.PkgMatchTypeAllVersions} - mSpecific = model.MatchFlags{Pkg: model.PkgMatchTypeSpecificVersion} -) - -func TestIsDependencyNeighbors(t *testing.T) { - type call struct { - P1 *model.PkgInputSpec - P2 *model.PkgInputSpec - MF model.MatchFlags - ID *model.IsDependencyInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - Calls []call - ExpNeighbors map[string][]string - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{p1, p2}, - Calls: []call{ - { - P1: p1, - P2: p2, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - }, - ExpNeighbors: map[string][]string{ - "3": {"1", "1", "1", "6"}, // p1/p2 name - "4": {"1", "6"}, // p1 version - "5": {"1"}, // p2 version - "6": {"1", "1"}, // isDep - }, - }, - { - Name: "Multiple", - InPkg: []*model.PkgInputSpec{p1, p2, p4}, - Calls: []call{ - { - P1: p1, - P2: p4, - MF: mAll, - ID: &model.IsDependencyInputSpec{ - Justification: "test justification", - }, - }, - { - P1: p2, - P2: p4, - MF: mAll, - ID: &model.IsDependencyInputSpec{ - Justification: "test justification", - }, - }, - }, - ExpNeighbors: map[string][]string{ - "3": {"1", "1", "1"}, // p1/p2 name, 1 up, 2 down - "4": {"1", "10"}, // p1 version, 1 up, isdep - "5": {"1", "11"}, // p2 version, 1 up, isdep - "8": {"6", "6", "10", "11"}, // p4 name, 1 up, 1 down, 2 isdeps - "10": {"1", "6"}, // isdep 1 - "11": {"1", "6"}, // isdep 2 - }, - }, - } - ctx := context.Background() - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, a := range test.InPkg { - if _, err := b.IngestPackage(ctx, *a); err != nil { - t.Fatalf("Could not ingest pkg: %v", err) - } - } - for _, o := range test.Calls { - if _, err := b.IngestDependency(ctx, *o.P1, *o.P2, o.MF, *o.ID); err != nil { - t.Fatalf("Could not ingest IsDependency: %v", err) - } - } - for q, r := range test.ExpNeighbors { - got, err := b.Neighbors(ctx, q, nil) - if err != nil { - t.Fatalf("Could not query neighbors: %s", err) - } - gotIDs := convNodes(got) - slices.Sort(r) - slices.Sort(gotIDs) - if diff := cmp.Diff(r, gotIDs); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - } - }) - } -} diff --git a/pkg/assembler/backends/keyvalue/isOccurrence.go b/pkg/assembler/backends/keyvalue/isOccurrence.go index a9fa4e7b7d..16b26cdee2 100644 --- a/pkg/assembler/backends/keyvalue/isOccurrence.go +++ b/pkg/assembler/backends/keyvalue/isOccurrence.go @@ -72,7 +72,7 @@ func (n *isOccurrenceStruct) Key() string { // Ingest IngestOccurrences -func (c *demoClient) IngestOccurrences(ctx context.Context, subjects model.PackageOrSourceInputs, artifacts []*model.ArtifactInputSpec, occurrences []*model.IsOccurrenceInputSpec) ([]string, error) { +func (c *demoClient) IngestOccurrences(ctx context.Context, subjects model.PackageOrSourceInputs, artifacts []*model.IDorArtifactInput, occurrences []*model.IsOccurrenceInputSpec) ([]string, error) { var modelIsOccurrences []string for i := range occurrences { @@ -98,11 +98,11 @@ func (c *demoClient) IngestOccurrences(ctx context.Context, subjects model.Packa // Ingest IsOccurrence -func (c *demoClient) IngestOccurrence(ctx context.Context, subject model.PackageOrSourceInput, artifact model.ArtifactInputSpec, occurrence model.IsOccurrenceInputSpec) (string, error) { +func (c *demoClient) IngestOccurrence(ctx context.Context, subject model.PackageOrSourceInput, artifact model.IDorArtifactInput, occurrence model.IsOccurrenceInputSpec) (string, error) { return c.ingestOccurrence(ctx, subject, artifact, occurrence, true) } -func (c *demoClient) ingestOccurrence(ctx context.Context, subject model.PackageOrSourceInput, artifact model.ArtifactInputSpec, occurrence model.IsOccurrenceInputSpec, readOnly bool) (string, error) { +func (c *demoClient) ingestOccurrence(ctx context.Context, subject model.PackageOrSourceInput, artifact model.IDorArtifactInput, occurrence model.IsOccurrenceInputSpec, readOnly bool) (string, error) { funcName := "IngestOccurrence" in := &isOccurrenceStruct{ @@ -114,7 +114,7 @@ func (c *demoClient) ingestOccurrence(ctx context.Context, subject model.Package lock(&c.m, readOnly) defer unlock(&c.m, readOnly) - a, err := c.artifactByInput(ctx, &artifact) + a, err := c.returnFoundArtifact(ctx, &artifact) if err != nil { return "", gqlerror.Errorf("%v :: Artifact not found %s", funcName, err) } @@ -123,9 +123,9 @@ func (c *demoClient) ingestOccurrence(ctx context.Context, subject model.Package var pkgVer *pkgVersion if subject.Package != nil { var err error - pkgVer, err = c.getPackageVerFromInput(ctx, *subject.Package) + pkgVer, err = c.returnFoundPkgVersion(ctx, subject.Package) if err != nil { - return "", gqlerror.Errorf("IngestOccurrence :: %v", err) + return "", gqlerror.Errorf("%v :: %s", funcName, err) } in.Pkg = pkgVer.ThisID } @@ -133,9 +133,9 @@ func (c *demoClient) ingestOccurrence(ctx context.Context, subject model.Package var src *srcNameNode if subject.Source != nil { var err error - src, err = c.getSourceNameFromInput(ctx, *subject.Source) + src, err = c.returnFoundSource(ctx, subject.Source) if err != nil { - return "", gqlerror.Errorf("IngestOccurrence :: %v", err) + return "", gqlerror.Errorf("%v :: %s", funcName, err) } in.Source = src.ThisID } diff --git a/pkg/assembler/backends/keyvalue/isOccurrence_test.go b/pkg/assembler/backends/keyvalue/isOccurrence_test.go deleted file mode 100644 index eeb4407f06..0000000000 --- a/pkg/assembler/backends/keyvalue/isOccurrence_test.go +++ /dev/null @@ -1,786 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package keyvalue_test - -import ( - "context" - "slices" - "strings" - "testing" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/internal/testing/stablememmap" - "github.com/guacsec/guac/pkg/assembler/backends" - "github.com/guacsec/guac/pkg/assembler/graphql/model" - jsoniter "github.com/json-iterator/go" -) - -var json = jsoniter.ConfigCompatibleWithStandardLibrary - -func convNode(n model.Node) hasID { - // All nodes have a json "id" - // Only getting top-level id however - var h hasID - b, _ := json.Marshal(n) - _ = json.Unmarshal(b, &h) - return h -} - -func convNodes(ns []model.Node) []string { - var ids []string - for _, n := range ns { - h := convNode(n) - ids = append(ids, h.ID) - } - return ids -} - -type hasID struct { - ID string `json:"id"` -} - -var a1 = &model.ArtifactInputSpec{ - Algorithm: "sha256", - Digest: "6bbb0da1891646e58eb3e6a63af3a6fc3c8eb5a0d44824cba581d2e14a0450cf", -} - -var a1out = &model.Artifact{ - Algorithm: "sha256", - Digest: "6bbb0da1891646e58eb3e6a63af3a6fc3c8eb5a0d44824cba581d2e14a0450cf", -} - -var a2 = &model.ArtifactInputSpec{ - Algorithm: "sha1", - Digest: "7A8F47318E4676DACB0142AFA0B83029CD7BEFD9", -} - -var a2out = &model.Artifact{ - Algorithm: "sha1", - Digest: "7a8f47318e4676dacb0142afa0b83029cd7befd9", -} - -var a3 = &model.ArtifactInputSpec{ - Algorithm: "sha512", - Digest: "374AB8F711235830769AA5F0B31CE9B72C5670074B34CB302CDAFE3B606233EE92EE01E298E5701F15CC7087714CD9ABD7DDB838A6E1206B3642DE16D9FC9DD7", -} - -var a3out = &model.Artifact{ - Algorithm: "sha512", - Digest: "374ab8f711235830769aa5f0b31ce9b72c5670074b34cb302cdafe3b606233ee92ee01e298e5701f15cc7087714cd9abd7ddb838a6e1206b3642de16d9fc9dd7", -} - -var a4 = &model.ArtifactInputSpec{ - Algorithm: "sha1", - Digest: "5a787865sd676dacb0142afa0b83029cd7befd9", -} - -var p1 = &model.PkgInputSpec{ - Type: "pypi", - Name: "tensorflow", -} - -var p1out = &model.Package{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{{ - Names: []*model.PackageName{{ - Name: "tensorflow", - Versions: []*model.PackageVersion{{ - Version: "", - Qualifiers: []*model.PackageQualifier{}, - }}, - }}, - }}, -} - -var p1outName = &model.Package{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{{ - Names: []*model.PackageName{{ - Name: "tensorflow", - Versions: []*model.PackageVersion{}, - }}, - }}, -} - -var p2 = &model.PkgInputSpec{ - Type: "pypi", - Name: "tensorflow", - Version: ptrfrom.String("2.11.1"), -} - -var p2out = &model.Package{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{{ - Names: []*model.PackageName{{ - Name: "tensorflow", - Versions: []*model.PackageVersion{{ - Version: "2.11.1", - Qualifiers: []*model.PackageQualifier{}, - }}, - }}, - }}, -} - -var p2outName = &model.Package{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{{ - Names: []*model.PackageName{{ - Name: "tensorflow", - Versions: []*model.PackageVersion{}, - }}, - }}, -} - -var p3 = &model.PkgInputSpec{ - Type: "pypi", - Name: "tensorflow", - Version: ptrfrom.String("2.11.1"), - Subpath: ptrfrom.String("saved_model_cli.py"), -} - -var p3out = &model.Package{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{{ - Names: []*model.PackageName{{ - Name: "tensorflow", - Versions: []*model.PackageVersion{{ - Version: "2.11.1", - Subpath: "saved_model_cli.py", - Qualifiers: []*model.PackageQualifier{}, - }}, - }}, - }}, -} - -var p4 = &model.PkgInputSpec{ - Type: "conan", - Namespace: ptrfrom.String("openssl.org"), - Name: "openssl", - Version: ptrfrom.String("3.0.3"), -} - -var p4out = &model.Package{ - Type: "conan", - Namespaces: []*model.PackageNamespace{{ - Namespace: "openssl.org", - Names: []*model.PackageName{{ - Name: "openssl", - Versions: []*model.PackageVersion{{ - Version: "3.0.3", - Qualifiers: []*model.PackageQualifier{}, - }}, - }}, - }}, -} - -var p4outName = &model.Package{ - Type: "conan", - Namespaces: []*model.PackageNamespace{{ - Namespace: "openssl.org", - Names: []*model.PackageName{{ - Name: "openssl", - Versions: []*model.PackageVersion{}, - }}, - }}, -} - -var s1 = &model.SourceInputSpec{ - Type: "git", - Namespace: "github.com/jeff", - Name: "myrepo", -} - -var s1out = &model.Source{ - Type: "git", - Namespaces: []*model.SourceNamespace{{ - Namespace: "github.com/jeff", - Names: []*model.SourceName{{ - Name: "myrepo", - }}, - }}, -} - -var s2 = &model.SourceInputSpec{ - Type: "git", - Namespace: "github.com/bob", - Name: "bobsrepo", -} - -var s2out = &model.Source{ - Type: "git", - Namespaces: []*model.SourceNamespace{{ - Namespace: "github.com/bob", - Names: []*model.SourceName{{ - Name: "bobsrepo", - }}, - }}, -} - -func TestOccurrence(t *testing.T) { - type call struct { - PkgSrc model.PackageOrSourceInput - Artifact *model.ArtifactInputSpec - Occurrence *model.IsOccurrenceInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - InArt []*model.ArtifactInputSpec - Calls []call - Query *model.IsOccurrenceSpec - ExpOcc []*model.IsOccurrence - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{p1}, - InArt: []*model.ArtifactInputSpec{a1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: p1, - }, - Artifact: a1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.IsOccurrenceSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpOcc: []*model.IsOccurrence{ - { - Subject: p1out, - Artifact: a1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Igest same twice", - InPkg: []*model.PkgInputSpec{p1}, - InArt: []*model.ArtifactInputSpec{a1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: p1, - }, - Artifact: a1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "test justification", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Package: p1, - }, - Artifact: a1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.IsOccurrenceSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpOcc: []*model.IsOccurrence{ - { - Subject: p1out, - Artifact: a1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Justification", - InPkg: []*model.PkgInputSpec{p1}, - InArt: []*model.ArtifactInputSpec{a1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: p1, - }, - Artifact: a1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "justification one", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Package: p1, - }, - Artifact: a1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "justification two", - }, - }, - }, - Query: &model.IsOccurrenceSpec{ - Justification: ptrfrom.String("justification one"), - }, - ExpOcc: []*model.IsOccurrence{ - { - Subject: p1out, - Artifact: a1out, - Justification: "justification one", - }, - }, - }, - { - Name: "Query on Artifact", - InPkg: []*model.PkgInputSpec{p1}, - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: p1, - }, - Artifact: a1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "justification", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Package: p1, - }, - Artifact: a2, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "justification", - }, - }, - }, - Query: &model.IsOccurrenceSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha256"), - }, - }, - ExpOcc: []*model.IsOccurrence{ - { - Subject: p1out, - Artifact: a1out, - Justification: "justification", - }, - }, - }, - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{p1, p2}, - InArt: []*model.ArtifactInputSpec{a1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: p1, - }, - Artifact: a1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "justification", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Package: p2, - }, - Artifact: a1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "justification", - }, - }, - }, - Query: &model.IsOccurrenceSpec{ - Subject: &model.PackageOrSourceSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String(""), - }, - }, - }, - ExpOcc: []*model.IsOccurrence{ - { - Subject: p1out, - Artifact: a1out, - Justification: "justification", - }, - }, - }, - { - Name: "Query on Source", - InPkg: []*model.PkgInputSpec{p1}, - InSrc: []*model.SourceInputSpec{s1}, - InArt: []*model.ArtifactInputSpec{a1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: p1, - }, - Artifact: a1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "justification", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Source: s1, - }, - Artifact: a1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "justification", - }, - }, - }, - Query: &model.IsOccurrenceSpec{ - Subject: &model.PackageOrSourceSpec{ - Source: &model.SourceSpec{}, - }, - }, - ExpOcc: []*model.IsOccurrence{ - { - Subject: s1out, - Artifact: a1out, - Justification: "justification", - }, - }, - }, - { - Name: "Query none", - InPkg: []*model.PkgInputSpec{p1}, - InArt: []*model.ArtifactInputSpec{a1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: p1, - }, - Artifact: a1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.IsOccurrenceSpec{ - ID: ptrfrom.String("12345"), - }, - ExpOcc: nil, - }, - { - Name: "Query multiple", - InPkg: []*model.PkgInputSpec{p1}, - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: p1, - }, - Artifact: a1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "test justification", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Package: p1, - }, - Artifact: a2, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.IsOccurrenceSpec{}, - ExpOcc: []*model.IsOccurrence{ - { - Subject: p1out, - Artifact: a1out, - Justification: "test justification", - }, - { - Subject: p1out, - Artifact: a2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest without package", - InPkg: []*model.PkgInputSpec{}, - InArt: []*model.ArtifactInputSpec{a1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: p1, - }, - Artifact: a1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "justification", - }, - }, - }, - ExpIngestErr: true, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - ctx := context.Background() - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - for _, o := range test.Calls { - _, err := b.IngestOccurrence(ctx, o.PkgSrc, *o.Artifact, *o.Occurrence) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.IsOccurrence(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpOcc, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func TestIngestOccurrences(t *testing.T) { - type call struct { - PkgSrcs model.PackageOrSourceInputs - Artifacts []*model.ArtifactInputSpec - Occurrences []*model.IsOccurrenceInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - InArt []*model.ArtifactInputSpec - Calls []call - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath - packages", - InPkg: []*model.PkgInputSpec{p1, p2}, - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - PkgSrcs: model.PackageOrSourceInputs{ - Packages: []*model.PkgInputSpec{p1, p2}, - }, - Artifacts: []*model.ArtifactInputSpec{a1, a2}, - Occurrences: []*model.IsOccurrenceInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - }, - { - Name: "HappyPath - sources", - InSrc: []*model.SourceInputSpec{s1}, - InArt: []*model.ArtifactInputSpec{a1}, - Calls: []call{ - { - PkgSrcs: model.PackageOrSourceInputs{ - Sources: []*model.SourceInputSpec{s1}, - }, - Artifacts: []*model.ArtifactInputSpec{a1}, - Occurrences: []*model.IsOccurrenceInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - }, - } - ctx := context.Background() - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - for _, o := range test.Calls { - _, err := b.IngestOccurrences(ctx, o.PkgSrcs, o.Artifacts, o.Occurrences) - if (err != nil) != test.ExpIngestErr { - t.Errorf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - } - }) - } -} - -func TestOccurrenceNeighbors(t *testing.T) { - type call struct { - PkgSrc model.PackageOrSourceInput - Artifact *model.ArtifactInputSpec - Occurrence *model.IsOccurrenceInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - InArt []*model.ArtifactInputSpec - Calls []call - ExpNeighbors map[string][]string - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{p1}, - InArt: []*model.ArtifactInputSpec{a1}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: p1, - }, - Artifact: a1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "test justification", - }, - }, - }, - ExpNeighbors: map[string][]string{ - "1": {"1"}, - "2": {"1", "1"}, - "3": {"1", "1"}, - "4": {"1", "6"}, // pkg version - "5": {"6"}, // artifact - "6": {"1", "5"}, // isOccurence - }, - }, - { - Name: "Two occurrences", - InPkg: []*model.PkgInputSpec{p1}, - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - PkgSrc: model.PackageOrSourceInput{ - Package: p1, - }, - Artifact: a1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "test justification", - }, - }, - { - PkgSrc: model.PackageOrSourceInput{ - Package: p1, - }, - Artifact: a2, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "test justification", - }, - }, - }, - ExpNeighbors: map[string][]string{ - "4": {"1", "7", "8"}, // pkg version - "5": {"7"}, // artifact1 - "6": {"8"}, // artifact2 - "7": {"1", "5"}, // isOccurence 1 - "8": {"1", "6"}, // isOccurence 2 - }, - }, - } - ctx := context.Background() - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - for _, o := range test.Calls { - if _, err := b.IngestOccurrence(ctx, o.PkgSrc, *o.Artifact, *o.Occurrence); err != nil { - t.Fatalf("Could not ingest isOccurrence: %s", err) - } - } - for q, r := range test.ExpNeighbors { - got, err := b.Neighbors(ctx, q, nil) - if err != nil { - t.Fatalf("Could not query neighbors: %s", err) - } - gotIDs := convNodes(got) - slices.Sort(r) - slices.Sort(gotIDs) - if diff := cmp.Diff(r, gotIDs); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - } - }) - } -} diff --git a/pkg/assembler/backends/keyvalue/license.go b/pkg/assembler/backends/keyvalue/license.go index da36d8c3e8..722e034c61 100644 --- a/pkg/assembler/backends/keyvalue/license.go +++ b/pkg/assembler/backends/keyvalue/license.go @@ -69,7 +69,7 @@ func (c *demoClient) licenseByInput(ctx context.Context, b *model.LicenseInputSp // Ingest Licenses -func (c *demoClient) IngestLicenses(ctx context.Context, licenses []*model.LicenseInputSpec) ([]string, error) { +func (c *demoClient) IngestLicenses(ctx context.Context, licenses []*model.IDorLicenseInput) ([]string, error) { var modelLicenses []string for _, lic := range licenses { modelLic, err := c.IngestLicense(ctx, lic) @@ -81,15 +81,15 @@ func (c *demoClient) IngestLicenses(ctx context.Context, licenses []*model.Licen return modelLicenses, nil } -func (c *demoClient) IngestLicense(ctx context.Context, license *model.LicenseInputSpec) (string, error) { +func (c *demoClient) IngestLicense(ctx context.Context, license *model.IDorLicenseInput) (string, error) { return c.ingestLicense(ctx, license, true) } -func (c *demoClient) ingestLicense(ctx context.Context, license *model.LicenseInputSpec, readOnly bool) (string, error) { +func (c *demoClient) ingestLicense(ctx context.Context, license *model.IDorLicenseInput, readOnly bool) (string, error) { in := &licStruct{ - Name: license.Name, - Inline: nilToEmpty(license.Inline), - ListVersion: nilToEmpty(license.ListVersion), + Name: license.LicenseInput.Name, + Inline: nilToEmpty(license.LicenseInput.Inline), + ListVersion: nilToEmpty(license.LicenseInput.ListVersion), } lock(&c.m, readOnly) @@ -206,3 +206,20 @@ func (c *demoClient) convLicense(a *licStruct) *model.License { } return rv } + +// returnFoundLicense return the node by first searching via ID. If the ID is not specified, it defaults to searching via inputspec +func (c *demoClient) returnFoundLicense(ctx context.Context, licenseIDorInput *model.IDorLicenseInput) (*licStruct, error) { + if licenseIDorInput.LicenseID != nil { + licStruct, err := byIDkv[*licStruct](ctx, *licenseIDorInput.LicenseID, c) + if err != nil { + return nil, gqlerror.Errorf("failed to return licStruct node by ID with error: %v", err) + } + return licStruct, nil + } else { + licStruct, err := c.licenseByInput(ctx, licenseIDorInput.LicenseInput) + if err != nil { + return nil, gqlerror.Errorf("failed to licenseByInput with error: %v", err) + } + return licStruct, nil + } +} diff --git a/pkg/assembler/backends/keyvalue/license_test.go b/pkg/assembler/backends/keyvalue/license_test.go deleted file mode 100644 index c80a1ac78e..0000000000 --- a/pkg/assembler/backends/keyvalue/license_test.go +++ /dev/null @@ -1,209 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package keyvalue_test - -import ( - "context" - "slices" - "strings" - "testing" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/internal/testing/stablememmap" - "github.com/guacsec/guac/pkg/assembler/backends" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -var l1 = &model.LicenseInputSpec{ - Name: "BSD-3-Clause", - ListVersion: ptrfrom.String("3.21 2023-06-18"), -} - -var l1out = &model.License{ - Name: "BSD-3-Clause", - ListVersion: ptrfrom.String("3.21 2023-06-18"), -} - -var l2 = &model.LicenseInputSpec{ - Name: "GPL-2.0-or-later", - ListVersion: ptrfrom.String("3.21 2023-06-18"), -} - -var l2out = &model.License{ - Name: "GPL-2.0-or-later", - ListVersion: ptrfrom.String("3.21 2023-06-18"), -} - -var l3 = &model.LicenseInputSpec{ - Name: "MPL-2.0", - ListVersion: ptrfrom.String("1.23 2020"), -} - -var l3out = &model.License{ - Name: "MPL-2.0", - ListVersion: ptrfrom.String("1.23 2020"), -} - -var inlineLicense = ` -Redistribution and use of the MAME code or any derivative works are permitted provided that the following conditions are met: -* Redistributions may not be sold, nor may they be used in a commercial product or activity. -* Redistributions that are modified from the original source must include the complete source code, including the source code for all components used by a binary built from the modified sources. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. -* Redistributions must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -` - -var l4 = &model.LicenseInputSpec{ - Name: "LicenseRef-d58b4101", - Inline: &inlineLicense, -} - -var l4out = &model.License{ - Name: "LicenseRef-d58b4101", - Inline: &inlineLicense, -} - -func TestLicense(t *testing.T) { - tests := []struct { - Name string - Ingests []*model.LicenseInputSpec - ExpIngestErr bool - Query *model.LicenseSpec - Exp []*model.License - ExpQueryErr bool - }{ - { - Name: "HappyPath", - Ingests: []*model.LicenseInputSpec{l1}, - Query: &model.LicenseSpec{}, - Exp: []*model.License{l1out}, - }, - { - Name: "Multiple", - Ingests: []*model.LicenseInputSpec{l1, l2}, - Query: &model.LicenseSpec{}, - Exp: []*model.License{l1out, l2out}, - }, - { - Name: "Duplicates", - Ingests: []*model.LicenseInputSpec{l1, l1, l1}, - Query: &model.LicenseSpec{}, - Exp: []*model.License{l1out}, - }, - { - Name: "Query by Name", - Ingests: []*model.LicenseInputSpec{l1, l2, l3}, - Query: &model.LicenseSpec{ - Name: ptrfrom.String("BSD-3-Clause"), - }, - Exp: []*model.License{l1out}, - }, - { - Name: "Query by Inline", - Ingests: []*model.LicenseInputSpec{l2, l3, l4}, - Query: &model.LicenseSpec{ - Inline: &inlineLicense, - }, - Exp: []*model.License{l4out}, - }, - { - Name: "Query by ListVersion", - Ingests: []*model.LicenseInputSpec{l2, l3, l4}, - Query: &model.LicenseSpec{ - ListVersion: ptrfrom.String("1.23 2020"), - }, - Exp: []*model.License{l3out}, - }, - { - Name: "Query by ID", - Ingests: []*model.LicenseInputSpec{l2, l3, l4}, - Query: &model.LicenseSpec{ - ID: ptrfrom.String("2"), - }, - Exp: []*model.License{l3out}, - }, - { - Name: "Query None", - Ingests: []*model.LicenseInputSpec{l2, l3, l4}, - Query: &model.LicenseSpec{ - ListVersion: ptrfrom.String("foo"), - }, - Exp: nil, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - ctx := context.Background() - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, i := range test.Ingests { - _, err := b.IngestLicense(ctx, i) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.Licenses(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - slices.SortFunc(got, lessLic) - if diff := cmp.Diff(test.Exp, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func lessLic(a, b *model.License) int { - return strings.Compare(a.Name, b.Name) -} - -func TestIngestLicenses(t *testing.T) { - tests := []struct { - name string - ingests []*model.LicenseInputSpec - }{ - { - name: "Multiple", - ingests: []*model.LicenseInputSpec{l1, l2, l3, l4}, - }, - } - ctx := context.Background() - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - if _, err := b.IngestLicenses(ctx, test.ingests); err != nil { - t.Errorf("ingest error: %v", err) - } - }) - } -} diff --git a/pkg/assembler/backends/keyvalue/path_test.go b/pkg/assembler/backends/keyvalue/path_test.go deleted file mode 100644 index 089cb2bb4c..0000000000 --- a/pkg/assembler/backends/keyvalue/path_test.go +++ /dev/null @@ -1,803 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package keyvalue_test - -import ( - "context" - "strings" - "testing" - "time" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/stablememmap" - "github.com/guacsec/guac/internal/testing/testdata" - "github.com/guacsec/guac/pkg/assembler/backends" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -func Test_Nodes(t *testing.T) { - ctx := context.Background() - type certifyBadCall struct { - Sub model.PackageSourceOrArtifactInput - Match *model.MatchFlags - CB *model.CertifyBadInputSpec - } - type certifyGoodCall struct { - Sub model.PackageSourceOrArtifactInput - Match *model.MatchFlags - CG *model.CertifyGoodInputSpec - } - type certifyLegalCall struct { - PkgSrc model.PackageOrSourceInput - Dec []*model.LicenseInputSpec - Dis []*model.LicenseInputSpec - Legal *model.CertifyLegalInputSpec - } - type scorecardCall struct { - Src *model.SourceInputSpec - SC *model.ScorecardInputSpec - } - type vexCall struct { - Sub model.PackageOrArtifactInput - Vuln *model.VulnerabilityInputSpec - In *model.VexStatementInputSpec - } - type certifyVulnCall struct { - Pkg *model.PkgInputSpec - Vuln *model.VulnerabilityInputSpec - CertifyVuln *model.ScanMetadataInput - } - type hashEqualCall struct { - A1 *model.ArtifactInputSpec - A2 *model.ArtifactInputSpec - HE *model.HashEqualInputSpec - } - type hasMetadataCall struct { - Sub model.PackageSourceOrArtifactInput - Match *model.MatchFlags - HM *model.HasMetadataInputSpec - } - type hasSBOMCall struct { - Sub model.PackageOrArtifactInput - HS *model.HasSBOMInputSpec - } - type hasSlsaCall struct { - Sub *model.ArtifactInputSpec - BF []*model.ArtifactInputSpec - BB *model.BuilderInputSpec - SLSA *model.SLSAInputSpec - } - type hasSourceAtCall struct { - Pkg *model.PkgInputSpec - Src *model.SourceInputSpec - Match *model.MatchFlags - HSA *model.HasSourceAtInputSpec - } - type isDepCall struct { - P1 *model.PkgInputSpec - P2 *model.PkgInputSpec - MF model.MatchFlags - ID *model.IsDependencyInputSpec - } - type isOcurCall struct { - PkgSrc model.PackageOrSourceInput - Artifact *model.ArtifactInputSpec - Occurrence *model.IsOccurrenceInputSpec - } - type pkgEqualCall struct { - P1 *model.PkgInputSpec - P2 *model.PkgInputSpec - HE *model.PkgEqualInputSpec - } - type pointOfContactCall struct { - Sub model.PackageSourceOrArtifactInput - Match *model.MatchFlags - POC *model.PointOfContactInputSpec - } - type vulnEqualCall struct { - Vuln *model.VulnerabilityInputSpec - OtherVuln *model.VulnerabilityInputSpec - In *model.VulnEqualInputSpec - } - type vulnMetadataCall struct { - Vuln *model.VulnerabilityInputSpec - VulnMetadata *model.VulnerabilityMetadataInputSpec - } - tests := []struct { - name string - pkgInput *model.PkgInputSpec - artifactInput *model.ArtifactInputSpec - builderInput *model.BuilderInputSpec - srcInput *model.SourceInputSpec - vulnInput *model.VulnerabilityInputSpec - licenseInput *model.LicenseInputSpec - inPkg []*model.PkgInputSpec - inSrc []*model.SourceInputSpec - inArt []*model.ArtifactInputSpec - inVuln []*model.VulnerabilityInputSpec - inBld []*model.BuilderInputSpec - inLic []*model.LicenseInputSpec - certifyBadCall *certifyBadCall - certifyGoodCall *certifyGoodCall - certifyLegalCall *certifyLegalCall - scorecardCall *scorecardCall - vexCall *vexCall - certifyVulnCall *certifyVulnCall - hashEqualCall *hashEqualCall - hasMetadataCall *hasMetadataCall - hasSBOMCall *hasSBOMCall - hasSlsaCall *hasSlsaCall - hasSourceAtCall *hasSourceAtCall - isDepCall *isDepCall - isOcurCall *isOcurCall - pkgEqualCall *pkgEqualCall - pointOfContactCall *pointOfContactCall - vulnEqualCall *vulnEqualCall - vulnMetadataCall *vulnMetadataCall - want []model.Node - wantErr bool - }{{ - name: "package", - pkgInput: testdata.P1, - want: []model.Node{testdata.P1out}, - wantErr: false, - }, { - name: "artifact", - artifactInput: &model.ArtifactInputSpec{ - Algorithm: "sha256", - Digest: "6bbb0da1891646e58eb3e6a63af3a6fc3c8eb5a0d44824cba581d2e14a0450cf", - }, - want: []model.Node{&model.Artifact{ - Algorithm: "sha256", - Digest: "6bbb0da1891646e58eb3e6a63af3a6fc3c8eb5a0d44824cba581d2e14a0450cf", - }}, - wantErr: false, - }, { - name: "builder", - builderInput: &model.BuilderInputSpec{ - URI: "https://github.com/CreateFork/HubHostedActions@v1", - }, - want: []model.Node{&model.Builder{ - URI: "https://github.com/CreateFork/HubHostedActions@v1", - }}, - wantErr: false, - }, { - name: "source", - srcInput: testdata.S1, - want: []model.Node{s1out}, - wantErr: false, - }, { - name: "vulnerability", - vulnInput: testdata.C1, - want: []model.Node{&model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.C1out}, - }}, - }, { - name: "license", - licenseInput: testdata.L1, - want: []model.Node{testdata.L1out}, - }, { - name: "certifyBad", - inPkg: []*model.PkgInputSpec{testdata.P1}, - certifyBadCall: &certifyBadCall{ - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CB: &model.CertifyBadInputSpec{ - Justification: "test justification", - }, - }, - want: []model.Node{&model.CertifyBad{ - Subject: testdata.P1out, - Justification: "test justification", - }}, - }, { - name: "certifyGood", - inPkg: []*model.PkgInputSpec{testdata.P1}, - certifyGoodCall: &certifyGoodCall{ - Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - CG: &model.CertifyGoodInputSpec{ - Justification: "test justification", - }, - }, - want: []model.Node{&model.CertifyGood{ - Subject: testdata.P1out, - Justification: "test justification", - }}, - }, { - name: "certifyLegal", - inPkg: []*model.PkgInputSpec{testdata.P1}, - inLic: []*model.LicenseInputSpec{testdata.L1}, - certifyLegalCall: &certifyLegalCall{ - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Dec: []*model.LicenseInputSpec{testdata.L1}, - Legal: &model.CertifyLegalInputSpec{ - Justification: "test justification 2", - }, - }, - want: []model.Node{&model.CertifyLegal{ - Subject: testdata.P1out, - DeclaredLicenses: []*model.License{testdata.L1out}, - Justification: "test justification 2", - }}, - }, { - name: "scorecard", - inSrc: []*model.SourceInputSpec{testdata.S2}, - scorecardCall: &scorecardCall{ - Src: testdata.S2, - SC: &model.ScorecardInputSpec{ - Origin: "test origin", - }, - }, - want: []model.Node{&model.CertifyScorecard{ - Source: s2out, - Scorecard: &model.Scorecard{ - Checks: []*model.ScorecardCheck{}, - Origin: "test origin", - }, - }}, - }, { - name: "vex", - inPkg: []*model.PkgInputSpec{testdata.P1}, - inVuln: []*model.VulnerabilityInputSpec{testdata.O2}, - vexCall: &vexCall{ - Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, - }, - Vuln: testdata.O2, - In: &model.VexStatementInputSpec{ - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }, - }, - want: []model.Node{&model.CertifyVEXStatement{ - Subject: testdata.P1out, - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O2out}, - }, - VexJustification: "test justification", - KnownSince: time.Unix(1e9, 0), - }}, - }, { - name: "certifyVuln", - inVuln: []*model.VulnerabilityInputSpec{testdata.G1}, - inPkg: []*model.PkgInputSpec{testdata.P2}, - certifyVulnCall: &certifyVulnCall{ - Pkg: testdata.P2, - Vuln: testdata.G1, - CertifyVuln: &model.ScanMetadataInput{ - Collector: "test collector", - Origin: "test origin", - ScannerVersion: "v1.0.0", - ScannerURI: "test scanner uri", - DbVersion: "2023.01.01", - DbURI: "test db uri", - TimeScanned: testdata.T1, - }, - }, - want: []model.Node{&model.CertifyVuln{ - Package: testdata.P2out, - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - Metadata: vmd1, - }}, - }, { - name: "hashEqual", - inArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2, testdata.A3}, - hashEqualCall: &hashEqualCall{ - A1: testdata.A1, - A2: testdata.A3, - HE: &model.HashEqualInputSpec{}, - }, - want: []model.Node{&model.HashEqual{ - Artifacts: []*model.Artifact{testdata.A1out, testdata.A3out}, - }}, - }, { - name: "hasMetadata", - inArt: []*model.ArtifactInputSpec{testdata.A2}, - hasMetadataCall: &hasMetadataCall{ - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, - }, - HM: &model.HasMetadataInputSpec{ - Justification: "test justification", - }, - }, - want: []model.Node{&model.HasMetadata{ - Subject: testdata.A2out, - Justification: "test justification", - }}, - }, { - name: "hasSBOM", - inPkg: []*model.PkgInputSpec{testdata.P2, testdata.P4}, - inArt: []*model.ArtifactInputSpec{testdata.A1}, - isDepCall: &isDepCall{ - P1: testdata.P2, - P2: testdata.P4, - MF: mSpecific, - ID: &model.IsDependencyInputSpec{ - Justification: "test justification", - }, - }, - isOcurCall: &isOcurCall{ - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P4, - }, - Artifact: testdata.A1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "test justification", - }, - }, - hasSBOMCall: &hasSBOMCall{ - Sub: model.PackageOrArtifactInput{ - Package: testdata.P2, - }, - HS: &model.HasSBOMInputSpec{ - DownloadLocation: "location two", - }, - }, - want: []model.Node{&model.HasSbom{ - Subject: testdata.P2out, - DownloadLocation: "location two", - IncludedSoftware: []model.PackageOrArtifact{testdata.P2out, testdata.P4out, testdata.A1out}, - IncludedDependencies: []*model.IsDependency{{ - Package: testdata.P2out, - DependencyPackage: testdata.P4out, - Justification: "test justification", - DependencyType: model.DependencyTypeUnknown, - }}, - IncludedOccurrences: []*model.IsOccurrence{{ - Subject: testdata.P4out, - Artifact: testdata.A1out, - Justification: "test justification", - }}, - }}, - }, { - - name: "hasSLSA", - inArt: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - inBld: []*model.BuilderInputSpec{testdata.B1, testdata.B2}, - hasSlsaCall: &hasSlsaCall{ - Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, - BB: testdata.B2, - SLSA: &model.SLSAInputSpec{}, - }, - want: []model.Node{&model.HasSlsa{ - Subject: testdata.A1out, - Slsa: &model.Slsa{ - BuiltBy: testdata.B2out, - BuiltFrom: []*model.Artifact{testdata.A2out}, - }, - }}, - }, { - name: "hasSourceAt", - inPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - inSrc: []*model.SourceInputSpec{testdata.S1}, - hasSourceAtCall: &hasSourceAtCall{ - Pkg: testdata.P2, - Src: testdata.S1, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HSA: &model.HasSourceAtInputSpec{}, - }, - want: []model.Node{&model.HasSourceAt{ - Package: testdata.P2out, - Source: s1out, - }}, - }, { - name: "isDependency", - inPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - isDepCall: &isDepCall{ - P1: testdata.P1, - P2: testdata.P2, - MF: mAll, - ID: &model.IsDependencyInputSpec{}, - }, - want: []model.Node{&model.IsDependency{ - Package: testdata.P1out, - DependencyPackage: testdata.P2outName, - DependencyType: model.DependencyTypeUnknown, - }}, - }, { - name: "isOccurrence", - inPkg: []*model.PkgInputSpec{testdata.P1}, - inArt: []*model.ArtifactInputSpec{testdata.A1}, - isOcurCall: &isOcurCall{ - PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - }, - Artifact: testdata.A1, - Occurrence: &model.IsOccurrenceInputSpec{ - Justification: "test justification", - }, - }, - want: []model.Node{&model.IsOccurrence{ - Subject: testdata.P1out, - Artifact: testdata.A1out, - Justification: "test justification", - }}, - }, { - name: "pkgEqual", - inPkg: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - pkgEqualCall: &pkgEqualCall{ - P1: testdata.P1, - P2: testdata.P2, - HE: &model.PkgEqualInputSpec{ - Justification: "test justification two", - }, - }, - want: []model.Node{&model.PkgEqual{ - - Packages: []*model.Package{testdata.P1out, testdata.P2out}, - Justification: "test justification two", - }}, - }, { - name: "pointOfContact", - inArt: []*model.ArtifactInputSpec{testdata.A2}, - pointOfContactCall: &pointOfContactCall{ - Sub: model.PackageSourceOrArtifactInput{ - Artifact: testdata.A2, - }, - POC: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - want: []model.Node{&model.PointOfContact{ - Subject: testdata.A2out, - Justification: "test justification", - }}, - }, { - name: "vulnEqual", - inVuln: []*model.VulnerabilityInputSpec{testdata.O1, testdata.G1}, - vulnEqualCall: &vulnEqualCall{ - Vuln: testdata.O1, - OtherVuln: testdata.G1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - want: []model.Node{&model.VulnEqual{ - Vulnerabilities: []*model.Vulnerability{ - { - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.O1out}, - }, - { - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - }, - Justification: "test justification", - }}, - }, { - name: "vulnMetadata", - inVuln: []*model.VulnerabilityInputSpec{testdata.G1}, - vulnMetadataCall: &vulnMetadataCall{ - Vuln: testdata.G1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }, - }, - want: []model.Node{&model.VulnerabilityMetadata{ - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{testdata.G1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: testdata.T1, - Collector: "test collector", - Origin: "test origin", - }}, - }} - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - var nodeID string - includes := model.HasSBOMIncludesInputSpec{} - for _, p := range tt.inPkg { - if pkg, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } else { - includes.Software = append(includes.Software, pkg.PackageVersionID) - } - } - for _, s := range tt.inSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, a := range tt.inArt { - if art, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } else { - includes.Software = append(includes.Software, art) - } - } - for _, bld := range tt.inBld { - if _, err := b.IngestBuilder(ctx, bld); err != nil { - t.Fatalf("Could not ingest builder: %v", err) - } - } - for _, a := range tt.inLic { - if _, err := b.IngestLicense(ctx, a); err != nil { - t.Fatalf("Could not ingest license: %v", err) - } - } - for _, g := range tt.inVuln { - if _, err := b.IngestVulnerability(ctx, *g); err != nil { - t.Fatalf("Could not ingest vulnerability: %a", err) - } - } - if tt.pkgInput != nil { - ingestedPkg, err := b.IngestPackage(ctx, *tt.pkgInput) - if (err != nil) != tt.wantErr { - t.Errorf("arangoClient.IngestPackage() error = %v, wantErr %v", err, tt.wantErr) - return - } - nodeID = ingestedPkg.PackageVersionID - includes.Software = append(includes.Software, nodeID) - } - if tt.artifactInput != nil { - ingestedArt, err := b.IngestArtifact(ctx, tt.artifactInput) - if (err != nil) != tt.wantErr { - t.Errorf("arangoClient.IngestArtifact() error = %v, wantErr %v", err, tt.wantErr) - return - } - nodeID = ingestedArt - } - if tt.builderInput != nil { - ingestedBuilder, err := b.IngestBuilder(ctx, tt.builderInput) - if (err != nil) != tt.wantErr { - t.Errorf("demoClient.IngestBuilder() error = %v, wantErr %v", err, tt.wantErr) - return - } - nodeID = ingestedBuilder - } - if tt.srcInput != nil { - ingestedSrc, err := b.IngestSource(ctx, *tt.srcInput) - if (err != nil) != tt.wantErr { - t.Errorf("arangoClient.IngestSource() error = %v, wantErr %v", err, tt.wantErr) - return - } - nodeID = ingestedSrc.SourceNameID - } - if tt.vulnInput != nil { - ingestVuln, err := b.IngestVulnerability(ctx, *tt.vulnInput) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.want, err) - } - nodeID = ingestVuln.VulnerabilityNodeID - } - if tt.licenseInput != nil { - ingestedLicense, err := b.IngestLicense(ctx, tt.licenseInput) - if (err != nil) != tt.wantErr { - t.Errorf("demoClient.IngestLicense() error = %v, wantErr %v", err, tt.wantErr) - return - } - nodeID = ingestedLicense - } - if tt.certifyBadCall != nil { - found, err := b.IngestCertifyBad(ctx, tt.certifyBadCall.Sub, tt.certifyBadCall.Match, *tt.certifyBadCall.CB) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - nodeID = found - } - if tt.certifyGoodCall != nil { - found, err := b.IngestCertifyGood(ctx, tt.certifyGoodCall.Sub, tt.certifyGoodCall.Match, *tt.certifyGoodCall.CG) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - nodeID = found - } - if tt.certifyLegalCall != nil { - found, err := b.IngestCertifyLegal(ctx, tt.certifyLegalCall.PkgSrc, tt.certifyLegalCall.Dec, tt.certifyLegalCall.Dis, tt.certifyLegalCall.Legal) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - nodeID = found - } - if tt.scorecardCall != nil { - found, err := b.IngestScorecard(ctx, *tt.scorecardCall.Src, *tt.scorecardCall.SC) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - nodeID = found - } - if tt.vexCall != nil { - found, err := b.IngestVEXStatement(ctx, tt.vexCall.Sub, *tt.vexCall.Vuln, *tt.vexCall.In) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - nodeID = found - } - if tt.certifyVulnCall != nil { - found, err := b.IngestCertifyVuln(ctx, *tt.certifyVulnCall.Pkg, *tt.certifyVulnCall.Vuln, *tt.certifyVulnCall.CertifyVuln) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - nodeID = found - } - if tt.hashEqualCall != nil { - found, err := b.IngestHashEqual(ctx, *tt.hashEqualCall.A1, *tt.hashEqualCall.A2, *tt.hashEqualCall.HE) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - nodeID = found - } - if tt.hasMetadataCall != nil { - found, err := b.IngestHasMetadata(ctx, tt.hasMetadataCall.Sub, tt.hasMetadataCall.Match, *tt.hasMetadataCall.HM) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - nodeID = found - } - if tt.hasSlsaCall != nil { - found, err := b.IngestSLSA(ctx, *tt.hasSlsaCall.Sub, tt.hasSlsaCall.BF, *tt.hasSlsaCall.BB, *tt.hasSlsaCall.SLSA) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - nodeID = found - } - if tt.hasSourceAtCall != nil { - found, err := b.IngestHasSourceAt(ctx, *tt.hasSourceAtCall.Pkg, *tt.hasSourceAtCall.Match, *tt.hasSourceAtCall.Src, *tt.hasSourceAtCall.HSA) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - nodeID = found - } - if tt.isDepCall != nil { - found, err := b.IngestDependency(ctx, *tt.isDepCall.P1, *tt.isDepCall.P2, tt.isDepCall.MF, *tt.isDepCall.ID) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - nodeID = found - includes.Dependencies = append(includes.Dependencies, nodeID) - } - if tt.isOcurCall != nil { - found, err := b.IngestOccurrence(ctx, tt.isOcurCall.PkgSrc, *tt.isOcurCall.Artifact, *tt.isOcurCall.Occurrence) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - nodeID = found - includes.Occurrences = append(includes.Occurrences, nodeID) - } - if tt.hasSBOMCall != nil { - // After isDepCall and isOcurCall so they can set up includes. - found, err := b.IngestHasSbom(ctx, tt.hasSBOMCall.Sub, *tt.hasSBOMCall.HS, includes) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - nodeID = found - } - if tt.pkgEqualCall != nil { - found, err := b.IngestPkgEqual(ctx, *tt.pkgEqualCall.P1, *tt.pkgEqualCall.P2, *tt.pkgEqualCall.HE) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - nodeID = found - } - if tt.pointOfContactCall != nil { - found, err := b.IngestPointOfContact(ctx, tt.pointOfContactCall.Sub, tt.pointOfContactCall.Match, *tt.pointOfContactCall.POC) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - nodeID = found - } - if tt.vulnEqualCall != nil { - found, err := b.IngestVulnEqual(ctx, *tt.vulnEqualCall.Vuln, *tt.vulnEqualCall.OtherVuln, *tt.vulnEqualCall.In) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - nodeID = found - } - if tt.vulnMetadataCall != nil { - found, err := b.IngestVulnerabilityMetadata(ctx, *tt.vulnMetadataCall.Vuln, *tt.vulnMetadataCall.VulnMetadata) - if (err != nil) != tt.wantErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", tt.wantErr, err) - } - if err != nil { - return - } - nodeID = found - } - got, err := b.Nodes(ctx, []string{nodeID}) - if (err != nil) != tt.wantErr { - t.Errorf("node query error = %v, wantErr %v", err, tt.wantErr) - return - } - if diff := cmp.Diff(tt.want, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} diff --git a/pkg/assembler/backends/keyvalue/pkg.go b/pkg/assembler/backends/keyvalue/pkg.go index ad8ddaf03a..c3814213b8 100644 --- a/pkg/assembler/backends/keyvalue/pkg.go +++ b/pkg/assembler/backends/keyvalue/pkg.go @@ -352,7 +352,7 @@ func (n *pkgVersion) Key() string { // Ingest Package -func (c *demoClient) IngestPackages(ctx context.Context, pkgs []*model.PkgInputSpec) ([]*model.PackageIDs, error) { +func (c *demoClient) IngestPackages(ctx context.Context, pkgs []*model.IDorPkgInput) ([]*model.PackageIDs, error) { var modelPkgs []*model.PackageIDs for _, pkg := range pkgs { modelPkg, err := c.IngestPackage(ctx, *pkg) @@ -364,9 +364,9 @@ func (c *demoClient) IngestPackages(ctx context.Context, pkgs []*model.PkgInputS return modelPkgs, nil } -func (c *demoClient) IngestPackage(ctx context.Context, input model.PkgInputSpec) (*model.PackageIDs, error) { +func (c *demoClient) IngestPackage(ctx context.Context, input model.IDorPkgInput) (*model.PackageIDs, error) { inType := &pkgType{ - Type: input.Type, + Type: input.PackageInput.Type, } c.m.RLock() outType, err := byKeykv[*pkgType](ctx, pkgTypeCol, inType.Key(), c) @@ -398,7 +398,7 @@ func (c *demoClient) IngestPackage(ctx context.Context, input model.PkgInputSpec inNamespace := &pkgNamespace{ Parent: outType.ThisID, - Namespace: nilToEmpty(input.Namespace), + Namespace: nilToEmpty(input.PackageInput.Namespace), } c.m.RLock() outNamespace, err := byKeykv[*pkgNamespace](ctx, pkgNSCol, inNamespace.Key(), c) @@ -431,7 +431,7 @@ func (c *demoClient) IngestPackage(ctx context.Context, input model.PkgInputSpec inName := &pkgName{ Parent: outNamespace.ThisID, - Name: input.Name, + Name: input.PackageInput.Name, } c.m.RLock() outName, err := byKeykv[*pkgName](ctx, pkgNameCol, inName.Key(), c) @@ -464,9 +464,9 @@ func (c *demoClient) IngestPackage(ctx context.Context, input model.PkgInputSpec inVersion := &pkgVersion{ Parent: outName.ThisID, - Version: nilToEmpty(input.Version), - Subpath: nilToEmpty(input.Subpath), - Qualifiers: getQualifiersFromInput(input.Qualifiers), + Version: nilToEmpty(input.PackageInput.Version), + Subpath: nilToEmpty(input.PackageInput.Subpath), + Qualifiers: getQualifiersFromInput(input.PackageInput.Qualifiers), } c.m.RLock() outVersion, err := byKeykv[*pkgVersion](ctx, pkgVerCol, inVersion.Key(), c) @@ -1041,3 +1041,45 @@ func (c *demoClient) matchPackages(ctx context.Context, filter []*model.PkgSpec, } return true } + +// returnFoundPkgVersion return the node by first searching via ID. If the ID is not specified, it defaults to searching via inputspec +func (c *demoClient) returnFoundPkgVersion(ctx context.Context, pkgIDorInput *model.IDorPkgInput) (*pkgVersion, error) { + if pkgIDorInput.PackageVersionID != nil { + foundPkgVersionNode, err := byIDkv[*pkgVersion](ctx, *pkgIDorInput.PackageVersionID, c) + if err != nil { + return nil, gqlerror.Errorf("failed to return pkgVersion node by ID with error: %v", err) + } + return foundPkgVersionNode, nil + } else { + foundPkgVersionNode, err := c.getPackageVerFromInput(ctx, *pkgIDorInput.PackageInput) + if err != nil { + return nil, gqlerror.Errorf("failed to getPackageVerFromInput with error: %v", err) + } + return foundPkgVersionNode, nil + } +} + +// returnFoundPkgBasedOnMatchType return the node by first searching via ID depending on the match type. If the ID is not specified, it defaults to searching via inputspec +func (c *demoClient) returnFoundPkgBasedOnMatchType(ctx context.Context, pkgIDorInput *model.IDorPkgInput, pkgMatchType *model.MatchFlags) (string, pkgNameOrVersion, error) { + if pkgIDorInput.PackageVersionID != nil && pkgIDorInput.PackageNameID != nil { + if pkgMatchType.Pkg == model.PkgMatchTypeSpecificVersion { + foundPkgVersionNode, err := byIDkv[*pkgVersion](ctx, *pkgIDorInput.PackageVersionID, c) + if err != nil { + return "", nil, gqlerror.Errorf("failed to return pkgVersion node by ID with error: %v", err) + } + return *pkgIDorInput.PackageVersionID, foundPkgVersionNode, nil + } else { + foundPkgNameNode, err := byIDkv[*pkgName](ctx, *pkgIDorInput.PackageNameID, c) + if err != nil { + return "", nil, gqlerror.Errorf("failed to return pkgName node by ID with error: %v", err) + } + return *pkgIDorInput.PackageNameID, foundPkgNameNode, nil + } + } else { + foundPkgNameorVersionNode, err := c.getPackageNameOrVerFromInput(ctx, *pkgIDorInput.PackageInput, *pkgMatchType) + if err != nil { + return "", nil, gqlerror.Errorf("failed to getPackageNameOrVerFromInput with error: %v", err) + } + return foundPkgNameorVersionNode.ID(), foundPkgNameorVersionNode, nil + } +} diff --git a/pkg/assembler/backends/keyvalue/pkgEqual.go b/pkg/assembler/backends/keyvalue/pkgEqual.go index 5373a1d466..07380ce65b 100644 --- a/pkg/assembler/backends/keyvalue/pkgEqual.go +++ b/pkg/assembler/backends/keyvalue/pkgEqual.go @@ -58,7 +58,7 @@ func (n *pkgEqualStruct) BuildModelNode(ctx context.Context, c *demoClient) (mod // Ingest PkgEqual -func (c *demoClient) IngestPkgEquals(ctx context.Context, pkgs []*model.PkgInputSpec, otherPackages []*model.PkgInputSpec, pkgEquals []*model.PkgEqualInputSpec) ([]string, error) { +func (c *demoClient) IngestPkgEquals(ctx context.Context, pkgs []*model.IDorPkgInput, otherPackages []*model.IDorPkgInput, pkgEquals []*model.PkgEqualInputSpec) ([]string, error) { var modelPkgEqualsIDs []string for i := range pkgEquals { pkgEqual, err := c.IngestPkgEqual(ctx, *pkgs[i], *otherPackages[i], *pkgEquals[i]) @@ -87,11 +87,11 @@ func (c *demoClient) convPkgEqual(ctx context.Context, in *pkgEqualStruct) (*mod return out, nil } -func (c *demoClient) IngestPkgEqual(ctx context.Context, pkg model.PkgInputSpec, depPkg model.PkgInputSpec, pkgEqual model.PkgEqualInputSpec) (string, error) { +func (c *demoClient) IngestPkgEqual(ctx context.Context, pkg model.IDorPkgInput, depPkg model.IDorPkgInput, pkgEqual model.PkgEqualInputSpec) (string, error) { return c.ingestPkgEqual(ctx, pkg, depPkg, pkgEqual, true) } -func (c *demoClient) ingestPkgEqual(ctx context.Context, pkg model.PkgInputSpec, depPkg model.PkgInputSpec, pkgEqual model.PkgEqualInputSpec, readOnly bool) (string, error) { +func (c *demoClient) ingestPkgEqual(ctx context.Context, pkg model.IDorPkgInput, depPkg model.IDorPkgInput, pkgEqual model.PkgEqualInputSpec, readOnly bool) (string, error) { funcName := "IngestPkgEqual" in := &pkgEqualStruct{ @@ -105,10 +105,10 @@ func (c *demoClient) ingestPkgEqual(ctx context.Context, pkg model.PkgInputSpec, pIDs := make([]string, 0, 2) ps := make([]*pkgVersion, 0, 2) - for _, pi := range []model.PkgInputSpec{pkg, depPkg} { - p, err := c.getPackageVerFromInput(ctx, pi) + for _, pi := range []model.IDorPkgInput{pkg, depPkg} { + p, err := c.returnFoundPkgVersion(ctx, &pi) if err != nil { - return "", gqlerror.Errorf("%v :: %v", funcName, err) + return "", gqlerror.Errorf("%v :: %s", funcName, err) } ps = append(ps, p) pIDs = append(pIDs, p.ThisID) diff --git a/pkg/assembler/backends/keyvalue/pkgEqual_test.go b/pkg/assembler/backends/keyvalue/pkgEqual_test.go deleted file mode 100644 index e0d7c88c49..0000000000 --- a/pkg/assembler/backends/keyvalue/pkgEqual_test.go +++ /dev/null @@ -1,737 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package keyvalue_test - -import ( - "context" - "slices" - "strings" - "testing" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/internal/testing/stablememmap" - "github.com/guacsec/guac/pkg/assembler/backends" - "github.com/guacsec/guac/pkg/assembler/backends/keyvalue" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -func TestPkgEqual(t *testing.T) { - type call struct { - P1 *model.PkgInputSpec - P2 *model.PkgInputSpec - HE *model.PkgEqualInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - Calls []call - Query *model.PkgEqualSpec - ExpHE []*model.PkgEqual - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{p1, p2}, - Calls: []call{ - { - P1: p1, - P2: p2, - HE: &model.PkgEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.PkgEqualSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHE: []*model.PkgEqual{ - { - Packages: []*model.Package{p1out, p2out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest same, different order", - InPkg: []*model.PkgInputSpec{p1, p2}, - Calls: []call{ - { - P1: p1, - P2: p2, - HE: &model.PkgEqualInputSpec{ - Justification: "test justification", - }, - }, - { - P1: p2, - P2: p1, - HE: &model.PkgEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.PkgEqualSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHE: []*model.PkgEqual{ - { - Packages: []*model.Package{p1out, p2out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Justification", - InPkg: []*model.PkgInputSpec{p1, p2}, - Calls: []call{ - { - P1: p1, - P2: p2, - HE: &model.PkgEqualInputSpec{ - Justification: "test justification one", - }, - }, - { - P1: p1, - P2: p2, - HE: &model.PkgEqualInputSpec{ - Justification: "test justification two", - }, - }, - }, - Query: &model.PkgEqualSpec{ - Justification: ptrfrom.String("test justification one"), - }, - ExpHE: []*model.PkgEqual{ - { - Packages: []*model.Package{p1out, p2out}, - Justification: "test justification one", - }, - }, - }, - { - Name: "Query on pkg", - InPkg: []*model.PkgInputSpec{p1, p2, p3}, - Calls: []call{ - { - P1: p1, - P2: p2, - HE: &model.PkgEqualInputSpec{}, - }, - { - P1: p1, - P2: p3, - HE: &model.PkgEqualInputSpec{}, - }, - }, - Query: &model.PkgEqualSpec{ - Packages: []*model.PkgSpec{{ - ID: ptrfrom.String("6"), - }}, - }, - ExpHE: []*model.PkgEqual{ - { - Packages: []*model.Package{p1out, p3out}, - }, - }, - }, - { - Name: "Query on pkg multiple", - InPkg: []*model.PkgInputSpec{p1, p2, p3}, - Calls: []call{ - { - P1: p1, - P2: p2, - HE: &model.PkgEqualInputSpec{}, - }, - { - P1: p1, - P2: p3, - HE: &model.PkgEqualInputSpec{}, - }, - }, - Query: &model.PkgEqualSpec{ - Packages: []*model.PkgSpec{{ - ID: ptrfrom.String("4"), - }}, - }, - ExpHE: []*model.PkgEqual{ - { - Packages: []*model.Package{p1out, p2out}, - }, - { - Packages: []*model.Package{p1out, p3out}, - }, - }, - }, - { - Name: "Query on pkg details", - InPkg: []*model.PkgInputSpec{p1, p2, p3}, - Calls: []call{ - { - P1: p1, - P2: p2, - HE: &model.PkgEqualInputSpec{}, - }, - { - P1: p1, - P2: p3, - HE: &model.PkgEqualInputSpec{}, - }, - }, - Query: &model.PkgEqualSpec{ - Packages: []*model.PkgSpec{{ - Version: ptrfrom.String("2.11.1"), - Subpath: ptrfrom.String(""), - }}, - }, - ExpHE: []*model.PkgEqual{ - { - Packages: []*model.Package{p1out, p2out}, - }, - }, - }, - { - Name: "Query on pkg algo and pkg", - InPkg: []*model.PkgInputSpec{p1, p2, p3}, - Calls: []call{ - { - P1: p1, - P2: p2, - HE: &model.PkgEqualInputSpec{}, - }, - { - P1: p1, - P2: p3, - HE: &model.PkgEqualInputSpec{}, - }, - }, - Query: &model.PkgEqualSpec{ - Packages: []*model.PkgSpec{{ - Type: ptrfrom.String("pypi"), - Namespace: ptrfrom.String(""), - Name: ptrfrom.String("tensorflow"), - Version: ptrfrom.String("2.11.1"), - }}, - }, - ExpHE: []*model.PkgEqual{ - { - Packages: []*model.Package{p1out, p2out}, - }, - { - Packages: []*model.Package{p1out, p3out}, - }, - }, - }, - { - Name: "Query on both pkgs", - InPkg: []*model.PkgInputSpec{p1, p2, p3}, - Calls: []call{ - { - P1: p1, - P2: p2, - HE: &model.PkgEqualInputSpec{}, - }, - { - P1: p2, - P2: p3, - HE: &model.PkgEqualInputSpec{}, - }, - }, - Query: &model.PkgEqualSpec{ - Packages: []*model.PkgSpec{ - { - Subpath: ptrfrom.String("saved_model_cli.py"), - }, - { - ID: ptrfrom.String("6"), - }, - }, - }, - ExpHE: []*model.PkgEqual{ - { - Packages: []*model.Package{p2out, p3out}, - }, - }, - }, - { - Name: "Query on both pkgs, one filter", - InPkg: []*model.PkgInputSpec{p1, p2, p3}, - Calls: []call{ - { - P1: p1, - P2: p2, - HE: &model.PkgEqualInputSpec{}, - }, - { - P1: p2, - P2: p3, - HE: &model.PkgEqualInputSpec{}, - }, - { - P1: p1, - P2: p3, - HE: &model.PkgEqualInputSpec{}, - }, - }, - Query: &model.PkgEqualSpec{ - Packages: []*model.PkgSpec{ - { - Version: ptrfrom.String(""), - }, - { - Version: ptrfrom.String("2.11.1"), - Subpath: ptrfrom.String("saved_model_cli.py"), - }, - }, - }, - ExpHE: []*model.PkgEqual{ - { - Packages: []*model.Package{p1out, p3out}, - }, - }, - }, - { - Name: "Query none", - InPkg: []*model.PkgInputSpec{p1, p2, p3}, - Calls: []call{ - { - P1: p1, - P2: p2, - HE: &model.PkgEqualInputSpec{}, - }, - { - P1: p2, - P2: p3, - HE: &model.PkgEqualInputSpec{}, - }, - { - P1: p1, - P2: p3, - HE: &model.PkgEqualInputSpec{}, - }, - }, - Query: &model.PkgEqualSpec{ - Packages: []*model.PkgSpec{ - { - Version: ptrfrom.String("1.2.3"), - }, - }, - }, - ExpHE: nil, - }, - { - Name: "Query on ID", - InPkg: []*model.PkgInputSpec{p1, p2, p3}, - Calls: []call{ - { - P1: p1, - P2: p2, - HE: &model.PkgEqualInputSpec{}, - }, - { - P1: p2, - P2: p3, - HE: &model.PkgEqualInputSpec{}, - }, - { - P1: p1, - P2: p3, - HE: &model.PkgEqualInputSpec{}, - }, - }, - Query: &model.PkgEqualSpec{ - ID: ptrfrom.String("8"), - }, - ExpHE: []*model.PkgEqual{ - { - Packages: []*model.Package{p2out, p3out}, - }, - }, - }, - { - Name: "Ingest no P1", - InPkg: []*model.PkgInputSpec{p2}, - Calls: []call{ - { - P1: p1, - P2: p2, - HE: &model.PkgEqualInputSpec{}, - }, - }, - ExpIngestErr: true, - }, - { - Name: "Ingest no P2", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - P1: p1, - P2: p2, - HE: &model.PkgEqualInputSpec{}, - }, - }, - ExpIngestErr: true, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - ctx := context.Background() - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, a := range test.InPkg { - if _, err := b.IngestPackage(ctx, *a); err != nil { - t.Fatalf("Could not ingest pkg: %v", err) - } - } - for _, o := range test.Calls { - _, err := b.IngestPkgEqual(ctx, *o.P1, *o.P2, *o.HE) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.PkgEqual(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - - keyvalue.MakeCanonicalPkgEqualSlice(got) - keyvalue.MakeCanonicalPkgEqualSlice(test.ExpHE) - - if diff := cmp.Diff(test.ExpHE, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func TestIngestPkgEquals(t *testing.T) { - type call struct { - P1 []*model.PkgInputSpec - P2 []*model.PkgInputSpec - PE []*model.PkgEqualInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - Calls []call - Query *model.PkgEqualSpec - ExpHE []*model.PkgEqual - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{p1, p2}, - Calls: []call{ - { - P1: []*model.PkgInputSpec{p1, p1}, - P2: []*model.PkgInputSpec{p2, p2}, - PE: []*model.PkgEqualInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.PkgEqualSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHE: []*model.PkgEqual{ - { - Packages: []*model.Package{p1out, p2out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest same, different order", - InPkg: []*model.PkgInputSpec{p1, p2}, - Calls: []call{ - { - P1: []*model.PkgInputSpec{p1, p2}, - P2: []*model.PkgInputSpec{p2, p1}, - PE: []*model.PkgEqualInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.PkgEqualSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHE: []*model.PkgEqual{ - { - Packages: []*model.Package{p1out, p2out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on pkg details", - InPkg: []*model.PkgInputSpec{p1, p2, p3}, - Calls: []call{ - { - P1: []*model.PkgInputSpec{p1, p1}, - P2: []*model.PkgInputSpec{p2, p3}, - PE: []*model.PkgEqualInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.PkgEqualSpec{ - Packages: []*model.PkgSpec{{ - Version: ptrfrom.String("2.11.1"), - Subpath: ptrfrom.String(""), - }}, - }, - ExpHE: []*model.PkgEqual{ - { - Packages: []*model.Package{p1out, p2out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on pkg algo and pkg", - InPkg: []*model.PkgInputSpec{p1, p2, p3}, - Calls: []call{ - { - P1: []*model.PkgInputSpec{p1, p1}, - P2: []*model.PkgInputSpec{p2, p3}, - PE: []*model.PkgEqualInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.PkgEqualSpec{ - Packages: []*model.PkgSpec{{ - Type: ptrfrom.String("pypi"), - Namespace: ptrfrom.String(""), - Name: ptrfrom.String("tensorflow"), - Version: ptrfrom.String("2.11.1"), - }}, - }, - ExpHE: []*model.PkgEqual{ - { - Packages: []*model.Package{p1out, p2out}, - Justification: "test justification", - }, - { - Packages: []*model.Package{p1out, p3out}, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on both pkgs, one filter", - InPkg: []*model.PkgInputSpec{p1, p2, p3}, - Calls: []call{ - { - P1: []*model.PkgInputSpec{p1, p1}, - P2: []*model.PkgInputSpec{p2, p3}, - PE: []*model.PkgEqualInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.PkgEqualSpec{ - Packages: []*model.PkgSpec{ - { - Version: ptrfrom.String(""), - }, - { - Version: ptrfrom.String("2.11.1"), - Subpath: ptrfrom.String("saved_model_cli.py"), - }, - }, - }, - ExpHE: []*model.PkgEqual{ - { - Packages: []*model.Package{p1out, p3out}, - Justification: "test justification", - }, - }, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - ctx := context.Background() - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - if _, err := b.IngestPackages(ctx, test.InPkg); err != nil { - t.Fatalf("Could not ingest pkg: %v", err) - } - for _, o := range test.Calls { - _, err := b.IngestPkgEquals(ctx, o.P1, o.P2, o.PE) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.PkgEqual(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - - keyvalue.MakeCanonicalPkgEqualSlice(got) - keyvalue.MakeCanonicalPkgEqualSlice(test.ExpHE) - - if diff := cmp.Diff(test.ExpHE, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func TestPkgEqualNeighbors(t *testing.T) { - type call struct { - P1 *model.PkgInputSpec - P2 *model.PkgInputSpec - HE *model.PkgEqualInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - Calls []call - ExpNeighbors map[string][]string - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{p1, p2}, - Calls: []call{ - { - P1: p1, - P2: p2, - HE: &model.PkgEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - ExpNeighbors: map[string][]string{ - "4": {"1", "6"}, // p1 - "5": {"1", "6"}, // p2 - "6": {"1", "1"}, // pkgequal - }, - }, - { - Name: "Multiple", - InPkg: []*model.PkgInputSpec{p1, p2, p3}, - Calls: []call{ - { - P1: p1, - P2: p2, - HE: &model.PkgEqualInputSpec{ - Justification: "test justification", - }, - }, - { - P1: p1, - P2: p3, - HE: &model.PkgEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - ExpNeighbors: map[string][]string{ - "4": {"1", "7", "8"}, // p1 - "5": {"1", "7"}, // p2 - "6": {"1", "8"}, // p3 - "7": {"1", "1"}, // pkgequal 1 - "8": {"1", "1"}, // pkgequal 2 - }, - }, - } - ctx := context.Background() - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, a := range test.InPkg { - if _, err := b.IngestPackage(ctx, *a); err != nil { - t.Fatalf("Could not ingest pkg: %v", err) - } - } - for _, o := range test.Calls { - if _, err := b.IngestPkgEqual(ctx, *o.P1, *o.P2, *o.HE); err != nil { - t.Fatalf("Could not ingest PkgEqual: %v", err) - } - } - for q, r := range test.ExpNeighbors { - got, err := b.Neighbors(ctx, q, nil) - if err != nil { - t.Fatalf("Could not query neighbors: %s", err) - } - gotIDs := convNodes(got) - slices.Sort(r) - slices.Sort(gotIDs) - if diff := cmp.Diff(r, gotIDs); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - } - }) - } -} diff --git a/pkg/assembler/backends/keyvalue/pkg_test.go b/pkg/assembler/backends/keyvalue/pkg_test.go deleted file mode 100644 index eb2b2eb4af..0000000000 --- a/pkg/assembler/backends/keyvalue/pkg_test.go +++ /dev/null @@ -1,861 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package keyvalue - -import ( - "context" - "reflect" - "strings" - "testing" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -func Test_pkgType_ID(t *testing.T) { - tests := []struct { - name string - id string - want string - }{{ - name: "getID", - id: "643", - want: "643", - }} - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - n := &pkgType{ - ThisID: tt.id, - } - if got := n.ID(); got != tt.want { - t.Errorf("pkgType.ID() = %v, want %v", got, tt.want) - } - }) - } -} - -func Test_pkgNamespace_ID(t *testing.T) { - tests := []struct { - name string - id string - want string - }{{ - name: "getID", - id: "643", - want: "643", - }} - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - n := &pkgNamespace{ - ThisID: tt.id, - } - if got := n.ID(); got != tt.want { - t.Errorf("pkgNamespace.ID() = %v, want %v", got, tt.want) - } - }) - } -} - -func Test_pkgName_ID(t *testing.T) { - tests := []struct { - name string - id string - want string - }{{ - name: "getID", - id: "643", - want: "643", - }} - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - n := &pkgName{ - ThisID: tt.id, - } - if got := n.ID(); got != tt.want { - t.Errorf("pkgName.ID() = %v, want %v", got, tt.want) - } - }) - } -} - -func Test_pkgVersion_ID(t *testing.T) { - tests := []struct { - name string - id string - want string - }{{ - name: "getID", - id: "643", - want: "643", - }} - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - n := &pkgVersion{ - ThisID: tt.id, - } - if got := n.ID(); got != tt.want { - t.Errorf("pkgVersion.ID() = %v, want %v", got, tt.want) - } - }) - } -} - -func Test_PkgType_Neighbors(t *testing.T) { - type fields struct { - id string - namespaces []string - } - tests := []struct { - name string - fields fields - want []string - }{{ - name: "PkgType Neighbors", - fields: fields{ - id: "23", - namespaces: []string{"24"}, - }, - want: []string{"24"}, - }} - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - n := &pkgType{ - ThisID: tt.fields.id, - Namespaces: tt.fields.namespaces, - } - if got := n.Neighbors(edgeMap{ - model.EdgePackageTypePackageNamespace: true, - }); !reflect.DeepEqual(got, tt.want) { - t.Errorf("PkgType.Neighbors() = %v, want %v", got, tt.want) - } - }) - } -} - -func Test_pkgNamespace_Neighbors(t *testing.T) { - type fields struct { - id string - parent string - namespace string - names []string - } - tests := []struct { - name string - fields fields - want []string - }{{ - name: "pkgNamespace Neighbors", - fields: fields{ - id: "23", - parent: "22", - namespace: "test", - names: []string{"24"}, - }, - want: []string{"24", "22"}, - }} - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - n := &pkgNamespace{ - ThisID: tt.fields.id, - Parent: tt.fields.parent, - Namespace: tt.fields.namespace, - Names: tt.fields.names, - } - if got := n.Neighbors(edgeMap{ - model.EdgePackageNamespacePackageType: true, - model.EdgePackageNamespacePackageName: true, - }); !reflect.DeepEqual(got, tt.want) { - t.Errorf("pkgNamespace.Neighbors() = %v, want %v", got, tt.want) - } - }) - } -} - -func Test_pkgName_Neighbors(t *testing.T) { - type fields struct { - id string - parent string - versions []string - srcMapLinks []string - isDependencyLinks []string - badLinks []string - goodLinks []string - } - tests := []struct { - name string - allowedEdges edgeMap - fields fields - want []string - }{ - { - name: "packageNamespace", - fields: fields{ - id: "23", - parent: "22", - versions: []string{"24"}, - srcMapLinks: []string{"343", "546"}, - }, - allowedEdges: edgeMap{model.EdgePackageNamePackageNamespace: true}, - want: []string{"22"}, - }, - { - name: "packageVersion", - fields: fields{ - id: "23", - parent: "22", - versions: []string{"24"}, - srcMapLinks: []string{"343", "546"}, - }, - allowedEdges: edgeMap{model.EdgePackageNamePackageVersion: true}, - want: []string{"24"}, - }, - { - name: "srcMapLinks", - fields: fields{ - id: "23", - parent: "22", - versions: []string{"24"}, - srcMapLinks: []string{"343", "546"}, - }, - allowedEdges: edgeMap{model.EdgePackageHasSourceAt: true}, - want: []string{"343", "546"}, - }, - { - name: "isDependencyLinks", - fields: fields{ - id: "23", - parent: "22", - versions: []string{"24"}, - isDependencyLinks: []string{"2324", "1234"}, - }, - allowedEdges: edgeMap{model.EdgePackageIsDependency: true}, - want: []string{"2324", "1234"}, - }, - { - name: "badLinks", - fields: fields{ - id: "23", - parent: "22", - versions: []string{"24"}, - badLinks: []string{"445", "1232244"}, - }, - allowedEdges: edgeMap{model.EdgePackageCertifyBad: true}, - want: []string{"445", "1232244"}, - }, - { - name: "goodLinks", - fields: fields{ - id: "23", - parent: "22", - versions: []string{"24"}, - goodLinks: []string{"987", "9876"}, - }, - allowedEdges: edgeMap{model.EdgePackageCertifyGood: true}, - want: []string{"987", "9876"}, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - n := &pkgName{ - ThisID: tt.fields.id, - Parent: tt.fields.parent, - Versions: tt.fields.versions, - SrcMapLinks: tt.fields.srcMapLinks, - IsDependencyLinks: tt.fields.isDependencyLinks, - BadLinks: tt.fields.badLinks, - GoodLinks: tt.fields.goodLinks, - } - if got := n.Neighbors(tt.allowedEdges); !reflect.DeepEqual(got, tt.want) { - t.Errorf("pkgName.Neighbors() = %v, want %v", got, tt.want) - } - }) - } -} - -func Test_pkgVersion_Neighbors(t *testing.T) { - type fields struct { - id string - parent string - srcMapLinks []string - isDependencyLinks []string - occurrences []string - certifyVulnLinks []string - hasSBOMs []string - vexLinks []string - badLinks []string - goodLinks []string - pkgEquals []string - } - tests := []struct { - name string - allowedEdges edgeMap - fields fields - want []string - }{ - { - name: "packageName", - fields: fields{ - id: "23", - parent: "22", - srcMapLinks: []string{"343", "546"}, - }, - allowedEdges: edgeMap{model.EdgePackageVersionPackageName: true}, - want: []string{"22"}, - }, - { - name: "srcMapLinks", - fields: fields{ - id: "23", - parent: "22", - srcMapLinks: []string{"343", "546"}, - }, - allowedEdges: edgeMap{model.EdgePackageHasSourceAt: true}, - want: []string{"343", "546"}, - }, - { - name: "isDependencyLinks", - fields: fields{ - id: "23", - parent: "22", - isDependencyLinks: []string{"2324", "1234"}, - }, - allowedEdges: edgeMap{model.EdgePackageIsDependency: true}, - want: []string{"2324", "1234"}, - }, - { - name: "occurrences", - fields: fields{ - id: "23", - parent: "22", - occurrences: []string{"2324", "1234"}, - }, - allowedEdges: edgeMap{model.EdgePackageIsOccurrence: true}, - want: []string{"2324", "1234"}, - }, - { - name: "certifyVulnLinks", - fields: fields{ - id: "23", - parent: "22", - certifyVulnLinks: []string{"2324", "1234"}, - }, - allowedEdges: edgeMap{model.EdgePackageCertifyVuln: true}, - want: []string{"2324", "1234"}, - }, - { - name: "hasSBOMs", - fields: fields{ - id: "23", - parent: "22", - hasSBOMs: []string{"2324", "1234"}, - }, - allowedEdges: edgeMap{model.EdgePackageHasSbom: true}, - want: []string{"2324", "1234"}, - }, - { - name: "vexLinks", - fields: fields{ - id: "23", - parent: "22", - vexLinks: []string{"2324", "1234"}, - }, - allowedEdges: edgeMap{model.EdgePackageCertifyVexStatement: true}, - want: []string{"2324", "1234"}, - }, - { - name: "badLinks", - fields: fields{ - id: "23", - parent: "22", - badLinks: []string{"445", "1232244"}, - }, - allowedEdges: edgeMap{model.EdgePackageCertifyBad: true}, - want: []string{"445", "1232244"}, - }, - { - name: "goodLinks", - fields: fields{ - id: "23", - parent: "22", - goodLinks: []string{"987", "9876"}, - }, - allowedEdges: edgeMap{model.EdgePackageCertifyGood: true}, - want: []string{"987", "9876"}, - }, - { - name: "pkgEquals", - fields: fields{ - id: "23", - parent: "22", - pkgEquals: []string{"987", "9876"}, - }, - allowedEdges: edgeMap{model.EdgePackagePkgEqual: true}, - want: []string{"987", "9876"}, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - n := &pkgVersion{ - ThisID: tt.fields.id, - Parent: tt.fields.parent, - SrcMapLinks: tt.fields.srcMapLinks, - IsDependencyLinks: tt.fields.isDependencyLinks, - Occurrences: tt.fields.occurrences, - CertifyVulnLinks: tt.fields.certifyVulnLinks, - HasSBOMs: tt.fields.hasSBOMs, - VexLinks: tt.fields.vexLinks, - BadLinks: tt.fields.badLinks, - GoodLinks: tt.fields.goodLinks, - PkgEquals: tt.fields.pkgEquals, - } - if got := n.Neighbors(tt.allowedEdges); !reflect.DeepEqual(got, tt.want) { - t.Errorf("pkgVersion.Neighbors() = %v, want %v", got, tt.want) - } - }) - } -} - -var p1 = &model.PkgInputSpec{ - Type: "pypi", - Name: "tensorflow", -} -var p1out = &model.Package{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{{ - Names: []*model.PackageName{{ - Name: "tensorflow", - Versions: []*model.PackageVersion{{ - Version: "", - Qualifiers: []*model.PackageQualifier{}, - }}, - }}, - }}, -} - -var p2 = &model.PkgInputSpec{ - Type: "pypi", - Name: "tensorflow", - Version: ptrfrom.String("2.11.1"), -} -var p2out = &model.Package{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{{ - Names: []*model.PackageName{{ - Name: "tensorflow", - Versions: []*model.PackageVersion{{ - Version: "2.11.1", - Qualifiers: []*model.PackageQualifier{}, - }}, - }}, - }}, -} - -var p3 = &model.PkgInputSpec{ - Type: "pypi", - Name: "tensorflow", - Version: ptrfrom.String("2.11.1"), - Subpath: ptrfrom.String("saved_model_cli.py"), -} -var p3out = &model.Package{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{{ - Names: []*model.PackageName{{ - Name: "tensorflow", - Versions: []*model.PackageVersion{{ - Version: "2.11.1", - Subpath: "saved_model_cli.py", - Qualifiers: []*model.PackageQualifier{}, - }}, - }}, - }}, -} - -var p4 = &model.PkgInputSpec{ - Type: "conan", - Namespace: ptrfrom.String("openssl.org"), - Name: "openssl", - Version: ptrfrom.String("3.0.3"), -} -var p4out = &model.Package{ - Type: "conan", - Namespaces: []*model.PackageNamespace{{ - Namespace: "openssl.org", - Names: []*model.PackageName{{ - Name: "openssl", - Versions: []*model.PackageVersion{{ - Version: "3.0.3", - Qualifiers: []*model.PackageQualifier{}, - }}, - }}, - }}, -} - -func Test_demoClient_Packages(t *testing.T) { - ctx := context.Background() - tests := []struct { - name string - pkgInput *model.PkgInputSpec - pkgFilter *model.PkgSpec - idInFilter bool - want []*model.Package - wantErr bool - }{{ - name: "tensorflow empty version", - pkgInput: p1, - pkgFilter: &model.PkgSpec{ - Name: ptrfrom.String("tensorflow"), - }, - idInFilter: false, - want: []*model.Package{p1out}, - wantErr: false, - }, { - name: "tensorflow empty version, ID search", - pkgInput: p1, - pkgFilter: &model.PkgSpec{ - Name: ptrfrom.String("tensorflow"), - }, - idInFilter: true, - want: []*model.Package{p1out}, - wantErr: false, - }, { - name: "tensorflow with version", - pkgInput: p2, - pkgFilter: &model.PkgSpec{ - Type: ptrfrom.String("pypi"), - Name: ptrfrom.String("tensorflow"), - }, - idInFilter: false, - want: []*model.Package{p2out}, - wantErr: false, - }, { - name: "tensorflow with version and subpath", - pkgInput: p3, - pkgFilter: &model.PkgSpec{ - Type: ptrfrom.String("pypi"), - Name: ptrfrom.String("tensorflow"), - Subpath: ptrfrom.String("saved_model_cli.py"), - }, - idInFilter: false, - want: []*model.Package{p3out}, - wantErr: false, - }, { - name: "openssl with version", - pkgInput: p4, - pkgFilter: &model.PkgSpec{ - Name: ptrfrom.String("openssl"), - Version: ptrfrom.String("3.0.3"), - }, - idInFilter: false, - want: []*model.Package{p4out}, - wantErr: false, - }} - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - c, _ := getBackend(ctx, nil) - ingestedPkg, err := c.IngestPackage(ctx, *tt.pkgInput) - if (err != nil) != tt.wantErr { - t.Errorf("demoClient.IngestPackage() error = %v, wantErr %v", err, tt.wantErr) - return - } - if tt.idInFilter { - tt.pkgFilter.ID = &ingestedPkg.PackageVersionID - } - got, err := c.Packages(ctx, tt.pkgFilter) - if (err != nil) != tt.wantErr { - t.Errorf("demoClient.Packages() error = %v, wantErr %v", err, tt.wantErr) - return - } - if diff := cmp.Diff(tt.want, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func Test_demoClient_IngestPackages(t *testing.T) { - ctx := context.Background() - tests := []struct { - name string - pkgInputs []*model.PkgInputSpec - wantErr bool - }{ - { - name: "tensorflow empty version", - pkgInputs: []*model.PkgInputSpec{p1, p2, p3, p4}, - wantErr: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - c, _ := getBackend(ctx, nil) - _, err := c.IngestPackages(ctx, tt.pkgInputs) - if (err != nil) != tt.wantErr { - t.Errorf("demoClient.IngestPackages() error = %v, wantErr %v", err, tt.wantErr) - } - }) - } -} - -var pp5out = &model.Package{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{{ - Names: []*model.PackageName{{ - Name: "tensorflow", - Versions: []*model.PackageVersion{ - { - Version: "2.11.1", - Qualifiers: []*model.PackageQualifier{}, - }, - { - Version: "2.11.3", - Qualifiers: []*model.PackageQualifier{}, - }, - }, - }}, - }}, -} -var pp6out = &model.Package{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{{ - Names: []*model.PackageName{{ - Name: "tensorflow", - Versions: []*model.PackageVersion{ - { - Version: "2.11.1", - Qualifiers: []*model.PackageQualifier{}, - Subpath: "a", - }, - { - Version: "2.11.1", - Qualifiers: []*model.PackageQualifier{}, - Subpath: "b", - }, - }, - }}, - }}, -} -var pp7out = &model.Package{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{{ - Names: []*model.PackageName{{ - Name: "tensorflow", - Versions: []*model.PackageVersion{ - { - Version: "2.11.1", - Qualifiers: []*model.PackageQualifier{{Key: "1", Value: "2"}}, - }, - { - Version: "2.11.1", - Qualifiers: []*model.PackageQualifier{{Key: "a", Value: "b"}, {Key: "c", Value: "d"}}, - }, - }, - }}, - }}, -} -var pp8out = &model.Package{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{{ - Names: []*model.PackageName{{ - Name: "tensorflow", - Versions: []*model.PackageVersion{ - { - Version: "2.11.1", - Qualifiers: []*model.PackageQualifier{{Key: "a", Value: "b"}}, - }, - }, - }}, - }}, -} - -var p9out = &model.Package{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{{ - Names: []*model.PackageName{{ - Name: "tensorflow", - Versions: []*model.PackageVersion{ - { - Version: "", - Qualifiers: []*model.PackageQualifier{}, - }, - }, - }}, - }}, -} - -var p10out = &model.Package{ - Type: "pypi", - Namespaces: []*model.PackageNamespace{{ - Names: []*model.PackageName{{ - Name: "tensorflow", - Versions: []*model.PackageVersion{ - { - Version: "2.11.1", - Qualifiers: []*model.PackageQualifier{}, - }, - { - Version: "", - Qualifiers: []*model.PackageQualifier{}, - }, - }, - }}, - }}, -} - -func Test_IngestingVersions(t *testing.T) { - ctx := context.Background() - tests := []struct { - name string - pkgInputs []*model.PkgInputSpec - want []*model.Package - }{ - { - name: "package name without version", - pkgInputs: []*model.PkgInputSpec{ - { - Type: "pypi", - Name: "tensorflow", - }, - }, - want: []*model.Package{p9out}, - }, - { - name: "package names with and without version", - pkgInputs: []*model.PkgInputSpec{ - { - Type: "pypi", - Name: "tensorflow", - Version: ptrfrom.String("2.11.1"), - }, - { - Type: "pypi", - Name: "tensorflow", - }, - }, - want: []*model.Package{p10out}, - }, - { - name: "different versions are not considered duplicates ", - pkgInputs: []*model.PkgInputSpec{ - { - Type: "pypi", - Name: "tensorflow", - Version: ptrfrom.String("2.11.1"), - }, - { - Type: "pypi", - Name: "tensorflow", - Version: ptrfrom.String("2.11.3"), - }, - }, - want: []*model.Package{pp5out}, - }, - { - name: "version nodes with different subpaths are not considered duplicates ", - pkgInputs: []*model.PkgInputSpec{ - { - Type: "pypi", - Name: "tensorflow", - Version: ptrfrom.String("2.11.1"), - Subpath: ptrfrom.String("a"), - }, - { - Type: "pypi", - Name: "tensorflow", - Version: ptrfrom.String("2.11.1"), - Subpath: ptrfrom.String("b"), - }, - }, - want: []*model.Package{pp6out}, - }, - { - name: "version nodes with different qualifiers are not considered duplicates ", - pkgInputs: []*model.PkgInputSpec{ - { - Type: "pypi", - Name: "tensorflow", - Version: ptrfrom.String("2.11.1"), - Qualifiers: []*model.PackageQualifierInputSpec{{Key: "1", Value: "2"}}, - }, - { - Type: "pypi", - Name: "tensorflow", - Version: ptrfrom.String("2.11.1"), - Qualifiers: []*model.PackageQualifierInputSpec{{Key: "a", Value: "b"}, {Key: "c", Value: "d"}}, - }, - }, - want: []*model.Package{pp7out}, - }, - { - name: "a single package is created from duplicate version nodes (just with versions)", - pkgInputs: []*model.PkgInputSpec{p2, p2}, - want: []*model.Package{p2out}, - }, - { - name: "a single package is created from duplicate version nodes with (versions and subpaths)", - pkgInputs: []*model.PkgInputSpec{p3, p3}, - want: []*model.Package{p3out}, - }, - { - name: "a single package is created from duplicate version nodes (with versions, subpaths, and qualifiers)", - pkgInputs: []*model.PkgInputSpec{ - { - Type: "pypi", - Name: "tensorflow", - Version: ptrfrom.String("2.11.1"), - Qualifiers: []*model.PackageQualifierInputSpec{{Key: "a", Value: "b"}}, - }, - { - Type: "pypi", - Name: "tensorflow", - Version: ptrfrom.String("2.11.1"), - Qualifiers: []*model.PackageQualifierInputSpec{{Key: "a", Value: "b"}}, - }, - }, - want: []*model.Package{pp8out}, - }, - } - - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - c, _ := getBackend(ctx, nil) - _, err := c.IngestPackages(ctx, tt.pkgInputs) - if err != nil { - t.Errorf("Unexpected demoClient.IngestPackages() error = %v, ", err) - return - } - packages, err := c.Packages(ctx, nil) - if err != nil { - t.Errorf("Unexpected demoClient.Packages() error = %v, ", err) - return - } - - MakeCanonicalPackageSlice(packages) - MakeCanonicalPackageSlice(tt.want) - - if diff := cmp.Diff(tt.want, packages, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } - -} diff --git a/pkg/assembler/backends/keyvalue/pointOfContact.go b/pkg/assembler/backends/keyvalue/pointOfContact.go index 93a85afc9f..8d3a1d3ad5 100644 --- a/pkg/assembler/backends/keyvalue/pointOfContact.go +++ b/pkg/assembler/backends/keyvalue/pointOfContact.go @@ -125,30 +125,29 @@ func (c *demoClient) ingestPointOfContact(ctx context.Context, subject model.Pac lock(&c.m, readOnly) defer unlock(&c.m, readOnly) - var foundPkgNameorVersionNode pkgNameOrVersion - var foundArtStrct *artStruct + var foundPkgNameOrVersionNode pkgNameOrVersion + var foundArtStruct *artStruct var srcName *srcNameNode if subject.Package != nil { var err error - foundPkgNameorVersionNode, err = c.getPackageNameOrVerFromInput(ctx, *subject.Package, *pkgMatchType) + in.PackageID, foundPkgNameOrVersionNode, err = c.returnFoundPkgBasedOnMatchType(ctx, subject.Package, pkgMatchType) if err != nil { return "", gqlerror.Errorf("%v :: %s", funcName, err) } - in.PackageID = foundPkgNameorVersionNode.ID() } else if subject.Artifact != nil { var err error - foundArtStrct, err = c.artifactByInput(ctx, subject.Artifact) + foundArtStruct, err = c.returnFoundArtifact(ctx, subject.Artifact) if err != nil { return "", gqlerror.Errorf("%v :: %s", funcName, err) } - in.ArtifactID = foundArtStrct.ThisID + in.ArtifactID = foundArtStruct.ID() } else { var err error - srcName, err = c.getSourceNameFromInput(ctx, *subject.Source) + srcName, err = c.returnFoundSource(ctx, subject.Source) if err != nil { return "", gqlerror.Errorf("%v :: %s", funcName, err) } - in.SourceID = srcName.ThisID + in.SourceID = srcName.ID() } out, err := byKeykv[*pointOfContactLink](ctx, pocCol, in.Key(), c) @@ -171,13 +170,13 @@ func (c *demoClient) ingestPointOfContact(ctx context.Context, subject model.Pac return "", err } - if foundPkgNameorVersionNode != nil { - if err := foundPkgNameorVersionNode.setPointOfContactLinks(ctx, in.ThisID, c); err != nil { + if foundPkgNameOrVersionNode != nil { + if err := foundPkgNameOrVersionNode.setPointOfContactLinks(ctx, in.ThisID, c); err != nil { return "", err } } - if foundArtStrct != nil { - if err := foundArtStrct.setPointOfContactLinks(ctx, in.ThisID, c); err != nil { + if foundArtStruct != nil { + if err := foundArtStruct.setPointOfContactLinks(ctx, in.ThisID, c); err != nil { return "", err } } diff --git a/pkg/assembler/backends/keyvalue/pointOfContact_test.go b/pkg/assembler/backends/keyvalue/pointOfContact_test.go deleted file mode 100644 index eebc43ac16..0000000000 --- a/pkg/assembler/backends/keyvalue/pointOfContact_test.go +++ /dev/null @@ -1,1076 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package keyvalue_test - -import ( - "context" - "slices" - "strings" - "testing" - "time" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/internal/testing/stablememmap" - "github.com/guacsec/guac/pkg/assembler/backends" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -func TestPointOfContact(t *testing.T) { - type call struct { - Sub model.PackageSourceOrArtifactInput - Match *model.MatchFlags - HM *model.PointOfContactInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - InArt []*model.ArtifactInputSpec - Calls []call - Query *model.PointOfContactSpec - ExpHM []*model.PointOfContact - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.PointOfContactInputSpec{ - Email: "a@b.com", - Info: "info1", - Since: time.Unix(1e9, 0), - Justification: "test justification", - }, - }, - }, - Query: &model.PointOfContactSpec{ - Email: ptrfrom.String("a@b.com"), - Info: ptrfrom.String("info1"), - Since: ptrfrom.Time(time.Unix(1e9, 0)), - Justification: ptrfrom.String("test justification"), - }, - ExpHM: []*model.PointOfContact{ - { - Subject: p1out, - Email: "a@b.com", - Info: "info1", - Since: time.Unix(1e9, 0), - Justification: "test justification", - }, - }, - }, - { - Name: "HappyPath check time since", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.PointOfContactInputSpec{ - Email: "a@b.com", - Info: "info1", - Since: time.Unix(1e9, 0), - Justification: "test justification", - }, - }, - }, - Query: &model.PointOfContactSpec{ - Email: ptrfrom.String("a@b.com"), - Info: ptrfrom.String("info1"), - Since: ptrfrom.Time(time.Unix(1e8, 0)), - Justification: ptrfrom.String("test justification"), - }, - ExpHM: []*model.PointOfContact{ - { - Subject: p1out, - Email: "a@b.com", - Info: "info1", - Since: time.Unix(1e9, 0), - Justification: "test justification", - }, - }, - }, - { - Name: "UnhappyPath check time since", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.PointOfContactInputSpec{ - Email: "a@b.com", - Info: "info1", - Since: time.Unix(1e9, 0), - Justification: "test justification", - }, - }, - }, - Query: &model.PointOfContactSpec{ - Email: ptrfrom.String("a@b.com"), - Info: ptrfrom.String("info1"), - Since: ptrfrom.Time(time.Unix(1e10, 0)), - Justification: ptrfrom.String("test justification"), - }, - ExpHM: nil, - }, - { - Name: "HappyPath All Version", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.PointOfContactSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHM: []*model.PointOfContact{ - { - Subject: p1outName, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest same twice", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.PointOfContactSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHM: []*model.PointOfContact{ - { - Subject: p1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest two different keys", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.PointOfContactInputSpec{ - Email: "a@b.com", - Info: "info1", - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.PointOfContactInputSpec{ - Email: "x@y.com", - Info: "info2", - Justification: "test justification", - }, - }, - }, - Query: &model.PointOfContactSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHM: []*model.PointOfContact{ - { - Subject: p1out, - Email: "x@y.com", - Info: "info2", - Justification: "test justification", - }, - { - Subject: p1out, - Email: "a@b.com", - Info: "info1", - Justification: "test justification", - }, - }, - }, - - { - Name: "Query on Justification", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification one", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification two", - }, - }, - }, - Query: &model.PointOfContactSpec{ - Justification: ptrfrom.String("test justification one"), - }, - ExpHM: []*model.PointOfContact{ - { - Subject: p1out, - Justification: "test justification one", - }, - }, - }, - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{p1, p2}, - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s1, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.PointOfContactSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String("2.11.1"), - }, - }, - }, - ExpHM: []*model.PointOfContact{ - { - Subject: p2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Source", - InPkg: []*model.PkgInputSpec{p1}, - InSrc: []*model.SourceInputSpec{s1, s2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s1, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s2, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.PointOfContactSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Source: &model.SourceSpec{ - Name: ptrfrom.String("bobsrepo"), - }, - }, - }, - ExpHM: []*model.PointOfContact{ - { - Subject: s2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Artifact", - InSrc: []*model.SourceInputSpec{s1}, - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a1, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a2, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s1, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.PointOfContactSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha1"), - }, - }, - }, - ExpHM: []*model.PointOfContact{ - { - Subject: a2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query none", - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a1, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a2, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.PointOfContactSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("asdf"), - }, - }, - }, - ExpHM: nil, - }, - { - Name: "Query multiple", - InSrc: []*model.SourceInputSpec{s1, s2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s1, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s2, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.PointOfContactSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpHM: []*model.PointOfContact{ - { - Subject: s2out, - Justification: "test justification", - }, - { - Subject: s1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query Packages", - InPkg: []*model.PkgInputSpec{p1, p2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p2, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.PointOfContactSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String("2.11.1"), - }, - }, - }, - ExpHM: []*model.PointOfContact{ - { - Subject: p2out, - Justification: "test justification", - }, - { - Subject: p1outName, - Justification: "test justification", - }, - }, - }, - { - Name: "Query ID", - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a1, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a2, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.PointOfContactSpec{ - ID: ptrfrom.String("3"), - }, - ExpHM: []*model.PointOfContact{ - { - Subject: a1out, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest without subject", - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a1, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - }, - ExpIngestErr: true, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - ctx := context.Background() - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - for _, o := range test.Calls { - _, err := b.IngestPointOfContact(ctx, o.Sub, o.Match, *o.HM) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.PointOfContact(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpHM, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func TestIngestPointOfContacts(t *testing.T) { - type call struct { - Sub model.PackageSourceOrArtifactInputs - Match *model.MatchFlags - PC []*model.PointOfContactInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - InArt []*model.ArtifactInputSpec - Calls []call - Query *model.PointOfContactSpec - ExpPC []*model.PointOfContact - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - PC: []*model.PointOfContactInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.PointOfContactSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpPC: []*model.PointOfContact{ - { - Subject: p1out, - Justification: "test justification", - }, - }, - }, - { - Name: "HappyPath All Version", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - PC: []*model.PointOfContactInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.PointOfContactSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpPC: []*model.PointOfContact{ - { - Subject: p1outName, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest same twice", - InPkg: []*model.PkgInputSpec{p3}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p3, p3}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - PC: []*model.PointOfContactInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.PointOfContactSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Package: &model.PkgSpec{ - Version: ptrfrom.String("2.11.1"), - Subpath: ptrfrom.String("saved_model_cli.py"), - }, - }, - }, - ExpPC: []*model.PointOfContact{ - { - Subject: p3out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Package", - InPkg: []*model.PkgInputSpec{p1, p4}, - InSrc: []*model.SourceInputSpec{s1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1, p4}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - PC: []*model.PointOfContactInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - { - Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{s1}, - }, - PC: []*model.PointOfContactInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.PointOfContactSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Package: &model.PkgSpec{ - Type: ptrfrom.String("conan"), - Namespace: ptrfrom.String("openssl.org"), - Name: ptrfrom.String("openssl"), - }, - }, - }, - ExpPC: []*model.PointOfContact{ - { - Subject: p4out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Source", - InPkg: []*model.PkgInputSpec{p1}, - InSrc: []*model.SourceInputSpec{s1, s2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{p1}, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - PC: []*model.PointOfContactInputSpec{ - { - Justification: "test justification", - }, - }, - }, - { - Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{s2, s2}, - }, - PC: []*model.PointOfContactInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.PointOfContactSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Source: &model.SourceSpec{ - Name: ptrfrom.String("bobsrepo"), - }, - }, - }, - ExpPC: []*model.PointOfContact{ - { - Subject: s2out, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Artifact", - InSrc: []*model.SourceInputSpec{s1}, - InArt: []*model.ArtifactInputSpec{a1, a2}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInputs{ - Artifacts: []*model.ArtifactInputSpec{a1, a2}, - }, - PC: []*model.PointOfContactInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - { - Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{s1}, - }, - PC: []*model.PointOfContactInputSpec{ - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.PointOfContactSpec{ - Subject: &model.PackageSourceOrArtifactSpec{ - Artifact: &model.ArtifactSpec{ - Algorithm: ptrfrom.String("sha1"), - }, - }, - }, - ExpPC: []*model.PointOfContact{ - { - Subject: a2out, - Justification: "test justification", - }, - }, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - ctx := context.Background() - - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - for _, o := range test.Calls { - _, err := b.IngestPointOfContacts(ctx, o.Sub, o.Match, o.PC) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.PointOfContact(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpPC, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func TestPointOfContactNeighbors(t *testing.T) { - type call struct { - Sub model.PackageSourceOrArtifactInput - Match *model.MatchFlags - HM *model.PointOfContactInputSpec - } - tests := []struct { - Name string - InPkg []*model.PkgInputSpec - InSrc []*model.SourceInputSpec - InArt []*model.ArtifactInputSpec - Calls []call - ExpNeighbors map[string][]string - }{ - { - Name: "HappyPath", - InPkg: []*model.PkgInputSpec{p1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeSpecificVersion, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - }, - ExpNeighbors: map[string][]string{ - "4": {"1", "5"}, // pkg version - "5": {"1"}, // certify good - }, - }, - { - Name: "Pkg Name Src and Artifact", - InPkg: []*model.PkgInputSpec{p1}, - InSrc: []*model.SourceInputSpec{s1}, - InArt: []*model.ArtifactInputSpec{a1}, - Calls: []call{ - { - Sub: model.PackageSourceOrArtifactInput{ - Package: p1, - }, - Match: &model.MatchFlags{ - Pkg: model.PkgMatchTypeAllVersions, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Source: s1, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - { - Sub: model.PackageSourceOrArtifactInput{ - Artifact: a1, - }, - HM: &model.PointOfContactInputSpec{ - Justification: "test justification", - }, - }, - }, - ExpNeighbors: map[string][]string{ - "1": {"1"}, - "2": {"1", "1"}, - "3": {"1", "1", "9"}, // pkg name - "4": {"1"}, // pkg version - "5": {"5"}, - "6": {"5", "5"}, - "7": {"5", "10"}, // src name - "8": {"11"}, // art - "9": {"1"}, // cb 1 -> pkg name - "10": {"5"}, // cb 2 -> src name - "11": {"8"}, // cb 3 -> art - }, - }, - } - ctx := context.Background() - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, p := range test.InPkg { - if _, err := b.IngestPackage(ctx, *p); err != nil { - t.Fatalf("Could not ingest package: %v", err) - } - } - for _, s := range test.InSrc { - if _, err := b.IngestSource(ctx, *s); err != nil { - t.Fatalf("Could not ingest source: %v", err) - } - } - for _, a := range test.InArt { - if _, err := b.IngestArtifact(ctx, a); err != nil { - t.Fatalf("Could not ingest artifact: %v", err) - } - } - for _, o := range test.Calls { - if _, err := b.IngestPointOfContact(ctx, o.Sub, o.Match, *o.HM); err != nil { - t.Fatalf("Could not ingest PointOfContact: %v", err) - } - } - for q, r := range test.ExpNeighbors { - got, err := b.Neighbors(ctx, q, nil) - if err != nil { - t.Fatalf("Could not query neighbors: %s", err) - } - gotIDs := convNodes(got) - slices.Sort(r) - slices.Sort(gotIDs) - if diff := cmp.Diff(r, gotIDs); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - } - }) - } -} diff --git a/pkg/assembler/backends/keyvalue/src.go b/pkg/assembler/backends/keyvalue/src.go index 7c003d6c76..57b42a30ad 100644 --- a/pkg/assembler/backends/keyvalue/src.go +++ b/pkg/assembler/backends/keyvalue/src.go @@ -184,7 +184,7 @@ func (n *srcNamespace) addName(ctx context.Context, name string, c *demoClient) // Ingest Source -func (c *demoClient) IngestSources(ctx context.Context, sources []*model.SourceInputSpec) ([]*model.SourceIDs, error) { +func (c *demoClient) IngestSources(ctx context.Context, sources []*model.IDorSourceInput) ([]*model.SourceIDs, error) { var modelSources []*model.SourceIDs for _, src := range sources { modelSrc, err := c.IngestSource(ctx, *src) @@ -196,9 +196,9 @@ func (c *demoClient) IngestSources(ctx context.Context, sources []*model.SourceI return modelSources, nil } -func (c *demoClient) IngestSource(ctx context.Context, input model.SourceInputSpec) (*model.SourceIDs, error) { +func (c *demoClient) IngestSource(ctx context.Context, input model.IDorSourceInput) (*model.SourceIDs, error) { inType := &srcType{ - Type: input.Type, + Type: input.SourceInput.Type, } c.m.RLock() outType, err := byKeykv[*srcType](ctx, srcTypeCol, inType.Key(), c) @@ -230,7 +230,7 @@ func (c *demoClient) IngestSource(ctx context.Context, input model.SourceInputSp inNamespace := &srcNamespace{ Parent: outType.ThisID, - Namespace: input.Namespace, + Namespace: input.SourceInput.Namespace, } c.m.RLock() outNamespace, err := byKeykv[*srcNamespace](ctx, srcNSCol, inNamespace.Key(), c) @@ -266,9 +266,9 @@ func (c *demoClient) IngestSource(ctx context.Context, input model.SourceInputSp inName := &srcNameNode{ Parent: outNamespace.ThisID, - Name: input.Name, - Tag: nilToEmpty(input.Tag), - Commit: nilToEmpty(input.Commit), + Name: input.SourceInput.Name, + Tag: nilToEmpty(input.SourceInput.Tag), + Commit: nilToEmpty(input.SourceInput.Commit), } c.m.RLock() outName, err := byKeykv[*srcNameNode](ctx, srcNameCol, inName.Key(), c) @@ -621,3 +621,20 @@ func (c *demoClient) exactSource(ctx context.Context, filter *model.SourceSpec) } return nil, nil } + +// returnFoundSource return the node by first searching via ID. If the ID is not specified, it defaults to searching via inputspec +func (c *demoClient) returnFoundSource(ctx context.Context, srcIDorInput *model.IDorSourceInput) (*srcNameNode, error) { + if srcIDorInput.SourceNameID != nil { + foundSrcNameNode, err := byIDkv[*srcNameNode](ctx, *srcIDorInput.SourceNameID, c) + if err != nil { + return nil, gqlerror.Errorf("failed to return srcNameNode node by ID with error: %v", err) + } + return foundSrcNameNode, nil + } else { + foundSrcNameNode, err := c.getSourceNameFromInput(ctx, *srcIDorInput.SourceInput) + if err != nil { + return nil, gqlerror.Errorf("failed to getSourceNameFromInput with error: %v", err) + } + return foundSrcNameNode, nil + } +} diff --git a/pkg/assembler/backends/keyvalue/src_test.go b/pkg/assembler/backends/keyvalue/src_test.go deleted file mode 100644 index a9a00df85f..0000000000 --- a/pkg/assembler/backends/keyvalue/src_test.go +++ /dev/null @@ -1,157 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package keyvalue - -import ( - "context" - "strings" - "testing" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -var s1 = &model.SourceInputSpec{ - Type: "git", - Namespace: "github.com/jeff", - Name: "myrepo", - Tag: ptrfrom.String("v1.0"), -} -var s1out = &model.Source{ - Type: "git", - Namespaces: []*model.SourceNamespace{{ - Namespace: "github.com/jeff", - Names: []*model.SourceName{{ - Name: "myrepo", - Tag: ptrfrom.String("v1.0"), - }}, - }}, -} - -var s2 = &model.SourceInputSpec{ - Type: "git", - Namespace: "github.com/bob", - Name: "bobsrepo", - Commit: ptrfrom.String("5e7c41f"), -} -var s2out = &model.Source{ - Type: "git", - Namespaces: []*model.SourceNamespace{{ - Namespace: "github.com/bob", - Names: []*model.SourceName{{ - Name: "bobsrepo", - Commit: ptrfrom.String("5e7c41f"), - }}, - }}, -} - -func Test_demoClient_IngestSources(t *testing.T) { - ctx := context.Background() - tests := []struct { - name string - srcInputs []*model.SourceInputSpec - wantErr bool - }{{ - name: "test batch source intestion", - srcInputs: []*model.SourceInputSpec{s1, s2}, - wantErr: false, - }} - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - c, _ := getBackend(context.Background(), nil) - _, err := c.IngestSources(ctx, tt.srcInputs) - if (err != nil) != tt.wantErr { - t.Errorf("demoClient.IngestSources() error = %v, wantErr %v", err, tt.wantErr) - } - }) - } -} - -func Test_demoClient_Sources(t *testing.T) { - ctx := context.Background() - tests := []struct { - name string - srcInput *model.SourceInputSpec - srcFilter *model.SourceSpec - idInFilter bool - want []*model.Source - wantErr bool - }{{ - name: "myrepo with tag", - srcInput: s1, - srcFilter: &model.SourceSpec{ - Name: ptrfrom.String("myrepo"), - }, - idInFilter: false, - want: []*model.Source{s1out}, - wantErr: false, - }, { - name: "myrepo with tag, ID search", - srcInput: s1, - srcFilter: &model.SourceSpec{ - Name: ptrfrom.String("myrepo"), - }, - idInFilter: true, - want: []*model.Source{s1out}, - wantErr: false, - }, { - name: "bobsrepo with commit", - srcInput: s2, - srcFilter: &model.SourceSpec{ - Namespace: ptrfrom.String("github.com/bob"), - Commit: ptrfrom.String("5e7c41f"), - }, - idInFilter: false, - want: []*model.Source{s2out}, - wantErr: false, - }, { - name: "bobsrepo with commit, type search", - srcInput: s2, - srcFilter: &model.SourceSpec{ - Type: ptrfrom.String("git"), - Namespace: ptrfrom.String("github.com/bob"), - Commit: ptrfrom.String("5e7c41f"), - }, - idInFilter: false, - want: []*model.Source{s2out}, - wantErr: false, - }} - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - c, _ := getBackend(context.Background(), nil) - ingestedPkg, err := c.IngestSource(ctx, *tt.srcInput) - if (err != nil) != tt.wantErr { - t.Errorf("demoClient.IngestSource() error = %v, wantErr %v", err, tt.wantErr) - return - } - if tt.idInFilter { - tt.srcFilter.ID = &ingestedPkg.SourceNameID - } - got, err := c.Sources(ctx, tt.srcFilter) - if (err != nil) != tt.wantErr { - t.Errorf("demoClient.Sources() error = %v, wantErr %v", err, tt.wantErr) - return - } - if diff := cmp.Diff(tt.want, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} diff --git a/pkg/assembler/backends/keyvalue/vulnEqual.go b/pkg/assembler/backends/keyvalue/vulnEqual.go index 94982734f1..49477ae3c2 100644 --- a/pkg/assembler/backends/keyvalue/vulnEqual.go +++ b/pkg/assembler/backends/keyvalue/vulnEqual.go @@ -59,7 +59,7 @@ func (n *vulnerabilityEqualLink) BuildModelNode(ctx context.Context, c *demoClie // Ingest IngestVulnEqual -func (c *demoClient) IngestVulnEquals(ctx context.Context, vulnerabilities []*model.VulnerabilityInputSpec, otherVulnerabilities []*model.VulnerabilityInputSpec, vulnEquals []*model.VulnEqualInputSpec) ([]string, error) { +func (c *demoClient) IngestVulnEquals(ctx context.Context, vulnerabilities []*model.IDorVulnerabilityInput, otherVulnerabilities []*model.IDorVulnerabilityInput, vulnEquals []*model.VulnEqualInputSpec) ([]string, error) { var modelHashEqualsIDs []string for i := range vulnEquals { vulnEqual, err := c.IngestVulnEqual(ctx, *vulnerabilities[i], *otherVulnerabilities[i], *vulnEquals[i]) @@ -71,11 +71,11 @@ func (c *demoClient) IngestVulnEquals(ctx context.Context, vulnerabilities []*mo return modelHashEqualsIDs, nil } -func (c *demoClient) IngestVulnEqual(ctx context.Context, vulnerability model.VulnerabilityInputSpec, otherVulnerability model.VulnerabilityInputSpec, vulnEqual model.VulnEqualInputSpec) (string, error) { +func (c *demoClient) IngestVulnEqual(ctx context.Context, vulnerability model.IDorVulnerabilityInput, otherVulnerability model.IDorVulnerabilityInput, vulnEqual model.VulnEqualInputSpec) (string, error) { return c.ingestVulnEqual(ctx, vulnerability, otherVulnerability, vulnEqual, true) } -func (c *demoClient) ingestVulnEqual(ctx context.Context, vulnerability model.VulnerabilityInputSpec, otherVulnerability model.VulnerabilityInputSpec, vulnEqual model.VulnEqualInputSpec, readOnly bool) (string, error) { +func (c *demoClient) ingestVulnEqual(ctx context.Context, vulnerability model.IDorVulnerabilityInput, otherVulnerability model.IDorVulnerabilityInput, vulnEqual model.VulnEqualInputSpec, readOnly bool) (string, error) { funcName := "ingestVulnEqual" in := &vulnerabilityEqualLink{ @@ -89,10 +89,10 @@ func (c *demoClient) ingestVulnEqual(ctx context.Context, vulnerability model.Vu vIDs := make([]string, 0, 2) vs := make([]*vulnIDNode, 0, 2) - for _, vi := range []model.VulnerabilityInputSpec{vulnerability, otherVulnerability} { - v, err := c.getVulnerabilityFromInput(ctx, vi) + for _, vi := range []model.IDorVulnerabilityInput{vulnerability, otherVulnerability} { + v, err := c.returnFoundVulnerability(ctx, &vi) if err != nil { - return "", gqlerror.Errorf("%v :: %v", funcName, err) + return "", gqlerror.Errorf("%v :: %s", funcName, err) } vs = append(vs, v) vIDs = append(vIDs, v.ThisID) diff --git a/pkg/assembler/backends/keyvalue/vulnEqual_test.go b/pkg/assembler/backends/keyvalue/vulnEqual_test.go deleted file mode 100644 index 3cbcb7ff40..0000000000 --- a/pkg/assembler/backends/keyvalue/vulnEqual_test.go +++ /dev/null @@ -1,737 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package keyvalue_test - -import ( - "context" - "slices" - "strings" - "testing" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/internal/testing/stablememmap" - "github.com/guacsec/guac/pkg/assembler/backends" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -func TestVulnEqual(t *testing.T) { - type call struct { - Vuln *model.VulnerabilityInputSpec - OtherVuln *model.VulnerabilityInputSpec - In *model.VulnEqualInputSpec - } - tests := []struct { - Name string - InVuln []*model.VulnerabilityInputSpec - Calls []call - Query *model.VulnEqualSpec - ExpVulnEqual []*model.VulnEqual - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InVuln: []*model.VulnerabilityInputSpec{o1, c1}, - Calls: []call{ - { - Vuln: o1, - OtherVuln: c1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.VulnEqualSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpVulnEqual: []*model.VulnEqual{ - { - Vulnerabilities: []*model.Vulnerability{ - { - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o1out}, - }, - { - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out}, - }, - }, - Justification: "test justification", - }, - }, - }, - { - Name: "Igest same twice", - InVuln: []*model.VulnerabilityInputSpec{o1, c1}, - Calls: []call{ - { - Vuln: o1, - OtherVuln: c1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - { - Vuln: o1, - OtherVuln: c1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.VulnEqualSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpVulnEqual: []*model.VulnEqual{ - { - Vulnerabilities: []*model.Vulnerability{ - { - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o1out}, - }, - { - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out}, - }, - }, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on Justification", - InVuln: []*model.VulnerabilityInputSpec{o1, c1}, - Calls: []call{ - { - Vuln: o1, - OtherVuln: c1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - { - Vuln: o1, - OtherVuln: c1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.VulnEqualSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpVulnEqual: []*model.VulnEqual{ - { - Vulnerabilities: []*model.Vulnerability{ - { - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o1out}, - }, - { - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out}, - }, - }, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on OSV", - InVuln: []*model.VulnerabilityInputSpec{o1, o2, c1}, - Calls: []call{ - { - Vuln: o1, - OtherVuln: c1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - { - Vuln: o2, - OtherVuln: c1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.VulnEqualSpec{ - Vulnerabilities: []*model.VulnerabilitySpec{ - { - VulnerabilityID: ptrfrom.String("CVE-2022-26499"), - }, - }, - }, - ExpVulnEqual: []*model.VulnEqual{ - { - Vulnerabilities: []*model.Vulnerability{ - { - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o2out}, - }, - { - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out}, - }, - }, - Justification: "test justification", - }, - }, - }, - { - Name: "Query on GHSA", - InVuln: []*model.VulnerabilityInputSpec{o1, c1, c2, g1}, - Calls: []call{ - { - Vuln: o1, - OtherVuln: c1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - { - Vuln: o1, - OtherVuln: c2, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - { - Vuln: o1, - OtherVuln: g1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.VulnEqualSpec{ - Vulnerabilities: []*model.VulnerabilitySpec{ - { - Type: ptrfrom.String("ghsa"), - }, - }, - }, - ExpVulnEqual: []*model.VulnEqual{ - { - Vulnerabilities: []*model.Vulnerability{ - { - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o1out}, - }, - { - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{g1out}, - }, - }, - Justification: "test justification", - }, - }, - }, - { - Name: "Query none", - InVuln: []*model.VulnerabilityInputSpec{o1, c1, c2, g1}, - Calls: []call{ - { - Vuln: o1, - OtherVuln: c1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - { - Vuln: o1, - OtherVuln: c2, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - { - Vuln: o1, - OtherVuln: g1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.VulnEqualSpec{ - Vulnerabilities: []*model.VulnerabilitySpec{ - { - VulnerabilityID: ptrfrom.String("AEV-2022-26499"), - }, - }, - }, - ExpVulnEqual: nil, - }, - { - Name: "Query multiple", - InVuln: []*model.VulnerabilityInputSpec{o1, c1, c2, g1}, - Calls: []call{ - { - Vuln: o1, - OtherVuln: c1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - { - Vuln: o1, - OtherVuln: c2, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - { - Vuln: o1, - OtherVuln: g1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.VulnEqualSpec{ - Vulnerabilities: []*model.VulnerabilitySpec{ - { - Type: ptrfrom.String("cve"), - }, - }, - }, - ExpVulnEqual: []*model.VulnEqual{ - { - Vulnerabilities: []*model.Vulnerability{ - { - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o1out}, - }, - { - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out}, - }, - }, - Justification: "test justification", - }, - { - Vulnerabilities: []*model.Vulnerability{ - { - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o1out}, - }, - { - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c2out}, - }, - }, - Justification: "test justification", - }, - }, - }, - { - Name: "Query ID", - InVuln: []*model.VulnerabilityInputSpec{o1, c1, c2, g1}, - Calls: []call{ - { - Vuln: o1, - OtherVuln: c1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - { - Vuln: o1, - OtherVuln: c2, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - { - Vuln: o1, - OtherVuln: g1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.VulnEqualSpec{ - ID: ptrfrom.String("8"), - }, - ExpVulnEqual: []*model.VulnEqual{ - { - Vulnerabilities: []*model.Vulnerability{ - { - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o1out}, - }, - { - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out}, - }, - }, - Justification: "test justification", - }, - }, - }, - { - Name: "Query ID not found", - InVuln: []*model.VulnerabilityInputSpec{o1, c1, c2, g1}, - Calls: []call{ - { - Vuln: o1, - OtherVuln: c1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - { - Vuln: o1, - OtherVuln: c2, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - { - Vuln: o1, - OtherVuln: g1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - Query: &model.VulnEqualSpec{ - ID: ptrfrom.String("123456"), - }, - ExpVulnEqual: nil, - }, - { - Name: "Query Error", - Query: &model.VulnEqualSpec{ - Vulnerabilities: []*model.VulnerabilitySpec{ - { - ID: ptrfrom.String("6"), - }, - }, - }, - ExpQueryErr: false, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - ctx := context.Background() - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, g := range test.InVuln { - if _, err := b.IngestVulnerability(ctx, *g); err != nil { - t.Fatalf("Could not ingest vulnerability: %a", err) - } - } - for _, o := range test.Calls { - _, err := b.IngestVulnEqual(ctx, *o.Vuln, *o.OtherVuln, *o.In) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.VulnEqual(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpVulnEqual, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func TestIngestVulnEquals(t *testing.T) { - type call struct { - Vulns []*model.VulnerabilityInputSpec - OtherVulns []*model.VulnerabilityInputSpec - Ins []*model.VulnEqualInputSpec - } - tests := []struct { - Name string - InVuln []*model.VulnerabilityInputSpec - Calls []call - Query *model.VulnEqualSpec - ExpVulnEqual []*model.VulnEqual - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InVuln: []*model.VulnerabilityInputSpec{o1, c1, o1, c2}, - Calls: []call{ - { - Vulns: []*model.VulnerabilityInputSpec{o1, o1}, - OtherVulns: []*model.VulnerabilityInputSpec{c1, c2}, - Ins: []*model.VulnEqualInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.VulnEqualSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpVulnEqual: []*model.VulnEqual{ - { - Vulnerabilities: []*model.Vulnerability{ - { - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o1out}, - }, - { - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out}, - }, - }, - Justification: "test justification", - }, - { - Vulnerabilities: []*model.Vulnerability{ - { - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o1out}, - }, - { - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c2out}, - }, - }, - Justification: "test justification", - }, - }, - }, - { - Name: "Ingest same twice", - InVuln: []*model.VulnerabilityInputSpec{o1, c1, o1, c1}, - Calls: []call{ - { - Vulns: []*model.VulnerabilityInputSpec{o1, o1}, - OtherVulns: []*model.VulnerabilityInputSpec{c1, c1}, - Ins: []*model.VulnEqualInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.VulnEqualSpec{ - Justification: ptrfrom.String("test justification"), - }, - ExpVulnEqual: []*model.VulnEqual{ - { - Vulnerabilities: []*model.Vulnerability{ - { - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o1out}, - }, - { - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out}, - }, - }, - Justification: "test justification", - }, - }, - }, - - { - Name: "Query on OSV", - InVuln: []*model.VulnerabilityInputSpec{o1, c1, o2, g2}, - Calls: []call{ - { - Vulns: []*model.VulnerabilityInputSpec{o1, o2}, - OtherVulns: []*model.VulnerabilityInputSpec{c1, g2}, - Ins: []*model.VulnEqualInputSpec{ - { - Justification: "test justification", - }, - { - Justification: "test justification", - }, - }, - }, - }, - Query: &model.VulnEqualSpec{ - Vulnerabilities: []*model.VulnerabilitySpec{ - { - VulnerabilityID: ptrfrom.String("GHSA-xrw3-wqph-3fxg"), - }, - }, - }, - ExpVulnEqual: []*model.VulnEqual{ - { - Vulnerabilities: []*model.Vulnerability{ - { - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o2out}, - }, - { - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{g2out}, - }, - }, - Justification: "test justification", - }, - }, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - ctx := context.Background() - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - if _, err := b.IngestVulnerabilities(ctx, test.InVuln); err != nil { - t.Fatalf("Could not ingest vulnerability: %a", err) - } - for _, o := range test.Calls { - _, err := b.IngestVulnEquals(ctx, o.Vulns, o.OtherVulns, o.Ins) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.VulnEqual(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpVulnEqual, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func TestVulnerabilityEqualNeighbors(t *testing.T) { - type call struct { - Vuln *model.VulnerabilityInputSpec - OtherVuln *model.VulnerabilityInputSpec - In *model.VulnEqualInputSpec - } - tests := []struct { - Name string - InVuln []*model.VulnerabilityInputSpec - Calls []call - ExpNeighbors map[string][]string - }{ - { - Name: "HappyPath", - InVuln: []*model.VulnerabilityInputSpec{o1, c1}, - Calls: []call{ - { - Vuln: o1, - OtherVuln: c1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - ExpNeighbors: map[string][]string{ - "2": {"1", "5"}, // osv to isVuln - "4": {"3", "5"}, // cve to isVuln - "5": {"1", "3"}, // isVuln to osv and cve - }, - }, - { - Name: "Two IsVuln", - InVuln: []*model.VulnerabilityInputSpec{o1, c1, g1}, - Calls: []call{ - { - Vuln: o1, - OtherVuln: c1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - { - Vuln: o1, - OtherVuln: g1, - In: &model.VulnEqualInputSpec{ - Justification: "test justification", - }, - }, - }, - ExpNeighbors: map[string][]string{ - "2": {"1", "7", "8"}, // osv to both isVuln - "4": {"3", "7"}, - "6": {"5", "8"}, - "7": {"1", "3"}, - "8": {"1", "5"}, - }, - }, - } - ctx := context.Background() - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, g := range test.InVuln { - if _, err := b.IngestVulnerability(ctx, *g); err != nil { - t.Fatalf("Could not ingest vulnerability: %s", err) - } - } - for _, o := range test.Calls { - if _, err := b.IngestVulnEqual(ctx, *o.Vuln, *o.OtherVuln, *o.In); err != nil { - t.Fatalf("Could not ingest vuln Equal: %s", err) - } - } - for q, r := range test.ExpNeighbors { - got, err := b.Neighbors(ctx, q, nil) - if err != nil { - t.Fatalf("Could not query neighbors: %s", err) - } - gotIDs := convNodes(got) - slices.Sort(r) - slices.Sort(gotIDs) - if diff := cmp.Diff(r, gotIDs); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - } - }) - } -} diff --git a/pkg/assembler/backends/keyvalue/vulnMetadata.go b/pkg/assembler/backends/keyvalue/vulnMetadata.go index 72976546a7..e7ccb4dcb2 100644 --- a/pkg/assembler/backends/keyvalue/vulnMetadata.go +++ b/pkg/assembler/backends/keyvalue/vulnMetadata.go @@ -62,7 +62,7 @@ func (n *vulnerabilityMetadataLink) BuildModelNode(ctx context.Context, c *demoC } // Ingest VulnerabilityMetadata -func (c *demoClient) IngestBulkVulnerabilityMetadata(ctx context.Context, vulnerabilities []*model.VulnerabilityInputSpec, vulnerabilityMetadataList []*model.VulnerabilityMetadataInputSpec) ([]string, error) { +func (c *demoClient) IngestBulkVulnerabilityMetadata(ctx context.Context, vulnerabilities []*model.IDorVulnerabilityInput, vulnerabilityMetadataList []*model.VulnerabilityMetadataInputSpec) ([]string, error) { var modelVulnMetadataIDList []string for i := range vulnerabilityMetadataList { vulnMetadata, err := c.IngestVulnerabilityMetadata(ctx, *vulnerabilities[i], *vulnerabilityMetadataList[i]) @@ -74,11 +74,11 @@ func (c *demoClient) IngestBulkVulnerabilityMetadata(ctx context.Context, vulner return modelVulnMetadataIDList, nil } -func (c *demoClient) IngestVulnerabilityMetadata(ctx context.Context, vulnerability model.VulnerabilityInputSpec, vulnerabilityMetadata model.VulnerabilityMetadataInputSpec) (string, error) { +func (c *demoClient) IngestVulnerabilityMetadata(ctx context.Context, vulnerability model.IDorVulnerabilityInput, vulnerabilityMetadata model.VulnerabilityMetadataInputSpec) (string, error) { return c.ingestVulnerabilityMetadata(ctx, vulnerability, vulnerabilityMetadata, true) } -func (c *demoClient) ingestVulnerabilityMetadata(ctx context.Context, vulnerability model.VulnerabilityInputSpec, vulnerabilityMetadata model.VulnerabilityMetadataInputSpec, readOnly bool) (string, error) { +func (c *demoClient) ingestVulnerabilityMetadata(ctx context.Context, vulnerability model.IDorVulnerabilityInput, vulnerabilityMetadata model.VulnerabilityMetadataInputSpec, readOnly bool) (string, error) { funcName := "IngestVulnerabilityMetadata" in := &vulnerabilityMetadataLink{ @@ -92,11 +92,11 @@ func (c *demoClient) ingestVulnerabilityMetadata(ctx context.Context, vulnerabil lock(&c.m, readOnly) defer unlock(&c.m, readOnly) - foundVulnNode, err := c.getVulnerabilityFromInput(ctx, vulnerability) + foundVulnNode, err := c.returnFoundVulnerability(ctx, &vulnerability) if err != nil { return "", gqlerror.Errorf("%v :: %s", funcName, err) } - in.VulnerabilityID = foundVulnNode.ThisID + in.VulnerabilityID = foundVulnNode.ID() out, err := byKeykv[*vulnerabilityMetadataLink](ctx, vulnMDCol, in.Key(), c) if err == nil { diff --git a/pkg/assembler/backends/keyvalue/vulnMetadata_test.go b/pkg/assembler/backends/keyvalue/vulnMetadata_test.go deleted file mode 100644 index 8ccb8afc49..0000000000 --- a/pkg/assembler/backends/keyvalue/vulnMetadata_test.go +++ /dev/null @@ -1,1221 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package keyvalue_test - -import ( - "context" - "slices" - "strconv" - "strings" - "testing" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/internal/testing/stablememmap" - "github.com/guacsec/guac/pkg/assembler/backends" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -var ( - greater model.Comparator = model.ComparatorGreater - greaterEqual model.Comparator = model.ComparatorGreaterEqual - less model.Comparator = model.ComparatorLess - lessEqual model.Comparator = model.ComparatorLessEqual - equal model.Comparator = model.ComparatorEqual -) - -var cvss2ScoreType model.VulnerabilityScoreType = model.VulnerabilityScoreTypeCVSSv2 - -func TestIngestVulnMetadata(t *testing.T) { - type call struct { - Vuln *model.VulnerabilityInputSpec - VulnMetadata *model.VulnerabilityMetadataInputSpec - } - - tests := []struct { - Name string - InVuln []*model.VulnerabilityInputSpec - Calls []call - ExpVuln []*model.VulnerabilityMetadata - Query *model.VulnerabilityMetadataSpec - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InVuln: []*model.VulnerabilityInputSpec{c1}, - Calls: []call{ - { - Vuln: c1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Collector: ptrfrom.String("test collector"), - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - ID: "1", - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Duplicate", - InVuln: []*model.VulnerabilityInputSpec{c1, c1}, - Calls: []call{ - { - Vuln: c1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - { - Vuln: c1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Collector: ptrfrom.String("test collector"), - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - ID: "1", - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Certify OSV", - InVuln: []*model.VulnerabilityInputSpec{o1}, - Calls: []call{ - { - Vuln: o1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Collector: ptrfrom.String("test collector"), - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Certify GHSA", - InVuln: []*model.VulnerabilityInputSpec{g1}, - Calls: []call{ - { - Vuln: g1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeEPSSv1, - ScoreValue: 0.95, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Collector: ptrfrom.String("test collector"), - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{g1out}, - }, - ScoreType: model.VulnerabilityScoreTypeEPSSv1, - ScoreValue: 0.95, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Query on GHSA", - InVuln: []*model.VulnerabilityInputSpec{g1}, - Calls: []call{ - { - Vuln: g1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeEPSSv2, - ScoreValue: 0.98, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Vulnerability: &model.VulnerabilitySpec{ - Type: ptrfrom.String("ghsa"), - VulnerabilityID: &g1.VulnerabilityID, - }, - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{g1out}, - }, - ScoreType: model.VulnerabilityScoreTypeEPSSv2, - ScoreValue: 0.98, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Query ID", - InVuln: []*model.VulnerabilityInputSpec{g1}, - Calls: []call{ - { - Vuln: g1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - ID: ptrfrom.String("3"), - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{g1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Query none", - InVuln: []*model.VulnerabilityInputSpec{g1}, - Calls: []call{ - { - Vuln: g1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Vulnerability: &model.VulnerabilitySpec{ - VulnerabilityID: ptrfrom.String("asdf"), - }, - }, - ExpVuln: nil, - }, - { - Name: "Query greater than - no score value", - InVuln: []*model.VulnerabilityInputSpec{c2, c1}, - Calls: []call{ - { - Vuln: c2, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - { - Vuln: c1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Comparator: &greater, - }, - ExpQueryErr: true, - ExpVuln: []*model.VulnerabilityMetadata{}, - }, - { - Name: "Query greater than", - InVuln: []*model.VulnerabilityInputSpec{c2, c1}, - Calls: []call{ - { - Vuln: c2, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - { - Vuln: c1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Comparator: &greater, - ScoreValue: ptrfrom.Float64(7.0), - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - { - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c2out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Query greater than - specific type", - InVuln: []*model.VulnerabilityInputSpec{c2, c1}, - Calls: []call{ - { - Vuln: c2, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - { - Vuln: c1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Comparator: &greater, - ScoreValue: ptrfrom.Float64(7.0), - ScoreType: &cvss2ScoreType, - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c2out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Query greater than or equal", - InVuln: []*model.VulnerabilityInputSpec{c2, c1, g1}, - Calls: []call{ - { - Vuln: c2, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - { - Vuln: c1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - { - Vuln: g1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 6.3, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Comparator: &greaterEqual, - ScoreValue: ptrfrom.Float64(7.9), - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - { - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c2out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Query less than", - InVuln: []*model.VulnerabilityInputSpec{c2, c1, g1}, - Calls: []call{ - { - Vuln: c2, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - { - Vuln: c1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - { - Vuln: g1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 6.3, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Comparator: &less, - ScoreValue: ptrfrom.Float64(6.5), - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{g1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 6.3, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Query less than or equal", - InVuln: []*model.VulnerabilityInputSpec{c2, c1, g1}, - Calls: []call{ - { - Vuln: c2, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - { - Vuln: c1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - { - Vuln: g1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 6.3, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Comparator: &lessEqual, - ScoreValue: ptrfrom.Float64(7.9), - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{g1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 6.3, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - { - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Query equal", - InVuln: []*model.VulnerabilityInputSpec{c2, c1, g1}, - Calls: []call{ - { - Vuln: c2, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - { - Vuln: c1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - { - Vuln: g1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 6.3, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Comparator: &equal, - ScoreValue: ptrfrom.Float64(7.9), - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Query without comparator", - InVuln: []*model.VulnerabilityInputSpec{c2, c1, g1}, - Calls: []call{ - { - Vuln: c2, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - { - Vuln: c1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - { - Vuln: g1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 6.3, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - ScoreValue: ptrfrom.Float64(7.9), - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Query all vulns - with novuln boolean omitted", - InVuln: []*model.VulnerabilityInputSpec{c2, c1, g1}, - Calls: []call{ - { - Vuln: c2, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - { - Vuln: c1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeEPSSv2, - ScoreValue: 0.96, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - { - Vuln: g1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 2.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Vulnerability: &model.VulnerabilitySpec{}, - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out}, - }, - ScoreType: model.VulnerabilityScoreTypeEPSSv2, - ScoreValue: 0.96, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - { - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{g1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 2.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - { - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c2out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Ingest without vuln", - Calls: []call{ - { - Vuln: &model.VulnerabilityInputSpec{}, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{}, - }, - }, - Query: &model.VulnerabilityMetadataSpec{}, - ExpIngestErr: true, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - ctx := context.Background() - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, g := range test.InVuln { - if _, err := b.IngestVulnerability(ctx, *g); err != nil { - t.Fatalf("Could not ingest vulnerability: %a", err) - } - } - - ids := make([]string, len(test.Calls)) - for i, o := range test.Calls { - record, err := b.IngestVulnerabilityMetadata(ctx, *o.Vuln, *o.VulnMetadata) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - ids[i] = record - } - if test.Query != nil { - if test.Query.ID != nil { - idIndex, err := strconv.Atoi(*test.Query.ID) - if err == nil && idIndex > -1 && idIndex < len(ids) { - test.Query.ID = ptrfrom.String(ids[idIndex]) - } - } - } - - got, err := b.VulnerabilityMetadata(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpVuln, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func TestIngestVulnMetadatas(t *testing.T) { - type call struct { - Vulns []*model.VulnerabilityInputSpec - VulnMetadatas []*model.VulnerabilityMetadataInputSpec - } - - tests := []struct { - Name string - InVuln []*model.VulnerabilityInputSpec - Calls []call - ExpVuln []*model.VulnerabilityMetadata - Query *model.VulnerabilityMetadataSpec - ExpIngestErr bool - ExpQueryErr bool - }{ - { - Name: "HappyPath", - InVuln: []*model.VulnerabilityInputSpec{c1, c2}, - Calls: []call{ - { - Vulns: []*model.VulnerabilityInputSpec{c1, c2}, - VulnMetadatas: []*model.VulnerabilityMetadataInputSpec{ - { - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - { - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Collector: ptrfrom.String("test collector"), - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - ID: "1", - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - { - ID: "10", - Vulnerability: &model.Vulnerability{ - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c2out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Certify OSV", - InVuln: []*model.VulnerabilityInputSpec{o1, o2}, - Calls: []call{ - { - Vulns: []*model.VulnerabilityInputSpec{o1, o2}, - VulnMetadatas: []*model.VulnerabilityMetadataInputSpec{ - { - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - { - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Collector: ptrfrom.String("test collector"), - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - { - Vulnerability: &model.Vulnerability{ - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o2out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Certify GHSA", - InVuln: []*model.VulnerabilityInputSpec{g1, g2}, - Calls: []call{ - { - Vulns: []*model.VulnerabilityInputSpec{g1, g2}, - VulnMetadatas: []*model.VulnerabilityMetadataInputSpec{ - { - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - { - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Collector: ptrfrom.String("test collector"), - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{g1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - { - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{g2out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Query on GHSA", - InVuln: []*model.VulnerabilityInputSpec{g1, g2}, - Calls: []call{ - { - Vulns: []*model.VulnerabilityInputSpec{g1, g2}, - VulnMetadatas: []*model.VulnerabilityMetadataInputSpec{ - { - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - { - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Vulnerability: &model.VulnerabilitySpec{ - VulnerabilityID: &g1.VulnerabilityID, - }, - }, - ExpVuln: []*model.VulnerabilityMetadata{ - { - Vulnerability: &model.Vulnerability{ - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{g1out}, - }, - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - { - Name: "Query none", - InVuln: []*model.VulnerabilityInputSpec{g1, g2}, - Calls: []call{ - { - Vulns: []*model.VulnerabilityInputSpec{g1, g2}, - VulnMetadatas: []*model.VulnerabilityMetadataInputSpec{ - { - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - { - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - }, - Query: &model.VulnerabilityMetadataSpec{ - Vulnerability: &model.VulnerabilitySpec{ - VulnerabilityID: ptrfrom.String("asdf"), - }, - }, - ExpVuln: nil, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - ctx := context.Background() - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - - if _, err := b.IngestVulnerabilities(ctx, test.InVuln); err != nil { - t.Fatalf("Could not ingest vulnerabilities: %a", err) - } - for _, o := range test.Calls { - _, err := b.IngestBulkVulnerabilityMetadata(ctx, o.Vulns, o.VulnMetadatas) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - - } - - got, err := b.VulnerabilityMetadata(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - if diff := cmp.Diff(test.ExpVuln, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func TestVulnMetadataNeighbors(t *testing.T) { - type call struct { - Vuln *model.VulnerabilityInputSpec - VulnMetadata *model.VulnerabilityMetadataInputSpec - } - tests := []struct { - Name string - InVuln []*model.VulnerabilityInputSpec - Calls []call - ExpNeighbors map[string][]string - }{ - { - Name: "HappyPath", - InVuln: []*model.VulnerabilityInputSpec{o1}, - Calls: []call{ - { - Vuln: o1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - ExpNeighbors: map[string][]string{ - "2": {"1", "3"}, // Vuln -> vunType, vulnMeta1 - "3": {"1"}, // vulnMeta1 -> vuln - }, - }, - { - Name: "Two vuln metadata on same vulnerability", - InVuln: []*model.VulnerabilityInputSpec{o1}, - Calls: []call{ - { - Vuln: o1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv3, - ScoreValue: 7.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - { - Vuln: o1, - VulnMetadata: &model.VulnerabilityMetadataInputSpec{ - ScoreType: model.VulnerabilityScoreTypeCVSSv2, - ScoreValue: 8.9, - Timestamp: t1, - Collector: "test collector", - Origin: "test origin", - }, - }, - }, - ExpNeighbors: map[string][]string{ - "2": {"1", "3", "4"}, // Vuln1 -> vunType, vulnMeta1 - "3": {"1"}, // vulnMeta1 -> vuln1 - "4": {"1"}, // vulnMeta2 -> vuln2 - }, - }, - } - ctx := context.Background() - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, o := range test.InVuln { - if _, err := b.IngestVulnerability(ctx, *o); err != nil { - t.Fatalf("Could not ingest osv: %v", err) - } - } - for _, o := range test.Calls { - if _, err := b.IngestVulnerabilityMetadata(ctx, *o.Vuln, *o.VulnMetadata); err != nil { - t.Fatalf("Could not ingest certifyVuln") - } - } - for q, r := range test.ExpNeighbors { - got, err := b.Neighbors(ctx, q, nil) - if err != nil { - t.Fatalf("Could not query neighbors: %s", err) - } - gotIDs := convNodes(got) - slices.Sort(r) - slices.Sort(gotIDs) - if diff := cmp.Diff(r, gotIDs); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - } - }) - } -} diff --git a/pkg/assembler/backends/keyvalue/vulnerability.go b/pkg/assembler/backends/keyvalue/vulnerability.go index 125f33bbe7..40b7e90ecf 100644 --- a/pkg/assembler/backends/keyvalue/vulnerability.go +++ b/pkg/assembler/backends/keyvalue/vulnerability.go @@ -126,7 +126,7 @@ func (n *vulnTypeStruct) addVulnID(ctx context.Context, vulnID string, c *demoCl // Ingest Vulnerabilities -func (c *demoClient) IngestVulnerabilities(ctx context.Context, vulns []*model.VulnerabilityInputSpec) ([]*model.VulnerabilityIDs, error) { +func (c *demoClient) IngestVulnerabilities(ctx context.Context, vulns []*model.IDorVulnerabilityInput) ([]*model.VulnerabilityIDs, error) { var modelVulnerabilities []*model.VulnerabilityIDs for _, vuln := range vulns { modelVuln, err := c.IngestVulnerability(ctx, *vuln) @@ -138,9 +138,9 @@ func (c *demoClient) IngestVulnerabilities(ctx context.Context, vulns []*model.V return modelVulnerabilities, nil } -func (c *demoClient) IngestVulnerability(ctx context.Context, input model.VulnerabilityInputSpec) (*model.VulnerabilityIDs, error) { +func (c *demoClient) IngestVulnerability(ctx context.Context, input model.IDorVulnerabilityInput) (*model.VulnerabilityIDs, error) { inType := &vulnTypeStruct{ - Type: strings.ToLower(input.Type), + Type: strings.ToLower(input.VulnerabilityInput.Type), } c.m.RLock() outType, err := byKeykv[*vulnTypeStruct](ctx, vulnTypeCol, inType.Key(), c) @@ -172,7 +172,7 @@ func (c *demoClient) IngestVulnerability(ctx context.Context, input model.Vulner inVulnID := &vulnIDNode{ Parent: outType.ThisID, - VulnID: strings.ToLower(input.VulnerabilityID), + VulnID: strings.ToLower(input.VulnerabilityInput.VulnerabilityID), } c.m.RLock() outVulnID, err := byKeykv[*vulnIDNode](ctx, vulnIDCol, inVulnID.Key(), c) @@ -422,3 +422,20 @@ func (c *demoClient) getVulnerabilityFromInput(ctx context.Context, input model. } return vulnID, nil } + +// returnFoundVulnerability return the node by first searching via ID. If the ID is not specified, it defaults to searching via inputspec +func (c *demoClient) returnFoundVulnerability(ctx context.Context, vulnIDorInput *model.IDorVulnerabilityInput) (*vulnIDNode, error) { + if vulnIDorInput.VulnerabilityNodeID != nil { + foundVulnID, err := byIDkv[*vulnIDNode](ctx, *vulnIDorInput.VulnerabilityNodeID, c) + if err != nil { + return nil, gqlerror.Errorf("failed to return vulnIDNode node by ID with error: %v", err) + } + return foundVulnID, nil + } else { + foundVulnID, err := c.getVulnerabilityFromInput(ctx, *vulnIDorInput.VulnerabilityInput) + if err != nil { + return nil, gqlerror.Errorf("failed to getVulnerabilityFromInput with error: %v", err) + } + return foundVulnID, nil + } +} diff --git a/pkg/assembler/backends/keyvalue/vulnerability_test.go b/pkg/assembler/backends/keyvalue/vulnerability_test.go deleted file mode 100644 index fa295c8956..0000000000 --- a/pkg/assembler/backends/keyvalue/vulnerability_test.go +++ /dev/null @@ -1,345 +0,0 @@ -// -// Copyright 2023 The GUAC Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package keyvalue_test - -import ( - "context" - "slices" - "strings" - "testing" - - "github.com/google/go-cmp/cmp" - "github.com/guacsec/guac/internal/testing/ptrfrom" - "github.com/guacsec/guac/internal/testing/stablememmap" - "github.com/guacsec/guac/pkg/assembler/backends" - "github.com/guacsec/guac/pkg/assembler/graphql/model" -) - -var c1 = &model.VulnerabilityInputSpec{ - Type: "cve", - VulnerabilityID: "CVE-2019-13110", -} - -var c1out = &model.VulnerabilityID{ - VulnerabilityID: "cve-2019-13110", -} - -var c2 = &model.VulnerabilityInputSpec{ - Type: "cve", - VulnerabilityID: "CVE-2014-8139", -} - -var c2out = &model.VulnerabilityID{ - VulnerabilityID: "cve-2014-8139", -} - -var c3 = &model.VulnerabilityInputSpec{ - Type: "CVE", - VulnerabilityID: "cVe-2014-8140", -} - -var c3out = &model.VulnerabilityID{ - VulnerabilityID: "cve-2014-8140", -} - -var g1 = &model.VulnerabilityInputSpec{ - Type: "GHSA", - VulnerabilityID: "GHSA-h45f-rjvw-2rv2", -} - -var g1out = &model.VulnerabilityID{ - VulnerabilityID: "ghsa-h45f-rjvw-2rv2", -} - -var g2 = &model.VulnerabilityInputSpec{ - Type: "ghsa", - VulnerabilityID: "GHSA-xrw3-wqph-3fxg", -} - -var g2out = &model.VulnerabilityID{ - VulnerabilityID: "ghsa-xrw3-wqph-3fxg", -} - -var g3 = &model.VulnerabilityInputSpec{ - Type: "ghsa", - VulnerabilityID: "GHSA-8v4j-7jgf-5rg9", -} - -var g3out = &model.VulnerabilityID{ - VulnerabilityID: "ghsa-8v4j-7jgf-5rg9", -} - -var o1 = &model.VulnerabilityInputSpec{ - Type: "OSV", - VulnerabilityID: "CVE-2014-8140", -} - -var o1out = &model.VulnerabilityID{ - VulnerabilityID: "cve-2014-8140", -} - -var o2 = &model.VulnerabilityInputSpec{ - Type: "osv", - VulnerabilityID: "CVE-2022-26499", -} - -var o2out = &model.VulnerabilityID{ - VulnerabilityID: "cve-2022-26499", -} - -var o3 = &model.VulnerabilityInputSpec{ - Type: "osv", - VulnerabilityID: "GHSA-h45f-rjvw-2rv2", -} - -var o3out = &model.VulnerabilityID{ - VulnerabilityID: "ghsa-h45f-rjvw-2rv2", -} - -var noVulnInput = &model.VulnerabilityInputSpec{ - Type: "noVuln", - VulnerabilityID: "", -} - -var noVulnOut = &model.VulnerabilityID{ - VulnerabilityID: "", -} - -func lessCve(a, b *model.Vulnerability) int { - return strings.Compare(a.VulnerabilityIDs[0].VulnerabilityID, - b.VulnerabilityIDs[0].VulnerabilityID) -} - -func TestVulnerability(t *testing.T) { - tests := []struct { - Name string - Ingests []*model.VulnerabilityInputSpec - ExpIngestErr bool - Query *model.VulnerabilitySpec - Exp []*model.Vulnerability - ExpQueryErr bool - }{ - { - Name: "HappyPath", - Ingests: []*model.VulnerabilityInputSpec{c1}, - Query: &model.VulnerabilitySpec{}, - Exp: []*model.Vulnerability{ - { - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out}, - }, - }, - }, - { - Name: "Multiple", - Ingests: []*model.VulnerabilityInputSpec{c1, c2}, - Query: &model.VulnerabilitySpec{}, - Exp: []*model.Vulnerability{ - { - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out, c2out}, - }, - }, - }, - { - Name: "Duplicates", - Ingests: []*model.VulnerabilityInputSpec{c1, c1, c1}, - Query: &model.VulnerabilitySpec{}, - Exp: []*model.Vulnerability{ - { - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out}, - }, - }, - }, - { - Name: "Query by type - cve", - Ingests: []*model.VulnerabilityInputSpec{c1, c2, c3, g1, o1}, - Query: &model.VulnerabilitySpec{ - Type: ptrfrom.String("cve"), - }, - Exp: []*model.Vulnerability{ - { - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out, c2out, c3out}, - }, - }, - }, - { - Name: "Query by type - ghsa", - Ingests: []*model.VulnerabilityInputSpec{c1, c2, c3, g2, g3, o1}, - Query: &model.VulnerabilitySpec{ - Type: ptrfrom.String("ghsa"), - }, - Exp: []*model.Vulnerability{ - { - Type: "ghsa", - VulnerabilityIDs: []*model.VulnerabilityID{g2out, g3out}, - }, - }, - }, - { - Name: "Query by type - osv", - Ingests: []*model.VulnerabilityInputSpec{c1, c2, c3, g3, o1, o2, o3}, - Query: &model.VulnerabilitySpec{ - Type: ptrfrom.String("osv"), - }, - Exp: []*model.Vulnerability{ - { - Type: "osv", - VulnerabilityIDs: []*model.VulnerabilityID{o1out, o2out, o3out}, - }, - }, - }, - { - Name: "Query by type - noVuln", - Ingests: []*model.VulnerabilityInputSpec{noVulnInput}, - Query: &model.VulnerabilitySpec{ - Type: ptrfrom.String("noVuln"), - }, - Exp: []*model.Vulnerability{ - { - Type: "novuln", - VulnerabilityIDs: []*model.VulnerabilityID{noVulnOut}, - }, - }, - }, - { - Name: "Query by type - noVuln with boolean", - Ingests: []*model.VulnerabilityInputSpec{noVulnInput}, - Query: &model.VulnerabilitySpec{ - NoVuln: ptrfrom.Bool(true), - }, - Exp: []*model.Vulnerability{ - { - Type: "novuln", - VulnerabilityIDs: []*model.VulnerabilityID{noVulnOut}, - }, - }, - }, - { - Name: "Query by vulnID", - Ingests: []*model.VulnerabilityInputSpec{c1, c2, c3}, - Query: &model.VulnerabilitySpec{ - VulnerabilityID: ptrfrom.String("CVE-2014-8140"), - }, - Exp: []*model.Vulnerability{ - { - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c3out}, - }, - }, - }, - { - Name: "Query by vulnID - noVuln", - Ingests: []*model.VulnerabilityInputSpec{c1, c2, c3, noVulnInput}, - Query: &model.VulnerabilitySpec{ - Type: ptrfrom.String("noVuln"), - }, - Exp: []*model.Vulnerability{ - { - Type: "novuln", - VulnerabilityIDs: []*model.VulnerabilityID{noVulnOut}, - }, - }, - }, - { - Name: "Query by ID", - Ingests: []*model.VulnerabilityInputSpec{c1}, - Query: &model.VulnerabilitySpec{ - ID: ptrfrom.String("2"), - }, - Exp: []*model.Vulnerability{ - { - Type: "cve", - VulnerabilityIDs: []*model.VulnerabilityID{c1out}, - }, - }, - }, - { - Name: "Query none", - Ingests: []*model.VulnerabilityInputSpec{c1, c2, c3}, - Query: &model.VulnerabilitySpec{ - Type: ptrfrom.String("ghsa"), - }, - Exp: []*model.Vulnerability{}, - }, - { - Name: "Query none ID", - Ingests: []*model.VulnerabilityInputSpec{c1, c2, c3}, - Query: &model.VulnerabilitySpec{ - ID: ptrfrom.String("12345"), - }, - Exp: nil, - }, - } - ignoreID := cmp.FilterPath(func(p cmp.Path) bool { - return strings.Compare(".ID", p[len(p)-1].String()) == 0 - }, cmp.Ignore()) - ctx := context.Background() - for _, test := range tests { - t.Run(test.Name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - for _, i := range test.Ingests { - _, err := b.IngestVulnerability(ctx, *i) - if (err != nil) != test.ExpIngestErr { - t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) - } - if err != nil { - return - } - } - got, err := b.Vulnerabilities(ctx, test.Query) - if (err != nil) != test.ExpQueryErr { - t.Fatalf("did not get expected query error, want: %v, got: %v", test.ExpQueryErr, err) - } - if err != nil { - return - } - slices.SortFunc(got, lessCve) - if diff := cmp.Diff(test.Exp, got, ignoreID); diff != "" { - t.Errorf("Unexpected results. (-want +got):\n%s", diff) - } - }) - } -} - -func TestIngestVulnerabilities(t *testing.T) { - tests := []struct { - name string - ingests []*model.VulnerabilityInputSpec - }{{ - name: "Multiple", - ingests: []*model.VulnerabilityInputSpec{c1, c2, c3}, - }} - ctx := context.Background() - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - store := stablememmap.GetStore() - b, err := backends.Get("keyvalue", nil, store) - if err != nil { - t.Fatalf("Could not instantiate testing backend: %v", err) - } - if _, err := b.IngestVulnerabilities(ctx, test.ingests); err != nil { - t.Errorf("ingest error: %v", err) - } - }) - } -} diff --git a/pkg/assembler/backends/neo4j/artifact.go b/pkg/assembler/backends/neo4j/artifact.go index d4bc0c6dbd..a0117ef47d 100644 --- a/pkg/assembler/backends/neo4j/artifact.go +++ b/pkg/assembler/backends/neo4j/artifact.go @@ -65,17 +65,17 @@ func (c *neo4jClient) Artifacts(ctx context.Context, artifactSpec *model.Artifac return result.([]*model.Artifact), nil } -func (c *neo4jClient) IngestArtifacts(ctx context.Context, artifacts []*model.ArtifactInputSpec) ([]string, error) { +func (c *neo4jClient) IngestArtifacts(ctx context.Context, artifacts []*model.IDorArtifactInput) ([]string, error) { return []string{}, fmt.Errorf("not implemented: IngestArtifacts") } -func (c *neo4jClient) IngestArtifact(ctx context.Context, artifact *model.ArtifactInputSpec) (string, error) { +func (c *neo4jClient) IngestArtifact(ctx context.Context, artifact *model.IDorArtifactInput) (string, error) { session := c.driver.NewSession(neo4j.SessionConfig{AccessMode: neo4j.AccessModeWrite}) defer session.Close() values := map[string]any{} - values["algorithm"] = strings.ToLower(artifact.Algorithm) - values["digest"] = strings.ToLower(artifact.Digest) + values["algorithm"] = strings.ToLower(artifact.ArtifactInput.Algorithm) + values["digest"] = strings.ToLower(artifact.ArtifactInput.Digest) result, err := session.WriteTransaction( func(tx neo4j.Transaction) (interface{}, error) { diff --git a/pkg/assembler/backends/neo4j/backend.go b/pkg/assembler/backends/neo4j/backend.go index e4b57786b3..cbb40ab095 100644 --- a/pkg/assembler/backends/neo4j/backend.go +++ b/pkg/assembler/backends/neo4j/backend.go @@ -166,18 +166,18 @@ func getPreloadString(prefix, name string) string { func (c *neo4jClient) Licenses(ctx context.Context, licenseSpec *model.LicenseSpec) ([]*model.License, error) { panic(fmt.Errorf("not implemented: Licenses")) } -func (c *neo4jClient) IngestLicense(ctx context.Context, license *model.LicenseInputSpec) (string, error) { +func (c *neo4jClient) IngestLicense(ctx context.Context, license *model.IDorLicenseInput) (string, error) { panic(fmt.Errorf("not implemented: IngestLicense")) } -func (c *neo4jClient) IngestLicenses(ctx context.Context, licenses []*model.LicenseInputSpec) ([]string, error) { +func (c *neo4jClient) IngestLicenses(ctx context.Context, licenses []*model.IDorLicenseInput) ([]string, error) { panic(fmt.Errorf("not implemented: IngestLicenses")) } func (c *neo4jClient) CertifyLegal(ctx context.Context, certifyLegalSpec *model.CertifyLegalSpec) ([]*model.CertifyLegal, error) { panic(fmt.Errorf("not implemented: CertifyLegal")) } -func (c *neo4jClient) IngestCertifyLegal(ctx context.Context, subject model.PackageOrSourceInput, declaredLicenses []*model.LicenseInputSpec, discoveredLicenses []*model.LicenseInputSpec, certifyLegal *model.CertifyLegalInputSpec) (string, error) { +func (c *neo4jClient) IngestCertifyLegal(ctx context.Context, subject model.PackageOrSourceInput, declaredLicenses []*model.IDorLicenseInput, discoveredLicenses []*model.IDorLicenseInput, certifyLegal *model.CertifyLegalInputSpec) (string, error) { panic(fmt.Errorf("not implemented: IngestCertifyLegal")) } -func (c *neo4jClient) IngestCertifyLegals(ctx context.Context, subjects model.PackageOrSourceInputs, declaredLicensesList [][]*model.LicenseInputSpec, discoveredLicensesList [][]*model.LicenseInputSpec, certifyLegals []*model.CertifyLegalInputSpec) ([]string, error) { +func (c *neo4jClient) IngestCertifyLegals(ctx context.Context, subjects model.PackageOrSourceInputs, declaredLicensesList [][]*model.IDorLicenseInput, discoveredLicensesList [][]*model.IDorLicenseInput, certifyLegals []*model.CertifyLegalInputSpec) ([]string, error) { panic(fmt.Errorf("not implemented: IngestCertifyLegals")) } diff --git a/pkg/assembler/backends/neo4j/builder.go b/pkg/assembler/backends/neo4j/builder.go index cc4aa03010..d0927e732c 100644 --- a/pkg/assembler/backends/neo4j/builder.go +++ b/pkg/assembler/backends/neo4j/builder.go @@ -62,16 +62,16 @@ func (c *neo4jClient) Builders(ctx context.Context, builderSpec *model.BuilderSp return result.([]*model.Builder), nil } -func (c *neo4jClient) IngestBuilders(ctx context.Context, builders []*model.BuilderInputSpec) ([]string, error) { +func (c *neo4jClient) IngestBuilders(ctx context.Context, builders []*model.IDorBuilderInput) ([]string, error) { return []string{}, fmt.Errorf("not implemented: IngestBuilders") } -func (c *neo4jClient) IngestBuilder(ctx context.Context, builder *model.BuilderInputSpec) (string, error) { +func (c *neo4jClient) IngestBuilder(ctx context.Context, builder *model.IDorBuilderInput) (string, error) { session := c.driver.NewSession(neo4j.SessionConfig{AccessMode: neo4j.AccessModeWrite}) defer session.Close() values := map[string]any{} - values["uri"] = builder.URI + values["uri"] = builder.BuilderInput.URI result, err := session.WriteTransaction( func(tx neo4j.Transaction) (interface{}, error) { diff --git a/pkg/assembler/backends/neo4j/certifyScorecard.go b/pkg/assembler/backends/neo4j/certifyScorecard.go index 5e9edc5d58..7342534f9b 100644 --- a/pkg/assembler/backends/neo4j/certifyScorecard.go +++ b/pkg/assembler/backends/neo4j/certifyScorecard.go @@ -190,35 +190,35 @@ func setCertifyScorecardValues(sb *strings.Builder, certifyScorecardSpec *model. // Ingest Scorecards -func (c *neo4jClient) IngestScorecards(ctx context.Context, sources []*model.SourceInputSpec, scorecards []*model.ScorecardInputSpec) ([]string, error) { +func (c *neo4jClient) IngestScorecards(ctx context.Context, sources []*model.IDorSourceInput, scorecards []*model.ScorecardInputSpec) ([]string, error) { return []string{}, fmt.Errorf("not implemented: IngestScorecards") } // Ingest Scorecard -func (c *neo4jClient) IngestScorecard(ctx context.Context, source model.SourceInputSpec, scorecard model.ScorecardInputSpec) (string, error) { +func (c *neo4jClient) IngestScorecard(ctx context.Context, source model.IDorSourceInput, scorecard model.ScorecardInputSpec) (string, error) { session := c.driver.NewSession(neo4j.SessionConfig{AccessMode: neo4j.AccessModeWrite}) defer session.Close() values := map[string]any{} - values["sourceType"] = source.Type - values["namespace"] = source.Namespace - values["name"] = source.Name + values["sourceType"] = source.SourceInput.Type + values["namespace"] = source.SourceInput.Namespace + values["name"] = source.SourceInput.Name - if source.Commit != nil && source.Tag != nil { - if *source.Commit != "" && *source.Tag != "" { + if source.SourceInput.Commit != nil && source.SourceInput.Tag != nil { + if *source.SourceInput.Commit != "" && *source.SourceInput.Tag != "" { return "", gqlerror.Errorf("Passing both commit and tag selectors is an error") } } - if source.Commit != nil { - values["commit"] = *source.Commit + if source.SourceInput.Commit != nil { + values["commit"] = *source.SourceInput.Commit } else { values["commit"] = "" } - if source.Tag != nil { - values["tag"] = *source.Tag + if source.SourceInput.Tag != nil { + values["tag"] = *source.SourceInput.Tag } else { values["tag"] = "" } diff --git a/pkg/assembler/backends/neo4j/certifyVEXStatement.go b/pkg/assembler/backends/neo4j/certifyVEXStatement.go index 30f95de5d7..c0f5d5fa07 100644 --- a/pkg/assembler/backends/neo4j/certifyVEXStatement.go +++ b/pkg/assembler/backends/neo4j/certifyVEXStatement.go @@ -630,7 +630,7 @@ func (c *neo4jClient) CertifyVEXStatement(ctx context.Context, certifyVEXStateme // return model.VexJustificationNotProvided, fmt.Errorf("failed to convert justification to enum") // } -func (c *neo4jClient) IngestVEXStatement(ctx context.Context, subject model.PackageOrArtifactInput, vulnerability model.VulnerabilityInputSpec, vexStatement model.VexStatementInputSpec) (string, error) { +func (c *neo4jClient) IngestVEXStatement(ctx context.Context, subject model.PackageOrArtifactInput, vulnerability model.IDorVulnerabilityInput, vexStatement model.VexStatementInputSpec) (string, error) { // err := helper.ValidatePackageOrArtifactInput(&subject, "IngestVEXStatement") // if err != nil { @@ -644,6 +644,6 @@ func (c *neo4jClient) IngestVEXStatement(ctx context.Context, subject model.Pack return "", fmt.Errorf("not implemented - IngestVEXStatement") } -func (c *neo4jClient) IngestVEXStatements(ctx context.Context, subjects model.PackageOrArtifactInputs, vulnerabilities []*model.VulnerabilityInputSpec, vexStatements []*model.VexStatementInputSpec) ([]string, error) { +func (c *neo4jClient) IngestVEXStatements(ctx context.Context, subjects model.PackageOrArtifactInputs, vulnerabilities []*model.IDorVulnerabilityInput, vexStatements []*model.VexStatementInputSpec) ([]string, error) { return []string{}, fmt.Errorf("not implemented - IngestVEXStatements") } diff --git a/pkg/assembler/backends/neo4j/certifyVuln.go b/pkg/assembler/backends/neo4j/certifyVuln.go index 7c757a530e..178e11777c 100644 --- a/pkg/assembler/backends/neo4j/certifyVuln.go +++ b/pkg/assembler/backends/neo4j/certifyVuln.go @@ -328,7 +328,7 @@ func (c *neo4jClient) CertifyVuln(ctx context.Context, certifyVulnSpec *model.Ce // Ingest Vulnerability -func (c *neo4jClient) IngestCertifyVuln(ctx context.Context, pkg model.PkgInputSpec, vulnerability model.VulnerabilityInputSpec, certifyVuln model.ScanMetadataInput) (string, error) { +func (c *neo4jClient) IngestCertifyVuln(ctx context.Context, pkg model.IDorPkgInput, vulnerability model.IDorVulnerabilityInput, certifyVuln model.ScanMetadataInput) (string, error) { // err := helper.ValidateVulnerabilityIngestionInput(vulnerability, "IngestVulnerability", true) // if err != nil { @@ -558,6 +558,6 @@ func (c *neo4jClient) IngestCertifyVuln(ctx context.Context, pkg model.PkgInputS return "", fmt.Errorf("not implemented - IngestCertifyVuln") } -func (c *neo4jClient) IngestCertifyVulns(ctx context.Context, pkgs []*model.PkgInputSpec, vulnerabilities []*model.VulnerabilityInputSpec, certifyVulns []*model.ScanMetadataInput) ([]string, error) { +func (c *neo4jClient) IngestCertifyVulns(ctx context.Context, pkgs []*model.IDorPkgInput, vulnerabilities []*model.IDorVulnerabilityInput, certifyVulns []*model.ScanMetadataInput) ([]string, error) { return []string{}, fmt.Errorf("not implemented - IngestCertifyVulns") } diff --git a/pkg/assembler/backends/neo4j/hasSLSA.go b/pkg/assembler/backends/neo4j/hasSLSA.go index b070dc4e31..3f46e54008 100644 --- a/pkg/assembler/backends/neo4j/hasSLSA.go +++ b/pkg/assembler/backends/neo4j/hasSLSA.go @@ -597,10 +597,10 @@ func (c *neo4jClient) HasSlsa(ctx context.Context, hasSLSASpec *model.HasSLSASpe // return &hasSLSA // } -func (c *neo4jClient) IngestSLSA(ctx context.Context, subject model.ArtifactInputSpec, builtFrom []*model.ArtifactInputSpec, builtBy model.BuilderInputSpec, slsa model.SLSAInputSpec) (string, error) { +func (c *neo4jClient) IngestSLSA(ctx context.Context, subject model.IDorArtifactInput, builtFrom []*model.IDorArtifactInput, builtBy model.IDorBuilderInput, slsa model.SLSAInputSpec) (string, error) { panic(fmt.Errorf("not implemented: IngestSlsa - ingestSLSA")) } -func (c *neo4jClient) IngestSLSAs(ctx context.Context, subjects []*model.ArtifactInputSpec, builtFromList [][]*model.ArtifactInputSpec, builtByList []*model.BuilderInputSpec, slsaList []*model.SLSAInputSpec) ([]string, error) { +func (c *neo4jClient) IngestSLSAs(ctx context.Context, subjects []*model.IDorArtifactInput, builtFromList [][]*model.IDorArtifactInput, builtByList []*model.IDorBuilderInput, slsaList []*model.SLSAInputSpec) ([]string, error) { return []string{}, fmt.Errorf("not implemented: IngestSLSAs") } diff --git a/pkg/assembler/backends/neo4j/hasSourceAt.go b/pkg/assembler/backends/neo4j/hasSourceAt.go index 178f2b881a..d1d76df3c2 100644 --- a/pkg/assembler/backends/neo4j/hasSourceAt.go +++ b/pkg/assembler/backends/neo4j/hasSourceAt.go @@ -158,10 +158,10 @@ func setHasSourceAtValues(sb *strings.Builder, hasSourceAtSpec *model.HasSourceA } } -func (c *neo4jClient) IngestHasSourceAt(ctx context.Context, pkg model.PkgInputSpec, pkgMatchType model.MatchFlags, source model.SourceInputSpec, hasSourceAt model.HasSourceAtInputSpec) (string, error) { +func (c *neo4jClient) IngestHasSourceAt(ctx context.Context, pkg model.IDorPkgInput, pkgMatchType model.MatchFlags, source model.IDorSourceInput, hasSourceAt model.HasSourceAtInputSpec) (string, error) { panic(fmt.Errorf("not implemented: IngestHasSourceAt")) } -func (c *neo4jClient) IngestHasSourceAts(ctx context.Context, pkgs []*model.PkgInputSpec, pkgMatchType *model.MatchFlags, sources []*model.SourceInputSpec, hasSourceAts []*model.HasSourceAtInputSpec) ([]string, error) { +func (c *neo4jClient) IngestHasSourceAts(ctx context.Context, pkgs []*model.IDorPkgInput, pkgMatchType *model.MatchFlags, sources []*model.IDorSourceInput, hasSourceAts []*model.HasSourceAtInputSpec) ([]string, error) { panic(fmt.Errorf("not implemented: IngestHasSourceAts")) } diff --git a/pkg/assembler/backends/neo4j/hashEqual.go b/pkg/assembler/backends/neo4j/hashEqual.go index 2a42acabb7..3e5cff95bb 100644 --- a/pkg/assembler/backends/neo4j/hashEqual.go +++ b/pkg/assembler/backends/neo4j/hashEqual.go @@ -138,10 +138,10 @@ func setHashEqualValues(sb *strings.Builder, hashEqualSpec *model.HashEqualSpec, } } -func (c *neo4jClient) IngestHashEqual(ctx context.Context, artifact model.ArtifactInputSpec, equalArtifact model.ArtifactInputSpec, hashEqual model.HashEqualInputSpec) (string, error) { +func (c *neo4jClient) IngestHashEqual(ctx context.Context, artifact model.IDorArtifactInput, equalArtifact model.IDorArtifactInput, hashEqual model.HashEqualInputSpec) (string, error) { panic(fmt.Errorf("not implemented: IngestHashEqual - IngestHashEqual")) } -func (c *neo4jClient) IngestHashEquals(ctx context.Context, artifacts []*model.ArtifactInputSpec, otherArtifacts []*model.ArtifactInputSpec, hashEquals []*model.HashEqualInputSpec) ([]string, error) { +func (c *neo4jClient) IngestHashEquals(ctx context.Context, artifacts []*model.IDorArtifactInput, otherArtifacts []*model.IDorArtifactInput, hashEquals []*model.HashEqualInputSpec) ([]string, error) { return []string{}, fmt.Errorf("not implemented: IngestHashEquals") } diff --git a/pkg/assembler/backends/neo4j/isDependency.go b/pkg/assembler/backends/neo4j/isDependency.go index 1059947b02..e3b476c200 100644 --- a/pkg/assembler/backends/neo4j/isDependency.go +++ b/pkg/assembler/backends/neo4j/isDependency.go @@ -159,13 +159,13 @@ func setIsDependencyValues(sb *strings.Builder, isDependencySpec *model.IsDepend // Ingest IngestDependencies -func (c *neo4jClient) IngestDependencies(ctx context.Context, pkgs []*model.PkgInputSpec, depPkgs []*model.PkgInputSpec, depPkgMatchType model.MatchFlags, dependencies []*model.IsDependencyInputSpec) ([]string, error) { +func (c *neo4jClient) IngestDependencies(ctx context.Context, pkgs []*model.IDorPkgInput, depPkgs []*model.IDorPkgInput, depPkgMatchType model.MatchFlags, dependencies []*model.IsDependencyInputSpec) ([]string, error) { return []string{}, fmt.Errorf("not implemented: IngestDependencies") } // Ingest IsDependency -func (c *neo4jClient) IngestDependency(ctx context.Context, pkg model.PkgInputSpec, depPkg model.PkgInputSpec, depPkgMatchType model.MatchFlags, dependency model.IsDependencyInputSpec) (string, error) { +func (c *neo4jClient) IngestDependency(ctx context.Context, pkg model.IDorPkgInput, depPkg model.IDorPkgInput, depPkgMatchType model.MatchFlags, dependency model.IsDependencyInputSpec) (string, error) { session := c.driver.NewSession(neo4j.SessionConfig{AccessMode: neo4j.AccessModeWrite}) defer session.Close() // TODO: handle depPkgMatchType @@ -175,15 +175,15 @@ func (c *neo4jClient) IngestDependency(ctx context.Context, pkg model.PkgInputSp queryValues := map[string]any{} // TODO: use generics here between PkgInputSpec and PkgSpec? - selectedPkgSpec := helper.ConvertPkgInputSpecToPkgSpec(&pkg) + selectedPkgSpec := helper.ConvertPkgInputSpecToPkgSpec(pkg.PackageInput) // Note: depPkgSpec only takes up to the pkgName as IsDependency does not allow for the attestation // to be made at the pkgVersion level. Version range for the dependent package is defined as a property // on IsDependency. matchEmpty := false depPkgSpec := model.PkgSpec{ - Type: &depPkg.Type, - Namespace: depPkg.Namespace, - Name: &depPkg.Name, + Type: &depPkg.PackageInput.Type, + Namespace: depPkg.PackageInput.Namespace, + Name: &depPkg.PackageInput.Name, Version: nil, Subpath: nil, Qualifiers: nil, diff --git a/pkg/assembler/backends/neo4j/isOccurrence.go b/pkg/assembler/backends/neo4j/isOccurrence.go index f12f9e9dab..e0309fc40f 100644 --- a/pkg/assembler/backends/neo4j/isOccurrence.go +++ b/pkg/assembler/backends/neo4j/isOccurrence.go @@ -201,13 +201,13 @@ func generateModelIsOccurrence(subject model.PackageOrSource, artifact *model.Ar // Ingest IngestOccurrences -func (c *neo4jClient) IngestOccurrences(ctx context.Context, subjects model.PackageOrSourceInputs, artifacts []*model.ArtifactInputSpec, occurrences []*model.IsOccurrenceInputSpec) ([]string, error) { +func (c *neo4jClient) IngestOccurrences(ctx context.Context, subjects model.PackageOrSourceInputs, artifacts []*model.IDorArtifactInput, occurrences []*model.IsOccurrenceInputSpec) ([]string, error) { return []string{}, fmt.Errorf("not implemented: IngestOccurrences") } // Ingest IngestOccurrence -func (c *neo4jClient) IngestOccurrence(ctx context.Context, subject model.PackageOrSourceInput, artifact model.ArtifactInputSpec, occurrence model.IsOccurrenceInputSpec) (string, error) { +func (c *neo4jClient) IngestOccurrence(ctx context.Context, subject model.PackageOrSourceInput, artifact model.IDorArtifactInput, occurrence model.IsOccurrenceInputSpec) (string, error) { session := c.driver.NewSession(neo4j.SessionConfig{AccessMode: neo4j.AccessModeWrite}) defer session.Close() @@ -216,7 +216,7 @@ func (c *neo4jClient) IngestOccurrence(ctx context.Context, subject model.Packag var firstMatch bool = true queryValues := map[string]any{} - occurrenceArt := helper.ConvertArtInputSpecToArtSpec(&artifact) + occurrenceArt := helper.ConvertArtInputSpecToArtSpec(artifact.ArtifactInput) queryValues[justification] = occurrence.Justification queryValues[origin] = occurrence.Origin @@ -224,7 +224,7 @@ func (c *neo4jClient) IngestOccurrence(ctx context.Context, subject model.Packag if subject.Package != nil { // TODO: use generics here between PkgInputSpec and PkgSpecs? - selectedPkgSpec := helper.ConvertPkgInputSpecToPkgSpec(subject.Package) + selectedPkgSpec := helper.ConvertPkgInputSpecToPkgSpec(subject.Package.PackageInput) query := "MATCH (root:Pkg)-[:PkgHasType]->(type:PkgType)-[:PkgHasNamespace]->(namespace:PkgNamespace)" + "-[:PkgHasName]->(name:PkgName)-[:PkgHasVersion]->(version:PkgVersion), (objArt:Artifact)" @@ -285,7 +285,7 @@ func (c *neo4jClient) IngestOccurrence(ctx context.Context, subject model.Packag return result.(*model.IsOccurrence).ID, nil } else if subject.Source != nil { // TODO: use generics here between SourceInputSpec and SourceSpec? - selectedSrcSpec := helper.ConvertSrcInputSpecToSrcSpec(subject.Source) + selectedSrcSpec := helper.ConvertSrcInputSpecToSrcSpec(subject.Source.SourceInput) returnValue := " RETURN type.type, namespace.namespace, name.name, name.tag, name.commit, isOccurrence, objArt.algorithm, objArt.digest" diff --git a/pkg/assembler/backends/neo4j/pkg.go b/pkg/assembler/backends/neo4j/pkg.go index bc0ba0dddc..2f59db9d38 100644 --- a/pkg/assembler/backends/neo4j/pkg.go +++ b/pkg/assembler/backends/neo4j/pkg.go @@ -355,29 +355,29 @@ func removeInvalidCharFromProperty(key string) string { return strings.ReplaceAll(key, ".", "_") } -func (c *neo4jClient) IngestPackages(ctx context.Context, pkgs []*model.PkgInputSpec) ([]*model.PackageIDs, error) { +func (c *neo4jClient) IngestPackages(ctx context.Context, pkgs []*model.IDorPkgInput) ([]*model.PackageIDs, error) { return []*model.PackageIDs{}, fmt.Errorf("not implemented: IngestPackages") } -func (c *neo4jClient) IngestPackage(ctx context.Context, pkg model.PkgInputSpec) (*model.PackageIDs, error) { +func (c *neo4jClient) IngestPackage(ctx context.Context, pkg model.IDorPkgInput) (*model.PackageIDs, error) { session := c.driver.NewSession(neo4j.SessionConfig{AccessMode: neo4j.AccessModeWrite}) defer session.Close() values := map[string]any{} - values["pkgType"] = pkg.Type - values["name"] = pkg.Name - if pkg.Namespace != nil { - values["namespace"] = *pkg.Namespace + values["pkgType"] = pkg.PackageInput.Type + values["name"] = pkg.PackageInput.Name + if pkg.PackageInput.Namespace != nil { + values["namespace"] = *pkg.PackageInput.Namespace } else { values["namespace"] = "" } - if pkg.Version != nil { - values["version"] = *pkg.Version + if pkg.PackageInput.Version != nil { + values["version"] = *pkg.PackageInput.Version } else { values["version"] = "" } - if pkg.Subpath != nil { - values["subpath"] = *pkg.Subpath + if pkg.PackageInput.Subpath != nil { + values["subpath"] = *pkg.PackageInput.Subpath } else { values["subpath"] = "" } @@ -385,7 +385,7 @@ func (c *neo4jClient) IngestPackage(ctx context.Context, pkg model.PkgInputSpec) // To ensure consistency, always sort the qualifiers by key qualifiersMap := map[string]string{} keys := []string{} - for _, kv := range pkg.Qualifiers { + for _, kv := range pkg.PackageInput.Qualifiers { qualifiersMap[kv.Key] = kv.Value keys = append(keys, kv.Key) } diff --git a/pkg/assembler/backends/neo4j/pkgEqual.go b/pkg/assembler/backends/neo4j/pkgEqual.go index e44af997ac..187325d3b4 100644 --- a/pkg/assembler/backends/neo4j/pkgEqual.go +++ b/pkg/assembler/backends/neo4j/pkgEqual.go @@ -165,7 +165,7 @@ func setPkgEqualValues(sb *strings.Builder, pkgEqualSpec *model.PkgEqualSpec, fi // Ingest PkgEqual -func (c *neo4jClient) IngestPkgEqual(ctx context.Context, pkg model.PkgInputSpec, depPkg model.PkgInputSpec, pkgEqual model.PkgEqualInputSpec) (string, error) { +func (c *neo4jClient) IngestPkgEqual(ctx context.Context, pkg model.IDorPkgInput, depPkg model.IDorPkgInput, pkgEqual model.PkgEqualInputSpec) (string, error) { session := c.driver.NewSession(neo4j.SessionConfig{AccessMode: neo4j.AccessModeWrite}) defer session.Close() @@ -173,8 +173,8 @@ func (c *neo4jClient) IngestPkgEqual(ctx context.Context, pkg model.PkgInputSpec queryValues := map[string]any{} // TODO: use generics here between PkgInputSpec and PkgSpec? - selectedPkgSpec := helper.ConvertPkgInputSpecToPkgSpec(&pkg) - depPkgSpec := helper.ConvertPkgInputSpecToPkgSpec(&depPkg) + selectedPkgSpec := helper.ConvertPkgInputSpecToPkgSpec(pkg.PackageInput) + depPkgSpec := helper.ConvertPkgInputSpecToPkgSpec(depPkg.PackageInput) queryValues[justification] = pkgEqual.Justification queryValues[origin] = pkgEqual.Origin @@ -258,6 +258,6 @@ func (c *neo4jClient) IngestPkgEqual(ctx context.Context, pkg model.PkgInputSpec return result.(*model.PkgEqual).ID, nil } -func (c *neo4jClient) IngestPkgEquals(ctx context.Context, pkgs []*model.PkgInputSpec, otherPackages []*model.PkgInputSpec, pkgEquals []*model.PkgEqualInputSpec) ([]string, error) { +func (c *neo4jClient) IngestPkgEquals(ctx context.Context, pkgs []*model.IDorPkgInput, otherPackages []*model.IDorPkgInput, pkgEquals []*model.PkgEqualInputSpec) ([]string, error) { return nil, fmt.Errorf("not implemented - IngestPkgEquals") } diff --git a/pkg/assembler/backends/neo4j/src.go b/pkg/assembler/backends/neo4j/src.go index 4e3291ca70..475c737d2f 100644 --- a/pkg/assembler/backends/neo4j/src.go +++ b/pkg/assembler/backends/neo4j/src.go @@ -240,33 +240,33 @@ func (c *neo4jClient) sourcesNamespace(ctx context.Context, sourceSpec *model.So return result.([]*model.Source), nil } -func (c *neo4jClient) IngestSources(ctx context.Context, sources []*model.SourceInputSpec) ([]*model.SourceIDs, error) { +func (c *neo4jClient) IngestSources(ctx context.Context, sources []*model.IDorSourceInput) ([]*model.SourceIDs, error) { return []*model.SourceIDs{}, fmt.Errorf("not implemented: IngestSources") } -func (c *neo4jClient) IngestSource(ctx context.Context, source model.SourceInputSpec) (*model.SourceIDs, error) { +func (c *neo4jClient) IngestSource(ctx context.Context, source model.IDorSourceInput) (*model.SourceIDs, error) { session := c.driver.NewSession(neo4j.SessionConfig{AccessMode: neo4j.AccessModeWrite}) defer session.Close() values := map[string]any{} - values["sourceType"] = source.Type - values["namespace"] = source.Namespace - values["name"] = source.Name + values["sourceType"] = source.SourceInput.Type + values["namespace"] = source.SourceInput.Namespace + values["name"] = source.SourceInput.Name - if source.Commit != nil && source.Tag != nil { - if *source.Commit != "" && *source.Tag != "" { + if source.SourceInput.Commit != nil && source.SourceInput.Tag != nil { + if *source.SourceInput.Commit != "" && *source.SourceInput.Tag != "" { return nil, gqlerror.Errorf("Passing both commit and tag selectors is an error") } } - if source.Commit != nil { - values["commit"] = *source.Commit + if source.SourceInput.Commit != nil { + values["commit"] = *source.SourceInput.Commit } else { values["commit"] = "" } - if source.Tag != nil { - values["tag"] = *source.Tag + if source.SourceInput.Tag != nil { + values["tag"] = *source.SourceInput.Tag } else { values["tag"] = "" } diff --git a/pkg/assembler/backends/neo4j/vulnEqual.go b/pkg/assembler/backends/neo4j/vulnEqual.go index c673efe31b..0d246b406b 100644 --- a/pkg/assembler/backends/neo4j/vulnEqual.go +++ b/pkg/assembler/backends/neo4j/vulnEqual.go @@ -192,10 +192,10 @@ func (c *neo4jClient) VulnEqual(ctx context.Context, vulnEqualSpec *model.VulnEq // return &isVulnerability // } -func (c *neo4jClient) IngestVulnEqual(ctx context.Context, vulnerability model.VulnerabilityInputSpec, otherVulnerability model.VulnerabilityInputSpec, vulnEqual model.VulnEqualInputSpec) (string, error) { +func (c *neo4jClient) IngestVulnEqual(ctx context.Context, vulnerability model.IDorVulnerabilityInput, otherVulnerability model.IDorVulnerabilityInput, vulnEqual model.VulnEqualInputSpec) (string, error) { return "", fmt.Errorf("not implemented - IngestVulnEqual") } -func (c *neo4jClient) IngestVulnEquals(ctx context.Context, vulnerabilities []*model.VulnerabilityInputSpec, otherVulnerabilities []*model.VulnerabilityInputSpec, vulnEquals []*model.VulnEqualInputSpec) ([]string, error) { +func (c *neo4jClient) IngestVulnEquals(ctx context.Context, vulnerabilities []*model.IDorVulnerabilityInput, otherVulnerabilities []*model.IDorVulnerabilityInput, vulnEquals []*model.VulnEqualInputSpec) ([]string, error) { return []string{}, fmt.Errorf("not implemented - IngestVulnEquals") } diff --git a/pkg/assembler/backends/neo4j/vulnMetadata.go b/pkg/assembler/backends/neo4j/vulnMetadata.go index 12b6ee0911..d7f2094e01 100644 --- a/pkg/assembler/backends/neo4j/vulnMetadata.go +++ b/pkg/assembler/backends/neo4j/vulnMetadata.go @@ -22,11 +22,11 @@ import ( "github.com/guacsec/guac/pkg/assembler/graphql/model" ) -func (c *neo4jClient) IngestVulnerabilityMetadata(ctx context.Context, vulnerability model.VulnerabilityInputSpec, vulnerabilityMetadata model.VulnerabilityMetadataInputSpec) (string, error) { +func (c *neo4jClient) IngestVulnerabilityMetadata(ctx context.Context, vulnerability model.IDorVulnerabilityInput, vulnerabilityMetadata model.VulnerabilityMetadataInputSpec) (string, error) { return "", fmt.Errorf("not implemented - IngestVulnerabilityMetadata") } -func (c *neo4jClient) IngestBulkVulnerabilityMetadata(ctx context.Context, vulnerabilities []*model.VulnerabilityInputSpec, vulnerabilityMetadataList []*model.VulnerabilityMetadataInputSpec) ([]string, error) { +func (c *neo4jClient) IngestBulkVulnerabilityMetadata(ctx context.Context, vulnerabilities []*model.IDorVulnerabilityInput, vulnerabilityMetadataList []*model.VulnerabilityMetadataInputSpec) ([]string, error) { return []string{}, fmt.Errorf("not implemented - IngestBulkVulnerabilityMetadata") } diff --git a/pkg/assembler/backends/neo4j/vulnerability.go b/pkg/assembler/backends/neo4j/vulnerability.go index c5cc023feb..fb91c94adf 100644 --- a/pkg/assembler/backends/neo4j/vulnerability.go +++ b/pkg/assembler/backends/neo4j/vulnerability.go @@ -150,12 +150,12 @@ func (c *neo4jClient) Vulnerabilities(ctx context.Context, vulnSpec *model.Vulne // } // } -func (c *neo4jClient) IngestVulnerabilities(ctx context.Context, vulns []*model.VulnerabilityInputSpec) ([]*model.VulnerabilityIDs, error) { +func (c *neo4jClient) IngestVulnerabilities(ctx context.Context, vulns []*model.IDorVulnerabilityInput) ([]*model.VulnerabilityIDs, error) { return []*model.VulnerabilityIDs{}, fmt.Errorf("not implemented: IngestVulnerabilities") } // TODO (pxp928): fix for new vulnerability -func (c *neo4jClient) IngestVulnerability(ctx context.Context, vuln model.VulnerabilityInputSpec) (*model.VulnerabilityIDs, error) { +func (c *neo4jClient) IngestVulnerability(ctx context.Context, vuln model.IDorVulnerabilityInput) (*model.VulnerabilityIDs, error) { // session := c.driver.NewSession(neo4j.SessionConfig{AccessMode: neo4j.AccessModeWrite}) // defer session.Close() diff --git a/pkg/assembler/clients/generated/operations.go b/pkg/assembler/clients/generated/operations.go index 7e3904b337..b6686d8842 100644 --- a/pkg/assembler/clients/generated/operations.go +++ b/pkg/assembler/clients/generated/operations.go @@ -8059,9 +8059,131 @@ func (v *HashEqualInputSpec) GetOrigin() string { return v.Origin } // GetCollector returns HashEqualInputSpec.Collector, and is useful for accessing the field via an interface. func (v *HashEqualInputSpec) GetCollector() string { return v.Collector } +// IDorArtifactInput allows for specifying either the artifact ID or the ArtifactInputSpec. +// +// Either the ID or the ArtifactInputSpec must be specified. Both cannot be nil. +// +// If the ID is specified, the ArtifactInputSpec is not used. +type IDorArtifactInput struct { + ArtifactID *string `json:"artifactID"` + ArtifactInput *ArtifactInputSpec `json:"artifactInput"` +} + +// GetArtifactID returns IDorArtifactInput.ArtifactID, and is useful for accessing the field via an interface. +func (v *IDorArtifactInput) GetArtifactID() *string { return v.ArtifactID } + +// GetArtifactInput returns IDorArtifactInput.ArtifactInput, and is useful for accessing the field via an interface. +func (v *IDorArtifactInput) GetArtifactInput() *ArtifactInputSpec { return v.ArtifactInput } + +// IDorBuilderInput allows for specifying either the builder ID or the BuilderInputSpec. +// +// Either the ID or the BuilderInputSpec must be specified. Both cannot be nil. +// +// If the ID is specified, the BuilderInputSpec is not used. +type IDorBuilderInput struct { + BuilderID *string `json:"builderID"` + BuilderInput *BuilderInputSpec `json:"builderInput"` +} + +// GetBuilderID returns IDorBuilderInput.BuilderID, and is useful for accessing the field via an interface. +func (v *IDorBuilderInput) GetBuilderID() *string { return v.BuilderID } + +// GetBuilderInput returns IDorBuilderInput.BuilderInput, and is useful for accessing the field via an interface. +func (v *IDorBuilderInput) GetBuilderInput() *BuilderInputSpec { return v.BuilderInput } + +// IDorLicenseInput allows for specifying either the license ID or the LicenseInputSpec. +// +// Either the ID or the LicenseInputSpec must be specified. Both cannot be nil. +// +// If the ID is specified, the LicenseInputSpec is not used. +type IDorLicenseInput struct { + LicenseID *string `json:"licenseID"` + LicenseInput *LicenseInputSpec `json:"licenseInput"` +} + +// GetLicenseID returns IDorLicenseInput.LicenseID, and is useful for accessing the field via an interface. +func (v *IDorLicenseInput) GetLicenseID() *string { return v.LicenseID } + +// GetLicenseInput returns IDorLicenseInput.LicenseInput, and is useful for accessing the field via an interface. +func (v *IDorLicenseInput) GetLicenseInput() *LicenseInputSpec { return v.LicenseInput } + +// IDorPkgInput allows for specifying either the package IDs or the PkgInputSpec. +// +// Either the IDs or the PkgInputSpec must be specified. Both cannot be nil. +// +// If the IDs are specified, the PkgInputSpec is not used. +type IDorPkgInput struct { + PackageTypeID *string `json:"packageTypeID"` + PackageNamespaceID *string `json:"packageNamespaceID"` + PackageNameID *string `json:"packageNameID"` + PackageVersionID *string `json:"packageVersionID"` + PackageInput *PkgInputSpec `json:"packageInput"` +} + +// GetPackageTypeID returns IDorPkgInput.PackageTypeID, and is useful for accessing the field via an interface. +func (v *IDorPkgInput) GetPackageTypeID() *string { return v.PackageTypeID } + +// GetPackageNamespaceID returns IDorPkgInput.PackageNamespaceID, and is useful for accessing the field via an interface. +func (v *IDorPkgInput) GetPackageNamespaceID() *string { return v.PackageNamespaceID } + +// GetPackageNameID returns IDorPkgInput.PackageNameID, and is useful for accessing the field via an interface. +func (v *IDorPkgInput) GetPackageNameID() *string { return v.PackageNameID } + +// GetPackageVersionID returns IDorPkgInput.PackageVersionID, and is useful for accessing the field via an interface. +func (v *IDorPkgInput) GetPackageVersionID() *string { return v.PackageVersionID } + +// GetPackageInput returns IDorPkgInput.PackageInput, and is useful for accessing the field via an interface. +func (v *IDorPkgInput) GetPackageInput() *PkgInputSpec { return v.PackageInput } + +// IDorSourceInput allows for specifying either the source IDs or the SourceInputSpec. +// +// Either the IDs or the SourceInputSpec must be specified. Both cannot be nil. +// +// If the IDs are specified, the SourceInputSpec is not used. +type IDorSourceInput struct { + SourceTypeID *string `json:"sourceTypeID"` + SourceNamespaceID *string `json:"sourceNamespaceID"` + SourceNameID *string `json:"sourceNameID"` + SourceInput *SourceInputSpec `json:"sourceInput"` +} + +// GetSourceTypeID returns IDorSourceInput.SourceTypeID, and is useful for accessing the field via an interface. +func (v *IDorSourceInput) GetSourceTypeID() *string { return v.SourceTypeID } + +// GetSourceNamespaceID returns IDorSourceInput.SourceNamespaceID, and is useful for accessing the field via an interface. +func (v *IDorSourceInput) GetSourceNamespaceID() *string { return v.SourceNamespaceID } + +// GetSourceNameID returns IDorSourceInput.SourceNameID, and is useful for accessing the field via an interface. +func (v *IDorSourceInput) GetSourceNameID() *string { return v.SourceNameID } + +// GetSourceInput returns IDorSourceInput.SourceInput, and is useful for accessing the field via an interface. +func (v *IDorSourceInput) GetSourceInput() *SourceInputSpec { return v.SourceInput } + +// IDorVulnerabilityInput allows for specifying either the vulnerability IDs or the VulnerabilityInputSpec. +// +// Either the IDs or the VulnerabilityInputSpec must be specified. Both cannot be nil. +// +// If the IDs are specified, the VulnerabilityInputSpec is not used. +type IDorVulnerabilityInput struct { + VulnerabilityTypeID *string `json:"vulnerabilityTypeID"` + VulnerabilityNodeID *string `json:"vulnerabilityNodeID"` + VulnerabilityInput *VulnerabilityInputSpec `json:"vulnerabilityInput"` +} + +// GetVulnerabilityTypeID returns IDorVulnerabilityInput.VulnerabilityTypeID, and is useful for accessing the field via an interface. +func (v *IDorVulnerabilityInput) GetVulnerabilityTypeID() *string { return v.VulnerabilityTypeID } + +// GetVulnerabilityNodeID returns IDorVulnerabilityInput.VulnerabilityNodeID, and is useful for accessing the field via an interface. +func (v *IDorVulnerabilityInput) GetVulnerabilityNodeID() *string { return v.VulnerabilityNodeID } + +// GetVulnerabilityInput returns IDorVulnerabilityInput.VulnerabilityInput, and is useful for accessing the field via an interface. +func (v *IDorVulnerabilityInput) GetVulnerabilityInput() *VulnerabilityInputSpec { + return v.VulnerabilityInput +} + // IngestArtifactResponse is returned by IngestArtifact on success. type IngestArtifactResponse struct { - // Ingests a new artifact and returns it. The returned ID can be empty string. + // Ingests a new artifact and returns it. IngestArtifact string `json:"ingestArtifact"` } @@ -8070,7 +8192,7 @@ func (v *IngestArtifactResponse) GetIngestArtifact() string { return v.IngestArt // IngestArtifactsResponse is returned by IngestArtifacts on success. type IngestArtifactsResponse struct { - // Bulk ingests new artifacts and returns a list of them. The returned array of IDs can be a an array of empty string. + // Bulk ingests new artifacts and returns a list of them. The returned array of IDs must be in the same order as the inputs. IngestArtifacts []string `json:"ingestArtifacts"` } @@ -8079,7 +8201,7 @@ func (v *IngestArtifactsResponse) GetIngestArtifacts() []string { return v.Inges // IngestBuilderResponse is returned by IngestBuilder on success. type IngestBuilderResponse struct { - // Ingests a new builder and returns it. The returned ID can be empty string. + // Ingests a new builder and returns it. IngestBuilder string `json:"ingestBuilder"` } @@ -8088,7 +8210,7 @@ func (v *IngestBuilderResponse) GetIngestBuilder() string { return v.IngestBuild // IngestBuildersResponse is returned by IngestBuilders on success. type IngestBuildersResponse struct { - // Bulk ingests new builders and returns a list of them. The returned array of IDs can be a an array of empty string. + // Bulk ingests new builders and returns a list of them. The returned array of IDs must be in the same order as the inputs. IngestBuilders []string `json:"ingestBuilders"` } @@ -8470,7 +8592,7 @@ func (v *IngestHashEqualsResponse) GetIngestHashEquals() []string { return v.Ing // IngestIsDependenciesResponse is returned by IngestIsDependencies on success. type IngestIsDependenciesResponse struct { - // Bulk adds a dependency between two packages. The returned array of IDs can be a an array of empty string. + // Bulk adds a dependency between two packages. The returned array of IDs cannot be an empty string as its used by hasSBOM. IngestDependencies []string `json:"ingestDependencies"` } @@ -8479,7 +8601,7 @@ func (v *IngestIsDependenciesResponse) GetIngestDependencies() []string { return // IngestIsDependencyResponse is returned by IngestIsDependency on success. type IngestIsDependencyResponse struct { - // Adds a dependency between two packages. The returned ID can be empty string. + // Adds a dependency between two packages. The returned ID cannot be empty string as its used by hasSBOM. IngestDependency string `json:"ingestDependency"` } @@ -8488,7 +8610,7 @@ func (v *IngestIsDependencyResponse) GetIngestDependency() string { return v.Ing // IngestIsOccurrencePkgResponse is returned by IngestIsOccurrencePkg on success. type IngestIsOccurrencePkgResponse struct { - // Ingest that an artifact is produced from a package or source. The returned ID can be empty string. + // Ingest that an artifact is produced from a package or source. The returned ID cannot be empty string as its used by hasSBOM. IngestOccurrence string `json:"ingestOccurrence"` } @@ -8497,7 +8619,7 @@ func (v *IngestIsOccurrencePkgResponse) GetIngestOccurrence() string { return v. // IngestIsOccurrenceSrcResponse is returned by IngestIsOccurrenceSrc on success. type IngestIsOccurrenceSrcResponse struct { - // Ingest that an artifact is produced from a package or source. The returned ID can be empty string. + // Ingest that an artifact is produced from a package or source. The returned ID cannot be empty string as its used by hasSBOM. IngestOccurrence string `json:"ingestOccurrence"` } @@ -8506,7 +8628,7 @@ func (v *IngestIsOccurrenceSrcResponse) GetIngestOccurrence() string { return v. // IngestIsOccurrencesPkgResponse is returned by IngestIsOccurrencesPkg on success. type IngestIsOccurrencesPkgResponse struct { - // Bulk ingest that an artifact is produced from a package or source. The returned array of IDs can be a an array of empty string. + // Bulk ingest that an artifact is produced from a package or source. The returned array of IDs cannot be an empty string as its used by hasSBOM IngestOccurrences []string `json:"ingestOccurrences"` } @@ -8515,7 +8637,7 @@ func (v *IngestIsOccurrencesPkgResponse) GetIngestOccurrences() []string { retur // IngestIsOccurrencesSrcResponse is returned by IngestIsOccurrencesSrc on success. type IngestIsOccurrencesSrcResponse struct { - // Bulk ingest that an artifact is produced from a package or source. The returned array of IDs can be a an array of empty string. + // Bulk ingest that an artifact is produced from a package or source. The returned array of IDs cannot be an empty string as its used by hasSBOM IngestOccurrences []string `json:"ingestOccurrences"` } @@ -8533,7 +8655,7 @@ func (v *IngestLicenseResponse) GetIngestLicense() string { return v.IngestLicen // IngestLicensesResponse is returned by IngestLicenses on success. type IngestLicensesResponse struct { - // Bulk ingests new licenses and returns a list of them. + // Bulk ingests new licenses and returns a list of them. The returned array of IDs must be in the same order as the inputs. IngestLicenses []string `json:"ingestLicenses"` } @@ -8569,7 +8691,7 @@ func (v *IngestPackageIngestPackagePackageIDs) GetPackageVersionID() string { // IngestPackageResponse is returned by IngestPackage on success. type IngestPackageResponse struct { - // Ingests a new package and returns a corresponding package hierarchy containing only the IDs. The returned ID can be empty string. + // Ingests a new package and returns a corresponding package hierarchy containing only the IDs. IngestPackage IngestPackageIngestPackagePackageIDs `json:"ingestPackage"` } @@ -8607,7 +8729,7 @@ func (v *IngestPackagesIngestPackagesPackageIDs) GetPackageVersionID() string { // IngestPackagesResponse is returned by IngestPackages on success. type IngestPackagesResponse struct { - // Bulk ingests packages and returns the list of corresponding package hierarchies containing only the IDs. The returned array of IDs can be empty strings. + // Bulk ingests packages and returns the list of corresponding package hierarchies containing only the IDs. The returned array of IDs must be in the same order as the inputs. IngestPackages []IngestPackagesIngestPackagesPackageIDs `json:"ingestPackages"` } @@ -8739,7 +8861,7 @@ func (v *IngestSourceIngestSourceSourceIDs) GetSourceNameID() string { return v. // IngestSourceResponse is returned by IngestSource on success. type IngestSourceResponse struct { - // Ingests a new source and returns the corresponding source trie path. The returned ID can be empty string. + // Ingests a new source and returns the corresponding source trie path. IngestSource IngestSourceIngestSourceSourceIDs `json:"ingestSource"` } @@ -8771,7 +8893,7 @@ func (v *IngestSourcesIngestSourcesSourceIDs) GetSourceNameID() string { return // IngestSourcesResponse is returned by IngestSources on success. type IngestSourcesResponse struct { - // Bulk ingests sources and returns the list of corresponding source trie path. The returned array of IDs can be a an array of empty string. + // Bulk ingests sources and returns the list of corresponding source trie path. The returned array of IDs must be in the same order as the inputs. IngestSources []IngestSourcesIngestSourcesSourceIDs `json:"ingestSources"` } @@ -8830,7 +8952,7 @@ func (v *IngestVulnerabilitiesIngestVulnerabilitiesVulnerabilityIDs) GetVulnerab // IngestVulnerabilitiesResponse is returned by IngestVulnerabilities on success. type IngestVulnerabilitiesResponse struct { - // Bulk ingests vulnerabilities and returns the list of corresponding vulnerability trie path. The returned array of IDs can be a an array of empty string. + // Bulk ingests vulnerabilities and returns the list of corresponding vulnerability trie path. The returned array of IDs must be in the same order as the inputs IngestVulnerabilities []IngestVulnerabilitiesIngestVulnerabilitiesVulnerabilityIDs `json:"ingestVulnerabilities"` } @@ -8860,7 +8982,7 @@ func (v *IngestVulnerabilityIngestVulnerabilityVulnerabilityIDs) GetVulnerabilit // IngestVulnerabilityResponse is returned by IngestVulnerability on success. type IngestVulnerabilityResponse struct { - // Ingests a new vulnerability and returns the corresponding vulnerability trie path. The returned ID can be empty string. + // Ingests a new vulnerability and returns the corresponding vulnerability trie path. IngestVulnerability IngestVulnerabilityIngestVulnerabilityVulnerabilityIDs `json:"ingestVulnerability"` } @@ -22313,44 +22435,44 @@ func (v *__HasSBOMsInput) GetFilter() HasSBOMSpec { return v.Filter } // __IngestArtifactInput is used internally by genqlient type __IngestArtifactInput struct { - Artifact ArtifactInputSpec `json:"artifact"` + Artifact IDorArtifactInput `json:"artifact"` } // GetArtifact returns __IngestArtifactInput.Artifact, and is useful for accessing the field via an interface. -func (v *__IngestArtifactInput) GetArtifact() ArtifactInputSpec { return v.Artifact } +func (v *__IngestArtifactInput) GetArtifact() IDorArtifactInput { return v.Artifact } // __IngestArtifactsInput is used internally by genqlient type __IngestArtifactsInput struct { - Artifacts []ArtifactInputSpec `json:"artifacts"` + Artifacts []IDorArtifactInput `json:"artifacts"` } // GetArtifacts returns __IngestArtifactsInput.Artifacts, and is useful for accessing the field via an interface. -func (v *__IngestArtifactsInput) GetArtifacts() []ArtifactInputSpec { return v.Artifacts } +func (v *__IngestArtifactsInput) GetArtifacts() []IDorArtifactInput { return v.Artifacts } // __IngestBuilderInput is used internally by genqlient type __IngestBuilderInput struct { - Builder BuilderInputSpec `json:"builder"` + Builder IDorBuilderInput `json:"builder"` } // GetBuilder returns __IngestBuilderInput.Builder, and is useful for accessing the field via an interface. -func (v *__IngestBuilderInput) GetBuilder() BuilderInputSpec { return v.Builder } +func (v *__IngestBuilderInput) GetBuilder() IDorBuilderInput { return v.Builder } // __IngestBuildersInput is used internally by genqlient type __IngestBuildersInput struct { - Builders []BuilderInputSpec `json:"builders"` + Builders []IDorBuilderInput `json:"builders"` } // GetBuilders returns __IngestBuildersInput.Builders, and is useful for accessing the field via an interface. -func (v *__IngestBuildersInput) GetBuilders() []BuilderInputSpec { return v.Builders } +func (v *__IngestBuildersInput) GetBuilders() []IDorBuilderInput { return v.Builders } // __IngestBulkVulnHasMetadataInput is used internally by genqlient type __IngestBulkVulnHasMetadataInput struct { - Vulnerabilities []VulnerabilityInputSpec `json:"vulnerabilities"` + Vulnerabilities []IDorVulnerabilityInput `json:"vulnerabilities"` VulnerabilityMetadataList []VulnerabilityMetadataInputSpec `json:"vulnerabilityMetadataList"` } // GetVulnerabilities returns __IngestBulkVulnHasMetadataInput.Vulnerabilities, and is useful for accessing the field via an interface. -func (v *__IngestBulkVulnHasMetadataInput) GetVulnerabilities() []VulnerabilityInputSpec { +func (v *__IngestBulkVulnHasMetadataInput) GetVulnerabilities() []IDorVulnerabilityInput { return v.Vulnerabilities } @@ -22361,24 +22483,24 @@ func (v *__IngestBulkVulnHasMetadataInput) GetVulnerabilityMetadataList() []Vuln // __IngestCertifyBadArtifactInput is used internally by genqlient type __IngestCertifyBadArtifactInput struct { - Artifact ArtifactInputSpec `json:"artifact"` + Artifact IDorArtifactInput `json:"artifact"` CertifyBad CertifyBadInputSpec `json:"certifyBad"` } // GetArtifact returns __IngestCertifyBadArtifactInput.Artifact, and is useful for accessing the field via an interface. -func (v *__IngestCertifyBadArtifactInput) GetArtifact() ArtifactInputSpec { return v.Artifact } +func (v *__IngestCertifyBadArtifactInput) GetArtifact() IDorArtifactInput { return v.Artifact } // GetCertifyBad returns __IngestCertifyBadArtifactInput.CertifyBad, and is useful for accessing the field via an interface. func (v *__IngestCertifyBadArtifactInput) GetCertifyBad() CertifyBadInputSpec { return v.CertifyBad } // __IngestCertifyBadArtifactsInput is used internally by genqlient type __IngestCertifyBadArtifactsInput struct { - Artifacts []ArtifactInputSpec `json:"artifacts"` + Artifacts []IDorArtifactInput `json:"artifacts"` CertifyBads []CertifyBadInputSpec `json:"certifyBads"` } // GetArtifacts returns __IngestCertifyBadArtifactsInput.Artifacts, and is useful for accessing the field via an interface. -func (v *__IngestCertifyBadArtifactsInput) GetArtifacts() []ArtifactInputSpec { return v.Artifacts } +func (v *__IngestCertifyBadArtifactsInput) GetArtifacts() []IDorArtifactInput { return v.Artifacts } // GetCertifyBads returns __IngestCertifyBadArtifactsInput.CertifyBads, and is useful for accessing the field via an interface. func (v *__IngestCertifyBadArtifactsInput) GetCertifyBads() []CertifyBadInputSpec { @@ -22387,13 +22509,13 @@ func (v *__IngestCertifyBadArtifactsInput) GetCertifyBads() []CertifyBadInputSpe // __IngestCertifyBadPkgInput is used internally by genqlient type __IngestCertifyBadPkgInput struct { - Pkg PkgInputSpec `json:"pkg"` + Pkg IDorPkgInput `json:"pkg"` PkgMatchType MatchFlags `json:"pkgMatchType"` CertifyBad CertifyBadInputSpec `json:"certifyBad"` } // GetPkg returns __IngestCertifyBadPkgInput.Pkg, and is useful for accessing the field via an interface. -func (v *__IngestCertifyBadPkgInput) GetPkg() PkgInputSpec { return v.Pkg } +func (v *__IngestCertifyBadPkgInput) GetPkg() IDorPkgInput { return v.Pkg } // GetPkgMatchType returns __IngestCertifyBadPkgInput.PkgMatchType, and is useful for accessing the field via an interface. func (v *__IngestCertifyBadPkgInput) GetPkgMatchType() MatchFlags { return v.PkgMatchType } @@ -22403,13 +22525,13 @@ func (v *__IngestCertifyBadPkgInput) GetCertifyBad() CertifyBadInputSpec { retur // __IngestCertifyBadPkgsInput is used internally by genqlient type __IngestCertifyBadPkgsInput struct { - Pkgs []PkgInputSpec `json:"pkgs"` + Pkgs []IDorPkgInput `json:"pkgs"` PkgMatchType MatchFlags `json:"pkgMatchType"` CertifyBads []CertifyBadInputSpec `json:"certifyBads"` } // GetPkgs returns __IngestCertifyBadPkgsInput.Pkgs, and is useful for accessing the field via an interface. -func (v *__IngestCertifyBadPkgsInput) GetPkgs() []PkgInputSpec { return v.Pkgs } +func (v *__IngestCertifyBadPkgsInput) GetPkgs() []IDorPkgInput { return v.Pkgs } // GetPkgMatchType returns __IngestCertifyBadPkgsInput.PkgMatchType, and is useful for accessing the field via an interface. func (v *__IngestCertifyBadPkgsInput) GetPkgMatchType() MatchFlags { return v.PkgMatchType } @@ -22419,36 +22541,36 @@ func (v *__IngestCertifyBadPkgsInput) GetCertifyBads() []CertifyBadInputSpec { r // __IngestCertifyBadSrcInput is used internally by genqlient type __IngestCertifyBadSrcInput struct { - Source SourceInputSpec `json:"source"` + Source IDorSourceInput `json:"source"` CertifyBad CertifyBadInputSpec `json:"certifyBad"` } // GetSource returns __IngestCertifyBadSrcInput.Source, and is useful for accessing the field via an interface. -func (v *__IngestCertifyBadSrcInput) GetSource() SourceInputSpec { return v.Source } +func (v *__IngestCertifyBadSrcInput) GetSource() IDorSourceInput { return v.Source } // GetCertifyBad returns __IngestCertifyBadSrcInput.CertifyBad, and is useful for accessing the field via an interface. func (v *__IngestCertifyBadSrcInput) GetCertifyBad() CertifyBadInputSpec { return v.CertifyBad } // __IngestCertifyBadSrcsInput is used internally by genqlient type __IngestCertifyBadSrcsInput struct { - Sources []SourceInputSpec `json:"sources"` + Sources []IDorSourceInput `json:"sources"` CertifyBads []CertifyBadInputSpec `json:"certifyBads"` } // GetSources returns __IngestCertifyBadSrcsInput.Sources, and is useful for accessing the field via an interface. -func (v *__IngestCertifyBadSrcsInput) GetSources() []SourceInputSpec { return v.Sources } +func (v *__IngestCertifyBadSrcsInput) GetSources() []IDorSourceInput { return v.Sources } // GetCertifyBads returns __IngestCertifyBadSrcsInput.CertifyBads, and is useful for accessing the field via an interface. func (v *__IngestCertifyBadSrcsInput) GetCertifyBads() []CertifyBadInputSpec { return v.CertifyBads } // __IngestCertifyGoodArtifactInput is used internally by genqlient type __IngestCertifyGoodArtifactInput struct { - Artifact ArtifactInputSpec `json:"artifact"` + Artifact IDorArtifactInput `json:"artifact"` CertifyGood CertifyGoodInputSpec `json:"certifyGood"` } // GetArtifact returns __IngestCertifyGoodArtifactInput.Artifact, and is useful for accessing the field via an interface. -func (v *__IngestCertifyGoodArtifactInput) GetArtifact() ArtifactInputSpec { return v.Artifact } +func (v *__IngestCertifyGoodArtifactInput) GetArtifact() IDorArtifactInput { return v.Artifact } // GetCertifyGood returns __IngestCertifyGoodArtifactInput.CertifyGood, and is useful for accessing the field via an interface. func (v *__IngestCertifyGoodArtifactInput) GetCertifyGood() CertifyGoodInputSpec { @@ -22457,12 +22579,12 @@ func (v *__IngestCertifyGoodArtifactInput) GetCertifyGood() CertifyGoodInputSpec // __IngestCertifyGoodArtifactsInput is used internally by genqlient type __IngestCertifyGoodArtifactsInput struct { - Artifacts []ArtifactInputSpec `json:"artifacts"` + Artifacts []IDorArtifactInput `json:"artifacts"` CertifyGoods []CertifyGoodInputSpec `json:"certifyGoods"` } // GetArtifacts returns __IngestCertifyGoodArtifactsInput.Artifacts, and is useful for accessing the field via an interface. -func (v *__IngestCertifyGoodArtifactsInput) GetArtifacts() []ArtifactInputSpec { return v.Artifacts } +func (v *__IngestCertifyGoodArtifactsInput) GetArtifacts() []IDorArtifactInput { return v.Artifacts } // GetCertifyGoods returns __IngestCertifyGoodArtifactsInput.CertifyGoods, and is useful for accessing the field via an interface. func (v *__IngestCertifyGoodArtifactsInput) GetCertifyGoods() []CertifyGoodInputSpec { @@ -22471,13 +22593,13 @@ func (v *__IngestCertifyGoodArtifactsInput) GetCertifyGoods() []CertifyGoodInput // __IngestCertifyGoodPkgInput is used internally by genqlient type __IngestCertifyGoodPkgInput struct { - Pkg PkgInputSpec `json:"pkg"` + Pkg IDorPkgInput `json:"pkg"` PkgMatchType MatchFlags `json:"pkgMatchType"` CertifyGood CertifyGoodInputSpec `json:"certifyGood"` } // GetPkg returns __IngestCertifyGoodPkgInput.Pkg, and is useful for accessing the field via an interface. -func (v *__IngestCertifyGoodPkgInput) GetPkg() PkgInputSpec { return v.Pkg } +func (v *__IngestCertifyGoodPkgInput) GetPkg() IDorPkgInput { return v.Pkg } // GetPkgMatchType returns __IngestCertifyGoodPkgInput.PkgMatchType, and is useful for accessing the field via an interface. func (v *__IngestCertifyGoodPkgInput) GetPkgMatchType() MatchFlags { return v.PkgMatchType } @@ -22487,13 +22609,13 @@ func (v *__IngestCertifyGoodPkgInput) GetCertifyGood() CertifyGoodInputSpec { re // __IngestCertifyGoodPkgsInput is used internally by genqlient type __IngestCertifyGoodPkgsInput struct { - Pkgs []PkgInputSpec `json:"pkgs"` + Pkgs []IDorPkgInput `json:"pkgs"` PkgMatchType MatchFlags `json:"pkgMatchType"` CertifyGoods []CertifyGoodInputSpec `json:"certifyGoods"` } // GetPkgs returns __IngestCertifyGoodPkgsInput.Pkgs, and is useful for accessing the field via an interface. -func (v *__IngestCertifyGoodPkgsInput) GetPkgs() []PkgInputSpec { return v.Pkgs } +func (v *__IngestCertifyGoodPkgsInput) GetPkgs() []IDorPkgInput { return v.Pkgs } // GetPkgMatchType returns __IngestCertifyGoodPkgsInput.PkgMatchType, and is useful for accessing the field via an interface. func (v *__IngestCertifyGoodPkgsInput) GetPkgMatchType() MatchFlags { return v.PkgMatchType } @@ -22505,24 +22627,24 @@ func (v *__IngestCertifyGoodPkgsInput) GetCertifyGoods() []CertifyGoodInputSpec // __IngestCertifyGoodSrcInput is used internally by genqlient type __IngestCertifyGoodSrcInput struct { - Source SourceInputSpec `json:"source"` + Source IDorSourceInput `json:"source"` CertifyGood CertifyGoodInputSpec `json:"certifyGood"` } // GetSource returns __IngestCertifyGoodSrcInput.Source, and is useful for accessing the field via an interface. -func (v *__IngestCertifyGoodSrcInput) GetSource() SourceInputSpec { return v.Source } +func (v *__IngestCertifyGoodSrcInput) GetSource() IDorSourceInput { return v.Source } // GetCertifyGood returns __IngestCertifyGoodSrcInput.CertifyGood, and is useful for accessing the field via an interface. func (v *__IngestCertifyGoodSrcInput) GetCertifyGood() CertifyGoodInputSpec { return v.CertifyGood } // __IngestCertifyGoodSrcsInput is used internally by genqlient type __IngestCertifyGoodSrcsInput struct { - Sources []SourceInputSpec `json:"sources"` + Sources []IDorSourceInput `json:"sources"` CertifyGoods []CertifyGoodInputSpec `json:"certifyGoods"` } // GetSources returns __IngestCertifyGoodSrcsInput.Sources, and is useful for accessing the field via an interface. -func (v *__IngestCertifyGoodSrcsInput) GetSources() []SourceInputSpec { return v.Sources } +func (v *__IngestCertifyGoodSrcsInput) GetSources() []IDorSourceInput { return v.Sources } // GetCertifyGoods returns __IngestCertifyGoodSrcsInput.CertifyGoods, and is useful for accessing the field via an interface. func (v *__IngestCertifyGoodSrcsInput) GetCertifyGoods() []CertifyGoodInputSpec { @@ -22531,22 +22653,22 @@ func (v *__IngestCertifyGoodSrcsInput) GetCertifyGoods() []CertifyGoodInputSpec // __IngestCertifyLegalPkgInput is used internally by genqlient type __IngestCertifyLegalPkgInput struct { - Pkg PkgInputSpec `json:"pkg"` - DeclaredLicenses []LicenseInputSpec `json:"declaredLicenses"` - DiscoveredLicenses []LicenseInputSpec `json:"discoveredLicenses"` + Pkg IDorPkgInput `json:"pkg"` + DeclaredLicenses []IDorLicenseInput `json:"declaredLicenses"` + DiscoveredLicenses []IDorLicenseInput `json:"discoveredLicenses"` Legal CertifyLegalInputSpec `json:"legal"` } // GetPkg returns __IngestCertifyLegalPkgInput.Pkg, and is useful for accessing the field via an interface. -func (v *__IngestCertifyLegalPkgInput) GetPkg() PkgInputSpec { return v.Pkg } +func (v *__IngestCertifyLegalPkgInput) GetPkg() IDorPkgInput { return v.Pkg } // GetDeclaredLicenses returns __IngestCertifyLegalPkgInput.DeclaredLicenses, and is useful for accessing the field via an interface. -func (v *__IngestCertifyLegalPkgInput) GetDeclaredLicenses() []LicenseInputSpec { +func (v *__IngestCertifyLegalPkgInput) GetDeclaredLicenses() []IDorLicenseInput { return v.DeclaredLicenses } // GetDiscoveredLicenses returns __IngestCertifyLegalPkgInput.DiscoveredLicenses, and is useful for accessing the field via an interface. -func (v *__IngestCertifyLegalPkgInput) GetDiscoveredLicenses() []LicenseInputSpec { +func (v *__IngestCertifyLegalPkgInput) GetDiscoveredLicenses() []IDorLicenseInput { return v.DiscoveredLicenses } @@ -22555,22 +22677,22 @@ func (v *__IngestCertifyLegalPkgInput) GetLegal() CertifyLegalInputSpec { return // __IngestCertifyLegalPkgsInput is used internally by genqlient type __IngestCertifyLegalPkgsInput struct { - Pkgs []PkgInputSpec `json:"pkgs"` - DeclaredLicensesList [][]LicenseInputSpec `json:"declaredLicensesList"` - DiscoveredLicensesList [][]LicenseInputSpec `json:"discoveredLicensesList"` + Pkgs []IDorPkgInput `json:"pkgs"` + DeclaredLicensesList [][]IDorLicenseInput `json:"declaredLicensesList"` + DiscoveredLicensesList [][]IDorLicenseInput `json:"discoveredLicensesList"` Legals []CertifyLegalInputSpec `json:"legals"` } // GetPkgs returns __IngestCertifyLegalPkgsInput.Pkgs, and is useful for accessing the field via an interface. -func (v *__IngestCertifyLegalPkgsInput) GetPkgs() []PkgInputSpec { return v.Pkgs } +func (v *__IngestCertifyLegalPkgsInput) GetPkgs() []IDorPkgInput { return v.Pkgs } // GetDeclaredLicensesList returns __IngestCertifyLegalPkgsInput.DeclaredLicensesList, and is useful for accessing the field via an interface. -func (v *__IngestCertifyLegalPkgsInput) GetDeclaredLicensesList() [][]LicenseInputSpec { +func (v *__IngestCertifyLegalPkgsInput) GetDeclaredLicensesList() [][]IDorLicenseInput { return v.DeclaredLicensesList } // GetDiscoveredLicensesList returns __IngestCertifyLegalPkgsInput.DiscoveredLicensesList, and is useful for accessing the field via an interface. -func (v *__IngestCertifyLegalPkgsInput) GetDiscoveredLicensesList() [][]LicenseInputSpec { +func (v *__IngestCertifyLegalPkgsInput) GetDiscoveredLicensesList() [][]IDorLicenseInput { return v.DiscoveredLicensesList } @@ -22579,22 +22701,22 @@ func (v *__IngestCertifyLegalPkgsInput) GetLegals() []CertifyLegalInputSpec { re // __IngestCertifyLegalSrcInput is used internally by genqlient type __IngestCertifyLegalSrcInput struct { - Src SourceInputSpec `json:"src"` - DeclaredLicenses []LicenseInputSpec `json:"declaredLicenses"` - DiscoveredLicenses []LicenseInputSpec `json:"discoveredLicenses"` + Src IDorSourceInput `json:"src"` + DeclaredLicenses []IDorLicenseInput `json:"declaredLicenses"` + DiscoveredLicenses []IDorLicenseInput `json:"discoveredLicenses"` Legal CertifyLegalInputSpec `json:"legal"` } // GetSrc returns __IngestCertifyLegalSrcInput.Src, and is useful for accessing the field via an interface. -func (v *__IngestCertifyLegalSrcInput) GetSrc() SourceInputSpec { return v.Src } +func (v *__IngestCertifyLegalSrcInput) GetSrc() IDorSourceInput { return v.Src } // GetDeclaredLicenses returns __IngestCertifyLegalSrcInput.DeclaredLicenses, and is useful for accessing the field via an interface. -func (v *__IngestCertifyLegalSrcInput) GetDeclaredLicenses() []LicenseInputSpec { +func (v *__IngestCertifyLegalSrcInput) GetDeclaredLicenses() []IDorLicenseInput { return v.DeclaredLicenses } // GetDiscoveredLicenses returns __IngestCertifyLegalSrcInput.DiscoveredLicenses, and is useful for accessing the field via an interface. -func (v *__IngestCertifyLegalSrcInput) GetDiscoveredLicenses() []LicenseInputSpec { +func (v *__IngestCertifyLegalSrcInput) GetDiscoveredLicenses() []IDorLicenseInput { return v.DiscoveredLicenses } @@ -22603,22 +22725,22 @@ func (v *__IngestCertifyLegalSrcInput) GetLegal() CertifyLegalInputSpec { return // __IngestCertifyLegalSrcsInput is used internally by genqlient type __IngestCertifyLegalSrcsInput struct { - Srcs []SourceInputSpec `json:"srcs"` - DeclaredLicensesList [][]LicenseInputSpec `json:"declaredLicensesList"` - DiscoveredLicensesList [][]LicenseInputSpec `json:"discoveredLicensesList"` + Srcs []IDorSourceInput `json:"srcs"` + DeclaredLicensesList [][]IDorLicenseInput `json:"declaredLicensesList"` + DiscoveredLicensesList [][]IDorLicenseInput `json:"discoveredLicensesList"` Legals []CertifyLegalInputSpec `json:"legals"` } // GetSrcs returns __IngestCertifyLegalSrcsInput.Srcs, and is useful for accessing the field via an interface. -func (v *__IngestCertifyLegalSrcsInput) GetSrcs() []SourceInputSpec { return v.Srcs } +func (v *__IngestCertifyLegalSrcsInput) GetSrcs() []IDorSourceInput { return v.Srcs } // GetDeclaredLicensesList returns __IngestCertifyLegalSrcsInput.DeclaredLicensesList, and is useful for accessing the field via an interface. -func (v *__IngestCertifyLegalSrcsInput) GetDeclaredLicensesList() [][]LicenseInputSpec { +func (v *__IngestCertifyLegalSrcsInput) GetDeclaredLicensesList() [][]IDorLicenseInput { return v.DeclaredLicensesList } // GetDiscoveredLicensesList returns __IngestCertifyLegalSrcsInput.DiscoveredLicensesList, and is useful for accessing the field via an interface. -func (v *__IngestCertifyLegalSrcsInput) GetDiscoveredLicensesList() [][]LicenseInputSpec { +func (v *__IngestCertifyLegalSrcsInput) GetDiscoveredLicensesList() [][]IDorLicenseInput { return v.DiscoveredLicensesList } @@ -22627,40 +22749,40 @@ func (v *__IngestCertifyLegalSrcsInput) GetLegals() []CertifyLegalInputSpec { re // __IngestCertifyScorecardInput is used internally by genqlient type __IngestCertifyScorecardInput struct { - Source SourceInputSpec `json:"source"` + Source IDorSourceInput `json:"source"` Scorecard ScorecardInputSpec `json:"scorecard"` } // GetSource returns __IngestCertifyScorecardInput.Source, and is useful for accessing the field via an interface. -func (v *__IngestCertifyScorecardInput) GetSource() SourceInputSpec { return v.Source } +func (v *__IngestCertifyScorecardInput) GetSource() IDorSourceInput { return v.Source } // GetScorecard returns __IngestCertifyScorecardInput.Scorecard, and is useful for accessing the field via an interface. func (v *__IngestCertifyScorecardInput) GetScorecard() ScorecardInputSpec { return v.Scorecard } // __IngestCertifyScorecardsInput is used internally by genqlient type __IngestCertifyScorecardsInput struct { - Sources []SourceInputSpec `json:"sources"` + Sources []IDorSourceInput `json:"sources"` Scorecards []ScorecardInputSpec `json:"scorecards"` } // GetSources returns __IngestCertifyScorecardsInput.Sources, and is useful for accessing the field via an interface. -func (v *__IngestCertifyScorecardsInput) GetSources() []SourceInputSpec { return v.Sources } +func (v *__IngestCertifyScorecardsInput) GetSources() []IDorSourceInput { return v.Sources } // GetScorecards returns __IngestCertifyScorecardsInput.Scorecards, and is useful for accessing the field via an interface. func (v *__IngestCertifyScorecardsInput) GetScorecards() []ScorecardInputSpec { return v.Scorecards } // __IngestCertifyVexArtifactInput is used internally by genqlient type __IngestCertifyVexArtifactInput struct { - Artifact ArtifactInputSpec `json:"artifact"` - Vulnerability VulnerabilityInputSpec `json:"vulnerability"` + Artifact IDorArtifactInput `json:"artifact"` + Vulnerability IDorVulnerabilityInput `json:"vulnerability"` VexStatement VexStatementInputSpec `json:"vexStatement"` } // GetArtifact returns __IngestCertifyVexArtifactInput.Artifact, and is useful for accessing the field via an interface. -func (v *__IngestCertifyVexArtifactInput) GetArtifact() ArtifactInputSpec { return v.Artifact } +func (v *__IngestCertifyVexArtifactInput) GetArtifact() IDorArtifactInput { return v.Artifact } // GetVulnerability returns __IngestCertifyVexArtifactInput.Vulnerability, and is useful for accessing the field via an interface. -func (v *__IngestCertifyVexArtifactInput) GetVulnerability() VulnerabilityInputSpec { +func (v *__IngestCertifyVexArtifactInput) GetVulnerability() IDorVulnerabilityInput { return v.Vulnerability } @@ -22671,16 +22793,16 @@ func (v *__IngestCertifyVexArtifactInput) GetVexStatement() VexStatementInputSpe // __IngestCertifyVexArtifactsInput is used internally by genqlient type __IngestCertifyVexArtifactsInput struct { - Artifacts []ArtifactInputSpec `json:"artifacts"` - Vulnerabilities []VulnerabilityInputSpec `json:"vulnerabilities"` + Artifacts []IDorArtifactInput `json:"artifacts"` + Vulnerabilities []IDorVulnerabilityInput `json:"vulnerabilities"` VexStatements []VexStatementInputSpec `json:"vexStatements"` } // GetArtifacts returns __IngestCertifyVexArtifactsInput.Artifacts, and is useful for accessing the field via an interface. -func (v *__IngestCertifyVexArtifactsInput) GetArtifacts() []ArtifactInputSpec { return v.Artifacts } +func (v *__IngestCertifyVexArtifactsInput) GetArtifacts() []IDorArtifactInput { return v.Artifacts } // GetVulnerabilities returns __IngestCertifyVexArtifactsInput.Vulnerabilities, and is useful for accessing the field via an interface. -func (v *__IngestCertifyVexArtifactsInput) GetVulnerabilities() []VulnerabilityInputSpec { +func (v *__IngestCertifyVexArtifactsInput) GetVulnerabilities() []IDorVulnerabilityInput { return v.Vulnerabilities } @@ -22691,16 +22813,16 @@ func (v *__IngestCertifyVexArtifactsInput) GetVexStatements() []VexStatementInpu // __IngestCertifyVexPkgInput is used internally by genqlient type __IngestCertifyVexPkgInput struct { - Pkg PkgInputSpec `json:"pkg"` - Vulnerability VulnerabilityInputSpec `json:"vulnerability"` + Pkg IDorPkgInput `json:"pkg"` + Vulnerability IDorVulnerabilityInput `json:"vulnerability"` VexStatement VexStatementInputSpec `json:"vexStatement"` } // GetPkg returns __IngestCertifyVexPkgInput.Pkg, and is useful for accessing the field via an interface. -func (v *__IngestCertifyVexPkgInput) GetPkg() PkgInputSpec { return v.Pkg } +func (v *__IngestCertifyVexPkgInput) GetPkg() IDorPkgInput { return v.Pkg } // GetVulnerability returns __IngestCertifyVexPkgInput.Vulnerability, and is useful for accessing the field via an interface. -func (v *__IngestCertifyVexPkgInput) GetVulnerability() VulnerabilityInputSpec { +func (v *__IngestCertifyVexPkgInput) GetVulnerability() IDorVulnerabilityInput { return v.Vulnerability } @@ -22709,16 +22831,16 @@ func (v *__IngestCertifyVexPkgInput) GetVexStatement() VexStatementInputSpec { r // __IngestCertifyVexPkgsInput is used internally by genqlient type __IngestCertifyVexPkgsInput struct { - Pkgs []PkgInputSpec `json:"pkgs"` - Vulnerabilities []VulnerabilityInputSpec `json:"vulnerabilities"` + Pkgs []IDorPkgInput `json:"pkgs"` + Vulnerabilities []IDorVulnerabilityInput `json:"vulnerabilities"` VexStatements []VexStatementInputSpec `json:"vexStatements"` } // GetPkgs returns __IngestCertifyVexPkgsInput.Pkgs, and is useful for accessing the field via an interface. -func (v *__IngestCertifyVexPkgsInput) GetPkgs() []PkgInputSpec { return v.Pkgs } +func (v *__IngestCertifyVexPkgsInput) GetPkgs() []IDorPkgInput { return v.Pkgs } // GetVulnerabilities returns __IngestCertifyVexPkgsInput.Vulnerabilities, and is useful for accessing the field via an interface. -func (v *__IngestCertifyVexPkgsInput) GetVulnerabilities() []VulnerabilityInputSpec { +func (v *__IngestCertifyVexPkgsInput) GetVulnerabilities() []IDorVulnerabilityInput { return v.Vulnerabilities } @@ -22729,16 +22851,16 @@ func (v *__IngestCertifyVexPkgsInput) GetVexStatements() []VexStatementInputSpec // __IngestCertifyVulnPkgInput is used internally by genqlient type __IngestCertifyVulnPkgInput struct { - Pkg PkgInputSpec `json:"pkg"` - Vulnerability VulnerabilityInputSpec `json:"vulnerability"` + Pkg IDorPkgInput `json:"pkg"` + Vulnerability IDorVulnerabilityInput `json:"vulnerability"` CertifyVuln ScanMetadataInput `json:"certifyVuln"` } // GetPkg returns __IngestCertifyVulnPkgInput.Pkg, and is useful for accessing the field via an interface. -func (v *__IngestCertifyVulnPkgInput) GetPkg() PkgInputSpec { return v.Pkg } +func (v *__IngestCertifyVulnPkgInput) GetPkg() IDorPkgInput { return v.Pkg } // GetVulnerability returns __IngestCertifyVulnPkgInput.Vulnerability, and is useful for accessing the field via an interface. -func (v *__IngestCertifyVulnPkgInput) GetVulnerability() VulnerabilityInputSpec { +func (v *__IngestCertifyVulnPkgInput) GetVulnerability() IDorVulnerabilityInput { return v.Vulnerability } @@ -22747,16 +22869,16 @@ func (v *__IngestCertifyVulnPkgInput) GetCertifyVuln() ScanMetadataInput { retur // __IngestCertifyVulnPkgsInput is used internally by genqlient type __IngestCertifyVulnPkgsInput struct { - Pkgs []PkgInputSpec `json:"pkgs"` - Vulnerabilities []VulnerabilityInputSpec `json:"vulnerabilities"` + Pkgs []IDorPkgInput `json:"pkgs"` + Vulnerabilities []IDorVulnerabilityInput `json:"vulnerabilities"` CertifyVulns []ScanMetadataInput `json:"certifyVulns"` } // GetPkgs returns __IngestCertifyVulnPkgsInput.Pkgs, and is useful for accessing the field via an interface. -func (v *__IngestCertifyVulnPkgsInput) GetPkgs() []PkgInputSpec { return v.Pkgs } +func (v *__IngestCertifyVulnPkgsInput) GetPkgs() []IDorPkgInput { return v.Pkgs } // GetVulnerabilities returns __IngestCertifyVulnPkgsInput.Vulnerabilities, and is useful for accessing the field via an interface. -func (v *__IngestCertifyVulnPkgsInput) GetVulnerabilities() []VulnerabilityInputSpec { +func (v *__IngestCertifyVulnPkgsInput) GetVulnerabilities() []IDorVulnerabilityInput { return v.Vulnerabilities } @@ -22765,12 +22887,12 @@ func (v *__IngestCertifyVulnPkgsInput) GetCertifyVulns() []ScanMetadataInput { r // __IngestHasMetadataArtifactInput is used internally by genqlient type __IngestHasMetadataArtifactInput struct { - Artifact ArtifactInputSpec `json:"artifact"` + Artifact IDorArtifactInput `json:"artifact"` HasMetadata HasMetadataInputSpec `json:"hasMetadata"` } // GetArtifact returns __IngestHasMetadataArtifactInput.Artifact, and is useful for accessing the field via an interface. -func (v *__IngestHasMetadataArtifactInput) GetArtifact() ArtifactInputSpec { return v.Artifact } +func (v *__IngestHasMetadataArtifactInput) GetArtifact() IDorArtifactInput { return v.Artifact } // GetHasMetadata returns __IngestHasMetadataArtifactInput.HasMetadata, and is useful for accessing the field via an interface. func (v *__IngestHasMetadataArtifactInput) GetHasMetadata() HasMetadataInputSpec { @@ -22779,12 +22901,12 @@ func (v *__IngestHasMetadataArtifactInput) GetHasMetadata() HasMetadataInputSpec // __IngestHasMetadataArtifactsInput is used internally by genqlient type __IngestHasMetadataArtifactsInput struct { - Artifacts []ArtifactInputSpec `json:"artifacts"` + Artifacts []IDorArtifactInput `json:"artifacts"` HasMetadataList []HasMetadataInputSpec `json:"hasMetadataList"` } // GetArtifacts returns __IngestHasMetadataArtifactsInput.Artifacts, and is useful for accessing the field via an interface. -func (v *__IngestHasMetadataArtifactsInput) GetArtifacts() []ArtifactInputSpec { return v.Artifacts } +func (v *__IngestHasMetadataArtifactsInput) GetArtifacts() []IDorArtifactInput { return v.Artifacts } // GetHasMetadataList returns __IngestHasMetadataArtifactsInput.HasMetadataList, and is useful for accessing the field via an interface. func (v *__IngestHasMetadataArtifactsInput) GetHasMetadataList() []HasMetadataInputSpec { @@ -22793,13 +22915,13 @@ func (v *__IngestHasMetadataArtifactsInput) GetHasMetadataList() []HasMetadataIn // __IngestHasMetadataPkgInput is used internally by genqlient type __IngestHasMetadataPkgInput struct { - Pkg PkgInputSpec `json:"pkg"` + Pkg IDorPkgInput `json:"pkg"` PkgMatchType MatchFlags `json:"pkgMatchType"` HasMetadata HasMetadataInputSpec `json:"hasMetadata"` } // GetPkg returns __IngestHasMetadataPkgInput.Pkg, and is useful for accessing the field via an interface. -func (v *__IngestHasMetadataPkgInput) GetPkg() PkgInputSpec { return v.Pkg } +func (v *__IngestHasMetadataPkgInput) GetPkg() IDorPkgInput { return v.Pkg } // GetPkgMatchType returns __IngestHasMetadataPkgInput.PkgMatchType, and is useful for accessing the field via an interface. func (v *__IngestHasMetadataPkgInput) GetPkgMatchType() MatchFlags { return v.PkgMatchType } @@ -22809,13 +22931,13 @@ func (v *__IngestHasMetadataPkgInput) GetHasMetadata() HasMetadataInputSpec { re // __IngestHasMetadataPkgsInput is used internally by genqlient type __IngestHasMetadataPkgsInput struct { - Pkgs []PkgInputSpec `json:"pkgs"` + Pkgs []IDorPkgInput `json:"pkgs"` PkgMatchType MatchFlags `json:"pkgMatchType"` HasMetadataList []HasMetadataInputSpec `json:"hasMetadataList"` } // GetPkgs returns __IngestHasMetadataPkgsInput.Pkgs, and is useful for accessing the field via an interface. -func (v *__IngestHasMetadataPkgsInput) GetPkgs() []PkgInputSpec { return v.Pkgs } +func (v *__IngestHasMetadataPkgsInput) GetPkgs() []IDorPkgInput { return v.Pkgs } // GetPkgMatchType returns __IngestHasMetadataPkgsInput.PkgMatchType, and is useful for accessing the field via an interface. func (v *__IngestHasMetadataPkgsInput) GetPkgMatchType() MatchFlags { return v.PkgMatchType } @@ -22827,24 +22949,24 @@ func (v *__IngestHasMetadataPkgsInput) GetHasMetadataList() []HasMetadataInputSp // __IngestHasMetadataSrcInput is used internally by genqlient type __IngestHasMetadataSrcInput struct { - Source SourceInputSpec `json:"source"` + Source IDorSourceInput `json:"source"` HasMetadata HasMetadataInputSpec `json:"hasMetadata"` } // GetSource returns __IngestHasMetadataSrcInput.Source, and is useful for accessing the field via an interface. -func (v *__IngestHasMetadataSrcInput) GetSource() SourceInputSpec { return v.Source } +func (v *__IngestHasMetadataSrcInput) GetSource() IDorSourceInput { return v.Source } // GetHasMetadata returns __IngestHasMetadataSrcInput.HasMetadata, and is useful for accessing the field via an interface. func (v *__IngestHasMetadataSrcInput) GetHasMetadata() HasMetadataInputSpec { return v.HasMetadata } // __IngestHasMetadataSrcsInput is used internally by genqlient type __IngestHasMetadataSrcsInput struct { - Sources []SourceInputSpec `json:"sources"` + Sources []IDorSourceInput `json:"sources"` HasMetadataList []HasMetadataInputSpec `json:"hasMetadataList"` } // GetSources returns __IngestHasMetadataSrcsInput.Sources, and is useful for accessing the field via an interface. -func (v *__IngestHasMetadataSrcsInput) GetSources() []SourceInputSpec { return v.Sources } +func (v *__IngestHasMetadataSrcsInput) GetSources() []IDorSourceInput { return v.Sources } // GetHasMetadataList returns __IngestHasMetadataSrcsInput.HasMetadataList, and is useful for accessing the field via an interface. func (v *__IngestHasMetadataSrcsInput) GetHasMetadataList() []HasMetadataInputSpec { @@ -22853,13 +22975,13 @@ func (v *__IngestHasMetadataSrcsInput) GetHasMetadataList() []HasMetadataInputSp // __IngestHasSBOMArtifactInput is used internally by genqlient type __IngestHasSBOMArtifactInput struct { - Artifact ArtifactInputSpec `json:"artifact"` + Artifact IDorArtifactInput `json:"artifact"` HasSBOM HasSBOMInputSpec `json:"hasSBOM"` Includes HasSBOMIncludesInputSpec `json:"includes"` } // GetArtifact returns __IngestHasSBOMArtifactInput.Artifact, and is useful for accessing the field via an interface. -func (v *__IngestHasSBOMArtifactInput) GetArtifact() ArtifactInputSpec { return v.Artifact } +func (v *__IngestHasSBOMArtifactInput) GetArtifact() IDorArtifactInput { return v.Artifact } // GetHasSBOM returns __IngestHasSBOMArtifactInput.HasSBOM, and is useful for accessing the field via an interface. func (v *__IngestHasSBOMArtifactInput) GetHasSBOM() HasSBOMInputSpec { return v.HasSBOM } @@ -22869,13 +22991,13 @@ func (v *__IngestHasSBOMArtifactInput) GetIncludes() HasSBOMIncludesInputSpec { // __IngestHasSBOMArtifactsInput is used internally by genqlient type __IngestHasSBOMArtifactsInput struct { - Artifacts []ArtifactInputSpec `json:"artifacts"` + Artifacts []IDorArtifactInput `json:"artifacts"` HasSBOMs []HasSBOMInputSpec `json:"hasSBOMs"` Includes []HasSBOMIncludesInputSpec `json:"includes"` } // GetArtifacts returns __IngestHasSBOMArtifactsInput.Artifacts, and is useful for accessing the field via an interface. -func (v *__IngestHasSBOMArtifactsInput) GetArtifacts() []ArtifactInputSpec { return v.Artifacts } +func (v *__IngestHasSBOMArtifactsInput) GetArtifacts() []IDorArtifactInput { return v.Artifacts } // GetHasSBOMs returns __IngestHasSBOMArtifactsInput.HasSBOMs, and is useful for accessing the field via an interface. func (v *__IngestHasSBOMArtifactsInput) GetHasSBOMs() []HasSBOMInputSpec { return v.HasSBOMs } @@ -22885,13 +23007,13 @@ func (v *__IngestHasSBOMArtifactsInput) GetIncludes() []HasSBOMIncludesInputSpec // __IngestHasSBOMPkgInput is used internally by genqlient type __IngestHasSBOMPkgInput struct { - Pkg PkgInputSpec `json:"pkg"` + Pkg IDorPkgInput `json:"pkg"` HasSBOM HasSBOMInputSpec `json:"hasSBOM"` Includes HasSBOMIncludesInputSpec `json:"includes"` } // GetPkg returns __IngestHasSBOMPkgInput.Pkg, and is useful for accessing the field via an interface. -func (v *__IngestHasSBOMPkgInput) GetPkg() PkgInputSpec { return v.Pkg } +func (v *__IngestHasSBOMPkgInput) GetPkg() IDorPkgInput { return v.Pkg } // GetHasSBOM returns __IngestHasSBOMPkgInput.HasSBOM, and is useful for accessing the field via an interface. func (v *__IngestHasSBOMPkgInput) GetHasSBOM() HasSBOMInputSpec { return v.HasSBOM } @@ -22901,13 +23023,13 @@ func (v *__IngestHasSBOMPkgInput) GetIncludes() HasSBOMIncludesInputSpec { retur // __IngestHasSBOMPkgsInput is used internally by genqlient type __IngestHasSBOMPkgsInput struct { - Pkgs []PkgInputSpec `json:"pkgs"` + Pkgs []IDorPkgInput `json:"pkgs"` HasSBOMs []HasSBOMInputSpec `json:"hasSBOMs"` Includes []HasSBOMIncludesInputSpec `json:"includes"` } // GetPkgs returns __IngestHasSBOMPkgsInput.Pkgs, and is useful for accessing the field via an interface. -func (v *__IngestHasSBOMPkgsInput) GetPkgs() []PkgInputSpec { return v.Pkgs } +func (v *__IngestHasSBOMPkgsInput) GetPkgs() []IDorPkgInput { return v.Pkgs } // GetHasSBOMs returns __IngestHasSBOMPkgsInput.HasSBOMs, and is useful for accessing the field via an interface. func (v *__IngestHasSBOMPkgsInput) GetHasSBOMs() []HasSBOMInputSpec { return v.HasSBOMs } @@ -22917,89 +23039,89 @@ func (v *__IngestHasSBOMPkgsInput) GetIncludes() []HasSBOMIncludesInputSpec { re // __IngestHasSourceAtInput is used internally by genqlient type __IngestHasSourceAtInput struct { - Pkg PkgInputSpec `json:"pkg"` + Pkg IDorPkgInput `json:"pkg"` PkgMatchType MatchFlags `json:"pkgMatchType"` - Source SourceInputSpec `json:"source"` + Source IDorSourceInput `json:"source"` HasSourceAt HasSourceAtInputSpec `json:"hasSourceAt"` } // GetPkg returns __IngestHasSourceAtInput.Pkg, and is useful for accessing the field via an interface. -func (v *__IngestHasSourceAtInput) GetPkg() PkgInputSpec { return v.Pkg } +func (v *__IngestHasSourceAtInput) GetPkg() IDorPkgInput { return v.Pkg } // GetPkgMatchType returns __IngestHasSourceAtInput.PkgMatchType, and is useful for accessing the field via an interface. func (v *__IngestHasSourceAtInput) GetPkgMatchType() MatchFlags { return v.PkgMatchType } // GetSource returns __IngestHasSourceAtInput.Source, and is useful for accessing the field via an interface. -func (v *__IngestHasSourceAtInput) GetSource() SourceInputSpec { return v.Source } +func (v *__IngestHasSourceAtInput) GetSource() IDorSourceInput { return v.Source } // GetHasSourceAt returns __IngestHasSourceAtInput.HasSourceAt, and is useful for accessing the field via an interface. func (v *__IngestHasSourceAtInput) GetHasSourceAt() HasSourceAtInputSpec { return v.HasSourceAt } // __IngestHasSourcesAtInput is used internally by genqlient type __IngestHasSourcesAtInput struct { - Pkgs []PkgInputSpec `json:"pkgs"` + Pkgs []IDorPkgInput `json:"pkgs"` PkgMatchType MatchFlags `json:"pkgMatchType"` - Sources []SourceInputSpec `json:"sources"` + Sources []IDorSourceInput `json:"sources"` HasSourceAts []HasSourceAtInputSpec `json:"hasSourceAts"` } // GetPkgs returns __IngestHasSourcesAtInput.Pkgs, and is useful for accessing the field via an interface. -func (v *__IngestHasSourcesAtInput) GetPkgs() []PkgInputSpec { return v.Pkgs } +func (v *__IngestHasSourcesAtInput) GetPkgs() []IDorPkgInput { return v.Pkgs } // GetPkgMatchType returns __IngestHasSourcesAtInput.PkgMatchType, and is useful for accessing the field via an interface. func (v *__IngestHasSourcesAtInput) GetPkgMatchType() MatchFlags { return v.PkgMatchType } // GetSources returns __IngestHasSourcesAtInput.Sources, and is useful for accessing the field via an interface. -func (v *__IngestHasSourcesAtInput) GetSources() []SourceInputSpec { return v.Sources } +func (v *__IngestHasSourcesAtInput) GetSources() []IDorSourceInput { return v.Sources } // GetHasSourceAts returns __IngestHasSourcesAtInput.HasSourceAts, and is useful for accessing the field via an interface. func (v *__IngestHasSourcesAtInput) GetHasSourceAts() []HasSourceAtInputSpec { return v.HasSourceAts } // __IngestHashEqualInput is used internally by genqlient type __IngestHashEqualInput struct { - Artifact ArtifactInputSpec `json:"artifact"` - OtherArtifact ArtifactInputSpec `json:"otherArtifact"` + Artifact IDorArtifactInput `json:"artifact"` + OtherArtifact IDorArtifactInput `json:"otherArtifact"` HashEqual HashEqualInputSpec `json:"hashEqual"` } // GetArtifact returns __IngestHashEqualInput.Artifact, and is useful for accessing the field via an interface. -func (v *__IngestHashEqualInput) GetArtifact() ArtifactInputSpec { return v.Artifact } +func (v *__IngestHashEqualInput) GetArtifact() IDorArtifactInput { return v.Artifact } // GetOtherArtifact returns __IngestHashEqualInput.OtherArtifact, and is useful for accessing the field via an interface. -func (v *__IngestHashEqualInput) GetOtherArtifact() ArtifactInputSpec { return v.OtherArtifact } +func (v *__IngestHashEqualInput) GetOtherArtifact() IDorArtifactInput { return v.OtherArtifact } // GetHashEqual returns __IngestHashEqualInput.HashEqual, and is useful for accessing the field via an interface. func (v *__IngestHashEqualInput) GetHashEqual() HashEqualInputSpec { return v.HashEqual } // __IngestHashEqualsInput is used internally by genqlient type __IngestHashEqualsInput struct { - Artifacts []ArtifactInputSpec `json:"artifacts"` - OtherArtifacts []ArtifactInputSpec `json:"otherArtifacts"` + Artifacts []IDorArtifactInput `json:"artifacts"` + OtherArtifacts []IDorArtifactInput `json:"otherArtifacts"` HashEquals []HashEqualInputSpec `json:"hashEquals"` } // GetArtifacts returns __IngestHashEqualsInput.Artifacts, and is useful for accessing the field via an interface. -func (v *__IngestHashEqualsInput) GetArtifacts() []ArtifactInputSpec { return v.Artifacts } +func (v *__IngestHashEqualsInput) GetArtifacts() []IDorArtifactInput { return v.Artifacts } // GetOtherArtifacts returns __IngestHashEqualsInput.OtherArtifacts, and is useful for accessing the field via an interface. -func (v *__IngestHashEqualsInput) GetOtherArtifacts() []ArtifactInputSpec { return v.OtherArtifacts } +func (v *__IngestHashEqualsInput) GetOtherArtifacts() []IDorArtifactInput { return v.OtherArtifacts } // GetHashEquals returns __IngestHashEqualsInput.HashEquals, and is useful for accessing the field via an interface. func (v *__IngestHashEqualsInput) GetHashEquals() []HashEqualInputSpec { return v.HashEquals } // __IngestIsDependenciesInput is used internally by genqlient type __IngestIsDependenciesInput struct { - Pkgs []PkgInputSpec `json:"pkgs"` - DepPkgs []PkgInputSpec `json:"depPkgs"` + Pkgs []IDorPkgInput `json:"pkgs"` + DepPkgs []IDorPkgInput `json:"depPkgs"` DepPkgMatchType MatchFlags `json:"depPkgMatchType"` Dependencies []IsDependencyInputSpec `json:"dependencies"` } // GetPkgs returns __IngestIsDependenciesInput.Pkgs, and is useful for accessing the field via an interface. -func (v *__IngestIsDependenciesInput) GetPkgs() []PkgInputSpec { return v.Pkgs } +func (v *__IngestIsDependenciesInput) GetPkgs() []IDorPkgInput { return v.Pkgs } // GetDepPkgs returns __IngestIsDependenciesInput.DepPkgs, and is useful for accessing the field via an interface. -func (v *__IngestIsDependenciesInput) GetDepPkgs() []PkgInputSpec { return v.DepPkgs } +func (v *__IngestIsDependenciesInput) GetDepPkgs() []IDorPkgInput { return v.DepPkgs } // GetDepPkgMatchType returns __IngestIsDependenciesInput.DepPkgMatchType, and is useful for accessing the field via an interface. func (v *__IngestIsDependenciesInput) GetDepPkgMatchType() MatchFlags { return v.DepPkgMatchType } @@ -23011,17 +23133,17 @@ func (v *__IngestIsDependenciesInput) GetDependencies() []IsDependencyInputSpec // __IngestIsDependencyInput is used internally by genqlient type __IngestIsDependencyInput struct { - Pkg PkgInputSpec `json:"pkg"` - DepPkg PkgInputSpec `json:"depPkg"` + Pkg IDorPkgInput `json:"pkg"` + DepPkg IDorPkgInput `json:"depPkg"` DepPkgMatchType MatchFlags `json:"depPkgMatchType"` Dependency IsDependencyInputSpec `json:"dependency"` } // GetPkg returns __IngestIsDependencyInput.Pkg, and is useful for accessing the field via an interface. -func (v *__IngestIsDependencyInput) GetPkg() PkgInputSpec { return v.Pkg } +func (v *__IngestIsDependencyInput) GetPkg() IDorPkgInput { return v.Pkg } // GetDepPkg returns __IngestIsDependencyInput.DepPkg, and is useful for accessing the field via an interface. -func (v *__IngestIsDependencyInput) GetDepPkg() PkgInputSpec { return v.DepPkg } +func (v *__IngestIsDependencyInput) GetDepPkg() IDorPkgInput { return v.DepPkg } // GetDepPkgMatchType returns __IngestIsDependencyInput.DepPkgMatchType, and is useful for accessing the field via an interface. func (v *__IngestIsDependencyInput) GetDepPkgMatchType() MatchFlags { return v.DepPkgMatchType } @@ -23031,48 +23153,48 @@ func (v *__IngestIsDependencyInput) GetDependency() IsDependencyInputSpec { retu // __IngestIsOccurrencePkgInput is used internally by genqlient type __IngestIsOccurrencePkgInput struct { - Pkg PkgInputSpec `json:"pkg"` - Artifact ArtifactInputSpec `json:"artifact"` + Pkg IDorPkgInput `json:"pkg"` + Artifact IDorArtifactInput `json:"artifact"` Occurrence IsOccurrenceInputSpec `json:"occurrence"` } // GetPkg returns __IngestIsOccurrencePkgInput.Pkg, and is useful for accessing the field via an interface. -func (v *__IngestIsOccurrencePkgInput) GetPkg() PkgInputSpec { return v.Pkg } +func (v *__IngestIsOccurrencePkgInput) GetPkg() IDorPkgInput { return v.Pkg } // GetArtifact returns __IngestIsOccurrencePkgInput.Artifact, and is useful for accessing the field via an interface. -func (v *__IngestIsOccurrencePkgInput) GetArtifact() ArtifactInputSpec { return v.Artifact } +func (v *__IngestIsOccurrencePkgInput) GetArtifact() IDorArtifactInput { return v.Artifact } // GetOccurrence returns __IngestIsOccurrencePkgInput.Occurrence, and is useful for accessing the field via an interface. func (v *__IngestIsOccurrencePkgInput) GetOccurrence() IsOccurrenceInputSpec { return v.Occurrence } // __IngestIsOccurrenceSrcInput is used internally by genqlient type __IngestIsOccurrenceSrcInput struct { - Source SourceInputSpec `json:"source"` - Artifact ArtifactInputSpec `json:"artifact"` + Source IDorSourceInput `json:"source"` + Artifact IDorArtifactInput `json:"artifact"` Occurrence IsOccurrenceInputSpec `json:"occurrence"` } // GetSource returns __IngestIsOccurrenceSrcInput.Source, and is useful for accessing the field via an interface. -func (v *__IngestIsOccurrenceSrcInput) GetSource() SourceInputSpec { return v.Source } +func (v *__IngestIsOccurrenceSrcInput) GetSource() IDorSourceInput { return v.Source } // GetArtifact returns __IngestIsOccurrenceSrcInput.Artifact, and is useful for accessing the field via an interface. -func (v *__IngestIsOccurrenceSrcInput) GetArtifact() ArtifactInputSpec { return v.Artifact } +func (v *__IngestIsOccurrenceSrcInput) GetArtifact() IDorArtifactInput { return v.Artifact } // GetOccurrence returns __IngestIsOccurrenceSrcInput.Occurrence, and is useful for accessing the field via an interface. func (v *__IngestIsOccurrenceSrcInput) GetOccurrence() IsOccurrenceInputSpec { return v.Occurrence } // __IngestIsOccurrencesPkgInput is used internally by genqlient type __IngestIsOccurrencesPkgInput struct { - Pkgs []PkgInputSpec `json:"pkgs"` - Artifacts []ArtifactInputSpec `json:"artifacts"` + Pkgs []IDorPkgInput `json:"pkgs"` + Artifacts []IDorArtifactInput `json:"artifacts"` Occurrences []IsOccurrenceInputSpec `json:"occurrences"` } // GetPkgs returns __IngestIsOccurrencesPkgInput.Pkgs, and is useful for accessing the field via an interface. -func (v *__IngestIsOccurrencesPkgInput) GetPkgs() []PkgInputSpec { return v.Pkgs } +func (v *__IngestIsOccurrencesPkgInput) GetPkgs() []IDorPkgInput { return v.Pkgs } // GetArtifacts returns __IngestIsOccurrencesPkgInput.Artifacts, and is useful for accessing the field via an interface. -func (v *__IngestIsOccurrencesPkgInput) GetArtifacts() []ArtifactInputSpec { return v.Artifacts } +func (v *__IngestIsOccurrencesPkgInput) GetArtifacts() []IDorArtifactInput { return v.Artifacts } // GetOccurrences returns __IngestIsOccurrencesPkgInput.Occurrences, and is useful for accessing the field via an interface. func (v *__IngestIsOccurrencesPkgInput) GetOccurrences() []IsOccurrenceInputSpec { @@ -23081,16 +23203,16 @@ func (v *__IngestIsOccurrencesPkgInput) GetOccurrences() []IsOccurrenceInputSpec // __IngestIsOccurrencesSrcInput is used internally by genqlient type __IngestIsOccurrencesSrcInput struct { - Sources []SourceInputSpec `json:"sources"` - Artifacts []ArtifactInputSpec `json:"artifacts"` + Sources []IDorSourceInput `json:"sources"` + Artifacts []IDorArtifactInput `json:"artifacts"` Occurrences []IsOccurrenceInputSpec `json:"occurrences"` } // GetSources returns __IngestIsOccurrencesSrcInput.Sources, and is useful for accessing the field via an interface. -func (v *__IngestIsOccurrencesSrcInput) GetSources() []SourceInputSpec { return v.Sources } +func (v *__IngestIsOccurrencesSrcInput) GetSources() []IDorSourceInput { return v.Sources } // GetArtifacts returns __IngestIsOccurrencesSrcInput.Artifacts, and is useful for accessing the field via an interface. -func (v *__IngestIsOccurrencesSrcInput) GetArtifacts() []ArtifactInputSpec { return v.Artifacts } +func (v *__IngestIsOccurrencesSrcInput) GetArtifacts() []IDorArtifactInput { return v.Artifacts } // GetOccurrences returns __IngestIsOccurrencesSrcInput.Occurrences, and is useful for accessing the field via an interface. func (v *__IngestIsOccurrencesSrcInput) GetOccurrences() []IsOccurrenceInputSpec { @@ -23099,76 +23221,76 @@ func (v *__IngestIsOccurrencesSrcInput) GetOccurrences() []IsOccurrenceInputSpec // __IngestLicenseInput is used internally by genqlient type __IngestLicenseInput struct { - License LicenseInputSpec `json:"license"` + License IDorLicenseInput `json:"license"` } // GetLicense returns __IngestLicenseInput.License, and is useful for accessing the field via an interface. -func (v *__IngestLicenseInput) GetLicense() LicenseInputSpec { return v.License } +func (v *__IngestLicenseInput) GetLicense() IDorLicenseInput { return v.License } // __IngestLicensesInput is used internally by genqlient type __IngestLicensesInput struct { - Licenses []LicenseInputSpec `json:"licenses"` + Licenses []IDorLicenseInput `json:"licenses"` } // GetLicenses returns __IngestLicensesInput.Licenses, and is useful for accessing the field via an interface. -func (v *__IngestLicensesInput) GetLicenses() []LicenseInputSpec { return v.Licenses } +func (v *__IngestLicensesInput) GetLicenses() []IDorLicenseInput { return v.Licenses } // __IngestPackageInput is used internally by genqlient type __IngestPackageInput struct { - Pkg PkgInputSpec `json:"pkg"` + Pkg IDorPkgInput `json:"pkg"` } // GetPkg returns __IngestPackageInput.Pkg, and is useful for accessing the field via an interface. -func (v *__IngestPackageInput) GetPkg() PkgInputSpec { return v.Pkg } +func (v *__IngestPackageInput) GetPkg() IDorPkgInput { return v.Pkg } // __IngestPackagesInput is used internally by genqlient type __IngestPackagesInput struct { - Pkgs []PkgInputSpec `json:"pkgs"` + Pkgs []IDorPkgInput `json:"pkgs"` } // GetPkgs returns __IngestPackagesInput.Pkgs, and is useful for accessing the field via an interface. -func (v *__IngestPackagesInput) GetPkgs() []PkgInputSpec { return v.Pkgs } +func (v *__IngestPackagesInput) GetPkgs() []IDorPkgInput { return v.Pkgs } // __IngestPkgEqualInput is used internally by genqlient type __IngestPkgEqualInput struct { - Pkg PkgInputSpec `json:"pkg"` - OtherPackage PkgInputSpec `json:"otherPackage"` + Pkg IDorPkgInput `json:"pkg"` + OtherPackage IDorPkgInput `json:"otherPackage"` PkgEqual PkgEqualInputSpec `json:"pkgEqual"` } // GetPkg returns __IngestPkgEqualInput.Pkg, and is useful for accessing the field via an interface. -func (v *__IngestPkgEqualInput) GetPkg() PkgInputSpec { return v.Pkg } +func (v *__IngestPkgEqualInput) GetPkg() IDorPkgInput { return v.Pkg } // GetOtherPackage returns __IngestPkgEqualInput.OtherPackage, and is useful for accessing the field via an interface. -func (v *__IngestPkgEqualInput) GetOtherPackage() PkgInputSpec { return v.OtherPackage } +func (v *__IngestPkgEqualInput) GetOtherPackage() IDorPkgInput { return v.OtherPackage } // GetPkgEqual returns __IngestPkgEqualInput.PkgEqual, and is useful for accessing the field via an interface. func (v *__IngestPkgEqualInput) GetPkgEqual() PkgEqualInputSpec { return v.PkgEqual } // __IngestPkgEqualsInput is used internally by genqlient type __IngestPkgEqualsInput struct { - Pkgs []PkgInputSpec `json:"pkgs"` - OtherPackages []PkgInputSpec `json:"otherPackages"` + Pkgs []IDorPkgInput `json:"pkgs"` + OtherPackages []IDorPkgInput `json:"otherPackages"` PkgEquals []PkgEqualInputSpec `json:"pkgEquals"` } // GetPkgs returns __IngestPkgEqualsInput.Pkgs, and is useful for accessing the field via an interface. -func (v *__IngestPkgEqualsInput) GetPkgs() []PkgInputSpec { return v.Pkgs } +func (v *__IngestPkgEqualsInput) GetPkgs() []IDorPkgInput { return v.Pkgs } // GetOtherPackages returns __IngestPkgEqualsInput.OtherPackages, and is useful for accessing the field via an interface. -func (v *__IngestPkgEqualsInput) GetOtherPackages() []PkgInputSpec { return v.OtherPackages } +func (v *__IngestPkgEqualsInput) GetOtherPackages() []IDorPkgInput { return v.OtherPackages } // GetPkgEquals returns __IngestPkgEqualsInput.PkgEquals, and is useful for accessing the field via an interface. func (v *__IngestPkgEqualsInput) GetPkgEquals() []PkgEqualInputSpec { return v.PkgEquals } // __IngestPointOfContactArtifactInput is used internally by genqlient type __IngestPointOfContactArtifactInput struct { - Artifact ArtifactInputSpec `json:"artifact"` + Artifact IDorArtifactInput `json:"artifact"` PointOfContact PointOfContactInputSpec `json:"pointOfContact"` } // GetArtifact returns __IngestPointOfContactArtifactInput.Artifact, and is useful for accessing the field via an interface. -func (v *__IngestPointOfContactArtifactInput) GetArtifact() ArtifactInputSpec { return v.Artifact } +func (v *__IngestPointOfContactArtifactInput) GetArtifact() IDorArtifactInput { return v.Artifact } // GetPointOfContact returns __IngestPointOfContactArtifactInput.PointOfContact, and is useful for accessing the field via an interface. func (v *__IngestPointOfContactArtifactInput) GetPointOfContact() PointOfContactInputSpec { @@ -23177,12 +23299,12 @@ func (v *__IngestPointOfContactArtifactInput) GetPointOfContact() PointOfContact // __IngestPointOfContactArtifactsInput is used internally by genqlient type __IngestPointOfContactArtifactsInput struct { - Artifacts []ArtifactInputSpec `json:"artifacts"` + Artifacts []IDorArtifactInput `json:"artifacts"` PointOfContacts []PointOfContactInputSpec `json:"pointOfContacts"` } // GetArtifacts returns __IngestPointOfContactArtifactsInput.Artifacts, and is useful for accessing the field via an interface. -func (v *__IngestPointOfContactArtifactsInput) GetArtifacts() []ArtifactInputSpec { return v.Artifacts } +func (v *__IngestPointOfContactArtifactsInput) GetArtifacts() []IDorArtifactInput { return v.Artifacts } // GetPointOfContacts returns __IngestPointOfContactArtifactsInput.PointOfContacts, and is useful for accessing the field via an interface. func (v *__IngestPointOfContactArtifactsInput) GetPointOfContacts() []PointOfContactInputSpec { @@ -23191,13 +23313,13 @@ func (v *__IngestPointOfContactArtifactsInput) GetPointOfContacts() []PointOfCon // __IngestPointOfContactPkgInput is used internally by genqlient type __IngestPointOfContactPkgInput struct { - Pkg PkgInputSpec `json:"pkg"` + Pkg IDorPkgInput `json:"pkg"` PkgMatchType MatchFlags `json:"pkgMatchType"` PointOfContact PointOfContactInputSpec `json:"pointOfContact"` } // GetPkg returns __IngestPointOfContactPkgInput.Pkg, and is useful for accessing the field via an interface. -func (v *__IngestPointOfContactPkgInput) GetPkg() PkgInputSpec { return v.Pkg } +func (v *__IngestPointOfContactPkgInput) GetPkg() IDorPkgInput { return v.Pkg } // GetPkgMatchType returns __IngestPointOfContactPkgInput.PkgMatchType, and is useful for accessing the field via an interface. func (v *__IngestPointOfContactPkgInput) GetPkgMatchType() MatchFlags { return v.PkgMatchType } @@ -23209,13 +23331,13 @@ func (v *__IngestPointOfContactPkgInput) GetPointOfContact() PointOfContactInput // __IngestPointOfContactPkgsInput is used internally by genqlient type __IngestPointOfContactPkgsInput struct { - Pkgs []PkgInputSpec `json:"pkgs"` + Pkgs []IDorPkgInput `json:"pkgs"` PkgMatchType MatchFlags `json:"pkgMatchType"` PointOfContacts []PointOfContactInputSpec `json:"pointOfContacts"` } // GetPkgs returns __IngestPointOfContactPkgsInput.Pkgs, and is useful for accessing the field via an interface. -func (v *__IngestPointOfContactPkgsInput) GetPkgs() []PkgInputSpec { return v.Pkgs } +func (v *__IngestPointOfContactPkgsInput) GetPkgs() []IDorPkgInput { return v.Pkgs } // GetPkgMatchType returns __IngestPointOfContactPkgsInput.PkgMatchType, and is useful for accessing the field via an interface. func (v *__IngestPointOfContactPkgsInput) GetPkgMatchType() MatchFlags { return v.PkgMatchType } @@ -23227,12 +23349,12 @@ func (v *__IngestPointOfContactPkgsInput) GetPointOfContacts() []PointOfContactI // __IngestPointOfContactSrcInput is used internally by genqlient type __IngestPointOfContactSrcInput struct { - Source SourceInputSpec `json:"source"` + Source IDorSourceInput `json:"source"` PointOfContact PointOfContactInputSpec `json:"pointOfContact"` } // GetSource returns __IngestPointOfContactSrcInput.Source, and is useful for accessing the field via an interface. -func (v *__IngestPointOfContactSrcInput) GetSource() SourceInputSpec { return v.Source } +func (v *__IngestPointOfContactSrcInput) GetSource() IDorSourceInput { return v.Source } // GetPointOfContact returns __IngestPointOfContactSrcInput.PointOfContact, and is useful for accessing the field via an interface. func (v *__IngestPointOfContactSrcInput) GetPointOfContact() PointOfContactInputSpec { @@ -23241,12 +23363,12 @@ func (v *__IngestPointOfContactSrcInput) GetPointOfContact() PointOfContactInput // __IngestPointOfContactSrcsInput is used internally by genqlient type __IngestPointOfContactSrcsInput struct { - Sources []SourceInputSpec `json:"sources"` + Sources []IDorSourceInput `json:"sources"` PointOfContacts []PointOfContactInputSpec `json:"pointOfContacts"` } // GetSources returns __IngestPointOfContactSrcsInput.Sources, and is useful for accessing the field via an interface. -func (v *__IngestPointOfContactSrcsInput) GetSources() []SourceInputSpec { return v.Sources } +func (v *__IngestPointOfContactSrcsInput) GetSources() []IDorSourceInput { return v.Sources } // GetPointOfContacts returns __IngestPointOfContactSrcsInput.PointOfContacts, and is useful for accessing the field via an interface. func (v *__IngestPointOfContactSrcsInput) GetPointOfContacts() []PointOfContactInputSpec { @@ -23255,74 +23377,74 @@ func (v *__IngestPointOfContactSrcsInput) GetPointOfContacts() []PointOfContactI // __IngestSLSAForArtifactInput is used internally by genqlient type __IngestSLSAForArtifactInput struct { - Artifact ArtifactInputSpec `json:"artifact"` - Materials []ArtifactInputSpec `json:"materials"` - Builder BuilderInputSpec `json:"builder"` + Artifact IDorArtifactInput `json:"artifact"` + Materials []IDorArtifactInput `json:"materials"` + Builder IDorBuilderInput `json:"builder"` Slsa SLSAInputSpec `json:"slsa"` } // GetArtifact returns __IngestSLSAForArtifactInput.Artifact, and is useful for accessing the field via an interface. -func (v *__IngestSLSAForArtifactInput) GetArtifact() ArtifactInputSpec { return v.Artifact } +func (v *__IngestSLSAForArtifactInput) GetArtifact() IDorArtifactInput { return v.Artifact } // GetMaterials returns __IngestSLSAForArtifactInput.Materials, and is useful for accessing the field via an interface. -func (v *__IngestSLSAForArtifactInput) GetMaterials() []ArtifactInputSpec { return v.Materials } +func (v *__IngestSLSAForArtifactInput) GetMaterials() []IDorArtifactInput { return v.Materials } // GetBuilder returns __IngestSLSAForArtifactInput.Builder, and is useful for accessing the field via an interface. -func (v *__IngestSLSAForArtifactInput) GetBuilder() BuilderInputSpec { return v.Builder } +func (v *__IngestSLSAForArtifactInput) GetBuilder() IDorBuilderInput { return v.Builder } // GetSlsa returns __IngestSLSAForArtifactInput.Slsa, and is useful for accessing the field via an interface. func (v *__IngestSLSAForArtifactInput) GetSlsa() SLSAInputSpec { return v.Slsa } // __IngestSLSAForArtifactsInput is used internally by genqlient type __IngestSLSAForArtifactsInput struct { - Artifacts []ArtifactInputSpec `json:"artifacts"` - MaterialsList [][]ArtifactInputSpec `json:"materialsList"` - Builders []BuilderInputSpec `json:"builders"` + Artifacts []IDorArtifactInput `json:"artifacts"` + MaterialsList [][]IDorArtifactInput `json:"materialsList"` + Builders []IDorBuilderInput `json:"builders"` SlsaList []SLSAInputSpec `json:"slsaList"` } // GetArtifacts returns __IngestSLSAForArtifactsInput.Artifacts, and is useful for accessing the field via an interface. -func (v *__IngestSLSAForArtifactsInput) GetArtifacts() []ArtifactInputSpec { return v.Artifacts } +func (v *__IngestSLSAForArtifactsInput) GetArtifacts() []IDorArtifactInput { return v.Artifacts } // GetMaterialsList returns __IngestSLSAForArtifactsInput.MaterialsList, and is useful for accessing the field via an interface. -func (v *__IngestSLSAForArtifactsInput) GetMaterialsList() [][]ArtifactInputSpec { +func (v *__IngestSLSAForArtifactsInput) GetMaterialsList() [][]IDorArtifactInput { return v.MaterialsList } // GetBuilders returns __IngestSLSAForArtifactsInput.Builders, and is useful for accessing the field via an interface. -func (v *__IngestSLSAForArtifactsInput) GetBuilders() []BuilderInputSpec { return v.Builders } +func (v *__IngestSLSAForArtifactsInput) GetBuilders() []IDorBuilderInput { return v.Builders } // GetSlsaList returns __IngestSLSAForArtifactsInput.SlsaList, and is useful for accessing the field via an interface. func (v *__IngestSLSAForArtifactsInput) GetSlsaList() []SLSAInputSpec { return v.SlsaList } // __IngestSourceInput is used internally by genqlient type __IngestSourceInput struct { - Source SourceInputSpec `json:"source"` + Source IDorSourceInput `json:"source"` } // GetSource returns __IngestSourceInput.Source, and is useful for accessing the field via an interface. -func (v *__IngestSourceInput) GetSource() SourceInputSpec { return v.Source } +func (v *__IngestSourceInput) GetSource() IDorSourceInput { return v.Source } // __IngestSourcesInput is used internally by genqlient type __IngestSourcesInput struct { - Sources []SourceInputSpec `json:"sources"` + Sources []IDorSourceInput `json:"sources"` } // GetSources returns __IngestSourcesInput.Sources, and is useful for accessing the field via an interface. -func (v *__IngestSourcesInput) GetSources() []SourceInputSpec { return v.Sources } +func (v *__IngestSourcesInput) GetSources() []IDorSourceInput { return v.Sources } // __IngestVulnEqualInput is used internally by genqlient type __IngestVulnEqualInput struct { - Vulnerability VulnerabilityInputSpec `json:"vulnerability"` - OtherVulnerability VulnerabilityInputSpec `json:"otherVulnerability"` + Vulnerability IDorVulnerabilityInput `json:"vulnerability"` + OtherVulnerability IDorVulnerabilityInput `json:"otherVulnerability"` VulnEqual VulnEqualInputSpec `json:"vulnEqual"` } // GetVulnerability returns __IngestVulnEqualInput.Vulnerability, and is useful for accessing the field via an interface. -func (v *__IngestVulnEqualInput) GetVulnerability() VulnerabilityInputSpec { return v.Vulnerability } +func (v *__IngestVulnEqualInput) GetVulnerability() IDorVulnerabilityInput { return v.Vulnerability } // GetOtherVulnerability returns __IngestVulnEqualInput.OtherVulnerability, and is useful for accessing the field via an interface. -func (v *__IngestVulnEqualInput) GetOtherVulnerability() VulnerabilityInputSpec { +func (v *__IngestVulnEqualInput) GetOtherVulnerability() IDorVulnerabilityInput { return v.OtherVulnerability } @@ -23331,18 +23453,18 @@ func (v *__IngestVulnEqualInput) GetVulnEqual() VulnEqualInputSpec { return v.Vu // __IngestVulnEqualsInput is used internally by genqlient type __IngestVulnEqualsInput struct { - Vulnerabilities []VulnerabilityInputSpec `json:"vulnerabilities"` - OtherVulnerabilities []VulnerabilityInputSpec `json:"otherVulnerabilities"` + Vulnerabilities []IDorVulnerabilityInput `json:"vulnerabilities"` + OtherVulnerabilities []IDorVulnerabilityInput `json:"otherVulnerabilities"` VulnEquals []VulnEqualInputSpec `json:"vulnEquals"` } // GetVulnerabilities returns __IngestVulnEqualsInput.Vulnerabilities, and is useful for accessing the field via an interface. -func (v *__IngestVulnEqualsInput) GetVulnerabilities() []VulnerabilityInputSpec { +func (v *__IngestVulnEqualsInput) GetVulnerabilities() []IDorVulnerabilityInput { return v.Vulnerabilities } // GetOtherVulnerabilities returns __IngestVulnEqualsInput.OtherVulnerabilities, and is useful for accessing the field via an interface. -func (v *__IngestVulnEqualsInput) GetOtherVulnerabilities() []VulnerabilityInputSpec { +func (v *__IngestVulnEqualsInput) GetOtherVulnerabilities() []IDorVulnerabilityInput { return v.OtherVulnerabilities } @@ -23351,12 +23473,12 @@ func (v *__IngestVulnEqualsInput) GetVulnEquals() []VulnEqualInputSpec { return // __IngestVulnHasMetadataInput is used internally by genqlient type __IngestVulnHasMetadataInput struct { - Vulnerability VulnerabilityInputSpec `json:"vulnerability"` + Vulnerability IDorVulnerabilityInput `json:"vulnerability"` VulnMetadata VulnerabilityMetadataInputSpec `json:"vulnMetadata"` } // GetVulnerability returns __IngestVulnHasMetadataInput.Vulnerability, and is useful for accessing the field via an interface. -func (v *__IngestVulnHasMetadataInput) GetVulnerability() VulnerabilityInputSpec { +func (v *__IngestVulnHasMetadataInput) GetVulnerability() IDorVulnerabilityInput { return v.Vulnerability } @@ -23367,19 +23489,19 @@ func (v *__IngestVulnHasMetadataInput) GetVulnMetadata() VulnerabilityMetadataIn // __IngestVulnerabilitiesInput is used internally by genqlient type __IngestVulnerabilitiesInput struct { - Vulns []VulnerabilityInputSpec `json:"vulns"` + Vulns []IDorVulnerabilityInput `json:"vulns"` } // GetVulns returns __IngestVulnerabilitiesInput.Vulns, and is useful for accessing the field via an interface. -func (v *__IngestVulnerabilitiesInput) GetVulns() []VulnerabilityInputSpec { return v.Vulns } +func (v *__IngestVulnerabilitiesInput) GetVulns() []IDorVulnerabilityInput { return v.Vulns } // __IngestVulnerabilityInput is used internally by genqlient type __IngestVulnerabilityInput struct { - Vuln VulnerabilityInputSpec `json:"vuln"` + Vuln IDorVulnerabilityInput `json:"vuln"` } // GetVuln returns __IngestVulnerabilityInput.Vuln, and is useful for accessing the field via an interface. -func (v *__IngestVulnerabilityInput) GetVuln() VulnerabilityInputSpec { return v.Vuln } +func (v *__IngestVulnerabilityInput) GetVuln() IDorVulnerabilityInput { return v.Vuln } // __LicensesInput is used internally by genqlient type __LicensesInput struct { @@ -24025,7 +24147,7 @@ func HasSBOMs( // The query or mutation executed by IngestArtifact. const IngestArtifact_Operation = ` -mutation IngestArtifact ($artifact: ArtifactInputSpec!) { +mutation IngestArtifact ($artifact: IDorArtifactInput!) { ingestArtifact(artifact: $artifact) } ` @@ -24033,7 +24155,7 @@ mutation IngestArtifact ($artifact: ArtifactInputSpec!) { func IngestArtifact( ctx context.Context, client graphql.Client, - artifact ArtifactInputSpec, + artifact IDorArtifactInput, ) (*IngestArtifactResponse, error) { req := &graphql.Request{ OpName: "IngestArtifact", @@ -24058,7 +24180,7 @@ func IngestArtifact( // The query or mutation executed by IngestArtifacts. const IngestArtifacts_Operation = ` -mutation IngestArtifacts ($artifacts: [ArtifactInputSpec!]!) { +mutation IngestArtifacts ($artifacts: [IDorArtifactInput!]!) { ingestArtifacts(artifacts: $artifacts) } ` @@ -24066,7 +24188,7 @@ mutation IngestArtifacts ($artifacts: [ArtifactInputSpec!]!) { func IngestArtifacts( ctx context.Context, client graphql.Client, - artifacts []ArtifactInputSpec, + artifacts []IDorArtifactInput, ) (*IngestArtifactsResponse, error) { req := &graphql.Request{ OpName: "IngestArtifacts", @@ -24091,7 +24213,7 @@ func IngestArtifacts( // The query or mutation executed by IngestBuilder. const IngestBuilder_Operation = ` -mutation IngestBuilder ($builder: BuilderInputSpec!) { +mutation IngestBuilder ($builder: IDorBuilderInput!) { ingestBuilder(builder: $builder) } ` @@ -24099,7 +24221,7 @@ mutation IngestBuilder ($builder: BuilderInputSpec!) { func IngestBuilder( ctx context.Context, client graphql.Client, - builder BuilderInputSpec, + builder IDorBuilderInput, ) (*IngestBuilderResponse, error) { req := &graphql.Request{ OpName: "IngestBuilder", @@ -24124,7 +24246,7 @@ func IngestBuilder( // The query or mutation executed by IngestBuilders. const IngestBuilders_Operation = ` -mutation IngestBuilders ($builders: [BuilderInputSpec!]!) { +mutation IngestBuilders ($builders: [IDorBuilderInput!]!) { ingestBuilders(builders: $builders) } ` @@ -24132,7 +24254,7 @@ mutation IngestBuilders ($builders: [BuilderInputSpec!]!) { func IngestBuilders( ctx context.Context, client graphql.Client, - builders []BuilderInputSpec, + builders []IDorBuilderInput, ) (*IngestBuildersResponse, error) { req := &graphql.Request{ OpName: "IngestBuilders", @@ -24157,7 +24279,7 @@ func IngestBuilders( // The query or mutation executed by IngestBulkVulnHasMetadata. const IngestBulkVulnHasMetadata_Operation = ` -mutation IngestBulkVulnHasMetadata ($vulnerabilities: [VulnerabilityInputSpec!]!, $vulnerabilityMetadataList: [VulnerabilityMetadataInputSpec!]!) { +mutation IngestBulkVulnHasMetadata ($vulnerabilities: [IDorVulnerabilityInput!]!, $vulnerabilityMetadataList: [VulnerabilityMetadataInputSpec!]!) { ingestBulkVulnerabilityMetadata(vulnerabilities: $vulnerabilities, vulnerabilityMetadataList: $vulnerabilityMetadataList) } ` @@ -24165,7 +24287,7 @@ mutation IngestBulkVulnHasMetadata ($vulnerabilities: [VulnerabilityInputSpec!]! func IngestBulkVulnHasMetadata( ctx context.Context, client graphql.Client, - vulnerabilities []VulnerabilityInputSpec, + vulnerabilities []IDorVulnerabilityInput, vulnerabilityMetadataList []VulnerabilityMetadataInputSpec, ) (*IngestBulkVulnHasMetadataResponse, error) { req := &graphql.Request{ @@ -24192,7 +24314,7 @@ func IngestBulkVulnHasMetadata( // The query or mutation executed by IngestCertifyBadArtifact. const IngestCertifyBadArtifact_Operation = ` -mutation IngestCertifyBadArtifact ($artifact: ArtifactInputSpec!, $certifyBad: CertifyBadInputSpec!) { +mutation IngestCertifyBadArtifact ($artifact: IDorArtifactInput!, $certifyBad: CertifyBadInputSpec!) { ingestCertifyBad(subject: {artifact:$artifact}, pkgMatchType: {pkg:ALL_VERSIONS}, certifyBad: $certifyBad) } ` @@ -24200,7 +24322,7 @@ mutation IngestCertifyBadArtifact ($artifact: ArtifactInputSpec!, $certifyBad: C func IngestCertifyBadArtifact( ctx context.Context, client graphql.Client, - artifact ArtifactInputSpec, + artifact IDorArtifactInput, certifyBad CertifyBadInputSpec, ) (*IngestCertifyBadArtifactResponse, error) { req := &graphql.Request{ @@ -24227,7 +24349,7 @@ func IngestCertifyBadArtifact( // The query or mutation executed by IngestCertifyBadArtifacts. const IngestCertifyBadArtifacts_Operation = ` -mutation IngestCertifyBadArtifacts ($artifacts: [ArtifactInputSpec!]!, $certifyBads: [CertifyBadInputSpec!]!) { +mutation IngestCertifyBadArtifacts ($artifacts: [IDorArtifactInput!]!, $certifyBads: [CertifyBadInputSpec!]!) { ingestCertifyBads(subjects: {artifacts:$artifacts}, pkgMatchType: {pkg:ALL_VERSIONS}, certifyBads: $certifyBads) } ` @@ -24235,7 +24357,7 @@ mutation IngestCertifyBadArtifacts ($artifacts: [ArtifactInputSpec!]!, $certifyB func IngestCertifyBadArtifacts( ctx context.Context, client graphql.Client, - artifacts []ArtifactInputSpec, + artifacts []IDorArtifactInput, certifyBads []CertifyBadInputSpec, ) (*IngestCertifyBadArtifactsResponse, error) { req := &graphql.Request{ @@ -24262,7 +24384,7 @@ func IngestCertifyBadArtifacts( // The query or mutation executed by IngestCertifyBadPkg. const IngestCertifyBadPkg_Operation = ` -mutation IngestCertifyBadPkg ($pkg: PkgInputSpec!, $pkgMatchType: MatchFlags!, $certifyBad: CertifyBadInputSpec!) { +mutation IngestCertifyBadPkg ($pkg: IDorPkgInput!, $pkgMatchType: MatchFlags!, $certifyBad: CertifyBadInputSpec!) { ingestCertifyBad(subject: {package:$pkg}, pkgMatchType: $pkgMatchType, certifyBad: $certifyBad) } ` @@ -24270,7 +24392,7 @@ mutation IngestCertifyBadPkg ($pkg: PkgInputSpec!, $pkgMatchType: MatchFlags!, $ func IngestCertifyBadPkg( ctx context.Context, client graphql.Client, - pkg PkgInputSpec, + pkg IDorPkgInput, pkgMatchType MatchFlags, certifyBad CertifyBadInputSpec, ) (*IngestCertifyBadPkgResponse, error) { @@ -24299,7 +24421,7 @@ func IngestCertifyBadPkg( // The query or mutation executed by IngestCertifyBadPkgs. const IngestCertifyBadPkgs_Operation = ` -mutation IngestCertifyBadPkgs ($pkgs: [PkgInputSpec!]!, $pkgMatchType: MatchFlags!, $certifyBads: [CertifyBadInputSpec!]!) { +mutation IngestCertifyBadPkgs ($pkgs: [IDorPkgInput!]!, $pkgMatchType: MatchFlags!, $certifyBads: [CertifyBadInputSpec!]!) { ingestCertifyBads(subjects: {packages:$pkgs}, pkgMatchType: $pkgMatchType, certifyBads: $certifyBads) } ` @@ -24307,7 +24429,7 @@ mutation IngestCertifyBadPkgs ($pkgs: [PkgInputSpec!]!, $pkgMatchType: MatchFlag func IngestCertifyBadPkgs( ctx context.Context, client graphql.Client, - pkgs []PkgInputSpec, + pkgs []IDorPkgInput, pkgMatchType MatchFlags, certifyBads []CertifyBadInputSpec, ) (*IngestCertifyBadPkgsResponse, error) { @@ -24336,7 +24458,7 @@ func IngestCertifyBadPkgs( // The query or mutation executed by IngestCertifyBadSrc. const IngestCertifyBadSrc_Operation = ` -mutation IngestCertifyBadSrc ($source: SourceInputSpec!, $certifyBad: CertifyBadInputSpec!) { +mutation IngestCertifyBadSrc ($source: IDorSourceInput!, $certifyBad: CertifyBadInputSpec!) { ingestCertifyBad(subject: {source:$source}, pkgMatchType: {pkg:ALL_VERSIONS}, certifyBad: $certifyBad) } ` @@ -24344,7 +24466,7 @@ mutation IngestCertifyBadSrc ($source: SourceInputSpec!, $certifyBad: CertifyBad func IngestCertifyBadSrc( ctx context.Context, client graphql.Client, - source SourceInputSpec, + source IDorSourceInput, certifyBad CertifyBadInputSpec, ) (*IngestCertifyBadSrcResponse, error) { req := &graphql.Request{ @@ -24371,7 +24493,7 @@ func IngestCertifyBadSrc( // The query or mutation executed by IngestCertifyBadSrcs. const IngestCertifyBadSrcs_Operation = ` -mutation IngestCertifyBadSrcs ($sources: [SourceInputSpec!]!, $certifyBads: [CertifyBadInputSpec!]!) { +mutation IngestCertifyBadSrcs ($sources: [IDorSourceInput!]!, $certifyBads: [CertifyBadInputSpec!]!) { ingestCertifyBads(subjects: {sources:$sources}, pkgMatchType: {pkg:ALL_VERSIONS}, certifyBads: $certifyBads) } ` @@ -24379,7 +24501,7 @@ mutation IngestCertifyBadSrcs ($sources: [SourceInputSpec!]!, $certifyBads: [Cer func IngestCertifyBadSrcs( ctx context.Context, client graphql.Client, - sources []SourceInputSpec, + sources []IDorSourceInput, certifyBads []CertifyBadInputSpec, ) (*IngestCertifyBadSrcsResponse, error) { req := &graphql.Request{ @@ -24406,7 +24528,7 @@ func IngestCertifyBadSrcs( // The query or mutation executed by IngestCertifyGoodArtifact. const IngestCertifyGoodArtifact_Operation = ` -mutation IngestCertifyGoodArtifact ($artifact: ArtifactInputSpec!, $certifyGood: CertifyGoodInputSpec!) { +mutation IngestCertifyGoodArtifact ($artifact: IDorArtifactInput!, $certifyGood: CertifyGoodInputSpec!) { ingestCertifyGood(subject: {artifact:$artifact}, pkgMatchType: {pkg:ALL_VERSIONS}, certifyGood: $certifyGood) } ` @@ -24414,7 +24536,7 @@ mutation IngestCertifyGoodArtifact ($artifact: ArtifactInputSpec!, $certifyGood: func IngestCertifyGoodArtifact( ctx context.Context, client graphql.Client, - artifact ArtifactInputSpec, + artifact IDorArtifactInput, certifyGood CertifyGoodInputSpec, ) (*IngestCertifyGoodArtifactResponse, error) { req := &graphql.Request{ @@ -24441,7 +24563,7 @@ func IngestCertifyGoodArtifact( // The query or mutation executed by IngestCertifyGoodArtifacts. const IngestCertifyGoodArtifacts_Operation = ` -mutation IngestCertifyGoodArtifacts ($artifacts: [ArtifactInputSpec!]!, $certifyGoods: [CertifyGoodInputSpec!]!) { +mutation IngestCertifyGoodArtifacts ($artifacts: [IDorArtifactInput!]!, $certifyGoods: [CertifyGoodInputSpec!]!) { ingestCertifyGoods(subjects: {artifacts:$artifacts}, pkgMatchType: {pkg:ALL_VERSIONS}, certifyGoods: $certifyGoods) } ` @@ -24449,7 +24571,7 @@ mutation IngestCertifyGoodArtifacts ($artifacts: [ArtifactInputSpec!]!, $certify func IngestCertifyGoodArtifacts( ctx context.Context, client graphql.Client, - artifacts []ArtifactInputSpec, + artifacts []IDorArtifactInput, certifyGoods []CertifyGoodInputSpec, ) (*IngestCertifyGoodArtifactsResponse, error) { req := &graphql.Request{ @@ -24476,7 +24598,7 @@ func IngestCertifyGoodArtifacts( // The query or mutation executed by IngestCertifyGoodPkg. const IngestCertifyGoodPkg_Operation = ` -mutation IngestCertifyGoodPkg ($pkg: PkgInputSpec!, $pkgMatchType: MatchFlags!, $certifyGood: CertifyGoodInputSpec!) { +mutation IngestCertifyGoodPkg ($pkg: IDorPkgInput!, $pkgMatchType: MatchFlags!, $certifyGood: CertifyGoodInputSpec!) { ingestCertifyGood(subject: {package:$pkg}, pkgMatchType: $pkgMatchType, certifyGood: $certifyGood) } ` @@ -24484,7 +24606,7 @@ mutation IngestCertifyGoodPkg ($pkg: PkgInputSpec!, $pkgMatchType: MatchFlags!, func IngestCertifyGoodPkg( ctx context.Context, client graphql.Client, - pkg PkgInputSpec, + pkg IDorPkgInput, pkgMatchType MatchFlags, certifyGood CertifyGoodInputSpec, ) (*IngestCertifyGoodPkgResponse, error) { @@ -24513,7 +24635,7 @@ func IngestCertifyGoodPkg( // The query or mutation executed by IngestCertifyGoodPkgs. const IngestCertifyGoodPkgs_Operation = ` -mutation IngestCertifyGoodPkgs ($pkgs: [PkgInputSpec!]!, $pkgMatchType: MatchFlags!, $certifyGoods: [CertifyGoodInputSpec!]!) { +mutation IngestCertifyGoodPkgs ($pkgs: [IDorPkgInput!]!, $pkgMatchType: MatchFlags!, $certifyGoods: [CertifyGoodInputSpec!]!) { ingestCertifyGoods(subjects: {packages:$pkgs}, pkgMatchType: $pkgMatchType, certifyGoods: $certifyGoods) } ` @@ -24521,7 +24643,7 @@ mutation IngestCertifyGoodPkgs ($pkgs: [PkgInputSpec!]!, $pkgMatchType: MatchFla func IngestCertifyGoodPkgs( ctx context.Context, client graphql.Client, - pkgs []PkgInputSpec, + pkgs []IDorPkgInput, pkgMatchType MatchFlags, certifyGoods []CertifyGoodInputSpec, ) (*IngestCertifyGoodPkgsResponse, error) { @@ -24550,7 +24672,7 @@ func IngestCertifyGoodPkgs( // The query or mutation executed by IngestCertifyGoodSrc. const IngestCertifyGoodSrc_Operation = ` -mutation IngestCertifyGoodSrc ($source: SourceInputSpec!, $certifyGood: CertifyGoodInputSpec!) { +mutation IngestCertifyGoodSrc ($source: IDorSourceInput!, $certifyGood: CertifyGoodInputSpec!) { ingestCertifyGood(subject: {source:$source}, pkgMatchType: {pkg:ALL_VERSIONS}, certifyGood: $certifyGood) } ` @@ -24558,7 +24680,7 @@ mutation IngestCertifyGoodSrc ($source: SourceInputSpec!, $certifyGood: CertifyG func IngestCertifyGoodSrc( ctx context.Context, client graphql.Client, - source SourceInputSpec, + source IDorSourceInput, certifyGood CertifyGoodInputSpec, ) (*IngestCertifyGoodSrcResponse, error) { req := &graphql.Request{ @@ -24585,7 +24707,7 @@ func IngestCertifyGoodSrc( // The query or mutation executed by IngestCertifyGoodSrcs. const IngestCertifyGoodSrcs_Operation = ` -mutation IngestCertifyGoodSrcs ($sources: [SourceInputSpec!]!, $certifyGoods: [CertifyGoodInputSpec!]!) { +mutation IngestCertifyGoodSrcs ($sources: [IDorSourceInput!]!, $certifyGoods: [CertifyGoodInputSpec!]!) { ingestCertifyGoods(subjects: {sources:$sources}, pkgMatchType: {pkg:ALL_VERSIONS}, certifyGoods: $certifyGoods) } ` @@ -24593,7 +24715,7 @@ mutation IngestCertifyGoodSrcs ($sources: [SourceInputSpec!]!, $certifyGoods: [C func IngestCertifyGoodSrcs( ctx context.Context, client graphql.Client, - sources []SourceInputSpec, + sources []IDorSourceInput, certifyGoods []CertifyGoodInputSpec, ) (*IngestCertifyGoodSrcsResponse, error) { req := &graphql.Request{ @@ -24620,7 +24742,7 @@ func IngestCertifyGoodSrcs( // The query or mutation executed by IngestCertifyLegalPkg. const IngestCertifyLegalPkg_Operation = ` -mutation IngestCertifyLegalPkg ($pkg: PkgInputSpec!, $declaredLicenses: [LicenseInputSpec!]!, $discoveredLicenses: [LicenseInputSpec!]!, $legal: CertifyLegalInputSpec!) { +mutation IngestCertifyLegalPkg ($pkg: IDorPkgInput!, $declaredLicenses: [IDorLicenseInput!]!, $discoveredLicenses: [IDorLicenseInput!]!, $legal: CertifyLegalInputSpec!) { ingestCertifyLegal(subject: {package:$pkg}, declaredLicenses: $declaredLicenses, discoveredLicenses: $discoveredLicenses, certifyLegal: $legal) } ` @@ -24628,9 +24750,9 @@ mutation IngestCertifyLegalPkg ($pkg: PkgInputSpec!, $declaredLicenses: [License func IngestCertifyLegalPkg( ctx context.Context, client graphql.Client, - pkg PkgInputSpec, - declaredLicenses []LicenseInputSpec, - discoveredLicenses []LicenseInputSpec, + pkg IDorPkgInput, + declaredLicenses []IDorLicenseInput, + discoveredLicenses []IDorLicenseInput, legal CertifyLegalInputSpec, ) (*IngestCertifyLegalPkgResponse, error) { req := &graphql.Request{ @@ -24659,7 +24781,7 @@ func IngestCertifyLegalPkg( // The query or mutation executed by IngestCertifyLegalPkgs. const IngestCertifyLegalPkgs_Operation = ` -mutation IngestCertifyLegalPkgs ($pkgs: [PkgInputSpec!]!, $declaredLicensesList: [[LicenseInputSpec!]!]!, $discoveredLicensesList: [[LicenseInputSpec!]!]!, $legals: [CertifyLegalInputSpec!]!) { +mutation IngestCertifyLegalPkgs ($pkgs: [IDorPkgInput!]!, $declaredLicensesList: [[IDorLicenseInput!]!]!, $discoveredLicensesList: [[IDorLicenseInput!]!]!, $legals: [CertifyLegalInputSpec!]!) { ingestCertifyLegals(subjects: {packages:$pkgs}, declaredLicensesList: $declaredLicensesList, discoveredLicensesList: $discoveredLicensesList, certifyLegals: $legals) } ` @@ -24667,9 +24789,9 @@ mutation IngestCertifyLegalPkgs ($pkgs: [PkgInputSpec!]!, $declaredLicensesList: func IngestCertifyLegalPkgs( ctx context.Context, client graphql.Client, - pkgs []PkgInputSpec, - declaredLicensesList [][]LicenseInputSpec, - discoveredLicensesList [][]LicenseInputSpec, + pkgs []IDorPkgInput, + declaredLicensesList [][]IDorLicenseInput, + discoveredLicensesList [][]IDorLicenseInput, legals []CertifyLegalInputSpec, ) (*IngestCertifyLegalPkgsResponse, error) { req := &graphql.Request{ @@ -24698,7 +24820,7 @@ func IngestCertifyLegalPkgs( // The query or mutation executed by IngestCertifyLegalSrc. const IngestCertifyLegalSrc_Operation = ` -mutation IngestCertifyLegalSrc ($src: SourceInputSpec!, $declaredLicenses: [LicenseInputSpec!]!, $discoveredLicenses: [LicenseInputSpec!]!, $legal: CertifyLegalInputSpec!) { +mutation IngestCertifyLegalSrc ($src: IDorSourceInput!, $declaredLicenses: [IDorLicenseInput!]!, $discoveredLicenses: [IDorLicenseInput!]!, $legal: CertifyLegalInputSpec!) { ingestCertifyLegal(subject: {source:$src}, declaredLicenses: $declaredLicenses, discoveredLicenses: $discoveredLicenses, certifyLegal: $legal) } ` @@ -24706,9 +24828,9 @@ mutation IngestCertifyLegalSrc ($src: SourceInputSpec!, $declaredLicenses: [Lice func IngestCertifyLegalSrc( ctx context.Context, client graphql.Client, - src SourceInputSpec, - declaredLicenses []LicenseInputSpec, - discoveredLicenses []LicenseInputSpec, + src IDorSourceInput, + declaredLicenses []IDorLicenseInput, + discoveredLicenses []IDorLicenseInput, legal CertifyLegalInputSpec, ) (*IngestCertifyLegalSrcResponse, error) { req := &graphql.Request{ @@ -24737,7 +24859,7 @@ func IngestCertifyLegalSrc( // The query or mutation executed by IngestCertifyLegalSrcs. const IngestCertifyLegalSrcs_Operation = ` -mutation IngestCertifyLegalSrcs ($srcs: [SourceInputSpec!]!, $declaredLicensesList: [[LicenseInputSpec!]!]!, $discoveredLicensesList: [[LicenseInputSpec!]!]!, $legals: [CertifyLegalInputSpec!]!) { +mutation IngestCertifyLegalSrcs ($srcs: [IDorSourceInput!]!, $declaredLicensesList: [[IDorLicenseInput!]!]!, $discoveredLicensesList: [[IDorLicenseInput!]!]!, $legals: [CertifyLegalInputSpec!]!) { ingestCertifyLegals(subjects: {sources:$srcs}, declaredLicensesList: $declaredLicensesList, discoveredLicensesList: $discoveredLicensesList, certifyLegals: $legals) } ` @@ -24745,9 +24867,9 @@ mutation IngestCertifyLegalSrcs ($srcs: [SourceInputSpec!]!, $declaredLicensesLi func IngestCertifyLegalSrcs( ctx context.Context, client graphql.Client, - srcs []SourceInputSpec, - declaredLicensesList [][]LicenseInputSpec, - discoveredLicensesList [][]LicenseInputSpec, + srcs []IDorSourceInput, + declaredLicensesList [][]IDorLicenseInput, + discoveredLicensesList [][]IDorLicenseInput, legals []CertifyLegalInputSpec, ) (*IngestCertifyLegalSrcsResponse, error) { req := &graphql.Request{ @@ -24776,7 +24898,7 @@ func IngestCertifyLegalSrcs( // The query or mutation executed by IngestCertifyScorecard. const IngestCertifyScorecard_Operation = ` -mutation IngestCertifyScorecard ($source: SourceInputSpec!, $scorecard: ScorecardInputSpec!) { +mutation IngestCertifyScorecard ($source: IDorSourceInput!, $scorecard: ScorecardInputSpec!) { ingestScorecard(source: $source, scorecard: $scorecard) } ` @@ -24784,7 +24906,7 @@ mutation IngestCertifyScorecard ($source: SourceInputSpec!, $scorecard: Scorecar func IngestCertifyScorecard( ctx context.Context, client graphql.Client, - source SourceInputSpec, + source IDorSourceInput, scorecard ScorecardInputSpec, ) (*IngestCertifyScorecardResponse, error) { req := &graphql.Request{ @@ -24811,7 +24933,7 @@ func IngestCertifyScorecard( // The query or mutation executed by IngestCertifyScorecards. const IngestCertifyScorecards_Operation = ` -mutation IngestCertifyScorecards ($sources: [SourceInputSpec!]!, $scorecards: [ScorecardInputSpec!]!) { +mutation IngestCertifyScorecards ($sources: [IDorSourceInput!]!, $scorecards: [ScorecardInputSpec!]!) { ingestScorecards(sources: $sources, scorecards: $scorecards) } ` @@ -24819,7 +24941,7 @@ mutation IngestCertifyScorecards ($sources: [SourceInputSpec!]!, $scorecards: [S func IngestCertifyScorecards( ctx context.Context, client graphql.Client, - sources []SourceInputSpec, + sources []IDorSourceInput, scorecards []ScorecardInputSpec, ) (*IngestCertifyScorecardsResponse, error) { req := &graphql.Request{ @@ -24846,7 +24968,7 @@ func IngestCertifyScorecards( // The query or mutation executed by IngestCertifyVexArtifact. const IngestCertifyVexArtifact_Operation = ` -mutation IngestCertifyVexArtifact ($artifact: ArtifactInputSpec!, $vulnerability: VulnerabilityInputSpec!, $vexStatement: VexStatementInputSpec!) { +mutation IngestCertifyVexArtifact ($artifact: IDorArtifactInput!, $vulnerability: IDorVulnerabilityInput!, $vexStatement: VexStatementInputSpec!) { ingestVEXStatement(subject: {artifact:$artifact}, vulnerability: $vulnerability, vexStatement: $vexStatement) } ` @@ -24854,8 +24976,8 @@ mutation IngestCertifyVexArtifact ($artifact: ArtifactInputSpec!, $vulnerability func IngestCertifyVexArtifact( ctx context.Context, client graphql.Client, - artifact ArtifactInputSpec, - vulnerability VulnerabilityInputSpec, + artifact IDorArtifactInput, + vulnerability IDorVulnerabilityInput, vexStatement VexStatementInputSpec, ) (*IngestCertifyVexArtifactResponse, error) { req := &graphql.Request{ @@ -24883,7 +25005,7 @@ func IngestCertifyVexArtifact( // The query or mutation executed by IngestCertifyVexArtifacts. const IngestCertifyVexArtifacts_Operation = ` -mutation IngestCertifyVexArtifacts ($artifacts: [ArtifactInputSpec!]!, $vulnerabilities: [VulnerabilityInputSpec!]!, $vexStatements: [VexStatementInputSpec!]!) { +mutation IngestCertifyVexArtifacts ($artifacts: [IDorArtifactInput!]!, $vulnerabilities: [IDorVulnerabilityInput!]!, $vexStatements: [VexStatementInputSpec!]!) { ingestVEXStatements(subjects: {artifacts:$artifacts}, vulnerabilities: $vulnerabilities, vexStatements: $vexStatements) } ` @@ -24891,8 +25013,8 @@ mutation IngestCertifyVexArtifacts ($artifacts: [ArtifactInputSpec!]!, $vulnerab func IngestCertifyVexArtifacts( ctx context.Context, client graphql.Client, - artifacts []ArtifactInputSpec, - vulnerabilities []VulnerabilityInputSpec, + artifacts []IDorArtifactInput, + vulnerabilities []IDorVulnerabilityInput, vexStatements []VexStatementInputSpec, ) (*IngestCertifyVexArtifactsResponse, error) { req := &graphql.Request{ @@ -24920,7 +25042,7 @@ func IngestCertifyVexArtifacts( // The query or mutation executed by IngestCertifyVexPkg. const IngestCertifyVexPkg_Operation = ` -mutation IngestCertifyVexPkg ($pkg: PkgInputSpec!, $vulnerability: VulnerabilityInputSpec!, $vexStatement: VexStatementInputSpec!) { +mutation IngestCertifyVexPkg ($pkg: IDorPkgInput!, $vulnerability: IDorVulnerabilityInput!, $vexStatement: VexStatementInputSpec!) { ingestVEXStatement(subject: {package:$pkg}, vulnerability: $vulnerability, vexStatement: $vexStatement) } ` @@ -24928,8 +25050,8 @@ mutation IngestCertifyVexPkg ($pkg: PkgInputSpec!, $vulnerability: Vulnerability func IngestCertifyVexPkg( ctx context.Context, client graphql.Client, - pkg PkgInputSpec, - vulnerability VulnerabilityInputSpec, + pkg IDorPkgInput, + vulnerability IDorVulnerabilityInput, vexStatement VexStatementInputSpec, ) (*IngestCertifyVexPkgResponse, error) { req := &graphql.Request{ @@ -24957,7 +25079,7 @@ func IngestCertifyVexPkg( // The query or mutation executed by IngestCertifyVexPkgs. const IngestCertifyVexPkgs_Operation = ` -mutation IngestCertifyVexPkgs ($pkgs: [PkgInputSpec!]!, $vulnerabilities: [VulnerabilityInputSpec!]!, $vexStatements: [VexStatementInputSpec!]!) { +mutation IngestCertifyVexPkgs ($pkgs: [IDorPkgInput!]!, $vulnerabilities: [IDorVulnerabilityInput!]!, $vexStatements: [VexStatementInputSpec!]!) { ingestVEXStatements(subjects: {packages:$pkgs}, vulnerabilities: $vulnerabilities, vexStatements: $vexStatements) } ` @@ -24965,8 +25087,8 @@ mutation IngestCertifyVexPkgs ($pkgs: [PkgInputSpec!]!, $vulnerabilities: [Vulne func IngestCertifyVexPkgs( ctx context.Context, client graphql.Client, - pkgs []PkgInputSpec, - vulnerabilities []VulnerabilityInputSpec, + pkgs []IDorPkgInput, + vulnerabilities []IDorVulnerabilityInput, vexStatements []VexStatementInputSpec, ) (*IngestCertifyVexPkgsResponse, error) { req := &graphql.Request{ @@ -24994,7 +25116,7 @@ func IngestCertifyVexPkgs( // The query or mutation executed by IngestCertifyVulnPkg. const IngestCertifyVulnPkg_Operation = ` -mutation IngestCertifyVulnPkg ($pkg: PkgInputSpec!, $vulnerability: VulnerabilityInputSpec!, $certifyVuln: ScanMetadataInput!) { +mutation IngestCertifyVulnPkg ($pkg: IDorPkgInput!, $vulnerability: IDorVulnerabilityInput!, $certifyVuln: ScanMetadataInput!) { ingestCertifyVuln(pkg: $pkg, vulnerability: $vulnerability, certifyVuln: $certifyVuln) } ` @@ -25002,8 +25124,8 @@ mutation IngestCertifyVulnPkg ($pkg: PkgInputSpec!, $vulnerability: Vulnerabilit func IngestCertifyVulnPkg( ctx context.Context, client graphql.Client, - pkg PkgInputSpec, - vulnerability VulnerabilityInputSpec, + pkg IDorPkgInput, + vulnerability IDorVulnerabilityInput, certifyVuln ScanMetadataInput, ) (*IngestCertifyVulnPkgResponse, error) { req := &graphql.Request{ @@ -25031,7 +25153,7 @@ func IngestCertifyVulnPkg( // The query or mutation executed by IngestCertifyVulnPkgs. const IngestCertifyVulnPkgs_Operation = ` -mutation IngestCertifyVulnPkgs ($pkgs: [PkgInputSpec!]!, $vulnerabilities: [VulnerabilityInputSpec!]!, $certifyVulns: [ScanMetadataInput!]!) { +mutation IngestCertifyVulnPkgs ($pkgs: [IDorPkgInput!]!, $vulnerabilities: [IDorVulnerabilityInput!]!, $certifyVulns: [ScanMetadataInput!]!) { ingestCertifyVulns(pkgs: $pkgs, vulnerabilities: $vulnerabilities, certifyVulns: $certifyVulns) } ` @@ -25039,8 +25161,8 @@ mutation IngestCertifyVulnPkgs ($pkgs: [PkgInputSpec!]!, $vulnerabilities: [Vuln func IngestCertifyVulnPkgs( ctx context.Context, client graphql.Client, - pkgs []PkgInputSpec, - vulnerabilities []VulnerabilityInputSpec, + pkgs []IDorPkgInput, + vulnerabilities []IDorVulnerabilityInput, certifyVulns []ScanMetadataInput, ) (*IngestCertifyVulnPkgsResponse, error) { req := &graphql.Request{ @@ -25068,7 +25190,7 @@ func IngestCertifyVulnPkgs( // The query or mutation executed by IngestHasMetadataArtifact. const IngestHasMetadataArtifact_Operation = ` -mutation IngestHasMetadataArtifact ($artifact: ArtifactInputSpec!, $hasMetadata: HasMetadataInputSpec!) { +mutation IngestHasMetadataArtifact ($artifact: IDorArtifactInput!, $hasMetadata: HasMetadataInputSpec!) { ingestHasMetadata(subject: {artifact:$artifact}, pkgMatchType: {pkg:ALL_VERSIONS}, hasMetadata: $hasMetadata) } ` @@ -25076,7 +25198,7 @@ mutation IngestHasMetadataArtifact ($artifact: ArtifactInputSpec!, $hasMetadata: func IngestHasMetadataArtifact( ctx context.Context, client graphql.Client, - artifact ArtifactInputSpec, + artifact IDorArtifactInput, hasMetadata HasMetadataInputSpec, ) (*IngestHasMetadataArtifactResponse, error) { req := &graphql.Request{ @@ -25103,7 +25225,7 @@ func IngestHasMetadataArtifact( // The query or mutation executed by IngestHasMetadataArtifacts. const IngestHasMetadataArtifacts_Operation = ` -mutation IngestHasMetadataArtifacts ($artifacts: [ArtifactInputSpec!]!, $hasMetadataList: [HasMetadataInputSpec!]!) { +mutation IngestHasMetadataArtifacts ($artifacts: [IDorArtifactInput!]!, $hasMetadataList: [HasMetadataInputSpec!]!) { ingestBulkHasMetadata(subjects: {artifacts:$artifacts}, pkgMatchType: {pkg:ALL_VERSIONS}, hasMetadataList: $hasMetadataList) } ` @@ -25111,7 +25233,7 @@ mutation IngestHasMetadataArtifacts ($artifacts: [ArtifactInputSpec!]!, $hasMeta func IngestHasMetadataArtifacts( ctx context.Context, client graphql.Client, - artifacts []ArtifactInputSpec, + artifacts []IDorArtifactInput, hasMetadataList []HasMetadataInputSpec, ) (*IngestHasMetadataArtifactsResponse, error) { req := &graphql.Request{ @@ -25138,7 +25260,7 @@ func IngestHasMetadataArtifacts( // The query or mutation executed by IngestHasMetadataPkg. const IngestHasMetadataPkg_Operation = ` -mutation IngestHasMetadataPkg ($pkg: PkgInputSpec!, $pkgMatchType: MatchFlags!, $hasMetadata: HasMetadataInputSpec!) { +mutation IngestHasMetadataPkg ($pkg: IDorPkgInput!, $pkgMatchType: MatchFlags!, $hasMetadata: HasMetadataInputSpec!) { ingestHasMetadata(subject: {package:$pkg}, pkgMatchType: $pkgMatchType, hasMetadata: $hasMetadata) } ` @@ -25146,7 +25268,7 @@ mutation IngestHasMetadataPkg ($pkg: PkgInputSpec!, $pkgMatchType: MatchFlags!, func IngestHasMetadataPkg( ctx context.Context, client graphql.Client, - pkg PkgInputSpec, + pkg IDorPkgInput, pkgMatchType MatchFlags, hasMetadata HasMetadataInputSpec, ) (*IngestHasMetadataPkgResponse, error) { @@ -25175,7 +25297,7 @@ func IngestHasMetadataPkg( // The query or mutation executed by IngestHasMetadataPkgs. const IngestHasMetadataPkgs_Operation = ` -mutation IngestHasMetadataPkgs ($pkgs: [PkgInputSpec!]!, $pkgMatchType: MatchFlags!, $hasMetadataList: [HasMetadataInputSpec!]!) { +mutation IngestHasMetadataPkgs ($pkgs: [IDorPkgInput!]!, $pkgMatchType: MatchFlags!, $hasMetadataList: [HasMetadataInputSpec!]!) { ingestBulkHasMetadata(subjects: {packages:$pkgs}, pkgMatchType: $pkgMatchType, hasMetadataList: $hasMetadataList) } ` @@ -25183,7 +25305,7 @@ mutation IngestHasMetadataPkgs ($pkgs: [PkgInputSpec!]!, $pkgMatchType: MatchFla func IngestHasMetadataPkgs( ctx context.Context, client graphql.Client, - pkgs []PkgInputSpec, + pkgs []IDorPkgInput, pkgMatchType MatchFlags, hasMetadataList []HasMetadataInputSpec, ) (*IngestHasMetadataPkgsResponse, error) { @@ -25212,7 +25334,7 @@ func IngestHasMetadataPkgs( // The query or mutation executed by IngestHasMetadataSrc. const IngestHasMetadataSrc_Operation = ` -mutation IngestHasMetadataSrc ($source: SourceInputSpec!, $hasMetadata: HasMetadataInputSpec!) { +mutation IngestHasMetadataSrc ($source: IDorSourceInput!, $hasMetadata: HasMetadataInputSpec!) { ingestHasMetadata(subject: {source:$source}, pkgMatchType: {pkg:ALL_VERSIONS}, hasMetadata: $hasMetadata) } ` @@ -25220,7 +25342,7 @@ mutation IngestHasMetadataSrc ($source: SourceInputSpec!, $hasMetadata: HasMetad func IngestHasMetadataSrc( ctx context.Context, client graphql.Client, - source SourceInputSpec, + source IDorSourceInput, hasMetadata HasMetadataInputSpec, ) (*IngestHasMetadataSrcResponse, error) { req := &graphql.Request{ @@ -25247,7 +25369,7 @@ func IngestHasMetadataSrc( // The query or mutation executed by IngestHasMetadataSrcs. const IngestHasMetadataSrcs_Operation = ` -mutation IngestHasMetadataSrcs ($sources: [SourceInputSpec!]!, $hasMetadataList: [HasMetadataInputSpec!]!) { +mutation IngestHasMetadataSrcs ($sources: [IDorSourceInput!]!, $hasMetadataList: [HasMetadataInputSpec!]!) { ingestBulkHasMetadata(subjects: {sources:$sources}, pkgMatchType: {pkg:ALL_VERSIONS}, hasMetadataList: $hasMetadataList) } ` @@ -25255,7 +25377,7 @@ mutation IngestHasMetadataSrcs ($sources: [SourceInputSpec!]!, $hasMetadataList: func IngestHasMetadataSrcs( ctx context.Context, client graphql.Client, - sources []SourceInputSpec, + sources []IDorSourceInput, hasMetadataList []HasMetadataInputSpec, ) (*IngestHasMetadataSrcsResponse, error) { req := &graphql.Request{ @@ -25282,7 +25404,7 @@ func IngestHasMetadataSrcs( // The query or mutation executed by IngestHasSBOMArtifact. const IngestHasSBOMArtifact_Operation = ` -mutation IngestHasSBOMArtifact ($artifact: ArtifactInputSpec!, $hasSBOM: HasSBOMInputSpec!, $includes: HasSBOMIncludesInputSpec!) { +mutation IngestHasSBOMArtifact ($artifact: IDorArtifactInput!, $hasSBOM: HasSBOMInputSpec!, $includes: HasSBOMIncludesInputSpec!) { ingestHasSBOM(subject: {artifact:$artifact}, hasSBOM: $hasSBOM, includes: $includes) } ` @@ -25290,7 +25412,7 @@ mutation IngestHasSBOMArtifact ($artifact: ArtifactInputSpec!, $hasSBOM: HasSBOM func IngestHasSBOMArtifact( ctx context.Context, client graphql.Client, - artifact ArtifactInputSpec, + artifact IDorArtifactInput, hasSBOM HasSBOMInputSpec, includes HasSBOMIncludesInputSpec, ) (*IngestHasSBOMArtifactResponse, error) { @@ -25319,7 +25441,7 @@ func IngestHasSBOMArtifact( // The query or mutation executed by IngestHasSBOMArtifacts. const IngestHasSBOMArtifacts_Operation = ` -mutation IngestHasSBOMArtifacts ($artifacts: [ArtifactInputSpec!]!, $hasSBOMs: [HasSBOMInputSpec!]!, $includes: [HasSBOMIncludesInputSpec!]!) { +mutation IngestHasSBOMArtifacts ($artifacts: [IDorArtifactInput!]!, $hasSBOMs: [HasSBOMInputSpec!]!, $includes: [HasSBOMIncludesInputSpec!]!) { ingestHasSBOMs(subjects: {artifacts:$artifacts}, hasSBOMs: $hasSBOMs, includes: $includes) } ` @@ -25327,7 +25449,7 @@ mutation IngestHasSBOMArtifacts ($artifacts: [ArtifactInputSpec!]!, $hasSBOMs: [ func IngestHasSBOMArtifacts( ctx context.Context, client graphql.Client, - artifacts []ArtifactInputSpec, + artifacts []IDorArtifactInput, hasSBOMs []HasSBOMInputSpec, includes []HasSBOMIncludesInputSpec, ) (*IngestHasSBOMArtifactsResponse, error) { @@ -25356,7 +25478,7 @@ func IngestHasSBOMArtifacts( // The query or mutation executed by IngestHasSBOMPkg. const IngestHasSBOMPkg_Operation = ` -mutation IngestHasSBOMPkg ($pkg: PkgInputSpec!, $hasSBOM: HasSBOMInputSpec!, $includes: HasSBOMIncludesInputSpec!) { +mutation IngestHasSBOMPkg ($pkg: IDorPkgInput!, $hasSBOM: HasSBOMInputSpec!, $includes: HasSBOMIncludesInputSpec!) { ingestHasSBOM(subject: {package:$pkg}, hasSBOM: $hasSBOM, includes: $includes) } ` @@ -25364,7 +25486,7 @@ mutation IngestHasSBOMPkg ($pkg: PkgInputSpec!, $hasSBOM: HasSBOMInputSpec!, $in func IngestHasSBOMPkg( ctx context.Context, client graphql.Client, - pkg PkgInputSpec, + pkg IDorPkgInput, hasSBOM HasSBOMInputSpec, includes HasSBOMIncludesInputSpec, ) (*IngestHasSBOMPkgResponse, error) { @@ -25393,7 +25515,7 @@ func IngestHasSBOMPkg( // The query or mutation executed by IngestHasSBOMPkgs. const IngestHasSBOMPkgs_Operation = ` -mutation IngestHasSBOMPkgs ($pkgs: [PkgInputSpec!]!, $hasSBOMs: [HasSBOMInputSpec!]!, $includes: [HasSBOMIncludesInputSpec!]!) { +mutation IngestHasSBOMPkgs ($pkgs: [IDorPkgInput!]!, $hasSBOMs: [HasSBOMInputSpec!]!, $includes: [HasSBOMIncludesInputSpec!]!) { ingestHasSBOMs(subjects: {packages:$pkgs}, hasSBOMs: $hasSBOMs, includes: $includes) } ` @@ -25401,7 +25523,7 @@ mutation IngestHasSBOMPkgs ($pkgs: [PkgInputSpec!]!, $hasSBOMs: [HasSBOMInputSpe func IngestHasSBOMPkgs( ctx context.Context, client graphql.Client, - pkgs []PkgInputSpec, + pkgs []IDorPkgInput, hasSBOMs []HasSBOMInputSpec, includes []HasSBOMIncludesInputSpec, ) (*IngestHasSBOMPkgsResponse, error) { @@ -25430,7 +25552,7 @@ func IngestHasSBOMPkgs( // The query or mutation executed by IngestHasSourceAt. const IngestHasSourceAt_Operation = ` -mutation IngestHasSourceAt ($pkg: PkgInputSpec!, $pkgMatchType: MatchFlags!, $source: SourceInputSpec!, $hasSourceAt: HasSourceAtInputSpec!) { +mutation IngestHasSourceAt ($pkg: IDorPkgInput!, $pkgMatchType: MatchFlags!, $source: IDorSourceInput!, $hasSourceAt: HasSourceAtInputSpec!) { ingestHasSourceAt(pkg: $pkg, pkgMatchType: $pkgMatchType, source: $source, hasSourceAt: $hasSourceAt) } ` @@ -25438,9 +25560,9 @@ mutation IngestHasSourceAt ($pkg: PkgInputSpec!, $pkgMatchType: MatchFlags!, $so func IngestHasSourceAt( ctx context.Context, client graphql.Client, - pkg PkgInputSpec, + pkg IDorPkgInput, pkgMatchType MatchFlags, - source SourceInputSpec, + source IDorSourceInput, hasSourceAt HasSourceAtInputSpec, ) (*IngestHasSourceAtResponse, error) { req := &graphql.Request{ @@ -25469,7 +25591,7 @@ func IngestHasSourceAt( // The query or mutation executed by IngestHasSourcesAt. const IngestHasSourcesAt_Operation = ` -mutation IngestHasSourcesAt ($pkgs: [PkgInputSpec!]!, $pkgMatchType: MatchFlags!, $sources: [SourceInputSpec!]!, $hasSourceAts: [HasSourceAtInputSpec!]!) { +mutation IngestHasSourcesAt ($pkgs: [IDorPkgInput!]!, $pkgMatchType: MatchFlags!, $sources: [IDorSourceInput!]!, $hasSourceAts: [HasSourceAtInputSpec!]!) { ingestHasSourceAts(pkgs: $pkgs, pkgMatchType: $pkgMatchType, sources: $sources, hasSourceAts: $hasSourceAts) } ` @@ -25477,9 +25599,9 @@ mutation IngestHasSourcesAt ($pkgs: [PkgInputSpec!]!, $pkgMatchType: MatchFlags! func IngestHasSourcesAt( ctx context.Context, client graphql.Client, - pkgs []PkgInputSpec, + pkgs []IDorPkgInput, pkgMatchType MatchFlags, - sources []SourceInputSpec, + sources []IDorSourceInput, hasSourceAts []HasSourceAtInputSpec, ) (*IngestHasSourcesAtResponse, error) { req := &graphql.Request{ @@ -25508,7 +25630,7 @@ func IngestHasSourcesAt( // The query or mutation executed by IngestHashEqual. const IngestHashEqual_Operation = ` -mutation IngestHashEqual ($artifact: ArtifactInputSpec!, $otherArtifact: ArtifactInputSpec!, $hashEqual: HashEqualInputSpec!) { +mutation IngestHashEqual ($artifact: IDorArtifactInput!, $otherArtifact: IDorArtifactInput!, $hashEqual: HashEqualInputSpec!) { ingestHashEqual(artifact: $artifact, otherArtifact: $otherArtifact, hashEqual: $hashEqual) } ` @@ -25516,8 +25638,8 @@ mutation IngestHashEqual ($artifact: ArtifactInputSpec!, $otherArtifact: Artifac func IngestHashEqual( ctx context.Context, client graphql.Client, - artifact ArtifactInputSpec, - otherArtifact ArtifactInputSpec, + artifact IDorArtifactInput, + otherArtifact IDorArtifactInput, hashEqual HashEqualInputSpec, ) (*IngestHashEqualResponse, error) { req := &graphql.Request{ @@ -25545,7 +25667,7 @@ func IngestHashEqual( // The query or mutation executed by IngestHashEquals. const IngestHashEquals_Operation = ` -mutation IngestHashEquals ($artifacts: [ArtifactInputSpec!]!, $otherArtifacts: [ArtifactInputSpec!]!, $hashEquals: [HashEqualInputSpec!]!) { +mutation IngestHashEquals ($artifacts: [IDorArtifactInput!]!, $otherArtifacts: [IDorArtifactInput!]!, $hashEquals: [HashEqualInputSpec!]!) { ingestHashEquals(artifacts: $artifacts, otherArtifacts: $otherArtifacts, hashEquals: $hashEquals) } ` @@ -25553,8 +25675,8 @@ mutation IngestHashEquals ($artifacts: [ArtifactInputSpec!]!, $otherArtifacts: [ func IngestHashEquals( ctx context.Context, client graphql.Client, - artifacts []ArtifactInputSpec, - otherArtifacts []ArtifactInputSpec, + artifacts []IDorArtifactInput, + otherArtifacts []IDorArtifactInput, hashEquals []HashEqualInputSpec, ) (*IngestHashEqualsResponse, error) { req := &graphql.Request{ @@ -25582,7 +25704,7 @@ func IngestHashEquals( // The query or mutation executed by IngestIsDependencies. const IngestIsDependencies_Operation = ` -mutation IngestIsDependencies ($pkgs: [PkgInputSpec!]!, $depPkgs: [PkgInputSpec!]!, $depPkgMatchType: MatchFlags!, $dependencies: [IsDependencyInputSpec!]!) { +mutation IngestIsDependencies ($pkgs: [IDorPkgInput!]!, $depPkgs: [IDorPkgInput!]!, $depPkgMatchType: MatchFlags!, $dependencies: [IsDependencyInputSpec!]!) { ingestDependencies(pkgs: $pkgs, depPkgs: $depPkgs, depPkgMatchType: $depPkgMatchType, dependencies: $dependencies) } ` @@ -25590,8 +25712,8 @@ mutation IngestIsDependencies ($pkgs: [PkgInputSpec!]!, $depPkgs: [PkgInputSpec! func IngestIsDependencies( ctx context.Context, client graphql.Client, - pkgs []PkgInputSpec, - depPkgs []PkgInputSpec, + pkgs []IDorPkgInput, + depPkgs []IDorPkgInput, depPkgMatchType MatchFlags, dependencies []IsDependencyInputSpec, ) (*IngestIsDependenciesResponse, error) { @@ -25621,7 +25743,7 @@ func IngestIsDependencies( // The query or mutation executed by IngestIsDependency. const IngestIsDependency_Operation = ` -mutation IngestIsDependency ($pkg: PkgInputSpec!, $depPkg: PkgInputSpec!, $depPkgMatchType: MatchFlags!, $dependency: IsDependencyInputSpec!) { +mutation IngestIsDependency ($pkg: IDorPkgInput!, $depPkg: IDorPkgInput!, $depPkgMatchType: MatchFlags!, $dependency: IsDependencyInputSpec!) { ingestDependency(pkg: $pkg, depPkg: $depPkg, depPkgMatchType: $depPkgMatchType, dependency: $dependency) } ` @@ -25629,8 +25751,8 @@ mutation IngestIsDependency ($pkg: PkgInputSpec!, $depPkg: PkgInputSpec!, $depPk func IngestIsDependency( ctx context.Context, client graphql.Client, - pkg PkgInputSpec, - depPkg PkgInputSpec, + pkg IDorPkgInput, + depPkg IDorPkgInput, depPkgMatchType MatchFlags, dependency IsDependencyInputSpec, ) (*IngestIsDependencyResponse, error) { @@ -25660,7 +25782,7 @@ func IngestIsDependency( // The query or mutation executed by IngestIsOccurrencePkg. const IngestIsOccurrencePkg_Operation = ` -mutation IngestIsOccurrencePkg ($pkg: PkgInputSpec!, $artifact: ArtifactInputSpec!, $occurrence: IsOccurrenceInputSpec!) { +mutation IngestIsOccurrencePkg ($pkg: IDorPkgInput!, $artifact: IDorArtifactInput!, $occurrence: IsOccurrenceInputSpec!) { ingestOccurrence(subject: {package:$pkg}, artifact: $artifact, occurrence: $occurrence) } ` @@ -25668,8 +25790,8 @@ mutation IngestIsOccurrencePkg ($pkg: PkgInputSpec!, $artifact: ArtifactInputSpe func IngestIsOccurrencePkg( ctx context.Context, client graphql.Client, - pkg PkgInputSpec, - artifact ArtifactInputSpec, + pkg IDorPkgInput, + artifact IDorArtifactInput, occurrence IsOccurrenceInputSpec, ) (*IngestIsOccurrencePkgResponse, error) { req := &graphql.Request{ @@ -25697,7 +25819,7 @@ func IngestIsOccurrencePkg( // The query or mutation executed by IngestIsOccurrenceSrc. const IngestIsOccurrenceSrc_Operation = ` -mutation IngestIsOccurrenceSrc ($source: SourceInputSpec!, $artifact: ArtifactInputSpec!, $occurrence: IsOccurrenceInputSpec!) { +mutation IngestIsOccurrenceSrc ($source: IDorSourceInput!, $artifact: IDorArtifactInput!, $occurrence: IsOccurrenceInputSpec!) { ingestOccurrence(subject: {source:$source}, artifact: $artifact, occurrence: $occurrence) } ` @@ -25705,8 +25827,8 @@ mutation IngestIsOccurrenceSrc ($source: SourceInputSpec!, $artifact: ArtifactIn func IngestIsOccurrenceSrc( ctx context.Context, client graphql.Client, - source SourceInputSpec, - artifact ArtifactInputSpec, + source IDorSourceInput, + artifact IDorArtifactInput, occurrence IsOccurrenceInputSpec, ) (*IngestIsOccurrenceSrcResponse, error) { req := &graphql.Request{ @@ -25734,7 +25856,7 @@ func IngestIsOccurrenceSrc( // The query or mutation executed by IngestIsOccurrencesPkg. const IngestIsOccurrencesPkg_Operation = ` -mutation IngestIsOccurrencesPkg ($pkgs: [PkgInputSpec!]!, $artifacts: [ArtifactInputSpec!]!, $occurrences: [IsOccurrenceInputSpec!]!) { +mutation IngestIsOccurrencesPkg ($pkgs: [IDorPkgInput!]!, $artifacts: [IDorArtifactInput!]!, $occurrences: [IsOccurrenceInputSpec!]!) { ingestOccurrences(subjects: {packages:$pkgs}, artifacts: $artifacts, occurrences: $occurrences) } ` @@ -25742,8 +25864,8 @@ mutation IngestIsOccurrencesPkg ($pkgs: [PkgInputSpec!]!, $artifacts: [ArtifactI func IngestIsOccurrencesPkg( ctx context.Context, client graphql.Client, - pkgs []PkgInputSpec, - artifacts []ArtifactInputSpec, + pkgs []IDorPkgInput, + artifacts []IDorArtifactInput, occurrences []IsOccurrenceInputSpec, ) (*IngestIsOccurrencesPkgResponse, error) { req := &graphql.Request{ @@ -25771,7 +25893,7 @@ func IngestIsOccurrencesPkg( // The query or mutation executed by IngestIsOccurrencesSrc. const IngestIsOccurrencesSrc_Operation = ` -mutation IngestIsOccurrencesSrc ($sources: [SourceInputSpec!]!, $artifacts: [ArtifactInputSpec!]!, $occurrences: [IsOccurrenceInputSpec!]!) { +mutation IngestIsOccurrencesSrc ($sources: [IDorSourceInput!]!, $artifacts: [IDorArtifactInput!]!, $occurrences: [IsOccurrenceInputSpec!]!) { ingestOccurrences(subjects: {sources:$sources}, artifacts: $artifacts, occurrences: $occurrences) } ` @@ -25779,8 +25901,8 @@ mutation IngestIsOccurrencesSrc ($sources: [SourceInputSpec!]!, $artifacts: [Art func IngestIsOccurrencesSrc( ctx context.Context, client graphql.Client, - sources []SourceInputSpec, - artifacts []ArtifactInputSpec, + sources []IDorSourceInput, + artifacts []IDorArtifactInput, occurrences []IsOccurrenceInputSpec, ) (*IngestIsOccurrencesSrcResponse, error) { req := &graphql.Request{ @@ -25808,7 +25930,7 @@ func IngestIsOccurrencesSrc( // The query or mutation executed by IngestLicense. const IngestLicense_Operation = ` -mutation IngestLicense ($license: LicenseInputSpec!) { +mutation IngestLicense ($license: IDorLicenseInput!) { ingestLicense(license: $license) } ` @@ -25816,7 +25938,7 @@ mutation IngestLicense ($license: LicenseInputSpec!) { func IngestLicense( ctx context.Context, client graphql.Client, - license LicenseInputSpec, + license IDorLicenseInput, ) (*IngestLicenseResponse, error) { req := &graphql.Request{ OpName: "IngestLicense", @@ -25841,7 +25963,7 @@ func IngestLicense( // The query or mutation executed by IngestLicenses. const IngestLicenses_Operation = ` -mutation IngestLicenses ($licenses: [LicenseInputSpec!]!) { +mutation IngestLicenses ($licenses: [IDorLicenseInput!]!) { ingestLicenses(licenses: $licenses) } ` @@ -25849,7 +25971,7 @@ mutation IngestLicenses ($licenses: [LicenseInputSpec!]!) { func IngestLicenses( ctx context.Context, client graphql.Client, - licenses []LicenseInputSpec, + licenses []IDorLicenseInput, ) (*IngestLicensesResponse, error) { req := &graphql.Request{ OpName: "IngestLicenses", @@ -25874,7 +25996,7 @@ func IngestLicenses( // The query or mutation executed by IngestPackage. const IngestPackage_Operation = ` -mutation IngestPackage ($pkg: PkgInputSpec!) { +mutation IngestPackage ($pkg: IDorPkgInput!) { ingestPackage(pkg: $pkg) { packageTypeID packageNamespaceID @@ -25887,7 +26009,7 @@ mutation IngestPackage ($pkg: PkgInputSpec!) { func IngestPackage( ctx context.Context, client graphql.Client, - pkg PkgInputSpec, + pkg IDorPkgInput, ) (*IngestPackageResponse, error) { req := &graphql.Request{ OpName: "IngestPackage", @@ -25912,7 +26034,7 @@ func IngestPackage( // The query or mutation executed by IngestPackages. const IngestPackages_Operation = ` -mutation IngestPackages ($pkgs: [PkgInputSpec!]!) { +mutation IngestPackages ($pkgs: [IDorPkgInput!]!) { ingestPackages(pkgs: $pkgs) { packageTypeID packageNamespaceID @@ -25925,7 +26047,7 @@ mutation IngestPackages ($pkgs: [PkgInputSpec!]!) { func IngestPackages( ctx context.Context, client graphql.Client, - pkgs []PkgInputSpec, + pkgs []IDorPkgInput, ) (*IngestPackagesResponse, error) { req := &graphql.Request{ OpName: "IngestPackages", @@ -25950,7 +26072,7 @@ func IngestPackages( // The query or mutation executed by IngestPkgEqual. const IngestPkgEqual_Operation = ` -mutation IngestPkgEqual ($pkg: PkgInputSpec!, $otherPackage: PkgInputSpec!, $pkgEqual: PkgEqualInputSpec!) { +mutation IngestPkgEqual ($pkg: IDorPkgInput!, $otherPackage: IDorPkgInput!, $pkgEqual: PkgEqualInputSpec!) { ingestPkgEqual(pkg: $pkg, otherPackage: $otherPackage, pkgEqual: $pkgEqual) } ` @@ -25958,8 +26080,8 @@ mutation IngestPkgEqual ($pkg: PkgInputSpec!, $otherPackage: PkgInputSpec!, $pkg func IngestPkgEqual( ctx context.Context, client graphql.Client, - pkg PkgInputSpec, - otherPackage PkgInputSpec, + pkg IDorPkgInput, + otherPackage IDorPkgInput, pkgEqual PkgEqualInputSpec, ) (*IngestPkgEqualResponse, error) { req := &graphql.Request{ @@ -25987,7 +26109,7 @@ func IngestPkgEqual( // The query or mutation executed by IngestPkgEquals. const IngestPkgEquals_Operation = ` -mutation IngestPkgEquals ($pkgs: [PkgInputSpec!]!, $otherPackages: [PkgInputSpec!]!, $pkgEquals: [PkgEqualInputSpec!]!) { +mutation IngestPkgEquals ($pkgs: [IDorPkgInput!]!, $otherPackages: [IDorPkgInput!]!, $pkgEquals: [PkgEqualInputSpec!]!) { ingestPkgEquals(pkgs: $pkgs, otherPackages: $otherPackages, pkgEquals: $pkgEquals) } ` @@ -25995,8 +26117,8 @@ mutation IngestPkgEquals ($pkgs: [PkgInputSpec!]!, $otherPackages: [PkgInputSpec func IngestPkgEquals( ctx context.Context, client graphql.Client, - pkgs []PkgInputSpec, - otherPackages []PkgInputSpec, + pkgs []IDorPkgInput, + otherPackages []IDorPkgInput, pkgEquals []PkgEqualInputSpec, ) (*IngestPkgEqualsResponse, error) { req := &graphql.Request{ @@ -26024,7 +26146,7 @@ func IngestPkgEquals( // The query or mutation executed by IngestPointOfContactArtifact. const IngestPointOfContactArtifact_Operation = ` -mutation IngestPointOfContactArtifact ($artifact: ArtifactInputSpec!, $pointOfContact: PointOfContactInputSpec!) { +mutation IngestPointOfContactArtifact ($artifact: IDorArtifactInput!, $pointOfContact: PointOfContactInputSpec!) { ingestPointOfContact(subject: {artifact:$artifact}, pkgMatchType: {pkg:ALL_VERSIONS}, pointOfContact: $pointOfContact) } ` @@ -26032,7 +26154,7 @@ mutation IngestPointOfContactArtifact ($artifact: ArtifactInputSpec!, $pointOfCo func IngestPointOfContactArtifact( ctx context.Context, client graphql.Client, - artifact ArtifactInputSpec, + artifact IDorArtifactInput, pointOfContact PointOfContactInputSpec, ) (*IngestPointOfContactArtifactResponse, error) { req := &graphql.Request{ @@ -26059,7 +26181,7 @@ func IngestPointOfContactArtifact( // The query or mutation executed by IngestPointOfContactArtifacts. const IngestPointOfContactArtifacts_Operation = ` -mutation IngestPointOfContactArtifacts ($artifacts: [ArtifactInputSpec!]!, $pointOfContacts: [PointOfContactInputSpec!]!) { +mutation IngestPointOfContactArtifacts ($artifacts: [IDorArtifactInput!]!, $pointOfContacts: [PointOfContactInputSpec!]!) { ingestPointOfContacts(subjects: {artifacts:$artifacts}, pkgMatchType: {pkg:ALL_VERSIONS}, pointOfContacts: $pointOfContacts) } ` @@ -26067,7 +26189,7 @@ mutation IngestPointOfContactArtifacts ($artifacts: [ArtifactInputSpec!]!, $poin func IngestPointOfContactArtifacts( ctx context.Context, client graphql.Client, - artifacts []ArtifactInputSpec, + artifacts []IDorArtifactInput, pointOfContacts []PointOfContactInputSpec, ) (*IngestPointOfContactArtifactsResponse, error) { req := &graphql.Request{ @@ -26094,7 +26216,7 @@ func IngestPointOfContactArtifacts( // The query or mutation executed by IngestPointOfContactPkg. const IngestPointOfContactPkg_Operation = ` -mutation IngestPointOfContactPkg ($pkg: PkgInputSpec!, $pkgMatchType: MatchFlags!, $pointOfContact: PointOfContactInputSpec!) { +mutation IngestPointOfContactPkg ($pkg: IDorPkgInput!, $pkgMatchType: MatchFlags!, $pointOfContact: PointOfContactInputSpec!) { ingestPointOfContact(subject: {package:$pkg}, pkgMatchType: $pkgMatchType, pointOfContact: $pointOfContact) } ` @@ -26102,7 +26224,7 @@ mutation IngestPointOfContactPkg ($pkg: PkgInputSpec!, $pkgMatchType: MatchFlags func IngestPointOfContactPkg( ctx context.Context, client graphql.Client, - pkg PkgInputSpec, + pkg IDorPkgInput, pkgMatchType MatchFlags, pointOfContact PointOfContactInputSpec, ) (*IngestPointOfContactPkgResponse, error) { @@ -26131,7 +26253,7 @@ func IngestPointOfContactPkg( // The query or mutation executed by IngestPointOfContactPkgs. const IngestPointOfContactPkgs_Operation = ` -mutation IngestPointOfContactPkgs ($pkgs: [PkgInputSpec!]!, $pkgMatchType: MatchFlags!, $pointOfContacts: [PointOfContactInputSpec!]!) { +mutation IngestPointOfContactPkgs ($pkgs: [IDorPkgInput!]!, $pkgMatchType: MatchFlags!, $pointOfContacts: [PointOfContactInputSpec!]!) { ingestPointOfContacts(subjects: {packages:$pkgs}, pkgMatchType: $pkgMatchType, pointOfContacts: $pointOfContacts) } ` @@ -26139,7 +26261,7 @@ mutation IngestPointOfContactPkgs ($pkgs: [PkgInputSpec!]!, $pkgMatchType: Match func IngestPointOfContactPkgs( ctx context.Context, client graphql.Client, - pkgs []PkgInputSpec, + pkgs []IDorPkgInput, pkgMatchType MatchFlags, pointOfContacts []PointOfContactInputSpec, ) (*IngestPointOfContactPkgsResponse, error) { @@ -26168,7 +26290,7 @@ func IngestPointOfContactPkgs( // The query or mutation executed by IngestPointOfContactSrc. const IngestPointOfContactSrc_Operation = ` -mutation IngestPointOfContactSrc ($source: SourceInputSpec!, $pointOfContact: PointOfContactInputSpec!) { +mutation IngestPointOfContactSrc ($source: IDorSourceInput!, $pointOfContact: PointOfContactInputSpec!) { ingestPointOfContact(subject: {source:$source}, pkgMatchType: {pkg:ALL_VERSIONS}, pointOfContact: $pointOfContact) } ` @@ -26176,7 +26298,7 @@ mutation IngestPointOfContactSrc ($source: SourceInputSpec!, $pointOfContact: Po func IngestPointOfContactSrc( ctx context.Context, client graphql.Client, - source SourceInputSpec, + source IDorSourceInput, pointOfContact PointOfContactInputSpec, ) (*IngestPointOfContactSrcResponse, error) { req := &graphql.Request{ @@ -26203,7 +26325,7 @@ func IngestPointOfContactSrc( // The query or mutation executed by IngestPointOfContactSrcs. const IngestPointOfContactSrcs_Operation = ` -mutation IngestPointOfContactSrcs ($sources: [SourceInputSpec!]!, $pointOfContacts: [PointOfContactInputSpec!]!) { +mutation IngestPointOfContactSrcs ($sources: [IDorSourceInput!]!, $pointOfContacts: [PointOfContactInputSpec!]!) { ingestPointOfContacts(subjects: {sources:$sources}, pkgMatchType: {pkg:ALL_VERSIONS}, pointOfContacts: $pointOfContacts) } ` @@ -26211,7 +26333,7 @@ mutation IngestPointOfContactSrcs ($sources: [SourceInputSpec!]!, $pointOfContac func IngestPointOfContactSrcs( ctx context.Context, client graphql.Client, - sources []SourceInputSpec, + sources []IDorSourceInput, pointOfContacts []PointOfContactInputSpec, ) (*IngestPointOfContactSrcsResponse, error) { req := &graphql.Request{ @@ -26238,7 +26360,7 @@ func IngestPointOfContactSrcs( // The query or mutation executed by IngestSLSAForArtifact. const IngestSLSAForArtifact_Operation = ` -mutation IngestSLSAForArtifact ($artifact: ArtifactInputSpec!, $materials: [ArtifactInputSpec!]!, $builder: BuilderInputSpec!, $slsa: SLSAInputSpec!) { +mutation IngestSLSAForArtifact ($artifact: IDorArtifactInput!, $materials: [IDorArtifactInput!]!, $builder: IDorBuilderInput!, $slsa: SLSAInputSpec!) { ingestSLSA(subject: $artifact, builtFrom: $materials, builtBy: $builder, slsa: $slsa) } ` @@ -26246,9 +26368,9 @@ mutation IngestSLSAForArtifact ($artifact: ArtifactInputSpec!, $materials: [Arti func IngestSLSAForArtifact( ctx context.Context, client graphql.Client, - artifact ArtifactInputSpec, - materials []ArtifactInputSpec, - builder BuilderInputSpec, + artifact IDorArtifactInput, + materials []IDorArtifactInput, + builder IDorBuilderInput, slsa SLSAInputSpec, ) (*IngestSLSAForArtifactResponse, error) { req := &graphql.Request{ @@ -26277,7 +26399,7 @@ func IngestSLSAForArtifact( // The query or mutation executed by IngestSLSAForArtifacts. const IngestSLSAForArtifacts_Operation = ` -mutation IngestSLSAForArtifacts ($artifacts: [ArtifactInputSpec!]!, $materialsList: [[ArtifactInputSpec!]!]!, $builders: [BuilderInputSpec!]!, $slsaList: [SLSAInputSpec!]!) { +mutation IngestSLSAForArtifacts ($artifacts: [IDorArtifactInput!]!, $materialsList: [[IDorArtifactInput!]!]!, $builders: [IDorBuilderInput!]!, $slsaList: [SLSAInputSpec!]!) { ingestSLSAs(subjects: $artifacts, builtFromList: $materialsList, builtByList: $builders, slsaList: $slsaList) } ` @@ -26285,9 +26407,9 @@ mutation IngestSLSAForArtifacts ($artifacts: [ArtifactInputSpec!]!, $materialsLi func IngestSLSAForArtifacts( ctx context.Context, client graphql.Client, - artifacts []ArtifactInputSpec, - materialsList [][]ArtifactInputSpec, - builders []BuilderInputSpec, + artifacts []IDorArtifactInput, + materialsList [][]IDorArtifactInput, + builders []IDorBuilderInput, slsaList []SLSAInputSpec, ) (*IngestSLSAForArtifactsResponse, error) { req := &graphql.Request{ @@ -26316,7 +26438,7 @@ func IngestSLSAForArtifacts( // The query or mutation executed by IngestSource. const IngestSource_Operation = ` -mutation IngestSource ($source: SourceInputSpec!) { +mutation IngestSource ($source: IDorSourceInput!) { ingestSource(source: $source) { sourceTypeID sourceNamespaceID @@ -26328,7 +26450,7 @@ mutation IngestSource ($source: SourceInputSpec!) { func IngestSource( ctx context.Context, client graphql.Client, - source SourceInputSpec, + source IDorSourceInput, ) (*IngestSourceResponse, error) { req := &graphql.Request{ OpName: "IngestSource", @@ -26353,7 +26475,7 @@ func IngestSource( // The query or mutation executed by IngestSources. const IngestSources_Operation = ` -mutation IngestSources ($sources: [SourceInputSpec!]!) { +mutation IngestSources ($sources: [IDorSourceInput!]!) { ingestSources(sources: $sources) { sourceTypeID sourceNamespaceID @@ -26365,7 +26487,7 @@ mutation IngestSources ($sources: [SourceInputSpec!]!) { func IngestSources( ctx context.Context, client graphql.Client, - sources []SourceInputSpec, + sources []IDorSourceInput, ) (*IngestSourcesResponse, error) { req := &graphql.Request{ OpName: "IngestSources", @@ -26390,7 +26512,7 @@ func IngestSources( // The query or mutation executed by IngestVulnEqual. const IngestVulnEqual_Operation = ` -mutation IngestVulnEqual ($vulnerability: VulnerabilityInputSpec!, $otherVulnerability: VulnerabilityInputSpec!, $vulnEqual: VulnEqualInputSpec!) { +mutation IngestVulnEqual ($vulnerability: IDorVulnerabilityInput!, $otherVulnerability: IDorVulnerabilityInput!, $vulnEqual: VulnEqualInputSpec!) { ingestVulnEqual(vulnerability: $vulnerability, otherVulnerability: $otherVulnerability, vulnEqual: $vulnEqual) } ` @@ -26398,8 +26520,8 @@ mutation IngestVulnEqual ($vulnerability: VulnerabilityInputSpec!, $otherVulnera func IngestVulnEqual( ctx context.Context, client graphql.Client, - vulnerability VulnerabilityInputSpec, - otherVulnerability VulnerabilityInputSpec, + vulnerability IDorVulnerabilityInput, + otherVulnerability IDorVulnerabilityInput, vulnEqual VulnEqualInputSpec, ) (*IngestVulnEqualResponse, error) { req := &graphql.Request{ @@ -26427,7 +26549,7 @@ func IngestVulnEqual( // The query or mutation executed by IngestVulnEquals. const IngestVulnEquals_Operation = ` -mutation IngestVulnEquals ($vulnerabilities: [VulnerabilityInputSpec!]!, $otherVulnerabilities: [VulnerabilityInputSpec!]!, $vulnEquals: [VulnEqualInputSpec!]!) { +mutation IngestVulnEquals ($vulnerabilities: [IDorVulnerabilityInput!]!, $otherVulnerabilities: [IDorVulnerabilityInput!]!, $vulnEquals: [VulnEqualInputSpec!]!) { ingestVulnEquals(vulnerabilities: $vulnerabilities, otherVulnerabilities: $otherVulnerabilities, vulnEquals: $vulnEquals) } ` @@ -26435,8 +26557,8 @@ mutation IngestVulnEquals ($vulnerabilities: [VulnerabilityInputSpec!]!, $otherV func IngestVulnEquals( ctx context.Context, client graphql.Client, - vulnerabilities []VulnerabilityInputSpec, - otherVulnerabilities []VulnerabilityInputSpec, + vulnerabilities []IDorVulnerabilityInput, + otherVulnerabilities []IDorVulnerabilityInput, vulnEquals []VulnEqualInputSpec, ) (*IngestVulnEqualsResponse, error) { req := &graphql.Request{ @@ -26464,7 +26586,7 @@ func IngestVulnEquals( // The query or mutation executed by IngestVulnHasMetadata. const IngestVulnHasMetadata_Operation = ` -mutation IngestVulnHasMetadata ($vulnerability: VulnerabilityInputSpec!, $vulnMetadata: VulnerabilityMetadataInputSpec!) { +mutation IngestVulnHasMetadata ($vulnerability: IDorVulnerabilityInput!, $vulnMetadata: VulnerabilityMetadataInputSpec!) { ingestVulnerabilityMetadata(vulnerability: $vulnerability, vulnerabilityMetadata: $vulnMetadata) } ` @@ -26472,7 +26594,7 @@ mutation IngestVulnHasMetadata ($vulnerability: VulnerabilityInputSpec!, $vulnMe func IngestVulnHasMetadata( ctx context.Context, client graphql.Client, - vulnerability VulnerabilityInputSpec, + vulnerability IDorVulnerabilityInput, vulnMetadata VulnerabilityMetadataInputSpec, ) (*IngestVulnHasMetadataResponse, error) { req := &graphql.Request{ @@ -26499,7 +26621,7 @@ func IngestVulnHasMetadata( // The query or mutation executed by IngestVulnerabilities. const IngestVulnerabilities_Operation = ` -mutation IngestVulnerabilities ($vulns: [VulnerabilityInputSpec!]!) { +mutation IngestVulnerabilities ($vulns: [IDorVulnerabilityInput!]!) { ingestVulnerabilities(vulns: $vulns) { vulnerabilityTypeID vulnerabilityNodeID @@ -26510,7 +26632,7 @@ mutation IngestVulnerabilities ($vulns: [VulnerabilityInputSpec!]!) { func IngestVulnerabilities( ctx context.Context, client graphql.Client, - vulns []VulnerabilityInputSpec, + vulns []IDorVulnerabilityInput, ) (*IngestVulnerabilitiesResponse, error) { req := &graphql.Request{ OpName: "IngestVulnerabilities", @@ -26535,7 +26657,7 @@ func IngestVulnerabilities( // The query or mutation executed by IngestVulnerability. const IngestVulnerability_Operation = ` -mutation IngestVulnerability ($vuln: VulnerabilityInputSpec!) { +mutation IngestVulnerability ($vuln: IDorVulnerabilityInput!) { ingestVulnerability(vuln: $vuln) { vulnerabilityTypeID vulnerabilityNodeID @@ -26546,7 +26668,7 @@ mutation IngestVulnerability ($vuln: VulnerabilityInputSpec!) { func IngestVulnerability( ctx context.Context, client graphql.Client, - vuln VulnerabilityInputSpec, + vuln IDorVulnerabilityInput, ) (*IngestVulnerabilityResponse, error) { req := &graphql.Request{ OpName: "IngestVulnerability", diff --git a/pkg/assembler/clients/helpers/assembler.go b/pkg/assembler/clients/helpers/assembler.go index 58ed73ab7d..2bf6e977c8 100644 --- a/pkg/assembler/clients/helpers/assembler.go +++ b/pkg/assembler/clients/helpers/assembler.go @@ -23,6 +23,7 @@ import ( "github.com/guacsec/guac/pkg/assembler" model "github.com/guacsec/guac/pkg/assembler/clients/generated" + "github.com/guacsec/guac/pkg/assembler/helpers" "github.com/guacsec/guac/pkg/logging" ) @@ -31,69 +32,89 @@ func GetAssembler(ctx context.Context, gqlclient graphql.Client) func([]assemble return func(preds []assembler.IngestPredicates) error { for _, p := range preds { var packageAndArtifactIDs []string + collectedIDorPkgInputs := make(map[string]*model.IDorPkgInput) packages := p.GetPackages(ctx) logger.Infof("assembling Package: %v", len(packages)) - for _, v := range packages { - if id, err := ingestPackage(ctx, gqlclient, v); err != nil { - return err + for _, p := range packages { + if id, err := ingestPackage(ctx, gqlclient, p); err != nil { + return fmt.Errorf("failed package ingest with error: %w", err) } else { - packageAndArtifactIDs = append(packageAndArtifactIDs, *id) + collectedIDorPkgInputs[helpers.PkgInputSpecToPurl(p.PackageInput)] = id + packageAndArtifactIDs = append(packageAndArtifactIDs, *id.PackageVersionID) } } + collectedIDorSrcInputs := make(map[string]*model.IDorSourceInput) sources := p.GetSources(ctx) logger.Infof("assembling Source: %v", len(sources)) - for _, v := range sources { - if err := ingestSource(ctx, gqlclient, v); err != nil { - return err + for _, s := range sources { + if id, err := ingestSource(ctx, gqlclient, s); err != nil { + return fmt.Errorf("failed source ingest with error: %w", err) + } else { + collectedIDorSrcInputs[helpers.ConcatenateSourceInput(s.SourceInput)] = id } } + collectedIDorArtInputs := make(map[string]*model.IDorArtifactInput) artifacts := p.GetArtifacts(ctx) logger.Infof("assembling Artifact: %v", len(artifacts)) - for _, v := range artifacts { - if id, err := ingestArtifact(ctx, gqlclient, v); err != nil { - return err + for _, a := range artifacts { + if id, err := ingestArtifact(ctx, gqlclient, a); err != nil { + return fmt.Errorf("failed artifact ingest with error: %w", err) } else { - packageAndArtifactIDs = append(packageAndArtifactIDs, *id) + collectedIDorArtInputs[helpers.ArtifactKey(a.ArtifactInput)] = id + packageAndArtifactIDs = append(packageAndArtifactIDs, *id.ArtifactID) } } materials := p.GetMaterials(ctx) logger.Infof("assembling Materials (Artifact): %v", len(materials)) - if ids, err := ingestArtifacts(ctx, gqlclient, materials); err != nil { - return err - } else { - packageAndArtifactIDs = append(packageAndArtifactIDs, ids...) + collectedIDorMatInputs, err := ingestArtifacts(ctx, gqlclient, materials) + if err != nil { + return fmt.Errorf("failed materials (artifacts) ingest with error: %w", err) + } + var matIDs []string + for _, matID := range collectedIDorMatInputs { + matIDs = append(matIDs, *matID.ArtifactID) } + packageAndArtifactIDs = append(packageAndArtifactIDs, matIDs...) + collectedIDorBuilderInputs := make(map[string]*model.IDorBuilderInput) builders := p.GetBuilders(ctx) logger.Infof("assembling Builder: %v", len(builders)) for _, v := range builders { - if err := ingestBuilder(ctx, gqlclient, v); err != nil { - return err + if id, err := ingestBuilder(ctx, gqlclient, v); err != nil { + return fmt.Errorf("failed builder ingest with error: %w", err) + } else { + collectedIDorBuilderInputs[v.BuilderInput.Uri] = id } } + collectedIDorVulnInputs := make(map[string]*model.IDorVulnerabilityInput) vulns := p.GetVulnerabilities(ctx) logger.Infof("assembling Vulnerability: %v", len(vulns)) for _, v := range vulns { - if err := ingestVulnerability(ctx, gqlclient, v); err != nil { - return err + if id, err := ingestVulnerability(ctx, gqlclient, v); err != nil { + return fmt.Errorf("failed vulnerability ingest with error: %w", err) + } else { + collectedIDorVulnInputs[helpers.VulnInputToVURI(v.VulnerabilityInput)] = id } } + collectedIDorLicenseInputs := make(map[string]*model.IDorLicenseInput) licenses := p.GetLicenses(ctx) logger.Infof("assembling License: %v", len(licenses)) - for _, v := range licenses { - if err := ingestLicense(ctx, gqlclient, &v); err != nil { - return err + for _, l := range licenses { + if id, err := ingestLicense(ctx, gqlclient, l); err != nil { + return fmt.Errorf("failed license ingest with error: %w", err) + } else { + collectedIDorLicenseInputs[helpers.LicenseKey(l.LicenseInput)] = id } } logger.Infof("assembling CertifyScorecard: %v", len(p.CertifyScorecard)) for _, v := range p.CertifyScorecard { - if err := ingestCertifyScorecard(ctx, gqlclient, v); err != nil { + if err := ingestCertifyScorecard(ctx, gqlclient, v, collectedIDorSrcInputs); err != nil { return err } } @@ -101,7 +122,7 @@ func GetAssembler(ctx context.Context, gqlclient graphql.Client) func([]assemble var isDependenciesIDs []string logger.Infof("assembling IsDependency: %v", len(p.IsDependency)) for _, v := range p.IsDependency { - if id, err := ingestIsDependency(ctx, gqlclient, v); err != nil { + if id, err := ingestIsDependency(ctx, gqlclient, v, collectedIDorPkgInputs); err != nil { return err } else { isDependenciesIDs = append(isDependenciesIDs, *id) @@ -111,7 +132,7 @@ func GetAssembler(ctx context.Context, gqlclient graphql.Client) func([]assemble var isOccurrencesIDs []string logger.Infof("assembling IsOccurrence: %v", len(p.IsOccurrence)) for _, v := range p.IsOccurrence { - if id, err := ingestIsOccurrence(ctx, gqlclient, v); err != nil { + if id, err := ingestIsOccurrence(ctx, gqlclient, v, collectedIDorPkgInputs, collectedIDorArtInputs, collectedIDorSrcInputs); err != nil { return err } else { isOccurrencesIDs = append(isOccurrencesIDs, *id) @@ -120,63 +141,63 @@ func GetAssembler(ctx context.Context, gqlclient graphql.Client) func([]assemble logger.Infof("assembling HasSLSA: %v", len(p.HasSlsa)) for _, v := range p.HasSlsa { - if err := ingestHasSlsa(ctx, gqlclient, v); err != nil { + if err := ingestHasSlsa(ctx, gqlclient, v, collectedIDorArtInputs, collectedIDorMatInputs, collectedIDorBuilderInputs); err != nil { return err } } logger.Infof("assembling CertifyVuln: %v", len(p.CertifyVuln)) for _, cv := range p.CertifyVuln { - if err := ingestCertifyVuln(ctx, gqlclient, cv); err != nil { + if err := ingestCertifyVuln(ctx, gqlclient, cv, collectedIDorPkgInputs, collectedIDorVulnInputs); err != nil { return err } } logger.Infof("assembling VulnMetadata: %v", len(p.VulnMetadata)) for _, vm := range p.VulnMetadata { - if err := ingestVulnMetadata(ctx, gqlclient, vm); err != nil { + if err := ingestVulnMetadata(ctx, gqlclient, vm, collectedIDorVulnInputs); err != nil { return err } } logger.Infof("assembling VulnEqual: %v", len(p.VulnEqual)) for _, ve := range p.VulnEqual { - if err := ingestVulnEqual(ctx, gqlclient, ve); err != nil { + if err := ingestVulnEqual(ctx, gqlclient, ve, collectedIDorVulnInputs); err != nil { return err } } logger.Infof("assembling HasSourceAt: %v", len(p.HasSourceAt)) for _, hsa := range p.HasSourceAt { - if err := hasSourceAt(ctx, gqlclient, hsa); err != nil { + if err := hasSourceAt(ctx, gqlclient, hsa, collectedIDorPkgInputs, collectedIDorSrcInputs); err != nil { return err } } logger.Infof("assembling CertifyBad: %v", len(p.CertifyBad)) for _, bad := range p.CertifyBad { - if err := ingestCertifyBad(ctx, gqlclient, bad); err != nil { + if err := ingestCertifyBad(ctx, gqlclient, bad, collectedIDorPkgInputs, collectedIDorArtInputs, collectedIDorSrcInputs); err != nil { return err } } logger.Infof("assembling CertifyGood: %v", len(p.CertifyGood)) for _, good := range p.CertifyGood { - if err := ingestCertifyGood(ctx, gqlclient, good); err != nil { + if err := ingestCertifyGood(ctx, gqlclient, good, collectedIDorPkgInputs, collectedIDorArtInputs, collectedIDorSrcInputs); err != nil { return err } } logger.Infof("assembling PointOfContact: %v", len(p.PointOfContact)) for _, poc := range p.PointOfContact { - if err := ingestPointOfContact(ctx, gqlclient, poc); err != nil { + if err := ingestPointOfContact(ctx, gqlclient, poc, collectedIDorPkgInputs, collectedIDorArtInputs, collectedIDorSrcInputs); err != nil { return err } } logger.Infof("assembling HasMetadata: %v", len(p.HasMetadata)) for _, hm := range p.HasMetadata { - if err := ingestHasMetadata(ctx, gqlclient, hm); err != nil { + if err := ingestHasMetadata(ctx, gqlclient, hm, collectedIDorPkgInputs, collectedIDorArtInputs, collectedIDorSrcInputs); err != nil { return err } } @@ -190,35 +211,35 @@ func GetAssembler(ctx context.Context, gqlclient graphql.Client) func([]assemble logger.Infof("assembling HasSBOM: %v", len(p.HasSBOM)) for _, hb := range p.HasSBOM { hb.Includes = &includes - if err := ingestHasSBOM(ctx, gqlclient, hb); err != nil { + if err := ingestHasSBOM(ctx, gqlclient, hb, collectedIDorPkgInputs, collectedIDorArtInputs); err != nil { return err } } logger.Infof("assembling VEX : %v", len(p.Vex)) for _, v := range p.Vex { - if err := ingestVex(ctx, gqlclient, v); err != nil { + if err := ingestVex(ctx, gqlclient, v, collectedIDorPkgInputs, collectedIDorArtInputs, collectedIDorVulnInputs); err != nil { return err } } logger.Infof("assembling HashEqual : %v", len(p.HashEqual)) for _, equal := range p.HashEqual { - if err := ingestHashEqual(ctx, gqlclient, equal); err != nil { + if err := ingestHashEqual(ctx, gqlclient, equal, collectedIDorArtInputs); err != nil { return err } } logger.Infof("assembling PkgEqual : %v", len(p.PkgEqual)) for _, equal := range p.PkgEqual { - if err := ingestPkgEqual(ctx, gqlclient, equal); err != nil { + if err := ingestPkgEqual(ctx, gqlclient, equal, collectedIDorPkgInputs); err != nil { return err } } logger.Infof("assembling CertifyLegal : %v", len(p.CertifyLegal)) for _, cl := range p.CertifyLegal { - if err := ingestCertifyLegal(ctx, gqlclient, cl); err != nil { + if err := ingestCertifyLegal(ctx, gqlclient, cl, collectedIDorPkgInputs, collectedIDorSrcInputs, collectedIDorLicenseInputs); err != nil { return err } } @@ -227,88 +248,193 @@ func GetAssembler(ctx context.Context, gqlclient graphql.Client) func([]assemble } } -func ingestPackage(ctx context.Context, client graphql.Client, v *model.PkgInputSpec) (*string, error) { - if result, err := model.IngestPackage(ctx, client, *v); err != nil { - return nil, err +// ingestPackages takes in IDorPkgInput which contains the pkgInputSpec and outputs IDorPkgInput that contains the pkgIDs to be used for verb ingestion +func ingestPackage(ctx context.Context, client graphql.Client, p *model.IDorPkgInput) (*model.IDorPkgInput, error) { + if result, err := model.IngestPackage(ctx, client, *p); err != nil { + return nil, fmt.Errorf("IngestPackage failed with error: %w", err) } else { - return &result.IngestPackage.PackageVersionID, nil + return &model.IDorPkgInput{ + PackageInput: p.PackageInput, + PackageTypeID: &result.IngestPackage.PackageTypeID, + PackageNamespaceID: &result.IngestPackage.PackageNamespaceID, + PackageNameID: &result.IngestPackage.PackageNameID, + PackageVersionID: &result.IngestPackage.PackageVersionID, + }, nil } } -func ingestSource(ctx context.Context, client graphql.Client, v *model.SourceInputSpec) error { - _, err := model.IngestSource(ctx, client, *v) - return err +func ingestSource(ctx context.Context, client graphql.Client, s *model.IDorSourceInput) (*model.IDorSourceInput, error) { + if result, err := model.IngestSource(ctx, client, *s); err != nil { + return nil, fmt.Errorf("IngestSource failed with error: %w", err) + } else { + return &model.IDorSourceInput{ + SourceInput: s.SourceInput, + SourceTypeID: &result.IngestSource.SourceTypeID, + SourceNamespaceID: &result.IngestSource.SourceNamespaceID, + SourceNameID: &result.IngestSource.SourceNameID, + }, nil + } } -func ingestArtifact(ctx context.Context, client graphql.Client, v *model.ArtifactInputSpec) (*string, error) { - if result, err := model.IngestArtifact(ctx, client, *v); err != nil { - return nil, err +func ingestArtifact(ctx context.Context, client graphql.Client, a *model.IDorArtifactInput) (*model.IDorArtifactInput, error) { + if result, err := model.IngestArtifact(ctx, client, *a); err != nil { + return nil, fmt.Errorf("IngestArtifact failed with error: %w", err) } else { - return &result.IngestArtifact, err + return &model.IDorArtifactInput{ArtifactID: &result.IngestArtifact, ArtifactInput: a.ArtifactInput}, err } } -func ingestBuilder(ctx context.Context, client graphql.Client, v *model.BuilderInputSpec) error { - _, err := model.IngestBuilder(ctx, client, *v) - return err +func ingestBuilder(ctx context.Context, client graphql.Client, b *model.IDorBuilderInput) (*model.IDorBuilderInput, error) { + if result, err := model.IngestBuilder(ctx, client, *b); err != nil { + return nil, fmt.Errorf("IngestBuilder failed with error: %w", err) + } else { + return &model.IDorBuilderInput{BuilderID: &result.IngestBuilder, BuilderInput: b.BuilderInput}, err + } } -func ingestVulnerability(ctx context.Context, client graphql.Client, v *model.VulnerabilityInputSpec) error { - _, err := model.IngestVulnerability(ctx, client, *v) - return err +func ingestVulnerability(ctx context.Context, client graphql.Client, v *model.IDorVulnerabilityInput) (*model.IDorVulnerabilityInput, error) { + if result, err := model.IngestVulnerability(ctx, client, *v); err != nil { + return nil, fmt.Errorf("IngestVulnerability failed with error: %w", err) + } else { + return &model.IDorVulnerabilityInput{ + VulnerabilityInput: v.VulnerabilityInput, + VulnerabilityTypeID: &result.IngestVulnerability.VulnerabilityTypeID, + VulnerabilityNodeID: &result.IngestVulnerability.VulnerabilityNodeID, + }, err + } } -func ingestLicense(ctx context.Context, client graphql.Client, l *model.LicenseInputSpec) error { - _, err := model.IngestLicense(ctx, client, *l) - return err +func ingestLicense(ctx context.Context, client graphql.Client, l *model.IDorLicenseInput) (*model.IDorLicenseInput, error) { + if result, err := model.IngestLicense(ctx, client, *l); err != nil { + return nil, fmt.Errorf("IngestLicense failed with error: %w", err) + } else { + return &model.IDorLicenseInput{ + LicenseInput: l.LicenseInput, + LicenseID: &result.IngestLicense, + }, err + } } -func ingestCertifyScorecard(ctx context.Context, client graphql.Client, v assembler.CertifyScorecardIngest) error { - _, err := model.IngestCertifyScorecard(ctx, client, *v.Source, *v.Scorecard) +func ingestCertifyScorecard(ctx context.Context, client graphql.Client, cs assembler.CertifyScorecardIngest, sourceInputMap map[string]*model.IDorSourceInput) error { + srcID, found := sourceInputMap[helpers.ConcatenateSourceInput(cs.Source)] + if !found { + return fmt.Errorf("failed to find ingested Source ID for scorecard: %s", helpers.ConcatenateSourceInput(cs.Source)) + } + + _, err := model.IngestCertifyScorecard(ctx, client, *srcID, *cs.Scorecard) return err } -func ingestIsDependency(ctx context.Context, client graphql.Client, v assembler.IsDependencyIngest) (*string, error) { - if response, err := model.IngestIsDependency(ctx, client, *v.Pkg, *v.DepPkg, v.DepPkgMatchFlag, *v.IsDependency); err != nil { +func ingestIsDependency(ctx context.Context, client graphql.Client, d assembler.IsDependencyIngest, packageInputMap map[string]*model.IDorPkgInput) (*string, error) { + pkgID, found := packageInputMap[helpers.PkgInputSpecToPurl(d.Pkg)] + if !found { + return nil, fmt.Errorf("failed to find ingested Source ID for isDependency: %s", helpers.PkgInputSpecToPurl(d.Pkg)) + } + + depPkgID, found := packageInputMap[helpers.PkgInputSpecToPurl(d.DepPkg)] + if !found { + return nil, fmt.Errorf("failed to find ingested Source ID for isDependency: %s", helpers.PkgInputSpecToPurl(d.DepPkg)) + } + + if response, err := model.IngestIsDependency(ctx, client, *pkgID, *depPkgID, d.DepPkgMatchFlag, *d.IsDependency); err != nil { return nil, err } else { return &response.IngestDependency, nil } } -func ingestIsOccurrence(ctx context.Context, client graphql.Client, v assembler.IsOccurrenceIngest) (*string, error) { - if v.Pkg != nil && v.Src != nil { +func ingestIsOccurrence(ctx context.Context, client graphql.Client, o assembler.IsOccurrenceIngest, packageInputMap map[string]*model.IDorPkgInput, + artInputMap map[string]*model.IDorArtifactInput, sourceInputMap map[string]*model.IDorSourceInput) (*string, error) { + + if o.Pkg != nil && o.Src != nil { return nil, fmt.Errorf("unable to create IsOccurrence with both Src and Pkg subject specified") } - if v.Pkg == nil && v.Src == nil { + if o.Pkg == nil && o.Src == nil { return nil, fmt.Errorf("unable to create IsOccurrence without either Src and Pkg subject specified") } - if v.Src != nil { - if result, err := model.IngestIsOccurrenceSrc(ctx, client, *v.Src, *v.Artifact, *v.IsOccurrence); err != nil { + if o.Src != nil { + + srcID, found := sourceInputMap[helpers.ConcatenateSourceInput(o.Src)] + if !found { + return nil, fmt.Errorf("failed to find ingested Source ID for isOccurrence: %s", helpers.ConcatenateSourceInput(o.Src)) + } + + artID, found := artInputMap[helpers.ArtifactKey(o.Artifact)] + if !found { + return nil, fmt.Errorf("failed to find ingested artifact ID for isOccurrence: %s", helpers.ArtifactKey(o.Artifact)) + } + + if result, err := model.IngestIsOccurrenceSrc(ctx, client, *srcID, *artID, *o.IsOccurrence); err != nil { return nil, err } else { return &result.IngestOccurrence, nil } } - if result, err := model.IngestIsOccurrencePkg(ctx, client, *v.Pkg, *v.Artifact, *v.IsOccurrence); err != nil { - return nil, err - } else { - return &result.IngestOccurrence, err + if o.Pkg != nil { + + pkgID, found := packageInputMap[helpers.PkgInputSpecToPurl(o.Pkg)] + if !found { + return nil, fmt.Errorf("failed to find ingested package ID for isOccurrence: %s", helpers.PkgInputSpecToPurl(o.Pkg)) + } + + artID, found := artInputMap[helpers.ArtifactKey(o.Artifact)] + if !found { + return nil, fmt.Errorf("failed to find ingested artifact ID for isOccurrence: %s", helpers.ArtifactKey(o.Artifact)) + } + + if result, err := model.IngestIsOccurrencePkg(ctx, client, *pkgID, *artID, *o.IsOccurrence); err != nil { + return nil, err + } else { + return &result.IngestOccurrence, err + } } + return nil, nil } -func ingestHasSlsa(ctx context.Context, client graphql.Client, v assembler.HasSlsaIngest) error { - _, err := model.IngestSLSAForArtifact(ctx, client, *v.Artifact, v.Materials, *v.Builder, *v.HasSlsa) +func ingestHasSlsa(ctx context.Context, client graphql.Client, hs assembler.HasSlsaIngest, artInputMap map[string]*model.IDorArtifactInput, + matInputSpec map[string]*model.IDorArtifactInput, builderInputMap map[string]*model.IDorBuilderInput) error { + + var matIDList []model.IDorArtifactInput + for _, mat := range hs.Materials { + if matID, found := matInputSpec[helpers.ArtifactKey(&mat)]; found { + matIDList = append(matIDList, *matID) + } else { + return fmt.Errorf("failed to find ingested material ID for hasSLSA: %s", helpers.ArtifactKey(&mat)) + } + } + + artID, found := artInputMap[helpers.ArtifactKey(hs.Artifact)] + if !found { + return fmt.Errorf("failed to find ingested artifact ID for hasSLSA: %s", helpers.ArtifactKey(hs.Artifact)) + } + + buildID, found := builderInputMap[hs.Builder.Uri] + if !found { + return fmt.Errorf("failed to find ingested artifact ID for hasSLSA: %s", hs.Builder.Uri) + } + + _, err := model.IngestSLSAForArtifact(ctx, client, *artID, matIDList, *buildID, *hs.HasSlsa) return err } -func ingestCertifyVuln(ctx context.Context, client graphql.Client, cv assembler.CertifyVulnIngest) error { - _, err := model.IngestCertifyVulnPkg(ctx, client, *cv.Pkg, *cv.Vulnerability, *cv.VulnData) +func ingestCertifyVuln(ctx context.Context, client graphql.Client, cv assembler.CertifyVulnIngest, packageInputMap map[string]*model.IDorPkgInput, + vulnInputMap map[string]*model.IDorVulnerabilityInput) error { + + pkgID, found := packageInputMap[helpers.PkgInputSpecToPurl(cv.Pkg)] + if !found { + return fmt.Errorf("failed to find ingested package ID for certifyVuln: %s", helpers.PkgInputSpecToPurl(cv.Pkg)) + } + vulnID, found := vulnInputMap[helpers.VulnInputToVURI(cv.Vulnerability)] + if !found { + return fmt.Errorf("failed to find ingested vulnerability ID for certifyVuln: %s", helpers.VulnInputToVURI(cv.Vulnerability)) + } + + _, err := model.IngestCertifyVulnPkg(ctx, client, *pkgID, *vulnID, *cv.VulnData) return err } -func ingestVulnEqual(ctx context.Context, client graphql.Client, ve assembler.VulnEqualIngest) error { +func ingestVulnEqual(ctx context.Context, client graphql.Client, ve assembler.VulnEqualIngest, vulnInputMap map[string]*model.IDorVulnerabilityInput) error { if ve.Vulnerability == nil { return fmt.Errorf("unable to create VulnEqual without vulnerability") } @@ -316,108 +442,217 @@ func ingestVulnEqual(ctx context.Context, client graphql.Client, ve assembler.Vu return fmt.Errorf("unable to create VulnEqual without equal vulnerability") } - _, err := model.IngestVulnEqual(ctx, client, *ve.Vulnerability, *ve.EqualVulnerability, *ve.VulnEqual) + vulnID, found := vulnInputMap[helpers.VulnInputToVURI(ve.Vulnerability)] + if !found { + return fmt.Errorf("failed to find ingested vulnerability ID for vulnEqual: %s", helpers.VulnInputToVURI(ve.Vulnerability)) + } + + equalVulnID, found := vulnInputMap[helpers.VulnInputToVURI(ve.EqualVulnerability)] + if !found { + return fmt.Errorf("failed to find ingested vulnerability ID for vulnEqual: %s", helpers.VulnInputToVURI(ve.EqualVulnerability)) + } + + _, err := model.IngestVulnEqual(ctx, client, *vulnID, *equalVulnID, *ve.VulnEqual) return err } -func hasSourceAt(ctx context.Context, client graphql.Client, hsa assembler.HasSourceAtIngest) error { - _, err := model.IngestHasSourceAt(ctx, client, *hsa.Pkg, hsa.PkgMatchFlag, *hsa.Src, *hsa.HasSourceAt) +func hasSourceAt(ctx context.Context, client graphql.Client, hsa assembler.HasSourceAtIngest, packageInputMap map[string]*model.IDorPkgInput, + sourceInputMap map[string]*model.IDorSourceInput) error { + + pkgID, found := packageInputMap[helpers.PkgInputSpecToPurl(hsa.Pkg)] + if !found { + return fmt.Errorf("failed to find ingested package ID for hasSourceAt: %s", helpers.PkgInputSpecToPurl(hsa.Pkg)) + } + + srcID, found := sourceInputMap[helpers.ConcatenateSourceInput(hsa.Src)] + if !found { + return fmt.Errorf("failed to find ingested Source ID for hasSourceAt: %s", helpers.ConcatenateSourceInput(hsa.Src)) + } + + _, err := model.IngestHasSourceAt(ctx, client, *pkgID, hsa.PkgMatchFlag, *srcID, *hsa.HasSourceAt) return err } -func ingestCertifyBad(ctx context.Context, client graphql.Client, bad assembler.CertifyBadIngest) error { +func ingestCertifyBad(ctx context.Context, client graphql.Client, bad assembler.CertifyBadIngest, packageInputMap map[string]*model.IDorPkgInput, + artInputMap map[string]*model.IDorArtifactInput, sourceInputMap map[string]*model.IDorSourceInput) error { + if err := validatePackageSourceOrArtifactInput(bad.Pkg, bad.Src, bad.Artifact, "certifyBad"); err != nil { return fmt.Errorf("input validation failed for certifyBad: %w", err) } if bad.Pkg != nil { - _, err := model.IngestCertifyBadPkg(ctx, client, *bad.Pkg, bad.PkgMatchFlag, *bad.CertifyBad) + pkgID, found := packageInputMap[helpers.PkgInputSpecToPurl(bad.Pkg)] + if !found { + return fmt.Errorf("failed to find ingested package ID for certifyBad: %s", helpers.PkgInputSpecToPurl(bad.Pkg)) + } + _, err := model.IngestCertifyBadPkg(ctx, client, *pkgID, bad.PkgMatchFlag, *bad.CertifyBad) return err } if bad.Src != nil { - _, err := model.IngestCertifyBadSrc(ctx, client, *bad.Src, *bad.CertifyBad) + srcID, found := sourceInputMap[helpers.ConcatenateSourceInput(bad.Src)] + if !found { + return fmt.Errorf("failed to find ingested Source ID for certifyBad: %s", helpers.ConcatenateSourceInput(bad.Src)) + } + _, err := model.IngestCertifyBadSrc(ctx, client, *srcID, *bad.CertifyBad) return err } - _, err := model.IngestCertifyBadArtifact(ctx, client, *bad.Artifact, *bad.CertifyBad) - return err + if bad.Artifact != nil { + artID, found := artInputMap[helpers.ArtifactKey(bad.Artifact)] + if !found { + return fmt.Errorf("failed to find ingested artifact ID for certifyBad: %s", helpers.ArtifactKey(bad.Artifact)) + } + _, err := model.IngestCertifyBadArtifact(ctx, client, *artID, *bad.CertifyBad) + return err + } + return nil } -func ingestCertifyGood(ctx context.Context, client graphql.Client, good assembler.CertifyGoodIngest) error { +func ingestCertifyGood(ctx context.Context, client graphql.Client, good assembler.CertifyGoodIngest, packageInputMap map[string]*model.IDorPkgInput, + artInputMap map[string]*model.IDorArtifactInput, sourceInputMap map[string]*model.IDorSourceInput) error { + if err := validatePackageSourceOrArtifactInput(good.Pkg, good.Src, good.Artifact, "certifyGood"); err != nil { return fmt.Errorf("input validation failed for certifyGood: %w", err) } if good.Pkg != nil { - _, err := model.IngestCertifyGoodPkg(ctx, client, *good.Pkg, good.PkgMatchFlag, *good.CertifyGood) + pkgID, found := packageInputMap[helpers.PkgInputSpecToPurl(good.Pkg)] + if !found { + return fmt.Errorf("failed to find ingested package ID for certifyGood: %s", helpers.PkgInputSpecToPurl(good.Pkg)) + } + _, err := model.IngestCertifyGoodPkg(ctx, client, *pkgID, good.PkgMatchFlag, *good.CertifyGood) return err } if good.Src != nil { - _, err := model.IngestCertifyGoodSrc(ctx, client, *good.Src, *good.CertifyGood) + srcID, found := sourceInputMap[helpers.ConcatenateSourceInput(good.Src)] + if !found { + return fmt.Errorf("failed to find ingested Source ID for certifyGood: %s", helpers.ConcatenateSourceInput(good.Src)) + } + _, err := model.IngestCertifyGoodSrc(ctx, client, *srcID, *good.CertifyGood) return err } - _, err := model.IngestCertifyGoodArtifact(ctx, client, *good.Artifact, *good.CertifyGood) - return err + if good.Artifact != nil { + artID, found := artInputMap[helpers.ArtifactKey(good.Artifact)] + if !found { + return fmt.Errorf("failed to find ingested artifact ID for certifyGood: %s", helpers.ArtifactKey(good.Artifact)) + } + _, err := model.IngestCertifyGoodArtifact(ctx, client, *artID, *good.CertifyGood) + return err + } + return nil } -func ingestPointOfContact(ctx context.Context, client graphql.Client, poc assembler.PointOfContactIngest) error { +func ingestPointOfContact(ctx context.Context, client graphql.Client, poc assembler.PointOfContactIngest, packageInputMap map[string]*model.IDorPkgInput, + artInputMap map[string]*model.IDorArtifactInput, sourceInputMap map[string]*model.IDorSourceInput) error { + if err := validatePackageSourceOrArtifactInput(poc.Pkg, poc.Src, poc.Artifact, "pointOfContact"); err != nil { return fmt.Errorf("input validation failed for pointOfContact: %w", err) } if poc.Pkg != nil { - _, err := model.IngestPointOfContactPkg(ctx, client, *poc.Pkg, poc.PkgMatchFlag, *poc.PointOfContact) + pkgID, found := packageInputMap[helpers.PkgInputSpecToPurl(poc.Pkg)] + if !found { + return fmt.Errorf("failed to find ingested package ID for pointOfContact: %s", helpers.PkgInputSpecToPurl(poc.Pkg)) + } + _, err := model.IngestPointOfContactPkg(ctx, client, *pkgID, poc.PkgMatchFlag, *poc.PointOfContact) return err } if poc.Src != nil { - _, err := model.IngestPointOfContactSrc(ctx, client, *poc.Src, *poc.PointOfContact) + srcID, found := sourceInputMap[helpers.ConcatenateSourceInput(poc.Src)] + if !found { + return fmt.Errorf("failed to find ingested Source ID for pointOfContact: %s", helpers.ConcatenateSourceInput(poc.Src)) + } + _, err := model.IngestPointOfContactSrc(ctx, client, *srcID, *poc.PointOfContact) return err } - _, err := model.IngestPointOfContactArtifact(ctx, client, *poc.Artifact, *poc.PointOfContact) - return err + if poc.Artifact != nil { + artID, found := artInputMap[helpers.ArtifactKey(poc.Artifact)] + if !found { + return fmt.Errorf("failed to find ingested artifact ID for pointOfContact: %s", helpers.ArtifactKey(poc.Artifact)) + } + _, err := model.IngestPointOfContactArtifact(ctx, client, *artID, *poc.PointOfContact) + return err + } + return nil } -func ingestHasMetadata(ctx context.Context, client graphql.Client, hm assembler.HasMetadataIngest) error { +func ingestHasMetadata(ctx context.Context, client graphql.Client, hm assembler.HasMetadataIngest, packageInputMap map[string]*model.IDorPkgInput, + artInputMap map[string]*model.IDorArtifactInput, sourceInputMap map[string]*model.IDorSourceInput) error { + if err := validatePackageSourceOrArtifactInput(hm.Pkg, hm.Src, hm.Artifact, "hasMetadata"); err != nil { return fmt.Errorf("input validation failed for hasMetadata: %w", err) } if hm.Pkg != nil { - _, err := model.IngestHasMetadataPkg(ctx, client, *hm.Pkg, hm.PkgMatchFlag, *hm.HasMetadata) + pkgID, found := packageInputMap[helpers.PkgInputSpecToPurl(hm.Pkg)] + if !found { + return fmt.Errorf("failed to find ingested package ID for hasMetadata: %s", helpers.PkgInputSpecToPurl(hm.Pkg)) + } + _, err := model.IngestHasMetadataPkg(ctx, client, *pkgID, hm.PkgMatchFlag, *hm.HasMetadata) return err } if hm.Src != nil { - _, err := model.IngestHasMetadataSrc(ctx, client, *hm.Src, *hm.HasMetadata) + srcID, found := sourceInputMap[helpers.ConcatenateSourceInput(hm.Src)] + if !found { + return fmt.Errorf("failed to find ingested Source ID for hasMetadata: %s", helpers.ConcatenateSourceInput(hm.Src)) + } + _, err := model.IngestHasMetadataSrc(ctx, client, *srcID, *hm.HasMetadata) return err } - _, err := model.IngestHasMetadataArtifact(ctx, client, *hm.Artifact, *hm.HasMetadata) - return err + if hm.Artifact != nil { + artID, found := artInputMap[helpers.ArtifactKey(hm.Artifact)] + if !found { + return fmt.Errorf("failed to find ingested artifact ID for hasMetadata: %s", helpers.ArtifactKey(hm.Artifact)) + } + _, err := model.IngestHasMetadataArtifact(ctx, client, *artID, *hm.HasMetadata) + return err + } + return nil } -func ingestHasSBOM(ctx context.Context, client graphql.Client, hb assembler.HasSBOMIngest) error { +func ingestHasSBOM(ctx context.Context, client graphql.Client, hb assembler.HasSBOMIngest, packageInputMap map[string]*model.IDorPkgInput, + artInputMap map[string]*model.IDorArtifactInput) error { + if hb.Pkg != nil && hb.Artifact != nil { return fmt.Errorf("unable to create hasSBOM with both Pkg and Src subject specified") } if hb.Pkg == nil && hb.Artifact == nil { - return fmt.Errorf("unable to create hasSBOM without either Pkg and Src ssubject specified") + return fmt.Errorf("unable to create hasSBOM without either Pkg and Src subject specified") } if hb.Pkg != nil { - _, err := model.IngestHasSBOMPkg(ctx, client, *hb.Pkg, *hb.HasSBOM, *hb.Includes) + pkgID, found := packageInputMap[helpers.PkgInputSpecToPurl(hb.Pkg)] + if !found { + return fmt.Errorf("failed to find ingested package ID for hasSBOM: %s", helpers.PkgInputSpecToPurl(hb.Pkg)) + } + _, err := model.IngestHasSBOMPkg(ctx, client, *pkgID, *hb.HasSBOM, *hb.Includes) return err } - _, err := model.IngestHasSBOMArtifact(ctx, client, *hb.Artifact, *hb.HasSBOM, *hb.Includes) - return err + if hb.Artifact != nil { + artID, found := artInputMap[helpers.ArtifactKey(hb.Artifact)] + if !found { + return fmt.Errorf("failed to find ingested artifact ID for hasMetadata: %s", helpers.ArtifactKey(hb.Artifact)) + } + _, err := model.IngestHasSBOMArtifact(ctx, client, *artID, *hb.HasSBOM, *hb.Includes) + return err + } + return nil } -func ingestVulnMetadata(ctx context.Context, client graphql.Client, vi assembler.VulnMetadataIngest) error { - _, err := model.IngestVulnHasMetadata(ctx, client, *vi.Vulnerability, *vi.VulnMetadata) +func ingestVulnMetadata(ctx context.Context, client graphql.Client, vi assembler.VulnMetadataIngest, vulnInputMap map[string]*model.IDorVulnerabilityInput) error { + vulnID, found := vulnInputMap[helpers.VulnInputToVURI(vi.Vulnerability)] + if !found { + return fmt.Errorf("failed to find ingested vulnerability ID for vulnEqual: %s", helpers.VulnInputToVURI(vi.Vulnerability)) + } + + _, err := model.IngestVulnHasMetadata(ctx, client, *vulnID, *vi.VulnMetadata) if err != nil { return err } return nil } -func ingestVex(ctx context.Context, client graphql.Client, vi assembler.VexIngest) error { +func ingestVex(ctx context.Context, client graphql.Client, vi assembler.VexIngest, packageInputMap map[string]*model.IDorPkgInput, + artInputMap map[string]*model.IDorArtifactInput, vulnInputMap map[string]*model.IDorVulnerabilityInput) error { if vi.Artifact != nil && vi.Pkg != nil { return fmt.Errorf("unable to create VexIngest with both Pkg and Artifact specified") } @@ -426,15 +661,28 @@ func ingestVex(ctx context.Context, client graphql.Client, vi assembler.VexInges return fmt.Errorf("unable to create VexIngest without either Pkg or Artifact specified") } + vulnID, found := vulnInputMap[helpers.VulnInputToVURI(vi.Vulnerability)] + if !found { + return fmt.Errorf("failed to find ingested vulnerability ID for VexIngest: %s", helpers.VulnInputToVURI(vi.Vulnerability)) + } + if vi.Pkg != nil { - _, err := model.IngestCertifyVexPkg(ctx, client, *vi.Pkg, *vi.Vulnerability, *vi.VexData) + pkgID, found := packageInputMap[helpers.PkgInputSpecToPurl(vi.Pkg)] + if !found { + return fmt.Errorf("failed to find ingested package ID for VexIngest: %s", helpers.PkgInputSpecToPurl(vi.Pkg)) + } + _, err := model.IngestCertifyVexPkg(ctx, client, *pkgID, *vulnID, *vi.VexData) if err != nil { return err } } if vi.Artifact != nil { - _, err := model.IngestCertifyVexArtifact(ctx, client, *vi.Artifact, *vi.Vulnerability, *vi.VexData) + artID, found := artInputMap[helpers.ArtifactKey(vi.Artifact)] + if !found { + return fmt.Errorf("failed to find ingested artifact ID for hasMetadata: %s", helpers.ArtifactKey(vi.Artifact)) + } + _, err := model.IngestCertifyVexArtifact(ctx, client, *artID, *vulnID, *vi.VexData) if err != nil { return err } @@ -442,42 +690,96 @@ func ingestVex(ctx context.Context, client graphql.Client, vi assembler.VexInges return nil } -func ingestPkgEqual(ctx context.Context, client graphql.Client, v assembler.PkgEqualIngest) error { - if v.Pkg == nil { +func ingestPkgEqual(ctx context.Context, client graphql.Client, pe assembler.PkgEqualIngest, packageInputMap map[string]*model.IDorPkgInput) error { + if pe.Pkg == nil { return fmt.Errorf("unable to create pkgEqual without Pkg") } - if v.EqualPkg == nil { + if pe.EqualPkg == nil { return fmt.Errorf("unable to create pkgEqual without EqualPkg") } - _, err := model.IngestPkgEqual(ctx, client, *v.Pkg, *v.EqualPkg, *v.PkgEqual) + + pkgID, found := packageInputMap[helpers.PkgInputSpecToPurl(pe.Pkg)] + if !found { + return fmt.Errorf("failed to find ingested package ID for pkgEqual: %s", helpers.PkgInputSpecToPurl(pe.Pkg)) + } + + equalPkgID, found := packageInputMap[helpers.PkgInputSpecToPurl(pe.EqualPkg)] + if !found { + return fmt.Errorf("failed to find ingested package ID for pkgEqual: %s", helpers.PkgInputSpecToPurl(pe.EqualPkg)) + } + + _, err := model.IngestPkgEqual(ctx, client, *pkgID, *equalPkgID, *pe.PkgEqual) return err } -func ingestHashEqual(ctx context.Context, client graphql.Client, v assembler.HashEqualIngest) error { - if v.Artifact == nil { +func ingestHashEqual(ctx context.Context, client graphql.Client, he assembler.HashEqualIngest, artInputMap map[string]*model.IDorArtifactInput) error { + if he.Artifact == nil { return fmt.Errorf("unable to create HashEqual without artifact") } - if v.EqualArtifact == nil { + if he.EqualArtifact == nil { return fmt.Errorf("unable to create HashEqual without equal artifact") } - _, err := model.IngestHashEqual(ctx, client, *v.Artifact, *v.EqualArtifact, *v.HashEqual) + + artID, found := artInputMap[helpers.ArtifactKey(he.Artifact)] + if !found { + return fmt.Errorf("failed to find ingested artifact ID for HashEqual: %s", helpers.ArtifactKey(he.Artifact)) + } + equalArtID, found := artInputMap[helpers.ArtifactKey(he.EqualArtifact)] + if !found { + return fmt.Errorf("failed to find ingested artifact ID for HashEqual: %s", helpers.ArtifactKey(he.EqualArtifact)) + } + + _, err := model.IngestHashEqual(ctx, client, *artID, *equalArtID, *he.HashEqual) return err } -func ingestCertifyLegal(ctx context.Context, client graphql.Client, v assembler.CertifyLegalIngest) error { - if v.Pkg != nil && v.Src != nil { +func ingestCertifyLegal(ctx context.Context, client graphql.Client, cl assembler.CertifyLegalIngest, packageInputMap map[string]*model.IDorPkgInput, + sourceInputMap map[string]*model.IDorSourceInput, licenseInputMap map[string]*model.IDorLicenseInput) error { + + if cl.Pkg != nil && cl.Src != nil { return fmt.Errorf("unable to create CertifyLegal with both Src and Pkg subject specified") } - if v.Pkg == nil && v.Src == nil { + if cl.Pkg == nil && cl.Src == nil { return fmt.Errorf("unable to create CertifyLegal without either Src and Pkg subject specified") } - if v.Src != nil { - _, err := model.IngestCertifyLegalSrc(ctx, client, *v.Src, v.Declared, v.Discovered, *v.CertifyLegal) + // Declared Licenses + var decList []model.IDorLicenseInput + for _, dec := range cl.Declared { + if licID, found := licenseInputMap[helpers.LicenseKey(&dec)]; found { + decList = append(decList, *licID) + } else { + return fmt.Errorf("failed to find ingested license ID for certifyLegal: %s", helpers.LicenseKey(&dec)) + } + } + + // Discovered Licenses + var disList []model.IDorLicenseInput + for _, dis := range cl.Discovered { + if licID, found := licenseInputMap[helpers.LicenseKey(&dis)]; found { + disList = append(disList, *licID) + } else { + return fmt.Errorf("failed to find ingested license ID for certifyLegal: %s", helpers.LicenseKey(&dis)) + } + } + + if cl.Src != nil { + srcID, found := sourceInputMap[helpers.ConcatenateSourceInput(cl.Src)] + if !found { + return fmt.Errorf("failed to find ingested Source ID for CertifyLegal: %s", helpers.ConcatenateSourceInput(cl.Src)) + } + _, err := model.IngestCertifyLegalSrc(ctx, client, *srcID, decList, disList, *cl.CertifyLegal) return err } - _, err := model.IngestCertifyLegalPkg(ctx, client, *v.Pkg, v.Declared, v.Discovered, *v.CertifyLegal) - return err + if cl.Pkg != nil { + pkgID, found := packageInputMap[helpers.PkgInputSpecToPurl(cl.Pkg)] + if !found { + return fmt.Errorf("failed to find ingested package ID for CertifyLegal: %s", helpers.PkgInputSpecToPurl(cl.Pkg)) + } + _, err := model.IngestCertifyLegalPkg(ctx, client, *pkgID, decList, disList, *cl.CertifyLegal) + return err + } + return nil } func validatePackageSourceOrArtifactInput(pkg *model.PkgInputSpec, src *model.SourceInputSpec, artifact *model.ArtifactInputSpec, path string) error { diff --git a/pkg/assembler/clients/helpers/bulk.go b/pkg/assembler/clients/helpers/bulk.go index 35a460a320..686b80ba78 100644 --- a/pkg/assembler/clients/helpers/bulk.go +++ b/pkg/assembler/clients/helpers/bulk.go @@ -23,6 +23,7 @@ import ( "github.com/guacsec/guac/pkg/assembler" model "github.com/guacsec/guac/pkg/assembler/clients/generated" + "github.com/guacsec/guac/pkg/assembler/helpers" "github.com/guacsec/guac/pkg/logging" ) @@ -30,90 +31,96 @@ func GetBulkAssembler(ctx context.Context, gqlclient graphql.Client) func([]asse logger := logging.FromContext(ctx) return func(preds []assembler.IngestPredicates) error { for _, p := range preds { + + // Ingest Packages var packageAndArtifactIDs []string packages := p.GetPackages(ctx) logger.Infof("assembling Package: %v", len(packages)) - var collectedPackages []model.PkgInputSpec - collectedPackages = make([]model.PkgInputSpec, 0) - for _, v := range packages { - collectedPackages = append(collectedPackages, *v) + + collectedIDorPkgInputs, err := ingestPackages(ctx, gqlclient, packages) + if err != nil { + return fmt.Errorf("ingestPackages failed with error: %v", err) } - if ids, err := ingestPackages(ctx, gqlclient, collectedPackages); err != nil { - logger.Errorf("ingestPackages failed with error: %v", err) - } else { - packageAndArtifactIDs = append(packageAndArtifactIDs, ids...) + + var pkgVersionIDs []string + for _, pkgVersionID := range collectedIDorPkgInputs { + pkgVersionIDs = append(pkgVersionIDs, *pkgVersionID.PackageVersionID) } + packageAndArtifactIDs = append(packageAndArtifactIDs, pkgVersionIDs...) + // Ingest sources sources := p.GetSources(ctx) logger.Infof("assembling Source: %v", len(sources)) - var collectedSources []model.SourceInputSpec - collectedSources = make([]model.SourceInputSpec, 0) - for _, v := range sources { - collectedSources = append(collectedSources, *v) - } - if err := ingestSources(ctx, gqlclient, collectedSources); err != nil { - logger.Errorf("ingestSources failed with error: %v", err) + collectedIDorSrcInputs, err := ingestSources(ctx, gqlclient, sources) + if err != nil { + return fmt.Errorf("ingestSources failed with error: %v", err) } + // Ingest Artifacts artifacts := p.GetArtifacts(ctx) logger.Infof("assembling Artifact: %v", len(artifacts)) - var collectedArtifacts []model.ArtifactInputSpec - collectedArtifacts = make([]model.ArtifactInputSpec, 0) - for _, v := range artifacts { - collectedArtifacts = append(collectedArtifacts, *v) + + collectedIDorArtInputs, err := ingestArtifacts(ctx, gqlclient, artifacts) + if err != nil { + return fmt.Errorf("ingestArtifacts failed with error: %v", err) } - if ids, err := ingestArtifacts(ctx, gqlclient, collectedArtifacts); err != nil { - logger.Errorf("ingestArtifacts failed with error: %v", err) - } else { - packageAndArtifactIDs = append(packageAndArtifactIDs, ids...) + var artIDs []string + for _, artID := range collectedIDorArtInputs { + artIDs = append(artIDs, *artID.ArtifactID) } + packageAndArtifactIDs = append(packageAndArtifactIDs, artIDs...) + // Ingest Materials materials := p.GetMaterials(ctx) logger.Infof("assembling Materials (Artifact): %v", len(materials)) - if ids, err := ingestArtifacts(ctx, gqlclient, materials); err != nil { - logger.Errorf("ingestArtifacts failed with error: %v", err) - } else { - packageAndArtifactIDs = append(packageAndArtifactIDs, ids...) + + collectedIDorMatInputs, err := ingestArtifacts(ctx, gqlclient, materials) + if err != nil { + return fmt.Errorf("ingestArtifacts failed with error: %v", err) + } + var matIDs []string + for _, matID := range collectedIDorMatInputs { + matIDs = append(matIDs, *matID.ArtifactID) } + packageAndArtifactIDs = append(packageAndArtifactIDs, matIDs...) + // Ingest Builders builders := p.GetBuilders(ctx) logger.Infof("assembling Builder: %v", len(builders)) - var collectedBuilders []model.BuilderInputSpec - collectedBuilders = make([]model.BuilderInputSpec, 0) - for _, v := range builders { - collectedBuilders = append(collectedBuilders, *v) - } - if err := ingestBuilders(ctx, gqlclient, collectedBuilders); err != nil { - logger.Errorf("ingestBuilders failed with error: %v", err) + + collectedIDorBuilderInputs, err := ingestBuilders(ctx, gqlclient, builders) + if err != nil { + return fmt.Errorf("ingestBuilders failed with error: %v", err) } + // Ingest Vulnerabilities vulns := p.GetVulnerabilities(ctx) logger.Infof("assembling Vulnerability: %v", len(vulns)) - var collectedVulns []model.VulnerabilityInputSpec - collectedVulns = make([]model.VulnerabilityInputSpec, 0) - for _, v := range vulns { - collectedVulns = append(collectedVulns, *v) - } - if err := ingestVulnerabilities(ctx, gqlclient, collectedVulns); err != nil { - logger.Errorf("ingestVulnerabilities failed with error: %v", err) + + collectedIDorVulnInputs, err := ingestVulnerabilities(ctx, gqlclient, vulns) + if err != nil { + return fmt.Errorf("ingestVulnerabilities failed with error: %v", err) } + // Ingest Licenses licenses := p.GetLicenses(ctx) logger.Infof("assembling Licenses: %v", len(licenses)) - if err := ingestLicenses(ctx, gqlclient, licenses); err != nil { - logger.Errorf("ingestLicenses failed with error: %v", err) + + collectedIDorLicenseInputs, err := ingestLicenses(ctx, gqlclient, licenses) + if err != nil { + return fmt.Errorf("ingestLicenses failed with error: %v", err) } logger.Infof("assembling CertifyScorecard: %v", len(p.CertifyScorecard)) - if err := ingestCertifyScorecards(ctx, gqlclient, p.CertifyScorecard); err != nil { + if err := ingestCertifyScorecards(ctx, gqlclient, p.CertifyScorecard, collectedIDorSrcInputs); err != nil { logger.Errorf("ingestCertifyScorecards failed with error: %v", err) } logger.Infof("assembling IsDependency: %v", len(p.IsDependency)) isDependenciesIDs := []string{} - if ingestedIsDependenciesIDs, err := ingestIsDependencies(ctx, gqlclient, p.IsDependency); err != nil { + if ingestedIsDependenciesIDs, err := ingestIsDependencies(ctx, gqlclient, p.IsDependency, collectedIDorPkgInputs); err != nil { logger.Errorf("ingestIsDependencies failed with error: %v", err) } else { isDependenciesIDs = append(isDependenciesIDs, ingestedIsDependenciesIDs...) @@ -121,57 +128,57 @@ func GetBulkAssembler(ctx context.Context, gqlclient graphql.Client) func([]asse logger.Infof("assembling IsOccurrence: %v", len(p.IsOccurrence)) isOccurrencesIDs := []string{} - if ingestedIsOccurrencesIDs, err := ingestIsOccurrences(ctx, gqlclient, p.IsOccurrence); err != nil { + if ingestedIsOccurrencesIDs, err := ingestIsOccurrences(ctx, gqlclient, p.IsOccurrence, collectedIDorPkgInputs, collectedIDorArtInputs, collectedIDorSrcInputs); err != nil { logger.Errorf("ingestIsOccurrences failed with error: %v", err) } else { isOccurrencesIDs = append(isOccurrencesIDs, ingestedIsOccurrencesIDs...) } logger.Infof("assembling HasSLSA: %v", len(p.HasSlsa)) - if err := ingestHasSLSAs(ctx, gqlclient, p.HasSlsa); err != nil { + if err := ingestHasSLSAs(ctx, gqlclient, p.HasSlsa, collectedIDorArtInputs, collectedIDorMatInputs, collectedIDorBuilderInputs); err != nil { logger.Errorf("ingestHasSLSAs failed with error: %v", err) } logger.Infof("assembling CertifyVuln: %v", len(p.CertifyVuln)) - if err := ingestCertifyVulns(ctx, gqlclient, p.CertifyVuln); err != nil { + if err := ingestCertifyVulns(ctx, gqlclient, p.CertifyVuln, collectedIDorPkgInputs, collectedIDorVulnInputs); err != nil { logger.Errorf("ingestCertifyVulns failed with error: %v", err) } logger.Infof("assembling VulnMetadata: %v", len(p.VulnMetadata)) - if err := ingestVulnMetadatas(ctx, gqlclient, p.VulnMetadata); err != nil { + if err := ingestVulnMetadatas(ctx, gqlclient, p.VulnMetadata, collectedIDorVulnInputs); err != nil { logger.Errorf("ingestVulnMetadatas failed with error: %v", err) } logger.Infof("assembling VulnEqual: %v", len(p.VulnEqual)) - if err := ingestVulnEquals(ctx, gqlclient, p.VulnEqual); err != nil { + if err := ingestVulnEquals(ctx, gqlclient, p.VulnEqual, collectedIDorVulnInputs); err != nil { logger.Errorf("ingestVulnEquals failed with error: %v", err) } logger.Infof("assembling HasSourceAt: %v", len(p.HasSourceAt)) - if err := ingestHasSourceAts(ctx, gqlclient, p.HasSourceAt); err != nil { + if err := ingestHasSourceAts(ctx, gqlclient, p.HasSourceAt, collectedIDorPkgInputs, collectedIDorSrcInputs); err != nil { return fmt.Errorf("ingestHasSourceAts failed with error: %w", err) } logger.Infof("assembling CertifyBad: %v", len(p.CertifyBad)) - if err := ingestCertifyBads(ctx, gqlclient, p.CertifyBad); err != nil { + if err := ingestCertifyBads(ctx, gqlclient, p.CertifyBad, collectedIDorPkgInputs, collectedIDorArtInputs, collectedIDorSrcInputs); err != nil { logger.Errorf("ingestCertifyBads failed with error: %v", err) } logger.Infof("assembling CertifyGood: %v", len(p.CertifyGood)) - if err := ingestCertifyGoods(ctx, gqlclient, p.CertifyGood); err != nil { + if err := ingestCertifyGoods(ctx, gqlclient, p.CertifyGood, collectedIDorPkgInputs, collectedIDorArtInputs, collectedIDorSrcInputs); err != nil { logger.Errorf("ingestCertifyGoods failed with error: %v", err) } logger.Infof("assembling PointOfContact: %v", len(p.PointOfContact)) - if err := ingestPointOfContacts(ctx, gqlclient, p.PointOfContact); err != nil { + if err := ingestPointOfContacts(ctx, gqlclient, p.PointOfContact, collectedIDorPkgInputs, collectedIDorArtInputs, collectedIDorSrcInputs); err != nil { logger.Errorf("ingestPointOfContacts failed with error: %v", err) } logger.Infof("assembling HasMetadata: %v", len(p.HasMetadata)) - if err := ingestBulkHasMetadata(ctx, gqlclient, p.HasMetadata); err != nil { + if err := ingestBulkHasMetadata(ctx, gqlclient, p.HasMetadata, collectedIDorPkgInputs, collectedIDorArtInputs, collectedIDorSrcInputs); err != nil { logger.Errorf("ingestBulkHasMetadata failed with error: %v", err) } @@ -180,27 +187,27 @@ func GetBulkAssembler(ctx context.Context, gqlclient graphql.Client) func([]asse Software: packageAndArtifactIDs, Dependencies: isDependenciesIDs, Occurrences: isOccurrencesIDs, - }); err != nil { + }, collectedIDorPkgInputs, collectedIDorArtInputs); err != nil { logger.Errorf("ingestHasSBOMs failed with error: %v", err) } logger.Infof("assembling VEX : %v", len(p.Vex)) - if err := ingestVEXs(ctx, gqlclient, p.Vex); err != nil { + if err := ingestVEXs(ctx, gqlclient, p.Vex, collectedIDorPkgInputs, collectedIDorArtInputs, collectedIDorVulnInputs); err != nil { logger.Errorf("ingestVEXs failed with error: %v", err) } logger.Infof("assembling HashEqual : %v", len(p.HashEqual)) - if err := ingestHashEquals(ctx, gqlclient, p.HashEqual); err != nil { + if err := ingestHashEquals(ctx, gqlclient, p.HashEqual, collectedIDorArtInputs); err != nil { logger.Errorf("ingestHashEquals failed with error: %v", err) } logger.Infof("assembling PkgEqual : %v", len(p.PkgEqual)) - if err := ingestPkgEquals(ctx, gqlclient, p.PkgEqual); err != nil { + if err := ingestPkgEquals(ctx, gqlclient, p.PkgEqual, collectedIDorPkgInputs); err != nil { logger.Errorf("ingestPkgEquals failed with error: %v", err) } logger.Infof("assembling CertifyLegal : %v", len(p.CertifyLegal)) - if err := ingestCertifyLegals(ctx, gqlclient, p.CertifyLegal); err != nil { + if err := ingestCertifyLegals(ctx, gqlclient, p.CertifyLegal, collectedIDorPkgInputs, collectedIDorSrcInputs, collectedIDorLicenseInputs); err != nil { logger.Errorf("ingestCertifyLegals failed with error: %v", err) } } @@ -208,69 +215,184 @@ func GetBulkAssembler(ctx context.Context, gqlclient graphql.Client) func([]asse } } -func ingestPackages(ctx context.Context, client graphql.Client, v []model.PkgInputSpec) ([]string, error) { - response, err := model.IngestPackages(ctx, client, v) +// ingestPackages takes in the map of IDorPkgInput which contains the pkgInputSpec and outputs a map that contains the pkgIDs to be used for verb ingestion +func ingestPackages(ctx context.Context, client graphql.Client, packageInputMap map[string]*model.IDorPkgInput) (map[string]*model.IDorPkgInput, error) { + var keys []string + var pkgInputs []model.IDorPkgInput + pkgInputs = make([]model.IDorPkgInput, 0) + for key, pkgInput := range packageInputMap { + keys = append(keys, key) + pkgInputs = append(pkgInputs, *pkgInput) + } + response, err := model.IngestPackages(ctx, client, pkgInputs) if err != nil { - return nil, fmt.Errorf("ingestPackages failed with error: %w", err) + return nil, fmt.Errorf("IngestPackages failed with error: %w", err) } - var results []string - for _, pkg := range response.IngestPackages { - results = append(results, pkg.PackageVersionID) + + results := make(map[string]*model.IDorPkgInput) + + for i := range response.IngestPackages { + pkgIDs := response.IngestPackages[i] + results[keys[i]] = &model.IDorPkgInput{ + PackageInput: pkgInputs[i].PackageInput, + PackageTypeID: &pkgIDs.PackageTypeID, + PackageNamespaceID: &pkgIDs.PackageNamespaceID, + PackageNameID: &pkgIDs.PackageNameID, + PackageVersionID: &pkgIDs.PackageVersionID, + } } return results, nil } -func ingestSources(ctx context.Context, client graphql.Client, v []model.SourceInputSpec) error { - _, err := model.IngestSources(ctx, client, v) +// ingestSources takes in the map of IDorSourceInput which contains the sourceInputSpec and outputs a map that contains the srcIDs to be used for verb ingestion +func ingestSources(ctx context.Context, client graphql.Client, sourceInputMap map[string]*model.IDorSourceInput) (map[string]*model.IDorSourceInput, error) { + var keys []string + var srcInputs []model.IDorSourceInput + srcInputs = make([]model.IDorSourceInput, 0) + for key, srcInput := range sourceInputMap { + keys = append(keys, key) + srcInputs = append(srcInputs, *srcInput) + } + response, err := model.IngestSources(ctx, client, srcInputs) if err != nil { - return fmt.Errorf("ingestSources failed with error: %w", err) + return nil, fmt.Errorf("IngestSources failed with error: %w", err) } - return nil + results := make(map[string]*model.IDorSourceInput) + + for i := range response.IngestSources { + srcIDs := response.IngestSources[i] + results[keys[i]] = &model.IDorSourceInput{ + SourceInput: srcInputs[i].SourceInput, + SourceTypeID: &srcIDs.SourceTypeID, + SourceNamespaceID: &srcIDs.SourceNamespaceID, + SourceNameID: &srcIDs.SourceNameID, + } + } + return results, nil } -func ingestArtifacts(ctx context.Context, client graphql.Client, v []model.ArtifactInputSpec) ([]string, error) { - response, err := model.IngestArtifacts(ctx, client, v) +// ingestArtifacts takes in the map of IDorArtifactInput which contains the artifactInputSpec and outputs a map that contains the artifactID to be used for verb ingestion +func ingestArtifacts(ctx context.Context, client graphql.Client, artInputMap map[string]*model.IDorArtifactInput) (map[string]*model.IDorArtifactInput, error) { + var keys []string + var artInputs []model.IDorArtifactInput + artInputs = make([]model.IDorArtifactInput, 0) + for key, artInput := range artInputMap { + keys = append(keys, key) + artInputs = append(artInputs, *artInput) + } + response, err := model.IngestArtifacts(ctx, client, artInputs) if err != nil { - return nil, fmt.Errorf("ingestArtifacts failed with error: %w", err) + return nil, fmt.Errorf("IngestArtifacts failed with error: %w", err) } - return response.IngestArtifacts, nil + results := make(map[string]*model.IDorArtifactInput) + + for i := range response.IngestArtifacts { + artID := response.IngestArtifacts[i] + results[keys[i]] = &model.IDorArtifactInput{ + ArtifactInput: artInputs[i].ArtifactInput, + ArtifactID: &artID, + } + } + return results, nil } -func ingestBuilders(ctx context.Context, client graphql.Client, v []model.BuilderInputSpec) error { - _, err := model.IngestBuilders(ctx, client, v) +// ingestBuilders takes in the map of IDorBuilderInput which contains the builderInput and outputs a map that contains the builderID to be used for verb ingestion +func ingestBuilders(ctx context.Context, client graphql.Client, buildInputMap map[string]*model.IDorBuilderInput) (map[string]*model.IDorBuilderInput, error) { + var keys []string + var buildInputs []model.IDorBuilderInput + buildInputs = make([]model.IDorBuilderInput, 0) + for key, srcInput := range buildInputMap { + keys = append(keys, key) + buildInputs = append(buildInputs, *srcInput) + } + response, err := model.IngestBuilders(ctx, client, buildInputs) if err != nil { - return fmt.Errorf("ingestBuilders failed with error: %w", err) + return nil, fmt.Errorf("IngestBuilders failed with error: %w", err) } - return nil + + results := make(map[string]*model.IDorBuilderInput) + + for i := range response.IngestBuilders { + buildID := response.IngestBuilders[i] + results[keys[i]] = &model.IDorBuilderInput{ + BuilderInput: buildInputs[i].BuilderInput, + BuilderID: &buildID, + } + } + return results, nil } -func ingestVulnerabilities(ctx context.Context, client graphql.Client, v []model.VulnerabilityInputSpec) error { - _, err := model.IngestVulnerabilities(ctx, client, v) +// ingestVulnerabilities takes in the map of IDorVulnerabilityInput which contains the vulnerabilityInput and outputs a map that contains the vulnerabilityIDs to be used for verb ingestion +func ingestVulnerabilities(ctx context.Context, client graphql.Client, vulnInputMap map[string]*model.IDorVulnerabilityInput) (map[string]*model.IDorVulnerabilityInput, error) { + var keys []string + var vulnInputs []model.IDorVulnerabilityInput + vulnInputs = make([]model.IDorVulnerabilityInput, 0) + for key, vulnInput := range vulnInputMap { + keys = append(keys, key) + vulnInputs = append(vulnInputs, *vulnInput) + } + response, err := model.IngestVulnerabilities(ctx, client, vulnInputs) if err != nil { - return fmt.Errorf("ingestVulnerabilities failed with error: %w", err) + return nil, fmt.Errorf("IngestVulnerabilities failed with error: %w", err) } - return nil + results := make(map[string]*model.IDorVulnerabilityInput) + + for i := range response.IngestVulnerabilities { + vulnIDs := response.IngestVulnerabilities[i] + results[keys[i]] = &model.IDorVulnerabilityInput{ + VulnerabilityInput: vulnInputs[i].VulnerabilityInput, + VulnerabilityTypeID: &vulnIDs.VulnerabilityTypeID, + VulnerabilityNodeID: &vulnIDs.VulnerabilityNodeID, + } + } + return results, nil } -func ingestLicenses(ctx context.Context, client graphql.Client, v []model.LicenseInputSpec) error { - _, err := model.IngestLicenses(ctx, client, v) +// ingestLicenses takes in the map of IDorLicenseInput which contains the licenseInput and outputs a map that contains the licenseID to be used for verb ingestion +func ingestLicenses(ctx context.Context, client graphql.Client, licenseInputMap map[string]*model.IDorLicenseInput) (map[string]*model.IDorLicenseInput, error) { + var keys []string + var licenseInputs []model.IDorLicenseInput + licenseInputs = make([]model.IDorLicenseInput, 0) + for key, licenseInput := range licenseInputMap { + keys = append(keys, key) + licenseInputs = append(licenseInputs, *licenseInput) + } + response, err := model.IngestLicenses(ctx, client, licenseInputs) if err != nil { - return fmt.Errorf("ingestLicenses failed with error: %w", err) + return nil, fmt.Errorf("IngestLicenses failed with error: %w", err) } - return nil + results := make(map[string]*model.IDorLicenseInput) + + for i := range response.IngestLicenses { + licenseID := response.IngestLicenses[i] + results[keys[i]] = &model.IDorLicenseInput{ + LicenseInput: licenseInputs[i].LicenseInput, + LicenseID: &licenseID, + } + } + return results, nil } -func ingestCertifyVulns(ctx context.Context, client graphql.Client, cv []assembler.CertifyVulnIngest) error { - var pkgs []model.PkgInputSpec - var vulnerabilities []model.VulnerabilityInputSpec +func ingestCertifyVulns(ctx context.Context, client graphql.Client, cv []assembler.CertifyVulnIngest, packageInputMap map[string]*model.IDorPkgInput, vulnInputMap map[string]*model.IDorVulnerabilityInput) error { + var pkgIDs []model.IDorPkgInput + var vulnerabilityIDs []model.IDorVulnerabilityInput var scanMetadataList []model.ScanMetadataInput + for _, ingest := range cv { - pkgs = append(pkgs, *ingest.Pkg) - vulnerabilities = append(vulnerabilities, *ingest.Vulnerability) + if pkgID, found := packageInputMap[helpers.PkgInputSpecToPurl(ingest.Pkg)]; found { + pkgIDs = append(pkgIDs, *pkgID) + } else { + return fmt.Errorf("failed to find ingested Package ID for certifyVuln: %s", helpers.PkgInputSpecToPurl(ingest.Pkg)) + } + if vulnID, found := vulnInputMap[helpers.VulnInputToVURI(ingest.Vulnerability)]; found { + vulnerabilityIDs = append(vulnerabilityIDs, *vulnID) + } else { + return fmt.Errorf("failed to find ingested vulnerability ID for certifyVuln: %s", helpers.VulnInputToVURI(ingest.Vulnerability)) + } scanMetadataList = append(scanMetadataList, *ingest.VulnData) } if len(cv) > 0 { - _, err := model.IngestCertifyVulnPkgs(ctx, client, pkgs, vulnerabilities, scanMetadataList) + _, err := model.IngestCertifyVulnPkgs(ctx, client, pkgIDs, vulnerabilityIDs, scanMetadataList) if err != nil { return fmt.Errorf("CertifyVulnPkgs failed with error: %w", err) } @@ -278,12 +400,11 @@ func ingestCertifyVulns(ctx context.Context, client graphql.Client, cv []assembl return nil } -func ingestVEXs(ctx context.Context, client graphql.Client, vi []assembler.VexIngest) error { - - var pkgs []model.PkgInputSpec - var artifacts []model.ArtifactInputSpec - var pkgVulns []model.VulnerabilityInputSpec - var artVulns []model.VulnerabilityInputSpec +func ingestVEXs(ctx context.Context, client graphql.Client, vi []assembler.VexIngest, packageInputMap map[string]*model.IDorPkgInput, artInputMap map[string]*model.IDorArtifactInput, vulnInputMap map[string]*model.IDorVulnerabilityInput) error { + var pkgIDs []model.IDorPkgInput + var artifactIDs []model.IDorArtifactInput + var pkgVulns []model.IDorVulnerabilityInput + var artVulns []model.IDorVulnerabilityInput var pkgVEXs []model.VexStatementInputSpec var artVEXs []model.VexStatementInputSpec for _, ingest := range vi { @@ -295,23 +416,39 @@ func ingestVEXs(ctx context.Context, client graphql.Client, vi []assembler.VexIn } if ingest.Pkg != nil { - pkgs = append(pkgs, *ingest.Pkg) - pkgVulns = append(pkgVulns, *ingest.Vulnerability) + if pkgID, found := packageInputMap[helpers.PkgInputSpecToPurl(ingest.Pkg)]; found { + pkgIDs = append(pkgIDs, *pkgID) + } else { + return fmt.Errorf("failed to find ingested Package ID for Vex: %s", helpers.PkgInputSpecToPurl(ingest.Pkg)) + } + if vulnID, found := vulnInputMap[helpers.VulnInputToVURI(ingest.Vulnerability)]; found { + pkgVulns = append(pkgVulns, *vulnID) + } else { + return fmt.Errorf("failed to find ingested vulnerability ID for Vex: %s", helpers.VulnInputToVURI(ingest.Vulnerability)) + } pkgVEXs = append(pkgVEXs, *ingest.VexData) } else { - artifacts = append(artifacts, *ingest.Artifact) - artVulns = append(artVulns, *ingest.Vulnerability) + if artID, found := artInputMap[helpers.ArtifactKey(ingest.Artifact)]; found { + artifactIDs = append(artifactIDs, *artID) + } else { + return fmt.Errorf("failed to find ingested artifact ID for Vex: %s", helpers.ArtifactKey(ingest.Artifact)) + } + if vulnID, found := vulnInputMap[helpers.VulnInputToVURI(ingest.Vulnerability)]; found { + artVulns = append(artVulns, *vulnID) + } else { + return fmt.Errorf("failed to find ingested vulnerability ID for Vex: %s", helpers.VulnInputToVURI(ingest.Vulnerability)) + } artVEXs = append(artVEXs, *ingest.VexData) } } - if len(artifacts) > 0 { - _, err := model.IngestCertifyVexArtifacts(ctx, client, artifacts, artVulns, artVEXs) + if len(artifactIDs) > 0 { + _, err := model.IngestCertifyVexArtifacts(ctx, client, artifactIDs, artVulns, artVEXs) if err != nil { return fmt.Errorf("CertifyVexArtifacts failed with error: %w", err) } } - if len(pkgs) > 0 { - _, err := model.IngestCertifyVexPkgs(ctx, client, pkgs, pkgVulns, pkgVEXs) + if len(pkgIDs) > 0 { + _, err := model.IngestCertifyVexPkgs(ctx, client, pkgIDs, pkgVulns, pkgVEXs) if err != nil { return fmt.Errorf("CertifyVexPkgs failed with error: %w", err) } @@ -319,15 +456,19 @@ func ingestVEXs(ctx context.Context, client graphql.Client, vi []assembler.VexIn return nil } -func ingestVulnMetadatas(ctx context.Context, client graphql.Client, vm []assembler.VulnMetadataIngest) error { - var vulnerabilities []model.VulnerabilityInputSpec +func ingestVulnMetadatas(ctx context.Context, client graphql.Client, vm []assembler.VulnMetadataIngest, vulnInputMap map[string]*model.IDorVulnerabilityInput) error { + var vulnIDs []model.IDorVulnerabilityInput var vulnMetadataList []model.VulnerabilityMetadataInputSpec for _, ingest := range vm { - vulnerabilities = append(vulnerabilities, *ingest.Vulnerability) + if vulnID, found := vulnInputMap[helpers.VulnInputToVURI(ingest.Vulnerability)]; found { + vulnIDs = append(vulnIDs, *vulnID) + } else { + return fmt.Errorf("failed to find ingested vulnerability ID for vulnMetadata: %s", helpers.VulnInputToVURI(ingest.Vulnerability)) + } vulnMetadataList = append(vulnMetadataList, *ingest.VulnMetadata) } if len(vm) > 0 { - _, err := model.IngestBulkVulnHasMetadata(ctx, client, vulnerabilities, vulnMetadataList) + _, err := model.IngestBulkVulnHasMetadata(ctx, client, vulnIDs, vulnMetadataList) if err != nil { return fmt.Errorf("VulnHasMetadatas failed with error: %w", err) } @@ -335,17 +476,25 @@ func ingestVulnMetadatas(ctx context.Context, client graphql.Client, vm []assemb return nil } -func ingestVulnEquals(ctx context.Context, client graphql.Client, ve []assembler.VulnEqualIngest) error { - var vulnerabilities []model.VulnerabilityInputSpec - var equalVulnerabilities []model.VulnerabilityInputSpec +func ingestVulnEquals(ctx context.Context, client graphql.Client, ve []assembler.VulnEqualIngest, vulnInputMap map[string]*model.IDorVulnerabilityInput) error { + var vulnIDs []model.IDorVulnerabilityInput + var equalVulnIDs []model.IDorVulnerabilityInput var vulnEqualList []model.VulnEqualInputSpec for _, ingest := range ve { - vulnerabilities = append(vulnerabilities, *ingest.Vulnerability) - equalVulnerabilities = append(equalVulnerabilities, *ingest.EqualVulnerability) + if vulnID, found := vulnInputMap[helpers.VulnInputToVURI(ingest.Vulnerability)]; found { + vulnIDs = append(vulnIDs, *vulnID) + } else { + return fmt.Errorf("failed to find ingested vulnerability ID for vulnMetadata: %s", helpers.VulnInputToVURI(ingest.Vulnerability)) + } + if equalVulnID, found := vulnInputMap[helpers.VulnInputToVURI(ingest.EqualVulnerability)]; found { + equalVulnIDs = append(equalVulnIDs, *equalVulnID) + } else { + return fmt.Errorf("failed to find ingested equal vulnerability ID for vulnMetadata: %s", helpers.VulnInputToVURI(ingest.EqualVulnerability)) + } vulnEqualList = append(vulnEqualList, *ingest.VulnEqual) } if len(ve) > 0 { - _, err := model.IngestVulnEquals(ctx, client, vulnerabilities, equalVulnerabilities, vulnEqualList) + _, err := model.IngestVulnEquals(ctx, client, vulnIDs, equalVulnIDs, vulnEqualList) if err != nil { return fmt.Errorf("IngestVulnEquals failed with error: %w", err) } @@ -353,32 +502,48 @@ func ingestVulnEquals(ctx context.Context, client graphql.Client, ve []assembler return nil } -func ingestHasSourceAts(ctx context.Context, client graphql.Client, hs []assembler.HasSourceAtIngest) error { - var pkgVersions []model.PkgInputSpec - var pkgNames []model.PkgInputSpec - var pkgVersionSources []model.SourceInputSpec - var pkgNameSources []model.SourceInputSpec +func ingestHasSourceAts(ctx context.Context, client graphql.Client, hs []assembler.HasSourceAtIngest, packageInputMap map[string]*model.IDorPkgInput, sourceInputMap map[string]*model.IDorSourceInput) error { + var specificVersionPkgIDs []model.IDorPkgInput + var allVersionPkgIDs []model.IDorPkgInput + var specificVersionSrcIDs []model.IDorSourceInput + var allVersionSrcIDs []model.IDorSourceInput var pkgVersionHasSourceAt []model.HasSourceAtInputSpec var pkgNameHasSourceAt []model.HasSourceAtInputSpec for _, ingest := range hs { if ingest.PkgMatchFlag.Pkg == model.PkgMatchTypeSpecificVersion { - pkgVersions = append(pkgVersions, *ingest.Pkg) - pkgVersionSources = append(pkgVersionSources, *ingest.Src) + if pkgID, found := packageInputMap[helpers.PkgInputSpecToPurl(ingest.Pkg)]; found { + specificVersionPkgIDs = append(specificVersionPkgIDs, *pkgID) + } else { + return fmt.Errorf("failed to find ingested Package ID for hasSourceAt: %s", helpers.PkgInputSpecToPurl(ingest.Pkg)) + } + if srcID, found := sourceInputMap[helpers.ConcatenateSourceInput(ingest.Src)]; found { + specificVersionSrcIDs = append(specificVersionSrcIDs, *srcID) + } else { + return fmt.Errorf("failed to find ingested Source ID for hasSourceAt: %s", helpers.ConcatenateSourceInput(ingest.Src)) + } pkgVersionHasSourceAt = append(pkgVersionHasSourceAt, *ingest.HasSourceAt) } else { - pkgNames = append(pkgNames, *ingest.Pkg) - pkgNameSources = append(pkgNameSources, *ingest.Src) + if pkgID, found := packageInputMap[helpers.PkgInputSpecToPurl(ingest.Pkg)]; found { + allVersionPkgIDs = append(allVersionPkgIDs, *pkgID) + } else { + return fmt.Errorf("failed to find ingested Package ID for hasSourceAt: %s", helpers.PkgInputSpecToPurl(ingest.Pkg)) + } + if srcID, found := sourceInputMap[helpers.ConcatenateSourceInput(ingest.Src)]; found { + allVersionSrcIDs = append(allVersionSrcIDs, *srcID) + } else { + return fmt.Errorf("failed to find ingested Source ID for hasSourceAt: %s", helpers.ConcatenateSourceInput(ingest.Src)) + } pkgNameHasSourceAt = append(pkgNameHasSourceAt, *ingest.HasSourceAt) } } - if len(pkgVersions) > 0 { - _, err := model.IngestHasSourcesAt(ctx, client, pkgVersions, model.MatchFlags{Pkg: model.PkgMatchTypeSpecificVersion}, pkgVersionSources, pkgVersionHasSourceAt) + if len(specificVersionPkgIDs) > 0 { + _, err := model.IngestHasSourcesAt(ctx, client, specificVersionPkgIDs, model.MatchFlags{Pkg: model.PkgMatchTypeSpecificVersion}, specificVersionSrcIDs, pkgVersionHasSourceAt) if err != nil { return fmt.Errorf("IngestHasSourceAts - specific version failed with error: %w", err) } } - if len(pkgNames) > 0 { - _, err := model.IngestHasSourcesAt(ctx, client, pkgNames, model.MatchFlags{Pkg: model.PkgMatchTypeAllVersions}, pkgNameSources, pkgNameHasSourceAt) + if len(allVersionPkgIDs) > 0 { + _, err := model.IngestHasSourcesAt(ctx, client, allVersionPkgIDs, model.MatchFlags{Pkg: model.PkgMatchTypeAllVersions}, allVersionSrcIDs, pkgNameHasSourceAt) if err != nil { return fmt.Errorf("IngestHasSourceAts - all versions failed with error: %w", err) } @@ -386,19 +551,37 @@ func ingestHasSourceAts(ctx context.Context, client graphql.Client, hs []assembl return nil } -func ingestHasSLSAs(ctx context.Context, client graphql.Client, v []assembler.HasSlsaIngest) error { - var subjects []model.ArtifactInputSpec +func ingestHasSLSAs(ctx context.Context, client graphql.Client, hs []assembler.HasSlsaIngest, artInputMap map[string]*model.IDorArtifactInput, + matInputSpec map[string]*model.IDorArtifactInput, builderInputMap map[string]*model.IDorBuilderInput) error { + + var subjectIDs []model.IDorArtifactInput var slsaAttestations []model.SLSAInputSpec - var materialList [][]model.ArtifactInputSpec - var builders []model.BuilderInputSpec - for _, ingest := range v { - subjects = append(subjects, *ingest.Artifact) + var materialIDs [][]model.IDorArtifactInput + var builderIDs []model.IDorBuilderInput + for _, ingest := range hs { + if artID, found := artInputMap[helpers.ArtifactKey(ingest.Artifact)]; found { + subjectIDs = append(subjectIDs, *artID) + } else { + return fmt.Errorf("failed to find ingested artifact ID for hasSLSA: %s", helpers.ArtifactKey(ingest.Artifact)) + } + if buildID, found := builderInputMap[ingest.Builder.Uri]; found { + builderIDs = append(builderIDs, *buildID) + } else { + return fmt.Errorf("failed to find ingested builder ID for hasSLSA: %s", ingest.Builder.Uri) + } + var matIDList []model.IDorArtifactInput + for _, mat := range ingest.Materials { + if matID, found := matInputSpec[helpers.ArtifactKey(&mat)]; found { + matIDList = append(matIDList, *matID) + } else { + return fmt.Errorf("failed to find ingested material ID for hasSLSA: %s", helpers.ArtifactKey(&mat)) + } + } + materialIDs = append(materialIDs, matIDList) slsaAttestations = append(slsaAttestations, *ingest.HasSlsa) - builders = append(builders, *ingest.Builder) - materialList = append(materialList, ingest.Materials) } - if len(v) > 0 { - _, err := model.IngestSLSAForArtifacts(ctx, client, subjects, materialList, builders, slsaAttestations) + if len(hs) > 0 { + _, err := model.IngestSLSAForArtifacts(ctx, client, subjectIDs, materialIDs, builderIDs, slsaAttestations) if err != nil { return fmt.Errorf("SLSAForArtifacts failed with error: %w", err) } @@ -406,15 +589,19 @@ func ingestHasSLSAs(ctx context.Context, client graphql.Client, v []assembler.Ha return nil } -func ingestCertifyScorecards(ctx context.Context, client graphql.Client, v []assembler.CertifyScorecardIngest) error { - var srcs []model.SourceInputSpec +func ingestCertifyScorecards(ctx context.Context, client graphql.Client, cs []assembler.CertifyScorecardIngest, sourceInputMap map[string]*model.IDorSourceInput) error { + var sourceIDs []model.IDorSourceInput var scorecards []model.ScorecardInputSpec - for _, ingest := range v { - srcs = append(srcs, *ingest.Source) + for _, ingest := range cs { + if srcID, found := sourceInputMap[helpers.ConcatenateSourceInput(ingest.Source)]; found { + sourceIDs = append(sourceIDs, *srcID) + } else { + return fmt.Errorf("failed to find ingested Source ID for certifyScorecard: %s", helpers.ConcatenateSourceInput(ingest.Source)) + } scorecards = append(scorecards, *ingest.Scorecard) } - if len(v) > 0 { - _, err := model.IngestCertifyScorecards(ctx, client, srcs, scorecards) + if len(cs) > 0 { + _, err := model.IngestCertifyScorecards(ctx, client, sourceIDs, scorecards) if err != nil { return fmt.Errorf("certifyScorecards failed with error: %w", err) } @@ -422,40 +609,56 @@ func ingestCertifyScorecards(ctx context.Context, client graphql.Client, v []ass return nil } -func ingestIsDependencies(ctx context.Context, client graphql.Client, v []assembler.IsDependencyIngest) ([]string, error) { +func ingestIsDependencies(ctx context.Context, client graphql.Client, deps []assembler.IsDependencyIngest, packageInputMap map[string]*model.IDorPkgInput) ([]string, error) { - var depToVersion, depToName struct { - pkgs []model.PkgInputSpec - depPkgs []model.PkgInputSpec + var depToSpecificVersion, depToAllVersions struct { + pkgs []model.IDorPkgInput + depPkgs []model.IDorPkgInput depPkgMatchFlag model.MatchFlags dependencies []model.IsDependencyInputSpec } - depToVersion.depPkgMatchFlag = model.MatchFlags{Pkg: model.PkgMatchTypeSpecificVersion} - depToName.depPkgMatchFlag = model.MatchFlags{Pkg: model.PkgMatchTypeAllVersions} + depToSpecificVersion.depPkgMatchFlag = model.MatchFlags{Pkg: model.PkgMatchTypeSpecificVersion} + depToAllVersions.depPkgMatchFlag = model.MatchFlags{Pkg: model.PkgMatchTypeAllVersions} - for _, ingest := range v { + for _, ingest := range deps { if ingest.DepPkgMatchFlag.Pkg == model.PkgMatchTypeSpecificVersion { - depToVersion.pkgs = append(depToVersion.pkgs, *ingest.Pkg) - depToVersion.depPkgs = append(depToVersion.depPkgs, *ingest.DepPkg) - depToVersion.dependencies = append(depToVersion.dependencies, *ingest.IsDependency) + if pkgID, found := packageInputMap[helpers.PkgInputSpecToPurl(ingest.Pkg)]; found { + depToSpecificVersion.pkgs = append(depToSpecificVersion.pkgs, *pkgID) + } else { + return nil, fmt.Errorf("failed to find ingested Package ID for isDependency: %s", helpers.PkgInputSpecToPurl(ingest.Pkg)) + } + if depPkgID, found := packageInputMap[helpers.PkgInputSpecToPurl(ingest.DepPkg)]; found { + depToSpecificVersion.depPkgs = append(depToSpecificVersion.depPkgs, *depPkgID) + } else { + return nil, fmt.Errorf("failed to find ingested dependency Package ID for isDependency: %s", helpers.PkgInputSpecToPurl(ingest.DepPkg)) + } + depToSpecificVersion.dependencies = append(depToSpecificVersion.dependencies, *ingest.IsDependency) } else if ingest.DepPkgMatchFlag.Pkg == model.PkgMatchTypeAllVersions { - depToName.pkgs = append(depToName.pkgs, *ingest.Pkg) - depToName.depPkgs = append(depToName.depPkgs, *ingest.DepPkg) - depToName.dependencies = append(depToName.dependencies, *ingest.IsDependency) + if pkgID, found := packageInputMap[helpers.PkgInputSpecToPurl(ingest.Pkg)]; found { + depToAllVersions.pkgs = append(depToAllVersions.pkgs, *pkgID) + } else { + return nil, fmt.Errorf("failed to find ingested Package ID for isDependency: %s", helpers.PkgInputSpecToPurl(ingest.Pkg)) + } + if depPkgID, found := packageInputMap[helpers.PkgInputSpecToPurl(ingest.DepPkg)]; found { + depToAllVersions.depPkgs = append(depToAllVersions.depPkgs, *depPkgID) + } else { + return nil, fmt.Errorf("failed to find ingested dependency Package ID for isDependency: %s", helpers.PkgInputSpecToPurl(ingest.DepPkg)) + } + depToAllVersions.dependencies = append(depToAllVersions.dependencies, *ingest.IsDependency) } } var isDependenciesIDs []string - if len(depToVersion.pkgs) > 0 { - isDependencies, err := model.IngestIsDependencies(ctx, client, depToVersion.pkgs, depToVersion.depPkgs, depToVersion.depPkgMatchFlag, depToVersion.dependencies) + if len(depToSpecificVersion.pkgs) > 0 { + isDependencies, err := model.IngestIsDependencies(ctx, client, depToSpecificVersion.pkgs, depToSpecificVersion.depPkgs, depToSpecificVersion.depPkgMatchFlag, depToSpecificVersion.dependencies) if err != nil { return nil, fmt.Errorf("isDependencies failed with error: %w", err) } isDependenciesIDs = append(isDependenciesIDs, isDependencies.IngestDependencies...) } - if len(depToName.pkgs) > 0 { - isDependencies, err := model.IngestIsDependencies(ctx, client, depToName.pkgs, depToName.depPkgs, depToName.depPkgMatchFlag, depToName.dependencies) + if len(depToAllVersions.pkgs) > 0 { + isDependencies, err := model.IngestIsDependencies(ctx, client, depToAllVersions.pkgs, depToAllVersions.depPkgs, depToAllVersions.depPkgMatchFlag, depToAllVersions.dependencies) if err != nil { return nil, fmt.Errorf("isDependencies failed with error: %w", err) } @@ -465,17 +668,25 @@ func ingestIsDependencies(ctx context.Context, client graphql.Client, v []assemb return isDependenciesIDs, nil } -func ingestPkgEquals(ctx context.Context, client graphql.Client, v []assembler.PkgEqualIngest) error { - var packages []model.PkgInputSpec - var equalPackages []model.PkgInputSpec +func ingestPkgEquals(ctx context.Context, client graphql.Client, pe []assembler.PkgEqualIngest, packageInputMap map[string]*model.IDorPkgInput) error { + var pkgIDs []model.IDorPkgInput + var equalPkgIDs []model.IDorPkgInput var pkgEquals []model.PkgEqualInputSpec - for _, ingest := range v { - packages = append(packages, *ingest.Pkg) - equalPackages = append(equalPackages, *ingest.EqualPkg) + for _, ingest := range pe { + if pkgID, found := packageInputMap[helpers.PkgInputSpecToPurl(ingest.Pkg)]; found { + pkgIDs = append(pkgIDs, *pkgID) + } else { + return fmt.Errorf("failed to find ingested Package ID for pkgEqual: %s", helpers.PkgInputSpecToPurl(ingest.Pkg)) + } + if equalPkgID, found := packageInputMap[helpers.PkgInputSpecToPurl(ingest.EqualPkg)]; found { + equalPkgIDs = append(equalPkgIDs, *equalPkgID) + } else { + return fmt.Errorf("failed to find ingested equal Package ID for pkgEqual: %s", helpers.PkgInputSpecToPurl(ingest.EqualPkg)) + } pkgEquals = append(pkgEquals, *ingest.PkgEqual) } - if len(v) > 0 { - _, err := model.IngestPkgEquals(ctx, client, packages, equalPackages, pkgEquals) + if len(pe) > 0 { + _, err := model.IngestPkgEquals(ctx, client, pkgIDs, equalPkgIDs, pkgEquals) if err != nil { return fmt.Errorf("PkgEquals failed with error: %w", err) } @@ -483,17 +694,25 @@ func ingestPkgEquals(ctx context.Context, client graphql.Client, v []assembler.P return nil } -func ingestHashEquals(ctx context.Context, client graphql.Client, v []assembler.HashEqualIngest) error { - var artifacts []model.ArtifactInputSpec - var equalArtifacts []model.ArtifactInputSpec +func ingestHashEquals(ctx context.Context, client graphql.Client, he []assembler.HashEqualIngest, artInputMap map[string]*model.IDorArtifactInput) error { + var artIDs []model.IDorArtifactInput + var equalArtIDs []model.IDorArtifactInput var hashEquals []model.HashEqualInputSpec - for _, ingest := range v { - artifacts = append(artifacts, *ingest.Artifact) - equalArtifacts = append(equalArtifacts, *ingest.EqualArtifact) + for _, ingest := range he { + if artID, found := artInputMap[helpers.ArtifactKey(ingest.Artifact)]; found { + artIDs = append(artIDs, *artID) + } else { + return fmt.Errorf("failed to find ingested artifact ID for hashEqual: %s", helpers.ArtifactKey(ingest.Artifact)) + } + if equalArtID, found := artInputMap[helpers.ArtifactKey(ingest.EqualArtifact)]; found { + equalArtIDs = append(equalArtIDs, *equalArtID) + } else { + return fmt.Errorf("failed to find ingested artifact ID for hashEqual: %s", helpers.ArtifactKey(ingest.EqualArtifact)) + } hashEquals = append(hashEquals, *ingest.HashEqual) } - if len(v) > 0 { - _, err := model.IngestHashEquals(ctx, client, artifacts, equalArtifacts, hashEquals) + if len(he) > 0 { + _, err := model.IngestHashEquals(ctx, client, artIDs, equalArtIDs, hashEquals) if err != nil { return fmt.Errorf("HashEquals failed with error: %w", err) } @@ -501,14 +720,16 @@ func ingestHashEquals(ctx context.Context, client graphql.Client, v []assembler. return nil } -func ingestHasSBOMs(ctx context.Context, client graphql.Client, v []assembler.HasSBOMIngest, includes model.HasSBOMIncludesInputSpec) error { - var pkgs []model.PkgInputSpec - var artifacts []model.ArtifactInputSpec +func ingestHasSBOMs(ctx context.Context, client graphql.Client, hs []assembler.HasSBOMIngest, includes model.HasSBOMIncludesInputSpec, packageInputMap map[string]*model.IDorPkgInput, + artInputMap map[string]*model.IDorArtifactInput) error { + + var pkgIDs []model.IDorPkgInput + var artIDs []model.IDorArtifactInput var pkgSBOMs []model.HasSBOMInputSpec var artSBOMs []model.HasSBOMInputSpec var pkgIncludes []model.HasSBOMIncludesInputSpec var artIncludes []model.HasSBOMIncludesInputSpec - for _, ingest := range v { + for _, ingest := range hs { if ingest.Pkg != nil && ingest.Artifact != nil { return fmt.Errorf("unable to create hasSBOM with both artifact and Pkg subject specified") } @@ -517,23 +738,31 @@ func ingestHasSBOMs(ctx context.Context, client graphql.Client, v []assembler.Ha } if ingest.Pkg != nil { - pkgs = append(pkgs, *ingest.Pkg) + if pkgID, found := packageInputMap[helpers.PkgInputSpecToPurl(ingest.Pkg)]; found { + pkgIDs = append(pkgIDs, *pkgID) + } else { + return fmt.Errorf("failed to find ingested Package ID for hasSBOM: %s", helpers.PkgInputSpecToPurl(ingest.Pkg)) + } pkgSBOMs = append(pkgSBOMs, *ingest.HasSBOM) pkgIncludes = append(pkgIncludes, includes) } else { - artifacts = append(artifacts, *ingest.Artifact) + if artID, found := artInputMap[helpers.ArtifactKey(ingest.Artifact)]; found { + artIDs = append(artIDs, *artID) + } else { + return fmt.Errorf("failed to find ingested artifact ID for hasSBOM: %s", helpers.ArtifactKey(ingest.Artifact)) + } artSBOMs = append(artSBOMs, *ingest.HasSBOM) artIncludes = append(artIncludes, includes) } } - if len(artifacts) > 0 { - _, err := model.IngestHasSBOMArtifacts(ctx, client, artifacts, artSBOMs, artIncludes) + if len(artIDs) > 0 { + _, err := model.IngestHasSBOMArtifacts(ctx, client, artIDs, artSBOMs, artIncludes) if err != nil { return fmt.Errorf("hasSBOMArtifacts failed with error: %w", err) } } - if len(pkgs) > 0 { - _, err := model.IngestHasSBOMPkgs(ctx, client, pkgs, pkgSBOMs, pkgIncludes) + if len(pkgIDs) > 0 { + _, err := model.IngestHasSBOMPkgs(ctx, client, pkgIDs, pkgSBOMs, pkgIncludes) if err != nil { return fmt.Errorf("hasSBOMPkgs failed with error: %w", err) } @@ -541,11 +770,13 @@ func ingestHasSBOMs(ctx context.Context, client graphql.Client, v []assembler.Ha return nil } -func ingestPointOfContacts(ctx context.Context, client graphql.Client, poc []assembler.PointOfContactIngest) error { - var pkgVersions []model.PkgInputSpec - var pkgNames []model.PkgInputSpec - var sources []model.SourceInputSpec - var artifacts []model.ArtifactInputSpec +func ingestPointOfContacts(ctx context.Context, client graphql.Client, poc []assembler.PointOfContactIngest, packageInputMap map[string]*model.IDorPkgInput, + artInputMap map[string]*model.IDorArtifactInput, sourceInputMap map[string]*model.IDorSourceInput) error { + + var pkgSpecificVersionIDs []model.IDorPkgInput + var pkgAllVersionsIDs []model.IDorPkgInput + var sourceIDs []model.IDorSourceInput + var artIDs []model.IDorArtifactInput var pkgVersionPOC []model.PointOfContactInputSpec var pkgNamePOC []model.PointOfContactInputSpec var srcPOC []model.PointOfContactInputSpec @@ -556,40 +787,56 @@ func ingestPointOfContacts(ctx context.Context, client graphql.Client, poc []ass } if ingest.Pkg != nil { if ingest.PkgMatchFlag.Pkg == model.PkgMatchTypeSpecificVersion { - pkgVersions = append(pkgVersions, *ingest.Pkg) + if pkgID, found := packageInputMap[helpers.PkgInputSpecToPurl(ingest.Pkg)]; found { + pkgSpecificVersionIDs = append(pkgSpecificVersionIDs, *pkgID) + } else { + return fmt.Errorf("failed to find ingested Package ID for point of contact: %s", helpers.PkgInputSpecToPurl(ingest.Pkg)) + } pkgVersionPOC = append(pkgVersionPOC, *ingest.PointOfContact) } else { - pkgNames = append(pkgNames, *ingest.Pkg) + if pkgID, found := packageInputMap[helpers.PkgInputSpecToPurl(ingest.Pkg)]; found { + pkgAllVersionsIDs = append(pkgAllVersionsIDs, *pkgID) + } else { + return fmt.Errorf("failed to find ingested Package ID for point of contact: %s", helpers.PkgInputSpecToPurl(ingest.Pkg)) + } pkgNamePOC = append(pkgNamePOC, *ingest.PointOfContact) } } else if ingest.Src != nil { - sources = append(sources, *ingest.Src) + if srcID, found := sourceInputMap[helpers.ConcatenateSourceInput(ingest.Src)]; found { + sourceIDs = append(sourceIDs, *srcID) + } else { + return fmt.Errorf("failed to find ingested Source ID for point of contact: %s", helpers.ConcatenateSourceInput(ingest.Src)) + } srcPOC = append(srcPOC, *ingest.PointOfContact) } else { - artifacts = append(artifacts, *ingest.Artifact) + if artID, found := artInputMap[helpers.ArtifactKey(ingest.Artifact)]; found { + artIDs = append(artIDs, *artID) + } else { + return fmt.Errorf("failed to find ingested artifact ID for point of contact: %s", helpers.ArtifactKey(ingest.Artifact)) + } artPOC = append(artPOC, *ingest.PointOfContact) } } - if len(pkgVersions) > 0 { - _, err := model.IngestPointOfContactPkgs(ctx, client, pkgVersions, model.MatchFlags{Pkg: model.PkgMatchTypeSpecificVersion}, pkgVersionPOC) + if len(pkgSpecificVersionIDs) > 0 { + _, err := model.IngestPointOfContactPkgs(ctx, client, pkgSpecificVersionIDs, model.MatchFlags{Pkg: model.PkgMatchTypeSpecificVersion}, pkgVersionPOC) if err != nil { return fmt.Errorf("HasMetadataPkgs - specific version failed with error: %w", err) } } - if len(pkgNames) > 0 { - _, err := model.IngestPointOfContactPkgs(ctx, client, pkgNames, model.MatchFlags{Pkg: model.PkgMatchTypeAllVersions}, pkgNamePOC) + if len(pkgAllVersionsIDs) > 0 { + _, err := model.IngestPointOfContactPkgs(ctx, client, pkgAllVersionsIDs, model.MatchFlags{Pkg: model.PkgMatchTypeAllVersions}, pkgNamePOC) if err != nil { return fmt.Errorf("HasMetadataPkgs - all versions failed with error: %w", err) } } - if len(sources) > 0 { - _, err := model.IngestPointOfContactSrcs(ctx, client, sources, srcPOC) + if len(sourceIDs) > 0 { + _, err := model.IngestPointOfContactSrcs(ctx, client, sourceIDs, srcPOC) if err != nil { return fmt.Errorf("HasMetadataSrcs failed with error: %w", err) } } - if len(artifacts) > 0 { - _, err := model.IngestPointOfContactArtifacts(ctx, client, artifacts, artPOC) + if len(artIDs) > 0 { + _, err := model.IngestPointOfContactArtifacts(ctx, client, artIDs, artPOC) if err != nil { return fmt.Errorf("HasMetadataArtifacts failed with error: %w", err) } @@ -597,55 +844,73 @@ func ingestPointOfContacts(ctx context.Context, client graphql.Client, poc []ass return nil } -func ingestBulkHasMetadata(ctx context.Context, client graphql.Client, v []assembler.HasMetadataIngest) error { - var pkgVersions []model.PkgInputSpec - var pkgNames []model.PkgInputSpec - var sources []model.SourceInputSpec - var artifacts []model.ArtifactInputSpec +func ingestBulkHasMetadata(ctx context.Context, client graphql.Client, hm []assembler.HasMetadataIngest, packageInputMap map[string]*model.IDorPkgInput, + artInputMap map[string]*model.IDorArtifactInput, sourceInputMap map[string]*model.IDorSourceInput) error { + + var pkgSpecificVersionIDs []model.IDorPkgInput + var pkgAllVersionsIDs []model.IDorPkgInput + var sourceIDs []model.IDorSourceInput + var artIDs []model.IDorArtifactInput var pkgVersionHasMetadata []model.HasMetadataInputSpec var pkgNameHasMetadata []model.HasMetadataInputSpec var srcHasMetadata []model.HasMetadataInputSpec var artHasMetadata []model.HasMetadataInputSpec - for _, ingest := range v { + for _, ingest := range hm { if err := validatePackageSourceOrArtifactInput(ingest.Pkg, ingest.Src, ingest.Artifact, "ingestBulkHasMetadata"); err != nil { return fmt.Errorf("input validation failed for ingestBulkHasMetadata: %w", err) } if ingest.Pkg != nil { if ingest.PkgMatchFlag.Pkg == model.PkgMatchTypeSpecificVersion { - pkgVersions = append(pkgVersions, *ingest.Pkg) + if pkgID, found := packageInputMap[helpers.PkgInputSpecToPurl(ingest.Pkg)]; found { + pkgSpecificVersionIDs = append(pkgSpecificVersionIDs, *pkgID) + } else { + return fmt.Errorf("failed to find ingested Package ID for hasMetadata: %s", helpers.PkgInputSpecToPurl(ingest.Pkg)) + } pkgVersionHasMetadata = append(pkgVersionHasMetadata, *ingest.HasMetadata) } else { - pkgNames = append(pkgNames, *ingest.Pkg) + if pkgID, found := packageInputMap[helpers.PkgInputSpecToPurl(ingest.Pkg)]; found { + pkgAllVersionsIDs = append(pkgAllVersionsIDs, *pkgID) + } else { + return fmt.Errorf("failed to find ingested Package ID for hasMetadata: %s", helpers.PkgInputSpecToPurl(ingest.Pkg)) + } pkgNameHasMetadata = append(pkgNameHasMetadata, *ingest.HasMetadata) } } else if ingest.Src != nil { - sources = append(sources, *ingest.Src) + if srcID, found := sourceInputMap[helpers.ConcatenateSourceInput(ingest.Src)]; found { + sourceIDs = append(sourceIDs, *srcID) + } else { + return fmt.Errorf("failed to find ingested Source ID for point of contact: %s", helpers.ConcatenateSourceInput(ingest.Src)) + } srcHasMetadata = append(srcHasMetadata, *ingest.HasMetadata) } else { - artifacts = append(artifacts, *ingest.Artifact) + if artID, found := artInputMap[helpers.ArtifactKey(ingest.Artifact)]; found { + artIDs = append(artIDs, *artID) + } else { + return fmt.Errorf("failed to find ingested artifact ID for point of contact: %s", helpers.ArtifactKey(ingest.Artifact)) + } artHasMetadata = append(artHasMetadata, *ingest.HasMetadata) } } - if len(pkgVersions) > 0 { - _, err := model.IngestHasMetadataPkgs(ctx, client, pkgVersions, model.MatchFlags{Pkg: model.PkgMatchTypeSpecificVersion}, pkgVersionHasMetadata) + if len(pkgSpecificVersionIDs) > 0 { + _, err := model.IngestHasMetadataPkgs(ctx, client, pkgSpecificVersionIDs, model.MatchFlags{Pkg: model.PkgMatchTypeSpecificVersion}, pkgVersionHasMetadata) if err != nil { return fmt.Errorf("HasMetadataPkgs - specific version failed with error: %w", err) } } - if len(pkgNames) > 0 { - _, err := model.IngestHasMetadataPkgs(ctx, client, pkgNames, model.MatchFlags{Pkg: model.PkgMatchTypeAllVersions}, pkgNameHasMetadata) + if len(pkgAllVersionsIDs) > 0 { + _, err := model.IngestHasMetadataPkgs(ctx, client, pkgAllVersionsIDs, model.MatchFlags{Pkg: model.PkgMatchTypeAllVersions}, pkgNameHasMetadata) if err != nil { return fmt.Errorf("HasMetadataPkgs - all versions failed with error: %w", err) } } - if len(sources) > 0 { - _, err := model.IngestHasMetadataSrcs(ctx, client, sources, srcHasMetadata) + if len(sourceIDs) > 0 { + _, err := model.IngestHasMetadataSrcs(ctx, client, sourceIDs, srcHasMetadata) if err != nil { return fmt.Errorf("HasMetadataSrcs failed with error: %w", err) } } - if len(artifacts) > 0 { - _, err := model.IngestHasMetadataArtifacts(ctx, client, artifacts, artHasMetadata) + if len(artIDs) > 0 { + _, err := model.IngestHasMetadataArtifacts(ctx, client, artIDs, artHasMetadata) if err != nil { return fmt.Errorf("HasMetadataArtifacts failed with error: %w", err) } @@ -653,55 +918,73 @@ func ingestBulkHasMetadata(ctx context.Context, client graphql.Client, v []assem return nil } -func ingestCertifyGoods(ctx context.Context, client graphql.Client, v []assembler.CertifyGoodIngest) error { - var pkgVersions []model.PkgInputSpec - var pkgNames []model.PkgInputSpec - var sources []model.SourceInputSpec - var artifacts []model.ArtifactInputSpec +func ingestCertifyGoods(ctx context.Context, client graphql.Client, cg []assembler.CertifyGoodIngest, packageInputMap map[string]*model.IDorPkgInput, + artInputMap map[string]*model.IDorArtifactInput, sourceInputMap map[string]*model.IDorSourceInput) error { + + var pkgSpecificVersionIDs []model.IDorPkgInput + var pkgAllVersionsIDs []model.IDorPkgInput + var sourceIDs []model.IDorSourceInput + var artIDs []model.IDorArtifactInput var pkgVersionCertifyGoods []model.CertifyGoodInputSpec var pkgNameCertifyGoods []model.CertifyGoodInputSpec var srcCertifyGoods []model.CertifyGoodInputSpec var artCertifyGoods []model.CertifyGoodInputSpec - for _, ingest := range v { + for _, ingest := range cg { if err := validatePackageSourceOrArtifactInput(ingest.Pkg, ingest.Src, ingest.Artifact, "ingestCertifyGoods"); err != nil { return fmt.Errorf("input validation failed for ingestCertifyGoods: %w", err) } if ingest.Pkg != nil { if ingest.PkgMatchFlag.Pkg == model.PkgMatchTypeSpecificVersion { - pkgVersions = append(pkgVersions, *ingest.Pkg) + if pkgID, found := packageInputMap[helpers.PkgInputSpecToPurl(ingest.Pkg)]; found { + pkgSpecificVersionIDs = append(pkgSpecificVersionIDs, *pkgID) + } else { + return fmt.Errorf("failed to find ingested Package ID for certifyGood: %s", helpers.PkgInputSpecToPurl(ingest.Pkg)) + } pkgVersionCertifyGoods = append(pkgVersionCertifyGoods, *ingest.CertifyGood) } else { - pkgNames = append(pkgNames, *ingest.Pkg) + if pkgID, found := packageInputMap[helpers.PkgInputSpecToPurl(ingest.Pkg)]; found { + pkgAllVersionsIDs = append(pkgAllVersionsIDs, *pkgID) + } else { + return fmt.Errorf("failed to find ingested Package ID for certifyGood: %s", helpers.PkgInputSpecToPurl(ingest.Pkg)) + } pkgNameCertifyGoods = append(pkgNameCertifyGoods, *ingest.CertifyGood) } } else if ingest.Src != nil { - sources = append(sources, *ingest.Src) + if srcID, found := sourceInputMap[helpers.ConcatenateSourceInput(ingest.Src)]; found { + sourceIDs = append(sourceIDs, *srcID) + } else { + return fmt.Errorf("failed to find ingested Source ID for certifyGood: %s", helpers.ConcatenateSourceInput(ingest.Src)) + } srcCertifyGoods = append(srcCertifyGoods, *ingest.CertifyGood) } else { - artifacts = append(artifacts, *ingest.Artifact) + if artID, found := artInputMap[helpers.ArtifactKey(ingest.Artifact)]; found { + artIDs = append(artIDs, *artID) + } else { + return fmt.Errorf("failed to find ingested artifact ID for certifyGood: %s", helpers.ArtifactKey(ingest.Artifact)) + } artCertifyGoods = append(artCertifyGoods, *ingest.CertifyGood) } } - if len(pkgVersions) > 0 { - _, err := model.IngestCertifyGoodPkgs(ctx, client, pkgVersions, model.MatchFlags{Pkg: model.PkgMatchTypeSpecificVersion}, pkgVersionCertifyGoods) + if len(pkgSpecificVersionIDs) > 0 { + _, err := model.IngestCertifyGoodPkgs(ctx, client, pkgSpecificVersionIDs, model.MatchFlags{Pkg: model.PkgMatchTypeSpecificVersion}, pkgVersionCertifyGoods) if err != nil { return fmt.Errorf("CertifyGoodPkgs - specific version failed with error: %w", err) } } - if len(pkgNames) > 0 { - _, err := model.IngestCertifyGoodPkgs(ctx, client, pkgNames, model.MatchFlags{Pkg: model.PkgMatchTypeAllVersions}, pkgNameCertifyGoods) + if len(pkgAllVersionsIDs) > 0 { + _, err := model.IngestCertifyGoodPkgs(ctx, client, pkgAllVersionsIDs, model.MatchFlags{Pkg: model.PkgMatchTypeAllVersions}, pkgNameCertifyGoods) if err != nil { return fmt.Errorf("CertifyGoodPkgs - all versions failed with error: %w", err) } } - if len(sources) > 0 { - _, err := model.IngestCertifyGoodSrcs(ctx, client, sources, srcCertifyGoods) + if len(sourceIDs) > 0 { + _, err := model.IngestCertifyGoodSrcs(ctx, client, sourceIDs, srcCertifyGoods) if err != nil { return fmt.Errorf("CertifyGoodSrcs failed with error: %w", err) } } - if len(artifacts) > 0 { - _, err := model.IngestCertifyGoodArtifacts(ctx, client, artifacts, artCertifyGoods) + if len(artIDs) > 0 { + _, err := model.IngestCertifyGoodArtifacts(ctx, client, artIDs, artCertifyGoods) if err != nil { return fmt.Errorf("CertifyGoodArtifacts failed with error: %w", err) } @@ -709,55 +992,73 @@ func ingestCertifyGoods(ctx context.Context, client graphql.Client, v []assemble return nil } -func ingestCertifyBads(ctx context.Context, client graphql.Client, v []assembler.CertifyBadIngest) error { - var pkgVersions []model.PkgInputSpec - var pkgNames []model.PkgInputSpec - var sources []model.SourceInputSpec - var artifacts []model.ArtifactInputSpec +func ingestCertifyBads(ctx context.Context, client graphql.Client, cb []assembler.CertifyBadIngest, packageInputMap map[string]*model.IDorPkgInput, + artInputMap map[string]*model.IDorArtifactInput, sourceInputMap map[string]*model.IDorSourceInput) error { + + var pkgSpecificVersionIDs []model.IDorPkgInput + var pkgAllVersionsIDs []model.IDorPkgInput + var sourceIDs []model.IDorSourceInput + var artIDs []model.IDorArtifactInput var pkgVersionCertifyBads []model.CertifyBadInputSpec var pkgNameCertifyBads []model.CertifyBadInputSpec var srcCertifyBads []model.CertifyBadInputSpec var artCertifyBads []model.CertifyBadInputSpec - for _, ingest := range v { + for _, ingest := range cb { if err := validatePackageSourceOrArtifactInput(ingest.Pkg, ingest.Src, ingest.Artifact, "ingestCertifyBads"); err != nil { return fmt.Errorf("input validation failed for ingestCertifyBads: %w", err) } if ingest.Pkg != nil { if ingest.PkgMatchFlag.Pkg == model.PkgMatchTypeSpecificVersion { - pkgVersions = append(pkgVersions, *ingest.Pkg) + if pkgID, found := packageInputMap[helpers.PkgInputSpecToPurl(ingest.Pkg)]; found { + pkgSpecificVersionIDs = append(pkgSpecificVersionIDs, *pkgID) + } else { + return fmt.Errorf("failed to find ingested Package ID for certifyBad: %s", helpers.PkgInputSpecToPurl(ingest.Pkg)) + } pkgVersionCertifyBads = append(pkgVersionCertifyBads, *ingest.CertifyBad) } else { - pkgNames = append(pkgNames, *ingest.Pkg) + if pkgID, found := packageInputMap[helpers.PkgInputSpecToPurl(ingest.Pkg)]; found { + pkgAllVersionsIDs = append(pkgAllVersionsIDs, *pkgID) + } else { + return fmt.Errorf("failed to find ingested Package ID for certifyBad: %s", helpers.PkgInputSpecToPurl(ingest.Pkg)) + } pkgNameCertifyBads = append(pkgNameCertifyBads, *ingest.CertifyBad) } } else if ingest.Src != nil { - sources = append(sources, *ingest.Src) + if srcID, found := sourceInputMap[helpers.ConcatenateSourceInput(ingest.Src)]; found { + sourceIDs = append(sourceIDs, *srcID) + } else { + return fmt.Errorf("failed to find ingested Source ID for certifyBad: %s", helpers.ConcatenateSourceInput(ingest.Src)) + } srcCertifyBads = append(srcCertifyBads, *ingest.CertifyBad) } else { - artifacts = append(artifacts, *ingest.Artifact) + if artID, found := artInputMap[helpers.ArtifactKey(ingest.Artifact)]; found { + artIDs = append(artIDs, *artID) + } else { + return fmt.Errorf("failed to find ingested artifact ID for certifyBad: %s", helpers.ArtifactKey(ingest.Artifact)) + } artCertifyBads = append(artCertifyBads, *ingest.CertifyBad) } } - if len(pkgVersions) > 0 { - _, err := model.IngestCertifyBadPkgs(ctx, client, pkgVersions, model.MatchFlags{Pkg: model.PkgMatchTypeSpecificVersion}, pkgVersionCertifyBads) + if len(pkgSpecificVersionIDs) > 0 { + _, err := model.IngestCertifyBadPkgs(ctx, client, pkgSpecificVersionIDs, model.MatchFlags{Pkg: model.PkgMatchTypeSpecificVersion}, pkgVersionCertifyBads) if err != nil { return fmt.Errorf("certifyBadPkgs - specific version failed with error: %w", err) } } - if len(pkgNames) > 0 { - _, err := model.IngestCertifyBadPkgs(ctx, client, pkgNames, model.MatchFlags{Pkg: model.PkgMatchTypeAllVersions}, pkgNameCertifyBads) + if len(pkgAllVersionsIDs) > 0 { + _, err := model.IngestCertifyBadPkgs(ctx, client, pkgAllVersionsIDs, model.MatchFlags{Pkg: model.PkgMatchTypeAllVersions}, pkgNameCertifyBads) if err != nil { return fmt.Errorf("certifyBadPkgs - all versions failed with error: %w", err) } } - if len(sources) > 0 { - _, err := model.IngestCertifyBadSrcs(ctx, client, sources, srcCertifyBads) + if len(sourceIDs) > 0 { + _, err := model.IngestCertifyBadSrcs(ctx, client, sourceIDs, srcCertifyBads) if err != nil { return fmt.Errorf("CertifyBadSrcs failed with error: %w", err) } } - if len(artifacts) > 0 { - _, err := model.IngestCertifyBadArtifacts(ctx, client, artifacts, artCertifyBads) + if len(artIDs) > 0 { + _, err := model.IngestCertifyBadArtifacts(ctx, client, artIDs, artCertifyBads) if err != nil { return fmt.Errorf("CertifyBadArtifacts failed with error: %w", err) } @@ -765,14 +1066,16 @@ func ingestCertifyBads(ctx context.Context, client graphql.Client, v []assembler return nil } -func ingestIsOccurrences(ctx context.Context, client graphql.Client, v []assembler.IsOccurrenceIngest) ([]string, error) { - var pkgs []model.PkgInputSpec - var sources []model.SourceInputSpec - var pkgArtifacts []model.ArtifactInputSpec +func ingestIsOccurrences(ctx context.Context, client graphql.Client, io []assembler.IsOccurrenceIngest, packageInputMap map[string]*model.IDorPkgInput, + artInputMap map[string]*model.IDorArtifactInput, sourceInputMap map[string]*model.IDorSourceInput) ([]string, error) { + + var pkgIDs []model.IDorPkgInput + var sourceIDs []model.IDorSourceInput + var pkgArtIDs []model.IDorArtifactInput var pkgOccurrences []model.IsOccurrenceInputSpec - var srcArtifacts []model.ArtifactInputSpec + var srcArtIDs []model.IDorArtifactInput var srcOccurrences []model.IsOccurrenceInputSpec - for _, ingest := range v { + for _, ingest := range io { if ingest.Pkg != nil && ingest.Src != nil { return nil, fmt.Errorf("unable to create IsOccurrence with both Src and Pkg subject specified") @@ -782,25 +1085,41 @@ func ingestIsOccurrences(ctx context.Context, client graphql.Client, v []assembl } if ingest.Pkg != nil { - pkgs = append(pkgs, *ingest.Pkg) - pkgArtifacts = append(pkgArtifacts, *ingest.Artifact) + if pkgID, found := packageInputMap[helpers.PkgInputSpecToPurl(ingest.Pkg)]; found { + pkgIDs = append(pkgIDs, *pkgID) + } else { + return nil, fmt.Errorf("failed to find ingested Package ID for isOccurrence: %s", helpers.PkgInputSpecToPurl(ingest.Pkg)) + } + if artID, found := artInputMap[helpers.ArtifactKey(ingest.Artifact)]; found { + pkgArtIDs = append(pkgArtIDs, *artID) + } else { + return nil, fmt.Errorf("failed to find ingested artifact ID for isOccurrence: %s", helpers.ArtifactKey(ingest.Artifact)) + } pkgOccurrences = append(pkgOccurrences, *ingest.IsOccurrence) } else { - sources = append(sources, *ingest.Src) - srcArtifacts = append(srcArtifacts, *ingest.Artifact) + if srcID, found := sourceInputMap[helpers.ConcatenateSourceInput(ingest.Src)]; found { + sourceIDs = append(sourceIDs, *srcID) + } else { + return nil, fmt.Errorf("failed to find ingested Source ID for isOccurrence: %s", helpers.ConcatenateSourceInput(ingest.Src)) + } + if artID, found := artInputMap[helpers.ArtifactKey(ingest.Artifact)]; found { + srcArtIDs = append(srcArtIDs, *artID) + } else { + return nil, fmt.Errorf("failed to find ingested artifact ID for isOccurrence: %s", helpers.ArtifactKey(ingest.Artifact)) + } srcOccurrences = append(srcOccurrences, *ingest.IsOccurrence) } } var isOccurrencesIDs []string - if len(sources) > 0 { - isOccurrences, err := model.IngestIsOccurrencesSrc(ctx, client, sources, srcArtifacts, srcOccurrences) + if len(sourceIDs) > 0 { + isOccurrences, err := model.IngestIsOccurrencesSrc(ctx, client, sourceIDs, srcArtIDs, srcOccurrences) if err != nil { return nil, fmt.Errorf("isOccurrencesSrc failed with error: %w", err) } isOccurrencesIDs = append(isOccurrencesIDs, isOccurrences.IngestOccurrences...) } - if len(pkgs) > 0 { - isOccurrences, err := model.IngestIsOccurrencesPkg(ctx, client, pkgs, pkgArtifacts, pkgOccurrences) + if len(pkgIDs) > 0 { + isOccurrences, err := model.IngestIsOccurrencesPkg(ctx, client, pkgIDs, pkgArtIDs, pkgOccurrences) if err != nil { return nil, fmt.Errorf("isOccurrencesPkg failed with error: %w", err) } @@ -809,14 +1128,16 @@ func ingestIsOccurrences(ctx context.Context, client graphql.Client, v []assembl return isOccurrencesIDs, nil } -func ingestCertifyLegals(ctx context.Context, client graphql.Client, v []assembler.CertifyLegalIngest) error { - var pkgs []model.PkgInputSpec - var sources []model.SourceInputSpec - var pkgDec [][]model.LicenseInputSpec - var pkgDis [][]model.LicenseInputSpec +func ingestCertifyLegals(ctx context.Context, client graphql.Client, v []assembler.CertifyLegalIngest, packageInputMap map[string]*model.IDorPkgInput, + sourceInputMap map[string]*model.IDorSourceInput, licenseInputMap map[string]*model.IDorLicenseInput) error { + + var pkgIDs []model.IDorPkgInput + var sourceIDs []model.IDorSourceInput + var pkgDecIDs [][]model.IDorLicenseInput + var pkgDisIDs [][]model.IDorLicenseInput var pkgCL []model.CertifyLegalInputSpec - var srcDec [][]model.LicenseInputSpec - var srcDis [][]model.LicenseInputSpec + var srcDecIDs [][]model.IDorLicenseInput + var srcDisIDs [][]model.IDorLicenseInput var srcCL []model.CertifyLegalInputSpec for _, ingest := range v { @@ -828,25 +1149,73 @@ func ingestCertifyLegals(ctx context.Context, client graphql.Client, v []assembl } if ingest.Pkg != nil { - pkgs = append(pkgs, *ingest.Pkg) - pkgDec = append(pkgDec, ingest.Declared) - pkgDis = append(pkgDis, ingest.Discovered) + if pkgID, found := packageInputMap[helpers.PkgInputSpecToPurl(ingest.Pkg)]; found { + pkgIDs = append(pkgIDs, *pkgID) + } else { + return fmt.Errorf("failed to find ingested Package ID for certifyLegal: %s", helpers.PkgInputSpecToPurl(ingest.Pkg)) + } + + // Declared Licenses + var pkgDecList []model.IDorLicenseInput + for _, dec := range ingest.Declared { + if licID, found := licenseInputMap[helpers.LicenseKey(&dec)]; found { + pkgDecList = append(pkgDecList, *licID) + } else { + return fmt.Errorf("failed to find ingested license ID for certifyLegal: %s", helpers.LicenseKey(&dec)) + } + } + pkgDecIDs = append(pkgDecIDs, pkgDecList) + + // Discovered Licenses + var pkgDisList []model.IDorLicenseInput + for _, dis := range ingest.Discovered { + if licID, found := licenseInputMap[helpers.LicenseKey(&dis)]; found { + pkgDisList = append(pkgDisList, *licID) + } else { + return fmt.Errorf("failed to find ingested license ID for certifyLegal: %s", helpers.LicenseKey(&dis)) + } + } + pkgDisIDs = append(pkgDisIDs, pkgDisList) pkgCL = append(pkgCL, *ingest.CertifyLegal) } else { - sources = append(sources, *ingest.Src) - srcDec = append(srcDec, ingest.Declared) - srcDis = append(srcDis, ingest.Discovered) + if srcID, found := sourceInputMap[helpers.ConcatenateSourceInput(ingest.Src)]; found { + sourceIDs = append(sourceIDs, *srcID) + } else { + return fmt.Errorf("failed to find ingested Source ID for certifyLegal: %s", helpers.ConcatenateSourceInput(ingest.Src)) + } + + // Declared Licenses + var srcDecList []model.IDorLicenseInput + for _, dec := range ingest.Declared { + if licID, found := licenseInputMap[helpers.LicenseKey(&dec)]; found { + srcDecList = append(srcDecList, *licID) + } else { + return fmt.Errorf("failed to find ingested license ID for certifyLegal: %s", helpers.LicenseKey(&dec)) + } + } + srcDecIDs = append(srcDecIDs, srcDecList) + + // Discovered Licenses + var srcDisList []model.IDorLicenseInput + for _, dis := range ingest.Discovered { + if licID, found := licenseInputMap[helpers.LicenseKey(&dis)]; found { + srcDisList = append(srcDisList, *licID) + } else { + return fmt.Errorf("failed to find ingested license ID for certifyLegal: %s", helpers.LicenseKey(&dis)) + } + } + srcDisIDs = append(srcDisIDs, srcDisList) srcCL = append(srcCL, *ingest.CertifyLegal) } } - if len(sources) > 0 { - _, err := model.IngestCertifyLegalSrcs(ctx, client, sources, srcDec, srcDis, srcCL) + if len(sourceIDs) > 0 { + _, err := model.IngestCertifyLegalSrcs(ctx, client, sourceIDs, srcDecIDs, srcDisIDs, srcCL) if err != nil { return fmt.Errorf("certifyLegalSrc failed with error: %w", err) } } - if len(pkgs) > 0 { - _, err := model.IngestCertifyLegalPkgs(ctx, client, pkgs, pkgDec, pkgDis, pkgCL) + if len(pkgIDs) > 0 { + _, err := model.IngestCertifyLegalPkgs(ctx, client, pkgIDs, pkgDecIDs, pkgDisIDs, pkgCL) if err != nil { return fmt.Errorf("certifyLegalPkg failed with error: %w", err) } diff --git a/pkg/assembler/clients/operations/artifact.graphql b/pkg/assembler/clients/operations/artifact.graphql index 8ba029b96e..37b0c5b752 100644 --- a/pkg/assembler/clients/operations/artifact.graphql +++ b/pkg/assembler/clients/operations/artifact.graphql @@ -17,13 +17,13 @@ # Ingest Artifact -mutation IngestArtifact($artifact: ArtifactInputSpec!) { +mutation IngestArtifact($artifact: IDorArtifactInput!) { ingestArtifact(artifact: $artifact) } # Bulk Ingest Artifacts -mutation IngestArtifacts($artifacts: [ArtifactInputSpec!]!) { +mutation IngestArtifacts($artifacts: [IDorArtifactInput!]!) { ingestArtifacts(artifacts: $artifacts) } diff --git a/pkg/assembler/clients/operations/builder.graphql b/pkg/assembler/clients/operations/builder.graphql index 08846fb290..8ca4dd850c 100644 --- a/pkg/assembler/clients/operations/builder.graphql +++ b/pkg/assembler/clients/operations/builder.graphql @@ -17,12 +17,12 @@ # Ingest Builder -mutation IngestBuilder($builder: BuilderInputSpec!) { +mutation IngestBuilder($builder: IDorBuilderInput!) { ingestBuilder(builder: $builder) } # Bulk Ingest Builder -mutation IngestBuilders($builders: [BuilderInputSpec!]!) { +mutation IngestBuilders($builders: [IDorBuilderInput!]!) { ingestBuilders(builders: $builders) } diff --git a/pkg/assembler/clients/operations/certifyBad.graphql b/pkg/assembler/clients/operations/certifyBad.graphql index e588058a1c..b3948b8258 100644 --- a/pkg/assembler/clients/operations/certifyBad.graphql +++ b/pkg/assembler/clients/operations/certifyBad.graphql @@ -18,7 +18,7 @@ # Defines the GraphQL operations to ingest a CertifyBad into GUAC mutation IngestCertifyBadPkg( - $pkg: PkgInputSpec! + $pkg: IDorPkgInput! $pkgMatchType: MatchFlags! $certifyBad: CertifyBadInputSpec! ) { @@ -30,7 +30,7 @@ mutation IngestCertifyBadPkg( } mutation IngestCertifyBadSrc( - $source: SourceInputSpec! + $source: IDorSourceInput! $certifyBad: CertifyBadInputSpec! ) { ingestCertifyBad( @@ -41,7 +41,7 @@ mutation IngestCertifyBadSrc( } mutation IngestCertifyBadArtifact( - $artifact: ArtifactInputSpec! + $artifact: IDorArtifactInput! $certifyBad: CertifyBadInputSpec! ) { ingestCertifyBad( @@ -54,7 +54,7 @@ mutation IngestCertifyBadArtifact( # Defines the GraphQL operations to bulk ingest a CertifyBad into GUAC mutation IngestCertifyBadPkgs( - $pkgs: [PkgInputSpec!]! + $pkgs: [IDorPkgInput!]! $pkgMatchType: MatchFlags! $certifyBads: [CertifyBadInputSpec!]! ) { @@ -66,7 +66,7 @@ mutation IngestCertifyBadPkgs( } mutation IngestCertifyBadSrcs( - $sources: [SourceInputSpec!]! + $sources: [IDorSourceInput!]! $certifyBads: [CertifyBadInputSpec!]! ) { ingestCertifyBads( @@ -77,7 +77,7 @@ mutation IngestCertifyBadSrcs( } mutation IngestCertifyBadArtifacts( - $artifacts: [ArtifactInputSpec!]! + $artifacts: [IDorArtifactInput!]! $certifyBads: [CertifyBadInputSpec!]! ) { ingestCertifyBads( diff --git a/pkg/assembler/clients/operations/certifyGood.graphql b/pkg/assembler/clients/operations/certifyGood.graphql index 14cbccbc48..a561c9fbe4 100644 --- a/pkg/assembler/clients/operations/certifyGood.graphql +++ b/pkg/assembler/clients/operations/certifyGood.graphql @@ -18,7 +18,7 @@ # Defines the GraphQL operations to ingest a CertifyGood into GUAC mutation IngestCertifyGoodPkg( - $pkg: PkgInputSpec! + $pkg: IDorPkgInput! $pkgMatchType: MatchFlags! $certifyGood: CertifyGoodInputSpec! ) { @@ -30,7 +30,7 @@ mutation IngestCertifyGoodPkg( } mutation IngestCertifyGoodSrc( - $source: SourceInputSpec! + $source: IDorSourceInput! $certifyGood: CertifyGoodInputSpec! ) { ingestCertifyGood( @@ -41,7 +41,7 @@ mutation IngestCertifyGoodSrc( } mutation IngestCertifyGoodArtifact( - $artifact: ArtifactInputSpec! + $artifact: IDorArtifactInput! $certifyGood: CertifyGoodInputSpec! ) { ingestCertifyGood( @@ -54,7 +54,7 @@ mutation IngestCertifyGoodArtifact( # Defines the GraphQL operations to bulk ingest a CertifyGood into GUAC mutation IngestCertifyGoodPkgs( - $pkgs: [PkgInputSpec!]! + $pkgs: [IDorPkgInput!]! $pkgMatchType: MatchFlags! $certifyGoods: [CertifyGoodInputSpec!]! ) { @@ -66,7 +66,7 @@ mutation IngestCertifyGoodPkgs( } mutation IngestCertifyGoodSrcs( - $sources: [SourceInputSpec!]! + $sources: [IDorSourceInput!]! $certifyGoods: [CertifyGoodInputSpec!]! ) { ingestCertifyGoods( @@ -77,7 +77,7 @@ mutation IngestCertifyGoodSrcs( } mutation IngestCertifyGoodArtifacts( - $artifacts: [ArtifactInputSpec!]! + $artifacts: [IDorArtifactInput!]! $certifyGoods: [CertifyGoodInputSpec!]! ) { ingestCertifyGoods( diff --git a/pkg/assembler/clients/operations/certifyLegal.graphql b/pkg/assembler/clients/operations/certifyLegal.graphql index 668f4a4186..ba87128a31 100644 --- a/pkg/assembler/clients/operations/certifyLegal.graphql +++ b/pkg/assembler/clients/operations/certifyLegal.graphql @@ -17,19 +17,19 @@ # Defines the GraphQL operations to ingest legal attestations into GUAC -mutation IngestCertifyLegalPkg($pkg: PkgInputSpec!, $declaredLicenses: [LicenseInputSpec!]!, $discoveredLicenses: [LicenseInputSpec!]!, $legal: CertifyLegalInputSpec!) { +mutation IngestCertifyLegalPkg($pkg: IDorPkgInput!, $declaredLicenses: [IDorLicenseInput!]!, $discoveredLicenses: [IDorLicenseInput!]!, $legal: CertifyLegalInputSpec!) { ingestCertifyLegal(subject: {package: $pkg}, declaredLicenses: $declaredLicenses, discoveredLicenses: $discoveredLicenses, certifyLegal: $legal) } -mutation IngestCertifyLegalPkgs($pkgs: [PkgInputSpec!]!, $declaredLicensesList: [[LicenseInputSpec!]!]!, $discoveredLicensesList: [[LicenseInputSpec!]!]!, $legals: [CertifyLegalInputSpec!]!) { +mutation IngestCertifyLegalPkgs($pkgs: [IDorPkgInput!]!, $declaredLicensesList: [[IDorLicenseInput!]!]!, $discoveredLicensesList: [[IDorLicenseInput!]!]!, $legals: [CertifyLegalInputSpec!]!) { ingestCertifyLegals(subjects: {packages: $pkgs}, declaredLicensesList: $declaredLicensesList, discoveredLicensesList: $discoveredLicensesList, certifyLegals: $legals) } -mutation IngestCertifyLegalSrc($src: SourceInputSpec!, $declaredLicenses: [LicenseInputSpec!]!, $discoveredLicenses: [LicenseInputSpec!]!, $legal: CertifyLegalInputSpec!) { +mutation IngestCertifyLegalSrc($src: IDorSourceInput!, $declaredLicenses: [IDorLicenseInput!]!, $discoveredLicenses: [IDorLicenseInput!]!, $legal: CertifyLegalInputSpec!) { ingestCertifyLegal(subject: {source: $src}, declaredLicenses: $declaredLicenses, discoveredLicenses: $discoveredLicenses, certifyLegal: $legal) } -mutation IngestCertifyLegalSrcs($srcs: [SourceInputSpec!]!, $declaredLicensesList: [[LicenseInputSpec!]!]!, $discoveredLicensesList: [[LicenseInputSpec!]!]!, $legals: [CertifyLegalInputSpec!]!) { +mutation IngestCertifyLegalSrcs($srcs: [IDorSourceInput!]!, $declaredLicensesList: [[IDorLicenseInput!]!]!, $discoveredLicensesList: [[IDorLicenseInput!]!]!, $legals: [CertifyLegalInputSpec!]!) { ingestCertifyLegals(subjects: {sources: $srcs}, declaredLicensesList: $declaredLicensesList, discoveredLicensesList: $discoveredLicensesList, certifyLegals: $legals) } diff --git a/pkg/assembler/clients/operations/certifyScorecard.graphql b/pkg/assembler/clients/operations/certifyScorecard.graphql index 6692fc4761..7ddc6e99ac 100644 --- a/pkg/assembler/clients/operations/certifyScorecard.graphql +++ b/pkg/assembler/clients/operations/certifyScorecard.graphql @@ -18,7 +18,7 @@ # Defines the GraphQL operations to ingest a Scorecard certification into GUAC mutation IngestCertifyScorecard( - $source: SourceInputSpec! + $source: IDorSourceInput! $scorecard: ScorecardInputSpec! ) { ingestScorecard(source: $source, scorecard: $scorecard) @@ -27,7 +27,7 @@ mutation IngestCertifyScorecard( # Defines the GraphQL operations to bulk ingest Scorecard certifications into GUAC mutation IngestCertifyScorecards( - $sources: [SourceInputSpec!]! + $sources: [IDorSourceInput!]! $scorecards: [ScorecardInputSpec!]! ) { ingestScorecards(sources: $sources, scorecards: $scorecards) diff --git a/pkg/assembler/clients/operations/certifyVEXStatement.graphql b/pkg/assembler/clients/operations/certifyVEXStatement.graphql index bf9f5e4aac..9608e8c389 100644 --- a/pkg/assembler/clients/operations/certifyVEXStatement.graphql +++ b/pkg/assembler/clients/operations/certifyVEXStatement.graphql @@ -18,8 +18,8 @@ # Defines the GraphQL operations to ingest VEX statements into GUAC mutation IngestCertifyVexPkg( - $pkg: PkgInputSpec! - $vulnerability: VulnerabilityInputSpec! + $pkg: IDorPkgInput! + $vulnerability: IDorVulnerabilityInput! $vexStatement: VexStatementInputSpec! ) { ingestVEXStatement( @@ -30,8 +30,8 @@ mutation IngestCertifyVexPkg( } mutation IngestCertifyVexArtifact( - $artifact: ArtifactInputSpec! - $vulnerability: VulnerabilityInputSpec! + $artifact: IDorArtifactInput! + $vulnerability: IDorVulnerabilityInput! $vexStatement: VexStatementInputSpec! ) { ingestVEXStatement( @@ -45,8 +45,8 @@ mutation IngestCertifyVexArtifact( # Defines the GraphQL operations to bulk ingest VEX statements into GUAC mutation IngestCertifyVexPkgs( - $pkgs: [PkgInputSpec!]!, - $vulnerabilities: [VulnerabilityInputSpec!]!, + $pkgs: [IDorPkgInput!]!, + $vulnerabilities: [IDorVulnerabilityInput!]!, $vexStatements: [VexStatementInputSpec!]! ) { ingestVEXStatements( @@ -58,8 +58,8 @@ mutation IngestCertifyVexPkgs( } mutation IngestCertifyVexArtifacts( - $artifacts: [ArtifactInputSpec!]!, - $vulnerabilities: [VulnerabilityInputSpec!]!, + $artifacts: [IDorArtifactInput!]!, + $vulnerabilities: [IDorVulnerabilityInput!]!, $vexStatements: [VexStatementInputSpec!]! ) { ingestVEXStatements( diff --git a/pkg/assembler/clients/operations/certifyVuln.graphql b/pkg/assembler/clients/operations/certifyVuln.graphql index 2959772406..8a079d931f 100644 --- a/pkg/assembler/clients/operations/certifyVuln.graphql +++ b/pkg/assembler/clients/operations/certifyVuln.graphql @@ -18,8 +18,8 @@ # Defines the GraphQL operations to ingest a vulnerability certification into GUAC mutation IngestCertifyVulnPkg( - $pkg: PkgInputSpec! - $vulnerability: VulnerabilityInputSpec! + $pkg: IDorPkgInput! + $vulnerability: IDorVulnerabilityInput! $certifyVuln: ScanMetadataInput! ) { ingestCertifyVuln( @@ -32,8 +32,8 @@ mutation IngestCertifyVulnPkg( # Defines the GraphQL operations to bulk ingest vulnerability certifications into GUAC mutation IngestCertifyVulnPkgs( - $pkgs: [PkgInputSpec!]! - $vulnerabilities: [VulnerabilityInputSpec!]! + $pkgs: [IDorPkgInput!]! + $vulnerabilities: [IDorVulnerabilityInput!]! $certifyVulns: [ScanMetadataInput!]! ) { ingestCertifyVulns( diff --git a/pkg/assembler/clients/operations/contact.graphql b/pkg/assembler/clients/operations/contact.graphql index 28ee26e45f..1d02f49d54 100644 --- a/pkg/assembler/clients/operations/contact.graphql +++ b/pkg/assembler/clients/operations/contact.graphql @@ -18,7 +18,7 @@ # Defines the GraphQL operations to ingest a PointOfContact into GUAC mutation IngestPointOfContactPkg( - $pkg: PkgInputSpec! + $pkg: IDorPkgInput! $pkgMatchType: MatchFlags! $pointOfContact: PointOfContactInputSpec! ) { @@ -30,7 +30,7 @@ mutation IngestPointOfContactPkg( } mutation IngestPointOfContactSrc( - $source: SourceInputSpec! + $source: IDorSourceInput! $pointOfContact: PointOfContactInputSpec! ) { ingestPointOfContact( @@ -41,7 +41,7 @@ mutation IngestPointOfContactSrc( } mutation IngestPointOfContactArtifact( - $artifact: ArtifactInputSpec! + $artifact: IDorArtifactInput! $pointOfContact: PointOfContactInputSpec! ) { ingestPointOfContact( @@ -54,7 +54,7 @@ mutation IngestPointOfContactArtifact( # Defines the GraphQL operations to bulk ingest a PointOfContact into GUAC mutation IngestPointOfContactPkgs( - $pkgs: [PkgInputSpec!]! + $pkgs: [IDorPkgInput!]! $pkgMatchType: MatchFlags! $pointOfContacts: [PointOfContactInputSpec!]! ) { @@ -66,7 +66,7 @@ mutation IngestPointOfContactPkgs( } mutation IngestPointOfContactSrcs( - $sources: [SourceInputSpec!]! + $sources: [IDorSourceInput!]! $pointOfContacts: [PointOfContactInputSpec!]! ) { ingestPointOfContacts( @@ -77,7 +77,7 @@ mutation IngestPointOfContactSrcs( } mutation IngestPointOfContactArtifacts( - $artifacts: [ArtifactInputSpec!]! + $artifacts: [IDorArtifactInput!]! $pointOfContacts: [PointOfContactInputSpec!]! ) { ingestPointOfContacts( diff --git a/pkg/assembler/clients/operations/hasSBOM.graphql b/pkg/assembler/clients/operations/hasSBOM.graphql index 3f4a81805b..5254aceefd 100644 --- a/pkg/assembler/clients/operations/hasSBOM.graphql +++ b/pkg/assembler/clients/operations/hasSBOM.graphql @@ -17,12 +17,12 @@ # Defines the GraphQL operations to ingest that a package or source has an SBOM (specified by a URI) into GUAC -mutation IngestHasSBOMPkg($pkg: PkgInputSpec!, $hasSBOM: HasSBOMInputSpec!, $includes: HasSBOMIncludesInputSpec!) { +mutation IngestHasSBOMPkg($pkg: IDorPkgInput!, $hasSBOM: HasSBOMInputSpec!, $includes: HasSBOMIncludesInputSpec!) { ingestHasSBOM(subject: { package: $pkg }, hasSBOM: $hasSBOM, includes: $includes) } mutation IngestHasSBOMArtifact( - $artifact: ArtifactInputSpec! + $artifact: IDorArtifactInput! $hasSBOM: HasSBOMInputSpec! $includes: HasSBOMIncludesInputSpec! ) { @@ -31,12 +31,12 @@ mutation IngestHasSBOMArtifact( # Defines the GraphQL operations to bulk ingest hasSBOM information into GUAC -mutation IngestHasSBOMPkgs($pkgs: [PkgInputSpec!]!, $hasSBOMs: [HasSBOMInputSpec!]!, $includes: [HasSBOMIncludesInputSpec!]!) { +mutation IngestHasSBOMPkgs($pkgs: [IDorPkgInput!]!, $hasSBOMs: [HasSBOMInputSpec!]!, $includes: [HasSBOMIncludesInputSpec!]!) { ingestHasSBOMs(subjects: { packages: $pkgs }, hasSBOMs: $hasSBOMs, includes: $includes) } mutation IngestHasSBOMArtifacts( - $artifacts: [ArtifactInputSpec!]! + $artifacts: [IDorArtifactInput!]! $hasSBOMs: [HasSBOMInputSpec!]! $includes: [HasSBOMIncludesInputSpec!]! ) { diff --git a/pkg/assembler/clients/operations/hasSLSA.graphql b/pkg/assembler/clients/operations/hasSLSA.graphql index 8bfc07541d..016810eb61 100644 --- a/pkg/assembler/clients/operations/hasSLSA.graphql +++ b/pkg/assembler/clients/operations/hasSLSA.graphql @@ -18,9 +18,9 @@ # Defines the GraphQL operations to ingest SLSA attestation into GUAC mutation IngestSLSAForArtifact( - $artifact: ArtifactInputSpec! - $materials: [ArtifactInputSpec!]! - $builder: BuilderInputSpec! + $artifact: IDorArtifactInput! + $materials: [IDorArtifactInput!]! + $builder: IDorBuilderInput! $slsa: SLSAInputSpec! ) { ingestSLSA( @@ -34,9 +34,9 @@ mutation IngestSLSAForArtifact( # Defines the GraphQL operations to bulk ingest SLSA attestations into GUAC mutation IngestSLSAForArtifacts( - $artifacts: [ArtifactInputSpec!]! - $materialsList: [[ArtifactInputSpec!]!]! - $builders: [BuilderInputSpec!]! + $artifacts: [IDorArtifactInput!]! + $materialsList: [[IDorArtifactInput!]!]! + $builders: [IDorBuilderInput!]! $slsaList: [SLSAInputSpec!]! ) { ingestSLSAs( diff --git a/pkg/assembler/clients/operations/hasSourceAt.graphql b/pkg/assembler/clients/operations/hasSourceAt.graphql index bc00e0ba12..e998c01ddb 100644 --- a/pkg/assembler/clients/operations/hasSourceAt.graphql +++ b/pkg/assembler/clients/operations/hasSourceAt.graphql @@ -18,9 +18,9 @@ # Defines the GraphQL operations to ingest that a package (either at the package version or package name level) has the specified source into GUAC mutation IngestHasSourceAt( - $pkg: PkgInputSpec! + $pkg: IDorPkgInput! $pkgMatchType: MatchFlags! - $source: SourceInputSpec! + $source: IDorSourceInput! $hasSourceAt: HasSourceAtInputSpec! ) { ingestHasSourceAt( @@ -35,9 +35,9 @@ mutation IngestHasSourceAt( # Defines the GraphQL operations to bulk ingest that a package (either at the package version or package name level) has the specified source into GUAC mutation IngestHasSourcesAt( - $pkgs: [PkgInputSpec!]! + $pkgs: [IDorPkgInput!]! $pkgMatchType: MatchFlags! - $sources: [SourceInputSpec!]! + $sources: [IDorSourceInput!]! $hasSourceAts: [HasSourceAtInputSpec!]! ) { ingestHasSourceAts( diff --git a/pkg/assembler/clients/operations/hashEqual.graphql b/pkg/assembler/clients/operations/hashEqual.graphql index 5f4f39961c..a252b02d7e 100644 --- a/pkg/assembler/clients/operations/hashEqual.graphql +++ b/pkg/assembler/clients/operations/hashEqual.graphql @@ -18,8 +18,8 @@ # Defines the GraphQL operations to certify that two artifacts are identical mutation IngestHashEqual( - $artifact: ArtifactInputSpec! - $otherArtifact: ArtifactInputSpec! + $artifact: IDorArtifactInput! + $otherArtifact: IDorArtifactInput! $hashEqual: HashEqualInputSpec! ) { ingestHashEqual( @@ -32,8 +32,8 @@ mutation IngestHashEqual( # Defines the GraphQL operations to bulk ingest hasEqual information into GUAC mutation IngestHashEquals( - $artifacts: [ArtifactInputSpec!]! - $otherArtifacts: [ArtifactInputSpec!]! + $artifacts: [IDorArtifactInput!]! + $otherArtifacts: [IDorArtifactInput!]! $hashEquals: [HashEqualInputSpec!]! ) { ingestHashEquals( diff --git a/pkg/assembler/clients/operations/isDependency.graphql b/pkg/assembler/clients/operations/isDependency.graphql index f13e654c46..7c013f1c45 100644 --- a/pkg/assembler/clients/operations/isDependency.graphql +++ b/pkg/assembler/clients/operations/isDependency.graphql @@ -18,8 +18,8 @@ # Defines the GraphQL operations to ingest dependency information into GUAC mutation IngestIsDependency( - $pkg: PkgInputSpec! - $depPkg: PkgInputSpec! + $pkg: IDorPkgInput! + $depPkg: IDorPkgInput! $depPkgMatchType: MatchFlags! $dependency: IsDependencyInputSpec! ) { @@ -34,8 +34,8 @@ mutation IngestIsDependency( # Defines the GraphQL operations to bulk ingest dependencies information into GUAC mutation IngestIsDependencies( - $pkgs: [PkgInputSpec!]! - $depPkgs: [PkgInputSpec!]! + $pkgs: [IDorPkgInput!]! + $depPkgs: [IDorPkgInput!]! $depPkgMatchType: MatchFlags! $dependencies: [IsDependencyInputSpec!]! ) { diff --git a/pkg/assembler/clients/operations/isOccurrence.graphql b/pkg/assembler/clients/operations/isOccurrence.graphql index d93c501e50..9a7ab19b45 100644 --- a/pkg/assembler/clients/operations/isOccurrence.graphql +++ b/pkg/assembler/clients/operations/isOccurrence.graphql @@ -18,8 +18,8 @@ # Defines the GraphQL operations to ingest occurrence information into GUAC mutation IngestIsOccurrencePkg( - $pkg: PkgInputSpec! - $artifact: ArtifactInputSpec! + $pkg: IDorPkgInput! + $artifact: IDorArtifactInput! $occurrence: IsOccurrenceInputSpec! ) { ingestOccurrence( @@ -30,8 +30,8 @@ mutation IngestIsOccurrencePkg( } mutation IngestIsOccurrenceSrc( - $source: SourceInputSpec! - $artifact: ArtifactInputSpec! + $source: IDorSourceInput! + $artifact: IDorArtifactInput! $occurrence: IsOccurrenceInputSpec! ) { ingestOccurrence( @@ -44,8 +44,8 @@ mutation IngestIsOccurrenceSrc( # Defines the GraphQL operations to bulk ingest occurrences information into GUAC mutation IngestIsOccurrencesPkg( - $pkgs: [PkgInputSpec!]! - $artifacts: [ArtifactInputSpec!]! + $pkgs: [IDorPkgInput!]! + $artifacts: [IDorArtifactInput!]! $occurrences: [IsOccurrenceInputSpec!]! ) { ingestOccurrences( @@ -56,8 +56,8 @@ mutation IngestIsOccurrencesPkg( } mutation IngestIsOccurrencesSrc( - $sources: [SourceInputSpec!]! - $artifacts: [ArtifactInputSpec!]! + $sources: [IDorSourceInput!]! + $artifacts: [IDorArtifactInput!]! $occurrences: [IsOccurrenceInputSpec!]! ) { ingestOccurrences( diff --git a/pkg/assembler/clients/operations/license.graphql b/pkg/assembler/clients/operations/license.graphql index 1a16ff3078..c745afa64b 100644 --- a/pkg/assembler/clients/operations/license.graphql +++ b/pkg/assembler/clients/operations/license.graphql @@ -17,13 +17,13 @@ # Ingest License -mutation IngestLicense($license: LicenseInputSpec!) { +mutation IngestLicense($license: IDorLicenseInput!) { ingestLicense(license: $license) } # Bulk Ingest Licenses -mutation IngestLicenses($licenses: [LicenseInputSpec!]!) { +mutation IngestLicenses($licenses: [IDorLicenseInput!]!) { ingestLicenses(licenses: $licenses) } diff --git a/pkg/assembler/clients/operations/metadata.graphql b/pkg/assembler/clients/operations/metadata.graphql index c02a2d8a78..b35b743515 100644 --- a/pkg/assembler/clients/operations/metadata.graphql +++ b/pkg/assembler/clients/operations/metadata.graphql @@ -18,7 +18,7 @@ # Defines the GraphQL operations to ingest a HasMetadata into GUAC mutation IngestHasMetadataPkg( - $pkg: PkgInputSpec! + $pkg: IDorPkgInput! $pkgMatchType: MatchFlags! $hasMetadata: HasMetadataInputSpec! ) { @@ -30,7 +30,7 @@ mutation IngestHasMetadataPkg( } mutation IngestHasMetadataSrc( - $source: SourceInputSpec! + $source: IDorSourceInput! $hasMetadata: HasMetadataInputSpec! ) { ingestHasMetadata( @@ -41,7 +41,7 @@ mutation IngestHasMetadataSrc( } mutation IngestHasMetadataArtifact( - $artifact: ArtifactInputSpec! + $artifact: IDorArtifactInput! $hasMetadata: HasMetadataInputSpec! ) { ingestHasMetadata( @@ -54,7 +54,7 @@ mutation IngestHasMetadataArtifact( # Defines the GraphQL operations to bulk ingest a HasMetadata into GUAC mutation IngestHasMetadataPkgs( - $pkgs: [PkgInputSpec!]! + $pkgs: [IDorPkgInput!]! $pkgMatchType: MatchFlags! $hasMetadataList: [HasMetadataInputSpec!]! ) { @@ -66,7 +66,7 @@ mutation IngestHasMetadataPkgs( } mutation IngestHasMetadataSrcs( - $sources: [SourceInputSpec!]! + $sources: [IDorSourceInput!]! $hasMetadataList: [HasMetadataInputSpec!]! ) { ingestBulkHasMetadata( @@ -77,7 +77,7 @@ mutation IngestHasMetadataSrcs( } mutation IngestHasMetadataArtifacts( - $artifacts: [ArtifactInputSpec!]! + $artifacts: [IDorArtifactInput!]! $hasMetadataList: [HasMetadataInputSpec!]! ) { ingestBulkHasMetadata( diff --git a/pkg/assembler/clients/operations/package.graphql b/pkg/assembler/clients/operations/package.graphql index c475acc6b1..da10ac0658 100644 --- a/pkg/assembler/clients/operations/package.graphql +++ b/pkg/assembler/clients/operations/package.graphql @@ -17,7 +17,7 @@ # Ingest Package -mutation IngestPackage($pkg: PkgInputSpec!) { +mutation IngestPackage($pkg: IDorPkgInput!) { ingestPackage(pkg: $pkg) { packageTypeID packageNamespaceID @@ -28,7 +28,7 @@ mutation IngestPackage($pkg: PkgInputSpec!) { # Bulk Ingest Packages -mutation IngestPackages($pkgs: [PkgInputSpec!]!) { +mutation IngestPackages($pkgs: [IDorPkgInput!]!) { ingestPackages(pkgs: $pkgs) { packageTypeID packageNamespaceID diff --git a/pkg/assembler/clients/operations/pkgEqual.graphql b/pkg/assembler/clients/operations/pkgEqual.graphql index a169b540b7..0f43f30542 100644 --- a/pkg/assembler/clients/operations/pkgEqual.graphql +++ b/pkg/assembler/clients/operations/pkgEqual.graphql @@ -18,8 +18,8 @@ # Defines the GraphQL operations to certify that two packages are identical mutation IngestPkgEqual( - $pkg: PkgInputSpec! - $otherPackage: PkgInputSpec! + $pkg: IDorPkgInput! + $otherPackage: IDorPkgInput! $pkgEqual: PkgEqualInputSpec! ) { ingestPkgEqual(pkg: $pkg, otherPackage: $otherPackage, pkgEqual: $pkgEqual) @@ -29,8 +29,8 @@ mutation IngestPkgEqual( # Defines the GraphQL operations to bulk certify that two packages are identical mutation IngestPkgEquals( - $pkgs: [PkgInputSpec!]! - $otherPackages: [PkgInputSpec!]! + $pkgs: [IDorPkgInput!]! + $otherPackages: [IDorPkgInput!]! $pkgEquals: [PkgEqualInputSpec!]! ) { ingestPkgEquals( diff --git a/pkg/assembler/clients/operations/source.graphql b/pkg/assembler/clients/operations/source.graphql index 3adb63829b..14776f38d1 100644 --- a/pkg/assembler/clients/operations/source.graphql +++ b/pkg/assembler/clients/operations/source.graphql @@ -17,7 +17,7 @@ # Ingest Source -mutation IngestSource($source: SourceInputSpec!) { +mutation IngestSource($source: IDorSourceInput!) { ingestSource(source: $source) { sourceTypeID sourceNamespaceID @@ -27,7 +27,7 @@ mutation IngestSource($source: SourceInputSpec!) { # Bulk Ingest Sources -mutation IngestSources($sources: [SourceInputSpec!]!) { +mutation IngestSources($sources: [IDorSourceInput!]!) { ingestSources(sources: $sources) { sourceTypeID sourceNamespaceID diff --git a/pkg/assembler/clients/operations/vulnEqual.graphql b/pkg/assembler/clients/operations/vulnEqual.graphql index c18552535d..b7bdafb10f 100644 --- a/pkg/assembler/clients/operations/vulnEqual.graphql +++ b/pkg/assembler/clients/operations/vulnEqual.graphql @@ -18,8 +18,8 @@ # Defines the GraphQL operations to certify that two vulnerabilities are identical mutation IngestVulnEqual( - $vulnerability: VulnerabilityInputSpec! - $otherVulnerability: VulnerabilityInputSpec! + $vulnerability: IDorVulnerabilityInput! + $otherVulnerability: IDorVulnerabilityInput! $vulnEqual: VulnEqualInputSpec! ) { ingestVulnEqual( @@ -32,8 +32,8 @@ mutation IngestVulnEqual( # Defines the GraphQL operations to bulk certify that two vulnerabilities are identical mutation IngestVulnEquals( - $vulnerabilities: [VulnerabilityInputSpec!]!, - $otherVulnerabilities: [VulnerabilityInputSpec!]! + $vulnerabilities: [IDorVulnerabilityInput!]!, + $otherVulnerabilities: [IDorVulnerabilityInput!]! $vulnEquals: [VulnEqualInputSpec!]! ) { ingestVulnEquals( diff --git a/pkg/assembler/clients/operations/vulnMetadata.graphql b/pkg/assembler/clients/operations/vulnMetadata.graphql index 6c4a220db1..3ef51256b9 100644 --- a/pkg/assembler/clients/operations/vulnMetadata.graphql +++ b/pkg/assembler/clients/operations/vulnMetadata.graphql @@ -18,7 +18,7 @@ # Defines the GraphQL operations to ingest metadata for a vulnerability into GUAC mutation IngestVulnHasMetadata( - $vulnerability: VulnerabilityInputSpec!, + $vulnerability: IDorVulnerabilityInput!, $vulnMetadata: VulnerabilityMetadataInputSpec! ) { ingestVulnerabilityMetadata( @@ -30,7 +30,7 @@ mutation IngestVulnHasMetadata( # Defines the GraphQL operations to bulk ingest metadata for a vulnerability into GUAC mutation IngestBulkVulnHasMetadata( - $vulnerabilities: [VulnerabilityInputSpec!]!, + $vulnerabilities: [IDorVulnerabilityInput!]!, $vulnerabilityMetadataList: [VulnerabilityMetadataInputSpec!]! ) { ingestBulkVulnerabilityMetadata( diff --git a/pkg/assembler/clients/operations/vulnerability.graphql b/pkg/assembler/clients/operations/vulnerability.graphql index 41cce4bf1c..0e80c55c1a 100644 --- a/pkg/assembler/clients/operations/vulnerability.graphql +++ b/pkg/assembler/clients/operations/vulnerability.graphql @@ -17,7 +17,7 @@ # Ingest Vulnerability -mutation IngestVulnerability($vuln: VulnerabilityInputSpec!) { +mutation IngestVulnerability($vuln: IDorVulnerabilityInput!) { ingestVulnerability(vuln: $vuln) { vulnerabilityTypeID vulnerabilityNodeID @@ -26,7 +26,7 @@ mutation IngestVulnerability($vuln: VulnerabilityInputSpec!) { # Bulk Ingest Vulnerability -mutation IngestVulnerabilities($vulns: [VulnerabilityInputSpec!]!) { +mutation IngestVulnerabilities($vulns: [IDorVulnerabilityInput!]!) { ingestVulnerabilities(vulns: $vulns) { vulnerabilityTypeID vulnerabilityNodeID diff --git a/pkg/assembler/graphql/examples/certify_scorecard.gql b/pkg/assembler/graphql/examples/certify_scorecard.gql index 1f352f3677..95daa05278 100644 --- a/pkg/assembler/graphql/examples/certify_scorecard.gql +++ b/pkg/assembler/graphql/examples/certify_scorecard.gql @@ -58,7 +58,7 @@ query ScorecardQ4 { } } -mutation Scorecard($source: SourceInputSpec!, $scorecard: ScorecardInputSpec!) { +mutation Scorecard($source: IDorSourceInput!, $scorecard: ScorecardInputSpec!) { ingestSource(source: $source) ingestScorecard(source: $source, scorecard: $scorecard) } diff --git a/pkg/assembler/graphql/generated/artifact.generated.go b/pkg/assembler/graphql/generated/artifact.generated.go index 599d86e6e0..ecf5360db7 100644 --- a/pkg/assembler/graphql/generated/artifact.generated.go +++ b/pkg/assembler/graphql/generated/artifact.generated.go @@ -19,52 +19,52 @@ import ( // region ************************** generated!.gotpl ************************** type MutationResolver interface { - IngestArtifact(ctx context.Context, artifact *model.ArtifactInputSpec) (string, error) - IngestArtifacts(ctx context.Context, artifacts []*model.ArtifactInputSpec) ([]string, error) - IngestBuilder(ctx context.Context, builder *model.BuilderInputSpec) (string, error) - IngestBuilders(ctx context.Context, builders []*model.BuilderInputSpec) ([]string, error) + IngestArtifact(ctx context.Context, artifact *model.IDorArtifactInput) (string, error) + IngestArtifacts(ctx context.Context, artifacts []*model.IDorArtifactInput) ([]string, error) + IngestBuilder(ctx context.Context, builder *model.IDorBuilderInput) (string, error) + IngestBuilders(ctx context.Context, builders []*model.IDorBuilderInput) ([]string, error) IngestCertifyBad(ctx context.Context, subject model.PackageSourceOrArtifactInput, pkgMatchType model.MatchFlags, certifyBad model.CertifyBadInputSpec) (string, error) IngestCertifyBads(ctx context.Context, subjects model.PackageSourceOrArtifactInputs, pkgMatchType model.MatchFlags, certifyBads []*model.CertifyBadInputSpec) ([]string, error) IngestCertifyGood(ctx context.Context, subject model.PackageSourceOrArtifactInput, pkgMatchType model.MatchFlags, certifyGood model.CertifyGoodInputSpec) (string, error) IngestCertifyGoods(ctx context.Context, subjects model.PackageSourceOrArtifactInputs, pkgMatchType model.MatchFlags, certifyGoods []*model.CertifyGoodInputSpec) ([]string, error) - IngestCertifyLegal(ctx context.Context, subject model.PackageOrSourceInput, declaredLicenses []*model.LicenseInputSpec, discoveredLicenses []*model.LicenseInputSpec, certifyLegal model.CertifyLegalInputSpec) (string, error) - IngestCertifyLegals(ctx context.Context, subjects model.PackageOrSourceInputs, declaredLicensesList [][]*model.LicenseInputSpec, discoveredLicensesList [][]*model.LicenseInputSpec, certifyLegals []*model.CertifyLegalInputSpec) ([]string, error) - IngestScorecard(ctx context.Context, source model.SourceInputSpec, scorecard model.ScorecardInputSpec) (string, error) - IngestScorecards(ctx context.Context, sources []*model.SourceInputSpec, scorecards []*model.ScorecardInputSpec) ([]string, error) - IngestVEXStatement(ctx context.Context, subject model.PackageOrArtifactInput, vulnerability model.VulnerabilityInputSpec, vexStatement model.VexStatementInputSpec) (string, error) - IngestVEXStatements(ctx context.Context, subjects model.PackageOrArtifactInputs, vulnerabilities []*model.VulnerabilityInputSpec, vexStatements []*model.VexStatementInputSpec) ([]string, error) - IngestCertifyVuln(ctx context.Context, pkg model.PkgInputSpec, vulnerability model.VulnerabilityInputSpec, certifyVuln model.ScanMetadataInput) (string, error) - IngestCertifyVulns(ctx context.Context, pkgs []*model.PkgInputSpec, vulnerabilities []*model.VulnerabilityInputSpec, certifyVulns []*model.ScanMetadataInput) ([]string, error) + IngestCertifyLegal(ctx context.Context, subject model.PackageOrSourceInput, declaredLicenses []*model.IDorLicenseInput, discoveredLicenses []*model.IDorLicenseInput, certifyLegal model.CertifyLegalInputSpec) (string, error) + IngestCertifyLegals(ctx context.Context, subjects model.PackageOrSourceInputs, declaredLicensesList [][]*model.IDorLicenseInput, discoveredLicensesList [][]*model.IDorLicenseInput, certifyLegals []*model.CertifyLegalInputSpec) ([]string, error) + IngestScorecard(ctx context.Context, source model.IDorSourceInput, scorecard model.ScorecardInputSpec) (string, error) + IngestScorecards(ctx context.Context, sources []*model.IDorSourceInput, scorecards []*model.ScorecardInputSpec) ([]string, error) + IngestVEXStatement(ctx context.Context, subject model.PackageOrArtifactInput, vulnerability model.IDorVulnerabilityInput, vexStatement model.VexStatementInputSpec) (string, error) + IngestVEXStatements(ctx context.Context, subjects model.PackageOrArtifactInputs, vulnerabilities []*model.IDorVulnerabilityInput, vexStatements []*model.VexStatementInputSpec) ([]string, error) + IngestCertifyVuln(ctx context.Context, pkg model.IDorPkgInput, vulnerability model.IDorVulnerabilityInput, certifyVuln model.ScanMetadataInput) (string, error) + IngestCertifyVulns(ctx context.Context, pkgs []*model.IDorPkgInput, vulnerabilities []*model.IDorVulnerabilityInput, certifyVulns []*model.ScanMetadataInput) ([]string, error) IngestPointOfContact(ctx context.Context, subject model.PackageSourceOrArtifactInput, pkgMatchType model.MatchFlags, pointOfContact model.PointOfContactInputSpec) (string, error) IngestPointOfContacts(ctx context.Context, subjects model.PackageSourceOrArtifactInputs, pkgMatchType model.MatchFlags, pointOfContacts []*model.PointOfContactInputSpec) ([]string, error) IngestHasSbom(ctx context.Context, subject model.PackageOrArtifactInput, hasSbom model.HasSBOMInputSpec, includes model.HasSBOMIncludesInputSpec) (string, error) IngestHasSBOMs(ctx context.Context, subjects model.PackageOrArtifactInputs, hasSBOMs []*model.HasSBOMInputSpec, includes []*model.HasSBOMIncludesInputSpec) ([]string, error) - IngestSlsa(ctx context.Context, subject model.ArtifactInputSpec, builtFrom []*model.ArtifactInputSpec, builtBy model.BuilderInputSpec, slsa model.SLSAInputSpec) (string, error) - IngestSLSAs(ctx context.Context, subjects []*model.ArtifactInputSpec, builtFromList [][]*model.ArtifactInputSpec, builtByList []*model.BuilderInputSpec, slsaList []*model.SLSAInputSpec) ([]string, error) - IngestHasSourceAt(ctx context.Context, pkg model.PkgInputSpec, pkgMatchType model.MatchFlags, source model.SourceInputSpec, hasSourceAt model.HasSourceAtInputSpec) (string, error) - IngestHasSourceAts(ctx context.Context, pkgs []*model.PkgInputSpec, pkgMatchType model.MatchFlags, sources []*model.SourceInputSpec, hasSourceAts []*model.HasSourceAtInputSpec) ([]string, error) - IngestHashEqual(ctx context.Context, artifact model.ArtifactInputSpec, otherArtifact model.ArtifactInputSpec, hashEqual model.HashEqualInputSpec) (string, error) - IngestHashEquals(ctx context.Context, artifacts []*model.ArtifactInputSpec, otherArtifacts []*model.ArtifactInputSpec, hashEquals []*model.HashEqualInputSpec) ([]string, error) - IngestDependency(ctx context.Context, pkg model.PkgInputSpec, depPkg model.PkgInputSpec, depPkgMatchType model.MatchFlags, dependency model.IsDependencyInputSpec) (string, error) - IngestDependencies(ctx context.Context, pkgs []*model.PkgInputSpec, depPkgs []*model.PkgInputSpec, depPkgMatchType model.MatchFlags, dependencies []*model.IsDependencyInputSpec) ([]string, error) - IngestOccurrence(ctx context.Context, subject model.PackageOrSourceInput, artifact model.ArtifactInputSpec, occurrence model.IsOccurrenceInputSpec) (string, error) - IngestOccurrences(ctx context.Context, subjects model.PackageOrSourceInputs, artifacts []*model.ArtifactInputSpec, occurrences []*model.IsOccurrenceInputSpec) ([]string, error) - IngestLicense(ctx context.Context, license *model.LicenseInputSpec) (string, error) - IngestLicenses(ctx context.Context, licenses []*model.LicenseInputSpec) ([]string, error) + IngestSlsa(ctx context.Context, subject model.IDorArtifactInput, builtFrom []*model.IDorArtifactInput, builtBy model.IDorBuilderInput, slsa model.SLSAInputSpec) (string, error) + IngestSLSAs(ctx context.Context, subjects []*model.IDorArtifactInput, builtFromList [][]*model.IDorArtifactInput, builtByList []*model.IDorBuilderInput, slsaList []*model.SLSAInputSpec) ([]string, error) + IngestHasSourceAt(ctx context.Context, pkg model.IDorPkgInput, pkgMatchType model.MatchFlags, source model.IDorSourceInput, hasSourceAt model.HasSourceAtInputSpec) (string, error) + IngestHasSourceAts(ctx context.Context, pkgs []*model.IDorPkgInput, pkgMatchType model.MatchFlags, sources []*model.IDorSourceInput, hasSourceAts []*model.HasSourceAtInputSpec) ([]string, error) + IngestHashEqual(ctx context.Context, artifact model.IDorArtifactInput, otherArtifact model.IDorArtifactInput, hashEqual model.HashEqualInputSpec) (string, error) + IngestHashEquals(ctx context.Context, artifacts []*model.IDorArtifactInput, otherArtifacts []*model.IDorArtifactInput, hashEquals []*model.HashEqualInputSpec) ([]string, error) + IngestDependency(ctx context.Context, pkg model.IDorPkgInput, depPkg model.IDorPkgInput, depPkgMatchType model.MatchFlags, dependency model.IsDependencyInputSpec) (string, error) + IngestDependencies(ctx context.Context, pkgs []*model.IDorPkgInput, depPkgs []*model.IDorPkgInput, depPkgMatchType model.MatchFlags, dependencies []*model.IsDependencyInputSpec) ([]string, error) + IngestOccurrence(ctx context.Context, subject model.PackageOrSourceInput, artifact model.IDorArtifactInput, occurrence model.IsOccurrenceInputSpec) (string, error) + IngestOccurrences(ctx context.Context, subjects model.PackageOrSourceInputs, artifacts []*model.IDorArtifactInput, occurrences []*model.IsOccurrenceInputSpec) ([]string, error) + IngestLicense(ctx context.Context, license *model.IDorLicenseInput) (string, error) + IngestLicenses(ctx context.Context, licenses []*model.IDorLicenseInput) ([]string, error) IngestHasMetadata(ctx context.Context, subject model.PackageSourceOrArtifactInput, pkgMatchType model.MatchFlags, hasMetadata model.HasMetadataInputSpec) (string, error) IngestBulkHasMetadata(ctx context.Context, subjects model.PackageSourceOrArtifactInputs, pkgMatchType model.MatchFlags, hasMetadataList []*model.HasMetadataInputSpec) ([]string, error) - IngestPackage(ctx context.Context, pkg model.PkgInputSpec) (*model.PackageIDs, error) - IngestPackages(ctx context.Context, pkgs []*model.PkgInputSpec) ([]*model.PackageIDs, error) - IngestPkgEqual(ctx context.Context, pkg model.PkgInputSpec, otherPackage model.PkgInputSpec, pkgEqual model.PkgEqualInputSpec) (string, error) - IngestPkgEquals(ctx context.Context, pkgs []*model.PkgInputSpec, otherPackages []*model.PkgInputSpec, pkgEquals []*model.PkgEqualInputSpec) ([]string, error) - IngestSource(ctx context.Context, source model.SourceInputSpec) (*model.SourceIDs, error) - IngestSources(ctx context.Context, sources []*model.SourceInputSpec) ([]*model.SourceIDs, error) - IngestVulnEqual(ctx context.Context, vulnerability model.VulnerabilityInputSpec, otherVulnerability model.VulnerabilityInputSpec, vulnEqual model.VulnEqualInputSpec) (string, error) - IngestVulnEquals(ctx context.Context, vulnerabilities []*model.VulnerabilityInputSpec, otherVulnerabilities []*model.VulnerabilityInputSpec, vulnEquals []*model.VulnEqualInputSpec) ([]string, error) - IngestVulnerabilityMetadata(ctx context.Context, vulnerability model.VulnerabilityInputSpec, vulnerabilityMetadata model.VulnerabilityMetadataInputSpec) (string, error) - IngestBulkVulnerabilityMetadata(ctx context.Context, vulnerabilities []*model.VulnerabilityInputSpec, vulnerabilityMetadataList []*model.VulnerabilityMetadataInputSpec) ([]string, error) - IngestVulnerability(ctx context.Context, vuln model.VulnerabilityInputSpec) (*model.VulnerabilityIDs, error) - IngestVulnerabilities(ctx context.Context, vulns []*model.VulnerabilityInputSpec) ([]*model.VulnerabilityIDs, error) + IngestPackage(ctx context.Context, pkg model.IDorPkgInput) (*model.PackageIDs, error) + IngestPackages(ctx context.Context, pkgs []*model.IDorPkgInput) ([]*model.PackageIDs, error) + IngestPkgEqual(ctx context.Context, pkg model.IDorPkgInput, otherPackage model.IDorPkgInput, pkgEqual model.PkgEqualInputSpec) (string, error) + IngestPkgEquals(ctx context.Context, pkgs []*model.IDorPkgInput, otherPackages []*model.IDorPkgInput, pkgEquals []*model.PkgEqualInputSpec) ([]string, error) + IngestSource(ctx context.Context, source model.IDorSourceInput) (*model.SourceIDs, error) + IngestSources(ctx context.Context, sources []*model.IDorSourceInput) ([]*model.SourceIDs, error) + IngestVulnEqual(ctx context.Context, vulnerability model.IDorVulnerabilityInput, otherVulnerability model.IDorVulnerabilityInput, vulnEqual model.VulnEqualInputSpec) (string, error) + IngestVulnEquals(ctx context.Context, vulnerabilities []*model.IDorVulnerabilityInput, otherVulnerabilities []*model.IDorVulnerabilityInput, vulnEquals []*model.VulnEqualInputSpec) ([]string, error) + IngestVulnerabilityMetadata(ctx context.Context, vulnerability model.IDorVulnerabilityInput, vulnerabilityMetadata model.VulnerabilityMetadataInputSpec) (string, error) + IngestBulkVulnerabilityMetadata(ctx context.Context, vulnerabilities []*model.IDorVulnerabilityInput, vulnerabilityMetadataList []*model.VulnerabilityMetadataInputSpec) ([]string, error) + IngestVulnerability(ctx context.Context, vuln model.IDorVulnerabilityInput) (*model.VulnerabilityIDs, error) + IngestVulnerabilities(ctx context.Context, vulns []*model.IDorVulnerabilityInput) ([]*model.VulnerabilityIDs, error) } type QueryResolver interface { Artifacts(ctx context.Context, artifactSpec model.ArtifactSpec) ([]*model.Artifact, error) @@ -104,10 +104,10 @@ type QueryResolver interface { func (ec *executionContext) field_Mutation_ingestArtifact_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} - var arg0 *model.ArtifactInputSpec + var arg0 *model.IDorArtifactInput if tmp, ok := rawArgs["artifact"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("artifact")) - arg0, err = ec.unmarshalOArtifactInputSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐArtifactInputSpec(ctx, tmp) + arg0, err = ec.unmarshalOIDorArtifactInput2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorArtifactInput(ctx, tmp) if err != nil { return nil, err } @@ -119,10 +119,10 @@ func (ec *executionContext) field_Mutation_ingestArtifact_args(ctx context.Conte func (ec *executionContext) field_Mutation_ingestArtifacts_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} - var arg0 []*model.ArtifactInputSpec + var arg0 []*model.IDorArtifactInput if tmp, ok := rawArgs["artifacts"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("artifacts")) - arg0, err = ec.unmarshalNArtifactInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐArtifactInputSpecᚄ(ctx, tmp) + arg0, err = ec.unmarshalNIDorArtifactInput2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorArtifactInputᚄ(ctx, tmp) if err != nil { return nil, err } @@ -134,10 +134,10 @@ func (ec *executionContext) field_Mutation_ingestArtifacts_args(ctx context.Cont func (ec *executionContext) field_Mutation_ingestBuilder_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} - var arg0 *model.BuilderInputSpec + var arg0 *model.IDorBuilderInput if tmp, ok := rawArgs["builder"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("builder")) - arg0, err = ec.unmarshalOBuilderInputSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐBuilderInputSpec(ctx, tmp) + arg0, err = ec.unmarshalOIDorBuilderInput2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorBuilderInput(ctx, tmp) if err != nil { return nil, err } @@ -149,10 +149,10 @@ func (ec *executionContext) field_Mutation_ingestBuilder_args(ctx context.Contex func (ec *executionContext) field_Mutation_ingestBuilders_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} - var arg0 []*model.BuilderInputSpec + var arg0 []*model.IDorBuilderInput if tmp, ok := rawArgs["builders"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("builders")) - arg0, err = ec.unmarshalNBuilderInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐBuilderInputSpecᚄ(ctx, tmp) + arg0, err = ec.unmarshalNIDorBuilderInput2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorBuilderInputᚄ(ctx, tmp) if err != nil { return nil, err } @@ -197,10 +197,10 @@ func (ec *executionContext) field_Mutation_ingestBulkHasMetadata_args(ctx contex func (ec *executionContext) field_Mutation_ingestBulkVulnerabilityMetadata_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} - var arg0 []*model.VulnerabilityInputSpec + var arg0 []*model.IDorVulnerabilityInput if tmp, ok := rawArgs["vulnerabilities"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("vulnerabilities")) - arg0, err = ec.unmarshalNVulnerabilityInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐVulnerabilityInputSpecᚄ(ctx, tmp) + arg0, err = ec.unmarshalNIDorVulnerabilityInput2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorVulnerabilityInputᚄ(ctx, tmp) if err != nil { return nil, err } @@ -362,19 +362,19 @@ func (ec *executionContext) field_Mutation_ingestCertifyLegal_args(ctx context.C } } args["subject"] = arg0 - var arg1 []*model.LicenseInputSpec + var arg1 []*model.IDorLicenseInput if tmp, ok := rawArgs["declaredLicenses"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("declaredLicenses")) - arg1, err = ec.unmarshalNLicenseInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐLicenseInputSpecᚄ(ctx, tmp) + arg1, err = ec.unmarshalNIDorLicenseInput2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorLicenseInputᚄ(ctx, tmp) if err != nil { return nil, err } } args["declaredLicenses"] = arg1 - var arg2 []*model.LicenseInputSpec + var arg2 []*model.IDorLicenseInput if tmp, ok := rawArgs["discoveredLicenses"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("discoveredLicenses")) - arg2, err = ec.unmarshalNLicenseInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐLicenseInputSpecᚄ(ctx, tmp) + arg2, err = ec.unmarshalNIDorLicenseInput2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorLicenseInputᚄ(ctx, tmp) if err != nil { return nil, err } @@ -404,19 +404,19 @@ func (ec *executionContext) field_Mutation_ingestCertifyLegals_args(ctx context. } } args["subjects"] = arg0 - var arg1 [][]*model.LicenseInputSpec + var arg1 [][]*model.IDorLicenseInput if tmp, ok := rawArgs["declaredLicensesList"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("declaredLicensesList")) - arg1, err = ec.unmarshalNLicenseInputSpec2ᚕᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐLicenseInputSpecᚄ(ctx, tmp) + arg1, err = ec.unmarshalNIDorLicenseInput2ᚕᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorLicenseInputᚄ(ctx, tmp) if err != nil { return nil, err } } args["declaredLicensesList"] = arg1 - var arg2 [][]*model.LicenseInputSpec + var arg2 [][]*model.IDorLicenseInput if tmp, ok := rawArgs["discoveredLicensesList"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("discoveredLicensesList")) - arg2, err = ec.unmarshalNLicenseInputSpec2ᚕᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐLicenseInputSpecᚄ(ctx, tmp) + arg2, err = ec.unmarshalNIDorLicenseInput2ᚕᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorLicenseInputᚄ(ctx, tmp) if err != nil { return nil, err } @@ -437,19 +437,19 @@ func (ec *executionContext) field_Mutation_ingestCertifyLegals_args(ctx context. func (ec *executionContext) field_Mutation_ingestCertifyVuln_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} - var arg0 model.PkgInputSpec + var arg0 model.IDorPkgInput if tmp, ok := rawArgs["pkg"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("pkg")) - arg0, err = ec.unmarshalNPkgInputSpec2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐPkgInputSpec(ctx, tmp) + arg0, err = ec.unmarshalNIDorPkgInput2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorPkgInput(ctx, tmp) if err != nil { return nil, err } } args["pkg"] = arg0 - var arg1 model.VulnerabilityInputSpec + var arg1 model.IDorVulnerabilityInput if tmp, ok := rawArgs["vulnerability"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("vulnerability")) - arg1, err = ec.unmarshalNVulnerabilityInputSpec2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐVulnerabilityInputSpec(ctx, tmp) + arg1, err = ec.unmarshalNIDorVulnerabilityInput2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorVulnerabilityInput(ctx, tmp) if err != nil { return nil, err } @@ -470,19 +470,19 @@ func (ec *executionContext) field_Mutation_ingestCertifyVuln_args(ctx context.Co func (ec *executionContext) field_Mutation_ingestCertifyVulns_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} - var arg0 []*model.PkgInputSpec + var arg0 []*model.IDorPkgInput if tmp, ok := rawArgs["pkgs"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("pkgs")) - arg0, err = ec.unmarshalNPkgInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐPkgInputSpecᚄ(ctx, tmp) + arg0, err = ec.unmarshalNIDorPkgInput2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorPkgInputᚄ(ctx, tmp) if err != nil { return nil, err } } args["pkgs"] = arg0 - var arg1 []*model.VulnerabilityInputSpec + var arg1 []*model.IDorVulnerabilityInput if tmp, ok := rawArgs["vulnerabilities"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("vulnerabilities")) - arg1, err = ec.unmarshalNVulnerabilityInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐVulnerabilityInputSpecᚄ(ctx, tmp) + arg1, err = ec.unmarshalNIDorVulnerabilityInput2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorVulnerabilityInputᚄ(ctx, tmp) if err != nil { return nil, err } @@ -503,19 +503,19 @@ func (ec *executionContext) field_Mutation_ingestCertifyVulns_args(ctx context.C func (ec *executionContext) field_Mutation_ingestDependencies_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} - var arg0 []*model.PkgInputSpec + var arg0 []*model.IDorPkgInput if tmp, ok := rawArgs["pkgs"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("pkgs")) - arg0, err = ec.unmarshalNPkgInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐPkgInputSpecᚄ(ctx, tmp) + arg0, err = ec.unmarshalNIDorPkgInput2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorPkgInputᚄ(ctx, tmp) if err != nil { return nil, err } } args["pkgs"] = arg0 - var arg1 []*model.PkgInputSpec + var arg1 []*model.IDorPkgInput if tmp, ok := rawArgs["depPkgs"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("depPkgs")) - arg1, err = ec.unmarshalNPkgInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐPkgInputSpecᚄ(ctx, tmp) + arg1, err = ec.unmarshalNIDorPkgInput2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorPkgInputᚄ(ctx, tmp) if err != nil { return nil, err } @@ -545,19 +545,19 @@ func (ec *executionContext) field_Mutation_ingestDependencies_args(ctx context.C func (ec *executionContext) field_Mutation_ingestDependency_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} - var arg0 model.PkgInputSpec + var arg0 model.IDorPkgInput if tmp, ok := rawArgs["pkg"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("pkg")) - arg0, err = ec.unmarshalNPkgInputSpec2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐPkgInputSpec(ctx, tmp) + arg0, err = ec.unmarshalNIDorPkgInput2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorPkgInput(ctx, tmp) if err != nil { return nil, err } } args["pkg"] = arg0 - var arg1 model.PkgInputSpec + var arg1 model.IDorPkgInput if tmp, ok := rawArgs["depPkg"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("depPkg")) - arg1, err = ec.unmarshalNPkgInputSpec2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐPkgInputSpec(ctx, tmp) + arg1, err = ec.unmarshalNIDorPkgInput2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorPkgInput(ctx, tmp) if err != nil { return nil, err } @@ -686,10 +686,10 @@ func (ec *executionContext) field_Mutation_ingestHasSBOMs_args(ctx context.Conte func (ec *executionContext) field_Mutation_ingestHasSourceAt_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} - var arg0 model.PkgInputSpec + var arg0 model.IDorPkgInput if tmp, ok := rawArgs["pkg"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("pkg")) - arg0, err = ec.unmarshalNPkgInputSpec2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐPkgInputSpec(ctx, tmp) + arg0, err = ec.unmarshalNIDorPkgInput2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorPkgInput(ctx, tmp) if err != nil { return nil, err } @@ -704,10 +704,10 @@ func (ec *executionContext) field_Mutation_ingestHasSourceAt_args(ctx context.Co } } args["pkgMatchType"] = arg1 - var arg2 model.SourceInputSpec + var arg2 model.IDorSourceInput if tmp, ok := rawArgs["source"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("source")) - arg2, err = ec.unmarshalNSourceInputSpec2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐSourceInputSpec(ctx, tmp) + arg2, err = ec.unmarshalNIDorSourceInput2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorSourceInput(ctx, tmp) if err != nil { return nil, err } @@ -728,10 +728,10 @@ func (ec *executionContext) field_Mutation_ingestHasSourceAt_args(ctx context.Co func (ec *executionContext) field_Mutation_ingestHasSourceAts_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} - var arg0 []*model.PkgInputSpec + var arg0 []*model.IDorPkgInput if tmp, ok := rawArgs["pkgs"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("pkgs")) - arg0, err = ec.unmarshalNPkgInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐPkgInputSpecᚄ(ctx, tmp) + arg0, err = ec.unmarshalNIDorPkgInput2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorPkgInputᚄ(ctx, tmp) if err != nil { return nil, err } @@ -746,10 +746,10 @@ func (ec *executionContext) field_Mutation_ingestHasSourceAts_args(ctx context.C } } args["pkgMatchType"] = arg1 - var arg2 []*model.SourceInputSpec + var arg2 []*model.IDorSourceInput if tmp, ok := rawArgs["sources"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("sources")) - arg2, err = ec.unmarshalNSourceInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐSourceInputSpecᚄ(ctx, tmp) + arg2, err = ec.unmarshalNIDorSourceInput2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorSourceInputᚄ(ctx, tmp) if err != nil { return nil, err } @@ -770,19 +770,19 @@ func (ec *executionContext) field_Mutation_ingestHasSourceAts_args(ctx context.C func (ec *executionContext) field_Mutation_ingestHashEqual_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} - var arg0 model.ArtifactInputSpec + var arg0 model.IDorArtifactInput if tmp, ok := rawArgs["artifact"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("artifact")) - arg0, err = ec.unmarshalNArtifactInputSpec2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐArtifactInputSpec(ctx, tmp) + arg0, err = ec.unmarshalNIDorArtifactInput2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorArtifactInput(ctx, tmp) if err != nil { return nil, err } } args["artifact"] = arg0 - var arg1 model.ArtifactInputSpec + var arg1 model.IDorArtifactInput if tmp, ok := rawArgs["otherArtifact"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("otherArtifact")) - arg1, err = ec.unmarshalNArtifactInputSpec2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐArtifactInputSpec(ctx, tmp) + arg1, err = ec.unmarshalNIDorArtifactInput2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorArtifactInput(ctx, tmp) if err != nil { return nil, err } @@ -803,19 +803,19 @@ func (ec *executionContext) field_Mutation_ingestHashEqual_args(ctx context.Cont func (ec *executionContext) field_Mutation_ingestHashEquals_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} - var arg0 []*model.ArtifactInputSpec + var arg0 []*model.IDorArtifactInput if tmp, ok := rawArgs["artifacts"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("artifacts")) - arg0, err = ec.unmarshalNArtifactInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐArtifactInputSpecᚄ(ctx, tmp) + arg0, err = ec.unmarshalNIDorArtifactInput2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorArtifactInputᚄ(ctx, tmp) if err != nil { return nil, err } } args["artifacts"] = arg0 - var arg1 []*model.ArtifactInputSpec + var arg1 []*model.IDorArtifactInput if tmp, ok := rawArgs["otherArtifacts"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("otherArtifacts")) - arg1, err = ec.unmarshalNArtifactInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐArtifactInputSpecᚄ(ctx, tmp) + arg1, err = ec.unmarshalNIDorArtifactInput2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorArtifactInputᚄ(ctx, tmp) if err != nil { return nil, err } @@ -836,10 +836,10 @@ func (ec *executionContext) field_Mutation_ingestHashEquals_args(ctx context.Con func (ec *executionContext) field_Mutation_ingestLicense_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} - var arg0 *model.LicenseInputSpec + var arg0 *model.IDorLicenseInput if tmp, ok := rawArgs["license"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("license")) - arg0, err = ec.unmarshalOLicenseInputSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐLicenseInputSpec(ctx, tmp) + arg0, err = ec.unmarshalOIDorLicenseInput2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorLicenseInput(ctx, tmp) if err != nil { return nil, err } @@ -851,10 +851,10 @@ func (ec *executionContext) field_Mutation_ingestLicense_args(ctx context.Contex func (ec *executionContext) field_Mutation_ingestLicenses_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} - var arg0 []*model.LicenseInputSpec + var arg0 []*model.IDorLicenseInput if tmp, ok := rawArgs["licenses"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("licenses")) - arg0, err = ec.unmarshalNLicenseInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐLicenseInputSpecᚄ(ctx, tmp) + arg0, err = ec.unmarshalNIDorLicenseInput2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorLicenseInputᚄ(ctx, tmp) if err != nil { return nil, err } @@ -875,10 +875,10 @@ func (ec *executionContext) field_Mutation_ingestOccurrence_args(ctx context.Con } } args["subject"] = arg0 - var arg1 model.ArtifactInputSpec + var arg1 model.IDorArtifactInput if tmp, ok := rawArgs["artifact"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("artifact")) - arg1, err = ec.unmarshalNArtifactInputSpec2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐArtifactInputSpec(ctx, tmp) + arg1, err = ec.unmarshalNIDorArtifactInput2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorArtifactInput(ctx, tmp) if err != nil { return nil, err } @@ -908,10 +908,10 @@ func (ec *executionContext) field_Mutation_ingestOccurrences_args(ctx context.Co } } args["subjects"] = arg0 - var arg1 []*model.ArtifactInputSpec + var arg1 []*model.IDorArtifactInput if tmp, ok := rawArgs["artifacts"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("artifacts")) - arg1, err = ec.unmarshalNArtifactInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐArtifactInputSpecᚄ(ctx, tmp) + arg1, err = ec.unmarshalNIDorArtifactInput2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorArtifactInputᚄ(ctx, tmp) if err != nil { return nil, err } @@ -932,10 +932,10 @@ func (ec *executionContext) field_Mutation_ingestOccurrences_args(ctx context.Co func (ec *executionContext) field_Mutation_ingestPackage_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} - var arg0 model.PkgInputSpec + var arg0 model.IDorPkgInput if tmp, ok := rawArgs["pkg"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("pkg")) - arg0, err = ec.unmarshalNPkgInputSpec2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐPkgInputSpec(ctx, tmp) + arg0, err = ec.unmarshalNIDorPkgInput2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorPkgInput(ctx, tmp) if err != nil { return nil, err } @@ -947,10 +947,10 @@ func (ec *executionContext) field_Mutation_ingestPackage_args(ctx context.Contex func (ec *executionContext) field_Mutation_ingestPackages_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} - var arg0 []*model.PkgInputSpec + var arg0 []*model.IDorPkgInput if tmp, ok := rawArgs["pkgs"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("pkgs")) - arg0, err = ec.unmarshalNPkgInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐPkgInputSpecᚄ(ctx, tmp) + arg0, err = ec.unmarshalNIDorPkgInput2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorPkgInputᚄ(ctx, tmp) if err != nil { return nil, err } @@ -962,19 +962,19 @@ func (ec *executionContext) field_Mutation_ingestPackages_args(ctx context.Conte func (ec *executionContext) field_Mutation_ingestPkgEqual_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} - var arg0 model.PkgInputSpec + var arg0 model.IDorPkgInput if tmp, ok := rawArgs["pkg"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("pkg")) - arg0, err = ec.unmarshalNPkgInputSpec2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐPkgInputSpec(ctx, tmp) + arg0, err = ec.unmarshalNIDorPkgInput2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorPkgInput(ctx, tmp) if err != nil { return nil, err } } args["pkg"] = arg0 - var arg1 model.PkgInputSpec + var arg1 model.IDorPkgInput if tmp, ok := rawArgs["otherPackage"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("otherPackage")) - arg1, err = ec.unmarshalNPkgInputSpec2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐPkgInputSpec(ctx, tmp) + arg1, err = ec.unmarshalNIDorPkgInput2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorPkgInput(ctx, tmp) if err != nil { return nil, err } @@ -995,19 +995,19 @@ func (ec *executionContext) field_Mutation_ingestPkgEqual_args(ctx context.Conte func (ec *executionContext) field_Mutation_ingestPkgEquals_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} - var arg0 []*model.PkgInputSpec + var arg0 []*model.IDorPkgInput if tmp, ok := rawArgs["pkgs"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("pkgs")) - arg0, err = ec.unmarshalNPkgInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐPkgInputSpecᚄ(ctx, tmp) + arg0, err = ec.unmarshalNIDorPkgInput2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorPkgInputᚄ(ctx, tmp) if err != nil { return nil, err } } args["pkgs"] = arg0 - var arg1 []*model.PkgInputSpec + var arg1 []*model.IDorPkgInput if tmp, ok := rawArgs["otherPackages"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("otherPackages")) - arg1, err = ec.unmarshalNPkgInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐPkgInputSpecᚄ(ctx, tmp) + arg1, err = ec.unmarshalNIDorPkgInput2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorPkgInputᚄ(ctx, tmp) if err != nil { return nil, err } @@ -1094,28 +1094,28 @@ func (ec *executionContext) field_Mutation_ingestPointOfContacts_args(ctx contex func (ec *executionContext) field_Mutation_ingestSLSA_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} - var arg0 model.ArtifactInputSpec + var arg0 model.IDorArtifactInput if tmp, ok := rawArgs["subject"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("subject")) - arg0, err = ec.unmarshalNArtifactInputSpec2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐArtifactInputSpec(ctx, tmp) + arg0, err = ec.unmarshalNIDorArtifactInput2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorArtifactInput(ctx, tmp) if err != nil { return nil, err } } args["subject"] = arg0 - var arg1 []*model.ArtifactInputSpec + var arg1 []*model.IDorArtifactInput if tmp, ok := rawArgs["builtFrom"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("builtFrom")) - arg1, err = ec.unmarshalNArtifactInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐArtifactInputSpecᚄ(ctx, tmp) + arg1, err = ec.unmarshalNIDorArtifactInput2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorArtifactInputᚄ(ctx, tmp) if err != nil { return nil, err } } args["builtFrom"] = arg1 - var arg2 model.BuilderInputSpec + var arg2 model.IDorBuilderInput if tmp, ok := rawArgs["builtBy"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("builtBy")) - arg2, err = ec.unmarshalNBuilderInputSpec2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐBuilderInputSpec(ctx, tmp) + arg2, err = ec.unmarshalNIDorBuilderInput2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorBuilderInput(ctx, tmp) if err != nil { return nil, err } @@ -1136,28 +1136,28 @@ func (ec *executionContext) field_Mutation_ingestSLSA_args(ctx context.Context, func (ec *executionContext) field_Mutation_ingestSLSAs_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} - var arg0 []*model.ArtifactInputSpec + var arg0 []*model.IDorArtifactInput if tmp, ok := rawArgs["subjects"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("subjects")) - arg0, err = ec.unmarshalNArtifactInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐArtifactInputSpecᚄ(ctx, tmp) + arg0, err = ec.unmarshalNIDorArtifactInput2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorArtifactInputᚄ(ctx, tmp) if err != nil { return nil, err } } args["subjects"] = arg0 - var arg1 [][]*model.ArtifactInputSpec + var arg1 [][]*model.IDorArtifactInput if tmp, ok := rawArgs["builtFromList"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("builtFromList")) - arg1, err = ec.unmarshalNArtifactInputSpec2ᚕᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐArtifactInputSpecᚄ(ctx, tmp) + arg1, err = ec.unmarshalNIDorArtifactInput2ᚕᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorArtifactInputᚄ(ctx, tmp) if err != nil { return nil, err } } args["builtFromList"] = arg1 - var arg2 []*model.BuilderInputSpec + var arg2 []*model.IDorBuilderInput if tmp, ok := rawArgs["builtByList"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("builtByList")) - arg2, err = ec.unmarshalNBuilderInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐBuilderInputSpecᚄ(ctx, tmp) + arg2, err = ec.unmarshalNIDorBuilderInput2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorBuilderInputᚄ(ctx, tmp) if err != nil { return nil, err } @@ -1178,10 +1178,10 @@ func (ec *executionContext) field_Mutation_ingestSLSAs_args(ctx context.Context, func (ec *executionContext) field_Mutation_ingestScorecard_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} - var arg0 model.SourceInputSpec + var arg0 model.IDorSourceInput if tmp, ok := rawArgs["source"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("source")) - arg0, err = ec.unmarshalNSourceInputSpec2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐSourceInputSpec(ctx, tmp) + arg0, err = ec.unmarshalNIDorSourceInput2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorSourceInput(ctx, tmp) if err != nil { return nil, err } @@ -1202,10 +1202,10 @@ func (ec *executionContext) field_Mutation_ingestScorecard_args(ctx context.Cont func (ec *executionContext) field_Mutation_ingestScorecards_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} - var arg0 []*model.SourceInputSpec + var arg0 []*model.IDorSourceInput if tmp, ok := rawArgs["sources"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("sources")) - arg0, err = ec.unmarshalNSourceInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐSourceInputSpecᚄ(ctx, tmp) + arg0, err = ec.unmarshalNIDorSourceInput2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorSourceInputᚄ(ctx, tmp) if err != nil { return nil, err } @@ -1226,10 +1226,10 @@ func (ec *executionContext) field_Mutation_ingestScorecards_args(ctx context.Con func (ec *executionContext) field_Mutation_ingestSource_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} - var arg0 model.SourceInputSpec + var arg0 model.IDorSourceInput if tmp, ok := rawArgs["source"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("source")) - arg0, err = ec.unmarshalNSourceInputSpec2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐSourceInputSpec(ctx, tmp) + arg0, err = ec.unmarshalNIDorSourceInput2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorSourceInput(ctx, tmp) if err != nil { return nil, err } @@ -1241,10 +1241,10 @@ func (ec *executionContext) field_Mutation_ingestSource_args(ctx context.Context func (ec *executionContext) field_Mutation_ingestSources_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} - var arg0 []*model.SourceInputSpec + var arg0 []*model.IDorSourceInput if tmp, ok := rawArgs["sources"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("sources")) - arg0, err = ec.unmarshalNSourceInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐSourceInputSpecᚄ(ctx, tmp) + arg0, err = ec.unmarshalNIDorSourceInput2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorSourceInputᚄ(ctx, tmp) if err != nil { return nil, err } @@ -1265,10 +1265,10 @@ func (ec *executionContext) field_Mutation_ingestVEXStatement_args(ctx context.C } } args["subject"] = arg0 - var arg1 model.VulnerabilityInputSpec + var arg1 model.IDorVulnerabilityInput if tmp, ok := rawArgs["vulnerability"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("vulnerability")) - arg1, err = ec.unmarshalNVulnerabilityInputSpec2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐVulnerabilityInputSpec(ctx, tmp) + arg1, err = ec.unmarshalNIDorVulnerabilityInput2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorVulnerabilityInput(ctx, tmp) if err != nil { return nil, err } @@ -1298,10 +1298,10 @@ func (ec *executionContext) field_Mutation_ingestVEXStatements_args(ctx context. } } args["subjects"] = arg0 - var arg1 []*model.VulnerabilityInputSpec + var arg1 []*model.IDorVulnerabilityInput if tmp, ok := rawArgs["vulnerabilities"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("vulnerabilities")) - arg1, err = ec.unmarshalNVulnerabilityInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐVulnerabilityInputSpecᚄ(ctx, tmp) + arg1, err = ec.unmarshalNIDorVulnerabilityInput2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorVulnerabilityInputᚄ(ctx, tmp) if err != nil { return nil, err } @@ -1322,19 +1322,19 @@ func (ec *executionContext) field_Mutation_ingestVEXStatements_args(ctx context. func (ec *executionContext) field_Mutation_ingestVulnEqual_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} - var arg0 model.VulnerabilityInputSpec + var arg0 model.IDorVulnerabilityInput if tmp, ok := rawArgs["vulnerability"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("vulnerability")) - arg0, err = ec.unmarshalNVulnerabilityInputSpec2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐVulnerabilityInputSpec(ctx, tmp) + arg0, err = ec.unmarshalNIDorVulnerabilityInput2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorVulnerabilityInput(ctx, tmp) if err != nil { return nil, err } } args["vulnerability"] = arg0 - var arg1 model.VulnerabilityInputSpec + var arg1 model.IDorVulnerabilityInput if tmp, ok := rawArgs["otherVulnerability"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("otherVulnerability")) - arg1, err = ec.unmarshalNVulnerabilityInputSpec2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐVulnerabilityInputSpec(ctx, tmp) + arg1, err = ec.unmarshalNIDorVulnerabilityInput2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorVulnerabilityInput(ctx, tmp) if err != nil { return nil, err } @@ -1355,19 +1355,19 @@ func (ec *executionContext) field_Mutation_ingestVulnEqual_args(ctx context.Cont func (ec *executionContext) field_Mutation_ingestVulnEquals_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} - var arg0 []*model.VulnerabilityInputSpec + var arg0 []*model.IDorVulnerabilityInput if tmp, ok := rawArgs["vulnerabilities"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("vulnerabilities")) - arg0, err = ec.unmarshalNVulnerabilityInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐVulnerabilityInputSpecᚄ(ctx, tmp) + arg0, err = ec.unmarshalNIDorVulnerabilityInput2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorVulnerabilityInputᚄ(ctx, tmp) if err != nil { return nil, err } } args["vulnerabilities"] = arg0 - var arg1 []*model.VulnerabilityInputSpec + var arg1 []*model.IDorVulnerabilityInput if tmp, ok := rawArgs["otherVulnerabilities"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("otherVulnerabilities")) - arg1, err = ec.unmarshalNVulnerabilityInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐVulnerabilityInputSpecᚄ(ctx, tmp) + arg1, err = ec.unmarshalNIDorVulnerabilityInput2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorVulnerabilityInputᚄ(ctx, tmp) if err != nil { return nil, err } @@ -1388,10 +1388,10 @@ func (ec *executionContext) field_Mutation_ingestVulnEquals_args(ctx context.Con func (ec *executionContext) field_Mutation_ingestVulnerabilities_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} - var arg0 []*model.VulnerabilityInputSpec + var arg0 []*model.IDorVulnerabilityInput if tmp, ok := rawArgs["vulns"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("vulns")) - arg0, err = ec.unmarshalNVulnerabilityInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐVulnerabilityInputSpecᚄ(ctx, tmp) + arg0, err = ec.unmarshalNIDorVulnerabilityInput2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorVulnerabilityInputᚄ(ctx, tmp) if err != nil { return nil, err } @@ -1403,10 +1403,10 @@ func (ec *executionContext) field_Mutation_ingestVulnerabilities_args(ctx contex func (ec *executionContext) field_Mutation_ingestVulnerabilityMetadata_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} - var arg0 model.VulnerabilityInputSpec + var arg0 model.IDorVulnerabilityInput if tmp, ok := rawArgs["vulnerability"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("vulnerability")) - arg0, err = ec.unmarshalNVulnerabilityInputSpec2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐVulnerabilityInputSpec(ctx, tmp) + arg0, err = ec.unmarshalNIDorVulnerabilityInput2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorVulnerabilityInput(ctx, tmp) if err != nil { return nil, err } @@ -1427,10 +1427,10 @@ func (ec *executionContext) field_Mutation_ingestVulnerabilityMetadata_args(ctx func (ec *executionContext) field_Mutation_ingestVulnerability_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} - var arg0 model.VulnerabilityInputSpec + var arg0 model.IDorVulnerabilityInput if tmp, ok := rawArgs["vuln"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("vuln")) - arg0, err = ec.unmarshalNVulnerabilityInputSpec2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐVulnerabilityInputSpec(ctx, tmp) + arg0, err = ec.unmarshalNIDorVulnerabilityInput2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorVulnerabilityInput(ctx, tmp) if err != nil { return nil, err } @@ -2055,7 +2055,7 @@ func (ec *executionContext) _Mutation_ingestArtifact(ctx context.Context, field }() resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Mutation().IngestArtifact(rctx, fc.Args["artifact"].(*model.ArtifactInputSpec)) + return ec.resolvers.Mutation().IngestArtifact(rctx, fc.Args["artifact"].(*model.IDorArtifactInput)) }) if resTmp == nil { @@ -2107,7 +2107,7 @@ func (ec *executionContext) _Mutation_ingestArtifacts(ctx context.Context, field }() resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Mutation().IngestArtifacts(rctx, fc.Args["artifacts"].([]*model.ArtifactInputSpec)) + return ec.resolvers.Mutation().IngestArtifacts(rctx, fc.Args["artifacts"].([]*model.IDorArtifactInput)) }) if resTmp == nil { @@ -2159,7 +2159,7 @@ func (ec *executionContext) _Mutation_ingestBuilder(ctx context.Context, field g }() resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Mutation().IngestBuilder(rctx, fc.Args["builder"].(*model.BuilderInputSpec)) + return ec.resolvers.Mutation().IngestBuilder(rctx, fc.Args["builder"].(*model.IDorBuilderInput)) }) if resTmp == nil { @@ -2211,7 +2211,7 @@ func (ec *executionContext) _Mutation_ingestBuilders(ctx context.Context, field }() resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Mutation().IngestBuilders(rctx, fc.Args["builders"].([]*model.BuilderInputSpec)) + return ec.resolvers.Mutation().IngestBuilders(rctx, fc.Args["builders"].([]*model.IDorBuilderInput)) }) if resTmp == nil { @@ -2471,7 +2471,7 @@ func (ec *executionContext) _Mutation_ingestCertifyLegal(ctx context.Context, fi }() resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Mutation().IngestCertifyLegal(rctx, fc.Args["subject"].(model.PackageOrSourceInput), fc.Args["declaredLicenses"].([]*model.LicenseInputSpec), fc.Args["discoveredLicenses"].([]*model.LicenseInputSpec), fc.Args["certifyLegal"].(model.CertifyLegalInputSpec)) + return ec.resolvers.Mutation().IngestCertifyLegal(rctx, fc.Args["subject"].(model.PackageOrSourceInput), fc.Args["declaredLicenses"].([]*model.IDorLicenseInput), fc.Args["discoveredLicenses"].([]*model.IDorLicenseInput), fc.Args["certifyLegal"].(model.CertifyLegalInputSpec)) }) if resTmp == nil { @@ -2523,7 +2523,7 @@ func (ec *executionContext) _Mutation_ingestCertifyLegals(ctx context.Context, f }() resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Mutation().IngestCertifyLegals(rctx, fc.Args["subjects"].(model.PackageOrSourceInputs), fc.Args["declaredLicensesList"].([][]*model.LicenseInputSpec), fc.Args["discoveredLicensesList"].([][]*model.LicenseInputSpec), fc.Args["certifyLegals"].([]*model.CertifyLegalInputSpec)) + return ec.resolvers.Mutation().IngestCertifyLegals(rctx, fc.Args["subjects"].(model.PackageOrSourceInputs), fc.Args["declaredLicensesList"].([][]*model.IDorLicenseInput), fc.Args["discoveredLicensesList"].([][]*model.IDorLicenseInput), fc.Args["certifyLegals"].([]*model.CertifyLegalInputSpec)) }) if resTmp == nil { @@ -2575,7 +2575,7 @@ func (ec *executionContext) _Mutation_ingestScorecard(ctx context.Context, field }() resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Mutation().IngestScorecard(rctx, fc.Args["source"].(model.SourceInputSpec), fc.Args["scorecard"].(model.ScorecardInputSpec)) + return ec.resolvers.Mutation().IngestScorecard(rctx, fc.Args["source"].(model.IDorSourceInput), fc.Args["scorecard"].(model.ScorecardInputSpec)) }) if resTmp == nil { @@ -2627,7 +2627,7 @@ func (ec *executionContext) _Mutation_ingestScorecards(ctx context.Context, fiel }() resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Mutation().IngestScorecards(rctx, fc.Args["sources"].([]*model.SourceInputSpec), fc.Args["scorecards"].([]*model.ScorecardInputSpec)) + return ec.resolvers.Mutation().IngestScorecards(rctx, fc.Args["sources"].([]*model.IDorSourceInput), fc.Args["scorecards"].([]*model.ScorecardInputSpec)) }) if resTmp == nil { @@ -2679,7 +2679,7 @@ func (ec *executionContext) _Mutation_ingestVEXStatement(ctx context.Context, fi }() resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Mutation().IngestVEXStatement(rctx, fc.Args["subject"].(model.PackageOrArtifactInput), fc.Args["vulnerability"].(model.VulnerabilityInputSpec), fc.Args["vexStatement"].(model.VexStatementInputSpec)) + return ec.resolvers.Mutation().IngestVEXStatement(rctx, fc.Args["subject"].(model.PackageOrArtifactInput), fc.Args["vulnerability"].(model.IDorVulnerabilityInput), fc.Args["vexStatement"].(model.VexStatementInputSpec)) }) if resTmp == nil { @@ -2731,7 +2731,7 @@ func (ec *executionContext) _Mutation_ingestVEXStatements(ctx context.Context, f }() resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Mutation().IngestVEXStatements(rctx, fc.Args["subjects"].(model.PackageOrArtifactInputs), fc.Args["vulnerabilities"].([]*model.VulnerabilityInputSpec), fc.Args["vexStatements"].([]*model.VexStatementInputSpec)) + return ec.resolvers.Mutation().IngestVEXStatements(rctx, fc.Args["subjects"].(model.PackageOrArtifactInputs), fc.Args["vulnerabilities"].([]*model.IDorVulnerabilityInput), fc.Args["vexStatements"].([]*model.VexStatementInputSpec)) }) if resTmp == nil { @@ -2783,7 +2783,7 @@ func (ec *executionContext) _Mutation_ingestCertifyVuln(ctx context.Context, fie }() resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Mutation().IngestCertifyVuln(rctx, fc.Args["pkg"].(model.PkgInputSpec), fc.Args["vulnerability"].(model.VulnerabilityInputSpec), fc.Args["certifyVuln"].(model.ScanMetadataInput)) + return ec.resolvers.Mutation().IngestCertifyVuln(rctx, fc.Args["pkg"].(model.IDorPkgInput), fc.Args["vulnerability"].(model.IDorVulnerabilityInput), fc.Args["certifyVuln"].(model.ScanMetadataInput)) }) if resTmp == nil { @@ -2835,7 +2835,7 @@ func (ec *executionContext) _Mutation_ingestCertifyVulns(ctx context.Context, fi }() resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Mutation().IngestCertifyVulns(rctx, fc.Args["pkgs"].([]*model.PkgInputSpec), fc.Args["vulnerabilities"].([]*model.VulnerabilityInputSpec), fc.Args["certifyVulns"].([]*model.ScanMetadataInput)) + return ec.resolvers.Mutation().IngestCertifyVulns(rctx, fc.Args["pkgs"].([]*model.IDorPkgInput), fc.Args["vulnerabilities"].([]*model.IDorVulnerabilityInput), fc.Args["certifyVulns"].([]*model.ScanMetadataInput)) }) if resTmp == nil { @@ -3095,7 +3095,7 @@ func (ec *executionContext) _Mutation_ingestSLSA(ctx context.Context, field grap }() resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Mutation().IngestSlsa(rctx, fc.Args["subject"].(model.ArtifactInputSpec), fc.Args["builtFrom"].([]*model.ArtifactInputSpec), fc.Args["builtBy"].(model.BuilderInputSpec), fc.Args["slsa"].(model.SLSAInputSpec)) + return ec.resolvers.Mutation().IngestSlsa(rctx, fc.Args["subject"].(model.IDorArtifactInput), fc.Args["builtFrom"].([]*model.IDorArtifactInput), fc.Args["builtBy"].(model.IDorBuilderInput), fc.Args["slsa"].(model.SLSAInputSpec)) }) if resTmp == nil { @@ -3147,7 +3147,7 @@ func (ec *executionContext) _Mutation_ingestSLSAs(ctx context.Context, field gra }() resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Mutation().IngestSLSAs(rctx, fc.Args["subjects"].([]*model.ArtifactInputSpec), fc.Args["builtFromList"].([][]*model.ArtifactInputSpec), fc.Args["builtByList"].([]*model.BuilderInputSpec), fc.Args["slsaList"].([]*model.SLSAInputSpec)) + return ec.resolvers.Mutation().IngestSLSAs(rctx, fc.Args["subjects"].([]*model.IDorArtifactInput), fc.Args["builtFromList"].([][]*model.IDorArtifactInput), fc.Args["builtByList"].([]*model.IDorBuilderInput), fc.Args["slsaList"].([]*model.SLSAInputSpec)) }) if resTmp == nil { @@ -3199,7 +3199,7 @@ func (ec *executionContext) _Mutation_ingestHasSourceAt(ctx context.Context, fie }() resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Mutation().IngestHasSourceAt(rctx, fc.Args["pkg"].(model.PkgInputSpec), fc.Args["pkgMatchType"].(model.MatchFlags), fc.Args["source"].(model.SourceInputSpec), fc.Args["hasSourceAt"].(model.HasSourceAtInputSpec)) + return ec.resolvers.Mutation().IngestHasSourceAt(rctx, fc.Args["pkg"].(model.IDorPkgInput), fc.Args["pkgMatchType"].(model.MatchFlags), fc.Args["source"].(model.IDorSourceInput), fc.Args["hasSourceAt"].(model.HasSourceAtInputSpec)) }) if resTmp == nil { @@ -3251,7 +3251,7 @@ func (ec *executionContext) _Mutation_ingestHasSourceAts(ctx context.Context, fi }() resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Mutation().IngestHasSourceAts(rctx, fc.Args["pkgs"].([]*model.PkgInputSpec), fc.Args["pkgMatchType"].(model.MatchFlags), fc.Args["sources"].([]*model.SourceInputSpec), fc.Args["hasSourceAts"].([]*model.HasSourceAtInputSpec)) + return ec.resolvers.Mutation().IngestHasSourceAts(rctx, fc.Args["pkgs"].([]*model.IDorPkgInput), fc.Args["pkgMatchType"].(model.MatchFlags), fc.Args["sources"].([]*model.IDorSourceInput), fc.Args["hasSourceAts"].([]*model.HasSourceAtInputSpec)) }) if resTmp == nil { @@ -3303,7 +3303,7 @@ func (ec *executionContext) _Mutation_ingestHashEqual(ctx context.Context, field }() resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Mutation().IngestHashEqual(rctx, fc.Args["artifact"].(model.ArtifactInputSpec), fc.Args["otherArtifact"].(model.ArtifactInputSpec), fc.Args["hashEqual"].(model.HashEqualInputSpec)) + return ec.resolvers.Mutation().IngestHashEqual(rctx, fc.Args["artifact"].(model.IDorArtifactInput), fc.Args["otherArtifact"].(model.IDorArtifactInput), fc.Args["hashEqual"].(model.HashEqualInputSpec)) }) if resTmp == nil { @@ -3355,7 +3355,7 @@ func (ec *executionContext) _Mutation_ingestHashEquals(ctx context.Context, fiel }() resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Mutation().IngestHashEquals(rctx, fc.Args["artifacts"].([]*model.ArtifactInputSpec), fc.Args["otherArtifacts"].([]*model.ArtifactInputSpec), fc.Args["hashEquals"].([]*model.HashEqualInputSpec)) + return ec.resolvers.Mutation().IngestHashEquals(rctx, fc.Args["artifacts"].([]*model.IDorArtifactInput), fc.Args["otherArtifacts"].([]*model.IDorArtifactInput), fc.Args["hashEquals"].([]*model.HashEqualInputSpec)) }) if resTmp == nil { @@ -3407,7 +3407,7 @@ func (ec *executionContext) _Mutation_ingestDependency(ctx context.Context, fiel }() resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Mutation().IngestDependency(rctx, fc.Args["pkg"].(model.PkgInputSpec), fc.Args["depPkg"].(model.PkgInputSpec), fc.Args["depPkgMatchType"].(model.MatchFlags), fc.Args["dependency"].(model.IsDependencyInputSpec)) + return ec.resolvers.Mutation().IngestDependency(rctx, fc.Args["pkg"].(model.IDorPkgInput), fc.Args["depPkg"].(model.IDorPkgInput), fc.Args["depPkgMatchType"].(model.MatchFlags), fc.Args["dependency"].(model.IsDependencyInputSpec)) }) if resTmp == nil { @@ -3459,7 +3459,7 @@ func (ec *executionContext) _Mutation_ingestDependencies(ctx context.Context, fi }() resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Mutation().IngestDependencies(rctx, fc.Args["pkgs"].([]*model.PkgInputSpec), fc.Args["depPkgs"].([]*model.PkgInputSpec), fc.Args["depPkgMatchType"].(model.MatchFlags), fc.Args["dependencies"].([]*model.IsDependencyInputSpec)) + return ec.resolvers.Mutation().IngestDependencies(rctx, fc.Args["pkgs"].([]*model.IDorPkgInput), fc.Args["depPkgs"].([]*model.IDorPkgInput), fc.Args["depPkgMatchType"].(model.MatchFlags), fc.Args["dependencies"].([]*model.IsDependencyInputSpec)) }) if resTmp == nil { @@ -3511,7 +3511,7 @@ func (ec *executionContext) _Mutation_ingestOccurrence(ctx context.Context, fiel }() resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Mutation().IngestOccurrence(rctx, fc.Args["subject"].(model.PackageOrSourceInput), fc.Args["artifact"].(model.ArtifactInputSpec), fc.Args["occurrence"].(model.IsOccurrenceInputSpec)) + return ec.resolvers.Mutation().IngestOccurrence(rctx, fc.Args["subject"].(model.PackageOrSourceInput), fc.Args["artifact"].(model.IDorArtifactInput), fc.Args["occurrence"].(model.IsOccurrenceInputSpec)) }) if resTmp == nil { @@ -3563,7 +3563,7 @@ func (ec *executionContext) _Mutation_ingestOccurrences(ctx context.Context, fie }() resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Mutation().IngestOccurrences(rctx, fc.Args["subjects"].(model.PackageOrSourceInputs), fc.Args["artifacts"].([]*model.ArtifactInputSpec), fc.Args["occurrences"].([]*model.IsOccurrenceInputSpec)) + return ec.resolvers.Mutation().IngestOccurrences(rctx, fc.Args["subjects"].(model.PackageOrSourceInputs), fc.Args["artifacts"].([]*model.IDorArtifactInput), fc.Args["occurrences"].([]*model.IsOccurrenceInputSpec)) }) if resTmp == nil { @@ -3615,7 +3615,7 @@ func (ec *executionContext) _Mutation_ingestLicense(ctx context.Context, field g }() resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Mutation().IngestLicense(rctx, fc.Args["license"].(*model.LicenseInputSpec)) + return ec.resolvers.Mutation().IngestLicense(rctx, fc.Args["license"].(*model.IDorLicenseInput)) }) if resTmp == nil { @@ -3667,7 +3667,7 @@ func (ec *executionContext) _Mutation_ingestLicenses(ctx context.Context, field }() resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Mutation().IngestLicenses(rctx, fc.Args["licenses"].([]*model.LicenseInputSpec)) + return ec.resolvers.Mutation().IngestLicenses(rctx, fc.Args["licenses"].([]*model.IDorLicenseInput)) }) if resTmp == nil { @@ -3823,7 +3823,7 @@ func (ec *executionContext) _Mutation_ingestPackage(ctx context.Context, field g }() resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Mutation().IngestPackage(rctx, fc.Args["pkg"].(model.PkgInputSpec)) + return ec.resolvers.Mutation().IngestPackage(rctx, fc.Args["pkg"].(model.IDorPkgInput)) }) if resTmp == nil { @@ -3885,7 +3885,7 @@ func (ec *executionContext) _Mutation_ingestPackages(ctx context.Context, field }() resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Mutation().IngestPackages(rctx, fc.Args["pkgs"].([]*model.PkgInputSpec)) + return ec.resolvers.Mutation().IngestPackages(rctx, fc.Args["pkgs"].([]*model.IDorPkgInput)) }) if resTmp == nil { @@ -3947,7 +3947,7 @@ func (ec *executionContext) _Mutation_ingestPkgEqual(ctx context.Context, field }() resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Mutation().IngestPkgEqual(rctx, fc.Args["pkg"].(model.PkgInputSpec), fc.Args["otherPackage"].(model.PkgInputSpec), fc.Args["pkgEqual"].(model.PkgEqualInputSpec)) + return ec.resolvers.Mutation().IngestPkgEqual(rctx, fc.Args["pkg"].(model.IDorPkgInput), fc.Args["otherPackage"].(model.IDorPkgInput), fc.Args["pkgEqual"].(model.PkgEqualInputSpec)) }) if resTmp == nil { @@ -3999,7 +3999,7 @@ func (ec *executionContext) _Mutation_ingestPkgEquals(ctx context.Context, field }() resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Mutation().IngestPkgEquals(rctx, fc.Args["pkgs"].([]*model.PkgInputSpec), fc.Args["otherPackages"].([]*model.PkgInputSpec), fc.Args["pkgEquals"].([]*model.PkgEqualInputSpec)) + return ec.resolvers.Mutation().IngestPkgEquals(rctx, fc.Args["pkgs"].([]*model.IDorPkgInput), fc.Args["otherPackages"].([]*model.IDorPkgInput), fc.Args["pkgEquals"].([]*model.PkgEqualInputSpec)) }) if resTmp == nil { @@ -4051,7 +4051,7 @@ func (ec *executionContext) _Mutation_ingestSource(ctx context.Context, field gr }() resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Mutation().IngestSource(rctx, fc.Args["source"].(model.SourceInputSpec)) + return ec.resolvers.Mutation().IngestSource(rctx, fc.Args["source"].(model.IDorSourceInput)) }) if resTmp == nil { @@ -4111,7 +4111,7 @@ func (ec *executionContext) _Mutation_ingestSources(ctx context.Context, field g }() resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Mutation().IngestSources(rctx, fc.Args["sources"].([]*model.SourceInputSpec)) + return ec.resolvers.Mutation().IngestSources(rctx, fc.Args["sources"].([]*model.IDorSourceInput)) }) if resTmp == nil { @@ -4171,7 +4171,7 @@ func (ec *executionContext) _Mutation_ingestVulnEqual(ctx context.Context, field }() resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Mutation().IngestVulnEqual(rctx, fc.Args["vulnerability"].(model.VulnerabilityInputSpec), fc.Args["otherVulnerability"].(model.VulnerabilityInputSpec), fc.Args["vulnEqual"].(model.VulnEqualInputSpec)) + return ec.resolvers.Mutation().IngestVulnEqual(rctx, fc.Args["vulnerability"].(model.IDorVulnerabilityInput), fc.Args["otherVulnerability"].(model.IDorVulnerabilityInput), fc.Args["vulnEqual"].(model.VulnEqualInputSpec)) }) if resTmp == nil { @@ -4223,7 +4223,7 @@ func (ec *executionContext) _Mutation_ingestVulnEquals(ctx context.Context, fiel }() resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Mutation().IngestVulnEquals(rctx, fc.Args["vulnerabilities"].([]*model.VulnerabilityInputSpec), fc.Args["otherVulnerabilities"].([]*model.VulnerabilityInputSpec), fc.Args["vulnEquals"].([]*model.VulnEqualInputSpec)) + return ec.resolvers.Mutation().IngestVulnEquals(rctx, fc.Args["vulnerabilities"].([]*model.IDorVulnerabilityInput), fc.Args["otherVulnerabilities"].([]*model.IDorVulnerabilityInput), fc.Args["vulnEquals"].([]*model.VulnEqualInputSpec)) }) if resTmp == nil { @@ -4275,7 +4275,7 @@ func (ec *executionContext) _Mutation_ingestVulnerabilityMetadata(ctx context.Co }() resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Mutation().IngestVulnerabilityMetadata(rctx, fc.Args["vulnerability"].(model.VulnerabilityInputSpec), fc.Args["vulnerabilityMetadata"].(model.VulnerabilityMetadataInputSpec)) + return ec.resolvers.Mutation().IngestVulnerabilityMetadata(rctx, fc.Args["vulnerability"].(model.IDorVulnerabilityInput), fc.Args["vulnerabilityMetadata"].(model.VulnerabilityMetadataInputSpec)) }) if resTmp == nil { @@ -4327,7 +4327,7 @@ func (ec *executionContext) _Mutation_ingestBulkVulnerabilityMetadata(ctx contex }() resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Mutation().IngestBulkVulnerabilityMetadata(rctx, fc.Args["vulnerabilities"].([]*model.VulnerabilityInputSpec), fc.Args["vulnerabilityMetadataList"].([]*model.VulnerabilityMetadataInputSpec)) + return ec.resolvers.Mutation().IngestBulkVulnerabilityMetadata(rctx, fc.Args["vulnerabilities"].([]*model.IDorVulnerabilityInput), fc.Args["vulnerabilityMetadataList"].([]*model.VulnerabilityMetadataInputSpec)) }) if resTmp == nil { @@ -4379,7 +4379,7 @@ func (ec *executionContext) _Mutation_ingestVulnerability(ctx context.Context, f }() resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Mutation().IngestVulnerability(rctx, fc.Args["vuln"].(model.VulnerabilityInputSpec)) + return ec.resolvers.Mutation().IngestVulnerability(rctx, fc.Args["vuln"].(model.IDorVulnerabilityInput)) }) if resTmp == nil { @@ -4437,7 +4437,7 @@ func (ec *executionContext) _Mutation_ingestVulnerabilities(ctx context.Context, }() resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Mutation().IngestVulnerabilities(rctx, fc.Args["vulns"].([]*model.VulnerabilityInputSpec)) + return ec.resolvers.Mutation().IngestVulnerabilities(rctx, fc.Args["vulns"].([]*model.IDorVulnerabilityInput)) }) if resTmp == nil { @@ -6449,6 +6449,40 @@ func (ec *executionContext) unmarshalInputArtifactSpec(ctx context.Context, obj return it, nil } +func (ec *executionContext) unmarshalInputIDorArtifactInput(ctx context.Context, obj interface{}) (model.IDorArtifactInput, error) { + var it model.IDorArtifactInput + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"artifactID", "artifactInput"} + for _, k := range fieldsInOrder { + v, ok := asMap[k] + if !ok { + continue + } + switch k { + case "artifactID": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("artifactID")) + data, err := ec.unmarshalOID2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.ArtifactID = data + case "artifactInput": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("artifactInput")) + data, err := ec.unmarshalOArtifactInputSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐArtifactInputSpec(ctx, v) + if err != nil { + return it, err + } + it.ArtifactInput = data + } + } + + return it, nil +} + // endregion **************************** input.gotpl ***************************** // region ************************** interface.gotpl *************************** @@ -7594,21 +7628,31 @@ func (ec *executionContext) marshalNArtifact2ᚖgithubᚗcomᚋguacsecᚋguacᚋ return ec._Artifact(ctx, sel, v) } -func (ec *executionContext) unmarshalNArtifactInputSpec2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐArtifactInputSpec(ctx context.Context, v interface{}) (model.ArtifactInputSpec, error) { - res, err := ec.unmarshalInputArtifactInputSpec(ctx, v) +func (ec *executionContext) unmarshalNArtifactSpec2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐArtifactSpec(ctx context.Context, v interface{}) (model.ArtifactSpec, error) { + res, err := ec.unmarshalInputArtifactSpec(ctx, v) return res, graphql.ErrorOnPath(ctx, err) } -func (ec *executionContext) unmarshalNArtifactInputSpec2ᚕᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐArtifactInputSpecᚄ(ctx context.Context, v interface{}) ([][]*model.ArtifactInputSpec, error) { +func (ec *executionContext) unmarshalNArtifactSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐArtifactSpec(ctx context.Context, v interface{}) (*model.ArtifactSpec, error) { + res, err := ec.unmarshalInputArtifactSpec(ctx, v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) unmarshalNIDorArtifactInput2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorArtifactInput(ctx context.Context, v interface{}) (model.IDorArtifactInput, error) { + res, err := ec.unmarshalInputIDorArtifactInput(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) unmarshalNIDorArtifactInput2ᚕᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorArtifactInputᚄ(ctx context.Context, v interface{}) ([][]*model.IDorArtifactInput, error) { var vSlice []interface{} if v != nil { vSlice = graphql.CoerceList(v) } var err error - res := make([][]*model.ArtifactInputSpec, len(vSlice)) + res := make([][]*model.IDorArtifactInput, len(vSlice)) for i := range vSlice { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) - res[i], err = ec.unmarshalNArtifactInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐArtifactInputSpecᚄ(ctx, vSlice[i]) + res[i], err = ec.unmarshalNIDorArtifactInput2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorArtifactInputᚄ(ctx, vSlice[i]) if err != nil { return nil, err } @@ -7616,16 +7660,16 @@ func (ec *executionContext) unmarshalNArtifactInputSpec2ᚕᚕᚖgithubᚗcomᚋ return res, nil } -func (ec *executionContext) unmarshalNArtifactInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐArtifactInputSpecᚄ(ctx context.Context, v interface{}) ([]*model.ArtifactInputSpec, error) { +func (ec *executionContext) unmarshalNIDorArtifactInput2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorArtifactInputᚄ(ctx context.Context, v interface{}) ([]*model.IDorArtifactInput, error) { var vSlice []interface{} if v != nil { vSlice = graphql.CoerceList(v) } var err error - res := make([]*model.ArtifactInputSpec, len(vSlice)) + res := make([]*model.IDorArtifactInput, len(vSlice)) for i := range vSlice { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) - res[i], err = ec.unmarshalNArtifactInputSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐArtifactInputSpec(ctx, vSlice[i]) + res[i], err = ec.unmarshalNIDorArtifactInput2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorArtifactInput(ctx, vSlice[i]) if err != nil { return nil, err } @@ -7633,22 +7677,20 @@ func (ec *executionContext) unmarshalNArtifactInputSpec2ᚕᚖgithubᚗcomᚋgua return res, nil } -func (ec *executionContext) unmarshalNArtifactInputSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐArtifactInputSpec(ctx context.Context, v interface{}) (*model.ArtifactInputSpec, error) { - res, err := ec.unmarshalInputArtifactInputSpec(ctx, v) +func (ec *executionContext) unmarshalNIDorArtifactInput2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorArtifactInput(ctx context.Context, v interface{}) (*model.IDorArtifactInput, error) { + res, err := ec.unmarshalInputIDorArtifactInput(ctx, v) return &res, graphql.ErrorOnPath(ctx, err) } -func (ec *executionContext) unmarshalNArtifactSpec2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐArtifactSpec(ctx context.Context, v interface{}) (model.ArtifactSpec, error) { - res, err := ec.unmarshalInputArtifactSpec(ctx, v) - return res, graphql.ErrorOnPath(ctx, err) -} - -func (ec *executionContext) unmarshalNArtifactSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐArtifactSpec(ctx context.Context, v interface{}) (*model.ArtifactSpec, error) { - res, err := ec.unmarshalInputArtifactSpec(ctx, v) +func (ec *executionContext) unmarshalOArtifactInputSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐArtifactInputSpec(ctx context.Context, v interface{}) (*model.ArtifactInputSpec, error) { + if v == nil { + return nil, nil + } + res, err := ec.unmarshalInputArtifactInputSpec(ctx, v) return &res, graphql.ErrorOnPath(ctx, err) } -func (ec *executionContext) unmarshalOArtifactInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐArtifactInputSpecᚄ(ctx context.Context, v interface{}) ([]*model.ArtifactInputSpec, error) { +func (ec *executionContext) unmarshalOArtifactSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐArtifactSpec(ctx context.Context, v interface{}) ([]*model.ArtifactSpec, error) { if v == nil { return nil, nil } @@ -7657,10 +7699,10 @@ func (ec *executionContext) unmarshalOArtifactInputSpec2ᚕᚖgithubᚗcomᚋgua vSlice = graphql.CoerceList(v) } var err error - res := make([]*model.ArtifactInputSpec, len(vSlice)) + res := make([]*model.ArtifactSpec, len(vSlice)) for i := range vSlice { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) - res[i], err = ec.unmarshalNArtifactInputSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐArtifactInputSpec(ctx, vSlice[i]) + res[i], err = ec.unmarshalOArtifactSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐArtifactSpec(ctx, vSlice[i]) if err != nil { return nil, err } @@ -7668,15 +7710,7 @@ func (ec *executionContext) unmarshalOArtifactInputSpec2ᚕᚖgithubᚗcomᚋgua return res, nil } -func (ec *executionContext) unmarshalOArtifactInputSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐArtifactInputSpec(ctx context.Context, v interface{}) (*model.ArtifactInputSpec, error) { - if v == nil { - return nil, nil - } - res, err := ec.unmarshalInputArtifactInputSpec(ctx, v) - return &res, graphql.ErrorOnPath(ctx, err) -} - -func (ec *executionContext) unmarshalOArtifactSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐArtifactSpec(ctx context.Context, v interface{}) ([]*model.ArtifactSpec, error) { +func (ec *executionContext) unmarshalOArtifactSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐArtifactSpecᚄ(ctx context.Context, v interface{}) ([]*model.ArtifactSpec, error) { if v == nil { return nil, nil } @@ -7688,7 +7722,7 @@ func (ec *executionContext) unmarshalOArtifactSpec2ᚕᚖgithubᚗcomᚋguacsec res := make([]*model.ArtifactSpec, len(vSlice)) for i := range vSlice { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) - res[i], err = ec.unmarshalOArtifactSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐArtifactSpec(ctx, vSlice[i]) + res[i], err = ec.unmarshalNArtifactSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐArtifactSpec(ctx, vSlice[i]) if err != nil { return nil, err } @@ -7696,7 +7730,15 @@ func (ec *executionContext) unmarshalOArtifactSpec2ᚕᚖgithubᚗcomᚋguacsec return res, nil } -func (ec *executionContext) unmarshalOArtifactSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐArtifactSpecᚄ(ctx context.Context, v interface{}) ([]*model.ArtifactSpec, error) { +func (ec *executionContext) unmarshalOArtifactSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐArtifactSpec(ctx context.Context, v interface{}) (*model.ArtifactSpec, error) { + if v == nil { + return nil, nil + } + res, err := ec.unmarshalInputArtifactSpec(ctx, v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) unmarshalOIDorArtifactInput2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorArtifactInputᚄ(ctx context.Context, v interface{}) ([]*model.IDorArtifactInput, error) { if v == nil { return nil, nil } @@ -7705,10 +7747,10 @@ func (ec *executionContext) unmarshalOArtifactSpec2ᚕᚖgithubᚗcomᚋguacsec vSlice = graphql.CoerceList(v) } var err error - res := make([]*model.ArtifactSpec, len(vSlice)) + res := make([]*model.IDorArtifactInput, len(vSlice)) for i := range vSlice { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) - res[i], err = ec.unmarshalNArtifactSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐArtifactSpec(ctx, vSlice[i]) + res[i], err = ec.unmarshalNIDorArtifactInput2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorArtifactInput(ctx, vSlice[i]) if err != nil { return nil, err } @@ -7716,11 +7758,11 @@ func (ec *executionContext) unmarshalOArtifactSpec2ᚕᚖgithubᚗcomᚋguacsec return res, nil } -func (ec *executionContext) unmarshalOArtifactSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐArtifactSpec(ctx context.Context, v interface{}) (*model.ArtifactSpec, error) { +func (ec *executionContext) unmarshalOIDorArtifactInput2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorArtifactInput(ctx context.Context, v interface{}) (*model.IDorArtifactInput, error) { if v == nil { return nil, nil } - res, err := ec.unmarshalInputArtifactSpec(ctx, v) + res, err := ec.unmarshalInputIDorArtifactInput(ctx, v) return &res, graphql.ErrorOnPath(ctx, err) } diff --git a/pkg/assembler/graphql/generated/builder.generated.go b/pkg/assembler/graphql/generated/builder.generated.go index ab30d681b9..b320e9a91d 100644 --- a/pkg/assembler/graphql/generated/builder.generated.go +++ b/pkg/assembler/graphql/generated/builder.generated.go @@ -175,6 +175,40 @@ func (ec *executionContext) unmarshalInputBuilderSpec(ctx context.Context, obj i return it, nil } +func (ec *executionContext) unmarshalInputIDorBuilderInput(ctx context.Context, obj interface{}) (model.IDorBuilderInput, error) { + var it model.IDorBuilderInput + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"builderID", "builderInput"} + for _, k := range fieldsInOrder { + v, ok := asMap[k] + if !ok { + continue + } + switch k { + case "builderID": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("builderID")) + data, err := ec.unmarshalOID2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.BuilderID = data + case "builderInput": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("builderInput")) + data, err := ec.unmarshalOBuilderInputSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐBuilderInputSpec(ctx, v) + if err != nil { + return it, err + } + it.BuilderInput = data + } + } + + return it, nil +} + // endregion **************************** input.gotpl ***************************** // region ************************** interface.gotpl *************************** @@ -285,21 +319,26 @@ func (ec *executionContext) marshalNBuilder2ᚖgithubᚗcomᚋguacsecᚋguacᚋp return ec._Builder(ctx, sel, v) } -func (ec *executionContext) unmarshalNBuilderInputSpec2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐBuilderInputSpec(ctx context.Context, v interface{}) (model.BuilderInputSpec, error) { - res, err := ec.unmarshalInputBuilderInputSpec(ctx, v) +func (ec *executionContext) unmarshalNBuilderSpec2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐBuilderSpec(ctx context.Context, v interface{}) (model.BuilderSpec, error) { + res, err := ec.unmarshalInputBuilderSpec(ctx, v) return res, graphql.ErrorOnPath(ctx, err) } -func (ec *executionContext) unmarshalNBuilderInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐBuilderInputSpecᚄ(ctx context.Context, v interface{}) ([]*model.BuilderInputSpec, error) { +func (ec *executionContext) unmarshalNIDorBuilderInput2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorBuilderInput(ctx context.Context, v interface{}) (model.IDorBuilderInput, error) { + res, err := ec.unmarshalInputIDorBuilderInput(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) unmarshalNIDorBuilderInput2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorBuilderInputᚄ(ctx context.Context, v interface{}) ([]*model.IDorBuilderInput, error) { var vSlice []interface{} if v != nil { vSlice = graphql.CoerceList(v) } var err error - res := make([]*model.BuilderInputSpec, len(vSlice)) + res := make([]*model.IDorBuilderInput, len(vSlice)) for i := range vSlice { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) - res[i], err = ec.unmarshalNBuilderInputSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐBuilderInputSpec(ctx, vSlice[i]) + res[i], err = ec.unmarshalNIDorBuilderInput2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorBuilderInput(ctx, vSlice[i]) if err != nil { return nil, err } @@ -307,16 +346,11 @@ func (ec *executionContext) unmarshalNBuilderInputSpec2ᚕᚖgithubᚗcomᚋguac return res, nil } -func (ec *executionContext) unmarshalNBuilderInputSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐBuilderInputSpec(ctx context.Context, v interface{}) (*model.BuilderInputSpec, error) { - res, err := ec.unmarshalInputBuilderInputSpec(ctx, v) +func (ec *executionContext) unmarshalNIDorBuilderInput2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorBuilderInput(ctx context.Context, v interface{}) (*model.IDorBuilderInput, error) { + res, err := ec.unmarshalInputIDorBuilderInput(ctx, v) return &res, graphql.ErrorOnPath(ctx, err) } -func (ec *executionContext) unmarshalNBuilderSpec2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐBuilderSpec(ctx context.Context, v interface{}) (model.BuilderSpec, error) { - res, err := ec.unmarshalInputBuilderSpec(ctx, v) - return res, graphql.ErrorOnPath(ctx, err) -} - func (ec *executionContext) unmarshalOBuilderInputSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐBuilderInputSpec(ctx context.Context, v interface{}) (*model.BuilderInputSpec, error) { if v == nil { return nil, nil @@ -333,4 +367,12 @@ func (ec *executionContext) unmarshalOBuilderSpec2ᚖgithubᚗcomᚋguacsecᚋgu return &res, graphql.ErrorOnPath(ctx, err) } +func (ec *executionContext) unmarshalOIDorBuilderInput2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorBuilderInput(ctx context.Context, v interface{}) (*model.IDorBuilderInput, error) { + if v == nil { + return nil, nil + } + res, err := ec.unmarshalInputIDorBuilderInput(ctx, v) + return &res, graphql.ErrorOnPath(ctx, err) +} + // endregion ***************************** type.gotpl ***************************** diff --git a/pkg/assembler/graphql/generated/certifyBad.generated.go b/pkg/assembler/graphql/generated/certifyBad.generated.go index b4eb0602c4..9a9a98258c 100644 --- a/pkg/assembler/graphql/generated/certifyBad.generated.go +++ b/pkg/assembler/graphql/generated/certifyBad.generated.go @@ -433,21 +433,21 @@ func (ec *executionContext) unmarshalInputPackageSourceOrArtifactInput(ctx conte switch k { case "package": ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("package")) - data, err := ec.unmarshalOPkgInputSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐPkgInputSpec(ctx, v) + data, err := ec.unmarshalOIDorPkgInput2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorPkgInput(ctx, v) if err != nil { return it, err } it.Package = data case "source": ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("source")) - data, err := ec.unmarshalOSourceInputSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐSourceInputSpec(ctx, v) + data, err := ec.unmarshalOIDorSourceInput2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorSourceInput(ctx, v) if err != nil { return it, err } it.Source = data case "artifact": ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("artifact")) - data, err := ec.unmarshalOArtifactInputSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐArtifactInputSpec(ctx, v) + data, err := ec.unmarshalOIDorArtifactInput2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorArtifactInput(ctx, v) if err != nil { return it, err } @@ -474,21 +474,21 @@ func (ec *executionContext) unmarshalInputPackageSourceOrArtifactInputs(ctx cont switch k { case "packages": ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("packages")) - data, err := ec.unmarshalOPkgInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐPkgInputSpecᚄ(ctx, v) + data, err := ec.unmarshalOIDorPkgInput2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorPkgInputᚄ(ctx, v) if err != nil { return it, err } it.Packages = data case "sources": ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("sources")) - data, err := ec.unmarshalOSourceInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐSourceInputSpecᚄ(ctx, v) + data, err := ec.unmarshalOIDorSourceInput2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorSourceInputᚄ(ctx, v) if err != nil { return it, err } it.Sources = data case "artifacts": ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("artifacts")) - data, err := ec.unmarshalOArtifactInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐArtifactInputSpecᚄ(ctx, v) + data, err := ec.unmarshalOIDorArtifactInput2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorArtifactInputᚄ(ctx, v) if err != nil { return it, err } diff --git a/pkg/assembler/graphql/generated/certifyVEXStatement.generated.go b/pkg/assembler/graphql/generated/certifyVEXStatement.generated.go index 33477793ca..af3cb39968 100644 --- a/pkg/assembler/graphql/generated/certifyVEXStatement.generated.go +++ b/pkg/assembler/graphql/generated/certifyVEXStatement.generated.go @@ -558,14 +558,14 @@ func (ec *executionContext) unmarshalInputPackageOrArtifactInput(ctx context.Con switch k { case "package": ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("package")) - data, err := ec.unmarshalOPkgInputSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐPkgInputSpec(ctx, v) + data, err := ec.unmarshalOIDorPkgInput2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorPkgInput(ctx, v) if err != nil { return it, err } it.Package = data case "artifact": ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("artifact")) - data, err := ec.unmarshalOArtifactInputSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐArtifactInputSpec(ctx, v) + data, err := ec.unmarshalOIDorArtifactInput2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorArtifactInput(ctx, v) if err != nil { return it, err } @@ -592,14 +592,14 @@ func (ec *executionContext) unmarshalInputPackageOrArtifactInputs(ctx context.Co switch k { case "packages": ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("packages")) - data, err := ec.unmarshalOPkgInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐPkgInputSpecᚄ(ctx, v) + data, err := ec.unmarshalOIDorPkgInput2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorPkgInputᚄ(ctx, v) if err != nil { return it, err } it.Packages = data case "artifacts": ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("artifacts")) - data, err := ec.unmarshalOArtifactInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐArtifactInputSpecᚄ(ctx, v) + data, err := ec.unmarshalOIDorArtifactInput2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorArtifactInputᚄ(ctx, v) if err != nil { return it, err } diff --git a/pkg/assembler/graphql/generated/isOccurrence.generated.go b/pkg/assembler/graphql/generated/isOccurrence.generated.go index 4d8368cbb7..f8ab0ae087 100644 --- a/pkg/assembler/graphql/generated/isOccurrence.generated.go +++ b/pkg/assembler/graphql/generated/isOccurrence.generated.go @@ -406,14 +406,14 @@ func (ec *executionContext) unmarshalInputPackageOrSourceInput(ctx context.Conte switch k { case "package": ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("package")) - data, err := ec.unmarshalOPkgInputSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐPkgInputSpec(ctx, v) + data, err := ec.unmarshalOIDorPkgInput2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorPkgInput(ctx, v) if err != nil { return it, err } it.Package = data case "source": ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("source")) - data, err := ec.unmarshalOSourceInputSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐSourceInputSpec(ctx, v) + data, err := ec.unmarshalOIDorSourceInput2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorSourceInput(ctx, v) if err != nil { return it, err } @@ -440,14 +440,14 @@ func (ec *executionContext) unmarshalInputPackageOrSourceInputs(ctx context.Cont switch k { case "packages": ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("packages")) - data, err := ec.unmarshalOPkgInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐPkgInputSpecᚄ(ctx, v) + data, err := ec.unmarshalOIDorPkgInput2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorPkgInputᚄ(ctx, v) if err != nil { return it, err } it.Packages = data case "sources": ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("sources")) - data, err := ec.unmarshalOSourceInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐSourceInputSpecᚄ(ctx, v) + data, err := ec.unmarshalOIDorSourceInput2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorSourceInputᚄ(ctx, v) if err != nil { return it, err } diff --git a/pkg/assembler/graphql/generated/license.generated.go b/pkg/assembler/graphql/generated/license.generated.go index eb201878b1..73442b49c0 100644 --- a/pkg/assembler/graphql/generated/license.generated.go +++ b/pkg/assembler/graphql/generated/license.generated.go @@ -190,6 +190,40 @@ func (ec *executionContext) fieldContext_License_listVersion(ctx context.Context // region **************************** input.gotpl ***************************** +func (ec *executionContext) unmarshalInputIDorLicenseInput(ctx context.Context, obj interface{}) (model.IDorLicenseInput, error) { + var it model.IDorLicenseInput + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"licenseID", "licenseInput"} + for _, k := range fieldsInOrder { + v, ok := asMap[k] + if !ok { + continue + } + switch k { + case "licenseID": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("licenseID")) + data, err := ec.unmarshalOID2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.LicenseID = data + case "licenseInput": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("licenseInput")) + data, err := ec.unmarshalOLicenseInputSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐLicenseInputSpec(ctx, v) + if err != nil { + return it, err + } + it.LicenseInput = data + } + } + + return it, nil +} + func (ec *executionContext) unmarshalInputLicenseInputSpec(ctx context.Context, obj interface{}) (model.LicenseInputSpec, error) { var it model.LicenseInputSpec asMap := map[string]interface{}{} @@ -339,6 +373,45 @@ func (ec *executionContext) _License(ctx context.Context, sel ast.SelectionSet, // region ***************************** type.gotpl ***************************** +func (ec *executionContext) unmarshalNIDorLicenseInput2ᚕᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorLicenseInputᚄ(ctx context.Context, v interface{}) ([][]*model.IDorLicenseInput, error) { + var vSlice []interface{} + if v != nil { + vSlice = graphql.CoerceList(v) + } + var err error + res := make([][]*model.IDorLicenseInput, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNIDorLicenseInput2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorLicenseInputᚄ(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) unmarshalNIDorLicenseInput2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorLicenseInputᚄ(ctx context.Context, v interface{}) ([]*model.IDorLicenseInput, error) { + var vSlice []interface{} + if v != nil { + vSlice = graphql.CoerceList(v) + } + var err error + res := make([]*model.IDorLicenseInput, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNIDorLicenseInput2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorLicenseInput(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) unmarshalNIDorLicenseInput2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorLicenseInput(ctx context.Context, v interface{}) (*model.IDorLicenseInput, error) { + res, err := ec.unmarshalInputIDorLicenseInput(ctx, v) + return &res, graphql.ErrorOnPath(ctx, err) +} + func (ec *executionContext) marshalNLicense2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐLicenseᚄ(ctx context.Context, sel ast.SelectionSet, v []*model.License) graphql.Marshaler { ret := make(graphql.Array, len(v)) var wg sync.WaitGroup @@ -393,45 +466,6 @@ func (ec *executionContext) marshalNLicense2ᚖgithubᚗcomᚋguacsecᚋguacᚋp return ec._License(ctx, sel, v) } -func (ec *executionContext) unmarshalNLicenseInputSpec2ᚕᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐLicenseInputSpecᚄ(ctx context.Context, v interface{}) ([][]*model.LicenseInputSpec, error) { - var vSlice []interface{} - if v != nil { - vSlice = graphql.CoerceList(v) - } - var err error - res := make([][]*model.LicenseInputSpec, len(vSlice)) - for i := range vSlice { - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) - res[i], err = ec.unmarshalNLicenseInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐLicenseInputSpecᚄ(ctx, vSlice[i]) - if err != nil { - return nil, err - } - } - return res, nil -} - -func (ec *executionContext) unmarshalNLicenseInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐLicenseInputSpecᚄ(ctx context.Context, v interface{}) ([]*model.LicenseInputSpec, error) { - var vSlice []interface{} - if v != nil { - vSlice = graphql.CoerceList(v) - } - var err error - res := make([]*model.LicenseInputSpec, len(vSlice)) - for i := range vSlice { - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) - res[i], err = ec.unmarshalNLicenseInputSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐLicenseInputSpec(ctx, vSlice[i]) - if err != nil { - return nil, err - } - } - return res, nil -} - -func (ec *executionContext) unmarshalNLicenseInputSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐLicenseInputSpec(ctx context.Context, v interface{}) (*model.LicenseInputSpec, error) { - res, err := ec.unmarshalInputLicenseInputSpec(ctx, v) - return &res, graphql.ErrorOnPath(ctx, err) -} - func (ec *executionContext) unmarshalNLicenseSpec2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐLicenseSpec(ctx context.Context, v interface{}) (model.LicenseSpec, error) { res, err := ec.unmarshalInputLicenseSpec(ctx, v) return res, graphql.ErrorOnPath(ctx, err) @@ -442,6 +476,14 @@ func (ec *executionContext) unmarshalNLicenseSpec2ᚖgithubᚗcomᚋguacsecᚋgu return &res, graphql.ErrorOnPath(ctx, err) } +func (ec *executionContext) unmarshalOIDorLicenseInput2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorLicenseInput(ctx context.Context, v interface{}) (*model.IDorLicenseInput, error) { + if v == nil { + return nil, nil + } + res, err := ec.unmarshalInputIDorLicenseInput(ctx, v) + return &res, graphql.ErrorOnPath(ctx, err) +} + func (ec *executionContext) unmarshalOLicenseInputSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐLicenseInputSpec(ctx context.Context, v interface{}) (*model.LicenseInputSpec, error) { if v == nil { return nil, nil diff --git a/pkg/assembler/graphql/generated/package.generated.go b/pkg/assembler/graphql/generated/package.generated.go index d4de5f1593..57091efcd5 100644 --- a/pkg/assembler/graphql/generated/package.generated.go +++ b/pkg/assembler/graphql/generated/package.generated.go @@ -891,6 +891,61 @@ func (ec *executionContext) fieldContext_PackageVersion_subpath(ctx context.Cont // region **************************** input.gotpl ***************************** +func (ec *executionContext) unmarshalInputIDorPkgInput(ctx context.Context, obj interface{}) (model.IDorPkgInput, error) { + var it model.IDorPkgInput + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"packageTypeID", "packageNamespaceID", "packageNameID", "packageVersionID", "packageInput"} + for _, k := range fieldsInOrder { + v, ok := asMap[k] + if !ok { + continue + } + switch k { + case "packageTypeID": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("packageTypeID")) + data, err := ec.unmarshalOID2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.PackageTypeID = data + case "packageNamespaceID": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("packageNamespaceID")) + data, err := ec.unmarshalOID2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.PackageNamespaceID = data + case "packageNameID": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("packageNameID")) + data, err := ec.unmarshalOID2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.PackageNameID = data + case "packageVersionID": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("packageVersionID")) + data, err := ec.unmarshalOID2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.PackageVersionID = data + case "packageInput": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("packageInput")) + data, err := ec.unmarshalOPkgInputSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐPkgInputSpec(ctx, v) + if err != nil { + return it, err + } + it.PackageInput = data + } + } + + return it, nil +} + func (ec *executionContext) unmarshalInputPackageQualifierInputSpec(ctx context.Context, obj interface{}) (model.PackageQualifierInputSpec, error) { var it model.PackageQualifierInputSpec asMap := map[string]interface{}{} @@ -1464,6 +1519,33 @@ func (ec *executionContext) _PackageVersion(ctx context.Context, sel ast.Selecti // region ***************************** type.gotpl ***************************** +func (ec *executionContext) unmarshalNIDorPkgInput2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorPkgInput(ctx context.Context, v interface{}) (model.IDorPkgInput, error) { + res, err := ec.unmarshalInputIDorPkgInput(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) unmarshalNIDorPkgInput2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorPkgInputᚄ(ctx context.Context, v interface{}) ([]*model.IDorPkgInput, error) { + var vSlice []interface{} + if v != nil { + vSlice = graphql.CoerceList(v) + } + var err error + res := make([]*model.IDorPkgInput, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNIDorPkgInput2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorPkgInput(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) unmarshalNIDorPkgInput2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorPkgInput(ctx context.Context, v interface{}) (*model.IDorPkgInput, error) { + res, err := ec.unmarshalInputIDorPkgInput(ctx, v) + return &res, graphql.ErrorOnPath(ctx, err) +} + func (ec *executionContext) marshalNPackage2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐPackageᚄ(ctx context.Context, sel ast.SelectionSet, v []*model.Package) graphql.Marshaler { ret := make(graphql.Array, len(v)) var wg sync.WaitGroup @@ -1802,21 +1884,24 @@ func (ec *executionContext) marshalNPackageVersion2ᚖgithubᚗcomᚋguacsecᚋg return ec._PackageVersion(ctx, sel, v) } -func (ec *executionContext) unmarshalNPkgInputSpec2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐPkgInputSpec(ctx context.Context, v interface{}) (model.PkgInputSpec, error) { - res, err := ec.unmarshalInputPkgInputSpec(ctx, v) +func (ec *executionContext) unmarshalNPkgSpec2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐPkgSpec(ctx context.Context, v interface{}) (model.PkgSpec, error) { + res, err := ec.unmarshalInputPkgSpec(ctx, v) return res, graphql.ErrorOnPath(ctx, err) } -func (ec *executionContext) unmarshalNPkgInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐPkgInputSpecᚄ(ctx context.Context, v interface{}) ([]*model.PkgInputSpec, error) { +func (ec *executionContext) unmarshalOIDorPkgInput2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorPkgInputᚄ(ctx context.Context, v interface{}) ([]*model.IDorPkgInput, error) { + if v == nil { + return nil, nil + } var vSlice []interface{} if v != nil { vSlice = graphql.CoerceList(v) } var err error - res := make([]*model.PkgInputSpec, len(vSlice)) + res := make([]*model.IDorPkgInput, len(vSlice)) for i := range vSlice { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) - res[i], err = ec.unmarshalNPkgInputSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐPkgInputSpec(ctx, vSlice[i]) + res[i], err = ec.unmarshalNIDorPkgInput2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorPkgInput(ctx, vSlice[i]) if err != nil { return nil, err } @@ -1824,16 +1909,14 @@ func (ec *executionContext) unmarshalNPkgInputSpec2ᚕᚖgithubᚗcomᚋguacsec return res, nil } -func (ec *executionContext) unmarshalNPkgInputSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐPkgInputSpec(ctx context.Context, v interface{}) (*model.PkgInputSpec, error) { - res, err := ec.unmarshalInputPkgInputSpec(ctx, v) +func (ec *executionContext) unmarshalOIDorPkgInput2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorPkgInput(ctx context.Context, v interface{}) (*model.IDorPkgInput, error) { + if v == nil { + return nil, nil + } + res, err := ec.unmarshalInputIDorPkgInput(ctx, v) return &res, graphql.ErrorOnPath(ctx, err) } -func (ec *executionContext) unmarshalNPkgSpec2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐPkgSpec(ctx context.Context, v interface{}) (model.PkgSpec, error) { - res, err := ec.unmarshalInputPkgSpec(ctx, v) - return res, graphql.ErrorOnPath(ctx, err) -} - func (ec *executionContext) unmarshalOPackageQualifierInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐPackageQualifierInputSpecᚄ(ctx context.Context, v interface{}) ([]*model.PackageQualifierInputSpec, error) { if v == nil { return nil, nil @@ -1874,26 +1957,6 @@ func (ec *executionContext) unmarshalOPackageQualifierSpec2ᚕᚖgithubᚗcomᚋ return res, nil } -func (ec *executionContext) unmarshalOPkgInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐPkgInputSpecᚄ(ctx context.Context, v interface{}) ([]*model.PkgInputSpec, error) { - if v == nil { - return nil, nil - } - var vSlice []interface{} - if v != nil { - vSlice = graphql.CoerceList(v) - } - var err error - res := make([]*model.PkgInputSpec, len(vSlice)) - for i := range vSlice { - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) - res[i], err = ec.unmarshalNPkgInputSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐPkgInputSpec(ctx, vSlice[i]) - if err != nil { - return nil, err - } - } - return res, nil -} - func (ec *executionContext) unmarshalOPkgInputSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐPkgInputSpec(ctx context.Context, v interface{}) (*model.PkgInputSpec, error) { if v == nil { return nil, nil diff --git a/pkg/assembler/graphql/generated/root_.generated.go b/pkg/assembler/graphql/generated/root_.generated.go index e5a471e2af..c8df94c091 100644 --- a/pkg/assembler/graphql/generated/root_.generated.go +++ b/pkg/assembler/graphql/generated/root_.generated.go @@ -190,52 +190,52 @@ type ComplexityRoot struct { } Mutation struct { - IngestArtifact func(childComplexity int, artifact *model.ArtifactInputSpec) int - IngestArtifacts func(childComplexity int, artifacts []*model.ArtifactInputSpec) int - IngestBuilder func(childComplexity int, builder *model.BuilderInputSpec) int - IngestBuilders func(childComplexity int, builders []*model.BuilderInputSpec) int + IngestArtifact func(childComplexity int, artifact *model.IDorArtifactInput) int + IngestArtifacts func(childComplexity int, artifacts []*model.IDorArtifactInput) int + IngestBuilder func(childComplexity int, builder *model.IDorBuilderInput) int + IngestBuilders func(childComplexity int, builders []*model.IDorBuilderInput) int IngestBulkHasMetadata func(childComplexity int, subjects model.PackageSourceOrArtifactInputs, pkgMatchType model.MatchFlags, hasMetadataList []*model.HasMetadataInputSpec) int - IngestBulkVulnerabilityMetadata func(childComplexity int, vulnerabilities []*model.VulnerabilityInputSpec, vulnerabilityMetadataList []*model.VulnerabilityMetadataInputSpec) int + IngestBulkVulnerabilityMetadata func(childComplexity int, vulnerabilities []*model.IDorVulnerabilityInput, vulnerabilityMetadataList []*model.VulnerabilityMetadataInputSpec) int IngestCertifyBad func(childComplexity int, subject model.PackageSourceOrArtifactInput, pkgMatchType model.MatchFlags, certifyBad model.CertifyBadInputSpec) int IngestCertifyBads func(childComplexity int, subjects model.PackageSourceOrArtifactInputs, pkgMatchType model.MatchFlags, certifyBads []*model.CertifyBadInputSpec) int IngestCertifyGood func(childComplexity int, subject model.PackageSourceOrArtifactInput, pkgMatchType model.MatchFlags, certifyGood model.CertifyGoodInputSpec) int IngestCertifyGoods func(childComplexity int, subjects model.PackageSourceOrArtifactInputs, pkgMatchType model.MatchFlags, certifyGoods []*model.CertifyGoodInputSpec) int - IngestCertifyLegal func(childComplexity int, subject model.PackageOrSourceInput, declaredLicenses []*model.LicenseInputSpec, discoveredLicenses []*model.LicenseInputSpec, certifyLegal model.CertifyLegalInputSpec) int - IngestCertifyLegals func(childComplexity int, subjects model.PackageOrSourceInputs, declaredLicensesList [][]*model.LicenseInputSpec, discoveredLicensesList [][]*model.LicenseInputSpec, certifyLegals []*model.CertifyLegalInputSpec) int - IngestCertifyVuln func(childComplexity int, pkg model.PkgInputSpec, vulnerability model.VulnerabilityInputSpec, certifyVuln model.ScanMetadataInput) int - IngestCertifyVulns func(childComplexity int, pkgs []*model.PkgInputSpec, vulnerabilities []*model.VulnerabilityInputSpec, certifyVulns []*model.ScanMetadataInput) int - IngestDependencies func(childComplexity int, pkgs []*model.PkgInputSpec, depPkgs []*model.PkgInputSpec, depPkgMatchType model.MatchFlags, dependencies []*model.IsDependencyInputSpec) int - IngestDependency func(childComplexity int, pkg model.PkgInputSpec, depPkg model.PkgInputSpec, depPkgMatchType model.MatchFlags, dependency model.IsDependencyInputSpec) int + IngestCertifyLegal func(childComplexity int, subject model.PackageOrSourceInput, declaredLicenses []*model.IDorLicenseInput, discoveredLicenses []*model.IDorLicenseInput, certifyLegal model.CertifyLegalInputSpec) int + IngestCertifyLegals func(childComplexity int, subjects model.PackageOrSourceInputs, declaredLicensesList [][]*model.IDorLicenseInput, discoveredLicensesList [][]*model.IDorLicenseInput, certifyLegals []*model.CertifyLegalInputSpec) int + IngestCertifyVuln func(childComplexity int, pkg model.IDorPkgInput, vulnerability model.IDorVulnerabilityInput, certifyVuln model.ScanMetadataInput) int + IngestCertifyVulns func(childComplexity int, pkgs []*model.IDorPkgInput, vulnerabilities []*model.IDorVulnerabilityInput, certifyVulns []*model.ScanMetadataInput) int + IngestDependencies func(childComplexity int, pkgs []*model.IDorPkgInput, depPkgs []*model.IDorPkgInput, depPkgMatchType model.MatchFlags, dependencies []*model.IsDependencyInputSpec) int + IngestDependency func(childComplexity int, pkg model.IDorPkgInput, depPkg model.IDorPkgInput, depPkgMatchType model.MatchFlags, dependency model.IsDependencyInputSpec) int IngestHasMetadata func(childComplexity int, subject model.PackageSourceOrArtifactInput, pkgMatchType model.MatchFlags, hasMetadata model.HasMetadataInputSpec) int IngestHasSBOMs func(childComplexity int, subjects model.PackageOrArtifactInputs, hasSBOMs []*model.HasSBOMInputSpec, includes []*model.HasSBOMIncludesInputSpec) int IngestHasSbom func(childComplexity int, subject model.PackageOrArtifactInput, hasSbom model.HasSBOMInputSpec, includes model.HasSBOMIncludesInputSpec) int - IngestHasSourceAt func(childComplexity int, pkg model.PkgInputSpec, pkgMatchType model.MatchFlags, source model.SourceInputSpec, hasSourceAt model.HasSourceAtInputSpec) int - IngestHasSourceAts func(childComplexity int, pkgs []*model.PkgInputSpec, pkgMatchType model.MatchFlags, sources []*model.SourceInputSpec, hasSourceAts []*model.HasSourceAtInputSpec) int - IngestHashEqual func(childComplexity int, artifact model.ArtifactInputSpec, otherArtifact model.ArtifactInputSpec, hashEqual model.HashEqualInputSpec) int - IngestHashEquals func(childComplexity int, artifacts []*model.ArtifactInputSpec, otherArtifacts []*model.ArtifactInputSpec, hashEquals []*model.HashEqualInputSpec) int - IngestLicense func(childComplexity int, license *model.LicenseInputSpec) int - IngestLicenses func(childComplexity int, licenses []*model.LicenseInputSpec) int - IngestOccurrence func(childComplexity int, subject model.PackageOrSourceInput, artifact model.ArtifactInputSpec, occurrence model.IsOccurrenceInputSpec) int - IngestOccurrences func(childComplexity int, subjects model.PackageOrSourceInputs, artifacts []*model.ArtifactInputSpec, occurrences []*model.IsOccurrenceInputSpec) int - IngestPackage func(childComplexity int, pkg model.PkgInputSpec) int - IngestPackages func(childComplexity int, pkgs []*model.PkgInputSpec) int - IngestPkgEqual func(childComplexity int, pkg model.PkgInputSpec, otherPackage model.PkgInputSpec, pkgEqual model.PkgEqualInputSpec) int - IngestPkgEquals func(childComplexity int, pkgs []*model.PkgInputSpec, otherPackages []*model.PkgInputSpec, pkgEquals []*model.PkgEqualInputSpec) int + IngestHasSourceAt func(childComplexity int, pkg model.IDorPkgInput, pkgMatchType model.MatchFlags, source model.IDorSourceInput, hasSourceAt model.HasSourceAtInputSpec) int + IngestHasSourceAts func(childComplexity int, pkgs []*model.IDorPkgInput, pkgMatchType model.MatchFlags, sources []*model.IDorSourceInput, hasSourceAts []*model.HasSourceAtInputSpec) int + IngestHashEqual func(childComplexity int, artifact model.IDorArtifactInput, otherArtifact model.IDorArtifactInput, hashEqual model.HashEqualInputSpec) int + IngestHashEquals func(childComplexity int, artifacts []*model.IDorArtifactInput, otherArtifacts []*model.IDorArtifactInput, hashEquals []*model.HashEqualInputSpec) int + IngestLicense func(childComplexity int, license *model.IDorLicenseInput) int + IngestLicenses func(childComplexity int, licenses []*model.IDorLicenseInput) int + IngestOccurrence func(childComplexity int, subject model.PackageOrSourceInput, artifact model.IDorArtifactInput, occurrence model.IsOccurrenceInputSpec) int + IngestOccurrences func(childComplexity int, subjects model.PackageOrSourceInputs, artifacts []*model.IDorArtifactInput, occurrences []*model.IsOccurrenceInputSpec) int + IngestPackage func(childComplexity int, pkg model.IDorPkgInput) int + IngestPackages func(childComplexity int, pkgs []*model.IDorPkgInput) int + IngestPkgEqual func(childComplexity int, pkg model.IDorPkgInput, otherPackage model.IDorPkgInput, pkgEqual model.PkgEqualInputSpec) int + IngestPkgEquals func(childComplexity int, pkgs []*model.IDorPkgInput, otherPackages []*model.IDorPkgInput, pkgEquals []*model.PkgEqualInputSpec) int IngestPointOfContact func(childComplexity int, subject model.PackageSourceOrArtifactInput, pkgMatchType model.MatchFlags, pointOfContact model.PointOfContactInputSpec) int IngestPointOfContacts func(childComplexity int, subjects model.PackageSourceOrArtifactInputs, pkgMatchType model.MatchFlags, pointOfContacts []*model.PointOfContactInputSpec) int - IngestSLSAs func(childComplexity int, subjects []*model.ArtifactInputSpec, builtFromList [][]*model.ArtifactInputSpec, builtByList []*model.BuilderInputSpec, slsaList []*model.SLSAInputSpec) int - IngestScorecard func(childComplexity int, source model.SourceInputSpec, scorecard model.ScorecardInputSpec) int - IngestScorecards func(childComplexity int, sources []*model.SourceInputSpec, scorecards []*model.ScorecardInputSpec) int - IngestSlsa func(childComplexity int, subject model.ArtifactInputSpec, builtFrom []*model.ArtifactInputSpec, builtBy model.BuilderInputSpec, slsa model.SLSAInputSpec) int - IngestSource func(childComplexity int, source model.SourceInputSpec) int - IngestSources func(childComplexity int, sources []*model.SourceInputSpec) int - IngestVEXStatement func(childComplexity int, subject model.PackageOrArtifactInput, vulnerability model.VulnerabilityInputSpec, vexStatement model.VexStatementInputSpec) int - IngestVEXStatements func(childComplexity int, subjects model.PackageOrArtifactInputs, vulnerabilities []*model.VulnerabilityInputSpec, vexStatements []*model.VexStatementInputSpec) int - IngestVulnEqual func(childComplexity int, vulnerability model.VulnerabilityInputSpec, otherVulnerability model.VulnerabilityInputSpec, vulnEqual model.VulnEqualInputSpec) int - IngestVulnEquals func(childComplexity int, vulnerabilities []*model.VulnerabilityInputSpec, otherVulnerabilities []*model.VulnerabilityInputSpec, vulnEquals []*model.VulnEqualInputSpec) int - IngestVulnerabilities func(childComplexity int, vulns []*model.VulnerabilityInputSpec) int - IngestVulnerability func(childComplexity int, vuln model.VulnerabilityInputSpec) int - IngestVulnerabilityMetadata func(childComplexity int, vulnerability model.VulnerabilityInputSpec, vulnerabilityMetadata model.VulnerabilityMetadataInputSpec) int + IngestSLSAs func(childComplexity int, subjects []*model.IDorArtifactInput, builtFromList [][]*model.IDorArtifactInput, builtByList []*model.IDorBuilderInput, slsaList []*model.SLSAInputSpec) int + IngestScorecard func(childComplexity int, source model.IDorSourceInput, scorecard model.ScorecardInputSpec) int + IngestScorecards func(childComplexity int, sources []*model.IDorSourceInput, scorecards []*model.ScorecardInputSpec) int + IngestSlsa func(childComplexity int, subject model.IDorArtifactInput, builtFrom []*model.IDorArtifactInput, builtBy model.IDorBuilderInput, slsa model.SLSAInputSpec) int + IngestSource func(childComplexity int, source model.IDorSourceInput) int + IngestSources func(childComplexity int, sources []*model.IDorSourceInput) int + IngestVEXStatement func(childComplexity int, subject model.PackageOrArtifactInput, vulnerability model.IDorVulnerabilityInput, vexStatement model.VexStatementInputSpec) int + IngestVEXStatements func(childComplexity int, subjects model.PackageOrArtifactInputs, vulnerabilities []*model.IDorVulnerabilityInput, vexStatements []*model.VexStatementInputSpec) int + IngestVulnEqual func(childComplexity int, vulnerability model.IDorVulnerabilityInput, otherVulnerability model.IDorVulnerabilityInput, vulnEqual model.VulnEqualInputSpec) int + IngestVulnEquals func(childComplexity int, vulnerabilities []*model.IDorVulnerabilityInput, otherVulnerabilities []*model.IDorVulnerabilityInput, vulnEquals []*model.VulnEqualInputSpec) int + IngestVulnerabilities func(childComplexity int, vulns []*model.IDorVulnerabilityInput) int + IngestVulnerability func(childComplexity int, vuln model.IDorVulnerabilityInput) int + IngestVulnerabilityMetadata func(childComplexity int, vulnerability model.IDorVulnerabilityInput, vulnerabilityMetadata model.VulnerabilityMetadataInputSpec) int } Package struct { @@ -1143,7 +1143,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return 0, false } - return e.complexity.Mutation.IngestArtifact(childComplexity, args["artifact"].(*model.ArtifactInputSpec)), true + return e.complexity.Mutation.IngestArtifact(childComplexity, args["artifact"].(*model.IDorArtifactInput)), true case "Mutation.ingestArtifacts": if e.complexity.Mutation.IngestArtifacts == nil { @@ -1155,7 +1155,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return 0, false } - return e.complexity.Mutation.IngestArtifacts(childComplexity, args["artifacts"].([]*model.ArtifactInputSpec)), true + return e.complexity.Mutation.IngestArtifacts(childComplexity, args["artifacts"].([]*model.IDorArtifactInput)), true case "Mutation.ingestBuilder": if e.complexity.Mutation.IngestBuilder == nil { @@ -1167,7 +1167,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return 0, false } - return e.complexity.Mutation.IngestBuilder(childComplexity, args["builder"].(*model.BuilderInputSpec)), true + return e.complexity.Mutation.IngestBuilder(childComplexity, args["builder"].(*model.IDorBuilderInput)), true case "Mutation.ingestBuilders": if e.complexity.Mutation.IngestBuilders == nil { @@ -1179,7 +1179,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return 0, false } - return e.complexity.Mutation.IngestBuilders(childComplexity, args["builders"].([]*model.BuilderInputSpec)), true + return e.complexity.Mutation.IngestBuilders(childComplexity, args["builders"].([]*model.IDorBuilderInput)), true case "Mutation.ingestBulkHasMetadata": if e.complexity.Mutation.IngestBulkHasMetadata == nil { @@ -1203,7 +1203,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return 0, false } - return e.complexity.Mutation.IngestBulkVulnerabilityMetadata(childComplexity, args["vulnerabilities"].([]*model.VulnerabilityInputSpec), args["vulnerabilityMetadataList"].([]*model.VulnerabilityMetadataInputSpec)), true + return e.complexity.Mutation.IngestBulkVulnerabilityMetadata(childComplexity, args["vulnerabilities"].([]*model.IDorVulnerabilityInput), args["vulnerabilityMetadataList"].([]*model.VulnerabilityMetadataInputSpec)), true case "Mutation.ingestCertifyBad": if e.complexity.Mutation.IngestCertifyBad == nil { @@ -1263,7 +1263,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return 0, false } - return e.complexity.Mutation.IngestCertifyLegal(childComplexity, args["subject"].(model.PackageOrSourceInput), args["declaredLicenses"].([]*model.LicenseInputSpec), args["discoveredLicenses"].([]*model.LicenseInputSpec), args["certifyLegal"].(model.CertifyLegalInputSpec)), true + return e.complexity.Mutation.IngestCertifyLegal(childComplexity, args["subject"].(model.PackageOrSourceInput), args["declaredLicenses"].([]*model.IDorLicenseInput), args["discoveredLicenses"].([]*model.IDorLicenseInput), args["certifyLegal"].(model.CertifyLegalInputSpec)), true case "Mutation.ingestCertifyLegals": if e.complexity.Mutation.IngestCertifyLegals == nil { @@ -1275,7 +1275,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return 0, false } - return e.complexity.Mutation.IngestCertifyLegals(childComplexity, args["subjects"].(model.PackageOrSourceInputs), args["declaredLicensesList"].([][]*model.LicenseInputSpec), args["discoveredLicensesList"].([][]*model.LicenseInputSpec), args["certifyLegals"].([]*model.CertifyLegalInputSpec)), true + return e.complexity.Mutation.IngestCertifyLegals(childComplexity, args["subjects"].(model.PackageOrSourceInputs), args["declaredLicensesList"].([][]*model.IDorLicenseInput), args["discoveredLicensesList"].([][]*model.IDorLicenseInput), args["certifyLegals"].([]*model.CertifyLegalInputSpec)), true case "Mutation.ingestCertifyVuln": if e.complexity.Mutation.IngestCertifyVuln == nil { @@ -1287,7 +1287,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return 0, false } - return e.complexity.Mutation.IngestCertifyVuln(childComplexity, args["pkg"].(model.PkgInputSpec), args["vulnerability"].(model.VulnerabilityInputSpec), args["certifyVuln"].(model.ScanMetadataInput)), true + return e.complexity.Mutation.IngestCertifyVuln(childComplexity, args["pkg"].(model.IDorPkgInput), args["vulnerability"].(model.IDorVulnerabilityInput), args["certifyVuln"].(model.ScanMetadataInput)), true case "Mutation.ingestCertifyVulns": if e.complexity.Mutation.IngestCertifyVulns == nil { @@ -1299,7 +1299,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return 0, false } - return e.complexity.Mutation.IngestCertifyVulns(childComplexity, args["pkgs"].([]*model.PkgInputSpec), args["vulnerabilities"].([]*model.VulnerabilityInputSpec), args["certifyVulns"].([]*model.ScanMetadataInput)), true + return e.complexity.Mutation.IngestCertifyVulns(childComplexity, args["pkgs"].([]*model.IDorPkgInput), args["vulnerabilities"].([]*model.IDorVulnerabilityInput), args["certifyVulns"].([]*model.ScanMetadataInput)), true case "Mutation.ingestDependencies": if e.complexity.Mutation.IngestDependencies == nil { @@ -1311,7 +1311,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return 0, false } - return e.complexity.Mutation.IngestDependencies(childComplexity, args["pkgs"].([]*model.PkgInputSpec), args["depPkgs"].([]*model.PkgInputSpec), args["depPkgMatchType"].(model.MatchFlags), args["dependencies"].([]*model.IsDependencyInputSpec)), true + return e.complexity.Mutation.IngestDependencies(childComplexity, args["pkgs"].([]*model.IDorPkgInput), args["depPkgs"].([]*model.IDorPkgInput), args["depPkgMatchType"].(model.MatchFlags), args["dependencies"].([]*model.IsDependencyInputSpec)), true case "Mutation.ingestDependency": if e.complexity.Mutation.IngestDependency == nil { @@ -1323,7 +1323,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return 0, false } - return e.complexity.Mutation.IngestDependency(childComplexity, args["pkg"].(model.PkgInputSpec), args["depPkg"].(model.PkgInputSpec), args["depPkgMatchType"].(model.MatchFlags), args["dependency"].(model.IsDependencyInputSpec)), true + return e.complexity.Mutation.IngestDependency(childComplexity, args["pkg"].(model.IDorPkgInput), args["depPkg"].(model.IDorPkgInput), args["depPkgMatchType"].(model.MatchFlags), args["dependency"].(model.IsDependencyInputSpec)), true case "Mutation.ingestHasMetadata": if e.complexity.Mutation.IngestHasMetadata == nil { @@ -1371,7 +1371,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return 0, false } - return e.complexity.Mutation.IngestHasSourceAt(childComplexity, args["pkg"].(model.PkgInputSpec), args["pkgMatchType"].(model.MatchFlags), args["source"].(model.SourceInputSpec), args["hasSourceAt"].(model.HasSourceAtInputSpec)), true + return e.complexity.Mutation.IngestHasSourceAt(childComplexity, args["pkg"].(model.IDorPkgInput), args["pkgMatchType"].(model.MatchFlags), args["source"].(model.IDorSourceInput), args["hasSourceAt"].(model.HasSourceAtInputSpec)), true case "Mutation.ingestHasSourceAts": if e.complexity.Mutation.IngestHasSourceAts == nil { @@ -1383,7 +1383,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return 0, false } - return e.complexity.Mutation.IngestHasSourceAts(childComplexity, args["pkgs"].([]*model.PkgInputSpec), args["pkgMatchType"].(model.MatchFlags), args["sources"].([]*model.SourceInputSpec), args["hasSourceAts"].([]*model.HasSourceAtInputSpec)), true + return e.complexity.Mutation.IngestHasSourceAts(childComplexity, args["pkgs"].([]*model.IDorPkgInput), args["pkgMatchType"].(model.MatchFlags), args["sources"].([]*model.IDorSourceInput), args["hasSourceAts"].([]*model.HasSourceAtInputSpec)), true case "Mutation.ingestHashEqual": if e.complexity.Mutation.IngestHashEqual == nil { @@ -1395,7 +1395,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return 0, false } - return e.complexity.Mutation.IngestHashEqual(childComplexity, args["artifact"].(model.ArtifactInputSpec), args["otherArtifact"].(model.ArtifactInputSpec), args["hashEqual"].(model.HashEqualInputSpec)), true + return e.complexity.Mutation.IngestHashEqual(childComplexity, args["artifact"].(model.IDorArtifactInput), args["otherArtifact"].(model.IDorArtifactInput), args["hashEqual"].(model.HashEqualInputSpec)), true case "Mutation.ingestHashEquals": if e.complexity.Mutation.IngestHashEquals == nil { @@ -1407,7 +1407,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return 0, false } - return e.complexity.Mutation.IngestHashEquals(childComplexity, args["artifacts"].([]*model.ArtifactInputSpec), args["otherArtifacts"].([]*model.ArtifactInputSpec), args["hashEquals"].([]*model.HashEqualInputSpec)), true + return e.complexity.Mutation.IngestHashEquals(childComplexity, args["artifacts"].([]*model.IDorArtifactInput), args["otherArtifacts"].([]*model.IDorArtifactInput), args["hashEquals"].([]*model.HashEqualInputSpec)), true case "Mutation.ingestLicense": if e.complexity.Mutation.IngestLicense == nil { @@ -1419,7 +1419,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return 0, false } - return e.complexity.Mutation.IngestLicense(childComplexity, args["license"].(*model.LicenseInputSpec)), true + return e.complexity.Mutation.IngestLicense(childComplexity, args["license"].(*model.IDorLicenseInput)), true case "Mutation.ingestLicenses": if e.complexity.Mutation.IngestLicenses == nil { @@ -1431,7 +1431,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return 0, false } - return e.complexity.Mutation.IngestLicenses(childComplexity, args["licenses"].([]*model.LicenseInputSpec)), true + return e.complexity.Mutation.IngestLicenses(childComplexity, args["licenses"].([]*model.IDorLicenseInput)), true case "Mutation.ingestOccurrence": if e.complexity.Mutation.IngestOccurrence == nil { @@ -1443,7 +1443,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return 0, false } - return e.complexity.Mutation.IngestOccurrence(childComplexity, args["subject"].(model.PackageOrSourceInput), args["artifact"].(model.ArtifactInputSpec), args["occurrence"].(model.IsOccurrenceInputSpec)), true + return e.complexity.Mutation.IngestOccurrence(childComplexity, args["subject"].(model.PackageOrSourceInput), args["artifact"].(model.IDorArtifactInput), args["occurrence"].(model.IsOccurrenceInputSpec)), true case "Mutation.ingestOccurrences": if e.complexity.Mutation.IngestOccurrences == nil { @@ -1455,7 +1455,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return 0, false } - return e.complexity.Mutation.IngestOccurrences(childComplexity, args["subjects"].(model.PackageOrSourceInputs), args["artifacts"].([]*model.ArtifactInputSpec), args["occurrences"].([]*model.IsOccurrenceInputSpec)), true + return e.complexity.Mutation.IngestOccurrences(childComplexity, args["subjects"].(model.PackageOrSourceInputs), args["artifacts"].([]*model.IDorArtifactInput), args["occurrences"].([]*model.IsOccurrenceInputSpec)), true case "Mutation.ingestPackage": if e.complexity.Mutation.IngestPackage == nil { @@ -1467,7 +1467,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return 0, false } - return e.complexity.Mutation.IngestPackage(childComplexity, args["pkg"].(model.PkgInputSpec)), true + return e.complexity.Mutation.IngestPackage(childComplexity, args["pkg"].(model.IDorPkgInput)), true case "Mutation.ingestPackages": if e.complexity.Mutation.IngestPackages == nil { @@ -1479,7 +1479,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return 0, false } - return e.complexity.Mutation.IngestPackages(childComplexity, args["pkgs"].([]*model.PkgInputSpec)), true + return e.complexity.Mutation.IngestPackages(childComplexity, args["pkgs"].([]*model.IDorPkgInput)), true case "Mutation.ingestPkgEqual": if e.complexity.Mutation.IngestPkgEqual == nil { @@ -1491,7 +1491,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return 0, false } - return e.complexity.Mutation.IngestPkgEqual(childComplexity, args["pkg"].(model.PkgInputSpec), args["otherPackage"].(model.PkgInputSpec), args["pkgEqual"].(model.PkgEqualInputSpec)), true + return e.complexity.Mutation.IngestPkgEqual(childComplexity, args["pkg"].(model.IDorPkgInput), args["otherPackage"].(model.IDorPkgInput), args["pkgEqual"].(model.PkgEqualInputSpec)), true case "Mutation.ingestPkgEquals": if e.complexity.Mutation.IngestPkgEquals == nil { @@ -1503,7 +1503,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return 0, false } - return e.complexity.Mutation.IngestPkgEquals(childComplexity, args["pkgs"].([]*model.PkgInputSpec), args["otherPackages"].([]*model.PkgInputSpec), args["pkgEquals"].([]*model.PkgEqualInputSpec)), true + return e.complexity.Mutation.IngestPkgEquals(childComplexity, args["pkgs"].([]*model.IDorPkgInput), args["otherPackages"].([]*model.IDorPkgInput), args["pkgEquals"].([]*model.PkgEqualInputSpec)), true case "Mutation.ingestPointOfContact": if e.complexity.Mutation.IngestPointOfContact == nil { @@ -1539,7 +1539,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return 0, false } - return e.complexity.Mutation.IngestSLSAs(childComplexity, args["subjects"].([]*model.ArtifactInputSpec), args["builtFromList"].([][]*model.ArtifactInputSpec), args["builtByList"].([]*model.BuilderInputSpec), args["slsaList"].([]*model.SLSAInputSpec)), true + return e.complexity.Mutation.IngestSLSAs(childComplexity, args["subjects"].([]*model.IDorArtifactInput), args["builtFromList"].([][]*model.IDorArtifactInput), args["builtByList"].([]*model.IDorBuilderInput), args["slsaList"].([]*model.SLSAInputSpec)), true case "Mutation.ingestScorecard": if e.complexity.Mutation.IngestScorecard == nil { @@ -1551,7 +1551,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return 0, false } - return e.complexity.Mutation.IngestScorecard(childComplexity, args["source"].(model.SourceInputSpec), args["scorecard"].(model.ScorecardInputSpec)), true + return e.complexity.Mutation.IngestScorecard(childComplexity, args["source"].(model.IDorSourceInput), args["scorecard"].(model.ScorecardInputSpec)), true case "Mutation.ingestScorecards": if e.complexity.Mutation.IngestScorecards == nil { @@ -1563,7 +1563,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return 0, false } - return e.complexity.Mutation.IngestScorecards(childComplexity, args["sources"].([]*model.SourceInputSpec), args["scorecards"].([]*model.ScorecardInputSpec)), true + return e.complexity.Mutation.IngestScorecards(childComplexity, args["sources"].([]*model.IDorSourceInput), args["scorecards"].([]*model.ScorecardInputSpec)), true case "Mutation.ingestSLSA": if e.complexity.Mutation.IngestSlsa == nil { @@ -1575,7 +1575,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return 0, false } - return e.complexity.Mutation.IngestSlsa(childComplexity, args["subject"].(model.ArtifactInputSpec), args["builtFrom"].([]*model.ArtifactInputSpec), args["builtBy"].(model.BuilderInputSpec), args["slsa"].(model.SLSAInputSpec)), true + return e.complexity.Mutation.IngestSlsa(childComplexity, args["subject"].(model.IDorArtifactInput), args["builtFrom"].([]*model.IDorArtifactInput), args["builtBy"].(model.IDorBuilderInput), args["slsa"].(model.SLSAInputSpec)), true case "Mutation.ingestSource": if e.complexity.Mutation.IngestSource == nil { @@ -1587,7 +1587,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return 0, false } - return e.complexity.Mutation.IngestSource(childComplexity, args["source"].(model.SourceInputSpec)), true + return e.complexity.Mutation.IngestSource(childComplexity, args["source"].(model.IDorSourceInput)), true case "Mutation.ingestSources": if e.complexity.Mutation.IngestSources == nil { @@ -1599,7 +1599,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return 0, false } - return e.complexity.Mutation.IngestSources(childComplexity, args["sources"].([]*model.SourceInputSpec)), true + return e.complexity.Mutation.IngestSources(childComplexity, args["sources"].([]*model.IDorSourceInput)), true case "Mutation.ingestVEXStatement": if e.complexity.Mutation.IngestVEXStatement == nil { @@ -1611,7 +1611,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return 0, false } - return e.complexity.Mutation.IngestVEXStatement(childComplexity, args["subject"].(model.PackageOrArtifactInput), args["vulnerability"].(model.VulnerabilityInputSpec), args["vexStatement"].(model.VexStatementInputSpec)), true + return e.complexity.Mutation.IngestVEXStatement(childComplexity, args["subject"].(model.PackageOrArtifactInput), args["vulnerability"].(model.IDorVulnerabilityInput), args["vexStatement"].(model.VexStatementInputSpec)), true case "Mutation.ingestVEXStatements": if e.complexity.Mutation.IngestVEXStatements == nil { @@ -1623,7 +1623,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return 0, false } - return e.complexity.Mutation.IngestVEXStatements(childComplexity, args["subjects"].(model.PackageOrArtifactInputs), args["vulnerabilities"].([]*model.VulnerabilityInputSpec), args["vexStatements"].([]*model.VexStatementInputSpec)), true + return e.complexity.Mutation.IngestVEXStatements(childComplexity, args["subjects"].(model.PackageOrArtifactInputs), args["vulnerabilities"].([]*model.IDorVulnerabilityInput), args["vexStatements"].([]*model.VexStatementInputSpec)), true case "Mutation.ingestVulnEqual": if e.complexity.Mutation.IngestVulnEqual == nil { @@ -1635,7 +1635,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return 0, false } - return e.complexity.Mutation.IngestVulnEqual(childComplexity, args["vulnerability"].(model.VulnerabilityInputSpec), args["otherVulnerability"].(model.VulnerabilityInputSpec), args["vulnEqual"].(model.VulnEqualInputSpec)), true + return e.complexity.Mutation.IngestVulnEqual(childComplexity, args["vulnerability"].(model.IDorVulnerabilityInput), args["otherVulnerability"].(model.IDorVulnerabilityInput), args["vulnEqual"].(model.VulnEqualInputSpec)), true case "Mutation.ingestVulnEquals": if e.complexity.Mutation.IngestVulnEquals == nil { @@ -1647,7 +1647,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return 0, false } - return e.complexity.Mutation.IngestVulnEquals(childComplexity, args["vulnerabilities"].([]*model.VulnerabilityInputSpec), args["otherVulnerabilities"].([]*model.VulnerabilityInputSpec), args["vulnEquals"].([]*model.VulnEqualInputSpec)), true + return e.complexity.Mutation.IngestVulnEquals(childComplexity, args["vulnerabilities"].([]*model.IDorVulnerabilityInput), args["otherVulnerabilities"].([]*model.IDorVulnerabilityInput), args["vulnEquals"].([]*model.VulnEqualInputSpec)), true case "Mutation.ingestVulnerabilities": if e.complexity.Mutation.IngestVulnerabilities == nil { @@ -1659,7 +1659,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return 0, false } - return e.complexity.Mutation.IngestVulnerabilities(childComplexity, args["vulns"].([]*model.VulnerabilityInputSpec)), true + return e.complexity.Mutation.IngestVulnerabilities(childComplexity, args["vulns"].([]*model.IDorVulnerabilityInput)), true case "Mutation.ingestVulnerability": if e.complexity.Mutation.IngestVulnerability == nil { @@ -1671,7 +1671,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return 0, false } - return e.complexity.Mutation.IngestVulnerability(childComplexity, args["vuln"].(model.VulnerabilityInputSpec)), true + return e.complexity.Mutation.IngestVulnerability(childComplexity, args["vuln"].(model.IDorVulnerabilityInput)), true case "Mutation.ingestVulnerabilityMetadata": if e.complexity.Mutation.IngestVulnerabilityMetadata == nil { @@ -1683,7 +1683,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return 0, false } - return e.complexity.Mutation.IngestVulnerabilityMetadata(childComplexity, args["vulnerability"].(model.VulnerabilityInputSpec), args["vulnerabilityMetadata"].(model.VulnerabilityMetadataInputSpec)), true + return e.complexity.Mutation.IngestVulnerabilityMetadata(childComplexity, args["vulnerability"].(model.IDorVulnerabilityInput), args["vulnerabilityMetadata"].(model.VulnerabilityMetadataInputSpec)), true case "Package.id": if e.complexity.Package.ID == nil { @@ -2696,6 +2696,12 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { ec.unmarshalInputHasSourceAtSpec, ec.unmarshalInputHashEqualInputSpec, ec.unmarshalInputHashEqualSpec, + ec.unmarshalInputIDorArtifactInput, + ec.unmarshalInputIDorBuilderInput, + ec.unmarshalInputIDorLicenseInput, + ec.unmarshalInputIDorPkgInput, + ec.unmarshalInputIDorSourceInput, + ec.unmarshalInputIDorVulnerabilityInput, ec.unmarshalInputIsDependencyInputSpec, ec.unmarshalInputIsDependencySpec, ec.unmarshalInputIsOccurrenceInputSpec, @@ -2888,16 +2894,28 @@ input ArtifactInputSpec { digest: String! } +""" +IDorArtifactInput allows for specifying either the artifact ID or the ArtifactInputSpec. + +Either the ID or the ArtifactInputSpec must be specified. Both cannot be nil. + +If the ID is specified, the ArtifactInputSpec is not used. +""" +input IDorArtifactInput { + artifactID: ID + artifactInput: ArtifactInputSpec +} + extend type Query { "Returns all artifacts matching a filter." artifacts(artifactSpec: ArtifactSpec!): [Artifact!]! } extend type Mutation { - "Ingests a new artifact and returns it. The returned ID can be empty string." - ingestArtifact(artifact: ArtifactInputSpec): ID! - "Bulk ingests new artifacts and returns a list of them. The returned array of IDs can be a an array of empty string." - ingestArtifacts(artifacts: [ArtifactInputSpec!]!): [ID!]! + "Ingests a new artifact and returns it." + ingestArtifact(artifact: IDorArtifactInput): ID! + "Bulk ingests new artifacts and returns a list of them. The returned array of IDs must be in the same order as the inputs." + ingestArtifacts(artifacts: [IDorArtifactInput!]!): [ID!]! } `, BuiltIn: false}, {Name: "../schema/builder.graphql", Input: `# @@ -2940,16 +2958,28 @@ input BuilderInputSpec { uri: String! } +""" +IDorBuilderInput allows for specifying either the builder ID or the BuilderInputSpec. + +Either the ID or the BuilderInputSpec must be specified. Both cannot be nil. + +If the ID is specified, the BuilderInputSpec is not used. +""" +input IDorBuilderInput { + builderID: ID + builderInput: BuilderInputSpec +} + extend type Query { "Returns all builders matching a filter." builders(builderSpec: BuilderSpec!): [Builder!]! } extend type Mutation { - "Ingests a new builder and returns it. The returned ID can be empty string." - ingestBuilder(builder: BuilderInputSpec): ID! - "Bulk ingests new builders and returns a list of them. The returned array of IDs can be a an array of empty string." - ingestBuilders(builders: [BuilderInputSpec!]!): [ID!]! + "Ingests a new builder and returns it." + ingestBuilder(builder: IDorBuilderInput): ID! + "Bulk ingests new builders and returns a list of them. The returned array of IDs must be in the same order as the inputs." + ingestBuilders(builders: [IDorBuilderInput!]!): [ID!]! } `, BuiltIn: false}, {Name: "../schema/certifyBad.graphql", Input: `# @@ -2993,9 +3023,9 @@ input type to be used in mutations. Exactly one of the value must be set to non-nil. """ input PackageSourceOrArtifactInput { - package: PkgInputSpec - source: SourceInputSpec - artifact: ArtifactInputSpec + package: IDorPkgInput + source: IDorSourceInput + artifact: IDorArtifactInput } """ @@ -3005,9 +3035,9 @@ input type to be used in bulk mutations. Exactly one list must be specified. """ input PackageSourceOrArtifactInputs { - packages: [PkgInputSpec!] - sources: [SourceInputSpec!] - artifacts: [ArtifactInputSpec!] + packages: [IDorPkgInput!] + sources: [IDorSourceInput!] + artifacts: [IDorArtifactInput!] } """ @@ -3295,9 +3325,9 @@ extend type Query { extend type Mutation { "Adds a legal certification to a package or source." - ingestCertifyLegal(subject: PackageOrSourceInput!, declaredLicenses: [LicenseInputSpec!]!, discoveredLicenses: [LicenseInputSpec!]!, certifyLegal: CertifyLegalInputSpec!): ID! + ingestCertifyLegal(subject: PackageOrSourceInput!, declaredLicenses: [IDorLicenseInput!]!, discoveredLicenses: [IDorLicenseInput!]!, certifyLegal: CertifyLegalInputSpec!): ID! "Bulk add legal certifications to packages or sources, not both at same time." - ingestCertifyLegals(subjects: PackageOrSourceInputs!, declaredLicensesList: [[LicenseInputSpec!]!]!, discoveredLicensesList: [[LicenseInputSpec!]!]!, certifyLegals: [CertifyLegalInputSpec!]!): [ID!]! + ingestCertifyLegals(subjects: PackageOrSourceInputs!, declaredLicensesList: [[IDorLicenseInput!]!]!, discoveredLicensesList: [[IDorLicenseInput!]!]!, certifyLegals: [CertifyLegalInputSpec!]!): [ID!]! } `, BuiltIn: false}, {Name: "../schema/certifyScorecard.graphql", Input: `# @@ -3428,10 +3458,10 @@ extend type Query { extend type Mutation { "Adds a certification that a source repository has a Scorecard. The returned ID can be empty string." - ingestScorecard(source: SourceInputSpec!, scorecard: ScorecardInputSpec!): ID! + ingestScorecard(source: IDorSourceInput!, scorecard: ScorecardInputSpec!): ID! "Adds bulk certifications that a source repository has a Scorecard. The returned array of IDs can be a an array of empty string." ingestScorecards( - sources: [SourceInputSpec!]! + sources: [IDorSourceInput!]! scorecards: [ScorecardInputSpec!]! ): [ID!]! } @@ -3476,8 +3506,8 @@ input type to be used in mutations. Exactly one of the value must be set to non-nil. """ input PackageOrArtifactInput { - package: PkgInputSpec - artifact: ArtifactInputSpec + package: IDorPkgInput + artifact: IDorArtifactInput } """ @@ -3485,8 +3515,8 @@ PackageOrArtifactInputs allows using packages and artifacts as input for batch m Exactly one list must be specified. """ input PackageOrArtifactInputs { - packages: [PkgInputSpec!] - artifacts: [ArtifactInputSpec!] + packages: [IDorPkgInput!] + artifacts: [IDorArtifactInput!] } "Records the status of a VEX statement subject." @@ -3576,13 +3606,13 @@ extend type Mutation { "Adds a VEX certification for a package. The returned ID can be empty string." ingestVEXStatement( subject: PackageOrArtifactInput! - vulnerability: VulnerabilityInputSpec! + vulnerability: IDorVulnerabilityInput! vexStatement: VexStatementInputSpec! ): ID! "Bulk add VEX certifications for a package and vulnerability. The returned array of IDs can be a an array of empty string." ingestVEXStatements( subjects: PackageOrArtifactInputs!, - vulnerabilities: [VulnerabilityInputSpec!]!, + vulnerabilities: [IDorVulnerabilityInput!]!, vexStatements: [VexStatementInputSpec!]! ): [ID!]! } @@ -3690,14 +3720,14 @@ extend type Query { extend type Mutation { "Adds a certification that a package has been scanned for vulnerabilities. The returned ID can be empty string." ingestCertifyVuln( - pkg: PkgInputSpec! - vulnerability: VulnerabilityInputSpec! + pkg: IDorPkgInput! + vulnerability: IDorVulnerabilityInput! certifyVuln: ScanMetadataInput! ): ID! "Bulk add certifications that a package has been scanned for vulnerabilities. The returned array of IDs can be a an array of empty string." ingestCertifyVulns( - pkgs: [PkgInputSpec!]! - vulnerabilities: [VulnerabilityInputSpec!]! + pkgs: [IDorPkgInput!]! + vulnerabilities: [IDorVulnerabilityInput!]! certifyVulns: [ScanMetadataInput!]! ): [ID!]! } @@ -4056,16 +4086,16 @@ extend type Query { extend type Mutation { "Ingests a SLSA attestation. The returned ID can be empty string." ingestSLSA( - subject: ArtifactInputSpec! - builtFrom: [ArtifactInputSpec!]! - builtBy: BuilderInputSpec! + subject: IDorArtifactInput! + builtFrom: [IDorArtifactInput!]! + builtBy: IDorBuilderInput! slsa: SLSAInputSpec! ): ID! "Bulk Ingest SLSA attestations. The returned array of IDs can be a an array of empty string." ingestSLSAs( - subjects: [ArtifactInputSpec!]! - builtFromList: [[ArtifactInputSpec!]!]! - builtByList: [BuilderInputSpec!]! + subjects: [IDorArtifactInput!]! + builtFromList: [[IDorArtifactInput!]!]! + builtByList: [IDorBuilderInput!]! slsaList: [SLSAInputSpec!]! ): [ID!]! } @@ -4133,16 +4163,16 @@ extend type Query { extend type Mutation { "Adds a certification that a package (PackageName or PackageVersion) is built from the source. The returned ID can be empty string." ingestHasSourceAt( - pkg: PkgInputSpec! + pkg: IDorPkgInput! pkgMatchType: MatchFlags! - source: SourceInputSpec! + source: IDorSourceInput! hasSourceAt: HasSourceAtInputSpec! ): ID! "Bulk ingestion of certifications that a package (PackageName or PackageVersion) is built from the source. The returned array of IDs can be a an array of empty string." ingestHasSourceAts( - pkgs: [PkgInputSpec!]! + pkgs: [IDorPkgInput!]! pkgMatchType: MatchFlags! - sources: [SourceInputSpec!]! + sources: [IDorSourceInput!]! hasSourceAts: [HasSourceAtInputSpec!]! ):[ID!]! } @@ -4209,14 +4239,14 @@ extend type Query { extend type Mutation { "Adds a certification that two artifacts are equal. The returned ID can be empty string." ingestHashEqual( - artifact: ArtifactInputSpec! - otherArtifact: ArtifactInputSpec! + artifact: IDorArtifactInput! + otherArtifact: IDorArtifactInput! hashEqual: HashEqualInputSpec! ): ID! "Bulk ingest certifications that two artifacts are equal. The returned array of IDs can be a an array of empty string." ingestHashEquals( - artifacts: [ArtifactInputSpec!]! - otherArtifacts: [ArtifactInputSpec!]! + artifacts: [IDorArtifactInput!]! + otherArtifacts: [IDorArtifactInput!]! hashEquals: [HashEqualInputSpec!]! ): [ID!]! } @@ -4304,17 +4334,17 @@ extend type Query { } extend type Mutation { - "Adds a dependency between two packages. The returned ID can be empty string." + "Adds a dependency between two packages. The returned ID cannot be empty string as its used by hasSBOM." ingestDependency( - pkg: PkgInputSpec! - depPkg: PkgInputSpec! + pkg: IDorPkgInput! + depPkg: IDorPkgInput! depPkgMatchType: MatchFlags! dependency: IsDependencyInputSpec! ): ID! - "Bulk adds a dependency between two packages. The returned array of IDs can be a an array of empty string." + "Bulk adds a dependency between two packages. The returned array of IDs cannot be an empty string as its used by hasSBOM." ingestDependencies( - pkgs: [PkgInputSpec!]! - depPkgs: [PkgInputSpec!]! + pkgs: [IDorPkgInput!]! + depPkgs: [IDorPkgInput!]! depPkgMatchType: MatchFlags! dependencies: [IsDependencyInputSpec!]! ): [ID!]! @@ -4358,8 +4388,8 @@ PackageOrSourceInput allows using PackageOrSource union as input for mutations. Exactly one field must be specified. """ input PackageOrSourceInput { - package: PkgInputSpec - source: SourceInputSpec + package: IDorPkgInput + source: IDorSourceInput } """ @@ -4367,8 +4397,8 @@ PackageOrSourceInputs allows using packages and sources as input for batch mutat Exactly one list must be specified. """ input PackageOrSourceInputs { - packages: [PkgInputSpec!] - sources: [SourceInputSpec!] + packages: [IDorPkgInput!] + sources: [IDorSourceInput!] } """ @@ -4416,16 +4446,16 @@ extend type Query { } extend type Mutation { - "Ingest that an artifact is produced from a package or source. The returned ID can be empty string." + "Ingest that an artifact is produced from a package or source. The returned ID cannot be empty string as its used by hasSBOM." ingestOccurrence( subject: PackageOrSourceInput! - artifact: ArtifactInputSpec! + artifact: IDorArtifactInput! occurrence: IsOccurrenceInputSpec! ): ID! - "Bulk ingest that an artifact is produced from a package or source. The returned array of IDs can be a an array of empty string." + "Bulk ingest that an artifact is produced from a package or source. The returned array of IDs cannot be an empty string as its used by hasSBOM" ingestOccurrences( subjects: PackageOrSourceInputs! - artifacts: [ArtifactInputSpec!]! + artifacts: [IDorArtifactInput!]! occurrences: [IsOccurrenceInputSpec!]! ): [ID!]! } @@ -4503,6 +4533,18 @@ input LicenseInputSpec { listVersion: String } +""" +IDorLicenseInput allows for specifying either the license ID or the LicenseInputSpec. + +Either the ID or the LicenseInputSpec must be specified. Both cannot be nil. + +If the ID is specified, the LicenseInputSpec is not used. +""" +input IDorLicenseInput { + licenseID: ID + licenseInput: LicenseInputSpec +} + extend type Query { "Returns all licenses matching a filter." licenses(licenseSpec: LicenseSpec!): [License!]! @@ -4510,9 +4552,9 @@ extend type Query { extend type Mutation { "Ingests a new license and returns it." - ingestLicense(license: LicenseInputSpec): ID! - "Bulk ingests new licenses and returns a list of them." - ingestLicenses(licenses: [LicenseInputSpec!]!): [ID!]! + ingestLicense(license: IDorLicenseInput): ID! + "Bulk ingests new licenses and returns a list of them. The returned array of IDs must be in the same order as the inputs." + ingestLicenses(licenses: [IDorLicenseInput!]!): [ID!]! } `, BuiltIn: false}, {Name: "../schema/metadata.graphql", Input: `# @@ -4808,16 +4850,31 @@ input PackageQualifierInputSpec { value: String! } +""" +IDorPkgInput allows for specifying either the package IDs or the PkgInputSpec. + +Either the IDs or the PkgInputSpec must be specified. Both cannot be nil. + +If the IDs are specified, the PkgInputSpec is not used. +""" +input IDorPkgInput { + packageTypeID: ID + packageNamespaceID: ID + packageNameID: ID + packageVersionID: ID + packageInput: PkgInputSpec +} + extend type Query { "Returns all packages matching a filter." packages(pkgSpec: PkgSpec!): [Package!]! } extend type Mutation { - "Ingests a new package and returns a corresponding package hierarchy containing only the IDs. The returned ID can be empty string." - ingestPackage(pkg: PkgInputSpec!): PackageIDs! - "Bulk ingests packages and returns the list of corresponding package hierarchies containing only the IDs. The returned array of IDs can be empty strings." - ingestPackages(pkgs: [PkgInputSpec!]!): [PackageIDs!]! + "Ingests a new package and returns a corresponding package hierarchy containing only the IDs." + ingestPackage(pkg: IDorPkgInput!): PackageIDs! + "Bulk ingests packages and returns the list of corresponding package hierarchies containing only the IDs. The returned array of IDs must be in the same order as the inputs." + ingestPackages(pkgs: [IDorPkgInput!]!): [PackageIDs!]! } `, BuiltIn: false}, {Name: "../schema/path.graphql", Input: `# @@ -5078,14 +5135,14 @@ extend type Query { extend type Mutation { "Adds a certification that two packages are similar. The returned ID can be empty string." ingestPkgEqual( - pkg: PkgInputSpec! - otherPackage: PkgInputSpec! + pkg: IDorPkgInput! + otherPackage: IDorPkgInput! pkgEqual: PkgEqualInputSpec! ): ID! "Bulk ingest mapping between packages. The returned array of IDs can be a an array of empty string." ingestPkgEquals( - pkgs: [PkgInputSpec!]! - otherPackages: [PkgInputSpec!]! + pkgs: [IDorPkgInput!]! + otherPackages: [IDorPkgInput!]! pkgEquals: [PkgEqualInputSpec!]! ): [ID!]! } @@ -5240,16 +5297,30 @@ input SourceInputSpec { commit: String = "" } +""" +IDorSourceInput allows for specifying either the source IDs or the SourceInputSpec. + +Either the IDs or the SourceInputSpec must be specified. Both cannot be nil. + +If the IDs are specified, the SourceInputSpec is not used. +""" +input IDorSourceInput { + sourceTypeID: ID + sourceNamespaceID: ID + sourceNameID: ID + sourceInput: SourceInputSpec +} + extend type Query { "Returns all sources matching a filter." sources(sourceSpec: SourceSpec!): [Source!]! } extend type Mutation { - "Ingests a new source and returns the corresponding source trie path. The returned ID can be empty string." - ingestSource(source: SourceInputSpec!): SourceIDs! - "Bulk ingests sources and returns the list of corresponding source trie path. The returned array of IDs can be a an array of empty string." - ingestSources(sources: [SourceInputSpec!]!): [SourceIDs!]! + "Ingests a new source and returns the corresponding source trie path." + ingestSource(source: IDorSourceInput!): SourceIDs! + "Bulk ingests sources and returns the list of corresponding source trie path. The returned array of IDs must be in the same order as the inputs." + ingestSources(sources: [IDorSourceInput!]!): [SourceIDs!]! } `, BuiltIn: false}, {Name: "../schema/vulnEqual.graphql", Input: `# @@ -5315,14 +5386,14 @@ extend type Query { extend type Mutation { "Ingest a mapping between vulnerabilities. The returned ID can be empty string." ingestVulnEqual( - vulnerability: VulnerabilityInputSpec! - otherVulnerability: VulnerabilityInputSpec! + vulnerability: IDorVulnerabilityInput! + otherVulnerability: IDorVulnerabilityInput! vulnEqual: VulnEqualInputSpec! ): ID! "Bulk ingest mapping between vulnerabilities. The returned array of IDs can be a an array of empty string." ingestVulnEquals( - vulnerabilities: [VulnerabilityInputSpec!]! - otherVulnerabilities: [VulnerabilityInputSpec!]! + vulnerabilities: [IDorVulnerabilityInput!]! + otherVulnerabilities: [IDorVulnerabilityInput!]! vulnEquals: [VulnEqualInputSpec!]! ): [ID!]! } @@ -5438,9 +5509,9 @@ extend type Query { extend type Mutation { "Adds metadata about a vulnerability. The returned ID can be empty string." - ingestVulnerabilityMetadata(vulnerability: VulnerabilityInputSpec!, vulnerabilityMetadata: VulnerabilityMetadataInputSpec!): ID! + ingestVulnerabilityMetadata(vulnerability: IDorVulnerabilityInput!, vulnerabilityMetadata: VulnerabilityMetadataInputSpec!): ID! "Bulk add certifications that vulnerability has a specific score. The returned array of IDs can be a an array of empty string." - ingestBulkVulnerabilityMetadata(vulnerabilities: [VulnerabilityInputSpec!]!, vulnerabilityMetadataList: [VulnerabilityMetadataInputSpec!]!): [ID!]! + ingestBulkVulnerabilityMetadata(vulnerabilities: [IDorVulnerabilityInput!]!, vulnerabilityMetadataList: [VulnerabilityMetadataInputSpec!]!): [ID!]! } `, BuiltIn: false}, {Name: "../schema/vulnerability.graphql", Input: `# @@ -5547,16 +5618,29 @@ type VulnerabilityIDs { vulnerabilityNodeID: ID! } +""" +IDorVulnerabilityInput allows for specifying either the vulnerability IDs or the VulnerabilityInputSpec. + +Either the IDs or the VulnerabilityInputSpec must be specified. Both cannot be nil. + +If the IDs are specified, the VulnerabilityInputSpec is not used. +""" +input IDorVulnerabilityInput { + vulnerabilityTypeID: ID + vulnerabilityNodeID: ID + vulnerabilityInput: VulnerabilityInputSpec +} + extend type Query { "Returns all vulnerabilities matching a filter." vulnerabilities(vulnSpec: VulnerabilitySpec!): [Vulnerability!]! } extend type Mutation { - "Ingests a new vulnerability and returns the corresponding vulnerability trie path. The returned ID can be empty string." - ingestVulnerability(vuln: VulnerabilityInputSpec!): VulnerabilityIDs! - "Bulk ingests vulnerabilities and returns the list of corresponding vulnerability trie path. The returned array of IDs can be a an array of empty string." - ingestVulnerabilities(vulns: [VulnerabilityInputSpec!]!): [VulnerabilityIDs!]! + "Ingests a new vulnerability and returns the corresponding vulnerability trie path." + ingestVulnerability(vuln: IDorVulnerabilityInput!): VulnerabilityIDs! + "Bulk ingests vulnerabilities and returns the list of corresponding vulnerability trie path. The returned array of IDs must be in the same order as the inputs" + ingestVulnerabilities(vulns: [IDorVulnerabilityInput!]!): [VulnerabilityIDs!]! } `, BuiltIn: false}, } diff --git a/pkg/assembler/graphql/generated/source.generated.go b/pkg/assembler/graphql/generated/source.generated.go index c19ea7c45d..01af450447 100644 --- a/pkg/assembler/graphql/generated/source.generated.go +++ b/pkg/assembler/graphql/generated/source.generated.go @@ -578,6 +578,54 @@ func (ec *executionContext) fieldContext_SourceNamespace_names(ctx context.Conte // region **************************** input.gotpl ***************************** +func (ec *executionContext) unmarshalInputIDorSourceInput(ctx context.Context, obj interface{}) (model.IDorSourceInput, error) { + var it model.IDorSourceInput + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"sourceTypeID", "sourceNamespaceID", "sourceNameID", "sourceInput"} + for _, k := range fieldsInOrder { + v, ok := asMap[k] + if !ok { + continue + } + switch k { + case "sourceTypeID": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("sourceTypeID")) + data, err := ec.unmarshalOID2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.SourceTypeID = data + case "sourceNamespaceID": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("sourceNamespaceID")) + data, err := ec.unmarshalOID2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.SourceNamespaceID = data + case "sourceNameID": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("sourceNameID")) + data, err := ec.unmarshalOID2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.SourceNameID = data + case "sourceInput": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("sourceInput")) + data, err := ec.unmarshalOSourceInputSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐSourceInputSpec(ctx, v) + if err != nil { + return it, err + } + it.SourceInput = data + } + } + + return it, nil +} + func (ec *executionContext) unmarshalInputSourceInputSpec(ctx context.Context, obj interface{}) (model.SourceInputSpec, error) { var it model.SourceInputSpec asMap := map[string]interface{}{} @@ -909,6 +957,33 @@ func (ec *executionContext) _SourceNamespace(ctx context.Context, sel ast.Select // region ***************************** type.gotpl ***************************** +func (ec *executionContext) unmarshalNIDorSourceInput2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorSourceInput(ctx context.Context, v interface{}) (model.IDorSourceInput, error) { + res, err := ec.unmarshalInputIDorSourceInput(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) unmarshalNIDorSourceInput2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorSourceInputᚄ(ctx context.Context, v interface{}) ([]*model.IDorSourceInput, error) { + var vSlice []interface{} + if v != nil { + vSlice = graphql.CoerceList(v) + } + var err error + res := make([]*model.IDorSourceInput, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNIDorSourceInput2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorSourceInput(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) unmarshalNIDorSourceInput2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorSourceInput(ctx context.Context, v interface{}) (*model.IDorSourceInput, error) { + res, err := ec.unmarshalInputIDorSourceInput(ctx, v) + return &res, graphql.ErrorOnPath(ctx, err) +} + func (ec *executionContext) marshalNSource2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐSourceᚄ(ctx context.Context, sel ast.SelectionSet, v []*model.Source) graphql.Marshaler { ret := make(graphql.Array, len(v)) var wg sync.WaitGroup @@ -1021,33 +1096,6 @@ func (ec *executionContext) marshalNSourceIDs2ᚖgithubᚗcomᚋguacsecᚋguac return ec._SourceIDs(ctx, sel, v) } -func (ec *executionContext) unmarshalNSourceInputSpec2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐSourceInputSpec(ctx context.Context, v interface{}) (model.SourceInputSpec, error) { - res, err := ec.unmarshalInputSourceInputSpec(ctx, v) - return res, graphql.ErrorOnPath(ctx, err) -} - -func (ec *executionContext) unmarshalNSourceInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐSourceInputSpecᚄ(ctx context.Context, v interface{}) ([]*model.SourceInputSpec, error) { - var vSlice []interface{} - if v != nil { - vSlice = graphql.CoerceList(v) - } - var err error - res := make([]*model.SourceInputSpec, len(vSlice)) - for i := range vSlice { - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) - res[i], err = ec.unmarshalNSourceInputSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐSourceInputSpec(ctx, vSlice[i]) - if err != nil { - return nil, err - } - } - return res, nil -} - -func (ec *executionContext) unmarshalNSourceInputSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐSourceInputSpec(ctx context.Context, v interface{}) (*model.SourceInputSpec, error) { - res, err := ec.unmarshalInputSourceInputSpec(ctx, v) - return &res, graphql.ErrorOnPath(ctx, err) -} - func (ec *executionContext) marshalNSourceName2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐSourceNameᚄ(ctx context.Context, sel ast.SelectionSet, v []*model.SourceName) graphql.Marshaler { ret := make(graphql.Array, len(v)) var wg sync.WaitGroup @@ -1161,7 +1209,7 @@ func (ec *executionContext) unmarshalNSourceSpec2githubᚗcomᚋguacsecᚋguac return res, graphql.ErrorOnPath(ctx, err) } -func (ec *executionContext) unmarshalOSourceInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐSourceInputSpecᚄ(ctx context.Context, v interface{}) ([]*model.SourceInputSpec, error) { +func (ec *executionContext) unmarshalOIDorSourceInput2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorSourceInputᚄ(ctx context.Context, v interface{}) ([]*model.IDorSourceInput, error) { if v == nil { return nil, nil } @@ -1170,10 +1218,10 @@ func (ec *executionContext) unmarshalOSourceInputSpec2ᚕᚖgithubᚗcomᚋguacs vSlice = graphql.CoerceList(v) } var err error - res := make([]*model.SourceInputSpec, len(vSlice)) + res := make([]*model.IDorSourceInput, len(vSlice)) for i := range vSlice { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) - res[i], err = ec.unmarshalNSourceInputSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐSourceInputSpec(ctx, vSlice[i]) + res[i], err = ec.unmarshalNIDorSourceInput2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorSourceInput(ctx, vSlice[i]) if err != nil { return nil, err } @@ -1181,6 +1229,14 @@ func (ec *executionContext) unmarshalOSourceInputSpec2ᚕᚖgithubᚗcomᚋguacs return res, nil } +func (ec *executionContext) unmarshalOIDorSourceInput2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorSourceInput(ctx context.Context, v interface{}) (*model.IDorSourceInput, error) { + if v == nil { + return nil, nil + } + res, err := ec.unmarshalInputIDorSourceInput(ctx, v) + return &res, graphql.ErrorOnPath(ctx, err) +} + func (ec *executionContext) unmarshalOSourceInputSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐSourceInputSpec(ctx context.Context, v interface{}) (*model.SourceInputSpec, error) { if v == nil { return nil, nil diff --git a/pkg/assembler/graphql/generated/vulnerability.generated.go b/pkg/assembler/graphql/generated/vulnerability.generated.go index 0a1d746f75..4f475b384e 100644 --- a/pkg/assembler/graphql/generated/vulnerability.generated.go +++ b/pkg/assembler/graphql/generated/vulnerability.generated.go @@ -326,6 +326,47 @@ func (ec *executionContext) fieldContext_VulnerabilityIDs_vulnerabilityNodeID(ct // region **************************** input.gotpl ***************************** +func (ec *executionContext) unmarshalInputIDorVulnerabilityInput(ctx context.Context, obj interface{}) (model.IDorVulnerabilityInput, error) { + var it model.IDorVulnerabilityInput + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"vulnerabilityTypeID", "vulnerabilityNodeID", "vulnerabilityInput"} + for _, k := range fieldsInOrder { + v, ok := asMap[k] + if !ok { + continue + } + switch k { + case "vulnerabilityTypeID": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("vulnerabilityTypeID")) + data, err := ec.unmarshalOID2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.VulnerabilityTypeID = data + case "vulnerabilityNodeID": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("vulnerabilityNodeID")) + data, err := ec.unmarshalOID2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.VulnerabilityNodeID = data + case "vulnerabilityInput": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("vulnerabilityInput")) + data, err := ec.unmarshalOVulnerabilityInputSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐVulnerabilityInputSpec(ctx, v) + if err != nil { + return it, err + } + it.VulnerabilityInput = data + } + } + + return it, nil +} + func (ec *executionContext) unmarshalInputVulnerabilityInputSpec(ctx context.Context, obj interface{}) (model.VulnerabilityInputSpec, error) { var it model.VulnerabilityInputSpec asMap := map[string]interface{}{} @@ -557,6 +598,33 @@ func (ec *executionContext) _VulnerabilityIDs(ctx context.Context, sel ast.Selec // region ***************************** type.gotpl ***************************** +func (ec *executionContext) unmarshalNIDorVulnerabilityInput2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorVulnerabilityInput(ctx context.Context, v interface{}) (model.IDorVulnerabilityInput, error) { + res, err := ec.unmarshalInputIDorVulnerabilityInput(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) unmarshalNIDorVulnerabilityInput2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorVulnerabilityInputᚄ(ctx context.Context, v interface{}) ([]*model.IDorVulnerabilityInput, error) { + var vSlice []interface{} + if v != nil { + vSlice = graphql.CoerceList(v) + } + var err error + res := make([]*model.IDorVulnerabilityInput, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNIDorVulnerabilityInput2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorVulnerabilityInput(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) unmarshalNIDorVulnerabilityInput2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐIDorVulnerabilityInput(ctx context.Context, v interface{}) (*model.IDorVulnerabilityInput, error) { + res, err := ec.unmarshalInputIDorVulnerabilityInput(ctx, v) + return &res, graphql.ErrorOnPath(ctx, err) +} + func (ec *executionContext) marshalNVulnerability2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐVulnerabilityᚄ(ctx context.Context, sel ast.SelectionSet, v []*model.Vulnerability) graphql.Marshaler { ret := make(graphql.Array, len(v)) var wg sync.WaitGroup @@ -723,38 +791,19 @@ func (ec *executionContext) marshalNVulnerabilityIDs2ᚖgithubᚗcomᚋguacsec return ec._VulnerabilityIDs(ctx, sel, v) } -func (ec *executionContext) unmarshalNVulnerabilityInputSpec2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐVulnerabilityInputSpec(ctx context.Context, v interface{}) (model.VulnerabilityInputSpec, error) { - res, err := ec.unmarshalInputVulnerabilityInputSpec(ctx, v) +func (ec *executionContext) unmarshalNVulnerabilitySpec2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐVulnerabilitySpec(ctx context.Context, v interface{}) (model.VulnerabilitySpec, error) { + res, err := ec.unmarshalInputVulnerabilitySpec(ctx, v) return res, graphql.ErrorOnPath(ctx, err) } -func (ec *executionContext) unmarshalNVulnerabilityInputSpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐVulnerabilityInputSpecᚄ(ctx context.Context, v interface{}) ([]*model.VulnerabilityInputSpec, error) { - var vSlice []interface{} - if v != nil { - vSlice = graphql.CoerceList(v) - } - var err error - res := make([]*model.VulnerabilityInputSpec, len(vSlice)) - for i := range vSlice { - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) - res[i], err = ec.unmarshalNVulnerabilityInputSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐVulnerabilityInputSpec(ctx, vSlice[i]) - if err != nil { - return nil, err - } +func (ec *executionContext) unmarshalOVulnerabilityInputSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐVulnerabilityInputSpec(ctx context.Context, v interface{}) (*model.VulnerabilityInputSpec, error) { + if v == nil { + return nil, nil } - return res, nil -} - -func (ec *executionContext) unmarshalNVulnerabilityInputSpec2ᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐVulnerabilityInputSpec(ctx context.Context, v interface{}) (*model.VulnerabilityInputSpec, error) { res, err := ec.unmarshalInputVulnerabilityInputSpec(ctx, v) return &res, graphql.ErrorOnPath(ctx, err) } -func (ec *executionContext) unmarshalNVulnerabilitySpec2githubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐVulnerabilitySpec(ctx context.Context, v interface{}) (model.VulnerabilitySpec, error) { - res, err := ec.unmarshalInputVulnerabilitySpec(ctx, v) - return res, graphql.ErrorOnPath(ctx, err) -} - func (ec *executionContext) unmarshalOVulnerabilitySpec2ᚕᚖgithubᚗcomᚋguacsecᚋguacᚋpkgᚋassemblerᚋgraphqlᚋmodelᚐVulnerabilitySpec(ctx context.Context, v interface{}) ([]*model.VulnerabilitySpec, error) { if v == nil { return nil, nil diff --git a/pkg/assembler/graphql/model/nodes.go b/pkg/assembler/graphql/model/nodes.go index 7e51eeada1..43d665fbbd 100644 --- a/pkg/assembler/graphql/model/nodes.go +++ b/pkg/assembler/graphql/model/nodes.go @@ -596,6 +596,72 @@ type HashEqualSpec struct { Collector *string `json:"collector,omitempty"` } +// IDorArtifactInput allows for specifying either the artifact ID or the ArtifactInputSpec. +// +// Either the ID or the ArtifactInputSpec must be specified. Both cannot be nil. +// +// If the ID is specified, the ArtifactInputSpec is not used. +type IDorArtifactInput struct { + ArtifactID *string `json:"artifactID,omitempty"` + ArtifactInput *ArtifactInputSpec `json:"artifactInput,omitempty"` +} + +// IDorBuilderInput allows for specifying either the builder ID or the BuilderInputSpec. +// +// Either the ID or the BuilderInputSpec must be specified. Both cannot be nil. +// +// If the ID is specified, the BuilderInputSpec is not used. +type IDorBuilderInput struct { + BuilderID *string `json:"builderID,omitempty"` + BuilderInput *BuilderInputSpec `json:"builderInput,omitempty"` +} + +// IDorLicenseInput allows for specifying either the license ID or the LicenseInputSpec. +// +// Either the ID or the LicenseInputSpec must be specified. Both cannot be nil. +// +// If the ID is specified, the LicenseInputSpec is not used. +type IDorLicenseInput struct { + LicenseID *string `json:"licenseID,omitempty"` + LicenseInput *LicenseInputSpec `json:"licenseInput,omitempty"` +} + +// IDorPkgInput allows for specifying either the package IDs or the PkgInputSpec. +// +// Either the IDs or the PkgInputSpec must be specified. Both cannot be nil. +// +// If the IDs are specified, the PkgInputSpec is not used. +type IDorPkgInput struct { + PackageTypeID *string `json:"packageTypeID,omitempty"` + PackageNamespaceID *string `json:"packageNamespaceID,omitempty"` + PackageNameID *string `json:"packageNameID,omitempty"` + PackageVersionID *string `json:"packageVersionID,omitempty"` + PackageInput *PkgInputSpec `json:"packageInput,omitempty"` +} + +// IDorSourceInput allows for specifying either the source IDs or the SourceInputSpec. +// +// Either the IDs or the SourceInputSpec must be specified. Both cannot be nil. +// +// If the IDs are specified, the SourceInputSpec is not used. +type IDorSourceInput struct { + SourceTypeID *string `json:"sourceTypeID,omitempty"` + SourceNamespaceID *string `json:"sourceNamespaceID,omitempty"` + SourceNameID *string `json:"sourceNameID,omitempty"` + SourceInput *SourceInputSpec `json:"sourceInput,omitempty"` +} + +// IDorVulnerabilityInput allows for specifying either the vulnerability IDs or the VulnerabilityInputSpec. +// +// Either the IDs or the VulnerabilityInputSpec must be specified. Both cannot be nil. +// +// If the IDs are specified, the VulnerabilityInputSpec is not used. +type IDorVulnerabilityInput struct { + VulnerabilityTypeID *string `json:"vulnerabilityTypeID,omitempty"` + VulnerabilityNodeID *string `json:"vulnerabilityNodeID,omitempty"` + VulnerabilityInput *VulnerabilityInputSpec `json:"vulnerabilityInput,omitempty"` +} + // IsDependency is an attestation to record that a package depends on another. type IsDependency struct { ID string `json:"id"` @@ -736,6 +802,9 @@ type MatchFlags struct { Pkg PkgMatchType `json:"pkg"` } +type Mutation struct { +} + // Package represents the root of the package trie/tree. // // We map package information to a trie, closely matching the pURL specification @@ -805,15 +874,15 @@ type PackageNamespace struct { // // Exactly one of the value must be set to non-nil. type PackageOrArtifactInput struct { - Package *PkgInputSpec `json:"package,omitempty"` - Artifact *ArtifactInputSpec `json:"artifact,omitempty"` + Package *IDorPkgInput `json:"package,omitempty"` + Artifact *IDorArtifactInput `json:"artifact,omitempty"` } // PackageOrArtifactInputs allows using packages and artifacts as input for batch mutations. // Exactly one list must be specified. type PackageOrArtifactInputs struct { - Packages []*PkgInputSpec `json:"packages,omitempty"` - Artifacts []*ArtifactInputSpec `json:"artifacts,omitempty"` + Packages []*IDorPkgInput `json:"packages,omitempty"` + Artifacts []*IDorArtifactInput `json:"artifacts,omitempty"` } // PackageOrArtifactSpec allows using PackageOrArtifact union as @@ -829,15 +898,15 @@ type PackageOrArtifactSpec struct { // // Exactly one field must be specified. type PackageOrSourceInput struct { - Package *PkgInputSpec `json:"package,omitempty"` - Source *SourceInputSpec `json:"source,omitempty"` + Package *IDorPkgInput `json:"package,omitempty"` + Source *IDorSourceInput `json:"source,omitempty"` } // PackageOrSourceInputs allows using packages and sources as input for batch mutations. // Exactly one list must be specified. type PackageOrSourceInputs struct { - Packages []*PkgInputSpec `json:"packages,omitempty"` - Sources []*SourceInputSpec `json:"sources,omitempty"` + Packages []*IDorPkgInput `json:"packages,omitempty"` + Sources []*IDorSourceInput `json:"sources,omitempty"` } // PackageOrSourceSpec allows using PackageOrSource union as input for queries. @@ -885,9 +954,9 @@ type PackageQualifierSpec struct { // // Exactly one of the value must be set to non-nil. type PackageSourceOrArtifactInput struct { - Package *PkgInputSpec `json:"package,omitempty"` - Source *SourceInputSpec `json:"source,omitempty"` - Artifact *ArtifactInputSpec `json:"artifact,omitempty"` + Package *IDorPkgInput `json:"package,omitempty"` + Source *IDorSourceInput `json:"source,omitempty"` + Artifact *IDorArtifactInput `json:"artifact,omitempty"` } // PackageSourceOrArtifactInputs allows using PackageSourceOrArtifact union as @@ -895,9 +964,9 @@ type PackageSourceOrArtifactInput struct { // // Exactly one list must be specified. type PackageSourceOrArtifactInputs struct { - Packages []*PkgInputSpec `json:"packages,omitempty"` - Sources []*SourceInputSpec `json:"sources,omitempty"` - Artifacts []*ArtifactInputSpec `json:"artifacts,omitempty"` + Packages []*IDorPkgInput `json:"packages,omitempty"` + Sources []*IDorSourceInput `json:"sources,omitempty"` + Artifacts []*IDorArtifactInput `json:"artifacts,omitempty"` } // PackageSourceOrArtifactSpec allows using PackageSourceOrArtifact union as @@ -1077,6 +1146,9 @@ type PointOfContactSpec struct { Collector *string `json:"collector,omitempty"` } +type Query struct { +} + // SLSA contains all of the fields present in a SLSA attestation. // // The materials and builders are objects of the HasSLSA predicate, everything diff --git a/pkg/assembler/graphql/resolvers/artifact.resolvers.go b/pkg/assembler/graphql/resolvers/artifact.resolvers.go index 2c039877af..6ef33929f7 100644 --- a/pkg/assembler/graphql/resolvers/artifact.resolvers.go +++ b/pkg/assembler/graphql/resolvers/artifact.resolvers.go @@ -2,7 +2,7 @@ package resolvers // This file will be automatically regenerated based on the schema, any resolver implementations // will be copied through when generating and any unknown code will be moved to the end. -// Code generated by github.com/99designs/gqlgen version v0.17.41 +// Code generated by github.com/99designs/gqlgen version v0.17.43 import ( "context" @@ -12,12 +12,12 @@ import ( ) // IngestArtifact is the resolver for the ingestArtifact field. -func (r *mutationResolver) IngestArtifact(ctx context.Context, artifact *model.ArtifactInputSpec) (string, error) { +func (r *mutationResolver) IngestArtifact(ctx context.Context, artifact *model.IDorArtifactInput) (string, error) { return r.Backend.IngestArtifact(ctx, artifact) } // IngestArtifacts is the resolver for the ingestArtifacts field. -func (r *mutationResolver) IngestArtifacts(ctx context.Context, artifacts []*model.ArtifactInputSpec) ([]string, error) { +func (r *mutationResolver) IngestArtifacts(ctx context.Context, artifacts []*model.IDorArtifactInput) ([]string, error) { return r.Backend.IngestArtifacts(ctx, artifacts) } diff --git a/pkg/assembler/graphql/resolvers/builder.resolvers.go b/pkg/assembler/graphql/resolvers/builder.resolvers.go index 2d51c0a25d..24a58a78d5 100644 --- a/pkg/assembler/graphql/resolvers/builder.resolvers.go +++ b/pkg/assembler/graphql/resolvers/builder.resolvers.go @@ -2,7 +2,7 @@ package resolvers // This file will be automatically regenerated based on the schema, any resolver implementations // will be copied through when generating and any unknown code will be moved to the end. -// Code generated by github.com/99designs/gqlgen version v0.17.41 +// Code generated by github.com/99designs/gqlgen version v0.17.43 import ( "context" @@ -11,12 +11,12 @@ import ( ) // IngestBuilder is the resolver for the ingestBuilder field. -func (r *mutationResolver) IngestBuilder(ctx context.Context, builder *model.BuilderInputSpec) (string, error) { +func (r *mutationResolver) IngestBuilder(ctx context.Context, builder *model.IDorBuilderInput) (string, error) { return r.Backend.IngestBuilder(ctx, builder) } // IngestBuilders is the resolver for the ingestBuilders field. -func (r *mutationResolver) IngestBuilders(ctx context.Context, builders []*model.BuilderInputSpec) ([]string, error) { +func (r *mutationResolver) IngestBuilders(ctx context.Context, builders []*model.IDorBuilderInput) ([]string, error) { return r.Backend.IngestBuilders(ctx, builders) } diff --git a/pkg/assembler/graphql/resolvers/certifyBad.resolvers.go b/pkg/assembler/graphql/resolvers/certifyBad.resolvers.go index 1d5c70702b..273906efd6 100644 --- a/pkg/assembler/graphql/resolvers/certifyBad.resolvers.go +++ b/pkg/assembler/graphql/resolvers/certifyBad.resolvers.go @@ -2,7 +2,7 @@ package resolvers // This file will be automatically regenerated based on the schema, any resolver implementations // will be copied through when generating and any unknown code will be moved to the end. -// Code generated by github.com/99designs/gqlgen version v0.17.41 +// Code generated by github.com/99designs/gqlgen version v0.17.43 import ( "context" diff --git a/pkg/assembler/graphql/resolvers/certifyBad.resolvers_test.go b/pkg/assembler/graphql/resolvers/certifyBad.resolvers_test.go index 6c9dac57ff..4d71033bd4 100644 --- a/pkg/assembler/graphql/resolvers/certifyBad.resolvers_test.go +++ b/pkg/assembler/graphql/resolvers/certifyBad.resolvers_test.go @@ -46,8 +46,8 @@ func TestIngestCertifyBad(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, - Artifact: testdata.A1, + Source: &model.IDorSourceInput{SourceInput: testdata.S1}, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A1}, }, CB: &model.CertifyBadInputSpec{ Justification: "test justification", @@ -61,7 +61,7 @@ func TestIngestCertifyBad(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, CB: &model.CertifyBadInputSpec{ Justification: "test justification", @@ -116,7 +116,7 @@ func TestIngestCertifyBads(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1, testdata.P2}, + Packages: []*model.IDorPkgInput{{PackageInput: testdata.P1}, {PackageInput: testdata.P2}}, }, Match: model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -135,7 +135,7 @@ func TestIngestCertifyBads(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{testdata.S1, testdata.S2}, + Sources: []*model.IDorSourceInput{{SourceInput: testdata.S1}, {SourceInput: testdata.S2}}, }, CB: []*model.CertifyBadInputSpec{ { @@ -151,7 +151,7 @@ func TestIngestCertifyBads(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInputs{ - Artifacts: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, + Artifacts: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}, {ArtifactInput: testdata.A2}}, }, CB: []*model.CertifyBadInputSpec{ { @@ -167,9 +167,9 @@ func TestIngestCertifyBads(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1}, - Sources: []*model.SourceInputSpec{testdata.S1}, - Artifacts: []*model.ArtifactInputSpec{testdata.A1}, + Packages: []*model.IDorPkgInput{{PackageInput: testdata.P1}}, + Sources: []*model.IDorSourceInput{{SourceInput: testdata.S1}}, + Artifacts: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}}, }, CB: []*model.CertifyBadInputSpec{ { @@ -185,7 +185,7 @@ func TestIngestCertifyBads(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1}, + Packages: []*model.IDorPkgInput{{PackageInput: testdata.P1}}, }, Match: model.MatchFlags{ Pkg: model.PkgMatchTypeAllVersions, diff --git a/pkg/assembler/graphql/resolvers/certifyGood.resolvers.go b/pkg/assembler/graphql/resolvers/certifyGood.resolvers.go index 5d79002c09..2bfb9a14a0 100644 --- a/pkg/assembler/graphql/resolvers/certifyGood.resolvers.go +++ b/pkg/assembler/graphql/resolvers/certifyGood.resolvers.go @@ -2,7 +2,7 @@ package resolvers // This file will be automatically regenerated based on the schema, any resolver implementations // will be copied through when generating and any unknown code will be moved to the end. -// Code generated by github.com/99designs/gqlgen version v0.17.41 +// Code generated by github.com/99designs/gqlgen version v0.17.43 import ( "context" diff --git a/pkg/assembler/graphql/resolvers/certifyGood.resolvers_test.go b/pkg/assembler/graphql/resolvers/certifyGood.resolvers_test.go index 2dc721d559..fa43f43ec5 100644 --- a/pkg/assembler/graphql/resolvers/certifyGood.resolvers_test.go +++ b/pkg/assembler/graphql/resolvers/certifyGood.resolvers_test.go @@ -43,8 +43,8 @@ func TestIngestCertifyGood(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, - Artifact: testdata.A1, + Source: &model.IDorSourceInput{SourceInput: testdata.S1}, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A1}, }, CG: &model.CertifyGoodInputSpec{ Justification: "test justification", @@ -58,7 +58,7 @@ func TestIngestCertifyGood(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, CG: &model.CertifyGoodInputSpec{ Justification: "test justification", @@ -113,7 +113,7 @@ func TestIngestCertifyGoods(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1, testdata.P2}, + Packages: []*model.IDorPkgInput{{PackageInput: testdata.P1}, {PackageInput: testdata.P2}}, }, Match: model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -132,7 +132,7 @@ func TestIngestCertifyGoods(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{testdata.S1, testdata.S2}, + Sources: []*model.IDorSourceInput{{SourceInput: testdata.S1}, {SourceInput: testdata.S2}}, }, CG: []*model.CertifyGoodInputSpec{ { @@ -148,7 +148,7 @@ func TestIngestCertifyGoods(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInputs{ - Artifacts: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, + Artifacts: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}, {ArtifactInput: testdata.A2}}, }, CG: []*model.CertifyGoodInputSpec{ { @@ -164,9 +164,9 @@ func TestIngestCertifyGoods(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1}, - Sources: []*model.SourceInputSpec{testdata.S1}, - Artifacts: []*model.ArtifactInputSpec{testdata.A1}, + Packages: []*model.IDorPkgInput{{PackageInput: testdata.P1}}, + Sources: []*model.IDorSourceInput{{SourceInput: testdata.S1}}, + Artifacts: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}}, }, CG: []*model.CertifyGoodInputSpec{ { @@ -182,7 +182,7 @@ func TestIngestCertifyGoods(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1}, + Packages: []*model.IDorPkgInput{{PackageInput: testdata.P1}}, }, Match: model.MatchFlags{ Pkg: model.PkgMatchTypeAllVersions, diff --git a/pkg/assembler/graphql/resolvers/certifyLegal.resolvers.go b/pkg/assembler/graphql/resolvers/certifyLegal.resolvers.go index c620112732..33e3b02acb 100644 --- a/pkg/assembler/graphql/resolvers/certifyLegal.resolvers.go +++ b/pkg/assembler/graphql/resolvers/certifyLegal.resolvers.go @@ -2,7 +2,7 @@ package resolvers // This file will be automatically regenerated based on the schema, any resolver implementations // will be copied through when generating and any unknown code will be moved to the end. -// Code generated by github.com/99designs/gqlgen version v0.17.41 +// Code generated by github.com/99designs/gqlgen version v0.17.43 import ( "context" @@ -13,7 +13,7 @@ import ( ) // IngestCertifyLegal is the resolver for the ingestCertifyLegal field. -func (r *mutationResolver) IngestCertifyLegal(ctx context.Context, subject model.PackageOrSourceInput, declaredLicenses []*model.LicenseInputSpec, discoveredLicenses []*model.LicenseInputSpec, certifyLegal model.CertifyLegalInputSpec) (string, error) { +func (r *mutationResolver) IngestCertifyLegal(ctx context.Context, subject model.PackageOrSourceInput, declaredLicenses []*model.IDorLicenseInput, discoveredLicenses []*model.IDorLicenseInput, certifyLegal model.CertifyLegalInputSpec) (string, error) { funcName := "IngestCertifyLegal" if err := helper.ValidatePackageOrSourceInput(&subject, funcName); err != nil { return "", gqlerror.Errorf("%v :: %s", funcName, err) @@ -23,7 +23,7 @@ func (r *mutationResolver) IngestCertifyLegal(ctx context.Context, subject model } // IngestCertifyLegals is the resolver for the ingestCertifyLegals field. -func (r *mutationResolver) IngestCertifyLegals(ctx context.Context, subjects model.PackageOrSourceInputs, declaredLicensesList [][]*model.LicenseInputSpec, discoveredLicensesList [][]*model.LicenseInputSpec, certifyLegals []*model.CertifyLegalInputSpec) ([]string, error) { +func (r *mutationResolver) IngestCertifyLegals(ctx context.Context, subjects model.PackageOrSourceInputs, declaredLicensesList [][]*model.IDorLicenseInput, discoveredLicensesList [][]*model.IDorLicenseInput, certifyLegals []*model.CertifyLegalInputSpec) ([]string, error) { funcName := "IngestCertifyLegals" valuesDefined := 0 if (len(certifyLegals) != len(discoveredLicensesList)) || diff --git a/pkg/assembler/graphql/resolvers/certifyLegal.resolvers_test.go b/pkg/assembler/graphql/resolvers/certifyLegal.resolvers_test.go index 16a2ace9e9..ad8c6827f1 100644 --- a/pkg/assembler/graphql/resolvers/certifyLegal.resolvers_test.go +++ b/pkg/assembler/graphql/resolvers/certifyLegal.resolvers_test.go @@ -30,8 +30,8 @@ import ( func TestIngestCertifyLegal(t *testing.T) { type call struct { Sub model.PackageOrSourceInput - Dec []*model.LicenseInputSpec - Dis []*model.LicenseInputSpec + Dec []*model.IDorLicenseInput + Dis []*model.IDorLicenseInput CL *model.CertifyLegalInputSpec } tests := []struct { @@ -43,8 +43,8 @@ func TestIngestCertifyLegal(t *testing.T) { Name: "Ingest with two subjects", Call: call{ Sub: model.PackageOrSourceInput{ - Source: testdata.S1, - Package: testdata.P1, + Source: &model.IDorSourceInput{SourceInput: testdata.S1}, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, CL: &model.CertifyLegalInputSpec{ Justification: "test justification", @@ -56,7 +56,7 @@ func TestIngestCertifyLegal(t *testing.T) { Name: "Happy path", Call: call{ Sub: model.PackageOrSourceInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, CL: &model.CertifyLegalInputSpec{ Justification: "test justification", @@ -94,8 +94,8 @@ func TestIngestCertifyLegal(t *testing.T) { func TestIngestCertifyLegals(t *testing.T) { type call struct { Sub model.PackageOrSourceInputs - Dec [][]*model.LicenseInputSpec - Dis [][]*model.LicenseInputSpec + Dec [][]*model.IDorLicenseInput + Dis [][]*model.IDorLicenseInput CL []*model.CertifyLegalInputSpec } tests := []struct { @@ -107,10 +107,10 @@ func TestIngestCertifyLegals(t *testing.T) { Name: "HappyPath Pkg", Call: call{ Sub: model.PackageOrSourceInputs{ - Packages: []*model.PkgInputSpec{testdata.P1, testdata.P2}, + Packages: []*model.IDorPkgInput{{PackageInput: testdata.P1}, {PackageInput: testdata.P2}}, }, - Dec: [][]*model.LicenseInputSpec{nil, nil}, - Dis: [][]*model.LicenseInputSpec{nil, nil}, + Dec: [][]*model.IDorLicenseInput{nil, nil}, + Dis: [][]*model.IDorLicenseInput{nil, nil}, CL: []*model.CertifyLegalInputSpec{ { Justification: "test justification", @@ -125,10 +125,10 @@ func TestIngestCertifyLegals(t *testing.T) { Name: "HappyPath Src", Call: call{ Sub: model.PackageOrSourceInputs{ - Sources: []*model.SourceInputSpec{testdata.S1, testdata.S2}, + Sources: []*model.IDorSourceInput{{SourceInput: testdata.S1}, {SourceInput: testdata.S2}}, }, - Dec: [][]*model.LicenseInputSpec{nil, nil}, - Dis: [][]*model.LicenseInputSpec{nil, nil}, + Dec: [][]*model.IDorLicenseInput{nil, nil}, + Dis: [][]*model.IDorLicenseInput{nil, nil}, CL: []*model.CertifyLegalInputSpec{ { Justification: "test justification", @@ -143,10 +143,10 @@ func TestIngestCertifyLegals(t *testing.T) { Name: "Ingest with two packages and one CertifyLegal", Call: call{ Sub: model.PackageOrSourceInputs{ - Packages: []*model.PkgInputSpec{testdata.P1, testdata.P2}, + Packages: []*model.IDorPkgInput{{PackageInput: testdata.P1}, {PackageInput: testdata.P2}}, }, - Dec: [][]*model.LicenseInputSpec{nil, nil}, - Dis: [][]*model.LicenseInputSpec{nil, nil}, + Dec: [][]*model.IDorLicenseInput{nil, nil}, + Dis: [][]*model.IDorLicenseInput{nil, nil}, CL: []*model.CertifyLegalInputSpec{ { Justification: "test justification", @@ -159,10 +159,10 @@ func TestIngestCertifyLegals(t *testing.T) { Name: "Ingest with two sources and one CertifyLegal", Call: call{ Sub: model.PackageOrSourceInputs{ - Sources: []*model.SourceInputSpec{testdata.S1, testdata.S2}, + Sources: []*model.IDorSourceInput{{SourceInput: testdata.S1}, {SourceInput: testdata.S2}}, }, - Dec: [][]*model.LicenseInputSpec{nil, nil}, - Dis: [][]*model.LicenseInputSpec{nil, nil}, + Dec: [][]*model.IDorLicenseInput{nil, nil}, + Dis: [][]*model.IDorLicenseInput{nil, nil}, CL: []*model.CertifyLegalInputSpec{ { Justification: "test justification", @@ -175,10 +175,10 @@ func TestIngestCertifyLegals(t *testing.T) { Name: "Ingest with one Dis", Call: call{ Sub: model.PackageOrSourceInputs{ - Packages: []*model.PkgInputSpec{testdata.P1, testdata.P2}, + Packages: []*model.IDorPkgInput{{PackageInput: testdata.P1}, {PackageInput: testdata.P2}}, }, - Dec: [][]*model.LicenseInputSpec{nil, nil}, - Dis: [][]*model.LicenseInputSpec{nil}, + Dec: [][]*model.IDorLicenseInput{nil, nil}, + Dis: [][]*model.IDorLicenseInput{nil}, CL: []*model.CertifyLegalInputSpec{ { Justification: "test justification", @@ -194,11 +194,11 @@ func TestIngestCertifyLegals(t *testing.T) { Name: "Ingest with one package and one source, two everything else", Call: call{ Sub: model.PackageOrSourceInputs{ - Packages: []*model.PkgInputSpec{testdata.P1}, - Sources: []*model.SourceInputSpec{testdata.S1}, + Packages: []*model.IDorPkgInput{{PackageInput: testdata.P1}}, + Sources: []*model.IDorSourceInput{{SourceInput: testdata.S1}}, }, - Dec: [][]*model.LicenseInputSpec{nil, nil}, - Dis: [][]*model.LicenseInputSpec{nil, nil}, + Dec: [][]*model.IDorLicenseInput{nil, nil}, + Dis: [][]*model.IDorLicenseInput{nil, nil}, CL: []*model.CertifyLegalInputSpec{ { Justification: "test justification", diff --git a/pkg/assembler/graphql/resolvers/certifyScorecard.resolvers.go b/pkg/assembler/graphql/resolvers/certifyScorecard.resolvers.go index f65f3f8511..7ff0b828a7 100644 --- a/pkg/assembler/graphql/resolvers/certifyScorecard.resolvers.go +++ b/pkg/assembler/graphql/resolvers/certifyScorecard.resolvers.go @@ -2,7 +2,7 @@ package resolvers // This file will be automatically regenerated based on the schema, any resolver implementations // will be copied through when generating and any unknown code will be moved to the end. -// Code generated by github.com/99designs/gqlgen version v0.17.41 +// Code generated by github.com/99designs/gqlgen version v0.17.43 import ( "context" @@ -12,12 +12,12 @@ import ( ) // IngestScorecard is the resolver for the ingestScorecard field. -func (r *mutationResolver) IngestScorecard(ctx context.Context, source model.SourceInputSpec, scorecard model.ScorecardInputSpec) (string, error) { +func (r *mutationResolver) IngestScorecard(ctx context.Context, source model.IDorSourceInput, scorecard model.ScorecardInputSpec) (string, error) { return r.Backend.IngestScorecard(ctx, source, scorecard) } // IngestScorecards is the resolver for the ingestScorecards field. -func (r *mutationResolver) IngestScorecards(ctx context.Context, sources []*model.SourceInputSpec, scorecards []*model.ScorecardInputSpec) ([]string, error) { +func (r *mutationResolver) IngestScorecards(ctx context.Context, sources []*model.IDorSourceInput, scorecards []*model.ScorecardInputSpec) ([]string, error) { funcName := "IngestScorecards" ingestedScorecardsIDS := []string{} if len(sources) != len(scorecards) { diff --git a/pkg/assembler/graphql/resolvers/certifyScorecard.resolvers_test.go b/pkg/assembler/graphql/resolvers/certifyScorecard.resolvers_test.go index 8b03ffb397..b8bd0ee51e 100644 --- a/pkg/assembler/graphql/resolvers/certifyScorecard.resolvers_test.go +++ b/pkg/assembler/graphql/resolvers/certifyScorecard.resolvers_test.go @@ -28,7 +28,7 @@ import ( func TestIngestScorecards(t *testing.T) { type call struct { - Src []*model.SourceInputSpec + Src []*model.IDorSourceInput SC []*model.ScorecardInputSpec } tests := []struct { @@ -40,7 +40,7 @@ func TestIngestScorecards(t *testing.T) { Name: "Ingest with two sources and one Scorecard", Calls: []call{ { - Src: []*model.SourceInputSpec{testdata.S1, testdata.S2}, + Src: []*model.IDorSourceInput{{SourceInput: testdata.S1}, {SourceInput: testdata.S2}}, SC: []*model.ScorecardInputSpec{ { Origin: "test origin", @@ -55,7 +55,7 @@ func TestIngestScorecards(t *testing.T) { Name: "Happy path", Calls: []call{ { - Src: []*model.SourceInputSpec{testdata.S1}, + Src: []*model.IDorSourceInput{{SourceInput: testdata.S1}}, SC: []*model.ScorecardInputSpec{ { Origin: "test origin", diff --git a/pkg/assembler/graphql/resolvers/certifyVEXStatement.resolvers.go b/pkg/assembler/graphql/resolvers/certifyVEXStatement.resolvers.go index 589d02680a..e32498a178 100644 --- a/pkg/assembler/graphql/resolvers/certifyVEXStatement.resolvers.go +++ b/pkg/assembler/graphql/resolvers/certifyVEXStatement.resolvers.go @@ -2,7 +2,7 @@ package resolvers // This file will be automatically regenerated based on the schema, any resolver implementations // will be copied through when generating and any unknown code will be moved to the end. -// Code generated by github.com/99designs/gqlgen version v0.17.41 +// Code generated by github.com/99designs/gqlgen version v0.17.43 import ( "context" @@ -14,7 +14,7 @@ import ( ) // IngestVEXStatement is the resolver for the ingestVEXStatement field. -func (r *mutationResolver) IngestVEXStatement(ctx context.Context, subject model.PackageOrArtifactInput, vulnerability model.VulnerabilityInputSpec, vexStatement model.VexStatementInputSpec) (string, error) { +func (r *mutationResolver) IngestVEXStatement(ctx context.Context, subject model.PackageOrArtifactInput, vulnerability model.IDorVulnerabilityInput, vexStatement model.VexStatementInputSpec) (string, error) { funcName := "IngestVEXStatement" if err := helper.ValidatePackageOrArtifactInput(&subject, funcName); err != nil { return "", gqlerror.Errorf("%v :: %s", funcName, err) @@ -23,24 +23,28 @@ func (r *mutationResolver) IngestVEXStatement(ctx context.Context, subject model if err != nil { return "", gqlerror.Errorf("%v :: %s", funcName, err) } - err = helper.ValidateNoVul(vulnerability) - if err != nil { - return "", gqlerror.Errorf("%v :: %s", funcName, err) - } - - err = helper.ValidateVulnerabilityIDInputSpec(vulnerability) - if err != nil { - return "", gqlerror.Errorf("%v :: %s", funcName, err) + if vulnerability.VulnerabilityInput != nil { + err = helper.ValidateNoVul(*vulnerability.VulnerabilityInput) + if err != nil { + return "", gqlerror.Errorf("%v :: %s", funcName, err) + } + err = helper.ValidateVulnerabilityIDInputSpec(*vulnerability.VulnerabilityInput) + if err != nil { + return "", gqlerror.Errorf("%v :: %s", funcName, err) + } + // vulnerability input (type and vulnerability ID) will be enforced to be lowercase + return r.Backend.IngestVEXStatement(ctx, subject, model.IDorVulnerabilityInput{ + VulnerabilityTypeID: vulnerability.VulnerabilityTypeID, + VulnerabilityNodeID: vulnerability.VulnerabilityNodeID, + VulnerabilityInput: &model.VulnerabilityInputSpec{Type: strings.ToLower(vulnerability.VulnerabilityInput.Type), VulnerabilityID: strings.ToLower(vulnerability.VulnerabilityInput.VulnerabilityID)}, + }, vexStatement) + } else { + return r.Backend.IngestVEXStatement(ctx, subject, vulnerability, vexStatement) } - - // vulnerability input (type and vulnerability ID) will be enforced to be lowercase - return r.Backend.IngestVEXStatement(ctx, subject, - model.VulnerabilityInputSpec{Type: strings.ToLower(vulnerability.Type), VulnerabilityID: strings.ToLower(vulnerability.VulnerabilityID)}, - vexStatement) } // IngestVEXStatements is the resolver for the ingestVEXStatements field. -func (r *mutationResolver) IngestVEXStatements(ctx context.Context, subjects model.PackageOrArtifactInputs, vulnerabilities []*model.VulnerabilityInputSpec, vexStatements []*model.VexStatementInputSpec) ([]string, error) { +func (r *mutationResolver) IngestVEXStatements(ctx context.Context, subjects model.PackageOrArtifactInputs, vulnerabilities []*model.IDorVulnerabilityInput, vexStatements []*model.VexStatementInputSpec) ([]string, error) { funcName := "IngestVEXStatements" valuesDefined := 0 if len(subjects.Packages) > 0 { @@ -62,26 +66,34 @@ func (r *mutationResolver) IngestVEXStatements(ctx context.Context, subjects mod return []string{}, gqlerror.Errorf("must specify at most packages or artifacts for %v", "IngestVEXStatements") } - var lowercaseVulnInputList []*model.VulnerabilityInputSpec + var lowercaseVulnList []*model.IDorVulnerabilityInput for _, v := range vulnerabilities { - - err := helper.ValidateNoVul(*v) + if v.VulnerabilityInput == nil { + lowercaseVulnList = append(lowercaseVulnList, v) + continue + } + err := helper.ValidateNoVul(*v.VulnerabilityInput) if err != nil { return []string{}, gqlerror.Errorf("%v :: %s", funcName, err) } - err = helper.ValidateVulnerabilityIDInputSpec(*v) + err = helper.ValidateVulnerabilityIDInputSpec(*v.VulnerabilityInput) if err != nil { return []string{}, gqlerror.Errorf("%v :: %s", funcName, err) } lowercaseVulnInput := model.VulnerabilityInputSpec{ - Type: strings.ToLower(v.Type), - VulnerabilityID: strings.ToLower(v.VulnerabilityID), + Type: strings.ToLower(v.VulnerabilityInput.Type), + VulnerabilityID: strings.ToLower(v.VulnerabilityInput.VulnerabilityID), } - lowercaseVulnInputList = append(lowercaseVulnInputList, &lowercaseVulnInput) + + lowercaseVulnList = append(lowercaseVulnList, &model.IDorVulnerabilityInput{ + VulnerabilityTypeID: v.VulnerabilityTypeID, + VulnerabilityNodeID: v.VulnerabilityNodeID, + VulnerabilityInput: &lowercaseVulnInput, + }) } - return r.Backend.IngestVEXStatements(ctx, subjects, lowercaseVulnInputList, vexStatements) + return r.Backend.IngestVEXStatements(ctx, subjects, lowercaseVulnList, vexStatements) } // CertifyVEXStatement is the resolver for the CertifyVEXStatement field. diff --git a/pkg/assembler/graphql/resolvers/certifyVEXStatement.resolvers_test.go b/pkg/assembler/graphql/resolvers/certifyVEXStatement.resolvers_test.go index 74e90f85fc..bcaccdb495 100644 --- a/pkg/assembler/graphql/resolvers/certifyVEXStatement.resolvers_test.go +++ b/pkg/assembler/graphql/resolvers/certifyVEXStatement.resolvers_test.go @@ -31,7 +31,7 @@ import ( func TestIngestVEXStatement(t *testing.T) { type call struct { Sub model.PackageOrArtifactInput - Vuln *model.VulnerabilityInputSpec + Vuln *model.IDorVulnerabilityInput In *model.VexStatementInputSpec } tests := []struct { @@ -44,10 +44,10 @@ func TestIngestVEXStatement(t *testing.T) { Calls: []call{ { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, - Artifact: testdata.A1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A1}, }, - Vuln: testdata.V1, + Vuln: &model.IDorVulnerabilityInput{VulnerabilityInput: testdata.V1}, In: &model.VexStatementInputSpec{ VexJustification: "test justification", KnownSince: time.Unix(1e9, 0), @@ -61,9 +61,9 @@ func TestIngestVEXStatement(t *testing.T) { Calls: []call{ { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, - Vuln: testdata.V1, + Vuln: &model.IDorVulnerabilityInput{VulnerabilityInput: testdata.V1}, In: &model.VexStatementInputSpec{ Status: model.VexStatusNotAffected, VexJustification: model.VexJustificationNotProvided, @@ -77,9 +77,9 @@ func TestIngestVEXStatement(t *testing.T) { Calls: []call{ { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, - Vuln: testdata.V1, + Vuln: &model.IDorVulnerabilityInput{VulnerabilityInput: testdata.V1}, In: &model.VexStatementInputSpec{ Status: model.VexStatusAffected, VexJustification: model.VexJustificationNotProvided, @@ -93,11 +93,11 @@ func TestIngestVEXStatement(t *testing.T) { Calls: []call{ { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, - Vuln: &model.VulnerabilityInputSpec{ + Vuln: &model.IDorVulnerabilityInput{VulnerabilityInput: &model.VulnerabilityInputSpec{ Type: "NoVuln", - }, + }}, In: &model.VexStatementInputSpec{ Status: model.VexStatusAffected, VexJustification: "test justification", @@ -111,12 +111,12 @@ func TestIngestVEXStatement(t *testing.T) { Calls: []call{ { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, - Vuln: &model.VulnerabilityInputSpec{ + Vuln: &model.IDorVulnerabilityInput{VulnerabilityInput: &model.VulnerabilityInputSpec{ Type: "cve", VulnerabilityID: "", - }, + }}, In: &model.VexStatementInputSpec{ Status: model.VexStatusAffected, VexJustification: "test justification", @@ -130,9 +130,9 @@ func TestIngestVEXStatement(t *testing.T) { Calls: []call{ { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, - Vuln: testdata.V1, + Vuln: &model.IDorVulnerabilityInput{VulnerabilityInput: testdata.V1}, In: &model.VexStatementInputSpec{ VexJustification: "test justification", KnownSince: time.Unix(1e9, 0), diff --git a/pkg/assembler/graphql/resolvers/certifyVuln.resolvers.go b/pkg/assembler/graphql/resolvers/certifyVuln.resolvers.go index e8a1b902b8..31e29fb252 100644 --- a/pkg/assembler/graphql/resolvers/certifyVuln.resolvers.go +++ b/pkg/assembler/graphql/resolvers/certifyVuln.resolvers.go @@ -2,7 +2,7 @@ package resolvers // This file will be automatically regenerated based on the schema, any resolver implementations // will be copied through when generating and any unknown code will be moved to the end. -// Code generated by github.com/99designs/gqlgen version v0.17.41 +// Code generated by github.com/99designs/gqlgen version v0.17.43 import ( "context" @@ -14,20 +14,26 @@ import ( ) // IngestCertifyVuln is the resolver for the ingestCertifyVuln field. -func (r *mutationResolver) IngestCertifyVuln(ctx context.Context, pkg model.PkgInputSpec, vulnerability model.VulnerabilityInputSpec, certifyVuln model.ScanMetadataInput) (string, error) { - funcName := "IngestCertifyVuln" - err := helper.ValidateVulnerabilityIDInputSpec(vulnerability) - if err != nil { - return "", gqlerror.Errorf("%v :: %s", funcName, err) - } +func (r *mutationResolver) IngestCertifyVuln(ctx context.Context, pkg model.IDorPkgInput, vulnerability model.IDorVulnerabilityInput, certifyVuln model.ScanMetadataInput) (string, error) { // vulnerability input (type and vulnerability ID) will be enforced to be lowercase - return r.Backend.IngestCertifyVuln(ctx, pkg, - model.VulnerabilityInputSpec{Type: strings.ToLower(vulnerability.Type), VulnerabilityID: strings.ToLower(vulnerability.VulnerabilityID)}, - certifyVuln) + if vulnerability.VulnerabilityInput != nil { + funcName := "IngestCertifyVuln" + err := helper.ValidateVulnerabilityIDInputSpec(*vulnerability.VulnerabilityInput) + if err != nil { + return "", gqlerror.Errorf("%v :: %s", funcName, err) + } + return r.Backend.IngestCertifyVuln(ctx, pkg, model.IDorVulnerabilityInput{ + VulnerabilityTypeID: vulnerability.VulnerabilityTypeID, + VulnerabilityNodeID: vulnerability.VulnerabilityNodeID, + VulnerabilityInput: &model.VulnerabilityInputSpec{Type: strings.ToLower(vulnerability.VulnerabilityInput.Type), VulnerabilityID: strings.ToLower(vulnerability.VulnerabilityInput.VulnerabilityID)}, + }, certifyVuln) + } else { + return r.Backend.IngestCertifyVuln(ctx, pkg, vulnerability, certifyVuln) + } } // IngestCertifyVulns is the resolver for the ingestCertifyVulns field. -func (r *mutationResolver) IngestCertifyVulns(ctx context.Context, pkgs []*model.PkgInputSpec, vulnerabilities []*model.VulnerabilityInputSpec, certifyVulns []*model.ScanMetadataInput) ([]string, error) { +func (r *mutationResolver) IngestCertifyVulns(ctx context.Context, pkgs []*model.IDorPkgInput, vulnerabilities []*model.IDorVulnerabilityInput, certifyVulns []*model.ScanMetadataInput) ([]string, error) { funcName := "IngestCertifyVulns" ingestedCertifyVulnsIDS := []string{} if len(pkgs) != len(vulnerabilities) { @@ -38,21 +44,29 @@ func (r *mutationResolver) IngestCertifyVulns(ctx context.Context, pkgs []*model } // vulnerability input (type and vulnerability ID) will be enforced to be lowercase - var lowercaseVulnInputList []*model.VulnerabilityInputSpec + var lowercaseVulnList []*model.IDorVulnerabilityInput for _, v := range vulnerabilities { - - err := helper.ValidateVulnerabilityIDInputSpec(*v) + if v.VulnerabilityInput == nil { + lowercaseVulnList = append(lowercaseVulnList, v) + continue + } + err := helper.ValidateVulnerabilityIDInputSpec(*v.VulnerabilityInput) if err != nil { return []string{}, gqlerror.Errorf("%v :: %s", funcName, err) } lowercaseVulnInput := model.VulnerabilityInputSpec{ - Type: strings.ToLower(v.Type), - VulnerabilityID: strings.ToLower(v.VulnerabilityID), + Type: strings.ToLower(v.VulnerabilityInput.Type), + VulnerabilityID: strings.ToLower(v.VulnerabilityInput.VulnerabilityID), } - lowercaseVulnInputList = append(lowercaseVulnInputList, &lowercaseVulnInput) + + lowercaseVulnList = append(lowercaseVulnList, &model.IDorVulnerabilityInput{ + VulnerabilityTypeID: v.VulnerabilityTypeID, + VulnerabilityNodeID: v.VulnerabilityNodeID, + VulnerabilityInput: &lowercaseVulnInput, + }) } - return r.Backend.IngestCertifyVulns(ctx, pkgs, lowercaseVulnInputList, certifyVulns) + return r.Backend.IngestCertifyVulns(ctx, pkgs, lowercaseVulnList, certifyVulns) } // CertifyVuln is the resolver for the CertifyVuln field. diff --git a/pkg/assembler/graphql/resolvers/certifyVuln.resolvers_test.go b/pkg/assembler/graphql/resolvers/certifyVuln.resolvers_test.go index b7372065bd..4e50476806 100644 --- a/pkg/assembler/graphql/resolvers/certifyVuln.resolvers_test.go +++ b/pkg/assembler/graphql/resolvers/certifyVuln.resolvers_test.go @@ -31,8 +31,8 @@ var t1, _ = time.Parse(time.RFC3339, "2023-01-01T00:00:00Z") func TestIngestCertifyVulns(t *testing.T) { type call struct { - Pkgs []*model.PkgInputSpec - Vulns []*model.VulnerabilityInputSpec + Pkgs []*model.IDorPkgInput + Vulns []*model.IDorVulnerabilityInput CertifyVulns []*model.ScanMetadataInput } tests := []struct { @@ -44,8 +44,8 @@ func TestIngestCertifyVulns(t *testing.T) { Name: "Ingest without vuln", Calls: []call{ { - Pkgs: []*model.PkgInputSpec{testdata.P2}, - Vulns: []*model.VulnerabilityInputSpec{}, + Pkgs: []*model.IDorPkgInput{{PackageInput: testdata.P2}}, + Vulns: []*model.IDorVulnerabilityInput{}, CertifyVulns: []*model.ScanMetadataInput{{}}, }, }, @@ -55,8 +55,8 @@ func TestIngestCertifyVulns(t *testing.T) { Name: "Ingest missing pkg", Calls: []call{ { - Pkgs: []*model.PkgInputSpec{}, - Vulns: []*model.VulnerabilityInputSpec{}, + Pkgs: []*model.IDorPkgInput{}, + Vulns: []*model.IDorVulnerabilityInput{}, CertifyVulns: []*model.ScanMetadataInput{{}}, }, }, @@ -66,13 +66,12 @@ func TestIngestCertifyVulns(t *testing.T) { Name: "Ingest vulnerability cve with novulnID", Calls: []call{ { - Pkgs: []*model.PkgInputSpec{testdata.P2}, - Vulns: []*model.VulnerabilityInputSpec{ - { + Pkgs: []*model.IDorPkgInput{{PackageInput: testdata.P2}}, + Vulns: []*model.IDorVulnerabilityInput{{ + VulnerabilityInput: &model.VulnerabilityInputSpec{ Type: "cve", - VulnerabilityID: "", - }, - }, + VulnerabilityID: ""}, + }}, CertifyVulns: []*model.ScanMetadataInput{{}}, }, }, @@ -82,8 +81,8 @@ func TestIngestCertifyVulns(t *testing.T) { Name: "Happy path", Calls: []call{ { - Pkgs: []*model.PkgInputSpec{testdata.P2, testdata.P1}, - Vulns: []*model.VulnerabilityInputSpec{testdata.C1, testdata.C2}, + Pkgs: []*model.IDorPkgInput{{PackageInput: testdata.P1}, {PackageInput: testdata.P2}}, + Vulns: []*model.IDorVulnerabilityInput{{VulnerabilityInput: testdata.C1}, {VulnerabilityInput: testdata.C2}}, CertifyVulns: []*model.ScanMetadataInput{ { Collector: "test collector", diff --git a/pkg/assembler/graphql/resolvers/contact.resolvers.go b/pkg/assembler/graphql/resolvers/contact.resolvers.go index 221124226e..d534a98216 100644 --- a/pkg/assembler/graphql/resolvers/contact.resolvers.go +++ b/pkg/assembler/graphql/resolvers/contact.resolvers.go @@ -2,7 +2,7 @@ package resolvers // This file will be automatically regenerated based on the schema, any resolver implementations // will be copied through when generating and any unknown code will be moved to the end. -// Code generated by github.com/99designs/gqlgen version v0.17.41 +// Code generated by github.com/99designs/gqlgen version v0.17.43 import ( "context" diff --git a/pkg/assembler/graphql/resolvers/contact.resolvers_test.go b/pkg/assembler/graphql/resolvers/contact.resolvers_test.go index 02c0739be7..fa767b1851 100644 --- a/pkg/assembler/graphql/resolvers/contact.resolvers_test.go +++ b/pkg/assembler/graphql/resolvers/contact.resolvers_test.go @@ -44,8 +44,8 @@ func TestIngestPointOfContact(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, - Artifact: testdata.A1, + Source: &model.IDorSourceInput{SourceInput: testdata.S1}, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A1}, }, HM: &model.PointOfContactInputSpec{ Justification: "test justification", @@ -59,7 +59,7 @@ func TestIngestPointOfContact(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, + Source: &model.IDorSourceInput{SourceInput: testdata.S1}, }, HM: &model.PointOfContactInputSpec{ Justification: "test justification", @@ -113,7 +113,7 @@ func TestIngestPointOfContacts(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1, testdata.P2}, + Packages: []*model.IDorPkgInput{{PackageInput: testdata.P1}, {PackageInput: testdata.P2}}, }, Match: model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -132,7 +132,7 @@ func TestIngestPointOfContacts(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{testdata.S1, testdata.S2}, + Sources: []*model.IDorSourceInput{{SourceInput: testdata.S1}, {SourceInput: testdata.S2}}, }, PC: []*model.PointOfContactInputSpec{ { @@ -148,7 +148,7 @@ func TestIngestPointOfContacts(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInputs{ - Artifacts: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, + Artifacts: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}, {ArtifactInput: testdata.A2}}, }, PC: []*model.PointOfContactInputSpec{ { @@ -164,9 +164,9 @@ func TestIngestPointOfContacts(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1}, - Sources: []*model.SourceInputSpec{testdata.S1}, - Artifacts: []*model.ArtifactInputSpec{testdata.A1}, + Packages: []*model.IDorPkgInput{{PackageInput: testdata.P1}}, + Sources: []*model.IDorSourceInput{{SourceInput: testdata.S1}}, + Artifacts: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}}, }, PC: []*model.PointOfContactInputSpec{ { @@ -182,7 +182,7 @@ func TestIngestPointOfContacts(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1}, + Packages: []*model.IDorPkgInput{{PackageInput: testdata.P1}}, }, Match: model.MatchFlags{ Pkg: model.PkgMatchTypeAllVersions, diff --git a/pkg/assembler/graphql/resolvers/filterDirective.resolver.go b/pkg/assembler/graphql/resolvers/filterDirective.resolver.go index a7f949e9c6..d4a21aa9e8 100644 --- a/pkg/assembler/graphql/resolvers/filterDirective.resolver.go +++ b/pkg/assembler/graphql/resolvers/filterDirective.resolver.go @@ -29,8 +29,7 @@ func worker(ctx context.Context, input reflect.Value, start, end int, keyName, v item := input.Index(i) item, isStruct := isStructOrPointerToStruct(item) found := fieldMatchesRecursive(item, keyName, value, operation) - - + if isStruct && found { resultChan <- item } @@ -45,7 +44,7 @@ func fieldMatchesRecursive(item reflect.Value, keyName, value string, operation for i := 0; i < item.NumField(); i++ { field := item.Field(i) fieldName := item.Type().Field(i).Name - + if isStructPtrField(field) && strings.EqualFold(fieldName, keys[0]) { found = handleStructPtrField(field, keys, value, operation) @@ -57,7 +56,7 @@ func fieldMatchesRecursive(item reflect.Value, keyName, value string, operation } else { found = false } - + } else if isMatchingField(fieldName, keys) { found = handleMatchingField(field, keys, value, operation) } @@ -110,7 +109,7 @@ func handleMatchingField(field reflect.Value, keys []string, value string, opera if strings.HasPrefix(lowercaseFieldValue, lowercaseInputValue) { return true } - } + } } return false @@ -119,7 +118,7 @@ func handleMatchingField(field reflect.Value, keys []string, value string, opera func isStructOrPointerToStruct(v reflect.Value) (reflect.Value, bool) { if v.Kind() == reflect.Ptr { v = v.Elem() - } + } return v, v.Kind() == reflect.Struct } @@ -145,7 +144,7 @@ func Filter(ctx context.Context, obj interface{}, next graphql.Resolver, keyName if err != nil { return nil, err } - + v := reflect.ValueOf(result) if v.Kind() == reflect.Slice && v.Len() > 0 { modelType := v.Index(0).Type().Elem() diff --git a/pkg/assembler/graphql/resolvers/hasSBOM.resolvers.go b/pkg/assembler/graphql/resolvers/hasSBOM.resolvers.go index 0654c4434a..487e01ccd7 100644 --- a/pkg/assembler/graphql/resolvers/hasSBOM.resolvers.go +++ b/pkg/assembler/graphql/resolvers/hasSBOM.resolvers.go @@ -2,7 +2,7 @@ package resolvers // This file will be automatically regenerated based on the schema, any resolver implementations // will be copied through when generating and any unknown code will be moved to the end. -// Code generated by github.com/99designs/gqlgen version v0.17.41 +// Code generated by github.com/99designs/gqlgen version v0.17.43 import ( "context" diff --git a/pkg/assembler/graphql/resolvers/hasSBOM.resolvers_test.go b/pkg/assembler/graphql/resolvers/hasSBOM.resolvers_test.go index c4edeec272..e5ab2a82a2 100644 --- a/pkg/assembler/graphql/resolvers/hasSBOM.resolvers_test.go +++ b/pkg/assembler/graphql/resolvers/hasSBOM.resolvers_test.go @@ -43,8 +43,8 @@ func TestIngestHasSbom(t *testing.T) { Calls: []call{ { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, - Artifact: testdata.A1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A1}, }, HS: &model.HasSBOMInputSpec{ DownloadLocation: "location one", @@ -59,7 +59,7 @@ func TestIngestHasSbom(t *testing.T) { Calls: []call{ { Sub: model.PackageOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, HS: &model.HasSBOMInputSpec{ URI: "test uri", @@ -115,7 +115,7 @@ func TestIngestHasSBOMs(t *testing.T) { Calls: []call{ { Sub: model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1, testdata.P2}, + Packages: []*model.IDorPkgInput{{PackageInput: testdata.P1}, {PackageInput: testdata.P2}}, }, HS: []*model.HasSBOMInputSpec{ { @@ -132,7 +132,7 @@ func TestIngestHasSBOMs(t *testing.T) { Calls: []call{ { Sub: model.PackageOrArtifactInputs{ - Artifacts: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, + Artifacts: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}, {ArtifactInput: testdata.A2}}, }, HS: []*model.HasSBOMInputSpec{ { @@ -149,7 +149,7 @@ func TestIngestHasSBOMs(t *testing.T) { Calls: []call{ { Sub: model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1, testdata.P2}, + Packages: []*model.IDorPkgInput{{PackageInput: testdata.P1}, {PackageInput: testdata.P2}}, }, HS: []*model.HasSBOMInputSpec{ { @@ -166,8 +166,8 @@ func TestIngestHasSBOMs(t *testing.T) { Calls: []call{ { Sub: model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1}, - Artifacts: []*model.ArtifactInputSpec{testdata.A1}, + Packages: []*model.IDorPkgInput{{PackageInput: testdata.P1}}, + Artifacts: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}}, }, HS: []*model.HasSBOMInputSpec{ { @@ -185,7 +185,7 @@ func TestIngestHasSBOMs(t *testing.T) { Calls: []call{ { Sub: model.PackageOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1}, + Packages: []*model.IDorPkgInput{{PackageInput: testdata.P1}}, }, HS: []*model.HasSBOMInputSpec{ { diff --git a/pkg/assembler/graphql/resolvers/hasSLSA.resolvers.go b/pkg/assembler/graphql/resolvers/hasSLSA.resolvers.go index c038b93eb7..594f441e3c 100644 --- a/pkg/assembler/graphql/resolvers/hasSLSA.resolvers.go +++ b/pkg/assembler/graphql/resolvers/hasSLSA.resolvers.go @@ -2,7 +2,7 @@ package resolvers // This file will be automatically regenerated based on the schema, any resolver implementations // will be copied through when generating and any unknown code will be moved to the end. -// Code generated by github.com/99designs/gqlgen version v0.17.41 +// Code generated by github.com/99designs/gqlgen version v0.17.43 import ( "context" @@ -12,7 +12,7 @@ import ( ) // IngestSlsa is the resolver for the ingestSLSA field. -func (r *mutationResolver) IngestSlsa(ctx context.Context, subject model.ArtifactInputSpec, builtFrom []*model.ArtifactInputSpec, builtBy model.BuilderInputSpec, slsa model.SLSAInputSpec) (string, error) { +func (r *mutationResolver) IngestSlsa(ctx context.Context, subject model.IDorArtifactInput, builtFrom []*model.IDorArtifactInput, builtBy model.IDorBuilderInput, slsa model.SLSAInputSpec) (string, error) { if len(builtFrom) < 1 { return "", gqlerror.Errorf("IngestSLSA :: Must have at least 1 builtFrom") } @@ -21,7 +21,7 @@ func (r *mutationResolver) IngestSlsa(ctx context.Context, subject model.Artifac } // IngestSLSAs is the resolver for the ingestSLSAs field. -func (r *mutationResolver) IngestSLSAs(ctx context.Context, subjects []*model.ArtifactInputSpec, builtFromList [][]*model.ArtifactInputSpec, builtByList []*model.BuilderInputSpec, slsaList []*model.SLSAInputSpec) ([]string, error) { +func (r *mutationResolver) IngestSLSAs(ctx context.Context, subjects []*model.IDorArtifactInput, builtFromList [][]*model.IDorArtifactInput, builtByList []*model.IDorBuilderInput, slsaList []*model.SLSAInputSpec) ([]string, error) { funcName := "IngestSLSAs" ingestedSLSAIDS := []string{} if len(subjects) != len(slsaList) { diff --git a/pkg/assembler/graphql/resolvers/hasSLSA.resolvers_test.go b/pkg/assembler/graphql/resolvers/hasSLSA.resolvers_test.go index 2713be37b7..2b5f24cdfd 100644 --- a/pkg/assembler/graphql/resolvers/hasSLSA.resolvers_test.go +++ b/pkg/assembler/graphql/resolvers/hasSLSA.resolvers_test.go @@ -30,9 +30,9 @@ import ( func TestIngestHasSLSA(t *testing.T) { testTime := time.Unix(1e9+5, 0) type call struct { - Sub *model.ArtifactInputSpec - BF []*model.ArtifactInputSpec - BB *model.BuilderInputSpec + Sub *model.IDorArtifactInput + BF []*model.IDorArtifactInput + BB *model.IDorBuilderInput SLSA *model.SLSAInputSpec } tests := []struct { @@ -44,9 +44,9 @@ func TestIngestHasSLSA(t *testing.T) { Name: "Ingest with no builtFrom", Calls: []call{ { - Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{}, - BB: testdata.B1, + Sub: &model.IDorArtifactInput{ArtifactInput: testdata.A1}, + BF: []*model.IDorArtifactInput{}, + BB: &model.IDorBuilderInput{BuilderInput: testdata.B1}, SLSA: &model.SLSAInputSpec{ StartedOn: &testTime, }, @@ -58,9 +58,9 @@ func TestIngestHasSLSA(t *testing.T) { Name: "Happy path", Calls: []call{ { - Sub: testdata.A1, - BF: []*model.ArtifactInputSpec{testdata.A2}, - BB: testdata.B1, + Sub: &model.IDorArtifactInput{ArtifactInput: testdata.A1}, + BF: []*model.IDorArtifactInput{{ArtifactInput: testdata.A2}}, + BB: &model.IDorBuilderInput{BuilderInput: testdata.B1}, SLSA: &model.SLSAInputSpec{ BuildType: "test type", }, @@ -99,9 +99,9 @@ func TestIngestHasSLSA(t *testing.T) { func TestIngestHasSLSAs(t *testing.T) { type call struct { - Sub []*model.ArtifactInputSpec - BF [][]*model.ArtifactInputSpec - BB []*model.BuilderInputSpec + Sub []*model.IDorArtifactInput + BF [][]*model.IDorArtifactInput + BB []*model.IDorBuilderInput SLSA []*model.SLSAInputSpec } tests := []struct { @@ -113,9 +113,9 @@ func TestIngestHasSLSAs(t *testing.T) { Name: "Ingest without slsaList", Calls: []call{ { - Sub: []*model.ArtifactInputSpec{testdata.A1}, - BF: [][]*model.ArtifactInputSpec{{testdata.A2}}, - BB: []*model.BuilderInputSpec{testdata.B1}, + Sub: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}}, + BF: [][]*model.IDorArtifactInput{{{ArtifactInput: testdata.A2}}}, + BB: []*model.IDorBuilderInput{{BuilderInput: testdata.B1}}, SLSA: []*model.SLSAInputSpec{}, }, }, @@ -125,9 +125,9 @@ func TestIngestHasSLSAs(t *testing.T) { Name: "Ingest without builtFrom", Calls: []call{ { - Sub: []*model.ArtifactInputSpec{testdata.A1}, - BF: [][]*model.ArtifactInputSpec{}, - BB: []*model.BuilderInputSpec{testdata.B1}, + Sub: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}}, + BF: [][]*model.IDorArtifactInput{}, + BB: []*model.IDorBuilderInput{{BuilderInput: testdata.B1}}, SLSA: []*model.SLSAInputSpec{ { BuildType: "test type", @@ -141,9 +141,9 @@ func TestIngestHasSLSAs(t *testing.T) { Name: "Ingest without builtByList", Calls: []call{ { - Sub: []*model.ArtifactInputSpec{testdata.A1}, - BF: [][]*model.ArtifactInputSpec{{testdata.A2}}, - BB: []*model.BuilderInputSpec{}, + Sub: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}}, + BF: [][]*model.IDorArtifactInput{{{ArtifactInput: testdata.A2}}}, + BB: []*model.IDorBuilderInput{}, SLSA: []*model.SLSAInputSpec{ { BuildType: "test type", @@ -157,9 +157,9 @@ func TestIngestHasSLSAs(t *testing.T) { Name: "HappyPath", Calls: []call{ { - Sub: []*model.ArtifactInputSpec{testdata.A1}, - BF: [][]*model.ArtifactInputSpec{{testdata.A2}}, - BB: []*model.BuilderInputSpec{testdata.B1}, + Sub: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}}, + BF: [][]*model.IDorArtifactInput{{{ArtifactInput: testdata.A2}}}, + BB: []*model.IDorBuilderInput{{BuilderInput: testdata.B1}}, SLSA: []*model.SLSAInputSpec{ { BuildType: "test type", diff --git a/pkg/assembler/graphql/resolvers/hasSourceAt.resolvers.go b/pkg/assembler/graphql/resolvers/hasSourceAt.resolvers.go index 8bfe3bdc20..40adc141ca 100644 --- a/pkg/assembler/graphql/resolvers/hasSourceAt.resolvers.go +++ b/pkg/assembler/graphql/resolvers/hasSourceAt.resolvers.go @@ -2,7 +2,7 @@ package resolvers // This file will be automatically regenerated based on the schema, any resolver implementations // will be copied through when generating and any unknown code will be moved to the end. -// Code generated by github.com/99designs/gqlgen version v0.17.41 +// Code generated by github.com/99designs/gqlgen version v0.17.43 import ( "context" @@ -12,12 +12,12 @@ import ( ) // IngestHasSourceAt is the resolver for the ingestHasSourceAt field. -func (r *mutationResolver) IngestHasSourceAt(ctx context.Context, pkg model.PkgInputSpec, pkgMatchType model.MatchFlags, source model.SourceInputSpec, hasSourceAt model.HasSourceAtInputSpec) (string, error) { +func (r *mutationResolver) IngestHasSourceAt(ctx context.Context, pkg model.IDorPkgInput, pkgMatchType model.MatchFlags, source model.IDorSourceInput, hasSourceAt model.HasSourceAtInputSpec) (string, error) { return r.Backend.IngestHasSourceAt(ctx, pkg, pkgMatchType, source, hasSourceAt) } // IngestHasSourceAts is the resolver for the ingestHasSourceAts field. -func (r *mutationResolver) IngestHasSourceAts(ctx context.Context, pkgs []*model.PkgInputSpec, pkgMatchType model.MatchFlags, sources []*model.SourceInputSpec, hasSourceAts []*model.HasSourceAtInputSpec) ([]string, error) { +func (r *mutationResolver) IngestHasSourceAts(ctx context.Context, pkgs []*model.IDorPkgInput, pkgMatchType model.MatchFlags, sources []*model.IDorSourceInput, hasSourceAts []*model.HasSourceAtInputSpec) ([]string, error) { funcName := "IngestHasSourceAts" if len(pkgs) != len(sources) { return []string{}, gqlerror.Errorf("%v :: uneven packages and sources for ingestion", funcName) diff --git a/pkg/assembler/graphql/resolvers/hasSourceAt.resolvers_test.go b/pkg/assembler/graphql/resolvers/hasSourceAt.resolvers_test.go index 683c376625..91eab5a38f 100644 --- a/pkg/assembler/graphql/resolvers/hasSourceAt.resolvers_test.go +++ b/pkg/assembler/graphql/resolvers/hasSourceAt.resolvers_test.go @@ -28,9 +28,9 @@ import ( func TestIngestHasSourceAts(t *testing.T) { type call struct { - Pkgs []*model.PkgInputSpec + Pkgs []*model.IDorPkgInput Match model.MatchFlags - Sources []*model.SourceInputSpec + Sources []*model.IDorSourceInput HasSources []*model.HasSourceAtInputSpec } tests := []struct { @@ -42,11 +42,11 @@ func TestIngestHasSourceAts(t *testing.T) { Name: "Ingest without source", Calls: []call{ { - Pkgs: []*model.PkgInputSpec{testdata.P2}, + Pkgs: []*model.IDorPkgInput{{PackageInput: testdata.P2}}, Match: model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, }, - Sources: []*model.SourceInputSpec{}, + Sources: []*model.IDorSourceInput{}, HasSources: []*model.HasSourceAtInputSpec{{}}, }, }, @@ -56,11 +56,11 @@ func TestIngestHasSourceAts(t *testing.T) { Name: "Ingest missing pkg", Calls: []call{ { - Pkgs: []*model.PkgInputSpec{}, + Pkgs: []*model.IDorPkgInput{}, Match: model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, }, - Sources: []*model.SourceInputSpec{testdata.S1}, + Sources: []*model.IDorSourceInput{{SourceInput: testdata.S1}}, HasSources: []*model.HasSourceAtInputSpec{{}}, }, }, @@ -70,11 +70,11 @@ func TestIngestHasSourceAts(t *testing.T) { Name: "Ingest without hasSource", Calls: []call{ { - Pkgs: []*model.PkgInputSpec{testdata.P2}, + Pkgs: []*model.IDorPkgInput{{PackageInput: testdata.P2}}, Match: model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, }, - Sources: []*model.SourceInputSpec{testdata.S1}, + Sources: []*model.IDorSourceInput{{SourceInput: testdata.S1}}, HasSources: []*model.HasSourceAtInputSpec{}, }, }, @@ -84,11 +84,11 @@ func TestIngestHasSourceAts(t *testing.T) { Name: "Happy path", Calls: []call{ { - Pkgs: []*model.PkgInputSpec{testdata.P2, testdata.P1}, + Pkgs: []*model.IDorPkgInput{{PackageInput: testdata.P1}, {PackageInput: testdata.P2}}, Match: model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, }, - Sources: []*model.SourceInputSpec{testdata.S1, testdata.S2}, + Sources: []*model.IDorSourceInput{{SourceInput: testdata.S1}, {SourceInput: testdata.S2}}, HasSources: []*model.HasSourceAtInputSpec{ { Justification: "test", diff --git a/pkg/assembler/graphql/resolvers/hashEqual.resolvers.go b/pkg/assembler/graphql/resolvers/hashEqual.resolvers.go index 13c24a1204..5cd4010162 100644 --- a/pkg/assembler/graphql/resolvers/hashEqual.resolvers.go +++ b/pkg/assembler/graphql/resolvers/hashEqual.resolvers.go @@ -2,7 +2,7 @@ package resolvers // This file will be automatically regenerated based on the schema, any resolver implementations // will be copied through when generating and any unknown code will be moved to the end. -// Code generated by github.com/99designs/gqlgen version v0.17.41 +// Code generated by github.com/99designs/gqlgen version v0.17.43 import ( "context" @@ -12,12 +12,12 @@ import ( ) // IngestHashEqual is the resolver for the ingestHashEqual field. -func (r *mutationResolver) IngestHashEqual(ctx context.Context, artifact model.ArtifactInputSpec, otherArtifact model.ArtifactInputSpec, hashEqual model.HashEqualInputSpec) (string, error) { +func (r *mutationResolver) IngestHashEqual(ctx context.Context, artifact model.IDorArtifactInput, otherArtifact model.IDorArtifactInput, hashEqual model.HashEqualInputSpec) (string, error) { return r.Backend.IngestHashEqual(ctx, artifact, otherArtifact, hashEqual) } // IngestHashEquals is the resolver for the ingestHashEquals field. -func (r *mutationResolver) IngestHashEquals(ctx context.Context, artifacts []*model.ArtifactInputSpec, otherArtifacts []*model.ArtifactInputSpec, hashEquals []*model.HashEqualInputSpec) ([]string, error) { +func (r *mutationResolver) IngestHashEquals(ctx context.Context, artifacts []*model.IDorArtifactInput, otherArtifacts []*model.IDorArtifactInput, hashEquals []*model.HashEqualInputSpec) ([]string, error) { funcName := "IngestHashEquals" ingestedHashEqualsIDS := []string{} if len(artifacts) != len(otherArtifacts) { diff --git a/pkg/assembler/graphql/resolvers/hashEqual.resolvers_test.go b/pkg/assembler/graphql/resolvers/hashEqual.resolvers_test.go index 68c56699a1..d46c67144a 100644 --- a/pkg/assembler/graphql/resolvers/hashEqual.resolvers_test.go +++ b/pkg/assembler/graphql/resolvers/hashEqual.resolvers_test.go @@ -29,8 +29,8 @@ import ( func TestIngestHashEquals(t *testing.T) { type call struct { - A1 []*model.ArtifactInputSpec - A2 []*model.ArtifactInputSpec + A1 []*model.IDorArtifactInput + A2 []*model.IDorArtifactInput HE []*model.HashEqualInputSpec } tests := []struct { @@ -42,8 +42,8 @@ func TestIngestHashEquals(t *testing.T) { Name: "Ingest with different number of artifacts", Calls: []call{ { - A1: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, - A2: []*model.ArtifactInputSpec{testdata.A2}, + A1: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}, {ArtifactInput: testdata.A2}}, + A2: []*model.IDorArtifactInput{{ArtifactInput: testdata.A2}}, HE: []*model.HashEqualInputSpec{ { Justification: "test justification", @@ -57,8 +57,8 @@ func TestIngestHashEquals(t *testing.T) { Name: "Ingest with different number of HashEqual", Calls: []call{ { - A1: []*model.ArtifactInputSpec{testdata.A1}, - A2: []*model.ArtifactInputSpec{testdata.A2}, + A1: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}}, + A2: []*model.IDorArtifactInput{{ArtifactInput: testdata.A2}}, HE: []*model.HashEqualInputSpec{ { Justification: "test justification", @@ -75,8 +75,8 @@ func TestIngestHashEquals(t *testing.T) { Name: "HappyPath", Calls: []call{ { - A1: []*model.ArtifactInputSpec{testdata.A1}, - A2: []*model.ArtifactInputSpec{testdata.A2}, + A1: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}}, + A2: []*model.IDorArtifactInput{{ArtifactInput: testdata.A2}}, HE: []*model.HashEqualInputSpec{ { Justification: "test justification", diff --git a/pkg/assembler/graphql/resolvers/isDependency.resolvers.go b/pkg/assembler/graphql/resolvers/isDependency.resolvers.go index 11252f8de4..076bcd05ce 100644 --- a/pkg/assembler/graphql/resolvers/isDependency.resolvers.go +++ b/pkg/assembler/graphql/resolvers/isDependency.resolvers.go @@ -2,7 +2,7 @@ package resolvers // This file will be automatically regenerated based on the schema, any resolver implementations // will be copied through when generating and any unknown code will be moved to the end. -// Code generated by github.com/99designs/gqlgen version v0.17.41 +// Code generated by github.com/99designs/gqlgen version v0.17.43 import ( "context" @@ -12,12 +12,12 @@ import ( ) // IngestDependency is the resolver for the ingestDependency field. -func (r *mutationResolver) IngestDependency(ctx context.Context, pkg model.PkgInputSpec, depPkg model.PkgInputSpec, depPkgMatchType model.MatchFlags, dependency model.IsDependencyInputSpec) (string, error) { +func (r *mutationResolver) IngestDependency(ctx context.Context, pkg model.IDorPkgInput, depPkg model.IDorPkgInput, depPkgMatchType model.MatchFlags, dependency model.IsDependencyInputSpec) (string, error) { return r.Backend.IngestDependency(ctx, pkg, depPkg, depPkgMatchType, dependency) } // IngestDependencies is the resolver for the ingestDependencies field. -func (r *mutationResolver) IngestDependencies(ctx context.Context, pkgs []*model.PkgInputSpec, depPkgs []*model.PkgInputSpec, depPkgMatchType model.MatchFlags, dependencies []*model.IsDependencyInputSpec) ([]string, error) { +func (r *mutationResolver) IngestDependencies(ctx context.Context, pkgs []*model.IDorPkgInput, depPkgs []*model.IDorPkgInput, depPkgMatchType model.MatchFlags, dependencies []*model.IsDependencyInputSpec) ([]string, error) { funcName := "IngestDependencies" ingestedDependenciesIDS := []string{} if len(pkgs) != len(depPkgs) { diff --git a/pkg/assembler/graphql/resolvers/isDependency.resolvers_test.go b/pkg/assembler/graphql/resolvers/isDependency.resolvers_test.go index 439b389091..20a030bc36 100644 --- a/pkg/assembler/graphql/resolvers/isDependency.resolvers_test.go +++ b/pkg/assembler/graphql/resolvers/isDependency.resolvers_test.go @@ -28,8 +28,8 @@ import ( func TestIngestDependencies(t *testing.T) { type call struct { - P1s []*model.PkgInputSpec - P2s []*model.PkgInputSpec + P1s []*model.IDorPkgInput + P2s []*model.IDorPkgInput MF model.MatchFlags IDs []*model.IsDependencyInputSpec } @@ -42,8 +42,8 @@ func TestIngestDependencies(t *testing.T) { Name: "Ingest two packages and one dependent package", Calls: []call{ { - P1s: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - P2s: []*model.PkgInputSpec{testdata.P4}, + P1s: []*model.IDorPkgInput{{PackageInput: testdata.P1}, {PackageInput: testdata.P2}}, + P2s: []*model.IDorPkgInput{{PackageInput: testdata.P4}}, MF: testdata.MAll, IDs: []*model.IsDependencyInputSpec{ { @@ -61,8 +61,8 @@ func TestIngestDependencies(t *testing.T) { Name: "Ingest one package and two dependency notes", Calls: []call{ { - P1s: []*model.PkgInputSpec{testdata.P1}, - P2s: []*model.PkgInputSpec{testdata.P4}, + P1s: []*model.IDorPkgInput{{PackageInput: testdata.P1}}, + P2s: []*model.IDorPkgInput{{PackageInput: testdata.P4}}, MF: testdata.MAll, IDs: []*model.IsDependencyInputSpec{ { @@ -79,8 +79,8 @@ func TestIngestDependencies(t *testing.T) { { Name: "HappyPath", Calls: []call{{ - P1s: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - P2s: []*model.PkgInputSpec{testdata.P2, testdata.P4}, + P1s: []*model.IDorPkgInput{{PackageInput: testdata.P1}, {PackageInput: testdata.P2}}, + P2s: []*model.IDorPkgInput{{PackageInput: testdata.P2}, {PackageInput: testdata.P4}}, MF: testdata.MAll, IDs: []*model.IsDependencyInputSpec{ { diff --git a/pkg/assembler/graphql/resolvers/isOccurrence.resolvers.go b/pkg/assembler/graphql/resolvers/isOccurrence.resolvers.go index fb73a6ac25..444f836974 100644 --- a/pkg/assembler/graphql/resolvers/isOccurrence.resolvers.go +++ b/pkg/assembler/graphql/resolvers/isOccurrence.resolvers.go @@ -2,7 +2,7 @@ package resolvers // This file will be automatically regenerated based on the schema, any resolver implementations // will be copied through when generating and any unknown code will be moved to the end. -// Code generated by github.com/99designs/gqlgen version v0.17.41 +// Code generated by github.com/99designs/gqlgen version v0.17.43 import ( "context" @@ -13,7 +13,7 @@ import ( ) // IngestOccurrence is the resolver for the ingestOccurrence field. -func (r *mutationResolver) IngestOccurrence(ctx context.Context, subject model.PackageOrSourceInput, artifact model.ArtifactInputSpec, occurrence model.IsOccurrenceInputSpec) (string, error) { +func (r *mutationResolver) IngestOccurrence(ctx context.Context, subject model.PackageOrSourceInput, artifact model.IDorArtifactInput, occurrence model.IsOccurrenceInputSpec) (string, error) { funcName := "IngestOccurrence" if err := helper.ValidatePackageOrSourceInput(&subject, funcName); err != nil { return "", gqlerror.Errorf("%v :: %s", funcName, err) @@ -22,7 +22,7 @@ func (r *mutationResolver) IngestOccurrence(ctx context.Context, subject model.P } // IngestOccurrences is the resolver for the ingestOccurrences field. -func (r *mutationResolver) IngestOccurrences(ctx context.Context, subjects model.PackageOrSourceInputs, artifacts []*model.ArtifactInputSpec, occurrences []*model.IsOccurrenceInputSpec) ([]string, error) { +func (r *mutationResolver) IngestOccurrences(ctx context.Context, subjects model.PackageOrSourceInputs, artifacts []*model.IDorArtifactInput, occurrences []*model.IsOccurrenceInputSpec) ([]string, error) { funcName := "IngestOccurrences" ingestedOccurrencesIDs := []string{} valuesDefined := 0 diff --git a/pkg/assembler/graphql/resolvers/isOccurrence.resolvers_test.go b/pkg/assembler/graphql/resolvers/isOccurrence.resolvers_test.go index d6cc566edb..052e4bb6d4 100644 --- a/pkg/assembler/graphql/resolvers/isOccurrence.resolvers_test.go +++ b/pkg/assembler/graphql/resolvers/isOccurrence.resolvers_test.go @@ -30,7 +30,7 @@ import ( func TestIngestOccurrence(t *testing.T) { type call struct { PkgSrc model.PackageOrSourceInput - Artifact *model.ArtifactInputSpec + Artifact *model.IDorArtifactInput Occurrence *model.IsOccurrenceInputSpec } tests := []struct { @@ -43,10 +43,10 @@ func TestIngestOccurrence(t *testing.T) { Calls: []call{ { PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, - Source: testdata.S1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, + Source: &model.IDorSourceInput{SourceInput: testdata.S1}, }, - Artifact: testdata.A1, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A1}, Occurrence: &model.IsOccurrenceInputSpec{ Justification: "test justification", }, @@ -59,9 +59,9 @@ func TestIngestOccurrence(t *testing.T) { Calls: []call{ { PkgSrc: model.PackageOrSourceInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, - Artifact: testdata.A1, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A1}, Occurrence: &model.IsOccurrenceInputSpec{ Justification: "test justification", }, @@ -101,7 +101,7 @@ func TestIngestOccurrence(t *testing.T) { func TestIngestOccurrences(t *testing.T) { type call struct { PkgSrcs model.PackageOrSourceInputs - Artifacts []*model.ArtifactInputSpec + Artifacts []*model.IDorArtifactInput Occurrences []*model.IsOccurrenceInputSpec } tests := []struct { @@ -114,9 +114,9 @@ func TestIngestOccurrences(t *testing.T) { Calls: []call{ { PkgSrcs: model.PackageOrSourceInputs{ - Packages: []*model.PkgInputSpec{testdata.P1, testdata.P2}, + Packages: []*model.IDorPkgInput{{PackageInput: testdata.P1}, {PackageInput: testdata.P2}}, }, - Artifacts: []*model.ArtifactInputSpec{testdata.A1}, + Artifacts: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}}, Occurrences: []*model.IsOccurrenceInputSpec{ { Justification: "test justification", @@ -134,9 +134,9 @@ func TestIngestOccurrences(t *testing.T) { Calls: []call{ { PkgSrcs: model.PackageOrSourceInputs{ - Packages: []*model.PkgInputSpec{testdata.P1, testdata.P2}, + Packages: []*model.IDorPkgInput{{PackageInput: testdata.P1}, {PackageInput: testdata.P2}}, }, - Artifacts: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, + Artifacts: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}, {ArtifactInput: testdata.A2}}, Occurrences: []*model.IsOccurrenceInputSpec{ { Justification: "test justification", @@ -151,9 +151,9 @@ func TestIngestOccurrences(t *testing.T) { Calls: []call{ { PkgSrcs: model.PackageOrSourceInputs{ - Sources: []*model.SourceInputSpec{testdata.S1}, + Sources: []*model.IDorSourceInput{{SourceInput: testdata.S1}}, }, - Artifacts: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, + Artifacts: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}, {ArtifactInput: testdata.A2}}, Occurrences: []*model.IsOccurrenceInputSpec{ { Justification: "test justification", @@ -171,9 +171,9 @@ func TestIngestOccurrences(t *testing.T) { Calls: []call{ { PkgSrcs: model.PackageOrSourceInputs{ - Sources: []*model.SourceInputSpec{testdata.S1}, + Sources: []*model.IDorSourceInput{{SourceInput: testdata.S1}}, }, - Artifacts: []*model.ArtifactInputSpec{testdata.A1}, + Artifacts: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}}, Occurrences: []*model.IsOccurrenceInputSpec{ { Justification: "test justification", @@ -191,10 +191,10 @@ func TestIngestOccurrences(t *testing.T) { Calls: []call{ { PkgSrcs: model.PackageOrSourceInputs{ - Packages: []*model.PkgInputSpec{testdata.P1}, - Sources: []*model.SourceInputSpec{testdata.S1}, + Packages: []*model.IDorPkgInput{{PackageInput: testdata.P1}}, + Sources: []*model.IDorSourceInput{{SourceInput: testdata.S1}}, }, - Artifacts: []*model.ArtifactInputSpec{testdata.A1}, + Artifacts: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}}, Occurrences: []*model.IsOccurrenceInputSpec{ { Justification: "test justification", @@ -209,9 +209,9 @@ func TestIngestOccurrences(t *testing.T) { Calls: []call{ { PkgSrcs: model.PackageOrSourceInputs{ - Packages: []*model.PkgInputSpec{testdata.P1, testdata.P2}, + Packages: []*model.IDorPkgInput{{PackageInput: testdata.P1}, {PackageInput: testdata.P2}}, }, - Artifacts: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, + Artifacts: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}, {ArtifactInput: testdata.A2}}, Occurrences: []*model.IsOccurrenceInputSpec{ { Justification: "test justification", @@ -228,9 +228,9 @@ func TestIngestOccurrences(t *testing.T) { Calls: []call{ { PkgSrcs: model.PackageOrSourceInputs{ - Sources: []*model.SourceInputSpec{testdata.S1}, + Sources: []*model.IDorSourceInput{{SourceInput: testdata.S1}}, }, - Artifacts: []*model.ArtifactInputSpec{testdata.A1}, + Artifacts: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}}, Occurrences: []*model.IsOccurrenceInputSpec{{ Justification: "test justification", }}, diff --git a/pkg/assembler/graphql/resolvers/license.resolvers.go b/pkg/assembler/graphql/resolvers/license.resolvers.go index 6026960a49..ba5ff9d971 100644 --- a/pkg/assembler/graphql/resolvers/license.resolvers.go +++ b/pkg/assembler/graphql/resolvers/license.resolvers.go @@ -2,7 +2,7 @@ package resolvers // This file will be automatically regenerated based on the schema, any resolver implementations // will be copied through when generating and any unknown code will be moved to the end. -// Code generated by github.com/99designs/gqlgen version v0.17.41 +// Code generated by github.com/99designs/gqlgen version v0.17.43 import ( "context" @@ -12,18 +12,22 @@ import ( ) // IngestLicense is the resolver for the ingestLicense field. -func (r *mutationResolver) IngestLicense(ctx context.Context, license *model.LicenseInputSpec) (string, error) { - if err := helper.ValidateLicenseInput(license); err != nil { - return "", err +func (r *mutationResolver) IngestLicense(ctx context.Context, license *model.IDorLicenseInput) (string, error) { + if license.LicenseInput != nil { + if err := helper.ValidateLicenseInput(license.LicenseInput); err != nil { + return "", err + } } return r.Backend.IngestLicense(ctx, license) } // IngestLicenses is the resolver for the ingestLicenses field. -func (r *mutationResolver) IngestLicenses(ctx context.Context, licenses []*model.LicenseInputSpec) ([]string, error) { +func (r *mutationResolver) IngestLicenses(ctx context.Context, licenses []*model.IDorLicenseInput) ([]string, error) { for _, l := range licenses { - if err := helper.ValidateLicenseInput(l); err != nil { - return nil, err + if l.LicenseInput != nil { + if err := helper.ValidateLicenseInput(l.LicenseInput); err != nil { + return nil, err + } } } return r.Backend.IngestLicenses(ctx, licenses) diff --git a/pkg/assembler/graphql/resolvers/license.resolvers_test.go b/pkg/assembler/graphql/resolvers/license.resolvers_test.go index cdffa8f924..7e558e3989 100644 --- a/pkg/assembler/graphql/resolvers/license.resolvers_test.go +++ b/pkg/assembler/graphql/resolvers/license.resolvers_test.go @@ -125,10 +125,10 @@ func TestIngestLicense(t *testing.T) { } b. EXPECT(). - IngestLicense(ctx, test.Call). + IngestLicense(ctx, &model.IDorLicenseInput{LicenseInput: test.Call}). Return("", nil). Times(times) - _, err := r.Mutation().IngestLicense(ctx, test.Call) + _, err := r.Mutation().IngestLicense(ctx, &model.IDorLicenseInput{LicenseInput: test.Call}) if (err != nil) != test.ExpIngestErr { t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) } @@ -142,38 +142,48 @@ func TestIngestLicense(t *testing.T) { func TestIngestBulkLicense(t *testing.T) { tests := []struct { Name string - Call []*model.LicenseInputSpec + Call []*model.IDorLicenseInput ExpIngestErr bool }{ { Name: "All Good", - Call: []*model.LicenseInputSpec{ + Call: []*model.IDorLicenseInput{ { - Name: "LIC-ID", - ListVersion: ptrfrom.String("1.2.3"), + LicenseInput: &model.LicenseInputSpec{ + Name: "LIC-ID", + ListVersion: ptrfrom.String("1.2.3"), + }, }, { - Name: "LicenseRef-123", - Inline: ptrfrom.String("text"), + LicenseInput: &model.LicenseInputSpec{ + Name: "LicenseRef-123", + Inline: ptrfrom.String("text"), + }, }, }, ExpIngestErr: false, }, { Name: "One Bad", - Call: []*model.LicenseInputSpec{ + Call: []*model.IDorLicenseInput{ { - Name: "LIC-ID", - ListVersion: ptrfrom.String("1.2.3"), + LicenseInput: &model.LicenseInputSpec{ + Name: "LIC-ID", + ListVersion: ptrfrom.String("1.2.3"), + }, }, { - Name: "LIC-ID", - ListVersion: ptrfrom.String("1.2.3"), - Inline: ptrfrom.String("asdf"), + LicenseInput: &model.LicenseInputSpec{ + Name: "LIC-ID", + ListVersion: ptrfrom.String("1.2.3"), + Inline: ptrfrom.String("asdf"), + }, }, { - Name: "LicenseRef-123", - Inline: ptrfrom.String("text"), + LicenseInput: &model.LicenseInputSpec{ + Name: "LicenseRef-123", + Inline: ptrfrom.String("text"), + }, }, }, ExpIngestErr: true, diff --git a/pkg/assembler/graphql/resolvers/metadata.resolvers.go b/pkg/assembler/graphql/resolvers/metadata.resolvers.go index ae79f8f20a..fedf20d317 100644 --- a/pkg/assembler/graphql/resolvers/metadata.resolvers.go +++ b/pkg/assembler/graphql/resolvers/metadata.resolvers.go @@ -2,7 +2,7 @@ package resolvers // This file will be automatically regenerated based on the schema, any resolver implementations // will be copied through when generating and any unknown code will be moved to the end. -// Code generated by github.com/99designs/gqlgen version v0.17.41 +// Code generated by github.com/99designs/gqlgen version v0.17.43 import ( "context" diff --git a/pkg/assembler/graphql/resolvers/metadata.resolvers_test.go b/pkg/assembler/graphql/resolvers/metadata.resolvers_test.go index 90106c34f8..92a7485ecf 100644 --- a/pkg/assembler/graphql/resolvers/metadata.resolvers_test.go +++ b/pkg/assembler/graphql/resolvers/metadata.resolvers_test.go @@ -44,8 +44,8 @@ func TestIngestMetadata(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Source: testdata.S1, - Artifact: testdata.A1, + Source: &model.IDorSourceInput{SourceInput: testdata.S1}, + Artifact: &model.IDorArtifactInput{ArtifactInput: testdata.A1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -62,7 +62,7 @@ func TestIngestMetadata(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInput{ - Package: testdata.P1, + Package: &model.IDorPkgInput{PackageInput: testdata.P1}, }, Match: &model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -122,7 +122,7 @@ func TestIngestBulkMetadata(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1, testdata.P2}, + Packages: []*model.IDorPkgInput{{PackageInput: testdata.P1}, {PackageInput: testdata.P2}}, }, Match: model.MatchFlags{ Pkg: model.PkgMatchTypeSpecificVersion, @@ -141,7 +141,7 @@ func TestIngestBulkMetadata(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInputs{ - Sources: []*model.SourceInputSpec{testdata.S1, testdata.S2}, + Sources: []*model.IDorSourceInput{{SourceInput: testdata.S1}, {SourceInput: testdata.S2}}, }, HM: []*model.HasMetadataInputSpec{ { @@ -157,7 +157,7 @@ func TestIngestBulkMetadata(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInputs{ - Artifacts: []*model.ArtifactInputSpec{testdata.A1, testdata.A2}, + Artifacts: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}, {ArtifactInput: testdata.A2}}, }, HM: []*model.HasMetadataInputSpec{ { @@ -173,9 +173,9 @@ func TestIngestBulkMetadata(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1}, - Sources: []*model.SourceInputSpec{testdata.S1}, - Artifacts: []*model.ArtifactInputSpec{testdata.A1}, + Packages: []*model.IDorPkgInput{{PackageInput: testdata.P1}}, + Sources: []*model.IDorSourceInput{{SourceInput: testdata.S1}}, + Artifacts: []*model.IDorArtifactInput{{ArtifactInput: testdata.A1}}, }, HM: []*model.HasMetadataInputSpec{ { @@ -191,7 +191,7 @@ func TestIngestBulkMetadata(t *testing.T) { Calls: []call{ { Sub: model.PackageSourceOrArtifactInputs{ - Packages: []*model.PkgInputSpec{testdata.P1}, + Packages: []*model.IDorPkgInput{{PackageInput: testdata.P1}}, }, Match: model.MatchFlags{ Pkg: model.PkgMatchTypeAllVersions, diff --git a/pkg/assembler/graphql/resolvers/package.resolvers.go b/pkg/assembler/graphql/resolvers/package.resolvers.go index d443105411..95c210b474 100644 --- a/pkg/assembler/graphql/resolvers/package.resolvers.go +++ b/pkg/assembler/graphql/resolvers/package.resolvers.go @@ -2,7 +2,7 @@ package resolvers // This file will be automatically regenerated based on the schema, any resolver implementations // will be copied through when generating and any unknown code will be moved to the end. -// Code generated by github.com/99designs/gqlgen version v0.17.41 +// Code generated by github.com/99designs/gqlgen version v0.17.43 import ( "context" @@ -13,14 +13,14 @@ import ( ) // IngestPackage is the resolver for the ingestPackage field. -func (r *mutationResolver) IngestPackage(ctx context.Context, pkg model.PkgInputSpec) (*model.PackageIDs, error) { +func (r *mutationResolver) IngestPackage(ctx context.Context, pkg model.IDorPkgInput) (*model.PackageIDs, error) { // Return the ids of the package which has been ingested return r.Backend.IngestPackage(ctx, pkg) } // IngestPackages is the resolver for the ingestPackages field. -func (r *mutationResolver) IngestPackages(ctx context.Context, pkgs []*model.PkgInputSpec) ([]*model.PackageIDs, error) { +func (r *mutationResolver) IngestPackages(ctx context.Context, pkgs []*model.IDorPkgInput) ([]*model.PackageIDs, error) { return r.Backend.IngestPackages(ctx, pkgs) } diff --git a/pkg/assembler/graphql/resolvers/path.resolvers.go b/pkg/assembler/graphql/resolvers/path.resolvers.go index c2bfe47d3a..85a64a37fe 100644 --- a/pkg/assembler/graphql/resolvers/path.resolvers.go +++ b/pkg/assembler/graphql/resolvers/path.resolvers.go @@ -2,7 +2,7 @@ package resolvers // This file will be automatically regenerated based on the schema, any resolver implementations // will be copied through when generating and any unknown code will be moved to the end. -// Code generated by github.com/99designs/gqlgen version v0.17.41 +// Code generated by github.com/99designs/gqlgen version v0.17.43 import ( "context" diff --git a/pkg/assembler/graphql/resolvers/pkgEqual.resolvers.go b/pkg/assembler/graphql/resolvers/pkgEqual.resolvers.go index a0581aa451..95314b65ce 100644 --- a/pkg/assembler/graphql/resolvers/pkgEqual.resolvers.go +++ b/pkg/assembler/graphql/resolvers/pkgEqual.resolvers.go @@ -2,7 +2,7 @@ package resolvers // This file will be automatically regenerated based on the schema, any resolver implementations // will be copied through when generating and any unknown code will be moved to the end. -// Code generated by github.com/99designs/gqlgen version v0.17.41 +// Code generated by github.com/99designs/gqlgen version v0.17.43 import ( "context" @@ -12,12 +12,12 @@ import ( ) // IngestPkgEqual is the resolver for the ingestPkgEqual field. -func (r *mutationResolver) IngestPkgEqual(ctx context.Context, pkg model.PkgInputSpec, otherPackage model.PkgInputSpec, pkgEqual model.PkgEqualInputSpec) (string, error) { +func (r *mutationResolver) IngestPkgEqual(ctx context.Context, pkg model.IDorPkgInput, otherPackage model.IDorPkgInput, pkgEqual model.PkgEqualInputSpec) (string, error) { return r.Backend.IngestPkgEqual(ctx, pkg, otherPackage, pkgEqual) } // IngestPkgEquals is the resolver for the ingestPkgEquals field. -func (r *mutationResolver) IngestPkgEquals(ctx context.Context, pkgs []*model.PkgInputSpec, otherPackages []*model.PkgInputSpec, pkgEquals []*model.PkgEqualInputSpec) ([]string, error) { +func (r *mutationResolver) IngestPkgEquals(ctx context.Context, pkgs []*model.IDorPkgInput, otherPackages []*model.IDorPkgInput, pkgEquals []*model.PkgEqualInputSpec) ([]string, error) { funcName := "IngestPkgEquals" ingestedHashEqualsIDS := []string{} if len(pkgs) != len(otherPackages) { diff --git a/pkg/assembler/graphql/resolvers/pkgEqual.resolvers_test.go b/pkg/assembler/graphql/resolvers/pkgEqual.resolvers_test.go index 2f88960ed9..490996b78a 100644 --- a/pkg/assembler/graphql/resolvers/pkgEqual.resolvers_test.go +++ b/pkg/assembler/graphql/resolvers/pkgEqual.resolvers_test.go @@ -29,8 +29,8 @@ import ( func TestIngestPkgEquals(t *testing.T) { type call struct { - P1 []*model.PkgInputSpec - P2 []*model.PkgInputSpec + P1 []*model.IDorPkgInput + P2 []*model.IDorPkgInput PE []*model.PkgEqualInputSpec } tests := []struct { @@ -42,8 +42,8 @@ func TestIngestPkgEquals(t *testing.T) { Name: "Ingest with different number of artifacts", Calls: []call{ { - P1: []*model.PkgInputSpec{testdata.P1, testdata.P2}, - P2: []*model.PkgInputSpec{testdata.P2}, + P1: []*model.IDorPkgInput{{PackageInput: testdata.P1}, {PackageInput: testdata.P2}}, + P2: []*model.IDorPkgInput{{PackageInput: testdata.P2}}, PE: []*model.PkgEqualInputSpec{ { Justification: "test justification", @@ -57,8 +57,8 @@ func TestIngestPkgEquals(t *testing.T) { Name: "Ingest with different number of HashEqual", Calls: []call{ { - P1: []*model.PkgInputSpec{testdata.P1}, - P2: []*model.PkgInputSpec{testdata.P2}, + P1: []*model.IDorPkgInput{{PackageInput: testdata.P1}}, + P2: []*model.IDorPkgInput{{PackageInput: testdata.P2}}, PE: []*model.PkgEqualInputSpec{ { Justification: "test justification", @@ -75,8 +75,8 @@ func TestIngestPkgEquals(t *testing.T) { Name: "HappyPath", Calls: []call{ { - P1: []*model.PkgInputSpec{testdata.P1}, - P2: []*model.PkgInputSpec{testdata.P2}, + P1: []*model.IDorPkgInput{{PackageInput: testdata.P1}}, + P2: []*model.IDorPkgInput{{PackageInput: testdata.P2}}, PE: []*model.PkgEqualInputSpec{ { Justification: "test justification", diff --git a/pkg/assembler/graphql/resolvers/search.resolvers.go b/pkg/assembler/graphql/resolvers/search.resolvers.go index f11f6378f4..e782bb4a22 100644 --- a/pkg/assembler/graphql/resolvers/search.resolvers.go +++ b/pkg/assembler/graphql/resolvers/search.resolvers.go @@ -2,7 +2,7 @@ package resolvers // This file will be automatically regenerated based on the schema, any resolver implementations // will be copied through when generating and any unknown code will be moved to the end. -// Code generated by github.com/99designs/gqlgen version v0.17.41 +// Code generated by github.com/99designs/gqlgen version v0.17.43 import ( "context" diff --git a/pkg/assembler/graphql/resolvers/source.resolvers.go b/pkg/assembler/graphql/resolvers/source.resolvers.go index a7d176df17..eddc5bba41 100644 --- a/pkg/assembler/graphql/resolvers/source.resolvers.go +++ b/pkg/assembler/graphql/resolvers/source.resolvers.go @@ -2,7 +2,7 @@ package resolvers // This file will be automatically regenerated based on the schema, any resolver implementations // will be copied through when generating and any unknown code will be moved to the end. -// Code generated by github.com/99designs/gqlgen version v0.17.41 +// Code generated by github.com/99designs/gqlgen version v0.17.43 import ( "context" @@ -12,12 +12,12 @@ import ( ) // IngestSource is the resolver for the ingestSource field. -func (r *mutationResolver) IngestSource(ctx context.Context, source model.SourceInputSpec) (*model.SourceIDs, error) { +func (r *mutationResolver) IngestSource(ctx context.Context, source model.IDorSourceInput) (*model.SourceIDs, error) { return r.Backend.IngestSource(ctx, source) } // IngestSources is the resolver for the ingestSources field. -func (r *mutationResolver) IngestSources(ctx context.Context, sources []*model.SourceInputSpec) ([]*model.SourceIDs, error) { +func (r *mutationResolver) IngestSources(ctx context.Context, sources []*model.IDorSourceInput) ([]*model.SourceIDs, error) { return r.Backend.IngestSources(ctx, sources) } diff --git a/pkg/assembler/graphql/resolvers/vulnEqual.resolvers.go b/pkg/assembler/graphql/resolvers/vulnEqual.resolvers.go index a9e574d255..dbaf8fbd09 100644 --- a/pkg/assembler/graphql/resolvers/vulnEqual.resolvers.go +++ b/pkg/assembler/graphql/resolvers/vulnEqual.resolvers.go @@ -2,7 +2,7 @@ package resolvers // This file will be automatically regenerated based on the schema, any resolver implementations // will be copied through when generating and any unknown code will be moved to the end. -// Code generated by github.com/99designs/gqlgen version v0.17.41 +// Code generated by github.com/99designs/gqlgen version v0.17.43 import ( "context" @@ -14,37 +14,53 @@ import ( ) // IngestVulnEqual is the resolver for the ingestVulnEqual field. -func (r *mutationResolver) IngestVulnEqual(ctx context.Context, vulnerability model.VulnerabilityInputSpec, otherVulnerability model.VulnerabilityInputSpec, vulnEqual model.VulnEqualInputSpec) (string, error) { +func (r *mutationResolver) IngestVulnEqual(ctx context.Context, vulnerability model.IDorVulnerabilityInput, otherVulnerability model.IDorVulnerabilityInput, vulnEqual model.VulnEqualInputSpec) (string, error) { funcName := "IngestVulnEqual" - err := helper.ValidateNoVul(vulnerability) - if err != nil { - return "", gqlerror.Errorf("%v :: %s", funcName, err) - } + var vulnLowerCase model.IDorVulnerabilityInput + if vulnerability.VulnerabilityInput != nil { + if err := helper.ValidateNoVul(*vulnerability.VulnerabilityInput); err != nil { + return "", gqlerror.Errorf("%v :: %s", funcName, err) + } - err = helper.ValidateVulnerabilityIDInputSpec(vulnerability) - if err != nil { - return "", gqlerror.Errorf("%v :: %s", funcName, err) - } + if err := helper.ValidateVulnerabilityIDInputSpec(*vulnerability.VulnerabilityInput); err != nil { + return "", gqlerror.Errorf("%v :: %s", funcName, err) + } - err = helper.ValidateNoVul(otherVulnerability) - if err != nil { - return "", gqlerror.Errorf("%v :: %s", funcName, err) + vulnLowerCase = model.IDorVulnerabilityInput{ + VulnerabilityTypeID: otherVulnerability.VulnerabilityTypeID, + VulnerabilityNodeID: otherVulnerability.VulnerabilityNodeID, + VulnerabilityInput: &model.VulnerabilityInputSpec{Type: strings.ToLower(vulnerability.VulnerabilityInput.Type), VulnerabilityID: strings.ToLower(vulnerability.VulnerabilityInput.VulnerabilityID)}, + } + } else { + vulnLowerCase = vulnerability } - err = helper.ValidateVulnerabilityIDInputSpec(otherVulnerability) - if err != nil { - return "", gqlerror.Errorf("%v :: %s", funcName, err) + var otherVulnLowerCase model.IDorVulnerabilityInput + if otherVulnerability.VulnerabilityInput != nil { + if err := helper.ValidateNoVul(*otherVulnerability.VulnerabilityInput); err != nil { + return "", gqlerror.Errorf("%v :: %s", funcName, err) + } + + if err := helper.ValidateVulnerabilityIDInputSpec(*otherVulnerability.VulnerabilityInput); err != nil { + return "", gqlerror.Errorf("%v :: %s", funcName, err) + } + otherVulnLowerCase = model.IDorVulnerabilityInput{ + VulnerabilityTypeID: otherVulnerability.VulnerabilityTypeID, + VulnerabilityNodeID: otherVulnerability.VulnerabilityNodeID, + VulnerabilityInput: &model.VulnerabilityInputSpec{Type: strings.ToLower(otherVulnerability.VulnerabilityInput.Type), VulnerabilityID: strings.ToLower(otherVulnerability.VulnerabilityInput.VulnerabilityID)}, + } + } else { + otherVulnLowerCase = vulnerability } // vulnerability input (type and vulnerability ID) will be enforced to be lowercase - return r.Backend.IngestVulnEqual(ctx, - model.VulnerabilityInputSpec{Type: strings.ToLower(vulnerability.Type), VulnerabilityID: strings.ToLower(vulnerability.VulnerabilityID)}, - model.VulnerabilityInputSpec{Type: strings.ToLower(otherVulnerability.Type), VulnerabilityID: strings.ToLower(otherVulnerability.VulnerabilityID)}, + return r.Backend.IngestVulnEqual(ctx, vulnLowerCase, + otherVulnLowerCase, vulnEqual) } // IngestVulnEquals is the resolver for the ingestVulnEquals field. -func (r *mutationResolver) IngestVulnEquals(ctx context.Context, vulnerabilities []*model.VulnerabilityInputSpec, otherVulnerabilities []*model.VulnerabilityInputSpec, vulnEquals []*model.VulnEqualInputSpec) ([]string, error) { +func (r *mutationResolver) IngestVulnEquals(ctx context.Context, vulnerabilities []*model.IDorVulnerabilityInput, otherVulnerabilities []*model.IDorVulnerabilityInput, vulnEquals []*model.VulnEqualInputSpec) ([]string, error) { funcName := "IngestVulnEquals" if len(vulnerabilities) != len(otherVulnerabilities) { @@ -53,40 +69,54 @@ func (r *mutationResolver) IngestVulnEquals(ctx context.Context, vulnerabilities return []string{}, gqlerror.Errorf("%v :: uneven artifacts and hashEquals for ingestion", funcName) } - var lowercaseVulnList []*model.VulnerabilityInputSpec - var lowercaseOtherVulnList []*model.VulnerabilityInputSpec + var lowercaseVulnList []*model.IDorVulnerabilityInput + var lowercaseOtherVulnList []*model.IDorVulnerabilityInput for i := range vulnEquals { - err := helper.ValidateNoVul(*vulnerabilities[i]) - if err != nil { - return []string{}, gqlerror.Errorf("%v :: %s", funcName, err) - } + if vulnerabilities[i].VulnerabilityInput == nil { + lowercaseVulnList = append(lowercaseVulnList, vulnerabilities[i]) + } else { + if err := helper.ValidateNoVul(*vulnerabilities[i].VulnerabilityInput); err != nil { + return []string{}, gqlerror.Errorf("%v :: %s", funcName, err) + } - err = helper.ValidateVulnerabilityIDInputSpec(*vulnerabilities[i]) - if err != nil { - return []string{}, gqlerror.Errorf("%v :: %s", funcName, err) - } + if err := helper.ValidateVulnerabilityIDInputSpec(*vulnerabilities[i].VulnerabilityInput); err != nil { + return []string{}, gqlerror.Errorf("%v :: %s", funcName, err) + } - err = helper.ValidateNoVul(*otherVulnerabilities[i]) - if err != nil { - return []string{}, gqlerror.Errorf("%v :: %s", funcName, err) - } + lowercaseVulnInput := model.VulnerabilityInputSpec{ + Type: strings.ToLower(vulnerabilities[i].VulnerabilityInput.Type), + VulnerabilityID: strings.ToLower(vulnerabilities[i].VulnerabilityInput.VulnerabilityID), + } - err = helper.ValidateVulnerabilityIDInputSpec(*otherVulnerabilities[i]) - if err != nil { - return []string{}, gqlerror.Errorf("%v :: %s", funcName, err) + lowercaseVulnList = append(lowercaseVulnList, &model.IDorVulnerabilityInput{ + VulnerabilityTypeID: vulnerabilities[i].VulnerabilityTypeID, + VulnerabilityNodeID: vulnerabilities[i].VulnerabilityNodeID, + VulnerabilityInput: &lowercaseVulnInput, + }) } - lowercaseVulnInput := model.VulnerabilityInputSpec{ - Type: strings.ToLower(vulnerabilities[i].Type), - VulnerabilityID: strings.ToLower(vulnerabilities[i].VulnerabilityID), - } - lowercaseVulnList = append(lowercaseVulnList, &lowercaseVulnInput) + if otherVulnerabilities[i].VulnerabilityInput == nil { + lowercaseOtherVulnList = append(lowercaseOtherVulnList, otherVulnerabilities[i]) + } else { + if err := helper.ValidateNoVul(*otherVulnerabilities[i].VulnerabilityInput); err != nil { + return []string{}, gqlerror.Errorf("%v :: %s", funcName, err) + } + + if err := helper.ValidateVulnerabilityIDInputSpec(*otherVulnerabilities[i].VulnerabilityInput); err != nil { + return []string{}, gqlerror.Errorf("%v :: %s", funcName, err) + } + + lowercaseOtherVulnInput := model.VulnerabilityInputSpec{ + Type: strings.ToLower(otherVulnerabilities[i].VulnerabilityInput.Type), + VulnerabilityID: strings.ToLower(otherVulnerabilities[i].VulnerabilityInput.VulnerabilityID), + } - lowercaseOtherVulnInput := model.VulnerabilityInputSpec{ - Type: strings.ToLower(otherVulnerabilities[i].Type), - VulnerabilityID: strings.ToLower(otherVulnerabilities[i].VulnerabilityID), + lowercaseOtherVulnList = append(lowercaseOtherVulnList, &model.IDorVulnerabilityInput{ + VulnerabilityTypeID: otherVulnerabilities[i].VulnerabilityTypeID, + VulnerabilityNodeID: otherVulnerabilities[i].VulnerabilityNodeID, + VulnerabilityInput: &lowercaseOtherVulnInput, + }) } - lowercaseOtherVulnList = append(lowercaseOtherVulnList, &lowercaseOtherVulnInput) } // vulnerability input (type and vulnerability ID) will be enforced to be lowercase diff --git a/pkg/assembler/graphql/resolvers/vulnEqual.resolvers_test.go b/pkg/assembler/graphql/resolvers/vulnEqual.resolvers_test.go index babb78832d..1fd0f1155a 100644 --- a/pkg/assembler/graphql/resolvers/vulnEqual.resolvers_test.go +++ b/pkg/assembler/graphql/resolvers/vulnEqual.resolvers_test.go @@ -200,7 +200,7 @@ func TestIngestVulnEqual(t *testing.T) { IngestVulnEqual(ctx, gomock.Any(), gomock.Any(), *o.VE). Return("", nil). Times(times) - _, err := r.Mutation().IngestVulnEqual(ctx, *o.V1, *o.V2, *o.VE) + _, err := r.Mutation().IngestVulnEqual(ctx, model.IDorVulnerabilityInput{VulnerabilityInput: o.V1}, model.IDorVulnerabilityInput{VulnerabilityInput: o.V2}, *o.VE) if (err != nil) != test.ExpIngestErr { t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) } @@ -214,8 +214,8 @@ func TestIngestVulnEqual(t *testing.T) { func TestIngestVulnEquals(t *testing.T) { type call struct { - V1 []*model.VulnerabilityInputSpec - V2 []*model.VulnerabilityInputSpec + V1 []*model.IDorVulnerabilityInput + V2 []*model.IDorVulnerabilityInput VE []*model.VulnEqualInputSpec } tests := []struct { @@ -227,8 +227,8 @@ func TestIngestVulnEquals(t *testing.T) { Name: "uneven vulnerabilities", Calls: []call{ { - V1: []*model.VulnerabilityInputSpec{testdata.O1, testdata.NoVulnInput}, - V2: []*model.VulnerabilityInputSpec{testdata.O2}, + V1: []*model.IDorVulnerabilityInput{{VulnerabilityInput: testdata.O1}, {VulnerabilityInput: testdata.NoVulnInput}}, + V2: []*model.IDorVulnerabilityInput{{VulnerabilityInput: testdata.O2}}, VE: []*model.VulnEqualInputSpec{ { Justification: "test justification", @@ -242,8 +242,8 @@ func TestIngestVulnEquals(t *testing.T) { Name: "uneven vulnEqual", Calls: []call{ { - V1: []*model.VulnerabilityInputSpec{testdata.O1, testdata.NoVulnInput}, - V2: []*model.VulnerabilityInputSpec{testdata.O2, testdata.NoVulnInput}, + V1: []*model.IDorVulnerabilityInput{{VulnerabilityInput: testdata.O1}, {VulnerabilityInput: testdata.NoVulnInput}}, + V2: []*model.IDorVulnerabilityInput{{VulnerabilityInput: testdata.O1}, {VulnerabilityInput: testdata.NoVulnInput}}, VE: []*model.VulnEqualInputSpec{ { Justification: "test justification", @@ -257,8 +257,8 @@ func TestIngestVulnEquals(t *testing.T) { Name: "novuln vulnerability", Calls: []call{ { - V1: []*model.VulnerabilityInputSpec{testdata.O1, testdata.NoVulnInput}, - V2: []*model.VulnerabilityInputSpec{testdata.O2, testdata.O2}, + V1: []*model.IDorVulnerabilityInput{{VulnerabilityInput: testdata.O1}, {VulnerabilityInput: testdata.NoVulnInput}}, + V2: []*model.IDorVulnerabilityInput{{VulnerabilityInput: testdata.O2}, {VulnerabilityInput: testdata.O2}}, VE: []*model.VulnEqualInputSpec{ { Justification: "test justification", @@ -275,8 +275,8 @@ func TestIngestVulnEquals(t *testing.T) { Name: "novuln other vulnerability", Calls: []call{ { - V1: []*model.VulnerabilityInputSpec{testdata.O1, testdata.O2}, - V2: []*model.VulnerabilityInputSpec{testdata.O2, testdata.NoVulnInput}, + V1: []*model.IDorVulnerabilityInput{{VulnerabilityInput: testdata.O1}, {VulnerabilityInput: testdata.O2}}, + V2: []*model.IDorVulnerabilityInput{{VulnerabilityInput: testdata.O2}, {VulnerabilityInput: testdata.NoVulnInput}}, VE: []*model.VulnEqualInputSpec{ { Justification: "test justification", @@ -293,11 +293,8 @@ func TestIngestVulnEquals(t *testing.T) { Name: "Ingest with no vuln ID", Calls: []call{ { - V1: []*model.VulnerabilityInputSpec{{ - Type: "cve", - VulnerabilityID: "", - }}, - V2: []*model.VulnerabilityInputSpec{testdata.O1}, + V1: []*model.IDorVulnerabilityInput{{VulnerabilityInput: &model.VulnerabilityInputSpec{Type: "cve", VulnerabilityID: ""}}}, + V2: []*model.IDorVulnerabilityInput{{VulnerabilityInput: testdata.O1}}, VE: []*model.VulnEqualInputSpec{ { Justification: "test justification", @@ -311,11 +308,8 @@ func TestIngestVulnEquals(t *testing.T) { Name: "Ingest with no vuln ID other vuln", Calls: []call{ { - V1: []*model.VulnerabilityInputSpec{testdata.O1}, - V2: []*model.VulnerabilityInputSpec{{ - Type: "cve", - VulnerabilityID: "", - }}, + V1: []*model.IDorVulnerabilityInput{{VulnerabilityInput: testdata.O1}}, + V2: []*model.IDorVulnerabilityInput{{VulnerabilityInput: &model.VulnerabilityInputSpec{Type: "cve", VulnerabilityID: ""}}}, VE: []*model.VulnEqualInputSpec{ { Justification: "test justification", @@ -329,8 +323,8 @@ func TestIngestVulnEquals(t *testing.T) { Name: "Ingest with vuln ID", Calls: []call{ { - V1: []*model.VulnerabilityInputSpec{testdata.O1}, - V2: []*model.VulnerabilityInputSpec{testdata.O2}, + V1: []*model.IDorVulnerabilityInput{{VulnerabilityInput: testdata.O1}}, + V2: []*model.IDorVulnerabilityInput{{VulnerabilityInput: testdata.O2}}, VE: []*model.VulnEqualInputSpec{ { Justification: "test justification", diff --git a/pkg/assembler/graphql/resolvers/vulnMetadata.resolvers.go b/pkg/assembler/graphql/resolvers/vulnMetadata.resolvers.go index 04ea0dc878..83ec792d0f 100644 --- a/pkg/assembler/graphql/resolvers/vulnMetadata.resolvers.go +++ b/pkg/assembler/graphql/resolvers/vulnMetadata.resolvers.go @@ -2,7 +2,7 @@ package resolvers // This file will be automatically regenerated based on the schema, any resolver implementations // will be copied through when generating and any unknown code will be moved to the end. -// Code generated by github.com/99designs/gqlgen version v0.17.41 +// Code generated by github.com/99designs/gqlgen version v0.17.43 import ( "context" @@ -14,49 +14,62 @@ import ( ) // IngestVulnerabilityMetadata is the resolver for the ingestVulnerabilityMetadata field. -func (r *mutationResolver) IngestVulnerabilityMetadata(ctx context.Context, vulnerability model.VulnerabilityInputSpec, vulnerabilityMetadata model.VulnerabilityMetadataInputSpec) (string, error) { +func (r *mutationResolver) IngestVulnerabilityMetadata(ctx context.Context, vulnerability model.IDorVulnerabilityInput, vulnerabilityMetadata model.VulnerabilityMetadataInputSpec) (string, error) { funcName := "IngestVulnerabilityMetadata" - err := helper.ValidateNoVul(vulnerability) - if err != nil { - return "", gqlerror.Errorf("%v :: %s", funcName, err) - } - err = helper.ValidateVulnerabilityIDInputSpec(vulnerability) - if err != nil { - return "", gqlerror.Errorf("%v :: %s", funcName, err) - } + if vulnerability.VulnerabilityInput != nil { + err := helper.ValidateNoVul(*vulnerability.VulnerabilityInput) + if err != nil { + return "", gqlerror.Errorf("%v :: %s", funcName, err) + } - // vulnerability input (type and vulnerability ID) will be enforced to be lowercase - return r.Backend.IngestVulnerabilityMetadata(ctx, - model.VulnerabilityInputSpec{Type: strings.ToLower(vulnerability.Type), VulnerabilityID: strings.ToLower(vulnerability.VulnerabilityID)}, vulnerabilityMetadata) + err = helper.ValidateVulnerabilityIDInputSpec(*vulnerability.VulnerabilityInput) + if err != nil { + return "", gqlerror.Errorf("%v :: %s", funcName, err) + } + return r.Backend.IngestVulnerabilityMetadata(ctx, model.IDorVulnerabilityInput{ + VulnerabilityTypeID: vulnerability.VulnerabilityTypeID, + VulnerabilityNodeID: vulnerability.VulnerabilityNodeID, + VulnerabilityInput: &model.VulnerabilityInputSpec{Type: strings.ToLower(vulnerability.VulnerabilityInput.Type), VulnerabilityID: strings.ToLower(vulnerability.VulnerabilityInput.VulnerabilityID)}, + }, vulnerabilityMetadata) + } else { + return r.Backend.IngestVulnerabilityMetadata(ctx, vulnerability, vulnerabilityMetadata) + } } // IngestBulkVulnerabilityMetadata is the resolver for the ingestBulkVulnerabilityMetadata field. -func (r *mutationResolver) IngestBulkVulnerabilityMetadata(ctx context.Context, vulnerabilities []*model.VulnerabilityInputSpec, vulnerabilityMetadataList []*model.VulnerabilityMetadataInputSpec) ([]string, error) { +func (r *mutationResolver) IngestBulkVulnerabilityMetadata(ctx context.Context, vulnerabilities []*model.IDorVulnerabilityInput, vulnerabilityMetadataList []*model.VulnerabilityMetadataInputSpec) ([]string, error) { funcName := "IngestVulnerabilityMetadatas" if len(vulnerabilities) != len(vulnerabilityMetadataList) { return []string{}, gqlerror.Errorf("%v :: uneven vulnerabilities and vulnerabilityMetadata for ingestion", funcName) } // vulnerability input (type and vulnerability ID) will be enforced to be lowercase - var lowercaseVulnInputList []*model.VulnerabilityInputSpec + var lowercaseVulnInputList []*model.IDorVulnerabilityInput for _, v := range vulnerabilities { - - err := helper.ValidateNoVul(*v) + if v.VulnerabilityInput == nil { + lowercaseVulnInputList = append(lowercaseVulnInputList, v) + continue + } + err := helper.ValidateNoVul(*v.VulnerabilityInput) if err != nil { return []string{}, gqlerror.Errorf("%v :: %s", funcName, err) } - err = helper.ValidateVulnerabilityIDInputSpec(*v) + err = helper.ValidateVulnerabilityIDInputSpec(*v.VulnerabilityInput) if err != nil { return []string{}, gqlerror.Errorf("%v :: %s", funcName, err) } lowercaseVulnInput := model.VulnerabilityInputSpec{ - Type: strings.ToLower(v.Type), - VulnerabilityID: strings.ToLower(v.VulnerabilityID), + Type: strings.ToLower(v.VulnerabilityInput.Type), + VulnerabilityID: strings.ToLower(v.VulnerabilityInput.VulnerabilityID), } - lowercaseVulnInputList = append(lowercaseVulnInputList, &lowercaseVulnInput) + lowercaseVulnInputList = append(lowercaseVulnInputList, &model.IDorVulnerabilityInput{ + VulnerabilityTypeID: v.VulnerabilityTypeID, + VulnerabilityNodeID: v.VulnerabilityNodeID, + VulnerabilityInput: &lowercaseVulnInput, + }) } return r.Backend.IngestBulkVulnerabilityMetadata(ctx, lowercaseVulnInputList, vulnerabilityMetadataList) } diff --git a/pkg/assembler/graphql/resolvers/vulnMetadata.resolvers_test.go b/pkg/assembler/graphql/resolvers/vulnMetadata.resolvers_test.go index 4b6212b40a..f78bfdb0dd 100644 --- a/pkg/assembler/graphql/resolvers/vulnMetadata.resolvers_test.go +++ b/pkg/assembler/graphql/resolvers/vulnMetadata.resolvers_test.go @@ -108,7 +108,7 @@ func TestIngestVulnerabilityMetadata(t *testing.T) { IngestVulnerabilityMetadata(ctx, gomock.Any(), *o.VulnMetadata). Return("xyz", nil). Times(times) - _, err := r.Mutation().IngestVulnerabilityMetadata(ctx, *o.Vuln, *o.VulnMetadata) + _, err := r.Mutation().IngestVulnerabilityMetadata(ctx, model.IDorVulnerabilityInput{VulnerabilityInput: o.Vuln}, *o.VulnMetadata) if (err != nil) != test.ExpIngestErr { t.Fatalf("did not get expected ingest error, want: %v, got: %v", test.ExpIngestErr, err) } @@ -122,7 +122,7 @@ func TestIngestVulnerabilityMetadata(t *testing.T) { func TestIngestVulnerabilityMetadatas(t *testing.T) { type call struct { - Vulns []*model.VulnerabilityInputSpec + Vulns []*model.IDorVulnerabilityInput VulnMetadatas []*model.VulnerabilityMetadataInputSpec } tests := []struct { @@ -134,7 +134,7 @@ func TestIngestVulnerabilityMetadatas(t *testing.T) { Name: "Ingest with two vulnerabilities and one vulnerabilityMetadata", Calls: []call{ { - Vulns: []*model.VulnerabilityInputSpec{testdata.C1, testdata.C2}, + Vulns: []*model.IDorVulnerabilityInput{{VulnerabilityInput: testdata.C1}, {VulnerabilityInput: testdata.C2}}, VulnMetadatas: []*model.VulnerabilityMetadataInputSpec{ { ScoreType: model.VulnerabilityScoreTypeCVSSv3, @@ -152,11 +152,7 @@ func TestIngestVulnerabilityMetadatas(t *testing.T) { Name: "Ingest with vulnerability type novuln", Calls: []call{ { - Vulns: []*model.VulnerabilityInputSpec{ - { - Type: "novuln", - }, - }, + Vulns: []*model.IDorVulnerabilityInput{{VulnerabilityInput: &model.VulnerabilityInputSpec{Type: "novuln"}}}, VulnMetadatas: []*model.VulnerabilityMetadataInputSpec{ { ScoreType: model.VulnerabilityScoreTypeCVSSv3, @@ -174,11 +170,7 @@ func TestIngestVulnerabilityMetadatas(t *testing.T) { Name: "Ingest with vulnerability type cve with no id", Calls: []call{ { - Vulns: []*model.VulnerabilityInputSpec{ - { - Type: "cve", - }, - }, + Vulns: []*model.IDorVulnerabilityInput{{VulnerabilityInput: &model.VulnerabilityInputSpec{Type: "cve"}}}, VulnMetadatas: []*model.VulnerabilityMetadataInputSpec{ { ScoreType: model.VulnerabilityScoreTypeCVSSv3, @@ -196,7 +188,7 @@ func TestIngestVulnerabilityMetadatas(t *testing.T) { Name: "HappyPath", Calls: []call{ { - Vulns: []*model.VulnerabilityInputSpec{testdata.C1, testdata.C2}, + Vulns: []*model.IDorVulnerabilityInput{{VulnerabilityInput: testdata.C1}, {VulnerabilityInput: testdata.C2}}, VulnMetadatas: []*model.VulnerabilityMetadataInputSpec{ { ScoreType: model.VulnerabilityScoreTypeCVSSv3, diff --git a/pkg/assembler/graphql/resolvers/vulnerability.resolvers.go b/pkg/assembler/graphql/resolvers/vulnerability.resolvers.go index 74a7d114be..1229e2d1b0 100644 --- a/pkg/assembler/graphql/resolvers/vulnerability.resolvers.go +++ b/pkg/assembler/graphql/resolvers/vulnerability.resolvers.go @@ -2,7 +2,7 @@ package resolvers // This file will be automatically regenerated based on the schema, any resolver implementations // will be copied through when generating and any unknown code will be moved to the end. -// Code generated by github.com/99designs/gqlgen version v0.17.41 +// Code generated by github.com/99designs/gqlgen version v0.17.43 import ( "context" @@ -14,35 +14,48 @@ import ( ) // IngestVulnerability is the resolver for the ingestVulnerability field. -func (r *mutationResolver) IngestVulnerability(ctx context.Context, vuln model.VulnerabilityInputSpec) (*model.VulnerabilityIDs, error) { +func (r *mutationResolver) IngestVulnerability(ctx context.Context, vuln model.IDorVulnerabilityInput) (*model.VulnerabilityIDs, error) { funcName := "IngestVulnerability" - err := helper.ValidateVulnerabilityIDInputSpec(vuln) - if err != nil { - return nil, gqlerror.Errorf("%v :: %s", funcName, err) + if vuln.VulnerabilityInput != nil { + err := helper.ValidateVulnerabilityIDInputSpec(*vuln.VulnerabilityInput) + if err != nil { + return nil, gqlerror.Errorf("%v :: %s", funcName, err) + } + // vulnerability input (type and vulnerability ID) will be enforced to be lowercase + return r.Backend.IngestVulnerability(ctx, model.IDorVulnerabilityInput{ + VulnerabilityTypeID: vuln.VulnerabilityTypeID, + VulnerabilityNodeID: vuln.VulnerabilityNodeID, + VulnerabilityInput: &model.VulnerabilityInputSpec{Type: strings.ToLower(vuln.VulnerabilityInput.Type), VulnerabilityID: strings.ToLower(vuln.VulnerabilityInput.VulnerabilityID)}}) + } else { + return r.Backend.IngestVulnerability(ctx, vuln) } - - // vulnerability input (type and vulnerability ID) will be enforced to be lowercase - return r.Backend.IngestVulnerability(ctx, model.VulnerabilityInputSpec{Type: strings.ToLower(vuln.Type), VulnerabilityID: strings.ToLower(vuln.VulnerabilityID)}) } // IngestVulnerabilities is the resolver for the ingestVulnerabilities field. -func (r *mutationResolver) IngestVulnerabilities(ctx context.Context, vulns []*model.VulnerabilityInputSpec) ([]*model.VulnerabilityIDs, error) { +func (r *mutationResolver) IngestVulnerabilities(ctx context.Context, vulns []*model.IDorVulnerabilityInput) ([]*model.VulnerabilityIDs, error) { funcName := "IngestVulnerabilities" // vulnerability input (type and vulnerability ID) will be enforced to be lowercase - var lowercaseVulnInputList []*model.VulnerabilityInputSpec + var lowercaseVulnInputList []*model.IDorVulnerabilityInput for _, v := range vulns { - - err := helper.ValidateVulnerabilityIDInputSpec(*v) + if v.VulnerabilityInput == nil { + lowercaseVulnInputList = append(lowercaseVulnInputList, v) + continue + } + err := helper.ValidateVulnerabilityIDInputSpec(*v.VulnerabilityInput) if err != nil { return []*model.VulnerabilityIDs{}, gqlerror.Errorf("%v :: %s", funcName, err) } lowercaseVulnInput := model.VulnerabilityInputSpec{ - Type: strings.ToLower(v.Type), - VulnerabilityID: strings.ToLower(v.VulnerabilityID), + Type: strings.ToLower(v.VulnerabilityInput.Type), + VulnerabilityID: strings.ToLower(v.VulnerabilityInput.VulnerabilityID), } - lowercaseVulnInputList = append(lowercaseVulnInputList, &lowercaseVulnInput) + lowercaseVulnInputList = append(lowercaseVulnInputList, &model.IDorVulnerabilityInput{ + VulnerabilityTypeID: v.VulnerabilityTypeID, + VulnerabilityNodeID: v.VulnerabilityNodeID, + VulnerabilityInput: &lowercaseVulnInput, + }) } return r.Backend.IngestVulnerabilities(ctx, lowercaseVulnInputList) diff --git a/pkg/assembler/graphql/schema/artifact.graphql b/pkg/assembler/graphql/schema/artifact.graphql index 458ec82552..32c9c86321 100644 --- a/pkg/assembler/graphql/schema/artifact.graphql +++ b/pkg/assembler/graphql/schema/artifact.graphql @@ -53,14 +53,26 @@ input ArtifactInputSpec { digest: String! } +""" +IDorArtifactInput allows for specifying either the artifact ID or the ArtifactInputSpec. + +Either the ID or the ArtifactInputSpec must be specified. Both cannot be nil. + +If the ID is specified, the ArtifactInputSpec is not used. +""" +input IDorArtifactInput { + artifactID: ID + artifactInput: ArtifactInputSpec +} + extend type Query { "Returns all artifacts matching a filter." artifacts(artifactSpec: ArtifactSpec!): [Artifact!]! } extend type Mutation { - "Ingests a new artifact and returns it. The returned ID can be empty string." - ingestArtifact(artifact: ArtifactInputSpec): ID! - "Bulk ingests new artifacts and returns a list of them. The returned array of IDs can be a an array of empty string." - ingestArtifacts(artifacts: [ArtifactInputSpec!]!): [ID!]! + "Ingests a new artifact and returns it." + ingestArtifact(artifact: IDorArtifactInput): ID! + "Bulk ingests new artifacts and returns a list of them. The returned array of IDs must be in the same order as the inputs." + ingestArtifacts(artifacts: [IDorArtifactInput!]!): [ID!]! } diff --git a/pkg/assembler/graphql/schema/builder.graphql b/pkg/assembler/graphql/schema/builder.graphql index 5d99b9c41b..dfb352f69a 100644 --- a/pkg/assembler/graphql/schema/builder.graphql +++ b/pkg/assembler/graphql/schema/builder.graphql @@ -38,14 +38,26 @@ input BuilderInputSpec { uri: String! } +""" +IDorBuilderInput allows for specifying either the builder ID or the BuilderInputSpec. + +Either the ID or the BuilderInputSpec must be specified. Both cannot be nil. + +If the ID is specified, the BuilderInputSpec is not used. +""" +input IDorBuilderInput { + builderID: ID + builderInput: BuilderInputSpec +} + extend type Query { "Returns all builders matching a filter." builders(builderSpec: BuilderSpec!): [Builder!]! } extend type Mutation { - "Ingests a new builder and returns it. The returned ID can be empty string." - ingestBuilder(builder: BuilderInputSpec): ID! - "Bulk ingests new builders and returns a list of them. The returned array of IDs can be a an array of empty string." - ingestBuilders(builders: [BuilderInputSpec!]!): [ID!]! + "Ingests a new builder and returns it." + ingestBuilder(builder: IDorBuilderInput): ID! + "Bulk ingests new builders and returns a list of them. The returned array of IDs must be in the same order as the inputs." + ingestBuilders(builders: [IDorBuilderInput!]!): [ID!]! } diff --git a/pkg/assembler/graphql/schema/certifyBad.graphql b/pkg/assembler/graphql/schema/certifyBad.graphql index 4562b36a58..0a2384cf85 100644 --- a/pkg/assembler/graphql/schema/certifyBad.graphql +++ b/pkg/assembler/graphql/schema/certifyBad.graphql @@ -39,9 +39,9 @@ input type to be used in mutations. Exactly one of the value must be set to non-nil. """ input PackageSourceOrArtifactInput { - package: PkgInputSpec - source: SourceInputSpec - artifact: ArtifactInputSpec + package: IDorPkgInput + source: IDorSourceInput + artifact: IDorArtifactInput } """ @@ -51,9 +51,9 @@ input type to be used in bulk mutations. Exactly one list must be specified. """ input PackageSourceOrArtifactInputs { - packages: [PkgInputSpec!] - sources: [SourceInputSpec!] - artifacts: [ArtifactInputSpec!] + packages: [IDorPkgInput!] + sources: [IDorSourceInput!] + artifacts: [IDorArtifactInput!] } """ diff --git a/pkg/assembler/graphql/schema/certifyLegal.graphql b/pkg/assembler/graphql/schema/certifyLegal.graphql index a4c3d6221b..df32d58cf5 100644 --- a/pkg/assembler/graphql/schema/certifyLegal.graphql +++ b/pkg/assembler/graphql/schema/certifyLegal.graphql @@ -99,7 +99,7 @@ extend type Query { extend type Mutation { "Adds a legal certification to a package or source." - ingestCertifyLegal(subject: PackageOrSourceInput!, declaredLicenses: [LicenseInputSpec!]!, discoveredLicenses: [LicenseInputSpec!]!, certifyLegal: CertifyLegalInputSpec!): ID! + ingestCertifyLegal(subject: PackageOrSourceInput!, declaredLicenses: [IDorLicenseInput!]!, discoveredLicenses: [IDorLicenseInput!]!, certifyLegal: CertifyLegalInputSpec!): ID! "Bulk add legal certifications to packages or sources, not both at same time." - ingestCertifyLegals(subjects: PackageOrSourceInputs!, declaredLicensesList: [[LicenseInputSpec!]!]!, discoveredLicensesList: [[LicenseInputSpec!]!]!, certifyLegals: [CertifyLegalInputSpec!]!): [ID!]! + ingestCertifyLegals(subjects: PackageOrSourceInputs!, declaredLicensesList: [[IDorLicenseInput!]!]!, discoveredLicensesList: [[IDorLicenseInput!]!]!, certifyLegals: [CertifyLegalInputSpec!]!): [ID!]! } diff --git a/pkg/assembler/graphql/schema/certifyScorecard.graphql b/pkg/assembler/graphql/schema/certifyScorecard.graphql index 892b666e54..e9c2306bf2 100644 --- a/pkg/assembler/graphql/schema/certifyScorecard.graphql +++ b/pkg/assembler/graphql/schema/certifyScorecard.graphql @@ -126,10 +126,10 @@ extend type Query { extend type Mutation { "Adds a certification that a source repository has a Scorecard. The returned ID can be empty string." - ingestScorecard(source: SourceInputSpec!, scorecard: ScorecardInputSpec!): ID! + ingestScorecard(source: IDorSourceInput!, scorecard: ScorecardInputSpec!): ID! "Adds bulk certifications that a source repository has a Scorecard. The returned array of IDs can be a an array of empty string." ingestScorecards( - sources: [SourceInputSpec!]! + sources: [IDorSourceInput!]! scorecards: [ScorecardInputSpec!]! ): [ID!]! } diff --git a/pkg/assembler/graphql/schema/certifyVEXStatement.graphql b/pkg/assembler/graphql/schema/certifyVEXStatement.graphql index 206270b469..6a1e844b80 100644 --- a/pkg/assembler/graphql/schema/certifyVEXStatement.graphql +++ b/pkg/assembler/graphql/schema/certifyVEXStatement.graphql @@ -38,8 +38,8 @@ input type to be used in mutations. Exactly one of the value must be set to non-nil. """ input PackageOrArtifactInput { - package: PkgInputSpec - artifact: ArtifactInputSpec + package: IDorPkgInput + artifact: IDorArtifactInput } """ @@ -47,8 +47,8 @@ PackageOrArtifactInputs allows using packages and artifacts as input for batch m Exactly one list must be specified. """ input PackageOrArtifactInputs { - packages: [PkgInputSpec!] - artifacts: [ArtifactInputSpec!] + packages: [IDorPkgInput!] + artifacts: [IDorArtifactInput!] } "Records the status of a VEX statement subject." @@ -138,13 +138,13 @@ extend type Mutation { "Adds a VEX certification for a package. The returned ID can be empty string." ingestVEXStatement( subject: PackageOrArtifactInput! - vulnerability: VulnerabilityInputSpec! + vulnerability: IDorVulnerabilityInput! vexStatement: VexStatementInputSpec! ): ID! "Bulk add VEX certifications for a package and vulnerability. The returned array of IDs can be a an array of empty string." ingestVEXStatements( subjects: PackageOrArtifactInputs!, - vulnerabilities: [VulnerabilityInputSpec!]!, + vulnerabilities: [IDorVulnerabilityInput!]!, vexStatements: [VexStatementInputSpec!]! ): [ID!]! } diff --git a/pkg/assembler/graphql/schema/certifyVuln.graphql b/pkg/assembler/graphql/schema/certifyVuln.graphql index 6d13f1925b..966a4362b6 100644 --- a/pkg/assembler/graphql/schema/certifyVuln.graphql +++ b/pkg/assembler/graphql/schema/certifyVuln.graphql @@ -101,14 +101,14 @@ extend type Query { extend type Mutation { "Adds a certification that a package has been scanned for vulnerabilities. The returned ID can be empty string." ingestCertifyVuln( - pkg: PkgInputSpec! - vulnerability: VulnerabilityInputSpec! + pkg: IDorPkgInput! + vulnerability: IDorVulnerabilityInput! certifyVuln: ScanMetadataInput! ): ID! "Bulk add certifications that a package has been scanned for vulnerabilities. The returned array of IDs can be a an array of empty string." ingestCertifyVulns( - pkgs: [PkgInputSpec!]! - vulnerabilities: [VulnerabilityInputSpec!]! + pkgs: [IDorPkgInput!]! + vulnerabilities: [IDorVulnerabilityInput!]! certifyVulns: [ScanMetadataInput!]! ): [ID!]! } diff --git a/pkg/assembler/graphql/schema/hasSLSA.graphql b/pkg/assembler/graphql/schema/hasSLSA.graphql index 33b2580651..2db72045f6 100644 --- a/pkg/assembler/graphql/schema/hasSLSA.graphql +++ b/pkg/assembler/graphql/schema/hasSLSA.graphql @@ -135,16 +135,16 @@ extend type Query { extend type Mutation { "Ingests a SLSA attestation. The returned ID can be empty string." ingestSLSA( - subject: ArtifactInputSpec! - builtFrom: [ArtifactInputSpec!]! - builtBy: BuilderInputSpec! + subject: IDorArtifactInput! + builtFrom: [IDorArtifactInput!]! + builtBy: IDorBuilderInput! slsa: SLSAInputSpec! ): ID! "Bulk Ingest SLSA attestations. The returned array of IDs can be a an array of empty string." ingestSLSAs( - subjects: [ArtifactInputSpec!]! - builtFromList: [[ArtifactInputSpec!]!]! - builtByList: [BuilderInputSpec!]! + subjects: [IDorArtifactInput!]! + builtFromList: [[IDorArtifactInput!]!]! + builtByList: [IDorBuilderInput!]! slsaList: [SLSAInputSpec!]! ): [ID!]! } diff --git a/pkg/assembler/graphql/schema/hasSourceAt.graphql b/pkg/assembler/graphql/schema/hasSourceAt.graphql index 462be77fa9..2610b40229 100644 --- a/pkg/assembler/graphql/schema/hasSourceAt.graphql +++ b/pkg/assembler/graphql/schema/hasSourceAt.graphql @@ -61,16 +61,16 @@ extend type Query { extend type Mutation { "Adds a certification that a package (PackageName or PackageVersion) is built from the source. The returned ID can be empty string." ingestHasSourceAt( - pkg: PkgInputSpec! + pkg: IDorPkgInput! pkgMatchType: MatchFlags! - source: SourceInputSpec! + source: IDorSourceInput! hasSourceAt: HasSourceAtInputSpec! ): ID! "Bulk ingestion of certifications that a package (PackageName or PackageVersion) is built from the source. The returned array of IDs can be a an array of empty string." ingestHasSourceAts( - pkgs: [PkgInputSpec!]! + pkgs: [IDorPkgInput!]! pkgMatchType: MatchFlags! - sources: [SourceInputSpec!]! + sources: [IDorSourceInput!]! hasSourceAts: [HasSourceAtInputSpec!]! ):[ID!]! } diff --git a/pkg/assembler/graphql/schema/hashEqual.graphql b/pkg/assembler/graphql/schema/hashEqual.graphql index d11974e330..c4907209d9 100644 --- a/pkg/assembler/graphql/schema/hashEqual.graphql +++ b/pkg/assembler/graphql/schema/hashEqual.graphql @@ -60,14 +60,14 @@ extend type Query { extend type Mutation { "Adds a certification that two artifacts are equal. The returned ID can be empty string." ingestHashEqual( - artifact: ArtifactInputSpec! - otherArtifact: ArtifactInputSpec! + artifact: IDorArtifactInput! + otherArtifact: IDorArtifactInput! hashEqual: HashEqualInputSpec! ): ID! "Bulk ingest certifications that two artifacts are equal. The returned array of IDs can be a an array of empty string." ingestHashEquals( - artifacts: [ArtifactInputSpec!]! - otherArtifacts: [ArtifactInputSpec!]! + artifacts: [IDorArtifactInput!]! + otherArtifacts: [IDorArtifactInput!]! hashEquals: [HashEqualInputSpec!]! ): [ID!]! } diff --git a/pkg/assembler/graphql/schema/isDependency.graphql b/pkg/assembler/graphql/schema/isDependency.graphql index 56a8e63588..494eb7d5b6 100644 --- a/pkg/assembler/graphql/schema/isDependency.graphql +++ b/pkg/assembler/graphql/schema/isDependency.graphql @@ -81,17 +81,17 @@ extend type Query { } extend type Mutation { - "Adds a dependency between two packages. The returned ID can be empty string." + "Adds a dependency between two packages. The returned ID cannot be empty string as its used by hasSBOM." ingestDependency( - pkg: PkgInputSpec! - depPkg: PkgInputSpec! + pkg: IDorPkgInput! + depPkg: IDorPkgInput! depPkgMatchType: MatchFlags! dependency: IsDependencyInputSpec! ): ID! - "Bulk adds a dependency between two packages. The returned array of IDs can be a an array of empty string." + "Bulk adds a dependency between two packages. The returned array of IDs cannot be an empty string as its used by hasSBOM." ingestDependencies( - pkgs: [PkgInputSpec!]! - depPkgs: [PkgInputSpec!]! + pkgs: [IDorPkgInput!]! + depPkgs: [IDorPkgInput!]! depPkgMatchType: MatchFlags! dependencies: [IsDependencyInputSpec!]! ): [ID!]! diff --git a/pkg/assembler/graphql/schema/isOccurrence.graphql b/pkg/assembler/graphql/schema/isOccurrence.graphql index 1f8506f040..b768958801 100644 --- a/pkg/assembler/graphql/schema/isOccurrence.graphql +++ b/pkg/assembler/graphql/schema/isOccurrence.graphql @@ -36,8 +36,8 @@ PackageOrSourceInput allows using PackageOrSource union as input for mutations. Exactly one field must be specified. """ input PackageOrSourceInput { - package: PkgInputSpec - source: SourceInputSpec + package: IDorPkgInput + source: IDorSourceInput } """ @@ -45,8 +45,8 @@ PackageOrSourceInputs allows using packages and sources as input for batch mutat Exactly one list must be specified. """ input PackageOrSourceInputs { - packages: [PkgInputSpec!] - sources: [SourceInputSpec!] + packages: [IDorPkgInput!] + sources: [IDorSourceInput!] } """ @@ -94,16 +94,16 @@ extend type Query { } extend type Mutation { - "Ingest that an artifact is produced from a package or source. The returned ID can be empty string." + "Ingest that an artifact is produced from a package or source. The returned ID cannot be empty string as its used by hasSBOM." ingestOccurrence( subject: PackageOrSourceInput! - artifact: ArtifactInputSpec! + artifact: IDorArtifactInput! occurrence: IsOccurrenceInputSpec! ): ID! - "Bulk ingest that an artifact is produced from a package or source. The returned array of IDs can be a an array of empty string." + "Bulk ingest that an artifact is produced from a package or source. The returned array of IDs cannot be an empty string as its used by hasSBOM" ingestOccurrences( subjects: PackageOrSourceInputs! - artifacts: [ArtifactInputSpec!]! + artifacts: [IDorArtifactInput!]! occurrences: [IsOccurrenceInputSpec!]! ): [ID!]! } diff --git a/pkg/assembler/graphql/schema/license.graphql b/pkg/assembler/graphql/schema/license.graphql index c8f65f5ede..b33233d10a 100644 --- a/pkg/assembler/graphql/schema/license.graphql +++ b/pkg/assembler/graphql/schema/license.graphql @@ -71,6 +71,18 @@ input LicenseInputSpec { listVersion: String } +""" +IDorLicenseInput allows for specifying either the license ID or the LicenseInputSpec. + +Either the ID or the LicenseInputSpec must be specified. Both cannot be nil. + +If the ID is specified, the LicenseInputSpec is not used. +""" +input IDorLicenseInput { + licenseID: ID + licenseInput: LicenseInputSpec +} + extend type Query { "Returns all licenses matching a filter." licenses(licenseSpec: LicenseSpec!): [License!]! @@ -78,7 +90,7 @@ extend type Query { extend type Mutation { "Ingests a new license and returns it." - ingestLicense(license: LicenseInputSpec): ID! - "Bulk ingests new licenses and returns a list of them." - ingestLicenses(licenses: [LicenseInputSpec!]!): [ID!]! + ingestLicense(license: IDorLicenseInput): ID! + "Bulk ingests new licenses and returns a list of them. The returned array of IDs must be in the same order as the inputs." + ingestLicenses(licenses: [IDorLicenseInput!]!): [ID!]! } diff --git a/pkg/assembler/graphql/schema/package.graphql b/pkg/assembler/graphql/schema/package.graphql index 96934bb6c8..3c3b260c3a 100644 --- a/pkg/assembler/graphql/schema/package.graphql +++ b/pkg/assembler/graphql/schema/package.graphql @@ -189,14 +189,29 @@ input PackageQualifierInputSpec { value: String! } +""" +IDorPkgInput allows for specifying either the package IDs or the PkgInputSpec. + +Either the IDs or the PkgInputSpec must be specified. Both cannot be nil. + +If the IDs are specified, the PkgInputSpec is not used. +""" +input IDorPkgInput { + packageTypeID: ID + packageNamespaceID: ID + packageNameID: ID + packageVersionID: ID + packageInput: PkgInputSpec +} + extend type Query { "Returns all packages matching a filter." packages(pkgSpec: PkgSpec!): [Package!]! } extend type Mutation { - "Ingests a new package and returns a corresponding package hierarchy containing only the IDs. The returned ID can be empty string." - ingestPackage(pkg: PkgInputSpec!): PackageIDs! - "Bulk ingests packages and returns the list of corresponding package hierarchies containing only the IDs. The returned array of IDs can be empty strings." - ingestPackages(pkgs: [PkgInputSpec!]!): [PackageIDs!]! + "Ingests a new package and returns a corresponding package hierarchy containing only the IDs." + ingestPackage(pkg: IDorPkgInput!): PackageIDs! + "Bulk ingests packages and returns the list of corresponding package hierarchies containing only the IDs. The returned array of IDs must be in the same order as the inputs." + ingestPackages(pkgs: [IDorPkgInput!]!): [PackageIDs!]! } diff --git a/pkg/assembler/graphql/schema/pkgEqual.graphql b/pkg/assembler/graphql/schema/pkgEqual.graphql index 8c9a9e6acb..33231f9db5 100644 --- a/pkg/assembler/graphql/schema/pkgEqual.graphql +++ b/pkg/assembler/graphql/schema/pkgEqual.graphql @@ -60,14 +60,14 @@ extend type Query { extend type Mutation { "Adds a certification that two packages are similar. The returned ID can be empty string." ingestPkgEqual( - pkg: PkgInputSpec! - otherPackage: PkgInputSpec! + pkg: IDorPkgInput! + otherPackage: IDorPkgInput! pkgEqual: PkgEqualInputSpec! ): ID! "Bulk ingest mapping between packages. The returned array of IDs can be a an array of empty string." ingestPkgEquals( - pkgs: [PkgInputSpec!]! - otherPackages: [PkgInputSpec!]! + pkgs: [IDorPkgInput!]! + otherPackages: [IDorPkgInput!]! pkgEquals: [PkgEqualInputSpec!]! ): [ID!]! } diff --git a/pkg/assembler/graphql/schema/source.graphql b/pkg/assembler/graphql/schema/source.graphql index 44ba7a87cc..e35eea814d 100644 --- a/pkg/assembler/graphql/schema/source.graphql +++ b/pkg/assembler/graphql/schema/source.graphql @@ -110,14 +110,28 @@ input SourceInputSpec { commit: String = "" } +""" +IDorSourceInput allows for specifying either the source IDs or the SourceInputSpec. + +Either the IDs or the SourceInputSpec must be specified. Both cannot be nil. + +If the IDs are specified, the SourceInputSpec is not used. +""" +input IDorSourceInput { + sourceTypeID: ID + sourceNamespaceID: ID + sourceNameID: ID + sourceInput: SourceInputSpec +} + extend type Query { "Returns all sources matching a filter." sources(sourceSpec: SourceSpec!): [Source!]! } extend type Mutation { - "Ingests a new source and returns the corresponding source trie path. The returned ID can be empty string." - ingestSource(source: SourceInputSpec!): SourceIDs! - "Bulk ingests sources and returns the list of corresponding source trie path. The returned array of IDs can be a an array of empty string." - ingestSources(sources: [SourceInputSpec!]!): [SourceIDs!]! + "Ingests a new source and returns the corresponding source trie path." + ingestSource(source: IDorSourceInput!): SourceIDs! + "Bulk ingests sources and returns the list of corresponding source trie path. The returned array of IDs must be in the same order as the inputs." + ingestSources(sources: [IDorSourceInput!]!): [SourceIDs!]! } diff --git a/pkg/assembler/graphql/schema/vulnEqual.graphql b/pkg/assembler/graphql/schema/vulnEqual.graphql index eefc3ff478..7d2e68cc14 100644 --- a/pkg/assembler/graphql/schema/vulnEqual.graphql +++ b/pkg/assembler/graphql/schema/vulnEqual.graphql @@ -61,14 +61,14 @@ extend type Query { extend type Mutation { "Ingest a mapping between vulnerabilities. The returned ID can be empty string." ingestVulnEqual( - vulnerability: VulnerabilityInputSpec! - otherVulnerability: VulnerabilityInputSpec! + vulnerability: IDorVulnerabilityInput! + otherVulnerability: IDorVulnerabilityInput! vulnEqual: VulnEqualInputSpec! ): ID! "Bulk ingest mapping between vulnerabilities. The returned array of IDs can be a an array of empty string." ingestVulnEquals( - vulnerabilities: [VulnerabilityInputSpec!]! - otherVulnerabilities: [VulnerabilityInputSpec!]! + vulnerabilities: [IDorVulnerabilityInput!]! + otherVulnerabilities: [IDorVulnerabilityInput!]! vulnEquals: [VulnEqualInputSpec!]! ): [ID!]! } diff --git a/pkg/assembler/graphql/schema/vulnMetadata.graphql b/pkg/assembler/graphql/schema/vulnMetadata.graphql index fe62bd36e2..c469144cde 100644 --- a/pkg/assembler/graphql/schema/vulnMetadata.graphql +++ b/pkg/assembler/graphql/schema/vulnMetadata.graphql @@ -109,7 +109,7 @@ extend type Query { extend type Mutation { "Adds metadata about a vulnerability. The returned ID can be empty string." - ingestVulnerabilityMetadata(vulnerability: VulnerabilityInputSpec!, vulnerabilityMetadata: VulnerabilityMetadataInputSpec!): ID! + ingestVulnerabilityMetadata(vulnerability: IDorVulnerabilityInput!, vulnerabilityMetadata: VulnerabilityMetadataInputSpec!): ID! "Bulk add certifications that vulnerability has a specific score. The returned array of IDs can be a an array of empty string." - ingestBulkVulnerabilityMetadata(vulnerabilities: [VulnerabilityInputSpec!]!, vulnerabilityMetadataList: [VulnerabilityMetadataInputSpec!]!): [ID!]! + ingestBulkVulnerabilityMetadata(vulnerabilities: [IDorVulnerabilityInput!]!, vulnerabilityMetadataList: [VulnerabilityMetadataInputSpec!]!): [ID!]! } diff --git a/pkg/assembler/graphql/schema/vulnerability.graphql b/pkg/assembler/graphql/schema/vulnerability.graphql index 15e6496e1b..69d95c8e8e 100644 --- a/pkg/assembler/graphql/schema/vulnerability.graphql +++ b/pkg/assembler/graphql/schema/vulnerability.graphql @@ -102,14 +102,27 @@ type VulnerabilityIDs { vulnerabilityNodeID: ID! } +""" +IDorVulnerabilityInput allows for specifying either the vulnerability IDs or the VulnerabilityInputSpec. + +Either the IDs or the VulnerabilityInputSpec must be specified. Both cannot be nil. + +If the IDs are specified, the VulnerabilityInputSpec is not used. +""" +input IDorVulnerabilityInput { + vulnerabilityTypeID: ID + vulnerabilityNodeID: ID + vulnerabilityInput: VulnerabilityInputSpec +} + extend type Query { "Returns all vulnerabilities matching a filter." vulnerabilities(vulnSpec: VulnerabilitySpec!): [Vulnerability!]! } extend type Mutation { - "Ingests a new vulnerability and returns the corresponding vulnerability trie path. The returned ID can be empty string." - ingestVulnerability(vuln: VulnerabilityInputSpec!): VulnerabilityIDs! - "Bulk ingests vulnerabilities and returns the list of corresponding vulnerability trie path. The returned array of IDs can be a an array of empty string." - ingestVulnerabilities(vulns: [VulnerabilityInputSpec!]!): [VulnerabilityIDs!]! + "Ingests a new vulnerability and returns the corresponding vulnerability trie path." + ingestVulnerability(vuln: IDorVulnerabilityInput!): VulnerabilityIDs! + "Bulk ingests vulnerabilities and returns the list of corresponding vulnerability trie path. The returned array of IDs must be in the same order as the inputs" + ingestVulnerabilities(vulns: [IDorVulnerabilityInput!]!): [VulnerabilityIDs!]! } diff --git a/pkg/assembler/helpers/artifact.go b/pkg/assembler/helpers/artifact.go new file mode 100644 index 0000000000..501e3e3280 --- /dev/null +++ b/pkg/assembler/helpers/artifact.go @@ -0,0 +1,26 @@ +// +// Copyright 2024 The GUAC Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package helpers + +import ( + "fmt" + + "github.com/guacsec/guac/pkg/assembler/clients/generated" +) + +func ArtifactKey(input *generated.ArtifactInputSpec) string { + return fmt.Sprintf("%s:%s", input.Algorithm, input.Digest) +} diff --git a/pkg/assembler/helpers/artifact_test.go b/pkg/assembler/helpers/artifact_test.go new file mode 100644 index 0000000000..4e6790c61e --- /dev/null +++ b/pkg/assembler/helpers/artifact_test.go @@ -0,0 +1,62 @@ +// +// Copyright 2024 The GUAC Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package helpers + +import ( + "testing" + + "github.com/guacsec/guac/pkg/assembler/clients/generated" +) + +func TestArtifactKey(t *testing.T) { + tests := []struct { + name string + input *generated.ArtifactInputSpec + want string + }{ + { + name: "sha1", + input: &generated.ArtifactInputSpec{ + Algorithm: "sha1", + Digest: "7A8F47318E4676DACB0142AFA0B83029CD7BEFD9", + }, + want: "sha1:7A8F47318E4676DACB0142AFA0B83029CD7BEFD9", + }, + { + name: "sha256", + input: &generated.ArtifactInputSpec{ + Algorithm: "sha256", + Digest: "1234e40ac7250263c5dbe1cf3138912f3f416140aa248637a60d65fe22c47da4", + }, + want: "sha256:1234e40ac7250263c5dbe1cf3138912f3f416140aa248637a60d65fe22c47da4", + }, + { + name: "sha256", + input: &generated.ArtifactInputSpec{ + Algorithm: "sha256", + Digest: "575d810a9fae5f2f0671c9b2c0ce973e46c7207fbe5cb8d1b0d1836a6a0470e3", + }, + want: "sha256:575d810a9fae5f2f0671c9b2c0ce973e46c7207fbe5cb8d1b0d1836a6a0470e3", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := ArtifactKey(tt.input); got != tt.want { + t.Errorf("ArtifactKey() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/pkg/assembler/helpers/license.go b/pkg/assembler/helpers/license.go new file mode 100644 index 0000000000..ad149fa21a --- /dev/null +++ b/pkg/assembler/helpers/license.go @@ -0,0 +1,29 @@ +// +// Copyright 2024 The GUAC Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package helpers + +import ( + "strings" + + "github.com/guacsec/guac/pkg/assembler/clients/generated" +) + +func LicenseKey(l *generated.LicenseInputSpec) string { + if l.ListVersion != nil && *l.ListVersion != "" { + return strings.Join([]string{l.Name, *l.ListVersion}, ":") + } + return l.Name +} diff --git a/pkg/assembler/helpers/license_test.go b/pkg/assembler/helpers/license_test.go new file mode 100644 index 0000000000..b7b3a2a4ad --- /dev/null +++ b/pkg/assembler/helpers/license_test.go @@ -0,0 +1,54 @@ +// +// Copyright 2024 The GUAC Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package helpers + +import ( + "testing" + + "github.com/guacsec/guac/internal/testing/ptrfrom" + "github.com/guacsec/guac/pkg/assembler/clients/generated" +) + +func TestLicenseKey(t *testing.T) { + tests := []struct { + name string + lic *generated.LicenseInputSpec + want string + }{ + { + name: "LicenseRef", + lic: &generated.LicenseInputSpec{Name: "LicenseRef-123", Inline: ptrfrom.String("This is the license text.")}, + want: "LicenseRef-123", + }, + { + name: "ListVersion", + lic: &generated.LicenseInputSpec{Name: "asdf", ListVersion: ptrfrom.String("1.2.3")}, + want: "asdf:1.2.3", + }, + { + name: "ListVersion2", + lic: &generated.LicenseInputSpec{Name: "qwer", ListVersion: ptrfrom.String("1.2.3")}, + want: "qwer:1.2.3", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := LicenseKey(tt.lic); got != tt.want { + t.Errorf("LicenseKey() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/pkg/assembler/helpers/source.go b/pkg/assembler/helpers/source.go new file mode 100644 index 0000000000..8c7d11f72f --- /dev/null +++ b/pkg/assembler/helpers/source.go @@ -0,0 +1,34 @@ +// +// Copyright 2024 The GUAC Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package helpers + +import ( + "strings" + + "github.com/guacsec/guac/pkg/assembler/clients/generated" +) + +func ConcatenateSourceInput(source *generated.SourceInputSpec) string { + var sourceElements []string + sourceElements = append(sourceElements, source.Type, source.Namespace, source.Name) + if source.Tag != nil { + sourceElements = append(sourceElements, *source.Tag) + } + if source.Commit != nil { + sourceElements = append(sourceElements, *source.Commit) + } + return strings.Join(sourceElements, "/") +} diff --git a/pkg/assembler/helpers/source_test.go b/pkg/assembler/helpers/source_test.go new file mode 100644 index 0000000000..72295b7929 --- /dev/null +++ b/pkg/assembler/helpers/source_test.go @@ -0,0 +1,68 @@ +// +// Copyright 2024 The GUAC Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package helpers + +import ( + "testing" + + "github.com/guacsec/guac/internal/testing/ptrfrom" + "github.com/guacsec/guac/pkg/assembler/clients/generated" +) + +func TestConcatenateSourceInput(t *testing.T) { + tests := []struct { + name string + source *generated.SourceInputSpec + want string + }{ + { + name: "commit", + source: &generated.SourceInputSpec{ + Type: "git", + Namespace: "github.com/kubernetes", + Name: "kubernetes", + Commit: ptrfrom.String("5835544ca568b757a8ecae5c153f317e5736700e"), + }, + want: "git/github.com/kubernetes/kubernetes/5835544ca568b757a8ecae5c153f317e5736700e", + }, + { + name: "tag", + source: &generated.SourceInputSpec{ + Type: "git", + Namespace: "github.com/guacsec", + Name: "guac", + Tag: ptrfrom.String("v0.4.0"), + }, + want: "git/github.com/guacsec/guac/v0.4.0", + }, + { + name: "no tag or commit", + source: &generated.SourceInputSpec{ + Type: "git", + Namespace: "github.com/guacsec", + Name: "guac", + }, + want: "git/github.com/guacsec/guac", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := ConcatenateSourceInput(tt.source); got != tt.want { + t.Errorf("ConcatenateSourceInput() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/pkg/guacanalytics/patchPlanning_test.go b/pkg/guacanalytics/patchPlanning_test.go index 7339a0c650..190bc0fcc5 100644 --- a/pkg/guacanalytics/patchPlanning_test.go +++ b/pkg/guacanalytics/patchPlanning_test.go @@ -946,19 +946,16 @@ var ( func ingestIsDependency(ctx context.Context, client graphql.Client, graph assembler.IngestPredicates) error { for _, ingest := range graph.IsDependency { - _, err := model.IngestPackage(ctx, client, *ingest.Pkg) - + _, err := model.IngestPackage(ctx, client, model.IDorPkgInput{PackageInput: ingest.Pkg}) if err != nil { return fmt.Errorf("error in ingesting package: %s\n", err) } - _, err = model.IngestPackage(ctx, client, *ingest.DepPkg) - + _, err = model.IngestPackage(ctx, client, model.IDorPkgInput{PackageInput: ingest.DepPkg}) if err != nil { return fmt.Errorf("error in ingesting dependent package: %s\n", err) } - _, err = model.IngestIsDependency(ctx, client, *ingest.Pkg, *ingest.DepPkg, ingest.DepPkgMatchFlag, *ingest.IsDependency) - + _, err = model.IngestIsDependency(ctx, client, model.IDorPkgInput{PackageInput: ingest.Pkg}, model.IDorPkgInput{PackageInput: ingest.DepPkg}, ingest.DepPkgMatchFlag, *ingest.IsDependency) if err != nil { return fmt.Errorf("error in ingesting isDependency: %s\n", err) } @@ -968,13 +965,17 @@ func ingestIsDependency(ctx context.Context, client graphql.Client, graph assemb func ingestHasSLSA(ctx context.Context, client graphql.Client, graph assembler.IngestPredicates) error { for _, ingest := range graph.HasSlsa { - _, err := model.IngestBuilder(ctx, client, *ingest.Builder) - + _, err := model.IngestBuilder(ctx, client, model.IDorBuilderInput{BuilderInput: ingest.Builder}) if err != nil { return fmt.Errorf("error in ingesting Builder for HasSlsa: %v\n", err) } - _, err = model.IngestSLSAForArtifact(ctx, client, *ingest.Artifact, ingest.Materials, *ingest.Builder, *ingest.HasSlsa) + var matsIDorInput []model.IDorArtifactInput + for _, mat := range ingest.Materials { + matsIDorInput = append(matsIDorInput, model.IDorArtifactInput{ArtifactInput: &mat}) + } + + _, err = model.IngestSLSAForArtifact(ctx, client, model.IDorArtifactInput{ArtifactInput: ingest.Artifact}, matsIDorInput, model.IDorBuilderInput{BuilderInput: ingest.Builder}, *ingest.HasSlsa) if err != nil { return fmt.Errorf("error in ingesting HasSlsa: %v\n", err) } @@ -984,19 +985,19 @@ func ingestHasSLSA(ctx context.Context, client graphql.Client, graph assembler.I func ingestHasSourceAt(ctx context.Context, client graphql.Client, graph assembler.IngestPredicates) error { for _, ingest := range graph.HasSourceAt { - _, err := model.IngestPackage(ctx, client, *ingest.Pkg) + _, err := model.IngestPackage(ctx, client, model.IDorPkgInput{PackageInput: ingest.Pkg}) if err != nil { return fmt.Errorf("error in ingesting pkg HasSourceAt: %v\n", err) } - _, err = model.IngestSource(ctx, client, *ingest.Src) + _, err = model.IngestSource(ctx, client, model.IDorSourceInput{SourceInput: ingest.Src}) if err != nil { return fmt.Errorf("error in ingesting src HasSourceAt: %v\n", err) } - _, err = model.IngestHasSourceAt(ctx, client, *ingest.Pkg, ingest.PkgMatchFlag, *ingest.Src, *ingest.HasSourceAt) + _, err = model.IngestHasSourceAt(ctx, client, model.IDorPkgInput{PackageInput: ingest.Pkg}, ingest.PkgMatchFlag, model.IDorSourceInput{SourceInput: ingest.Src}, *ingest.HasSourceAt) if err != nil { return fmt.Errorf("error in ingesting HasSourceAt: %v\n", err) @@ -1010,9 +1011,9 @@ func ingestIsOccurrence(ctx context.Context, client graphql.Client, graph assemb var err error if ingest.Src != nil { - _, err = model.IngestSource(ctx, client, *ingest.Src) + _, err = model.IngestSource(ctx, client, model.IDorSourceInput{SourceInput: ingest.Src}) } else { - _, err = model.IngestPackage(ctx, client, *ingest.Pkg) + _, err = model.IngestPackage(ctx, client, model.IDorPkgInput{PackageInput: ingest.Pkg}) } @@ -1020,16 +1021,16 @@ func ingestIsOccurrence(ctx context.Context, client graphql.Client, graph assemb return fmt.Errorf("error in ingesting pkg/src IsOccurrence: %v\n", err) } - _, err = model.IngestArtifact(ctx, client, *ingest.Artifact) + _, err = model.IngestArtifact(ctx, client, model.IDorArtifactInput{ArtifactInput: ingest.Artifact}) if err != nil { return fmt.Errorf("error in ingesting artifact for IsOccurrence: %v\n", err) } if ingest.Src != nil { - _, err = model.IngestIsOccurrenceSrc(ctx, client, *ingest.Src, *ingest.Artifact, *ingest.IsOccurrence) + _, err = model.IngestIsOccurrenceSrc(ctx, client, model.IDorSourceInput{SourceInput: ingest.Src}, model.IDorArtifactInput{ArtifactInput: ingest.Artifact}, *ingest.IsOccurrence) } else { - _, err = model.IngestIsOccurrencePkg(ctx, client, *ingest.Pkg, *ingest.Artifact, *ingest.IsOccurrence) + _, err = model.IngestIsOccurrencePkg(ctx, client, model.IDorPkgInput{PackageInput: ingest.Pkg}, model.IDorArtifactInput{ArtifactInput: ingest.Artifact}, *ingest.IsOccurrence) } if err != nil { @@ -1041,13 +1042,13 @@ func ingestIsOccurrence(ctx context.Context, client graphql.Client, graph assemb func ingestCertifyGood(ctx context.Context, client graphql.Client, graph assembler.IngestPredicates) error { for _, ingest := range graph.CertifyGood { - _, err := model.IngestPackage(ctx, client, *ingest.Pkg) + _, err := model.IngestPackage(ctx, client, model.IDorPkgInput{PackageInput: ingest.Pkg}) if err != nil { return fmt.Errorf("error in ingesting Package for CertifyGood: %v\n", err) } - _, err = model.IngestCertifyGoodPkg(ctx, client, *ingest.Pkg, ingest.PkgMatchFlag, *ingest.CertifyGood) + _, err = model.IngestCertifyGoodPkg(ctx, client, model.IDorPkgInput{PackageInput: ingest.Pkg}, ingest.PkgMatchFlag, *ingest.CertifyGood) if err != nil { return fmt.Errorf("error in ingesting CertifyGood: %v\n", err) @@ -1058,19 +1059,19 @@ func ingestCertifyGood(ctx context.Context, client graphql.Client, graph assembl func ingestPkgEqual(ctx context.Context, client graphql.Client, graph assembler.IngestPredicates) error { for _, ingest := range graph.PkgEqual { - _, err := model.IngestPackage(ctx, client, *ingest.Pkg) + _, err := model.IngestPackage(ctx, client, model.IDorPkgInput{PackageInput: ingest.Pkg}) if err != nil { return fmt.Errorf("error in ingesting Pkg for PkgEqual: %v\n", err) } - _, err = model.IngestPackage(ctx, client, *ingest.EqualPkg) + _, err = model.IngestPackage(ctx, client, model.IDorPkgInput{PackageInput: ingest.EqualPkg}) if err != nil { return fmt.Errorf("error in ingesting EqualPkg for PkgEqual: %v\n", err) } - _, err = model.IngestPkgEqual(ctx, client, *ingest.Pkg, *ingest.EqualPkg, *ingest.PkgEqual) + _, err = model.IngestPkgEqual(ctx, client, model.IDorPkgInput{PackageInput: ingest.Pkg}, model.IDorPkgInput{PackageInput: ingest.EqualPkg}, *ingest.PkgEqual) if err != nil { return fmt.Errorf("error in ingesting PkgEqual: %v\n", err) @@ -1081,19 +1082,19 @@ func ingestPkgEqual(ctx context.Context, client graphql.Client, graph assembler. func ingestHashEqual(ctx context.Context, client graphql.Client, graph assembler.IngestPredicates) error { for _, ingest := range graph.HashEqual { - _, err := model.IngestArtifact(ctx, client, *ingest.Artifact) + _, err := model.IngestArtifact(ctx, client, model.IDorArtifactInput{ArtifactInput: ingest.Artifact}) if err != nil { return fmt.Errorf("error in ingesting Artifact for HashEqual: %v\n", err) } - _, err = model.IngestArtifact(ctx, client, *ingest.EqualArtifact) + _, err = model.IngestArtifact(ctx, client, model.IDorArtifactInput{ArtifactInput: ingest.EqualArtifact}) if err != nil { return fmt.Errorf("error in ingesting EqualArtifact for HashEqual: %v\n", err) } - _, err = model.IngestHashEqual(ctx, client, *ingest.Artifact, *ingest.EqualArtifact, *ingest.HashEqual) + _, err = model.IngestHashEqual(ctx, client, model.IDorArtifactInput{ArtifactInput: ingest.Artifact}, model.IDorArtifactInput{ArtifactInput: ingest.EqualArtifact}, *ingest.HashEqual) if err != nil { return fmt.Errorf("error in ingesting HashEqual: %v\n", err) @@ -1107,12 +1108,12 @@ func ingestPointOfContact(ctx context.Context, client graphql.Client, graph asse var err error if ingest.Src != nil { - _, err = model.IngestSource(ctx, client, *ingest.Src) + _, err = model.IngestSource(ctx, client, model.IDorSourceInput{SourceInput: ingest.Src}) } else if ingest.Pkg != nil { - _, err = model.IngestPackage(ctx, client, *ingest.Pkg) + _, err = model.IngestPackage(ctx, client, model.IDorPkgInput{PackageInput: ingest.Pkg}) } else { - _, err = model.IngestArtifact(ctx, client, *ingest.Artifact) + _, err = model.IngestArtifact(ctx, client, model.IDorArtifactInput{ArtifactInput: ingest.Artifact}) } if err != nil { @@ -1120,11 +1121,11 @@ func ingestPointOfContact(ctx context.Context, client graphql.Client, graph asse } if ingest.Src != nil { - _, err = model.IngestPointOfContactSrc(ctx, client, *ingest.Src, *ingest.PointOfContact) + _, err = model.IngestPointOfContactSrc(ctx, client, model.IDorSourceInput{SourceInput: ingest.Src}, *ingest.PointOfContact) } else if ingest.Pkg != nil { - _, err = model.IngestPointOfContactPkg(ctx, client, *ingest.Pkg, ingest.PkgMatchFlag, *ingest.PointOfContact) + _, err = model.IngestPointOfContactPkg(ctx, client, model.IDorPkgInput{PackageInput: ingest.Pkg}, ingest.PkgMatchFlag, *ingest.PointOfContact) } else { - _, err = model.IngestPointOfContactArtifact(ctx, client, *ingest.Artifact, *ingest.PointOfContact) + _, err = model.IngestPointOfContactArtifact(ctx, client, model.IDorArtifactInput{ArtifactInput: ingest.Artifact}, *ingest.PointOfContact) } if err != nil { diff --git a/pkg/handler/processor/process/process_test.go b/pkg/handler/processor/process/process_test.go index b5cb6048a5..80ac25e60f 100644 --- a/pkg/handler/processor/process/process_test.go +++ b/pkg/handler/processor/process/process_test.go @@ -41,32 +41,32 @@ func Test_SimpleDocProcessTest(t *testing.T) { doc processor.Document expected processor.DocumentTree expectErr bool - }{{ - - name: "simple test", - doc: processor.Document{ - Blob: []byte(`{ + }{ + { + name: "simple test", + doc: processor.Document{ + Blob: []byte(`{ "issuer": "google.com", "info": "this is a cool document" }`), - Type: simpledoc.SimpleDocType, - Format: processor.FormatJSON, - SourceInformation: processor.SourceInformation{}, - }, - expected: dochelper.DocNode(&processor.Document{ - Blob: []byte(`{ + Type: simpledoc.SimpleDocType, + Format: processor.FormatJSON, + SourceInformation: processor.SourceInformation{}, + }, + expected: dochelper.DocNode(&processor.Document{ + Blob: []byte(`{ "issuer": "google.com", "info": "this is a cool document" }`), - Type: simpledoc.SimpleDocType, - Format: processor.FormatJSON, - SourceInformation: processor.SourceInformation{}, - }), - }, { + Type: simpledoc.SimpleDocType, + Format: processor.FormatJSON, + SourceInformation: processor.SourceInformation{}, + }), + }, { - name: "unpack test", - doc: processor.Document{ - Blob: []byte(`{ + name: "unpack test", + doc: processor.Document{ + Blob: []byte(`{ "issuer": "google.com", "info": "this is a cool document", "nested": [{ @@ -77,13 +77,13 @@ func Test_SimpleDocProcessTest(t *testing.T) { "info": "this is a cooler nested doc 2" }] }`), - Type: simpledoc.SimpleDocType, - Format: processor.FormatJSON, - SourceInformation: processor.SourceInformation{}, - }, - expected: dochelper.DocNode( - &processor.Document{ //root - Blob: []byte(`{ + Type: simpledoc.SimpleDocType, + Format: processor.FormatJSON, + SourceInformation: processor.SourceInformation{}, + }, + expected: dochelper.DocNode( + &processor.Document{ //root + Blob: []byte(`{ "issuer": "google.com", "info": "this is a cool document", "nested": [{ @@ -94,33 +94,33 @@ func Test_SimpleDocProcessTest(t *testing.T) { "info": "this is a cooler nested doc 2" }] }`), - Type: simpledoc.SimpleDocType, - Format: processor.FormatJSON, - SourceInformation: processor.SourceInformation{}, - }, - dochelper.DocNode(&processor.Document{ // child 1 - Blob: []byte(`{ + Type: simpledoc.SimpleDocType, + Format: processor.FormatJSON, + SourceInformation: processor.SourceInformation{}, + }, + dochelper.DocNode(&processor.Document{ // child 1 + Blob: []byte(`{ "issuer": "google.com", "info": "this is a cooler nested doc 1" }`), - Type: simpledoc.SimpleDocType, - Format: processor.FormatJSON, - SourceInformation: processor.SourceInformation{}, - }), - dochelper.DocNode(&processor.Document{ //child 2 - Blob: []byte(`{ + Type: simpledoc.SimpleDocType, + Format: processor.FormatJSON, + SourceInformation: processor.SourceInformation{}, + }), + dochelper.DocNode(&processor.Document{ //child 2 + Blob: []byte(`{ "issuer": "google.com", "info": "this is a cooler nested doc 2" }`), - Type: simpledoc.SimpleDocType, - Format: processor.FormatJSON, - SourceInformation: processor.SourceInformation{}, - })), - }, { + Type: simpledoc.SimpleDocType, + Format: processor.FormatJSON, + SourceInformation: processor.SourceInformation{}, + })), + }, { - name: "unpack twice test", - doc: processor.Document{ - Blob: []byte(`{ + name: "unpack twice test", + doc: processor.Document{ + Blob: []byte(`{ "issuer": "google.com", "info": "this is a cool document", "nested": [{ @@ -139,13 +139,13 @@ func Test_SimpleDocProcessTest(t *testing.T) { }] }] }`), - Type: simpledoc.SimpleDocType, - Format: processor.FormatJSON, - SourceInformation: processor.SourceInformation{}, - }, - expected: dochelper.DocNode( - &processor.Document{ // root - Blob: []byte(`{ + Type: simpledoc.SimpleDocType, + Format: processor.FormatJSON, + SourceInformation: processor.SourceInformation{}, + }, + expected: dochelper.DocNode( + &processor.Document{ // root + Blob: []byte(`{ "issuer": "google.com", "info": "this is a cool document", "nested": [{ @@ -164,12 +164,12 @@ func Test_SimpleDocProcessTest(t *testing.T) { }] }] }`), - Type: simpledoc.SimpleDocType, - Format: processor.FormatJSON, - SourceInformation: processor.SourceInformation{}, - }, - dochelper.DocNode(&processor.Document{ - Blob: []byte(`{ + Type: simpledoc.SimpleDocType, + Format: processor.FormatJSON, + SourceInformation: processor.SourceInformation{}, + }, + dochelper.DocNode(&processor.Document{ + Blob: []byte(`{ "issuer": "google.com", "info": "this is a cooler nested doc 1", "nested": [{ @@ -177,21 +177,21 @@ func Test_SimpleDocProcessTest(t *testing.T) { "info": "this is a cooler nested doc 3" }] }`), - Type: simpledoc.SimpleDocType, - Format: processor.FormatJSON, - SourceInformation: processor.SourceInformation{}, - }, - dochelper.DocNode(&processor.Document{ - Blob: []byte(`{ - "issuer": "google.com", - "info": "this is a cooler nested doc 3" - }`), Type: simpledoc.SimpleDocType, Format: processor.FormatJSON, SourceInformation: processor.SourceInformation{}, - })), - dochelper.DocNode(&processor.Document{ - Blob: []byte(`{ + }, + dochelper.DocNode(&processor.Document{ + Blob: []byte(`{ + "issuer": "google.com", + "info": "this is a cooler nested doc 3" + }`), + Type: simpledoc.SimpleDocType, + Format: processor.FormatJSON, + SourceInformation: processor.SourceInformation{}, + })), + dochelper.DocNode(&processor.Document{ + Blob: []byte(`{ "issuer": "google.com", "info": "this is a cooler nested doc 2", "nested": [{ @@ -199,24 +199,24 @@ func Test_SimpleDocProcessTest(t *testing.T) { "info": "this is a cooler nested doc 4" }] }`), - Type: simpledoc.SimpleDocType, - Format: processor.FormatJSON, - SourceInformation: processor.SourceInformation{}, - }, - dochelper.DocNode(&processor.Document{ - Blob: []byte(`{ - "issuer": "google.com", - "info": "this is a cooler nested doc 4" - }`), Type: simpledoc.SimpleDocType, Format: processor.FormatJSON, SourceInformation: processor.SourceInformation{}, - }))), - }, { + }, + dochelper.DocNode(&processor.Document{ + Blob: []byte(`{ + "issuer": "google.com", + "info": "this is a cooler nested doc 4" + }`), + Type: simpledoc.SimpleDocType, + Format: processor.FormatJSON, + SourceInformation: processor.SourceInformation{}, + }))), + }, { - name: "unpack assymetric test", - doc: processor.Document{ - Blob: []byte(`{ + name: "unpack assymetric test", + doc: processor.Document{ + Blob: []byte(`{ "issuer": "google.com", "info": "this is a cool document", "nested": [{ @@ -231,13 +231,13 @@ func Test_SimpleDocProcessTest(t *testing.T) { }] }] }`), - Type: simpledoc.SimpleDocType, - Format: processor.FormatJSON, - SourceInformation: processor.SourceInformation{}, - }, - expected: dochelper.DocNode( - &processor.Document{ //root - Blob: []byte(`{ + Type: simpledoc.SimpleDocType, + Format: processor.FormatJSON, + SourceInformation: processor.SourceInformation{}, + }, + expected: dochelper.DocNode( + &processor.Document{ //root + Blob: []byte(`{ "issuer": "google.com", "info": "this is a cool document", "nested": [{ @@ -252,21 +252,21 @@ func Test_SimpleDocProcessTest(t *testing.T) { }] }] }`), - Type: simpledoc.SimpleDocType, - Format: processor.FormatJSON, - SourceInformation: processor.SourceInformation{}, - }, - dochelper.DocNode(&processor.Document{ // child 1 - Blob: []byte(`{ + Type: simpledoc.SimpleDocType, + Format: processor.FormatJSON, + SourceInformation: processor.SourceInformation{}, + }, + dochelper.DocNode(&processor.Document{ // child 1 + Blob: []byte(`{ "issuer": "google.com", "info": "this is a cooler nested doc 1" }`), - Type: simpledoc.SimpleDocType, - Format: processor.FormatJSON, - SourceInformation: processor.SourceInformation{}, - }), - dochelper.DocNode(&processor.Document{ // child 2 - Blob: []byte(`{ + Type: simpledoc.SimpleDocType, + Format: processor.FormatJSON, + SourceInformation: processor.SourceInformation{}, + }), + dochelper.DocNode(&processor.Document{ // child 2 + Blob: []byte(`{ "issuer": "google.com", "info": "this is a cooler nested doc 2", "nested": [{ @@ -274,131 +274,131 @@ func Test_SimpleDocProcessTest(t *testing.T) { "info": "this is a cooler nested doc 4" }] }`), - Type: simpledoc.SimpleDocType, - Format: processor.FormatJSON, - SourceInformation: processor.SourceInformation{}, - }, - dochelper.DocNode(&processor.Document{ // child 2.1 - Blob: []byte(`{ - "issuer": "google.com", - "info": "this is a cooler nested doc 4" - }`), Type: simpledoc.SimpleDocType, Format: processor.FormatJSON, SourceInformation: processor.SourceInformation{}, - })), - ), - }, { - - name: "bad format", - doc: processor.Document{ - Blob: []byte(`{ NOT JSON YO + }, + dochelper.DocNode(&processor.Document{ // child 2.1 + Blob: []byte(`{ + "issuer": "google.com", + "info": "this is a cooler nested doc 4" + }`), + Type: simpledoc.SimpleDocType, + Format: processor.FormatJSON, + SourceInformation: processor.SourceInformation{}, + })), + ), + }, { + + name: "bad format", + doc: processor.Document{ + Blob: []byte(`{ NOT JSON YO "issuer": "google.com", "info": "this is a cool document" }`), - Type: simpledoc.SimpleDocType, - Format: processor.FormatJSON, - SourceInformation: processor.SourceInformation{}, - }, - expectErr: true, - }, { + Type: simpledoc.SimpleDocType, + Format: processor.FormatJSON, + SourceInformation: processor.SourceInformation{}, + }, + expectErr: true, + }, { - name: "bad format type", - doc: processor.Document{ - Blob: []byte(`{ + name: "bad format type", + doc: processor.Document{ + Blob: []byte(`{ "issuer": "google.com", "info": "this is a cool document" }`), - Type: simpledoc.SimpleDocType, - Format: "invalid-format", - SourceInformation: processor.SourceInformation{}, - }, - expectErr: true, - }, { + Type: simpledoc.SimpleDocType, + Format: "invalid-format", + SourceInformation: processor.SourceInformation{}, + }, + expectErr: true, + }, { - name: "bad document schema", - doc: processor.Document{ - // simpledoc requires issuer - Blob: []byte(`{ + name: "bad document schema", + doc: processor.Document{ + // simpledoc requires issuer + Blob: []byte(`{ "info": "this is a cool document" }`), - Type: simpledoc.SimpleDocType, - Format: processor.FormatJSON, - SourceInformation: processor.SourceInformation{}, - }, - expectErr: true, - }, { + Type: simpledoc.SimpleDocType, + Format: processor.FormatJSON, + SourceInformation: processor.SourceInformation{}, + }, + expectErr: true, + }, { - name: "bad schema type", - doc: processor.Document{ - Blob: []byte(`{ + name: "bad schema type", + doc: processor.Document{ + Blob: []byte(`{ "issuer": "google.com", "info": "this is a cool document" }`), - Type: "invalid-document-type", - Format: processor.FormatJSON, - SourceInformation: processor.SourceInformation{}, - }, - expectErr: true, - }, { + Type: "invalid-document-type", + Format: processor.FormatJSON, + SourceInformation: processor.SourceInformation{}, + }, + expectErr: true, + }, { - name: "unknown format", - doc: processor.Document{ - Blob: []byte(`{ NOT JSON YO + name: "unknown format", + doc: processor.Document{ + Blob: []byte(`{ NOT JSON YO "issuer": "google.com", "info": "this is a cool document" }`), - Type: processor.DocumentUnknown, - Format: processor.FormatUnknown, - SourceInformation: processor.SourceInformation{}, - }, - expectErr: true, - }, { + Type: processor.DocumentUnknown, + Format: processor.FormatUnknown, + SourceInformation: processor.SourceInformation{}, + }, + expectErr: true, + }, { - name: "unknown document", - doc: processor.Document{ - Blob: []byte(`{ + name: "unknown document", + doc: processor.Document{ + Blob: []byte(`{ "abc": "def" }`), - Type: processor.DocumentUnknown, - Format: processor.FormatJSON, - SourceInformation: processor.SourceInformation{}, - }, - expectErr: true, - }, { + Type: processor.DocumentUnknown, + Format: processor.FormatJSON, + SourceInformation: processor.SourceInformation{}, + }, + expectErr: true, + }, { - // misc - name: "propagate source info", - doc: processor.Document{ - Blob: []byte(`{ + // misc + name: "propagate source info", + doc: processor.Document{ + Blob: []byte(`{ "issuer": "google.com", "info": "this is a cool document" }`), - Type: simpledoc.SimpleDocType, - Format: processor.FormatJSON, - SourceInformation: processor.SourceInformation{ - Collector: "a-collector", - Source: "a-source", + Type: simpledoc.SimpleDocType, + Format: processor.FormatJSON, + SourceInformation: processor.SourceInformation{ + Collector: "a-collector", + Source: "a-source", + }, }, - }, - expected: dochelper.DocNode(&processor.Document{ - Blob: []byte(`{ + expected: dochelper.DocNode(&processor.Document{ + Blob: []byte(`{ "issuer": "google.com", "info": "this is a cool document" }`), - Type: simpledoc.SimpleDocType, - Format: processor.FormatJSON, - SourceInformation: processor.SourceInformation{ - Collector: "a-collector", - Source: "a-source", - }, - }), - }, { + Type: simpledoc.SimpleDocType, + Format: processor.FormatJSON, + SourceInformation: processor.SourceInformation{ + Collector: "a-collector", + Source: "a-source", + }, + }), + }, { - // misc - name: "propagate nested source info", - doc: processor.Document{ - Blob: []byte(`{ + // misc + name: "propagate nested source info", + doc: processor.Document{ + Blob: []byte(`{ "issuer": "google.com", "info": "this is a cool document", "nested": [{ @@ -409,16 +409,16 @@ func Test_SimpleDocProcessTest(t *testing.T) { "info": "this is a cooler nested doc 2" }] }`), - Type: simpledoc.SimpleDocType, - Format: processor.FormatJSON, - SourceInformation: processor.SourceInformation{ - Collector: "a-collector", - Source: "a-source", + Type: simpledoc.SimpleDocType, + Format: processor.FormatJSON, + SourceInformation: processor.SourceInformation{ + Collector: "a-collector", + Source: "a-source", + }, }, - }, - expected: dochelper.DocNode( - &processor.Document{ //root - Blob: []byte(`{ + expected: dochelper.DocNode( + &processor.Document{ //root + Blob: []byte(`{ "issuer": "google.com", "info": "this is a cool document", "nested": [{ @@ -429,82 +429,100 @@ func Test_SimpleDocProcessTest(t *testing.T) { "info": "this is a cooler nested doc 2" }] }`), - Type: simpledoc.SimpleDocType, - Format: processor.FormatJSON, - SourceInformation: processor.SourceInformation{ - Collector: "a-collector", - Source: "a-source", + Type: simpledoc.SimpleDocType, + Format: processor.FormatJSON, + SourceInformation: processor.SourceInformation{ + Collector: "a-collector", + Source: "a-source", + }, }, - }, - dochelper.DocNode(&processor.Document{ //child 1 - Blob: []byte(`{ + dochelper.DocNode(&processor.Document{ //child 1 + Blob: []byte(`{ "issuer": "google.com", "info": "this is a cooler nested doc 1" }`), - Type: simpledoc.SimpleDocType, - Format: processor.FormatJSON, - SourceInformation: processor.SourceInformation{ - Collector: "a-collector", - Source: "a-source", - }, - }), - dochelper.DocNode(&processor.Document{ //child 2 - Blob: []byte(`{ + Type: simpledoc.SimpleDocType, + Format: processor.FormatJSON, + SourceInformation: processor.SourceInformation{ + Collector: "a-collector", + Source: "a-source", + }, + }), + dochelper.DocNode(&processor.Document{ //child 2 + Blob: []byte(`{ "issuer": "google.com", "info": "this is a cooler nested doc 2" }`), - Type: simpledoc.SimpleDocType, - Format: processor.FormatJSON, - SourceInformation: processor.SourceInformation{ - Collector: "a-collector", - Source: "a-source", - }, - })), - }, { + Type: simpledoc.SimpleDocType, + Format: processor.FormatJSON, + SourceInformation: processor.SourceInformation{ + Collector: "a-collector", + Source: "a-source", + }, + })), + }, { - // preprocessor tests - name: "preprocessor on format JSON", - doc: processor.Document{ - Blob: []byte(`{ + // preprocessor tests + name: "preprocessor on format JSON", + doc: processor.Document{ + Blob: []byte(`{ "issuer": "google.com", "info": "this is a cool document" }`), - Type: simpledoc.SimpleDocType, - Format: processor.FormatUnknown, - SourceInformation: processor.SourceInformation{}, - }, - expected: dochelper.DocNode(&processor.Document{ - Blob: []byte(`{ + Type: simpledoc.SimpleDocType, + Format: processor.FormatUnknown, + SourceInformation: processor.SourceInformation{}, + }, + expected: dochelper.DocNode(&processor.Document{ + Blob: []byte(`{ "issuer": "google.com", "info": "this is a cool document" }`), - Type: simpledoc.SimpleDocType, - Format: processor.FormatJSON, - SourceInformation: processor.SourceInformation{}, - }), - }, { + Type: simpledoc.SimpleDocType, + Format: processor.FormatJSON, + SourceInformation: processor.SourceInformation{}, + }), + }, { - name: "preprocessor on simpledoc", - doc: processor.Document{ - Blob: []byte(`{ + name: "preprocessor on simpledoc", + doc: processor.Document{ + Blob: []byte(`{ "issuer": "google.com", "info": "this is a cool document" }`), - Type: processor.DocumentUnknown, - Format: processor.FormatUnknown, - SourceInformation: processor.SourceInformation{}, - }, - expected: dochelper.DocNode(&processor.Document{ - Blob: []byte(`{ + Type: processor.DocumentUnknown, + Format: processor.FormatUnknown, + SourceInformation: processor.SourceInformation{}, + }, + expected: dochelper.DocNode(&processor.Document{ + Blob: []byte(`{ "issuer": "google.com", "info": "this is a cool document" }`), - Type: simpledoc.SimpleDocType, - Format: processor.FormatJSON, - SourceInformation: processor.SourceInformation{}, - }), - }, - } + Type: simpledoc.SimpleDocType, + Format: processor.FormatJSON, + SourceInformation: processor.SourceInformation{}, + }), + }, { + name: "JsonBz2Ingestion", + doc: processor.Document{ + Blob: testdata.CycloneDXBz2Example, + Type: processor.DocumentCycloneDX, + Format: processor.FormatJSON, + SourceInformation: processor.SourceInformation{ + Source: "exampledata/busybox-cyclonedx.json.bz2", + }, + }, + expected: dochelper.DocNode(&processor.Document{ + Blob: testdata.CycloneDXBusyboxExample, + Type: processor.DocumentCycloneDX, + Format: processor.FormatJSON, + Encoding: processor.EncodingBzip2, + SourceInformation: processor.SourceInformation{ + Source: "exampledata/busybox-cyclonedx.json.bz2", + }, + }), + }} // Register err := RegisterDocumentProcessor(&simpledoc.SimpleDocProc{}, simpledoc.SimpleDocType)