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
29 changes: 29 additions & 0 deletions internal/testutil/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"os"
"path/filepath"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

Expand Down Expand Up @@ -52,3 +53,31 @@ func ReadFile(t TestingT, path string) string {

return string(b)
}

// StatFile returns the file info for a file.
func StatFile(t TestingT, path string) os.FileInfo {
fi, err := os.Stat(path)
require.NoError(t, err)

return fi
}

// AssertFileContents asserts that the file at path has the expected content.
func AssertFileContents(t TestingT, path, expected string) bool {
actual := ReadFile(t, path)
return assert.Equal(t, expected, actual)
}

// AssertFilePermissions asserts that the file at path has the expected permissions.
func AssertFilePermissions(t TestingT, path string, expected os.FileMode) bool {
fi := StatFile(t, path)
assert.False(t, fi.Mode().IsDir(), "expected a file, got a directory")
return assert.Equal(t, expected, fi.Mode().Perm(), "expected 0%o, got 0%o", expected, fi.Mode().Perm())
}

// AssertDirPermissions asserts that the file at path has the expected permissions.
func AssertDirPermissions(t TestingT, path string, expected os.FileMode) bool {
fi := StatFile(t, path)
assert.True(t, fi.Mode().IsDir(), "expected a directory, got a file")
return assert.Equal(t, expected, fi.Mode().Perm(), "expected 0%o, got 0%o", expected, fi.Mode().Perm())
}
9 changes: 5 additions & 4 deletions libs/template/file_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"runtime"
"testing"

"github.com/databricks/cli/internal/testutil"
"github.com/databricks/cli/libs/filer"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
Expand All @@ -27,8 +28,8 @@ func testInMemoryFile(t *testing.T, ctx context.Context, perm fs.FileMode) {
err = f.Write(ctx, out)
assert.NoError(t, err)

assertFileContent(t, filepath.Join(tmpDir, "a/b/c"), "123")
assertFilePermissions(t, filepath.Join(tmpDir, "a/b/c"), perm)
testutil.AssertFileContents(t, filepath.Join(tmpDir, "a/b/c"), "123")
testutil.AssertFilePermissions(t, filepath.Join(tmpDir, "a/b/c"), perm)
}

func testCopyFile(t *testing.T, ctx context.Context, perm fs.FileMode) {
Expand All @@ -48,8 +49,8 @@ func testCopyFile(t *testing.T, ctx context.Context, perm fs.FileMode) {
err = f.Write(ctx, out)
assert.NoError(t, err)

assertFileContent(t, filepath.Join(tmpDir, "a/b/c"), "qwerty")
assertFilePermissions(t, filepath.Join(tmpDir, "a/b/c"), perm)
testutil.AssertFileContents(t, filepath.Join(tmpDir, "source"), "qwerty")
testutil.AssertFilePermissions(t, filepath.Join(tmpDir, "source"), perm)
}

func TestTemplateInMemoryFilePersistToDisk(t *testing.T) {
Expand Down
4 changes: 4 additions & 0 deletions libs/template/renderer.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,10 @@ func (r *renderer) computeFile(relPathTemplate string) (file, error) {
}
perm := info.Mode().Perm()

// Always include the write bit for the owner of the file.
// It does not make sense to have a file that is not writable by the owner.
perm |= 0o200

// Execute relative path template to get destination path for the file
relPath, err := r.executeTemplate(relPathTemplate)
if err != nil {
Expand Down
37 changes: 22 additions & 15 deletions libs/template/renderer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,19 @@ import (
"github.com/stretchr/testify/require"
)

func assertFileContent(t *testing.T, path, content string) {
b, err := os.ReadFile(path)
require.NoError(t, err)
assert.Equal(t, content, string(b))
}
var (
defaultFilePermissions fs.FileMode
defaultDirPermissions fs.FileMode
)

func assertFilePermissions(t *testing.T, path string, perm fs.FileMode) {
info, err := os.Stat(path)
require.NoError(t, err)
assert.Equal(t, perm, info.Mode().Perm())
func init() {
if runtime.GOOS == "windows" {
defaultFilePermissions = fs.FileMode(0o666)
defaultDirPermissions = fs.FileMode(0o777)
} else {
defaultFilePermissions = fs.FileMode(0o644)
defaultDirPermissions = fs.FileMode(0o755)
}
}

func assertBuiltinTemplateValid(t *testing.T, template string, settings map[string]any, target string, isServicePrincipal, build bool, tempDir string) {
Expand Down Expand Up @@ -69,6 +72,10 @@ func assertBuiltinTemplateValid(t *testing.T, template string, settings map[stri
err = renderer.persistToDisk(ctx, out)
require.NoError(t, err)

// Verify permissions on file and directory
testutil.AssertFilePermissions(t, filepath.Join(tempDir, "my_project/README.md"), defaultFilePermissions)
testutil.AssertDirPermissions(t, filepath.Join(tempDir, "my_project/resources"), defaultDirPermissions)

b, err := bundle.Load(ctx, filepath.Join(tempDir, "my_project"))
require.NoError(t, err)
diags := bundle.Apply(ctx, b, phases.LoadNamedTarget(target))
Expand Down Expand Up @@ -347,10 +354,10 @@ func TestRendererPersistToDisk(t *testing.T) {
assert.NoFileExists(t, filepath.Join(tmpDir, "a", "b", "c"))
assert.NoFileExists(t, filepath.Join(tmpDir, "mno"))

assertFileContent(t, filepath.Join(tmpDir, "a", "b", "d"), "123")
assertFilePermissions(t, filepath.Join(tmpDir, "a", "b", "d"), 0o444)
assertFileContent(t, filepath.Join(tmpDir, "mmnn"), "456")
assertFilePermissions(t, filepath.Join(tmpDir, "mmnn"), 0o444)
testutil.AssertFileContents(t, filepath.Join(tmpDir, "a/b/d"), "123")
testutil.AssertFilePermissions(t, filepath.Join(tmpDir, "a/b/d"), fs.FileMode(0o444))
testutil.AssertFileContents(t, filepath.Join(tmpDir, "mmnn"), "456")
testutil.AssertFilePermissions(t, filepath.Join(tmpDir, "mmnn"), fs.FileMode(0o444))
}

func TestRendererWalk(t *testing.T) {
Expand Down Expand Up @@ -617,8 +624,8 @@ func TestRendererFileTreeRendering(t *testing.T) {
require.NoError(t, err)

// Assert files and directories are correctly materialized.
assert.DirExists(t, filepath.Join(tmpDir, "my_directory"))
assert.FileExists(t, filepath.Join(tmpDir, "my_directory", "my_file"))
testutil.AssertDirPermissions(t, filepath.Join(tmpDir, "my_directory"), defaultDirPermissions)
testutil.AssertFilePermissions(t, filepath.Join(tmpDir, "my_directory", "my_file"), defaultFilePermissions)
}

func TestRendererSubTemplateInPath(t *testing.T) {
Expand Down
Loading