diff --git a/config/detekt.yml b/config/detekt.yml new file mode 100644 index 0000000000..59fc9d4dce --- /dev/null +++ b/config/detekt.yml @@ -0,0 +1,521 @@ +autoCorrect: true +failFast: false + +test-pattern: # Configure exclusions for test sources + active: true + patterns: # Test file regexes + - '.*/test/.*' + - '.*Tests?.kt' + exclude-rule-sets: + - 'comments' + exclude-rules: + - 'NamingRules' + - 'WildcardImport' + - 'MagicNumber' + - 'MaxLineLength' + - 'LateinitUsage' + - 'StringLiteralDuplication' + - 'SpreadOperator' + - 'TooManyFunctions' + - 'ForEachOnRange' + - 'FunctionMaxLength' + - 'TooGenericExceptionCaught' + - 'LongMethod' + - 'LargeClass' + - 'UnsafeCallOnNullableType' + - 'MaximumLineLength' + +build: + maxIssues: 0 + weights: + # complexity: 2 + # LongParameterList: 1 + # style: 1 + # comments: 1 + +processors: + active: true + exclude: + # - 'FunctionCountProcessor' + # - 'PropertyCountProcessor' + # - 'ClassCountProcessor' + # - 'PackageCountProcessor' + # - 'KtFileCountProcessor' + +console-reports: + active: true + exclude: + # - 'ProjectStatisticsReport' + # - 'ComplexityReport' + # - 'NotificationReport' + # - 'FindingsReport' + # - 'BuildFailureReport' + +comments: + active: true + CommentOverPrivateFunction: + active: false + CommentOverPrivateProperty: + active: false + EndOfSentenceFormat: + active: false + endOfSentenceFormat: ([.?!][ \t\n\r\f<])|([.?!]$) + UndocumentedPublicClass: + active: false + searchInNestedClass: true + searchInInnerClass: true + searchInInnerObject: true + searchInInnerInterface: true + UndocumentedPublicFunction: + active: false + +complexity: + active: true + ComplexCondition: + active: true + threshold: 8 + ComplexInterface: + active: false + threshold: 10 + includeStaticDeclarations: false + ComplexMethod: + active: true + threshold: 20 + ignoreSingleWhenExpression: false + ignoreSimpleWhenEntries: false + LabeledExpression: + active: false + ignoredLabels: "" + LargeClass: + active: false + threshold: 150 + LongMethod: + active: false + threshold: 20 + LongParameterList: + active: true + threshold: 10 + ignoreDefaultParameters: false + MethodOverloading: + active: false + threshold: 6 + NestedBlockDepth: + active: false + threshold: 4 + StringLiteralDuplication: + active: false + threshold: 3 + ignoreAnnotation: true + excludeStringsWithLessThan5Characters: true + ignoreStringsRegex: '$^' + TooManyFunctions: + active: true + thresholdInFiles: 30 + thresholdInClasses: 30 + thresholdInInterfaces: 30 + thresholdInObjects: 30 + thresholdInEnums: 30 + ignoreDeprecated: false + ignorePrivate: false + +empty-blocks: + active: true + EmptyCatchBlock: + active: true + allowedExceptionNameRegex: "^(_|(ignore|expected).*)" + EmptyClassBlock: + active: true + EmptyDefaultConstructor: + active: true + EmptyDoWhileBlock: + active: true + EmptyElseBlock: + active: true + EmptyFinallyBlock: + active: true + EmptyForBlock: + active: true + EmptyFunctionBlock: + active: true + ignoreOverriddenFunctions: false + EmptyIfBlock: + active: true + EmptyInitBlock: + active: true + EmptyKtFile: + active: true + EmptySecondaryConstructor: + active: true + EmptyWhenBlock: + active: true + EmptyWhileBlock: + active: true + +exceptions: + active: true + ExceptionRaisedInUnexpectedLocation: + active: false + methodNames: 'toString,hashCode,equals,finalize' + InstanceOfCheckForException: + active: false + NotImplementedDeclaration: + active: false + PrintStackTrace: + active: false + RethrowCaughtException: + active: false + ReturnFromFinally: + active: false + SwallowedException: + active: false + ignoredExceptionTypes: 'InterruptedException,NumberFormatException,ParseException,MalformedURLException' + ThrowingExceptionFromFinally: + active: false + ThrowingExceptionInMain: + active: false + ThrowingExceptionsWithoutMessageOrCause: + active: false + exceptions: 'IllegalArgumentException,IllegalStateException,IOException' + ThrowingNewInstanceOfSameException: + active: false + TooGenericExceptionCaught: + active: false + exceptionNames: + - ArrayIndexOutOfBoundsException + - Error + - Exception + - IllegalMonitorStateException + - NullPointerException + - IndexOutOfBoundsException + - RuntimeException + - Throwable + allowedExceptionNameRegex: "^(_|(ignore|expected).*)" + TooGenericExceptionThrown: + active: false + exceptionNames: + - Error + - Exception + - Throwable + - RuntimeException + +formatting: + active: true + android: false + autoCorrect: true + ChainWrapping: + active: true + autoCorrect: true + CommentSpacing: + active: true + autoCorrect: true + Filename: + active: true + FinalNewline: + active: true + autoCorrect: true + ImportOrdering: + active: true + autoCorrect: true + Indentation: + active: true + autoCorrect: true + indentSize: 4 + continuationIndentSize: 4 + MaximumLineLength: + active: false + maxLineLength: 120 + ModifierOrdering: + active: true + autoCorrect: true + NoBlankLineBeforeRbrace: + active: true + autoCorrect: true + NoConsecutiveBlankLines: + active: true + autoCorrect: true + NoEmptyClassBody: + active: true + autoCorrect: true + NoItParamInMultilineLambda: + active: false + NoLineBreakAfterElse: + active: true + autoCorrect: true + NoLineBreakBeforeAssignment: + active: true + autoCorrect: true + NoMultipleSpaces: + active: true + autoCorrect: true + NoSemicolons: + active: true + autoCorrect: true + NoTrailingSpaces: + active: true + autoCorrect: true + NoUnitReturn: + active: true + autoCorrect: true + NoUnusedImports: + active: true + autoCorrect: true + NoWildcardImports: + active: true + autoCorrect: true + PackageName: + active: true + autoCorrect: true + ParameterListWrapping: + active: true + autoCorrect: true + indentSize: 4 + SpacingAroundColon: + active: true + autoCorrect: true + SpacingAroundComma: + active: true + autoCorrect: true + SpacingAroundCurly: + active: true + autoCorrect: true + SpacingAroundKeyword: + active: true + autoCorrect: true + SpacingAroundOperators: + active: true + autoCorrect: true + SpacingAroundParens: + active: true + autoCorrect: true + SpacingAroundRangeOperator: + active: true + autoCorrect: true + StringTemplate: + active: true + autoCorrect: true + +naming: + active: true + ClassNaming: + active: true + classPattern: '[A-Z$][a-zA-Z0-9$]*' + ConstructorParameterNaming: + active: true + parameterPattern: '[a-z][A-Za-z0-9]*' + privateParameterPattern: '[a-z][A-Za-z0-9]*' + excludeClassPattern: '$^' + EnumNaming: + active: true + enumEntryPattern: '^[A-Z][_a-zA-Z0-9]*' + ForbiddenClassName: + active: false + forbiddenName: '' + FunctionMaxLength: + active: false + maximumFunctionNameLength: 30 + FunctionMinLength: + active: false + minimumFunctionNameLength: 3 + FunctionNaming: + active: true + functionPattern: '^([a-z$][a-zA-Z$0-9]*)|(`.*`)$' + excludeClassPattern: '$^' + ignoreOverridden: true + FunctionParameterNaming: + active: true + parameterPattern: '[a-z][A-Za-z0-9]*' + excludeClassPattern: '$^' + ignoreOverriddenFunctions: true + MatchingDeclarationName: + active: false + MemberNameEqualsClassName: + active: false + ignoreOverriddenFunction: true + ObjectPropertyNaming: + active: true + constantPattern: '[A-Za-z][_A-Za-z0-9]*' + propertyPattern: '[A-Za-z][_A-Za-z0-9]*' + privatePropertyPattern: '(_)?[A-Za-z][_A-Za-z0-9]*' + PackageNaming: + active: true + packagePattern: '^[a-z]+(\.[a-z][a-z0-9]*)*$' + TopLevelPropertyNaming: + active: true + constantPattern: '[A-Z][_A-Z0-9]*' + propertyPattern: '[A-Za-z][_A-Za-z0-9]*' + privatePropertyPattern: '(_)?[A-Za-z][A-Za-z0-9]*' + VariableMaxLength: + active: false + maximumVariableNameLength: 64 + VariableMinLength: + active: false + minimumVariableNameLength: 1 + VariableNaming: + active: true + variablePattern: '[a-z][A-Za-z0-9]*' + privateVariablePattern: '(_)?[a-z][A-Za-z0-9]*' + excludeClassPattern: '$^' + ignoreOverridden: true + +performance: + active: true + ArrayPrimitive: + active: true + ForEachOnRange: + active: true + SpreadOperator: + active: false + UnnecessaryTemporaryInstantiation: + active: true + +potential-bugs: + active: true + DuplicateCaseInWhenExpression: + active: true + EqualsAlwaysReturnsTrueOrFalse: + active: false + EqualsWithHashCodeExist: + active: false + ExplicitGarbageCollectionCall: + active: true + InvalidRange: + active: true + IteratorHasNextCallsNextMethod: + active: true + IteratorNotThrowingNoSuchElementException: + active: false + LateinitUsage: + active: false + excludeAnnotatedProperties: "" + ignoreOnClassesPattern: "" + UnconditionalJumpStatementInLoop: + active: true + UnreachableCode: + active: true + UnsafeCallOnNullableType: + active: false + UnsafeCast: + active: false + UselessPostfixExpression: + active: true + WrongEqualsTypeParameter: + active: false + +style: + active: true + CollapsibleIfStatements: + active: false + DataClassContainsFunctions: + active: false + conversionFunctionPrefix: 'to' + EqualsNullCall: + active: false + EqualsOnSignatureLine: + active: false + ExplicitItLambdaParameter: + active: false + ExpressionBodySyntax: + active: false + includeLineWrapping: false + ForbiddenComment: + active: false + values: 'TODO:,FIXME:,STOPSHIP:' + ForbiddenImport: + active: false + imports: '' + ForbiddenVoid: + active: false + FunctionOnlyReturningConstant: + active: false + ignoreOverridableFunction: true + excludedFunctions: 'describeContents' + LoopWithTooManyJumpStatements: + active: false + maxJumpCount: 1 + MagicNumber: + active: false + ignoreNumbers: '-1,0,1,2' + ignoreHashCodeFunction: true + ignorePropertyDeclaration: false + ignoreConstantDeclaration: true + ignoreCompanionObjectPropertyDeclaration: true + ignoreAnnotation: false + ignoreNamedArgument: true + ignoreEnums: false + MandatoryBracesIfStatements: + active: false + MaxLineLength: + active: false + maxLineLength: 120 + excludePackageStatements: true + excludeImportStatements: true + excludeCommentStatements: false + MayBeConst: + active: true + ModifierOrder: + active: true + NestedClassesVisibility: + active: false + NewLineAtEndOfFile: + active: false + NoTabs: + active: false + OptionalAbstractKeyword: + active: true + OptionalUnit: + active: true + OptionalWhenBraces: + active: false + PreferToOverPairSyntax: + active: true + ProtectedMemberInFinalClass: + active: true + RedundantVisibilityModifierRule: + active: true + ReturnCount: + active: false + max: 4 + excludedFunctions: "equals" + excludeLabeled: false + excludeReturnFromLambda: true + SafeCast: + active: true + SerialVersionUIDInSerializableClass: + active: false + SpacingBetweenPackageAndImports: + active: false + ThrowsCount: + active: false + max: 2 + TrailingWhitespace: + active: false + UnnecessaryAbstractClass: + active: false + excludeAnnotatedClasses: "dagger.Module" + UnnecessaryApply: + active: false + UnnecessaryInheritance: + active: false + UnnecessaryLet: + active: false + UnnecessaryParentheses: + active: false + UntilInsteadOfRangeTo: + active: false + UnusedImports: + active: true + UnusedPrivateClass: + active: true + UnusedPrivateMember: + active: true + allowedNames: "(_|ignored|expected|serialVersionUID)" + UseDataClass: + active: false + excludeAnnotatedClasses: "" + UtilityClassWithPublicConstructor: + active: false + VarCouldBeVal: + active: true + WildcardImport: + active: true + excludeImports: 'java.util.*,kotlinx.android.synthetic.*' diff --git a/test_runner/build.gradle.kts b/test_runner/build.gradle.kts index bb096d8a0a..d2f8305829 100644 --- a/test_runner/build.gradle.kts +++ b/test_runner/build.gradle.kts @@ -9,11 +9,21 @@ plugins { application jacoco kotlin("jvm") version Versions.KOTLIN - // https://github.com/JLLeitschuh/ktlint-gradle/releases - // ./gradlew ktlintFormat - // ./gradlew ktlintCheck - // ./gradlew ktlintApplyToIdea - id("org.jlleitschuh.gradle.ktlint") version "6.3.1" + + id("io.gitlab.arturbosch.detekt") version Versions.DETEKT +} + +detekt { + input = files("src/main/kotlin", "src/test/kotlin") + config = files("../config/detekt.yml") + reports { + xml { + enabled = false + } + html { + enabled = true + } + } } // http://www.eclemma.org/jacoco/ @@ -129,6 +139,8 @@ dependencies { // todo: move to testImplementation once DI is implemented https://github.com/TestArmada/flank/issues/248 // https://search.maven.org/search?q=a:google-cloud-nio%20g:com.google.cloud compile("com.google.cloud:google-cloud-nio:0.75.0-alpha") + + detektPlugins("io.gitlab.arturbosch.detekt:detekt-formatting:${Versions.DETEKT}") } // Fix Exception in thread "main" java.lang.NoSuchMethodError: com.google.common.hash.Hashing.crc32c()Lcom/google/common/hash/HashFunction; @@ -161,4 +173,4 @@ tasks.withType { // https://github.com/gradle/kotlin-dsl/blob/master/samples/task-dependencies/build.gradle.kts#L41 // https://github.com/codecov/example-gradle/blob/master/build.gradle#L25 -tasks["check"].dependsOn(tasks["jacocoTestReport"]) +tasks["check"].dependsOn(tasks["jacocoTestReport"], tasks["detekt"]) diff --git a/test_runner/buildSrc/src/main/java/Deps.java b/test_runner/buildSrc/src/main/java/Deps.java index fb67833484..158b409bd9 100644 --- a/test_runner/buildSrc/src/main/java/Deps.java +++ b/test_runner/buildSrc/src/main/java/Deps.java @@ -6,6 +6,8 @@ abstract class Versions { public static final String KOTLIN_COROUTINES = "1.1.0"; // https://github.com/FasterXML/jackson-core/releases public static final String JACKSON = "2.9.8"; + // https://github.com/arturbosch/detekt + public static final String DETEKT = "1.0.0-RC12"; } @SuppressWarnings("unused") diff --git a/test_runner/src/main/kotlin/ftl/android/AndroidCatalog.kt b/test_runner/src/main/kotlin/ftl/android/AndroidCatalog.kt index 7521ad4d34..8f7759fd46 100644 --- a/test_runner/src/main/kotlin/ftl/android/AndroidCatalog.kt +++ b/test_runner/src/main/kotlin/ftl/android/AndroidCatalog.kt @@ -1,8 +1,8 @@ package ftl.android import com.google.api.services.testing.model.AndroidDevice -import ftl.http.executeWithRetry import ftl.gc.GcTesting +import ftl.http.executeWithRetry /** * Contains lists of possible Android device and version ids, as well as checks diff --git a/test_runner/src/main/kotlin/ftl/args/AndroidArgs.kt b/test_runner/src/main/kotlin/ftl/args/AndroidArgs.kt index 976b87c588..b75cb6dddf 100644 --- a/test_runner/src/main/kotlin/ftl/args/AndroidArgs.kt +++ b/test_runner/src/main/kotlin/ftl/args/AndroidArgs.kt @@ -28,9 +28,9 @@ import ftl.config.FtlConstants.useMock import ftl.filter.TestFilters import ftl.gc.GcStorage import ftl.util.Utils -import kotlinx.coroutines.runBlocking import java.nio.file.Files import java.nio.file.Path +import kotlinx.coroutines.runBlocking // set default values, init properties, etc. class AndroidArgs( diff --git a/test_runner/src/main/kotlin/ftl/args/ArgsHelper.kt b/test_runner/src/main/kotlin/ftl/args/ArgsHelper.kt index 2c63b25d7b..ab4d21371e 100644 --- a/test_runner/src/main/kotlin/ftl/args/ArgsHelper.kt +++ b/test_runner/src/main/kotlin/ftl/args/ArgsHelper.kt @@ -112,7 +112,7 @@ object ArgsHelper { if (bucket.startsWith("test-lab-")) return bucket val storage = StorageOptions.newBuilder().setProjectId(projectId).build().service - val bucketLabel = mapOf(Pair("flank", "")) + val bucketLabel = mapOf("flank" to "") val storageLocation = "us-central1" val bucketListOption = Storage.BucketListOption.prefix(bucket) diff --git a/test_runner/src/main/kotlin/ftl/cli/firebase/test/android/AndroidDoctorCommand.kt b/test_runner/src/main/kotlin/ftl/cli/firebase/test/android/AndroidDoctorCommand.kt index 6e2119b6db..1b4566c772 100644 --- a/test_runner/src/main/kotlin/ftl/cli/firebase/test/android/AndroidDoctorCommand.kt +++ b/test_runner/src/main/kotlin/ftl/cli/firebase/test/android/AndroidDoctorCommand.kt @@ -2,9 +2,9 @@ package ftl.cli.firebase.test.android import ftl.args.AndroidArgs import ftl.doctor.Doctor.validateYaml +import java.nio.file.Paths import picocli.CommandLine.Command import picocli.CommandLine.Option -import java.nio.file.Paths @Command( name = "doctor", diff --git a/test_runner/src/main/kotlin/ftl/cli/firebase/test/android/AndroidRunCommand.kt b/test_runner/src/main/kotlin/ftl/cli/firebase/test/android/AndroidRunCommand.kt index a0a85a9c2f..3ef5fa0d98 100644 --- a/test_runner/src/main/kotlin/ftl/cli/firebase/test/android/AndroidRunCommand.kt +++ b/test_runner/src/main/kotlin/ftl/cli/firebase/test/android/AndroidRunCommand.kt @@ -8,10 +8,10 @@ import ftl.config.FtlConstants.defaultAndroidVersion import ftl.config.FtlConstants.defaultLocale import ftl.config.FtlConstants.defaultOrientation import ftl.run.TestRunner +import java.nio.file.Paths import kotlinx.coroutines.runBlocking import picocli.CommandLine.Command import picocli.CommandLine.Option -import java.nio.file.Paths @Command( name = "run", diff --git a/test_runner/src/main/kotlin/ftl/cli/firebase/test/ios/IosDoctorCommand.kt b/test_runner/src/main/kotlin/ftl/cli/firebase/test/ios/IosDoctorCommand.kt index a27727d99f..78dbab9682 100644 --- a/test_runner/src/main/kotlin/ftl/cli/firebase/test/ios/IosDoctorCommand.kt +++ b/test_runner/src/main/kotlin/ftl/cli/firebase/test/ios/IosDoctorCommand.kt @@ -3,9 +3,9 @@ package ftl.cli.firebase.test.ios import ftl.args.IosArgs import ftl.doctor.Doctor.checkIosCatalog import ftl.doctor.Doctor.validateYaml +import java.nio.file.Paths import picocli.CommandLine.Command import picocli.CommandLine.Option -import java.nio.file.Paths @Command( name = "doctor", diff --git a/test_runner/src/main/kotlin/ftl/cli/firebase/test/ios/IosRunCommand.kt b/test_runner/src/main/kotlin/ftl/cli/firebase/test/ios/IosRunCommand.kt index 817bbe8e52..b8e164ddc5 100644 --- a/test_runner/src/main/kotlin/ftl/cli/firebase/test/ios/IosRunCommand.kt +++ b/test_runner/src/main/kotlin/ftl/cli/firebase/test/ios/IosRunCommand.kt @@ -6,10 +6,10 @@ import ftl.config.FtlConstants import ftl.config.FtlConstants.defaultIosModel import ftl.config.FtlConstants.defaultIosVersion import ftl.run.TestRunner +import java.nio.file.Paths import kotlinx.coroutines.runBlocking import picocli.CommandLine.Command import picocli.CommandLine.Option -import java.nio.file.Paths @Command( name = "run", diff --git a/test_runner/src/main/kotlin/ftl/ios/IosCatalog.kt b/test_runner/src/main/kotlin/ftl/ios/IosCatalog.kt index 9483986f8b..56d93ea62f 100644 --- a/test_runner/src/main/kotlin/ftl/ios/IosCatalog.kt +++ b/test_runner/src/main/kotlin/ftl/ios/IosCatalog.kt @@ -1,7 +1,7 @@ package ftl.ios -import ftl.http.executeWithRetry import ftl.gc.GcTesting +import ftl.http.executeWithRetry /** * Validates iOS device model and version diff --git a/test_runner/src/main/kotlin/ftl/reports/HtmlErrorReport.kt b/test_runner/src/main/kotlin/ftl/reports/HtmlErrorReport.kt index bb4a3fba87..88d80c4e3d 100644 --- a/test_runner/src/main/kotlin/ftl/reports/HtmlErrorReport.kt +++ b/test_runner/src/main/kotlin/ftl/reports/HtmlErrorReport.kt @@ -66,7 +66,7 @@ object HtmlErrorReport : IReport { } } - return Pair(groupList, itemList) + return groupList to itemList } private fun reactJson(testSuites: JUnitTestResult): Pair? { @@ -74,7 +74,7 @@ object HtmlErrorReport : IReport { val groupJson = gson.toJson(groupItemList.first) val itemJson = gson.toJson(groupItemList.second) - return Pair(groupJson, itemJson) + return groupJson to itemJson } override fun run(matrices: MatrixMap, testSuite: JUnitTestResult?, printToStdout: Boolean) { diff --git a/test_runner/src/main/kotlin/ftl/reports/util/ReportManager.kt b/test_runner/src/main/kotlin/ftl/reports/util/ReportManager.kt index 79142cb343..8a221d647f 100644 --- a/test_runner/src/main/kotlin/ftl/reports/util/ReportManager.kt +++ b/test_runner/src/main/kotlin/ftl/reports/util/ReportManager.kt @@ -9,8 +9,8 @@ import ftl.reports.HtmlErrorReport import ftl.reports.JUnitReport import ftl.reports.MatrixResultsReport import ftl.reports.xml.model.JUnitTestResult -import ftl.reports.xml.parseOneSuiteXml import ftl.reports.xml.parseAllSuitesXml +import ftl.reports.xml.parseOneSuiteXml import ftl.util.Artifacts import ftl.util.resolveLocalRunPath import java.io.File diff --git a/test_runner/src/main/kotlin/ftl/reports/xml/model/JUnitTestCase.kt b/test_runner/src/main/kotlin/ftl/reports/xml/model/JUnitTestCase.kt index 09510bb259..ae5e39714b 100644 --- a/test_runner/src/main/kotlin/ftl/reports/xml/model/JUnitTestCase.kt +++ b/test_runner/src/main/kotlin/ftl/reports/xml/model/JUnitTestCase.kt @@ -3,6 +3,7 @@ package ftl.reports.xml.model import com.fasterxml.jackson.annotation.JsonInclude import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty +@Suppress("UnusedPrivateClass") private class FilterNotNull { override fun equals(other: Any?): Boolean { // other is null = present diff --git a/test_runner/src/main/kotlin/ftl/run/AndroidTestRunner.kt b/test_runner/src/main/kotlin/ftl/run/AndroidTestRunner.kt index b5623dded7..ff93b0260a 100644 --- a/test_runner/src/main/kotlin/ftl/run/AndroidTestRunner.kt +++ b/test_runner/src/main/kotlin/ftl/run/AndroidTestRunner.kt @@ -76,6 +76,6 @@ object AndroidTestRunner { } } - Pair(appApkGcsPath.await(), testApkGcsPath.await()) + appApkGcsPath.await() to testApkGcsPath.await() } } diff --git a/test_runner/src/main/kotlin/ftl/run/GenericTestRunner.kt b/test_runner/src/main/kotlin/ftl/run/GenericTestRunner.kt index 8e6d8e80c8..c878bc81ef 100644 --- a/test_runner/src/main/kotlin/ftl/run/GenericTestRunner.kt +++ b/test_runner/src/main/kotlin/ftl/run/GenericTestRunner.kt @@ -15,7 +15,7 @@ object GenericTestRunner { TestRunner.assertMockUrl() val resultsDir = args.resultsDir ?: Utils.uniqueObjectName() - return Pair(stopwatch, resultsDir) + return stopwatch to resultsDir } fun afterRunTests( diff --git a/test_runner/src/main/kotlin/ftl/run/TestRunner.kt b/test_runner/src/main/kotlin/ftl/run/TestRunner.kt index 073aeabc5d..66c8b79c5e 100644 --- a/test_runner/src/main/kotlin/ftl/run/TestRunner.kt +++ b/test_runner/src/main/kotlin/ftl/run/TestRunner.kt @@ -27,15 +27,15 @@ import ftl.util.MatrixState import ftl.util.StopWatch import ftl.util.Utils import ftl.util.Utils.fatalError +import java.nio.file.Files +import java.nio.file.Path +import java.nio.file.Paths import kotlinx.coroutines.Deferred import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking -import java.nio.file.Files -import java.nio.file.Path -import java.nio.file.Paths object TestRunner { private val gson = GsonBuilder().setPrettyPrinting().create()!! diff --git a/test_runner/src/main/kotlin/ftl/util/Utils.kt b/test_runner/src/main/kotlin/ftl/util/Utils.kt index 5764a9aead..b315499cc5 100644 --- a/test_runner/src/main/kotlin/ftl/util/Utils.kt +++ b/test_runner/src/main/kotlin/ftl/util/Utils.kt @@ -34,6 +34,7 @@ object Utils { try { Thread.sleep(ofSeconds(seconds).toMillis()) } catch (e: Exception) { + System.err.println(e) } } @@ -86,7 +87,7 @@ object Utils { val random = Random() // a-z: 97 - 122 // A-Z: 65 - 90 - for (i in 0..3) { + repeat(4) { val ascii = random.nextInt(26) var letter = (ascii + 'a'.toInt()).toChar() diff --git a/test_runner/src/test/kotlin/ftl/args/AndroidArgsFileTest.kt b/test_runner/src/test/kotlin/ftl/args/AndroidArgsFileTest.kt index 92e6d43c18..57213ccb96 100644 --- a/test_runner/src/test/kotlin/ftl/args/AndroidArgsFileTest.kt +++ b/test_runner/src/test/kotlin/ftl/args/AndroidArgsFileTest.kt @@ -8,6 +8,7 @@ import ftl.args.yml.GcloudYml import ftl.args.yml.GcloudYmlParams import ftl.config.Device import ftl.test.util.FlankTestRunner +import ftl.test.util.TestHelper.absolutePath import ftl.test.util.TestHelper.assert import ftl.test.util.TestHelper.getPath import ftl.test.util.TestHelper.getString @@ -17,7 +18,6 @@ import org.junit.contrib.java.lang.system.SystemErrRule import org.junit.contrib.java.lang.system.SystemOutRule import org.junit.rules.ExpectedException import org.junit.runner.RunWith -import ftl.test.util.TestHelper.absolutePath @RunWith(FlankTestRunner::class) class AndroidArgsFileTest { @@ -69,7 +69,7 @@ class AndroidArgsFileTest { assert(autoGoogleLogin, true) assert(useOrchestrator, true) - assert(environmentVariables, mapOf(Pair("clearPackageData", "true"))) + assert(environmentVariables, mapOf("clearPackageData" to "true")) assert(directoriesToPull, listOf(directoryToPull)) assert(resultsBucket, "tmp_bucket_2") assert(performanceMetrics, true) diff --git a/test_runner/src/test/kotlin/ftl/args/ArgsHelperFilePathTest.kt b/test_runner/src/test/kotlin/ftl/args/ArgsHelperFilePathTest.kt index 95a04c3fb3..b0b5d2e4e1 100644 --- a/test_runner/src/test/kotlin/ftl/args/ArgsHelperFilePathTest.kt +++ b/test_runner/src/test/kotlin/ftl/args/ArgsHelperFilePathTest.kt @@ -3,11 +3,11 @@ package ftl.args import com.google.common.truth.Truth import ftl.test.util.FlankTestRunner import ftl.test.util.TestHelper.absolutePath +import java.io.File import org.junit.Rule import org.junit.Test import org.junit.contrib.java.lang.system.EnvironmentVariables import org.junit.runner.RunWith -import java.io.File @RunWith(FlankTestRunner::class) class ArgsHelperFilePathTest { diff --git a/test_runner/src/test/kotlin/ftl/args/ArgsHelperTest.kt b/test_runner/src/test/kotlin/ftl/args/ArgsHelperTest.kt index 279c748030..599f20d21c 100644 --- a/test_runner/src/test/kotlin/ftl/args/ArgsHelperTest.kt +++ b/test_runner/src/test/kotlin/ftl/args/ArgsHelperTest.kt @@ -13,13 +13,13 @@ import ftl.shard.TestShard import ftl.shard.stringShards import ftl.test.util.FlankTestRunner import ftl.test.util.TestHelper.absolutePath +import java.io.File import org.junit.Rule import org.junit.Test import org.junit.contrib.java.lang.system.EnvironmentVariables import org.junit.contrib.java.lang.system.SystemErrRule import org.junit.rules.ExpectedException import org.junit.runner.RunWith -import java.io.File @RunWith(FlankTestRunner::class) class ArgsHelperTest { diff --git a/test_runner/src/test/kotlin/ftl/cli/firebase/RefreshCommandTest.kt b/test_runner/src/test/kotlin/ftl/cli/firebase/RefreshCommandTest.kt index 0631601c9d..ecaffb9f15 100644 --- a/test_runner/src/test/kotlin/ftl/cli/firebase/RefreshCommandTest.kt +++ b/test_runner/src/test/kotlin/ftl/cli/firebase/RefreshCommandTest.kt @@ -3,14 +3,14 @@ package ftl.cli.firebase import com.google.common.truth.Truth import com.google.common.truth.Truth.assertThat import ftl.test.util.FlankTestRunner +import java.nio.file.Files +import java.nio.file.Paths import org.junit.Rule import org.junit.Test import org.junit.contrib.java.lang.system.ExpectedSystemExit import org.junit.contrib.java.lang.system.SystemOutRule import org.junit.runner.RunWith import picocli.CommandLine -import java.nio.file.Files -import java.nio.file.Paths @RunWith(FlankTestRunner::class) class RefreshCommandTest { diff --git a/test_runner/src/test/kotlin/ftl/doctor/DoctorTest.kt b/test_runner/src/test/kotlin/ftl/doctor/DoctorTest.kt index 441dbe7720..24b5298bd6 100644 --- a/test_runner/src/test/kotlin/ftl/doctor/DoctorTest.kt +++ b/test_runner/src/test/kotlin/ftl/doctor/DoctorTest.kt @@ -4,9 +4,9 @@ import com.google.common.truth.Truth.assertThat import ftl.args.AndroidArgs import ftl.args.IosArgs import ftl.test.util.FlankTestRunner +import java.nio.file.Paths import org.junit.Test import org.junit.runner.RunWith -import java.nio.file.Paths @RunWith(FlankTestRunner::class) class DoctorTest { diff --git a/test_runner/src/test/kotlin/ftl/ios/XctestrunTest.kt b/test_runner/src/test/kotlin/ftl/ios/XctestrunTest.kt index 9bc3812766..3d1375b0e2 100644 --- a/test_runner/src/test/kotlin/ftl/ios/XctestrunTest.kt +++ b/test_runner/src/test/kotlin/ftl/ios/XctestrunTest.kt @@ -4,10 +4,10 @@ import com.dd.plist.NSDictionary import com.google.common.truth.Truth.assertThat import ftl.test.util.FlankTestRunner import ftl.test.util.TestArtifact.fixturesPath -import org.junit.Test -import org.junit.runner.RunWith import java.nio.file.Files import java.nio.file.Paths +import org.junit.Test +import org.junit.runner.RunWith @RunWith(FlankTestRunner::class) class XctestrunTest { diff --git a/test_runner/src/test/kotlin/ftl/json/SavedMatrixTest.kt b/test_runner/src/test/kotlin/ftl/json/SavedMatrixTest.kt index 97f2019441..08ff989a8a 100644 --- a/test_runner/src/test/kotlin/ftl/json/SavedMatrixTest.kt +++ b/test_runner/src/test/kotlin/ftl/json/SavedMatrixTest.kt @@ -37,8 +37,8 @@ class SavedMatrixTest { return testExecution } - private val mockFileName = "mockFileName" - private val mockBucket = "mockBucket" + private const val mockFileName = "mockFileName" + private const val mockBucket = "mockBucket" private val mockGcsPath = "$mockBucket/$mockFileName" fun createResultsStorage(): ResultStorage { diff --git a/test_runner/src/test/kotlin/ftl/reports/HtmlErrorReportTest.kt b/test_runner/src/test/kotlin/ftl/reports/HtmlErrorReportTest.kt index 0b8571553c..a0de6d4f8f 100644 --- a/test_runner/src/test/kotlin/ftl/reports/HtmlErrorReportTest.kt +++ b/test_runner/src/test/kotlin/ftl/reports/HtmlErrorReportTest.kt @@ -2,8 +2,8 @@ package ftl.reports import com.google.common.truth.Truth.assertThat import ftl.reports.xml.JUnitXmlTest -import ftl.reports.xml.parseOneSuiteXml import ftl.reports.xml.parseAllSuitesXml +import ftl.reports.xml.parseOneSuiteXml import org.junit.Test class HtmlErrorReportTest { diff --git a/test_runner/src/test/kotlin/ftl/reports/xml/JUnitXmlTest.kt b/test_runner/src/test/kotlin/ftl/reports/xml/JUnitXmlTest.kt index b8764345b2..80b8eb1574 100644 --- a/test_runner/src/test/kotlin/ftl/reports/xml/JUnitXmlTest.kt +++ b/test_runner/src/test/kotlin/ftl/reports/xml/JUnitXmlTest.kt @@ -1,8 +1,8 @@ package ftl.reports.xml import com.google.common.truth.Truth.assertThat -import org.junit.Test import java.nio.file.Paths +import org.junit.Test class JUnitXmlTest { diff --git a/test_runner/src/test/kotlin/ftl/run/TestRunnerTest.kt b/test_runner/src/test/kotlin/ftl/run/TestRunnerTest.kt index 4bc438f2b2..ab20d1bd21 100644 --- a/test_runner/src/test/kotlin/ftl/run/TestRunnerTest.kt +++ b/test_runner/src/test/kotlin/ftl/run/TestRunnerTest.kt @@ -3,10 +3,10 @@ package ftl.run import ftl.args.AndroidArgs import ftl.args.IosArgs import ftl.test.util.FlankTestRunner +import java.nio.file.Paths import kotlinx.coroutines.runBlocking import org.junit.Test import org.junit.runner.RunWith -import java.nio.file.Paths @RunWith(FlankTestRunner::class) class TestRunnerTest { diff --git a/test_runner/src/test/kotlin/ftl/shard/ShardTest.kt b/test_runner/src/test/kotlin/ftl/shard/ShardTest.kt index aca13cd3bb..231bfc5b45 100644 --- a/test_runner/src/test/kotlin/ftl/shard/ShardTest.kt +++ b/test_runner/src/test/kotlin/ftl/shard/ShardTest.kt @@ -7,12 +7,12 @@ import ftl.reports.xml.model.JUnitTestCase import ftl.reports.xml.model.JUnitTestResult import ftl.reports.xml.model.JUnitTestSuite import ftl.test.util.FlankTestRunner +import java.util.concurrent.TimeUnit +import kotlin.system.measureNanoTime import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mockito.`when` import org.mockito.Mockito.mock -import java.util.concurrent.TimeUnit -import kotlin.system.measureNanoTime @RunWith(FlankTestRunner::class) class ShardTest { diff --git a/test_runner/src/test/kotlin/ftl/test/util/FlankTestRunner.kt b/test_runner/src/test/kotlin/ftl/test/util/FlankTestRunner.kt index f2200a29c5..834c25123c 100644 --- a/test_runner/src/test/kotlin/ftl/test/util/FlankTestRunner.kt +++ b/test_runner/src/test/kotlin/ftl/test/util/FlankTestRunner.kt @@ -2,8 +2,8 @@ package ftl.test.util import ftl.config.FtlConstants import ftl.util.Bash -import org.junit.runners.BlockJUnit4ClassRunner import java.net.BindException +import org.junit.runners.BlockJUnit4ClassRunner class FlankTestRunner(klass: Class<*>) : BlockJUnit4ClassRunner(klass) { diff --git a/test_runner/src/test/kotlin/ftl/test/util/LocalGcs.kt b/test_runner/src/test/kotlin/ftl/test/util/LocalGcs.kt index a192ba3b3f..4455612a7b 100644 --- a/test_runner/src/test/kotlin/ftl/test/util/LocalGcs.kt +++ b/test_runner/src/test/kotlin/ftl/test/util/LocalGcs.kt @@ -1,14 +1,11 @@ package ftl.test.util -import com.google.auth.oauth2.ComputeEngineCredentials import com.google.cloud.storage.BlobInfo import ftl.gc.GcStorage -import org.junit.Assert import java.nio.file.Files import java.nio.file.Path import java.nio.file.Paths -import java.util.logging.Level -import java.util.logging.Logger +import org.junit.Assert object LocalGcs { @@ -31,13 +28,6 @@ object LocalGcs { ) } - private fun silenceComputeEngine() { - // Set log level then access the storage var to lazy load it. - // Silence info log about "Failed to detect whether we are running on Google Compute Engine." - Logger.getLogger(ComputeEngineCredentials::class.java.name).level = Level.OFF - GcStorage.storage - } - fun uploadFiles() { val appApk = "../test_app/apks/app-debug.apk" val testApk = "../test_app/apks/app-debug-androidTest.apk" diff --git a/test_runner/src/test/kotlin/ftl/test/util/MockServer.kt b/test_runner/src/test/kotlin/ftl/test/util/MockServer.kt index 6770749be9..91d8a6a057 100644 --- a/test_runner/src/test/kotlin/ftl/test/util/MockServer.kt +++ b/test_runner/src/test/kotlin/ftl/test/util/MockServer.kt @@ -13,16 +13,16 @@ import com.google.api.services.testing.model.TestExecution import com.google.api.services.testing.model.TestMatrix import com.google.api.services.testing.model.ToolResultsStep import com.google.api.services.toolresults.model.Duration +import com.google.api.services.toolresults.model.FailureDetail import com.google.api.services.toolresults.model.History +import com.google.api.services.toolresults.model.InconclusiveDetail import com.google.api.services.toolresults.model.ListHistoriesResponse import com.google.api.services.toolresults.model.Outcome import com.google.api.services.toolresults.model.ProjectSettings +import com.google.api.services.toolresults.model.SkippedDetail import com.google.api.services.toolresults.model.Step import com.google.api.services.toolresults.model.TestExecutionStep import com.google.api.services.toolresults.model.TestTiming -import com.google.api.services.toolresults.model.FailureDetail -import com.google.api.services.toolresults.model.InconclusiveDetail -import com.google.api.services.toolresults.model.SkippedDetail import com.google.gson.GsonBuilder import com.google.gson.LongSerializationPolicy import ftl.config.FtlConstants.JSON_FACTORY @@ -42,10 +42,10 @@ import io.ktor.routing.post import io.ktor.routing.routing import io.ktor.server.engine.embeddedServer import io.ktor.server.netty.Netty -import org.slf4j.LoggerFactory.getLogger import java.nio.file.Files import java.nio.file.Paths import java.util.concurrent.atomic.AtomicInteger +import org.slf4j.LoggerFactory.getLogger object MockServer { diff --git a/test_runner/src/test/kotlin/ftl/test/util/TestArtifact.kt b/test_runner/src/test/kotlin/ftl/test/util/TestArtifact.kt index 361f3defe2..cec2a6207f 100644 --- a/test_runner/src/test/kotlin/ftl/test/util/TestArtifact.kt +++ b/test_runner/src/test/kotlin/ftl/test/util/TestArtifact.kt @@ -1,12 +1,6 @@ package ftl.test.util import ftl.util.Bash -import okhttp3.OkHttpClient -import okhttp3.Request -import okhttp3.ResponseBody -import org.jsoup.Jsoup -import org.jsoup.nodes.Document -import org.jsoup.nodes.Element import java.io.File import java.net.InetAddress import java.net.InetSocketAddress @@ -15,6 +9,12 @@ import java.nio.file.Files import java.nio.file.Paths import java.util.concurrent.TimeUnit import kotlin.math.pow +import okhttp3.OkHttpClient +import okhttp3.Request +import okhttp3.ResponseBody +import org.jsoup.Jsoup +import org.jsoup.nodes.Document +import org.jsoup.nodes.Element object TestArtifact { const val fixturesPath = "./src/test/kotlin/ftl/fixtures/tmp" diff --git a/test_runner/src/test/kotlin/task/UpdateCatalogFixtures.kt b/test_runner/src/test/kotlin/task/UpdateCatalogFixtures.kt index cf42ce0b6b..f9b13ad9af 100644 --- a/test_runner/src/test/kotlin/task/UpdateCatalogFixtures.kt +++ b/test_runner/src/test/kotlin/task/UpdateCatalogFixtures.kt @@ -13,6 +13,7 @@ object UpdateCatalogFixtures { } @JvmStatic + @Suppress("UnusedPrivateMember") fun main(args: Array) { val androidCatalog = GcTesting.get.testEnvironmentCatalog().get("android").execute().androidDeviceCatalog write("android_catalog.json", androidCatalog)