github.com/google/osv-scalibr@v0.4.1/clients/datasource/maven_registry_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 datasource_test 16 17 import ( 18 "bytes" 19 "os" 20 "path/filepath" 21 "reflect" 22 "testing" 23 24 "deps.dev/util/maven" 25 "github.com/google/osv-scalibr/clients/clienttest" 26 "github.com/google/osv-scalibr/clients/datasource" 27 ) 28 29 func TestGetProject(t *testing.T) { 30 srv := clienttest.NewMockHTTPServer(t) 31 client, _ := datasource.NewDefaultMavenRegistryAPIClient(t.Context(), srv.URL) 32 srv.SetResponse(t, "org/example/x.y.z/1.0.0/x.y.z-1.0.0.pom", []byte(` 33 <project> 34 <groupId>org.example</groupId> 35 <artifactId>x.y.z</artifactId> 36 <version>1.0.0</version> 37 </project> 38 `)) 39 40 got, err := client.GetProject(t.Context(), "org.example", "x.y.z", "1.0.0") 41 if err != nil { 42 t.Fatalf("failed to get Maven project %s:%s verion %s: %v", "org.example", "x.y.z", "1.0.0", err) 43 } 44 want := maven.Project{ 45 ProjectKey: maven.ProjectKey{ 46 GroupID: "org.example", 47 ArtifactID: "x.y.z", 48 Version: "1.0.0", 49 }, 50 } 51 if !reflect.DeepEqual(got, want) { 52 t.Errorf("GetProject(%s, %s, %s):\ngot %v\nwant %v\n", "org.example", "x.y.z", "1.0.0", got, want) 53 } 54 } 55 56 func TestGetProjectSnapshot(t *testing.T) { 57 srv := clienttest.NewMockHTTPServer(t) 58 client, _ := datasource.NewMavenRegistryAPIClient(t.Context(), datasource.MavenRegistry{URL: srv.URL, SnapshotsEnabled: true}, "", false) 59 srv.SetResponse(t, "org/example/x.y.z/3.3.1-SNAPSHOT/maven-metadata.xml", []byte(` 60 <metadata> 61 <groupId>org.example</groupId> 62 <artifactId>x.y.z</artifactId> 63 <versioning> 64 <snapshot> 65 <timestamp>20230302.052731</timestamp> 66 <buildNumber>9</buildNumber> 67 </snapshot> 68 <lastUpdated>20230302052731</lastUpdated> 69 <snapshotVersions> 70 <snapshotVersion> 71 <extension>jar</extension> 72 <value>3.3.1-20230302.052731-9</value> 73 <updated>20230302052731</updated> 74 </snapshotVersion> 75 <snapshotVersion> 76 <extension>pom</extension> 77 <value>3.3.1-20230302.052731-9</value> 78 <updated>20230302052731</updated> 79 </snapshotVersion> 80 </snapshotVersions> 81 </versioning> 82 </metadata> 83 `)) 84 srv.SetResponse(t, "org/example/x.y.z/3.3.1-SNAPSHOT/x.y.z-3.3.1-20230302.052731-9.pom", []byte(` 85 <project> 86 <groupId>org.example</groupId> 87 <artifactId>x.y.z</artifactId> 88 <version>3.3.1-SNAPSHOT</version> 89 </project> 90 `)) 91 92 got, err := client.GetProject(t.Context(), "org.example", "x.y.z", "3.3.1-SNAPSHOT") 93 if err != nil { 94 t.Fatalf("failed to get Maven project %s:%s verion %s: %v", "org.example", "x.y.z", "3.3.1-SNAPSHOT", err) 95 } 96 want := maven.Project{ 97 ProjectKey: maven.ProjectKey{ 98 GroupID: "org.example", 99 ArtifactID: "x.y.z", 100 Version: "3.3.1-SNAPSHOT", 101 }, 102 } 103 if !reflect.DeepEqual(got, want) { 104 t.Errorf("GetProject(%s, %s, %s):\ngot %v\nwant %v\n", "org.example", "x.y.z", "3.3.1-SNAPSHOT", got, want) 105 } 106 } 107 108 func TestMultipleRegistry(t *testing.T) { 109 dft := clienttest.NewMockHTTPServer(t) 110 client, _ := datasource.NewDefaultMavenRegistryAPIClient(t.Context(), dft.URL) 111 dft.SetResponse(t, "org/example/x.y.z/maven-metadata.xml", []byte(` 112 <metadata> 113 <groupId>org.example</groupId> 114 <artifactId>x.y.z</artifactId> 115 <versioning> 116 <latest>3.0.0</latest> 117 <release>3.0.0</release> 118 <versions> 119 <version>2.0.0</version> 120 <version>3.0.0</version> 121 </versions> 122 </versioning> 123 </metadata> 124 `)) 125 dft.SetResponse(t, "org/example/x.y.z/2.0.0/x.y.z-2.0.0.pom", []byte(` 126 <project> 127 <groupId>org.example</groupId> 128 <artifactId>x.y.z</artifactId> 129 <version>2.0.0</version> 130 </project> 131 `)) 132 dft.SetResponse(t, "org/example/x.y.z/3.0.0/x.y.z-3.0.0.pom", []byte(` 133 <project> 134 <groupId>org.example</groupId> 135 <artifactId>x.y.z</artifactId> 136 <version>3.0.0</version> 137 </project> 138 `)) 139 140 srv := clienttest.NewMockHTTPServer(t) 141 if err := client.AddRegistry(t.Context(), datasource.MavenRegistry{URL: srv.URL, ReleasesEnabled: true}); err != nil { 142 t.Fatalf("failed to add registry %s: %v", srv.URL, err) 143 } 144 srv.SetResponse(t, "org/example/x.y.z/maven-metadata.xml", []byte(` 145 <metadata> 146 <groupId>org.example</groupId> 147 <artifactId>x.y.z</artifactId> 148 <versioning> 149 <latest>2.0.0</latest> 150 <release>2.0.0</release> 151 <versions> 152 <version>1.0.0</version> 153 <version>2.0.0</version> 154 </versions> 155 </versioning> 156 </metadata> 157 `)) 158 srv.SetResponse(t, "org/example/x.y.z/1.0.0/x.y.z-1.0.0.pom", []byte(` 159 <project> 160 <groupId>org.example</groupId> 161 <artifactId>x.y.z</artifactId> 162 <version>1.0.0</version> 163 </project> 164 `)) 165 srv.SetResponse(t, "org/example/x.y.z/2.0.0/x.y.z-2.0.0.pom", []byte(` 166 <project> 167 <groupId>org.example</groupId> 168 <artifactId>x.y.z</artifactId> 169 <version>2.0.0</version> 170 </project> 171 `)) 172 173 gotProj, err := client.GetProject(t.Context(), "org.example", "x.y.z", "1.0.0") 174 if err != nil { 175 t.Fatalf("failed to get Maven project %s:%s verion %s: %v", "org.example", "x.y.z", "1.0.0", err) 176 } 177 wantProj := maven.Project{ 178 ProjectKey: maven.ProjectKey{ 179 GroupID: "org.example", 180 ArtifactID: "x.y.z", 181 Version: "1.0.0", 182 }, 183 } 184 if !reflect.DeepEqual(gotProj, wantProj) { 185 t.Errorf("GetProject(%s, %s, %s):\ngot %v\nwant %v\n", "org.example", "x.y.z", "1.0.0", gotProj, wantProj) 186 } 187 188 gotVersions, err := client.GetVersions(t.Context(), "org.example", "x.y.z") 189 if err != nil { 190 t.Fatalf("failed to get versions for Maven package %s:%s: %v", "org.example", "x.y.z", err) 191 } 192 wantVersions := []maven.String{"1.0.0", "2.0.0", "3.0.0"} 193 if !reflect.DeepEqual(gotVersions, wantVersions) { 194 t.Errorf("GetVersions(%s, %s):\ngot %v\nwant %v\n", "org.example", "x.y.z", gotVersions, wantVersions) 195 } 196 } 197 198 func TestUpdateDefaultRegistry(t *testing.T) { 199 dft := clienttest.NewMockHTTPServer(t) 200 client, _ := datasource.NewDefaultMavenRegistryAPIClient(t.Context(), dft.URL) 201 dft.SetResponse(t, "org/example/x.y.z/maven-metadata.xml", []byte(` 202 <metadata> 203 <groupId>org.example</groupId> 204 <artifactId>x.y.z</artifactId> 205 <versioning> 206 <latest>1.0.0</latest> 207 <release>1.0.0</release> 208 <versions> 209 <version>1.0.0</version> 210 </versions> 211 </versioning> 212 </metadata> 213 `)) 214 215 gotVersions, err := client.GetVersions(t.Context(), "org.example", "x.y.z") 216 if err != nil { 217 t.Fatalf("failed to get versions for Maven package %s:%s: %v", "org.example", "x.y.z", err) 218 } 219 wantVersions := []maven.String{"1.0.0"} 220 if !reflect.DeepEqual(gotVersions, wantVersions) { 221 t.Errorf("GetVersions(%s, %s):\ngot %v\nwant %v\n", "org.example", "x.y.z", gotVersions, wantVersions) 222 } 223 224 srv := clienttest.NewMockHTTPServer(t) 225 if err := client.AddRegistry(t.Context(), datasource.MavenRegistry{URL: srv.URL, ID: "default", ReleasesEnabled: true}); err != nil { 226 t.Fatalf("failed to add registry %s: %v", srv.URL, err) 227 } 228 srv.SetResponse(t, "org/example/x.y.z/maven-metadata.xml", []byte(` 229 <metadata> 230 <groupId>org.example</groupId> 231 <artifactId>x.y.z</artifactId> 232 <versioning> 233 <latest>2.0.0</latest> 234 <release>2.0.0</release> 235 <versions> 236 <version>2.0.0</version> 237 </versions> 238 </versioning> 239 </metadata> 240 `)) 241 242 gotVersions, err = client.GetVersions(t.Context(), "org.example", "x.y.z") 243 if err != nil { 244 t.Fatalf("failed to get versions for Maven package %s:%s: %v", "org.example", "x.y.z", err) 245 } 246 wantVersions = []maven.String{"2.0.0"} 247 if !reflect.DeepEqual(gotVersions, wantVersions) { 248 t.Errorf("GetVersions(%s, %s):\ngot %v\nwant %v\n", "org.example", "x.y.z", gotVersions, wantVersions) 249 } 250 } 251 252 func TestMavenLocalRegistry(t *testing.T) { 253 tempDir := t.TempDir() 254 srv := clienttest.NewMockHTTPServer(t) 255 client, _ := datasource.NewMavenRegistryAPIClient(t.Context(), datasource.MavenRegistry{URL: srv.URL, ReleasesEnabled: true}, tempDir, false) 256 path := "org/example/x.y.z/1.0.0/x.y.z-1.0.0.pom" 257 resp := []byte(` 258 <project> 259 <groupId>org.example</groupId> 260 <artifactId>x.y.z</artifactId> 261 <version>1.0.0</version> 262 </project>`) 263 srv.SetResponse(t, path, resp) 264 265 _, err := client.GetProject(t.Context(), "org.example", "x.y.z", "1.0.0") 266 if err != nil { 267 t.Fatalf("failed to get Maven project %s:%s verion %s: %v", "org.example", "x.y.z", "1.0.0", err) 268 } 269 270 // Check that the pom file is stored locally. 271 filePath := filepath.Join(tempDir, "maven", path) 272 content, err := os.ReadFile(filePath) 273 if err != nil { 274 t.Fatalf("failed to read file: %v", err) 275 } 276 if !bytes.Equal(content, resp) { 277 t.Errorf("unexpected file content: got %s, want %s", string(content), string(resp)) 278 } 279 }