Skip to content

Commit a993363

Browse files
authored
chore: dry tests (#87)
* chore: dry tests * chore: relocate run_cli_inspect * chore: fix type annotation * chore: note token isn't important * chore: cleanup args & typing * chore: extract 'get_platform_url' function * chore: extract 'support_otdfctl_args' module * chore: use '*get_cli_flags()' pattern * chore: DRY code * chore: DRY code * chore: extract 'get_testing_environ' function * chore: DRY code * chore: DRY code * chore: DRY code
1 parent 7fc9730 commit a993363

14 files changed

+704
-786
lines changed

.github/check_entitlements.sh

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
11
#!/bin/bash
22

3-
43
# Derive additional environment variables
54
TOKEN_URL="${OIDC_OP_TOKEN_ENDPOINT}"
65
OTDF_HOST_AND_PORT="${OPENTDF_PLATFORM_HOST}"
76
OTDF_CLIENT="${OPENTDF_CLIENT_ID}"
87
OTDF_CLIENT_SECRET="${OPENTDF_CLIENT_SECRET}"
98

10-
# Enable debug mode
11-
DEBUG=1
12-
139
echo "🔧 Environment Configuration:"
1410
echo " TOKEN_URL: ${TOKEN_URL}"
1511
echo " OTDF_HOST_AND_PORT: ${OTDF_HOST_AND_PORT}"
@@ -28,6 +24,8 @@ get_token() {
2824

2925
echo "🔐 Getting access token..."
3026
BEARER=$( get_token | jq -r '.access_token' )
27+
# NOTE: It's always okay to print this token, because it will
28+
# only be valid / available in dummy / dev scenarios
3129
[[ "${DEBUG:-}" == "1" ]] && echo "Got Access Token: ${BEARER}"
3230
echo ""
3331

tests/integration/conftest.py

Lines changed: 3 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -4,90 +4,14 @@
44

55
import json
66
import logging
7-
import os
8-
import subprocess
97
import tempfile
108
from pathlib import Path
119

1210
import pytest
1311

14-
from tests.support_cli_args import get_otdfctl_flags, get_platform_url
12+
from tests.support_otdfctl_args import generate_tdf_files_for_target_mode
1513

1614
logger = logging.getLogger(__name__)
17-
# from tests.config_pydantic import CONFIG_TDF
18-
19-
# Set up environment and configuration
20-
original_env = os.environ.copy()
21-
original_env["GRPC_ENFORCE_ALPN_ENABLED"] = "false"
22-
23-
platform_url = get_platform_url()
24-
otdfctl_flags = get_otdfctl_flags()
25-
26-
27-
def _generate_target_mode_tdf(
28-
input_file: Path,
29-
output_file: Path,
30-
target_mode: str,
31-
creds_file: Path,
32-
attributes: list[str] | None = None,
33-
mime_type: str | None = None,
34-
) -> None:
35-
"""
36-
Generate a TDF file using otdfctl with a specific target mode.
37-
38-
Args:
39-
input_file: Path to the input file to encrypt
40-
output_file: Path where the TDF file should be created
41-
target_mode: Target TDF spec version (e.g., "v4.2.2", "v4.3.1")
42-
creds_file: Path to credentials file
43-
attributes: Optional list of attributes to apply
44-
mime_type: Optional MIME type for the input file
45-
"""
46-
# Ensure output directory exists
47-
output_file.parent.mkdir(parents=True, exist_ok=True)
48-
49-
# Build otdfctl command
50-
cmd = [
51-
"otdfctl",
52-
"encrypt",
53-
"--host",
54-
platform_url,
55-
"--with-client-creds-file",
56-
str(creds_file),
57-
*otdfctl_flags,
58-
"--tdf-type",
59-
"tdf3",
60-
"--target-mode",
61-
target_mode,
62-
"-o",
63-
str(output_file),
64-
]
65-
66-
# Add optional parameters
67-
if attributes:
68-
for attr in attributes:
69-
cmd.extend(["--attr", attr])
70-
71-
if mime_type:
72-
cmd.extend(["--mime-type", mime_type])
73-
74-
# Add input file
75-
cmd.append(str(input_file))
76-
77-
# Run otdfctl command
78-
result = subprocess.run(
79-
cmd,
80-
capture_output=True,
81-
text=True,
82-
env=original_env,
83-
)
84-
85-
if result.returncode != 0:
86-
logger.error(f"otdfctl command failed: {result.stderr}")
87-
raise Exception(
88-
f"Failed to generate TDF with target mode {target_mode}: "
89-
f"stdout={result.stdout}, stderr={result.stderr}"
90-
)
9115

9216

9317
@pytest.fixture(scope="session")
@@ -118,79 +42,10 @@ def sample_input_files(test_data_dir):
11842
}
11943

12044

121-
def _generate_tdf_files_for_target_mode(
122-
target_mode: str,
123-
temp_credentials_file: Path,
124-
test_data_dir: Path,
125-
sample_input_files: dict[str, Path],
126-
) -> dict[str, Path]:
127-
"""
128-
Factory function to generate TDF files for a specific target mode.
129-
130-
Args:
131-
target_mode: Target TDF spec version (e.g., "v4.2.2", "v4.3.1")
132-
temp_credentials_file: Path to credentials file
133-
test_data_dir: Base test data directory
134-
sample_input_files: Dictionary of sample input files
135-
136-
Returns:
137-
Dictionary mapping file types to their TDF file paths
138-
"""
139-
output_dir = test_data_dir / target_mode
140-
tdf_files = {}
141-
142-
# Define the file generation configurations
143-
file_configs = [
144-
{
145-
"key": "text",
146-
"input_key": "text",
147-
"output_name": "sample_text.txt.tdf",
148-
"mime_type": "text/plain",
149-
},
150-
# {
151-
# "key": "empty",
152-
# "input_key": "empty",
153-
# "output_name": "empty_file.txt.tdf",
154-
# "mime_type": "text/plain",
155-
# },
156-
{
157-
"key": "binary",
158-
"input_key": "binary",
159-
"output_name": "sample_binary.png.tdf",
160-
"mime_type": "image/png",
161-
},
162-
{
163-
"key": "with_attributes",
164-
"input_key": "with_attributes",
165-
"output_name": "sample_with_attributes.txt.tdf",
166-
"mime_type": "text/plain",
167-
},
168-
]
169-
170-
try:
171-
for config in file_configs:
172-
tdf_path = output_dir / config["output_name"]
173-
_generate_target_mode_tdf(
174-
sample_input_files[config["input_key"]],
175-
tdf_path,
176-
target_mode,
177-
temp_credentials_file,
178-
# attributes=[CONFIG_TDF.TEST_OPENTDF_ATTRIBUTE_1] if config["key"] == "with_attributes" else None, # Temporarily disabled due to external KAS dependency
179-
mime_type=config["mime_type"],
180-
)
181-
tdf_files[config["key"]] = tdf_path
182-
183-
return tdf_files
184-
185-
except Exception as e:
186-
logger.error(f"Error generating {target_mode} TDF files: {e}")
187-
raise Exception(f"Failed to generate {target_mode} TDF files: {e}") from e
188-
189-
19045
@pytest.fixture(scope="session")
19146
def tdf_v4_2_2_files(temp_credentials_file, test_data_dir, sample_input_files):
19247
"""Generate TDF files with target mode v4.2.2."""
193-
tdf_files = _generate_tdf_files_for_target_mode(
48+
tdf_files = generate_tdf_files_for_target_mode(
19449
"v4.2.2", temp_credentials_file, test_data_dir, sample_input_files
19550
)
19651
yield tdf_files
@@ -199,7 +54,7 @@ def tdf_v4_2_2_files(temp_credentials_file, test_data_dir, sample_input_files):
19954
@pytest.fixture(scope="session")
20055
def tdf_v4_3_1_files(temp_credentials_file, test_data_dir, sample_input_files):
20156
"""Generate TDF files with target mode v4.3.1."""
202-
tdf_files = _generate_tdf_files_for_target_mode(
57+
tdf_files = generate_tdf_files_for_target_mode(
20358
"v4.3.1", temp_credentials_file, test_data_dir, sample_input_files
20459
)
20560
yield tdf_files

tests/integration/otdfctl_only/test_fixture_structure.py renamed to tests/integration/otdfctl_only/test_otdfctl_generated_fixtures.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from pathlib import Path
2+
13
import pytest
24

35

@@ -75,3 +77,49 @@ def test_sample_file_contents(sample_input_files):
7577
with open(attr_file) as f:
7678
content = f.read()
7779
assert "Classification: SECRET" in content
80+
81+
82+
@pytest.mark.integration
83+
def test_target_mode_fixtures_exist(all_target_mode_tdf_files):
84+
"""Test that target mode fixtures generate TDF files correctly."""
85+
# Check that we have both versions
86+
assert "v4.2.2" in all_target_mode_tdf_files
87+
assert "v4.3.1" in all_target_mode_tdf_files
88+
89+
# Check each version has the expected file types
90+
for version in ["v4.2.2", "v4.3.1"]:
91+
tdf_files = all_target_mode_tdf_files[version]
92+
93+
# Check all expected file types exist
94+
expected_types = [
95+
"text",
96+
"binary",
97+
"with_attributes",
98+
] # Consider 'empty' as well
99+
for file_type in expected_types:
100+
assert file_type in tdf_files, f"Missing {file_type} TDF for {version}"
101+
102+
# Check the TDF file exists and is not empty
103+
tdf_path = tdf_files[file_type]
104+
assert isinstance(tdf_path, Path)
105+
assert tdf_path.exists(), f"TDF file does not exist: {tdf_path}"
106+
assert tdf_path.stat().st_size > 0, f"TDF file is empty: {tdf_path}"
107+
108+
# Check it's a valid ZIP file (TDF format)
109+
with open(tdf_path, "rb") as f:
110+
header = f.read(4)
111+
assert header == b"PK\x03\x04", f"TDF file is not a valid ZIP: {tdf_path}"
112+
113+
114+
@pytest.mark.integration
115+
def test_v4_2_2_tdf_files(tdf_v4_2_2_files):
116+
"""Test that v4.2.2 TDF fixtures work independently."""
117+
assert "text" in tdf_v4_2_2_files
118+
assert tdf_v4_2_2_files["text"].exists()
119+
120+
121+
@pytest.mark.integration
122+
def test_v4_3_1_tdf_files(tdf_v4_3_1_files):
123+
"""Test that v4.3.1 TDF fixtures work independently."""
124+
assert "text" in tdf_v4_3_1_files
125+
assert tdf_v4_3_1_files["text"].exists()

0 commit comments

Comments
 (0)