From 744e8f69462a85b55e87789c428aa15b7b85b51d Mon Sep 17 00:00:00 2001 From: openhands Date: Thu, 6 Nov 2025 19:53:39 +0000 Subject: [PATCH] Reorganize repository structure for better organization MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Created organized directory structure: - scripts/ - for utility scripts (test runners, etc.) - tests/mocks/ - for mock servers - deploy/ - for all deployment scripts - src/dashboard/ - for dashboard assets Moved files: - Test runners: run_tests_by_system.py, run_tests_detailed.py, run_tests_with_db.sh → scripts/ - Deployment scripts: deploy-onprem.sh, setup-server.sh, etc. → deploy/ - Mock servers: mock-optimization-server.py, mock-scada-server.py → tests/mocks/ - Individual tests: test_*.py files → tests/ - Integration tests: test-e2e-deployment.py, test-remote-integration.py → tests/integration/ - Dashboard assets: fixed-dashboard.js → src/dashboard/ Deleted redundant files: - pytest-mock.ini (redundant with pytest.ini) - setup-server-backup.sh (duplicate of setup-server.sh) Kept essential files in root: - Core documentation (README.md, QUICKSTART.md, etc.) - Environment templates - Docker files - Main test runner (run_tests.py) - Application entry point (start_dashboard.py) --- deploy-onprem.sh => deploy/deploy-onprem.sh | 0 .../generate-monitoring-secrets.sh | 0 .../setup-monitoring.sh | 0 setup-server.sh => deploy/setup-server.sh | 0 .../start-remote-test.sh | 0 .../test-deployment.sh | 0 .../validate-deployment.sh | 0 pytest-mock.ini | 40 -- .../run_tests_by_system.py | 0 .../run_tests_detailed.py | 0 .../run_tests_with_db.sh | 0 setup-server-backup.sh | 526 ------------------ .../dashboard/fixed-dashboard.js | 0 .../integration/test-e2e-deployment.py | 0 .../integration/test-remote-integration.py | 0 .../mocks/mock-optimization-server.py | 0 .../mocks/mock-scada-server.py | 0 .../test_dashboard_local.py | 0 .../test_discovery_endpoints.py | 0 .../test_opcua_client.py | 0 .../test_opcua_client_integration.py | 0 .../test_opcua_endpoints.py | 0 .../test_protocol_clients.py | 0 .../test_security_modes.py | 0 .../test_server_endpoints.py | 0 25 files changed, 566 deletions(-) rename deploy-onprem.sh => deploy/deploy-onprem.sh (100%) rename generate-monitoring-secrets.sh => deploy/generate-monitoring-secrets.sh (100%) rename setup-monitoring.sh => deploy/setup-monitoring.sh (100%) rename setup-server.sh => deploy/setup-server.sh (100%) rename start-remote-test.sh => deploy/start-remote-test.sh (100%) rename test-deployment.sh => deploy/test-deployment.sh (100%) rename validate-deployment.sh => deploy/validate-deployment.sh (100%) delete mode 100644 pytest-mock.ini rename run_tests_by_system.py => scripts/run_tests_by_system.py (100%) rename run_tests_detailed.py => scripts/run_tests_detailed.py (100%) rename run_tests_with_db.sh => scripts/run_tests_with_db.sh (100%) delete mode 100644 setup-server-backup.sh rename fixed-dashboard.js => src/dashboard/fixed-dashboard.js (100%) rename test-e2e-deployment.py => tests/integration/test-e2e-deployment.py (100%) rename test-remote-integration.py => tests/integration/test-remote-integration.py (100%) rename mock-optimization-server.py => tests/mocks/mock-optimization-server.py (100%) rename mock-scada-server.py => tests/mocks/mock-scada-server.py (100%) rename test_dashboard_local.py => tests/test_dashboard_local.py (100%) rename test_discovery_endpoints.py => tests/test_discovery_endpoints.py (100%) rename test_opcua_client.py => tests/test_opcua_client.py (100%) rename test_opcua_client_integration.py => tests/test_opcua_client_integration.py (100%) rename test_opcua_endpoints.py => tests/test_opcua_endpoints.py (100%) rename test_protocol_clients.py => tests/test_protocol_clients.py (100%) rename test_security_modes.py => tests/test_security_modes.py (100%) rename test_server_endpoints.py => tests/test_server_endpoints.py (100%) diff --git a/deploy-onprem.sh b/deploy/deploy-onprem.sh similarity index 100% rename from deploy-onprem.sh rename to deploy/deploy-onprem.sh diff --git a/generate-monitoring-secrets.sh b/deploy/generate-monitoring-secrets.sh similarity index 100% rename from generate-monitoring-secrets.sh rename to deploy/generate-monitoring-secrets.sh diff --git a/setup-monitoring.sh b/deploy/setup-monitoring.sh similarity index 100% rename from setup-monitoring.sh rename to deploy/setup-monitoring.sh diff --git a/setup-server.sh b/deploy/setup-server.sh similarity index 100% rename from setup-server.sh rename to deploy/setup-server.sh diff --git a/start-remote-test.sh b/deploy/start-remote-test.sh similarity index 100% rename from start-remote-test.sh rename to deploy/start-remote-test.sh diff --git a/test-deployment.sh b/deploy/test-deployment.sh similarity index 100% rename from test-deployment.sh rename to deploy/test-deployment.sh diff --git a/validate-deployment.sh b/deploy/validate-deployment.sh similarity index 100% rename from validate-deployment.sh rename to deploy/validate-deployment.sh diff --git a/pytest-mock.ini b/pytest-mock.ini deleted file mode 100644 index e93515e..0000000 --- a/pytest-mock.ini +++ /dev/null @@ -1,40 +0,0 @@ -[tool:pytest] -# Configuration for mock service tests - -# Test discovery -python_files = test_*.py -python_classes = Test* -python_functions = test_* - -# Output formatting -addopts = - -v - --tb=short - --strict-markers - --strict-config - --disable-warnings - -# Markers -markers = - mock: Tests that require mock services - scada: Tests for SCADA functionality - optimizer: Tests for optimizer functionality - integration: Integration tests - e2e: End-to-end tests - slow: Slow running tests - -# Filter warnings -filterwarnings = - ignore::DeprecationWarning - ignore::PendingDeprecationWarning - -# Test timeout (seconds) -timeout = 30 - -# Coverage configuration (if coverage is installed) -# --cov=src -# --cov-report=term-missing -# --cov-report=html - -# JUnit XML output (for CI/CD) -# junit_family = xunit2 \ No newline at end of file diff --git a/run_tests_by_system.py b/scripts/run_tests_by_system.py similarity index 100% rename from run_tests_by_system.py rename to scripts/run_tests_by_system.py diff --git a/run_tests_detailed.py b/scripts/run_tests_detailed.py similarity index 100% rename from run_tests_detailed.py rename to scripts/run_tests_detailed.py diff --git a/run_tests_with_db.sh b/scripts/run_tests_with_db.sh similarity index 100% rename from run_tests_with_db.sh rename to scripts/run_tests_with_db.sh diff --git a/setup-server-backup.sh b/setup-server-backup.sh deleted file mode 100644 index 0427a0e..0000000 --- a/setup-server-backup.sh +++ /dev/null @@ -1,526 +0,0 @@ -#!/bin/bash - -# Calejo Control Adapter - One-Click Server Setup Script -# Single command to provision server, install dependencies, deploy application, and start dashboard - -set -e - -# Colors for output -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -NC='\033[0m' # No Color - -# Default configuration -ENVIRONMENT="production" -SERVER_HOST="" -SSH_USERNAME="" -SSH_KEY_FILE="" -AUTO_DETECT=true -VERBOSE=false -DRY_RUN=false - -# Function to print colored output -print_status() { - echo -e "${BLUE}[INFO]${NC} $1" -} - -print_success() { - echo -e "${GREEN}[SUCCESS]${NC} $1" -} - -print_warning() { - echo -e "${YELLOW}[WARNING]${NC} $1" -} - -print_error() { - echo -e "${RED}[ERROR]${NC} $1" -} - -# Function to display usage -usage() { - echo "Calejo Control Adapter - One-Click Server Setup" - echo "==================================================" - echo "" - echo "Usage: $0 [OPTIONS]" - echo "" - echo "Options:" - echo " -e, --environment Deployment environment (production, staging) [default: production]" - echo " -h, --host Server hostname or IP address" - echo " -u, --user SSH username" - echo " -k, --key SSH private key file" - echo " --no-auto Disable auto-detection (manual configuration)" - echo " --verbose Enable verbose output" - echo " --dry-run Show what would be done without making changes" - echo " --help Show this help message" - echo "" - echo "Examples:" - echo " $0 # Auto-detect and setup local machine" - echo " $0 -h 192.168.1.100 -u ubuntu -k ~/.ssh/id_rsa # Setup remote server" - echo " $0 --dry-run # Show setup steps without executing" - echo "" -} - -# Function to read deployment configuration from files -read_deployment_config() { - local config_dir="deploy" - - # Read from production.yml if it exists - if [[ -f "$config_dir/config/production.yml" ]]; then - print_status "Reading configuration from $config_dir/config/production.yml" - - # Extract values from production.yml - if [[ -z "$SSH_HOST" ]]; then - SSH_HOST=$(grep -E "^\s*host:\s*" "$config_dir/config/production.yml" | head -1 | sed 's/^[[:space:]]*host:[[:space:]]*//' | sed 's/^"//' | sed 's/"$//' | tr -d '\r') - fi - - if [[ -z "$SSH_USERNAME" ]]; then - SSH_USERNAME=$(grep -E "^\s*username:\s*" "$config_dir/config/production.yml" | head -1 | sed 's/^[[:space:]]*username:[[:space:]]*//' | sed 's/^"//' | sed 's/"$//' | tr -d '\r') - fi - - if [[ -z "$SSH_KEY_FILE" ]]; then - SSH_KEY_FILE=$(grep -E "^\s*key_file:\s*" "$config_dir/config/production.yml" | head -1 | sed 's/^[[:space:]]*key_file:[[:space:]]*//' | sed 's/^"//' | sed 's/"$//' | tr -d '\r') - fi - fi - - # Read from staging.yml if it exists and environment is staging - if [[ "$ENVIRONMENT" == "staging" && -f "$config_dir/config/staging.yml" ]]; then - print_status "Reading configuration from $config_dir/config/staging.yml" - - if [[ -z "$SSH_HOST" ]]; then - SSH_HOST=$(grep -E "^\s*host:\s*" "$config_dir/config/staging.yml" | head -1 | sed 's/^[[:space:]]*host:[[:space:]]*//' | sed 's/^"//' | sed 's/"$//' | tr -d '\r') - fi - - if [[ -z "$SSH_USERNAME" ]]; then - SSH_USERNAME=$(grep -E "^\s*username:\s*" "$config_dir/config/staging.yml" | head -1 | sed 's/^[[:space:]]*username:[[:space:]]*//' | sed 's/^"//' | sed 's/"$//' | tr -d '\r') - fi - - if [[ -z "$SSH_KEY_FILE" ]]; then - SSH_KEY_FILE=$(grep -E "^\s*key_file:\s*" "$config_dir/config/staging.yml" | head -1 | sed 's/^[[:space:]]*key_file:[[:space:]]*//' | sed 's/^"//' | sed 's/"$//' | tr -d '\r') - fi - fi - - # Check for existing remote deployment script configuration - if [[ -f "$config_dir/ssh/deploy-remote.sh" ]]; then - print_status "Found existing remote deployment script: $config_dir/ssh/deploy-remote.sh" - - # Extract default values from deploy-remote.sh - if [[ -z "$SSH_HOST" ]]; then - SSH_HOST=$(grep -E "SSH_HOST=" "$config_dir/ssh/deploy-remote.sh" | head -1 | cut -d'=' -f2 | tr -d '\"' | tr -d '\'') - fi - - if [[ -z "$SSH_USERNAME" ]]; then - SSH_USERNAME=$(grep -E "SSH_USER=" "$config_dir/ssh/deploy-remote.sh" | head -1 | cut -d'=' -f2 | tr -d '\"' | tr -d '\'') - fi - - if [[ -z "$SSH_KEY_FILE" ]]; then - SSH_KEY_FILE=$(grep -E "SSH_KEY=" "$config_dir/ssh/deploy-remote.sh" | head -1 | cut -d'=' -f2 | tr -d '\"' | tr -d '\'') - fi - fi - - # Set defaults if still empty - ENVIRONMENT=${ENVIRONMENT:-production} - SSH_HOST=${SSH_HOST:-localhost} - SSH_USERNAME=${SSH_USERNAME:-$USER} - SSH_KEY_FILE=${SSH_KEY_FILE:-~/.ssh/id_rsa} - - # Use SSH_HOST as SERVER_HOST if not specified - SERVER_HOST=${SERVER_HOST:-$SSH_HOST} -} - -# Function to parse command line arguments -parse_arguments() { - while [[ $# -gt 0 ]]; do - case $1 in - -e|--environment) - ENVIRONMENT="$2" - shift 2 - ;; - -h|--host) - SERVER_HOST="$2" - AUTO_DETECT=false - shift 2 - ;; - -u|--user) - SSH_USERNAME="$2" - AUTO_DETECT=false - shift 2 - ;; - -k|--key) - SSH_KEY_FILE="$2" - AUTO_DETECT=false - shift 2 - ;; - --no-auto) - AUTO_DETECT=false - shift - ;; - --verbose) - VERBOSE=true - shift - ;; - --dry-run) - DRY_RUN=true - shift - ;; - --help) - usage - exit 0 - ;; - *) - print_error "Unknown option: $1" - usage - exit 1 - ;; - esac - done -} - -# Function to detect if running locally or needs remote setup -detect_deployment_type() { - if [[ -n "$SERVER_HOST" && "$SERVER_HOST" != "localhost" && "$SERVER_HOST" != "127.0.0.1" ]]; then - echo "remote" - else - echo "local" - fi -} - -# Function to check local prerequisites -check_local_prerequisites() { - print_status "Checking local prerequisites..." - - # Check if script is running with sufficient privileges - if [[ $EUID -eq 0 ]]; then - print_warning "Running as root - this is not recommended for security reasons" - fi - - # Check Docker - if ! command -v docker &> /dev/null; then - print_error "Docker is not installed locally" - echo "Please install Docker first: https://docs.docker.com/get-docker/" - exit 1 - fi - - # Check Docker Compose - if ! command -v docker-compose &> /dev/null; then - print_error "Docker Compose is not installed locally" - echo "Please install Docker Compose first: https://docs.docker.com/compose/install/" - exit 1 - fi - - print_success "Local prerequisites check passed" -} - -# Function to check remote prerequisites via SSH -check_remote_prerequisites() { - print_status "Checking remote server prerequisites..." - - local ssh_cmd="ssh -i $SSH_KEY_FILE $SSH_USERNAME@$SERVER_HOST" - - if [[ "$DRY_RUN" == "true" ]]; then - echo " [DRY RUN] Would check remote prerequisites" - return 0 - fi - - # Check Docker - if ! $ssh_cmd "command -v docker" &> /dev/null; then - print_error "Docker is not installed on remote server" - return 1 - fi - - # Check Docker Compose - if ! $ssh_cmd "command -v docker-compose" &> /dev/null; then - print_error "Docker Compose is not installed on remote server" - return 1 - fi - - # Check disk space - local disk_usage=$($ssh_cmd "df / | awk 'NR==2 {print \$5}' | sed 's/%//'") - if [[ $disk_usage -gt 90 ]]; then - print_warning "Low disk space on remote server: ${disk_usage}%" - fi - - print_success "Remote prerequisites check passed" -} - -# Function to setup local deployment -setup_local_deployment() { - print_status "Setting up local deployment..." - - if [[ "$DRY_RUN" == "true" ]]; then - echo " [DRY RUN] Would setup local deployment" - return 0 - fi - - # Create necessary directories - mkdir -p ./data/postgres - mkdir -p ./logs - mkdir -p ./certs - - # Set permissions - chmod 755 ./data - chmod 755 ./logs - chmod 700 ./certs - - # Generate default configuration if not exists - if [[ ! -f ".env" ]]; then - print_status "Creating default configuration..." - cp config/.env.example .env - - # Generate secure JWT secret - local jwt_secret=$(openssl rand -hex 32 2>/dev/null || echo "default-secret-change-in-production") - sed -i.bak "s/your-secret-key-change-in-production/$jwt_secret/" .env - rm -f .env.bak - - print_success "Default configuration created with secure JWT secret" - fi - - # Build and start services - print_status "Building and starting services..." - docker-compose up --build -d - - # Wait for services to be ready - wait_for_services "localhost" - - print_success "Local deployment completed successfully" -} - -# Function to setup remote deployment -setup_remote_deployment() { - print_status "Setting up remote deployment on $SERVER_HOST..." - - if [[ "$DRY_RUN" == "true" ]]; then - echo " [DRY RUN] Would setup remote deployment on $SERVER_HOST" - return 0 - fi - - # Use existing deployment script - if [[ -f "deploy/ssh/deploy-remote.sh" ]]; then - print_status "Using existing remote deployment script..." - - # Create temporary configuration - local temp_config=$(mktemp) - cat > "$temp_config" << EOF -ssh: - host: $SERVER_HOST - port: 22 - username: $SSH_USERNAME - key_file: $SSH_KEY_FILE - -deployment: - target_dir: /opt/calejo-control-adapter - backup_dir: /var/backup/calejo - log_dir: /var/log/calejo - config_dir: /etc/calejo -EOF - - # Run deployment - ./deploy/ssh/deploy-remote.sh -e "$ENVIRONMENT" -c "$temp_config" - - # Cleanup - rm -f "$temp_config" - else - print_error "Remote deployment script not found" - return 1 - fi - - print_success "Remote deployment completed successfully" -} - -# Function to wait for services to be ready -wait_for_services() { - local host="$1" - local max_attempts=30 - local attempt=1 - - print_status "Waiting for services to start..." - - while [[ $attempt -le $max_attempts ]]; do - if curl -s "http://$host:8080/health" > /dev/null 2>&1; then - print_success "Services are ready and responding" - return 0 - fi - - echo " Waiting... (attempt $attempt/$max_attempts)" - sleep 5 - ((attempt++)) - done - - print_error "Services failed to start within expected time" - return 1 -} - -# Function to generate SSL certificates for production -generate_ssl_certificates() { - if [[ "$ENVIRONMENT" == "production" ]]; then - print_status "Setting up SSL certificates for production..." - - if [[ "$DRY_RUN" == "true" ]]; then - echo " [DRY RUN] Would generate SSL certificates" - return 0 - fi - - mkdir -p ./certs - - # Generate self-signed certificate for development - # In production, you should use Let's Encrypt or proper CA - if openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ - -keyout ./certs/server.key \ - -out ./certs/server.crt \ - -subj "/C=US/ST=State/L=City/O=Organization/CN=localhost" 2>/dev/null; then - print_success "SSL certificates generated" - else - print_warning "SSL certificate generation failed - using development mode" - fi - - print_success "SSL certificates configured" - fi -} - -# Function to display setup completion message -display_completion_message() { - local deployment_type="$1" - local host="$2" - - echo "" - echo "==================================================" - echo " SETUP COMPLETED SUCCESSFULLY!" - echo "==================================================" - echo "" - echo "🎉 Calejo Control Adapter is now running!" - echo "" - echo "🌍 Access URLs:" - echo " Dashboard: http://$host:8080/dashboard" - echo " REST API: http://$host:8080" - echo " Health Check: http://$host:8080/health" - echo "" - echo "🔧 Next Steps:" - echo " 1. Open the dashboard in your browser" - echo " 2. Configure your SCADA systems and hardware" - echo " 3. Set up safety limits and user accounts" - echo " 4. Integrate with your existing infrastructure" - echo "" - echo "📚 Documentation:" - echo " Full documentation: ./docs/" - echo " Quick start: ./docs/INSTALLATION_CONFIGURATION.md" - echo " Dashboard guide: ./docs/OPERATIONS_MAINTENANCE.md" - echo "" - - if [[ "$deployment_type" == "local" ]]; then - echo "💡 Local Development Tips:" - echo " - View logs: docker-compose logs -f" - echo " - Stop services: docker-compose down" - echo " - Restart: docker-compose up -d" - else - echo "💡 Remote Server Tips:" - echo " - View logs: ssh -i $SSH_KEY_FILE $SSH_USERNAME@$host 'cd /opt/calejo-control-adapter && docker-compose logs -f'" - echo " - Stop services: ssh -i $SSH_KEY_FILE $SSH_USERNAME@$host 'cd /opt/calejo-control-adapter && docker-compose down'" - echo " - Restart: ssh -i $SSH_KEY_FILE $SSH_USERNAME@$host 'cd /opt/calejo-control-adapter && docker-compose up -d'" - fi - - echo "" - echo "==================================================" - echo "" -} - -# Function to validate setup -validate_setup() { - local host="$1" - - print_status "Validating setup..." - - if [[ "$DRY_RUN" == "true" ]]; then - echo " [DRY RUN] Would validate setup" - return 0 - fi - - # Test health endpoint - if ! curl -s "http://$host:8080/health" > /dev/null; then - print_error "Health check failed" - return 1 - fi - - # Test dashboard endpoint - if ! curl -s "http://$host:8080/dashboard" > /dev/null; then - print_error "Dashboard check failed" - return 1 - fi - - # Test API endpoint - if ! curl -s "http://$host:8080/api/v1/status" > /dev/null; then - print_warning "API status check failed (may require authentication)" - fi - - print_success "Setup validation passed" - return 0 -} - -# Main setup function -main() { - echo "" - echo "🚀 Calejo Control Adapter - One-Click Server Setup" - echo "==================================================" - echo "" - - # Parse command line arguments - parse_arguments "$@" - - # Read deployment configuration from files - read_deployment_config - - # Detect deployment type - local deployment_type=$(detect_deployment_type) - - # Display setup information - echo "Setup Configuration:" - echo " Environment: $ENVIRONMENT" - echo " Deployment: $deployment_type" - if [[ "$deployment_type" == "remote" ]]; then - echo " Server: $SERVER_HOST" - echo " User: $SSH_USERNAME" - else - echo " Server: localhost" - fi - if [[ "$DRY_RUN" == "true" ]]; then - echo " Mode: DRY RUN" - fi - echo "" - - # Check prerequisites - if [[ "$deployment_type" == "local" ]]; then - check_local_prerequisites - else - if [[ -z "$SERVER_HOST" || -z "$SSH_USERNAME" || -z "$SSH_KEY_FILE" ]]; then - print_error "Remote deployment requires --host, --user, and --key parameters" - usage - exit 1 - fi - check_remote_prerequisites - fi - - # Generate SSL certificates for production - generate_ssl_certificates - - # Perform deployment - if [[ "$deployment_type" == "local" ]]; then - setup_local_deployment - local final_host="localhost" - else - setup_remote_deployment - local final_host="$SERVER_HOST" - fi - - # Validate setup - validate_setup "$final_host" - - # Display completion message - display_completion_message "$deployment_type" "$final_host" - - echo "" - print_success "One-click setup completed!" - echo "" -} - -# Run main function -main "$@" \ No newline at end of file diff --git a/fixed-dashboard.js b/src/dashboard/fixed-dashboard.js similarity index 100% rename from fixed-dashboard.js rename to src/dashboard/fixed-dashboard.js diff --git a/test-e2e-deployment.py b/tests/integration/test-e2e-deployment.py similarity index 100% rename from test-e2e-deployment.py rename to tests/integration/test-e2e-deployment.py diff --git a/test-remote-integration.py b/tests/integration/test-remote-integration.py similarity index 100% rename from test-remote-integration.py rename to tests/integration/test-remote-integration.py diff --git a/mock-optimization-server.py b/tests/mocks/mock-optimization-server.py similarity index 100% rename from mock-optimization-server.py rename to tests/mocks/mock-optimization-server.py diff --git a/mock-scada-server.py b/tests/mocks/mock-scada-server.py similarity index 100% rename from mock-scada-server.py rename to tests/mocks/mock-scada-server.py diff --git a/test_dashboard_local.py b/tests/test_dashboard_local.py similarity index 100% rename from test_dashboard_local.py rename to tests/test_dashboard_local.py diff --git a/test_discovery_endpoints.py b/tests/test_discovery_endpoints.py similarity index 100% rename from test_discovery_endpoints.py rename to tests/test_discovery_endpoints.py diff --git a/test_opcua_client.py b/tests/test_opcua_client.py similarity index 100% rename from test_opcua_client.py rename to tests/test_opcua_client.py diff --git a/test_opcua_client_integration.py b/tests/test_opcua_client_integration.py similarity index 100% rename from test_opcua_client_integration.py rename to tests/test_opcua_client_integration.py diff --git a/test_opcua_endpoints.py b/tests/test_opcua_endpoints.py similarity index 100% rename from test_opcua_endpoints.py rename to tests/test_opcua_endpoints.py diff --git a/test_protocol_clients.py b/tests/test_protocol_clients.py similarity index 100% rename from test_protocol_clients.py rename to tests/test_protocol_clients.py diff --git a/test_security_modes.py b/tests/test_security_modes.py similarity index 100% rename from test_security_modes.py rename to tests/test_security_modes.py diff --git a/test_server_endpoints.py b/tests/test_server_endpoints.py similarity index 100% rename from test_server_endpoints.py rename to tests/test_server_endpoints.py