Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 28 additions & 40 deletions .github/workflows/acceptance.yml
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
# Acceptance test workflow — spins up a real OpenMetadata instance via
# docker compose (official release image) and runs TF_ACC=1 tests against it.
#
# The docker-compose.yml in docker/test/ is the verbatim official release file.
# docker/test/.env contains only the test-specific overrides (heap, log level,
# disable Airflow). To update to a new OM version, run:
# ./scripts/update-test-compose.sh
# then commit the updated docker-compose.yml and .env.
# To add a new version: add it to the matrix below and update docker/test/.env
# default if desired.
#
# Runs on pushes to main and PRs that touch the provider or its test harness —
# doc and config changes do not need a live OpenMetadata stack. Because a
# path-filtered workflow never reports its check, this one must NOT be a
# required status check, or unrelated PRs would block forever.
# Can also be triggered manually to test a specific version.
name: Acceptance Tests

on:
Expand All @@ -25,6 +21,7 @@ on:
- 'go.sum'
- 'docker/test/**'
- 'scripts/testacc.sh'
- 'scripts/testacc-all.sh'
- '.github/workflows/acceptance.yml'
pull_request:
paths:
Expand All @@ -34,68 +31,60 @@ on:
- 'go.sum'
- 'docker/test/**'
- 'scripts/testacc.sh'
- 'scripts/testacc-all.sh'
- '.github/workflows/acceptance.yml'
workflow_dispatch:
inputs:
openmetadata_version:
description: "OpenMetadata version (e.g. 1.12.4) — updates .env before running"
required: false
default: ""

permissions:
contents: read

jobs:
acceptance:
name: Acceptance Tests
name: "OM ${{ matrix.om_version }}"
runs-on: ubuntu-latest
timeout-minutes: 40

strategy:
fail-fast: false
matrix:
om_version:
- "1.12.4"
- "2.0.3"

env:
OM_HOST: "http://localhost:8585"
# Health check is on the admin port (8586), not the API port (8585).
OM_HEALTH_URL: "http://localhost:8586/healthcheck"
OM_ADMIN_EMAIL: "admin@open-metadata.org"
# Override via repo secret OM_ADMIN_PASSWORD if the default changes.
# Default is "admin" — the seeded password in the official OM DB image.
OM_ADMIN_PASSWORD: ${{ secrets.OM_ADMIN_PASSWORD || 'admin' }}
# Passed to docker compose — overrides OPENMETADATA_VERSION in .env.
OPENMETADATA_VERSION: ${{ matrix.om_version }}

steps:
# ── Checkout ────────────────────────────────────────────────────────────
# ── Checkout ──────────────────────────────────────────────────────────────
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

# ── Optionally override the version in .env ──────────────────────────────
- name: Override OPENMETADATA_VERSION
if: inputs.openmetadata_version != ''
# Via env, not direct interpolation — the input must not reach the shell as code.
env:
OM_VERSION: ${{ inputs.openmetadata_version }}
run: |
sed -i "s/^OPENMETADATA_VERSION=.*/OPENMETADATA_VERSION=${OM_VERSION}/" docker/test/.env
echo "Using OpenMetadata version: ${OM_VERSION}"

# ── Go toolchain ────────────────────────────────────────────────────────
# ── Go toolchain ──────────────────────────────────────────────────────────
- uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version-file: go.mod
cache: true

# ── Terraform CLI (required by terraform-plugin-testing) ─────────────────
# ── Terraform CLI (required by terraform-plugin-testing) ──────────────────
- uses: hashicorp/setup-terraform@dfe3c3f87815947d99a8997f908cb6525fc44e9e # v4.0.1
with:
terraform_wrapper: false

# ── Tune kernel for Elasticsearch ────────────────────────────────────────
# ── Tune kernel for Elasticsearch ─────────────────────────────────────────
# Elasticsearch 9.x requires vm.max_map_count ≥ 262144.
- name: Set vm.max_map_count for Elasticsearch
run: sudo sysctl -w vm.max_map_count=262144

