Hello CircleCI Community,
I’m facing a problem where my Spring Boot test (PlayerControllerTest.java
) runs successfully locally using SSH port forwarding, but fails in CircleCI with the following error:
Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.
Local Setup (working)
I use the following command to open an SSH tunnel from my Mac to my Bastion EC2 host, forwarding to RDS:
ssh -i my-key.pem -N -L 33066:<RDS-ENDPOINT>:3306 ec2-user@<BASTION-PUBLIC-IP>
Then, I run tests locally and they pass successfully.
My test class is as follows:
@ActiveProfiles("test")
@SpringBootTest
@AutoConfigureMockMvc
public class PlayerControllerTest {
@Autowired
private MockMvc mockMvc;
@Autowired
private PlayerRepository playerRepository;
@BeforeEach
public void setUp() {
playerRepository.deleteAll();
PlayerModel player = new PlayerModel();
player.setFirstName("John");
player.setFamilyName("Doe");
player.setEmailAddr("test@example.com");
player.setPassword("password123");
playerRepository.save(player);
}
@Test
public void testLoginSuccess() throws Exception {
mockMvc.perform(post("/api/player/login")
.with(csrf())
.content("{\"emailAddr\": \"test@example.com\", \"password\": \"password123\"}")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(jsonPath("$.loginTry").value(true))
.andExpect(jsonPath("$.msg").value("Succeed to login"));
}
}
src/test/resources/application-test.properties
spring.datasource.url=jdbc:mysql://localhost:33066/XXX-XXX
spring.datasource.username=admin
spring.datasource.password=${DB_PASSWORD}
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
build.gradle
implementation 'mysql:mysql-connector-java:8.0.30'
We verified with ./gradlew dependencies --configuration runtimeClasspath
that the MySQL driver is included in the runtime classpath.
CircleCI config.yml
version: 2.1
executors:
java-executor:
docker:
- image: gradle:8.13-jdk23
working_directory: ~/project
jobs:
test-java:
executor: java-executor
steps:
- checkout:
path: ~/project
- run:
name: Install tools
command: |
apt-get update
apt-get install -y openssh-client netcat-openbsd
- run:
name: Write SSH Key from Environment Variable
command: |
mkdir -p ~/.ssh
echo "$BASTION_PRIVATE_KEY" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
- run:
name: Start SSH tunnel to AWS RDS via EC2
background: true
command: |
ssh -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa -N -L 127.0.0.1:33066:<RDS-ENDPOINT>:3306 ec2-user@<BASTION-PUBLIC-IP>
- run:
name: Wait for tunnel
command: |
for i in {1..20}; do
nc -z localhost 33066 && echo "Tunnel ready" && exit 0
echo "Waiting for tunnel..."
sleep 5
done
echo "Tunnel failed" && exit 1
- run:
name: Verify MySQL Driver is Present
command: ./xxx_xxx/gradlew dependencies --configuration runtimeClasspath
- run:
name: Run tests
command: |
./xxx_xxx/gradlew test \
--project-dir ./xxx_xxx \
-Dspring.profiles.active=test \
-Dspring.datasource.url=jdbc:mysql://localhost:33066/XXX-XXX \
-Dspring.datasource.username=admin \
-Dspring.datasource.password=$DB_PASSWORD \
-Dspring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
workflows:
build-and-test:
jobs:
- test-java
Problem in CircleCI
Even though the SSH tunnel is established and the MySQL driver is present, the following error persists during the Run tests
step:
Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.
It seems like the application context cannot read the spring.datasource.url
correctly from the -D
flags or from the application-test.properties
.
Question
How can I ensure that the test picks up the correct datasource configuration when run in CircleCI?
Is there a better way to pass the database properties (especially spring.datasource.url
) when using port forwarding in a CircleCI Docker executor?
Any suggestions or examples would be greatly appreciated!