Add ArchUnit to test format of loggers and Abstract classes (#10335)

* Add archunit to programatically test format and scope of loggers

* Fix use of loggers

* Update error message

* Add check for abstract class

* Test if classes with abstract in name are abstract

* Make abstract class abstract

* Rename test class

* Make logger private final

* Make logger private
This commit is contained in:
agilob 2021-09-09 04:54:51 +01:00 committed by GitHub
parent 36ae0b9ffe
commit d2d06f0503
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 93 additions and 44 deletions

View File

@ -334,6 +334,18 @@
<artifactId>jackson-core</artifactId>
<version>${jackson-version}</version>
</dependency>
<dependency>
<groupId>com.tngtech.archunit</groupId>
<artifactId>archunit</artifactId>
<version>0.20.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.tngtech.archunit</groupId>
<artifactId>archunit-junit4</artifactId>
<version>0.20.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
@ -433,6 +445,7 @@
<artifactId>caffeine</artifactId>
<version>2.8.1</version>
</dependency>
</dependencies>
<repositories>
<repository>

View File

@ -26,7 +26,7 @@ import static org.openapitools.codegen.utils.StringUtils.*;
public abstract class AbstractDartCodegen extends DefaultCodegen {
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractDartCodegen.class);
private final Logger LOGGER = LoggerFactory.getLogger(AbstractDartCodegen.class);
protected static final List<String> DEFAULT_SUPPORTED_CONTENT_TYPES = Arrays.asList(
"application/json", "application/x-www-form-urlencoded", "multipart/form-data");

View File

@ -64,7 +64,7 @@ public class AspNetCoreServerCodegen extends AbstractCSharpCodegen {
private String packageGuid = "{" + randomUUID().toString().toUpperCase(Locale.ROOT) + "}";
private String userSecretsGuid = randomUUID().toString();
protected Logger LOGGER = LoggerFactory.getLogger(AspNetCoreServerCodegen.class);
protected final Logger LOGGER = LoggerFactory.getLogger(AspNetCoreServerCodegen.class);
private boolean useSwashbuckle = true;
protected int serverPort = 8080;

View File

@ -56,7 +56,7 @@ public class CSharpNetCoreClientCodegen extends AbstractCSharpCodegen {
protected static final String TARGET_FRAMEWORK_VERSION = "targetFrameworkVersion";
@SuppressWarnings({"hiding"})
private static final Logger LOGGER = LoggerFactory.getLogger(CSharpClientCodegen.class);
private final Logger LOGGER = LoggerFactory.getLogger(CSharpClientCodegen.class);
private static final List<FrameworkStrategy> frameworkStrategies = Arrays.asList(
FrameworkStrategy.NETSTANDARD_1_3,
FrameworkStrategy.NETSTANDARD_1_4,
@ -973,6 +973,9 @@ public class CSharpNetCoreClientCodegen extends AbstractCSharpCodegen {
// https://docs.microsoft.com/en-us/dotnet/standard/net-standard
@SuppressWarnings("Duplicates")
private static abstract class FrameworkStrategy {
private final Logger LOGGER = LoggerFactory.getLogger(CSharpClientCodegen.class);
static FrameworkStrategy NETSTANDARD_1_3 = new FrameworkStrategy("netstandard1.3", ".NET Standard 1.3 compatible", "netcoreapp2.0") {
};
static FrameworkStrategy NETSTANDARD_1_4 = new FrameworkStrategy("netstandard1.4", ".NET Standard 1.4 compatible", "netcoreapp2.0") {

View File

@ -13,7 +13,8 @@ import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.*;
public class CppQtAbstractCodegen extends AbstractCppCodegen implements CodegenConfig {
public abstract class CppQtAbstractCodegen extends AbstractCppCodegen implements CodegenConfig {
private final Logger LOGGER = LoggerFactory.getLogger(CppQtAbstractCodegen.class);
protected final String PREFIX = "OAI";
protected String apiVersion = "1.0.0";

View File

@ -23,7 +23,6 @@ import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.*;
import org.openapitools.codegen.meta.features.*;
import org.openapitools.codegen.utils.ModelUtils;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.*;
@ -33,8 +32,6 @@ import static org.openapitools.codegen.utils.StringUtils.camelize;
public class CppRestbedServerCodegen extends AbstractCppCodegen {
private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(CppRestbedServerCodegen.class);
public static final String DECLSPEC = "declspec";
public static final String DEFAULT_INCLUDE = "defaultInclude";

View File

@ -36,7 +36,7 @@ import org.slf4j.LoggerFactory;
public class CppTinyClientCodegen extends AbstractCppCodegen implements CodegenConfig {
public static final String PROJECT_NAME = "TinyClient";
static final Logger LOGGER = LoggerFactory.getLogger(CppTinyClientCodegen.class);
final Logger LOGGER = LoggerFactory.getLogger(CppTinyClientCodegen.class);
public static final String MICROCONTROLLER = "controller";
public static final String rootFolder = "";

View File

@ -37,7 +37,7 @@ import static org.openapitools.codegen.utils.StringUtils.underscore;
public class DartDioNextClientCodegen extends AbstractDartCodegen {
private static final Logger LOGGER = LoggerFactory.getLogger(DartDioNextClientCodegen.class);
private final Logger LOGGER = LoggerFactory.getLogger(DartDioNextClientCodegen.class);
public static final String DATE_LIBRARY = "dateLibrary";
public static final String DATE_LIBRARY_CORE = "core";

View File

@ -50,7 +50,7 @@ public class FsharpGiraffeServerCodegen extends AbstractFSharpCodegen {
private String packageGuid = "{" + randomUUID().toString().toUpperCase(Locale.ROOT) + "}";
@SuppressWarnings("hiding")
protected Logger LOGGER = LoggerFactory.getLogger(FsharpGiraffeServerCodegen.class);
protected final Logger LOGGER = LoggerFactory.getLogger(FsharpGiraffeServerCodegen.class);
private boolean useSwashbuckle = false;
protected int serverPort = 8080;

View File

@ -17,19 +17,17 @@
package org.openapitools.codegen.languages;
import org.openapitools.codegen.*;
import java.io.File;
import java.util.*;
import org.openapitools.codegen.meta.features.*;
import org.openapitools.codegen.meta.GeneratorMetadata;
import org.openapitools.codegen.meta.Stability;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.openapitools.codegen.meta.features.*;
import java.io.File;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
public class GoEchoServerCodegen extends AbstractGoCodegen {
static final Logger LOGGER = LoggerFactory.getLogger(GoEchoServerCodegen.class);
protected String apiVersion = "1.0.0";
protected int serverPort = 8080;
protected String projectName = "openapi-go-echo-server";

View File

@ -46,7 +46,7 @@ public class HaskellYesodServerCodegen extends DefaultCodegen implements Codegen
private static final Pattern LEADING_UNDERSCORE = Pattern.compile("^_+");
static final Logger LOGGER = LoggerFactory.getLogger(HaskellYesodServerCodegen.class);
private final Logger LOGGER = LoggerFactory.getLogger(HaskellYesodServerCodegen.class);
protected String projectName;
protected String apiModuleName;

View File

@ -43,7 +43,7 @@ import static org.openapitools.codegen.utils.StringUtils.camelize;
public class KotlinSpringServerCodegen extends AbstractKotlinCodegen
implements BeanValidationFeatures {
private static Logger LOGGER =
private final Logger LOGGER =
LoggerFactory.getLogger(KotlinSpringServerCodegen.class);
private static final HashSet<String> VARIABLE_RESERVED_WORDS =

View File

@ -39,7 +39,7 @@ import static org.openapitools.codegen.utils.StringUtils.*;
@SuppressWarnings("unchecked")
public class KtormSchemaCodegen extends AbstractKotlinCodegen {
static Logger LOGGER = LoggerFactory.getLogger(KtormSchemaCodegen.class);
private final Logger LOGGER = LoggerFactory.getLogger(KtormSchemaCodegen.class);
public static final String VENDOR_EXTENSION_SCHEMA = "x-ktorm-schema";
public static final String DEFAULT_DATABASE_NAME = "defaultDatabaseName";

View File

@ -51,7 +51,7 @@ public class ScalaAkkaClientCodegen extends AbstractScalaCodegen implements Code
protected boolean removeOAuthSecurities = true;
@SuppressWarnings("hiding")
protected Logger LOGGER = LoggerFactory.getLogger(ScalaAkkaClientCodegen.class);
protected final Logger LOGGER = LoggerFactory.getLogger(ScalaAkkaClientCodegen.class);
public ScalaAkkaClientCodegen() {
super();

View File

@ -50,7 +50,7 @@ public class ScalaAkkaHttpServerCodegen extends AbstractScalaCodegen implements
public static final String GENERATE_AS_MANAGED_SOURCES_DESC = "Resulting files cab be used as managed resources. No build files or default controllers will be generated";
public static final boolean DEFAULT_GENERATE_AS_MANAGED_SOURCES = false;
static final Logger LOGGER = LoggerFactory.getLogger(ScalaAkkaHttpServerCodegen.class);
final Logger LOGGER = LoggerFactory.getLogger(ScalaAkkaHttpServerCodegen.class);
public CodegenType getTag() {
return CodegenType.SERVER;
@ -305,7 +305,7 @@ public class ScalaAkkaHttpServerCodegen extends AbstractScalaCodegen implements
.put("String", "Segment")
.build();
protected static void addPathMatcher(CodegenOperation codegenOperation) {
protected void addPathMatcher(CodegenOperation codegenOperation) {
LinkedList<String> allPaths = new LinkedList<>(Arrays.asList(codegenOperation.path.split("/")));
allPaths.removeIf(""::equals);

View File

@ -18,35 +18,20 @@ package org.openapitools.codegen.languages;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import org.openapitools.codegen.*;
import org.openapitools.codegen.meta.GeneratorMetadata;
import org.openapitools.codegen.meta.Stability;
import java.io.File;
import java.text.Normalizer;
import java.util.List;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.openapitools.codegen.CliOption;
import org.openapitools.codegen.CodegenConfig;
import org.openapitools.codegen.CodegenModel;
import org.openapitools.codegen.CodegenOperation;
import org.openapitools.codegen.CodegenParameter;
import org.openapitools.codegen.CodegenProperty;
import org.openapitools.codegen.CodegenType;
import org.openapitools.codegen.DefaultCodegen;
import org.openapitools.codegen.meta.GeneratorMetadata;
import org.openapitools.codegen.meta.Stability;
import org.openapitools.codegen.meta.features.*;
import org.openapitools.codegen.SupportingFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class WsdlSchemaCodegen extends DefaultCodegen implements CodegenConfig {
public static final String PROJECT_NAME = "projectName";
static final Logger LOGGER = LoggerFactory.getLogger(WsdlSchemaCodegen.class);
public CodegenType getTag() {
return CodegenType.SCHEMA;
}

View File

@ -0,0 +1,52 @@
package org.openapitools.codegen;
import com.tngtech.archunit.core.domain.JavaClasses;
import com.tngtech.archunit.core.domain.JavaModifier;
import com.tngtech.archunit.core.importer.ClassFileImporter;
import com.tngtech.archunit.lang.ArchRule;
import org.junit.Test;
import org.slf4j.Logger;
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.*;
public class ArchUnitRulesTest {
@Test
public void testLoggersAreNotPublicFinalAndNotStatic() {
final JavaClasses importedClasses = new ClassFileImporter()
.importPackages("org.openapitools.codegen.languages");
ArchUnitRulesTest.LOGGERS_SHOULD_BE_NOT_PUBLIC_NOT_STATIC_AND_FINAL.check(importedClasses);
}
@Test
public void abstractClassesAreAbstract() {
final JavaClasses importedClasses = new ClassFileImporter()
.importPackages("org.openapitools.codegen.languages");
ArchUnitRulesTest.ABSTRACT_CLASS_MUST_BE_ABSTRACT.check(importedClasses);
}
/**
* Making loggers not static decreases memory consumption when running generator:
* https://github.com/OpenAPITools/openapi-generator/pull/8799
*/
public static final ArchRule LOGGERS_SHOULD_BE_NOT_PUBLIC_NOT_STATIC_AND_FINAL =
fields()
.that()
.haveRawType(Logger.class)
.should().notBePublic()
.andShould().notBeStatic()
.andShould().beFinal()
.because("Code generators are most often used once per program lifetime, " +
"so making them all static will cause higher memory consumption. " +
"See PR #8799");
public static final ArchRule ABSTRACT_CLASS_MUST_BE_ABSTRACT =
classes()
.that()
.haveSimpleNameContaining("Abstract").or().haveSimpleNameContaining("abstract")
.should()
.haveModifier(JavaModifier.ABSTRACT);
}