Add smoke tests for data-jdbc.

This commit is contained in:
Christoph Strobl
2023-09-22 10:47:04 +02:00
parent 888b9e0c02
commit 783d97531d
10 changed files with 279 additions and 0 deletions

View File

@@ -0,0 +1 @@
Tests if Spring Data JDBC with HikariCP is working.

View File

@@ -0,0 +1,24 @@
plugins {
id "java"
id "org.springframework.boot"
id "org.springframework.cr.smoke-test"
}
dependencies {
implementation(platform(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES))
implementation("org.springframework.boot:spring-boot-starter-data-jdbc")
implementation("org.crac:crac:$cracVersion")
implementation(project(":cr-listener"))
runtimeOnly("org.postgresql:postgresql")
testImplementation("org.springframework.boot:spring-boot-starter-test")
appTestImplementation(project(":cr-smoke-test-support"))
appTestImplementation("org.awaitility:awaitility:4.2.0")
}
crSmokeTest {
webApplication = false
}

View File

@@ -0,0 +1,7 @@
services:
postgres:
image: 'postgres:14'
environment:
- 'POSTGRES_PASSWORD=password'
ports:
- '5432'

View File

@@ -0,0 +1,38 @@
/*
* Copyright 2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.data.jdbc;
import static org.assertj.core.api.Assertions.*;
import java.time.Duration;
import org.awaitility.Awaitility;
import org.junit.jupiter.api.Test;
import org.springframework.cr.smoketest.support.assertj.AssertableOutput;
import org.springframework.cr.smoketest.support.junit.ApplicationTest;
@ApplicationTest
public class DataJdbcApplicationTests {
@Test
void connectionTest(AssertableOutput output) {
Awaitility.await().atMost(Duration.ofSeconds(10)).untilAsserted(() -> {
assertThat(output).hasLineMatching("Starting DataReader: was (INITIALIZED|STOPPED)");
assertThat(output).hasLineMatching("count \\d+: Author\\{id=\\d, name='.*'}");
});
}
}

View File

@@ -0,0 +1,45 @@
/*
* Copyright 2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.data.jdbc;
import org.springframework.data.annotation.Id;
public class Author {
@Id
private final Long id;
private final String name;
public Author(Long id, String name) {
this.id = id;
this.name = name;
}
public Long getId() {
return id;
}
public String getName() {
return name;
}
@Override
public String toString() {
return "Author{" + "id=" + id + ", name='" + name + '\'' + '}';
}
}

View File

@@ -0,0 +1,22 @@
/*
* Copyright 2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.data.jdbc;
import org.springframework.data.repository.ListCrudRepository;
public interface AuthorRepository extends ListCrudRepository<Author, Long> {
}

View File

@@ -0,0 +1,28 @@
/*
* Copyright 2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.data.jdbc;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DataJdbcApplication {
public static void main(String[] args) throws InterruptedException {
SpringApplication.run(DataJdbcApplication.class, args);
}
}

View File

@@ -0,0 +1,104 @@
/*
* Copyright 2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.data.jdbc;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.SmartLifecycle;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
@Component
@EnableScheduling
class DataReader implements SmartLifecycle {
private final Object lifecycleMonitor = new Object();
private final AtomicInteger counter = new AtomicInteger(0);
private State state = State.INITIALIZED;
private List<Long> authorIds;
@Autowired
private AuthorRepository authorRepository;
enum State {
INITIALIZED, STARTED, STOPPED
}
@Override
public void start() {
synchronized (lifecycleMonitor) {
switch (state) {
case INITIALIZED, STOPPED -> {
System.out.printf("Starting DataReader: was %s\n", state);
if (ObjectUtils.isEmpty(authorIds)) {
authorIds = insertAuthors().stream().map(Author::getId).collect(Collectors.toList());
}
state = State.STARTED;
}
}
}
}
@Scheduled(fixedDelay = 1000)
public void scheduled() {
if (isRunning()) {
int count = counter.incrementAndGet();
Author author = authorRepository.findById(authorIds.get(count % 3)).orElse(null);
System.out.printf("count %03d: %s\n", count, author);
}
}
@Override
public void stop() {
synchronized (lifecycleMonitor) {
switch (state) {
case INITIALIZED, STARTED -> {
System.out.printf("Stopping DataReader: was %s\n", state);
state = State.STOPPED;
}
}
}
}
@Override
public boolean isRunning() {
synchronized (lifecycleMonitor) {
return State.STARTED.equals(state);
}
}
private List<Author> insertAuthors() {
return authorRepository.saveAll(List.of(new Author(null, "Brandon Sanderson"), //
new Author(null, "Brent Weeks"), //
new Author(null, "Peter V. Brett")));
}
}

View File

@@ -0,0 +1,5 @@
spring.sql.init.mode=always
spring.datasource.url=jdbc:postgresql://${POSTGRES_HOST:localhost}:${POSTGRES_PORT_5432:5432}/postgres
spring.datasource.username=postgres
spring.datasource.password=password
spring.datasource.hikari.allow-pool-suspension=true

View File

@@ -0,0 +1,5 @@
create table author
(
id integer PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
name varchar NOT NULL
);