diff --git a/.e2e.ci.env b/.e2e.ci.env new file mode 100644 index 0000000..4f3f9dc --- /dev/null +++ b/.e2e.ci.env @@ -0,0 +1,5 @@ +TRAINER_HTTP_ADDR=trainer-http:3000 +TRAINER_GRPC_ADDR=trainer-grpc:3000 +TRAININGS_HTTP_ADDR=trainings-http:3000 +USERS_GRPC_ADDR=users-grpc:3000 +USERS_HTTP_ADDR=users-http:3000 diff --git a/.test.ci.env b/.test.ci.env new file mode 100644 index 0000000..55403fe --- /dev/null +++ b/.test.ci.env @@ -0,0 +1,8 @@ +FIRESTORE_EMULATOR_HOST=firestore-component-tests:8787 +MYSQL_ADDR=mysql + +TRAINER_HTTP_ADDR=localhost:5000 +TRAINER_GRPC_ADDR=localhost:5010 +TRAININGS_HTTP_ADDR=localhost:5001 +USERS_HTTP_ADDR=localhost:5002 +USERS_GRPC_ADDR=localhost:5020 diff --git a/cloudbuild.yaml b/cloudbuild.yaml index 1425f5a..121e0e2 100644 --- a/cloudbuild.yaml +++ b/cloudbuild.yaml @@ -28,31 +28,66 @@ steps: args: ["users", "$PROJECT_ID"] waitFor: [users-lint] +- id: docker-compose + name: 'docker/compose:1.19.0' + args: ['-f', 'docker-compose.yml', '-f', 'docker-compose.ci.yml', 'up', '-d'] + env: + - 'PROJECT_ID=$PROJECT_ID' + waitFor: [trainer-docker, trainings-docker, users-docker] + +- id: trainer-tests + name: golang + entrypoint: ./scripts/test.sh + args: ["trainer", ".test.ci.env"] + waitFor: [docker-compose] +- id: trainings-tests + name: golang + entrypoint: ./scripts/test.sh + args: ["trainings", ".test.ci.env"] + waitFor: [docker-compose] +- id: users-tests + name: golang + entrypoint: ./scripts/test.sh + args: ["users", ".test.ci.env"] + waitFor: [docker-compose] +- id: e2e-tests + name: golang + entrypoint: ./scripts/test.sh + args: ["common", ".e2e.ci.env"] + waitFor: [trainer-tests, trainings-tests, users-tests] + +- id: docker-compose-down + name: 'docker/compose:1.19.0' + args: ['-f', 'docker-compose.yml', '-f', 'docker-compose.ci.yml', 'down'] + env: + - 'PROJECT_ID=$PROJECT_ID' + waitFor: [e2e-tests] + - id: trainer-http-deploy name: gcr.io/cloud-builders/gcloud entrypoint: ./scripts/deploy.sh args: [trainer, http, "$PROJECT_ID"] - waitFor: [trainer-docker] + waitFor: [e2e-tests] - id: trainer-grpc-deploy name: gcr.io/cloud-builders/gcloud entrypoint: ./scripts/deploy.sh args: [trainer, grpc, "$PROJECT_ID"] - waitFor: [trainer-docker] + waitFor: [e2e-tests] - id: trainings-http-deploy name: gcr.io/cloud-builders/gcloud entrypoint: ./scripts/deploy.sh args: [trainings, http, "$PROJECT_ID"] - waitFor: [trainings-docker] + waitFor: [e2e-tests] - id: users-http-deploy name: gcr.io/cloud-builders/gcloud entrypoint: ./scripts/deploy.sh args: [users, http, "$PROJECT_ID"] - waitFor: [users-docker] + waitFor: [e2e-tests] - id: users-grpc-deploy name: gcr.io/cloud-builders/gcloud entrypoint: ./scripts/deploy.sh args: [users, grpc, "$PROJECT_ID"] - waitFor: [users-docker] + waitFor: [e2e-tests] - id: web-deps name: node:12.16.2 diff --git a/docker-compose.ci.yml b/docker-compose.ci.yml new file mode 100644 index 0000000..9e4afdb --- /dev/null +++ b/docker-compose.ci.yml @@ -0,0 +1,20 @@ +version: "3" +services: + trainer-http: + image: "gcr.io/${PROJECT_ID}/trainer" + + trainer-grpc: + image: "gcr.io/${PROJECT_ID}/trainer" + + trainings-http: + image: "gcr.io/${PROJECT_ID}/trainings" + + users-http: + image: "gcr.io/${PROJECT_ID}/users" + + users-grpc: + image: "gcr.io/${PROJECT_ID}/users" +networks: + default: + external: + name: cloudbuild diff --git a/internal/common/tests/clients.go b/internal/common/tests/clients.go index 6ad303f..1e9b233 100644 --- a/internal/common/tests/clients.go +++ b/internal/common/tests/clients.go @@ -27,7 +27,11 @@ type TrainerHTTPClient struct { } func NewTrainerHTTPClient(t *testing.T, token string) TrainerHTTPClient { - url := fmt.Sprintf("http://%v/api", os.Getenv("TRAINER_HTTP_ADDR")) + addr := os.Getenv("TRAINER_HTTP_ADDR") + ok := WaitForPort(addr) + require.True(t, ok, "Trainer HTTP timed out") + + url := fmt.Sprintf("http://%v/api", addr) client, err := trainer.NewClientWithResponses( url, @@ -72,7 +76,12 @@ type TrainingsHTTPClient struct { } func NewTrainingsHTTPClient(t *testing.T, token string) TrainingsHTTPClient { - url := fmt.Sprintf("http://%v/api", os.Getenv("TRAININGS_HTTP_ADDR")) + addr := os.Getenv("TRAININGS_HTTP_ADDR") + fmt.Println("Trying trainings http:", addr) + ok := WaitForPort(addr) + require.True(t, ok, "Trainings HTTP timed out") + + url := fmt.Sprintf("http://%v/api", addr) client, err := trainings.NewClientWithResponses( url, @@ -126,7 +135,11 @@ type UsersHTTPClient struct { } func NewUsersHTTPClient(t *testing.T, token string) UsersHTTPClient { - url := fmt.Sprintf("http://%v/api", os.Getenv("USERS_HTTP_ADDR")) + addr := os.Getenv("USERS_HTTP_ADDR") + ok := WaitForPort(addr) + require.True(t, ok, "Users HTTP timed out") + + url := fmt.Sprintf("http://%v/api", addr) client, err := users.NewClientWithResponses( url, diff --git a/internal/trainer/adapters/hour_mysql_repository.go b/internal/trainer/adapters/hour_mysql_repository.go index 3857675..621239b 100644 --- a/internal/trainer/adapters/hour_mysql_repository.go +++ b/internal/trainer/adapters/hour_mysql_repository.go @@ -181,13 +181,14 @@ func (m MySQLHourRepository) finishTransaction(err error, tx *sqlx.Tx) error { } func NewMySQLConnection() (*sqlx.DB, error) { - config := mysql.Config{ - Addr: os.Getenv("MYSQL_ADDR"), - User: os.Getenv("MYSQL_USER"), - Passwd: os.Getenv("MYSQL_PASSWORD"), - DBName: os.Getenv("MYSQL_DATABASE"), - ParseTime: true, // with that parameter, we can use time.Time in mysqlHour.Hour - } + config := mysql.NewConfig() + + config.Net = "tcp" + config.Addr = os.Getenv("MYSQL_ADDR") + config.User = os.Getenv("MYSQL_USER") + config.Passwd = os.Getenv("MYSQL_PASSWORD") + config.DBName = os.Getenv("MYSQL_DATABASE") + config.ParseTime = true // with that parameter, we can use time.Time in mysqlHour.Hour db, err := sqlx.Connect("mysql", config.FormatDSN()) if err != nil {