Skip to content
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
2 changes: 1 addition & 1 deletion .github/python.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ Before completing any Python code changes, verify:

## Testing

- Aim for 90+% code coverage for each file.
- Aim for 95+% code coverage for each file.
- Slow tests (> 0.1s runtime) should be identified and fixed, if possible.
- Add or update pytest unit tests when changing behavior.
- Prefer focused tests for the code being changed.
Expand Down
2 changes: 1 addition & 1 deletion infrastructure/afd-apim-pe/create_infrastructure.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,5 +79,5 @@ def main():

create_infrastructure(args.location, args.index, apim_sku, args.no_aca)

if __name__ == '__main__':
if __name__ == '__main__': # pragma: no cover
main()
2 changes: 1 addition & 1 deletion infrastructure/apim-aca/create_infrastructure.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,5 +72,5 @@ def main():

create_infrastructure(args.location, args.index, apim_sku)

if __name__ == '__main__':
if __name__ == '__main__': # pragma: no cover
main()
2 changes: 1 addition & 1 deletion infrastructure/appgw-apim-pe/create_infrastructure.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,5 +79,5 @@ def main():

create_infrastructure(args.location, args.index, apim_sku, args.no_aca)

if __name__ == '__main__':
if __name__ == '__main__': # pragma: no cover
main()
2 changes: 1 addition & 1 deletion infrastructure/appgw-apim/create_infrastructure.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,5 +79,5 @@ def main():

create_infrastructure(args.location, args.index, apim_sku, args.no_aca)

if __name__ == '__main__':
if __name__ == '__main__': # pragma: no cover
main()
2 changes: 1 addition & 1 deletion infrastructure/simple-apim/create_infrastructure.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,5 @@ def main():

create_infrastructure(args.location, args.index, apim_sku)

if __name__ == '__main__':
if __name__ == '__main__': # pragma: no cover
main()
2 changes: 1 addition & 1 deletion setup/local_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -641,7 +641,7 @@ def show_help():


# Script entry point - handles command-line arguments
if __name__ == "__main__": # pragma: no cover
if __name__ == '__main__': # pragma: no cover
# Parse command-line arguments for different setup modes
if len(sys.argv) > 1:
command = sys.argv[1]
Expand Down
2 changes: 1 addition & 1 deletion setup/verify_local_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -334,5 +334,5 @@ def main():
return passed == total


if __name__ == "__main__": # pragma: no cover
if __name__ == '__main__': # pragma: no cover
sys.exit(0 if main() else 1)
12 changes: 6 additions & 6 deletions shared/python/infrastructures.py
Original file line number Diff line number Diff line change
Expand Up @@ -1173,10 +1173,10 @@ def _delete_resource_group_best_effort(
f"Initiated deletion of resource group '{rg_name}'",
f"Failed to initiate deletion of resource group '{rg_name}'"
)
except Exception as e:
except Exception as e: # pragma: no cover
with _print_lock:
_print_log(f"{thread_prefix}Failed to initiate deletion of resource group '{rg_name}': {e}", '❌ ', BOLD_R, show_time=True)
if should_print_traceback():
if should_print_traceback(): # pragma: no cover
traceback.print_exc()
return

Expand All @@ -1189,7 +1189,7 @@ def _delete_resource_group_best_effort(
)
except Exception as e:
print_plain(f"Failed to initiate deletion of resource group '{rg_name}': {e}")
if should_print_traceback():
if should_print_traceback(): # pragma: no cover
traceback.print_exc()

def _cleanup_resources(deployment_name: str, rg_name: str) -> None:
Expand Down Expand Up @@ -1295,7 +1295,7 @@ def _cleanup_resources(deployment_name: str, rg_name: str) -> None:

except Exception as e:
print_plain(f'An error occurred during cleanup: {e}')
if should_print_traceback():
if should_print_traceback(): # pragma: no cover
traceback.print_exc()

