Compare commits

...

4 Commits

Author SHA1 Message Date
shreyas-goenka 65e4f79dfe
Switch to using `[` from `<` in text replacements (#2224)
## Changes
Noticed this when working on
https://github.com/databricks/cli/pull/2221. `<` is a special HTML
character that is encoded during text replacement when using
`AssertEqualTexts`.


## Tests
N/A
2025-01-28 10:54:23 +00:00
Denis Bilenko 3ffac80007
acc: Use real terraform when CLOUD_ENV is set (#2245)
## Changes
- If CLOUD_ENV is set to do not override with dummy value. This allows
running acceptance tests as integration tests.
- Needed for https://github.com/databricks/cli/pull/2242

## Tests
Manually run the test suite against dogfood. `CLOUD_ENV=aws go test
./acceptance`
2025-01-28 10:23:44 +00:00
Denis Bilenko 11436faafe
acc: Avoid reading and applying replacements on large files; validate utf8 (#2244)
## Changes
- Do not start replacement / comparison if file is too large or not
valid utf-8.
- This helps to prevent replacements if there is accidentally a large
binary (e.g. terraform).

## Tests
Found this problem when working on
https://github.com/databricks/cli/pull/2242 -- the tests tried to
applied replacements on terraform binary and crashed. With this change,
an error is reported instead.
2025-01-28 10:22:29 +00:00
Denis Bilenko 60709e3d48
acc: Restore unexpected output error (#2243)
## Changes
Restore original behaviour of acceptance tests: any unaccounted for
files trigger an error (not just those that start with "out"). This got
changed in
https://github.com/databricks/cli/pull/2146/files#diff-2bb968d823f4afb825e1dcea2879bdbdedf2b7c15d4e77f47905691b14246a04L196
which started only checking files starting with "out*" and skipping
everything else.

## Tests
Existing tests.
2025-01-28 10:15:32 +00:00
17 changed files with 71 additions and 45 deletions

View File

@ -15,6 +15,7 @@ import (
"strings"
"testing"
"time"
"unicode/utf8"
"github.com/databricks/cli/internal/testutil"
"github.com/databricks/cli/libs/env"
@ -44,6 +45,7 @@ const (
EntryPointScript = "script"
CleanupScript = "script.cleanup"
PrepareScript = "script.prepare"
MaxFileSize = 100_000
)
var Scripts = map[string]bool{
@ -97,9 +99,6 @@ func testAccept(t *testing.T, InprocessMode bool, singleTest string) int {
repls.SetPath(tempHomeDir, "$TMPHOME")
t.Logf("$TMPHOME=%v", tempHomeDir)
// Prevent CLI from downloading terraform in each test:
t.Setenv("DATABRICKS_TF_EXEC_PATH", tempHomeDir)
// Make use of uv cache; since we set HomeEnvVar to temporary directory, it is not picked up automatically
uvCache := getUVDefaultCacheDir(t)
t.Setenv("UV_CACHE_DIR", uvCache)
@ -117,6 +116,9 @@ func testAccept(t *testing.T, InprocessMode bool, singleTest string) int {
homeDir := t.TempDir()
// Do not read user's ~/.databrickscfg
t.Setenv(env.HomeEnvVar(), homeDir)
// Prevent CLI from downloading terraform in each test:
t.Setenv("DATABRICKS_TF_EXEC_PATH", tempHomeDir)
}
workspaceClient, err := databricks.NewWorkspaceClient()
@ -245,6 +247,7 @@ func runTest(t *testing.T, dir, coverDir string, repls testdiff.ReplacementsCont
if _, ok := outputs[relPath]; ok {
continue
}
t.Errorf("Unexpected output: %s", relPath)
if strings.HasPrefix(relPath, "out") {
// We have a new file starting with "out"
// Show the contents & support overwrite mode for it:
@ -256,15 +259,15 @@ func runTest(t *testing.T, dir, coverDir string, repls testdiff.ReplacementsCont
func doComparison(t *testing.T, repls testdiff.ReplacementsContext, dirRef, dirNew, relPath string, printedRepls *bool) {
pathRef := filepath.Join(dirRef, relPath)
pathNew := filepath.Join(dirNew, relPath)
bufRef, okRef := readIfExists(t, pathRef)
bufNew, okNew := readIfExists(t, pathNew)
bufRef, okRef := tryReading(t, pathRef)
bufNew, okNew := tryReading(t, pathNew)
if !okRef && !okNew {
t.Errorf("Both files are missing: %s, %s", pathRef, pathNew)
t.Errorf("Both files are missing or have errors: %s, %s", pathRef, pathNew)
return
}
valueRef := testdiff.NormalizeNewlines(string(bufRef))
valueNew := testdiff.NormalizeNewlines(string(bufNew))
valueRef := testdiff.NormalizeNewlines(bufRef)
valueNew := testdiff.NormalizeNewlines(bufNew)
// Apply replacements to the new value only.
// The reference value is stored after applying replacements.
@ -322,14 +325,14 @@ func readMergedScriptContents(t *testing.T, dir string) string {
cleanups := []string{}
for {
x, ok := readIfExists(t, filepath.Join(dir, CleanupScript))
x, ok := tryReading(t, filepath.Join(dir, CleanupScript))
if ok {
cleanups = append(cleanups, string(x))
cleanups = append(cleanups, x)
}
x, ok = readIfExists(t, filepath.Join(dir, PrepareScript))
x, ok = tryReading(t, filepath.Join(dir, PrepareScript))
if ok {
prepares = append(prepares, string(x))
prepares = append(prepares, x)
}
if dir == "" || dir == "." {
@ -416,16 +419,33 @@ func formatOutput(w io.Writer, err error) {
}
}
func readIfExists(t *testing.T, path string) ([]byte, bool) {
data, err := os.ReadFile(path)
if err == nil {
return data, true
func tryReading(t *testing.T, path string) (string, bool) {
info, err := os.Stat(path)
if err != nil {
if !errors.Is(err, os.ErrNotExist) {
t.Errorf("%s: %s", path, err)
}
return "", false
}
if !errors.Is(err, os.ErrNotExist) {
t.Fatalf("%s: %s", path, err)
if info.Size() > MaxFileSize {
t.Errorf("%s: ignoring, too large: %d", path, info.Size())
return "", false
}
return []byte{}, false
data, err := os.ReadFile(path)
if err != nil {
// already checked ErrNotExist above
t.Errorf("%s: %s", path, err)
return "", false
}
if !utf8.Valid(data) {
t.Errorf("%s: not valid utf-8", path)
return "", false
}
return string(data), true
}
func CopyDir(src, dst string, inputs, outputs map[string]bool) error {

View File

@ -22,4 +22,5 @@ trace chmod 000 .git/config
errcode trace $CLI bundle validate -o json | jq .bundle.git
errcode trace withdir subdir/a/b $CLI bundle validate -o json | jq .bundle.git
rm -fr .git
cd ..
rm -fr myrepo

View File

@ -3,4 +3,6 @@ mkdir myrepo
cd myrepo
cp ../databricks.yml .
git-repo-init
$CLI bundle validate | sed 's/\\\\/\//g'
errcode $CLI bundle validate
cd ..
rm -fr myrepo

View File

@ -0,0 +1,3 @@
[[Repls]]
Old = '\\\\myrepo'
New = '/myrepo'

View File

@ -3,7 +3,7 @@
# See https://docs.databricks.com/dev-tools/bundles/index.html for documentation.
bundle:
name: my_dbt_sql
uuid: <UUID>
uuid: [UUID]
include:
- resources/*.yml

View File

@ -2,7 +2,7 @@
# See https://docs.databricks.com/dev-tools/bundles/index.html for documentation.
bundle:
name: my_default_python
uuid: <UUID>
uuid: [UUID]
include:
- resources/*.yml

View File

@ -20,7 +20,7 @@
"rowLimit": 10000
},
"inputWidgets": {},
"nuid": "<UUID>",
"nuid": "[UUID]",
"showTitle": false,
"title": ""
}

View File

@ -6,7 +6,7 @@
"application/vnd.databricks.v1+cell": {
"cellMetadata": {},
"inputWidgets": {},
"nuid": "<UUID>",
"nuid": "[UUID]",
"showTitle": false,
"title": ""
}
@ -24,7 +24,7 @@
"application/vnd.databricks.v1+cell": {
"cellMetadata": {},
"inputWidgets": {},
"nuid": "<UUID>",
"nuid": "[UUID]",
"showTitle": false,
"title": ""
}
@ -47,7 +47,7 @@
"application/vnd.databricks.v1+cell": {
"cellMetadata": {},
"inputWidgets": {},
"nuid": "<UUID>",
"nuid": "[UUID]",
"showTitle": false,
"title": ""
}

View File

@ -6,7 +6,7 @@
"application/vnd.databricks.v1+cell": {
"cellMetadata": {},
"inputWidgets": {},
"nuid": "<UUID>",
"nuid": "[UUID]",
"showTitle": false,
"title": ""
}
@ -37,7 +37,7 @@
"rowLimit": 10000
},
"inputWidgets": {},
"nuid": "<UUID>",
"nuid": "[UUID]",
"showTitle": false,
"title": ""
}

View File

@ -2,7 +2,7 @@
# See https://docs.databricks.com/dev-tools/bundles/index.html for documentation.
bundle:
name: my_default_sql
uuid: <UUID>
uuid: [UUID]
include:
- resources/*.yml

View File

@ -7,7 +7,7 @@
"application/vnd.databricks.v1+cell": {
"cellMetadata": {},
"inputWidgets": {},
"nuid": "<UUID>",
"nuid": "[UUID]",
"showTitle": false,
"title": ""
}

View File

@ -2,7 +2,7 @@
# See https://docs.databricks.com/dev-tools/bundles/index.html for documentation.
bundle:
name: my_jobs_as_code
uuid: <UUID>
uuid: [UUID]
databricks_cli_version: ">= 0.238.0"
experimental:

View File

@ -6,7 +6,7 @@
"application/vnd.databricks.v1+cell": {
"cellMetadata": {},
"inputWidgets": {},
"nuid": "<UUID>",
"nuid": "[UUID]",
"showTitle": false,
"title": ""
}
@ -37,7 +37,7 @@
"rowLimit": 10000
},
"inputWidgets": {},
"nuid": "<UUID>",
"nuid": "[UUID]",
"showTitle": false,
"title": ""
}

View File

@ -1,5 +1,5 @@
Building project_name_$UNIQUE_PRJ...
Uploading project_name_$UNIQUE_PRJ-0.0.1+<NUMID>.<NUMID>-py3-none-any.whl...
Uploading project_name_$UNIQUE_PRJ-0.0.1+[NUMID].[NUMID]-py3-none-any.whl...
Uploading bundle files to /Workspace/Users/$USERNAME/.bundle/project_name_$UNIQUE_PRJ/dev/files...
Deploying resources...
Updating deployment state...

View File

@ -16,7 +16,7 @@
"enabled": false
}
},
"uuid": "<UUID>"
"uuid": "[UUID]"
},
"include": [
"resources/project_name_$UNIQUE_PRJ.job.yml",
@ -74,7 +74,7 @@
]
},
"format": "MULTI_TASK",
"id": "<NUMID>",
"id": "[NUMID]",
"job_clusters": [
{
"job_cluster_key": "job_cluster",
@ -141,7 +141,7 @@
"unit": "DAYS"
}
},
"url": "$DATABRICKS_URL/jobs/<NUMID>?o=<NUMID>"
"url": "$DATABRICKS_URL/jobs/[NUMID]?o=[NUMID]"
}
},
"pipelines": {
@ -155,7 +155,7 @@
"metadata_file_path": "/Workspace/Users/$USERNAME/.bundle/project_name_$UNIQUE_PRJ/dev/state/metadata.json"
},
"development": true,
"id": "<UUID>",
"id": "[UUID]",
"libraries": [
{
"notebook": {
@ -165,7 +165,7 @@
],
"name": "[dev $USERNAME] project_name_$UNIQUE_PRJ_pipeline",
"target": "project_name_$UNIQUE_PRJ_dev",
"url": "$DATABRICKS_URL/pipelines/<UUID>?o=<NUMID>"
"url": "$DATABRICKS_URL/pipelines/[UUID]?o=[NUMID]"
}
}
},
@ -183,4 +183,4 @@
"dev": "$USERNAME"
}
}
}
}

View File

@ -201,12 +201,12 @@ func PrepareReplacementsUser(t testutil.TestingT, r *ReplacementsContext, u iam.
func PrepareReplacementsUUID(t testutil.TestingT, r *ReplacementsContext) {
t.Helper()
r.append(uuidRegex, "<UUID>")
r.append(uuidRegex, "[UUID]")
}
func PrepareReplacementsNumber(t testutil.TestingT, r *ReplacementsContext) {
t.Helper()
r.append(numIdRegex, "<NUMID>")
r.append(numIdRegex, "[NUMID]")
}
func PrepareReplacementsTemporaryDirectory(t testutil.TestingT, r *ReplacementsContext) {

View File

@ -25,7 +25,7 @@ func TestReplacement_UUID(t *testing.T) {
PrepareReplacementsUUID(t, &repls)
assert.Equal(t, "<UUID>", repls.Replace("123e4567-e89b-12d3-a456-426614174000"))
assert.Equal(t, "[UUID]", repls.Replace("123e4567-e89b-12d3-a456-426614174000"))
}
func TestReplacement_Number(t *testing.T) {
@ -34,7 +34,7 @@ func TestReplacement_Number(t *testing.T) {
PrepareReplacementsNumber(t, &repls)
assert.Equal(t, "12", repls.Replace("12"))
assert.Equal(t, "<NUMID>", repls.Replace("123"))
assert.Equal(t, "[NUMID]", repls.Replace("123"))
}
func TestReplacement_TemporaryDirectory(t *testing.T) {