Coverage for conversion logic

This commit is contained in:
Pieter Noordhuis 2024-09-30 11:54:08 +02:00
parent 3a1d92c75c
commit 802be90687
No known key found for this signature in database
GPG Key ID: 12ACCCC104CF2930
4 changed files with 143 additions and 8 deletions

View File

@ -22,7 +22,7 @@ func (t *translateContext) dashboardRewritePatterns() []dashboardRewritePattern
// Compile list of configuration paths to rewrite.
return []dashboardRewritePattern{
{
base.Append(dyn.Key("definition_path")),
base.Append(dyn.Key("file_path")),
t.retainLocalAbsoluteFilePath,
},
}

View File

@ -47,7 +47,6 @@ type Dashboard struct {
// ===========================
// FilePath points to the local `.lvdash.json` file containing the dashboard definition.
// If specified, it will populate the `SerializedDashboard` field.
FilePath string `json:"file_path,omitempty"`
}

View File

@ -19,20 +19,48 @@ func convertDashboardResource(ctx context.Context, vin dyn.Value) (dyn.Value, er
log.Debugf(ctx, "dashboard normalization diagnostic: %s", diag.Summary)
}
// Include "serialized_dashboard" field if "definition_path" is set.
if path, ok := vin.Get("definition_path").AsString(); ok {
// Include "serialized_dashboard" field if "file_path" is set.
// Note: the Terraform resource supports "file_path" natively, but its
// change detection mechanism doesn't work as expected at the time of writing (Sep 30).
if path, ok := vout.Get("file_path").AsString(); ok {
vout, err = dyn.Set(vout, "serialized_dashboard", dyn.V(fmt.Sprintf("${file(\"%s\")}", path)))
if err != nil {
return dyn.InvalidValue, fmt.Errorf("failed to set serialized_dashboard: %w", err)
}
// Drop the "file_path" field. It is mutually exclusive with "serialized_dashboard".
vout, err = dyn.Walk(vout, func(p dyn.Path, v dyn.Value) (dyn.Value, error) {
switch len(p) {
case 0:
return v, nil
case 1:
if p[0] == dyn.Key("file_path") {
return v, dyn.ErrDrop
}
}
// Skip everything else.
return v, dyn.ErrSkip
})
if err != nil {
return dyn.InvalidValue, fmt.Errorf("failed to drop file_path: %w", err)
}
}
// Default the "embed_credentials" field to "false", if not already set.
// This is different from the behavior in the Terraform provider, so we make it explicit.
if _, ok := vout.Get("embed_credentials").AsBool(); !ok {
vout, err = dyn.Set(vout, "embed_credentials", dyn.V(false))
if err != nil {
return dyn.InvalidValue, fmt.Errorf("failed to set embed_credentials: %w", err)
}
}
return vout, nil
}
type DashboardConverter struct{}
type dashboardConverter struct{}
func (DashboardConverter) Convert(ctx context.Context, key string, vin dyn.Value, out *schema.Resources) error {
func (dashboardConverter) Convert(ctx context.Context, key string, vin dyn.Value, out *schema.Resources) error {
vout, err := convertDashboardResource(ctx, vin)
if err != nil {
return err
@ -51,5 +79,5 @@ func (DashboardConverter) Convert(ctx context.Context, key string, vin dyn.Value
}
func init() {
registerConverter("dashboards", DashboardConverter{})
registerConverter("dashboards", dashboardConverter{})
}

View File

@ -1,7 +1,115 @@
package tfdyn
import "testing"
import (
"context"
"fmt"
"testing"
"github.com/databricks/cli/bundle/config/resources"
"github.com/databricks/cli/bundle/internal/tf/schema"
"github.com/databricks/cli/libs/dyn"
"github.com/databricks/cli/libs/dyn/convert"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestConvertDashboard(t *testing.T) {
var src = resources.Dashboard{
DisplayName: "my dashboard",
WarehouseID: "f00dcafe",
ParentPath: "/some/path",
EmbedCredentials: true,
Permissions: []resources.Permission{
{
Level: "CAN_VIEW",
UserName: "jane@doe.com",
},
},
}
vin, err := convert.FromTyped(src, dyn.NilValue)
require.NoError(t, err)
ctx := context.Background()
out := schema.NewResources()
err = dashboardConverter{}.Convert(ctx, "my_dashboard", vin, out)
require.NoError(t, err)
// Assert equality on the job
assert.Equal(t, map[string]any{
"display_name": "my dashboard",
"warehouse_id": "f00dcafe",
"parent_path": "/some/path",
"embed_credentials": true,
}, out.Dashboard["my_dashboard"])
// Assert equality on the permissions
assert.Equal(t, &schema.ResourcePermissions{
DashboardId: "${databricks_dashboard.my_dashboard.id}",
AccessControl: []schema.ResourcePermissionsAccessControl{
{
PermissionLevel: "CAN_VIEW",
UserName: "jane@doe.com",
},
},
}, out.Permissions["dashboard_my_dashboard"])
}
func TestConvertDashboardFilePath(t *testing.T) {
var src = resources.Dashboard{
FilePath: "some/path",
}
vin, err := convert.FromTyped(src, dyn.NilValue)
require.NoError(t, err)
ctx := context.Background()
out := schema.NewResources()
err = dashboardConverter{}.Convert(ctx, "my_dashboard", vin, out)
require.NoError(t, err)
// Assert that the "serialized_dashboard" is included.
assert.Subset(t, out.Dashboard["my_dashboard"], map[string]any{
"serialized_dashboard": "${file(\"some/path\")}",
})
// Assert that the "file_path" doesn't carry over.
assert.NotSubset(t, out.Dashboard["my_dashboard"], map[string]any{
"file_path": "some/path",
})
}
func TestConvertDashboardEmbedCredentialsPassthrough(t *testing.T) {
for _, v := range []bool{true, false} {
t.Run(fmt.Sprintf("set to %v", v), func(t *testing.T) {
vin := dyn.V(map[string]dyn.Value{
"embed_credentials": dyn.V(v),
})
ctx := context.Background()
out := schema.NewResources()
err := dashboardConverter{}.Convert(ctx, "my_dashboard", vin, out)
require.NoError(t, err)
// Assert that the "embed_credentials" is set as configured.
assert.Subset(t, out.Dashboard["my_dashboard"], map[string]any{
"embed_credentials": v,
})
})
}
}
func TestConvertDashboardEmbedCredentialsDefault(t *testing.T) {
vin := dyn.V(map[string]dyn.Value{})
ctx := context.Background()
out := schema.NewResources()
err := dashboardConverter{}.Convert(ctx, "my_dashboard", vin, out)
require.NoError(t, err)
// Assert that the "embed_credentials" is set to false (by default).
assert.Subset(t, out.Dashboard["my_dashboard"], map[string]any{
"embed_credentials": false,
})
}