|
| 1 | +""" |
| 2 | +Integration test that exercise functionality specific to Oracle's launch function. |
| 3 | +
|
| 4 | +The basic lifecycle stuff is already tested in `tests/integration_tests/test_public_api.py`, but |
| 5 | +these tests go beyond the standard tests that exercise the base cloud agnostic functionality. |
| 6 | +""" |
| 7 | + |
| 8 | +import json |
| 9 | +import logging |
| 10 | + |
| 11 | +import pytest |
| 12 | + |
| 13 | +from pycloudlib.oci.cloud import OCI |
| 14 | +from pycloudlib.types import NetworkingConfig, NetworkingType |
| 15 | + |
| 16 | +logger = logging.getLogger(__name__) |
| 17 | + |
| 18 | + |
| 19 | +# create fixture that provides the oracle cloud object |
| 20 | +@pytest.fixture(scope="module") |
| 21 | +def oracle_cloud(): |
| 22 | + """Provide an OCI cloud instance for tests with automatic cleanup. |
| 23 | +
|
| 24 | + Returns: |
| 25 | + An OCI cloud instance configured for testing. |
| 26 | + """ |
| 27 | + # make sure region, AD, and compartment_id are set in your pycloudlib.toml config file |
| 28 | + # use context manager - instances will be deleted automatically after the test |
| 29 | + with OCI( |
| 30 | + tag="oracle-integrations-test-launch", |
| 31 | + ) as oracle_cloud: |
| 32 | + yield oracle_cloud |
| 33 | + |
| 34 | + |
| 35 | +class TestOracleLaunch: |
| 36 | + """ |
| 37 | + Test Oracle Cloud Infrastructure instance launch functionality. |
| 38 | +
|
| 39 | + This class contains tests specific to the OCI launch method, |
| 40 | + including various network configurations. |
| 41 | + """ |
| 42 | + |
| 43 | + @pytest.mark.parametrize( |
| 44 | + ("instance_type",), |
| 45 | + [ |
| 46 | + pytest.param( |
| 47 | + "VM.Standard2.1", |
| 48 | + id="VM", |
| 49 | + ), |
| 50 | + pytest.param( |
| 51 | + "BM.Optimized3.36", |
| 52 | + id="BM", |
| 53 | + ), |
| 54 | + ], |
| 55 | + ) |
| 56 | + @pytest.mark.parametrize( |
| 57 | + ( |
| 58 | + "primary_private", |
| 59 | + "primary_networking_type", |
| 60 | + "secondary_private", |
| 61 | + "secondary_networking_type", |
| 62 | + ), |
| 63 | + [ |
| 64 | + # both public ipv4 |
| 65 | + pytest.param( |
| 66 | + False, |
| 67 | + NetworkingType.IPV4, |
| 68 | + True, |
| 69 | + NetworkingType.IPV4, |
| 70 | + id="both_public_ipv4", |
| 71 | + ), |
| 72 | + # both public ipv6 |
| 73 | + pytest.param( |
| 74 | + False, |
| 75 | + NetworkingType.IPV6, |
| 76 | + True, |
| 77 | + NetworkingType.IPV6, |
| 78 | + id="both_public_ipv6", |
| 79 | + ), |
| 80 | + # primary public dual stack, secondary private ipv4 |
| 81 | + pytest.param( |
| 82 | + False, |
| 83 | + NetworkingType.DUAL_STACK, |
| 84 | + True, |
| 85 | + NetworkingType.DUAL_STACK, |
| 86 | + id="public_dual_stack_private_dual_stack", |
| 87 | + ), |
| 88 | + ], |
| 89 | + ) |
| 90 | + def test_launch_with_networking_configs( |
| 91 | + self, |
| 92 | + oracle_cloud: OCI, |
| 93 | + primary_private: bool, |
| 94 | + primary_networking_type: NetworkingType, |
| 95 | + secondary_private: bool, |
| 96 | + secondary_networking_type: NetworkingType, |
| 97 | + instance_type: str, |
| 98 | + ): |
| 99 | + """Test OCI instance launch with various networking configurations. |
| 100 | +
|
| 101 | + This test verifies that instances can be launched with different |
| 102 | + combinations of networking configurations (IPv4, IPv6, dual-stack) |
| 103 | + for both primary and secondary network interfaces. |
| 104 | +
|
| 105 | + Args: |
| 106 | + oracle_cloud (OCI): The OCI cloud fixture. |
| 107 | + primary_private (bool): Whether primary NIC should be private. |
| 108 | + primary_networking_type (NetworkingType): Network type for primary NIC. |
| 109 | + secondary_private (bool): Whether secondary NIC should be private. |
| 110 | + secondary_networking_type (NetworkingType): Network type for secondary NIC. |
| 111 | + instance_type (str): OCI instance type to launch. |
| 112 | +
|
| 113 | + Test Steps: |
| 114 | + 1. Launch an instance with the specified primary networking configuration and |
| 115 | + instance type |
| 116 | + 2. Add a secondary network interface with the specified secondary networking |
| 117 | + configuration |
| 118 | + 3. Restart the instance to apply the changes (As of 20250226 cloud-init does not support |
| 119 | + hotplugging nics on Oracle) |
| 120 | + 4. Verify that the instance has the expected number of VNICs in IMDS |
| 121 | + """ |
| 122 | + primary_networking_config = NetworkingConfig( |
| 123 | + private=primary_private, |
| 124 | + networking_type=primary_networking_type, |
| 125 | + ) |
| 126 | + |
| 127 | + logger.info("Launching instance...") |
| 128 | + instance = oracle_cloud.launch( |
| 129 | + image_id="ocid1.image.oc1.iad.aaaaaaaasukfowgzghuwrljl4ohlpv3uadhm5sn5dderkhhyymelebrzoima", |
| 130 | + primary_network_config=primary_networking_config, |
| 131 | + instance_type=instance_type, |
| 132 | + ) |
| 133 | + logger.info("Instance launched. Waiting for instance to be ready...") |
| 134 | + instance.wait() |
| 135 | + logger.info("Instance is ready!") |
| 136 | + assert instance.execute("true").ok |
| 137 | + |
| 138 | + if primary_networking_config.networking_type == NetworkingType.IPV6: |
| 139 | + imds_vnics_url = "curl http://[fd00:c1::a9fe:a9fe]/opc/v1/vnics" |
| 140 | + else: |
| 141 | + imds_vnics_url = "curl http://169.254.169.254/opc/v1/vnics" |
| 142 | + |
| 143 | + secondary_networking_config = NetworkingConfig( |
| 144 | + private=secondary_private, |
| 145 | + networking_type=secondary_networking_type, |
| 146 | + ) |
| 147 | + instance.add_network_interface( |
| 148 | + nic_index=(1 if instance_type == "BM.Optimized3.36" else 0), |
| 149 | + networking_config=secondary_networking_config, |
| 150 | + ) |
| 151 | + |
| 152 | + # run cloud-init clean and restart instance now that secondary NIC has been added |
| 153 | + logger.info("Running cloud-init clean and restarting instance...") |
| 154 | + instance.execute("cloud-init clean", use_sudo=True) |
| 155 | + instance.restart(wait=True) |
| 156 | + |
| 157 | + logger.info("Getting VNIC data from IMDS at '%s'...", imds_vnics_url) |
| 158 | + imds_response_2 = instance.execute(f"curl -s {imds_vnics_url}").stdout |
| 159 | + vnic_data_2 = json.loads(imds_response_2) |
| 160 | + logger.info("VNIC data from IMDS after adding secondary NIC: %s", imds_response_2) |
| 161 | + assert len(vnic_data_2) == 2, "Expected IMDS to return 2 VNICs after adding secondary NIC" |
0 commit comments