Skip to content

Commit 40afbc4

Browse files
committed
TRUNK-6345 Fix testing framework to be used by modules for openmrs-core 2.4+
1 parent 8b9a040 commit 40afbc4

33 files changed

+1178
-89
lines changed

.github/workflows/build.yml

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# standard build with Maven and push coverage data
2+
name: Build with Maven
3+
4+
# trigger build on branches that *should* support both Java 8 and Java 11
5+
on:
6+
push:
7+
branches:
8+
- master
9+
- 2.4.x
10+
pull_request:
11+
branches:
12+
- master
13+
- 2.4.x
14+
workflow_dispatch:
15+
16+
jobs:
17+
build:
18+
strategy:
19+
matrix:
20+
platform:
21+
- ubuntu-latest
22+
- windows-latest
23+
java-version:
24+
- 8
25+
- 11
26+
exclude:
27+
- platform: windows-latest
28+
java-version: 11
29+
runs-on: ${{ matrix.platform }}
30+
steps:
31+
- uses: actions/checkout@v4
32+
- name: Setup JDK
33+
uses: actions/setup-java@v4
34+
with:
35+
distribution: 'temurin'
36+
java-version: ${{ matrix.java-version }}
37+
cache: 'maven'
38+
- name: Install dependencies
39+
run: mvn clean install -DskipTests=true -D"maven.javadoc.skip"=true --batch-mode --show-version --file pom.xml
40+
- name: Build with Maven
41+
run: mvn clean install && mvn test -Pskip-default-test -Pintegration-test --batch-mode --file pom.xml
42+
# this is necessary to populate the environment variables for Coveralls properly
43+
- name: Set branch name and PR number
44+
id: refs
45+
if: ${{ matrix.java-version == '8' }}
46+
continue-on-error: true
47+
env:
48+
BRANCH_NAME_OR_REF: ${{ github.head_ref || github.ref }}
49+
run: |
50+
echo "::set-output name=branch_name::${BRANCH_NAME_OR_REF#refs/heads/}"
51+
echo "::set-output name=pr_number::$(jq --raw-output .pull_request.number "$GITHUB_EVENT_PATH")"
52+
- name: Update coverage data
53+
# only send coverage data for Java 8
54+
if: ${{ matrix.java-version == '8' && steps.refs.outcome == 'success' }}
55+
continue-on-error: true
56+
env:
57+
CI_NAME: Github
58+
CI_BUILD_NUMBER: ${{ github.run_id }}
59+
CI_BUILD_URL: https://github.com/${{ github.repository }}/commit/${{ github.event.after }}/checks
60+
CI_BRANCH: ${{ steps.refs.outputs.branch_name }}
61+
CI_PULL_REQUEST: ${{ steps.refs.outputs.pr_number }}
62+
run: mvn jacoco:report coveralls:report --batch-mode --file pom.xml --no-transfer-progress -DrepoToken=${{ secrets.COVERALLS_TOKEN }}

