Skip to content

Commit

Permalink
ENTESB-16216Migrate spring-boot-cxf-jaxws-xml quickstart off Arquillian
Browse files Browse the repository at this point in the history
  • Loading branch information
luigidemasi committed Apr 27, 2021
1 parent 29d47c2 commit 988fc88
Show file tree
Hide file tree
Showing 8 changed files with 652 additions and 37 deletions.
4 changes: 2 additions & 2 deletions README.adoc
Expand Up @@ -70,15 +70,15 @@ will now display the generated WSDL.

== Integration Testing

The example includes a https://github.com/fabric8io/fabric8/tree/master/components/fabric8-arquillian[fabric8 arquillian] Kubernetes Integration Test.
The example includes a Kubernetes Integration Test.
Once the container image has been built and deployed in Kubernetes, the integration test can be run with:

[source,bash,options="nowrap",subs="attributes+"]
----
mvn test -Dtest=*KT
----

The test is disabled by default and has to be enabled using `-Dtest`. https://fabric8.io/guide/testing.html[Integration Testing] and https://fabric8.io/guide/arquillian.html[Fabric8 Arquillian Extension] provide more information on writing full fledged black box integration tests for Kubernetes.
The test is disabled by default and has to be enabled using `-Dtest`.

== Running the quickstart standalone on your machine

Expand Down
17 changes: 8 additions & 9 deletions pom.xml
Expand Up @@ -62,24 +62,23 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.jboss.arquillian.junit</groupId>
<artifactId>arquillian-junit-container</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.arquillian.cube</groupId>
<artifactId>arquillian-cube-openshift</artifactId>
<groupId>io.fabric8</groupId>
<artifactId>kubernetes-model</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>io.fabric8</groupId>
<artifactId>kubernetes-model</artifactId>
<artifactId>kubernetes-client</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>io.fabric8</groupId>
<artifactId>kubernetes-client</artifactId>
<artifactId>openshift-client</artifactId>
<version>4.6.2</version>
<scope>test</scope>
</dependency>

Expand Down
Expand Up @@ -16,42 +16,53 @@

package io.fabric8.quickstarts.cxf.jaxws;


import static org.junit.Assert.assertTrue;

import org.arquillian.cube.kubernetes.api.Session;
import org.jboss.arquillian.container.test.api.RunAsClient;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.junit.Test;
import org.junit.runner.RunWith;

import io.fabric8.kubernetes.api.model.Pod;
import io.fabric8.kubernetes.api.model.PodList;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.internal.readiness.Readiness;
import io.fabric8.quickstarts.cxf.jaxws.support.KubernetesTestConfig;
import io.fabric8.quickstarts.cxf.jaxws.support.KubernetesTestSetup;
import org.junit.Assert;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.TimeUnit;

import static io.fabric8.quickstarts.cxf.jaxws.support.KubernetesTestConfig.createConfig;

