Skip to content

OpenVPN

This example demonstrates how to use the OpenVPN interface for HIL testing.

Prerequisites

On Debian/Ubuntu systems, install OpenVPN:

sudo apt-get install openvpn

What This Example Does

  1. Sets up an OpenVPN server - Creates CA certificate, server certificate, and configuration
  2. Starts the OpenVPN server - Launches the server process
  3. Generates client configuration - Creates a .ovpn file that clients can use to connect

Use Cases

This OpenVPN interface can be used for: - Testing network connectivity in isolated environments - Simulating VPN connections for IoT devices - Creating secure tunnels for HIL test communication - Testing VPN client behavior on embedded devices

Security Note

The certificates generated in this example are for testing purposes only and use default test values. Do not use in production environments.

import os
import pytest
import logging
import tempfile
import time
import shutil

from hil_sdk.version import __version__
from hil_sdk.interfaces.openvpn import OpenVPNInterface, OpenVPNInterfaceException

@pytest.fixture(autouse=True, scope="session")
def hil_version_fixture():
    logging.info(f"HIL SDK version {__version__}")

@pytest.fixture(scope="session")
def openvpn_work_dir():
    """Create a temporary directory for OpenVPN test files"""
    temp_dir = tempfile.mkdtemp(prefix="hil_openvpn_test_")
    logging.info(f"Using OpenVPN work directory: {temp_dir}")
    yield temp_dir
    # Cleanup is handled by the OpenVPN interface

@pytest.fixture(scope="session")
def openvpn_server_fixture(hil_version_fixture, openvpn_work_dir):
    """
    Set up and start OpenVPN server for testing.
    This fixture runs once per test session.
    """
    logging.info("Setting up OpenVPN server...")

    # Create OpenVPN interface with test configuration
    openvpn = OpenVPNInterface(
        server_ip="127.0.0.1",
        server_port=11194,  # Use non-standard port to avoid conflicts
        network="10.9.0.0",
        netmask="255.255.255.0",
        work_dir=openvpn_work_dir
    )

    try:
        # Setup server certificates and configuration
        openvpn.setup_server()

        # Start the server
        openvpn.start_server()

        # Give server time to fully initialize
        # Poll server status until ready or timeout
        max_attempts = 10
        for _ in range(max_attempts):
            if openvpn.is_running:
                break
            time.sleep(1)
        else:
            raise OpenVPNInterfaceException("Server failed to start within timeout")


        logging.info("OpenVPN server started successfully")

        yield openvpn

    except Exception as e:
        logging.error(f"Failed to setup OpenVPN server: {e}")
        raise
    finally:
        # Cleanup HIL gateway
        logging.info("Cleaning up HIL gateway...")
        try:
            openvpn.cleanup()
        except Exception as e:
            logging.warning(f"HIL gateway cleanup failed: {e}")

@pytest.fixture(scope="session")
def client_config_dir():
    """Create a temporary directory for client configuration files"""
    temp_dir = tempfile.mkdtemp(prefix="hil_openvpn_client_")
    logging.info(f"Using client config directory: {temp_dir}")
    yield temp_dir
    # Cleanup client config directory after all tests
    try:
        if os.path.exists(temp_dir):
            shutil.rmtree(temp_dir, ignore_errors=True)
            logging.info(f"Removed client config directory: {temp_dir}")
    except Exception as e:
        logging.warning(f"Client config directory cleanup failed: {e}")
import logging
from pathlib import Path


def test_generate_dut_client_config(request, openvpn_server_fixture, client_config_dir):
    """Generate OpenVPN client configuration for DUT using auto-detected IP"""

    dut_client_name = "dut_device"

    # Save configuration file for DUT deployment
    config_file_path = openvpn_server_fixture.save_client_config(
        dut_client_name, 
        client_config_dir
    )

    # Verify the configuration is suitable for DUT
    config_file = Path(config_file_path)
    assert config_file.exists()

    with open(config_file, 'r') as f:
        content = f.read()
        # Verify that remote directive exists (IP will be auto-detected)
        assert "remote " in content
        assert "client" in content
        # Extract the auto-detected IP for logging
        for line in content.split('\n'):
            if line.startswith('remote '):
                detected_ip = line.split()[1]
                logging.info(f"Auto-detected HIL server IP: {detected_ip}")
                break

    logging.info(f"DUT client config generated: {config_file_path}")

    # Store the config file path in the test session for other tests to use
    request.config.cache.set("dut_config_file_path", config_file_path)

    return config_file_path