Skip to content

Commit

Permalink
KOGITO-9605 Created abstract test class that implementations of Kuber…
Browse files Browse the repository at this point in the history
…netesServiceCatalog must cover
  • Loading branch information
hbelmiro committed Jul 25, 2023
1 parent 31f2b0f commit cc0804e
Show file tree
Hide file tree
Showing 10 changed files with 326 additions and 58 deletions.
13 changes: 13 additions & 0 deletions addons/common/kubernetes-service-catalog/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,17 @@
<artifactId>kogito-addons-kubernetes-service-catalog</artifactId>
<name>Kogito :: Add-Ons :: Kubernetes Service Catalog</name>
<description>Common Library for Kubernetes Service Discovery implementations</description>

<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/*
* Copyright 2023 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.kie.kogito.addons.k8s.resource.catalog;

import java.net.URI;
import java.util.stream.Stream;

import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

import static org.assertj.core.api.Assertions.assertThat;
import static org.kie.kogito.addons.k8s.resource.catalog.KubernetesProtocol.KNATIVE;
import static org.kie.kogito.addons.k8s.resource.catalog.KubernetesProtocol.KUBERNETES;
import static org.kie.kogito.addons.k8s.resource.catalog.KubernetesProtocol.OPENSHIFT;

/**
* Test classes for implementations of {@link KubernetesServiceCatalog} must extend this class.
* It tests all use cases an implementation of {@link KubernetesServiceCatalog} must cover.
*/
public abstract class KubernetesServiceCatalogTest {

private static final String EXPECTED_KNATIVE_URI = "http://serverless-workflow-greeting-quarkus.test.10.99.154.147.sslip.io";

private static final String EXPECTED_KUBERNETES_URI = "http://serverless-workflow-greeting-quarkus-kubernetes.test.10.99.154.147.sslip.io";

private static final String EXPECTED_OPENSHIFT_URI = "http://serverless-workflow-greeting-quarkus-openshift.test.10.99.154.147.sslip.io";

private static final String NAMESPACE = "test";

private static final String KNATIVE_SERVICENAME = "serverless-workflow-greeting-quarkus";

private static final String KUBERNETES_SERVICENAME = "serverless-workflow-greeting-quarkus-kubernetes";

private static final String OPENSHIFT_SERVICENAME = "serverless-workflow-greeting-quarkus-openshift";

private static final String NAMESPACE_KNATIVE_SERVICENAME = NAMESPACE + '/' + KNATIVE_SERVICENAME;

private static final String NAMESPACE_KUBERNETES_SERVICENAME = NAMESPACE + '/' + KUBERNETES_SERVICENAME;

private static final String NAMESPACE_OPENSHIFT_SERVICENAME = NAMESPACE + '/' + OPENSHIFT_SERVICENAME;

private static final String GVK = "services.v1.serving.knative.dev";

private static final String GVK_KNATIVE_SERVICENAME = GVK + '/' + KNATIVE_SERVICENAME;

private static final String GVK_NAMESPACE_SERVICENAME = GVK + '/' + NAMESPACE_KNATIVE_SERVICENAME;

private static final String GVK_KUBERNETES_SERVICENAME = GVK + '/' + KUBERNETES_SERVICENAME;

private static final String GVK_NAMESPACE_KUBERNETES_SERVICENAME = GVK + '/' + NAMESPACE_KUBERNETES_SERVICENAME;

private static final String GVK_OPENSHIFT_SERVICENAME = GVK + '/' + OPENSHIFT_SERVICENAME;

private static final String GVK_NAMESPACE_OPENSHIFT_SERVICENAME = GVK + '/' + NAMESPACE_OPENSHIFT_SERVICENAME;

private final KubernetesServiceCatalog kubernetesServiceCatalog;

protected KubernetesServiceCatalogTest(KubernetesServiceCatalog kubernetesServiceCatalog) {
this.kubernetesServiceCatalog = kubernetesServiceCatalog;
}

protected final String getNamespace() {
return NAMESPACE;
}

protected final String getKnativeServiceName() {
return KNATIVE_SERVICENAME;
}

protected final String getKubernetesServiceName() {
return KUBERNETES_SERVICENAME;
}

protected final String getOpenshiftServicename() {
return OPENSHIFT_SERVICENAME;
}

@ParameterizedTest
@MethodSource("possibleUriFormats")
void getServiceAddress(KubernetesProtocol kubernetesProtocol, String coordinates, String expectedUri) {
KubernetesServiceCatalogKey key = new KubernetesServiceCatalogKey(kubernetesProtocol, coordinates);
assertThat(kubernetesServiceCatalog.getServiceAddress(key))
.map(URI::toString)
.hasValue(expectedUri);
}

protected static Stream<Arguments> possibleUriFormats() {
return Stream.of(
Arguments.of(KNATIVE, KNATIVE_SERVICENAME, EXPECTED_KNATIVE_URI),
Arguments.of(KNATIVE, NAMESPACE_KNATIVE_SERVICENAME, EXPECTED_KNATIVE_URI),
Arguments.of(KNATIVE, GVK_KNATIVE_SERVICENAME, EXPECTED_KNATIVE_URI),
Arguments.of(KNATIVE, GVK_NAMESPACE_SERVICENAME, EXPECTED_KNATIVE_URI),

Arguments.of(KUBERNETES, GVK_KUBERNETES_SERVICENAME, EXPECTED_KUBERNETES_URI),
Arguments.of(KUBERNETES, GVK_NAMESPACE_KUBERNETES_SERVICENAME, EXPECTED_KUBERNETES_URI),

Arguments.of(OPENSHIFT, GVK_OPENSHIFT_SERVICENAME, EXPECTED_OPENSHIFT_URI),
Arguments.of(OPENSHIFT, GVK_NAMESPACE_OPENSHIFT_SERVICENAME, EXPECTED_OPENSHIFT_URI));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@
<artifactId>kubernetes-client</artifactId>
</dependency>

<dependency>
<groupId>org.kie.kogito</groupId>
<artifactId>kogito-addons-kubernetes-service-catalog</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-test-kubernetes-client</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Copyright 2023 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.kie.kogito.addons.quarkus.fabric8.k8s.service.catalog;

import javax.inject.Inject;

import org.junit.jupiter.api.BeforeEach;
import org.kie.kogito.addons.k8s.resource.catalog.KubernetesServiceCatalogTest;

import io.fabric8.kubernetes.client.server.mock.KubernetesServer;
import io.quarkus.test.junit.QuarkusTest;
import io.quarkus.test.kubernetes.client.KubernetesTestServer;
import io.quarkus.test.kubernetes.client.WithKubernetesTestServer;

import static org.kie.kogito.addons.quarkus.k8s.test.utils.KnativeResourceDiscoveryTestUtil.createServiceIfNotExists;

@QuarkusTest
@WithKubernetesTestServer
class Fabric8KubernetesServiceCatalogTest extends KubernetesServiceCatalogTest {

@KubernetesTestServer
KubernetesServer mockServer;

@BeforeEach
void beforeEach() {
createServiceIfNotExists(mockServer, "knative/quarkus-greeting.yaml", getNamespace(), getKnativeServiceName());
createServiceIfNotExists(mockServer, "knative/quarkus-greeting-kubernetes.yaml", getNamespace(), getKubernetesServiceName());
createServiceIfNotExists(mockServer, "knative/quarkus-greeting-openshift.yaml", getNamespace(), getOpenshiftServicename());
}

@Inject
Fabric8KubernetesServiceCatalogTest(Fabric8KubernetesServiceCatalog fabric8KubernetesServiceCatalog) {
super(fabric8KubernetesServiceCatalog);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class KnativeServiceDiscoveryTest {
@Test
void queryService() {
String remoteServiceUrl = "http://" + REMOTE_SERVICE_HOST;
KnativeResourceDiscoveryTestUtil.createServiceIfNotExists(mockServer, remoteServiceUrl, "knative/quarkus-greeting.yaml", "test", "serverless-workflow-greeting-quarkus");
KnativeResourceDiscoveryTestUtil.createServiceIfNotExists(mockServer, "knative/quarkus-greeting.yaml", "test", "serverless-workflow-greeting-quarkus", remoteServiceUrl);

Optional<URI> uri = knativeServiceDiscovery.query(new KnativeServiceUri("test", "serverless-workflow-greeting-quarkus"));

Expand All @@ -62,7 +62,7 @@ void queryService() {
@Test
void https() {
String remoteServiceUrl = "https://" + REMOTE_SERVICE_HOST;
KnativeResourceDiscoveryTestUtil.createServiceIfNotExists(mockServer, remoteServiceUrl, "knative/quarkus-greeting-https.yaml", "test", "serverless-workflow-greeting-quarkus-https");
KnativeResourceDiscoveryTestUtil.createServiceIfNotExists(mockServer, "knative/quarkus-greeting-https.yaml", "test", "serverless-workflow-greeting-quarkus-https", remoteServiceUrl);

Optional<URI> url = knativeServiceDiscovery.query(new KnativeServiceUri("test", "serverless-workflow-greeting-quarkus-https"));

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
annotations:
serving.knative.dev/creator: minikube-user
serving.knative.dev/lastModifier: minikube-user
creationTimestamp: '2022-08-17T13:58:53Z'
generation: 1
name: serverless-workflow-greeting-quarkus-kubernetes
resourceVersion: '43817'
uid: 98530cb6-3274-4d0c-b654-a82645cda058
spec:
template:
metadata:
annotations:
client.knative.dev/updateTimestamp: '2022-08-17T13:58:53Z'
client.knative.dev/user-image: kiegroup/serverless-workflow-greeting-quarkus:1.0
creationTimestamp:
spec:
containerConcurrency: 0
containers:
- image: kiegroup/serverless-workflow-greeting-quarkus:1.0
name: user-container
readinessProbe:
successThreshold: 1
tcpSocket:
port: 0
resources: { }
enableServiceLinks: false
timeoutSeconds: 300
traffic:
- latestRevision: true
percent: 100
status:
address:
url: http://serverless-workflow-greeting-quarkus.test.svc.cluster.local
conditions:
- lastTransitionTime: '2022-08-17T13:59:00Z'
status: 'True'
type: ConfigurationsReady
- lastTransitionTime: '2022-08-17T13:59:00Z'
status: 'True'
type: Ready
- lastTransitionTime: '2022-08-17T13:59:00Z'
status: 'True'
type: RoutesReady
latestCreatedRevisionName: serverless-workflow-greeting-quarkus-00001
latestReadyRevisionName: serverless-workflow-greeting-quarkus-00001
observedGeneration: 1
traffic:
- latestRevision: true
percent: 100
revisionName: serverless-workflow-greeting-quarkus-00001
url: http://serverless-workflow-greeting-quarkus-kubernetes.test.10.99.154.147.sslip.io
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
annotations:
serving.knative.dev/creator: minikube-user
serving.knative.dev/lastModifier: minikube-user
creationTimestamp: '2022-08-17T13:58:53Z'
generation: 1
name: serverless-workflow-greeting-quarkus-openshift
resourceVersion: '43817'
uid: 98530cb6-3274-4d0c-b654-a82645cda058
spec:
template:
metadata:
annotations:
client.knative.dev/updateTimestamp: '2022-08-17T13:58:53Z'
client.knative.dev/user-image: kiegroup/serverless-workflow-greeting-quarkus:1.0
creationTimestamp:
spec:
containerConcurrency: 0
containers:
- image: kiegroup/serverless-workflow-greeting-quarkus:1.0
name: user-container
readinessProbe:
successThreshold: 1
tcpSocket:
port: 0
resources: { }
enableServiceLinks: false
timeoutSeconds: 300
traffic:
- latestRevision: true
percent: 100
status:
address:
url: http://serverless-workflow-greeting-quarkus.test.svc.cluster.local
conditions:
- lastTransitionTime: '2022-08-17T13:59:00Z'
status: 'True'
type: ConfigurationsReady
- lastTransitionTime: '2022-08-17T13:59:00Z'
status: 'True'
type: Ready
- lastTransitionTime: '2022-08-17T13:59:00Z'
status: 'True'
type: RoutesReady
latestCreatedRevisionName: serverless-workflow-greeting-quarkus-00001
latestReadyRevisionName: serverless-workflow-greeting-quarkus-00001
observedGeneration: 1
traffic:
- latestRevision: true
percent: 100
revisionName: serverless-workflow-greeting-quarkus-00001
url: http://serverless-workflow-greeting-quarkus-openshift.test.10.99.154.147.sslip.io
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,12 @@ public final class KnativeResourceDiscoveryTestUtil {
private KnativeResourceDiscoveryTestUtil() {
}

public static void createServiceIfNotExists(KubernetesServer k8sServer, String knativeYaml, String namespace, String serviceName) {
createServiceIfNotExists(k8sServer, knativeYaml, namespace, serviceName, null);
}

@SuppressWarnings("deprecation") // Quarkus LTS 2.13 compatibility
public static void createServiceIfNotExists(KubernetesServer k8sServer, String remoteServiceUrl, String knativeYaml, String namespace, String serviceName) {
public static void createServiceIfNotExists(KubernetesServer k8sServer, String knativeYaml, String namespace, String serviceName, String remoteServiceUrl) {
if (k8sServer.getClient().services().inNamespace("test").withName(serviceName).get() == null) {
KnativeClient knativeClient = k8sServer.getClient().adapt(KnativeClient.class);

Expand All @@ -36,7 +40,9 @@ public static void createServiceIfNotExists(KubernetesServer k8sServer, String r
.load(getResourceAsStream(knativeYaml))
.get();

service.getStatus().setUrl(remoteServiceUrl);
if (remoteServiceUrl != null) {
service.getStatus().setUrl(remoteServiceUrl);
}

// ItemWritableOperation#create is deprecated. However, we can't use the new method while Quarkus LTS is not greater than 2.16.
knativeClient.services().inNamespace(namespace).create(service);
Expand Down
Loading

0 comments on commit cc0804e

Please sign in to comment.