GH-104 - Polish log output for test execution.

Also added ApplicationModules.toString().
This commit is contained in:
Oliver Drotbohm
2023-01-05 10:21:07 +01:00
parent d9aedb8ebf
commit 30203ecca8
4 changed files with 49 additions and 40 deletions

View File

@@ -304,7 +304,7 @@ public class ApplicationModule {
public String toString(@Nullable ApplicationModules modules) {
var builder = new StringBuilder("## ").append(getDisplayName()).append(" ##\n");
var builder = new StringBuilder("# ").append(getDisplayName()).append("\n");
builder.append("> Logical name: ").append(getName()).append('\n');
builder.append("> Base package: ").append(basePackage.getName()).append('\n');

View File

@@ -412,6 +412,15 @@ public class ApplicationModules implements Iterable<ApplicationModule> {
return orderedNames.stream().map(this::getRequiredModule).iterator();
}
/*
* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return this.stream().map(ApplicationModule::toString).collect(Collectors.joining("\n"));
}
private FailureReport assertNoCyclesFor(JavaPackage rootPackage) {
EvaluationResult result = SlicesRuleDefinition.slices() //

View File

@@ -59,7 +59,7 @@ class SpringModulithRuntimeAutoConfiguration {
var mainClass = runtime.getMainApplicationClass();
var modules = Executors.newFixedThreadPool(1)
.submit(() -> SpringModulithRuntimeAutoConfiguration.initializeApplicationModules(mainClass));
.submit(() -> ApplicationModulesBootstrap.initializeApplicationModules(mainClass));
return new ApplicationModulesRuntime(toSupplier(modules), runtime);
}
@@ -108,25 +108,29 @@ class SpringModulithRuntimeAutoConfiguration {
}
}
private static ApplicationModules initializeApplicationModules(Class<?> applicationMainClass) {
@Slf4j
private static class ApplicationModulesBootstrap {
LOG.debug("Obtaining Spring Modulith application modules");
static ApplicationModules initializeApplicationModules(Class<?> applicationMainClass) {
var result = ApplicationModules.of(applicationMainClass);
var numberOfModules = result.stream().count();
LOG.debug("Obtaining Spring Modulith application modules…");
if (numberOfModules == 0) {
var result = ApplicationModules.of(applicationMainClass);
var numberOfModules = result.stream().count();
LOG.warn("No application modules detected!");
if (numberOfModules == 0) {
} else {
LOG.warn("No application modules detected!");
LOG.debug("Detected {} application modules: {}", //
result.stream().count(), //
result.stream().map(ApplicationModule::getName).toList());
} else {
LOG.debug("Detected {} application modules: {}", //
result.stream().count(), //
result.stream().map(ApplicationModule::getName).toList());
}
return result;
}
return result;
}
private static Supplier<ApplicationModules> toSupplier(Future<ApplicationModules> modules) {

View File

@@ -19,17 +19,16 @@ import lombok.EqualsAndHashCode;
import lombok.extern.slf4j.Slf4j;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.modulith.model.ApplicationModule;
import org.springframework.modulith.model.ApplicationModules;
import org.springframework.test.context.ContextConfigurationAttributes;
import org.springframework.test.context.ContextCustomizer;
import org.springframework.test.context.ContextCustomizerFactory;
@@ -48,7 +47,8 @@ class ModuleContextCustomizerFactory implements ContextCustomizerFactory {
public ContextCustomizer createContextCustomizer(Class<?> testClass,
List<ContextConfigurationAttributes> configAttributes) {
ApplicationModuleTest moduleTest = AnnotatedElementUtils.getMergedAnnotation(testClass, ApplicationModuleTest.class);
ApplicationModuleTest moduleTest = AnnotatedElementUtils.getMergedAnnotation(testClass,
ApplicationModuleTest.class);
return moduleTest == null ? null : new ModuleContextCustomizer(testClass);
}
@@ -86,16 +86,16 @@ class ModuleContextCustomizerFactory implements ContextCustomizerFactory {
private static void logModules(ModuleTestExecution execution) {
ApplicationModule module = execution.getModule();
ApplicationModules modules = execution.getModules();
String moduleName = module.getDisplayName();
String bootstrapMode = execution.getBootstrapMode().name();
var module = execution.getModule();
var modules = execution.getModules();
var moduleName = module.getDisplayName();
var bootstrapMode = execution.getBootstrapMode().name();
String message = String.format("Bootstrapping @ModuleTest for %s in mode %s (%s)…", moduleName, bootstrapMode,
modules.getModulithSource());
var message = "Bootstrapping @%s for %s in mode %s (%s)…"
.formatted(ApplicationModuleTest.class.getName(), moduleName, bootstrapMode, modules.getModulithSource());
LOG.info(message);
LOG.info(getSeparator("=", message));
LOG.info("");
Arrays.stream(module.toString(modules).split("\n")).forEach(LOG::info);
@@ -103,25 +103,25 @@ class ModuleContextCustomizerFactory implements ContextCustomizerFactory {
if (!extraIncludes.isEmpty()) {
logHeadline("Extra includes:", message);
logHeadline("Extra includes:");
extraIncludes.forEach(it -> LOG.info("> ".concat(it.getName())));
LOG.info("> " + extraIncludes.stream().map(ApplicationModule::getName).collect(Collectors.joining(", ")));
}
Set<ApplicationModule> sharedModules = modules.getSharedModules();
if (!sharedModules.isEmpty()) {
logHeadline("Shared modules:", message);
logHeadline("Shared modules:");
sharedModules.forEach(it -> LOG.info("> ".concat(it.getName())));
LOG.info("> " + sharedModules.stream().map(ApplicationModule::getName).collect(Collectors.joining(", ")));
}
List<ApplicationModule> dependencies = execution.getDependencies();
if (!dependencies.isEmpty() || !sharedModules.isEmpty()) {
logHeadline("Included dependencies:", message);
logHeadline("Included dependencies:");
Stream<ApplicationModule> dependenciesPlusMissingSharedOnes = //
Stream.concat(dependencies.stream(), sharedModules.stream() //
@@ -130,27 +130,23 @@ class ModuleContextCustomizerFactory implements ContextCustomizerFactory {
dependenciesPlusMissingSharedOnes //
.map(it -> it.toString(modules)) //
.forEach(it -> {
LOG.info("");
Arrays.stream(it.split("\n")).forEach(LOG::info);
});
LOG.info(getSeparator("=", message));
}
LOG.info("");
}
private static String getSeparator(String character, String reference) {
return String.join("", Collections.nCopies(reference.length(), character));
private static void logHeadline(String headline) {
logHeadline(headline, () -> {});
}
private static void logHeadline(String headline, String reference) {
logHeadline(headline, reference, () -> {});
}
private static void logHeadline(String headline, Runnable additional) {
private static void logHeadline(String headline, String reference, Runnable additional) {
LOG.info(getSeparator("=", reference));
LOG.info("");
LOG.info(headline);
additional.run();
LOG.info(getSeparator("=", reference));
}
}
}