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

Rename GlobalLogCollector to MustGather and use only one callback #133

Merged
merged 3 commits into from
Jul 11, 2024
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
22 changes: 11 additions & 11 deletions test-frame-log-collector/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,33 +169,33 @@ the logs path will then look like this:
```
The tree path will look similarly to above examples, there will be folders for Namespaces matching the specified labels.

### Global log collector
`CollectLogs` is an annotation which can handle collecting logs which user want automatically in case of test failure or before/after failure.
It gets configuration passed into `GlobalLogCollector` and call collecting in proper callbacks.
### MustGather
`MustGather` is an annotation which can handle collecting logs which user want automatically in case of test failure or before/after failure.
It gets configuration passed into `MustGatherController` and call collecting in proper callbacks.

Register `GlobalLogCollector` handlers and configure
Register `MustGatherController` handlers and configure

```java
import io.skodjob.testframe.LogCollectorBuilder;
import io.skodjob.testframe.annotations.CollectLogs;
import io.skodjob.testframe.listeners.GlobalLogCollector;
import io.skodjob.testframe.annotations.MustGather;
import io.skodjob.testframe.listeners.MustGatherController;
import io.skodjob.testframe.resources.KubeResourceManager;
import org.junit.jupiter.api.Test;

@CollectLogs
@MustGather
class TestClass() {
static {
// Setup global log collector and handlers
GlobalLogCollector.setupGlobalLogCollector(new LogCollectorBuilder()
MustGatherController.setupMustGatherController(new LogCollectorBuilder()
.withNamespacedResources("sa", "deployment", "configmaps", "secret")
.withClusterWideResources("nodes")
.withKubeClient(KubeResourceManager.getKubeClient())
.withKubeCmdClient(KubeResourceManager.getKubeCmdClient())
.withRootFolderPath("/some-path/path/")
.build());
GlobalLogCollector.addLogCallback(() -> {
GlobalLogCollector.getGlobalLogCollector().collectFromNamespaces("test-namespace", "test-namespace-2");
GlobalLogCollector.getGlobalLogCollector().collectClusterWideResources();
MustGatherController.setMustGatherCallback(() -> {
MustGatherController.getMustGatherController().collectFromNamespaces("test-namespace", "test-namespace-2");
MustGatherController.getMustGatherController().collectClusterWideResources();
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/
package io.skodjob.testframe.annotations;

import io.skodjob.testframe.listeners.GlobalLogCollector;
import io.skodjob.testframe.listeners.MustGatherController;
import org.junit.jupiter.api.extension.ExtendWith;

import java.lang.annotation.ElementType;
Expand All @@ -19,11 +19,11 @@
* when test of prepare and post phase fails in JUnit tests.
* It is applied at the class level.
* <p>
* It uses the {@link GlobalLogCollector}
* It uses the {@link MustGatherController}
*/
@Target(ElementType.TYPE)
@Retention(RUNTIME)
@Inherited
@ExtendWith(GlobalLogCollector.class)
public @interface CollectLogs {
@ExtendWith(MustGatherController.class)
public @interface MustGather {
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,26 @@
package io.skodjob.testframe.listeners;

import io.skodjob.testframe.LogCollector;
import io.skodjob.testframe.annotations.CollectLogs;
import io.skodjob.testframe.annotations.MustGather;
import io.skodjob.testframe.interfaces.ThrowableRunner;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.LifecycleMethodExecutionExceptionHandler;
import org.junit.jupiter.api.extension.TestExecutionExceptionHandler;

import java.util.LinkedList;
import java.util.List;

/**
* Represents global log collector which is automatically called on text fail or error even in setup or post methods
*/
public class GlobalLogCollector implements TestExecutionExceptionHandler, LifecycleMethodExecutionExceptionHandler {
private static final Logger LOGGER = LogManager.getLogger(GlobalLogCollector.class);
private static LogCollector globalInstance;
private static final List<ThrowableRunner> COLLECT_CALLBACKS = new LinkedList<>();
public class MustGatherController implements TestExecutionExceptionHandler, LifecycleMethodExecutionExceptionHandler {
private static final Logger LOGGER = LogManager.getLogger(MustGatherController.class);
private static LogCollector mustGatherInstance;
private static ThrowableRunner collectCallback;

/**
* Private constructor
*/
private GlobalLogCollector() {
private MustGatherController() {
// empty constructor
}

Expand All @@ -40,7 +37,7 @@ private GlobalLogCollector() {
*/
@Override
public void handleTestExecutionException(ExtensionContext extensionContext, Throwable throwable) throws Throwable {
saveKubeState();
saveKubeState(extensionContext);
throw throwable;
}

Expand All @@ -53,7 +50,7 @@ public void handleTestExecutionException(ExtensionContext extensionContext, Thro
*/
@Override
public void handleBeforeAllMethodExecutionException(ExtensionContext context, Throwable throwable)throws Throwable {
saveKubeState();
saveKubeState(context);
LifecycleMethodExecutionExceptionHandler.super.handleBeforeAllMethodExecutionException(context, throwable);
}

Expand All @@ -67,7 +64,7 @@ public void handleBeforeAllMethodExecutionException(ExtensionContext context, Th
@Override
public void handleBeforeEachMethodExecutionException(ExtensionContext context,
Throwable throwable) throws Throwable {
saveKubeState();
saveKubeState(context);
LifecycleMethodExecutionExceptionHandler.super.handleBeforeEachMethodExecutionException(context, throwable);
}

Expand All @@ -81,7 +78,7 @@ public void handleBeforeEachMethodExecutionException(ExtensionContext context,
@Override
public void handleAfterEachMethodExecutionException(ExtensionContext context,
Throwable throwable) throws Throwable {
saveKubeState();
saveKubeState(context);
LifecycleMethodExecutionExceptionHandler.super.handleAfterEachMethodExecutionException(context, throwable);
}

Expand All @@ -94,44 +91,46 @@ public void handleAfterEachMethodExecutionException(ExtensionContext context,
*/
@Override
public void handleAfterAllMethodExecutionException(ExtensionContext context, Throwable throwable) throws Throwable {
saveKubeState();
saveKubeState(context);
LifecycleMethodExecutionExceptionHandler.super.handleAfterAllMethodExecutionException(context, throwable);
}

/**
* Setup globalLogCollector which is automatically used within {@link CollectLogs} annotation
* Setup globalLogCollector which is automatically used within {@link MustGather} annotation
*
* @param globalLogCollector log collector instance
*/
public static void setupGlobalLogCollector(LogCollector globalLogCollector) {
globalInstance = globalLogCollector;
public static void setupMustGatherController(LogCollector globalLogCollector) {
mustGatherInstance = globalLogCollector;
}

/**
* Returns globalLogCollector instance
*
* @return global log collector instance
*/
public static LogCollector getGlobalLogCollector() {
if (globalInstance == null) {
public static LogCollector getMustGatherController() {
if (mustGatherInstance == null) {
throw new NullPointerException("Global log collector is not initialized");
}
return globalInstance;
return mustGatherInstance;
}

/**
* Adds callback for running log collecting
*
* @param callback callback method with log collecting
*/
public static void addLogCallback(ThrowableRunner callback) {
COLLECT_CALLBACKS.add(callback);
public static void setMustGatherCallback(ThrowableRunner callback) {
collectCallback = callback;
}

private void saveKubeState() {
private void saveKubeState(ExtensionContext context) {
try {
for (ThrowableRunner runner : COLLECT_CALLBACKS) {
runner.run();
if (collectCallback != null) {
collectCallback.run();
} else {
LOGGER.warn("No logCallback defined");
}
} catch (Exception ex) {
LOGGER.error("Cannot collect all data", ex);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
package io.skodjob.testframe.test.integration;

import io.skodjob.testframe.LogCollectorBuilder;
import io.skodjob.testframe.annotations.CollectLogs;
import io.skodjob.testframe.listeners.GlobalLogCollector;
import io.skodjob.testframe.annotations.MustGather;
import io.skodjob.testframe.listeners.MustGatherController;
import io.skodjob.testframe.test.integration.helpers.GlobalLogCollectorTestHandler;
import io.skodjob.testframe.utils.LoggerUtils;
import io.skodjob.testframe.annotations.ResourceManager;
Expand All @@ -26,7 +26,7 @@

@ExtendWith(GlobalLogCollectorTestHandler.class) // For testing purpose
@ResourceManager
@CollectLogs
@MustGather
@TestVisualSeparator
public abstract class AbstractIT {
static AtomicBoolean isCreateHandlerCalled = new AtomicBoolean(false);
Expand Down Expand Up @@ -60,16 +60,16 @@ public abstract class AbstractIT {
});

// Setup global log collector and handlers
GlobalLogCollector.setupGlobalLogCollector(new LogCollectorBuilder()
MustGatherController.setupMustGatherController(new LogCollectorBuilder()
.withNamespacedResources("sa", "deployment", "configmaps", "secret")
.withClusterWideResources("nodes")
.withKubeClient(KubeResourceManager.getKubeClient())
.withKubeCmdClient(KubeResourceManager.getKubeCmdClient())
.withRootFolderPath(LOG_DIR.toString())
.build());
GlobalLogCollector.addLogCallback(() -> {
GlobalLogCollector.getGlobalLogCollector().collectFromNamespaces("default");
GlobalLogCollector.getGlobalLogCollector().collectClusterWideResources();
MustGatherController.setMustGatherCallback(() -> {
MustGatherController.getMustGatherController().collectFromNamespaces("default");
MustGatherController.getMustGatherController().collectClusterWideResources();
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import static org.junit.jupiter.api.Assertions.fail;

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class GlobalLogCollectorIT extends AbstractIT {
public class MustGatherControllerIT extends AbstractIT {
@Test
void testGlobalLogCollector() {
fail("Expected issue");
Expand Down
Loading