api/src/main/java/org/openmrs/api/cache/CacheConfig.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public class CacheConfig {
2828
public EhCacheManagerFactoryBean apiCacheManagerFactoryBean(){
2929
OpenmrsCacheManagerFactoryBean cacheManagerFactoryBean = new OpenmrsCacheManagerFactoryBean();
3030
cacheManagerFactoryBean.setConfigLocation(new ClassPathResource("ehcache-api.xml"));
31-
cacheManagerFactoryBean.setShared(false);
31+
cacheManagerFactoryBean.setShared(true);
3232
cacheManagerFactoryBean.setAcceptExisting(true);
3333

3434
return cacheManagerFactoryBean;

api/src/main/java/org/openmrs/logging/OpenmrsConfigurationFactory.java

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ public Configuration getConfiguration(LoggerContext loggerContext, String name,
6060
return null;
6161
}
6262

63-
// try to load the configuration from the application directory
6463
if (configLocation == null) {
64+
// Try to load the configuration from the application directory
6565
for (File applicationDirectory : new File[] {
6666
OpenmrsUtil.getDirectoryInApplicationDataDirectory("configuration"),
6767
OpenmrsUtil.getApplicationDataDirectoryAsFile()
@@ -78,24 +78,27 @@ public Configuration getConfiguration(LoggerContext loggerContext, String name,
7878
}
7979
}
8080
}
81-
82-
return super.getConfiguration(loggerContext, name, configLocation);
81+
82+
return super.getConfiguration(loggerContext, name, configLocation);
8383
}
84-
84+
8585
@Override
8686
public Configuration getConfiguration(LoggerContext loggerContext, ConfigurationSource source) {
87-
switch (FilenameUtils.getExtension(source.getFile().getName()).toLowerCase(Locale.ROOT)) {
88-
case "xml":
89-
return new OpenmrsXmlConfiguration(loggerContext, source);
90-
case "yaml":
91-
case "yml":
92-
return new OpenmrsYamlConfiguration(loggerContext, source);
93-
case "json":
94-
return new OpenmrsJsonConfiguration(loggerContext, source);
95-
default:
96-
throw new IllegalArgumentException(
97-
OpenmrsConfigurationFactory.class.getName() + " does not know how to handle source " + source.getFile());
87+
if (source != null && source.getFile() != null) {
88+
switch (FilenameUtils.getExtension(source.getFile().getName()).toLowerCase(Locale.ROOT)) {
89+
case "xml":
90+
return new OpenmrsXmlConfiguration(loggerContext, source);
91+
case "yaml":
92+
case "yml":
93+
return new OpenmrsYamlConfiguration(loggerContext, source);
94+
case "json":
95+
return new OpenmrsJsonConfiguration(loggerContext, source);
96+
default:
97+
throw new IllegalArgumentException(
98+
OpenmrsConfigurationFactory.class.getName() + " does not know how to handle source " + source.getFile());
99+
}
98100
}
101+
return null;
99102
}
100103

101104
@Override

api/src/main/resources/hibernate.default.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ hibernate.generate_statistics=true
2525
hibernate.cache.use_structured_entries=false
2626

2727
#Hibernate second level cache
28-
hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory
28+
hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory
2929
hibernate.cache.use_second_level_cache=true
3030

3131
hibernate.search.default.directory_provider=filesystem

api/src/main/resources/log4j2.xml

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<!--
3+
4+
This Source Code Form is subject to the terms of the Mozilla Public License,
5+
v. 2.0. If a copy of the MPL was not distributed with this file, You can
6+
obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under
7+
the terms of the Healthcare Disclaimer located at http://openmrs.org/license.
8+
9+
Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS
10+
graphic logo is a trademark of OpenMRS Inc.
11+
12+
-->
13+
14+
<Configuration xmlns="http://logging.apache.org/log4j/2.0/config">
15+
<Properties>
16+
<!-- The default pattern is stored as a property so that it's only defined once.
17+
It's also quite challenging to escape using Log4j2's variable substitution. -->
18+
<Property name="defaultPattern">%p - %C{1}.%M(%L) |%d{ISO8601}| %m%n</Property>
19+
</Properties>
20+
<Appenders>
21+
<!-- the console appender is not required but usually a good idea -->
22+
<Console name="CONSOLE" target="SYSTEM_OUT">
23+
<PatternLayout pattern="${openmrs:logLayout:-${defaultPattern}}" />
24+
</Console>
25+
<!-- OpenMRS should have an appender called "OPENMRS FILE APPENDER" that appends to a file -->
26+
<RollingFile name="OPENMRS FILE APPENDER"
27+
fileName="${openmrs:logLocation:-${openmrs:applicationDirectory}}/openmrs.log"
28+
filePattern="${openmrs:logLocation:-${openmrs:applicationDirectory}}/openmrs.%i.log">
29+
<PatternLayout pattern="${openmrs:logLayout:-${defaultPattern}}" />
30+
<Policies>
31+
<OnStartupTriggeringPolicy />
32+
<SizeBasedTriggeringPolicy size="10 MB" />
33+
</Policies>
34+
<DefaultRolloverStrategy max="1" />
35+
</RollingFile>
36+
<!-- The MEMORY_APPENDER is used to keep a subset of logging messages in memory to be displayed to the user.
37+
If one is not configured here, it will be created automatically. -->
38+
<Memory name="MEMORY_APPENDER"
39+
bufferSize="200"> <!-- bufferSize is how many messages are kept in memory -->
40+
<PatternLayout pattern="${openmrs:logLayout:-${defaultPattern}}" />
41+
</Memory>
42+
</Appenders>
43+
<Loggers>
44+
<Logger name="org.apache" level="WARN" />
45+
<Logger name="org.hibernate" level="ERROR" />
46+
<Logger name="net.sf.ehcache" level="ERROR" />
47+
<Logger name="org.springframework" level="WARN" />
48+
<Logger name="org.openmrs" level="WARN" />
49+
<Logger name="liquibase" level="INFO" />
50+
<!--
51+
This controls the LoggingAdvice class that wraps around the OpenMRS services
52+
WARN == don't log anything special for the services
53+
INFO == log all setters
54+
DEBUG == log all setters & log all getters & log execution time
55+
-->
56+
<Logger name="org.openmrs.api" level="INFO" />
57+
<Logger name="org.apache.fop" level="ERROR" />
58+
<!-- Hide the useless MissingResourceException -->
59+
<Logger name="org.springframework.context.support.ResourceBundleMessageSource" level="ERROR" />
60+
<Logger name="org.springframework.beans.factory.support.DefaultListableBeanFactory" level="ERROR" />
61+
<Root level="WARN">
62+
<AppenderRef ref="CONSOLE" />
63+
<AppenderRef ref="MEMORY_APPENDER" />
64+
<AppenderRef ref="OPENMRS FILE APPENDER" />
65+
</Root>
66+
</Loggers>
67+
</Configuration>

api/src/test/java/org/openmrs/test/BaseContextSensitiveTest.java

Lines changed: 12 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@
99
*/
1010
package org.openmrs.test;
1111

12+
import javax.swing.JFrame;
13+
import javax.swing.JLabel;
14+
import javax.swing.JOptionPane;
15+
import javax.swing.JPanel;
16+
import javax.swing.JPasswordField;
17+
import javax.swing.JTextField;
18+
import javax.swing.UIManager;
1219
import java.awt.Font;
1320
import java.awt.Frame;
1421
import java.awt.GridBagConstraints;
@@ -35,14 +42,6 @@
3542
import java.util.Timer;
3643
import java.util.TimerTask;
3744

38-
import javax.swing.JFrame;
39-
import javax.swing.JLabel;
40-
import javax.swing.JOptionPane;
41-
import javax.swing.JPanel;
42-
import javax.swing.JPasswordField;
43-
import javax.swing.JTextField;
44-
import javax.swing.UIManager;
45-
4645
import org.apache.commons.io.IOUtils;
4746
import org.apache.commons.lang3.ArrayUtils;
4847
import org.apache.commons.lang3.StringUtils;
@@ -111,7 +110,7 @@
111110
* To migrate your tests follow <a href="https://wiki.openmrs.org/display/docs/How+to+migrate+to+JUnit+5">How to migrate to JUnit 5</a>.
112111
* The JUnit 5 version of the class is {@link org.openmrs.test.jupiter.BaseContextSensitiveTest}.<p>
113112
*/
114-
@ContextConfiguration(locations = { "classpath:applicationContext-service.xml", "classpath*:openmrs-servlet.xml",
113+
@ContextConfiguration(locations = { "classpath:applicationContext-service.xml",
115114
"classpath*:moduleApplicationContext.xml", "classpath*:TestingApplicationContext.xml" })
116115
@TestExecutionListeners( { TransactionalTestExecutionListener.class, SkipBaseSetupAnnotationExecutionListener.class,
117116
StartModuleExecutionListener.class })
@@ -161,7 +160,7 @@ public abstract class BaseContextSensitiveTest extends AbstractJUnit4SpringConte
161160
/**
162161
* Allows to determine if the DB is initialized with standard data
163162
*/
164-
private static boolean isBaseSetup;
163+
private static volatile boolean isBaseSetup;
165164

166165
/**
167166
* Stores a user authenticated for running tests which allows to discover a situation when some
@@ -177,8 +176,6 @@ public abstract class BaseContextSensitiveTest extends AbstractJUnit4SpringConte
177176
@InjectMocks
178177
protected ContextMockHelper contextMockHelper;
179178

180-
private static volatile BaseContextSensitiveTest instance;
181-
182179
/**
183180
* Basic constructor for the super class to all openmrs api unit tests. This constructor sets up
184181
* the classloader and the properties file so that by the type spring gets around to finally
@@ -199,10 +196,8 @@ public BaseContextSensitiveTest() {
199196
Context.setRuntimeProperties(props);
200197

201198
loadCount++;
202-
203-
instance = this;
204199
}
205-
200+
206201
/**
207202
* Initializes fields annotated with {@link Mock}.
208203
*
@@ -874,11 +869,11 @@ public void deleteAllData() {
874869
connection.commit();
875870

876871
updateSearchIndex();
877-
878-
isBaseSetup = false;
879872
}
880873
catch (SQLException | DatabaseUnitException e) {
881874
throw new DatabaseUnitRuntimeException(e);
875+
} finally {
876+
isBaseSetup = false;
882877
}
883878
}
884879

@@ -985,18 +980,6 @@ public void clearSessionAfterEachTest() {
985980
*/
986981
@AfterClass
987982
public static void closeSessionAfterEachClass() throws Exception {
988-
//Some tests add data via executeDataset()
989-
//We need to delete it in order not to interfere with others
990-
if (instance != null) {
991-
try {
992-
instance.deleteAllData();
993-
}
994-
catch (Exception ex) {
995-
//No need to worry about this
996-
}
997-
instance = null;
998-
}
999-
1000983
// clean up the session so we don't leak memory
1001984
if (Context.isSessionOpen()) {
1002985
Context.closeSession();

api/src/test/java/org/openmrs/test/jupiter/BaseContextSensitiveTest.java

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,19 @@
1212
import static org.junit.jupiter.api.Assumptions.assumeTrue;
1313
import static org.springframework.test.context.TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS;
1414

15-
import javax.swing.*;
16-
import java.awt.*;
15+
import javax.swing.JFrame;
16+
import javax.swing.JLabel;
17+
import javax.swing.JOptionPane;
18+
import javax.swing.JPanel;
19+
import javax.swing.JPasswordField;
20+
import javax.swing.JTextField;
21+
import javax.swing.UIManager;
22+
import java.awt.Font;
23+
import java.awt.Frame;
24+
import java.awt.GridBagConstraints;
25+
import java.awt.GridBagLayout;
26+
import java.awt.Insets;
27+
import java.awt.Window;
1728
import java.io.File;
1829
import java.io.FileInputStream;
1930
import java.io.FileNotFoundException;
@@ -104,7 +115,7 @@
104115
*
105116
* @since 2.4.0
106117
*/
107-
@ContextConfiguration(locations = { "classpath:applicationContext-service.xml", "classpath*:openmrs-servlet.xml",
118+
@ContextConfiguration(locations = { "classpath:applicationContext-service.xml",
108119
"classpath*:moduleApplicationContext.xml", "classpath*:TestingApplicationContext.xml" })
109120
@TestExecutionListeners(
110121
listeners = { SkipBaseSetupAnnotationExecutionListener.class,
@@ -158,7 +169,7 @@ public abstract class BaseContextSensitiveTest {
158169
/**
159170
* Allows to determine if the DB is initialized with standard data
160171
*/
161-
private static boolean isBaseSetup;
172+
private static volatile boolean isBaseSetup;
162173

163174
/**
164175
* Stores a user authenticated for running tests which allows to discover a situation when some
@@ -176,8 +187,6 @@ public abstract class BaseContextSensitiveTest {
176187
@InjectMocks
177188
protected ContextMockHelper contextMockHelper;
178189

179-
private static volatile BaseContextSensitiveTest instance;
180-
181190
/**
182191
* Basic constructor for the super class to all openmrs api unit tests. This constructor sets up
183192
* the classloader and the properties file so that by the type spring gets around to finally
@@ -198,8 +207,6 @@ public BaseContextSensitiveTest() {
198207
Context.setRuntimeProperties(props);
199208

200209
loadCount++;
201-
202-
instance = this;
203210
}
204211

205212
/**
@@ -862,11 +869,11 @@ public void deleteAllData() {
862869
connection.commit();
863870

864871
updateSearchIndex();
865-
866-
isBaseSetup = false;
867872
}
868873
catch (SQLException | DatabaseUnitException e) {
869874
throw new DatabaseUnitRuntimeException(e);
875+
} finally {
876+
isBaseSetup = false;
870877
}
871878
}
872879

@@ -973,18 +980,6 @@ public void clearSessionAfterEachTest() {
973980
*/
974981
@AfterAll
975982
public static void closeSessionAfterEachClass() throws Exception {
976-
//Some tests add data via executeDataset()
977-
//We need to delete it in order not to interfere with others
978-
if (instance != null) {
979-
try {
980-
instance.deleteAllData();
981-
}
982-
catch (Exception ex) {
983-
//No need to worry about this
984-
}
985-
instance = null;
986-
}
987-
988983
// clean up the session so we don't leak memory
989984
if (Context.isSessionOpen()) {
990985
Context.closeSession();

0 commit comments

Comments
 (0)