Skip to content
Open
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
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import json
from functools import lru_cache
from typing import Any

from data_factory_testing_framework._expression_runtime.expression_runtime import ExpressionRuntime
Expand All @@ -10,6 +11,13 @@
from data_factory_testing_framework.state import RunState


@lru_cache(maxsize=None)
def _get_expression_runtime() -> ExpressionRuntime:
# Building an ExpressionRuntime compiles the Lark grammar, which costs more than evaluating
# an expression. It holds no per-evaluation state, so one instance serves every element.
return ExpressionRuntime()


class DataFactoryElement:
expression: str
result: DataFactoryObjectType
Expand All @@ -26,8 +34,7 @@ def __init__(self, expression: str) -> None:
def evaluate(self, state: RunState) -> DataFactoryObjectType:
"""Evaluate the expression."""
try:
expression_runtime = ExpressionRuntime()
self.result = expression_runtime.evaluate(self.expression, state)
self.result = _get_expression_runtime().evaluate(self.expression, state)
return self.result
except UserError as e:
raise e from e
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
from unittest.mock import patch

import pytest
from data_factory_testing_framework._expression_runtime.expression_runtime import ExpressionRuntime
from data_factory_testing_framework.exceptions import (
DataFactoryElementEvaluationError,
ParameterNotFoundError,
)
from data_factory_testing_framework.exceptions._user_error import UserError
from data_factory_testing_framework.models import DataFactoryElement
from data_factory_testing_framework.models import DataFactoryElement, _data_factory_element
from data_factory_testing_framework.models._data_factory_element import _get_expression_runtime
from data_factory_testing_framework.state import PipelineRunState


Expand Down Expand Up @@ -44,3 +48,19 @@ def test_evaluate_datafactory_element_raises_technical_errors() -> None:
# Act
with pytest.raises(DataFactoryElementEvaluationError):
data_factory_element.evaluate(state)


def test_evaluate_datafactory_element_reuses_one_expression_runtime() -> None:
# Arrange
_get_expression_runtime.cache_clear()
state = PipelineRunState()
elements = [DataFactoryElement("@mul(2, 3)"), DataFactoryElement("@add(2, 3)")]

# Act
with patch.object(_data_factory_element, "ExpressionRuntime", wraps=ExpressionRuntime) as runtime_class:
results = [element.evaluate(state) for element in elements]
results.append(elements[0].evaluate(state))

# Assert
assert results == [6, 5, 6]
assert runtime_class.call_count == 1
Loading