# ── Start OpenMetadata test stack ────────────────────────────────────────
# We start only the services needed for provider tests — mysql, elasticsearch,
# execute-migrate-all (DB migration), and openmetadata-server.
# The heavy `ingestion` (Airflow) service is intentionally excluded;
# PIPELINE_SERVICE_CLIENT_ENABLED=false in docker/test/.env means
# the OM server will not try to reach Airflow.
# ── Start OpenMetadata test stack ─────────────────────────────────────────
# OPENMETADATA_VERSION is set at the job level — docker compose picks it up
# from the shell environment, which takes precedence over the .env file.
# We skip the heavy `ingestion` (Airflow) service; PIPELINE_SERVICE_CLIENT_ENABLED=false
# in docker/test/.env means the OM server will not try to reach it.
- name: Pull images
run: |
docker compose \
Expand All @@ -112,10 +101,10 @@ jobs:
up -d \
mysql elasticsearch execute-migrate-all openmetadata-server

# ── Wait for OpenMetadata ────────────────────────────────────────────────
# ── Wait for OpenMetadata ──────────────────────────────────────────────────
- name: Wait for OpenMetadata to be healthy
run: |
echo "Polling ${OM_HEALTH_URL} (up to 10 minutes)..."
echo "Polling ${OM_HEALTH_URL} for OpenMetadata ${OPENMETADATA_VERSION} (up to 10 minutes)..."
for i in $(seq 1 60); do
if curl -sf "${OM_HEALTH_URL}" > /dev/null 2>&1; then
echo "OpenMetadata is ready after $((i * 10))s"
Expand All @@ -131,11 +120,10 @@ jobs:
logs openmetadata-server --tail=100
exit 1

# ── Acquire JWT token ────────────────────────────────────────────────────
# ── Acquire JWT token ──────────────────────────────────────────────────────
- name: Acquire JWT token
id: auth
run: |
# OM requires the password to be base64-encoded in the login payload.
OM_ADMIN_PASSWORD_B64="$(echo -n "${OM_ADMIN_PASSWORD}" | base64)"
PAYLOAD_FILE="$(mktemp)"
printf '{"email":"%s","password":"%s"}' "${OM_ADMIN_EMAIL}" "${OM_ADMIN_PASSWORD_B64}" > "${PAYLOAD_FILE}"
Expand Down Expand Up @@ -170,7 +158,7 @@ jobs:
echo "token=${TOKEN}" >> "${GITHUB_OUTPUT}"
echo "JWT token acquired (length: ${#TOKEN})"

# ── Run acceptance tests ─────────────────────────────────────────────────
# ── Run acceptance tests ───────────────────────────────────────────────────
- name: Run acceptance tests
env:
TF_ACC: "1"
Expand All @@ -183,7 +171,7 @@ jobs:
-timeout 25m \
./internal/provider/...

# ── Tear down (always runs) ──────────────────────────────────────────────
# ── Tear down (always runs) ────────────────────────────────────────────────
- name: Tear down test stack
if: always()
run: |
Expand Down
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ dist/
*.tfplan
crash.log

# Docker — volume data written by docker compose (never commit runtime data)
# Docker — volume data written by docker compose (never commit runtime data).
# mysql-data is now a named volume (cleaned by `docker compose down -v`).
# The docker-volume dir may still contain other bind-mount leftovers.
docker/test/docker-volume/

# Claude Code — local agent config, memory, and skills (dev-only, not project files)
Expand Down
22 changes: 15 additions & 7 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ ARCH := $(shell go env GOARCH 2>/dev/null || echo amd64)
# Terraform plugin directory
TF_PLUGIN_DIR := $(HOME)/.terraform.d/plugins/registry.terraform.io/codility/openmetadata/$(VERSION)/$(OS)_$(ARCH)

.PHONY: build install clean fmt lint test testacc testacc-external update-test-compose docs codegen deps help
.PHONY: build install clean fmt lint test testacc testacc-all testacc-external update-test-compose docs codegen deps help

## Build the provider binary
build:
Expand All @@ -35,9 +35,16 @@ test:
go test -v -count=1 ./...

