Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Logging framework #646

Merged
merged 4 commits into from
Mar 5, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions test_runner/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,8 @@ dependencies {

implementation(Libs.WOODSTOX)

implementation(Libs.KOTLIN_LOGGING)

// NOTE: iOS support isn't in the public artifact. Use testing jar generated from the private gcloud CLI json
// https://search.maven.org/#search%7Cga%7C1%7Cg%3A%22com.google.apis%22%20AND%20a%3A%22google-api-services-testing%22
// compile("com.google.apis:google-api-services-testing:v1-rev30-1.23.0")
Expand Down
4 changes: 4 additions & 0 deletions test_runner/buildSrc/src/main/kotlin/Deps.kt
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ object Versions {

// https://github.com/FasterXML/woodstox/releases
const val WOODSTOX = "6.0.1"

const val KOTLIN_LOGGING = "1.7.8"
}

object Libs {
Expand Down Expand Up @@ -99,6 +101,8 @@ object Libs {

const val WOODSTOX = "com.fasterxml.woodstox:woodstox-core:${Versions.WOODSTOX}"

const val KOTLIN_LOGGING = "io.github.microutils:kotlin-logging:${Versions.KOTLIN_LOGGING}"

//region Plugins
const val DETEKT_FORMATTING ="io.gitlab.arturbosch.detekt:detekt-formatting:${Versions.DETEKT}"
//endregion
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,26 @@
package com.google.api.client.http

import com.google.auth.oauth2.ComputeEngineCredentials
import ftl.log.FlankLogger
import java.util.logging.Level
import java.util.logging.Logger
import java.util.logging.SimpleFormatter
import java.util.logging.StreamHandler
import kotlin.properties.Delegates

// Used to enable cURL logging of the Java client API requests.
//
// Compare with gcloud sdk traffic by using the --log-http flag
//
// gcloud alpha firebase test ios models list --log-http
//
object GoogleApiLogger {
fun logAllToStdout() {
object GoogleApiLogger : FlankLogger {

override var isEnabled: Boolean by Delegates.observable(false) { _, _, enable ->
if (enable) logAllToStdout()
}

private fun logAllToStdout() {
val logger = HttpTransport.LOGGER
logger.level = Level.ALL

Expand Down
7 changes: 7 additions & 0 deletions test_runner/src/main/kotlin/ftl/Main.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import ftl.cli.firebase.CancelCommand
import ftl.cli.firebase.RefreshCommand
import ftl.cli.firebase.test.AndroidCommand
import ftl.cli.firebase.test.IosCommand
import ftl.log.setDebugLogging
import ftl.util.Utils.readRevision
import ftl.util.Utils.readVersion
import picocli.CommandLine
Expand Down Expand Up @@ -35,6 +36,12 @@ class Main : Runnable {
@CommandLine.Option(names = ["-v", "--version"], description = ["Prints the version"])
private var printVersion = false

@CommandLine.Option(
names = ["--debug"],
description = ["Enables debug logging"]
)
fun debug(enabled: Boolean) = setDebugLogging(enabled)

companion object {
@JvmStatic
fun main(args: Array<String>) {
Expand Down
4 changes: 0 additions & 4 deletions test_runner/src/main/kotlin/ftl/config/FtlConstants.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package ftl.config

import ch.qos.logback.classic.Level
import ch.qos.logback.classic.Logger
import com.bugsnag.Bugsnag
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport
import com.google.api.client.googleapis.util.Utils
Expand All @@ -23,7 +21,6 @@ import java.io.IOException
import java.nio.file.Path
import java.nio.file.Paths
import java.util.Date
import org.slf4j.LoggerFactory

object FtlConstants {
var useMock = false
Expand Down Expand Up @@ -60,7 +57,6 @@ object FtlConstants {

init {
bugsnag.setAppVersion(readRevision())
(LoggerFactory.getLogger(Bugsnag::class.java) as Logger).level = Level.OFF
}

val httpTransport: NetHttpTransport by lazy {
Expand Down
12 changes: 1 addition & 11 deletions test_runner/src/main/kotlin/ftl/gc/UserAuth.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package ftl.gc

import ch.qos.logback.classic.Level
import ch.qos.logback.classic.Logger
import com.google.auth.oauth2.ClientId
import com.google.auth.oauth2.MemoryTokensStorage
import com.google.auth.oauth2.UserAuthorizer
Expand All @@ -23,13 +21,12 @@ import java.nio.file.Paths
import java.util.concurrent.TimeUnit
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
import org.slf4j.LoggerFactory

class UserAuth {

companion object {
private val home = System.getProperty("user.home")!!
private val dotFlank = Paths.get(home, ".flank/")!!
private val dotFlank = Paths.get(home, ".flank/")
val userToken: Path = Paths.get(dotFlank.toString(), "UserToken")

fun exists() = userToken.toFile().exists()
Expand All @@ -40,13 +37,6 @@ class UserAuth {
}
}

// Silence Jetty logging.
private val logger = LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME) as Logger

init {
logger.level = Level.OFF
}

private var waitingForUserAuth = true

private val server = embeddedServer(Netty, 8085) {
Expand Down
5 changes: 5 additions & 0 deletions test_runner/src/main/kotlin/ftl/log/FlankLogger.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package ftl.log

interface FlankLogger {
var isEnabled: Boolean
}
20 changes: 20 additions & 0 deletions test_runner/src/main/kotlin/ftl/log/LogbackLogger.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package ftl.log

import ch.qos.logback.classic.Level
import ch.qos.logback.classic.Logger
import org.slf4j.LoggerFactory.getLogger
import kotlin.properties.Delegates

sealed class LogbackLogger(private val logger: Logger) : FlankLogger {

constructor(logger: Any) : this(logger as Logger)

override var isEnabled: Boolean by Delegates.observable(false) { _, _, enable ->
logger.level = if (enable)
Level.ALL else
Level.OFF
}

object Root : LogbackLogger(getLogger(Logger.ROOT_LOGGER_NAME))
object Bugsnag : LogbackLogger(getLogger(Bugsnag::class.java))
}
13 changes: 13 additions & 0 deletions test_runner/src/main/kotlin/ftl/log/Loggers.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package ftl.log

import com.google.api.client.http.GoogleApiLogger

private val LOGGERS = listOf(
LogbackLogger.Root,
LogbackLogger.Bugsnag,
GoogleApiLogger
)

fun setDebugLogging(enable: Boolean) = LOGGERS.forEach { logger ->
logger.isEnabled = enable
}
13 changes: 5 additions & 8 deletions test_runner/src/main/kotlin/ftl/mock/MockServer.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package ftl.mock

import ch.qos.logback.classic.Level
import ch.qos.logback.classic.Logger
import com.google.api.services.testing.model.AndroidDevice
import com.google.api.services.testing.model.AndroidDeviceCatalog
import com.google.api.services.testing.model.Environment
Expand All @@ -27,6 +25,7 @@ import com.google.gson.GsonBuilder
import com.google.gson.LongSerializationPolicy
import ftl.config.FtlConstants
import ftl.config.FtlConstants.JSON_FACTORY
import ftl.log.LogbackLogger
import ftl.util.Bash
import ftl.util.StepOutcome.failure
import ftl.util.StepOutcome.inconclusive
Expand All @@ -47,20 +46,14 @@ import io.ktor.server.netty.Netty
import java.nio.file.Files
import java.nio.file.Paths
import java.util.concurrent.atomic.AtomicInteger
import org.slf4j.LoggerFactory.getLogger
import java.net.BindException

object MockServer {

private val matrixIdCounter: AtomicInteger = AtomicInteger(0)
const val port = 8080
private val logger = getLogger(Logger.ROOT_LOGGER_NAME) as Logger
private var isStarted: Boolean = false

init {
logger.level = Level.OFF
}

private inline fun <reified T> loadCatalog(fileName: String): T {
val jsonPath = Paths.get("./src/test/kotlin/ftl/fixtures/$fileName")
if (!jsonPath.toFile().exists()) throw RuntimeException("Path doesn't exist: $fileName")
Expand Down Expand Up @@ -246,6 +239,9 @@ object MockServer {

fun start() {
if (isStarted) return
val loggingEnabled = LogbackLogger.Root.isEnabled
// Disable mock server initialization logs
LogbackLogger.Root.isEnabled = false
val server = application
try {
server.start(wait = false)
Expand All @@ -256,6 +252,7 @@ object MockServer {
Thread.sleep(2000)
server.start(wait = false)
}
LogbackLogger.Root.isEnabled = loggingEnabled
isStarted = true
FtlConstants.useMock = true
TestArtifact.checkFixtures
Expand Down
5 changes: 3 additions & 2 deletions test_runner/src/test/kotlin/Debug.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@ fun main() {
// run "gradle check" to generate required fixtures
val projectId = System.getenv("FLANK_PROJECT_ID")
?: "YOUR PROJECT ID"
val quantity = "multiple"
val quantity = "single"
val type = "success"

CommandLine(Main()).execute(
"--debug",
"firebase", "test",
"android", "run",
"--dry",
// "--dry",
"-c=src/test/kotlin/ftl/fixtures/test_app_cases/flank-$quantity-$type.yml",
"--project=$projectId"
)
Expand Down
29 changes: 23 additions & 6 deletions test_runner/src/test/kotlin/ftl/MainTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ class MainTest {
private fun assertMainHelpStrings(output: String) {
assertThat(output.normalizeLineEnding()).contains(
"flank.jar\n" +
" [-v] [COMMAND]\n" +
" [-v] [--debug] [COMMAND]\n" +
" --debug Enables debug logging\n" +
" -v, --version Prints the version\n" +
"Commands:\n" +
" firebase\n" +
Expand All @@ -40,11 +41,26 @@ class MainTest {
return systemOutRule.log.normalizeLineEnding() + systemErrRule.log.normalizeLineEnding()
}

private fun unknownOption(option: String) = "Unknown option: '$option'"

@Test
fun mainCLIVersionCommand() {
fun mainCLIVersionOption() {
val option = "-v"
assertThat(
runCommand("-v")
).isNotEmpty()
runCommand(option)
).doesNotContain(
unknownOption(option)
)
}

@Test
fun mainCLIDebugOption() {
val option = "--debug"
assertThat(
runCommand(option)
).doesNotContain(
unknownOption(option)
)
}

@Test
Expand All @@ -54,8 +70,9 @@ class MainTest {

@Test
fun mainCLIErrorsOnUnknownFlag() {
val output = runCommand("-unknown-flag")
assertThat(output).contains("Unknown option: '-unknown-flag'")
val option = "-unknown-flag"
val output = runCommand(option)
assertThat(output).contains(unknownOption(option))
assertMainHelpStrings(output)
}

Expand Down