Skip to content

Commit

Permalink
Merge pull request #22920 from famod/test-basic-logging
Browse files Browse the repository at this point in the history
Make sure (basic) logging is set up before each test class
  • Loading branch information
famod authored Jan 18, 2022
2 parents f3ee105 + c272ff0 commit 5e6acd9
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 15 deletions.
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
junit.jupiter.testclass.order.default=io.quarkus.test.junit.util.QuarkusTestProfileAwareClassOrderer
junit.jupiter.extensions.autodetection.enabled=true
junit.jupiter.testclass.order.default=io.quarkus.test.junit.util.QuarkusTestProfileAwareClassOrderer
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package io.quarkus.test.junit;

import org.eclipse.microprofile.config.ConfigProvider;
import org.eclipse.microprofile.config.spi.ConfigProviderResolver;
import org.junit.jupiter.api.extension.BeforeAllCallback;
import org.junit.jupiter.api.extension.ExtensionContext;

import io.quarkus.bootstrap.logging.InitialConfigurator;

/**
* A (global) JUnit callback that enables/sets up basic logging if logging has not already been set up.
* <p/>
* This is useful for getting log output from non-Quarkus tests (if executed separately or before the first Quarkus test),
* but also for getting instant log output from {@code QuarkusTestResourceLifecycleManagers} etc.
* <p/>
* This callback can be disabled via {@link #CFGKEY_ENABLED} in {@code junit-platform.properties} or via system property.
*/
public class BasicLoggingEnabler implements BeforeAllCallback {

private static final String CFGKEY_ENABLED = "junit.quarkus.enable-basic-logging";
private static Boolean enabled;

// to speed things up a little, eager async loading of the config that will be looked up in LoggingSetupRecorder
// downside: doesn't obey CFGKEY_ENABLED, but that should be bearable
static {
// e.g. continuous testing has everything set up already (DELAYED_HANDLER is active)
if (!InitialConfigurator.DELAYED_HANDLER.isActivated()) {
new Thread(() -> ConfigProvider.getConfig()).start();
}
}

@Override
public void beforeAll(ExtensionContext context) throws Exception {
if (enabled == null) {
enabled = context.getConfigurationParameter(CFGKEY_ENABLED).map(Boolean::valueOf).orElse(Boolean.TRUE);
}
if (!enabled || InitialConfigurator.DELAYED_HANDLER.isActivated()) {
return;
}
try {
IntegrationTestUtil.activateLogging();
} finally {
// release the config that was retrieved by above call so that tests that try to register their own config
// don't fail with:
// "IllegalStateException: SRCFG00017: Configuration already registered for the given class loader"
// also, a possible recreation of basically the same config for a later test class will consume far less time
var configProviderResolver = ConfigProviderResolver.instance();
var config = configProviderResolver.getConfig();
if (config != null) { // probably never null, but be safe
configProviderResolver.releaseConfig(config);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,22 @@ public class QuarkusTestProfileAwareClassOrderer implements ClassOrderer {
protected static final String DEFAULT_ORDER_PREFIX_QUARKUS_TEST_WITH_RESTRICTED_RES = "45_";
protected static final String DEFAULT_ORDER_PREFIX_NON_QUARKUS_TEST = "60_";

static final String CFGKEY_ORDER_PREFIX_QUARKUS_TEST = "quarkus.test.orderer.prefix.quarkus-test";
static final String CFGKEY_ORDER_PREFIX_QUARKUS_TEST_WITH_PROFILE = "quarkus.test.orderer.prefix.quarkus-test-with-profile";
static final String CFGKEY_ORDER_PREFIX_QUARKUS_TEST = "junit.quarkus.orderer.prefix.quarkus-test";
@Deprecated
static final String _CFGKEY_ORDER_PREFIX_QUARKUS_TEST = "quarkus.test.orderer.prefix.quarkus-test";

static final String CFGKEY_ORDER_PREFIX_QUARKUS_TEST_WITH_PROFILE = "junit.quarkus.orderer.prefix.quarkus-test-with-profile";
@Deprecated
static final String _CFGKEY_ORDER_PREFIX_QUARKUS_TEST_WITH_PROFILE = "quarkus.test.orderer.prefix.quarkus-test-with-profile";

static final String CFGKEY_ORDER_PREFIX_QUARKUS_TEST_WITH_RESTRICTED_RES = "quarkus.test.orderer.prefix.quarkus-test-with-restricted-resource";
@Deprecated
static final String _CFGKEY_ORDER_PREFIX_QUARKUS_TEST_WITH_RESTRICTED_RES = "junit.quarkus.orderer.prefix.quarkus-test-with-restricted-resource";

static final String CFGKEY_ORDER_PREFIX_NON_QUARKUS_TEST = "quarkus.test.orderer.prefix.non-quarkus-test";
@Deprecated
static final String _CFGKEY_ORDER_PREFIX_NON_QUARKUS_TEST = "junit.quarkus.orderer.prefix.non-quarkus-test";

static final String CFGKEY_SECONDARY_ORDERER = "quarkus.test.orderer.secondary-orderer";

@Override
Expand All @@ -67,18 +79,26 @@ public void orderClasses(ClassOrdererContext context) {
if (context.getClassDescriptors().size() <= 1 || context.getClassDescriptors().get(0).isAnnotated(Nested.class)) {
return;
}
var prefixQuarkusTest = context
.getConfigurationParameter(CFGKEY_ORDER_PREFIX_QUARKUS_TEST)
.orElse(DEFAULT_ORDER_PREFIX_QUARKUS_TEST);
var prefixQuarkusTestWithProfile = context
.getConfigurationParameter(CFGKEY_ORDER_PREFIX_QUARKUS_TEST_WITH_PROFILE)
.orElse(DEFAULT_ORDER_PREFIX_QUARKUS_TEST_WITH_PROFILE);
var prefixQuarkusTestWithRestrictedResource = context
.getConfigurationParameter(CFGKEY_ORDER_PREFIX_QUARKUS_TEST_WITH_RESTRICTED_RES)
.orElse(DEFAULT_ORDER_PREFIX_QUARKUS_TEST_WITH_RESTRICTED_RES);
var prefixNonQuarkusTest = context
.getConfigurationParameter(CFGKEY_ORDER_PREFIX_NON_QUARKUS_TEST)
.orElse(DEFAULT_ORDER_PREFIX_NON_QUARKUS_TEST);
var prefixQuarkusTest = getConfigParam(
CFGKEY_ORDER_PREFIX_QUARKUS_TEST,
_CFGKEY_ORDER_PREFIX_QUARKUS_TEST,
DEFAULT_ORDER_PREFIX_QUARKUS_TEST,
context);
var prefixQuarkusTestWithProfile = getConfigParam(
CFGKEY_ORDER_PREFIX_QUARKUS_TEST_WITH_PROFILE,
_CFGKEY_ORDER_PREFIX_QUARKUS_TEST_WITH_PROFILE,
DEFAULT_ORDER_PREFIX_QUARKUS_TEST_WITH_PROFILE,
context);
var prefixQuarkusTestWithRestrictedResource = getConfigParam(
CFGKEY_ORDER_PREFIX_QUARKUS_TEST_WITH_RESTRICTED_RES,
_CFGKEY_ORDER_PREFIX_QUARKUS_TEST_WITH_RESTRICTED_RES,
DEFAULT_ORDER_PREFIX_QUARKUS_TEST_WITH_RESTRICTED_RES,
context);
var prefixNonQuarkusTest = getConfigParam(
CFGKEY_ORDER_PREFIX_NON_QUARKUS_TEST,
_CFGKEY_ORDER_PREFIX_NON_QUARKUS_TEST,
DEFAULT_ORDER_PREFIX_NON_QUARKUS_TEST,
context);

// first pass: run secondary orderer first (!), which is easier than running it per "grouping"
buildSecondaryOrderer(context).orderClasses(context);
Expand Down Expand Up @@ -111,6 +131,19 @@ public void orderClasses(ClassOrdererContext context) {
}));
}

private String getConfigParam(String key, String deprecatedKey, String fallbackValue, ClassOrdererContext context) {
return context.getConfigurationParameter(key)
.orElseGet(() -> {
Optional<String> value = context.getConfigurationParameter(deprecatedKey);
if (value.isPresent()) {
System.out.printf("Config key %s is deprecated, please use %s instead.%n", deprecatedKey, key);
return value.orElseThrow();
} else {
return fallbackValue;
}
});
}

private ClassOrderer buildSecondaryOrderer(ClassOrdererContext context) {
return context.getConfigurationParameter(CFGKEY_SECONDARY_ORDERER)
.map(fqcn -> {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
io.quarkus.test.junit.BasicLoggingEnabler
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static io.quarkus.test.junit.util.QuarkusTestProfileAwareClassOrderer.CFGKEY_ORDER_PREFIX_NON_QUARKUS_TEST;
import static io.quarkus.test.junit.util.QuarkusTestProfileAwareClassOrderer.CFGKEY_SECONDARY_ORDERER;
import static io.quarkus.test.junit.util.QuarkusTestProfileAwareClassOrderer._CFGKEY_ORDER_PREFIX_NON_QUARKUS_TEST;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doReturn;
Expand Down Expand Up @@ -104,6 +105,23 @@ void configuredPrefix() {
assertThat(input).containsExactly(nonQuarkusTestDesc, quarkusTestDesc);
}

@Test
@Deprecated
void configuredPrefix_deprecated() {
ClassDescriptor quarkusTestDesc = quarkusDescriptorMock(Test01.class, null);
ClassDescriptor nonQuarkusTestDesc = descriptorMock(Test03.class);
List<ClassDescriptor> input = Arrays.asList(quarkusTestDesc, nonQuarkusTestDesc);
doReturn(input).when(contextMock).getClassDescriptors();

when(contextMock.getConfigurationParameter(anyString())).thenReturn(Optional.empty()); // for strict stubbing
// prioritize unit tests
when(contextMock.getConfigurationParameter(_CFGKEY_ORDER_PREFIX_NON_QUARKUS_TEST)).thenReturn(Optional.of("01_"));

underTest.orderClasses(contextMock);

assertThat(input).containsExactly(nonQuarkusTestDesc, quarkusTestDesc);
}

@Test
void secondaryOrderer() {
ClassDescriptor quarkusTest1Desc = quarkusDescriptorMock(Test01.class, null);
Expand Down

0 comments on commit 5e6acd9

Please sign in to comment.