You've already forked mariadb-columnstore-engine
							
							
				mirror of
				https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
				synced 2025-11-03 17:13:17 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			185 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			185 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
import json
 | 
						|
import subprocess
 | 
						|
from pathlib import Path
 | 
						|
 | 
						|
import pytest
 | 
						|
 | 
						|
from integration_tests import cluster_mgmt
 | 
						|
from integration_tests.ssh import ClusterConfig, RemoteHost, run_on_all_hosts_parallel
 | 
						|
from integration_tests.state import activate_single_node_config
 | 
						|
from integration_tests.utils import change_directory
 | 
						|
 | 
						|
 | 
						|
def pytest_addoption(parser):
 | 
						|
    """Add terraform directory option to pytest command line arguments."""
 | 
						|
    parser.addoption(
 | 
						|
        "--terraform-dir",
 | 
						|
        action="store",
 | 
						|
        default=None,
 | 
						|
        required=True,
 | 
						|
        help="Directory where terraform was run to set up the test cluster",
 | 
						|
    )
 | 
						|
    parser.addoption(
 | 
						|
        "--create-cluster",
 | 
						|
        action="store_true",
 | 
						|
        default=False,
 | 
						|
        help="Create the cluster before running tests",
 | 
						|
    )
 | 
						|
    parser.addoption(
 | 
						|
        "--destroy-cluster",
 | 
						|
        action="store_true",
 | 
						|
        default=False,
 | 
						|
        help="Destroy the cluster after running tests",
 | 
						|
    )
 | 
						|
    parser.addoption(
 | 
						|
        "--ssh-user",
 | 
						|
        default="ubuntu",
 | 
						|
        help="SSH user to connect to the cluster hosts",
 | 
						|
    )
 | 
						|
 | 
						|
 | 
						|
@pytest.fixture(scope="session")
 | 
						|
def terraform_dir(request) -> Path:
 | 
						|
    """
 | 
						|
    Fixture to provide the terraform directory path.
 | 
						|
    Fails explicitly if --terraform-dir option is not provided.
 | 
						|
    """
 | 
						|
    terraform_directory = request.config.getoption("--terraform-dir")
 | 
						|
    if not terraform_directory:
 | 
						|
        pytest.fail("--terraform-dir option is required but not provided")
 | 
						|
    terraform_directory = Path(terraform_directory).resolve()
 | 
						|
    if not terraform_directory.is_dir():
 | 
						|
        pytest.fail(f"Specified terraform directory '{terraform_directory}' does not exist")
 | 
						|
    return terraform_directory
 | 
						|
 | 
						|
 | 
						|
@pytest.fixture(scope="session")
 | 
						|
def prepared_cluster(request, terraform_dir):
 | 
						|
    """
 | 
						|
    Provides existence of the cluster
 | 
						|
    If it doesn't exist and --create-cluster is passed, it creates it.
 | 
						|
    If it exists and --create-cluster is passed, it re-creates it.
 | 
						|
    If --destroy-cluster is passed, it destroys the cluster when the tests finish.
 | 
						|
    """
 | 
						|
    create_cluster = request.config.getoption("--create-cluster")
 | 
						|
    destroy_cluster = request.config.getoption("--destroy-cluster")
 | 
						|
 | 
						|
    cluster_already_exists = cluster_mgmt.cluster_exists(terraform_dir)
 | 
						|
 | 
						|
    if create_cluster:
 | 
						|
        if cluster_already_exists:
 | 
						|
            print("Cluster already exists, destroying it first...")
 | 
						|
            cluster_mgmt.destroy_cluster(terraform_dir)
 | 
						|
        print("Creating the cluster...")
 | 
						|
        cluster_mgmt.create_cluster(terraform_dir)
 | 
						|
 | 
						|
    yield
 | 
						|
 | 
						|
    if destroy_cluster:
 | 
						|
        print("Destroying the cluster...")
 | 
						|
        cluster_mgmt.destroy_cluster(terraform_dir)
 | 
						|
 | 
						|
 | 
						|
@pytest.fixture(scope="session")
 | 
						|
