github.com/google/osv-scalibr@v0.4.1/guidedremediation/internal/strategy/override/override_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 override_test
    16  
    17  import (
    18  	"encoding/json"
    19  	"os"
    20  	"testing"
    21  
    22  	"deps.dev/util/resolve/dep"
    23  	"github.com/google/go-cmp/cmp"
    24  	"github.com/google/go-cmp/cmp/cmpopts"
    25  	"github.com/google/osv-scalibr/clients/clienttest"
    26  	"github.com/google/osv-scalibr/clients/datasource"
    27  	scalibrfs "github.com/google/osv-scalibr/fs"
    28  	"github.com/google/osv-scalibr/guidedremediation/internal/manifest"
    29  	"github.com/google/osv-scalibr/guidedremediation/internal/manifest/maven"
    30  	"github.com/google/osv-scalibr/guidedremediation/internal/remediation"
    31  	"github.com/google/osv-scalibr/guidedremediation/internal/strategy/override"
    32  	"github.com/google/osv-scalibr/guidedremediation/internal/vulnenrichertest"
    33  	"github.com/google/osv-scalibr/guidedremediation/options"
    34  	"github.com/google/osv-scalibr/guidedremediation/result"
    35  	"github.com/google/osv-scalibr/guidedremediation/upgrade"
    36  )
    37  
    38  func TestComputePatches(t *testing.T) {
    39  	client, _ := datasource.NewDefaultMavenRegistryAPIClient(t.Context(), "")
    40  	mavenRW, err := maven.GetReadWriter(client)
    41  	if err != nil {
    42  		t.Fatalf("failed getting ReadWriter: %v", err)
    43  	}
    44  
    45  	tests := []struct {
    46  		name         string
    47  		universeFile string
    48  		vulnsFile    string
    49  		manifestPath string
    50  		readWriter   manifest.ReadWriter
    51  		opts         options.RemediationOptions
    52  		wantFile     string
    53  	}{
    54  		{
    55  			name:         "maven-zeppelin-server",
    56  			universeFile: "testdata/zeppelin-server/universe.yaml",
    57  			vulnsFile:    "testdata/zeppelin-server/vulnerabilities.json",
    58  			manifestPath: "zeppelin-server/pom.xml",
    59  			readWriter:   mavenRW,
    60  			opts:         options.DefaultRemediationOptions(),
    61  			wantFile:     "testdata/zeppelin-server/patches.json",
    62  		},
    63  		{
    64  			name:         "maven-classifier",
    65  			universeFile: "testdata/maven-classifier/universe.yaml",
    66  			vulnsFile:    "testdata/maven-classifier/vulnerabilities.json",
    67  			manifestPath: "maven-classifier/pom.xml",
    68  			readWriter:   mavenRW,
    69  			opts:         options.DefaultRemediationOptions(),
    70  			wantFile:     "testdata/maven-classifier/patches.json",
    71  		},
    72  		{
    73  			name:         "maven-management-only",
    74  			universeFile: "testdata/zeppelin-server/universe.yaml",
    75  			vulnsFile:    "testdata/zeppelin-server/vulnerabilities.json",
    76  			manifestPath: "zeppelin-server/parent/pom.xml",
    77  			readWriter:   mavenRW,
    78  			opts: options.RemediationOptions{
    79  				ResolutionOptions: options.ResolutionOptions{
    80  					MavenManagement: true,
    81  				},
    82  				DevDeps:       true,
    83  				MaxDepth:      -1,
    84  				UpgradeConfig: upgrade.NewConfig(),
    85  			},
    86  			wantFile: "testdata/zeppelin-server/parent/patches.json",
    87  		},
    88  		{
    89  			name:         "workaround-maven-guava-none-to-jre",
    90  			universeFile: "testdata/workaround/universe.yaml",
    91  			vulnsFile:    "testdata/workaround/vulnerabilities.json",
    92  			manifestPath: "workaround/guava/none-to-jre/pom.xml",
    93  			readWriter:   mavenRW,
    94  			opts:         options.DefaultRemediationOptions(),
    95  			wantFile:     "testdata/workaround/guava/none-to-jre/patches.json",
    96  		},
    97  		{
    98  			name:         "workaround-maven-guava-jre-to-jre",
    99  			universeFile: "testdata/workaround/universe.yaml",
   100  			vulnsFile:    "testdata/workaround/vulnerabilities.json",
   101  			manifestPath: "workaround/guava/jre-to-jre/pom.xml",
   102  			readWriter:   mavenRW,
   103  			opts:         options.DefaultRemediationOptions(),
   104  			wantFile:     "testdata/workaround/guava/jre-to-jre/patches.json",
   105  		},
   106  		{
   107  			name:         "workaround-maven-guava-android-to-android",
   108  			universeFile: "testdata/workaround/universe.yaml",
   109  			vulnsFile:    "testdata/workaround/vulnerabilities.json",
   110  			manifestPath: "workaround/guava/android-to-android/pom.xml",
   111  			readWriter:   mavenRW,
   112  			opts:         options.DefaultRemediationOptions(),
   113  			wantFile:     "testdata/workaround/guava/android-to-android/patches.json",
   114  		},
   115  		{
   116  			name:         "workaround-commons",
   117  			universeFile: "testdata/workaround/universe.yaml",
   118  			vulnsFile:    "testdata/workaround/vulnerabilities.json",
   119  			manifestPath: "workaround/commons/pom.xml",
   120  			readWriter:   mavenRW,
   121  			opts:         options.DefaultRemediationOptions(),
   122  			wantFile:     "testdata/workaround/commons/patches.json",
   123  		},
   124  	}
   125  
   126  	for _, tt := range tests {
   127  		t.Run(tt.name, func(t *testing.T) {
   128  			wantFile, err := os.Open(tt.wantFile)
   129  			if err != nil {
   130  				t.Fatalf("failed opening wantFile: %v", err)
   131  			}
   132  			defer wantFile.Close()
   133  			var want []result.Patch
   134  			if err := json.NewDecoder(wantFile).Decode(&want); err != nil {
   135  				t.Fatalf("failed decoding wantFile: %v", err)
   136  			}
   137  
   138  			fsys := scalibrfs.DirFS("./testdata")
   139  			m, err := tt.readWriter.Read(tt.manifestPath, fsys)
   140  			if err != nil {
   141  				t.Fatalf("failed reading manifest: %v", err)
   142  			}
   143  
   144  			cl := clienttest.NewMockResolutionClient(t, tt.universeFile)
   145  			ve := vulnenrichertest.NewMockVulnerabilityEnricher(t, tt.vulnsFile)
   146  			resolved, err := remediation.ResolveManifest(t.Context(), cl, ve, m, &tt.opts)
   147  			if err != nil {
   148  				t.Fatalf("failed resolving manifest: %v", err)
   149  			}
   150  			gotFull, err := override.ComputePatches(t.Context(), cl, ve, resolved, &tt.opts)
   151  			if err != nil {
   152  				t.Fatalf("failed computing patches: %v", err)
   153  			}
   154  			got := gotFull.Patches
   155  
   156  			// Type is not in exported to json, so just ignore it.
   157  			if diff := cmp.Diff(want, got, cmpopts.EquateEmpty(), cmpopts.IgnoreTypes(dep.Type{})); diff != "" {
   158  				t.Errorf("ComputePatches: unexpected diff (-want +got):\n%s", diff)
   159  			}
   160  		})
   161  	}
   162  }