Skip to content

Commit b4f8fbc

Browse files
committed
Added ktorm listener
1 parent b782b29 commit b4f8fbc

File tree

8 files changed

+427
-1
lines changed

8 files changed

+427
-1
lines changed

allure-ktorm/build.gradle.kts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
description = "Allure Ktorm Integration"
2+
3+
plugins {
4+
id("org.jetbrains.kotlin.jvm") version "1.4.31"
5+
}
6+
apply(plugin = "kotlin")
7+
8+
val agent: Configuration by configurations.creating
9+
10+
val ktormVersion = "3.3.0"
11+
val assertK = "0.23.1"
12+
val h2 = "1.4.197"
13+
14+
dependencies {
15+
agent("org.aspectj:aspectjweaver")
16+
api(project(":allure-attachments"))
17+
18+
implementation("org.ktorm:ktorm-core:$ktormVersion")
19+
20+
testImplementation("com.h2database:h2:$h2")
21+
22+
testImplementation("com.willowtreeapps.assertk:assertk-jvm:$assertK")
23+
testImplementation("org.junit.jupiter:junit-jupiter-api")
24+
testImplementation("org.mockito:mockito-core")
25+
testImplementation("org.slf4j:slf4j-simple")
26+
testImplementation(project(":allure-java-commons-test"))
27+
testImplementation(project(":allure-junit-platform"))
28+
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")
29+
}
30+
31+
tasks.jar {
32+
manifest {
33+
attributes(
34+
mapOf(
35+
"Automatic-Module-Name" to "io.qameta.allure.ktorm"
36+
)
37+
)
38+
}
39+
}
40+
41+
tasks.test {
42+
useJUnitPlatform()
43+
doFirst {
44+
jvmArgs("-javaagent:${agent.singleFile}")
45+
}
46+
}
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
/*
2+
* Copyright 2021 Qameta Software OÜ
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.qameta.allure.ktorm
17+
18+
import io.qameta.allure.Allure
19+
import io.qameta.allure.model.Status
20+
import io.qameta.allure.model.StepResult
21+
import org.ktorm.logging.Logger
22+
import java.util.UUID
23+
24+
/**
25+
* Allure logger for Ktorm.
26+
*
27+
* Create attachments with sql, parameters and results.
28+
* Unfortunately now we can't add parameters and results to created step.
29+
*
30+
* @author crazyMoonkin(Sergey Frolov)
31+
*
32+
* @property createSqlSteps enable creating steps
33+
*/
34+
class AllureKtormLogger(
35+
private val createSqlSteps: Boolean = false,
36+
private val attachParams: Boolean = true,
37+
private val attachResults: Boolean = true,
38+
) : Logger {
39+
40+
override fun isTraceEnabled(): Boolean = false
41+
42+
override fun trace(msg: String, e: Throwable?) {
43+
log(msg, e)
44+
}
45+
46+
override fun isDebugEnabled(): Boolean = true
47+
48+
override fun debug(msg: String, e: Throwable?) {
49+
log(msg, e)
50+
}
51+
52+
override fun isInfoEnabled(): Boolean = false
53+
54+
override fun info(msg: String, e: Throwable?) {
55+
log(msg, e)
56+
}
57+
58+
override fun isWarnEnabled(): Boolean = false
59+
60+
override fun warn(msg: String, e: Throwable?) {
61+
log(msg, e)
62+
}
63+
64+
override fun isErrorEnabled(): Boolean = true
65+
66+
override fun error(msg: String, e: Throwable?) {
67+
log(msg, e)
68+
}
69+
70+
private fun log(msg: String, e: Throwable?) {
71+
val typedMessage = msg.toTypedMessage()
72+
lateinit var stepUUID: String
73+
74+
if (createSqlSteps && typedMessage?.type == MessageType.SQL) {
75+
stepUUID = UUID.randomUUID().toString()
76+
createStep(stepUUID = stepUUID)
77+
}
78+
try {
79+
typedMessage?.let {
80+
when {
81+
typedMessage.type == MessageType.SQL
82+
|| typedMessage.type == MessageType.PARAMETERS && attachParams
83+
|| typedMessage.type == MessageType.RESULTS && attachResults -> {
84+
Allure.addAttachment(typedMessage.type.name, typedMessage.msg)
85+
}
86+
}
87+
}
88+
89+
} finally {
90+
if (createSqlSteps && typedMessage?.type == MessageType.SQL) {
91+
e?.let { Allure.getLifecycle().updateStep(stepUUID) { it.status = Status.FAILED } }
92+
Allure.getLifecycle().stopStep(stepUUID)
93+
}
94+
}
95+
}
96+
97+
private fun createStep(stepUUID: String) = Allure.getLifecycle().startStep(
98+
stepUUID,
99+
StepResult().apply {
100+
name = "Executed SQL query"
101+
status = Status.PASSED
102+
}
103+
)
104+
105+
/**
106+
* Split logged messages and convert it to TypedMessage
107+
* Logged messages is type and message separated by colon
108+
*/
109+
private fun String.toTypedMessage() = split(": ").takeIf { it.size == 2 }?.let { msgParts ->
110+
MessageType.values().firstOrNull { it.name == msgParts[0].toUpperCase() }?.let {
111+
TypedMessage(
112+
type = it,
113+
msg = msgParts[1]
114+
)
115+
}
116+
}
117+
118+
internal enum class MessageType {
119+
SQL,
120+
RESULTS,
121+
PARAMETERS,
122+
}
123+
124+
internal data class TypedMessage(val type: MessageType, val msg: String)
125+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Copyright 2021 Qameta Software OÜ
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.qameta.allure.ktorm
18+
19+
import assertk.assertThat
20+
import assertk.assertions.containsExactly
21+
import assertk.assertions.extracting
22+
import io.qameta.allure.model.Attachment
23+
import io.qameta.allure.model.TestResult
24+
import org.junit.jupiter.api.Test
25+
import org.ktorm.dsl.from
26+
import org.ktorm.dsl.insert
27+
import org.ktorm.dsl.select
28+
29+
internal class AllureKtormLoggerTest : BaseTest() {
30+
31+
@Test
32+
fun selectShouldCreateAttachments() {
33+
val results = execute(database.from(Departments).select()::rowSet)
34+
35+
assertThat(results.testResults.flatMap(TestResult::getAttachments))
36+
.extracting(Attachment::getName)
37+
.containsExactly("SQL", "PARAMETERS", "RESULTS")
38+
}
39+
40+
@Test
41+
fun insertShouldCreateAttachments() {
42+
val results = execute {
43+
database.insert(Departments) {
44+
set(it.name, "John")
45+
set(it.location, "Moscow")
46+
}
47+
}
48+
49+
assertThat(results.testResults.flatMap(TestResult::getAttachments))
50+
.extracting(Attachment::getName)
51+
.containsExactly("SQL", "PARAMETERS")
52+
}
53+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
* Copyright 2021 Qameta Software OÜ
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.qameta.allure.ktorm
17+
18+
import assertk.assertThat
19+
import assertk.assertions.containsExactly
20+
import assertk.assertions.extracting
21+
import io.qameta.allure.model.Attachment
22+
import io.qameta.allure.model.StepResult
23+
import io.qameta.allure.model.TestResult
24+
import org.junit.jupiter.api.BeforeEach
25+
import org.junit.jupiter.api.Test
26+
import org.ktorm.database.Database
27+
import org.ktorm.dsl.from
28+
import org.ktorm.dsl.insert
29+
import org.ktorm.dsl.select
30+
31+
internal class AllureKtormLoggerWithCreateStepsTest : BaseTest() {
32+
33+
@BeforeEach
34+
override fun setup() {
35+
database = Database.connect(
36+
url = "jdbc:h2:mem:ktorm;DB_CLOSE_DELAY=-1",
37+
driver = "org.h2.Driver",
38+
logger = AllureKtormLogger(createSqlSteps = true),
39+
alwaysQuoteIdentifiers = true
40+
)
41+
42+
execSqlScript("init-data.sql")
43+
}
44+
45+
@Test
46+
fun selectShouldCreateStepAndAttachments() {
47+
val results = execute(database.from(Departments).select()::rowSet)
48+
49+
assertThat(results.testResults.flatMap(TestResult::getSteps))
50+
.extracting(StepResult::getName)
51+
.containsExactly("Executed SQL query")
52+
53+
assertThat(results.testResults.flatMap(TestResult::getSteps).flatMap(StepResult::getAttachments))
54+
.extracting(Attachment::getName)
55+
.containsExactly("SQL")
56+
57+
assertThat(results.testResults.flatMap(TestResult::getAttachments))
58+
.extracting(Attachment::getName)
59+
.containsExactly("PARAMETERS", "RESULTS")
60+
}
61+
62+
@Test
63+
fun insertShouldCreateStepAndAttachments() {
64+
val results = execute {
65+
database.insert(Departments) {
66+
set(it.name, "John")
67+
set(it.location, "Moscow")
68+
}
69+
}
70+
71+
assertThat(results.testResults.flatMap(TestResult::getSteps))
72+
.extracting(StepResult::getName)
73+
.containsExactly("Executed SQL query")
74+
75+
assertThat(results.testResults.flatMap(TestResult::getSteps).flatMap(StepResult::getAttachments))
76+
.extracting(Attachment::getName)
77+
.containsExactly("SQL")
78+
79+
assertThat(results.testResults.flatMap(TestResult::getAttachments))
80+
.extracting(Attachment::getName)
81+
.containsExactly("PARAMETERS")
82+
}
83+
}

0 commit comments

Comments
 (0)