Back to Repositories

Testing Environment Configuration Management in Kamal

This test suite validates environment configuration handling in Kamal, focusing on clear and secret environment variables management. It ensures proper handling of configuration parameters and secrets processing for deployment environments.

Test Coverage Overview

The test suite provides comprehensive coverage of environment configuration scenarios in Kamal:

  • Simple environment variable configuration
  • Clear environment variables handling
  • Secret environment variables processing
  • Combined secret and clear variable scenarios
  • Error handling for missing secrets

Implementation Analysis

The testing approach utilizes ActiveSupport::TestCase framework with custom assertion helpers for configuration validation. The implementation follows a structured pattern testing both positive and negative scenarios, with particular attention to secrets handling and environment variable formatting.

Technical Details

  • Framework: Minitest with ActiveSupport
  • Custom assertion helper: assert_config
  • Test environment setup using with_test_secrets
  • Configuration validation through Kamal::Configuration::Env class
  • Error handling verification for Kamal::ConfigurationError

Best Practices Demonstrated

The test suite exemplifies several testing best practices:

  • Isolated test cases with clear separation of concerns
  • Custom assertion methods for improved readability
  • Comprehensive error case coverage
  • Proper setup and teardown of test environment
  • Clear and maintainable test structure

basecamp/kamal

test/configuration/env_test.rb

            
require "test_helper"

class ConfigurationEnvTest < ActiveSupport::TestCase
  require "test_helper"

  test "simple" do
    assert_config \
      config: { "foo" => "bar", "baz" => "haz" },
      clear: { "foo" => "bar", "baz" => "haz" }
  end

  test "clear" do
    assert_config \
      config: { "clear" => { "foo" => "bar", "baz" => "haz" } },
      clear: { "foo" => "bar", "baz" => "haz" }
  end

  test "secret" do
    with_test_secrets("secrets" => "PASSWORD=hello") do
      assert_config \
        config: { "secret" => [ "PASSWORD" ] },
        secrets: { "PASSWORD" => "hello" }
    end
  end

  test "missing secret" do
    env = {
      "secret" => [ "PASSWORD" ]
    }

    assert_raises(Kamal::ConfigurationError) { Kamal::Configuration::Env.new(config: { "secret" => [ "PASSWORD" ] }, secrets: Kamal::Secrets.new).secrets_io }
  end

  test "secret and clear" do
    with_test_secrets("secrets" => "PASSWORD=hello") do
      config = {
        "secret" => [ "PASSWORD" ],
        "clear" => {
          "foo" => "bar",
          "baz" => "haz"
        }
      }

      assert_config \
        config: config,
        clear: { "foo" => "bar", "baz" => "haz" },
        secrets: { "PASSWORD" => "hello" }
    end
  end

  private
    def assert_config(config:, clear: {}, secrets: {})
      env = Kamal::Configuration::Env.new config: config, secrets: Kamal::Secrets.new
      expected_clear_args = clear.to_a.flat_map { |key, value| [ "--env", "#{key}=\"#{value}\"" ] }
      assert_equal expected_clear_args, env.clear_args.map(&:to_s) #  to_s removes the redactions
      expected_secrets = secrets.to_a.flat_map { |key, value| "#{key}=#{value}" }.join("\n") + "\n"
      assert_equal expected_secrets, env.secrets_io.string
    end
end