Skip to content

Commit e6645fe

Browse files
authored
Merge pull request bruin-data#366 from bruin-data/make-tests-independent
seperate pipelines for integration tests
2 parents dd78839 + 4c6e6fc commit e6645fe

File tree

91 files changed

+1871
-37
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

91 files changed

+1871
-37
lines changed

integration-tests/.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
logs/*.log
2-
.bruin.yml
2+
.bruin.yml
3+
logs/runs

integration-tests/integration-test.go

+36-36
Original file line numberDiff line numberDiff line change
@@ -238,24 +238,24 @@ func getWorkflow(binary string, currentFolder string, tempfile string) []e2e.Wor
238238
func getTasks(binary string, currentFolder string) []e2e.Task {
239239
return []e2e.Task{
240240
{
241-
Name: "happy-path",
241+
Name: "parse-whole-pipeline",
242242
Command: binary,
243-
Args: []string{"internal", "parse-pipeline", filepath.Join(currentFolder, "happy-path")},
243+
Args: []string{"internal", "parse-pipeline", filepath.Join(currentFolder, "test-pipelines/parse-whole-pipeline")},
244244
Env: []string{},
245245
SkipJSONNodes: []string{"\"path\""},
246246
Expected: e2e.Output{
247247
ExitCode: 0,
248-
Output: helpers.ReadFile(filepath.Join(currentFolder, "happy-path/expectations/pipeline.yml.json")),
248+
Output: helpers.ReadFile(filepath.Join(currentFolder, "test-pipelines/parse-whole-pipeline/expectations/pipeline.yml.json")),
249249
},
250250
Asserts: []func(*e2e.Task) error{
251251
e2e.AssertByExitCode,
252252
e2e.AssertByOutputJSON,
253253
},
254254
},
255255
{
256-
Name: "chess-extended",
256+
Name: "run-with-tags",
257257
Command: binary,
258-
Args: []string{"run", "--tag", "include", "--exclude-tag", "exclude", filepath.Join(currentFolder, "chess-extended")},
258+
Args: []string{"run", "--tag", "include", "--exclude-tag", "exclude", filepath.Join(currentFolder, "test-pipelines/run-with-tags-pipeline")},
259259
Env: []string{},
260260

261261
Expected: e2e.Output{
@@ -266,9 +266,9 @@ func getTasks(binary string, currentFolder string) []e2e.Task {
266266
},
267267
},
268268
{
269-
Name: "chess-extended-only-checks",
269+
Name: "run-with-filters",
270270
Command: binary,
271-
Args: []string{"run", "--tag", "include", "--exclude-tag", "exclude", "--only", "checks", filepath.Join(currentFolder, "chess-extended")},
271+
Args: []string{"run", "--tag", "include", "--exclude-tag", "exclude", "--only", "checks", filepath.Join(currentFolder, "test-pipelines/run-with-filters-pipeline")},
272272
Env: []string{},
273273

274274
Expected: e2e.Output{
@@ -283,7 +283,7 @@ func getTasks(binary string, currentFolder string) []e2e.Task {
283283
{
284284
Name: "format-if-fail",
285285
Command: binary,
286-
Args: []string{"format", "--fail-if-changed", filepath.Join(currentFolder, "chess-extended/assets/chess_games.asset.yml")},
286+
Args: []string{"format", "--fail-if-changed", filepath.Join(currentFolder, "test-pipelines/format-if-changed-pipeline/assets/correctly-formatted.sql")},
287287
Env: []string{},
288288
Expected: e2e.Output{
289289
ExitCode: 0,
@@ -293,9 +293,9 @@ func getTasks(binary string, currentFolder string) []e2e.Task {
293293
},
294294
},
295295
{
296-
Name: "chess-extended-only-main",
296+
Name: "run-main-with-filters",
297297
Command: binary,
298-
Args: []string{"run", "--tag", "include", "--exclude-tag", "exclude", "--only", "main", filepath.Join(currentFolder, "chess-extended")},
298+
Args: []string{"run", "--tag", "include", "--exclude-tag", "exclude", "--only", "main", filepath.Join(currentFolder, "test-pipelines/run-main-with-filters-pipeline")},
299299
Env: []string{},
300300

301301
Expected: e2e.Output{
@@ -308,9 +308,9 @@ func getTasks(binary string, currentFolder string) []e2e.Task {
308308
},
309309
},
310310
{
311-
Name: "downstream-chess-extended",
311+
Name: "run-with-downstream",
312312
Command: binary,
313-
Args: []string{"run", "--downstream", filepath.Join(currentFolder, "chess-extended/assets/game_outcome_summary.sql")},
313+
Args: []string{"run", "--downstream", filepath.Join(currentFolder, "test-pipelines/run-with-downstream-pipeline/assets/game_outcome_summary.sql")},
314314
Env: []string{},
315315
Expected: e2e.Output{
316316
ExitCode: 0,
@@ -322,9 +322,9 @@ func getTasks(binary string, currentFolder string) []e2e.Task {
322322
},
323323
},
324324
{
325-
Name: "downstream-only-main-chess-extended",
325+
Name: "run-main-with-downstream",
326326
Command: binary,
327-
Args: []string{"run", "--downstream", "--only", "main", filepath.Join(currentFolder, "chess-extended/assets/game_outcome_summary.sql")},
327+
Args: []string{"run", "--downstream", "--only", "main", filepath.Join(currentFolder, "test-pipelines/run-main-with-downstream-pipeline/assets/game_outcome_summary.sql")},
328328
Env: []string{},
329329
Expected: e2e.Output{
330330
ExitCode: 0,
@@ -338,7 +338,7 @@ func getTasks(binary string, currentFolder string) []e2e.Task {
338338
{
339339
Name: "push-metadata",
340340
Command: binary,
341-
Args: []string{"run", "--push-metadata", "--only", "push-metadata", filepath.Join(currentFolder, "bigquery-metadata")},
341+
Args: []string{"run", "--push-metadata", "--only", "push-metadata", filepath.Join(currentFolder, "test-pipelines/push-metadata-pipeline")},
342342
Env: []string{},
343343
Expected: e2e.Output{
344344
ExitCode: 1,
@@ -352,7 +352,7 @@ func getTasks(binary string, currentFolder string) []e2e.Task {
352352
{
353353
Name: "validate-happy-path",
354354
Command: binary,
355-
Args: []string{"validate", filepath.Join(currentFolder, "happy-path")},
355+
Args: []string{"validate", filepath.Join(currentFolder, "test-pipelines/happy-path")},
356356
Env: []string{},
357357
Expected: e2e.Output{
358358
ExitCode: 0,
@@ -362,9 +362,9 @@ func getTasks(binary string, currentFolder string) []e2e.Task {
362362
},
363363
},
364364
{
365-
Name: "run-use-uv-happy-path",
365+
Name: "run-use-uv",
366366
Command: binary,
367-
Args: []string{"run", "--use-uv", filepath.Join(currentFolder, "happy-path")},
367+
Args: []string{"run", "--use-uv", filepath.Join(currentFolder, "test-pipelines/run-use-uv-pipeline")},
368368
Env: []string{},
369369
Expected: e2e.Output{
370370
ExitCode: 0,
@@ -376,12 +376,12 @@ func getTasks(binary string, currentFolder string) []e2e.Task {
376376
{
377377
Name: "parse-asset-happy-path-asset-py",
378378
Command: binary,
379-
Args: []string{"internal", "parse-asset", filepath.Join(currentFolder, "happy-path/assets/asset.py")},
379+
Args: []string{"internal", "parse-asset", filepath.Join(currentFolder, "test-pipelines/happy-path/assets/asset.py")},
380380
Env: []string{},
381381
SkipJSONNodes: []string{"\"path\""},
382382
Expected: e2e.Output{
383383
ExitCode: 0,
384-
Output: helpers.ReadFile(filepath.Join(currentFolder, "happy-path/expectations/asset.py.json")),
384+
Output: helpers.ReadFile(filepath.Join(currentFolder, "test-pipelines/happy-path/expectations/asset.py.json")),
385385
},
386386
Asserts: []func(*e2e.Task) error{
387387
e2e.AssertByExitCode,
@@ -391,12 +391,12 @@ func getTasks(binary string, currentFolder string) []e2e.Task {
391391
{
392392
Name: "parse-asset-happy-path-chess-games",
393393
Command: binary,
394-
Args: []string{"internal", "parse-asset", filepath.Join(currentFolder, "happy-path/assets/chess_games.asset.yml")},
394+
Args: []string{"internal", "parse-asset", filepath.Join(currentFolder, "test-pipelines/happy-path/assets/chess_games.asset.yml")},
395395
Env: []string{},
396396
SkipJSONNodes: []string{"\"path\""},
397397
Expected: e2e.Output{
398398
ExitCode: 0,
399-
Output: helpers.ReadFile(filepath.Join(currentFolder, "happy-path/expectations/chess_games.asset.yml.json")),
399+
Output: helpers.ReadFile(filepath.Join(currentFolder, "test-pipelines/happy-path/expectations/chess_games.asset.yml.json")),
400400
},
401401
Asserts: []func(*e2e.Task) error{
402402
e2e.AssertByExitCode,
@@ -406,12 +406,12 @@ func getTasks(binary string, currentFolder string) []e2e.Task {
406406
{
407407
Name: "parse-asset-happy-path-chess-profiles",
408408
Command: binary,
409-
Args: []string{"internal", "parse-asset", filepath.Join(currentFolder, "happy-path/assets/chess_profiles.asset.yml")},
409+
Args: []string{"internal", "parse-asset", filepath.Join(currentFolder, "test-pipelines/happy-path/assets/chess_profiles.asset.yml")},
410410
Env: []string{},
411411
SkipJSONNodes: []string{"\"path\""},
412412
Expected: e2e.Output{
413413
ExitCode: 0,
414-
Output: helpers.ReadFile(filepath.Join(currentFolder, "happy-path/expectations/chess_profiles.asset.yml.json")),
414+
Output: helpers.ReadFile(filepath.Join(currentFolder, "test-pipelines/happy-path/expectations/chess_profiles.asset.yml.json")),
415415
},
416416
Asserts: []func(*e2e.Task) error{
417417
e2e.AssertByExitCode,
@@ -421,12 +421,12 @@ func getTasks(binary string, currentFolder string) []e2e.Task {
421421
{
422422
Name: "parse-asset-happy-path-player-summary",
423423
Command: binary,
424-
Args: []string{"internal", "parse-asset", filepath.Join(currentFolder, "happy-path/assets/player_summary.sql")},
424+
Args: []string{"internal", "parse-asset", filepath.Join(currentFolder, "test-pipelines/happy-path/assets/player_summary.sql")},
425425
Env: []string{},
426426
SkipJSONNodes: []string{"\"path\""},
427427
Expected: e2e.Output{
428428
ExitCode: 0,
429-
Output: helpers.ReadFile(filepath.Join(currentFolder, "happy-path/expectations/player_summary.sql.json")),
429+
Output: helpers.ReadFile(filepath.Join(currentFolder, "test-pipelines/happy-path/expectations/player_summary.sql.json")),
430430
},
431431
Asserts: []func(*e2e.Task) error{
432432
e2e.AssertByExitCode,
@@ -436,7 +436,7 @@ func getTasks(binary string, currentFolder string) []e2e.Task {
436436
{
437437
Name: "parse-asset-faulty-pipeline-error-sql",
438438
Command: binary,
439-
Args: []string{"internal", "parse-asset", filepath.Join(currentFolder, "faulty-pipeline/assets/error.sql")},
439+
Args: []string{"internal", "parse-asset", filepath.Join(currentFolder, "test-pipelines/faulty-pipeline/assets/error.sql")},
440440
Env: []string{},
441441

442442
Expected: e2e.Output{
@@ -451,12 +451,12 @@ func getTasks(binary string, currentFolder string) []e2e.Task {
451451
{
452452
Name: "validate-missing-upstream",
453453
Command: binary,
454-
Args: []string{"validate", "-o", "json", filepath.Join(currentFolder, "missing-upstream/assets/nonexistent.sql")},
454+
Args: []string{"validate", "-o", "json", filepath.Join(currentFolder, "test-pipelines/missing-upstream-pipeline/assets/nonexistent.sql")},
455455
Env: []string{},
456456
SkipJSONNodes: []string{"\"path\""},
457457
Expected: e2e.Output{
458458
ExitCode: 0,
459-
Output: helpers.ReadFile(filepath.Join(currentFolder, "missing-upstream/expectations/missing_upstream.json")),
459+
Output: helpers.ReadFile(filepath.Join(currentFolder, "test-pipelines/missing-upstream-pipeline/expectations/missing_upstream.json")),
460460
},
461461
Asserts: []func(*e2e.Task) error{
462462
e2e.AssertByExitCode,
@@ -466,7 +466,7 @@ func getTasks(binary string, currentFolder string) []e2e.Task {
466466
{
467467
Name: "run-malformed-sql",
468468
Command: binary,
469-
Args: []string{"run", filepath.Join(currentFolder, "malformed/assets/malformed.sql")},
469+
Args: []string{"run", filepath.Join(currentFolder, "test-pipelines/run-malformed-pipeline/assets/malformed.sql")},
470470
Env: []string{},
471471

472472
Expected: e2e.Output{
@@ -509,29 +509,29 @@ func getTasks(binary string, currentFolder string) []e2e.Task {
509509
},
510510
},
511511
{
512-
Name: "parse-pipeline-lineage",
512+
Name: "parse-lineage",
513513
Command: binary,
514-
Args: []string{"internal", "parse-pipeline", "-c", filepath.Join(currentFolder, "lineage")},
514+
Args: []string{"internal", "parse-pipeline", "-c", filepath.Join(currentFolder, "test-pipelines/parse-lineage-pipeline")},
515515
Env: []string{},
516516
SkipJSONNodes: []string{"\"path\""},
517517
Expected: e2e.Output{
518518
ExitCode: 0,
519-
Output: helpers.ReadFile(filepath.Join(currentFolder, "lineage/expectations/lineage.json")),
519+
Output: helpers.ReadFile(filepath.Join(currentFolder, "test-pipelines/parse-lineage-pipeline/expectations/lineage.json")),
520520
},
521521
Asserts: []func(*e2e.Task) error{
522522
e2e.AssertByExitCode,
523523
e2e.AssertByOutputJSON,
524524
},
525525
},
526526
{
527-
Name: "parse-asset-lineage-example",
527+
Name: "parse-asset-lineage",
528528
Command: binary,
529-
Args: []string{"internal", "parse-asset", "-c", filepath.Join(currentFolder, "lineage/assets/example.sql")},
529+
Args: []string{"internal", "parse-asset", "-c", filepath.Join(currentFolder, "test-pipelines/parse-asset-lineage-pipeline/assets/example.sql")},
530530
Env: []string{},
531531
SkipJSONNodes: []string{"\"path\""},
532532
Expected: e2e.Output{
533533
ExitCode: 0,
534-
Output: helpers.ReadFile(filepath.Join(currentFolder, "lineage/expectations/lineage-asset.json")),
534+
Output: helpers.ReadFile(filepath.Join(currentFolder, "test-pipelines/parse-asset-lineage-pipeline/expectations/lineage-asset.json")),
535535
},
536536
Asserts: []func(*e2e.Task) error{
537537
e2e.AssertByExitCode,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.bruin.yml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# Bruin - Sample Pipeline
2+
3+
This pipeline is a simple example of a Bruin pipeline. It demonstrates how to use the `bruin` CLI to build and run a pipeline.
4+
5+
The pipeline includes two sample assets already:
6+
- `myschema.example`: A simple SQL asset that creates a table in BigQuery.
7+
- Feel free to change the type from `bq.sql` to anything.
8+
- `myschema.country_list`: A simple Python asset that installs a dependency and runs the logic.
9+
10+
## Setup
11+
The pipeline already includes an empty `.bruin.yml` file, fill it with your connections and environments. You can read more about connections [here](https://bruin-data.github.io/bruin/connections/overview.html).
12+
13+
Here's a sample `.bruin.yml` file:
14+
15+
```yaml
16+
environments:
17+
default:
18+
connections:
19+
google_cloud_platform:
20+
- name: "gcp"
21+
service_account_file: "/path/to/my/key.json"
22+
project_id: "my-project-dev"
23+
snowflake:
24+
- name: "snowflake"
25+
username: "my-user"
26+
password: "my-password"
27+
account: "my-account"
28+
database: "my-database"
29+
warehouse: "my-warehouse"
30+
schema: "my-dev-schema"
31+
generic:
32+
- name: KEY1
33+
value: value1
34+
production:
35+
connections:
36+
google_cloud_platform:
37+
- name: "gcp"
38+
service_account_file: "/path/to/my/prod-key.json"
39+
project_id: "my-project-prod"
40+
snowflake:
41+
- name: "snowflake"
42+
username: "my-user"
43+
password: "my-password"
44+
account: "my-account"
45+
database: "my-database"
46+
warehouse: "my-warehouse"
47+
schema: "my-prod-schema"
48+
generic:
49+
- name: KEY1
50+
value: value1
51+
```
52+
53+
You can simply switch the environment using the `--environment` flag, e.g.:
54+
55+
```shell
56+
bruin validate --environment production .
57+
```
58+
59+
## Running the pipeline
60+
61+
bruin CLI can run the whole pipeline or any task with the downstreams:
62+
63+
```shell
64+
bruin run .
65+
```
66+
67+
```shell
68+
Starting the pipeline execution...
69+
70+
[2023-03-16T18:25:14Z] [worker-0] Running: dashboard.bruin-test
71+
[2023-03-16T18:25:16Z] [worker-0] Completed: dashboard.bruin-test (1.681s)
72+
[2023-03-16T18:25:16Z] [worker-4] Running: hello
73+
[2023-03-16T18:25:16Z] [worker-4] [hello] >> Hello, world!
74+
[2023-03-16T18:25:16Z] [worker-4] Completed: hello (116ms)
75+
76+
Executed 2 tasks in 1.798s
77+
```
78+
79+
You can also run a single task:
80+
81+
```shell
82+
bruin run assets/hello.py
83+
```
84+
85+
```shell
86+
Starting the pipeline execution...
87+
88+
[2023-03-16T18:25:59Z] [worker-0] Running: hello
89+
[2023-03-16T18:26:00Z] [worker-0] [hello] >> Hello, world!
90+
[2023-03-16T18:26:00Z] [worker-0] Completed: hello (103ms)
91+
92+
93+
Executed 1 tasks in 103ms
94+
```
95+
96+
You can optionally pass a `--downstream` flag to run the task with all of its downstreams.
97+
98+
That's it, good luck!
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/* @bruin
2+
name: product_categories
3+
type: duckdb.sql
4+
materialization:
5+
type: table
6+
7+
columns:
8+
- name: category_id
9+
type: INTEGER
10+
description: "Unique identifier for the product category"
11+
primary_key: true
12+
checks:
13+
- name: not_null
14+
- name: positive
15+
- name: category_name
16+
type: VARCHAR
17+
description: "Name of the product category"
18+
checks:
19+
- name: not_null
20+
- name: description
21+
type: VARCHAR
22+
description: "Description of the product category"
23+
@bruin */
24+
25+
SELECT
26+
1 AS category_id, 'Electronics' AS category_name, 'Devices like phones, laptops, and monitors' AS description
27+
UNION ALL
28+
SELECT
29+
2 AS category_id, 'Accessories' AS category_name, 'Complementary items like headphones and chargers' AS description
30+
UNION ALL
31+
SELECT
32+
3 AS category_id, 'Appliances' AS category_name, 'Household devices like refrigerators and microwaves' AS description
33+
UNION ALL
34+
SELECT
35+
4 AS category_id, 'Furniture' AS category_name, 'Home and office furniture like desks and chairs' AS description;

0 commit comments

Comments
 (0)