## Run acceptance tests against a local docker-compose OpenMetadata stack.
## Starts the stack, acquires a JWT, runs TF_ACC=1 tests, and tears down.
## Uses the default version from docker/test/.env, or override with OM_VERSION:
## make testacc
## make testacc OM_VERSION=2.0.3
testacc:
@bash scripts/testacc.sh
@OM_VERSION="$(OM_VERSION)" bash scripts/testacc.sh

## Run acceptance tests against all versions listed in docker/test/versions.
## Versions are tested sequentially; exits 1 if any version fails.
testacc-all:
@bash scripts/testacc-all.sh

## Run acceptance tests against an already-running OpenMetadata instance.
## Requires OPENMETADATA_HOST and OPENMETADATA_TOKEN to be exported.
Expand All @@ -47,11 +54,12 @@ testacc:
testacc-external:
TF_ACC=1 go test -v -count=1 -timeout 30m ./internal/provider/...

## Re-download the official OpenMetadata docker-compose.yml for the version
## pinned in docker/test/.env. Run this when bumping OPENMETADATA_VERSION,
## then commit both docker/test/docker-compose.yml and docker/test/.env.
## Re-download and re-parameterize the official OpenMetadata docker-compose.yml.
## Pass OM_VERSION to fetch a specific release (defaults to the version in .env):
## make update-test-compose
## make update-test-compose OM_VERSION=2.0.3
update-test-compose:
@bash scripts/update-test-compose.sh
@bash scripts/update-test-compose.sh $(OM_VERSION)

## Generate provider documentation (requires tfplugindocs)
docs:
Expand Down
24 changes: 15 additions & 9 deletions docker/test/.env
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
# OpenMetadata acceptance-test environment overrides.
#
# This file is loaded by docker compose alongside the official OpenMetadata
# docker-compose.yml (which already uses ${VAR:-default} for every setting).
# Only values that differ from the upstream defaults are listed here.
# This file is loaded by docker compose alongside docker-compose.yml, which
# uses ${VAR:-default} for every setting. Only values that differ from the
# upstream defaults are listed here.
#
# HOW TO UPGRADE TO A NEW OM VERSION
# ────────────────────────────────────
# RUNNING AGAINST A DIFFERENT VERSION
# ─────────────────────────────────────
# Override OPENMETADATA_VERSION via an environment variable — it takes
# precedence over the value in this file:
#
# OPENMETADATA_VERSION=2.0.3 make testacc
# OM_VERSION=2.0.3 make testacc # make target maps OM_VERSION → env var
#
# HOW TO BUMP THE DEFAULT VERSION
# ─────────────────────────────────
# 1. Update OPENMETADATA_VERSION below.
# 2. Run: ./scripts/update-test-compose.sh
# This re-downloads the official docker-compose.yml from that release.
# 3. Commit both docker/test/docker-compose.yml and docker/test/.env.
# 2. Commit.

# ── Version ───────────────────────────────────────────────────────────────────
# ── Default version ────────────────────────────────────────────────────────────
OPENMETADATA_VERSION=1.12.4

# ── Heap reduction (saves ~1 GB on CI runners vs. the 2 GB upstream default) ──
Expand Down
11 changes: 6 additions & 5 deletions docker/test/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ volumes:
ingestion-volume-dags:
ingestion-volume-tmp:
es-data:
mysql-data: # named volume so `docker compose down -v` fully cleans the DB
services:
mysql:
container_name: openmetadata_mysql
image: docker.getcollate.io/openmetadata/db:1.12.4
image: docker.getcollate.io/openmetadata/db:${OPENMETADATA_VERSION}
command: "--sort_buffer_size=10M"
restart: always
environment:
Expand All @@ -28,7 +29,7 @@ services:
ports:
- "3306:3306"
volumes:
- ./docker-volume/db-data:/var/lib/mysql
- mysql-data:/var/lib/mysql
networks:
- app_net
healthcheck:
Expand Down Expand Up @@ -59,7 +60,7 @@ services:

