Skip to content
Merged
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
39 changes: 39 additions & 0 deletions acceptance/bin/verify_no_drift.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/usr/bin/env python3
"""
Check that all actions in plan are "skip".
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe verify_no_drift.py?

"""

import sys
import json
import pprint


def check_plan(path):
with open(path) as fobj:
raw = fobj.read()

changes_detected = 0

try:
data = json.loads(raw)
for key, value in data["plan"].items():
action = value.get("action")
if action != "skip":
print(f"Unexpected {action=} for {key}")
changes_detected += 1
except Exception:
print(raw, flush=True)
raise

if changes_detected:
print(raw, flush=True)
sys.exit(10)


def main():
for path in sys.argv[1:]:
check_plan(path)


if __name__ == "__main__":
main()
6 changes: 6 additions & 0 deletions acceptance/bundle/invariant/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Invariant tests are acceptance tests that can be run against many configs to check for certain properties.
Unlike regular acceptance tests full output is not recorded, unless the condition is not met. For example,
no_drift test checks that there are no actions planned after successful deploy. If that's not the case, the
test will dump full JSON plan to the output.

In order to add a new test, add a config to configs/ and include it in test.toml.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ones in this PR are specific to bundles. Will they generalize? If not, they can be moved the bundles dir.

9 changes: 9 additions & 0 deletions acceptance/bundle/invariant/configs/alert.yml.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
bundle:
name: test-bundle-$UNIQUE_NAME

resources:
alerts:
foo:
warehouse_id: $TEST_DEFAULT_WAREHOUSE_ID
display_name: test-alert-$UNIQUE_NAME
file_path: ./alert.dbalert.json
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shreyas-goenka Do we need one with the alert inlined?

8 changes: 8 additions & 0 deletions acceptance/bundle/invariant/configs/app.yml.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
bundle:
name: test-bundle-$UNIQUE_NAME

resources:
apps:
foo:
name: app-$UNIQUE_NAME
source_code_path: ./app
10 changes: 10 additions & 0 deletions acceptance/bundle/invariant/configs/cluster.yml.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
bundle:
name: test-bundle-$UNIQUE_NAME

resources:
clusters:
foo:
cluster_name: test-cluster-$UNIQUE_NAME
spark_version: 13.3.x-scala2.12
node_type_id: i3.xlarge
num_workers: 1
9 changes: 9 additions & 0 deletions acceptance/bundle/invariant/configs/dashboard.yml.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
bundle:
name: test-bundle-$UNIQUE_NAME

resources:
dashboards:
foo:
warehouse_id: $TEST_DEFAULT_WAREHOUSE_ID
display_name: test-dashboard-$UNIQUE_NAME
file_path: ./dashboard.lvdash.json
15 changes: 15 additions & 0 deletions acceptance/bundle/invariant/configs/database_catalog.yml.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
bundle:
name: test-bundle-$UNIQUE_NAME

resources:
database_instances:
instance1:
name: test-db-instance-$UNIQUE_NAME
capacity: CU_1

database_catalogs:
foo:
database_instance_name: ${resources.database_instances.instance1.name}
database_name: test_db
name: test-catalog-$UNIQUE_NAME
create_database_if_not_exists: true
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
bundle:
name: test-bundle-$UNIQUE_NAME

resources:
database_instances:
foo:
name: test-db-instance-$UNIQUE_NAME
capacity: CU_1
7 changes: 7 additions & 0 deletions acceptance/bundle/invariant/configs/experiment.yml.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
bundle:
name: test-bundle-$UNIQUE_NAME

resources:
experiments:
foo:
name: /Users/$CURRENT_USER_NAME/test-experiment-$UNIQUE_NAME
7 changes: 7 additions & 0 deletions acceptance/bundle/invariant/configs/job.yml.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
bundle:
name: test-bundle-$UNIQUE_NAME

resources:
jobs:
foo:
name: test-job-$UNIQUE_NAME
7 changes: 7 additions & 0 deletions acceptance/bundle/invariant/configs/model.yml.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
bundle:
name: test-bundle-$UNIQUE_NAME

resources:
models:
foo:
name: test-model-$UNIQUE_NAME
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
bundle:
name: test-bundle-$UNIQUE_NAME

resources:
model_serving_endpoints:
foo:
name: test-endpoint-$UNIQUE_NAME
10 changes: 10 additions & 0 deletions acceptance/bundle/invariant/configs/pipeline.yml.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
bundle:
name: test-bundle-$UNIQUE_NAME

resources:
pipelines:
foo:
name: test-pipeline-$UNIQUE_NAME
libraries:
- file:
path: pipeline.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
bundle:
name: test-bundle-$UNIQUE_NAME

resources:
registered_models:
foo:
name: test-model-$UNIQUE_NAME
catalog_name: main
schema_name: default
8 changes: 8 additions & 0 deletions acceptance/bundle/invariant/configs/schema.yml.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
bundle:
name: test-bundle-$UNIQUE_NAME

resources:
schemas:
foo:
catalog_name: main
name: test-schema-$UNIQUE_NAME
8 changes: 8 additions & 0 deletions acceptance/bundle/invariant/configs/secret_scope.yml.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
bundle:
name: test-bundle-$UNIQUE_NAME

resources:
secret_scopes:
foo:
name: test-scope-$UNIQUE_NAME
backend_type: DATABRICKS
9 changes: 9 additions & 0 deletions acceptance/bundle/invariant/configs/sql_warehouse.yml.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
bundle:
name: test-bundle-$UNIQUE_NAME

resources:
sql_warehouses:
foo:
name: test-warehouse-$UNIQUE_NAME
cluster_size: X-Small
max_num_clusters: 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
bundle:
name: test-bundle-$UNIQUE_NAME

