From 6e29eaf3c4ca14d5dc9569aace3fad6791da5699 Mon Sep 17 00:00:00 2001 From: Piotr Adamczyk Date: Wed, 5 Aug 2020 21:09:29 +0200 Subject: [PATCH 1/4] #932 Added tests for flank scripts --- flank-scripts/build.gradle.kts | 5 + .../buildSrc/src/main/kotlin/Dependencies.kt | 5 + .../buildSrc/src/main/kotlin/Versions.kt | 7 ++ .../exceptions/FlankScriptsExceptions.kt | 6 +- .../release/updatebugsnag/UpdateBugSnag.kt | 12 +- .../flank/scripts/utils/ShellExecute.kt | 2 +- .../kotlin/flank/scripts/FuelTestRunner.kt | 60 +++++++++ .../FlankScriptsExceptionMappersTest.kt | 115 ++++++++++++++++++ .../exceptions/FlankScriptsExceptionsTest.kt | 35 ++++++ .../release/hub/DeleteOldTagCommandTest.kt | 36 ++++++ .../scripts/release/hub/DeleteOldTagTest.kt | 32 +++++ .../release/hub/ReleaseFlankCommandTest.kt | 27 ++++ .../jfrog/sync/SyncMavenCommandTest.kt | 31 +++++ .../updatebugsnag/UpdateBugSnagCommandTest.kt | 33 +++++ .../updatebugsnag/UpdateBugSnagTest.kt | 51 ++++++++ .../flank/scripts/utils/SerializationTest.kt | 40 ++++++ .../flank/scripts/utils/ShellExecuteTest.kt | 55 +++++++++ 17 files changed, 542 insertions(+), 10 deletions(-) create mode 100644 flank-scripts/src/test/kotlin/flank/scripts/FuelTestRunner.kt create mode 100644 flank-scripts/src/test/kotlin/flank/scripts/exceptions/FlankScriptsExceptionMappersTest.kt create mode 100644 flank-scripts/src/test/kotlin/flank/scripts/exceptions/FlankScriptsExceptionsTest.kt create mode 100644 flank-scripts/src/test/kotlin/flank/scripts/release/hub/DeleteOldTagCommandTest.kt create mode 100644 flank-scripts/src/test/kotlin/flank/scripts/release/hub/DeleteOldTagTest.kt create mode 100644 flank-scripts/src/test/kotlin/flank/scripts/release/hub/ReleaseFlankCommandTest.kt create mode 100644 flank-scripts/src/test/kotlin/flank/scripts/release/jfrog/sync/SyncMavenCommandTest.kt create mode 100644 flank-scripts/src/test/kotlin/flank/scripts/release/updatebugsnag/UpdateBugSnagCommandTest.kt create mode 100644 flank-scripts/src/test/kotlin/flank/scripts/release/updatebugsnag/UpdateBugSnagTest.kt create mode 100644 flank-scripts/src/test/kotlin/flank/scripts/utils/SerializationTest.kt create mode 100644 flank-scripts/src/test/kotlin/flank/scripts/utils/ShellExecuteTest.kt diff --git a/flank-scripts/build.gradle.kts b/flank-scripts/build.gradle.kts index c1092ff696..16b80ee074 100644 --- a/flank-scripts/build.gradle.kts +++ b/flank-scripts/build.gradle.kts @@ -41,4 +41,9 @@ dependencies { implementation(Fuel.KOTLINX_SERIALIZATION) implementation(Fuel.COROUTINES) implementation(CLIKT) + + testImplementation(JUNIT) + testImplementation(MOCKK) + testImplementation(TRUTH) + testImplementation(SYSTEM_RULES) } diff --git a/flank-scripts/buildSrc/src/main/kotlin/Dependencies.kt b/flank-scripts/buildSrc/src/main/kotlin/Dependencies.kt index 1fb0c2e8de..924d9ff07b 100644 --- a/flank-scripts/buildSrc/src/main/kotlin/Dependencies.kt +++ b/flank-scripts/buildSrc/src/main/kotlin/Dependencies.kt @@ -12,3 +12,8 @@ object Fuel { const val COROUTINES = "com.github.kittinunf.fuel:fuel-coroutines:${Versions.FUEL}" const val KOTLINX_SERIALIZATION = "com.github.kittinunf.fuel:fuel-kotlinx-serialization:${Versions.FUEL}" } + +const val TRUTH = "com.google.truth:truth:${Versions.TRUTH}" +const val MOCKK = "io.mockk:mockk:${Versions.MOCKK}" +const val JUNIT = "junit:junit:${Versions.JUNIT}" +const val SYSTEM_RULES = "com.github.stefanbirkner:system-rules:${Versions.SYSTEM_RULES}" diff --git a/flank-scripts/buildSrc/src/main/kotlin/Versions.kt b/flank-scripts/buildSrc/src/main/kotlin/Versions.kt index 0ea0d38734..042e24a0ba 100644 --- a/flank-scripts/buildSrc/src/main/kotlin/Versions.kt +++ b/flank-scripts/buildSrc/src/main/kotlin/Versions.kt @@ -4,4 +4,11 @@ object Versions { const val KOTLINX_SERIALIZATION = "0.20.0" const val FUEL = "2.2.3" const val CLIKT = "2.8.0" + // https://github.com/google/truth/releases + const val TRUTH = "1.0" + // https://github.com/mockk/mockk + const val MOCKK = "1.10.0" + const val JUNIT = "4.13" + // https://github.com/stefanbirkner/system-rules/releases + const val SYSTEM_RULES = "1.19.0" } diff --git a/flank-scripts/src/main/kotlin/flank/scripts/exceptions/FlankScriptsExceptions.kt b/flank-scripts/src/main/kotlin/flank/scripts/exceptions/FlankScriptsExceptions.kt index 60d59964fb..5471ad7b64 100644 --- a/flank-scripts/src/main/kotlin/flank/scripts/exceptions/FlankScriptsExceptions.kt +++ b/flank-scripts/src/main/kotlin/flank/scripts/exceptions/FlankScriptsExceptions.kt @@ -3,15 +3,15 @@ package flank.scripts.exceptions import flank.scripts.release.hub.GitHubErrorResponse import flank.scripts.release.updatebugsnag.BugSnagResponse -sealed class FlankScriptsExceptions() : Exception() +sealed class FlankScriptsExceptions : Exception() -class GitHubException(private val body: GitHubErrorResponse) : FlankScriptsExceptions() { +class GitHubException(val body: GitHubErrorResponse) : FlankScriptsExceptions() { override fun toString(): String { return "Error while doing GitHub request, because of ${body.message}, more info at ${body.documentationUrl}" } } -class BugsnagException(private val body: BugSnagResponse) : FlankScriptsExceptions() { +class BugsnagException(val body: BugSnagResponse) : FlankScriptsExceptions() { override fun toString(): String { return "Error while doing Bugnsag request, because of ${body.errors.joinToString()}" } diff --git a/flank-scripts/src/main/kotlin/flank/scripts/release/updatebugsnag/UpdateBugSnag.kt b/flank-scripts/src/main/kotlin/flank/scripts/release/updatebugsnag/UpdateBugSnag.kt index b581ea91bb..a36fa860e0 100644 --- a/flank-scripts/src/main/kotlin/flank/scripts/release/updatebugsnag/UpdateBugSnag.kt +++ b/flank-scripts/src/main/kotlin/flank/scripts/release/updatebugsnag/UpdateBugSnag.kt @@ -10,6 +10,12 @@ import flank.scripts.utils.toJson suspend fun updateBugsnag(bugsnagApiKey: String, appVersion: String, githubWorkflowUrl: String) = httpRequest(createRequestBody(bugsnagApiKey, appVersion, githubWorkflowUrl)) +private suspend fun httpRequest(jsonString: String) = + Fuel.post(BUGNSAG_URL) + .jsonBody(jsonString) + .awaitResult(BugSnagResponseDeserializer) + .mapClientError { it.toBugsnagException() } + private fun createRequestBody(bugsnagApiKey: String, appVersion: String, githubWorkflowUrl: String) = BugSnagRequest( apiKey = bugsnagApiKey, @@ -20,12 +26,6 @@ private fun createRequestBody(bugsnagApiKey: String, appVersion: String, githubW metadata = mapOf("github_actions_build_url" to githubWorkflowUrl) ).toJson(BugSnagRequest.serializer()) -private suspend fun httpRequest(jsonString: String) = - Fuel.post(BUGNSAG_URL) - .jsonBody(jsonString) - .awaitResult(BugSnagResponseDeserializer) - .mapClientError { it.toBugsnagException() } - private fun githubActionsSourceControl(appVersion: String) = SourceControl( "github", REPOSITORY, diff --git a/flank-scripts/src/main/kotlin/flank/scripts/utils/ShellExecute.kt b/flank-scripts/src/main/kotlin/flank/scripts/utils/ShellExecute.kt index 8422266847..66e24f6a8f 100644 --- a/flank-scripts/src/main/kotlin/flank/scripts/utils/ShellExecute.kt +++ b/flank-scripts/src/main/kotlin/flank/scripts/utils/ShellExecute.kt @@ -8,7 +8,7 @@ fun List.runCommand(retryCount: Int = 0) = fun String.runCommand(retryCount: Int = 0) = split(" ").toList().runCommand(retryCount) -private fun ProcessBuilder.startWithRetry(retryCount: Int): Int { +internal fun ProcessBuilder.startWithRetry(retryCount: Int): Int { var retryTries = 0 var processResponse: Int do { diff --git a/flank-scripts/src/test/kotlin/flank/scripts/FuelTestRunner.kt b/flank-scripts/src/test/kotlin/flank/scripts/FuelTestRunner.kt new file mode 100644 index 0000000000..8d1c8d6a16 --- /dev/null +++ b/flank-scripts/src/test/kotlin/flank/scripts/FuelTestRunner.kt @@ -0,0 +1,60 @@ +package flank.scripts + +import com.github.kittinunf.fuel.core.Client +import com.github.kittinunf.fuel.core.FuelManager +import com.github.kittinunf.fuel.core.Request +import com.github.kittinunf.fuel.core.Response +import com.github.kittinunf.fuel.core.requests.DefaultBody +import flank.scripts.release.updatebugsnag.BugSnagRequest +import flank.scripts.release.updatebugsnag.BugSnagResponse +import flank.scripts.utils.toJson +import flank.scripts.utils.toObject +import org.junit.runners.BlockJUnit4ClassRunner +import org.junit.runners.model.Statement + +class FuelTestRunner(klass: Class<*>) : BlockJUnit4ClassRunner(klass) { + + override fun withBeforeClasses(statement: Statement?): Statement { + startMockClient() + return super.withBeforeClasses(statement) + } + + private fun startMockClient() { + FuelManager.instance.client = object : Client { + override fun executeRequest(request: Request): Response { + return when (request.url.toString()) { + "https://api.github.com/repos/Flank/flank/git/refs/tags/success" -> request.buildResponse("", 200) + "https://api.github.com/repos/Flank/flank/git/refs/tags/failure" -> request.buildResponse(GITHUB_ERROR_BODY, 422) + "https://build.bugsnag.com/" -> { + val body = request.body.asString("application/json").toObject(BugSnagRequest.serializer()) + if(body.apiKey == "success") { + request.buildResponse(body = BugSnagResponse("success") + .toJson(BugSnagResponse.serializer()), statusCode = 200) + } else { + request.buildResponse( + body = BugSnagResponse( + status = "failure", + errors = listOf("errors") + ).toJson(BugSnagResponse.serializer()), statusCode = 422) + } + } + else -> Response(request.url) + } + } + } + } + + private fun Request.buildResponse(body: String, statusCode: Int) = + Response(url, statusCode = statusCode, responseMessage = body, body = DefaultBody( + { body.byteInputStream() }, + { body.length.toLong() } + )) + +} + +private val GITHUB_ERROR_BODY = """ + { + "message": "Bad credentials", + "documentation_url": "https://developer.github.com/v3" + } + """.trimIndent() diff --git a/flank-scripts/src/test/kotlin/flank/scripts/exceptions/FlankScriptsExceptionMappersTest.kt b/flank-scripts/src/test/kotlin/flank/scripts/exceptions/FlankScriptsExceptionMappersTest.kt new file mode 100644 index 0000000000..e75484abbe --- /dev/null +++ b/flank-scripts/src/test/kotlin/flank/scripts/exceptions/FlankScriptsExceptionMappersTest.kt @@ -0,0 +1,115 @@ +package flank.scripts.exceptions + +import com.github.kittinunf.fuel.core.FuelError +import com.github.kittinunf.result.Result +import com.github.kittinunf.result.failure +import com.google.common.truth.Truth.assertThat +import io.mockk.every +import io.mockk.mockk +import org.junit.Test + +class FlankScriptsExceptionMappersTest { + + @Test + fun `Should properly map client error`() { + // given + val fuelMockedError = mockk { + every { response.statusCode } returns 404 + } + val result: Result = Result.error(fuelMockedError) + val expectedException = Exception("test") + + // when + val (_, actualException) = result.mapClientError { expectedException } + + // then + + assertThat(actualException).isEqualTo(expectedException) + } + + @Test + fun `Should not map error when it is different than client error`() { + // given + val fuelMockedError = mockk { + every { response.statusCode } returns 500 + } + val result: Result = Result.error(fuelMockedError) + val testException = Exception("test") + + // when + val actual = result.mapClientError { testException } + + // then + assertThat(actual).isEqualTo(result) + actual.failure { + assertThat(it).isNotEqualTo(testException) + } + } + + @Test + fun `Should not map error when response is success`() { + // given + val result: Result = Result.success("") + val testException = Exception("test") + + // when + val actual = result.mapClientError { testException } + + // then + assertThat(actual).isEqualTo(result) + actual.failure { + assertThat(it).isNotEqualTo(testException) + } + } + + @Test + fun `Should properly map github exception from json body`() { + // given + val mockedFuelError = """ + { + "message": "Bad credentials", + "documentation_url": "https://developer.github.com/v3" + } + """.trimIndent().toMockFuelError() + val expectedMessage = "Bad credentials" + val expectedUrl = "https://developer.github.com/v3" + val expectedToString = "Error while doing GitHub request, because of $expectedMessage, more info at $expectedUrl" + + // when + val gitHubException = mockedFuelError.toGithubException() + + // then + assertThat(gitHubException.body.message).isEqualTo(expectedMessage) + assertThat(gitHubException.body.documentationUrl).isEqualTo(expectedUrl) + assertThat(gitHubException.toString()).isEqualTo(expectedToString) + } + + @Test + fun `Should properly map bugsnag exception from json body`() { + // given + val mockedFuelError = """ + { + "errors": [ + "Missing app version" + ], + "status": "error" + } + """.trimIndent().toMockFuelError() + val expectedErrors = listOf("Missing app version") + val expectedStatus = "error" + val expectedMessage = "Error while doing Bugnsag request, because of Missing app version" + + // when + val bugsnagException = mockedFuelError.toBugsnagException() + + // then + assertThat(bugsnagException.body.errors).isEqualTo(expectedErrors) + assertThat(bugsnagException.body.status).isEqualTo(expectedStatus) + assertThat(bugsnagException.toString()).isEqualTo(expectedMessage) + } + + + private fun String.toMockFuelError() = mockk { + every { response.body().asString(any()) } returns this@toMockFuelError + } +} diff --git a/flank-scripts/src/test/kotlin/flank/scripts/exceptions/FlankScriptsExceptionsTest.kt b/flank-scripts/src/test/kotlin/flank/scripts/exceptions/FlankScriptsExceptionsTest.kt new file mode 100644 index 0000000000..b6eb5e3173 --- /dev/null +++ b/flank-scripts/src/test/kotlin/flank/scripts/exceptions/FlankScriptsExceptionsTest.kt @@ -0,0 +1,35 @@ +package flank.scripts.exceptions + +import com.google.common.truth.Truth.assertThat +import flank.scripts.release.hub.GitHubErrorResponse +import flank.scripts.release.updatebugsnag.BugSnagResponse +import org.junit.Test + +class FlankScriptsExceptionsTest { + + @Test + fun `Should return correct description of github exception`() { + // given + val testBody = GitHubErrorResponse("error", "www.error.test") + val expectedToString = "Error while doing GitHub request, because of error, more info at www.error.test" + + // when + val actual = GitHubException(testBody) + + // then + assertThat(actual.toString()).isEqualTo(expectedToString) + } + + @Test + fun `Should return correct description of bugnsag exception`() { + // given + val testBody = BugSnagResponse("error", errors = listOf("test", "not good")) + val expectedToString = "Error while doing Bugnsag request, because of test, not good" + + // when + val actual = BugsnagException(testBody) + + // then + assertThat(actual.toString()).isEqualTo(expectedToString) + } +} diff --git a/flank-scripts/src/test/kotlin/flank/scripts/release/hub/DeleteOldTagCommandTest.kt b/flank-scripts/src/test/kotlin/flank/scripts/release/hub/DeleteOldTagCommandTest.kt new file mode 100644 index 0000000000..3cf7ecf94e --- /dev/null +++ b/flank-scripts/src/test/kotlin/flank/scripts/release/hub/DeleteOldTagCommandTest.kt @@ -0,0 +1,36 @@ +package flank.scripts.release.hub + +import com.google.common.truth.Truth.assertThat +import flank.scripts.FuelTestRunner +import org.junit.Rule +import org.junit.Test +import org.junit.contrib.java.lang.system.SystemOutRule +import org.junit.runner.RunWith + +@RunWith(FuelTestRunner::class) +class DeleteOldTagCommandTest { + + @Rule + @JvmField + val systemOutRule = SystemOutRule().enableLog()!! + + @Test + fun `Should return properly message when success`() { + // when + DeleteOldTagCommand().main(arrayOf("--git-tag=success", "--username=1","--token=1")) + + // then + assertThat(systemOutRule.log).contains("Tag success was deleted") + } + + @Test + fun `Should return with exit code 1 when failure`() { + // when + DeleteOldTagCommand().main(arrayOf("--git-tag=failure", "--username=1","--token=1")) + + // then + assertThat(systemOutRule.log).contains("Error while doing GitHub request") + } + + +} diff --git a/flank-scripts/src/test/kotlin/flank/scripts/release/hub/DeleteOldTagTest.kt b/flank-scripts/src/test/kotlin/flank/scripts/release/hub/DeleteOldTagTest.kt new file mode 100644 index 0000000000..f292211d0d --- /dev/null +++ b/flank-scripts/src/test/kotlin/flank/scripts/release/hub/DeleteOldTagTest.kt @@ -0,0 +1,32 @@ +package flank.scripts.release.hub + +import com.github.kittinunf.result.Result +import com.google.common.truth.Truth.assertThat +import flank.scripts.FuelTestRunner +import flank.scripts.exceptions.GitHubException +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(FuelTestRunner::class) +class DeleteOldTagTest { + + @Test + fun `Should return success for correct request call`() { + // when + val actual = deleteOldTag("success", "user", "password") + + // then + assertThat(actual).isInstanceOf(Result.Success::class.java) + } + + @Test + fun `Should return failure for incorrect request call`() { + // when + val actual = deleteOldTag("failure", "user", "password") + + // then + assertThat(actual).isInstanceOf(Result.Failure::class.java) + val (_, exception) = actual + assertThat(exception).isInstanceOf(GitHubException::class.java) + } +} diff --git a/flank-scripts/src/test/kotlin/flank/scripts/release/hub/ReleaseFlankCommandTest.kt b/flank-scripts/src/test/kotlin/flank/scripts/release/hub/ReleaseFlankCommandTest.kt new file mode 100644 index 0000000000..c8b62f51d5 --- /dev/null +++ b/flank-scripts/src/test/kotlin/flank/scripts/release/hub/ReleaseFlankCommandTest.kt @@ -0,0 +1,27 @@ +package flank.scripts.release.hub + +import io.mockk.every +import io.mockk.mockkStatic +import org.junit.Rule +import org.junit.Test +import org.junit.contrib.java.lang.system.ExpectedSystemExit + +class ReleaseFlankCommandTest { + + @Rule + @JvmField + val systemExit = ExpectedSystemExit.none()!! + + @Test + fun `Should return same exit code as command`() { + // given + mockkStatic("flank.scripts.release.hub.ReleaseFlankKt") + every { releaseFlank(any(), any(), any(), any()) } returns 1 + + // expect + systemExit.expectSystemExitWithStatus(1) + + // when + ReleaseFlankCommand().main(listOf("--input-file=./", "--git-tag=T", "--commit-hash=X")) + } +} diff --git a/flank-scripts/src/test/kotlin/flank/scripts/release/jfrog/sync/SyncMavenCommandTest.kt b/flank-scripts/src/test/kotlin/flank/scripts/release/jfrog/sync/SyncMavenCommandTest.kt new file mode 100644 index 0000000000..9000044699 --- /dev/null +++ b/flank-scripts/src/test/kotlin/flank/scripts/release/jfrog/sync/SyncMavenCommandTest.kt @@ -0,0 +1,31 @@ +package flank.scripts.release.jfrog.sync + +import io.mockk.every +import io.mockk.mockkStatic +import io.mockk.verify +import org.junit.Rule +import org.junit.Test +import org.junit.contrib.java.lang.system.ExpectedSystemExit + +class SyncMavenCommandTest { + + @Rule + @JvmField + val systemExit = ExpectedSystemExit.none()!! + + @Test + fun `Should return same exit code as command`() { + // given + mockkStatic("flank.scripts.release.jfrog.sync.SyncMavenKt") + every { jFrogSync(any()) } returns 1 + + // expect + systemExit.expectSystemExitWithStatus(1) + + // when + SyncMavenCommand().main(listOf("--git-tag=TAG")) + + // then + verify { jFrogSync("TAG") } + } +} diff --git a/flank-scripts/src/test/kotlin/flank/scripts/release/updatebugsnag/UpdateBugSnagCommandTest.kt b/flank-scripts/src/test/kotlin/flank/scripts/release/updatebugsnag/UpdateBugSnagCommandTest.kt new file mode 100644 index 0000000000..a27cdf521a --- /dev/null +++ b/flank-scripts/src/test/kotlin/flank/scripts/release/updatebugsnag/UpdateBugSnagCommandTest.kt @@ -0,0 +1,33 @@ +package flank.scripts.release.updatebugsnag + +import flank.scripts.FuelTestRunner +import org.junit.Rule +import org.junit.Test +import org.junit.contrib.java.lang.system.ExpectedSystemExit +import org.junit.runner.RunWith + +@RunWith(FuelTestRunner::class) +class UpdateBugSnagCommandTest { + + @Rule + @JvmField + val systemExit = ExpectedSystemExit.none()!! + + @Test + fun `Should return with exit code 0 when success`() { + // expect + systemExit.expectSystemExitWithStatus(0) + + // when + UpdateBugSnagCommand().main(arrayOf("--bugsnag-api-key=success", "--app-version=1")) + } + + @Test + fun `Should return with exit code 1 when failure`() { + // expect + systemExit.expectSystemExitWithStatus(1) + + // when + UpdateBugSnagCommand().main(arrayOf("--bugsnag-api-key=failure", "--app-version=1")) + } +} diff --git a/flank-scripts/src/test/kotlin/flank/scripts/release/updatebugsnag/UpdateBugSnagTest.kt b/flank-scripts/src/test/kotlin/flank/scripts/release/updatebugsnag/UpdateBugSnagTest.kt new file mode 100644 index 0000000000..d31c73391b --- /dev/null +++ b/flank-scripts/src/test/kotlin/flank/scripts/release/updatebugsnag/UpdateBugSnagTest.kt @@ -0,0 +1,51 @@ +package flank.scripts.release.updatebugsnag + +import com.google.common.truth.Truth.assertThat +import flank.scripts.FuelTestRunner +import kotlinx.coroutines.runBlocking +import org.junit.Test +import com.github.kittinunf.result.Result +import com.github.kittinunf.result.failure +import flank.scripts.exceptions.BugsnagException +import org.junit.runner.RunWith + +@RunWith(FuelTestRunner::class) +class UpdateBugSnagTest { + + @Test + fun `Should return success with correct request`() { + runBlocking { + // given + val expectedStatus = "success" + + // when + val actual = updateBugsnag("success", "version", "url") + + // then + assertThat(actual).isInstanceOf(Result.Success::class.java) + assertThat(actual.get().status).isEqualTo(expectedStatus) + assertThat(actual.get().errors).isEmpty() + } + } + + @Test + fun `Should return failure when bad request`() { + runBlocking { + // given + val expectedStatus = "failure" + + // when + val actual = updateBugsnag("failure", "version", "url") + + // then + assertThat(actual).isInstanceOf(Result.Failure::class.java) + actual.failure { + assertThat(it).isInstanceOf(BugsnagException::class.java) + with((it as BugsnagException).body) { + assertThat(status).isEqualTo(expectedStatus) + assertThat(errors).isNotEmpty() + } + } + } + } +} diff --git a/flank-scripts/src/test/kotlin/flank/scripts/utils/SerializationTest.kt b/flank-scripts/src/test/kotlin/flank/scripts/utils/SerializationTest.kt new file mode 100644 index 0000000000..744ea224af --- /dev/null +++ b/flank-scripts/src/test/kotlin/flank/scripts/utils/SerializationTest.kt @@ -0,0 +1,40 @@ +package flank.scripts.utils + +import com.google.common.truth.Truth.assertThat +import flank.scripts.release.hub.GitHubErrorResponse +import flank.scripts.release.updatebugsnag.SourceControl +import org.junit.Test + +class SerializationTest { + + @Test + fun `Should create object from json`() { + // given + val testJson = """ + { + "message": "Bad credentials", + "documentation_url": "https://developer.github.com/v3" + } + """.trimIndent() + val expected = GitHubErrorResponse("Bad credentials", "https://developer.github.com/v3") + + // when + val actual = testJson.toObject(GitHubErrorResponse.serializer()) + + // then + assertThat(actual).isEqualTo(expected) + } + + @Test + fun `Should create json from object`() { + // given + val testObject = SourceControl("a", "b", "c") + val expected = "{\"provider\":\"a\",\"repository\":\"b\",\"revision\":\"c\"}" + + // when + val actual = testObject.toJson(SourceControl.serializer()) + + // then + assertThat(actual).isEqualTo(expected) + } +} diff --git a/flank-scripts/src/test/kotlin/flank/scripts/utils/ShellExecuteTest.kt b/flank-scripts/src/test/kotlin/flank/scripts/utils/ShellExecuteTest.kt new file mode 100644 index 0000000000..0e35df8519 --- /dev/null +++ b/flank-scripts/src/test/kotlin/flank/scripts/utils/ShellExecuteTest.kt @@ -0,0 +1,55 @@ +package flank.scripts.utils + +import com.google.common.truth.Truth.assertThat +import io.mockk.every +import io.mockk.mockk +import io.mockk.verify +import org.junit.Test + +class ShellExecuteTest { + + @Test + fun `Should run process only once when success`() { + // given + val processBuilder = mockk() { + every { start().waitFor() } returns 0 + } + + // when + val actual = processBuilder.startWithRetry(0) + + // then + verify(exactly = 1) { processBuilder.start() } + assertThat(actual).isEqualTo(0) + } + + @Test + fun `Should retry process given number of retries when failed`() { + // given + val processBuilder = mockk() { + every { start().waitFor() } returns 1 + } + + // when + val actual = processBuilder.startWithRetry(3) + + // then + verify(exactly = 3) { processBuilder.start() } + assertThat(actual).isEqualTo(1) + } + + @Test + fun `Should not retry process when exception occurs`() { + // given + val processBuilder = mockk() { + every { start().waitFor() } throws Exception("test") + } + + // when + val actual = processBuilder.startWithRetry(3) + + // then + verify(exactly = 1) { processBuilder.start() } + assertThat(actual).isEqualTo(-1) + } +} From 8535c81c13dcfdab15709829b26b1d6d0ffabe4c Mon Sep 17 00:00:00 2001 From: Piotr Adamczyk Date: Wed, 5 Aug 2020 21:20:22 +0200 Subject: [PATCH 2/4] #932 Added tests for flank scripts --- release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/release_notes.md b/release_notes.md index 91e9cd61cd..032c21ae4f 100644 --- a/release_notes.md +++ b/release_notes.md @@ -2,6 +2,8 @@ - [#952](https://github.com/Flank/flank/pull/952) Fix version printing on Flank release - [#950](https://github.com/Flank/flank/pull/950) Fix crash when --legacy-junit-result set. ([adamfilipow92](https://github.com/adamfilipow92)) - [#948](https://github.com/Flank/flank/pull/948) Increment retry tries and change sync tag for jfrogSync. ([piotradamczyk5](https://github.com/piotradamczyk5)) +- [#946](https://github.com/Flank/flank/pull/946) Added tests for flank scripts. ([piotradamczyk5](https://github.com/piotradamczyk5)) +- - - From fe702f74853aa011961326f3180917767e0bdf87 Mon Sep 17 00:00:00 2001 From: Piotr Adamczyk Date: Thu, 6 Aug 2020 16:32:50 +0200 Subject: [PATCH 3/4] Added detekt and custom workflow --- .../flank-scripts-macos_workflow.yml | 29 +++++++++++++++++++ flank-scripts/build.gradle.kts | 18 ++++++++++++ .../buildSrc/src/main/kotlin/Dependencies.kt | 2 ++ .../buildSrc/src/main/kotlin/Versions.kt | 3 ++ .../src/main/kotlin/flank/scripts/Main.kt | 1 + .../flank/scripts/release/ReleaseCommand.kt | 1 + .../flank/scripts/utils/ShellExecute.kt | 6 ++-- .../kotlin/flank/scripts/FuelTestRunner.kt | 7 ++--- .../FlankScriptsExceptionMappersTest.kt | 2 -- .../release/hub/DeleteOldTagCommandTest.kt | 6 ++-- .../updatebugsnag/UpdateBugSnagTest.kt | 6 ++-- 11 files changed, 65 insertions(+), 16 deletions(-) create mode 100644 .github/workflows/flank-scripts-macos_workflow.yml diff --git a/.github/workflows/flank-scripts-macos_workflow.yml b/.github/workflows/flank-scripts-macos_workflow.yml new file mode 100644 index 0000000000..8d48f9a13e --- /dev/null +++ b/.github/workflows/flank-scripts-macos_workflow.yml @@ -0,0 +1,29 @@ +name: flank-scripts-macos-workflow + +on: + push: + branches: + - master + pull_request: + branches: [master] + path: + - /flank-scripts/** + +jobs: + build: + runs-on: macos-latest + + steps: + - uses: actions/checkout@v2 + - uses: actions/cache@v2 + with: + path: ~/.gradle/caches + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*') }} + restore-keys: | + ${{ runner.os }}-gradle- + + - name: Gradle check + uses: eskatos/gradle-command-action@v1 + with: + gradle-executable: "./flank-scripts/gradlew" + arguments: "-p flank-scripts check" diff --git a/flank-scripts/build.gradle.kts b/flank-scripts/build.gradle.kts index 16b80ee074..641f1ff651 100644 --- a/flank-scripts/build.gradle.kts +++ b/flank-scripts/build.gradle.kts @@ -5,6 +5,7 @@ plugins { kotlin(Kotlin.PLUGIN_JVM) version Versions.KOTLIN_VERSION kotlin(Kotlin.PLUGIN_SERIALIZATION) version Versions.KOTLIN_VERSION id(PLUGIN_SHADOW_JAR) version Versions.SHADOW_JAR + id(DETEKT_PLUGIN) version Versions.DETEKT } val artifactID = "flankScripts" @@ -34,6 +35,21 @@ repositories { maven(url = "https://kotlin.bintray.com/kotlinx") } +detekt { + input = files("src/main/kotlin", "src/test/kotlin") + config = files("../config/detekt.yml") + reports { + xml { + enabled = false + } + html { + enabled = true + } + } +} + +tasks["check"].dependsOn(tasks["detekt"]) + dependencies { implementation(kotlin("stdlib")) implementation(Kotlin.KOTLIN_SERIALIZATION) @@ -42,6 +58,8 @@ dependencies { implementation(Fuel.COROUTINES) implementation(CLIKT) + detektPlugins(DETEKT_FORMATTING) + testImplementation(JUNIT) testImplementation(MOCKK) testImplementation(TRUTH) diff --git a/flank-scripts/buildSrc/src/main/kotlin/Dependencies.kt b/flank-scripts/buildSrc/src/main/kotlin/Dependencies.kt index 924d9ff07b..72a7de03f1 100644 --- a/flank-scripts/buildSrc/src/main/kotlin/Dependencies.kt +++ b/flank-scripts/buildSrc/src/main/kotlin/Dependencies.kt @@ -17,3 +17,5 @@ const val TRUTH = "com.google.truth:truth:${Versions.TRUTH}" const val MOCKK = "io.mockk:mockk:${Versions.MOCKK}" const val JUNIT = "junit:junit:${Versions.JUNIT}" const val SYSTEM_RULES = "com.github.stefanbirkner:system-rules:${Versions.SYSTEM_RULES}" +const val DETEKT_PLUGIN = "io.gitlab.arturbosch.detekt" +const val DETEKT_FORMATTING = "io.gitlab.arturbosch.detekt:detekt-formatting:${Versions.DETEKT}" diff --git a/flank-scripts/buildSrc/src/main/kotlin/Versions.kt b/flank-scripts/buildSrc/src/main/kotlin/Versions.kt index 042e24a0ba..ff03eb79fb 100644 --- a/flank-scripts/buildSrc/src/main/kotlin/Versions.kt +++ b/flank-scripts/buildSrc/src/main/kotlin/Versions.kt @@ -11,4 +11,7 @@ object Versions { const val JUNIT = "4.13" // https://github.com/stefanbirkner/system-rules/releases const val SYSTEM_RULES = "1.19.0" + + // https://github.com/detekt/detekt/releases + const val DETEKT = "1.1.0" // version must be same as flank cause they share config with each other } diff --git a/flank-scripts/src/main/kotlin/flank/scripts/Main.kt b/flank-scripts/src/main/kotlin/flank/scripts/Main.kt index 7034464074..80dbe36932 100644 --- a/flank-scripts/src/main/kotlin/flank/scripts/Main.kt +++ b/flank-scripts/src/main/kotlin/flank/scripts/Main.kt @@ -5,6 +5,7 @@ import com.github.ajalt.clikt.core.subcommands import flank.scripts.release.ReleaseCommand class Main : CliktCommand(name = "flankScripts") { + @Suppress("EmptyFunctionBlock") override fun run() {} } diff --git a/flank-scripts/src/main/kotlin/flank/scripts/release/ReleaseCommand.kt b/flank-scripts/src/main/kotlin/flank/scripts/release/ReleaseCommand.kt index 3ea6e0cc4c..9c5c91085a 100644 --- a/flank-scripts/src/main/kotlin/flank/scripts/release/ReleaseCommand.kt +++ b/flank-scripts/src/main/kotlin/flank/scripts/release/ReleaseCommand.kt @@ -22,5 +22,6 @@ class ReleaseCommand : CliktCommand(name = "release", help = "Contains all relea ) } + @Suppress("EmptyFunctionBlock") override fun run() {} } diff --git a/flank-scripts/src/main/kotlin/flank/scripts/utils/ShellExecute.kt b/flank-scripts/src/main/kotlin/flank/scripts/utils/ShellExecute.kt index 66e24f6a8f..d5ba791adc 100644 --- a/flank-scripts/src/main/kotlin/flank/scripts/utils/ShellExecute.kt +++ b/flank-scripts/src/main/kotlin/flank/scripts/utils/ShellExecute.kt @@ -25,9 +25,9 @@ internal fun ProcessBuilder.startWithRetry(retryCount: Int): Int { } private fun shouldRetry( - processResponse: Int, - retryCount: Int, - retryTries: Int + processResponse: Int, + retryCount: Int, + retryTries: Int ) = processResponse != 0 && processResponse != EXCEPTION_WHEN_CALLING_COMMAND_CODE && retryTries < retryCount const val SUCCESS = 0 diff --git a/flank-scripts/src/test/kotlin/flank/scripts/FuelTestRunner.kt b/flank-scripts/src/test/kotlin/flank/scripts/FuelTestRunner.kt index 8d1c8d6a16..7372fad814 100644 --- a/flank-scripts/src/test/kotlin/flank/scripts/FuelTestRunner.kt +++ b/flank-scripts/src/test/kotlin/flank/scripts/FuelTestRunner.kt @@ -24,10 +24,10 @@ class FuelTestRunner(klass: Class<*>) : BlockJUnit4ClassRunner(klass) { override fun executeRequest(request: Request): Response { return when (request.url.toString()) { "https://api.github.com/repos/Flank/flank/git/refs/tags/success" -> request.buildResponse("", 200) - "https://api.github.com/repos/Flank/flank/git/refs/tags/failure" -> request.buildResponse(GITHUB_ERROR_BODY, 422) + "https://api.github.com/repos/Flank/flank/git/refs/tags/failure" -> request.buildResponse(githubErrorBody, 422) "https://build.bugsnag.com/" -> { val body = request.body.asString("application/json").toObject(BugSnagRequest.serializer()) - if(body.apiKey == "success") { + if (body.apiKey == "success") { request.buildResponse(body = BugSnagResponse("success") .toJson(BugSnagResponse.serializer()), statusCode = 200) } else { @@ -49,10 +49,9 @@ class FuelTestRunner(klass: Class<*>) : BlockJUnit4ClassRunner(klass) { { body.byteInputStream() }, { body.length.toLong() } )) - } -private val GITHUB_ERROR_BODY = """ +private val githubErrorBody = """ { "message": "Bad credentials", "documentation_url": "https://developer.github.com/v3" diff --git a/flank-scripts/src/test/kotlin/flank/scripts/exceptions/FlankScriptsExceptionMappersTest.kt b/flank-scripts/src/test/kotlin/flank/scripts/exceptions/FlankScriptsExceptionMappersTest.kt index e75484abbe..1c7212e19b 100644 --- a/flank-scripts/src/test/kotlin/flank/scripts/exceptions/FlankScriptsExceptionMappersTest.kt +++ b/flank-scripts/src/test/kotlin/flank/scripts/exceptions/FlankScriptsExceptionMappersTest.kt @@ -23,7 +23,6 @@ class FlankScriptsExceptionMappersTest { val (_, actualException) = result.mapClientError { expectedException } // then - assertThat(actualException).isEqualTo(expectedException) } @@ -108,7 +107,6 @@ class FlankScriptsExceptionMappersTest { assertThat(bugsnagException.toString()).isEqualTo(expectedMessage) } - private fun String.toMockFuelError() = mockk { every { response.body().asString(any()) } returns this@toMockFuelError } diff --git a/flank-scripts/src/test/kotlin/flank/scripts/release/hub/DeleteOldTagCommandTest.kt b/flank-scripts/src/test/kotlin/flank/scripts/release/hub/DeleteOldTagCommandTest.kt index 3cf7ecf94e..268359bb70 100644 --- a/flank-scripts/src/test/kotlin/flank/scripts/release/hub/DeleteOldTagCommandTest.kt +++ b/flank-scripts/src/test/kotlin/flank/scripts/release/hub/DeleteOldTagCommandTest.kt @@ -17,7 +17,7 @@ class DeleteOldTagCommandTest { @Test fun `Should return properly message when success`() { // when - DeleteOldTagCommand().main(arrayOf("--git-tag=success", "--username=1","--token=1")) + DeleteOldTagCommand().main(arrayOf("--git-tag=success", "--username=1", "--token=1")) // then assertThat(systemOutRule.log).contains("Tag success was deleted") @@ -26,11 +26,9 @@ class DeleteOldTagCommandTest { @Test fun `Should return with exit code 1 when failure`() { // when - DeleteOldTagCommand().main(arrayOf("--git-tag=failure", "--username=1","--token=1")) + DeleteOldTagCommand().main(arrayOf("--git-tag=failure", "--username=1", "--token=1")) // then assertThat(systemOutRule.log).contains("Error while doing GitHub request") } - - } diff --git a/flank-scripts/src/test/kotlin/flank/scripts/release/updatebugsnag/UpdateBugSnagTest.kt b/flank-scripts/src/test/kotlin/flank/scripts/release/updatebugsnag/UpdateBugSnagTest.kt index d31c73391b..703a6109c8 100644 --- a/flank-scripts/src/test/kotlin/flank/scripts/release/updatebugsnag/UpdateBugSnagTest.kt +++ b/flank-scripts/src/test/kotlin/flank/scripts/release/updatebugsnag/UpdateBugSnagTest.kt @@ -1,12 +1,12 @@ package flank.scripts.release.updatebugsnag +import com.github.kittinunf.result.Result +import com.github.kittinunf.result.failure import com.google.common.truth.Truth.assertThat import flank.scripts.FuelTestRunner +import flank.scripts.exceptions.BugsnagException import kotlinx.coroutines.runBlocking import org.junit.Test -import com.github.kittinunf.result.Result -import com.github.kittinunf.result.failure -import flank.scripts.exceptions.BugsnagException import org.junit.runner.RunWith @RunWith(FuelTestRunner::class) From ba5c281fd51bb6399dd4fda178811c4352d1ccb4 Mon Sep 17 00:00:00 2001 From: Piotr Adamczyk Date: Thu, 6 Aug 2020 16:39:25 +0200 Subject: [PATCH 4/4] Workflow paths changes --- .github/workflows/flank-scripts-macos_workflow.yml | 4 ++-- .github/workflows/macos_workflow.yml | 2 ++ .github/workflows/ubuntu-workflow.yml | 2 ++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/flank-scripts-macos_workflow.yml b/.github/workflows/flank-scripts-macos_workflow.yml index 8d48f9a13e..78423bb097 100644 --- a/.github/workflows/flank-scripts-macos_workflow.yml +++ b/.github/workflows/flank-scripts-macos_workflow.yml @@ -6,8 +6,8 @@ on: - master pull_request: branches: [master] - path: - - /flank-scripts/** + paths: + - flank-scripts/** jobs: build: diff --git a/.github/workflows/macos_workflow.yml b/.github/workflows/macos_workflow.yml index d2f5401f32..2527d50a36 100644 --- a/.github/workflows/macos_workflow.yml +++ b/.github/workflows/macos_workflow.yml @@ -7,6 +7,8 @@ on: pull_request: branches: - '*' + paths: + - '!flank-scripts/**' jobs: build: diff --git a/.github/workflows/ubuntu-workflow.yml b/.github/workflows/ubuntu-workflow.yml index e4e4497e46..78b9eb8f9e 100644 --- a/.github/workflows/ubuntu-workflow.yml +++ b/.github/workflows/ubuntu-workflow.yml @@ -7,6 +7,8 @@ on: pull_request: branches: - '*' + paths: + - '!flank-scripts/**' jobs: build: