Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new xtf.openshift.namespace.per.testcase property which will exec… #490

Merged
merged 1 commit into from
Jul 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ Take a look at the
class to see possible configurations. Enabling some of them will allow you to instantiate as
`OpenShift openShift = OpenShifts.master()`.



##### Pull Secrets
There's a convenient method `OpenShift::setupPullSecret()` to set up pull secrets as recommended by OpenShift
[documentation](https://docs.openshift.com/container-platform/4.2/openshift_images/managing-images/using-image-pull-secrets.html).
Expand Down Expand Up @@ -157,6 +159,51 @@ xtf.foo.v2.version=1.0.3

Retrieving an instance with this metadata: `Produts.resolve("product");`

#### Using `TestCaseContext` to get name of currently running test case

If `junit.jupiter.extensions.autodetection.enabled=true` then JUnit 5 extension `cz.xtf.core.context.TestCaseContextExtension` is
automatically registered. It
sets name of currently running test case into `TestCaseContext` before `@BeforeAll` of test case is called.

Following code then can be used to retrieve the name of currently running test case in:
```
String testCase = TestCaseContext.getRunningTestCaseName()
```

#### Automatic creation of namespace(s)

XTF allows to automatically manage creation of testing namespace which is defined by `xtf.openshift.namespace` property. This
namespace is created before any test case is started.

This feature requires to have XTF JUnit5 `cz.xtf.junit5.listeners.ProjectCreator` extension enabled. This can be done by adding
mchoma marked this conversation as resolved.
Show resolved Hide resolved
`cz.xtf.junit5.listeners.ProjectCreator` line into files:
```
src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension
src/test/resources/META-INF/services/org.junit.platform.launcher.PostDiscoveryFilter
src/test/resources/META-INF/services/org.junit.platform.launcher.TestExecutionListener
```

#### Run test cases in separate namespaces using `xtf.openshift.namespace.per.testcase` property
mchoma marked this conversation as resolved.
Show resolved Hide resolved

You can enable running each test case in separate namespace by setting `xtf.openshift.namespace.per.testcase=true`.

Namespace names follow pattern: "`${xtf.openshift.namespace}`-TestCaseName".
For example for `xtf.openshift.namespace=testnamespace` and test case `org.test.SmokeTest` it will be `testnamespace-SmokeTest`.

You can limit the length of created namespace by `xtf.openshift.namespace.per.testcase.length.limit` property. By default it's `25` chars. If limit is breached then
test case name in namespace name is hashed to hold the limit. So namespace name would like `testnamespace-s623jd6332`

**Warning - Limitations**

When enabling this feature in your project, **you may need to replace [OpenShiftConfig.getNamespace()](core/src/main/java/cz/xtf/core/config/OpenShiftConfig.java)
with [NamespaceManager.getNamespace()](core/src/main/java/cz/xtf/core/namespace/NamespaceManager.java). Check method's javadoc to understand difference.**

In case that you're using this feature, consuming test suite must follow those rules to avoid unexpected behaviour when using `cz.xtf.core.openshift.OpenShift` instances:

* **Do not create static `cz.xtf.core.openshift.OpenShift` variable** like: `public static final OpenShift openshift = Openshifts.master()` on class level.
The reason is that during initialization of static instances the test case and corresponsing namespace is not known. To avoid unexpected behaviour `RuntimeException` is thrown, when programmer breaks this rule.
* Similarly as above do not create `cz.xtf.core.openshift.OpenShift` variables in static blocks or do not initialize other static variables which creates `cz.xtf.core.openshift.OpenShift` instance.

#### Service Logs Streaming (SLS)
This feature allows for you to stream the services output while the test is running; this way you can see immediately
what is happening inside the cluster.
Expand Down Expand Up @@ -216,6 +263,7 @@ following information:
**OPTIONAL**, if not assigned, logs will be streamed to `System.out`. When assigned, XTF will attempt to create the
path in case it doesn't exist and default to `System.out` should any error occur.


###### Usage examples
Given what above, enabling SLS for all test classes is possible by executing the following command:

Expand Down
6 changes: 6 additions & 0 deletions core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,17 @@
<artifactId>logback-classic</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>uk.org.webcompere</groupId>
<artifactId>system-stubs-jupiter</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/java/cz/xtf/core/bm/BuildManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public BuildManager(OpenShift openShift) {
// Otherwise you can see:
// $ oc label namespace <name> "label1=foo"
// Error from server (Forbidden): namespaces "<name>" is forbidden: User "<user>" cannot patch resource "namespaces" in API group "" in the namespace "<name>"
OpenShifts.admin().namespaces().withName(openShift.getNamespace())
OpenShifts.admin(openShift.getNamespace()).namespaces().withName(openShift.getNamespace())
mnovak1 marked this conversation as resolved.
Show resolved Hide resolved
.edit(new Visitor<NamespaceBuilder>() {
@Override
public void visit(NamespaceBuilder builder) {
Expand Down
45 changes: 44 additions & 1 deletion core/src/main/java/cz/xtf/core/config/OpenShiftConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

import java.nio.file.Paths;

import cz.xtf.core.openshift.OpenShifts;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public final class OpenShiftConfig {
public static final String OPENSHIFT_URL = "xtf.openshift.url";
public static final String OPENSHIFT_TOKEN = "xtf.openshift.token";
Expand All @@ -22,6 +26,19 @@ public final class OpenShiftConfig {
public static final String OPENSHIFT_MASTER_TOKEN = "xtf.openshift.master.token";
public static final String OPENSHIFT_ROUTE_DOMAIN = "xtf.openshift.route_domain";
public static final String OPENSHIFT_PULL_SECRET = "xtf.openshift.pullsecret";
public static final String OPENSHIFT_NAMESPACE_PER_TESTCASE = "xtf.openshift.namespace.per.testcase";
/**
* Used only if xtf.openshift.namespace.per.testcase=true - this property can configure its maximum length. This is useful
* in case
* where namespace is used in first part of URL of route which must have <64 chars length.
*/
public static final String OPENSHIFT_NAMESPACE_NAME_LENGTH_LIMIT = "xtf.openshift.namespace.per.testcase.length.limit";

/**
* Used only if xtf.openshift.namespace.per.testcase=true - this property configures default maximum length of namespace
* name.
*/
private static final String DEFAULT_OPENSHIFT_NAMESPACE_NAME_LENGTH_LIMIT = "25";

public static String url() {
return XTFConfig.get(OPENSHIFT_URL);
Expand All @@ -48,10 +65,36 @@ public static String version() {
return XTFConfig.get(OPENSHIFT_VERSION);
}

/**
* Note that most likely you want to use {@see NamespaceManager#getNamespace()} which returns actual namespace
* used by current tests. For example {@link OpenShifts#master()} is using {@see NamespaceManager#getNamespace()}
* to get default namespace for currently running test.
*
* @return Returns namespace as defined in xtf.openshift.namespace property
*/
public static String namespace() {
return XTFConfig.get(OPENSHIFT_NAMESPACE);
}

/**
* @return if property xtf.openshift.namespace.per.testcase is empty or true then returns true otherwise false
*/
public static boolean useNamespacePerTestCase() {
return XTFConfig.get(OPENSHIFT_NAMESPACE_PER_TESTCASE) != null
&& (XTFConfig.get(OPENSHIFT_NAMESPACE_PER_TESTCASE).equals("")
|| XTFConfig.get(OPENSHIFT_NAMESPACE_PER_TESTCASE).toLowerCase().equals("true"));
}

/**
* Used only if xtf.openshift.namespace.per.testcase=true
*
* @return limit on namespace if it's set by -Dxtf.openshift.namespace.per.testcase.length.limit property
*/
public static int getNamespaceLengthLimitForUniqueNamespacePerTest() {
return Integer.parseInt(XTFConfig.get(OPENSHIFT_NAMESPACE_NAME_LENGTH_LIMIT,
DEFAULT_OPENSHIFT_NAMESPACE_NAME_LENGTH_LIMIT));
}

public static String binaryPath() {
return XTFConfig.get(OPENSHIFT_BINARY_PATH);
}
Expand All @@ -60,7 +103,7 @@ public static String binaryPath() {
* Channel configuration for download of OpenShift client from
* https://mirror.openshift.com/pub/openshift-v4/x86_64/clients/ocp/
* Channels are: stable, latest, fast, candidate
*
*
* @return channel as configured in xtf.openshift.binary.url.channel property, or default 'stable'
*/
public static String binaryUrlChannelPath() {
Expand Down
24 changes: 24 additions & 0 deletions core/src/main/java/cz/xtf/core/context/TestCaseContext.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package cz.xtf.core.context;

public class TestCaseContext {

/**
*
* This allows to track currently running test case for correct namespace mapping. This is used to automatically find
* namespace for running test case when
* creating {@link cz.xtf.core.openshift.OpenShift} instances.
*/
private static String runningTestCaseName;

/**
* @return test case name associated with current thread or null if not such mapping exists, for example for com.SmokeTest
* returns SmokeTest
*/
public static String getRunningTestCaseName() {
return runningTestCaseName;
}

public static void setRunningTestCase(String currentlyRunningTestCaseName) {
runningTestCaseName = currentlyRunningTestCaseName;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package cz.xtf.core.context;

import org.junit.jupiter.api.extension.BeforeAllCallback;
import org.junit.jupiter.api.extension.ExtensionContext;

import lombok.extern.slf4j.Slf4j;

/**
* Sets TestCaseContext to name of currently started test case in @BeforeAllCallback
*/
@Slf4j
public class TestCaseContextExtension implements BeforeAllCallback {

@Override
public void beforeAll(ExtensionContext extensionContext) {
TestCaseContext.setRunningTestCase(extensionContext.getTestClass().get().getName());
}
}
Loading