diff --git a/registry/registry-client/src/test/java/com/salesforce/multicloudj/registry/client/AbstractRegistryIT.java b/registry/registry-client/src/test/java/com/salesforce/multicloudj/registry/client/AbstractRegistryIT.java new file mode 100644 index 000000000..41b406a3a --- /dev/null +++ b/registry/registry-client/src/test/java/com/salesforce/multicloudj/registry/client/AbstractRegistryIT.java @@ -0,0 +1,102 @@ +package com.salesforce.multicloudj.registry.client; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import com.salesforce.multicloudj.common.util.common.TestsUtil; +import com.salesforce.multicloudj.registry.driver.AbstractRegistry; +import com.salesforce.multicloudj.registry.model.Image; +import java.io.InputStream; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; +import org.junit.jupiter.api.TestInstance; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +public abstract class AbstractRegistryIT { + + // Define the Harness interface + public interface Harness extends AutoCloseable { + AbstractRegistry createRegistryDriver(); + + String getEndpoint(); + + String getProviderId(); + + int getPort(); + + String getTestImageRef(); + + default String[] getWiremockExtensions() { + return new String[0]; + } + } + + protected abstract Harness createHarness(); + + private Harness harness; + protected AbstractRegistry registry; + + @BeforeAll + public void initializeWireMockServer() { + harness = createHarness(); + TestsUtil.startWireMockServer( + "src/test/resources", harness.getPort(), harness.getWiremockExtensions()); + } + + @AfterAll + public void shutdownWireMockServer() throws Exception { + TestsUtil.stopWireMockServer(); + harness.close(); + } + + @BeforeEach + public void setupTestEnvironment(TestInfo testInfo) { + String testClassName = testInfo.getTestClass().map(Class::getSimpleName).orElse("Unknown"); + String testMethodName = + testInfo.getTestMethod().map(java.lang.reflect.Method::getName).orElse("unknown"); + TestsUtil.startWireMockRecording(harness.getEndpoint(), testClassName, testMethodName); + registry = harness.createRegistryDriver(); + } + + @AfterEach + public void cleanupTestEnvironment() throws Exception { + TestsUtil.stopWireMockRecording(); + if (registry != null) { + registry.close(); + } + } + + @Test + public void testPull() { + String imageRef = harness.getTestImageRef(); + Image image = registry.pull(imageRef); + + assertNotNull(image, "Pulled image should not be null"); + assertNotNull(image.getDigest(), "Image digest should not be null"); + assertNotNull(image.getLayers(), "Layers should not be null"); + assertFalse(image.getLayers().isEmpty(), "Image should have at least one layer"); + } + + @Test + public void testExtract() throws Exception { + String imageRef = harness.getTestImageRef(); + Image image = registry.pull(imageRef); + assertNotNull(image); + + try (InputStream tar = registry.extract(image)) { + assertNotNull(tar, "Extracted tar stream should not be null"); + byte[] buffer = new byte[1024]; + int totalRead = 0; + int bytesRead; + while ((bytesRead = tar.read(buffer)) != -1) { + totalRead += bytesRead; + } + assertTrue(totalRead > 0, "Extracted tar should contain data"); + } + } +} diff --git a/registry/registry-gcp/pom.xml b/registry/registry-gcp/pom.xml index ed1634512..c01e6040b 100644 --- a/registry/registry-gcp/pom.xml +++ b/registry/registry-gcp/pom.xml @@ -62,12 +62,25 @@ 1.0-rc7 provided + + + org.wiremock + wiremock + 3.13.2 + test + - org.apache.httpcomponents.client5 - httpclient5 - 5.2.1 + com.salesforce.multicloudj + registry-client + test-jar + test + + + com.salesforce.multicloudj + multicloudj-common-gcp + test-jar + test - org.junit.jupiter junit-jupiter-api @@ -94,6 +107,26 @@ + + org.apache.maven.plugins + maven-failsafe-plugin + + + run-integration-tests + integration-test + + integration-test + + + + verify-integration-results + verify + + verify + + + + org.projectlombok lombok-maven-plugin diff --git a/registry/registry-gcp/src/main/java/com/salesforce/multicloudj/registry/gcp/GcpRegistry.java b/registry/registry-gcp/src/main/java/com/salesforce/multicloudj/registry/gcp/GcpRegistry.java index af1567198..e64ecd452 100644 --- a/registry/registry-gcp/src/main/java/com/salesforce/multicloudj/registry/gcp/GcpRegistry.java +++ b/registry/registry-gcp/src/main/java/com/salesforce/multicloudj/registry/gcp/GcpRegistry.java @@ -16,6 +16,7 @@ import java.io.IOException; import java.util.Collections; import org.apache.commons.lang3.StringUtils; +import org.apache.http.impl.client.CloseableHttpClient; /** * GCP Artifact Registry implementation. @@ -46,9 +47,15 @@ public GcpRegistry() { } public GcpRegistry(Builder builder) { + this(builder, null); + } + + public GcpRegistry(Builder builder, CloseableHttpClient httpClient) { super(builder); this.ociClient = - registryEndpoint != null ? new OciRegistryClient(registryEndpoint, this) : null; + registryEndpoint != null + ? new OciRegistryClient(registryEndpoint, this, httpClient) + : null; } @Override diff --git a/registry/registry-gcp/src/test/java/com/salesforce/multicloudj/registry/gcp/GcpRegistryIT.java b/registry/registry-gcp/src/test/java/com/salesforce/multicloudj/registry/gcp/GcpRegistryIT.java new file mode 100644 index 000000000..98c3f1464 --- /dev/null +++ b/registry/registry-gcp/src/test/java/com/salesforce/multicloudj/registry/gcp/GcpRegistryIT.java @@ -0,0 +1,119 @@ +package com.salesforce.multicloudj.registry.gcp; + +import static com.salesforce.multicloudj.common.util.common.TestsUtil.WIREMOCK_HOST; + +import com.salesforce.multicloudj.common.gcp.GcpConstants; +import com.salesforce.multicloudj.registry.client.AbstractRegistryIT; +import com.salesforce.multicloudj.registry.driver.AbstractRegistry; +import com.salesforce.multicloudj.sts.model.CredentialsOverrider; +import com.salesforce.multicloudj.sts.model.CredentialsType; +import com.salesforce.multicloudj.sts.model.StsCredentials; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.security.cert.X509Certificate; +import java.util.concurrent.ThreadLocalRandom; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; +import org.apache.http.HttpHost; +import org.apache.http.conn.ssl.NoopHostnameVerifier; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; + +public class GcpRegistryIT extends AbstractRegistryIT { + + private static final String ENDPOINT = "https://us-central1-docker.pkg.dev"; + private static final String TEST_IMAGE_REF = + "substrate-sdk-gcp-poc1/test-repo/hello-world:latest"; + + @Override + protected Harness createHarness() { + return new HarnessImpl(); + } + + public static class HarnessImpl implements Harness { + int port = ThreadLocalRandom.current().nextInt(1000, 10000); + + @Override + public AbstractRegistry createRegistryDriver() { + boolean isRecordingEnabled = System.getProperty("record") != null; + + CloseableHttpClient ociHttpClient = createProxyHttpClient(port); + + GcpRegistry.Builder builder = + (GcpRegistry.Builder) + new GcpRegistry.Builder().withRegistryEndpoint(ENDPOINT); + + if (isRecordingEnabled) { + return new GcpRegistry(builder, ociHttpClient); + } + + CredentialsOverrider overrider = + new CredentialsOverrider.Builder(CredentialsType.SESSION) + .withSessionCredentials( + new StsCredentials("mock-key-id", "mock-secret", "mock-gcp-oauth2-token")) + .build(); + builder.withCredentialsOverrider(overrider); + + return new GcpRegistry(builder, ociHttpClient); + } + + @Override + public String getEndpoint() { + return ENDPOINT; + } + + @Override + public String getProviderId() { + return GcpConstants.PROVIDER_ID; + } + + @Override + public int getPort() { + return port; + } + + @Override + public String getTestImageRef() { + return TEST_IMAGE_REF; + } + + @Override + public void close() {} + } + + /** + * Creates an Apache HttpClient that routes all traffic through the WireMock proxy with trust-all + * SSL configuration. + */ + static CloseableHttpClient createProxyHttpClient(int port) { + TrustManager[] trustAllCerts = { + new X509TrustManager() { + @Override + public void checkClientTrusted(X509Certificate[] certs, String authType) {} + + @Override + public void checkServerTrusted(X509Certificate[] certs, String authType) {} + + @Override + public X509Certificate[] getAcceptedIssuers() { + return new X509Certificate[0]; + } + } + }; + + try { + SSLContext sslContext = SSLContext.getInstance("TLS"); + sslContext.init(null, trustAllCerts, new SecureRandom()); + + return HttpClients.custom() + .setProxy(new HttpHost(WIREMOCK_HOST, port + 1)) + .setSSLContext(sslContext) + .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE) + .build(); + } catch (NoSuchAlgorithmException | KeyManagementException e) { + throw new RuntimeException("Failed to create proxy HTTP client", e); + } + } +} diff --git a/registry/registry-gcp/src/test/resources/mappings/gcpregistryit_testextract-get-0.json b/registry/registry-gcp/src/test/resources/mappings/gcpregistryit_testextract-get-0.json new file mode 100644 index 000000000..8a8b06d0e --- /dev/null +++ b/registry/registry-gcp/src/test/resources/mappings/gcpregistryit_testextract-get-0.json @@ -0,0 +1,26 @@ +{ + "id" : "93474093-ecb1-4555-8c99-93cb405ecc92", + "name" : "GcpRegistryIT_testExtract-GET-0", + "request" : { + "url" : "/artifacts-downloads/namespaces/substrate-sdk-gcp-poc1/repositories/test-repo/downloads/Y6KPFvg_QT5fwwnT", + "method" : "GET" + }, + "response" : { + "status" : 200, + "base64Body" : "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", + "headers" : { + "X-Goog-Hash" : "crc32c=gFxM7w==", + "Accept-Ranges" : "bytes", + "Alt-Svc" : "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "Server" : "UploadServer", + "Cache-Control" : "private, max-age=0", + "X-GUploader-UploadID" : "AGQBYWzR2vEr--BaozWeyEkw91q_fIEoc5SqME3Y6or5qgaSCJ8uJpijljtmqnw4XMBafJC7bHA5fXU", + "Expires" : "Mon, 09 Mar 2026 21:38:54 GMT", + "Date" : "Mon, 09 Mar 2026 21:38:54 GMT", + "Content-Type" : "application/octet-stream" + } + }, + "uuid" : "93474093-ecb1-4555-8c99-93cb405ecc92", + "persistent" : true, + "insertionIndex" : 1 +} \ No newline at end of file diff --git a/registry/registry-gcp/src/test/resources/mappings/gcpregistryit_testextract-get-1.json b/registry/registry-gcp/src/test/resources/mappings/gcpregistryit_testextract-get-1.json new file mode 100644 index 000000000..a118d76d1 --- /dev/null +++ b/registry/registry-gcp/src/test/resources/mappings/gcpregistryit_testextract-get-1.json @@ -0,0 +1,25 @@ +{ + "id" : "9923eef2-3bf8-4a22-a507-af81043a3166", + "name" : "GcpRegistryIT_testExtract-GET-1", + "request" : { + "url" : "/v2/substrate-sdk-gcp-poc1/test-repo/hello-world/blobs/sha256:198f93fd5094f85a71f793fb8d8f481294d75fb80e6190abb4c6fad2b052a6b6", + "method" : "GET" + }, + "response" : { + "status" : 302, + "body" : "Found.\n\n", + "headers" : { + "X-Frame-Options" : "SAMEORIGIN", + "Docker-Distribution-Api-Version" : "registry/2.0", + "Alt-Svc" : "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "X-Content-Type-Options" : "nosniff", + "X-Xss-Protection" : "0", + "Date" : "Mon, 09 Mar 2026 21:38:54 GMT", + "Location" : "/artifacts-downloads/namespaces/substrate-sdk-gcp-poc1/repositories/test-repo/downloads/Y6KPFvg_QT5fwwnT", + "Content-Type" : "text/html; charset=utf-8" + } + }, + "uuid" : "9923eef2-3bf8-4a22-a507-af81043a3166", + "persistent" : true, + "insertionIndex" : 2 +} \ No newline at end of file diff --git a/registry/registry-gcp/src/test/resources/mappings/gcpregistryit_testextract-get-2.json b/registry/registry-gcp/src/test/resources/mappings/gcpregistryit_testextract-get-2.json new file mode 100644 index 000000000..d1e082e1d --- /dev/null +++ b/registry/registry-gcp/src/test/resources/mappings/gcpregistryit_testextract-get-2.json @@ -0,0 +1,37 @@ +{ + "id" : "f6e4e4fc-0e47-45d7-a73b-301881eda8f7", + "name" : "GcpRegistryIT_testExtract-GET-2", + "request" : { + "urlPath" : "/v2/token", + "method" : "GET", + "headers" : { + "X-Query-Param-Count" : { + "equalTo" : "1" + } + }, + "queryParameters" : { + "scope" : { + "hasExactly" : [ { + "equalTo" : "repository:substrate-sdk-gcp-poc1/test-repo/hello-world:pull" + } ] + } + } + }, + "response" : { + "status" : 200, + "body" : "{\"token\":\"eyJhY2Nlc3NfdG9rZW4iOiJBQm1ZcmZDb3JnY3YxN1BXQURJRk12YUl1aWFFbm5ud2pod1k4emhiT05SbUtVNVhBdElJeFpJQlZUenpDTEdEcER6Tzg5K3U4SzFFRnU5ZzJGMXltRTZuLzZPQWNKMjBVL1BGZ0NVMWhHQ0tvVUtSOXg1NG0xTldiSk96UldZZjM2R0dXTEMyZUVVc1llRitOR0NmYTJmUVlyS3VUdy9seDFERXdWekFPZnhKTDl2WDlaWU9UWnR2aHpnUC8vRjNYNlJxNWxJV1BOMmtVV2Jrd0xWTnIyd3c3UWl3RHR0V0xWV3dpSURMNytONGVQb1FZUnNVK2c5OE5ZbjhBd2I2RUQ0bzBYeVlwZ3p4SEs3akU1R00rZ3FzbDd6eERzV3ZyNmhpU0ZnVzZaMkc2SkNTMmNUcHZscjJTVitKQjd3Q2FweHd3cGJrTitpRWZyWU9BZUhJcU9BSHh5d0prdzREcHFzOHR0K0lNWm5EaUh2L1ZhZ1JYdzBnM0tDNVN6d3N0L3dDRTF6SkRZRzVUeW4wcWpwR0tSOVpMU0tMUGFaQkU4VzBOOW1QbVZVdXd3U0E3aUlmbWRKelRKSlRGK0NiUDdLdUFpUTJKY2s0cnA0YVhqei9pRjBPRWxYUzVvOXUxKzV5bjNzdWYxY243WEo5QVlXeFErbW1QUGw0Y0szdmRTQ2krdS9WY2w0bFNxblFpT1ZxNHVNdE4vbVB2KzdwTkxTTERLbzdJYjFUQS9GbHI3SGdHV3V0bFloQkNwQ1VyaTBjRFJ2akQzNGRDZlYwUUJIVlFWMmpwb3pkZHg4dm9EMkJZZWhuUUNVZDVaL1VPUUxGM2dBZThPSmNhMDd1dmFXSnV5NTBPVzQ2SDduQVZubHZML0ptdk5sajVaV3NGdms3QnljclcyU1Z1Y3VYL1ZxSW9WZmZCdmVXUlRnUE1JY1lUalRIZ2dZaExRSUp6YVRpV2doSzl6dTFzVVUrRHMxSzBGaTYrVkR6Z0VBL3l2RldFM3JXWnJRWnd4dHVQZzd0MzZ1OGkxOE94cXlVNFdqYVBLdUpZQldxK2VMZDhJTEdjYVRwVVphVjViNURmRkJZRkNtZHcwaDFGM3JxWnk0Zi9Tb1piS2JjMVJwRlNYeC9XTm4zU29YYk92NklqODZOZFVxajczNjlzTlJaT1ZWOWk0enRyejVpdURYSmZQT0g5RlZWQ1daSnBxUWo2NXFXbTlNUW84SEtIQW1LblhzSzhqVjBDMXQ3aG15Uk0rd2hLaEhWVHVYb1VTWkl3WXp2NzEybytpTytHanV6TFVucy9IWUl1VndmV0REWFRjUGR1UnJrOXNLbjliVktUajYvOEtoODNEWEJ5UzFZc2h2VkdBbDdROHBWUEMzOVdyeFB5WEhsNnV1MVNaR0VYUEtWL0pBOXVzNllSc0d2anZNZjZTb0dMcDlRMUt4RG5MR0lCYXVxYkNJMCt0RWtJVmpNbGNRbktJckNCSURIekdlOWFldlUrc1V3dGhJM0JaU25zbi9HTDI2OWNRaDBnWVBFTW8xOVZVWXRDa0tFMmoxM0doeitSaGpZRy9VQktGcUZkazNvWGJhY1IyMG8xZDJkYVBTbTE0RGVhV2xQcW10TzFsZW5nMlFwUW00ZllHRXY4SFgvSDhwV1lYYWNOamJuanZrcmtoSXp0U05NSmZlRHd1UzRXVXBlSG5Ueko3TmFCdisrL2FpcmE2YUd5bmpzaSttWkNkcUtMM0FnVTVNRkZ3K21IVWl6bkV6VHhjbFd0RmZKS3pPeEJSMEhiUWlVNldKck1kbDhiUzlqZGkyVEZkWlJnMDQvYlM3YWRQRTN4Y3pIdTBnQnIvaFdFTkhUN1dQWjhtdDNQWC9qTmNyM21CdXJDN0xOaGpUWDR2WVI3ZXpJWVNNUW1RdkVZOXcwLzQvUU8yZlJFazIxUm5wWVZvZUJqRGRsZzhwWWxyRFl6NWxVcmF5c3ZsM3FJOTVLc2VJdHQvN0dkTDNjemYwWXlQdUV1ZTdyR2dGR2xqSEg2NUpsRk15enVvQndZUUVhSmd2ZXdXeEUvSEdUZGVBa3ZYTFIxZUFhL1d3dVYrbndDcE1CTngycURObmxDMi8rejVkeC9UMlhYaHJtS0RvZGlBYmVaYTB4YjQyN1pvYXhWb2tpKzhrdS9QMFR0QkRoSU1vUzB2bndERStuSnBJL0xxeUlvT3c3Y3JkcnlmUUZiNnhVeDNtajlocFhrMWsxN1QyVnpSK1lYYXdScFFwTnhVSTJXbjk1VGk5S0x6aHZ1SHpsOHU4enVCUkRCZHRLeTRmeGJrdjBzS0lqdGhTWG11Mmo0WDFEMnBtTFU5Y2g1cWhpUDJ5Vy9EeGZBQmdXV1c1Q2xKQVBMQlUvSlZUWTA1ODFRcjZhN2UyYkcrUDgrb2M5WUJaUFF1T3VNaUJsMzhGemxxeU1reWo4OE9XM2piaTZWWHVuOXJIcXB2S2RkUkQvcHRzakE2ZDZ0ekVDWTVCanVldlRkbkNsZHNRYjhFb1l0dk5LaUhqNGEzVjJhU2lCTzhxOENpelRRVmR3V2w3dzVhWGNtWGEvWG1TY054YzloNFZlQnk1K2twRThGM0x4aXJDNHU0SWE4ZVJxUlpkbzYyMHYrcjQyTmkzVnBXOG5zT1B5NnBackUyZFpIM2RNaWlBYXhyRkl1RUhQK0dJVjR0SkQyT3JGQTNuOW1NeGtsWWFGRU03aldsY3FuemxkT0Mxb0lGYnh2ZWxvYnpsVzBDNzBGNXZvL0ZkZ0F2UTVHQXFocWlGRnpFOTBwSU9sWGltaDRCcHVIK2IyajA4dEpldzBlV2xxTnhrMlJlbVVNanFTeE9TY0lzS09nVTVjczMxZytVT3lzUlpSZCsrdjVBQ3BlQTQ2WFRhU25SaGpyRVF2Tk1UbEVGWFhtQTYzcWxDd2g4eis2cExNRU1RcysxOG9yMDJrbkpUeFpVWlBxNnNJMWF3azRBTzhBYzF5V3cxVW9aT1pQU09zb0dwOUxCYmpTbzhGeitCcVh2ZFVRYWZicmRuNzNwUU1OZUpVaWg5ekdIOXNvTnZYd1JKcW1kdXAwVFBqZUpGdU1NZlJ6YjVJUnVaQk4vck4zYnNzaUx1czdFVk44OURxSFE0cUE1VGc0MmZZS0ZGQmViZXl2clZWMkVvT2lUZzQ4RVY1bmJFZjl4clIwK0g2TVNBTUV3QmJ0TXc1UzNMUkxmdjdhMllvTUtrS3p3UWFkMHFpditIRm1KNVdQNTJmdkRpMXgxV2l2bzRBdDU2dngwcXR6RDRaSUtUc3FXS09uNmcvZGFjOEhPQ3NTZ2ZSYmFPTmtVNnNjM0hUVU9sYWRUSkxWWmZkZE9LWHJLS0xaTUJYditpY0RiOXNTZVJwNjZXSCtrQ1hyd2JXUFpKcUdsdmRkaGNOTFZwRk1mWnhwYUFBY1dDQWU5ZExrM2R5clZOaEw3ZXB2MXVxa0lmbGhjL3RLTGlNWjQ2MzV5aFE0WjIvaFNOdW5ianlzdHVXbmZxd1o4MVpuOGVnWWVUb3FUWUNvc1lVWEFSLzZFaGEwQ2hLYVpLUi9ZZFRZOTNNb2xyLzZjUVUveVcrYzIwdk03Ky95N1ZnbTYxMzk2VDNqMWZIcFM3aUlJd1I2MWxnQm5PR3lZV0xlZWRVU3VscVowR09xeTNmL2IzVzVDSC81ZHNSSkpROStkRGhaSFRhNzFKSGE5SHo2TmxYdDFIRk9kWVI2QkhnNDVMZXhMM01BMU5TQmVpZFJ4Rjlkcm1oNzhrRjlqMEZTdm15ckM0Zm5nQTh5c0NhazVaV0ZqODh6VkpsUFRxaldEYncxQT09IiwiY29tbWFuZHMiOnsic3Vic3RyYXRlLXNkay1nY3AtcG9jMS90ZXN0LXJlcG8vaGVsbG8td29ybGQiOnsiMTQiOnRydWV9fSwidG9rZW5faWQiOjEzNzc5Mzc3MDExOTU2NTA4OTQ5LCJwcm9kdWN0IjoiYXJ0aWZhY3RyZWdpc3RyeSJ9\",\"expires_in\":43200}", + "headers" : { + "X-Frame-Options" : "SAMEORIGIN", + "Alt-Svc" : "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "X-Content-Type-Options" : "nosniff", + "X-Xss-Protection" : "0", + "Date" : "Mon, 09 Mar 2026 21:38:54 GMT", + "Content-Type" : "application/json" + } + }, + "uuid" : "f6e4e4fc-0e47-45d7-a73b-301881eda8f7", + "persistent" : true, + "scenarioName" : "scenario-1-v2-token", + "requiredScenarioState" : "scenario-1-v2-token-2", + "insertionIndex" : 3 +} \ No newline at end of file diff --git a/registry/registry-gcp/src/test/resources/mappings/gcpregistryit_testextract-get-3.json b/registry/registry-gcp/src/test/resources/mappings/gcpregistryit_testextract-get-3.json new file mode 100644 index 000000000..de158c675 --- /dev/null +++ b/registry/registry-gcp/src/test/resources/mappings/gcpregistryit_testextract-get-3.json @@ -0,0 +1,25 @@ +{ + "id" : "4a4e6eb8-b729-461e-a1c2-07bb705cfb81", + "name" : "GcpRegistryIT_testExtract-GET-3", + "request" : { + "url" : "/v2/substrate-sdk-gcp-poc1/test-repo/hello-world/manifests/latest", + "method" : "GET" + }, + "response" : { + "status" : 200, + "body" : "{\n \"schemaVersion\": 2,\n \"mediaType\": \"application/vnd.docker.distribution.manifest.v2+json\",\n \"config\": {\n \"mediaType\": \"application/vnd.docker.container.image.v1+json\",\n \"size\": 562,\n \"digest\": \"sha256:ca9905c726f06de3cb54aaa54d4d1eade5403594e3fbfb050ccc970fd0212983\"\n },\n \"layers\": [\n {\n \"mediaType\": \"application/vnd.docker.image.rootfs.diff.tar.gzip\",\n \"size\": 3021,\n \"digest\": \"sha256:198f93fd5094f85a71f793fb8d8f481294d75fb80e6190abb4c6fad2b052a6b6\"\n }\n ]\n}", + "headers" : { + "X-Frame-Options" : "SAMEORIGIN", + "Docker-Distribution-Api-Version" : "registry/2.0", + "Alt-Svc" : "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "X-Content-Type-Options" : "nosniff", + "X-Xss-Protection" : "0", + "Date" : "Mon, 09 Mar 2026 21:38:53 GMT", + "Docker-Content-Digest" : "sha256:48b5775c1cd7cf723f57537f82b68e3888f2eeb4bf34098e683a727982cc5b03", + "Content-Type" : "application/vnd.docker.distribution.manifest.v2+json" + } + }, + "uuid" : "4a4e6eb8-b729-461e-a1c2-07bb705cfb81", + "persistent" : true, + "insertionIndex" : 4 +} \ No newline at end of file diff --git a/registry/registry-gcp/src/test/resources/mappings/gcpregistryit_testextract-get-4.json b/registry/registry-gcp/src/test/resources/mappings/gcpregistryit_testextract-get-4.json new file mode 100644 index 000000000..530e852be --- /dev/null +++ b/registry/registry-gcp/src/test/resources/mappings/gcpregistryit_testextract-get-4.json @@ -0,0 +1,38 @@ +{ + "id" : "494bc309-f719-482a-934e-865f1b9792c6", + "name" : "GcpRegistryIT_testExtract-GET-4", + "request" : { + "urlPath" : "/v2/token", + "method" : "GET", + "headers" : { + "X-Query-Param-Count" : { + "equalTo" : "1" + } + }, + "queryParameters" : { + "scope" : { + "hasExactly" : [ { + "equalTo" : "repository:substrate-sdk-gcp-poc1/test-repo/hello-world:pull" + } ] + } + } + }, + "response" : { + "status" : 200, + "body" : "{\"token\":\"eyJhY2Nlc3NfdG9rZW4iOiJBQm1ZcmZEc2Y0WGlZRjZNOVVueUVGTnBVYlpqV1RzaE1vMmpBYStoeWFUYlE2cUtaS2R1VnduVU0xZ3pKOC82aHhVUUwwRE1TbzIyNGQ0ZXY3bG4xVXNZY2c1ck0rZU5zb1JIZVU1VXo1ckNmT01kaU1rOGl6NngxU1VTbm90Z2YzakhLNlh0amFIRDV0eG5OOERCc3lZOVNIaEZlY095Mm0zU0s0VGpxc3FxaWY5Vjc3Y2V3MGcwL0ZzUTBZUHRQUERNVzY5RElob1pkVTVja1hIcGVxVXZzVzh5MG5UV1hTd0V4KzRKZWRqUWxjMDY4S0M4UWRkTEJEQ0RvZUVxSUxsQi9GQVlraTArOHdyb2lDVi9kTkt2QXM0Z2xST0tZWEVZQmFqZHlEWi9zbVVKSm5PSjMxVWlLd3BPRmIrSm5MZHVKUC9YZmx0akVkRW9iQ1Y3a0JDVmNrNDdiNHV0UW1uS21MK2dkTDdGVGVQdzdBUjhjZkZaRWMwTUtTMXpNR1haMG4rRk9rdVZ3L0dHYStSVjk1UVZ1WHEvQmdycmR5YlFqMG9xTUVpMzF3R0R4SVljM09zWmJyOUN2ZFpTNWFZUEppVTFWWEJTR3RZM1FsVU4raCtDQVUyZzRZSXNjV2tRaWVlN1F1TmdQN3F5TnNQWCtWQVdtQlJxcUcyTEk4NHVJQ01CVUMrMkpPRWZjYnVtODRXRy90cEQyWktEVEVIUmlFNW5mWEo1RDNVZmpGMDlPM2x1M1hhbUVmZVR3Skh0a0FORG1oVWR3RUZuamsxM3BsSElhZ2I1SG9PMTZ1THllcjJVYkpBN2RueUhMODAwU2d6V0RyU016elQ5R1pyYzJha1hjekFPL1pjZlZKSkJ0QmlQL3ZwWWUzR3plR1R2U2VVcUMvVzZ4dU9jUE9uM2VtZnRNT0RVZURJbkpVOXVpdXg2ZEZJdFBCcE1NdjVaNnpuSlA4eGswVFFCb0lJdk52cWtiRlg5TEFBLzRtTDUyTkhtUHc5dW1DL2Y1SVQwa3VnakMxbmxac1d2elFOazk1N1R1eVZKdFFiRWhFclZUK3ZsNERQZHhXMGE0UVRFZ0lYZGNnbW9lSExYcGhRY2k0a1ZjeDBJSFl5N2I2TlMrd0QzZm0wNFo0U1dlYTNDMVowalJRcFBybE9hTlh4VGhhZ243Rk5VMlo3WUt1VGNtVXlRaWJWa2lTaGZaV1lSZWRxbEM3cCtuSG13ZTRvL2pVaU1DRk9DdUJBRnYrVzNSMzBpRmU2dk53ZW1VcGFDNmdqWHl4emJ2N2NybWhqUUx1T1Q2VFdkcUIxbjI5bi9FVkphVHFtbHoxVlJkMk42a2hTc2tKVU1KK25oaC9yRmdTYUV0dzJaQm5SNzJpbGJyRTRjemtISEc0ZDZMZU11K1ZYQ1V3M2w4UGwydCt4SVhZczQ0QWtiRWZUaGIzSFBNUnJRMHo4QjdGamI0YzdGOFk5c1FOY1M3NHgrOFlBSjF0NzJOZW1sU2lVaHlyMzZwellyV2VCcjVhUjVTZVZmaUhwajY1UC9NRWZZV2FIczVGckVwWDlZWVZWQWVRaWFXcEprMFNOWENuYmRQbUJtc2pEVFUvdmQ5WWVXVjJyOUlhZkt5Mm9EWTBHRWJjc0hlNVpGNkx0WXpqT3RvU3Rad1BIcWJ3K0lvVFQxMkFaNGlycnI2anFiMnk1QTAyVHpSNzZHUjMxUUpVa2JmRitKd3Brc3N0djU1RmlxT2hoa01OK2NhTGVaS3BRYkU3U0RYdkdVaEZyNnJaaURTQlNPRktJV0p1UkpoeVAzZjB2ZHRvKy9Xa3NNZGg4cTEwSXZ4ZmtCMVZIR2FPcnBoc2tLWXZHN2tBcTZOYTl5NU1uT3ptTHZ3VG5YMTVBUFo5ZWxndXpUTW9EdmQ4enFxbzB6NmJtb2JvWm1wUkYwWVN1Uk1OTnpWNHRPWkNxZ243RzdpQkFvTFd2RG1jOSt5WUEydzdiVDdHZTRxWHFJZTUxOVNjc1V2UzBMR0VzU0ZwQ2dBRU9OQjdWaGRucWk0VUkyRDgzbmlQOVgwdmZIQTFHd3RCVXM5Mms5TE5kbzBxRVV2Vm1QWnU3VGRLYjlpYXZ2ZVFyV3JsdEp0YUp2TkdWOGZCa2N1U00zWUJ3SFplcFcrWjhPZFV5cWttYXlXaDlIU0IyMGVmcGhiSnZ0WHF3ZUhBNjFyRzNQMk5PeGF5anNRcDRaYXZGVjFpQjAvUkZNZk9qUXdyRk1yckRnTGh4SjIzeEk5QzRkNE03RjN1N2hYcXl5Z0FuOVJyeHA1M2haaTZTMUxRdFVQSEhWRVhVZ3c5eXVmdTJxUmtyM1R2NEl1Wk5zRUVWWFdrZXVjNERENlM1eWpBdi9PdVExdlpqWmRjRGE4VXZvQjQ4MmxwTm8xZDVvTCtIQ2pnNGRxcGdZOXkvanpIcXVwQXo4U3VhSDFJZS9sZTk0anVNMFJqSndjcTViL1Q0WmZGakZ1bVN4d0IxMXRzVEpsT0Z5ZkhtWWR3MDFPNk92b1IrZUhzTEN1YjZpUHNBc2c1U1R3NlB3OFdDRHVBZW9hdXgyc0o0TWEydTBFbVhacG9KZG5QQll4YkRwaklpamFPRy8wNjJubmVJb0RCTTRrMkVsYUt3VStZM0V0V3dQWVNsN1R3cHdyTnFFQTkzQTlydHE1V3Z6K2JwYVo3d3lzODNjRitlMWhWZTFBcnJMWjRCTVB0aEMwM0pBMXo0OHhSZ2ZIVkRlZ0Z3eEk5UkNyN0FtRHB5eGY5dDc5clgxNFFjSk0vaytHMDN6YUxCTjRJOFFDWDk0Wk1pYVd4NW1xSXVwbHcxb0JIenQxVDRtcXp3UFJKNXQ0VWEvWUNEM2NaLzRiVjY5Unp6Z3N3VUZsSGphUXlTUXVsRDZoM1p0VlF2NmhmMWFhNkplMmwyUHp5bzYySE81Q0NBajlPN3hjS2pSVDNDdVpNSkFmc3huSzBYYmpQWDF5bzZBRUZJNC9qRG50UkxMOFFCTy9MSE1rUlJDdmxzVE5ENmJ4ZUxUZDRNVkpwVUhYc2l4MGIrWERlTnJaSnR0UXBUL0hGd0xlamNHTEhMeXlJUGhpMUwveHAwNEY3TG1BSHBGWlF1c0VQVTFTKytKMjFKRjQ2YnZUQ1Via1ZKM2pFME1SZ0pQam1zanJGSmpBbCtpa1YvMjhMWlp0aDFFMndOWWdkRytOSDZOOTJrN0N3d0ZYSkJNbnZyR3I5M1ZSUGhDNWdrSEFMR05tS1pFOGlCalBVS0JXOWkwVEtEOHJTNFRCUC94OU1KaUtXRlhpQmtYU3orOHo5TisyYStHUi9rNzBZbTV4SVlGOThiSGpVN0VsN1N2Yk1OV0VzRGJCVGhYZG5hN2g4Z1NGMk44UW00Z2g2QWUxMEdmb2hUQy9oMXIxVEM5cFJYRXNDRmlQTVk4cjRmdW85MTltbktScFVOcXNIRXBrSjlDM2YvNkllYU9HeEJzUEdta2dIMjdIN0Z6OHdKa2tVZmo5TXVqTDRveWhLUGNML0hBN1NlY1ZSY205UStaU1ZveW1mUnBmSy8wYndtTEZVYU53bDlNWGV3UXQzZkQ5dm94bmFpSk54WVpyVDNyQmNUQ2tKY3FrK1JmNU54TnV5RzZDbVhOODBqaE5acG14YU95ME5DVHpmb2lySzZTbTlCSC85R2QzQnlNdVF2aEc1M2pBM3JXcWE5RTIxUk9zbk9zUXpBYUE0aEFBU21IOTRyT2lWdEVLSmc2NmVCODlZeElEcFR1ZUJOTkVpT0x3VlJvSHhkR1RIOXpDeXFIL0xoaDE0aDNjTDRzUVdBSUhUYU9ydUlhYzhjPSIsImNvbW1hbmRzIjp7InN1YnN0cmF0ZS1zZGstZ2NwLXBvYzEvdGVzdC1yZXBvL2hlbGxvLXdvcmxkIjp7IjE0Ijp0cnVlfX0sInRva2VuX2lkIjo0MjQ1MTAzMDY5OTk1NjY3MTI4LCJwcm9kdWN0IjoiYXJ0aWZhY3RyZWdpc3RyeSJ9\",\"expires_in\":43200}", + "headers" : { + "X-Frame-Options" : "SAMEORIGIN", + "Alt-Svc" : "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "X-Content-Type-Options" : "nosniff", + "X-Xss-Protection" : "0", + "Date" : "Mon, 09 Mar 2026 21:38:53 GMT", + "Content-Type" : "application/json" + } + }, + "uuid" : "494bc309-f719-482a-934e-865f1b9792c6", + "persistent" : true, + "scenarioName" : "scenario-1-v2-token", + "requiredScenarioState" : "Started", + "newScenarioState" : "scenario-1-v2-token-2", + "insertionIndex" : 5 +} \ No newline at end of file diff --git a/registry/registry-gcp/src/test/resources/mappings/gcpregistryit_testextract-get-5.json b/registry/registry-gcp/src/test/resources/mappings/gcpregistryit_testextract-get-5.json new file mode 100644 index 000000000..f466cd579 --- /dev/null +++ b/registry/registry-gcp/src/test/resources/mappings/gcpregistryit_testextract-get-5.json @@ -0,0 +1,25 @@ +{ + "id" : "68ac07b6-e53a-4990-ac51-07856b4c8c93", + "name" : "GcpRegistryIT_testExtract-GET-5", + "request" : { + "url" : "/v2/", + "method" : "GET" + }, + "response" : { + "status" : 401, + "body" : "{\"errors\":[{\"code\":\"UNAUTHORIZED\",\"message\":\"not authenticated: No credential was supplied.\"}]}\n", + "headers" : { + "X-Frame-Options" : "SAMEORIGIN", + "Docker-Distribution-Api-Version" : "registry/2.0", + "Alt-Svc" : "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "X-Content-Type-Options" : "nosniff", + "X-Xss-Protection" : "0", + "Www-Authenticate" : "Bearer realm=\"https://us-central1-docker.pkg.dev/v2/token\"", + "Date" : "Mon, 09 Mar 2026 21:38:53 GMT", + "Content-Type" : "application/json; charset=utf-8" + } + }, + "uuid" : "68ac07b6-e53a-4990-ac51-07856b4c8c93", + "persistent" : true, + "insertionIndex" : 6 +} \ No newline at end of file diff --git a/registry/registry-gcp/src/test/resources/mappings/gcpregistryit_testpull-get-0.json b/registry/registry-gcp/src/test/resources/mappings/gcpregistryit_testpull-get-0.json new file mode 100644 index 000000000..6e60876fd --- /dev/null +++ b/registry/registry-gcp/src/test/resources/mappings/gcpregistryit_testpull-get-0.json @@ -0,0 +1,25 @@ +{ + "id" : "c7a9a03c-228c-44eb-8ef1-1ffe6ea58f2d", + "name" : "GcpRegistryIT_testPull-GET-0", + "request" : { + "url" : "/v2/substrate-sdk-gcp-poc1/test-repo/hello-world/manifests/latest", + "method" : "GET" + }, + "response" : { + "status" : 200, + "body" : "{\n \"schemaVersion\": 2,\n \"mediaType\": \"application/vnd.docker.distribution.manifest.v2+json\",\n \"config\": {\n \"mediaType\": \"application/vnd.docker.container.image.v1+json\",\n \"size\": 562,\n \"digest\": \"sha256:ca9905c726f06de3cb54aaa54d4d1eade5403594e3fbfb050ccc970fd0212983\"\n },\n \"layers\": [\n {\n \"mediaType\": \"application/vnd.docker.image.rootfs.diff.tar.gzip\",\n \"size\": 3021,\n \"digest\": \"sha256:198f93fd5094f85a71f793fb8d8f481294d75fb80e6190abb4c6fad2b052a6b6\"\n }\n ]\n}", + "headers" : { + "X-Frame-Options" : "SAMEORIGIN", + "Docker-Distribution-Api-Version" : "registry/2.0", + "Alt-Svc" : "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "X-Content-Type-Options" : "nosniff", + "X-Xss-Protection" : "0", + "Date" : "Mon, 09 Mar 2026 21:38:56 GMT", + "Docker-Content-Digest" : "sha256:48b5775c1cd7cf723f57537f82b68e3888f2eeb4bf34098e683a727982cc5b03", + "Content-Type" : "application/vnd.docker.distribution.manifest.v2+json" + } + }, + "uuid" : "c7a9a03c-228c-44eb-8ef1-1ffe6ea58f2d", + "persistent" : true, + "insertionIndex" : 8 +} \ No newline at end of file diff --git a/registry/registry-gcp/src/test/resources/mappings/gcpregistryit_testpull-get-1.json b/registry/registry-gcp/src/test/resources/mappings/gcpregistryit_testpull-get-1.json new file mode 100644 index 000000000..e9d3102c4 --- /dev/null +++ b/registry/registry-gcp/src/test/resources/mappings/gcpregistryit_testpull-get-1.json @@ -0,0 +1,35 @@ +{ + "id" : "44924d47-5946-41a5-8f98-b7a798541e1c", + "name" : "GcpRegistryIT_testPull-GET-1", + "request" : { + "urlPath" : "/v2/token", + "method" : "GET", + "headers" : { + "X-Query-Param-Count" : { + "equalTo" : "1" + } + }, + "queryParameters" : { + "scope" : { + "hasExactly" : [ { + "equalTo" : "repository:substrate-sdk-gcp-poc1/test-repo/hello-world:pull" + } ] + } + } + }, + "response" : { + "status" : 200, + "body" : "{\"token\":\"eyJhY2Nlc3NfdG9rZW4iOiJBQm1ZcmZETXlLVVFpVC80R2hKamxjMEZwTVhLYTlQaHZCRnBsY2ZhclB2ancrTjhDU0tzVk5QRk1KSTZJMDhKOUdoSkxlRTU0ZDhoNTB4bFQxZUxWZXRTOUxiYUJkS2Z4c3lsb0ZFSTczMFA3VmZtUmR2c20xSkt2NnIvaXJyYTN1UE5OVzVzdENIbHFBUVJMRGgxU2xXc21naTR4ZzZNRlBOQU56YW51OWxMTGdGU0Y5MndienhBSlp5OWJLUDhacHI2eml6aGJpRWFNUkVpMWdUcVNwT0NzQ0lJOEVwL1BlcnhULzM3c2RiN21IN0pNbm13a28rN1c4Q3k0UU5WcG1ON3lwTTN6cVpwaXlJRjZkOXI4SWlidC92UWhCQnBBUloybExDTzY4MVBhZ3Z6SWhrbTU5OEJnZFMwcGRNUGhORDVURzFYSzFXallmZGxGSFlncW9aNktia3JISHZCOXRwV29JMXIwaUQ4cllwSmdOZVJhNWlhRlcxeWdrUlFSR2hVMldtK1doNXR3aFJjTGhtWDlxNElLVXJnMS9RZDRUSlpmZGJ1bjFPaHRkeTdRZmZteEl4YmNuTnNSL0EvZlFmZHZMNVgyVENkRW1XcUVkZzFJcUJGU0NyU0hWL1J0UHV5aHdVSmZHeUNDazNCb0FYbTNiNDF0Tjc5WUNOeUQxaTRsaXQ1K1NOVWxQa21lbTB1NHNIMlJyYXlqN3JYOGFqaytsa0pyd2NXcE5yVlpZT3BxbVcra2w5YmNxejZUMjVSYlI1QTVEeHlrZHZUV0Z5QjErMGkrR1V4aDdkUUZLM3VTcko0ZGtTTFI4Z3I1QzhZd2w3eklWWnF6TjUwR3daUldNVzk5RWx6MjMzckdVamEvcGkzK0VBUFl4UFcxSU14TTRITFpSSm56U1JPanNIR2ZFV2Iyc2tMMWl4Rm5oR0QwKzJTNkhLelYzWEY3Yk4rT1JNNG1aYUlIbFROTmY1S3VFRmFFOUNUeTBhWlVGSUcwWjBBMVRNR3VvSmwwWHpEa1IzVHMvbmJVQjkyZFZ5Q212SW1KOC9ySDY3YU1oVHJwOFZzanhvSFREc0hmalNxaHkvLzBoRDdLd1pBRWltV09uazZrdUZMZ0pxOHh5SEpJWEprQThJeUJkQ3E0K3pCbUVPeml6V2krcEoxWHZEaWhGeUU1L2oxL2tCeU9MWVBVTVZ2MDBUbEp6YjJZSHZQVzBYd2gwV2djbjV4ZkprTlJaa0oyOGxLSzFpK2VOYlprZ0FQYkNUWmZudDdrTnF4dmtsbFlVbWZUWVIxR1Q5Yk1WYlNoV0w3YTZRQUxROEd3a0Q5bkFtZUZxTlZKY2dSU1RCV2g0VEE5VFRoZWtHOGZRNUExUmFMZ3NMREx5dlRTcHkrOTZrb2pSU20vNWFPNTJsNXhXZzBObk1qQVJ6REdoU3kyWXR4NmUvSXE5dWNEQTFOc0JFQ0ExUWdxOUZkc3k1ajZyTDE1WG5udWNaeGw4SmJWSUE4SmM4MElPK3QzOTFaUWY3YzVpdGVpQ3QzRFZzWFlnR1Y5RFRVNlpuWnpYRXgvQUVLcnI1L01JTjFKRm1Cb0J1bEZ5WnRwWDg1T0pQY3FMMFVlY3hRbHJRSk90S2w4WE1EenJTSGVVc3J4TUZVeXBlbkVyTnlLTEoxcUZmanp6cjVUaWJWdDFEQ0w0VUtFSWNWeUhXUW5GSjFCdUZjQ3plekptUTRvWkdHS1Y2bVdEd09Qc2djVTBYSDVvWVpwbXVoNmtxSk50L0o4bE5Md2RJRHZaVnZzZGlJSENBMm80bDlmMjFBbzEySGQ3WS9FNGdxOVN1cFFIeE9tTzhITk5pZHc2WWVBNHVEbEkvdGR0SHNlRkpJbU1pekIrNEpKKzNteE9ROVdsUy9Ic2ZjSEJzbjVYSUpGcEY3ay9xNHp0b3Y4b2d4Q1MrWTNFSnpUUzB3UWpqQldsczNmWFIyODlyODVwUmNnbkpXeVp0Qk1qN2ZKVXBSL1hUMnNac0pZcUZDa2RqN1Q0QUpoNFEvL0ZyT1VqTGlGNVVJZTlEUUc4WDZ3RHAyVm92OVNDamx2TXp0ZFcrRU16Q1p2enVUN1VWRHIvbE4wdkdjZHJXdmY0TjBBYzV2UndLcTlQVGk3WXErS2Z5cGdvT1lOeWxkQ05iUlRKa2ZIUUc1MzdiaEFFZlRIaE1ES0tTOEVQT25WdVRTelB4VVFUdEF6emZJU254K3N1ZW9qak5wTVVoajBZbVBYRDNpaXlVdWU3S0VBZDVYa0ZSVHNHYVpJS2ZUQTlseHlqUHJOd1dNT0U2MlpnTjdDYmJFY090TkVzYzNLTXp0WU82WjBmU1Nhb0NCR3VnSVA1dlU2OWphMUFWSitRSCtEM1IrQXN2K1hoNVc3Ry9IV3ZKbWREZGYzSVlXWENIaFFhdEduSkoxTWFXbDB2MDhYdjl2bjdsQXhhU3Z4MVRHcDJZcUl1OTduNzNLT04vc3lzcG45MmVxc1kxSUZ1WjRuOEl5OG12cWZjN0E2SkJwY29jekFPM09GSHp0WVpYbjk5Q1p3Q2dOcWtBblhJK0tXVE1kRzVkcWNZUGhqSEdEREs0WXVTNmQxY3lUK1QvQklzbW5zOEt1enpvek5BemtvSjhuTkk0T2tqTUJVL1VUTXdSZjRYV0NsTVlUbEFkL0xYdS9aYVRHQlZVSUhJNFdYRG1DSU1Pa1ROd203ZklNTHVZOGlHYkUycFhOaXVZN2p5dk1jZGpVbkxZV0hrVG9lRWU5d2RwUjVXaHRSdjl1QnhUZ21CaE5IczhlYjhneDNHNXBrWTQ4Y09SNUF4aURaNzhCbDNaZFN4aDIwWjlJOGIvT0lCN0dETms1cWZ3TTVmY1o4Vm9KVUlhdEVheXMyN1U5VmIrMlZkUlp1WlhaOFBjeXB1NW8ybFdha1hOZUJIeDkzTE93ZElWK21hbTFtV1lpTmJPVDlraUNRd2gxNE01bHgzcTJIZjBQVCtlTnAwdTFsK0tvSWk3eDFodUZoelRxZmw1cDBCRE8xRlYxbzMrNjlYNU1WR0pNNTN3bkFYWEx2aS9maHlUZXhWeHRHRXlRVkZCRWlzZytoZXNFWlpRTnljR2tGbmN5b09OakdkNjh6aWxpeVFTVWRLem1mVmxjT0phd3U3ek9XSDN0YUV1bzRDVTMwWVJxM2tLQ3psN0VJNFJ5NVdLOWpJbVJ2SWVMeVlHaHpsa2xFaWlzTUd1S3VsQk1HS3g2TXVsK2dnclRSL2dsV2VWK2RSV2JqV01YeDE3UzlCNkJFbTlDWHZ3cGgvY2piUXVNYXpLQnFWdHRSSml4blJsVStHT1NQT3FwZ2hUY0xjVWJBQktiWVh6dUhrbkhINFUwNFFlYm5CdmRMcVNFcHhuZHBoblFlak44Tnhrd2pqZEorQ0pOdjNSV0liZVR1Sm9hV0V0SzljMmRzZjk1ZlkvVTJSOWN6d1Z5NG5kSG9RSlpPVWk5RG80Ky9ua1plOVB4TERoYWgwZmNHUXpCQmtyRGJWRjhhWHNQcjhIRGo4ZEtxTnVyc2kwZ0lBalRoWTFLS2lDNlRhVGo3ZkNQU0ZKSStITEZZQUQwbm9JVlNTbm1LaFJqTDZ2TTRvb2ppdXdUS1VoVER4bmtLVmFlQ0ZES0FPdzFiL1p2dDREU2l3SFRDcmdGOHBXSWJPV0puYXl3bjNiZkdhYklCbDdwMEZ4TmZwRTYwY2RkMTFWQ0dDeHlrLzdvREg4RHVLeXQyL2Fha01hZkNHYmlwYkVMNUNVN0V6SC85V0dMcTlVNWZIYXNKNi9sZ0w4aHMwcDYxdkFsdlNZYllxck8wdVZsaUxRPSIsImNvbW1hbmRzIjp7InN1YnN0cmF0ZS1zZGstZ2NwLXBvYzEvdGVzdC1yZXBvL2hlbGxvLXdvcmxkIjp7IjE0Ijp0cnVlfX0sInRva2VuX2lkIjozMjcxMzU5MzIxNTUxODYzNDk4LCJwcm9kdWN0IjoiYXJ0aWZhY3RyZWdpc3RyeSJ9\",\"expires_in\":43200}", + "headers" : { + "X-Frame-Options" : "SAMEORIGIN", + "Alt-Svc" : "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "X-Content-Type-Options" : "nosniff", + "X-Xss-Protection" : "0", + "Date" : "Mon, 09 Mar 2026 21:38:55 GMT", + "Content-Type" : "application/json" + } + }, + "uuid" : "44924d47-5946-41a5-8f98-b7a798541e1c", + "persistent" : true, + "insertionIndex" : 9 +} \ No newline at end of file diff --git a/registry/registry-gcp/src/test/resources/mappings/gcpregistryit_testpull-get-2.json b/registry/registry-gcp/src/test/resources/mappings/gcpregistryit_testpull-get-2.json new file mode 100644 index 000000000..a4f5dfab2 --- /dev/null +++ b/registry/registry-gcp/src/test/resources/mappings/gcpregistryit_testpull-get-2.json @@ -0,0 +1,25 @@ +{ + "id" : "a7795cd8-7428-47e9-a171-e3dbc42e00dc", + "name" : "GcpRegistryIT_testPull-GET-2", + "request" : { + "url" : "/v2/", + "method" : "GET" + }, + "response" : { + "status" : 401, + "body" : "{\"errors\":[{\"code\":\"UNAUTHORIZED\",\"message\":\"not authenticated: No credential was supplied.\"}]}\n", + "headers" : { + "X-Frame-Options" : "SAMEORIGIN", + "Docker-Distribution-Api-Version" : "registry/2.0", + "Alt-Svc" : "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", + "X-Content-Type-Options" : "nosniff", + "X-Xss-Protection" : "0", + "Www-Authenticate" : "Bearer realm=\"https://us-central1-docker.pkg.dev/v2/token\"", + "Date" : "Mon, 09 Mar 2026 21:38:55 GMT", + "Content-Type" : "application/json; charset=utf-8" + } + }, + "uuid" : "a7795cd8-7428-47e9-a171-e3dbc42e00dc", + "persistent" : true, + "insertionIndex" : 10 +} \ No newline at end of file