Skip to content

Commit 77a78a7

Browse files
author
Varun Deep Saini
committed
Fix lakeview publish to default embed_credentials to false
1 parent f09bf1e commit 77a78a7

3 files changed

Lines changed: 241 additions & 0 deletions

File tree

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
RecordRequests = true
22

3+
[Env]
4+
MSYS_NO_PATHCONV = "1"
5+
36
[[Repls]]
47
Old = "[a-f0-9]{32}"
58
New = "[DASHBOARD_ID]"

bundle/direct/graph_test.go

Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
package direct
2+
3+
import (
4+
"sort"
5+
"sync"
6+
"testing"
7+
8+
"github.com/databricks/cli/bundle/deployplan"
9+
"github.com/stretchr/testify/assert"
10+
"github.com/stretchr/testify/require"
11+
)
12+
13+
func TestMakeGraph_DeploymentOrder(t *testing.T) {
14+
// Test that deployment uses normal dependency order: dependency before dependent
15+
// If B depends on A, A should be deployed before B
16+
plan := deployplan.NewPlan()
17+
plan.Plan["resources.jobs.a"] = &deployplan.PlanEntry{
18+
Action: deployplan.ActionTypeCreate.String(),
19+
}
20+
plan.Plan["resources.jobs.b"] = &deployplan.PlanEntry{
21+
Action: deployplan.ActionTypeCreate.String(),
22+
DependsOn: []deployplan.DependsOnEntry{
23+
{Node: "resources.jobs.a", Label: "${resources.jobs.a.id}"},
24+
},
25+
}
26+
27+
g, err := makeGraph(plan)
28+
require.NoError(t, err)
29+
30+
// Track execution order
31+
var mu sync.Mutex
32+
var order []string
33+
34+
g.Run(1, func(node string, failedDep *string) bool {
35+
mu.Lock()
36+
order = append(order, node)
37+
mu.Unlock()
38+
return true
39+
})
40+
41+
// A should be deployed before B
42+
require.Equal(t, []string{"resources.jobs.a", "resources.jobs.b"}, order)
43+
}
44+
45+
func TestMakeGraph_DeletionOrder(t *testing.T) {
46+
// Test that deletion uses reverse dependency order: dependent before dependency
47+
// If B depends on A, B should be deleted before A
48+
plan := deployplan.NewPlan()
49+
plan.Plan["resources.jobs.a"] = &deployplan.PlanEntry{
50+
Action: deployplan.ActionTypeDelete.String(),
51+
}
52+
plan.Plan["resources.jobs.b"] = &deployplan.PlanEntry{
53+
Action: deployplan.ActionTypeDelete.String(),
54+
DependsOn: []deployplan.DependsOnEntry{
55+
{Node: "resources.jobs.a", Label: "${resources.jobs.a.id}"},
56+
},
57+
}
58+
59+
g, err := makeGraph(plan)
60+
require.NoError(t, err)
61+
62+
// Track execution order
63+
var mu sync.Mutex
64+
var order []string
65+
66+
g.Run(1, func(node string, failedDep *string) bool {
67+
mu.Lock()
68+
order = append(order, node)
69+
mu.Unlock()
70+
return true
71+
})
72+
73+
// B should be deleted before A (reverse of deployment order)
74+
require.Equal(t, []string{"resources.jobs.b", "resources.jobs.a"}, order)
75+
}
76+
77+
func TestMakeGraph_DeletionOrderChain(t *testing.T) {
78+
// Test chain of dependencies: C depends on B, B depends on A
79+
// Deletion order should be: C, B, A
80+
plan := deployplan.NewPlan()
81+
plan.Plan["resources.jobs.a"] = &deployplan.PlanEntry{
82+
Action: deployplan.ActionTypeDelete.String(),
83+
}
84+
plan.Plan["resources.jobs.b"] = &deployplan.PlanEntry{
85+
Action: deployplan.ActionTypeDelete.String(),
86+
DependsOn: []deployplan.DependsOnEntry{
87+
{Node: "resources.jobs.a", Label: "${resources.jobs.a.id}"},
88+
},
89+
}
90+
plan.Plan["resources.jobs.c"] = &deployplan.PlanEntry{
91+
Action: deployplan.ActionTypeDelete.String(),
92+
DependsOn: []deployplan.DependsOnEntry{
93+
{Node: "resources.jobs.b", Label: "${resources.jobs.b.id}"},
94+
},
95+
}
96+
97+
g, err := makeGraph(plan)
98+
require.NoError(t, err)
99+
100+
var mu sync.Mutex
101+
var order []string
102+
103+
g.Run(1, func(node string, failedDep *string) bool {
104+
mu.Lock()
105+
order = append(order, node)
106+
mu.Unlock()
107+
return true
108+
})
109+
110+
// C should be deleted first, then B, then A
111+
require.Equal(t, []string{"resources.jobs.c", "resources.jobs.b", "resources.jobs.a"}, order)
112+
}
113+
114+
func TestMakeGraph_MixedDeployAndDelete(t *testing.T) {
115+
// Test mixed scenario: some resources being created, some deleted
116+
plan := deployplan.NewPlan()
117+
// A is being created
118+
plan.Plan["resources.jobs.a"] = &deployplan.PlanEntry{
119+
Action: deployplan.ActionTypeCreate.String(),
120+
}
121+
// B is being created and depends on A
122+
plan.Plan["resources.jobs.b"] = &deployplan.PlanEntry{
123+
Action: deployplan.ActionTypeCreate.String(),
124+
DependsOn: []deployplan.DependsOnEntry{
125+
{Node: "resources.jobs.a", Label: "${resources.jobs.a.id}"},
126+
},
127+
}
128+
// C is being deleted (independent)
129+
plan.Plan["resources.jobs.c"] = &deployplan.PlanEntry{
130+
Action: deployplan.ActionTypeDelete.String(),
131+
}
132+
// D is being deleted (independent)
133+
plan.Plan["resources.jobs.d"] = &deployplan.PlanEntry{
134+
Action: deployplan.ActionTypeDelete.String(),
135+
}
136+
137+
g, err := makeGraph(plan)
138+
require.NoError(t, err)
139+
140+
var mu sync.Mutex
141+
var order []string
142+
143+
g.Run(1, func(node string, failedDep *string) bool {
144+
mu.Lock()
145+
order = append(order, node)
146+
mu.Unlock()
147+
return true
148+
})
149+
150+
// Verify A is before B (deployment order)
151+
aIdx := indexOf(order, "resources.jobs.a")
152+
bIdx := indexOf(order, "resources.jobs.b")
153+
assert.Less(t, aIdx, bIdx, "A should be deployed before B")
154+
155+
// C and D can be in any order (independent deletes)
156+
assert.Contains(t, order, "resources.jobs.c")
157+
assert.Contains(t, order, "resources.jobs.d")
158+
}
159+
160+
func TestMakeGraph_DeleteWithMissingDependency(t *testing.T) {
161+
// Test that delete actions don't fail if a dependency doesn't exist in the plan
162+
// (e.g., the dependency resource was not removed from config)
163+
plan := deployplan.NewPlan()
164+
plan.Plan["resources.jobs.b"] = &deployplan.PlanEntry{
165+
Action: deployplan.ActionTypeDelete.String(),
166+
DependsOn: []deployplan.DependsOnEntry{
167+
{Node: "resources.jobs.a", Label: "${resources.jobs.a.id}"},
168+
},
169+
}
170+
171+
g, err := makeGraph(plan)
172+
require.NoError(t, err)
173+
174+
var executed []string
175+
g.Run(1, func(node string, failedDep *string) bool {
176+
executed = append(executed, node)
177+
return true
178+
})
179+
180+
require.Equal(t, []string{"resources.jobs.b"}, executed)
181+
}
182+
183+
func TestMakeGraph_CreateWithMissingDependency(t *testing.T) {
184+
// Test that create actions fail if a dependency doesn't exist in the plan
185+
plan := deployplan.NewPlan()
186+
plan.Plan["resources.jobs.b"] = &deployplan.PlanEntry{
187+
Action: deployplan.ActionTypeCreate.String(),
188+
DependsOn: []deployplan.DependsOnEntry{
189+
{Node: "resources.jobs.a", Label: "${resources.jobs.a.id}"},
190+
},
191+
}
192+
193+
_, err := makeGraph(plan)
194+
require.Error(t, err)
195+
assert.Contains(t, err.Error(), "invalid dependency")
196+
}
197+
198+
func TestMakeGraph_ParallelDeletions(t *testing.T) {
199+
// Test that independent deletions can run in parallel
200+
plan := deployplan.NewPlan()
201+
// A, B, C are independent deletions
202+
plan.Plan["resources.jobs.a"] = &deployplan.PlanEntry{
203+
Action: deployplan.ActionTypeDelete.String(),
204+
}
205+
plan.Plan["resources.jobs.b"] = &deployplan.PlanEntry{
206+
Action: deployplan.ActionTypeDelete.String(),
207+
}
208+
plan.Plan["resources.jobs.c"] = &deployplan.PlanEntry{
209+
Action: deployplan.ActionTypeDelete.String(),
210+
}
211+
212+
g, err := makeGraph(plan)
213+
require.NoError(t, err)
214+
215+
var mu sync.Mutex
216+
var executed []string
217+
218+
// Use parallelism > 1 to allow parallel execution
219+
g.Run(3, func(node string, failedDep *string) bool {
220+
mu.Lock()
221+
executed = append(executed, node)
222+
mu.Unlock()
223+
return true
224+
})
225+
226+
// All three should be executed (order doesn't matter for independent resources)
227+
sort.Strings(executed)
228+
require.Equal(t, []string{"resources.jobs.a", "resources.jobs.b", "resources.jobs.c"}, executed)
229+
}
230+
231+
func indexOf(slice []string, item string) int {
232+
for i, v := range slice {
233+
if v == item {
234+
return i
235+
}
236+
}
237+
return -1
238+
}

databricks

51 MB
Binary file not shown.

0 commit comments

Comments
 (0)