diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d4e3db49d..177d5b621 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -99,7 +99,564 @@ See [development documentation](DEVELOPMENT.md). ### Testing -Coming soon [TBD] +This project includes comprehensive test suites to ensure code quality and functionality. + +#### Before You Start Testing + +**Quick Decision Guide**: + +- 🚀 **Just want to validate code quality?** → Run static checks: `composer run-script static_check` +- ✅ **Testing business logic changes?** → Run unit tests: `composer run-script run_unit_tests` +- 🔧 **Changed the native extension (C code)?** → Use Docker: `make -f .ci/Makefile run-phpt-tests` +- 🌐 **Testing with real HTTP requests?** → Use Docker: `make -f .ci/Makefile component-test` +- 🎯 **Testing with a specific framework?** → Use the framework script: `./scripts/test-framework.sh` +- 📦 **Preparing a PR?** → Run the full suite with Docker + +#### Prerequisites + +- Docker (for containerized testing) +- PHP 7.2+ with required extensions +- Composer + +#### Test Requirements Overview + +| Test Type | Requires Extension | Requires External Services | Can Run Locally | Recommended Approach | +|-----------------|--------------------|---------------------------|-------------------|-----------------------------------------------| +| Static Checks | ❌ No | ❌ No | ✅ Yes | `composer run-script static_check` | +| Unit Tests | ❌ No | ❌ No | ✅ Yes | `composer run-script run_unit_tests` | +| Component Tests | ✅ **Yes** | ⚠️ MySQL (for some tests) | ⚠️ Advanced setup | Docker: `make -f .ci/Makefile component-test` | +| PHPT Tests | ✅ **Yes** | ❌ No | ⚠️ Advanced setup | Docker: `make -f .ci/Makefile run-phpt-tests` | + +**Key Points**: +- **Static checks and unit tests** work immediately after `composer install` - no extension build required +- **Component and PHPT tests** require the native extension to be built and loaded - use Docker for easiest setup +- **Component tests** include 1 MySQL-dependent test that will fail without MySQL running (248 total tests, ~247 pass without MySQL) + +#### Quick Start + +##### Unit Tests and Static Checks (No Extension Required) + +Unit tests and static checks can run directly without building the native extension: + +```bash +# Install dependencies +composer install + +# Run all static checks (linting, code style, PHPStan) +composer run-script static_check + +# Run unit tests only +composer run-script run_unit_tests + +# Run static checks and unit tests together +composer run-script static_check_and_run_unit_tests +``` + +##### Component Tests (Require Built Extension) + +**Important**: Component tests require the Elastic APM PHP extension to be built and loaded. You have two options: + +**Option 1: Using Docker (Recommended)** + +The Docker approach handles building the extension automatically: + +```bash +# Build the extension for your architecture (required first time) +BUILD_ARCHITECTURE=linux-x86-64 make -f .ci/Makefile build + +# Option A: Run component tests WITHOUT MySQL-dependent tests (fastest) +BUILD_ARCHITECTURE=linux-x86-64 PHP_VERSION=8.3 make -f .ci/Makefile component-test +# This will fail 1 test (MySQLi prerequisites) - see "Handling MySQL Tests" below + +# Option B: Run ALL component tests including MySQL tests (complete) +# First, start external services (MySQL) in the background +source .ci/env_vars_for_external_services_for_component_tests.sh +.ci/start_external_services_for_component_tests.sh + +# Then run component tests - all tests will pass +BUILD_ARCHITECTURE=linux-x86-64 PHP_VERSION=8.3 make -f .ci/Makefile component-test + +# Stop external services when done +.ci/stop_external_services_for_component_tests.sh +``` + +**Handling MySQL Tests**: + +Some component tests (specifically `MySQLiAutoInstrumentationTest`) require a MySQL server to be running. If you run component tests without starting external services, you'll see 1 test failure: + +``` +My SQLi Auto Instrumentation (ElasticApmTests\ComponentTests\MySQLiAutoInstrumentation) + ✘ Prerequisites satisfied + Failed asserting that null is not null. +``` + +This is **expected and safe to ignore** if you're not working on MySQL instrumentation. The other tests will pass successfully. + +If you need to test MySQL instrumentation: +1. Start the MySQL service using the commands in Option B below +2. The test expects these environment variables (set automatically by the script): + - `ELASTIC_APM_PHP_TESTS_MYSQL_HOST` + - `ELASTIC_APM_PHP_TESTS_MYSQL_PORT` + - `ELASTIC_APM_PHP_TESTS_MYSQL_USER` + - `ELASTIC_APM_PHP_TESTS_MYSQL_PASSWORD` + - `ELASTIC_APM_PHP_TESTS_MYSQL_DB` + +**Option 2: Local Setup (Advanced)** + +To run component tests locally without Docker: + +1. Build and install the extension (see [DEVELOPMENT.md](DEVELOPMENT.md)) +2. Verify the extension is loaded: + ```bash + php -m | grep elastic_apm + ``` +3. Run the tests: + ```bash + composer run-script run_component_tests + ``` + +##### Complete Test Suite Using Docker + +For testing across different PHP versions and architectures: + +```bash +# Run static checks and unit tests for PHP 8.3 +PHP_VERSION=8.3 make -f .ci/Makefile static-check-unit-test + +# Run static checks and unit tests for PHP 7.2 with Alpine +PHP_VERSION=7.2 DOCKERFILE=Dockerfile.alpine make -f .ci/Makefile static-check-unit-test + +# Run PHPT tests for PHP 8.3 (requires built extension) +BUILD_ARCHITECTURE=linux-x86-64 PHP_VERSION=8.3 make -f .ci/Makefile run-phpt-tests + +# Open interactive shell in test container +PHP_VERSION=8.3 make -f .ci/Makefile interactive +``` + +#### Best Practices for Testing Before Submitting a PR + +1. **Start with fast tests** - Run static checks and unit tests first for quick feedback +2. **Test the affected areas** - If you changed PHP code, run unit tests; if you changed C code, run PHPT tests +3. **Use Docker for comprehensive testing** - Before submitting, run the full Docker-based test suite +4. **Test on multiple PHP versions** - If your change affects compatibility, test on both older (7.2) and newer (8.4) PHP versions +5. **Add new tests** - If you're adding a feature or fixing a bug, include tests that validate the fix + +**Recommended PR preparation checklist**: +```bash +# 1. Fast local validation +composer run-script static_check +composer run-script run_unit_tests + +# 2. If you changed native extension code +BUILD_ARCHITECTURE=linux-x86-64 PHP_VERSION=8.3 make -f .ci/Makefile run-phpt-tests + +# 3. Full integration testing (1 MySQL test failure is expected, see notes below) +BUILD_ARCHITECTURE=linux-x86-64 PHP_VERSION=8.3 make -f .ci/Makefile component-test +# Expected result: Tests: 248, Assertions: ~640,000, Failures: 1 (MySQLi prerequisites) + +# 4. (Optional) If working on MySQL instrumentation, start external services first +source .ci/env_vars_for_external_services_for_component_tests.sh +.ci/start_external_services_for_component_tests.sh +BUILD_ARCHITECTURE=linux-x86-64 PHP_VERSION=8.3 make -f .ci/Makefile component-test +# Expected result: All 248 tests pass + +# 5. (Optional) Test with a real framework +./scripts/test-framework.sh 8.3 laravel +``` + +**Note**: It's normal and acceptable to have 1 test failure (MySQLi prerequisites check) when running component tests without starting external services. This will not prevent your PR from being merged. + +#### Test Types + +##### Static Analysis + +**What it validates**: Code quality, style compliance, type safety, and potential bugs without executing code. + +**When to run**: Before every commit, as part of your development workflow. + +- **Parallel Lint**: Checks PHP syntax errors across all PHP files + ```bash + composer run-script parallel-lint + ``` + +- **PHP_CodeSniffer**: Validates code style compliance with project standards + ```bash + composer run-script php_codesniffer_check + # Auto-fix issues + composer run-script php_codesniffer_fix + ``` + +- **PHPStan**: Static analysis for type safety and potential bugs (max level) + ```bash + composer run-script phpstan + # Generate JUnit reports for CI + composer run-script phpstan-junit-report-for-ci + ``` + +**Why it matters**: Catches common mistakes early and ensures consistent code style across the project. + +##### Unit Tests + +**What it validates**: Business logic, data transformations, utility functions, and internal APIs in isolation. + +**When to run**: After making changes to PHP code in `agent/php/ElasticApm/` or test code. + +**Test scope**: Tests in `tests/ElasticApmTests/UnitTests/` validate individual classes and functions without requiring the native extension or external services. + +```bash +# Run all unit tests +composer run-script run_unit_tests + +# Run specific test by filter +composer run-script run_unit_tests_filter -- + +# Example: Run only serialization tests +composer run-script run_unit_tests_filter -- Serializer +``` + +Configuration: `phpunit_v8_format.xml` + +**Why it matters**: Fast feedback on business logic changes without needing to build the native extension. These tests form the first line of defense against regressions. + +##### Component Tests + +**What it validates**: End-to-end behavior of the agent in realistic scenarios including: +- HTTP request/response instrumentation +- Database query tracing +- External service call tracking +- Error capturing and reporting +- Span creation and propagation +- Communication with APM server + +**When to run**: After making changes to instrumentation logic, configuration handling, or integration points. + +**Test scope**: Tests in `tests/ElasticApmTests/ComponentTests/` run the agent in both HTTP server and CLI contexts, simulating real application behavior. + +**Prerequisites**: +- The Elastic APM PHP extension must be built and loaded +- For local testing, see "Component Tests (Require Built Extension)" section above +- For Docker testing, the extension is built automatically + +```bash +# Using Docker (Recommended) - extension is built and loaded automatically +BUILD_ARCHITECTURE=linux-x86-64 PHP_VERSION=8.3 make -f .ci/Makefile component-test + +# Test on multiple PHP versions +BUILD_ARCHITECTURE=linux-x86-64 PHP_VERSION=7.2 make -f .ci/Makefile component-test +BUILD_ARCHITECTURE=linux-x86-64 PHP_VERSION=8.4 make -f .ci/Makefile component-test + +# Using local setup (requires extension to be built and installed first) +# Verify extension is loaded: +php -m | grep elastic_apm + +# Run HTTP server component tests +composer run-script run_component_tests_http + +# Run CLI component tests +composer run-script run_component_tests_cli + +# Run both +composer run-script run_component_tests + +# Filter specific component test +composer run-script run_component_tests_http_filter -- ApiKeySecretToken +``` + +Configuration: `phpunit_component_tests.xml` + +**Why it matters**: Validates that the agent correctly captures and reports APM data in realistic application scenarios. These tests catch integration issues that unit tests might miss. + +**Common Issues**: + +1. **Extension not loaded**: + ``` + RuntimeException: Environment hosting component tests application code should have elastic_apm extension loaded + ``` + - The extension is not built or not loaded in PHP + - **Solution**: Use Docker approach or build/install the extension locally + +2. **MySQL test failure** (expected without MySQL running): + ``` + MySQLiAutoInstrumentation ✘ Prerequisites satisfied + Failed asserting that null is not null + ``` + - MySQL server is not running or environment variables are not set + - **Impact**: 1 test fails, ~247 tests pass + - **Solution**: Either ignore this failure (if not working on MySQL instrumentation) OR start external services: + ```bash + source .ci/env_vars_for_external_services_for_component_tests.sh + .ci/start_external_services_for_component_tests.sh + ``` + +##### PHPT Tests + +**What it validates**: Native C extension functionality at a low level including: +- Extension loading and initialization +- PHP API interactions +- Memory management +- Internal function hooking +- Extension configuration (INI settings) +- Compatibility across PHP versions + +**When to run**: After making changes to the native extension code in `agent/native/`. + +**Test scope**: PHPT (PHP Test) files in `agent/native/ext/tests/` use PHP's built-in testing framework to validate extension behavior. + +**Prerequisites**: +- The Elastic APM PHP extension must be built +- Docker is the recommended approach for these tests + +```bash +# Build the extension first (if not already built) +BUILD_ARCHITECTURE=linux-x86-64 make -f .ci/Makefile build + +# Run PHPT tests for PHP 8.3 +BUILD_ARCHITECTURE=linux-x86-64 PHP_VERSION=8.3 make -f .ci/Makefile run-phpt-tests + +# Run PHPT tests for PHP 7.2 +BUILD_ARCHITECTURE=linux-x86-64 PHP_VERSION=7.2 make -f .ci/Makefile run-phpt-tests + +# Test on Alpine (musl libc) +BUILD_ARCHITECTURE=linuxmusl-x86-64 PHP_VERSION=8.3 make -f .ci/Makefile run-phpt-tests +``` + +**Why it matters**: These are the only tests that validate the C extension code directly. Essential for ensuring the extension doesn't crash, leak memory, or behave incorrectly at the PHP interpreter level. + +##### Framework Testing + +The `scripts/test-framework.sh` script helps you test the Elastic APM PHP Agent with real-world PHP frameworks. This is invaluable for: +- **Integration testing**: Verify the agent works correctly with popular frameworks +- **Compatibility validation**: Test across different PHP versions and framework versions +- **Issue reproduction**: Set up a minimal environment to reproduce framework-specific bugs +- **Development workflow**: Quickly spin up a framework instance instrumented with your local agent changes + +**How it works**: +1. Downloads and installs the specified framework (Laravel, Symfony, WordPress, Drupal, or Magento) +2. Configures the framework to use your local development version of the agent +3. Creates a PHP configuration file with Elastic APM settings +4. Provides instructions for running the framework with APM instrumentation + +**Usage**: +```bash +./scripts/test-framework.sh [FRAMEWORK_VERSION] +``` + +**Examples**: +```bash +# Test with Laravel 11.x on PHP 8.3 +./scripts/test-framework.sh 8.3 laravel 11.x + +# Test with Symfony 7.0 on PHP 8.2 +./scripts/test-framework.sh 8.2 symfony 8.0.x + +# Test with WordPress latest on PHP 8.1 +./scripts/test-framework.sh 8.1 wordpress latest + +# Test with Drupal on PHP 8.3 +./scripts/test-framework.sh 8.3 drupal 7.x-dev +``` + +**Supported frameworks**: Laravel, Symfony, WordPress, Drupal, Magento + +**Step-by-step workflow**: + +1. **Build the agent extension** (if not already built): + ```bash + BUILD_ARCHITECTURE=linux-x86-64 make -f .ci/Makefile build + ``` + +2. **Run the framework setup script**: + ```bash + ./scripts/test-framework.sh 8.3 laravel 11.x + ``` + + The script will: + - Check PHP availability + - Download and install Laravel 11.x in `build/framework-tests/laravel-8.3-11.x/` + - Add the agent as a Composer dependency + - Generate `php-apm.ini` with APM configuration + +3. **Configure the extension path** in the generated `php-apm.ini`: + ```ini + ; Update this line with the actual path to your built extension + extension=/path/to/apm-agent-php/agent/native/_build/linux-x86-64-release/ext/elastic_apm-PHPVERSION.so + ``` + +4. **Start the framework application**: + ```bash + cd build/framework-tests/laravel-8.3-11.x/ + php -c php-apm.ini artisan serve + ``` + +5. **Generate traffic** and verify traces appear in your APM server + +**What gets configured**: + +The script creates a `php-apm.ini` file with sensible defaults: +```ini +extension=elastic_apm.so +elastic_apm.enabled=1 +elastic_apm.service_name=laravel_test # Named after framework +elastic_apm.environment=development +elastic_apm.log_level=DEBUG # Verbose logging for debugging +elastic_apm.server_url=http://localhost:8200 +``` + +**Tips**: +- Each framework/PHP/version combination is installed in a separate directory +- You can reuse the same installation for multiple test runs +- Set `ELASTIC_APM_LOG_LEVEL_STDERR=TRACE` for even more detailed logs +- Use Docker for testing if your system PHP version doesn't match the desired version +- The script is extensible - you can add support for additional frameworks by editing it + +#### Supported PHP Versions + +Tests run against multiple PHP versions: +- PHP 7.2, 7.3, 7.4 +- PHP 8.0, 8.1, 8.2, 8.3, 8.4 + +#### Supported Architectures + +- `linux-x86-64` (default) +- `linux-arm64` +- `linuxmusl-x86-64` (Alpine) +- `linuxmusl-arm64` (Alpine ARM) + +#### CI/CD Testing + +GitHub Actions workflows automatically run tests on: +- Pull requests +- Pushes to main branch +- Multiple PHP versions and architectures in parallel + +See `.github/workflows/test.yml` for the complete CI configuration. + +#### Testing Workflow Summary + +Here's a complete workflow from code change to ready-for-PR: + +```bash +# 1. Make your code changes +# ... edit files ... + +# 2. Quick validation (< 1 minute) +composer run-script static_check + +# 3. Unit test validation (< 5 minutes) +composer run-script run_unit_tests + +# 4. If changes affect PHP code - you're done! Commit and push +git add . +git commit -m "Your changes" + +# 5. If changes affect native extension (C code) - run PHPT tests +BUILD_ARCHITECTURE=linux-x86-64 PHP_VERSION=8.3 make -f .ci/Makefile run-phpt-tests + +# 6. Before submitting PR - run full component test suite +BUILD_ARCHITECTURE=linux-x86-64 PHP_VERSION=8.3 make -f .ci/Makefile component-test +# Note: 1 MySQL test failure is expected (see documentation) + +# 7. (Optional) Validate with a real framework +./scripts/test-framework.sh 8.3 symfony +cd build/framework-tests/symfony-8.3-latest/ +# Configure php-apm.ini with extension path +php -c php-apm.ini bin/console about +``` + +#### Troubleshooting + +##### Test Failures + +1. **Ensure all dependencies are installed**: + ```bash + composer install + ``` + +2. **Check PHP version compatibility**: + ```bash + php -v + ``` + Make sure you're using PHP 7.2 or higher. + +3. **For Docker tests, ensure Docker is running**: + ```bash + docker ps + ``` + If Docker isn't running, start the Docker daemon. + +4. **Extension not loaded** (for component/PHPT tests): + ```bash + php -m | grep elastic_apm + ``` + If nothing is returned, the extension isn't loaded. Use Docker testing instead. + +5. **Component test shows 1 MySQL failure**: + ``` + FAILURES! + Tests: 248, Assertions: 640117, Failures: 1. + MySQLiAutoInstrumentation ✘ Prerequisites satisfied + ``` + This is **expected and normal** when MySQL is not running. The test suite includes MySQL-specific tests that require an external MySQL server. You have two options: + + **Option A** (Recommended for most contributors): Ignore this failure. It won't affect your PR. The CI system will run tests with MySQL available. + + **Option B** (If working on MySQL instrumentation): Start the external services: + ```bash + source .ci/env_vars_for_external_services_for_component_tests.sh + .ci/start_external_services_for_component_tests.sh + # Re-run your component tests + # Stop services when done: + .ci/stop_external_services_for_component_tests.sh + ``` + +##### Build Directory Permissions + +If you encounter permission issues with the `build/` directory when using Docker: + +```bash +sudo chown -R $(id -u):$(id -g) build/ +``` + +This can happen because Docker containers run as root and create files owned by root. + +##### Memory Limits + +PHPUnit tests are configured with 2GB memory limit. If you encounter memory issues: + +```bash +php -d memory_limit=4G vendor/bin/phpunit +``` + +##### Docker Build Issues + +If Docker builds fail or hang: + +```bash +# Clean up old containers and images +docker system prune -a + +# Rebuild from scratch +BUILD_ARCHITECTURE=linux-x86-64 make -f .ci/Makefile build +``` + +##### Framework Testing Issues + +If `./scripts/test-framework.sh` fails: + +1. **Check PHP version availability**: The script checks if the requested PHP version is installed +2. **Check Composer availability**: Framework installation requires Composer +3. **Check network access**: Frameworks are downloaded from the internet +4. **Consult script output**: The script provides colored output with helpful error messages + +**Extension path configuration**: After running the script, you must edit `php-apm.ini` to point to your built extension: + +```bash +# Find your built extension +ls -la agent/native/_build/linux-x86-64-release/ext/ + +# Update php-apm.ini with the correct path +extension=/home/you/apm-agent-php/agent/native/_build/linux-x86-64-release/ext/elastic_apm-83.so +``` ### Workflow diff --git a/scripts/test-framework.sh b/scripts/test-framework.sh index ab5089ea8..b098ce74f 100755 --- a/scripts/test-framework.sh +++ b/scripts/test-framework.sh @@ -1,7 +1,224 @@ #!/usr/bin/env bash set -e -VERSION=${1:?Please specify the PHP version to be tested with} -FRAMEWORK=${2:?Please specify the FRAMEWORK to be tested with} +# Script to test the Elastic APM PHP Agent with various PHP frameworks +# Usage: ./scripts/test-framework.sh [FRAMEWORK_VERSION] +# +# Examples: +# ./scripts/test-framework.sh 8.3 laravel 11.x +# ./scripts/test-framework.sh 8.2 symfony 7.0 +# ./scripts/test-framework.sh 8.1 wordpress 6.4 -echo "TBD: Testing ${FRAMEWORK} with PHP version ${VERSION}" +VERSION=${1:?Please specify the PHP version to be tested with (e.g., 8.3). Usage: ./scripts/test-framework.sh [FRAMEWORK_VERSION]} +FRAMEWORK=${2:?Please specify the FRAMEWORK to be tested with (e.g., laravel, symfony, wordpress) Usage: ./scripts/test-framework.sh [FRAMEWORK_VERSION]} +FRAMEWORK_VERSION=${3:-latest} + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +PROJECT_ROOT="$( cd "${SCRIPT_DIR}/.." && pwd )" +TEST_DIR="${PROJECT_ROOT}/build/framework-tests" +FRAMEWORK_DIR="${TEST_DIR}/${FRAMEWORK}-${VERSION}-${FRAMEWORK_VERSION}" + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +echo_info() { + echo -e "${GREEN}[INFO]${NC} $1" +} + +echo_warn() { + echo -e "${YELLOW}[WARN]${NC} $1" +} + +echo_error() { + echo -e "${RED}[ERROR]${NC} $1" +} + +# Check if PHP version is installed +check_php_version() { + echo_info "Checking PHP ${VERSION} availability..." + if ! command -v php${VERSION} &> /dev/null && ! php -v | grep -q "PHP ${VERSION}"; then + echo_error "PHP ${VERSION} is not installed or not in PATH" + echo_info "You can use Docker to test with different PHP versions:" + echo_info " PHP_VERSION=${VERSION} make -f .ci/Makefile interactive" + exit 1 + fi + echo_info "PHP ${VERSION} is available" +} + +# Setup framework test environment +setup_framework() { + echo_info "Setting up ${FRAMEWORK} ${FRAMEWORK_VERSION} with PHP ${VERSION}..." + mkdir -p "${FRAMEWORK_DIR}" + cd "${FRAMEWORK_DIR}" + + case "${FRAMEWORK}" in + laravel) + setup_laravel + ;; + symfony) + setup_symfony + ;; + wordpress) + setup_wordpress + ;; + drupal) + setup_drupal + ;; + magento) + setup_magento + ;; + *) + echo_error "Framework '${FRAMEWORK}' is not supported yet" + echo_info "Supported frameworks: laravel, symfony, wordpress, drupal, magento" + echo_info "You can add support by extending this script" + exit 1 + ;; + esac +} + +setup_laravel() { + echo_info "Installing Laravel ${FRAMEWORK_VERSION}..." + if [ ! -f "composer.json" ]; then + composer create-project --prefer-dist laravel/laravel . "${FRAMEWORK_VERSION}" + fi +} + +setup_symfony() { + echo_info "Installing Symfony ${FRAMEWORK_VERSION}..." + if [ ! -f "composer.json" ]; then + composer create-project symfony/skeleton . "${FRAMEWORK_VERSION}" + fi +} + +setup_wordpress() { + echo_info "Downloading WordPress ${FRAMEWORK_VERSION}..." + if [ ! -f "wp-config-sample.php" ]; then + if [ "${FRAMEWORK_VERSION}" = "latest" ]; then + curl -O https://wordpress.org/latest.tar.gz + else + curl -O "https://wordpress.org/wordpress-${FRAMEWORK_VERSION}.tar.gz" + fi + tar -xzf *.tar.gz --strip-components=1 + rm *.tar.gz + fi +} + +setup_drupal() { + echo_info "Installing Drupal ${FRAMEWORK_VERSION}..." + if [ ! -f "composer.json" ]; then + composer create-project drupal-composer/drupal-project . "${FRAMEWORK_VERSION}" + fi +} + +setup_magento() { + echo_info "Installing Magento ${FRAMEWORK_VERSION}..." + echo_warn "Magento requires additional setup (database, elasticsearch, etc.)" + echo_warn "This is a basic installation only" + if [ ! -f "composer.json" ]; then + composer create-project --repository-url=https://repo.magento.com/ magento/project-community-edition . "${FRAMEWORK_VERSION}" + fi +} + +# Configure Elastic APM for the framework +configure_apm() { + echo_info "Configuring Elastic APM PHP Agent..." + + # Add elastic-apm-php to composer dependencies if not already present + if [ -f "composer.json" ]; then + if ! grep -q "elastic/apm-agent" composer.json; then + echo_info "Adding Elastic APM PHP Agent to composer.json..." + composer config repositories.local path "${PROJECT_ROOT}" + composer require elastic/apm-agent:@dev + fi + fi + + # Create a basic php.ini configuration for the agent + cat > php-apm.ini <