Skip to content

Commit

Permalink
Merge branch 'main' into composer-3-serverless-upgrade
Browse files Browse the repository at this point in the history
  • Loading branch information
eeaton committed Jan 22, 2025
2 parents db4dc54 + 67a8d3b commit cf8d18d
Show file tree
Hide file tree
Showing 14 changed files with 526 additions and 1,190 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,9 +173,9 @@ Some workflows depend on a [custom classifier](https://cloud.google.com/document
1. After all steps to train and deploy the customer classifier are complete, add the following variable to your `terraform.tfvars` and run `terraform apply` again.
| Terraform variables | Description |
| -------------------- | ----------------------------------------------------------------------------------------- |
| custom_classifier_id | projects/<CLASSIFIER_PROJECT>/locations/ <CLASSIFIER_LOCATION>/processors/<CLASSIFIER_ID> |
| Terraform variables | Description |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| custom_classifier_id | projects/<CLASSIFIER_PROJECT>/locations/<CLASSIFIER_LOCATION>/processors/<CLASSIFIER_ID>. The value of <CLASSIFIER_ID> must be the alphanumeric ID, not the user-friendly name. |
### (Optional) Configure access to the Web UI search application
Expand Down
42 changes: 24 additions & 18 deletions build/int.cloudbuild.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
# limitations under the License.

---
timeout: 7200s
timeout: 9000s
steps:
- id: prepare
- id: create_ephemeral_test_project
name: "${_BUILDER_IMAGE_NAME}:${_BUILDER_IMAGE_TAG}"
entrypoint: /bin/bash
args:
Expand All @@ -28,7 +28,7 @@ steps:
trap "gcloud projects delete ${_TEST_PROJECT_ID} --quiet " ERR ;
gcloud billing projects link ${_TEST_PROJECT_ID} --billing-account=${_BILLING_ACCOUNT} ;
- id: pre_tf_setup
- id: run_script_pre_tf_setup
name: "${_BUILDER_IMAGE_NAME}:${_BUILDER_IMAGE_TAG}"
entrypoint: /bin/bash
args:
Expand All @@ -41,7 +41,7 @@ steps:
- "REGION=${_REGION}"
- "IAP_ADMIN_ACCOUNT=${_IAP_SUPPORT_EMAIL}"

- id: terratest
- id: deploy_infrastructure_
name: "${_BUILDER_IMAGE_NAME}:${_BUILDER_IMAGE_TAG}"
args:
- "-e"
Expand All @@ -50,7 +50,7 @@ steps:
- >-
export PROJECT_ID=${_TEST_PROJECT_ID};
gcloud config set auth/impersonate_service_account ${_DEPLOYER_SA};
(cd build/test && make e2e-test);
(cd build/test && make infra-test);
gcloud config unset auth/impersonate_service_account;
entrypoint: /bin/bash
env:
Expand All @@ -63,27 +63,32 @@ steps:
- "CUSTOM_CLASSIFIER_ID=${_CUSTOM_CLASSIFIER_ID}"
- "GOOGLE_IMPERSONATE_SERVICE_ACCOUNT=${_DEPLOYER_SA}"

- id: functional
- id: prepare_functional_tests
name: "${_BUILDER_IMAGE_NAME}:${_BUILDER_IMAGE_TAG}"
args:
- "-e"
- "-x"
- "-c"
- >-
export PROJECT_ID=${_TEST_PROJECT_ID};
gcloud composer environments run dpu-composer --project=${_TEST_PROJECT_ID} --location=us-central1 dags list;
build/test/ingest_test_docs.sh;
sleep 180;
gcloud composer environments run dpu-composer --project=${_TEST_PROJECT_ID} --location=us-central1 dags list;
sample-deployments/composer-orchestrated-process/scripts/trigger_workflow.sh;
sleep 1800;
(cd /workspace/build/test && make functional-test);
# sample-deployments/composer-orchestrated-process/scripts/delete_doc.sh;
# sample-deployments/composer-orchestrated-process/scripts/reset_datastore.sh;
echo "ingest test documents...";
build/test/helpers/ingest_test_docs.sh;
echo "grant IAM role for pretrained classifier in different project..." ;
build/test/helpers/enable_docai_sa.sh;
entrypoint: /bin/bash
env:
- "CICD_PROJECT_ID=${PROJECT_ID}"
- "CICD_PROJECT_ID=${_CICD_PROJECT_ID}"
- "TEST_PROJECT_ID=${_TEST_PROJECT_ID}"

- id: do_functional_tests_on_dag
name: "${_BUILDER_IMAGE_NAME}:${_BUILDER_IMAGE_TAG}"
args:
- "-e"
- "-c"
- >-
export PROJECT_ID=${_TEST_PROJECT_ID};
(cd /workspace/build/test && make dag-test);
entrypoint: /bin/bash
env:
- "LOCATION=${_REGION}"
- "COMPOSER_ENV_NAME=dpu-composer"
- "DAG_ID=run_docs_processing"
Expand All @@ -106,7 +111,8 @@ options:
logging: CLOUD_LOGGING_ONLY

substitutions:
_TEST_PROJECT_ID: "eks-int-${SHORT_SHA}"
_TEST_PROJECT_ID: "eks-int-${BUILD_ID:0:8}"
_CICD_PROJECT_ID: ${PROJECT_ID}
_DEPLOYER_SA: "deployer@${_TEST_PROJECT_ID}.iam.gserviceaccount.com"
_REGION: "us-central1"
_DOC_AI_LOCATION: "us"
Expand Down
12 changes: 6 additions & 6 deletions build/test/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@
# See the License for the specific language governing permissions and
# limitations under the License.

e2e-test: ## Run the end-to-end test
@echo "Running E2E test..."
@go test -v -run ./ -timeout 90m --tags=e2e
infra-test: ## Deploy infrastructure
@echo "Running infrastructure deployment test..."
@go test -v -run ./ -timeout 90m --tags=infra

functional-test: ## upload documents, trigger workflows, and check the results
@echo "running functional test..."
@go test -v -run ./ -timeout 60m --tags=functional
dag-test: ## upload documents, trigger workflows, and check the results
@echo "running functional test against Composer workflows..."
@go test -v -run ./ -timeout 90m --tags=dag

.PHONY: help
.DEFAULT_GOAL := help
Expand Down
117 changes: 117 additions & 0 deletions build/test/composer_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//go:build dag

package test

import (
"context"
"fmt"
"log"
"os/exec"
"regexp"
"strings"
"testing"
"time"

envconfig "github.com/sethvargo/go-envconfig"
"github.com/stretchr/testify/assert"
)

type CLIConfig struct {
PROJECT_ID string `env:"PROJECT_ID"`
LOCATION string `env:"LOCATION"`
COMPOSER_ENV_NAME string `env:"COMPOSER_ENV_NAME"`
DAG_ID string `env:"DAG_ID"`
}

var c CLIConfig

func init() {
ctx := context.Background()
if err := envconfig.Process(ctx, &c); err != nil {
log.Fatal(err)
}
}

type AssertionFunc func(string) bool

func runCommand(cmd *exec.Cmd) string {
originalArgs := cmd.Args
// Create a new Cmd instance for each retry with the original arguments (excluding cmd.Path), otherwise fails on second attempt
cmd = exec.Command(originalArgs[0], originalArgs[1:]...)
fmt.Println("Executing command: `", cmd, "`")
output, err := cmd.CombinedOutput()
if err != nil {
fmt.Println("Command failed with the following error: ", err)
}
return string(output)
}

func runCommandWithPolling(cmd *exec.Cmd, f AssertionFunc, retryAttempts int, retryInterval time.Duration) string {
for i := 0; i < retryAttempts; i++ {
fmt.Println("Attempt", i+1, "of", retryAttempts)
result := runCommand(cmd)

// trigger_workflow.sh returns ANSI escaped characters for formatting, remove these for testing string results
re := regexp.MustCompile(`\x1b\[[0-9;]*[mG]`)
result = re.ReplaceAllString(result, "")

fmt.Println("Output:", result)
if f(result) {
return result
}

fmt.Println("Assertion failed, sleeping for", retryInterval, "before trying again")
time.Sleep(retryInterval)
}
log.Fatal("Fatal error: initial stage failed, terminating without proceeding to later stages which depend on initial stages")
return "terminating without running later dependent stages"

}

func TestDagIsAvailable(t *testing.T) {
cmd := exec.Command("gcloud", "composer", "environments", "run", c.COMPOSER_ENV_NAME, "--project", c.PROJECT_ID, "--location", c.LOCATION, "dags", "list")
stringToMatch := c.DAG_ID

result := runCommandWithPolling(cmd, func(tmp string) bool {
return strings.Contains(tmp, stringToMatch)
}, 5, 30*time.Second)

assert.Contains(t, result, stringToMatch)
}

func TestDAGIsTriggered(t *testing.T) {
cmd := exec.Command("../../sample-deployments/composer-orchestrated-process/scripts/trigger_workflow.sh")
stringToMatch := "Trigger DAG - done"

result := runCommandWithPolling(cmd, func(tmp string) bool {
return strings.Contains(tmp, stringToMatch)
}, 5, 1*time.Minute) // flaky propagation delay, might require retry even after TestDagIsAvailable

assert.Contains(t, result, stringToMatch)
}

func TestDAGIsCompleteAndSuccess(t *testing.T) {
cmd := exec.Command("gcloud", "composer", "environments", "run", c.COMPOSER_ENV_NAME, "--project", c.PROJECT_ID, "--location", c.LOCATION, "dags", "list-runs", "--", "-d", c.DAG_ID)
stringToMatch := "| running |"

result := runCommandWithPolling(cmd, func(tmp string) bool {
return !strings.Contains(tmp, stringToMatch)
}, 6, 10*time.Minute) // Workflow takes 35~50 minutes to complete, might be greater depending on input documents

assert.NotContains(t, result, stringToMatch)
assert.Contains(t, result, "| success |")
}
63 changes: 0 additions & 63 deletions build/test/functional_test.go

This file was deleted.

Loading

0 comments on commit cf8d18d

Please sign in to comment.