Add data-jdbc-h2-kotlin smoke test

This commit is contained in:
Moritz Halbritter
2022-11-25 12:05:17 +01:00
parent 2c1897983d
commit 0d1e182dda
14 changed files with 280 additions and 0 deletions

View File

@@ -260,6 +260,12 @@ h|nativeTest
|image:https://ci.spring.io/api/v1/teams/spring-aot-smoke-tests/pipelines/spring-aot-smoke-tests-1.0.x/jobs/data-jdbc-h2-test/badge[link=https://ci.spring.io/teams/spring-aot-smoke-tests/pipelines/spring-aot-smoke-tests-1.0.x/jobs/data-jdbc-h2-test]
|image:https://ci.spring.io/api/v1/teams/spring-aot-smoke-tests/pipelines/spring-aot-smoke-tests-1.0.x/jobs/data-jdbc-h2-native-test/badge[link=https://ci.spring.io/teams/spring-aot-smoke-tests/pipelines/spring-aot-smoke-tests-1.0.x/jobs/data-jdbc-h2-native-test]
|data-jdbc-h2-kotlin
|image:https://ci.spring.io/api/v1/teams/spring-aot-smoke-tests/pipelines/spring-aot-smoke-tests-1.0.x/jobs/data-jdbc-h2-kotlin-app-test/badge[link=https://ci.spring.io/teams/spring-aot-smoke-tests/pipelines/spring-aot-smoke-tests-1.0.x/jobs/data-jdbc-h2-kotlin-app-test]
|image:https://ci.spring.io/api/v1/teams/spring-aot-smoke-tests/pipelines/spring-aot-smoke-tests-1.0.x/jobs/data-jdbc-h2-kotlin-native-app-test/badge[link=https://ci.spring.io/teams/spring-aot-smoke-tests/pipelines/spring-aot-smoke-tests-1.0.x/jobs/data-jdbc-h2-kotlin-native-app-test]
|image:https://ci.spring.io/api/v1/teams/spring-aot-smoke-tests/pipelines/spring-aot-smoke-tests-1.0.x/jobs/data-jdbc-h2-kotlin-test/badge[link=https://ci.spring.io/teams/spring-aot-smoke-tests/pipelines/spring-aot-smoke-tests-1.0.x/jobs/data-jdbc-h2-kotlin-test]
|image:https://ci.spring.io/api/v1/teams/spring-aot-smoke-tests/pipelines/spring-aot-smoke-tests-1.0.x/jobs/data-jdbc-h2-kotlin-native-test/badge[link=https://ci.spring.io/teams/spring-aot-smoke-tests/pipelines/spring-aot-smoke-tests-1.0.x/jobs/data-jdbc-h2-kotlin-native-test]
|data-jdbc-postgresql
|image:https://ci.spring.io/api/v1/teams/spring-aot-smoke-tests/pipelines/spring-aot-smoke-tests-1.0.x/jobs/data-jdbc-postgresql-app-test/badge[link=https://ci.spring.io/teams/spring-aot-smoke-tests/pipelines/spring-aot-smoke-tests-1.0.x/jobs/data-jdbc-postgresql-app-test]
|image:https://ci.spring.io/api/v1/teams/spring-aot-smoke-tests/pipelines/spring-aot-smoke-tests-1.0.x/jobs/data-jdbc-postgresql-native-app-test/badge[link=https://ci.spring.io/teams/spring-aot-smoke-tests/pipelines/spring-aot-smoke-tests-1.0.x/jobs/data-jdbc-postgresql-native-app-test]

View File

@@ -124,6 +124,9 @@ groups:
- name: data-jdbc-h2
app_test: true
test: true
- name: data-jdbc-h2-kotlin
app_test: true
test: true
- name: data-jdbc-postgresql
app_test: true
test: false

View File

@@ -0,0 +1 @@
Tests if Spring Data JDBC with the H2 database using Kotlin works

View File

@@ -0,0 +1,21 @@
plugins {
id 'java'
id 'org.springframework.boot'
id 'org.springframework.aot.smoke-test'
id 'org.graalvm.buildtools.native'
id 'org.jetbrains.kotlin.jvm'
id 'org.jetbrains.kotlin.plugin.spring' version "$kotlinVersion"
}
dependencies {
implementation(platform(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES))
implementation("org.springframework.boot:spring-boot-starter-data-jdbc")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
runtimeOnly("com.h2database:h2")
testImplementation("org.springframework.boot:spring-boot-starter-test")
appTestImplementation(project(":aot-smoke-test-support"))
appTestImplementation("org.awaitility:awaitility:4.2.0")
}

