diff --git a/.github/workflows/integrate.yaml b/.github/workflows/integrate.yaml index 17f5fc26..f5749122 100644 --- a/.github/workflows/integrate.yaml +++ b/.github/workflows/integrate.yaml @@ -8,6 +8,26 @@ on: required: true jobs: + build: + name: Build charm + uses: canonical/data-platform-workflows/.github/workflows/build_charm.yaml@v21.0.0 + strategy: + fail-fast: false + matrix: + charm: + - kfp-api + - kfp-metadata-writer + - kfp-persistence + - kfp-profile-controller + - kfp-schedwf + - kfp-ui + - kfp-viewer + - kfp-viz + with: + cache: ${{ github.event_name == 'pull_request' }} + charmcraft-snap-channel: 3.x/edge + path-to-charm-directory: ./charms/${{ matrix.charm }} + lib-check: name: Check libraries strategy: @@ -42,7 +62,7 @@ jobs: - kfp-viewer - kfp-viz steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - run: python3 -m pip install tox - run: tox -e ${{ matrix.charm }}-lint @@ -62,7 +82,7 @@ jobs: - kfp-viewer - kfp-viz steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - run: python3 -m pip install tox - run: tox -e ${{ matrix.charm }}-unit @@ -90,6 +110,7 @@ jobs: integration: name: Integration tests (microk8s) runs-on: ubuntu-20.04 + needs: [build] strategy: fail-fast: false matrix: @@ -111,7 +132,7 @@ jobs: - name: Maximise GH runner space uses: jlumbroso/free-disk-space@v1.3.1 - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup operator environment uses: charmed-kubernetes/actions-operator@main @@ -122,6 +143,15 @@ jobs: # Pinned to 3.x/stable due to https://github.com/canonical/charmcraft/issues/1845 charmcraft-channel: 3.x/stable + - name: Download packed charm(s) + id: download-charms + timeout-minutes: 5 + uses: actions/download-artifact@v4 + with: + pattern: packed-charm-cache-true-.-charms-${{ matrix.charm }}-* + merge-multiple: true + path: /tmp/ + - name: Integration tests run: | # Requires the model to be called kubeflow due to @@ -129,58 +159,55 @@ jobs: juju add-model kubeflow sg snap_microk8s -c "tox -e ${{ matrix.charm }}-integration -- --model kubeflow" - - name: Collect charm debug artifacts - uses: canonical/kubeflow-ci/actions/dump-charm-debug-artifacts@main - if: always() - - test-bundle: - name: Test the bundle - runs-on: ubuntu-20.04 - strategy: - fail-fast: false - matrix: - sdk: - - v1 - - v2 - steps: - # This is a workaround for https://github.com/canonical/kfp-operators/issues/250 - # Ideally we'd use self-hosted runners, but this effort is still not stable - # This action will remove unused software (dotnet, haskell, android libs, codeql, - # and docker images) from the GH runner. - # This leaves ~45GB free as of 2024-04-10, but this amount has varied as GH changed their - # runners - - name: Maximise GH runner space - uses: jlumbroso/free-disk-space@v1.3.1 - - - name: Check out code - uses: actions/checkout@v3 - - - name: Setup operator environment - uses: charmed-kubernetes/actions-operator@main - with: - provider: microk8s - channel: 1.29-strict/stable - juju-channel: 3.6/stable - # Pinned to 3.x/stable due to https://github.com/canonical/charmcraft/issues/1845 - charmcraft-channel: 3.x/stable - microk8s-addons: "dns hostpath-storage rbac metallb:10.64.140.43-10.64.140.49" - - - name: Run test - run: | - # Requires the model to be called kubeflow due to kfp-viewer - juju add-model kubeflow - sg snap_microk8s -c "tox -e bundle-integration-${{ matrix.sdk }} -- --model kubeflow --bundle=./tests/integration/bundles/kfp_latest_edge.yaml.j2" --charmcraft-clean - - - name: Get all - run: kubectl get all -A - if: failure() - - - name: Get juju status - run: juju status - if: failure() - - # Collect debug artefacts only on failure || cancelled as the CI for this repository - # in particular struggles with storage limitations. - - name: Collect charm debug artifacts - uses: canonical/kubeflow-ci/actions/dump-charm-debug-artifacts@main - if: failure() || cancelled() +# test-bundle: +# name: Test the bundle +# runs-on: ubuntu-20.04 +# needs: [build] +# strategy: +# fail-fast: false +# matrix: +# sdk: +# - v1 +# - v2 +# steps: +# # This is a workaround for https://github.com/canonical/kfp-operators/issues/250 +# # Ideally we'd use self-hosted runners, but this effort is still not stable +# # This action will remove unused software (dotnet, haskell, android libs, codeql, +# # and docker images) from the GH runner. +# # This leaves ~45GB free as of 2024-04-10, but this amount has varied as GH changed their +# # runners +# - name: Maximise GH runner space +# uses: jlumbroso/free-disk-space@v1.3.1 +# +# - name: Check out code +# uses: actions/checkout@v4 +# +# - name: Setup operator environment +# uses: charmed-kubernetes/actions-operator@main +# with: +# provider: microk8s +# channel: 1.29-strict/stable +# juju-channel: 3.6/stable +# # Pinned to 3.x/stable due to https://github.com/canonical/charmcraft/issues/1845 +# charmcraft-channel: 3.x/stable +# microk8s-addons: "dns hostpath-storage rbac metallb:10.64.140.43-10.64.140.49" +# +# - name: Run test +# run: | +# # Requires the model to be called kubeflow due to kfp-viewer +# juju add-model kubeflow +# sg snap_microk8s -c "tox -e bundle-integration-${{ matrix.sdk }} -- --model kubeflow --bundle=./tests/integration/bundles/kfp_latest_edge.yaml.j2" --charmcraft-clean +# +# - name: Get all +# run: kubectl get all -A +# if: failure() +# +# - name: Get juju status +# run: juju status +# if: failure() +# +# # Collect debug artefacts only on failure || cancelled as the CI for this repository +# # in particular struggles with storage limitations. +# - name: Collect charm debug artifacts +# uses: canonical/kubeflow-ci/actions/dump-charm-debug-artifacts@main +# if: failure() || cancelled() diff --git a/charms/kfp-api/tests/integration/test_charm.py b/charms/kfp-api/tests/integration/test_charm.py index 22e4374d..38badddd 100644 --- a/charms/kfp-api/tests/integration/test_charm.py +++ b/charms/kfp-api/tests/integration/test_charm.py @@ -52,22 +52,12 @@ async def test_build_and_deploy(self, ops_test: OpsTest): resources = {"oci-image": image_path} await ops_test.model.deploy( - entity_url=built_charm_path, + entity_url="/tmp/packed-charm-cache-true-.-charms-kfp-api-base-0", application_name=APP_NAME, resources=resources, trust=True, ) - # FIXME: we should probably stop deploying mariadb as: - # 1) The team has acceped and started using mysql-k8s more extensively - # 2) The repository level integration tests use mysql-k8s only - await ops_test.model.deploy( - entity_url=MARIADB_CHARM, - application_name=KFP_DB, - config=MARIADB_CONFIG, - channel=MARIADB_CHANNEL, - trust=MARIADB_TRUST, - ) await ops_test.model.deploy( entity_url=MINIO, config=MINIO_CONFIG, channel=MINIO_CHANNEL, trust=MINIO_TRUST ) @@ -75,133 +65,30 @@ async def test_build_and_deploy(self, ops_test: OpsTest): entity_url=KFP_VIZ, channel=KFP_VIZ_CHANNEL, trust=KFP_VIZ_TRUST ) - # FIXME: This assertion belongs to unit tests - # test no database relation, charm should be in blocked state - # assert ops_test.model.applications[APP_NAME].units[0].workload_status == "blocked" - - await ops_test.model.add_relation(f"{APP_NAME}:mysql", f"{KFP_DB}:mysql") await ops_test.model.add_relation(f"{APP_NAME}:object-storage", f"{MINIO}:object-storage") await ops_test.model.add_relation(f"{APP_NAME}:kfp-viz", f"{KFP_VIZ}:kfp-viz") - await ops_test.model.wait_for_idle( - apps=[APP_NAME, KFP_VIZ, KFP_DB, MINIO], - status="active", - raise_on_blocked=False, - raise_on_error=False, - timeout=90 * 20, - ) - # Deploying grafana-agent-k8s and add all relations - await deploy_and_assert_grafana_agent( - ops_test.model, APP_NAME, metrics=True, dashboard=True, logging=True - ) - - # FIXME: this test case belongs in unit tests as it is asserting the status of the - # unit under a certain condition, we don't actually need the presence of any deployed - # charm to test this. - @pytest.mark.abort_on_fail - async def test_relational_db_relation_with_mysql_relation(self, ops_test: OpsTest): - """Test failure of addition of relational-db relation with mysql relation present.""" - # deploy mysql-k8s charm await ops_test.model.deploy( MYSQL, channel=MYSQL_CHANNEL, + application_name=KFP_DB, config=MYSQL_CONFIG, trust=MYSQL_TRUST, ) + await ops_test.model.relate(f"{APP_NAME}:relational-db", f"{KFP_DB}:database") await ops_test.model.wait_for_idle( - apps=[MYSQL], - status="active", - raise_on_blocked=True, - timeout=90 * 30, - idle_period=20, - ) - - # add relational-db relation which should put charm into blocked state, - # because at this point mysql relation is already established - await ops_test.model.relate(f"{APP_NAME}:relational-db", f"{MYSQL}:database") - - # verify that charm goes into blocked state - await ops_test.model.wait_for_idle( - apps=[APP_NAME], - status="blocked", - raise_on_blocked=False, - raise_on_error=True, - timeout=60 * 10, - idle_period=10, - ) - assert ops_test.model.applications[APP_NAME].units[0].workload_status == "blocked" - - # remove just added relational-db relation - await ops_test.juju("remove-relation", f"{APP_NAME}:relational-db", f"{MYSQL}:database") - - # FIXME: this test case belongs in unit tests as it is asserting the status of the - # unit under a certain condition, we don't actually need the presence of any deployed - # charm to test this. - @pytest.mark.abort_on_fail - async def test_relational_db_relation_with_mysql_k8s(self, ops_test: OpsTest): - """Test no relation and relation with mysql-k8s charm.""" - - # verify that charm is active state - await ops_test.model.wait_for_idle( - apps=[APP_NAME], - status="active", - raise_on_blocked=False, - raise_on_error=True, - timeout=60 * 10, - ) - assert ops_test.model.applications[APP_NAME].units[0].workload_status == "active" - - # remove existing mysql relation which should put charm into blocked state, - # because there will be no database relations - await ops_test.juju("remove-relation", f"{APP_NAME}:mysql", f"{KFP_DB}:mysql") - - # verify that charm goes into blocked state - await ops_test.model.wait_for_idle( - apps=[APP_NAME], - status="blocked", - raise_on_blocked=False, - raise_on_error=True, - timeout=60 * 10, - ) - assert ops_test.model.applications[APP_NAME].units[0].workload_status == "blocked" - - # add relational-db relation which should put charm into active state - await ops_test.model.relate(f"{APP_NAME}:relational-db", f"{MYSQL}:database") - - # verify that charm goes into active state - await ops_test.model.wait_for_idle( - apps=[APP_NAME], + apps=[APP_NAME, KFP_VIZ, KFP_DB, MINIO], status="active", raise_on_blocked=False, - raise_on_error=True, - timeout=60 * 10, + raise_on_error=False, + timeout=90 * 20, ) - assert ops_test.model.applications[APP_NAME].units[0].workload_status == "active" - - # FIXME: this test case belongs in unit tests as it is asserting the status of the - # unit under a certain condition, we don't actually need the presence of any deployed - # charm to test this. - @pytest.mark.abort_on_fail - async def test_msql_relation_with_relational_db_relation(self, ops_test: OpsTest): - """Test failure of addition of mysql relation with relation-db relation present.""" - - # add mysql relation which should put charm into blocked state, - # because at this point relational-db relation is already established - await ops_test.model.relate(f"{APP_NAME}:mysql", f"{KFP_DB}:mysql") - # verify that charm goes into blocked state - await ops_test.model.wait_for_idle( - apps=[APP_NAME], - status="blocked", - raise_on_blocked=False, - raise_on_error=True, - timeout=60 * 10, + # Deploying grafana-agent-k8s and add all relations + await deploy_and_assert_grafana_agent( + ops_test.model, APP_NAME, metrics=True, dashboard=True, logging=True ) - assert ops_test.model.applications[APP_NAME].units[0].workload_status == "blocked" - - # remove redundant relation - await ops_test.juju("remove-relation", f"{APP_NAME}:mysql", f"{KFP_DB}:mysql") async def test_alert_rules(self, ops_test: OpsTest): """Test check charm alert rules and rules defined in relation data bag."""