Add smoke test for hibernate using MySQL driver and HikariCP

Closes gh-3
This commit is contained in:
Christoph Strobl
2023-07-26 14:42:59 +02:00
committed by Sébastien Deleuze
parent 1856ffa97d
commit 55011df1b2
9 changed files with 354 additions and 0 deletions

View File

@@ -0,0 +1 @@
Tests if Hibernate with MySQL & HikariCP is working.

View File

@@ -0,0 +1,27 @@
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-jdbc")
implementation("org.springframework:spring-orm")
implementation("jakarta.persistence:jakarta.persistence-api")
implementation("org.hibernate.orm:hibernate-core")
implementation("org.crac:crac:$cracVersion")
implementation(project(":cr-listener"))
runtimeOnly("com.mysql:mysql-connector-j")
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,10 @@
version: '3.1'
services:
mysql:
image: 'mysql/mysql-server:8.0'
environment:
- 'MYSQL_DATABASE=test'
- 'MYSQL_USER=mysql'
- 'MYSQL_PASSWORD=password'
ports:
- '3306'

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.hibernate;
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 HibernateApplicationTests {
@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,79 @@
/*
* 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.hibernate;
import java.util.Objects;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
@Entity
public class Author {
@Id
@GeneratedValue
private Integer id;
private String name;
protected Author() {
}
public Author(Integer id, String name) {
this.id = id;
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Author author = (Author) o;
return Objects.equals(id, author.id) && Objects.equals(name, author.name);
}
@Override
public int hashCode() {
return Objects.hash(id, name);
}
@Override
public String toString() {
return "Author{" + "id=" + id + ", name='" + name + '\'' + '}';
}
}

View File

@@ -0,0 +1,121 @@
/*
* 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.hibernate;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.transaction.Transactional;
import org.hibernate.Session;
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
@Transactional
@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<Integer> authorIds;
@PersistenceContext
private EntityManager entityManager;
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 = entityManager.find(Author.class, authorIds.get(count % 3));
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() {
return State.STARTED.equals(state);
}
private List<Author> insertAuthors() {
Author brandonSanderson = new Author(null, "Brandon Sanderson");
Author brentWeeks = new Author(null, "Brent Weeks");
Author peterVBrett = new Author(null, "Peter V. Brett");
entityManager.persist(brandonSanderson);
entityManager.persist(brentWeeks);
entityManager.persist(peterVBrett);
entityManager.flush();
entityManager.getEntityManagerFactory().getCache().evictAll();
Session session = entityManager.unwrap(Session.class);
if (session != null) {
session.clear(); // internal cache clear
}
return List.of(brandonSanderson, brentWeeks, peterVBrett);
}
}

View File

@@ -0,0 +1,30 @@
/*
* 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.hibernate;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@SpringBootApplication
@EnableTransactionManagement
public class HibernateApplication {
public static void main(String[] args) throws InterruptedException {
SpringApplication.run(HibernateApplication.class, args);
}
}

View File

@@ -0,0 +1,7 @@
spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect
spring.jpa.hibernate.ddl-auto=create
spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:${MYSQL_PORT_3306:3306}/test
spring.datasource.username=mysql
spring.datasource.password=password
spring.datasource.hikari.allow-pool-suspension=true

View File

@@ -0,0 +1,41 @@
/*
* 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.hibernate;
import static org.assertj.core.api.Assertions.*;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.persistence.Query;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.transaction.annotation.Transactional;
@Transactional
@SpringBootTest
class ApplicationTestes {
@PersistenceContext
EntityManager entityManager;
@Test
void canQueryAuthors() {
Query query = entityManager.createQuery("SELECT author.id, author.name FROM Author author");
assertThat(query.getResultList()).isNotEmpty();
}
}