@RunWith(Arquillian.class)
@RunAsClient
public class KubernetesIntegrationKT {

@ArquillianResource
KubernetesClient client;
private static Logger LOG = LoggerFactory.getLogger(KubernetesIntegrationKT.class);

@ArquillianResource
public Session session;

@Test
public void testAppProvisionsRunningPods() throws Exception {
boolean foundReadyPod = false;

PodList podList = client.pods().inNamespace(session.getNamespace()).list();
for (Pod p : podList.getItems()) {
if (!p.getMetadata().getName().endsWith("build") && !p.getMetadata().getName().endsWith("deploy")) {
assertTrue(p.getMetadata().getName() + " is not ready", Readiness.isReady(p));
foundReadyPod = true;
public void testAppProvisionsRunningPods() {
KubernetesTestConfig config = createConfig();
KubernetesTestSetup testSetup = new KubernetesTestSetup(config);

try {
testSetup.setUp();
KubernetesClient client = config.getClient();
PodList podList = client.pods().inNamespace(config.getNamespace()).list();

if (podList.getItems().isEmpty()) {
Assert.fail("No pods found in namespace "+ config.getNamespace());
}

for (Pod pod : podList.getItems()) {
try {
if (!pod.getMetadata().getName().endsWith("build") && !pod.getMetadata().getName().endsWith("deploy")) {
client.resource(pod)
.inNamespace(config.getNamespace())
.waitUntilReady(config.getKubernetesTimeout(), TimeUnit.SECONDS);
LOG.info("Pod {} is in state: {}",pod.getMetadata().getName(),pod.getStatus().getPhase());
}
} catch (InterruptedException e) {
Assert.fail("Timeout reached waiting for pod " + pod.getMetadata().getName());
}
}
} finally {
testSetup.tearDown();
}
assertTrue("Found no ready pods in namespace", foundReadyPod);
}
}
@@ -0,0 +1,233 @@
package io.fabric8.quickstarts.cxf.jaxws.support;

import io.fabric8.kubernetes.client.Config;
import io.fabric8.kubernetes.client.ConfigBuilder;
import io.fabric8.kubernetes.client.DefaultKubernetesClient;
import io.fabric8.kubernetes.client.KubernetesClient;
import org.xml.sax.SAXException;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPathExpressionException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
import java.util.UUID;
import java.util.function.Predicate;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static io.fabric8.quickstarts.cxf.jaxws.support.KubernetesTestUtil.failNotDeployed;
import static io.fabric8.quickstarts.cxf.jaxws.support.KubernetesTestUtil.getArrayListStringProperty;
import static io.fabric8.quickstarts.cxf.jaxws.support.KubernetesTestUtil.getArtifactId;
import static io.fabric8.quickstarts.cxf.jaxws.support.KubernetesTestUtil.getBooleanProperty;
import static io.fabric8.quickstarts.cxf.jaxws.support.KubernetesTestUtil.getIntProperty;
import static io.fabric8.quickstarts.cxf.jaxws.support.KubernetesTestUtil.getResourceFileAsStream;
import static io.fabric8.quickstarts.cxf.jaxws.support.KubernetesTestUtil.getStringProperty;
import static io.fabric8.quickstarts.cxf.jaxws.support.KubernetesTestUtil.isNullOrEmpty;
import static java.util.Collections.singletonMap;
import static java.util.Objects.nonNull;


public class KubernetesTestConfig {


public static final String NAMESPACE_USE_CURRENT = "kt.namespace.use.current";
public static final String NAMESPACE_TO_USE = "kt.namespace.use.existing";
public static final String NAMESPACE_DESTROY_ENABLED = "kt.namespace.destroy.enabled";
public static final String NAMESPACE_PREFIX = "kt.namespace.prefix";
public static final String RESOUCE_FILE_PATH = "kt.resource.file.path";
public static final String KUBERNETES_MASTER = "kubernetes.master";
public static final String KUBERNETES_USERNAME = "kubernetes.username";
public static final String KUBERNETES_PASSWORD = "kubernetes.password";
public static final String KUBERNETES_TIMEOUT = "kubernetes.timeout";

public static final int DEFAULT_KUBERNETES_TIMEOUT = 300;
public static final String ENV_DEPENDENCIES = "kt.env.dependencies";
public static final String DEFAULT_NAMESPACE_PREFIX = "ktest";

public static final String TARGET_DIR_PATH = System.getProperty("basedir", ".") + "/target";
public static final String DEFAULT_RESOUCE_FILE_PATH = TARGET_DIR_PATH + "/classes/META-INF/jkube/openshift.yml";

public static final String TEST_PROPERTIES_FILE = "kubernetesTest.properties";


private final Properties systemPropertiesVars = System.getProperties();

private boolean shouldDestroyNamespace = false;

private boolean useExistingNamespace = true;

private String namespace;

private String resourceFilePath;

private String imageStreamFilePath;

private List<String> dependencies;

private String kubernetesMaster;

private String kubernetesUsername;

private String kubernetesPassword;

private KubernetesClient kubeClient;

private int kubernetesTimeout;

private String mainNamespace;

private Map<String,String> ktestLabels = singletonMap("scope","ktest");

private KubernetesTestConfig() {
}

public static KubernetesTestConfig createConfig() {
KubernetesTestConfig config = new KubernetesTestConfig();
config.loadConfiguration();
return config;
}

public KubernetesClient getClient() {
if (kubeClient == null) {
if (isNullOrEmpty(kubernetesMaster)) {
kubeClient = new DefaultKubernetesClient();
}else {
Config config = new ConfigBuilder()
.withMasterUrl(kubernetesMaster)
.withUsername(kubernetesUsername)
.withPassword(kubernetesPassword)
.build();
kubeClient = new DefaultKubernetesClient(config);
}
}
return kubeClient;
}

private void loadConfiguration() {

Properties prop = new Properties();

try (InputStream input = getResourceFileAsStream(TEST_PROPERTIES_FILE)) {
// load a properties file
if(nonNull(input)) {
prop.load(input);
}
} catch (IOException e) {
throw new RuntimeException(e);
}

prop.putAll(systemPropertiesVars);

Map<String, String> testConfig = prop.entrySet().stream().collect(
Collectors.toMap(
e -> String.valueOf(e.getKey()),
e -> String.valueOf(e.getValue()),
(prev, next) -> next,
HashMap::new)
);
String artifactId = null;
try{
artifactId = getArtifactId();
} catch (XPathExpressionException | ParserConfigurationException |IOException| SAXException e) {
failNotDeployed();
}

namespace = generateNamespaceName(testConfig);

resourceFilePath = getStringProperty(RESOUCE_FILE_PATH, testConfig, DEFAULT_RESOUCE_FILE_PATH);

imageStreamFilePath = TARGET_DIR_PATH + "/" + artifactId + "-is.yml" ;

dependencies = getArrayListStringProperty(ENV_DEPENDENCIES, testConfig);

kubernetesMaster = getStringProperty(KUBERNETES_MASTER, testConfig, null);

kubernetesUsername = getStringProperty(KUBERNETES_USERNAME, testConfig, null);

kubernetesPassword = getStringProperty(KUBERNETES_PASSWORD, testConfig, null);

kubernetesTimeout = getIntProperty(KUBERNETES_TIMEOUT,testConfig,DEFAULT_KUBERNETES_TIMEOUT);

shouldDestroyNamespace = getBooleanProperty(NAMESPACE_DESTROY_ENABLED, testConfig, true);

mainNamespace = extractMainNamespaceName(imageStreamFilePath);
}


private String generateNamespaceName(Map<String, String> config) {
String sessionId = UUID.randomUUID().toString().split("-")[0];
String namespace = getBooleanProperty(NAMESPACE_USE_CURRENT, config, false)
? new ConfigBuilder().build().getNamespace()
: getStringProperty(NAMESPACE_TO_USE, config, null);
if (isNullOrEmpty(namespace)) {
namespace = getStringProperty(NAMESPACE_PREFIX, config, DEFAULT_NAMESPACE_PREFIX) + "-" + sessionId;
shouldDestroyNamespace = true;
useExistingNamespace = false;
}
return namespace;
}

private String extractMainNamespaceName(String imageStreamFilePath){
Pattern pattern = Pattern.compile("\\s*\"namespace\"\\s*:\\s*\"[a-z0-9]([-a-z0-9]*[a-z0-9])?\".*");
Predicate<String> namespacePredicate = pattern.asPredicate();

Optional<String> mainNamespace = Optional.empty();

try (Stream<String> stream = Files.lines(Paths.get(imageStreamFilePath))) {
mainNamespace = stream
.filter(namespacePredicate)
.map(x->pattern.matcher(x).group(1)).findFirst();
}catch (IOException e) {
failNotDeployed();
}
return mainNamespace.orElseGet(() -> new DefaultKubernetesClient().getNamespace());
}


// Getter


public String getNamespace() {
return namespace;
}

public String getResourceFilePath() {
return resourceFilePath;
}

public List<String> getDependencies() {
return dependencies;
}

public boolean isUseExistingNamespace() {
return useExistingNamespace;
}

public boolean isShouldDestroyNamespace() {
return shouldDestroyNamespace;
}

public int getKubernetesTimeout() {
return kubernetesTimeout;
}

public Map<String, String> getKtestLabels() {
return ktestLabels;
}

public String getImageStreamFilePath() {
return imageStreamFilePath;
}

public String getMainNamespace() {
return mainNamespace;
}
}

0 comments on commit 988fc88

Please sign in to comment.