Back to Repositories

Testing Proxy Lifecycle Management Operations in Kamal

This integration test suite validates the proxy management functionality in Kamal, focusing on lifecycle operations like boot, reboot, stop, start, and logging. The tests ensure reliable proxy container orchestration across multiple virtual machines.

Test Coverage Overview

The test suite provides comprehensive coverage of proxy lifecycle management operations in Kamal.

Key areas tested include:
  • Container lifecycle operations (boot, stop, start, restart)
  • Rolling and simultaneous reboot scenarios
  • Proxy state verification
  • Log retrieval functionality
  • Pre and post reboot hook execution

Implementation Analysis

The test implementation uses Minitest’s integration testing framework with a focused setup for proxy-specific operations. The approach employs assertion helpers to verify proxy states and hook executions, while capturing command outputs for detailed verification.

Notable patterns include:
  • Command output capture and pattern matching
  • State verification through custom assertions
  • Hook execution validation
  • Multi-VM deployment testing

Technical Details

Testing tools and configuration:
  • Framework: Minitest
  • Test Environment: Integration test setup with virtual machines (vm1, vm2)
  • Custom Assertions: assert_proxy_running, assert_proxy_not_running
  • Command Execution: kamal helper method for proxy operations
  • Output Validation: Regex pattern matching for command outputs

Best Practices Demonstrated

The test suite exemplifies several testing best practices in infrastructure automation verification.

Notable practices include:
  • Comprehensive lifecycle testing
  • Isolation of test environment
  • Explicit state verification
  • Verbose output validation
  • Hook execution verification
  • Rolling deployment testing

basecamp/kamal

test/integration/proxy_test.rb

            
require_relative "integration_test"

class ProxyTest < IntegrationTest
  setup do
    @app = "app_with_roles"
  end

  test "boot, reboot, stop, start, restart, logs, remove" do
    kamal :proxy, :boot
    assert_proxy_running

    output = kamal :proxy, :reboot, "-y", "--verbose", capture: true
    assert_proxy_running
    assert_hooks_ran "pre-proxy-reboot", "post-proxy-reboot"
    assert_match /Rebooting kamal-proxy on vm1,vm2.../, output
    assert_match /Rebooted kamal-proxy on vm1,vm2/, output

    output = kamal :proxy, :reboot, "--rolling", "-y", "--verbose", capture: true
    assert_proxy_running
    assert_hooks_ran "pre-proxy-reboot", "post-proxy-reboot"
    assert_match /Rebooting kamal-proxy on vm1.../, output
    assert_match /Rebooted kamal-proxy on vm1/, output
    assert_match /Rebooting kamal-proxy on vm2.../, output
    assert_match /Rebooted kamal-proxy on vm2/, output

    kamal :proxy, :boot
    assert_proxy_running

    # Check booting when booted doesn't raise an error
    kamal :proxy, :stop
    assert_proxy_not_running

    # Check booting when stopped works
    kamal :proxy, :boot
    assert_proxy_running

    kamal :proxy, :stop
    assert_proxy_not_running

    kamal :proxy, :start
    assert_proxy_running

    kamal :proxy, :restart
    assert_proxy_running

    logs = kamal :proxy, :logs, capture: true
    assert_match /No previous state to restore/, logs

    kamal :proxy, :remove
    assert_proxy_not_running
  end
end