0

I have a project that I would like to test using test container. However, when trying to initialize the database in the container, an error occurs

Caused by: org.springframework.r2dbc.connection.init.UncategorizedScriptException: Failed to execute database script at app//org.springframework.r2dbc.connection.init.DatabasePopulator.lambda$populate$4(DatabasePopulator.java:65)

Caused by: io.r2dbc.postgresql.ExceptionFactory$PostgresqlAuthenticationFailure: [28P01] password authentication failed for user "test" at app//io.r2dbc.postgresql.ExceptionFactory.createException(ExceptionFactory.java:86)

@TestConfiguration
public class PasswordDbInitializeConfiguration {

    @Bean(destroyMethod = "destroy")
    public ConnectionFactoryInitializer passwordConnectionFactoryInitializer(
            @Qualifier("passwordConnectionFactory") ConnectionFactory connectionFactory) {

        ConnectionFactoryInitializer initializer = new ConnectionFactoryInitializer();
        initializer.setConnectionFactory(connectionFactory);

        CompositeDatabasePopulator databasePopulation = new CompositeDatabasePopulator();
        databasePopulation.addPopulators(new ResourceDatabasePopulator(new ClassPathResource("sql/create_schema.sql")));
        databasePopulation.addPopulators(new ResourceDatabasePopulator(new ClassPathResource("sql/create_table_pwd_source.sql")));
        initializer.setDatabasePopulator(databasePopulation);

        return initializer;
    }
}
@Slf4j
public class PostgresqlContainerInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {


   private static final String POSTGRESQL_IMAGE = "postgres:14";

    private static final String[] CUSTOM_COMMAND_PARTS = {"-c", "shared_buffers=256MB", "-c", "max_connections=200"};

    private static final PostgreSQLContainer<?> postgresqlContainer = new PostgreSQLContainer<>(
            DockerImageName.parse(POSTGRESQL_IMAGE)
                    .asCompatibleSubstituteFor("postgres")
    ).withDatabaseName("testdb");

    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        postgresqlContainer.withLogConsumer(new Slf4jLogConsumer(log));
        postgresqlContainer.setCommand(ArrayUtils.addAll(postgresqlContainer.getCommandParts(), CUSTOM_COMMAND_PARTS));
        postgresqlContainer.start();

        ConnectionFactoryOptions options = PostgreSQLR2DBCDatabaseContainer.getOptions(
                postgresqlContainer
        );

        String r2dbcUrl = String.format("r2dbc:pool:postgresql://%s:%s/%s",
                options.getRequiredValue(HOST),
                options.getRequiredValue(PORT),
                options.getRequiredValue(DATABASE)
        );


        TestPropertyValues testPropertyValues = TestPropertyValues.of(
                "r2dbc.chatdb.url=" + r2dbcUrl,
                "r2dbc.chatdb.username=" + options.getRequiredValue(USER),
                "r2dbc.chatdb.password=" + options.getRequiredValue(PASSWORD)
        );

        testPropertyValues.applyTo(applicationContext.getEnvironment());
    }
}
DB_DATABASE_NAME: testdb
DB_URL: r2dbc:postgresql://${DB_IP}:${DB_PORT}/${DB_DATABASE_NAME}
DB_USERNAME: test
DB_PASSWORD: test


r2dbc:
  chatdb:
    username: ${DB_USERNAME}
    password: ${DB_PASSWORD}
    url: ${DB_URL}
@SpringBootConfiguration
@DataR2dbcTest
@ContextConfiguration(
        initializers = PostgresqlContainerInitializer.class,
        classes = {
                R2DBCConfigurationPostgresqlPasswordDb.class,
                PasswordDbInitializeConfiguration.class,
                AbstractPasswordTest.DetailsServiceConfiguration.class
        }
)

@ComponentScan(
        basePackageClasses = WebfluxR2dbcFlywaydbSecurityApplication.class,
        includeFilters = {
                @ComponentScan.Filter(value = Repository.class),
                @ComponentScan.Filter(value = {
                        PasswordRepository.class
                },
                        type = FilterType.ASSIGNABLE_TYPE)
        },
        useDefaultFilters = false
)
@AutoConfigurationPackage(basePackageClasses = WebfluxR2dbcFlywaydbSecurityApplication.class)
public abstract class AbstractPasswordTest {

    public static class DetailsServiceConfiguration {

        @Bean
        public ConnectionFactory connectionFactory() {
            return ConnectionFactories.get(
                    ConnectionFactoryOptions.builder()
                            .option(DRIVER, "postgresql")
                            .option(HOST, "localhost")
                            .option(USER, "test")
                            .option(PASSWORD, "test")
                            .option(DATABASE, "testdb")
                            .build());
        }

        @Bean
        public DatabaseClient userDbClient(ConnectionFactory connectionFactory) {
            return DatabaseClient.builder()
                    .connectionFactory(connectionFactory)
                    .namedParameters(true)
                    .build();
        }

    }
}

Who has any ideas about this ? What could it be because of and how to fix it ?

skyho
  • 1,438
  • 2
  • 20
  • 47

2 Answers2

0

Fixed it like this:


DB_IP: 127.0.0.1
DB_PORT: 5432
DB_DATABASE_NAME: testdb
DB_URL: r2dbc:postgresql://${DB_IP}:${DB_PORT}/${DB_DATABASE_NAME}
DB_USERNAME: test
DB_PASSWORD: test
DB_DRIVER_NAME: postgresql

r2dbc:
  chatdb:
    username: ${DB_USERNAME}
    password: ${DB_PASSWORD}
    driver-name: ${DB_DRIVER_NAME}
    port: ${DB_PORT}
    host: ${DB_IP}
    db-name: ${DB_DATABASE_NAME}

        TestPropertyValues testPropertyValues = TestPropertyValues.of(
                "r2dbc.chatdb.url=" + r2dbcUrl,
                "r2dbc.chatdb.username=" + options.getRequiredValue(USER),
                "r2dbc.chatdb.password=" + options.getRequiredValue(PASSWORD),
                "r2dbc.chatdb.port="+ options.getRequiredValue(PORT),
                "r2dbc.chatdb.db-name=" + options.getRequiredValue(DATABASE)
        );
skyho
  • 1,438
  • 2
  • 20
  • 47
0

I using @DynamicPropertySource in Spring Boot 3.1 blog

@SpringBootTest
@Testcontainers
class DemoApplicationTests {
    @Container
    private static final PostgreSQLContainer<?> postgreSQLContainer = new PostgreSQLContainer<>(DockerImageName.parse("postgres:latest"));

    @DynamicPropertySource
    static void dynamicPropertyRegistry(DynamicPropertyRegistry registry) {
        registry.add("spring.r2dbc.url", DemoApplicationTests::getR2dbcUrl);
        registry.add("spring.r2dbc.username", postgreSQLContainer::getUsername);
        registry.add("spring.r2dbc.password", postgreSQLContainer::getPassword);
    }

    private static String getR2dbcUrl() {
        return postgreSQLContainer.getJdbcUrl().replace("jdbc", "r2dbc");
    }


    @Test
    void contextLoads() {
    }

}