def cluster_config(request, terraform_dir, prepared_cluster) -> ClusterConfig:
 | 
						|
    """
 | 
						|
    Fixture to provide the cluster configuration.
 | 
						|
    """
 | 
						|
    with change_directory(terraform_dir):
 | 
						|
        # Read the cluster configuration from the terraform output
 | 
						|
        outputs = json.loads(subprocess.check_output(
 | 
						|
            ["terraform", "output", "-json"],
 | 
						|
            text=True,
 | 
						|
        ))
 | 
						|
 | 
						|
        if outputs == {}:
 | 
						|
            pytest.fail("Terraform output is empty, looks like cluster is not yet created. Pass --create-cluster option to create it.")
 | 
						|
 | 
						|
        key_file_path = Path(outputs["ssh_key_file"]["value"])
 | 
						|
        ssh_user = request.config.getoption("--ssh-user")
 | 
						|
 | 
						|
        mcs_nodes = []
 | 
						|
        for host_descr in outputs["columnstore_nodes"]["value"]:
 | 
						|
            mcs_nodes.append(
 | 
						|
                RemoteHost(
 | 
						|
                    name=host_descr["name"],
 | 
						|
                    private_ip=host_descr["private_ip"],
 | 
						|
                    public_fqdn=host_descr["public_dns"],
 | 
						|
                    key_file_path=key_file_path,
 | 
						|
                    ssh_user=ssh_user,
 | 
						|
                )
 | 
						|
            )
 | 
						|
 | 
						|
        maxscale_nodes = []
 | 
						|
        for host_descr in outputs["maxscale_nodes"]["value"]:
 | 
						|
            maxscale_nodes.append(
 | 
						|
                RemoteHost(
 | 
						|
                    name=host_descr["name"],
 | 
						|
                    private_ip=host_descr["private_ip"],
 | 
						|
                    public_fqdn=host_descr["public_dns"],
 | 
						|
                    key_file_path=key_file_path,
 | 
						|
                    ssh_user=ssh_user,
 | 
						|
                )
 | 
						|
            )
 | 
						|
 | 
						|
        all_hosts = mcs_nodes + maxscale_nodes
 | 
						|
        # Check if all hosts are reachable
 | 
						|
        for host in all_hosts:
 | 
						|
            if not host.is_reachable():
 | 
						|
                pytest.fail(f"Host {host.name} is not reachable via SSH")
 | 
						|
 | 
						|
        cluster_config = ClusterConfig(mcs_hosts=mcs_nodes, maxscale_hosts=maxscale_nodes)
 | 
						|
        return cluster_config
 | 
						|
 | 
						|
 | 
						|
@pytest.fixture
 | 
						|
def disconnected_cluster(cluster_config):
 | 
						|
    """
 | 
						|
    Fixture to activate single node configuration on all hosts in the cluster,
 | 
						|
      none of the nodes are in the cluster.
 | 
						|
    """
 | 
						|
    print("Activating single node configuration on all hosts...")
 | 
						|
    run_on_all_hosts_parallel(cluster_config.mcs_hosts, activate_single_node_config)
 | 
						|
 | 
						|
 | 
						|
@pytest.fixture
 | 
						|
def only_primary_in_cluster(disconnected_cluster, cluster_config):
 | 
						|
    """
 | 
						|
    Fixture that provides a cluster with only the primary node added
 | 
						|
    """
 | 
						|
    print("Adding only primary node to the cluster...")
 | 
						|
    cmd = f"cluster node add --node {cluster_config.primary.private_ip}"
 | 
						|
    cluster_config.primary.exec_mcs(cmd)
 | 
						|
 | 
						|
    status_out = cluster_config.primary.exec_mcs("cluster status")
 | 
						|
    assert status_out["num_nodes"] == 1
 | 
						|
    assert str(cluster_config.primary.private_ip) in status_out
 | 
						|
 | 
						|
 | 
						|
@pytest.fixture
 | 
						|
def only_primary_and_one_replica_in_cluster(only_primary_in_cluster, cluster_config):
 | 
						|
    """
 | 
						|
    Fixture that provides a cluster with only the primary and one replica node added
 | 
						|
    """
 | 
						|
    print("Adding one replica...")
 | 
						|
    cmd = f"cluster node add --node {cluster_config.replicas[0].private_ip}"
 | 
						|
    cluster_config.primary.exec_mcs(cmd)
 | 
						|
 | 
						|
    status_out = cluster_config.primary.exec_mcs("cluster status")
 | 
						|
    assert status_out["num_nodes"] == 2
 | 
						|
 | 
						|
 | 
						|
@pytest.fixture
 | 
						|
def complete_cluster(cluster_config, disconnected_cluster, only_primary_in_cluster):
 | 
						|
    """
 | 
						|
    Fixture to activate multinode configuration on all hosts in the cluster.
 | 
						|
    """
 | 
						|
    print("Adding replicas to the cluster...")
 | 
						|
    cmd = "cluster node add "
 | 
						|
    for host in cluster_config.replicas:
 | 
						|
        cmd += f"--node {host.private_ip} "
 | 
						|
    cluster_config.primary.exec_mcs(cmd)
 | 
						|
 | 
						|
    status_out = cluster_config.primary.exec_mcs("cluster status")
 | 
						|
    assert status_out["num_nodes"] == len(cluster_config.mcs_hosts)
 |