github.com/google/osv-scalibr@v0.4.1/binary/proto/package_vuln_test.go (about)

     1  // Copyright 2025 Google LLC
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package proto_test
    16  
    17  import (
    18  	"errors"
    19  	"testing"
    20  
    21  	"github.com/google/go-cmp/cmp"
    22  	"github.com/google/go-cmp/cmp/cmpopts"
    23  	"github.com/google/go-cpy/cpy"
    24  	"github.com/google/osv-scalibr/binary/proto"
    25  	"github.com/google/osv-scalibr/extractor"
    26  	"github.com/google/osv-scalibr/inventory"
    27  	"github.com/google/osv-scalibr/inventory/vex"
    28  	"google.golang.org/protobuf/testing/protocmp"
    29  
    30  	spb "github.com/google/osv-scalibr/binary/proto/scan_result_go_proto"
    31  	osvpb "github.com/ossf/osv-schema/bindings/go/osvschema"
    32  )
    33  
    34  var (
    35  	idToPkg = map[string]*extractor.Package{
    36  		"1": purlDPKGAnnotationPackage,
    37  	}
    38  	pkgToID = func() map[*extractor.Package]string {
    39  		m := make(map[*extractor.Package]string)
    40  		for id, pkg := range idToPkg {
    41  			m[pkg] = id
    42  		}
    43  		return m
    44  	}()
    45  
    46  	pkgVulnStruct1 = &inventory.PackageVuln{
    47  		Vulnerability: &osvpb.Vulnerability{},
    48  		Package:       purlDPKGAnnotationPackage,
    49  		Plugins:       []string{"cve/cve-1234-finder", "cve/cve-1234-enricher"},
    50  		ExploitabilitySignals: []*vex.FindingExploitabilitySignal{{
    51  			Plugin:        "some-plugin",
    52  			Justification: vex.ComponentNotPresent,
    53  		}},
    54  	}
    55  	pkgVulnProto1 = &spb.PackageVuln{
    56  		Vuln:      &osvpb.Vulnerability{},
    57  		PackageId: "1",
    58  		Plugins:   []string{"cve/cve-1234-finder", "cve/cve-1234-enricher"},
    59  		ExploitabilitySignals: []*spb.FindingExploitabilitySignal{
    60  			{
    61  				Plugin:        "some-plugin",
    62  				Justification: spb.VexJustification_COMPONENT_NOT_PRESENT,
    63  			},
    64  		},
    65  	}
    66  )
    67  
    68  func TestPackageVulnSetup(t *testing.T) {
    69  	if len(pkgToID) != len(idToPkg) {
    70  		t.Fatalf("pkgToID and idToPkg have different lengths: %d != %d", len(pkgToID), len(idToPkg))
    71  	}
    72  	for pkg, id := range pkgToID {
    73  		otherPkg, ok := idToPkg[id]
    74  		if !ok {
    75  			t.Fatalf("package with ID %q not found in idToPkg map", id)
    76  		}
    77  		if pkg != otherPkg {
    78  			t.Fatalf("package with ID %q has different pointer value %v", id, otherPkg)
    79  		}
    80  	}
    81  }
    82  
    83  func TestPackageVulnToProto(t *testing.T) {
    84  	copier := cpy.New(
    85  		cpy.IgnoreAllUnexported(),
    86  	)
    87  
    88  	testCases := []struct {
    89  		desc    string
    90  		pkgVuln *inventory.PackageVuln
    91  		want    *spb.PackageVuln
    92  		wantErr error
    93  	}{
    94  		{
    95  			desc:    "nil",
    96  			pkgVuln: nil,
    97  			want:    nil,
    98  		},
    99  		{
   100  			desc:    "success",
   101  			pkgVuln: pkgVulnStruct1,
   102  			want:    pkgVulnProto1,
   103  		},
   104  		{
   105  			desc: "missing_package",
   106  			pkgVuln: func(p *inventory.PackageVuln) *inventory.PackageVuln {
   107  				p = copier.Copy(p).(*inventory.PackageVuln)
   108  				p.Package = nil
   109  				return p
   110  			}(pkgVulnStruct1),
   111  			want: func(p *spb.PackageVuln) *spb.PackageVuln {
   112  				p = copier.Copy(p).(*spb.PackageVuln)
   113  				p.PackageId = ""
   114  				return p
   115  			}(pkgVulnProto1),
   116  		},
   117  	}
   118  
   119  	for _, tc := range testCases {
   120  		t.Run(tc.desc, func(t *testing.T) {
   121  			got, err := proto.PackageVulnToProto(tc.pkgVuln, pkgToID)
   122  			if !errors.Is(err, tc.wantErr) {
   123  				t.Fatalf("PackageVulnToProto(%v, %v) returned error %v, want error %v", tc.pkgVuln, pkgToID, err, tc.wantErr)
   124  			}
   125  
   126  			if diff := cmp.Diff(tc.want, got, protocmp.Transform()); diff != "" {
   127  				t.Fatalf("PackageVulnToProto(%+v, %+v) returned diff (-want +got):\n%s", tc.pkgVuln, pkgToID, diff)
   128  			}
   129  		})
   130  	}
   131  }
   132  
   133  func TestPackageVulnToStruct(t *testing.T) {
   134  	copier := cpy.New(
   135  		cpy.IgnoreAllUnexported(),
   136  	)
   137  
   138  	testCases := []struct {
   139  		desc    string
   140  		pkgVuln *spb.PackageVuln
   141  		idToPkg map[string]*extractor.Package
   142  		want    *inventory.PackageVuln
   143  		wantErr error
   144  	}{
   145  		{
   146  			desc:    "nil",
   147  			pkgVuln: nil,
   148  			want:    nil,
   149  		},
   150  		{
   151  			desc:    "success",
   152  			pkgVuln: pkgVulnProto1,
   153  			idToPkg: idToPkg,
   154  			want:    pkgVulnStruct1,
   155  		},
   156  		{
   157  			desc: "missing_package_ID",
   158  			pkgVuln: func(p *spb.PackageVuln) *spb.PackageVuln {
   159  				p = copier.Copy(p).(*spb.PackageVuln)
   160  				p.PackageId = ""
   161  				return p
   162  			}(pkgVulnProto1),
   163  			idToPkg: idToPkg,
   164  			want:    nil,
   165  			wantErr: cmpopts.AnyError,
   166  		},
   167  	}
   168  
   169  	for _, tc := range testCases {
   170  		t.Run(tc.desc, func(t *testing.T) {
   171  			got, err := proto.PackageVulnToStruct(tc.pkgVuln, tc.idToPkg)
   172  			if diff := cmp.Diff(tc.wantErr, err, cmpopts.EquateErrors()); diff != "" {
   173  				t.Fatalf("PackageVulnToStruct(%v, %v) returned error %v, want error %v", tc.pkgVuln, tc.idToPkg, err, tc.wantErr)
   174  			}
   175  			if diff := cmp.Diff(tc.want, got, protocmp.Transform()); diff != "" {
   176  				t.Fatalf("PackageVulnToStruct(%v, %v) returned diff (-want +got):\n%s", tc.pkgVuln, tc.idToPkg, diff)
   177  			}
   178  		})
   179  	}
   180  }