View File

@@ -0,0 +1,66 @@
package com.example.data.jdbc.h2;
import java.time.Duration;
import org.awaitility.Awaitility;
import org.junit.jupiter.api.Test;
import org.springframework.aot.smoketest.support.assertj.AssertableOutput;
import org.springframework.aot.smoketest.support.junit.ApplicationTest;
import static org.assertj.core.api.Assertions.assertThat;
@ApplicationTest
class DataJdbcH2ApplicationAotTests {
@Test
void insert(AssertableOutput output) {
Awaitility.await().atMost(Duration.ofSeconds(10)).untilAsserted(() -> {
assertThat(output).hasSingleLineContaining("insertAuthors(): author1 = Author(name='Josh Long')")
.hasSingleLineContaining("insertAuthors(): author2 = Author(name='Martin Kleppmann')");
});
}
@Test
void listAllAuthors(AssertableOutput output) {
Awaitility.await().atMost(Duration.ofSeconds(10)).untilAsserted(() -> {
assertThat(output).hasSingleLineContaining("listAllAuthors(): author = Author(name='Josh Long')")
.hasSingleLineContaining("Book(title='Cloud Native Java')")
.hasSingleLineContaining("Book(title='Reactive Spring')")
.hasSingleLineContaining("listAllAuthors(): author = Author(name='Martin Kleppmann')")
.hasSingleLineContaining("Book(title='Designing Data Intensive Applications')");
});
}
@Test
void findById(AssertableOutput output) {
Awaitility.await().atMost(Duration.ofSeconds(10)).untilAsserted(() -> {
assertThat(output).hasSingleLineContaining("findById(): author1 = Author(name='Josh Long')")
.hasSingleLineContaining("findById(): author2 = Author(name='Martin Kleppmann')");
});
}
@Test
void queryDerivedFromMethodName(AssertableOutput output) {
Awaitility.await().atMost(Duration.ofSeconds(10)).untilAsserted(() -> {
assertThat(output).hasSingleLineContaining("findByPartialName(): author1 = Author(name='Josh Long')")
.hasSingleLineContaining("findByPartialName(): author2 = Author(name='Martin Kleppmann')");
});
}
@Test
void queryAnnotatedMethod(AssertableOutput output) {
Awaitility.await().atMost(Duration.ofSeconds(10)).untilAsserted(() -> {
assertThat(output).hasSingleLineContaining("queryFindByName(): author1 = Author(name='Josh Long')")
.hasSingleLineContaining("queryFindByName(): author2 = Author(name='Martin Kleppmann')");
});
}
@Test
void deleteAll(AssertableOutput output) {
Awaitility.await().atMost(Duration.ofSeconds(10)).untilAsserted(() -> {
assertThat(output).hasSingleLineContaining("deleteAll(): count = 0");
});
}
}

View File

@@ -0,0 +1,13 @@
package com.example.data.jdbc.h2.kotlin
import com.example.data.jdbc.h2.kotlin.model.Author
import org.springframework.data.jdbc.repository.query.Query
import org.springframework.data.repository.ListCrudRepository
import java.util.*
interface AuthorRepository : ListCrudRepository<Author, Long> {
fun findByNameContainingIgnoreCase(partialName: String): Author?
@Query("SELECT * FROM author a WHERE a.name = :name LIMIT 1")
fun queryFindByName(name: String): Author?
}

View File

