Reputation: 307
I am using dagger wherein I am writing code using golang sdk. I want to perform integration testing for which I would need to start a postgres service. Once the postgres service is up I would want to start liquibase service to migrate data into the postgres database.
Here is my code
func (m *DaggerEnvy) IntegrationTest(ctx context.Context, source *dagger.Directory,
npmrcFile *dagger.Secret,
// optional
// +default="postgres"
dbName,
// optional
// +default="postgres"
dbUser,
// optional
// +default="postgres"
dbPassword string,
) (string, error) {
// postgres service
postgresService := m.postgresService(ctx, dbName, dbUser, dbPassword)
postgresService.Start(ctx)
defer postgresService.Stop(ctx)
// liquibase service
liquibaseService := m.liquibaseContainer(ctx, source, postgresService, dbName)
liquibaseService.Start(ctx)
defer liquibaseService.Stop(ctx)
return m.buildNodeEnv(source, npmrcFile).
WithServiceBinding("postgres-service", postgresService).
WithServiceBinding("liquibase-service", liquibaseService).
WithExec([]string{"npm", "run", "migrate:db"}).
Stderr(ctx)
}
func (m *DaggerEnvy) postgresService(
ctx context.Context,
// optional
// +default="postgres"
dbName,
// optional
// +default="root"
dbUser,
// optional
// +default="postgres"
dbPassword string,
) *dagger.Service {
// ? should optional parameters be stored in .env file?
// postgresDataVolume := dag.CacheVolume("./postgres-data") // Path for local persistence
return dag.Container().From("postgres:17").
WithEnvVariable(constants.POSTGRES_USER, dbUser).
WithEnvVariable(constants.POSTGRES_PASSWORD, dbPassword).
WithEnvVariable(constants.POSTGRES_DB, dbName).
WithExposedPort(5432).
// WithMountedCache("/var/lib/postgresql/data", postgresDataVolume).
AsService(dagger.ContainerAsServiceOpts{
UseEntrypoint: true,
})
}
func (m *DaggerEnvy) liquibaseContainer(
ctx context.Context,
source *dagger.Directory,
postgresService *dagger.Service,
// +optional
// +default="postgres"
dbName string,
) *dagger.Service {
return dag.Container().
From("liquibase").
WithFile("/liquibase/master.yaml", source.File("src/server/schema/liquibase/master.yaml")).
WithDirectory("/liquibase/changelog", source.Directory("src/server/schema/changelog")).
WithEnvVariable("LIQUIBASE_COMMAND_URL", fmt.Sprintf("jdbc:postgresql://postgres-service:5432/%s", dbName)).
WithEnvVariable("LIQUIBASE_COMMAND_USERNAME", "postgres").
WithEnvVariable("LIQUIBASE_COMMAND_PASSWORD", "postgres").
WithEnvVariable("LIQUIBASE_COMMAND_CHANGELOG_FILE", "master.yaml").
WithExec([]string{"liquibase", "update"}).
AsService()
}
When I run this using dagger call integration-test ...
then I am getting following error
Starting Liquibase at 12:14:08 using Java 17.0.13 (version 4.30.0 #4943 buil
2024-10-31 17:00+0000)
Liquibase Version: 4.30.0
Liquibase Open Source 4.30.0 by Liquibase
ERROR: Exception Details
ERROR: Exception Primary Class: UnknownHostException
ERROR: Exception Primary Reason: postgres-service
ERROR: Exception Primary Source: 4.30.0
Unexpected error running Liquibase: Connection could not be created to jdbc:
postgresql://postgres-service:5432/postgres with driver org.postgresql.Drive
r. The connection attempt failed.
For more information, please use the --log-level flag
! process "liquibase update" did not complete successfully: exit code: 1
According to my understanding the liquibase-service
has started its execution before postgres-service
is ready to accept connections.
I am also facing a similar issue where is WithExec([]string{"npm", "run", "migrate:db"})
gets executed before completion of both services.
How should I make the service binding run in synchronously? I am using dagger version: v0.15.1
I have generated dagger files using following command: dagger init --sdk=go
Let me know if anything more is required here.
Upvotes: 1
Views: 42
Reputation: 307
We dont need to manually wait for the postgres service to start and accept connections. When we use it along with container using WithServiceBinding("postgres-service", postgresService)
it should work correctly.
If we want to start the service explicitly then we can use Start
method
postgresService := m.postgresService(ctx, dbName, dbUser, dbPassword)
postgresService, err := postgresService.Start(ctx)
if err != nil {
return err
}
This should start the service before binding it with the container
Upvotes: 0