From 37167aca8c469671ed0bd644c02d71f38a170ed3 Mon Sep 17 00:00:00 2001 From: Rohan Kumar Date: Mon, 5 Aug 2024 16:39:15 +0530 Subject: [PATCH] test : Add wait for oci server to become ready in JibImageBuildServicePushTest (3283) test : Add wait for oci server to become ready in JibImageBuildServicePushTest Wait for 5 seconds for verifying that created Helm Oci Server instance is accepting connections. Signed-off-by: Rohan Kumar --- test:feat: create TestOciServer to reuse OciServer test server Signed-off-by: Marc Nuri Co-authored-by: Marc Nuri --- .../jkube/kit/service/jib/JibServiceTest.java | 38 ++++----- jkube-kit/common/pom.xml | 5 ++ .../jkube/kit/common/TestOciServer.java | 84 +++++++++++++++++++ .../JibImageBuildServicePushTest.java | 44 ++++------ 4 files changed, 121 insertions(+), 50 deletions(-) create mode 100644 jkube-kit/common/src/test/java/org/eclipse/jkube/kit/common/TestOciServer.java diff --git a/jkube-kit/build/service/jib/src/test/java/org/eclipse/jkube/kit/service/jib/JibServiceTest.java b/jkube-kit/build/service/jib/src/test/java/org/eclipse/jkube/kit/service/jib/JibServiceTest.java index 36ec7d4ef6..92ee505cff 100644 --- a/jkube-kit/build/service/jib/src/test/java/org/eclipse/jkube/kit/service/jib/JibServiceTest.java +++ b/jkube-kit/build/service/jib/src/test/java/org/eclipse/jkube/kit/service/jib/JibServiceTest.java @@ -19,9 +19,6 @@ import com.google.cloud.tools.jib.api.TarImage; import com.google.cloud.tools.jib.api.buildplan.ImageFormat; import com.google.cloud.tools.jib.global.JibSystemProperties; -import com.marcnuri.helm.jni.HelmLib; -import com.marcnuri.helm.jni.NativeLibrary; -import com.marcnuri.helm.jni.RepoServerOptions; import org.apache.commons.codec.binary.Base64; import org.apache.commons.io.IOUtils; import org.eclipse.jkube.kit.build.api.assembly.BuildDirs; @@ -31,11 +28,11 @@ import org.eclipse.jkube.kit.common.KitLogger; import org.eclipse.jkube.kit.common.RegistryConfig; import org.eclipse.jkube.kit.common.RegistryServerConfiguration; +import org.eclipse.jkube.kit.common.TestOciServer; import org.eclipse.jkube.kit.common.assertj.ArchiveAssertions; import org.eclipse.jkube.kit.config.image.ImageConfiguration; import org.eclipse.jkube.kit.config.image.build.BuildConfiguration; import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; @@ -55,35 +52,27 @@ class JibServiceTest { - private static HelmLib helmLib; @TempDir private Path tempDir; - private String remoteOciServer; + private TestOciServer remoteOciServer; private JibLogger jibLogger; private TestAuthConfigFactory testAuthConfigFactory; private JKubeConfiguration configuration; private ImageConfiguration imageConfiguration; - @BeforeAll - static void setUpAll() { - helmLib = NativeLibrary.getInstance().load(); - } - @BeforeEach void setUp() { - remoteOciServer = helmLib.RepoOciServerStart( - new RepoServerOptions(null, "oci-user", "oci-password") - ).out; + remoteOciServer = new TestOciServer(); jibLogger = new JibLogger(new KitLogger.SilentLogger()); testAuthConfigFactory = new TestAuthConfigFactory(); configuration = JKubeConfiguration.builder() .pullRegistryConfig(RegistryConfig.builder().build()) .pushRegistryConfig(RegistryConfig.builder() - .registry(remoteOciServer) + .registry(remoteOciServer.getUrl()) .settings(Collections.singletonList(RegistryServerConfiguration.builder() - .id(remoteOciServer) - .username("oci-user") - .password("oci-password") + .id(remoteOciServer.getUrl()) + .username(remoteOciServer.getUser()) + .password(remoteOciServer.getPassword()) .build())) .build()) .project(JavaProject.builder() @@ -91,13 +80,18 @@ void setUp() { .build()) .build(); imageConfiguration = ImageConfiguration.builder() - .name(remoteOciServer + "/" + "the-image-name") + .name(remoteOciServer.getUrl() + "/" + "the-image-name") .build(BuildConfiguration.builder() .from("scratch") .build()) .build(); } + @AfterEach + void tearDown() throws Exception { + remoteOciServer.close(); + } + @Test void prependsRegistryWhenNotConfiguredInName() throws Exception { configuration = configuration.toBuilder() @@ -207,7 +201,7 @@ void push() throws Exception { try (JibService jibService = new JibService(jibLogger, testAuthConfigFactory, configuration, imageConfiguration)) { jibService.push(); } - final HttpURLConnection connection = (HttpURLConnection) new URL("http://" + remoteOciServer + "/v2/the-image-name/tags/list") + final HttpURLConnection connection = (HttpURLConnection) new URL("http://" + remoteOciServer.getUrl() + "/v2/the-image-name/tags/list") .openConnection(); connection.setRequestProperty("Authorization", "Basic " + Base64.encodeBase64String("oci-user:oci-password".getBytes())); connection.connect(); @@ -227,7 +221,7 @@ void pushAdditionalTags() throws Exception { try (JibService jibService = new JibService(jibLogger, testAuthConfigFactory, configuration, imageConfiguration)) { jibService.push(); } - final HttpURLConnection connection = (HttpURLConnection) new URL("http://" + remoteOciServer + "/v2/the-image-name/tags/list") + final HttpURLConnection connection = (HttpURLConnection) new URL("http://" + remoteOciServer.getUrl() + "/v2/the-image-name/tags/list") .openConnection(); connection.setRequestProperty("Authorization", "Basic " + Base64.encodeBase64String("oci-user:oci-password".getBytes())); connection.connect(); @@ -248,7 +242,7 @@ void pushMultiplatform() throws Exception { try (JibService jibService = new JibService(jibLogger, testAuthConfigFactory, configuration, imageConfiguration)) { jibService.push(); } - final HttpURLConnection connection = (HttpURLConnection) new URL("http://" + remoteOciServer + "/v2/the-image-name/manifests/latest") + final HttpURLConnection connection = (HttpURLConnection) new URL("http://" + remoteOciServer.getUrl() + "/v2/the-image-name/manifests/latest") .openConnection(); connection.setRequestProperty("Authorization", "Basic " + Base64.encodeBase64String("oci-user:oci-password".getBytes())); connection.setRequestProperty("Accept", "application/vnd.docker.distribution.manifest.list.v2+json"); diff --git a/jkube-kit/common/pom.xml b/jkube-kit/common/pom.xml index 5fb24c919f..2389f6e75a 100644 --- a/jkube-kit/common/pom.xml +++ b/jkube-kit/common/pom.xml @@ -147,6 +147,11 @@ com.networknt json-schema-validator + + com.marcnuri.helm-java + helm-java + test + diff --git a/jkube-kit/common/src/test/java/org/eclipse/jkube/kit/common/TestOciServer.java b/jkube-kit/common/src/test/java/org/eclipse/jkube/kit/common/TestOciServer.java new file mode 100644 index 0000000000..c89f3bfc7c --- /dev/null +++ b/jkube-kit/common/src/test/java/org/eclipse/jkube/kit/common/TestOciServer.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2019 Red Hat, Inc. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at: + * + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.jkube.kit.common; + +import com.marcnuri.helm.jni.HelmLib; +import com.marcnuri.helm.jni.NativeLibrary; +import com.marcnuri.helm.jni.RepoServerOptions; +import lombok.Getter; +import org.eclipse.jkube.kit.common.util.Base64Util; + +import java.io.Closeable; +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.URL; +import java.time.Duration; + +import static org.eclipse.jkube.kit.common.util.AsyncUtil.await; +import static org.eclipse.jkube.kit.common.util.AsyncUtil.get; + +@Getter +public class TestOciServer implements Closeable { + + private static final Duration TIMEOUT = Duration.ofSeconds(5); + private static final String DEFAULT_USER = "oci-user"; + private static final String DEFAULT_PASSWORD = "oci-password"; + + // initialization-on-demand holder + private static final class HelmLibHolder { + private static final HelmLib INSTANCE = NativeLibrary.getInstance().load(); + } + + private static HelmLib getHelmLib() { + return HelmLibHolder.INSTANCE; + } + + private final String user; + private final String password; + private final String url; + + public TestOciServer() { + this(DEFAULT_USER, DEFAULT_PASSWORD); + } + + public TestOciServer(String user, String password) { + this.user = user; + this.password = password; + url = get(await(this::startServer).apply(this::waitForServer), TIMEOUT); + } + + @Override + public void close() throws IOException { + // No effect yet https://github.com/manusa/helm-java/blob/f44a88ed1ad351b2b5a00b5e735deb5cb35b32f7/native/internal/helm/repotest.go#L138 + getHelmLib().RepoServerStop(url); + } + + private String startServer() { + return getHelmLib().RepoOciServerStart( + new RepoServerOptions(null, user, password) + ).out; + } + + private boolean waitForServer(String serverUrl) { + try { + final HttpURLConnection connection = (HttpURLConnection) new URL("http://" + serverUrl + "/v2/") + .openConnection(); + connection.setRequestProperty("Authorization", "Basic " + Base64Util.encodeToString(String.join(":", user, password))); + connection.connect(); + return connection.getResponseCode() == HttpURLConnection.HTTP_OK; + } catch (IOException e) { + return false; + } + } +} diff --git a/jkube-kit/config/service/src/test/java/org/eclipse/jkube/kit/config/service/kubernetes/JibImageBuildServicePushTest.java b/jkube-kit/config/service/src/test/java/org/eclipse/jkube/kit/config/service/kubernetes/JibImageBuildServicePushTest.java index 96a516e550..b5d3b06449 100644 --- a/jkube-kit/config/service/src/test/java/org/eclipse/jkube/kit/config/service/kubernetes/JibImageBuildServicePushTest.java +++ b/jkube-kit/config/service/src/test/java/org/eclipse/jkube/kit/config/service/kubernetes/JibImageBuildServicePushTest.java @@ -18,9 +18,6 @@ import com.google.cloud.tools.jib.api.TarImage; import com.google.cloud.tools.jib.api.buildplan.ImageFormat; import com.google.cloud.tools.jib.global.JibSystemProperties; -import com.marcnuri.helm.jni.HelmLib; -import com.marcnuri.helm.jni.NativeLibrary; -import com.marcnuri.helm.jni.RepoServerOptions; import org.apache.commons.codec.binary.Base64; import org.apache.commons.io.IOUtils; import org.eclipse.jkube.kit.common.JKubeConfiguration; @@ -29,6 +26,7 @@ import org.eclipse.jkube.kit.common.KitLogger; import org.eclipse.jkube.kit.common.RegistryConfig; import org.eclipse.jkube.kit.common.RegistryServerConfiguration; +import org.eclipse.jkube.kit.common.TestOciServer; import org.eclipse.jkube.kit.config.image.ImageConfiguration; import org.eclipse.jkube.kit.config.image.build.BuildConfiguration; import org.eclipse.jkube.kit.config.resource.RuntimeMode; @@ -36,7 +34,6 @@ import org.eclipse.jkube.kit.config.service.JKubeServiceException; import org.eclipse.jkube.kit.config.service.JKubeServiceHub; import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; @@ -59,24 +56,16 @@ class JibImageBuildServicePushTest { - private static HelmLib helmLib; - @TempDir private Path temporaryFolder; private boolean sendCredentialsOverHttp; - private String remoteOciServer; - + private TestOciServer remoteOciServer; private KitLogger logger; private JKubeServiceHub jKubeServiceHub; private ImageConfiguration imageConfiguration; - @BeforeAll - static void setUpAll() { - helmLib = NativeLibrary.getInstance().load(); - } - @BeforeEach void setUp() throws Exception { sendCredentialsOverHttp = JibSystemProperties.sendCredentialsOverHttp(); @@ -85,9 +74,7 @@ void setUp() throws Exception { logger = spy(new KitLogger.SilentLogger()); // Setup OCI server - remoteOciServer = helmLib.RepoOciServerStart( - new RepoServerOptions(null, "oci-user", "oci-password") - ).out; + remoteOciServer = new TestOciServer(); // Configure OCI server in image and JKube imageConfiguration = ImageConfiguration.builder() @@ -95,7 +82,7 @@ void setUp() throws Exception { .build(BuildConfiguration.builder() .from("scratch") .build()) - .registry(remoteOciServer) + .registry(remoteOciServer.getUrl()) .build(); jKubeServiceHub = JKubeServiceHub.builder() .log(logger) @@ -105,12 +92,12 @@ void setUp() throws Exception { .project(JavaProject.builder().baseDirectory(temporaryFolder.toFile()).build()) .pullRegistryConfig(RegistryConfig.builder().settings(Collections.emptyList()).build()) .pushRegistryConfig(RegistryConfig.builder() - .registry(remoteOciServer) + .registry(remoteOciServer.getUrl()) .settings(Collections.singletonList( RegistryServerConfiguration.builder() - .id(remoteOciServer) - .username("oci-user") - .password("oci-password") + .id(remoteOciServer.getUrl()) + .username(remoteOciServer.getUser()) + .password(remoteOciServer.getPassword()) .build())) .passwordDecryptionMethod(s -> s) .build()) @@ -120,7 +107,7 @@ void setUp() throws Exception { // Build fake container image final Path tarPath = temporaryFolder .resolve("localhost") - .resolve(remoteOciServer.split(":")[1]) + .resolve(remoteOciServer.getUrl().split(":")[1]) .resolve("test") .resolve("test-image") .resolve("0.0.1") @@ -135,7 +122,8 @@ void setUp() throws Exception { } @AfterEach - void tearDown() { + void tearDown() throws Exception { + remoteOciServer.close(); if (!sendCredentialsOverHttp) { System.clearProperty(JibSystemProperties.SEND_CREDENTIALS_OVER_HTTP); } @@ -193,12 +181,12 @@ void pushValidImage() throws Exception { @Test void logsImagePush() { verify(logger, times(1)) - .info("Pushing image: %s", remoteOciServer + "/test/test-image:0.0.1"); + .info("Pushing image: %s", remoteOciServer.getUrl() + "/test/test-image:0.0.1"); } @Test void pushesImage() throws Exception { - final HttpURLConnection connection = (HttpURLConnection) new URL("http://" + remoteOciServer + "/v2/test/test-image/tags/list") + final HttpURLConnection connection = (HttpURLConnection) new URL("http://" + remoteOciServer.getUrl() + "/v2/test/test-image/tags/list") .openConnection(); connection.setRequestProperty("Authorization", "Basic " + Base64.encodeBase64String("oci-user:oci-password".getBytes())); connection.connect(); @@ -229,12 +217,12 @@ void pushValidImage() throws Exception { @Test void logsImagePush() { verify(logger, times(1)) - .info("Pushing image: %s", remoteOciServer + "/test/test-image:multiplatform"); + .info("Pushing image: %s", remoteOciServer.getUrl() + "/test/test-image:multiplatform"); } @Test void pushesImage() throws Exception { - final HttpURLConnection connection = (HttpURLConnection) new URL("http://" + remoteOciServer + "/v2/test/test-image/tags/list") + final HttpURLConnection connection = (HttpURLConnection) new URL("http://" + remoteOciServer.getUrl() + "/v2/test/test-image/tags/list") .openConnection(); connection.setRequestProperty("Authorization", "Basic " + Base64.encodeBase64String("oci-user:oci-password".getBytes())); connection.connect(); @@ -245,7 +233,7 @@ void pushesImage() throws Exception { @Test void pushedImageManifestIsMultiplatform() throws Exception { - final HttpURLConnection connection = (HttpURLConnection) new URL("http://" + remoteOciServer + "/v2/test/test-image/manifests/multiplatform") + final HttpURLConnection connection = (HttpURLConnection) new URL("http://" + remoteOciServer.getUrl() + "/v2/test/test-image/manifests/multiplatform") .openConnection(); connection.setRequestProperty("Authorization", "Basic " + Base64.encodeBase64String("oci-user:oci-password".getBytes())); connection.setRequestProperty("Accept", "application/vnd.docker.distribution.manifest.list.v2+json");