Skip to content

Commit d9ae334

Browse files
Improve test coverage
1 parent c372059 commit d9ae334

File tree

2 files changed

+671
-1
lines changed

2 files changed

+671
-1
lines changed

tests/python/test_infrastructures.py

Lines changed: 330 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1672,3 +1672,333 @@ def mock_run(command, ok_message=None, error_message=None, **kwargs):
16721672

16731673
# Should handle malformed responses gracefully without raising exceptions
16741674
infrastructures._cleanup_resources('test-deployment', 'test-rg')
1675+
1676+
# ==============================
1677+
# ENHANCED COVERAGE TESTS
1678+
# ==============================
1679+
1680+
def test_appgw_apim_infrastructure_bicep_parameters(mock_utils):
1681+
"""Test APPGW-APIM-PE specific Bicep parameters."""
1682+
# Test with custom APIs (should enable ACA)
1683+
custom_apis = [
1684+
API('test-api', 'Test API', '/test', 'Test API description')
1685+
]
1686+
1687+
infra = infrastructures.AppGwApimPeInfrastructure(
1688+
rg_location='eastus',
1689+
index=1,
1690+
apim_sku=APIM_SKU.STANDARDV2,
1691+
infra_apis=custom_apis
1692+
)
1693+
1694+
# Initialize components
1695+
infra._define_policy_fragments()
1696+
infra._define_apis()
1697+
1698+
bicep_params = infra._define_bicep_parameters()
1699+
1700+
# Check APPGW-specific parameters
1701+
assert 'apimPublicAccess' in bicep_params
1702+
assert bicep_params['apimPublicAccess']['value'] is True
1703+
assert 'useACA' in bicep_params
1704+
assert bicep_params['useACA']['value'] is True # Should be True due to custom APIs
1705+
1706+
1707+
def test_appgw_apim_internal_infrastructure_parameters(mock_utils):
1708+
"""Test APPGW-APIM (Internal) specific parameters."""
1709+
infra = infrastructures.AppGwApimInfrastructure(
1710+
rg_location='eastus',
1711+
index=1,
1712+
apim_sku=APIM_SKU.DEVELOPER
1713+
)
1714+
1715+
# Verify network mode is INTERNAL_VNET
1716+
assert infra.networkMode == APIMNetworkMode.INTERNAL_VNET
1717+
1718+
# Verify SKU defaults to DEVELOPER
1719+
assert infra.apim_sku == APIM_SKU.DEVELOPER
1720+
1721+
1722+
def test_infrastructure_resource_suffix_generation(mock_utils, mock_az):
1723+
"""Test that resource suffix is properly generated and stored."""
1724+
mock_az.get_unique_suffix_for_resource_group.return_value = 'test123abc'
1725+
1726+
infra = infrastructures.Infrastructure(
1727+
infra=INFRASTRUCTURE.SIMPLE_APIM,
1728+
index=1,
1729+
rg_location='eastus'
1730+
)
1731+
1732+
assert infra.resource_suffix == 'test123abc'
1733+
mock_az.get_unique_suffix_for_resource_group.assert_called_once()
1734+
1735+
1736+
def test_infrastructure_account_info_retrieval(mock_utils, mock_az):
1737+
"""Test that account info is properly retrieved and stored."""
1738+
mock_az.get_account_info.return_value = (
1739+
'test-user', 'user-id-123', 'tenant-id-456', 'subscription-id-789'
1740+
)
1741+
1742+
infra = infrastructures.Infrastructure(
1743+
infra=INFRASTRUCTURE.APIM_ACA,
1744+
index=1,
1745+
rg_location='westus2'
1746+
)
1747+
1748+
assert infra.current_user == 'test-user'
1749+
assert infra.current_user_id == 'user-id-123'
1750+
assert infra.tenant_id == 'tenant-id-456'
1751+
assert infra.subscription_id == 'subscription-id-789'
1752+
1753+
1754+
def test_infrastructure_policy_fragments_ordering(mock_utils):
1755+
"""Test that policy fragments are properly ordered (base + custom)."""
1756+
custom_pf = PolicyFragment('Custom-PF', '<policy>custom</policy>', 'Custom policy fragment')
1757+
1758+
infra = infrastructures.Infrastructure(
1759+
infra=INFRASTRUCTURE.SIMPLE_APIM,
1760+
index=1,
1761+
rg_location='eastus',
1762+
infra_pfs=[custom_pf]
1763+
)
1764+
1765+
pfs = infra._define_policy_fragments()
1766+
1767+
# Verify base fragments come before custom
1768+
base_names = [pf.name for pf in infra.base_pfs]
1769+
custom_names = [pf.name for pf in [custom_pf]]
1770+
1771+
pf_names = [pf.name for pf in pfs]
1772+
1773+
# Find indices
1774+
base_indices = [pf_names.index(name) for name in base_names if name in pf_names]
1775+
custom_indices = [pf_names.index(name) for name in custom_names if name in pf_names]
1776+
1777+
# Last base should come before first custom
1778+
if base_indices and custom_indices:
1779+
assert max(base_indices) < min(custom_indices)
1780+
1781+
1782+
def test_infrastructure_api_hello_world_always_present(mock_utils):
1783+
"""Test that hello-world API is always present in base APIs."""
1784+
# Test without custom APIs
1785+
infra1 = infrastructures.SimpleApimInfrastructure(
1786+
rg_location='eastus',
1787+
index=1
1788+
)
1789+
infra1._define_apis()
1790+
assert any(api.name == 'hello-world' for api in infra1.base_apis)
1791+
1792+
# Test with custom APIs
1793+
custom_api = API('custom-api', 'Custom API', '/custom', 'Custom API')
1794+
infra2 = infrastructures.SimpleApimInfrastructure(
1795+
rg_location='eastus',
1796+
index=1,
1797+
infra_apis=[custom_api]
1798+
)
1799+
infra2._define_apis()
1800+
assert any(api.name == 'hello-world' for api in infra2.base_apis)
1801+
assert any(api.name == 'custom-api' for api in infra2.apis)
1802+
1803+
1804+
def test_afd_apim_infrastructure_private_link_handling(mock_utils, mock_az):
1805+
"""Test AFD-APIM-PE infrastructure private link handling."""
1806+
infra = infrastructures.AfdApimAcaInfrastructure(
1807+
rg_location='eastus',
1808+
index=1
1809+
)
1810+
1811+
# Mock private endpoint connection list with single pending connection
1812+
pending_connection = {
1813+
'id': '/subscriptions/sub/resourceGroups/rg/providers/Microsoft.Network/privateEndpointConnections/conn1',
1814+
'name': 'conn1',
1815+
'properties': {'privateLinkServiceConnectionState': {'status': 'Pending'}}
1816+
}
1817+
1818+
mock_az.run.return_value = Mock(
1819+
success=True,
1820+
json_data=[pending_connection],
1821+
is_json=True
1822+
)
1823+
1824+
result = infra._approve_private_link_connections('/subscriptions/sub/resourceGroups/rg/providers/Microsoft.ApiManagement/service/test-apim')
1825+
1826+
# Verify approval was attempted and succeeded
1827+
assert mock_az.run.call_count >= 1
1828+
assert result is True
1829+
1830+
1831+
def test_appgw_apim_pe_infrastructure_keyvault_creation(mock_utils, mock_az):
1832+
"""Test APPGW-APIM-PE infrastructure Key Vault creation."""
1833+
infra = infrastructures.AppGwApimPeInfrastructure(
1834+
rg_location='eastus',
1835+
index=1
1836+
)
1837+
1838+
# Mock Key Vault doesn't exist
1839+
mock_az.run.return_value = Mock(success=False)
1840+
1841+
result = infra._create_keyvault('test-kv')
1842+
1843+
# Should attempt to create Key Vault when it doesn't exist
1844+
assert not result # Will fail due to mocking, but should attempt creation
1845+
1846+
1847+
def test_appgw_apim_certificate_properties():
1848+
"""Test APPGW-APIM certificate configuration."""
1849+
# Test that certificate constants are properly defined
1850+
assert infrastructures.AppGwApimPeInfrastructure.CERT_NAME == 'appgw-cert'
1851+
assert infrastructures.AppGwApimPeInfrastructure.DOMAIN_NAME == 'api.apim-samples.contoso.com'
1852+
1853+
# Test AppGwApimInfrastructure also has the same constants
1854+
assert infrastructures.AppGwApimInfrastructure.CERT_NAME == 'appgw-cert'
1855+
assert infrastructures.AppGwApimInfrastructure.DOMAIN_NAME == 'api.apim-samples.contoso.com'
1856+
1857+
1858+
def test_infrastructure_concrete_class_sku_inheritance():
1859+
"""Test that concrete infrastructure classes properly inherit and default SKUs."""
1860+
simple = infrastructures.SimpleApimInfrastructure('eastus', 1)
1861+
assert simple.apim_sku == APIM_SKU.BASICV2
1862+
1863+
aca = infrastructures.ApimAcaInfrastructure('eastus', 1)
1864+
assert aca.apim_sku == APIM_SKU.BASICV2
1865+
1866+
afd = infrastructures.AfdApimAcaInfrastructure('eastus', 1)
1867+
assert afd.apim_sku == APIM_SKU.BASICV2
1868+
1869+
appgw_pe = infrastructures.AppGwApimPeInfrastructure('eastus', 1)
1870+
assert appgw_pe.apim_sku == APIM_SKU.BASICV2
1871+
1872+
appgw = infrastructures.AppGwApimInfrastructure('eastus', 1)
1873+
assert appgw.apim_sku == APIM_SKU.DEVELOPER # This one defaults to DEVELOPER
1874+
1875+
1876+
def test_cleanup_single_resource_exception_handling(monkeypatch):
1877+
"""Test _cleanup_single_resource exception handling."""
1878+
def mock_run(command, ok_message=None, error_message=None):
1879+
raise Exception("Test exception")
1880+
1881+
monkeypatch.setattr(infrastructures.az, 'run', mock_run)
1882+
1883+
resource = {
1884+
'type': 'apim',
1885+
'name': 'test-apim',
1886+
'location': 'eastus',
1887+
'rg_name': 'test-rg'
1888+
}
1889+
1890+
success, error_msg = infrastructures._cleanup_single_resource(resource)
1891+
1892+
assert success is False
1893+
assert "Test exception" in error_msg
1894+
1895+
1896+
def test_cleanup_resources_with_all_resource_types(monkeypatch):
1897+
"""Test cleanup with a mix of all resource types."""
1898+
run_commands = []
1899+
1900+
def mock_run(command, ok_message=None, error_message=None, **kwargs):
1901+
run_commands.append(command)
1902+
1903+
# Mock deployment show response
1904+
if 'deployment group show' in command:
1905+
return Output(success=True, text='{"properties": {}}')
1906+
1907+
# Mock lists returning one of each resource type
1908+
if 'cognitiveservices account list' in command:
1909+
return Output(success=True, text='[{"name": "cog-1", "location": "eastus"}]')
1910+
1911+
if 'apim list' in command:
1912+
return Output(success=True, text='[{"name": "apim-1", "location": "eastus"}]')
1913+
1914+
if 'keyvault list' in command:
1915+
return Output(success=True, text='[{"name": "kv-1", "location": "eastus"}]')
1916+
1917+
# Default successful response
1918+
return Output(success=True, text='{}')
1919+
1920+
monkeypatch.setattr(infrastructures.az, 'run', mock_run)
1921+
monkeypatch.setattr(console, 'print_info', lambda *a, **kw: None)
1922+
monkeypatch.setattr(console, 'print_message', lambda *a, **kw: None)
1923+
1924+
infrastructures._cleanup_resources('test-deployment', 'test-rg')
1925+
1926+
# Verify all resource types were processed
1927+
all_commands = ' '.join(run_commands)
1928+
assert 'cognitiveservices' in all_commands
1929+
assert 'apim' in all_commands
1930+
assert 'keyvault' in all_commands
1931+
1932+
1933+
def test_infrastructure_initialization_error_handling(mock_utils, mock_az):
1934+
"""Test infrastructure initialization with mock errors."""
1935+
# Test with resource group creation failure
1936+
mock_az.create_resource_group.side_effect = Exception("RG creation failed")
1937+
1938+
with pytest.raises(Exception):
1939+
infrastructures.Infrastructure(
1940+
infra=INFRASTRUCTURE.SIMPLE_APIM,
1941+
index=1,
1942+
rg_location='eastus'
1943+
)
1944+
1945+
1946+
def test_policy_fragment_list_serialization(mock_utils):
1947+
"""Test that policy fragments serialize correctly for Bicep."""
1948+
custom_pf = PolicyFragment(
1949+
name='Test-PF',
1950+
policyXml='<policy>test</policy>',
1951+
description='Test policy fragment'
1952+
)
1953+
1954+
infra = infrastructures.Infrastructure(
1955+
infra=INFRASTRUCTURE.SIMPLE_APIM,
1956+
index=1,
1957+
rg_location='eastus',
1958+
infra_pfs=[custom_pf]
1959+
)
1960+
1961+
infra._define_policy_fragments()
1962+
infra._define_apis()
1963+
infra._define_bicep_parameters()
1964+
1965+
# Verify policy fragments are in Bicep parameters
1966+
assert 'policyFragments' in infra.bicep_parameters
1967+
pf_values = infra.bicep_parameters['policyFragments']['value']
1968+
1969+
# Should include both base and custom
1970+
assert len(pf_values) == 7 # 6 base + 1 custom
1971+
1972+
1973+
def test_api_serialization_for_bicep(mock_utils):
1974+
"""Test that APIs serialize correctly for Bicep."""
1975+
custom_api = API(
1976+
name='test-api',
1977+
displayName='Test API',
1978+
path='/test',
1979+
description='Test API',
1980+
policyXml='<policy></policy>'
1981+
)
1982+
1983+
infra = infrastructures.Infrastructure(
1984+
infra=INFRASTRUCTURE.SIMPLE_APIM,
1985+
index=1,
1986+
rg_location='eastus',
1987+
infra_apis=[custom_api]
1988+
)
1989+
1990+
infra._define_policy_fragments()
1991+
infra._define_apis()
1992+
infra._define_bicep_parameters()
1993+
1994+
# Verify APIs are in Bicep parameters
1995+
assert 'apis' in infra.bicep_parameters
1996+
api_values = infra.bicep_parameters['apis']['value']
1997+
1998+
# Should include both base (hello-world) and custom
1999+
assert len(api_values) == 2
2000+
2001+
# Verify serialization includes required fields
2002+
api_names = [api.get('name') if isinstance(api, dict) else api['name'] for api in api_values]
2003+
assert 'hello-world' in api_names
2004+
assert 'test-api' in api_names

0 commit comments

Comments
 (0)