execute-migrate-all:
container_name: execute_migrate_all
image: docker.getcollate.io/openmetadata/server:1.12.4
image: docker.getcollate.io/openmetadata/server:${OPENMETADATA_VERSION}
command: "./bootstrap/openmetadata-ops.sh migrate"
environment:
OPENMETADATA_CLUSTER_NAME: ${OPENMETADATA_CLUSTER_NAME:-openmetadata}
Expand Down Expand Up @@ -284,7 +285,7 @@ services:
openmetadata-server:
container_name: openmetadata_server
restart: always
image: docker.getcollate.io/openmetadata/server:1.12.4
image: docker.getcollate.io/openmetadata/server:${OPENMETADATA_VERSION}
environment:
OPENMETADATA_CLUSTER_NAME: ${OPENMETADATA_CLUSTER_NAME:-openmetadata}
SERVER_PORT: ${SERVER_PORT:-8585}
Expand Down Expand Up @@ -504,7 +505,7 @@ services:

ingestion:
container_name: openmetadata_ingestion
image: docker.getcollate.io/openmetadata/ingestion:1.12.4
image: docker.getcollate.io/openmetadata/ingestion:${OPENMETADATA_VERSION}
depends_on:
elasticsearch:
condition: service_started
Expand Down
11 changes: 11 additions & 0 deletions docker/test/versions
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Supported OpenMetadata versions for acceptance tests.
# First non-comment line is the default used by `make testacc` (no OM_VERSION set).
# To add a new version:
# 1. Add the version here.
# 2. Run: make update-test-compose OM_VERSION=<version>
# This downloads the official docker-compose.yml into docker/test/<version>/.
# 3. Copy docker/test/<existing>/.env to docker/test/<version>/.env and update
# OPENMETADATA_VERSION.
# 4. Commit docker/test/<version>/.env and docker/test/<version>/docker-compose.yml.
1.12.4
2.0.3
57 changes: 57 additions & 0 deletions internal/provider/team_resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,46 @@ func TestAccTeamResourceWithEmail(t *testing.T) {
})
}

// TestAccTeamResourceWithParents verifies that a team can be placed under a
// parent team using the parents field. parents is preserved in state from the
// plan (not re-read from the API) so no drift occurs on subsequent plans.
// Import ignores parents because the API does not expose them in a form we can
// round-trip back to the user-supplied names.
func TestAccTeamResourceWithParents(t *testing.T) {
parentName := testRandName("tp")
childName := testRandName("tc")

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
// ── Create parent and child ────────────────────────────────────────
{
Config: testAccTeamConfigWithParents(parentName, childName),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("openmetadata_team.parent", "name", parentName),
resource.TestCheckResourceAttr("openmetadata_team.child", "name", childName),
resource.TestCheckResourceAttr("openmetadata_team.child", "team_type", "Department"),
resource.TestCheckResourceAttr("openmetadata_team.child", "parents.#", "1"),
resource.TestCheckResourceAttr("openmetadata_team.child", "parents.0", parentName),
resource.TestCheckResourceAttrSet("openmetadata_team.child", "id"),
),
},
// ── Import child ────────────────────────────────────────────────
{
ResourceName: "openmetadata_team.child",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"parents"},
ImportStateIdFunc: func(s *terraform.State) (string, error) {
rs := s.RootModule().Resources["openmetadata_team.child"]
return rs.Primary.Attributes["name"], nil
},
},
},
})
}

func testAccTeamConfig(name, description, teamType string) string {
return fmt.Sprintf(`
%s
Expand All @@ -100,3 +140,20 @@ resource "openmetadata_team" "test" {
}
`, testProviderBlock(), name, email)
}

func testAccTeamConfigWithParents(parentName, childName string) string {
return fmt.Sprintf(`
%s

resource "openmetadata_team" "parent" {
name = %q
team_type = "Department"
}

resource "openmetadata_team" "child" {
name = %q
team_type = "Department"
parents = [openmetadata_team.parent.name]
}
`, testProviderBlock(), parentName, childName)
}
Loading