22Test CLI functionality
33"""
44
5- import subprocess
65import tempfile
76from pathlib import Path
87
98import pytest
109
11- from tests .support_cli_args import build_cli_decrypt_command
10+ from tests .support_cli_args import run_cli_decrypt
11+ from tests .support_common import (
12+ handle_subprocess_error ,
13+ validate_plaintext_file_created ,
14+ validate_tdf3_file ,
15+ )
1216from tests .support_otdfctl_args import (
13- build_otdfctl_decrypt_command ,
14- build_otdfctl_encrypt_command ,
17+ run_otdfctl_decrypt_command ,
18+ run_otdfctl_encrypt_command ,
1519)
1620
1721
1822@pytest .mark .integration
19- def test_otdfctl_encrypt_python_decrypt (collect_server_logs , temp_credentials_file ):
23+ def test_otdfctl_encrypt_python_decrypt (
24+ collect_server_logs , temp_credentials_file , project_root
25+ ):
2026 """Integration test that uses otdfctl for encryption and the Python CLI for decryption"""
2127
2228 # Create temporary directory for work
@@ -37,99 +43,57 @@ def test_otdfctl_encrypt_python_decrypt(collect_server_logs, temp_credentials_fi
3743 cli_decrypt_output = temp_path / "decrypted-by-cli.txt"
3844
3945 # Run otdfctl encrypt first to create a TDF file
40- otdfctl_encrypt_cmd = build_otdfctl_encrypt_command (
46+ otdfctl_encrypt_result = run_otdfctl_encrypt_command (
4147 creds_file = temp_credentials_file ,
4248 input_file = input_file ,
4349 output_file = otdfctl_tdf_output ,
4450 mime_type = "text/plain" ,
51+ cwd = temp_path ,
4552 )
4653
47- otdfctl_encrypt_result = subprocess .run (
48- otdfctl_encrypt_cmd , capture_output = True , text = True , cwd = temp_path
54+ # Fail fast on errors
55+ handle_subprocess_error (
56+ result = otdfctl_encrypt_result ,
57+ collect_server_logs = collect_server_logs ,
58+ scenario_name = "otdfctl encrypt" ,
4959 )
5060
51- # If otdfctl encrypt fails, skip the test (might be server issues)
52- if otdfctl_encrypt_result .returncode != 0 :
53- raise Exception (f"otdfctl encrypt failed: { otdfctl_encrypt_result .stderr } " )
54-
5561 # Verify the TDF file was created
5662 assert otdfctl_tdf_output .exists (), "otdfctl did not create TDF file"
5763 assert otdfctl_tdf_output .stat ().st_size > 0 , "otdfctl created empty TDF file"
5864
5965 # Now run otdfctl decrypt (this is the reference implementation)
60- otdfctl_decrypt_cmd = build_otdfctl_decrypt_command (
66+ otdfctl_decrypt_result = run_otdfctl_decrypt_command (
6167 temp_credentials_file ,
6268 otdfctl_tdf_output ,
6369 otdfctl_decrypt_output ,
70+ cwd = temp_path ,
6471 )
6572
66- otdfctl_decrypt_result = subprocess .run (
67- otdfctl_decrypt_cmd , capture_output = True , text = True , cwd = temp_path
73+ # Fail fast on errors
74+ handle_subprocess_error (
75+ result = otdfctl_decrypt_result ,
76+ collect_server_logs = collect_server_logs ,
77+ scenario_name = "otdfctl decrypt" ,
6878 )
6979
70- # Check that otdfctl decrypt succeeded
71- if otdfctl_decrypt_result .returncode != 0 :
72- # Collect server logs for debugging
73- logs = collect_server_logs ()
74- print (f"Server logs when otdfctl decrypt failed:\n { logs } " )
75-
76- # Check if this is a server connectivity issue
77- if (
78- "401 Unauthorized" in otdfctl_decrypt_result .stderr
79- or "token endpoint discovery" in otdfctl_decrypt_result .stderr
80- or "Issuer endpoint must be configured" in otdfctl_decrypt_result .stderr
81- ):
82- pytest .skip (
83- f"Server connectivity or authentication issue: { otdfctl_decrypt_result .stderr } "
84- )
85- else :
86- assert otdfctl_decrypt_result .returncode == 0 , (
87- f"otdfctl decrypt failed: { otdfctl_decrypt_result .stderr } "
88- )
89-
9080 # Run our Python CLI decrypt on the same TDF
91- cli_decrypt_cmd = build_cli_decrypt_command (
81+ cli_decrypt_result = run_cli_decrypt (
9282 creds_file = temp_credentials_file ,
9383 input_file = otdfctl_tdf_output ,
9484 output_file = cli_decrypt_output ,
85+ cwd = project_root ,
9586 )
9687
97- cli_decrypt_result = subprocess . run (
98- cli_decrypt_cmd ,
99- capture_output = True ,
100- text = True ,
101- cwd = Path ( __file__ ). parent . parent ,
88+ # Fail fast on errors
89+ handle_subprocess_error (
90+ result = cli_decrypt_result ,
91+ collect_server_logs = collect_server_logs ,
92+ scenario_name = "Python CLI decrypt" ,
10293 )
10394
104- # Check that our CLI succeeded
105- if cli_decrypt_result .returncode != 0 :
106- # Collect server logs for debugging
107- logs = collect_server_logs ()
108- print (f"Server logs when Python CLI decrypt failed:\n { logs } " )
109-
110- # Check if this is a server connectivity issue
111- if (
112- "401 Unauthorized" in cli_decrypt_result .stderr
113- or "token endpoint discovery" in cli_decrypt_result .stderr
114- or "Issuer endpoint must be configured" in cli_decrypt_result .stderr
115- ):
116- pytest .skip (
117- f"Server connectivity or authentication issue: { cli_decrypt_result .stderr } "
118- )
119- else :
120- assert cli_decrypt_result .returncode == 0 , (
121- f"Python CLI decrypt failed: { cli_decrypt_result .stderr } "
122- )
123-
124- # Verify both decrypted files were created
125- assert otdfctl_decrypt_output .exists (), "otdfctl did not create decrypted file"
126- assert otdfctl_decrypt_output .stat ().st_size > 0 , (
127- "otdfctl created empty decrypted file"
128- )
129- assert cli_decrypt_output .exists (), "Python CLI did not create decrypted file"
130- assert cli_decrypt_output .stat ().st_size > 0 , (
131- "Python CLI created empty decrypted file"
132- )
95+ validate_plaintext_file_created (path = otdfctl_decrypt_output , scenario = "otdfctl" )
96+ validate_plaintext_file_created (path = cli_decrypt_output , scenario = "Python CLI" )
13397
13498 # Verify both tools produce the same decrypted content
13599 with open (otdfctl_decrypt_output ) as f :
@@ -179,82 +143,40 @@ def test_otdfctl_encrypt_otdfctl_decrypt(collect_server_logs, temp_credentials_f
179143 otdfctl_decrypt_output = temp_path / "otdfctl-roundtrip-decrypted.txt"
180144
181145 # Run otdfctl encrypt
182- otdfctl_encrypt_cmd = build_otdfctl_encrypt_command (
146+ otdfctl_encrypt_result = run_otdfctl_encrypt_command (
183147 creds_file = temp_credentials_file ,
184148 input_file = input_file ,
185149 output_file = otdfctl_tdf_output ,
186150 mime_type = "text/plain" ,
151+ cwd = temp_path ,
187152 )
188153
189- otdfctl_encrypt_result = subprocess .run (
190- otdfctl_encrypt_cmd , capture_output = True , text = True , cwd = temp_path
154+ # Fail fast on errors
155+ handle_subprocess_error (
156+ result = otdfctl_encrypt_result ,
157+ collect_server_logs = collect_server_logs ,
158+ scenario_name = "otdfctl encrypt" ,
191159 )
192160
193- # If otdfctl encrypt fails, skip the test (might be server issues)
194- if otdfctl_encrypt_result .returncode != 0 :
195- # Collect server logs for debugging
196- logs = collect_server_logs ()
197- print (f"Server logs when otdfctl encrypt failed:\n { logs } " )
198-
199- # Check if this is a server connectivity issue
200- if (
201- "401 Unauthorized" in otdfctl_encrypt_result .stderr
202- or "token endpoint discovery" in otdfctl_encrypt_result .stderr
203- or "Issuer endpoint must be configured" in otdfctl_encrypt_result .stderr
204- ):
205- pytest .skip (
206- f"Server connectivity or authentication issue: { otdfctl_encrypt_result .stderr } "
207- )
208- else :
209- assert otdfctl_encrypt_result .returncode == 0 , (
210- f"otdfctl encrypt failed: { otdfctl_encrypt_result .stderr } "
211- )
212-
213161 # Verify the TDF file was created
214- assert otdfctl_tdf_output .exists (), "otdfctl did not create TDF file"
215- assert otdfctl_tdf_output .stat ().st_size > 0 , "otdfctl created empty TDF file"
216-
217- # Verify TDF file has correct ZIP signature
218- with open (otdfctl_tdf_output , "rb" ) as f :
219- tdf_header = f .read (4 )
220- assert tdf_header == b"PK\x03 \x04 " , "otdfctl output is not a valid ZIP file"
162+ validate_tdf3_file (tdf_path = otdfctl_tdf_output , tool_name = "otdfctl" )
221163
222164 # Run otdfctl decrypt
223- otdfctl_decrypt_cmd = build_otdfctl_decrypt_command (
165+ otdfctl_decrypt_result = run_otdfctl_decrypt_command (
224166 temp_credentials_file ,
225167 otdfctl_tdf_output ,
226168 otdfctl_decrypt_output ,
169+ cwd = temp_path ,
227170 )
228171
229- otdfctl_decrypt_result = subprocess .run (
230- otdfctl_decrypt_cmd , capture_output = True , text = True , cwd = temp_path
172+ # Fail fast on errors
173+ handle_subprocess_error (
174+ result = otdfctl_decrypt_result ,
175+ collect_server_logs = collect_server_logs ,
176+ scenario_name = "otdfctl decrypt" ,
231177 )
232178
233- # Check that otdfctl decrypt succeeded
234- if otdfctl_decrypt_result .returncode != 0 :
235- # Collect server logs for debugging
236- logs = collect_server_logs ()
237- print (f"Server logs when otdfctl decrypt failed:\n { logs } " )
238-
239- # Check if this is a server connectivity issue
240- if (
241- "401 Unauthorized" in otdfctl_decrypt_result .stderr
242- or "token endpoint discovery" in otdfctl_decrypt_result .stderr
243- or "Issuer endpoint must be configured" in otdfctl_decrypt_result .stderr
244- ):
245- pytest .skip (
246- f"Server connectivity or authentication issue: { otdfctl_decrypt_result .stderr } "
247- )
248- else :
249- assert otdfctl_decrypt_result .returncode == 0 , (
250- f"otdfctl decrypt failed: { otdfctl_decrypt_result .stderr } "
251- )
252-
253- # Verify the decrypted file was created
254- assert otdfctl_decrypt_output .exists (), "otdfctl did not create decrypted file"
255- assert otdfctl_decrypt_output .stat ().st_size > 0 , (
256- "otdfctl created empty decrypted file"
257- )
179+ validate_plaintext_file_created (path = otdfctl_decrypt_output , scenario = "otdfctl" )
258180
259181 # Verify the decrypted content matches the original
260182 with open (otdfctl_decrypt_output ) as f :
0 commit comments