# Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/) # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import logging, os, time, json, socket, re from common.Constants import DEFAULT_CONTEXT_NAME from common.proto.context_pb2 import ContextId, DeviceOperationalStatusEnum, Empty from common.tools.descriptor.Loader import DescriptorLoader, check_descriptor_load_results, validate_empty_scenario from common.tools.object_factory.Context import json_context_id from context.client.ContextClient import ContextClient from device.client.DeviceClient import DeviceClient from tests.Fixtures import context_client, device_client # pylint: disable=unused-import LOGGER = logging.getLogger(__name__) LOGGER.setLevel(logging.DEBUG) # Update the path to your QKD descriptor file DESCRIPTOR_FILE_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'descriptorQKD_links.json') ADMIN_CONTEXT_ID = ContextId(**json_context_id(DEFAULT_CONTEXT_NAME)) def load_descriptor_with_runtime_ip(descriptor_file_path): """ Load the descriptor file and replace placeholder IP with the machine's IP address. """ with open(descriptor_file_path, 'r') as descriptor_file: descriptor = descriptor_file.read() # Get the current machine's IP address try: # Use socket to get the local IP address directly from the network interface s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.connect(("8.8.8.8", 80)) current_ip = s.getsockname()[0] s.close() except Exception as e: raise Exception(f"Unable to get the IP address: {str(e)}") # Replace all occurrences of with the current IP updated_descriptor = re.sub(r"", current_ip, descriptor) # Write updated descriptor back with open(descriptor_file_path, 'w') as descriptor_file: descriptor_file.write(updated_descriptor) return json.loads(updated_descriptor) def load_and_process_descriptor(context_client, device_client, descriptor_file_path): """ Function to load and process descriptor programmatically, similar to what WebUI does. """ print(f"Loading descriptor from file: {descriptor_file_path}") try: # Update the descriptor with the runtime IP address descriptor = load_descriptor_with_runtime_ip(descriptor_file_path) # Initialize DescriptorLoader with the updated descriptor file descriptor_loader = DescriptorLoader( descriptors_file=descriptor_file_path, context_client=context_client, device_client=device_client ) # Process and validate the descriptor print("Processing the descriptor...") results = descriptor_loader.process() print(f"Descriptor processing results: {results}") print("Checking descriptor load results...") check_descriptor_load_results(results, descriptor_loader) print("Validating descriptor...") descriptor_loader.validate() print("Descriptor validated successfully.") except Exception as e: LOGGER.error(f"Failed to load and process descriptor: {e}") raise e def test_qkd_scenario_bootstrap( context_client: ContextClient, # pylint: disable=redefined-outer-name device_client: DeviceClient, # pylint: disable=redefined-outer-name ) -> None: """ This test validates that the QKD scenario is correctly bootstrapped. """ print("Starting QKD scenario bootstrap test...") # Check if context_client and device_client are instantiated if context_client is None: print("Error: context_client is not instantiated!") else: print(f"context_client is instantiated: {context_client}") if device_client is None: print("Error: device_client is not instantiated!") else: print(f"device_client is instantiated: {device_client}") # Validate empty scenario print("Validating empty scenario...") validate_empty_scenario(context_client) # Load the descriptor load_and_process_descriptor(context_client, device_client, DESCRIPTOR_FILE_PATH) def test_qkd_devices_enabled( context_client: ContextClient, # pylint: disable=redefined-outer-name ) -> None: """ This test validates that the QKD devices are enabled. """ print("Starting QKD devices enabled test...") # Check if context_client is instantiated if context_client is None: print("Error: context_client is not instantiated!") else: print(f"context_client is instantiated: {context_client}") DEVICE_OP_STATUS_ENABLED = DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_ENABLED num_devices = -1 num_devices_enabled, num_retry = 0, 0 while (num_devices != num_devices_enabled) and (num_retry < 10): print(f"Attempt {num_retry + 1}: Checking device status...") time.sleep(1.0) # Add a delay to allow for device enablement response = context_client.ListDevices(Empty()) num_devices = len(response.devices) print(f"Total devices found: {num_devices}") num_devices_enabled = 0 for device in response.devices: if device.device_operational_status == DEVICE_OP_STATUS_ENABLED: num_devices_enabled += 1 print(f"Devices enabled: {num_devices_enabled}/{num_devices}") num_retry += 1 # Final check to ensure all devices are enabled print(f"Final device status: {num_devices_enabled}/{num_devices} devices enabled.") assert num_devices_enabled == num_devices print("QKD devices enabled test completed.")