Skip to content

Commit e071ac9

Browse files
authored
Add schema management (flyway) (jenkinsci#6)
1 parent 398bd42 commit e071ac9

File tree

6 files changed

+66
-23
lines changed

6 files changed

+66
-23
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@ work
1313
.settings
1414
.classpath
1515
.project
16+
jmh-report.json

pom.xml

+5
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@
6060
<artifactId>database</artifactId>
6161
<version>1.7</version>
6262
</dependency>
63+
<dependency>
64+
<groupId>org.flywaydb</groupId>
65+
<artifactId>flyway-core</artifactId>
66+
<version>6.5.6</version>
67+
</dependency>
6368
<dependency>
6469
<groupId>org.jenkins-ci.plugins</groupId>
6570
<artifactId>database-postgresql</artifactId>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package io.jenkins.plugins.junit.storage.database;
2+
3+
import hudson.init.Initializer;
4+
import io.jenkins.plugins.junit.storage.JunitTestResultStorageConfiguration;
5+
import java.sql.SQLException;
6+
import javax.sql.DataSource;
7+
import org.flywaydb.core.Flyway;
8+
9+
import static hudson.init.InitMilestone.SYSTEM_CONFIG_ADAPTED;
10+
11+
public class DatabaseSchemaLoader {
12+
13+
public static boolean MIGRATED;
14+
15+
@Initializer(after = SYSTEM_CONFIG_ADAPTED)
16+
public static void migrateSchema() throws SQLException {
17+
JunitTestResultStorageConfiguration configuration = JunitTestResultStorageConfiguration.get();
18+
if (configuration.getStorage() instanceof DatabaseTestResultStorage) {
19+
DatabaseTestResultStorage storage = (DatabaseTestResultStorage) configuration.getStorage();
20+
DataSource dataSource = storage.getConnectionSupplier().database().getDataSource();
21+
Flyway flyway = Flyway
22+
.configure(DatabaseSchemaLoader.class.getClassLoader())
23+
.baselineOnMigrate(true)
24+
.table("junit_flyway_schema_history")
25+
.dataSource(dataSource)
26+
.load();
27+
flyway.migrate();
28+
MIGRATED = true;
29+
}
30+
}
31+
}

src/main/java/io/jenkins/plugins/junit/storage/database/DatabaseTestResultStorage.java

+17-21
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,6 @@
4242
@Extension
4343
public class DatabaseTestResultStorage extends JunitTestResultStorage {
4444

45-
static final String CASE_RESULTS_TABLE = "caseResults";
46-
4745
private transient ConnectionSupplier connectionSupplier;
4846

4947
@DataBoundConstructor
@@ -92,7 +90,7 @@ private <T> T query(Querier<T> querier) {
9290
}
9391
private int getCaseCount(String and) {
9492
return query(connection -> {
95-
try (PreparedStatement statement = connection.prepareStatement("SELECT COUNT(*) FROM " + CASE_RESULTS_TABLE + " WHERE job = ? AND build = ?" + and)) {
93+
try (PreparedStatement statement = connection.prepareStatement("SELECT COUNT(*) FROM caseResults WHERE job = ? AND build = ?" + and)) {
9694
statement.setString(1, job);
9795
statement.setInt(2, build);
9896
try (ResultSet result = statement.executeQuery()) {
@@ -106,7 +104,7 @@ private int getCaseCount(String and) {
106104

107105
private List<CaseResult> retrieveCaseResult(String whereCondition) {
108106
return query(connection -> {
109-
try (PreparedStatement statement = connection.prepareStatement("SELECT suite, package, testname, classname, errordetails, skipped, duration FROM " + CASE_RESULTS_TABLE + " WHERE job = ? AND build = ? AND " + whereCondition)) {
107+
try (PreparedStatement statement = connection.prepareStatement("SELECT suite, package, testname, classname, errordetails, skipped, duration FROM caseResults WHERE job = ? AND build = ? AND " + whereCondition)) {
110108
statement.setString(1, job);
111109
statement.setInt(2, build);
112110
try (ResultSet result = statement.executeQuery()) {
@@ -145,7 +143,7 @@ private List<CaseResult> retrieveCaseResult(String whereCondition) {
145143
@Override
146144
public List<PackageResult> getAllPackageResults() {
147145
return query(connection -> {
148-
try (PreparedStatement statement = connection.prepareStatement("SELECT suite, testname, package, classname, errordetails, skipped, duration FROM " + CASE_RESULTS_TABLE + " WHERE job = ? AND build = ?")) {
146+
try (PreparedStatement statement = connection.prepareStatement("SELECT suite, testname, package, classname, errordetails, skipped, duration FROM caseResults WHERE job = ? AND build = ?")) {
149147
statement.setString(1, job);
150148
statement.setInt(2, build);
151149
try (ResultSet result = statement.executeQuery()) {
@@ -194,7 +192,7 @@ public List<PackageResult> getAllPackageResults() {
194192
@Override
195193
public List<TrendTestResultSummary> getTrendTestResultSummary() {
196194
return query(connection -> {
197-
try (PreparedStatement statement = connection.prepareStatement("SELECT build, sum(case when errorDetails is not null then 1 else 0 end) as failCount, sum(case when skipped is not null then 1 else 0 end) as skipCount, sum(case when errorDetails is null and skipped is null then 1 else 0 end) as passCount FROM " + CASE_RESULTS_TABLE + " WHERE job = ? group by build order by build;")) {
195+
try (PreparedStatement statement = connection.prepareStatement("SELECT build, sum(case when errorDetails is not null then 1 else 0 end) as failCount, sum(case when skipped is not null then 1 else 0 end) as skipCount, sum(case when errorDetails is null and skipped is null then 1 else 0 end) as passCount FROM caseResults" + " WHERE job = ? group by build order by build;")) {
198196
statement.setString(1, job);
199197
try (ResultSet result = statement.executeQuery()) {
200198

@@ -217,7 +215,7 @@ public List<TrendTestResultSummary> getTrendTestResultSummary() {
217215
@Override
218216
public List<TestDurationResultSummary> getTestDurationResultSummary() {
219217
return query(connection -> {
220-
try (PreparedStatement statement = connection.prepareStatement("SELECT build, sum(duration) as duration FROM " + CASE_RESULTS_TABLE + " WHERE job = ? group by build order by build;")) {
218+
try (PreparedStatement statement = connection.prepareStatement("SELECT build, sum(duration) as duration FROM caseResults" + " WHERE job = ? group by build order by build;")) {
221219
statement.setString(1, job);
222220
try (ResultSet result = statement.executeQuery()) {
223221

@@ -251,7 +249,7 @@ public int getCountOfBuildsWithTestResults() {
251249
@Override
252250
public PackageResult getPackageResult(String packageName) {
253251
return query(connection -> {
254-
try (PreparedStatement statement = connection.prepareStatement("SELECT suite, testname, classname, errordetails, skipped, duration FROM " + CASE_RESULTS_TABLE + " WHERE job = ? AND build = ? AND package = ?")) {
252+
try (PreparedStatement statement = connection.prepareStatement("SELECT suite, testname, classname, errordetails, skipped, duration FROM caseResults WHERE job = ? AND build = ? AND package = ?")) {
255253
statement.setString(1, job);
256254
statement.setInt(2, build);
257255
statement.setString(3, packageName);
@@ -293,7 +291,7 @@ public PackageResult getPackageResult(String packageName) {
293291
@Override
294292
public ClassResult getClassResult(String name) {
295293
return query(connection -> {
296-
try (PreparedStatement statement = connection.prepareStatement("SELECT suite, package, testname, classname, errordetails, skipped, duration FROM " + CASE_RESULTS_TABLE + " WHERE job = ? AND build = ? AND classname = ?")) {
294+
try (PreparedStatement statement = connection.prepareStatement("SELECT suite, package, testname, classname, errordetails, skipped, duration FROM caseResults WHERE job = ? AND build = ? AND classname = ?")) {
297295
statement.setString(1, job);
298296
statement.setInt(2, build);
299297
statement.setString(3, name);
@@ -337,7 +335,7 @@ public ClassResult getClassResult(String name) {
337335
Job<?, ?> theJob = Objects.requireNonNull(Jenkins.get().getItemByFullName(job, Job.class));
338336
try (PreparedStatement statement = connection.prepareStatement(
339337
"SELECT build " +
340-
"FROM " + CASE_RESULTS_TABLE + " " +
338+
"FROM caseResults " +
341339
"WHERE job = ? " +
342340
"AND build < ? " +
343341
"AND suite = ? " +
@@ -365,7 +363,7 @@ public ClassResult getClassResult(String name) {
365363
}
366364
try (PreparedStatement statement = connection.prepareStatement(
367365
"SELECT build " +
368-
"FROM " + CASE_RESULTS_TABLE + " " +
366+
"FROM caseResults " +
369367
"WHERE job = ? " +
370368
"AND build > ? " +
371369
"AND suite = ? " +
@@ -412,7 +410,7 @@ public List<CaseResult> getFailedTestsByPackage(String packageName) {
412410

413411
private List<CaseResult> getByPackage(String packageName, String filter) {
414412
return query(connection -> {
415-
try (PreparedStatement statement = connection.prepareStatement("SELECT suite, testname, classname, errordetails, duration, skipped FROM " + CASE_RESULTS_TABLE + " WHERE job = ? AND build = ? AND package = ? " + filter)) {
413+
try (PreparedStatement statement = connection.prepareStatement("SELECT suite, testname, classname, errordetails, duration, skipped FROM caseResults WHERE job = ? AND build = ? AND package = ? " + filter)) {
416414
statement.setString(1, job);
417415
statement.setInt(2, build);
418416
statement.setString(3, packageName);
@@ -445,7 +443,7 @@ private List<CaseResult> getCaseResults(String column) {
445443
@Override
446444
public CaseResult getCaseResult(String testName) {
447445
return query(connection -> {
448-
try (PreparedStatement statement = connection.prepareStatement("SELECT suite, testname, package, classname, errordetails, skipped, duration FROM " + CASE_RESULTS_TABLE + " WHERE job = ? AND build = ? AND testname = ?")) {
446+
try (PreparedStatement statement = connection.prepareStatement("SELECT suite, testname, package, classname, errordetails, skipped, duration FROM caseResults WHERE job = ? AND build = ? AND testname = ?")) {
449447
statement.setString(1, job);
450448
statement.setInt(2, build);
451449
statement.setString(3, testName);
@@ -484,7 +482,7 @@ public CaseResult getCaseResult(String testName) {
484482
@Override
485483
public SuiteResult getSuite(String name) {
486484
return query(connection -> {
487-
try (PreparedStatement statement = connection.prepareStatement("SELECT testname, package, classname, errordetails, skipped, duration FROM " + CASE_RESULTS_TABLE + " WHERE job = ? AND build = ? AND suite = ?")) {
485+
try (PreparedStatement statement = connection.prepareStatement("SELECT testname, package, classname, errordetails, skipped, duration FROM caseResults WHERE job = ? AND build = ? AND suite = ?")) {
488486
statement.setString(1, job);
489487
statement.setInt(2, build);
490488
statement.setString(3, name);
@@ -518,7 +516,7 @@ public SuiteResult getSuite(String name) {
518516
@Override
519517
public float getTotalTestDuration() {
520518
return query(connection -> {
521-
try (PreparedStatement statement = connection.prepareStatement("SELECT sum(duration) as duration FROM " + CASE_RESULTS_TABLE + " WHERE job = ? and build = ?;")) {
519+
try (PreparedStatement statement = connection.prepareStatement("SELECT sum(duration) as duration FROM caseResults" + " WHERE job = ? and build = ?;")) {
522520
statement.setString(1, job);
523521
statement.setInt(2, build);
524522
try (ResultSet result = statement.executeQuery()) {
@@ -580,7 +578,7 @@ public List<CaseResult> getPassedTestsByPackage(String packageName) {
580578
@CheckForNull
581579
public TestResult getPreviousResult() {
582580
return query(connection -> {
583-
try (PreparedStatement statement = connection.prepareStatement("SELECT build FROM " + CASE_RESULTS_TABLE + " WHERE job = ? AND build < ? ORDER BY build DESC LIMIT 1")) {
581+
try (PreparedStatement statement = connection.prepareStatement("SELECT build FROM caseResults WHERE job = ? AND build < ? ORDER BY build DESC LIMIT 1")) {
584582
statement.setString(1, job);
585583
statement.setInt(2, build);
586584
try (ResultSet result = statement.executeQuery()) {
@@ -619,7 +617,7 @@ private static class RemotePublisherImpl implements RemotePublisher {
619617

620618
@Override public void publish(TestResult result, TaskListener listener) throws IOException {
621619
try {
622-
try (Connection connection = connectionSupplier.connection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO " + CASE_RESULTS_TABLE + " (job, build, suite, package, className, testName, errorDetails, skipped, duration) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)")) {
620+
try (Connection connection = connectionSupplier.connection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO caseResults (job, build, suite, package, className, testName, errorDetails, skipped, duration) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)")) {
623621
int count = 0;
624622
for (SuiteResult suiteResult : result.getSuites()) {
625623
for (CaseResult caseResult : suiteResult.getCases()) {
@@ -680,10 +678,8 @@ static class LocalConnectionSupplier extends ConnectionSupplier {
680678
}
681679

682680
@Override protected void initialize(Connection connection) throws SQLException {
683-
try (Statement statement = connection.createStatement()) {
684-
// TODO this and joined tables: errorStackTrace, stdout, stderr, nodeId, enclosingBlocks, enclosingBlockNames, etc.
685-
statement.execute("CREATE TABLE IF NOT EXISTS " + CASE_RESULTS_TABLE + "(job varchar(255), build int, suite varchar(255), package varchar(255), className varchar(255), testName varchar(255), errorDetails varchar(255), skipped varchar(255), duration numeric)");
686-
// TODO indices
681+
if (!DatabaseSchemaLoader.MIGRATED) {
682+
DatabaseSchemaLoader.migrateSchema();
687683
}
688684
}
689685

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
CREATE TABLE caseResults(
2+
job varchar(255),
3+
build int,
4+
suite varchar(255),
5+
package varchar(255),
6+
className varchar(255),
7+
testName varchar(255),
8+
errorDetails varchar(255),
9+
skipped varchar(255),
10+
duration numeric
11+
);

src/test/java/io/jenkins/plugins/junit/storage/database/DatabaseTestResultStorageTest.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@
4141
import org.w3c.dom.Node;
4242
import org.w3c.dom.NodeList;
4343

44-
import static io.jenkins.plugins.junit.storage.database.DatabaseTestResultStorage.CASE_RESULTS_TABLE;
4544
import static java.util.Objects.requireNonNull;
4645
import static org.hamcrest.MatcherAssert.assertThat;
4746
import static org.hamcrest.Matchers.equalTo;
@@ -83,7 +82,7 @@ public void smokes() throws Exception {
8382
"}", true));
8483
WorkflowRun b = p.scheduleBuild2(0).get();
8584
try (Connection connection = requireNonNull(GlobalDatabaseConfiguration.get().getDatabase()).getDataSource().getConnection();
86-
PreparedStatement statement = connection.prepareStatement("SELECT * FROM " + CASE_RESULTS_TABLE);
85+
PreparedStatement statement = connection.prepareStatement("SELECT * FROM caseResults");
8786
ResultSet result = statement.executeQuery()) {
8887
printResultSet(result);
8988
}

0 commit comments

Comments
 (0)