resources:
database_instances:
instance1:
name: test-db-instance-$UNIQUE_NAME
capacity: CU_1

database_catalogs:
catalog1:
database_instance_name: ${resources.database_instances.instance1.name}
database_name: test_db
name: test-catalog-$UNIQUE_NAME
create_database_if_not_exists: true

synced_database_tables:
foo:
name: ${resources.database_catalogs.catalog1.name}.${resources.database_catalogs.catalog1.database_name}.test_table
database_instance_name: ${resources.database_instances.instance1.name}
logical_database_name: ${resources.database_catalogs.catalog1.database_name}
spec:
source_table_full_name: samples.nyctaxi.trips
scheduling_policy: SNAPSHOT
primary_key_columns:
- tpep_pickup_datetime
9 changes: 9 additions & 0 deletions acceptance/bundle/invariant/configs/volume.yml.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
bundle:
name: test-bundle-$UNIQUE_NAME

resources:
volumes:
foo:
name: test-volume-$UNIQUE_NAME
catalog_name: main
schema_name: default
27 changes: 27 additions & 0 deletions acceptance/bundle/invariant/data/alert.dbalert.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"custom_summary": "test-alert",
"evaluation": {
"source": {
"name": "1",
"display": "1",
"aggregation": "MAX"
},
"comparison_operator": "EQUAL",
"threshold": {
"value": {
"double_value": 1.0
}
},
"notification": {
"retrigger_seconds": 60,
"notify_on_ok": false
}
},
"schedule": {
"quartz_cron_schedule": "0 0 * * * ?",
"timezone_id": "UTC"
},
"query_lines": [
"select 1"
]
}
8 changes: 8 additions & 0 deletions acceptance/bundle/invariant/data/app/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from flask import Flask

app = Flask(__name__)


@app.route("/")
def hello():
return "Hello"
1 change: 1 addition & 0 deletions acceptance/bundle/invariant/data/app/app.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
command: ["flask", "--app", "app", "run"]
1 change: 1 addition & 0 deletions acceptance/bundle/invariant/data/dashboard.lvdash.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"pages":[{"name":"page1","displayName":"Test Page"}]}
6 changes: 6 additions & 0 deletions acceptance/bundle/invariant/data/pipeline.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import dlt


@dlt.table
def my_table():
return spark.range(1)
7 changes: 7 additions & 0 deletions acceptance/bundle/invariant/no_drift/out.test.toml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions acceptance/bundle/invariant/no_drift/output.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
INPUT_CONFIG_OK
38 changes: 38 additions & 0 deletions acceptance/bundle/invariant/no_drift/script
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Invariant to test: no drift after deploy
# Additional checks: no internal errors / panics in validate/plan/deploy

# Copy data files to test directory
cp -r "$TESTDIR/../data/." . &> LOG.cp

envsubst < $TESTDIR/../configs/$INPUT_CONFIG > databricks.yml

cp databricks.yml LOG.config

# We redirect output rather than record it because some configs that are being tested may produce warnings
trace $CLI bundle validate &> LOG.validate

cat LOG.validate | contains.py '!panic' '!internal error' > /dev/null

cleanup() {
trace $CLI bundle destroy --auto-approve &> LOG.destroy
cat LOG.destroy | contains.py '!panic' '!internal error' > /dev/null
}

trap cleanup EXIT

trace $CLI bundle deploy &> LOG.deploy
cat LOG.deploy | contains.py '!panic' '!internal error' > /dev/null

# Special message to fuzzer that generated config was fine.
# Any failures after this point will be considered as "bug detected" by fuzzer.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fuzzer == vary over input configs?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes

echo INPUT_CONFIG_OK

$CLI bundle plan -o json &> plan.json
cat plan.json | contains.py '!panic' '!internal error' > /dev/null

# Check both text and JSON plan for no changes
# Note, expect that there maybe more than one resource unchanged
$CLI bundle plan | contains.py '!panic' '!internal error' 'Plan: 0 to add, 0 to change, 0 to delete' > LOG.plan

$CLI bundle plan -o json > plan.json
verify_no_drift.py plan.json
37 changes: 37 additions & 0 deletions acceptance/bundle/invariant/test.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
Local = true
Cloud = true
RequiresUnityCatalog = true

Ignore = [
".databricks",
"databricks.yml",
"plan.json",
"*.py",
"*.json",
"app",
]

EnvMatrix.DATABRICKS_BUNDLE_ENGINE = [
"direct",
# These tests work on terraform but commented out to save time on test run
#"terraform",
]

EnvMatrix.INPUT_CONFIG = [
"alert.yml.tmpl",
"app.yml.tmpl",
"cluster.yml.tmpl",
"dashboard.yml.tmpl",
"database_catalog.yml.tmpl",
"database_instance.yml.tmpl",
"experiment.yml.tmpl",
"job.yml.tmpl",
"model.yml.tmpl",
"model_serving_endpoint.yml.tmpl",
"pipeline.yml.tmpl",
"registered_model.yml.tmpl",
"schema.yml.tmpl",
"secret_scope.yml.tmpl",
"synced_database_table.yml.tmpl",
"volume.yml.tmpl",
]
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
"data_security_mode": "",
"docker_image": [],
"driver_instance_pool_id": "",
"driver_node_type_flexibility": [],
"driver_node_type_id": "",
"enable_elastic_disk": false,
"enable_local_disk_encryption": false,
Expand All @@ -84,6 +85,7 @@
"ssh_public_keys": null,
"total_initial_remote_disk_size": 0,
"use_ml_runtime": false,
"worker_node_type_flexibility": [],
"workload_type": []
}
]
Expand Down