github.com/google/osv-scalibr@v0.4.1/guidedremediation/internal/manifest/python/requirements_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 python 16 17 import ( 18 "os" 19 "path/filepath" 20 "testing" 21 22 "deps.dev/util/resolve" 23 "github.com/google/go-cmp/cmp" 24 "github.com/google/osv-scalibr/fs" 25 "github.com/google/osv-scalibr/guidedremediation/internal/manifest" 26 "github.com/google/osv-scalibr/guidedremediation/result" 27 ) 28 29 func TestReadRequirements(t *testing.T) { 30 fsys := fs.DirFS("./testdata/requirements") 31 pypiRW, _ := GetRequirementsReadWriter() 32 got, err := pypiRW.Read("requirements.txt", fsys) 33 if err != nil { 34 t.Fatalf("error reading manifest: %v", err) 35 } 36 want := testManifest{ 37 FilePath: "requirements.txt", 38 Root: resolve.Version{ 39 VersionKey: resolve.VersionKey{ 40 PackageKey: resolve.PackageKey{ 41 System: resolve.PyPI, 42 Name: "myproject", 43 }, 44 VersionType: resolve.Concrete, 45 Version: "1.0.0", 46 }, 47 }, 48 System: resolve.PyPI, 49 Requirements: []resolve.RequirementVersion{ 50 { 51 VersionKey: resolve.VersionKey{ 52 PackageKey: resolve.PackageKey{ 53 System: resolve.PyPI, 54 Name: "pytest", 55 }, 56 VersionType: resolve.Requirement, 57 }, 58 }, 59 { 60 VersionKey: resolve.VersionKey{ 61 PackageKey: resolve.PackageKey{ 62 System: resolve.PyPI, 63 Name: "pytest-cov", 64 }, 65 VersionType: resolve.Requirement, 66 }, 67 }, 68 { 69 VersionKey: resolve.VersionKey{ 70 PackageKey: resolve.PackageKey{ 71 System: resolve.PyPI, 72 Name: "beautifulsoup4", 73 }, 74 VersionType: resolve.Requirement, 75 }, 76 }, 77 78 { 79 VersionKey: resolve.VersionKey{ 80 PackageKey: resolve.PackageKey{ 81 System: resolve.PyPI, 82 Name: "docopt", 83 }, 84 VersionType: resolve.Requirement, 85 Version: "== 0.6.1", 86 }, 87 }, 88 { 89 VersionKey: resolve.VersionKey{ 90 PackageKey: resolve.PackageKey{ 91 System: resolve.PyPI, 92 Name: "requests", 93 }, 94 VersionType: resolve.Requirement, 95 Version: ">= 2.8.1, == 2.8.*", 96 }, 97 }, 98 99 { 100 VersionKey: resolve.VersionKey{ 101 PackageKey: resolve.PackageKey{ 102 System: resolve.PyPI, 103 Name: "keyring", 104 }, 105 VersionType: resolve.Requirement, 106 Version: ">= 4.1.1", 107 }, 108 }, 109 { 110 VersionKey: resolve.VersionKey{ 111 PackageKey: resolve.PackageKey{ 112 System: resolve.PyPI, 113 Name: "coverage", 114 }, 115 VersionType: resolve.Requirement, 116 Version: "!= 3.5", 117 }, 118 }, 119 120 { 121 VersionKey: resolve.VersionKey{ 122 PackageKey: resolve.PackageKey{ 123 System: resolve.PyPI, 124 Name: "Mopidy-Dirble", 125 }, 126 VersionType: resolve.Requirement, 127 Version: "~=1.1", 128 }, 129 }, 130 }, 131 Groups: map[manifest.RequirementKey][]string{}, 132 } 133 checkManifest(t, "Manifest", got, want) 134 } 135 136 func TestWriteRequirements(t *testing.T) { 137 rw, _ := GetRequirementsReadWriter() 138 fsys := fs.DirFS("./testdata/requirements") 139 manif, err := rw.Read("requirements.txt", fsys) 140 if err != nil { 141 t.Fatalf("error reading manifest: %v", err) 142 } 143 144 patches := []result.Patch{ 145 { 146 PackageUpdates: []result.PackageUpdate{ 147 { 148 Name: "docopt", 149 VersionFrom: "==0.6.1", 150 VersionTo: "==0.6.2", 151 }, 152 }, 153 }, 154 { 155 PackageUpdates: []result.PackageUpdate{ 156 { 157 Name: "requests", 158 VersionFrom: ">=2.8.1,==2.8.*", 159 VersionTo: ">=2.32.4,<3.0.0", 160 }, 161 }, 162 }, 163 { 164 PackageUpdates: []result.PackageUpdate{ 165 { 166 Name: "mopidy-dirble", 167 VersionFrom: "~=1.1", 168 VersionTo: ">=1.3.0,<2.0.0", 169 }, 170 }, 171 }, 172 } 173 outDir := t.TempDir() 174 outFile := filepath.Join(outDir, "requirements.txt") 175 176 if err := rw.Write(manif, fsys, patches, outFile); err != nil { 177 t.Fatalf("failed to write requirements.txt: %v", err) 178 } 179 180 got, err := os.ReadFile(outFile) 181 if err != nil { 182 t.Fatalf("failed to read got requirements.txt: %v", err) 183 } 184 want, err := os.ReadFile(filepath.Join("./testdata/requirements", "want.requirements.txt")) 185 if err != nil { 186 t.Fatalf("failed to read want requirements.txt: %v", err) 187 } 188 if diff := cmp.Diff(want, got); diff != "" { 189 t.Errorf("requirements.txt (-want +got):\n%s", diff) 190 } 191 }