moose-lib 0.6.157__tar.gz → 0.6.159__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of moose-lib might be problematic. Click here for more details.
- {moose_lib-0.6.157 → moose_lib-0.6.159}/PKG-INFO +1 -1
- {moose_lib-0.6.157 → moose_lib-0.6.159}/moose_lib/__init__.py +2 -0
- {moose_lib-0.6.157 → moose_lib-0.6.159}/moose_lib/dmv2/olap_table.py +1 -0
- {moose_lib-0.6.157 → moose_lib-0.6.159}/moose_lib/internal.py +3 -1
- moose_lib-0.6.159/moose_lib/secrets.py +100 -0
- {moose_lib-0.6.157 → moose_lib-0.6.159}/moose_lib.egg-info/PKG-INFO +1 -1
- {moose_lib-0.6.157 → moose_lib-0.6.159}/moose_lib.egg-info/SOURCES.txt +2 -0
- moose_lib-0.6.159/tests/test_secrets.py +221 -0
- {moose_lib-0.6.157 → moose_lib-0.6.159}/README.md +0 -0
- {moose_lib-0.6.157 → moose_lib-0.6.159}/moose_lib/blocks.py +0 -0
- {moose_lib-0.6.157 → moose_lib-0.6.159}/moose_lib/clients/__init__.py +0 -0
- {moose_lib-0.6.157 → moose_lib-0.6.159}/moose_lib/clients/redis_client.py +0 -0
- {moose_lib-0.6.157 → moose_lib-0.6.159}/moose_lib/commons.py +0 -0
- {moose_lib-0.6.157 → moose_lib-0.6.159}/moose_lib/config/__init__.py +0 -0
- {moose_lib-0.6.157 → moose_lib-0.6.159}/moose_lib/config/config_file.py +0 -0
- {moose_lib-0.6.157 → moose_lib-0.6.159}/moose_lib/config/runtime.py +0 -0
- {moose_lib-0.6.157 → moose_lib-0.6.159}/moose_lib/data_models.py +0 -0
- {moose_lib-0.6.157 → moose_lib-0.6.159}/moose_lib/dmv2/__init__.py +0 -0
- {moose_lib-0.6.157 → moose_lib-0.6.159}/moose_lib/dmv2/_registry.py +0 -0
- {moose_lib-0.6.157 → moose_lib-0.6.159}/moose_lib/dmv2/consumption.py +0 -0
- {moose_lib-0.6.157 → moose_lib-0.6.159}/moose_lib/dmv2/ingest_api.py +0 -0
- {moose_lib-0.6.157 → moose_lib-0.6.159}/moose_lib/dmv2/ingest_pipeline.py +0 -0
- {moose_lib-0.6.157 → moose_lib-0.6.159}/moose_lib/dmv2/life_cycle.py +0 -0
- {moose_lib-0.6.157 → moose_lib-0.6.159}/moose_lib/dmv2/materialized_view.py +0 -0
- {moose_lib-0.6.157 → moose_lib-0.6.159}/moose_lib/dmv2/registry.py +0 -0
- {moose_lib-0.6.157 → moose_lib-0.6.159}/moose_lib/dmv2/sql_resource.py +0 -0
- {moose_lib-0.6.157 → moose_lib-0.6.159}/moose_lib/dmv2/stream.py +0 -0
- {moose_lib-0.6.157 → moose_lib-0.6.159}/moose_lib/dmv2/types.py +0 -0
- {moose_lib-0.6.157 → moose_lib-0.6.159}/moose_lib/dmv2/view.py +0 -0
- {moose_lib-0.6.157 → moose_lib-0.6.159}/moose_lib/dmv2/web_app.py +0 -0
- {moose_lib-0.6.157 → moose_lib-0.6.159}/moose_lib/dmv2/web_app_helpers.py +0 -0
- {moose_lib-0.6.157 → moose_lib-0.6.159}/moose_lib/dmv2/workflow.py +0 -0
- {moose_lib-0.6.157 → moose_lib-0.6.159}/moose_lib/dmv2_serializer.py +0 -0
- {moose_lib-0.6.157 → moose_lib-0.6.159}/moose_lib/main.py +0 -0
- {moose_lib-0.6.157 → moose_lib-0.6.159}/moose_lib/query_builder.py +0 -0
- {moose_lib-0.6.157 → moose_lib-0.6.159}/moose_lib/query_param.py +0 -0
- {moose_lib-0.6.157 → moose_lib-0.6.159}/moose_lib/streaming/__init__.py +0 -0
- {moose_lib-0.6.157 → moose_lib-0.6.159}/moose_lib/streaming/streaming_function_runner.py +0 -0
- {moose_lib-0.6.157 → moose_lib-0.6.159}/moose_lib/utilities/__init__.py +0 -0
- {moose_lib-0.6.157 → moose_lib-0.6.159}/moose_lib/utilities/sql.py +0 -0
- {moose_lib-0.6.157 → moose_lib-0.6.159}/moose_lib.egg-info/dependency_links.txt +0 -0
- {moose_lib-0.6.157 → moose_lib-0.6.159}/moose_lib.egg-info/requires.txt +0 -0
- {moose_lib-0.6.157 → moose_lib-0.6.159}/moose_lib.egg-info/top_level.txt +0 -0
- {moose_lib-0.6.157 → moose_lib-0.6.159}/setup.cfg +0 -0
- {moose_lib-0.6.157 → moose_lib-0.6.159}/setup.py +0 -0
- {moose_lib-0.6.157 → moose_lib-0.6.159}/tests/__init__.py +0 -0
- {moose_lib-0.6.157 → moose_lib-0.6.159}/tests/conftest.py +0 -0
- {moose_lib-0.6.157 → moose_lib-0.6.159}/tests/test_moose.py +0 -0
- {moose_lib-0.6.157 → moose_lib-0.6.159}/tests/test_olap_table_versioning.py +0 -0
- {moose_lib-0.6.157 → moose_lib-0.6.159}/tests/test_query_builder.py +0 -0
- {moose_lib-0.6.157 → moose_lib-0.6.159}/tests/test_redis_client.py +0 -0
- {moose_lib-0.6.157 → moose_lib-0.6.159}/tests/test_s3queue_config.py +0 -0
- {moose_lib-0.6.157 → moose_lib-0.6.159}/tests/test_simple_aggregate.py +0 -0
- {moose_lib-0.6.157 → moose_lib-0.6.159}/tests/test_web_app.py +0 -0
|
@@ -143,6 +143,7 @@ class OlapConfig(BaseModel):
|
|
|
143
143
|
granularity: int = 1
|
|
144
144
|
|
|
145
145
|
indexes: list[TableIndex] = []
|
|
146
|
+
database: Optional[str] = None # Optional database name for multi-database support
|
|
146
147
|
|
|
147
148
|
def model_post_init(self, __context):
|
|
148
149
|
has_fields = bool(self.order_by_fields)
|
|
@@ -171,6 +171,7 @@ class TableConfig(BaseModel):
|
|
|
171
171
|
table_settings: Optional[dict[str, str]] = None
|
|
172
172
|
indexes: list[OlapConfig.TableIndex] = []
|
|
173
173
|
ttl: Optional[str] = None
|
|
174
|
+
database: Optional[str] = None
|
|
174
175
|
|
|
175
176
|
|
|
176
177
|
class TopicConfig(BaseModel):
|
|
@@ -613,6 +614,7 @@ def to_infra_map() -> dict:
|
|
|
613
614
|
table_settings=table_settings if table_settings else None,
|
|
614
615
|
indexes=table.config.indexes,
|
|
615
616
|
ttl=table.config.ttl,
|
|
617
|
+
database=table.config.database,
|
|
616
618
|
)
|
|
617
619
|
|
|
618
620
|
for name, stream in get_streams().items():
|
|
@@ -716,7 +718,7 @@ def to_infra_map() -> dict:
|
|
|
716
718
|
web_apps=web_apps
|
|
717
719
|
)
|
|
718
720
|
|
|
719
|
-
return infra_map.model_dump(by_alias=True)
|
|
721
|
+
return infra_map.model_dump(by_alias=True, exclude_none=False)
|
|
720
722
|
|
|
721
723
|
|
|
722
724
|
def load_models():
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"""Utilities for runtime environment variable resolution.
|
|
2
|
+
|
|
3
|
+
This module provides functionality to mark values that should be resolved
|
|
4
|
+
from environment variables at runtime by the Moose CLI, rather than being
|
|
5
|
+
embedded at build time.
|
|
6
|
+
|
|
7
|
+
Example:
|
|
8
|
+
>>> from moose_lib import S3QueueEngine, moose_runtime_env
|
|
9
|
+
>>>
|
|
10
|
+
>>> engine = S3QueueEngine(
|
|
11
|
+
... s3_path="s3://bucket/data/*.json",
|
|
12
|
+
... format="JSONEachRow",
|
|
13
|
+
... aws_access_key_id=moose_runtime_env.get("AWS_ACCESS_KEY_ID"),
|
|
14
|
+
... aws_secret_access_key=moose_runtime_env.get("AWS_SECRET_ACCESS_KEY")
|
|
15
|
+
... )
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
#: Prefix used to mark values for runtime environment variable resolution.
|
|
19
|
+
MOOSE_RUNTIME_ENV_PREFIX = "__MOOSE_RUNTIME_ENV__:"
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def get(env_var_name: str) -> str:
|
|
23
|
+
"""Marks a value to be resolved from an environment variable at runtime.
|
|
24
|
+
|
|
25
|
+
When you use this function, the value is not read immediately. Instead,
|
|
26
|
+
a special marker is created that the Moose CLI will resolve when it
|
|
27
|
+
processes your infrastructure configuration.
|
|
28
|
+
|
|
29
|
+
This is useful for:
|
|
30
|
+
- Credentials that should never be embedded in Docker images
|
|
31
|
+
- Configuration that can be rotated without rebuilding
|
|
32
|
+
- Different values for different environments (dev, staging, prod)
|
|
33
|
+
- Any runtime configuration in infrastructure elements (Tables, Topics, etc.)
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
env_var_name: Name of the environment variable to resolve
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
A marker string that Moose CLI will resolve at runtime
|
|
40
|
+
|
|
41
|
+
Raises:
|
|
42
|
+
ValueError: If the environment variable name is empty
|
|
43
|
+
|
|
44
|
+
Example:
|
|
45
|
+
>>> # Instead of this (evaluated at build time):
|
|
46
|
+
>>> import os
|
|
47
|
+
>>> aws_key = os.environ.get("AWS_ACCESS_KEY_ID")
|
|
48
|
+
>>>
|
|
49
|
+
>>> # Use this (evaluated at runtime):
|
|
50
|
+
>>> aws_key = moose_runtime_env.get("AWS_ACCESS_KEY_ID")
|
|
51
|
+
"""
|
|
52
|
+
if not env_var_name or not env_var_name.strip():
|
|
53
|
+
raise ValueError("Environment variable name cannot be empty")
|
|
54
|
+
return f"{MOOSE_RUNTIME_ENV_PREFIX}{env_var_name}"
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class MooseRuntimeEnv:
|
|
58
|
+
"""Utilities for marking values to be resolved from environment variables at runtime.
|
|
59
|
+
|
|
60
|
+
This class provides a namespace for runtime environment variable resolution.
|
|
61
|
+
Use the singleton instance `moose_runtime_env` rather than instantiating this class directly.
|
|
62
|
+
|
|
63
|
+
Attributes:
|
|
64
|
+
get: Static method for creating runtime environment variable markers
|
|
65
|
+
"""
|
|
66
|
+
|
|
67
|
+
@staticmethod
|
|
68
|
+
def get(env_var_name: str) -> str:
|
|
69
|
+
"""Marks a value to be resolved from an environment variable at runtime.
|
|
70
|
+
|
|
71
|
+
Args:
|
|
72
|
+
env_var_name: Name of the environment variable to resolve
|
|
73
|
+
|
|
74
|
+
Returns:
|
|
75
|
+
A marker string that Moose CLI will resolve at runtime
|
|
76
|
+
|
|
77
|
+
Raises:
|
|
78
|
+
ValueError: If the environment variable name is empty
|
|
79
|
+
"""
|
|
80
|
+
return get(env_var_name)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
# Export singleton instance for module-level access
|
|
84
|
+
moose_runtime_env = MooseRuntimeEnv()
|
|
85
|
+
|
|
86
|
+
# Legacy exports for backwards compatibility
|
|
87
|
+
MooseEnvSecrets = MooseRuntimeEnv # Deprecated: Use MooseRuntimeEnv instead
|
|
88
|
+
moose_env_secrets = moose_runtime_env # Deprecated: Use moose_runtime_env instead
|
|
89
|
+
MOOSE_ENV_SECRET_PREFIX = MOOSE_RUNTIME_ENV_PREFIX # Deprecated: Use MOOSE_RUNTIME_ENV_PREFIX instead
|
|
90
|
+
|
|
91
|
+
__all__ = [
|
|
92
|
+
"moose_runtime_env",
|
|
93
|
+
"MooseRuntimeEnv",
|
|
94
|
+
"get",
|
|
95
|
+
"MOOSE_RUNTIME_ENV_PREFIX",
|
|
96
|
+
# Legacy exports (deprecated)
|
|
97
|
+
"moose_env_secrets",
|
|
98
|
+
"MooseEnvSecrets",
|
|
99
|
+
"MOOSE_ENV_SECRET_PREFIX",
|
|
100
|
+
]
|
|
@@ -9,6 +9,7 @@ moose_lib/internal.py
|
|
|
9
9
|
moose_lib/main.py
|
|
10
10
|
moose_lib/query_builder.py
|
|
11
11
|
moose_lib/query_param.py
|
|
12
|
+
moose_lib/secrets.py
|
|
12
13
|
moose_lib.egg-info/PKG-INFO
|
|
13
14
|
moose_lib.egg-info/SOURCES.txt
|
|
14
15
|
moose_lib.egg-info/dependency_links.txt
|
|
@@ -46,5 +47,6 @@ tests/test_olap_table_versioning.py
|
|
|
46
47
|
tests/test_query_builder.py
|
|
47
48
|
tests/test_redis_client.py
|
|
48
49
|
tests/test_s3queue_config.py
|
|
50
|
+
tests/test_secrets.py
|
|
49
51
|
tests/test_simple_aggregate.py
|
|
50
52
|
tests/test_web_app.py
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
"""Tests for the moose_lib.secrets module.
|
|
2
|
+
|
|
3
|
+
This module tests the runtime environment variable marker functionality,
|
|
4
|
+
which allows users to defer secret resolution until runtime rather than
|
|
5
|
+
embedding secrets at build time.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import pytest
|
|
9
|
+
from moose_lib.secrets import moose_runtime_env, get, MOOSE_RUNTIME_ENV_PREFIX
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class TestMooseRuntimeEnvGet:
|
|
13
|
+
"""Tests for the moose_runtime_env.get() method."""
|
|
14
|
+
|
|
15
|
+
def test_creates_marker_with_correct_prefix(self):
|
|
16
|
+
"""Should create a marker string with the correct prefix."""
|
|
17
|
+
var_name = "AWS_ACCESS_KEY_ID"
|
|
18
|
+
result = moose_runtime_env.get(var_name)
|
|
19
|
+
|
|
20
|
+
assert result == f"{MOOSE_RUNTIME_ENV_PREFIX}{var_name}"
|
|
21
|
+
assert result == "__MOOSE_RUNTIME_ENV__:AWS_ACCESS_KEY_ID"
|
|
22
|
+
|
|
23
|
+
def test_handles_different_variable_names(self):
|
|
24
|
+
"""Should handle different environment variable names correctly."""
|
|
25
|
+
test_cases = [
|
|
26
|
+
"AWS_SECRET_ACCESS_KEY",
|
|
27
|
+
"DATABASE_PASSWORD",
|
|
28
|
+
"API_KEY",
|
|
29
|
+
"MY_CUSTOM_SECRET",
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
for var_name in test_cases:
|
|
33
|
+
result = moose_runtime_env.get(var_name)
|
|
34
|
+
assert result == f"{MOOSE_RUNTIME_ENV_PREFIX}{var_name}"
|
|
35
|
+
assert var_name in result
|
|
36
|
+
|
|
37
|
+
def test_raises_error_for_empty_string(self):
|
|
38
|
+
"""Should raise ValueError for empty string."""
|
|
39
|
+
with pytest.raises(ValueError, match="Environment variable name cannot be empty"):
|
|
40
|
+
moose_runtime_env.get("")
|
|
41
|
+
|
|
42
|
+
def test_raises_error_for_whitespace_only(self):
|
|
43
|
+
"""Should raise ValueError for whitespace-only string."""
|
|
44
|
+
with pytest.raises(ValueError, match="Environment variable name cannot be empty"):
|
|
45
|
+
moose_runtime_env.get(" ")
|
|
46
|
+
|
|
47
|
+
def test_raises_error_for_tabs_only(self):
|
|
48
|
+
"""Should raise ValueError for string with only tabs."""
|
|
49
|
+
with pytest.raises(ValueError, match="Environment variable name cannot be empty"):
|
|
50
|
+
moose_runtime_env.get("\t\t")
|
|
51
|
+
|
|
52
|
+
def test_allows_underscores_in_variable_names(self):
|
|
53
|
+
"""Should allow variable names with underscores."""
|
|
54
|
+
var_name = "MY_LONG_VAR_NAME"
|
|
55
|
+
result = moose_runtime_env.get(var_name)
|
|
56
|
+
|
|
57
|
+
assert result == f"{MOOSE_RUNTIME_ENV_PREFIX}{var_name}"
|
|
58
|
+
|
|
59
|
+
def test_allows_numbers_in_variable_names(self):
|
|
60
|
+
"""Should allow variable names with numbers."""
|
|
61
|
+
var_name = "API_KEY_123"
|
|
62
|
+
result = moose_runtime_env.get(var_name)
|
|
63
|
+
|
|
64
|
+
assert result == f"{MOOSE_RUNTIME_ENV_PREFIX}{var_name}"
|
|
65
|
+
|
|
66
|
+
def test_preserves_exact_casing(self):
|
|
67
|
+
"""Should preserve exact variable name casing."""
|
|
68
|
+
var_name = "MixedCase_VarName"
|
|
69
|
+
result = moose_runtime_env.get(var_name)
|
|
70
|
+
|
|
71
|
+
assert var_name in result
|
|
72
|
+
assert var_name.lower() not in result # Ensure casing wasn't changed
|
|
73
|
+
|
|
74
|
+
def test_can_be_used_in_s3queue_config(self):
|
|
75
|
+
"""Should create markers that can be used in S3Queue configuration."""
|
|
76
|
+
access_key_marker = moose_runtime_env.get("AWS_ACCESS_KEY_ID")
|
|
77
|
+
secret_key_marker = moose_runtime_env.get("AWS_SECRET_ACCESS_KEY")
|
|
78
|
+
|
|
79
|
+
config = {
|
|
80
|
+
"aws_access_key_id": access_key_marker,
|
|
81
|
+
"aws_secret_access_key": secret_key_marker,
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
assert "AWS_ACCESS_KEY_ID" in config["aws_access_key_id"]
|
|
85
|
+
assert "AWS_SECRET_ACCESS_KEY" in config["aws_secret_access_key"]
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
class TestModuleLevelGetFunction:
|
|
89
|
+
"""Tests for the module-level get() function."""
|
|
90
|
+
|
|
91
|
+
def test_module_level_get_creates_marker(self):
|
|
92
|
+
"""The module-level get function should create markers."""
|
|
93
|
+
var_name = "TEST_SECRET"
|
|
94
|
+
result = get(var_name)
|
|
95
|
+
|
|
96
|
+
assert result == f"{MOOSE_RUNTIME_ENV_PREFIX}{var_name}"
|
|
97
|
+
|
|
98
|
+
def test_module_level_get_matches_class_method(self):
|
|
99
|
+
"""Module-level get should produce same result as class method."""
|
|
100
|
+
var_name = "MY_SECRET"
|
|
101
|
+
|
|
102
|
+
result_module = get(var_name)
|
|
103
|
+
result_class = moose_runtime_env.get(var_name)
|
|
104
|
+
|
|
105
|
+
assert result_module == result_class
|
|
106
|
+
|
|
107
|
+
def test_module_level_get_raises_error_for_empty(self):
|
|
108
|
+
"""Module-level get should raise ValueError for empty string."""
|
|
109
|
+
with pytest.raises(ValueError, match="Environment variable name cannot be empty"):
|
|
110
|
+
get("")
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
class TestMooseRuntimeEnvPrefix:
|
|
114
|
+
"""Tests for the MOOSE_RUNTIME_ENV_PREFIX constant."""
|
|
115
|
+
|
|
116
|
+
def test_has_expected_value(self):
|
|
117
|
+
"""Should have the expected prefix value."""
|
|
118
|
+
assert MOOSE_RUNTIME_ENV_PREFIX == "__MOOSE_RUNTIME_ENV__:"
|
|
119
|
+
|
|
120
|
+
def test_is_string(self):
|
|
121
|
+
"""Should be a string."""
|
|
122
|
+
assert isinstance(MOOSE_RUNTIME_ENV_PREFIX, str)
|
|
123
|
+
|
|
124
|
+
def test_is_not_empty(self):
|
|
125
|
+
"""Should not be empty."""
|
|
126
|
+
assert len(MOOSE_RUNTIME_ENV_PREFIX) > 0
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
class TestMarkerFormatValidation:
|
|
130
|
+
"""Tests for marker format validation and parsing."""
|
|
131
|
+
|
|
132
|
+
def test_creates_easily_detectable_markers(self):
|
|
133
|
+
"""Should create markers that are easily detectable."""
|
|
134
|
+
marker = moose_runtime_env.get("TEST_VAR")
|
|
135
|
+
|
|
136
|
+
assert marker.startswith("__MOOSE_RUNTIME_ENV__:")
|
|
137
|
+
|
|
138
|
+
def test_markers_can_be_split_to_extract_variable_name(self):
|
|
139
|
+
"""Should create markers that can be split to extract variable name."""
|
|
140
|
+
var_name = "MY_SECRET"
|
|
141
|
+
marker = moose_runtime_env.get(var_name)
|
|
142
|
+
|
|
143
|
+
parts = marker.split(MOOSE_RUNTIME_ENV_PREFIX)
|
|
144
|
+
assert len(parts) == 2
|
|
145
|
+
assert parts[1] == var_name
|
|
146
|
+
|
|
147
|
+
def test_markers_are_json_serializable(self):
|
|
148
|
+
"""Should create markers that are JSON serializable."""
|
|
149
|
+
import json
|
|
150
|
+
|
|
151
|
+
marker = moose_runtime_env.get("TEST_VAR")
|
|
152
|
+
json_str = json.dumps({"secret": marker})
|
|
153
|
+
parsed = json.loads(json_str)
|
|
154
|
+
|
|
155
|
+
assert parsed["secret"] == marker
|
|
156
|
+
|
|
157
|
+
def test_markers_work_with_dict_serialization(self):
|
|
158
|
+
"""Should work correctly with dictionary serialization."""
|
|
159
|
+
marker = moose_runtime_env.get("DATABASE_PASSWORD")
|
|
160
|
+
|
|
161
|
+
config = {
|
|
162
|
+
"password": marker,
|
|
163
|
+
"other_field": "value"
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
# Verify the marker is preserved in the dict
|
|
167
|
+
assert config["password"] == marker
|
|
168
|
+
assert MOOSE_RUNTIME_ENV_PREFIX in config["password"]
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
class TestIntegrationScenarios:
|
|
172
|
+
"""Integration tests for real-world usage scenarios."""
|
|
173
|
+
|
|
174
|
+
def test_s3queue_engine_with_secrets(self):
|
|
175
|
+
"""Should work correctly in S3Queue engine configuration."""
|
|
176
|
+
from moose_lib.blocks import S3QueueEngine
|
|
177
|
+
|
|
178
|
+
engine = S3QueueEngine(
|
|
179
|
+
s3_path="s3://my-bucket/data/*.json",
|
|
180
|
+
format="JSONEachRow",
|
|
181
|
+
aws_access_key_id=moose_runtime_env.get("AWS_ACCESS_KEY_ID"),
|
|
182
|
+
aws_secret_access_key=moose_runtime_env.get("AWS_SECRET_ACCESS_KEY"),
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
# Verify markers were set correctly
|
|
186
|
+
assert engine.aws_access_key_id == "__MOOSE_RUNTIME_ENV__:AWS_ACCESS_KEY_ID"
|
|
187
|
+
assert engine.aws_secret_access_key == "__MOOSE_RUNTIME_ENV__:AWS_SECRET_ACCESS_KEY"
|
|
188
|
+
|
|
189
|
+
def test_multiple_secrets_in_same_config(self):
|
|
190
|
+
"""Should handle multiple secrets in the same configuration."""
|
|
191
|
+
config = {
|
|
192
|
+
"username": moose_runtime_env.get("DB_USERNAME"),
|
|
193
|
+
"password": moose_runtime_env.get("DB_PASSWORD"),
|
|
194
|
+
"api_key": moose_runtime_env.get("API_KEY"),
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
# All should have the correct prefix
|
|
198
|
+
for value in config.values():
|
|
199
|
+
assert value.startswith(MOOSE_RUNTIME_ENV_PREFIX)
|
|
200
|
+
|
|
201
|
+
# Each should have the correct variable name
|
|
202
|
+
assert "DB_USERNAME" in config["username"]
|
|
203
|
+
assert "DB_PASSWORD" in config["password"]
|
|
204
|
+
assert "API_KEY" in config["api_key"]
|
|
205
|
+
|
|
206
|
+
def test_mixed_secret_and_plain_values(self):
|
|
207
|
+
"""Should handle mix of secret markers and plain values."""
|
|
208
|
+
config = {
|
|
209
|
+
"region": "us-east-1", # Plain value
|
|
210
|
+
"access_key": moose_runtime_env.get("AWS_ACCESS_KEY_ID"), # Secret
|
|
211
|
+
"bucket": "my-bucket", # Plain value
|
|
212
|
+
"secret_key": moose_runtime_env.get("AWS_SECRET_ACCESS_KEY"), # Secret
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
# Plain values should be unchanged
|
|
216
|
+
assert config["region"] == "us-east-1"
|
|
217
|
+
assert config["bucket"] == "my-bucket"
|
|
218
|
+
|
|
219
|
+
# Secrets should have markers
|
|
220
|
+
assert MOOSE_RUNTIME_ENV_PREFIX in config["access_key"]
|
|
221
|
+
assert MOOSE_RUNTIME_ENV_PREFIX in config["secret_key"]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|