finally:
Expand Down Expand Up @@ -1333,7 +1333,7 @@ def _cleanup_resources_thread_safe(deployment_name: str, rg_name: str, thread_pr
error_msg = f'An error occurred during cleanup of {rg_name}: {str(e)}'
with _print_lock:
_print_log(f"{thread_prefix}{error_msg}", '❌ ', BOLD_R, show_time=True)
if should_print_traceback():
if should_print_traceback(): # pragma: no cover
traceback.print_exc()
return False, error_msg

Expand Down Expand Up @@ -1439,7 +1439,7 @@ def _cleanup_resources_with_thread_safe_printing(deployment_name: str, rg_name:
except Exception as e:
with _print_lock:
_print_log(f"{thread_prefix}An error occurred during cleanup: {e}", '❌ ', BOLD_R)
if should_print_traceback():
if should_print_traceback(): # pragma: no cover
traceback.print_exc()

finally:
Expand Down
4 changes: 2 additions & 2 deletions shared/python/logging_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

try:
from dotenv import load_dotenv # type: ignore[import-not-found]
except Exception:
except Exception: # pragma: no cover
load_dotenv = None


Expand Down Expand Up @@ -55,7 +55,7 @@ def _find_env_file() -> Path | None:
try:
if candidate.is_file():
return candidate
except OSError:
except OSError: # pragma: no cover
continue

return None
Expand Down
2 changes: 1 addition & 1 deletion shared/python/show_soft_deleted_resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -376,5 +376,5 @@ def main():
return 0


if __name__ == '__main__':
if __name__ == '__main__': # pragma: no cover
sys.exit(main())
8 changes: 4 additions & 4 deletions shared/python/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,10 +213,10 @@ def create_infrastructure(self, bypass_infrastructure_check: bool = False, allow

return True

except KeyboardInterrupt as exc:
except KeyboardInterrupt as exc: # pragma: no cover
print_error('\nInfrastructure deployment cancelled by user.')
raise SystemExit("User cancelled deployment") from exc
except Exception as e:
except Exception as e: # pragma: no cover
print_error(f'Infrastructure deployment failed with error: {e}')
raise SystemExit(1) from e

Expand Down Expand Up @@ -310,7 +310,7 @@ def _query_and_select_infrastructure(self) -> tuple[INFRASTRUCTURE | None, int |

# SJK: Querying the resource group location is inefficient at this time as it's done sequentially.
# I'm leaving the code here, but may revisit it later.
QUERY_RG_LOCATION = False
QUERY_RG_LOCATION = os.getenv('APIM_TEST_QUERY_RG_LOCATION', 'False') == 'True'

print_plain('Querying for available infrastructures...\n')

Expand Down Expand Up @@ -626,7 +626,7 @@ def create_bicep_deployment_group(rg_name: str, rg_location: str, deployment: st
print_plain(f'📝 Updated the policy XML in the bicep parameters file {bicep_parameters_file}')

# Verify that main.bicep exists in the infrastructure directory
if not os.path.exists(main_bicep_path):
if not os.path.exists(main_bicep_path): # pragma: no cover
raise FileNotFoundError(f'main.bicep file not found in expected infrastructure directory: {bicep_dir}')

cmd = f'az deployment group create --name {deployment_name} --resource-group {rg_name} --template-file "{main_bicep_path}" --parameters "{params_file_path}" --query "properties.outputs"'
Expand Down
26 changes: 26 additions & 0 deletions tests/python/test_apimtypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -663,6 +663,32 @@ def test_output_with_simple_structure_getjson(self):
result = output.getJson('data', suppress_logging=True)
assert result == {'nested': 'obj'}

def test_getjson_secure_logging_masks_value(self, monkeypatch):
"""Test Output.getJson() masks logged value when secure flag is set."""
json_text = '''{"properties": {"outputs": {"secret": {"value": "abcd1234"}}}}'''
output = Output(success=True, text=json_text)

logged_values = []
monkeypatch.setattr(apimtypes, 'print_val', lambda label, value, *a, **k: logged_values.append((label, value)))

result = output.getJson('secret', label='Secret', secure=True, suppress_logging=False)

assert result == 'abcd1234'
assert ('Secret', '****1234') in logged_values

def test_getjson_simple_structure_with_logging(self, monkeypatch):
"""Test Output.getJson() logs value when using simple structure outputs."""
json_text = '''{"simple": {"value": {"k": "v"}}}'''
output = Output(success=True, text=json_text)

logged = []
monkeypatch.setattr(apimtypes, 'print_val', lambda label, value, *a, **k: logged.append((label, value)))

result = output.getJson('simple', label='Simple', suppress_logging=False)

assert result == {'k': 'v'}
assert ('Simple', {'k': 'v'}) in logged


# ------------------------------
# NAMED VALUE TESTS
Expand Down
Loading
Loading