Skip to content

Commit

Permalink
fix: TestSqlAnnotationHandler fails if context stopped in test (#951)
Browse files Browse the repository at this point in the history
* fix: TestSqlAnnotationHandler fails if context stopped in test

The TestSqlAnnotationHandler tried to load a ResourceLoader bean even if there were no Sql annotations.
This fails if the context has been stopped in the test.

This PR does 2 things:

1. It only tries to load the bean if it has work to do
2. If it has work to do, and the context is stopped, it logs a warning and skips processing the scripts

Co-authored-by: Phil Hardwick <[email protected]>

* Add test with Sql annotations

---------

Co-authored-by: Phil Hardwick <[email protected]>
  • Loading branch information
timyates and PhilHardwick authored Feb 15, 2024
1 parent 19f84e3 commit 889dd61
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 17 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2017-2023 original authors
* Copyright 2017-2024 original authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -63,27 +63,37 @@ private TestSqlAnnotationHandler() {
* @throws IOException If an error occurs reading the SQL
*/
public static void handle(BeanDefinition<?> specDefinition, ApplicationContext applicationContext, Sql.Phase phase) throws IOException {
ResourceLoader resourceLoader = applicationContext.getBean(ResourceLoader.class);
Optional<List<AnnotationValue<Sql>>> sqlAnnotations = specDefinition
.findAnnotation(Sql.Sqls.class)
.map(s -> s.getAnnotations("value", Sql.class));

if (sqlAnnotations.isPresent()) {
for (var sql : sqlAnnotations.get()) {
if (sql.getRequiredValue("phase", Sql.Phase.class) != phase) {
continue;
}
List<@NonNull String> scripts = Arrays.asList(sql.stringValues());
if (!scripts.isEmpty()) {
Consumer<String> proc = bean(
sql.getRequiredValue("resourceType", Class.class),
sql.getRequiredValue("dataSourceName", String.class),
applicationContext
);
handleScript(resourceLoader, scripts, proc, phase);
} else if (LOG.isTraceEnabled()) {
LOG.trace("No SQL scripts found for {} phase", phase);
if (!applicationContext.isRunning()) {
if (LOG.isWarnEnabled()) {
LOG.warn("Application context has been stopped, skipping SQL script annotations");
}
} else {
processAnnotations(applicationContext, phase, sqlAnnotations.get());
}
}
}

private static void processAnnotations(ApplicationContext applicationContext, Sql.Phase phase, List<AnnotationValue<Sql>> sqlAnnotations) throws IOException {
ResourceLoader resourceLoader = applicationContext.getBean(ResourceLoader.class);
for (var sql : sqlAnnotations) {
if (sql.getRequiredValue("phase", Sql.Phase.class) != phase) {
continue;
}
List<@NonNull String> scripts = Arrays.asList(sql.stringValues());
if (!scripts.isEmpty()) {
Consumer<String> proc = bean(
sql.getRequiredValue("resourceType", Class.class),
sql.getRequiredValue("dataSourceName", String.class),
applicationContext
);
handleScript(resourceLoader, scripts, proc, phase);
} else if (LOG.isTraceEnabled()) {
LOG.trace("No SQL scripts found for {} phase", phase);
}
}
}
Expand Down Expand Up @@ -111,5 +121,4 @@ private static void handleScript(ResourceLoader loader, List<String> scripts, Co
}
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package io.micronaut.test.junit5;

import io.micronaut.context.ApplicationContext;
import io.micronaut.runtime.EmbeddedApplication;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;

import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;

@MicronautTest
class ApplicationStopTest {

@Inject
private ApplicationContext applicationContext;

@Test
void stoppingTheContextDoesntCauseFailures() {
applicationContext.stop();
assertTrue(true);
// should not error
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package io.micronaut.test.junit5;

import io.micronaut.context.ApplicationContext;
import io.micronaut.context.annotation.Property;
import io.micronaut.test.annotation.Sql;
import io.micronaut.test.annotation.TransactionMode;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

@DbProperties
@MicronautTest(transactionMode = TransactionMode.SINGLE_TRANSACTION)
@Property(name = "datasources.default.dialect", value = "H2")
@Property(name = "datasources.default.driverClassName", value = "org.h2.Driver")
@Property(name = "datasources.default.schema-generate", value = "CREATE_DROP")
@Property(name = "datasources.default.url", value = "jdbc:h2:mem:devDb;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE")
@Property(name = "datasources.default.username", value = "sa")
@Sql({"classpath:create.sql", "classpath:datasource_1_insert.sql"}) // <1>
class SqlDatasourceApplicationStopTest {

@Inject
ApplicationContext applicationContext;

@Inject
DataSource dataSource;

@Test
void stoppingTheContextDoesntCauseFailures() throws Exception {
assertEquals(List.of("Aardvark", "Albatross"), readAllNames(dataSource));
applicationContext.stop();
assertTrue(true);
// should not error
}

List<String> readAllNames(DataSource dataSource) throws SQLException {
var result = new ArrayList<String>();
try (
Connection ds = dataSource.getConnection();
PreparedStatement ps = ds.prepareStatement("select name from MyTable");
ResultSet rslt = ps.executeQuery()
) {
while(rslt.next()) {
result.add(rslt.getString(1));
}
}
return result;
}
}

0 comments on commit 889dd61

Please sign in to comment.