Test succeeds locally via SSH tunnel but fails in CircleCI with "url not specified" error

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.

:white_check_mark: 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"));
    }
}

:memo: 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

:counterclockwise_arrows_button: 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.


:gear: 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

:cross_mark: 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.


:folded_hands: 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!