Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Paw/record final #10045

Merged
merged 3 commits into from
Apr 26, 2024
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
6 changes: 6 additions & 0 deletions .changes/unreleased/Under the Hood-20240425-170138.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: Under the Hood
body: Enable use of record mode via environment variable
time: 2024-04-25T17:01:38.093524-04:00
custom:
Author: peterallenwebb
Issue: "10045"
40 changes: 37 additions & 3 deletions core/dbt/cli/requires.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import os

import dbt.tracking
from dbt_common.context import set_invocation_context
from dbt_common.context import get_invocation_context, set_invocation_context
from dbt_common.record import Recorder, RecorderMode, get_record_mode_from_env
from dbt_common.clients.system import get_env
from dbt_common.invocation import reset_invocation_id

import dbt.tracking
from dbt.version import installed as installed_version
from dbt.adapters.factory import adapter_management, register_adapter, get_adapter
from dbt.context.providers import generate_runtime_macro_context
Expand Down Expand Up @@ -44,6 +46,7 @@
import importlib.util
import time
import traceback
from typing import Optional


def preflight(func):
Expand All @@ -52,7 +55,14 @@
assert isinstance(ctx, Context)
ctx.obj = ctx.obj or {}

set_invocation_context(os.environ)
set_invocation_context({})

# Record/Replay
setup_record_replay()

# Must be set after record/replay is set up so that the env can be
# recorded or replayed if needed.
get_invocation_context()._env = get_env()

# Flags
flags = Flags(ctx)
Expand Down Expand Up @@ -93,6 +103,28 @@
return update_wrapper(wrapper, func)


def setup_record_replay():
rec_mode = get_record_mode_from_env()

recorder: Optional[Recorder] = None
if rec_mode == RecorderMode.REPLAY:
recording_path = os.environ["DBT_REPLAY"]
recorder = Recorder(RecorderMode.REPLAY, recording_path)

Check warning on line 112 in core/dbt/cli/requires.py

View check run for this annotation

Codecov / codecov/patch

core/dbt/cli/requires.py#L111-L112

Added lines #L111 - L112 were not covered by tests
elif rec_mode == RecorderMode.RECORD:
recorder = Recorder(RecorderMode.RECORD)

Check warning on line 114 in core/dbt/cli/requires.py

View check run for this annotation

Codecov / codecov/patch

core/dbt/cli/requires.py#L114

Added line #L114 was not covered by tests

get_invocation_context().recorder = recorder


def tear_down_record_replay():
recorder = get_invocation_context().recorder
if recorder is not None:
if recorder.mode == RecorderMode.RECORD:
recorder.write("recording.json")
elif recorder.mode == RecorderMode.REPLAY:
recorder.write_diffs("replay_diffs.json")

Check warning on line 125 in core/dbt/cli/requires.py

View check run for this annotation

Codecov / codecov/patch

core/dbt/cli/requires.py#L122-L125

Added lines #L122 - L125 were not covered by tests


def postflight(func):
"""The decorator that handles all exception handling for the click commands.
This decorator must be used before any other decorators that may throw an exception."""
Expand Down Expand Up @@ -146,6 +178,8 @@
)
)

tear_down_record_replay()

if not success:
raise ResultExit(result)

Expand Down
17 changes: 17 additions & 0 deletions tests/functional/record/record.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import os

from dbt.tests.util import run_dbt


class TestRecord:
def test_record_when_env_var_set(self, project):
temp = os.environ.get("DBT_RECORD", None)
try:
os.environ["DBT_RECORD"] = "True"
run_dbt(["run"])
assert os.path.isfile(os.path.join(os.getcwd(), "recording.json"))
finally:
if temp is None:
del os.environ["DBT_RECORD"]
else:
os.environ["DBT_RECORD"] = temp