@@ -0,0 +1,75 @@
package com.example.data.jdbc.h2.kotlin
import com.example.data.jdbc.h2.kotlin.model.Author
import com.example.data.jdbc.h2.kotlin.model.Book
import org.springframework.boot.CommandLineRunner
import org.springframework.stereotype.Component
@Component
class CLR(private val authorRepository: AuthorRepository) : CommandLineRunner {
override fun run(vararg args: String) {
insertAuthors()
listAllAuthors()
findById()
findByPartialName()
queryFindByName()
deleteAll()
}
private fun deleteAll() {
authorRepository.deleteAll()
val count = authorRepository.count()
System.out.printf("deleteAll(): count = %d%n", count)
}
private fun queryFindByName() {
val author1 = authorRepository.queryFindByName("Josh Long")
val author2 = authorRepository.queryFindByName("Martin Kleppmann")
System.out.printf("queryFindByName(): author1 = %s%n", author1)
System.out.printf("queryFindByName(): author2 = %s%n", author2)
}
private fun findByPartialName() {
val author1 =
authorRepository.findByNameContainingIgnoreCase("sh lo")
val author2 =
authorRepository.findByNameContainingIgnoreCase("in kl")
System.out.printf("findByPartialName(): author1 = %s%n", author1)
System.out.printf("findByPartialName(): author2 = %s%n", author2)
}
private fun findById() {
val author1 = authorRepository.findById(1L).orElse(null)
val author2 = authorRepository.findById(2L).orElse(null)
System.out.printf("findById(): author1 = %s%n", author1)
System.out.printf("findById(): author2 = %s%n", author2)
}
private fun listAllAuthors() {
val authors = authorRepository.findAll()
for (author in authors) {
System.out.printf("listAllAuthors(): author = %s%n", author)
for (book in author.books) {
System.out.printf("\t%s%n", book)
}
}
}
private fun insertAuthors() {
val author1 = authorRepository.save(
Author(
null, "Josh Long",
setOf(Book(null, "Reactive Spring"), Book(null, "Cloud Native Java"))
)
)
val author2 = authorRepository.save(
Author(
null,
"Martin Kleppmann",
setOf(Book(null, "Designing Data Intensive Applications"))
)
)
System.out.printf("insertAuthors(): author1 = %s%n", author1)
System.out.printf("insertAuthors(): author2 = %s%n", author2)
}
}

View File

@@ -0,0 +1,8 @@
package com.example.data.jdbc.h2.kotlin
import org.springframework.context.annotation.Configuration
import org.springframework.data.jdbc.repository.config.EnableJdbcRepositories
@Configuration
@EnableJdbcRepositories
class DataJdbcConfiguration

View File

@@ -0,0 +1,11 @@
package com.example.data.jdbc.h2.kotlin
import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.SpringBootApplication
@SpringBootApplication
class DataJdbcH2Application
fun main(args: Array<String>) {
SpringApplication.run(DataJdbcH2Application::class.java, *args)
}

View File

@@ -0,0 +1,13 @@
package com.example.data.jdbc.h2.kotlin.model
import org.springframework.data.annotation.Id
data class Author(
@Id val id: Long?,
val name: String,
val books: Set<Book>
) {
override fun toString(): String {
return "Author(name='$name')"
}
}

View File

@@ -0,0 +1,12 @@
package com.example.data.jdbc.h2.kotlin.model
import org.springframework.data.annotation.Id
data class Book(
@Id val id: Long?,
val title: String
) {
override fun toString(): String {
return "Book(title='$title')"
}
}

View File

@@ -0,0 +1,12 @@
create table author
(
id bigint auto_increment primary key,
name varchar not null
);
create table book
(
id bigint auto_increment primary key,
author bigint not null references author (id),
title varchar not null
);

View File

@@ -0,0 +1,39 @@
package com.example.data.jdbc.h2.kotlin
import com.example.data.jdbc.h2.kotlin.model.Author
import com.example.data.jdbc.h2.kotlin.model.Book
import org.assertj.core.api.Assertions
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.data.jdbc.DataJdbcTest
import org.springframework.jdbc.core.JdbcTemplate
import java.util.Set
@DataJdbcTest
class DataJdbcTests {
@Autowired
private lateinit var jdbcTemplate: JdbcTemplate
@Autowired
private lateinit var authorRepository: AuthorRepository
@Test
fun shouldHaveSchema() {
Assertions.assertThatCode { jdbcTemplate.execute("SELECT * FROM author") }
.doesNotThrowAnyException()
}
@Test
fun shouldSaveAndLoad() {
val book1 = Book(null, "book-1")
val author1 = Author(null, "author-1", Set.of(book1))
authorRepository.save(author1)
val found = authorRepository.queryFindByName("author-1")
assertThat(found).isNotNull()
checkNotNull(found)
assertThat(found.id).isNotNull()
assertThat(found.name).isEqualTo("author-1")
assertThat(found.books).hasSize(1)
}
}