├── examples ├── tmp │ └── .gitkeep ├── fixtures │ └── web_page │ │ └── styles.css ├── memcached_rspec.rb ├── redis_container_rspec.rb ├── redis_backed_cache_rspec.rb ├── redis_backed_cache_minitest.rb ├── mysql_ar_rspec.rb ├── redpanda_rspec.rb └── wkhtmltopdf_rspec.rb ├── rabbitmq ├── CHANGELOG.md ├── lib │ └── testcontainers │ │ └── rabbitmq │ │ └── version.rb ├── Gemfile ├── test │ ├── test_helper.rb │ └── rabbitmq_container_test.rb ├── Rakefile ├── LICENSE.txt ├── testcontainers-rabbitmq.gemspec └── Gemfile.lock ├── compose ├── test │ ├── .env.test │ ├── docker-compose2.yml │ ├── docker-compose3.yml │ ├── test_helper.rb │ └── docker-compose.yml ├── CHANGELOG.md ├── lib │ └── testcontainers │ │ └── compose │ │ └── version.rb ├── Gemfile ├── Rakefile ├── LICENSE.txt ├── testcontainers-compose.gemspec └── Gemfile.lock ├── core ├── lib │ ├── testcontainers-core.rb │ ├── testcontainers │ │ ├── version.rb │ │ └── docker_client.rb │ └── testcontainers.rb ├── Gemfile ├── test │ ├── test_helper.rb │ ├── testcontainers_test.rb │ └── docker_client_test.rb ├── Rakefile ├── LICENSE.txt ├── testcontainers-core.gemspec ├── CHANGELOG.md ├── Gemfile.lock └── README.md ├── module-gen ├── templates │ ├── CHANGELOG.md.tt │ ├── lib │ │ ├── module │ │ │ └── version.rb.tt │ │ └── module.rb.tt │ ├── test │ │ ├── test_helper.rb.tt │ │ └── module_test.rb.tt │ ├── Gemfile.tt │ ├── Rakefile.tt │ ├── LICENSE.txt.tt │ ├── README.md.tt │ └── module.gemspec.tt ├── Gemfile ├── Gemfile.lock └── module_generator.thor ├── mongo ├── CHANGELOG.md ├── lib │ └── testcontainers │ │ └── mongo │ │ └── version.rb ├── test │ ├── test_helper.rb │ └── mongo_container_test.rb ├── Gemfile ├── Rakefile ├── LICENSE.txt ├── testcontainers-mongo.gemspec └── Gemfile.lock ├── nginx ├── CHANGELOG.md ├── lib │ └── testcontainers │ │ ├── nginx │ │ └── version.rb │ │ └── nginx.rb ├── test │ ├── test_helper.rb │ └── nginx_container_test.rb ├── Gemfile ├── Rakefile ├── LICENSE.txt ├── testcontainers-nginx.gemspec ├── Gemfile.lock └── README.md ├── selenium ├── CHANGELOG.md ├── lib │ └── testcontainers │ │ ├── selenium │ │ └── version.rb │ │ └── selenium.rb ├── test │ ├── test_helper.rb │ └── selenium_container_test.rb ├── Gemfile ├── Rakefile ├── LICENSE.txt ├── testcontainers-selenium.gemspec ├── Gemfile.lock └── README.md ├── elasticsearch ├── CHANGELOG.md ├── lib │ └── testcontainers │ │ └── elasticsearch │ │ └── version.rb ├── test │ ├── test_helper.rb │ └── elasticsearch_container_test.rb ├── Gemfile ├── Rakefile ├── LICENSE.txt ├── testcontainers-elasticsearch.gemspec └── Gemfile.lock ├── .standard.yml ├── .yardopts ├── bin ├── setup └── console ├── kafka ├── lib │ └── testcontainers │ │ └── kafka │ │ └── version.rb ├── CHANGELOG.md ├── test │ ├── test_helper.rb │ └── kafka_container_test.rb ├── Gemfile ├── Rakefile ├── LICENSE.txt ├── README.md ├── testcontainers-kafka.gemspec └── Gemfile.lock ├── mysql ├── lib │ └── testcontainers │ │ └── mysql │ │ └── version.rb ├── test │ ├── test_helper.rb │ └── mysql_container_test.rb ├── Gemfile ├── CHANGELOG.md ├── Rakefile ├── LICENSE.txt ├── testcontainers-mysql.gemspec └── Gemfile.lock ├── redis ├── lib │ └── testcontainers │ │ ├── redis │ │ └── version.rb │ │ └── redis.rb ├── test │ ├── test_helper.rb │ └── redis_container_test.rb ├── Gemfile ├── CHANGELOG.md ├── Rakefile ├── LICENSE.txt ├── testcontainers-redis.gemspec └── Gemfile.lock ├── mariadb ├── lib │ └── testcontainers │ │ └── mariadb │ │ └── version.rb ├── CHANGELOG.md ├── test │ ├── test_helper.rb │ └── mariadb_container_test.rb ├── Gemfile ├── Rakefile ├── LICENSE.txt ├── testcontainers-mariadb.gemspec └── Gemfile.lock ├── postgres ├── lib │ └── testcontainers │ │ └── postgres │ │ └── version.rb ├── test │ └── test_helper.rb ├── Gemfile ├── CHANGELOG.md ├── Rakefile ├── LICENSE.txt ├── testcontainers-postgres.gemspec └── Gemfile.lock ├── redpanda ├── lib │ └── testcontainers │ │ ├── redpanda │ │ └── version.rb │ │ └── redpanda.rb ├── CHANGELOG.md ├── test │ ├── test_helper.rb │ └── redpanda_container_test.rb ├── Gemfile ├── Rakefile ├── LICENSE.txt ├── testcontainers-redpanda.gemspec └── Gemfile.lock ├── opensearch ├── lib │ └── testcontainers │ │ ├── opensearch │ │ └── version.rb │ │ └── opensearch.rb ├── CHANGELOG.md ├── test │ ├── test_helper.rb │ └── opensearch_container_test.rb ├── Gemfile ├── Rakefile ├── LICENSE.txt ├── README.md ├── testcontainers-opensearch.gemspec └── Gemfile.lock ├── .gitignore ├── .devcontainer └── devcontainer.json ├── .github └── workflows │ ├── main.yml │ ├── examples-redis_rspec.yml │ ├── examples-redpanda_rspec.yml │ ├── examples-wkhtmltopdf_rspec.yml │ ├── examples-memcached.yml │ ├── examples-core_rspec.yml │ ├── examples-mysql_rspec.yml │ ├── examples-core_minitest.yml │ ├── module-core.yml │ ├── module-mysql.yml │ ├── module-nginx.yml │ ├── module-redis.yml │ ├── module-mongo.yml │ ├── module-compose.yml │ ├── module-mariadb.yml │ ├── module-postgres.yml │ ├── module-rabbitmq.yml │ ├── module-redpanda.yml │ ├── module-selenium.yml │ └── module-elasticsearch.yml ├── Rakefile ├── Gemfile ├── LICENSE.txt ├── testcontainers.gemspec ├── .vscode └── .testcontainers-ruby.code-workspace └── CHANGELOG.md /examples/tmp/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /rabbitmq/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [Unreleased] 2 | 3 | ### Added 4 | -------------------------------------------------------------------------------- /compose/test/.env.test: -------------------------------------------------------------------------------- 1 | TAG_TEST_ASSERT_KEY="successful test" 2 | -------------------------------------------------------------------------------- /core/lib/testcontainers-core.rb: -------------------------------------------------------------------------------- 1 | require_relative "testcontainers" 2 | -------------------------------------------------------------------------------- /module-gen/templates/CHANGELOG.md.tt: -------------------------------------------------------------------------------- 1 | ## [Unreleased] 2 | 3 | ### Added 4 | -------------------------------------------------------------------------------- /module-gen/Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gem "thor", "~> 1.2" 4 | -------------------------------------------------------------------------------- /compose/test/docker-compose2.yml: -------------------------------------------------------------------------------- 1 | services: 2 | hello-world: 3 | image: "hello-world" 4 | -------------------------------------------------------------------------------- /mongo/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [0.1.0] - 2023-06-10 2 | 3 | ### Added 4 | 5 | - Initial release of the Mongo module 6 | -------------------------------------------------------------------------------- /nginx/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [0.1.0] - 2023-06-10 2 | 3 | ### Added 4 | 5 | - Initial release of the nginx module 6 | -------------------------------------------------------------------------------- /selenium/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [0.2.0] - 2024-02-08 2 | 3 | ### Added 4 | 5 | - Initial release of the Selenium module 6 | -------------------------------------------------------------------------------- /compose/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [0.2.0] - 2024-02-08 2 | 3 | ### Added 4 | 5 | - Initial release of the Docker Compose module 6 | -------------------------------------------------------------------------------- /elasticsearch/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [0.1.0] - 2023-05-13 2 | 3 | ### Added 4 | 5 | - Initial release of the ElasticSearch module 6 | -------------------------------------------------------------------------------- /.standard.yml: -------------------------------------------------------------------------------- 1 | # For available configuration options, see: 2 | # https://github.com/testdouble/standard 3 | ruby_version: 2.6 4 | -------------------------------------------------------------------------------- /.yardopts: -------------------------------------------------------------------------------- 1 | --readme README.md 2 | --title 'Testcontainers for Ruby' 3 | --charset utf-8 4 | --markup markdown 5 | core/lib/**/*.rb 6 | -------------------------------------------------------------------------------- /core/lib/testcontainers/version.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Testcontainers 4 | VERSION = "0.2.0" 5 | end 6 | -------------------------------------------------------------------------------- /core/Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source "https://rubygems.org" 4 | 5 | # Specify your gem's dependencies in testcontainers.gemspec 6 | gemspec 7 | -------------------------------------------------------------------------------- /bin/setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | IFS=$'\n\t' 4 | set -vx 5 | 6 | bundle install 7 | 8 | # Do any other automated setup that you need to do here 9 | -------------------------------------------------------------------------------- /kafka/lib/testcontainers/kafka/version.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Testcontainers 4 | module Kafka 5 | VERSION = "0.1.0" 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /mongo/lib/testcontainers/mongo/version.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Testcontainers 4 | module Mongo 5 | VERSION = "0.2.0" 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /mysql/lib/testcontainers/mysql/version.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Testcontainers 4 | module Mysql 5 | VERSION = "0.2.0" 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /nginx/lib/testcontainers/nginx/version.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Testcontainers 4 | module Nginx 5 | VERSION = "0.2.0" 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /redis/lib/testcontainers/redis/version.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Testcontainers 4 | module Redis 5 | VERSION = "0.2.0" 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /compose/lib/testcontainers/compose/version.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Testcontainers 4 | module Compose 5 | VERSION = "0.2.0" 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /mariadb/lib/testcontainers/mariadb/version.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Testcontainers 4 | module Mariadb 5 | VERSION = "0.2.0" 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /postgres/lib/testcontainers/postgres/version.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Testcontainers 4 | module Postgres 5 | VERSION = "0.2.0" 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /rabbitmq/lib/testcontainers/rabbitmq/version.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Testcontainers 4 | module Rabbitmq 5 | VERSION = "0.2.0" 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /redpanda/lib/testcontainers/redpanda/version.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Testcontainers 4 | module Redpanda 5 | VERSION = "0.2.0" 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /selenium/lib/testcontainers/selenium/version.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Testcontainers 4 | module Selenium 5 | VERSION = "0.2.0" 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /opensearch/lib/testcontainers/opensearch/version.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Testcontainers 4 | module Opensearch 5 | VERSION = "0.1.0" 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /elasticsearch/lib/testcontainers/elasticsearch/version.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Testcontainers 4 | module Elasticsearch 5 | VERSION = "0.2.0" 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /kafka/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [Unreleased] 2 | 3 | ### Added 4 | 5 | - Initial release of `testcontainers-kafka` providing a single-broker KRaft 6 | Kafka container and convenience helpers. 7 | -------------------------------------------------------------------------------- /module-gen/templates/lib/module/version.rb.tt: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Testcontainers 4 | module <%= name.capitalize %> 5 | VERSION = "0.1.0" 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.bundle/ 2 | /.yardoc 3 | /_yardoc/ 4 | /coverage/ 5 | /doc/ 6 | /pkg/ 7 | /spec/reports/ 8 | /tmp/ 9 | /examples/tmp/*.pdf 10 | *.gem 11 | .DS_Store 12 | .tool-versions 13 | -------------------------------------------------------------------------------- /opensearch/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [Unreleased] 2 | 3 | ### Added 4 | 5 | - Initial release of `testcontainers-opensearch` with an `OpensearchContainer` 6 | configured for single-node development usage. 7 | -------------------------------------------------------------------------------- /compose/test/docker-compose3.yml: -------------------------------------------------------------------------------- 1 | services: 2 | alpine: 3 | image: alpine 4 | command: sleep 3600 5 | ports: 6 | - "3306:3306" 7 | environment: 8 | TEST_ASSERT_KEY: ${TAG_TEST_ASSERT_KEY} 9 | -------------------------------------------------------------------------------- /module-gen/templates/lib/module.rb.tt: -------------------------------------------------------------------------------- 1 | require_relative "<%= name %>/version" 2 | require "testcontainers" 3 | 4 | module Testcontainers 5 | class <%= name.capitalize %>Container < ::Testcontainers::DockerContainer 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /mariadb/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [0.1.1] - 2023-06-13 2 | 3 | ### Fixed 4 | 5 | - Use healthcheck script shipped with the Docker image 6 | 7 | ## [0.1.0] - 2023-06-10 8 | 9 | ### Added 10 | 11 | - Initial release of the MariaDB module 12 | -------------------------------------------------------------------------------- /redpanda/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [0.2.0] - 2024-02-08 2 | 3 | ### Fixed 4 | 5 | - Fixed startup script for the Redpanda module 6 | 7 | 8 | ## [0.1.0] - 2023-06-10 9 | 10 | ### Added 11 | 12 | - Initial release of the Redpanda module 13 | -------------------------------------------------------------------------------- /module-gen/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | thor (1.2.2) 5 | 6 | PLATFORMS 7 | arm64-darwin-21 8 | arm64-darwin-23 9 | 10 | DEPENDENCIES 11 | thor (~> 1.2) 12 | 13 | BUNDLED WITH 14 | 2.4.1 15 | -------------------------------------------------------------------------------- /examples/fixtures/web_page/styles.css: -------------------------------------------------------------------------------- 1 | /* Custom page CSS 2 | -------------------------------------------------- */ 3 | /* Not required for template or sticky footer method. */ 4 | 5 | .container { 6 | width: auto; 7 | max-width: 680px; 8 | padding: 0 15px; 9 | } 10 | -------------------------------------------------------------------------------- /kafka/test/test_helper.rb: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift File.expand_path("../lib", __dir__) 2 | require "testcontainers/kafka" 3 | 4 | require "minitest/autorun" 5 | require "minitest/hooks/test" 6 | 7 | class TestcontainersTest < Minitest::Test 8 | include Minitest::Hooks 9 | end 10 | -------------------------------------------------------------------------------- /mongo/test/test_helper.rb: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift File.expand_path("../lib", __dir__) 2 | require "testcontainers/mongo" 3 | 4 | require "minitest/autorun" 5 | require "minitest/hooks/test" 6 | 7 | class TestcontainersTest < Minitest::Test 8 | include Minitest::Hooks 9 | end 10 | -------------------------------------------------------------------------------- /mysql/test/test_helper.rb: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift File.expand_path("../lib", __dir__) 2 | require "testcontainers/mysql" 3 | 4 | require "minitest/autorun" 5 | require "minitest/hooks/test" 6 | 7 | class TestcontainersTest < Minitest::Test 8 | include Minitest::Hooks 9 | end 10 | -------------------------------------------------------------------------------- /nginx/test/test_helper.rb: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift File.expand_path("../lib", __dir__) 2 | require "testcontainers/nginx" 3 | 4 | require "minitest/autorun" 5 | require "minitest/hooks/test" 6 | 7 | class TestcontainersTest < Minitest::Test 8 | include Minitest::Hooks 9 | end 10 | -------------------------------------------------------------------------------- /redis/test/test_helper.rb: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift File.expand_path("../lib", __dir__) 2 | require "testcontainers/redis" 3 | 4 | require "minitest/autorun" 5 | require "minitest/hooks/test" 6 | 7 | class TestcontainersTest < Minitest::Test 8 | include Minitest::Hooks 9 | end 10 | -------------------------------------------------------------------------------- /compose/test/test_helper.rb: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift File.expand_path("../lib", __dir__) 2 | require "testcontainers/compose" 3 | 4 | require "minitest/autorun" 5 | require "minitest/hooks/test" 6 | 7 | class TestcontainersTest < Minitest::Test 8 | include Minitest::Hooks 9 | end 10 | -------------------------------------------------------------------------------- /mariadb/test/test_helper.rb: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift File.expand_path("../lib", __dir__) 2 | require "testcontainers/mariadb" 3 | 4 | require "minitest/autorun" 5 | require "minitest/hooks/test" 6 | 7 | class TestcontainersTest < Minitest::Test 8 | include Minitest::Hooks 9 | end 10 | -------------------------------------------------------------------------------- /opensearch/test/test_helper.rb: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift File.expand_path("../lib", __dir__) 2 | require "testcontainers/opensearch" 3 | 4 | require "minitest/autorun" 5 | require "minitest/hooks/test" 6 | 7 | class TestcontainersTest < Minitest::Test 8 | include Minitest::Hooks 9 | end 10 | -------------------------------------------------------------------------------- /postgres/test/test_helper.rb: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift File.expand_path("../lib", __dir__) 2 | require "testcontainers/postgres" 3 | 4 | require "minitest/autorun" 5 | require "minitest/hooks/test" 6 | 7 | class TestcontainersTest < Minitest::Test 8 | include Minitest::Hooks 9 | end 10 | -------------------------------------------------------------------------------- /redpanda/test/test_helper.rb: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift File.expand_path("../lib", __dir__) 2 | require "testcontainers/redpanda" 3 | 4 | require "minitest/autorun" 5 | require "minitest/hooks/test" 6 | 7 | class TestcontainersTest < Minitest::Test 8 | include Minitest::Hooks 9 | end 10 | -------------------------------------------------------------------------------- /selenium/test/test_helper.rb: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift File.expand_path("../lib", __dir__) 2 | require "testcontainers/selenium" 3 | 4 | require "minitest/autorun" 5 | require "minitest/hooks/test" 6 | 7 | class TestcontainersTest < Minitest::Test 8 | include Minitest::Hooks 9 | end 10 | -------------------------------------------------------------------------------- /elasticsearch/test/test_helper.rb: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift File.expand_path("../lib", __dir__) 2 | require "testcontainers/elasticsearch" 3 | 4 | require "minitest/autorun" 5 | require "minitest/hooks/test" 6 | 7 | class TestcontainersTest < Minitest::Test 8 | include Minitest::Hooks 9 | end 10 | -------------------------------------------------------------------------------- /kafka/Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source "https://rubygems.org" 4 | 5 | # Specify your gem's dependencies in testcontainers-kafka.gemspec 6 | gemspec 7 | 8 | # Use the latest version of testcontainers-core from the local path 9 | gem "testcontainers-core", path: "../core" 10 | -------------------------------------------------------------------------------- /mongo/Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source "https://rubygems.org" 4 | 5 | # Specify your gem's dependencies in testcontainers-mongo.gemspec 6 | gemspec 7 | 8 | # Use the latest version of testcontainers-core from the local path 9 | gem "testcontainers-core", path: "../core" 10 | -------------------------------------------------------------------------------- /mysql/Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source "https://rubygems.org" 4 | 5 | # Specify your gem's dependencies in testcontainers-mysql.gemspec 6 | gemspec 7 | 8 | # Use the latest version of testcontainers-core from the local path 9 | gem "testcontainers-core", path: "../core" 10 | -------------------------------------------------------------------------------- /nginx/Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source "https://rubygems.org" 4 | 5 | # Specify your gem's dependencies in testcontainers-nginx.gemspec 6 | gemspec 7 | 8 | # Use the latest version of testcontainers-core from the local path 9 | gem "testcontainers-core", path: "../core" 10 | -------------------------------------------------------------------------------- /redis/Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source "https://rubygems.org" 4 | 5 | # Specify your gem's dependencies in testcontainers-redis.gemspec 6 | gemspec 7 | 8 | # Use the latest version of testcontainers-core from the local path 9 | gem "testcontainers-core", path: "../core" 10 | -------------------------------------------------------------------------------- /compose/Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source "https://rubygems.org" 4 | 5 | # Specify your gem's dependencies in testcontainers-compose.gemspec 6 | gemspec 7 | 8 | # Use the latest version of testcontainers-core from the local path 9 | gem "testcontainers-core", path: "../core" 10 | -------------------------------------------------------------------------------- /mariadb/Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source "https://rubygems.org" 4 | 5 | # Specify your gem's dependencies in testcontainers-mariadb.gemspec 6 | gemspec 7 | 8 | # Use the latest version of testcontainers-core from the local path 9 | gem "testcontainers-core", path: "../core" 10 | -------------------------------------------------------------------------------- /module-gen/templates/test/test_helper.rb.tt: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift File.expand_path("../lib", __dir__) 2 | require "testcontainers/<%= name %>" 3 | 4 | require "minitest/autorun" 5 | require "minitest/hooks/test" 6 | 7 | class TestcontainersTest < Minitest::Test 8 | include Minitest::Hooks 9 | end 10 | -------------------------------------------------------------------------------- /postgres/Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source "https://rubygems.org" 4 | 5 | # Specify your gem's dependencies in testcontainers-postgres.gemspec 6 | gemspec 7 | 8 | # Use the latest version of testcontainers-core from the local path 9 | gem "testcontainers-core", path: "../core" 10 | -------------------------------------------------------------------------------- /rabbitmq/Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source "https://rubygems.org" 4 | 5 | # Specify your gem's dependencies in testcontainers-rabbitmq.gemspec 6 | gemspec 7 | 8 | # Use the latest version of testcontainers-core from the local path 9 | gem "testcontainers-core", path: "../core" 10 | -------------------------------------------------------------------------------- /redpanda/Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source "https://rubygems.org" 4 | 5 | # Specify your gem's dependencies in testcontainers-redpanda.gemspec 6 | gemspec 7 | 8 | # Use the latest version of testcontainers-core from the local path 9 | gem "testcontainers-core", path: "../core" 10 | -------------------------------------------------------------------------------- /selenium/Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source "https://rubygems.org" 4 | 5 | # Specify your gem's dependencies in testcontainers-selenium.gemspec 6 | gemspec 7 | 8 | # Use the latest version of testcontainers-core from the local path 9 | gem "testcontainers-core", path: "../core" 10 | -------------------------------------------------------------------------------- /opensearch/Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source "https://rubygems.org" 4 | 5 | # Specify your gem's dependencies in testcontainers-opensearch.gemspec 6 | gemspec 7 | 8 | # Use the latest version of testcontainers-core from the local path 9 | gem "testcontainers-core", path: "../core" 10 | -------------------------------------------------------------------------------- /rabbitmq/test/test_helper.rb: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift File.expand_path("../lib", __dir__) 2 | require "testcontainers/rabbitmq" 3 | 4 | require "minitest/autorun" 5 | require "minitest/hooks/test" 6 | require "bunny" 7 | 8 | class TestcontainersTest < Minitest::Test 9 | include Minitest::Hooks 10 | end 11 | -------------------------------------------------------------------------------- /core/test/test_helper.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | $LOAD_PATH.unshift File.expand_path("../lib", __dir__) 4 | require "testcontainers" 5 | 6 | require "minitest/autorun" 7 | require "minitest/hooks/test" 8 | 9 | class TestcontainersTest < Minitest::Test 10 | include Minitest::Hooks 11 | end 12 | -------------------------------------------------------------------------------- /elasticsearch/Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source "https://rubygems.org" 4 | 5 | # Specify your gem's dependencies in testcontainers-elasticsearch.gemspec 6 | gemspec 7 | 8 | # Use the latest version of testcontainers-core from the local path 9 | gem "testcontainers-core", path: "../core" 10 | -------------------------------------------------------------------------------- /module-gen/templates/Gemfile.tt: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source "https://rubygems.org" 4 | 5 | # Specify your gem's dependencies in testcontainers-<%= name %>.gemspec 6 | gemspec 7 | 8 | # Use the latest version of testcontainers-core from the local path 9 | gem "testcontainers-core", path: "../core" 10 | -------------------------------------------------------------------------------- /mysql/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [0.1.1] - 2023-06-10 2 | 3 | ### Added 4 | 5 | - Add healthcheck support on start 6 | 7 | ### Fixed 8 | 9 | - Remove support for custom ports, it is not supported by underlying 10 | images. 11 | 12 | ## [0.1.0] - 2023-05-13 13 | 14 | ### Added 15 | 16 | - Initial release of the MySQL module 17 | -------------------------------------------------------------------------------- /postgres/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [0.1.1] - 2023-6-10 2 | 3 | ### Added 4 | 5 | - Add healthcheck support on start 6 | 7 | ### Fixed 8 | 9 | - Remove support for custom ports, it is not supported by underlying 10 | images. 11 | 12 | ## [0.1.0] - 2023-05-13 13 | 14 | ### Added 15 | 16 | - Initial release of the Postgres module 17 | -------------------------------------------------------------------------------- /core/Rakefile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "bundler/gem_tasks" 4 | require "rake/testtask" 5 | 6 | Rake::TestTask.new(:test) do |t| 7 | t.libs << "test" 8 | t.libs << "lib" 9 | t.test_files = FileList["test/**/*_test.rb"] 10 | end 11 | 12 | require "standard/rake" 13 | 14 | task default: %i[test standard] 15 | -------------------------------------------------------------------------------- /kafka/Rakefile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "bundler/gem_tasks" 4 | require "rake/testtask" 5 | 6 | Rake::TestTask.new(:test) do |t| 7 | t.libs << "test" 8 | t.libs << "lib" 9 | t.test_files = FileList["test/**/*_test.rb"] 10 | end 11 | 12 | require "standard/rake" 13 | 14 | task default: %i[test standard] 15 | -------------------------------------------------------------------------------- /mongo/Rakefile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "bundler/gem_tasks" 4 | require "rake/testtask" 5 | 6 | Rake::TestTask.new(:test) do |t| 7 | t.libs << "test" 8 | t.libs << "lib" 9 | t.test_files = FileList["test/**/*_test.rb"] 10 | end 11 | 12 | require "standard/rake" 13 | 14 | task default: %i[test standard] 15 | -------------------------------------------------------------------------------- /mysql/Rakefile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "bundler/gem_tasks" 4 | require "rake/testtask" 5 | 6 | Rake::TestTask.new(:test) do |t| 7 | t.libs << "test" 8 | t.libs << "lib" 9 | t.test_files = FileList["test/**/*_test.rb"] 10 | end 11 | 12 | require "standard/rake" 13 | 14 | task default: %i[test standard] 15 | -------------------------------------------------------------------------------- /nginx/Rakefile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "bundler/gem_tasks" 4 | require "rake/testtask" 5 | 6 | Rake::TestTask.new(:test) do |t| 7 | t.libs << "test" 8 | t.libs << "lib" 9 | t.test_files = FileList["test/**/*_test.rb"] 10 | end 11 | 12 | require "standard/rake" 13 | 14 | task default: %i[test standard] 15 | -------------------------------------------------------------------------------- /redis/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [0.1.1] - 2023-6-10 2 | 3 | ### Added 4 | 5 | - Add healthcheck support on start 6 | 7 | ### Fixed 8 | 9 | - Remove support for custom password and port, those aren't supported by 10 | Redis images 11 | 12 | ## [0.1.0] - 2023-05-13 13 | 14 | ### Added 15 | 16 | - Initial release of the Redis module 17 | -------------------------------------------------------------------------------- /redis/Rakefile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "bundler/gem_tasks" 4 | require "rake/testtask" 5 | 6 | Rake::TestTask.new(:test) do |t| 7 | t.libs << "test" 8 | t.libs << "lib" 9 | t.test_files = FileList["test/**/*_test.rb"] 10 | end 11 | 12 | require "standard/rake" 13 | 14 | task default: %i[test standard] 15 | -------------------------------------------------------------------------------- /compose/Rakefile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "bundler/gem_tasks" 4 | require "rake/testtask" 5 | 6 | Rake::TestTask.new(:test) do |t| 7 | t.libs << "test" 8 | t.libs << "lib" 9 | t.test_files = FileList["test/**/*_test.rb"] 10 | end 11 | 12 | require "standard/rake" 13 | 14 | task default: %i[test standard] 15 | -------------------------------------------------------------------------------- /mariadb/Rakefile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "bundler/gem_tasks" 4 | require "rake/testtask" 5 | 6 | Rake::TestTask.new(:test) do |t| 7 | t.libs << "test" 8 | t.libs << "lib" 9 | t.test_files = FileList["test/**/*_test.rb"] 10 | end 11 | 12 | require "standard/rake" 13 | 14 | task default: %i[test standard] 15 | -------------------------------------------------------------------------------- /opensearch/Rakefile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "bundler/gem_tasks" 4 | require "rake/testtask" 5 | 6 | Rake::TestTask.new(:test) do |t| 7 | t.libs << "test" 8 | t.libs << "lib" 9 | t.test_files = FileList["test/**/*_test.rb"] 10 | end 11 | 12 | require "standard/rake" 13 | 14 | task default: %i[test standard] 15 | -------------------------------------------------------------------------------- /postgres/Rakefile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "bundler/gem_tasks" 4 | require "rake/testtask" 5 | 6 | Rake::TestTask.new(:test) do |t| 7 | t.libs << "test" 8 | t.libs << "lib" 9 | t.test_files = FileList["test/**/*_test.rb"] 10 | end 11 | 12 | require "standard/rake" 13 | 14 | task default: %i[test standard] 15 | -------------------------------------------------------------------------------- /rabbitmq/Rakefile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "bundler/gem_tasks" 4 | require "rake/testtask" 5 | 6 | Rake::TestTask.new(:test) do |t| 7 | t.libs << "test" 8 | t.libs << "lib" 9 | t.test_files = FileList["test/**/*_test.rb"] 10 | end 11 | 12 | require "standard/rake" 13 | 14 | task default: %i[test standard] 15 | -------------------------------------------------------------------------------- /redpanda/Rakefile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "bundler/gem_tasks" 4 | require "rake/testtask" 5 | 6 | Rake::TestTask.new(:test) do |t| 7 | t.libs << "test" 8 | t.libs << "lib" 9 | t.test_files = FileList["test/**/*_test.rb"] 10 | end 11 | 12 | require "standard/rake" 13 | 14 | task default: %i[test standard] 15 | -------------------------------------------------------------------------------- /selenium/Rakefile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "bundler/gem_tasks" 4 | require "rake/testtask" 5 | 6 | Rake::TestTask.new(:test) do |t| 7 | t.libs << "test" 8 | t.libs << "lib" 9 | t.test_files = FileList["test/**/*_test.rb"] 10 | end 11 | 12 | require "standard/rake" 13 | 14 | task default: %i[test standard] 15 | -------------------------------------------------------------------------------- /elasticsearch/Rakefile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "bundler/gem_tasks" 4 | require "rake/testtask" 5 | 6 | Rake::TestTask.new(:test) do |t| 7 | t.libs << "test" 8 | t.libs << "lib" 9 | t.test_files = FileList["test/**/*_test.rb"] 10 | end 11 | 12 | require "standard/rake" 13 | 14 | task default: %i[test standard] 15 | -------------------------------------------------------------------------------- /module-gen/templates/Rakefile.tt: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "bundler/gem_tasks" 4 | require "rake/testtask" 5 | 6 | Rake::TestTask.new(:test) do |t| 7 | t.libs << "test" 8 | t.libs << "lib" 9 | t.test_files = FileList["test/**/*_test.rb"] 10 | end 11 | 12 | require "standard/rake" 13 | 14 | task default: %i[test standard] 15 | -------------------------------------------------------------------------------- /compose/test/docker-compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | hub: 3 | image: selenium/hub 4 | ports: 5 | - "4444:4444" 6 | firefox: 7 | image: selenium/node-firefox 8 | links: 9 | - hub 10 | expose: 11 | - "5555" 12 | chrome: 13 | image: selenium/node-chrome 14 | links: 15 | - hub 16 | expose: 17 | - "5555" 18 | -------------------------------------------------------------------------------- /bin/console: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | require "bundler/setup" 5 | require "testcontainers" 6 | 7 | # You can add fixtures and/or initialization code here to make experimenting 8 | # with your gem easier. You can also use a different console, if you like. 9 | 10 | # (If you use this, don't forget to add pry to your Gemfile!) 11 | # require "pry" 12 | # Pry.start 13 | 14 | require "irb" 15 | IRB.start(__FILE__) 16 | -------------------------------------------------------------------------------- /core/test/testcontainers_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "test_helper" 4 | 5 | class TestcontainersTest < Minitest::Test 6 | def test_that_it_has_a_version_number 7 | refute_nil ::Testcontainers::VERSION 8 | end 9 | 10 | def test_that_it_sets_user_agent_header 11 | Testcontainers::DockerClient.configure 12 | assert_equal "tc-ruby/#{::Testcontainers::VERSION}", Docker.options[:headers]["User-Agent"] 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "image": "mcr.microsoft.com/devcontainers/ruby:3", 3 | "postStartCommand": "bundle install", 4 | "customizations": { 5 | "vscode": { 6 | "extensions": [ 7 | "Shopify.ruby-lsp" 8 | ] 9 | } 10 | }, 11 | "features": { 12 | "ghcr.io/devcontainers/features/docker-outside-of-docker:1": {}, 13 | "ghcr.io/devcontainers/features/sshd:1": { 14 | "version": "latest" 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /module-gen/templates/test/module_test.rb.tt: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "test_helper" 4 | 5 | class <%= name.capitalize %>ContainerTest < TestcontainersTest 6 | def before_all 7 | super 8 | 9 | @container = Testcontainers::<%= name.capitalize %>Container.new 10 | @container.start 11 | @host = @container.host 12 | @port = @container.first_mapped_port 13 | end 14 | 15 | def after_all 16 | if @container&.exists? 17 | @container&.stop if @container&.running? 18 | @container&.remove 19 | end 20 | 21 | super 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: "Ruby CI: Style Checks with Standard" 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | pull_request: 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | name: Ruby ${{ matrix.ruby }} 14 | strategy: 15 | matrix: 16 | ruby: 17 | - '3.4' 18 | 19 | steps: 20 | - uses: actions/checkout@v3 21 | - name: Set up Ruby 22 | uses: ruby/setup-ruby@v1 23 | with: 24 | ruby-version: ${{ matrix.ruby }} 25 | bundler-cache: true 26 | - name: Run standard code style checks 27 | run: bundle exec rake standard 28 | -------------------------------------------------------------------------------- /.github/workflows/examples-redis_rspec.yml: -------------------------------------------------------------------------------- 1 | name: "Examples: Redis module (RSpec)" 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | pull_request: 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | name: Ruby ${{ matrix.ruby }} 14 | strategy: 15 | matrix: 16 | ruby: 17 | - '3.4' 18 | 19 | steps: 20 | - uses: actions/checkout@v3 21 | - name: Set up Ruby 22 | uses: ruby/setup-ruby@v1 23 | with: 24 | ruby-version: ${{ matrix.ruby }} 25 | bundler-cache: true 26 | - name: Run the example 27 | working-directory: ./examples 28 | run: ruby redis_container_rspec.rb 29 | -------------------------------------------------------------------------------- /.github/workflows/examples-redpanda_rspec.yml: -------------------------------------------------------------------------------- 1 | name: "Examples: Redpanda module (RSpec)" 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | pull_request: 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | name: Ruby ${{ matrix.ruby }} 14 | strategy: 15 | matrix: 16 | ruby: 17 | - '3.4' 18 | 19 | steps: 20 | - uses: actions/checkout@v3 21 | - name: Set up Ruby 22 | uses: ruby/setup-ruby@v1 23 | with: 24 | ruby-version: ${{ matrix.ruby }} 25 | bundler-cache: true 26 | - name: Run the example 27 | working-directory: ./examples 28 | run: ruby redpanda_rspec.rb 29 | -------------------------------------------------------------------------------- /.github/workflows/examples-wkhtmltopdf_rspec.yml: -------------------------------------------------------------------------------- 1 | name: "Examples: wkhtmltopdf module (RSpec)" 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | pull_request: 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | name: Ruby ${{ matrix.ruby }} 14 | strategy: 15 | matrix: 16 | ruby: 17 | - '3.4' 18 | 19 | steps: 20 | - uses: actions/checkout@v3 21 | - name: Set up Ruby 22 | uses: ruby/setup-ruby@v1 23 | with: 24 | ruby-version: ${{ matrix.ruby }} 25 | bundler-cache: true 26 | - name: Run the example 27 | working-directory: ./examples 28 | run: ruby wkhtmltopdf_rspec.rb -------------------------------------------------------------------------------- /.github/workflows/examples-memcached.yml: -------------------------------------------------------------------------------- 1 | name: "Examples: Core module with Memcached (RSpec)" 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | pull_request: 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | name: Ruby ${{ matrix.ruby }} 14 | strategy: 15 | matrix: 16 | ruby: 17 | - '3.4' 18 | 19 | steps: 20 | - uses: actions/checkout@v3 21 | - name: Set up Ruby 22 | uses: ruby/setup-ruby@v1 23 | with: 24 | ruby-version: ${{ matrix.ruby }} 25 | bundler-cache: true 26 | - name: Run the example 27 | working-directory: ./examples 28 | run: ruby memcached_rspec.rb 29 | -------------------------------------------------------------------------------- /.github/workflows/examples-core_rspec.yml: -------------------------------------------------------------------------------- 1 | name: "Examples: Core module with Redis (RSpec)" 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | pull_request: 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | name: Ruby ${{ matrix.ruby }} 14 | strategy: 15 | matrix: 16 | ruby: 17 | - '3.4' 18 | 19 | steps: 20 | - uses: actions/checkout@v3 21 | - name: Set up Ruby 22 | uses: ruby/setup-ruby@v1 23 | with: 24 | ruby-version: ${{ matrix.ruby }} 25 | bundler-cache: true 26 | - name: Run the example 27 | working-directory: ./examples 28 | run: ruby redis_backed_cache_rspec.rb 29 | -------------------------------------------------------------------------------- /.github/workflows/examples-mysql_rspec.yml: -------------------------------------------------------------------------------- 1 | name: "Examples: MySQL module (ActiveRecord + RSpec)" 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | pull_request: 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | name: Ruby ${{ matrix.ruby }} 14 | strategy: 15 | matrix: 16 | ruby: 17 | - '3.4' 18 | 19 | steps: 20 | - uses: actions/checkout@v3 21 | - name: Set up Ruby 22 | uses: ruby/setup-ruby@v1 23 | with: 24 | ruby-version: ${{ matrix.ruby }} 25 | bundler-cache: true 26 | - name: Run the example 27 | working-directory: ./examples 28 | run: ruby mysql_ar_rspec.rb 29 | -------------------------------------------------------------------------------- /.github/workflows/examples-core_minitest.yml: -------------------------------------------------------------------------------- 1 | name: "Examples: Core module with Redis (Minitest)" 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | pull_request: 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | name: Ruby ${{ matrix.ruby }} 14 | strategy: 15 | matrix: 16 | ruby: 17 | - '3.4' 18 | 19 | steps: 20 | - uses: actions/checkout@v3 21 | - name: Set up Ruby 22 | uses: ruby/setup-ruby@v1 23 | with: 24 | ruby-version: ${{ matrix.ruby }} 25 | bundler-cache: true 26 | - name: Run the example 27 | working-directory: ./examples 28 | run: ruby redis_backed_cache_minitest.rb 29 | -------------------------------------------------------------------------------- /.github/workflows/module-core.yml: -------------------------------------------------------------------------------- 1 | name: "Modules: Core tests" 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | pull_request: 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | name: Ruby ${{ matrix.ruby }} 14 | strategy: 15 | matrix: 16 | ruby: 17 | - '3.4' 18 | 19 | steps: 20 | - uses: actions/checkout@v3 21 | - name: Set up Ruby 22 | uses: ruby/setup-ruby@v1 23 | with: 24 | ruby-version: ${{ matrix.ruby }} 25 | bundler-cache: true 26 | - name: Install development dependencies 27 | working-directory: ./core 28 | run: bundle install 29 | - name: Run the tests 30 | working-directory: ./core 31 | run: bundle exec rake test 32 | - name: Run standard code style checks 33 | working-directory: ./core 34 | run: bundle exec rake standard 35 | -------------------------------------------------------------------------------- /.github/workflows/module-mysql.yml: -------------------------------------------------------------------------------- 1 | name: "Modules: MySQL tests" 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | pull_request: 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | name: Ruby ${{ matrix.ruby }} 14 | strategy: 15 | matrix: 16 | ruby: 17 | - '3.4' 18 | 19 | steps: 20 | - uses: actions/checkout@v3 21 | - name: Set up Ruby 22 | uses: ruby/setup-ruby@v1 23 | with: 24 | ruby-version: ${{ matrix.ruby }} 25 | bundler-cache: true 26 | - name: Install development dependencies 27 | working-directory: ./mysql 28 | run: bundle install 29 | - name: Run the tests 30 | working-directory: ./mysql 31 | run: bundle exec rake test 32 | - name: Run standard code style checks 33 | working-directory: ./mysql 34 | run: bundle exec rake standard 35 | -------------------------------------------------------------------------------- /.github/workflows/module-nginx.yml: -------------------------------------------------------------------------------- 1 | name: "Modules: Nginx tests" 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | pull_request: 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | name: Ruby ${{ matrix.ruby }} 14 | strategy: 15 | matrix: 16 | ruby: 17 | - '3.4' 18 | 19 | steps: 20 | - uses: actions/checkout@v3 21 | - name: Set up Ruby 22 | uses: ruby/setup-ruby@v1 23 | with: 24 | ruby-version: ${{ matrix.ruby }} 25 | bundler-cache: true 26 | - name: Install development dependencies 27 | working-directory: ./nginx 28 | run: bundle install 29 | - name: Run the tests 30 | working-directory: ./nginx 31 | run: bundle exec rake test 32 | - name: Run standard code style checks 33 | working-directory: ./nginx 34 | run: bundle exec rake standard 35 | -------------------------------------------------------------------------------- /.github/workflows/module-redis.yml: -------------------------------------------------------------------------------- 1 | name: "Modules: Redis tests" 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | pull_request: 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | name: Ruby ${{ matrix.ruby }} 14 | strategy: 15 | matrix: 16 | ruby: 17 | - '3.4' 18 | 19 | steps: 20 | - uses: actions/checkout@v3 21 | - name: Set up Ruby 22 | uses: ruby/setup-ruby@v1 23 | with: 24 | ruby-version: ${{ matrix.ruby }} 25 | bundler-cache: true 26 | - name: Install development dependencies 27 | working-directory: ./redis 28 | run: bundle install 29 | - name: Run the tests 30 | working-directory: ./redis 31 | run: bundle exec rake test 32 | - name: Run standard code style checks 33 | working-directory: ./redis 34 | run: bundle exec rake standard 35 | -------------------------------------------------------------------------------- /.github/workflows/module-mongo.yml: -------------------------------------------------------------------------------- 1 | name: "Modules: MongoDB tests" 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | pull_request: 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | name: Ruby ${{ matrix.ruby }} 14 | strategy: 15 | matrix: 16 | ruby: 17 | - '3.4' 18 | 19 | steps: 20 | - uses: actions/checkout@v3 21 | - name: Set up Ruby 22 | uses: ruby/setup-ruby@v1 23 | with: 24 | ruby-version: ${{ matrix.ruby }} 25 | bundler-cache: true 26 | - name: Install development dependencies 27 | working-directory: ./mongo 28 | run: bundle install 29 | - name: Run the tests 30 | working-directory: ./mongo 31 | run: bundle exec rake test 32 | - name: Run standard code style checks 33 | working-directory: ./mongo 34 | run: bundle exec rake standard 35 | -------------------------------------------------------------------------------- /.github/workflows/module-compose.yml: -------------------------------------------------------------------------------- 1 | name: "Modules: Compose tests" 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | pull_request: 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | name: Ruby ${{ matrix.ruby }} 14 | strategy: 15 | matrix: 16 | ruby: 17 | - '3.4' 18 | 19 | steps: 20 | - uses: actions/checkout@v3 21 | - name: Set up Ruby 22 | uses: ruby/setup-ruby@v1 23 | with: 24 | ruby-version: ${{ matrix.ruby }} 25 | bundler-cache: true 26 | - name: Install development dependencies 27 | working-directory: ./compose 28 | run: bundle install 29 | - name: Run the tests 30 | working-directory: ./compose 31 | run: bundle exec rake test 32 | - name: Run standard code style checks 33 | working-directory: ./compose 34 | run: bundle exec rake standard 35 | -------------------------------------------------------------------------------- /.github/workflows/module-mariadb.yml: -------------------------------------------------------------------------------- 1 | name: "Modules: MariaDB tests" 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | pull_request: 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | name: Ruby ${{ matrix.ruby }} 14 | strategy: 15 | matrix: 16 | ruby: 17 | - '3.4' 18 | 19 | steps: 20 | - uses: actions/checkout@v3 21 | - name: Set up Ruby 22 | uses: ruby/setup-ruby@v1 23 | with: 24 | ruby-version: ${{ matrix.ruby }} 25 | bundler-cache: true 26 | - name: Install development dependencies 27 | working-directory: ./mariadb 28 | run: bundle install 29 | - name: Run the tests 30 | working-directory: ./mariadb 31 | run: bundle exec rake test 32 | - name: Run standard code style checks 33 | working-directory: ./mariadb 34 | run: bundle exec rake standard 35 | -------------------------------------------------------------------------------- /.github/workflows/module-postgres.yml: -------------------------------------------------------------------------------- 1 | name: "Modules: Postgres tests" 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | pull_request: 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | name: Ruby ${{ matrix.ruby }} 14 | strategy: 15 | matrix: 16 | ruby: 17 | - '3.4' 18 | 19 | steps: 20 | - uses: actions/checkout@v3 21 | - name: Set up Ruby 22 | uses: ruby/setup-ruby@v1 23 | with: 24 | ruby-version: ${{ matrix.ruby }} 25 | bundler-cache: true 26 | - name: Install development dependencies 27 | working-directory: ./postgres 28 | run: bundle install 29 | - name: Run the tests 30 | working-directory: ./postgres 31 | run: bundle exec rake test 32 | - name: Run standard code style checks 33 | working-directory: ./postgres 34 | run: bundle exec rake standard 35 | -------------------------------------------------------------------------------- /.github/workflows/module-rabbitmq.yml: -------------------------------------------------------------------------------- 1 | name: "Modules: RabbitMQ tests" 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | pull_request: 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | name: Ruby ${{ matrix.ruby }} 14 | strategy: 15 | matrix: 16 | ruby: 17 | - '3.4' 18 | 19 | steps: 20 | - uses: actions/checkout@v3 21 | - name: Set up Ruby 22 | uses: ruby/setup-ruby@v1 23 | with: 24 | ruby-version: ${{ matrix.ruby }} 25 | bundler-cache: true 26 | - name: Install development dependencies 27 | working-directory: ./rabbitmq 28 | run: bundle install 29 | - name: Run the tests 30 | working-directory: ./rabbitmq 31 | run: bundle exec rake test 32 | - name: Run standard code style checks 33 | working-directory: ./rabbitmq 34 | run: bundle exec rake standard 35 | -------------------------------------------------------------------------------- /.github/workflows/module-redpanda.yml: -------------------------------------------------------------------------------- 1 | name: "Modules: Redpanda tests" 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | pull_request: 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | name: Ruby ${{ matrix.ruby }} 14 | strategy: 15 | matrix: 16 | ruby: 17 | - '3.4' 18 | 19 | steps: 20 | - uses: actions/checkout@v3 21 | - name: Set up Ruby 22 | uses: ruby/setup-ruby@v1 23 | with: 24 | ruby-version: ${{ matrix.ruby }} 25 | bundler-cache: true 26 | - name: Install development dependencies 27 | working-directory: ./redpanda 28 | run: bundle install 29 | - name: Run the tests 30 | working-directory: ./redpanda 31 | run: bundle exec rake test 32 | - name: Run standard code style checks 33 | working-directory: ./redpanda 34 | run: bundle exec rake standard 35 | -------------------------------------------------------------------------------- /.github/workflows/module-selenium.yml: -------------------------------------------------------------------------------- 1 | name: "Modules: Selenium tests" 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | pull_request: 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | name: Ruby ${{ matrix.ruby }} 14 | strategy: 15 | matrix: 16 | ruby: 17 | - '3.4' 18 | 19 | steps: 20 | - uses: actions/checkout@v3 21 | - name: Set up Ruby 22 | uses: ruby/setup-ruby@v1 23 | with: 24 | ruby-version: ${{ matrix.ruby }} 25 | bundler-cache: true 26 | - name: Install development dependencies 27 | working-directory: ./selenium 28 | run: bundle install 29 | - name: Run the tests 30 | working-directory: ./selenium 31 | run: bundle exec rake test 32 | - name: Run standard code style checks 33 | working-directory: ./selenium 34 | run: bundle exec rake standard 35 | -------------------------------------------------------------------------------- /core/lib/testcontainers.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "docker" 4 | require "logger" 5 | require "open3" 6 | require "uri" 7 | require "testcontainers/docker_client" 8 | require "testcontainers/network" 9 | require "testcontainers/docker_container" 10 | require_relative "testcontainers/version" 11 | 12 | module Testcontainers 13 | class Error < StandardError; end 14 | 15 | class ConnectionError < Error; end 16 | 17 | class NotFoundError < Error; end 18 | 19 | class TimeoutError < Error; end 20 | 21 | class ContainerNotStartedError < Error; end 22 | 23 | class HealthcheckNotSupportedError < Error; end 24 | 25 | class PortNotMappedError < Error; end 26 | 27 | class ContainerLaunchException < Error; end 28 | 29 | class << self 30 | attr_writer :logger 31 | 32 | def logger 33 | @logger ||= Logger.new($stdout, level: :info) 34 | end 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /.github/workflows/module-elasticsearch.yml: -------------------------------------------------------------------------------- 1 | name: "Modules: ElasticSearch tests" 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | pull_request: 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | name: Ruby ${{ matrix.ruby }} 14 | strategy: 15 | matrix: 16 | ruby: 17 | - '3.4' 18 | 19 | steps: 20 | - uses: actions/checkout@v3 21 | - name: Set up Ruby 22 | uses: ruby/setup-ruby@v1 23 | with: 24 | ruby-version: ${{ matrix.ruby }} 25 | bundler-cache: true 26 | - name: Install development dependencies 27 | working-directory: ./elasticsearch 28 | run: bundle install 29 | - name: Run the tests 30 | working-directory: ./elasticsearch 31 | run: bundle exec rake test 32 | - name: Run standard code style checks 33 | working-directory: ./elasticsearch 34 | run: bundle exec rake standard 35 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | $:.unshift __dir__ 4 | require "bundler/gem_tasks" 5 | require "rake/testtask" 6 | require "yard" 7 | require "standard/rake" 8 | 9 | MODULES = %w[core mysql redis postgres nginx elasticsearch opensearch kafka mariadb mongo redpanda] 10 | 11 | %w[test standard].each do |task_name| 12 | desc "Run #{task_name} task for all projects" 13 | task task_name do 14 | errors = [] 15 | MODULES.each do |project| 16 | puts "Running #{task_name} for #{project}" 17 | system(%(cd #{project} && #{$0} #{task_name} --trace)) || errors << project 18 | end 19 | fail("Errors in #{errors.join(", ")}") unless errors.empty? 20 | end 21 | end 22 | 23 | YARD::Rake::YardocTask.new do |t| 24 | t.files = ["{#{MODULES.join(",")}}/lib/**/*.rb"] 25 | t.options = ["--protected", "--readme", "README.md", "--title", "Testcontainers for Ruby"] 26 | end 27 | 28 | task default: %i[test standard] 29 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source "https://rubygems.org" 4 | 5 | # Specify your gem's dependencies in testcontainers.gemspec 6 | gemspec 7 | 8 | gem "testcontainers-core", path: "./core" 9 | gem "testcontainers-mysql", path: "./mysql" 10 | gem "testcontainers-redis", path: "./redis" 11 | gem "testcontainers-postgres", path: "./postgres" 12 | gem "testcontainers-nginx", path: "./nginx" 13 | gem "testcontainers-elasticsearch", path: "./elasticsearch" 14 | gem "testcontainers-kafka", path: "./kafka" 15 | gem "testcontainers-opensearch", path: "./opensearch" 16 | gem "testcontainers-mariadb", path: "./mariadb" 17 | gem "testcontainers-mongo", path: "./mongo" 18 | gem "testcontainers-redpanda", path: "./redpanda" 19 | gem "testcontainers-rabbitmq", path: "./rabbitmq" 20 | gem "testcontainers-selenium", path: "./selenium" 21 | gem "testcontainers-compose", path: "./compose" 22 | gem "mysql2", "~> 0.5.3" 23 | gem "pg", "~> 1.5" 24 | gem "redis", "~> 5.0" 25 | gem "elasticsearch", "~> 8.7" 26 | gem "mongo", "~> 2.2" 27 | gem "rdkafka", "~> 0.12" 28 | gem "bunny", ">= 2.19.0" 29 | gem "selenium-webdriver", "~> 4.1.0" 30 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2023 Guillermo Iguaran 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /core/LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2023 Guillermo Iguaran 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /kafka/LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2023 Guillermo Iguaran 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /mongo/LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2023 Guillermo Iguaran 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /mysql/LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2023 Guillermo Iguaran 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /nginx/LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2023 Guillermo Iguaran 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /redis/LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2023 Guillermo Iguaran 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /compose/LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2023 Guillermo Iguaran 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /mariadb/LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2023 Guillermo Iguaran 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /opensearch/LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2023 Guillermo Iguaran 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /postgres/LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2023 Guillermo Iguaran 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /rabbitmq/LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2023 Guillermo Iguaran 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /redpanda/LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2023 Guillermo Iguaran 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /selenium/LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2023 Guillermo Iguaran 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /elasticsearch/LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2023 Guillermo Iguaran 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /module-gen/templates/LICENSE.txt.tt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2023 Guillermo Iguaran 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /testcontainers.gemspec: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative "core/lib/testcontainers/version" 4 | 5 | Gem::Specification.new do |spec| 6 | spec.name = "testcontainers" 7 | spec.version = Testcontainers::VERSION 8 | spec.authors = ["Guillermo Iguaran"] 9 | spec.email = ["guilleiguaran@gmail.com"] 10 | 11 | spec.summary = "Testcontainers for Ruby." 12 | spec.description = "Testcontainers makes it easy to create and clean up container-based dependencies for automated tests." 13 | spec.homepage = "https://github.com/testcontainers/testcontainers-ruby" 14 | spec.license = "MIT" 15 | spec.required_ruby_version = ">= 2.6.0" 16 | 17 | spec.metadata["homepage_uri"] = spec.homepage 18 | spec.metadata["source_code_uri"] = spec.homepage 19 | spec.files = [] 20 | 21 | # Uncomment to register a new dependency of your gem 22 | spec.add_dependency "testcontainers-core", Testcontainers::VERSION 23 | 24 | # For docs 25 | spec.add_development_dependency "yard", "~> 0.9" 26 | spec.add_development_dependency "rake", "~> 13.0" 27 | spec.add_development_dependency "minitest", "~> 5.0" 28 | spec.add_development_dependency "minitest-hooks", "~> 1.5" 29 | spec.add_development_dependency "standard", "~> 1.3" 30 | end 31 | -------------------------------------------------------------------------------- /module-gen/templates/README.md.tt: -------------------------------------------------------------------------------- 1 | # Testcontainers module for <%= name.capitalize %> 2 | 3 | ## Installation 4 | 5 | Add the library to the test section in your application's Gemfile: 6 | 7 | ```ruby 8 | group :test do 9 | gem 'testcontainers-<%= name %>' 10 | end 11 | ``` 12 | 13 | And then execute: 14 | 15 | ```bash 16 | $ bundle install 17 | ``` 18 | 19 | Or install it yourself as: 20 | 21 | ```bash 22 | $ gem install testcontainers-<%= name %> 23 | ``` 24 | 25 | ## Usage 26 | 27 | ## Contributing 28 | 29 | Bug reports and pull requests are welcome on GitHub at https://github.com/testcontainers/testcontainers-ruby. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/testcontainers/testcontainers-ruby/blob/main/CODE_OF_CONDUCT.md). 30 | 31 | ## License 32 | 33 | The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT). 34 | 35 | ## Code of Conduct 36 | 37 | Everyone interacting in the Testcontainers project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/testcontainers/testcontainers-ruby/blob/main/CODE_OF_CONDUCT.md). 38 | -------------------------------------------------------------------------------- /core/lib/testcontainers/docker_client.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "java-properties" 4 | require_relative "version" 5 | 6 | module Testcontainers 7 | module DockerClient 8 | module_function 9 | 10 | def connection 11 | configure 12 | Docker.connection 13 | end 14 | 15 | def configure 16 | configure_from_properties unless current_connection 17 | configure_user_agent 18 | end 19 | 20 | def current_connection 21 | Docker.instance_variable_get(:@connection) 22 | end 23 | 24 | def configure_from_properties 25 | properties = load_properties 26 | tc_host = ENV["TESTCONTAINERS_HOST"] || properties[:"tc.host"] 27 | Docker.url = tc_host if tc_host && !tc_host.empty? 28 | end 29 | 30 | def load_properties 31 | path = properties_path 32 | return {} unless File.exist?(path) 33 | 34 | JavaProperties.load(path) 35 | end 36 | 37 | def configure_user_agent 38 | Docker.options ||= {} 39 | Docker.options[:headers] ||= {} 40 | Docker.options[:headers]["User-Agent"] ||= "tc-ruby/#{Testcontainers::VERSION}" 41 | end 42 | 43 | def properties_path 44 | File.expand_path("~/.testcontainers.properties") 45 | end 46 | 47 | private_class_method :configure_from_properties, :configure_user_agent, :properties_path, :load_properties 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /.vscode/.testcontainers-ruby.code-workspace: -------------------------------------------------------------------------------- 1 | { 2 | "folders": [ 3 | { 4 | "name": "module / compose", 5 | "path": "../compose" 6 | }, 7 | { 8 | "name": "testcontainers-ruby", 9 | "path": "../core" 10 | }, 11 | { 12 | "name": "module / elasticsearch", 13 | "path": "../elasticsearch" 14 | }, 15 | { 16 | "name": "module / mariadb", 17 | "path": "../mariadb" 18 | }, 19 | { 20 | "name": "module / mongo", 21 | "path": "../mongo" 22 | }, 23 | { 24 | "name": "module / mysql", 25 | "path": "../mysql" 26 | }, 27 | { 28 | "name": "module / nginx", 29 | "path": "../nginx" 30 | }, 31 | { 32 | "name": "module / postgres", 33 | "path": "../postgres" 34 | }, 35 | { 36 | "name": "module / rabbitmq", 37 | "path": "../rabbitmq" 38 | }, 39 | { 40 | "name": "module / redis", 41 | "path": "../redis" 42 | }, 43 | { 44 | "name": "module / redpanda", 45 | "path": "../redpanda" 46 | }, 47 | { 48 | "name": "module / selenium", 49 | "path": "../selenium" 50 | } 51 | ] 52 | } -------------------------------------------------------------------------------- /examples/memcached_rspec.rb: -------------------------------------------------------------------------------- 1 | require "bundler/inline" 2 | 3 | gemfile do 4 | source "https://rubygems.org" 5 | gem "rspec" 6 | gem "testcontainers-core", path: "../core" 7 | gem "dalli" 8 | end 9 | 10 | require "dalli" 11 | require "rspec" 12 | require "rspec/autorun" 13 | require "testcontainers" 14 | 15 | RSpec.configure do |config| 16 | config.add_setting :memcached_container, default: nil 17 | 18 | config.before(:suite) do 19 | container = Testcontainers::GenericContainer.new("memcached:latest").with_exposed_port(11211).start 20 | ENV["MEMCACHED_HOST"] = "#{container.host}:#{container.mapped_port(11211)}" 21 | config.memcached_container = container 22 | end 23 | 24 | config.after(:suite) do 25 | config.memcached_container&.stop if config.memcached_container&.running? 26 | config.memcached_container&.remove 27 | end 28 | end 29 | 30 | RSpec.describe "Memcached" do 31 | before(:all) do 32 | @memcached = Dalli::Client.new(ENV["MEMCACHED_HOST"]) 33 | end 34 | 35 | before(:each) do 36 | @memcached.flush 37 | end 38 | 39 | it "set/get keys" do 40 | @memcached.set("foo", "bar") 41 | expect(@memcached.get("foo")).to eq("bar") 42 | end 43 | 44 | it "set/get multiple keys" do 45 | @memcached.set("foo", "bar") 46 | @memcached.set("baz", "qux") 47 | expect(@memcached.get_multi("foo", "baz")).to eq("foo" => "bar", "baz" => "qux") 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /examples/redis_container_rspec.rb: -------------------------------------------------------------------------------- 1 | require "bundler/inline" 2 | 3 | gemfile do 4 | source "https://rubygems.org" 5 | gem "rspec" 6 | gem "testcontainers-core", path: "../core" 7 | gem "testcontainers-redis", path: "../redis" 8 | gem "redis" 9 | end 10 | 11 | require "redis" 12 | require "rspec" 13 | require "rspec/autorun" 14 | require "testcontainers/redis" 15 | 16 | RSpec.configure do |config| 17 | config.add_setting :redis_container, default: nil 18 | config.add_setting :redis_url, default: nil 19 | 20 | config.before(:suite) do 21 | config.redis_container = Testcontainers::RedisContainer.new.start 22 | config.redis_url = config.redis_container.redis_url # We use this variable to avoid clashes with other Redis instances runnning on the host 23 | end 24 | 25 | config.after(:suite) do 26 | config.redis_container&.stop if config.redis_container&.running? 27 | config.redis_container&.remove 28 | end 29 | end 30 | 31 | RSpec.describe "Redis" do 32 | before(:all) do 33 | @redis = Redis.new(url: RSpec.configuration.redis_url) 34 | end 35 | 36 | before(:each) do 37 | @redis.flushdb 38 | end 39 | 40 | it "set/get keys" do 41 | @redis.set("foo", "bar") 42 | expect(@redis.get("foo")).to eq("bar") 43 | end 44 | 45 | it "set/get multiple keys" do 46 | @redis.mset("foo", "bar", "baz", "qux") 47 | expect(@redis.mget("foo", "baz")).to eq(["bar", "qux"]) 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /examples/redis_backed_cache_rspec.rb: -------------------------------------------------------------------------------- 1 | require "bundler/inline" 2 | 3 | gemfile do 4 | source "https://rubygems.org" 5 | gem "redis", require: "redis" 6 | gem "rspec", require: "rspec" 7 | gem "testcontainers-core", path: "../core", require: "testcontainers" 8 | end 9 | 10 | class RedisBackedCache 11 | def initialize(host, port) 12 | @redis = Redis.new(host: host, port: port) 13 | end 14 | 15 | def put(key, value) 16 | @redis.set(key, value) 17 | end 18 | 19 | def get(key) 20 | @redis.get(key) 21 | end 22 | 23 | def clear 24 | @redis.flushall 25 | end 26 | end 27 | 28 | require "rspec/autorun" 29 | 30 | RSpec.configure do |config| 31 | config.add_setting :redis, default: nil 32 | 33 | config.before(:suite) do 34 | config.redis = Testcontainers::DockerContainer.new("redis:6.2-alpine").with_exposed_ports("6379") 35 | config.redis.start 36 | config.redis.wait_for_tcp_port("6379") # wait for Redis to start 37 | config.redis.wait_for_logs(/Ready to accept connections/) 38 | end 39 | 40 | config.after(:suite) do 41 | config.redis&.stop if config.redis&.running? 42 | config.redis&.remove 43 | end 44 | end 45 | 46 | RSpec.describe RedisBackedCache do 47 | let(:cache) { RedisBackedCache.new(RSpec.configuration.redis.host, RSpec.configuration.redis.mapped_port(6379)) } 48 | 49 | before { cache.clear } 50 | 51 | it "can put and get values" do 52 | cache.put("foo", "bar") 53 | expect(cache.get("foo")).to eq("bar") 54 | end 55 | end 56 | -------------------------------------------------------------------------------- /module-gen/module_generator.thor: -------------------------------------------------------------------------------- 1 | require "thor" 2 | 3 | class ModuleGenerator < Thor::Group 4 | include Thor::Actions 5 | 6 | # Module name 7 | argument :name 8 | 9 | def self.source_root 10 | __dir__ 11 | end 12 | 13 | # Create our gem's root folder 14 | def make_module_folder 15 | self.destination_root = File.join(File.dirname(__dir__)) 16 | empty_directory(name) 17 | end 18 | 19 | # Create our gem's root files 20 | def create_root_files 21 | template("templates/CHANGELOG.md.tt", "#{name}/CHANGELOG.md") 22 | template("templates/Gemfile.tt", "#{name}/Gemfile") 23 | template("templates/LICENSE.txt.tt", "#{name}/LICENSE.txt") 24 | template("templates/Rakefile.tt", "#{name}/Rakefile") 25 | template("templates/README.md.tt", "#{name}/README.md") 26 | template("templates/module.gemspec.tt", "#{name}/testcontainers-#{name}.gemspec") 27 | end 28 | 29 | # Create our gem's module files 30 | def create_module_files 31 | empty_directory("#{name}/lib/testcontainers/#{name}") 32 | template("templates/lib/module.rb.tt", "#{name}/lib/testcontainers/#{name}.rb") 33 | template("templates/lib/module/version.rb.tt", "#{name}/lib/testcontainers/#{name}/version.rb") 34 | end 35 | 36 | # Create our gem's test files 37 | def create_test_files 38 | empty_directory("#{name}/test") 39 | template("templates/test/test_helper.rb.tt", "#{name}/test/test_helper.rb") 40 | template("templates/test/module_test.rb.tt", "#{name}/test/#{name}_container_test.rb") 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /examples/redis_backed_cache_minitest.rb: -------------------------------------------------------------------------------- 1 | require "bundler/inline" 2 | 3 | gemfile do 4 | source "https://rubygems.org" 5 | gem "redis", require: "redis" 6 | gem "minitest" 7 | gem "minitest-hooks" 8 | gem "testcontainers-core", path: "../core", require: "testcontainers" 9 | end 10 | 11 | class RedisBackedCache 12 | def initialize(host, port) 13 | @redis = Redis.new(host: host, port: port) 14 | end 15 | 16 | def put(key, value) 17 | @redis.set(key, value) 18 | end 19 | 20 | def get(key) 21 | @redis.get(key) 22 | end 23 | 24 | def clear 25 | @redis.flushall 26 | end 27 | end 28 | 29 | require "minitest/autorun" 30 | require "minitest/hooks/test" 31 | 32 | class RedisBackedCacheTest < Minitest::Test 33 | include Minitest::Hooks 34 | 35 | def before_all 36 | super 37 | 38 | @redis_container = Testcontainers::DockerContainer.new("redis:6.2-alpine").with_exposed_ports(6379) 39 | @redis_container.start 40 | @redis_container.wait_for_tcp_port(6379) 41 | @redis_container.wait_for_logs(/Ready to accept connections/) 42 | end 43 | 44 | def after_all 45 | if @redis_container&.exists? 46 | @redis_container&.stop! if @redis_container&.running? 47 | @redis_container&.remove 48 | end 49 | 50 | super 51 | end 52 | 53 | def setup 54 | address = @redis_container.host 55 | port = @redis_container.mapped_port(6379) 56 | @cache = RedisBackedCache.new(address, port) 57 | end 58 | 59 | def teardown 60 | @cache&.clear 61 | end 62 | 63 | def test_put_and_get 64 | @cache.put("test", "example") 65 | retrieved = @cache.get("test") 66 | assert_equal "example", retrieved 67 | end 68 | 69 | # Add more tests here, and they will reuse the same container. 70 | end 71 | -------------------------------------------------------------------------------- /nginx/lib/testcontainers/nginx.rb: -------------------------------------------------------------------------------- 1 | require_relative "nginx/version" 2 | require "testcontainers" 3 | 4 | module Testcontainers 5 | # NginxContainer class is used to manage containers that run an NGINX server 6 | class NginxContainer < ::Testcontainers::DockerContainer 7 | # Default port used by the container 8 | NGINX_DEFAULT_PORT = 80 9 | 10 | # Default image used by the container 11 | NGINX_DEFAULT_IMAGE = "nginx:latest" 12 | 13 | # Initializes a new instance of NginxContainer 14 | # 15 | # @param image [String] the image to use 16 | # @param port [String] the port to use 17 | # @param kwargs [Hash] the options to pass to the container. See {DockerContainer#initialize} 18 | # @return [NginxContainer] a new instance of NginxContainer 19 | def initialize(image = NGINX_DEFAULT_IMAGE, port: nil, **kwargs) 20 | super(image, **kwargs) 21 | add_wait_for(:logs, /start worker process/) unless wait_for_user_defined? 22 | end 23 | 24 | # Starts the container 25 | # 26 | # @return [NginxContainer] self 27 | def start 28 | with_exposed_ports(port) 29 | super 30 | end 31 | 32 | # Returns the port used by the container 33 | # 34 | # @return [Integer] the port used by the container 35 | def port 36 | NGINX_DEFAULT_PORT 37 | end 38 | 39 | # Returns the server url (e.g. http://host:port) 40 | # 41 | # @param protocol [String] the protocol to use in the string (default: "http") 42 | # @return [String] the server url 43 | # @raise [ConnectionError] If the connection to the Docker daemon fails. 44 | # @raise [ContainerNotStartedError] If the container has not been started. 45 | def server_url(protocol: "http") 46 | "#{protocol}://#{host}:#{mapped_port(port)}" 47 | end 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /nginx/test/nginx_container_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "test_helper" 4 | require "net/http" 5 | 6 | class NginxContainerTest < TestcontainersTest 7 | def before_all 8 | super 9 | 10 | @container = Testcontainers::NginxContainer.new 11 | @container.start 12 | @host = @container.host 13 | @port = @container.first_mapped_port 14 | end 15 | 16 | def after_all 17 | if @container&.exists? 18 | @container&.stop if @container&.running? 19 | @container&.remove 20 | end 21 | 22 | super 23 | end 24 | 25 | def test_it_returns_the_default_image 26 | assert_equal "nginx:latest", @container.image 27 | end 28 | 29 | def test_it_supports_custom_image 30 | container = Testcontainers::NginxContainer.new("nginx:1.18-alpine") 31 | assert_equal "nginx:1.18-alpine", container.image 32 | end 33 | 34 | def test_it_returns_the_default_port 35 | assert_equal 80, @container.port 36 | end 37 | 38 | def test_it_has_the_default_port_mapped 39 | assert @container.mapped_port(80) 40 | end 41 | 42 | def test_it_supports_custom_keyword_arguments 43 | container = Testcontainers::NginxContainer.new(filesystem_binds: ["#{Dir.pwd}/custom/conf:/etc/nginx/conf.d:rw"]) 44 | assert_equal ["#{Dir.pwd}/custom/conf:/etc/nginx/conf.d:rw"], container.filesystem_binds 45 | end 46 | 47 | def test_it_returns_the_default_server_url 48 | assert_equal "http://#{@host}:#{@port}", @container.server_url 49 | end 50 | 51 | def test_it_returns_the_server_url_with_custom_protocol 52 | assert_equal "https://#{@host}:#{@port}", @container.server_url(protocol: "https") 53 | end 54 | 55 | def test_it_is_reachable 56 | uri = URI.parse(@container.server_url) 57 | response = Net::HTTP.get_response(uri) 58 | 59 | assert_equal "200", response.code 60 | end 61 | end 62 | -------------------------------------------------------------------------------- /examples/mysql_ar_rspec.rb: -------------------------------------------------------------------------------- 1 | require "bundler/inline" 2 | 3 | gemfile do 4 | source "https://rubygems.org" 5 | gem "rspec" 6 | gem "testcontainers-core", path: "../core" 7 | gem "testcontainers-mysql", path: "../mysql" 8 | gem "activerecord" 9 | gem "mysql2" 10 | end 11 | 12 | require "active_record" 13 | require "logger" 14 | require "rspec" 15 | require "rspec/autorun" 16 | require "testcontainers/mysql" 17 | 18 | RSpec.configure do |config| 19 | config.add_setting :mysql_container, default: nil 20 | config.add_setting :database_url, default: nil 21 | 22 | config.before(:suite) do 23 | container = Testcontainers::MysqlContainer.new(database: "posts_test").start 24 | config.mysql_container = container 25 | # On your own tests, you would probably save this url on ENV["DATABASE_URL"] and point to it in your database.yml file 26 | # ENV["DATABASE_URL"] = container.database_url(protocol: "mysql2") 27 | config.database_url = container.database_url(protocol: "mysql2") 28 | end 29 | 30 | config.after(:suite) do 31 | config.mysql_container&.stop if config.mysql_container&.running? 32 | config.mysql_container&.remove 33 | end 34 | end 35 | 36 | class Post < ActiveRecord::Base 37 | end 38 | 39 | RSpec.describe Post do 40 | before(:all) do 41 | # On your own tests this would be done automatically by Rails 42 | ActiveRecord::Base.establish_connection(RSpec.configuration.database_url) 43 | 44 | # Schema required for the demo, ignore in your own tests 45 | ActiveRecord::Schema.define do 46 | create_table :posts, force: true do |t| 47 | end 48 | end 49 | 50 | # Print logs in stdout instead of an file, ignore in your own tests 51 | ActiveRecord::Base.logger = Logger.new($stdout) 52 | end 53 | 54 | it "create new posts" do 55 | Post.create! 56 | expect(Post.count).to eq(1) 57 | end 58 | end 59 | -------------------------------------------------------------------------------- /kafka/test/kafka_container_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "test_helper" 4 | require "rdkafka" 5 | 6 | class KafkaContainerTest < TestcontainersTest 7 | def before_all 8 | super 9 | 10 | @container = Testcontainers::KafkaContainer.new 11 | @container.start 12 | @container.wait_for_tcp_port(9092) 13 | @host = @container.host 14 | @port = @container.mapped_port(9092) 15 | end 16 | 17 | def after_all 18 | if @container&.exists? 19 | @container&.stop if @container&.running? 20 | @container&.remove 21 | end 22 | 23 | super 24 | end 25 | 26 | def test_it_returns_the_default_image 27 | assert_equal "confluentinc/cp-kafka:7.6.1", @container.image 28 | end 29 | 30 | def test_it_returns_the_connection_url 31 | assert_equal "#{@host}:#{@port}", @container.connection_url 32 | end 33 | 34 | def test_it_returns_bootstrap_servers 35 | assert_equal "PLAINTEXT://#{@host}:#{@port}", @container.bootstrap_servers 36 | end 37 | 38 | def test_it_supports_custom_image 39 | container = Testcontainers::KafkaContainer.new("confluentinc/cp-kafka:7.5.4") 40 | assert_equal "confluentinc/cp-kafka:7.5.4", container.image 41 | end 42 | 43 | def test_it_is_reachable 44 | config = { 45 | "bootstrap.servers": @container.connection_url, 46 | "group.id": "ruby-test", 47 | "auto.offset.reset": "earliest" 48 | } 49 | 50 | producer = Rdkafka::Config.new(config).producer 51 | producer.produce(payload: "Hello, Kafka!", topic: "ruby-test-topic").wait 52 | 53 | consumer = Rdkafka::Config.new(config).consumer 54 | consumer.subscribe("ruby-test-topic") 55 | 56 | message = consumer.each do |msg| 57 | break msg 58 | end 59 | 60 | assert_equal "Hello, Kafka!", message.payload 61 | assert_equal "ruby-test-topic", message.topic 62 | end 63 | end 64 | -------------------------------------------------------------------------------- /opensearch/README.md: -------------------------------------------------------------------------------- 1 | # Testcontainers module for Opensearch 2 | 3 | ## Installation 4 | 5 | Add the library to the test section in your application's Gemfile: 6 | 7 | ```ruby 8 | group :test do 9 | gem 'testcontainers-opensearch' 10 | end 11 | ``` 12 | 13 | And then execute: 14 | 15 | ```bash 16 | $ bundle install 17 | ``` 18 | 19 | Or install it yourself as: 20 | 21 | ```bash 22 | $ gem install testcontainers-opensearch 23 | ``` 24 | 25 | ## Usage 26 | 27 | ```ruby 28 | require "testcontainers/opensearch" 29 | 30 | container = Testcontainers::OpensearchContainer.new.start 31 | 32 | begin 33 | container.wait_for_healthcheck 34 | client = OpenSearch::Client.new(url: container.opensearch_url) 35 | client.ping # => true 36 | ensure 37 | container.stop if container.running? 38 | container.remove if container.exists? 39 | end 40 | ``` 41 | 42 | The container exposes ports 9200 (HTTP) and 9600 (metrics) by default and 43 | disables the security plugin so you can connect without credentials. Override 44 | environment variables via `with_env` before calling `start` if you need to 45 | change the defaults. 46 | 47 | ## Contributing 48 | 49 | Bug reports and pull requests are welcome on GitHub at https://github.com/testcontainers/testcontainers-ruby. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/testcontainers/testcontainers-ruby/blob/main/CODE_OF_CONDUCT.md). 50 | 51 | ## License 52 | 53 | The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT). 54 | 55 | ## Code of Conduct 56 | 57 | Everyone interacting in the Testcontainers project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/testcontainers/testcontainers-ruby/blob/main/CODE_OF_CONDUCT.md). 58 | -------------------------------------------------------------------------------- /kafka/README.md: -------------------------------------------------------------------------------- 1 | # Testcontainers module for Kafka 2 | 3 | ## Installation 4 | 5 | Add the library to the test section in your application's Gemfile: 6 | 7 | ```ruby 8 | group :test do 9 | gem 'testcontainers-kafka' 10 | end 11 | ``` 12 | 13 | And then execute: 14 | 15 | ```bash 16 | $ bundle install 17 | ``` 18 | 19 | Or install it yourself as: 20 | 21 | ```bash 22 | $ gem install testcontainers-kafka 23 | ``` 24 | 25 | ## Usage 26 | 27 | ```ruby 28 | require "testcontainers/kafka" 29 | require "rdkafka" 30 | 31 | container = Testcontainers::KafkaContainer.new.start 32 | 33 | begin 34 | container.wait_for_tcp_port(9092) 35 | config = { 36 | "bootstrap.servers": container.connection_url, 37 | "group.id": "ruby-example", 38 | "auto.offset.reset": "earliest" 39 | } 40 | 41 | producer = Rdkafka::Config.new(config).producer 42 | producer.produce(payload: "hello", topic: "example").wait 43 | 44 | consumer = Rdkafka::Config.new(config).consumer 45 | consumer.subscribe("example") 46 | puts consumer.each { |msg| break msg.payload } 47 | ensure 48 | container.stop if container.running? 49 | container.remove if container.exists? 50 | end 51 | ``` 52 | 53 | ## Contributing 54 | 55 | Bug reports and pull requests are welcome on GitHub at https://github.com/testcontainers/testcontainers-ruby. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/testcontainers/testcontainers-ruby/blob/main/CODE_OF_CONDUCT.md). 56 | 57 | ## License 58 | 59 | The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT). 60 | 61 | ## Code of Conduct 62 | 63 | Everyone interacting in the Testcontainers project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/testcontainers/testcontainers-ruby/blob/main/CODE_OF_CONDUCT.md). 64 | -------------------------------------------------------------------------------- /nginx/testcontainers-nginx.gemspec: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative "lib/testcontainers/nginx/version" 4 | 5 | Gem::Specification.new do |spec| 6 | spec.name = "testcontainers-nginx" 7 | spec.version = Testcontainers::Nginx::VERSION 8 | spec.authors = ["Guillermo Iguaran"] 9 | spec.email = ["guilleiguaran@gmail.com"] 10 | 11 | spec.summary = "Testcontainers for Ruby: Nginx module" 12 | spec.description = "Testcontainers makes it easy to create and clean up container-based dependencies for automated tests." 13 | spec.homepage = "https://github.com/testcontainers/testcontainers-ruby" 14 | spec.license = "MIT" 15 | spec.required_ruby_version = ">= 2.6.0" 16 | 17 | spec.metadata["homepage_uri"] = "#{spec.homepage}/blob/main/nginx" 18 | spec.metadata["source_code_uri"] = "#{spec.homepage}/blob/main/nginx" 19 | spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/main/nginx/CHANGELOG.md" 20 | 21 | # Specify which files should be added to the gem when it is released. 22 | # The `git ls-files -z` loads the files in the RubyGem that have been added into git. 23 | spec.files = Dir.chdir(__dir__) do 24 | `git ls-files -z`.split("\x0").reject do |f| 25 | (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|circleci)|appveyor)}) 26 | end 27 | end 28 | spec.bindir = "exe" 29 | spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) } 30 | spec.require_paths = ["lib"] 31 | 32 | # Uncomment to register a new dependency of your gem 33 | spec.add_dependency "testcontainers-core", "~> 0.1" 34 | 35 | spec.add_development_dependency "rake", "~> 13.0" 36 | spec.add_development_dependency "minitest", "~> 5.0" 37 | spec.add_development_dependency "minitest-hooks", "~> 1.5" 38 | spec.add_development_dependency "standard", "~> 1.3" 39 | 40 | # For more information and examples about making a new gem, check out our 41 | # guide at: https://bundler.io/guides/creating_gem.html 42 | end 43 | -------------------------------------------------------------------------------- /redis/test/redis_container_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "test_helper" 4 | require "redis" 5 | 6 | class RedisContainerTest < TestcontainersTest 7 | def before_all 8 | super 9 | 10 | @container = Testcontainers::RedisContainer.new 11 | @container.start 12 | @host = @container.host 13 | @port = @container.first_mapped_port 14 | end 15 | 16 | def after_all 17 | if @container&.exists? 18 | @container&.stop if @container&.running? 19 | @container&.remove 20 | end 21 | 22 | super 23 | end 24 | 25 | def test_it_returns_the_default_image 26 | assert_equal "redis:latest", @container.image 27 | end 28 | 29 | def test_it_supports_custom_image 30 | container = Testcontainers::RedisContainer.new("redis:alpine") 31 | assert_equal "redis:alpine", container.image 32 | end 33 | 34 | def test_it_returns_the_default_port 35 | assert_equal 6379, @container.port 36 | end 37 | 38 | def test_it_has_the_default_port_mapped 39 | assert @container.mapped_port(6379) 40 | end 41 | 42 | def test_it_supports_custom_keyword_arguments 43 | container = Testcontainers::RedisContainer.new(filesystem_binds: ["#{Dir.pwd}/custom/conf:/usr/local/etc/redis/redis.conf:rw"]) 44 | assert_equal ["#{Dir.pwd}/custom/conf:/usr/local/etc/redis/redis.conf:rw"], container.filesystem_binds 45 | end 46 | 47 | def test_it_returns_the_default_redis_url 48 | assert_equal "redis://#{@host}:#{@port}/0", @container.redis_url 49 | end 50 | 51 | def test_it_returns_the_redis_url_with_custom_protocol 52 | assert_equal "rediss://#{@host}:#{@port}/0", @container.redis_url(protocol: "rediss") 53 | end 54 | 55 | def test_it_returns_the_redis_url_with_custom_db_number 56 | assert_equal "redis://#{@host}:#{@port}/3", @container.redis_url(db: 3) 57 | end 58 | 59 | def test_it_is_reachable 60 | client = Redis.new(host: @host, port: @port, db: 0) 61 | assert_equal "PONG", client.ping 62 | end 63 | end 64 | -------------------------------------------------------------------------------- /compose/testcontainers-compose.gemspec: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative "lib/testcontainers/compose/version" 4 | 5 | Gem::Specification.new do |spec| 6 | spec.name = "testcontainers-compose" 7 | spec.version = Testcontainers::Compose::VERSION 8 | spec.authors = ["Guillermo Iguaran"] 9 | spec.email = ["guilleiguaran@gmail.com"] 10 | 11 | spec.summary = "Testcontainers for Ruby: Compose module" 12 | spec.description = "Testcontainers makes it easy to create and clean up container-based dependencies for automated tests." 13 | spec.homepage = "https://github.com/testcontainers/testcontainers-ruby" 14 | spec.license = "MIT" 15 | spec.required_ruby_version = ">= 2.6.0" 16 | 17 | spec.metadata["homepage_uri"] = "#{spec.homepage}/blob/main/compose" 18 | spec.metadata["source_code_uri"] = "#{spec.homepage}/blob/main/compose" 19 | spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/main/compose/CHANGELOG.md" 20 | 21 | # Specify which files should be added to the gem when it is released. 22 | # The `git ls-files -z` loads the files in the RubyGem that have been added into git. 23 | spec.files = Dir.chdir(__dir__) do 24 | `git ls-files -z`.split("\x0").reject do |f| 25 | (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|circleci)|appveyor)}) 26 | end 27 | end 28 | spec.bindir = "exe" 29 | spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) } 30 | spec.require_paths = ["lib"] 31 | 32 | # Uncomment to register a new dependency of your gem 33 | spec.add_dependency "testcontainers-core", "~> 0.1" 34 | 35 | spec.add_development_dependency "rake", "~> 13.0" 36 | spec.add_development_dependency "minitest", "~> 5.0" 37 | spec.add_development_dependency "minitest-hooks", "~> 1.5" 38 | spec.add_development_dependency "standard", "~> 1.3" 39 | 40 | # For more information and examples about making a new gem, check out our 41 | # guide at: https://bundler.io/guides/creating_gem.html 42 | end 43 | -------------------------------------------------------------------------------- /core/testcontainers-core.gemspec: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative "lib/testcontainers/version" 4 | 5 | Gem::Specification.new do |spec| 6 | spec.name = "testcontainers-core" 7 | spec.version = Testcontainers::VERSION 8 | spec.authors = ["Guillermo Iguaran"] 9 | spec.email = ["guilleiguaran@gmail.com"] 10 | 11 | spec.summary = "Testcontainers for Ruby." 12 | spec.description = "Testcontainers makes it easy to create and clean up container-based dependencies for automated tests." 13 | spec.homepage = "https://github.com/testcontainers/testcontainers-ruby" 14 | spec.license = "MIT" 15 | spec.required_ruby_version = ">= 2.6.0" 16 | 17 | spec.metadata["homepage_uri"] = spec.homepage 18 | spec.metadata["source_code_uri"] = spec.homepage 19 | spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/main/core/CHANGELOG.md" 20 | 21 | # Specify which files should be added to the gem when it is released. 22 | # The `git ls-files -z` loads the files in the RubyGem that have been added into git. 23 | spec.files = Dir.chdir(__dir__) do 24 | `git ls-files -z`.split("\x0").reject do |f| 25 | (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|circleci)|appveyor)}) 26 | end 27 | end 28 | spec.bindir = "exe" 29 | spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) } 30 | spec.require_paths = ["lib"] 31 | 32 | # Uncomment to register a new dependency of your gem 33 | spec.add_dependency "docker-api", "~> 2.4" 34 | spec.add_dependency "java-properties", "~> 0.3.0" 35 | spec.add_dependency "base64", "~> 0.3" 36 | 37 | spec.add_development_dependency "rake", "~> 13.0" 38 | spec.add_development_dependency "minitest", "~> 5.0" 39 | spec.add_development_dependency "minitest-hooks", "~> 1.5" 40 | spec.add_development_dependency "standard", "~> 1.3" 41 | 42 | # For more information and examples about making a new gem, check out our 43 | # guide at: https://bundler.io/guides/creating_gem.html 44 | end 45 | -------------------------------------------------------------------------------- /kafka/testcontainers-kafka.gemspec: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative "lib/testcontainers/kafka/version" 4 | 5 | Gem::Specification.new do |spec| 6 | spec.name = "testcontainers-kafka" 7 | spec.version = Testcontainers::Kafka::VERSION 8 | spec.authors = ["Guillermo Iguaran"] 9 | spec.email = ["guilleiguaran@gmail.com"] 10 | 11 | spec.summary = "Testcontainers for Ruby: Kafka module" 12 | spec.description = "Testcontainers makes it easy to create and clean up container-based dependencies for automated tests." 13 | spec.homepage = "https://github.com/testcontainers/testcontainers-ruby" 14 | spec.license = "MIT" 15 | spec.required_ruby_version = ">= 2.6.0" 16 | 17 | spec.metadata["homepage_uri"] = "#{spec.homepage}/blob/main/kafka" 18 | spec.metadata["source_code_uri"] = "#{spec.homepage}/blob/main/kafka" 19 | spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/main/kafka/CHANGELOG.md" 20 | 21 | # Specify which files should be added to the gem when it is released. 22 | # The `git ls-files -z` loads the files in the RubyGem that have been added into git. 23 | spec.files = Dir.chdir(__dir__) do 24 | `git ls-files -z`.split("\x0").reject do |f| 25 | (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|circleci)|appveyor)}) 26 | end 27 | end 28 | spec.bindir = "exe" 29 | spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) } 30 | spec.require_paths = ["lib"] 31 | 32 | # Uncomment to register a new dependency of your gem 33 | spec.add_dependency "testcontainers-core", "~> 0.1" 34 | 35 | spec.add_development_dependency "rake", "~> 13.0" 36 | spec.add_development_dependency "minitest", "~> 5.0" 37 | spec.add_development_dependency "minitest-hooks", "~> 1.5" 38 | spec.add_development_dependency "standard", "~> 1.3" 39 | spec.add_development_dependency "rdkafka", "~> 0.12" 40 | 41 | # For more information and examples about making a new gem, check out our 42 | # guide at: https://bundler.io/guides/creating_gem.html 43 | end 44 | -------------------------------------------------------------------------------- /mysql/testcontainers-mysql.gemspec: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative "lib/testcontainers/mysql/version" 4 | 5 | Gem::Specification.new do |spec| 6 | spec.name = "testcontainers-mysql" 7 | spec.version = Testcontainers::Mysql::VERSION 8 | spec.authors = ["Guillermo Iguaran"] 9 | spec.email = ["guilleiguaran@gmail.com"] 10 | 11 | spec.summary = "Testcontainers for Ruby: MySQL module" 12 | spec.description = "Testcontainers makes it easy to create and clean up container-based dependencies for automated tests." 13 | spec.homepage = "https://github.com/testcontainers/testcontainers-ruby" 14 | spec.license = "MIT" 15 | spec.required_ruby_version = ">= 2.6.0" 16 | 17 | spec.metadata["homepage_uri"] = "#{spec.homepage}/blob/main/mysql" 18 | spec.metadata["source_code_uri"] = "#{spec.homepage}/blob/main/mysql" 19 | spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/main/mysql/CHANGELOG.md" 20 | 21 | # Specify which files should be added to the gem when it is released. 22 | # The `git ls-files -z` loads the files in the RubyGem that have been added into git. 23 | spec.files = Dir.chdir(__dir__) do 24 | `git ls-files -z`.split("\x0").reject do |f| 25 | (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|circleci)|appveyor)}) 26 | end 27 | end 28 | spec.bindir = "exe" 29 | spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) } 30 | spec.require_paths = ["lib"] 31 | 32 | # Uncomment to register a new dependency of your gem 33 | spec.add_dependency "testcontainers-core", "~> 0.1" 34 | 35 | spec.add_development_dependency "rake", "~> 13.0" 36 | spec.add_development_dependency "minitest", "~> 5.0" 37 | spec.add_development_dependency "minitest-hooks", "~> 1.5" 38 | spec.add_development_dependency "standard", "~> 1.3" 39 | spec.add_development_dependency "mysql2", "~> 0.5.0" 40 | 41 | # For more information and examples about making a new gem, check out our 42 | # guide at: https://bundler.io/guides/creating_gem.html 43 | end 44 | -------------------------------------------------------------------------------- /redis/testcontainers-redis.gemspec: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative "lib/testcontainers/redis/version" 4 | 5 | Gem::Specification.new do |spec| 6 | spec.name = "testcontainers-redis" 7 | spec.version = Testcontainers::Redis::VERSION 8 | spec.authors = ["Guillermo Iguaran"] 9 | spec.email = ["guilleiguaran@gmail.com"] 10 | 11 | spec.summary = "Testcontainers for Ruby: Redis module" 12 | spec.description = "Testcontainers makes it easy to create and clean up container-based dependencies for automated tests." 13 | spec.homepage = "https://github.com/testcontainers/testcontainers-ruby" 14 | spec.license = "MIT" 15 | spec.required_ruby_version = ">= 2.6.0" 16 | 17 | spec.metadata["homepage_uri"] = "#{spec.homepage}/blob/main/redis" 18 | spec.metadata["source_code_uri"] = "#{spec.homepage}/blob/main/redis" 19 | spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/main/redis/CHANGELOG.md" 20 | 21 | # Specify which files should be added to the gem when it is released. 22 | # The `git ls-files -z` loads the files in the RubyGem that have been added into git. 23 | spec.files = Dir.chdir(__dir__) do 24 | `git ls-files -z`.split("\x0").reject do |f| 25 | (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|circleci)|appveyor)}) 26 | end 27 | end 28 | spec.bindir = "exe" 29 | spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) } 30 | spec.require_paths = ["lib"] 31 | 32 | # Uncomment to register a new dependency of your gem 33 | spec.add_dependency "testcontainers-core", "~> 0.1" 34 | 35 | spec.add_development_dependency "rake", "~> 13.0" 36 | spec.add_development_dependency "minitest", "~> 5.0" 37 | spec.add_development_dependency "minitest-hooks", "~> 1.5" 38 | spec.add_development_dependency "standard", "~> 1.3" 39 | spec.add_development_dependency "redis", "~> 5.0" 40 | 41 | # For more information and examples about making a new gem, check out our 42 | # guide at: https://bundler.io/guides/creating_gem.html 43 | end 44 | -------------------------------------------------------------------------------- /examples/redpanda_rspec.rb: -------------------------------------------------------------------------------- 1 | require "bundler/inline" 2 | 3 | gemfile do 4 | source "https://rubygems.org" 5 | gem "testcontainers-core", path: "../core" 6 | gem "testcontainers-redpanda", path: "../redpanda" 7 | 8 | gem "rspec" 9 | gem "rdkafka" 10 | end 11 | 12 | require "rdkafka" 13 | require "rspec" 14 | require "rspec/autorun" 15 | require "timeout" 16 | 17 | RSpec.configure do |config| 18 | config.add_setting :redpanda_container, default: nil 19 | 20 | config.before(:suite) do 21 | config.redpanda_container = Testcontainers::RedpandaContainer.new.start 22 | end 23 | 24 | config.after(:suite) do 25 | config.redpanda_container&.stop if config.redpanda_container&.running? 26 | config.redpanda_container&.remove 27 | end 28 | end 29 | 30 | RSpec.describe "Redpanda" do 31 | it "works" do 32 | topic = "ruby-test-topic" 33 | producer_config = { 34 | "bootstrap.servers": RSpec.configuration.redpanda_container.connection_url, 35 | "message.timeout.ms": 10_000 36 | } 37 | consumer_config = { 38 | "bootstrap.servers": RSpec.configuration.redpanda_container.connection_url, 39 | "group.id": "ruby-test", 40 | "auto.offset.reset": "earliest" 41 | } 42 | 43 | producer = nil 44 | consumer = nil 45 | 46 | begin 47 | producer = Rdkafka::Config.new(producer_config).producer 48 | consumer = Rdkafka::Config.new(consumer_config).consumer 49 | consumer.subscribe(topic) 50 | 51 | producer.produce(payload: "test", topic: topic).wait 52 | 53 | message = nil 54 | begin 55 | Timeout.timeout(15) do 56 | loop do 57 | message = consumer.poll(1000) 58 | break if message 59 | end 60 | end 61 | rescue Timeout::Error 62 | fail "Timed out waiting for message on #{topic}" 63 | end 64 | 65 | expect(message.payload).to eq("test") 66 | ensure 67 | producer&.flush(5_000) 68 | producer&.close 69 | consumer&.close 70 | end 71 | end 72 | end 73 | -------------------------------------------------------------------------------- /module-gen/templates/module.gemspec.tt: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative "lib/testcontainers/<%= name %>/version" 4 | 5 | Gem::Specification.new do |spec| 6 | spec.name = "testcontainers-<%= name %>" 7 | spec.version = Testcontainers::<%= name.capitalize %>::VERSION 8 | spec.authors = ["Guillermo Iguaran"] 9 | spec.email = ["guilleiguaran@gmail.com"] 10 | 11 | spec.summary = "Testcontainers for Ruby: <%= name.capitalize %> module" 12 | spec.description = "Testcontainers makes it easy to create and clean up container-based dependencies for automated tests." 13 | spec.homepage = "https://github.com/testcontainers/testcontainers-ruby" 14 | spec.license = "MIT" 15 | spec.required_ruby_version = ">= 2.6.0" 16 | 17 | spec.metadata["homepage_uri"] = "#{spec.homepage}/blob/main/<%= name %>" 18 | spec.metadata["source_code_uri"] = "#{spec.homepage}/blob/main/<%= name %>" 19 | spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/main/<%= name %>/CHANGELOG.md" 20 | 21 | # Specify which files should be added to the gem when it is released. 22 | # The `git ls-files -z` loads the files in the RubyGem that have been added into git. 23 | spec.files = Dir.chdir(__dir__) do 24 | `git ls-files -z`.split("\x0").reject do |f| 25 | (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|circleci)|appveyor)}) 26 | end 27 | end 28 | spec.bindir = "exe" 29 | spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) } 30 | spec.require_paths = ["lib"] 31 | 32 | # Uncomment to register a new dependency of your gem 33 | spec.add_dependency "testcontainers-core", "~> 0.1" 34 | 35 | spec.add_development_dependency "rake", "~> 13.0" 36 | spec.add_development_dependency "minitest", "~> 5.0" 37 | spec.add_development_dependency "minitest-hooks", "~> 1.5" 38 | spec.add_development_dependency "standard", "~> 1.3" 39 | 40 | # For more information and examples about making a new gem, check out our 41 | # guide at: https://bundler.io/guides/creating_gem.html 42 | end 43 | -------------------------------------------------------------------------------- /mariadb/testcontainers-mariadb.gemspec: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative "lib/testcontainers/mariadb/version" 4 | 5 | Gem::Specification.new do |spec| 6 | spec.name = "testcontainers-mariadb" 7 | spec.version = Testcontainers::Mariadb::VERSION 8 | spec.authors = ["Guillermo Iguaran"] 9 | spec.email = ["guilleiguaran@gmail.com"] 10 | 11 | spec.summary = "Testcontainers for Ruby: Mariadb module" 12 | spec.description = "Testcontainers makes it easy to create and clean up container-based dependencies for automated tests." 13 | spec.homepage = "https://github.com/testcontainers/testcontainers-ruby" 14 | spec.license = "MIT" 15 | spec.required_ruby_version = ">= 2.6.0" 16 | 17 | spec.metadata["homepage_uri"] = "#{spec.homepage}/blob/main/mariadb" 18 | spec.metadata["source_code_uri"] = "#{spec.homepage}/blob/main/mariadb" 19 | spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/main/mariadb/CHANGELOG.md" 20 | 21 | # Specify which files should be added to the gem when it is released. 22 | # The `git ls-files -z` loads the files in the RubyGem that have been added into git. 23 | spec.files = Dir.chdir(__dir__) do 24 | `git ls-files -z`.split("\x0").reject do |f| 25 | (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|circleci)|appveyor)}) 26 | end 27 | end 28 | spec.bindir = "exe" 29 | spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) } 30 | spec.require_paths = ["lib"] 31 | 32 | # Uncomment to register a new dependency of your gem 33 | spec.add_dependency "testcontainers-core", "~> 0.1" 34 | 35 | spec.add_development_dependency "rake", "~> 13.0" 36 | spec.add_development_dependency "minitest", "~> 5.0" 37 | spec.add_development_dependency "minitest-hooks", "~> 1.5" 38 | spec.add_development_dependency "standard", "~> 1.3" 39 | spec.add_development_dependency "mysql2", "~> 0.5.0" 40 | 41 | # For more information and examples about making a new gem, check out our 42 | # guide at: https://bundler.io/guides/creating_gem.html 43 | end 44 | -------------------------------------------------------------------------------- /redis/lib/testcontainers/redis.rb: -------------------------------------------------------------------------------- 1 | require_relative "redis/version" 2 | require "testcontainers" 3 | 4 | module Testcontainers 5 | # RedisContainer class is used to manage containers that run a Redis database 6 | class RedisContainer < ::Testcontainers::DockerContainer 7 | # Default port used by the container 8 | REDIS_DEFAULT_PORT = 6379 9 | 10 | # Default image used by the container 11 | REDIS_DEFAULT_IMAGE = "redis:latest" 12 | 13 | # Initializes a new instance of RedisContainer 14 | # 15 | # @param image [String] the image to use 16 | # @param port [String] the port to use 17 | # @param kwargs [Hash] the options to pass to the container. See {DockerContainer#initialize} 18 | # @return [RedisContainer] a new instance of RedisContainer 19 | def initialize(image = REDIS_DEFAULT_IMAGE, **kwargs) 20 | super 21 | add_wait_for(:logs, /Ready to accept connections/) unless wait_for_user_defined? 22 | end 23 | 24 | # Starts the container 25 | # 26 | # @return [RedisContainer] self 27 | def start 28 | with_exposed_ports(port) 29 | super 30 | end 31 | 32 | # Returns the port used by the container 33 | # 34 | # @return [Integer] the port used by the container 35 | def port 36 | REDIS_DEFAULT_PORT 37 | end 38 | 39 | # Returns the Redis connection url (e.g. redis://:password@localhost:6379/0) 40 | # 41 | # @param protocol [String] the protocol to use in the string (default: "redis") 42 | # @return [String] the Redis connection url 43 | # @raise [ConnectionError] If the connection to the Docker daemon fails. 44 | # @raise [ContainerNotStartedError] If the container has not been started. 45 | def redis_url(protocol: "redis", db: 0) 46 | if @password.nil? || @password.empty? 47 | "#{protocol}://#{host}:#{mapped_port(port)}/#{db}" 48 | else 49 | "#{protocol}://:#{password}@#{host}:#{mapped_port(port)}/#{db}" 50 | end 51 | end 52 | 53 | alias_method :database_url, :redis_url 54 | end 55 | end 56 | -------------------------------------------------------------------------------- /redpanda/testcontainers-redpanda.gemspec: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative "lib/testcontainers/redpanda/version" 4 | 5 | Gem::Specification.new do |spec| 6 | spec.name = "testcontainers-redpanda" 7 | spec.version = Testcontainers::Redpanda::VERSION 8 | spec.authors = ["Guillermo Iguaran"] 9 | spec.email = ["guilleiguaran@gmail.com"] 10 | 11 | spec.summary = "Testcontainers for Ruby: Redpanda module" 12 | spec.description = "Testcontainers makes it easy to create and clean up container-based dependencies for automated tests." 13 | spec.homepage = "https://github.com/testcontainers/testcontainers-ruby" 14 | spec.license = "MIT" 15 | spec.required_ruby_version = ">= 2.6.0" 16 | 17 | spec.metadata["homepage_uri"] = "#{spec.homepage}/blob/main/redpanda" 18 | spec.metadata["source_code_uri"] = "#{spec.homepage}/blob/main/redpanda" 19 | spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/main/redpanda/CHANGELOG.md" 20 | 21 | # Specify which files should be added to the gem when it is released. 22 | # The `git ls-files -z` loads the files in the RubyGem that have been added into git. 23 | spec.files = Dir.chdir(__dir__) do 24 | `git ls-files -z`.split("\x0").reject do |f| 25 | (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|circleci)|appveyor)}) 26 | end 27 | end 28 | spec.bindir = "exe" 29 | spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) } 30 | spec.require_paths = ["lib"] 31 | 32 | # Uncomment to register a new dependency of your gem 33 | spec.add_dependency "testcontainers-core", "~> 0.1" 34 | 35 | spec.add_development_dependency "rake", "~> 13.0" 36 | spec.add_development_dependency "minitest", "~> 5.0" 37 | spec.add_development_dependency "minitest-hooks", "~> 1.5" 38 | spec.add_development_dependency "standard", "~> 1.3" 39 | spec.add_development_dependency "rdkafka", "~> 0.12" 40 | 41 | # For more information and examples about making a new gem, check out our 42 | # guide at: https://bundler.io/guides/creating_gem.html 43 | end 44 | -------------------------------------------------------------------------------- /selenium/testcontainers-selenium.gemspec: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative "lib/testcontainers/selenium/version" 4 | 5 | Gem::Specification.new do |spec| 6 | spec.name = "testcontainers-selenium" 7 | spec.version = Testcontainers::Selenium::VERSION 8 | spec.authors = ["Guillermo Iguaran"] 9 | spec.email = ["guilleiguaran@gmail.com"] 10 | 11 | spec.summary = "Testcontainers for Ruby: Selenium module" 12 | spec.description = "Testcontainers makes it easy to create and clean up container-based dependencies for automated tests." 13 | spec.homepage = "https://github.com/testcontainers/testcontainers-ruby" 14 | spec.license = "MIT" 15 | spec.required_ruby_version = ">= 2.6.0" 16 | 17 | spec.metadata["homepage_uri"] = "#{spec.homepage}/blob/main/selenium" 18 | spec.metadata["source_code_uri"] = "#{spec.homepage}/blob/main/selenium" 19 | spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/main/selenium/CHANGELOG.md" 20 | 21 | # Specify which files should be added to the gem when it is released. 22 | # The `git ls-files -z` loads the files in the RubyGem that have been added into git. 23 | spec.files = Dir.chdir(__dir__) do 24 | `git ls-files -z`.split("\x0").reject do |f| 25 | (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|circleci)|appveyor)}) 26 | end 27 | end 28 | spec.bindir = "exe" 29 | spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) } 30 | spec.require_paths = ["lib"] 31 | 32 | # Uncomment to register a new dependency of your gem 33 | spec.add_dependency "testcontainers-core", "~> 0.1" 34 | 35 | spec.add_development_dependency "rake", "~> 13.0" 36 | spec.add_development_dependency "minitest", "~> 5.0" 37 | spec.add_development_dependency "minitest-hooks", "~> 1.5" 38 | spec.add_development_dependency "standard", "~> 1.3" 39 | spec.add_development_dependency "selenium-webdriver", "~> 4.1.0" 40 | 41 | # For more information and examples about making a new gem, check out our 42 | # guide at: https://bundler.io/guides/creating_gem.html 43 | end 44 | -------------------------------------------------------------------------------- /opensearch/testcontainers-opensearch.gemspec: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative "lib/testcontainers/opensearch/version" 4 | 5 | Gem::Specification.new do |spec| 6 | spec.name = "testcontainers-opensearch" 7 | spec.version = Testcontainers::Opensearch::VERSION 8 | spec.authors = ["Guillermo Iguaran"] 9 | spec.email = ["guilleiguaran@gmail.com"] 10 | 11 | spec.summary = "Testcontainers for Ruby: Opensearch module" 12 | spec.description = "Testcontainers makes it easy to create and clean up container-based dependencies for automated tests." 13 | spec.homepage = "https://github.com/testcontainers/testcontainers-ruby" 14 | spec.license = "MIT" 15 | spec.required_ruby_version = ">= 2.6.0" 16 | 17 | spec.metadata["homepage_uri"] = "#{spec.homepage}/blob/main/opensearch" 18 | spec.metadata["source_code_uri"] = "#{spec.homepage}/blob/main/opensearch" 19 | spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/main/opensearch/CHANGELOG.md" 20 | 21 | # Specify which files should be added to the gem when it is released. 22 | # The `git ls-files -z` loads the files in the RubyGem that have been added into git. 23 | spec.files = Dir.chdir(__dir__) do 24 | `git ls-files -z`.split("\x0").reject do |f| 25 | (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|circleci)|appveyor)}) 26 | end 27 | end 28 | spec.bindir = "exe" 29 | spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) } 30 | spec.require_paths = ["lib"] 31 | 32 | # Uncomment to register a new dependency of your gem 33 | spec.add_dependency "testcontainers-core", "~> 0.1" 34 | 35 | spec.add_development_dependency "rake", "~> 13.0" 36 | spec.add_development_dependency "minitest", "~> 5.0" 37 | spec.add_development_dependency "minitest-hooks", "~> 1.5" 38 | spec.add_development_dependency "standard", "~> 1.3" 39 | spec.add_development_dependency "opensearch-ruby", "~> 3.0" 40 | 41 | # For more information and examples about making a new gem, check out our 42 | # guide at: https://bundler.io/guides/creating_gem.html 43 | end 44 | -------------------------------------------------------------------------------- /postgres/testcontainers-postgres.gemspec: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative "lib/testcontainers/postgres/version" 4 | 5 | Gem::Specification.new do |spec| 6 | spec.name = "testcontainers-postgres" 7 | spec.version = Testcontainers::Postgres::VERSION 8 | spec.authors = ["Pedro Piza", "Guillermo Iguaran"] 9 | spec.email = ["pedro920224@gmail.com", "guilleiguaran@gmail.com"] 10 | 11 | spec.summary = "Testcontainers for Ruby: Postgres module" 12 | spec.description = "Testcontainers makes it easy to create and clean up container-based dependencies for automated tests." 13 | spec.homepage = "https://github.com/testcontainers/testcontainers-ruby" 14 | spec.license = "MIT" 15 | spec.required_ruby_version = ">= 2.6.0" 16 | 17 | spec.metadata["homepage_uri"] = "#{spec.homepage}/blob/main/postgres" 18 | spec.metadata["source_code_uri"] = "#{spec.homepage}/blob/main/postgres" 19 | spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/main/postgres/CHANGELOG.md" 20 | 21 | # Specify which files should be added to the gem when it is released. 22 | # The `git ls-files -z` loads the files in the RubyGem that have been added into git. 23 | spec.files = Dir.chdir(__dir__) do 24 | `git ls-files -z`.split("\x0").reject do |f| 25 | (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|circleci)|appveyor)}) 26 | end 27 | end 28 | spec.bindir = "exe" 29 | spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) } 30 | spec.require_paths = ["lib"] 31 | 32 | # Uncomment to register a new dependency of your gem 33 | spec.add_dependency "testcontainers-core", "~> 0.1" 34 | 35 | spec.add_development_dependency "rake", "~> 13.0" 36 | spec.add_development_dependency "minitest", "~> 5.0" 37 | spec.add_development_dependency "minitest-hooks", "~> 1.5" 38 | spec.add_development_dependency "standard", "~> 1.3" 39 | spec.add_development_dependency "pg", "~> 1.5" 40 | 41 | # For more information and examples about making a new gem, check out our 42 | # guide at: https://bundler.io/guides/creating_gem.html 43 | end 44 | -------------------------------------------------------------------------------- /rabbitmq/testcontainers-rabbitmq.gemspec: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative "lib/testcontainers/rabbitmq/version" 4 | 5 | Gem::Specification.new do |spec| 6 | spec.name = "testcontainers-rabbitmq" 7 | spec.version = Testcontainers::Rabbitmq::VERSION 8 | spec.authors = ["Pedro Piza", "Guillermo Iguaran"] 9 | spec.email = ["pedro920224@gmail.com", "guilleiguaran@gmail.com"] 10 | 11 | spec.summary = "Testcontainers for Ruby: Rabbitmq module" 12 | spec.description = "Testcontainers makes it easy to create and clean up container-based dependencies for automated tests." 13 | spec.homepage = "https://github.com/testcontainers/testcontainers-ruby" 14 | spec.license = "MIT" 15 | spec.required_ruby_version = ">= 2.6.0" 16 | 17 | spec.metadata["homepage_uri"] = "#{spec.homepage}/blob/main/rabbitmq" 18 | spec.metadata["source_code_uri"] = "#{spec.homepage}/blob/main/rabbitmq" 19 | spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/main/rabbitmq/CHANGELOG.md" 20 | 21 | # Specify which files should be added to the gem when it is released. 22 | # The `git ls-files -z` loads the files in the RubyGem that have been added into git. 23 | spec.files = Dir.chdir(__dir__) do 24 | `git ls-files -z`.split("\x0").reject do |f| 25 | (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|circleci)|appveyor)}) 26 | end 27 | end 28 | spec.bindir = "exe" 29 | spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) } 30 | spec.require_paths = ["lib"] 31 | 32 | # Uncomment to register a new dependency of your gem 33 | spec.add_dependency "testcontainers-core", "~> 0.1" 34 | 35 | spec.add_development_dependency "rake", "~> 13.0" 36 | spec.add_development_dependency "minitest", "~> 5.0" 37 | spec.add_development_dependency "minitest-hooks", "~> 1.5" 38 | spec.add_development_dependency "standard", "~> 1.3" 39 | spec.add_development_dependency "bunny", "~> 2.19" 40 | 41 | # For more information and examples about making a new gem, check out our 42 | # guide at: https://bundler.io/guides/creating_gem.html 43 | end 44 | -------------------------------------------------------------------------------- /core/test/docker_client_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "test_helper" 4 | require "tmpdir" 5 | 6 | class DockerClientTest < TestcontainersTest 7 | def setup 8 | super 9 | @original_env = ENV["TESTCONTAINERS_HOST"] 10 | ENV.delete("TESTCONTAINERS_HOST") 11 | Docker.reset! 12 | end 13 | 14 | def teardown 15 | Docker.reset! 16 | if @original_env 17 | ENV["TESTCONTAINERS_HOST"] = @original_env 18 | else 19 | ENV.delete("TESTCONTAINERS_HOST") 20 | end 21 | super 22 | end 23 | 24 | def test_connection_configures_user_agent_and_env_host 25 | ENV["TESTCONTAINERS_HOST"] = "tcp://example.test:2375" 26 | fake_connection = Object.new 27 | 28 | Docker::Connection.stub(:new, fake_connection) do 29 | connection = Testcontainers::DockerClient.connection 30 | assert_same fake_connection, connection 31 | end 32 | 33 | assert_equal "tcp://example.test:2375", Docker.url 34 | assert_equal "tc-ruby/#{Testcontainers::VERSION}", Docker.options[:headers]["User-Agent"] 35 | end 36 | 37 | def test_connection_reads_properties_file_when_env_absent 38 | Tempfile.create("tc-properties") do |file| 39 | file.write("tc.host=tcp://from-properties:1234\n") 40 | file.flush 41 | 42 | fake_connection = Object.new 43 | Docker::Connection.stub(:new, fake_connection) do 44 | Testcontainers::DockerClient.stub(:properties_path, file.path) do 45 | Testcontainers::DockerClient.connection 46 | end 47 | end 48 | 49 | assert_equal "tcp://from-properties:1234", Docker.url 50 | end 51 | end 52 | 53 | def test_configure_preserves_existing_connection_but_sets_user_agent 54 | existing_connection = Object.new 55 | Docker.instance_variable_set(:@connection, existing_connection) 56 | Docker.instance_variable_set(:@options, {}) 57 | 58 | connection = Testcontainers::DockerClient.connection 59 | 60 | assert_same existing_connection, connection 61 | assert_equal "tc-ruby/#{Testcontainers::VERSION}", Docker.options[:headers]["User-Agent"] 62 | end 63 | end 64 | -------------------------------------------------------------------------------- /elasticsearch/testcontainers-elasticsearch.gemspec: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative "lib/testcontainers/elasticsearch/version" 4 | 5 | Gem::Specification.new do |spec| 6 | spec.name = "testcontainers-elasticsearch" 7 | spec.version = Testcontainers::Elasticsearch::VERSION 8 | spec.authors = ["Guillermo Iguaran"] 9 | spec.email = ["guilleiguaran@gmail.com"] 10 | 11 | spec.summary = "Testcontainers for Ruby: Elasticsearch module" 12 | spec.description = "Testcontainers makes it easy to create and clean up container-based dependencies for automated tests." 13 | spec.homepage = "https://github.com/testcontainers/testcontainers-ruby" 14 | spec.license = "MIT" 15 | spec.required_ruby_version = ">= 2.6.0" 16 | 17 | spec.metadata["homepage_uri"] = "#{spec.homepage}/blob/main/elasticsearch" 18 | spec.metadata["source_code_uri"] = "#{spec.homepage}/blob/main/elasticsearch" 19 | spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/main/elasticsearch/CHANGELOG.md" 20 | 21 | # Specify which files should be added to the gem when it is released. 22 | # The `git ls-files -z` loads the files in the RubyGem that have been added into git. 23 | spec.files = Dir.chdir(__dir__) do 24 | `git ls-files -z`.split("\x0").reject do |f| 25 | (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|circleci)|appveyor)}) 26 | end 27 | end 28 | spec.bindir = "exe" 29 | spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) } 30 | spec.require_paths = ["lib"] 31 | 32 | # Uncomment to register a new dependency of your gem 33 | spec.add_dependency "testcontainers-core", "~> 0.1" 34 | 35 | spec.add_development_dependency "rake", "~> 13.0" 36 | spec.add_development_dependency "minitest", "~> 5.0" 37 | spec.add_development_dependency "minitest-hooks", "~> 1.5" 38 | spec.add_development_dependency "standard", "~> 1.3" 39 | spec.add_development_dependency "elasticsearch", "~> 8.7" 40 | 41 | # For more information and examples about making a new gem, check out our 42 | # guide at: https://bundler.io/guides/creating_gem.html 43 | end 44 | -------------------------------------------------------------------------------- /mongo/testcontainers-mongo.gemspec: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative "lib/testcontainers/mongo/version" 4 | 5 | Gem::Specification.new do |spec| 6 | spec.name = "testcontainers-mongo" 7 | spec.version = Testcontainers::Mongo::VERSION 8 | spec.authors = ["Pedro Piza", "Guillermo Iguaran"] 9 | spec.email = ["pedro920224@gmail.com", "guilleiguaran@gmail.com"] 10 | 11 | spec.summary = "Testcontainers for Ruby: Mongo module" 12 | spec.description = "Testcontainers makes it easy to create and clean up container-based dependencies for automated tests." 13 | spec.homepage = "https://github.com/testcontainers/testcontainers-ruby" 14 | spec.license = "MIT" 15 | spec.required_ruby_version = ">= 2.6.0" 16 | 17 | spec.metadata["homepage_uri"] = "#{spec.homepage}/blob/main/mongo" 18 | spec.metadata["source_code_uri"] = "#{spec.homepage}/blob/main/mongo" 19 | spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/main/mongo/CHANGELOG.md" 20 | 21 | # Specify which files should be added to the gem when it is released. 22 | # The `git ls-files -z` loads the files in the RubyGem that have been added into git. 23 | spec.files = Dir.chdir(__dir__) do 24 | `git ls-files -z`.split("\x0").reject do |f| 25 | (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|circleci)|appveyor)}) 26 | end 27 | end 28 | spec.bindir = "exe" 29 | spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) } 30 | spec.require_paths = ["lib"] 31 | 32 | # Uncomment to register a new dependency of your gem 33 | spec.add_dependency "testcontainers-core", "~> 0.1" 34 | 35 | spec.add_development_dependency "rake", "~> 13.0" 36 | spec.add_development_dependency "minitest", "~> 5.0" 37 | spec.add_development_dependency "minitest-hooks", "~> 1.5" 38 | spec.add_development_dependency "standard", "~> 1.3" 39 | spec.add_development_dependency "mongo", "~> 2.2" 40 | spec.add_development_dependency "bigdecimal", "~> 3.3" 41 | 42 | # For more information and examples about making a new gem, check out our 43 | # guide at: https://bundler.io/guides/creating_gem.html 44 | end 45 | -------------------------------------------------------------------------------- /elasticsearch/test/elasticsearch_container_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "test_helper" 4 | require "elasticsearch" 5 | 6 | class ElasticsearchContainerTest < TestcontainersTest 7 | def before_all 8 | super 9 | 10 | @container = Testcontainers::ElasticsearchContainer.new 11 | @container.start 12 | @host = @container.host 13 | @http_port = @container.mapped_port(@container.http_port) 14 | end 15 | 16 | def after_all 17 | if @container&.exists? 18 | @container&.stop if @container&.running? 19 | @container&.remove 20 | end 21 | 22 | super 23 | end 24 | 25 | def test_it_returns_the_default_image 26 | assert_equal "docker.elastic.co/elasticsearch/elasticsearch:8.7.1", @container.image 27 | end 28 | 29 | def test_it_supports_custom_image 30 | container = Testcontainers::ElasticsearchContainer.new("docker.elastic.co/elasticsearch/elasticsearch:7.17.10") 31 | assert_equal "docker.elastic.co/elasticsearch/elasticsearch:7.17.10", container.image 32 | end 33 | 34 | def test_it_returns_the_default_http_port 35 | assert_equal 9200, @container.http_port 36 | end 37 | 38 | def test_it_returns_the_default_tcp_port 39 | assert_equal 9300, @container.tcp_port 40 | end 41 | 42 | def test_it_has_the_default_ports_mapped 43 | assert @container.mapped_port(9200) 44 | assert @container.mapped_port(9300) 45 | end 46 | 47 | def test_it_returns_the_default_elasticsearch_url 48 | assert_equal "http://elastic:elastic@#{@host}:#{@http_port}", @container.elasticsearch_url 49 | end 50 | 51 | def test_it_returns_the_elasticsearch_url_with_custom_protocol 52 | assert_equal "https://elastic:elastic@#{@host}:#{@http_port}", @container.elasticsearch_url(protocol: "https") 53 | end 54 | 55 | def test_it_returns_the_elasticsearch_url_with_custom_username_and_password 56 | assert_equal "http://foo:bar@#{@host}:#{@http_port}", @container.elasticsearch_url(username: "foo", password: "bar") 57 | end 58 | 59 | def test_it_is_reachable 60 | client = Elasticsearch::Client.new(url: @container.elasticsearch_url) 61 | assert client.ping 62 | end 63 | end 64 | -------------------------------------------------------------------------------- /opensearch/test/opensearch_container_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "test_helper" 4 | require "opensearch-ruby" 5 | 6 | class OpensearchContainerTest < TestcontainersTest 7 | def setup 8 | super 9 | @container = Testcontainers::OpensearchContainer.new 10 | end 11 | 12 | def teardown 13 | if @container&.exists? 14 | @container&.stop if @container&.running? 15 | @container&.remove 16 | end 17 | 18 | super 19 | end 20 | 21 | def test_it_returns_the_default_image 22 | assert_equal "opensearchproject/opensearch:2.12.0", @container.image 23 | end 24 | 25 | def test_it_supports_custom_image 26 | container = Testcontainers::OpensearchContainer.new("opensearchproject/opensearch:2.11.1") 27 | assert_equal "opensearchproject/opensearch:2.11.1", container.image 28 | end 29 | 30 | def test_it_returns_the_default_http_port 31 | assert_equal 9200, @container.http_port 32 | end 33 | 34 | def test_it_returns_the_default_metrics_port 35 | assert_equal 9600, @container.metrics_port 36 | end 37 | 38 | def test_running_container_behaviour 39 | run_with_container do |container| 40 | host = container.host 41 | http_port = container.mapped_port(container.http_port) 42 | 43 | assert container.mapped_port(9200) 44 | assert container.mapped_port(9600) 45 | assert_equal "http://#{host}:#{http_port}", container.opensearch_url 46 | assert_equal "https://#{host}:#{http_port}", container.opensearch_url(protocol: "https") 47 | client = OpenSearch::Client.new(url: container.opensearch_url) 48 | assert client.ping 49 | end 50 | end 51 | 52 | private 53 | 54 | def run_with_container 55 | @container.start 56 | begin 57 | @container.wait_for_http(container_port: @container.http_port, path: "/_cluster/health", timeout: 180, interval: 1, status: 200) 58 | yield(@container) 59 | rescue Testcontainers::TimeoutError => e 60 | skip("OpenSearch container unavailable: #{e.message}") 61 | end 62 | ensure 63 | if @container&.exists? 64 | @container.stop if @container&.running? 65 | @container.remove 66 | end 67 | end 68 | end 69 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Testcontainers 2 | 3 | TestContainers is composed of modules for common databases and services. This changelog only notes changes to the collection of modules. See the individual module changelogs for detailed information: 4 | 5 | - [DockerContainer (core)](https://github.com/testcontainers/testcontainers-ruby/tree/main/core/CHANGELOG.md) 6 | 7 | - [ComposeContainer](https://github.com/testcontainers/testcontainers-ruby/tree/main/compose/CHANGELOG.md) 8 | 9 | - [ElasticsearchContainer](https://github.com/testcontainers/testcontainers-ruby/tree/main/elasticsearch/CHANGELOG.md) 10 | - [OpensearchContainer](https://github.com/testcontainers/testcontainers-ruby/tree/main/opensearch/CHANGELOG.md) 11 | - [KafkaContainer](https://github.com/testcontainers/testcontainers-ruby/tree/main/kafka/CHANGELOG.md) 12 | 13 | - [MariadbContainer](https://github.com/testcontainers/testcontainers-ruby/tree/main/mariadb/CHANGELOG.md) 14 | 15 | - [MongoContainer](https://github.com/testcontainers/testcontainers-ruby/tree/main/mongo/CHANGELOG.md) 16 | 17 | - [MysqlContainer](https://github.com/testcontainers/testcontainers-ruby/tree/main/mysql/CHANGELOG.md) 18 | 19 | - [NginxContainer](https://github.com/testcontainers/testcontainers-ruby/tree/main/nginx/CHANGELOG.md) 20 | 21 | - [PostgresContainer](https://github.com/testcontainers/testcontainers-ruby/tree/main/postgres/CHANGELOG.md) 22 | 23 | - [RabbitmqContainer](https://github.com/testcontainers/testcontainers-ruby/tree/main/rabbitmq/CHANGELOG.md) 24 | 25 | - [RedisContainer](https://github.com/testcontainers/testcontainers-ruby/tree/main/redis/CHANGELOG.md) 26 | 27 | - [RedpandaContainer](https://github.com/testcontainers/testcontainers-ruby/tree/main/redpanda/CHANGELOG.md) 28 | 29 | - [SeleniumContainer](https://github.com/testcontainers/testcontainers-ruby/tree/main/selenium/CHANGELOG.md) 30 | 31 | ## [0.2.0] - 2024-02-08 32 | 33 | ### Added 34 | 35 | - ComposeContainer. See the [testcontainers-compose readme](https://github.com/testcontainers/testcontainers-ruby/tree/main/compose/README.md) for more information. 36 | - SeleniumContainer. See the [testcontainers-selenium readme](https://github.com/testcontainers/testcontainers-ruby/tree/main/selenium/README.md) for more information. 37 | -------------------------------------------------------------------------------- /core/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [0.2.0] - 2024-02-08 2 | 3 | ### Added 4 | 5 | - DockerContainer#new now accepts optional keyword argument `image_create_options` which accepts a hash. Passes the options to `Docker::Image.create`. See the [Docker ImageCreate api](https://docs.docker.com/engine/api/v1.43/#tag/Image/operation/ImageCreate) for available parameters. 6 | 7 | - DockerContainer#remove now accepts an optional options hash. See the [Docker ContainerDelete api](https://docs.docker.com/engine/api/v1.43/#tag/Container/operation/ContainerDelete) for available parameters. 8 | 9 | ## [0.1.3] - 2023-06-10 10 | 11 | ### Added 12 | 13 | - Support for entrypoint customization and the DockerContainer#with_entrypoint method 14 | 15 | - Methods to read/write strings from and to containers: read_file, store_file 16 | 17 | - Methods to copy files from and to containers: copy_file_from_container, copy_file_to_container 18 | 19 | - Support for waiting strategies on start 20 | 21 | - DockerContainer#with_exposed_port (singular) for convenience 22 | 23 | - GenericContainer as alias for DockerContainer 24 | 25 | ### Fixed 26 | 27 | - DockerContainer#add_exposed_ports don't override PortBinding settings added by #add_fixed_exposed_port 28 | 29 | 30 | ## [0.1.2] - 2023-05-13 31 | 32 | ### Added 33 | 34 | - DockerContainer#first_mapped_port method returns the first of the 35 | mapped ports for convenience. 36 | 37 | - DockerContainer#get_env(key) method to gets the value of a single 38 | env variable in the container 39 | 40 | - Support custom healthchecks set with the new and 41 | DockerContainer#add_/with_healthcheck methods. Example: 42 | 43 | redis_container.with_healthcheck(test: ["redis-cli ping"], interval: 30, timeout: 30, retries: 3) 44 | 45 | ### Changed 46 | 47 | - DockerContainer#mapped_port(port) method now returns an Integer instead of a String. 48 | 49 | ### Fixed 50 | 51 | - Links to the GitHub project on the README.md file are fixed. 52 | 53 | - Healtchecks handling have been fixed 54 | 55 | ## [0.1.1] - 2023-05-04 56 | 57 | ### Added 58 | 59 | - Add .yardopts file to set the project ready for RubyDoc.info. 60 | 61 | ## [0.1.0] - 2023-05-04 62 | 63 | ### Added 64 | 65 | - Initial release of the project with the Testcontainer::DockerContainer working. 66 | -------------------------------------------------------------------------------- /core/Gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: . 3 | specs: 4 | testcontainers-core (0.2.0) 5 | base64 (~> 0.3) 6 | docker-api (~> 2.4) 7 | java-properties (~> 0.3.0) 8 | 9 | GEM 10 | remote: https://rubygems.org/ 11 | specs: 12 | ast (2.4.3) 13 | base64 (0.3.0) 14 | docker-api (2.4.0) 15 | excon (>= 0.64.0) 16 | multi_json 17 | excon (1.3.0) 18 | logger 19 | java-properties (0.3.0) 20 | json (2.15.1) 21 | language_server-protocol (3.17.0.5) 22 | lint_roller (1.1.0) 23 | logger (1.7.0) 24 | minitest (5.26.0) 25 | minitest-hooks (1.5.0) 26 | minitest (> 5.3) 27 | multi_json (1.17.0) 28 | parallel (1.27.0) 29 | parser (3.3.9.0) 30 | ast (~> 2.4.1) 31 | racc 32 | prism (1.6.0) 33 | racc (1.8.1) 34 | rainbow (3.1.1) 35 | rake (13.0.6) 36 | regexp_parser (2.11.3) 37 | rubocop (1.80.2) 38 | json (~> 2.3) 39 | language_server-protocol (~> 3.17.0.2) 40 | lint_roller (~> 1.1.0) 41 | parallel (~> 1.10) 42 | parser (>= 3.3.0.2) 43 | rainbow (>= 2.2.2, < 4.0) 44 | regexp_parser (>= 2.9.3, < 3.0) 45 | rubocop-ast (>= 1.46.0, < 2.0) 46 | ruby-progressbar (~> 1.7) 47 | unicode-display_width (>= 2.4.0, < 4.0) 48 | rubocop-ast (1.47.1) 49 | parser (>= 3.3.7.2) 50 | prism (~> 1.4) 51 | rubocop-performance (1.25.0) 52 | lint_roller (~> 1.1) 53 | rubocop (>= 1.75.0, < 2.0) 54 | rubocop-ast (>= 1.38.0, < 2.0) 55 | ruby-progressbar (1.13.0) 56 | standard (1.51.1) 57 | language_server-protocol (~> 3.17.0.2) 58 | lint_roller (~> 1.0) 59 | rubocop (~> 1.80.2) 60 | standard-custom (~> 1.0.0) 61 | standard-performance (~> 1.8) 62 | standard-custom (1.0.2) 63 | lint_roller (~> 1.0) 64 | rubocop (~> 1.50) 65 | standard-performance (1.8.0) 66 | lint_roller (~> 1.1) 67 | rubocop-performance (~> 1.25.0) 68 | unicode-display_width (3.2.0) 69 | unicode-emoji (~> 4.1) 70 | unicode-emoji (4.1.0) 71 | 72 | PLATFORMS 73 | arm64-darwin-21 74 | ruby 75 | x86_64-linux 76 | 77 | DEPENDENCIES 78 | minitest (~> 5.0) 79 | minitest-hooks (~> 1.5) 80 | rake (~> 13.0) 81 | standard (~> 1.3) 82 | testcontainers-core! 83 | 84 | BUNDLED WITH 85 | 2.4.1 86 | -------------------------------------------------------------------------------- /redpanda/test/redpanda_container_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "test_helper" 4 | require "rdkafka" 5 | 6 | class RedpandaContainerTest < TestcontainersTest 7 | def before_all 8 | super 9 | 10 | @container = Testcontainers::RedpandaContainer.new 11 | @container.start 12 | @container.wait_for_tcp_port(9092) 13 | @host = @container.host 14 | @port = @container.mapped_port(9092) 15 | @schema_registry_port = @container.mapped_port(8081) 16 | end 17 | 18 | def after_all 19 | if @container&.exists? 20 | @container&.stop if @container&.running? 21 | @container&.remove 22 | end 23 | 24 | super 25 | end 26 | 27 | def test_it_returns_the_default_image 28 | assert_equal "redpandadata/redpanda:latest", @container.image 29 | end 30 | 31 | def test_it_supports_custom_image 32 | container = Testcontainers::RedpandaContainer.new("vectorized/redpanda:latest") 33 | assert_equal "vectorized/redpanda:latest", container.image 34 | end 35 | 36 | def test_it_returns_the_default_port 37 | assert_equal 9092, @container.port 38 | end 39 | 40 | def test_it_has_the_default_port_mapped 41 | assert @container.mapped_port(9092) 42 | end 43 | 44 | def test_it_returns_the_connection_url 45 | assert_equal "#{@host}:#{@port}", @container.connection_url 46 | end 47 | 48 | def test_it_returns_bootstrap_servers 49 | assert_equal "PLAINTEXT://#{@host}:#{@port}", @container.bootstrap_servers 50 | end 51 | 52 | def test_it_returns_the_schema_registry_address 53 | assert_equal "http://#{@host}:#{@schema_registry_port}", @container.schema_registry_address 54 | end 55 | 56 | def test_it_is_reachable 57 | config = { 58 | "bootstrap.servers": @container.connection_url, 59 | "group.id": "ruby-test", 60 | "auto.offset.reset": "earliest" 61 | } 62 | 63 | producer = Rdkafka::Config.new(config).producer 64 | producer.produce(payload: "Hello, Redpanda!", topic: "ruby-test-topic").wait 65 | 66 | consumer = Rdkafka::Config.new(config).consumer 67 | consumer.subscribe("ruby-test-topic") 68 | 69 | message = consumer.each do |msg| 70 | break msg 71 | end 72 | 73 | assert_equal "Hello, Redpanda!", message.payload 74 | assert_equal "ruby-test-topic", message.topic 75 | end 76 | end 77 | -------------------------------------------------------------------------------- /examples/wkhtmltopdf_rspec.rb: -------------------------------------------------------------------------------- 1 | require "bundler/inline" 2 | 3 | gemfile do 4 | source "https://rubygems.org" 5 | gem "rspec" 6 | gem "wkhtmltopdf-binary" 7 | gem "testcontainers-core", path: "../core", require: "testcontainers" 8 | group :test do 9 | gem "webmock" 10 | end 11 | end 12 | 13 | require "rspec" 14 | require "rspec/autorun" 15 | require "webmock/rspec" 16 | 17 | RSpec.configure do |config| 18 | end 19 | 20 | RSpec::Matchers.define :exist_file do 21 | match do |file_path| 22 | File.exist?(file_path) 23 | end 24 | end 25 | 26 | describe "Wkhtmltopdf Example" do 27 | let(:url) { "https://getbootstrap.com/docs/5.3/examples/sticky-footer/" } 28 | let(:host_tmp_dir) { "#{__dir__}/tmp" } 29 | let(:container_tmp_dir) { "/tmp" } 30 | let(:file_name) { "document.pdf" } 31 | let(:file_path) { "#{host_tmp_dir}/#{file_name}" } 32 | let(:container_file_path) { "#{container_tmp_dir}/#{file_name}" } 33 | # wkhtmltopdf typically expects 'wkhtmltopdf [url] [output]' as command 34 | let(:container) do 35 | Testcontainers::DockerContainer.new("surnet/alpine-wkhtmltopdf:3.17.0-0.12.6-small") 36 | .with_entrypoint("wkhtmltopdf") 37 | .with_command([url, container_file_path]) 38 | end 39 | 40 | before do 41 | FileUtils.mkdir_p(host_tmp_dir) 42 | WebMock.allow_net_connect! 43 | container.with_filesystem_binds(["#{host_tmp_dir}:#{container_tmp_dir}:rw"]) 44 | stub_request(:get, url).to_return( 45 | body: File.read("#{__dir__}/fixtures/web_page/index.html") 46 | ) 47 | end 48 | 49 | after(:each) do 50 | WebMock.allow_net_connect! 51 | if container.running? 52 | puts "Container logs: #{container.logs}" 53 | container.stop 54 | end 55 | container&.remove 56 | FileUtils.rm_f(file_path) 57 | end 58 | 59 | context "when using html" do 60 | it "generates a PDF page" do 61 | container.start 62 | # Wait with a timeout and check periodically 63 | 10.times do |i| 64 | break if File.exist?(file_path) 65 | puts "Waiting for PDF (attempt #{i + 1}/10)..." 66 | sleep 1 67 | end 68 | 69 | puts "Checking for file at: #{file_path}" 70 | puts "File exists? #{File.exist?(file_path)}" 71 | puts "Directory contents: #{Dir.entries(host_tmp_dir)}" 72 | 73 | expect(file_path).to exist_file 74 | end 75 | end 76 | end 77 | -------------------------------------------------------------------------------- /nginx/Gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: ../core 3 | specs: 4 | testcontainers-core (0.2.0) 5 | base64 (~> 0.3) 6 | docker-api (~> 2.4) 7 | java-properties (~> 0.3.0) 8 | 9 | PATH 10 | remote: . 11 | specs: 12 | testcontainers-nginx (0.2.0) 13 | testcontainers-core (~> 0.1) 14 | 15 | GEM 16 | remote: https://rubygems.org/ 17 | specs: 18 | ast (2.4.3) 19 | base64 (0.3.0) 20 | docker-api (2.4.0) 21 | excon (>= 0.64.0) 22 | multi_json 23 | excon (0.99.0) 24 | java-properties (0.3.0) 25 | json (2.15.1) 26 | language_server-protocol (3.17.0.5) 27 | lint_roller (1.1.0) 28 | minitest (5.26.0) 29 | minitest-hooks (1.5.0) 30 | minitest (> 5.3) 31 | multi_json (1.15.0) 32 | parallel (1.27.0) 33 | parser (3.3.9.0) 34 | ast (~> 2.4.1) 35 | racc 36 | prism (1.6.0) 37 | racc (1.8.1) 38 | rainbow (3.1.1) 39 | rake (13.0.6) 40 | regexp_parser (2.11.3) 41 | rubocop (1.80.2) 42 | json (~> 2.3) 43 | language_server-protocol (~> 3.17.0.2) 44 | lint_roller (~> 1.1.0) 45 | parallel (~> 1.10) 46 | parser (>= 3.3.0.2) 47 | rainbow (>= 2.2.2, < 4.0) 48 | regexp_parser (>= 2.9.3, < 3.0) 49 | rubocop-ast (>= 1.46.0, < 2.0) 50 | ruby-progressbar (~> 1.7) 51 | unicode-display_width (>= 2.4.0, < 4.0) 52 | rubocop-ast (1.47.1) 53 | parser (>= 3.3.7.2) 54 | prism (~> 1.4) 55 | rubocop-performance (1.25.0) 56 | lint_roller (~> 1.1) 57 | rubocop (>= 1.75.0, < 2.0) 58 | rubocop-ast (>= 1.38.0, < 2.0) 59 | ruby-progressbar (1.13.0) 60 | standard (1.51.1) 61 | language_server-protocol (~> 3.17.0.2) 62 | lint_roller (~> 1.0) 63 | rubocop (~> 1.80.2) 64 | standard-custom (~> 1.0.0) 65 | standard-performance (~> 1.8) 66 | standard-custom (1.0.2) 67 | lint_roller (~> 1.0) 68 | rubocop (~> 1.50) 69 | standard-performance (1.8.0) 70 | lint_roller (~> 1.1) 71 | rubocop-performance (~> 1.25.0) 72 | unicode-display_width (3.2.0) 73 | unicode-emoji (~> 4.1) 74 | unicode-emoji (4.1.0) 75 | 76 | PLATFORMS 77 | arm64-darwin-21 78 | ruby 79 | 80 | DEPENDENCIES 81 | minitest (~> 5.0) 82 | minitest-hooks (~> 1.5) 83 | rake (~> 13.0) 84 | standard (~> 1.3) 85 | testcontainers-core! 86 | testcontainers-nginx! 87 | 88 | BUNDLED WITH 89 | 2.4.1 90 | -------------------------------------------------------------------------------- /compose/Gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: ../core 3 | specs: 4 | testcontainers-core (0.2.0) 5 | base64 (~> 0.3) 6 | docker-api (~> 2.4) 7 | java-properties (~> 0.3.0) 8 | 9 | PATH 10 | remote: . 11 | specs: 12 | testcontainers-compose (0.2.0) 13 | testcontainers-core (~> 0.1) 14 | 15 | GEM 16 | remote: https://rubygems.org/ 17 | specs: 18 | ast (2.4.3) 19 | base64 (0.3.0) 20 | docker-api (2.4.0) 21 | excon (>= 0.64.0) 22 | multi_json 23 | excon (0.100.0) 24 | java-properties (0.3.0) 25 | json (2.15.1) 26 | language_server-protocol (3.17.0.5) 27 | lint_roller (1.1.0) 28 | minitest (5.26.0) 29 | minitest-hooks (1.5.0) 30 | minitest (> 5.3) 31 | multi_json (1.15.0) 32 | parallel (1.27.0) 33 | parser (3.3.9.0) 34 | ast (~> 2.4.1) 35 | racc 36 | prism (1.6.0) 37 | racc (1.8.1) 38 | rainbow (3.1.1) 39 | rake (13.0.6) 40 | regexp_parser (2.11.3) 41 | rubocop (1.80.2) 42 | json (~> 2.3) 43 | language_server-protocol (~> 3.17.0.2) 44 | lint_roller (~> 1.1.0) 45 | parallel (~> 1.10) 46 | parser (>= 3.3.0.2) 47 | rainbow (>= 2.2.2, < 4.0) 48 | regexp_parser (>= 2.9.3, < 3.0) 49 | rubocop-ast (>= 1.46.0, < 2.0) 50 | ruby-progressbar (~> 1.7) 51 | unicode-display_width (>= 2.4.0, < 4.0) 52 | rubocop-ast (1.47.1) 53 | parser (>= 3.3.7.2) 54 | prism (~> 1.4) 55 | rubocop-performance (1.25.0) 56 | lint_roller (~> 1.1) 57 | rubocop (>= 1.75.0, < 2.0) 58 | rubocop-ast (>= 1.38.0, < 2.0) 59 | ruby-progressbar (1.13.0) 60 | standard (1.51.1) 61 | language_server-protocol (~> 3.17.0.2) 62 | lint_roller (~> 1.0) 63 | rubocop (~> 1.80.2) 64 | standard-custom (~> 1.0.0) 65 | standard-performance (~> 1.8) 66 | standard-custom (1.0.2) 67 | lint_roller (~> 1.0) 68 | rubocop (~> 1.50) 69 | standard-performance (1.8.0) 70 | lint_roller (~> 1.1) 71 | rubocop-performance (~> 1.25.0) 72 | unicode-display_width (3.2.0) 73 | unicode-emoji (~> 4.1) 74 | unicode-emoji (4.1.0) 75 | 76 | PLATFORMS 77 | arm64-darwin-21 78 | ruby 79 | x86_64-linux 80 | 81 | DEPENDENCIES 82 | minitest (~> 5.0) 83 | minitest-hooks (~> 1.5) 84 | rake (~> 13.0) 85 | standard (~> 1.3) 86 | testcontainers-compose! 87 | testcontainers-core! 88 | 89 | BUNDLED WITH 90 | 2.6.9 91 | -------------------------------------------------------------------------------- /core/README.md: -------------------------------------------------------------------------------- 1 | # Testcontainers 2 | 3 | TODO: Delete this and the text below, and describe your gem 4 | 5 | Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/testcontainers`. To experiment with that code, run `bin/console` for an interactive prompt. 6 | 7 | ## Installation 8 | 9 | TODO: Replace `UPDATE_WITH_YOUR_GEM_NAME_PRIOR_TO_RELEASE_TO_RUBYGEMS_ORG` with your gem name right after releasing it to RubyGems.org. Please do not do it earlier due to security reasons. Alternatively, replace this section with instructions to install your gem from git if you don't plan to release to RubyGems.org. 10 | 11 | Install the gem and add to the application's Gemfile by executing: 12 | 13 | $ bundle add UPDATE_WITH_YOUR_GEM_NAME_PRIOR_TO_RELEASE_TO_RUBYGEMS_ORG 14 | 15 | If bundler is not being used to manage dependencies, install the gem by executing: 16 | 17 | $ gem install UPDATE_WITH_YOUR_GEM_NAME_PRIOR_TO_RELEASE_TO_RUBYGEMS_ORG 18 | 19 | ## Usage 20 | 21 | TODO: Write usage instructions here 22 | 23 | ## Development 24 | 25 | After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment. 26 | 27 | To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org). 28 | 29 | ## Contributing 30 | 31 | Bug reports and pull requests are welcome on GitHub at https://github.com/testcontainers/testcontainers-ruby. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/testcontainers/testcontainers-ruby/blob/main/CODE_OF_CONDUCT.md). 32 | 33 | ## License 34 | 35 | The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT). 36 | 37 | ## Code of Conduct 38 | 39 | Everyone interacting in the Testcontainers project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/testcontainers/testcontainers-ruby/blob/main/CODE_OF_CONDUCT.md). 40 | -------------------------------------------------------------------------------- /postgres/Gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: ../core 3 | specs: 4 | testcontainers-core (0.2.0) 5 | base64 (~> 0.3) 6 | docker-api (~> 2.4) 7 | java-properties (~> 0.3.0) 8 | 9 | PATH 10 | remote: . 11 | specs: 12 | testcontainers-postgres (0.2.0) 13 | testcontainers-core (~> 0.1) 14 | 15 | GEM 16 | remote: https://rubygems.org/ 17 | specs: 18 | ast (2.4.3) 19 | base64 (0.3.0) 20 | docker-api (2.4.0) 21 | excon (>= 0.64.0) 22 | multi_json 23 | excon (0.99.0) 24 | java-properties (0.3.0) 25 | json (2.15.1) 26 | language_server-protocol (3.17.0.5) 27 | lint_roller (1.1.0) 28 | minitest (5.26.0) 29 | minitest-hooks (1.5.0) 30 | minitest (> 5.3) 31 | multi_json (1.15.0) 32 | parallel (1.27.0) 33 | parser (3.3.9.0) 34 | ast (~> 2.4.1) 35 | racc 36 | pg (1.5.3) 37 | prism (1.6.0) 38 | racc (1.8.1) 39 | rainbow (3.1.1) 40 | rake (13.0.6) 41 | regexp_parser (2.11.3) 42 | rubocop (1.80.2) 43 | json (~> 2.3) 44 | language_server-protocol (~> 3.17.0.2) 45 | lint_roller (~> 1.1.0) 46 | parallel (~> 1.10) 47 | parser (>= 3.3.0.2) 48 | rainbow (>= 2.2.2, < 4.0) 49 | regexp_parser (>= 2.9.3, < 3.0) 50 | rubocop-ast (>= 1.46.0, < 2.0) 51 | ruby-progressbar (~> 1.7) 52 | unicode-display_width (>= 2.4.0, < 4.0) 53 | rubocop-ast (1.47.1) 54 | parser (>= 3.3.7.2) 55 | prism (~> 1.4) 56 | rubocop-performance (1.25.0) 57 | lint_roller (~> 1.1) 58 | rubocop (>= 1.75.0, < 2.0) 59 | rubocop-ast (>= 1.38.0, < 2.0) 60 | ruby-progressbar (1.13.0) 61 | standard (1.51.1) 62 | language_server-protocol (~> 3.17.0.2) 63 | lint_roller (~> 1.0) 64 | rubocop (~> 1.80.2) 65 | standard-custom (~> 1.0.0) 66 | standard-performance (~> 1.8) 67 | standard-custom (1.0.2) 68 | lint_roller (~> 1.0) 69 | rubocop (~> 1.50) 70 | standard-performance (1.8.0) 71 | lint_roller (~> 1.1) 72 | rubocop-performance (~> 1.25.0) 73 | unicode-display_width (3.2.0) 74 | unicode-emoji (~> 4.1) 75 | unicode-emoji (4.1.0) 76 | 77 | PLATFORMS 78 | arm64-darwin-21 79 | ruby 80 | x86_64-darwin-22 81 | 82 | DEPENDENCIES 83 | minitest (~> 5.0) 84 | minitest-hooks (~> 1.5) 85 | pg (~> 1.5) 86 | rake (~> 13.0) 87 | standard (~> 1.3) 88 | testcontainers-core! 89 | testcontainers-postgres! 90 | 91 | BUNDLED WITH 92 | 2.4.1 93 | -------------------------------------------------------------------------------- /mysql/Gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: ../core 3 | specs: 4 | testcontainers-core (0.2.0) 5 | base64 (~> 0.3) 6 | docker-api (~> 2.4) 7 | java-properties (~> 0.3.0) 8 | 9 | PATH 10 | remote: . 11 | specs: 12 | testcontainers-mysql (0.2.0) 13 | testcontainers-core (~> 0.1) 14 | 15 | GEM 16 | remote: https://rubygems.org/ 17 | specs: 18 | ast (2.4.3) 19 | base64 (0.3.0) 20 | bigdecimal (3.3.1) 21 | docker-api (2.4.0) 22 | excon (>= 0.64.0) 23 | multi_json 24 | excon (0.99.0) 25 | java-properties (0.3.0) 26 | json (2.15.1) 27 | language_server-protocol (3.17.0.5) 28 | lint_roller (1.1.0) 29 | minitest (5.26.0) 30 | minitest-hooks (1.5.0) 31 | minitest (> 5.3) 32 | multi_json (1.15.0) 33 | mysql2 (0.5.7) 34 | bigdecimal 35 | parallel (1.27.0) 36 | parser (3.3.9.0) 37 | ast (~> 2.4.1) 38 | racc 39 | prism (1.6.0) 40 | racc (1.8.1) 41 | rainbow (3.1.1) 42 | rake (13.0.6) 43 | regexp_parser (2.11.3) 44 | rubocop (1.80.2) 45 | json (~> 2.3) 46 | language_server-protocol (~> 3.17.0.2) 47 | lint_roller (~> 1.1.0) 48 | parallel (~> 1.10) 49 | parser (>= 3.3.0.2) 50 | rainbow (>= 2.2.2, < 4.0) 51 | regexp_parser (>= 2.9.3, < 3.0) 52 | rubocop-ast (>= 1.46.0, < 2.0) 53 | ruby-progressbar (~> 1.7) 54 | unicode-display_width (>= 2.4.0, < 4.0) 55 | rubocop-ast (1.47.1) 56 | parser (>= 3.3.7.2) 57 | prism (~> 1.4) 58 | rubocop-performance (1.25.0) 59 | lint_roller (~> 1.1) 60 | rubocop (>= 1.75.0, < 2.0) 61 | rubocop-ast (>= 1.38.0, < 2.0) 62 | ruby-progressbar (1.13.0) 63 | standard (1.51.1) 64 | language_server-protocol (~> 3.17.0.2) 65 | lint_roller (~> 1.0) 66 | rubocop (~> 1.80.2) 67 | standard-custom (~> 1.0.0) 68 | standard-performance (~> 1.8) 69 | standard-custom (1.0.2) 70 | lint_roller (~> 1.0) 71 | rubocop (~> 1.50) 72 | standard-performance (1.8.0) 73 | lint_roller (~> 1.1) 74 | rubocop-performance (~> 1.25.0) 75 | unicode-display_width (3.2.0) 76 | unicode-emoji (~> 4.1) 77 | unicode-emoji (4.1.0) 78 | 79 | PLATFORMS 80 | arm64-darwin-21 81 | ruby 82 | 83 | DEPENDENCIES 84 | minitest (~> 5.0) 85 | minitest-hooks (~> 1.5) 86 | mysql2 (~> 0.5.0) 87 | rake (~> 13.0) 88 | standard (~> 1.3) 89 | testcontainers-core! 90 | testcontainers-mysql! 91 | 92 | BUNDLED WITH 93 | 2.4.1 94 | -------------------------------------------------------------------------------- /mariadb/Gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: ../core 3 | specs: 4 | testcontainers-core (0.2.0) 5 | base64 (~> 0.3) 6 | docker-api (~> 2.4) 7 | java-properties (~> 0.3.0) 8 | 9 | PATH 10 | remote: . 11 | specs: 12 | testcontainers-mariadb (0.2.0) 13 | testcontainers-core (~> 0.1) 14 | 15 | GEM 16 | remote: https://rubygems.org/ 17 | specs: 18 | ast (2.4.3) 19 | base64 (0.3.0) 20 | bigdecimal (3.3.1) 21 | docker-api (2.4.0) 22 | excon (>= 0.64.0) 23 | multi_json 24 | excon (0.99.0) 25 | java-properties (0.3.0) 26 | json (2.15.1) 27 | language_server-protocol (3.17.0.5) 28 | lint_roller (1.1.0) 29 | minitest (5.26.0) 30 | minitest-hooks (1.5.0) 31 | minitest (> 5.3) 32 | multi_json (1.15.0) 33 | mysql2 (0.5.7) 34 | bigdecimal 35 | parallel (1.27.0) 36 | parser (3.3.9.0) 37 | ast (~> 2.4.1) 38 | racc 39 | prism (1.6.0) 40 | racc (1.8.1) 41 | rainbow (3.1.1) 42 | rake (13.0.6) 43 | regexp_parser (2.11.3) 44 | rubocop (1.80.2) 45 | json (~> 2.3) 46 | language_server-protocol (~> 3.17.0.2) 47 | lint_roller (~> 1.1.0) 48 | parallel (~> 1.10) 49 | parser (>= 3.3.0.2) 50 | rainbow (>= 2.2.2, < 4.0) 51 | regexp_parser (>= 2.9.3, < 3.0) 52 | rubocop-ast (>= 1.46.0, < 2.0) 53 | ruby-progressbar (~> 1.7) 54 | unicode-display_width (>= 2.4.0, < 4.0) 55 | rubocop-ast (1.47.1) 56 | parser (>= 3.3.7.2) 57 | prism (~> 1.4) 58 | rubocop-performance (1.25.0) 59 | lint_roller (~> 1.1) 60 | rubocop (>= 1.75.0, < 2.0) 61 | rubocop-ast (>= 1.38.0, < 2.0) 62 | ruby-progressbar (1.13.0) 63 | standard (1.51.1) 64 | language_server-protocol (~> 3.17.0.2) 65 | lint_roller (~> 1.0) 66 | rubocop (~> 1.80.2) 67 | standard-custom (~> 1.0.0) 68 | standard-performance (~> 1.8) 69 | standard-custom (1.0.2) 70 | lint_roller (~> 1.0) 71 | rubocop (~> 1.50) 72 | standard-performance (1.8.0) 73 | lint_roller (~> 1.1) 74 | rubocop-performance (~> 1.25.0) 75 | unicode-display_width (3.2.0) 76 | unicode-emoji (~> 4.1) 77 | unicode-emoji (4.1.0) 78 | 79 | PLATFORMS 80 | arm64-darwin-21 81 | ruby 82 | 83 | DEPENDENCIES 84 | minitest (~> 5.0) 85 | minitest-hooks (~> 1.5) 86 | mysql2 (~> 0.5.0) 87 | rake (~> 13.0) 88 | standard (~> 1.3) 89 | testcontainers-core! 90 | testcontainers-mariadb! 91 | 92 | BUNDLED WITH 93 | 2.4.1 94 | -------------------------------------------------------------------------------- /opensearch/lib/testcontainers/opensearch.rb: -------------------------------------------------------------------------------- 1 | require_relative "opensearch/version" 2 | require "testcontainers" 3 | 4 | module Testcontainers 5 | # OpensearchContainer manages Docker containers running OpenSearch. 6 | # It mirrors the Elasticsearch container API but targets the OpenSearch images 7 | # and defaults, including disabled security for simple integration tests. 8 | class OpensearchContainer < ::Testcontainers::DockerContainer 9 | OPENSEARCH_DEFAULT_HTTP_PORT = 9200 10 | OPENSEARCH_DEFAULT_METRICS_PORT = 9600 11 | OPENSEARCH_DEFAULT_IMAGE = "opensearchproject/opensearch:2.12.0" 12 | 13 | # Initializes a new OpenSearch container. 14 | # 15 | # @param image [String] Docker image to use. 16 | # @param http_port [Integer] Port to expose for HTTP traffic (default: 9200). 17 | # @param metrics_port [Integer] Port to expose for the metrics endpoint (default: 9600). 18 | # @param kwargs [Hash] Additional options forwarded to DockerContainer. 19 | attr_reader :http_port, :metrics_port 20 | 21 | def initialize(image = OPENSEARCH_DEFAULT_IMAGE, http_port: nil, metrics_port: nil, **kwargs) 22 | @http_port = http_port || OPENSEARCH_DEFAULT_HTTP_PORT 23 | @metrics_port = metrics_port || OPENSEARCH_DEFAULT_METRICS_PORT 24 | super(image, **kwargs) 25 | end 26 | 27 | # Starts the container with the appropriate exposed ports and environment. 28 | def start 29 | with_exposed_ports(http_port, metrics_port) 30 | _configure 31 | super 32 | end 33 | 34 | # Returns the URL to access the OpenSearch HTTP endpoint. 35 | # 36 | # @param protocol [String] scheme to use (default: "http"). 37 | # @param port [Integer] HTTP port to use (default: mapped http_port). 38 | def opensearch_url(protocol: "http", port: http_port) 39 | "#{protocol}://#{host}:#{mapped_port(port)}" 40 | end 41 | 42 | private 43 | 44 | def _configure 45 | add_env("discovery.type", "single-node") unless get_env("discovery.type") 46 | add_env("bootstrap.memory_lock", "true") unless get_env("bootstrap.memory_lock") 47 | add_env("plugins.security.disabled", "true") unless get_env("plugins.security.disabled") 48 | add_env("DISABLE_INSTALL_DEMO_CONFIG", "true") unless get_env("DISABLE_INSTALL_DEMO_CONFIG") 49 | add_env("DISABLE_SECURITY_PLUGIN", "true") unless get_env("DISABLE_SECURITY_PLUGIN") 50 | add_env("OPENSEARCH_JAVA_OPTS", "-Xms512m -Xmx512m") unless get_env("OPENSEARCH_JAVA_OPTS") 51 | end 52 | end 53 | end 54 | -------------------------------------------------------------------------------- /redis/Gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: ../core 3 | specs: 4 | testcontainers-core (0.2.0) 5 | base64 (~> 0.3) 6 | docker-api (~> 2.4) 7 | java-properties (~> 0.3.0) 8 | 9 | PATH 10 | remote: . 11 | specs: 12 | testcontainers-redis (0.2.0) 13 | testcontainers-core (~> 0.1) 14 | 15 | GEM 16 | remote: https://rubygems.org/ 17 | specs: 18 | ast (2.4.3) 19 | base64 (0.3.0) 20 | connection_pool (2.4.0) 21 | docker-api (2.4.0) 22 | excon (>= 0.64.0) 23 | multi_json 24 | excon (0.99.0) 25 | java-properties (0.3.0) 26 | json (2.15.1) 27 | language_server-protocol (3.17.0.5) 28 | lint_roller (1.1.0) 29 | minitest (5.26.0) 30 | minitest-hooks (1.5.0) 31 | minitest (> 5.3) 32 | multi_json (1.15.0) 33 | parallel (1.27.0) 34 | parser (3.3.9.0) 35 | ast (~> 2.4.1) 36 | racc 37 | prism (1.6.0) 38 | racc (1.8.1) 39 | rainbow (3.1.1) 40 | rake (13.0.6) 41 | redis (5.0.6) 42 | redis-client (>= 0.9.0) 43 | redis-client (0.14.1) 44 | connection_pool 45 | regexp_parser (2.11.3) 46 | rubocop (1.80.2) 47 | json (~> 2.3) 48 | language_server-protocol (~> 3.17.0.2) 49 | lint_roller (~> 1.1.0) 50 | parallel (~> 1.10) 51 | parser (>= 3.3.0.2) 52 | rainbow (>= 2.2.2, < 4.0) 53 | regexp_parser (>= 2.9.3, < 3.0) 54 | rubocop-ast (>= 1.46.0, < 2.0) 55 | ruby-progressbar (~> 1.7) 56 | unicode-display_width (>= 2.4.0, < 4.0) 57 | rubocop-ast (1.47.1) 58 | parser (>= 3.3.7.2) 59 | prism (~> 1.4) 60 | rubocop-performance (1.25.0) 61 | lint_roller (~> 1.1) 62 | rubocop (>= 1.75.0, < 2.0) 63 | rubocop-ast (>= 1.38.0, < 2.0) 64 | ruby-progressbar (1.13.0) 65 | standard (1.51.1) 66 | language_server-protocol (~> 3.17.0.2) 67 | lint_roller (~> 1.0) 68 | rubocop (~> 1.80.2) 69 | standard-custom (~> 1.0.0) 70 | standard-performance (~> 1.8) 71 | standard-custom (1.0.2) 72 | lint_roller (~> 1.0) 73 | rubocop (~> 1.50) 74 | standard-performance (1.8.0) 75 | lint_roller (~> 1.1) 76 | rubocop-performance (~> 1.25.0) 77 | unicode-display_width (3.2.0) 78 | unicode-emoji (~> 4.1) 79 | unicode-emoji (4.1.0) 80 | 81 | PLATFORMS 82 | arm64-darwin-21 83 | ruby 84 | 85 | DEPENDENCIES 86 | minitest (~> 5.0) 87 | minitest-hooks (~> 1.5) 88 | rake (~> 13.0) 89 | redis (~> 5.0) 90 | standard (~> 1.3) 91 | testcontainers-core! 92 | testcontainers-redis! 93 | 94 | BUNDLED WITH 95 | 2.4.1 96 | -------------------------------------------------------------------------------- /redpanda/Gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: ../core 3 | specs: 4 | testcontainers-core (0.2.0) 5 | base64 (~> 0.3) 6 | docker-api (~> 2.4) 7 | java-properties (~> 0.3.0) 8 | 9 | PATH 10 | remote: . 11 | specs: 12 | testcontainers-redpanda (0.2.0) 13 | testcontainers-core (~> 0.1) 14 | 15 | GEM 16 | remote: https://rubygems.org/ 17 | specs: 18 | ast (2.4.3) 19 | base64 (0.3.0) 20 | docker-api (2.4.0) 21 | excon (>= 0.64.0) 22 | multi_json 23 | excon (0.99.0) 24 | ffi (1.15.5) 25 | java-properties (0.3.0) 26 | json (2.15.1) 27 | language_server-protocol (3.17.0.5) 28 | lint_roller (1.1.0) 29 | mini_portile2 (2.8.2) 30 | minitest (5.26.0) 31 | minitest-hooks (1.5.0) 32 | minitest (> 5.3) 33 | multi_json (1.15.0) 34 | parallel (1.27.0) 35 | parser (3.3.9.0) 36 | ast (~> 2.4.1) 37 | racc 38 | prism (1.6.0) 39 | racc (1.8.1) 40 | rainbow (3.1.1) 41 | rake (13.0.6) 42 | rdkafka (0.12.0) 43 | ffi (~> 1.15) 44 | mini_portile2 (~> 2.6) 45 | rake (> 12) 46 | regexp_parser (2.11.3) 47 | rubocop (1.80.2) 48 | json (~> 2.3) 49 | language_server-protocol (~> 3.17.0.2) 50 | lint_roller (~> 1.1.0) 51 | parallel (~> 1.10) 52 | parser (>= 3.3.0.2) 53 | rainbow (>= 2.2.2, < 4.0) 54 | regexp_parser (>= 2.9.3, < 3.0) 55 | rubocop-ast (>= 1.46.0, < 2.0) 56 | ruby-progressbar (~> 1.7) 57 | unicode-display_width (>= 2.4.0, < 4.0) 58 | rubocop-ast (1.47.1) 59 | parser (>= 3.3.7.2) 60 | prism (~> 1.4) 61 | rubocop-performance (1.25.0) 62 | lint_roller (~> 1.1) 63 | rubocop (>= 1.75.0, < 2.0) 64 | rubocop-ast (>= 1.38.0, < 2.0) 65 | ruby-progressbar (1.13.0) 66 | standard (1.51.1) 67 | language_server-protocol (~> 3.17.0.2) 68 | lint_roller (~> 1.0) 69 | rubocop (~> 1.80.2) 70 | standard-custom (~> 1.0.0) 71 | standard-performance (~> 1.8) 72 | standard-custom (1.0.2) 73 | lint_roller (~> 1.0) 74 | rubocop (~> 1.50) 75 | standard-performance (1.8.0) 76 | lint_roller (~> 1.1) 77 | rubocop-performance (~> 1.25.0) 78 | unicode-display_width (3.2.0) 79 | unicode-emoji (~> 4.1) 80 | unicode-emoji (4.1.0) 81 | 82 | PLATFORMS 83 | arm64-darwin-21 84 | ruby 85 | 86 | DEPENDENCIES 87 | minitest (~> 5.0) 88 | minitest-hooks (~> 1.5) 89 | rake (~> 13.0) 90 | rdkafka (~> 0.12) 91 | standard (~> 1.3) 92 | testcontainers-core! 93 | testcontainers-redpanda! 94 | 95 | BUNDLED WITH 96 | 2.4.1 97 | -------------------------------------------------------------------------------- /mongo/Gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: ../core 3 | specs: 4 | testcontainers-core (0.2.0) 5 | base64 (~> 0.3) 6 | docker-api (~> 2.4) 7 | java-properties (~> 0.3.0) 8 | 9 | PATH 10 | remote: . 11 | specs: 12 | testcontainers-mongo (0.2.0) 13 | testcontainers-core (~> 0.1) 14 | 15 | GEM 16 | remote: https://rubygems.org/ 17 | specs: 18 | ast (2.4.3) 19 | base64 (0.3.0) 20 | bigdecimal (3.3.1) 21 | bson (5.2.0) 22 | docker-api (2.4.0) 23 | excon (>= 0.64.0) 24 | multi_json 25 | excon (0.99.0) 26 | java-properties (0.3.0) 27 | json (2.15.1) 28 | language_server-protocol (3.17.0.5) 29 | lint_roller (1.1.0) 30 | minitest (5.26.0) 31 | minitest-hooks (1.5.0) 32 | minitest (> 5.3) 33 | mongo (2.21.3) 34 | base64 35 | bson (>= 4.14.1, < 6.0.0) 36 | multi_json (1.15.0) 37 | parallel (1.27.0) 38 | parser (3.3.9.0) 39 | ast (~> 2.4.1) 40 | racc 41 | prism (1.6.0) 42 | racc (1.8.1) 43 | rainbow (3.1.1) 44 | rake (13.0.6) 45 | regexp_parser (2.11.3) 46 | rubocop (1.80.2) 47 | json (~> 2.3) 48 | language_server-protocol (~> 3.17.0.2) 49 | lint_roller (~> 1.1.0) 50 | parallel (~> 1.10) 51 | parser (>= 3.3.0.2) 52 | rainbow (>= 2.2.2, < 4.0) 53 | regexp_parser (>= 2.9.3, < 3.0) 54 | rubocop-ast (>= 1.46.0, < 2.0) 55 | ruby-progressbar (~> 1.7) 56 | unicode-display_width (>= 2.4.0, < 4.0) 57 | rubocop-ast (1.47.1) 58 | parser (>= 3.3.7.2) 59 | prism (~> 1.4) 60 | rubocop-performance (1.25.0) 61 | lint_roller (~> 1.1) 62 | rubocop (>= 1.75.0, < 2.0) 63 | rubocop-ast (>= 1.38.0, < 2.0) 64 | ruby-progressbar (1.13.0) 65 | standard (1.51.1) 66 | language_server-protocol (~> 3.17.0.2) 67 | lint_roller (~> 1.0) 68 | rubocop (~> 1.80.2) 69 | standard-custom (~> 1.0.0) 70 | standard-performance (~> 1.8) 71 | standard-custom (1.0.2) 72 | lint_roller (~> 1.0) 73 | rubocop (~> 1.50) 74 | standard-performance (1.8.0) 75 | lint_roller (~> 1.1) 76 | rubocop-performance (~> 1.25.0) 77 | unicode-display_width (3.2.0) 78 | unicode-emoji (~> 4.1) 79 | unicode-emoji (4.1.0) 80 | 81 | PLATFORMS 82 | arm64-darwin-21 83 | ruby 84 | x86_64-darwin-22 85 | 86 | DEPENDENCIES 87 | bigdecimal (~> 3.3) 88 | minitest (~> 5.0) 89 | minitest-hooks (~> 1.5) 90 | mongo (~> 2.2) 91 | rake (~> 13.0) 92 | standard (~> 1.3) 93 | testcontainers-core! 94 | testcontainers-mongo! 95 | 96 | BUNDLED WITH 97 | 2.4.1 98 | -------------------------------------------------------------------------------- /selenium/Gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: ../core 3 | specs: 4 | testcontainers-core (0.2.0) 5 | base64 (~> 0.3) 6 | docker-api (~> 2.4) 7 | java-properties (~> 0.3.0) 8 | 9 | PATH 10 | remote: . 11 | specs: 12 | testcontainers-selenium (0.2.0) 13 | testcontainers-core (~> 0.1) 14 | 15 | GEM 16 | remote: https://rubygems.org/ 17 | specs: 18 | ast (2.4.3) 19 | base64 (0.3.0) 20 | childprocess (4.1.0) 21 | docker-api (2.4.0) 22 | excon (>= 0.64.0) 23 | multi_json 24 | excon (0.100.0) 25 | java-properties (0.3.0) 26 | json (2.15.1) 27 | language_server-protocol (3.17.0.5) 28 | lint_roller (1.1.0) 29 | minitest (5.26.0) 30 | minitest-hooks (1.5.0) 31 | minitest (> 5.3) 32 | multi_json (1.15.0) 33 | parallel (1.27.0) 34 | parser (3.3.9.0) 35 | ast (~> 2.4.1) 36 | racc 37 | prism (1.6.0) 38 | racc (1.8.1) 39 | rainbow (3.1.1) 40 | rake (13.0.6) 41 | regexp_parser (2.11.3) 42 | rexml (3.4.4) 43 | rubocop (1.80.2) 44 | json (~> 2.3) 45 | language_server-protocol (~> 3.17.0.2) 46 | lint_roller (~> 1.1.0) 47 | parallel (~> 1.10) 48 | parser (>= 3.3.0.2) 49 | rainbow (>= 2.2.2, < 4.0) 50 | regexp_parser (>= 2.9.3, < 3.0) 51 | rubocop-ast (>= 1.46.0, < 2.0) 52 | ruby-progressbar (~> 1.7) 53 | unicode-display_width (>= 2.4.0, < 4.0) 54 | rubocop-ast (1.47.1) 55 | parser (>= 3.3.7.2) 56 | prism (~> 1.4) 57 | rubocop-performance (1.25.0) 58 | lint_roller (~> 1.1) 59 | rubocop (>= 1.75.0, < 2.0) 60 | rubocop-ast (>= 1.38.0, < 2.0) 61 | ruby-progressbar (1.13.0) 62 | rubyzip (2.3.2) 63 | selenium-webdriver (4.1.0) 64 | childprocess (>= 0.5, < 5.0) 65 | rexml (~> 3.2, >= 3.2.5) 66 | rubyzip (>= 1.2.2) 67 | standard (1.51.1) 68 | language_server-protocol (~> 3.17.0.2) 69 | lint_roller (~> 1.0) 70 | rubocop (~> 1.80.2) 71 | standard-custom (~> 1.0.0) 72 | standard-performance (~> 1.8) 73 | standard-custom (1.0.2) 74 | lint_roller (~> 1.0) 75 | rubocop (~> 1.50) 76 | standard-performance (1.8.0) 77 | lint_roller (~> 1.1) 78 | rubocop-performance (~> 1.25.0) 79 | unicode-display_width (3.2.0) 80 | unicode-emoji (~> 4.1) 81 | unicode-emoji (4.1.0) 82 | 83 | PLATFORMS 84 | ruby 85 | x86_64-linux 86 | 87 | DEPENDENCIES 88 | minitest (~> 5.0) 89 | minitest-hooks (~> 1.5) 90 | rake (~> 13.0) 91 | selenium-webdriver (~> 4.1.0) 92 | standard (~> 1.3) 93 | testcontainers-core! 94 | testcontainers-selenium! 95 | 96 | BUNDLED WITH 97 | 2.6.9 98 | -------------------------------------------------------------------------------- /kafka/Gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: ../core 3 | specs: 4 | testcontainers-core (0.2.0) 5 | base64 (~> 0.3) 6 | docker-api (~> 2.4) 7 | java-properties (~> 0.3.0) 8 | 9 | PATH 10 | remote: . 11 | specs: 12 | testcontainers-kafka (0.1.0) 13 | testcontainers-core (~> 0.1) 14 | 15 | GEM 16 | remote: https://rubygems.org/ 17 | specs: 18 | ast (2.4.3) 19 | base64 (0.3.0) 20 | docker-api (2.4.0) 21 | excon (>= 0.64.0) 22 | multi_json 23 | excon (1.3.0) 24 | logger 25 | ffi (1.17.2-arm64-darwin) 26 | java-properties (0.3.0) 27 | json (2.15.1) 28 | language_server-protocol (3.17.0.5) 29 | lint_roller (1.1.0) 30 | logger (1.7.0) 31 | mini_portile2 (2.8.9) 32 | minitest (5.26.0) 33 | minitest-hooks (1.5.2) 34 | minitest (> 5.3) 35 | multi_json (1.17.0) 36 | parallel (1.27.0) 37 | parser (3.3.9.0) 38 | ast (~> 2.4.1) 39 | racc 40 | prism (1.6.0) 41 | racc (1.8.1) 42 | rainbow (3.1.1) 43 | rake (13.3.0) 44 | rdkafka (0.24.1-arm64-darwin) 45 | ffi (~> 1.15) 46 | json (> 2.0) 47 | logger 48 | mini_portile2 (~> 2.6) 49 | rake (> 12) 50 | regexp_parser (2.11.3) 51 | rubocop (1.80.2) 52 | json (~> 2.3) 53 | language_server-protocol (~> 3.17.0.2) 54 | lint_roller (~> 1.1.0) 55 | parallel (~> 1.10) 56 | parser (>= 3.3.0.2) 57 | rainbow (>= 2.2.2, < 4.0) 58 | regexp_parser (>= 2.9.3, < 3.0) 59 | rubocop-ast (>= 1.46.0, < 2.0) 60 | ruby-progressbar (~> 1.7) 61 | unicode-display_width (>= 2.4.0, < 4.0) 62 | rubocop-ast (1.47.1) 63 | parser (>= 3.3.7.2) 64 | prism (~> 1.4) 65 | rubocop-performance (1.25.0) 66 | lint_roller (~> 1.1) 67 | rubocop (>= 1.75.0, < 2.0) 68 | rubocop-ast (>= 1.38.0, < 2.0) 69 | ruby-progressbar (1.13.0) 70 | standard (1.51.1) 71 | language_server-protocol (~> 3.17.0.2) 72 | lint_roller (~> 1.0) 73 | rubocop (~> 1.80.2) 74 | standard-custom (~> 1.0.0) 75 | standard-performance (~> 1.8) 76 | standard-custom (1.0.2) 77 | lint_roller (~> 1.0) 78 | rubocop (~> 1.50) 79 | standard-performance (1.8.0) 80 | lint_roller (~> 1.1) 81 | rubocop-performance (~> 1.25.0) 82 | unicode-display_width (3.2.0) 83 | unicode-emoji (~> 4.1) 84 | unicode-emoji (4.1.0) 85 | 86 | PLATFORMS 87 | arm64-darwin-23 88 | 89 | DEPENDENCIES 90 | minitest (~> 5.0) 91 | minitest-hooks (~> 1.5) 92 | rake (~> 13.0) 93 | rdkafka (~> 0.12) 94 | standard (~> 1.3) 95 | testcontainers-core! 96 | testcontainers-kafka! 97 | 98 | BUNDLED WITH 99 | 2.6.9 100 | -------------------------------------------------------------------------------- /rabbitmq/Gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: ../core 3 | specs: 4 | testcontainers-core (0.2.0) 5 | base64 (~> 0.3) 6 | docker-api (~> 2.4) 7 | java-properties (~> 0.3.0) 8 | 9 | PATH 10 | remote: . 11 | specs: 12 | testcontainers-rabbitmq (0.2.0) 13 | testcontainers-core (~> 0.1) 14 | 15 | GEM 16 | remote: https://rubygems.org/ 17 | specs: 18 | amq-protocol (2.3.2) 19 | ast (2.4.3) 20 | base64 (0.3.0) 21 | bunny (2.20.3) 22 | amq-protocol (~> 2.3, >= 2.3.1) 23 | sorted_set (~> 1, >= 1.0.2) 24 | docker-api (2.4.0) 25 | excon (>= 0.64.0) 26 | multi_json 27 | excon (0.99.0) 28 | java-properties (0.3.0) 29 | json (2.15.1) 30 | language_server-protocol (3.17.0.5) 31 | lint_roller (1.1.0) 32 | minitest (5.26.0) 33 | minitest-hooks (1.5.0) 34 | minitest (> 5.3) 35 | multi_json (1.15.0) 36 | parallel (1.27.0) 37 | parser (3.3.9.0) 38 | ast (~> 2.4.1) 39 | racc 40 | prism (1.6.0) 41 | racc (1.8.1) 42 | rainbow (3.1.1) 43 | rake (13.0.6) 44 | rbtree (0.4.6) 45 | regexp_parser (2.11.3) 46 | rubocop (1.80.2) 47 | json (~> 2.3) 48 | language_server-protocol (~> 3.17.0.2) 49 | lint_roller (~> 1.1.0) 50 | parallel (~> 1.10) 51 | parser (>= 3.3.0.2) 52 | rainbow (>= 2.2.2, < 4.0) 53 | regexp_parser (>= 2.9.3, < 3.0) 54 | rubocop-ast (>= 1.46.0, < 2.0) 55 | ruby-progressbar (~> 1.7) 56 | unicode-display_width (>= 2.4.0, < 4.0) 57 | rubocop-ast (1.47.1) 58 | parser (>= 3.3.7.2) 59 | prism (~> 1.4) 60 | rubocop-performance (1.25.0) 61 | lint_roller (~> 1.1) 62 | rubocop (>= 1.75.0, < 2.0) 63 | rubocop-ast (>= 1.38.0, < 2.0) 64 | ruby-progressbar (1.13.0) 65 | set (1.0.3) 66 | sorted_set (1.0.3) 67 | rbtree 68 | set (~> 1.0) 69 | standard (1.51.1) 70 | language_server-protocol (~> 3.17.0.2) 71 | lint_roller (~> 1.0) 72 | rubocop (~> 1.80.2) 73 | standard-custom (~> 1.0.0) 74 | standard-performance (~> 1.8) 75 | standard-custom (1.0.2) 76 | lint_roller (~> 1.0) 77 | rubocop (~> 1.50) 78 | standard-performance (1.8.0) 79 | lint_roller (~> 1.1) 80 | rubocop-performance (~> 1.25.0) 81 | unicode-display_width (3.2.0) 82 | unicode-emoji (~> 4.1) 83 | unicode-emoji (4.1.0) 84 | 85 | PLATFORMS 86 | arm64-darwin-21 87 | ruby 88 | x86_64-darwin-22 89 | 90 | DEPENDENCIES 91 | bunny (~> 2.19) 92 | minitest (~> 5.0) 93 | minitest-hooks (~> 1.5) 94 | rake (~> 13.0) 95 | standard (~> 1.3) 96 | testcontainers-core! 97 | testcontainers-rabbitmq! 98 | 99 | BUNDLED WITH 100 | 2.4.1 101 | -------------------------------------------------------------------------------- /mongo/test/mongo_container_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "test_helper" 4 | require "mongo" 5 | 6 | class MongoContainerTest < TestcontainersTest 7 | def before_all 8 | super 9 | 10 | @container = Testcontainers::MongoContainer.new 11 | @container.start 12 | @host = @container.host 13 | @port = @container.first_mapped_port 14 | end 15 | 16 | def after_all 17 | if @container&.exists? 18 | @container&.stop if @container&.running? 19 | @container&.remove 20 | end 21 | 22 | super 23 | end 24 | 25 | def test_it_returns_the_default_image 26 | assert_equal "mongo:latest", @container.image 27 | end 28 | 29 | def test_it_supports_custom_image 30 | container = Testcontainers::MongoContainer.new("bitnami/mongodb:latest") 31 | assert_equal "bitnami/mongodb:latest", container.image 32 | end 33 | 34 | def test_it_returns_the_default_port 35 | assert_equal 27017, @container.port 36 | end 37 | 38 | def test_it_is_configured_with_the_default_environment_variables 39 | assert "test", @container.get_env("MONGO_DATABASE") 40 | assert "test", @container.get_env("MONGO_USER") 41 | assert "test", @container.get_env("MONGO_PASSWORD") 42 | end 43 | 44 | def test_it_has_the_default_port_mapped 45 | assert @container.mapped_port(27017) 46 | end 47 | 48 | def test_it_supports_custom_keyword_arguments 49 | container = Testcontainers::MongoContainer.new(filesystem_binds: ["#{Dir.pwd}/custom/conf:/etc/mongo/mongod.conf:rw"]) 50 | assert_equal ["#{Dir.pwd}/custom/conf:/etc/mongo/mongod.conf:rw"], container.filesystem_binds 51 | end 52 | 53 | def test_it_returns_the_default_database_url 54 | assert_equal "mongodb://test:test@#{@host}:#{@port}/test", @container.mongo_url 55 | end 56 | 57 | def test_it_returns_the_database_url_with_custom_database 58 | assert_equal "mongodb://test:test@#{@host}:#{@port}/foo", @container.mongo_url(database: "foo") 59 | end 60 | 61 | def test_it_returns_the_database_url_with_custom_protocol 62 | assert_equal "mongodb2://test:test@#{@host}:#{@port}/test", @container.mongo_url(protocol: "mongodb2") 63 | end 64 | 65 | def test_it_returns_the_database_url_with_custom_username 66 | assert_equal "mongodb://foo:test@#{@host}:#{@port}/test", @container.mongo_url(username: "foo") 67 | end 68 | 69 | def test_it_returns_the_database_url_with_custom_password 70 | assert_equal "mongodb://test:bar@#{@host}:#{@port}/test", @container.mongo_url(password: "bar") 71 | end 72 | 73 | def test_it_is_reachable 74 | client = Mongo::Client.new("mongodb://test:test@#{@host}:#{@port}/test", auth_source: "admin") 75 | client[:artists].insert_one({name: "FKA Twigs"}) 76 | 77 | assert_equal 1, client[:artists].find(name: "FKA Twigs").count_documents 78 | end 79 | end 80 | -------------------------------------------------------------------------------- /nginx/README.md: -------------------------------------------------------------------------------- 1 | # Testcontainers module for Nginx 2 | 3 | testcontainers-nginx simplifies the creation and management of Nginx containers for testing purposes using the Testcontainers library. 4 | 5 | ## Installation 6 | 7 | Add the library to the test section in your application's Gemfile: 8 | 9 | ```ruby 10 | group :test do 11 | gem 'testcontainers-nginx' 12 | end 13 | ``` 14 | 15 | And then execute: 16 | 17 | ```bash 18 | $ bundle install 19 | ``` 20 | 21 | Or install it yourself as: 22 | 23 | ```bash 24 | $ gem install testcontainers-nginx 25 | ``` 26 | 27 | ## Usage 28 | 29 | To use the library, you first need to require it: 30 | 31 | ```ruby 32 | require 'testcontainers/nginx' 33 | ``` 34 | 35 | ### Creating a Nginx container 36 | 37 | Create a new instance of the `Testcontainers::NginxContainer` class: 38 | 39 | ```ruby 40 | container = Testcontainers::NginxContainer.new 41 | ``` 42 | 43 | 44 | This creates a new container with the default Nginx image and port. You can customize these by passing arguments to the constructor: 45 | 46 | ```ruby 47 | container = Testcontainers::NginxContainer.new("nginx:alpine", port: 8080) 48 | ``` 49 | 50 | You can setup filesystem binds to configure the container with custom configuration files or to serve content from a custom path: 51 | 52 | ```ruby 53 | container.with_filesystem_binds(["/local/path/custom/conf:/etc/nginx/conf.d:ro"]) 54 | container.with_filesystem_binds(["/local/path/custom/content:/usr/share/nginx/html:ro"]) 55 | ``` 56 | 57 | ### Starting and stopping the container 58 | 59 | Start the container: 60 | 61 | ```ruby 62 | container.start 63 | ``` 64 | 65 | Stop the container when you're done: 66 | 67 | ```ruby 68 | container.stop 69 | ``` 70 | 71 | ### Connecting to the Nginx container 72 | 73 | Once the container is running, you can obtain the connection details using the following methods: 74 | 75 | ```ruby 76 | host = container.host 77 | port = container.first_mapped_port 78 | ``` 79 | 80 | 81 | Or, you can generate a full server URL: 82 | 83 | ```ruby 84 | server_url = container.server_url 85 | ``` 86 | 87 | 88 | ## Contributing 89 | 90 | Bug reports and pull requests are welcome on GitHub at https://github.com/testcontainers/testcontainers-ruby. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/testcontainers/testcontainers-ruby/blob/main/CODE_OF_CONDUCT.md). 91 | 92 | ## License 93 | 94 | The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT). 95 | 96 | ## Code of Conduct 97 | 98 | Everyone interacting in the Testcontainers project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/testcontainers/testcontainers-ruby/blob/main/CODE_OF_CONDUCT.md). 99 | -------------------------------------------------------------------------------- /selenium/lib/testcontainers/selenium.rb: -------------------------------------------------------------------------------- 1 | require_relative "selenium/version" 2 | require "testcontainers" 3 | 4 | module Testcontainers 5 | # SeleniumContainer class is used to manage containers that runs a automaticates test 6 | 7 | class SeleniumContainer < ::Testcontainers::DockerContainer 8 | # Default ports used by the container 9 | SELENIUM_DEFAULT_PORT = 4444 10 | VNC_DEFAULT_PORT = 5900 11 | SE_VNC_PASSWORD = 1 12 | 13 | # Hash that contains the images for the build of the containers of selenium that runs in the browsers chrome and firefox 14 | SELENIUM_IMAGES = { 15 | firefox: "selenium/standalone-firefox:latest", 16 | chrome: "selenium/standalone-chrome:latest" 17 | } 18 | 19 | attr_reader :headless 20 | 21 | # Initializes a new instance of SeleniumContainer 22 | # @param image [String] is use to define the image for the container 23 | # @param capabilities [Symbol] is use to define the image that are vailable for browser between firefox and chrome 24 | # @param port [String] is use to define the connection port for the container for Selenium 25 | # @param kwargs [Hash] the options to pass to the container. See {DockerContainer#initialize} 26 | def initialize(image = nil, capabilities: :firefox, headless: false, vnc_no_password: nil, vnc_password: nil, **kwargs) 27 | image ||= SELENIUM_IMAGES[capabilities] 28 | super(image, **kwargs) 29 | @vnc_password = vnc_password 30 | @vnc_no_password = vnc_no_password 31 | @headless = headless 32 | add_wait_for(:logs, /Started Selenium/) unless wait_for_user_defined? 33 | end 34 | 35 | # Starts the container 36 | # @return [SeleniumContainer] self 37 | def start 38 | with_exposed_ports([port, vnc_port]) 39 | _configure 40 | super 41 | end 42 | 43 | # Returns the port used by the container 44 | # @return [Integer] the port used by the container 45 | def port 46 | SELENIUM_DEFAULT_PORT 47 | end 48 | 49 | # @return [Integer] the port used by the container of vnc 50 | def vnc_port 51 | VNC_DEFAULT_PORT 52 | end 53 | 54 | # Returns the selenium connection url (e.g https://host:port/wd/hub) 55 | # 56 | # @param protocol [String] the protocol to use in the string (default: "http://") 57 | # @return [String] the url used by the container 58 | def selenium_url(protocol: "http://") 59 | "#{protocol}#{host}:#{mapped_port(port)}/wd/hub" 60 | end 61 | 62 | private 63 | 64 | def _configure 65 | if @vnc_no_passsword 66 | add_env("SE_VNC_NO_PASSWORD", "1") 67 | end 68 | 69 | if @vnc_password 70 | add_env("SE_VNC_PASSWORD", @vnc_password) 71 | end 72 | 73 | add_env("START_XVFB", (!@headless).to_s) 74 | add_env("no_proxy", "localhost") 75 | add_env("HUB_ENV_no_proxy", "localhost") 76 | end 77 | end 78 | end 79 | -------------------------------------------------------------------------------- /opensearch/Gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: ../core 3 | specs: 4 | testcontainers-core (0.2.0) 5 | base64 (~> 0.3) 6 | docker-api (~> 2.4) 7 | java-properties (~> 0.3.0) 8 | 9 | PATH 10 | remote: . 11 | specs: 12 | testcontainers-opensearch (0.1.0) 13 | testcontainers-core (~> 0.1) 14 | 15 | GEM 16 | remote: https://rubygems.org/ 17 | specs: 18 | ast (2.4.3) 19 | base64 (0.3.0) 20 | docker-api (2.4.0) 21 | excon (>= 0.64.0) 22 | multi_json 23 | excon (1.3.0) 24 | logger 25 | faraday (2.14.0) 26 | faraday-net_http (>= 2.0, < 3.5) 27 | json 28 | logger 29 | faraday-net_http (3.4.1) 30 | net-http (>= 0.5.0) 31 | java-properties (0.3.0) 32 | json (2.15.1) 33 | language_server-protocol (3.17.0.5) 34 | lint_roller (1.1.0) 35 | logger (1.7.0) 36 | minitest (5.26.0) 37 | minitest-hooks (1.5.2) 38 | minitest (> 5.3) 39 | multi_json (1.17.0) 40 | net-http (0.6.0) 41 | uri 42 | opensearch-ruby (3.4.0) 43 | faraday (>= 1.0, < 3) 44 | multi_json (>= 1.0) 45 | parallel (1.27.0) 46 | parser (3.3.9.0) 47 | ast (~> 2.4.1) 48 | racc 49 | prism (1.6.0) 50 | racc (1.8.1) 51 | rainbow (3.1.1) 52 | rake (13.3.0) 53 | regexp_parser (2.11.3) 54 | rubocop (1.80.2) 55 | json (~> 2.3) 56 | language_server-protocol (~> 3.17.0.2) 57 | lint_roller (~> 1.1.0) 58 | parallel (~> 1.10) 59 | parser (>= 3.3.0.2) 60 | rainbow (>= 2.2.2, < 4.0) 61 | regexp_parser (>= 2.9.3, < 3.0) 62 | rubocop-ast (>= 1.46.0, < 2.0) 63 | ruby-progressbar (~> 1.7) 64 | unicode-display_width (>= 2.4.0, < 4.0) 65 | rubocop-ast (1.47.1) 66 | parser (>= 3.3.7.2) 67 | prism (~> 1.4) 68 | rubocop-performance (1.25.0) 69 | lint_roller (~> 1.1) 70 | rubocop (>= 1.75.0, < 2.0) 71 | rubocop-ast (>= 1.38.0, < 2.0) 72 | ruby-progressbar (1.13.0) 73 | standard (1.51.1) 74 | language_server-protocol (~> 3.17.0.2) 75 | lint_roller (~> 1.0) 76 | rubocop (~> 1.80.2) 77 | standard-custom (~> 1.0.0) 78 | standard-performance (~> 1.8) 79 | standard-custom (1.0.2) 80 | lint_roller (~> 1.0) 81 | rubocop (~> 1.50) 82 | standard-performance (1.8.0) 83 | lint_roller (~> 1.1) 84 | rubocop-performance (~> 1.25.0) 85 | unicode-display_width (3.2.0) 86 | unicode-emoji (~> 4.1) 87 | unicode-emoji (4.1.0) 88 | uri (1.0.4) 89 | 90 | PLATFORMS 91 | arm64-darwin-23 92 | ruby 93 | 94 | DEPENDENCIES 95 | minitest (~> 5.0) 96 | minitest-hooks (~> 1.5) 97 | opensearch-ruby (~> 3.0) 98 | rake (~> 13.0) 99 | standard (~> 1.3) 100 | testcontainers-core! 101 | testcontainers-opensearch! 102 | 103 | BUNDLED WITH 104 | 2.6.9 105 | -------------------------------------------------------------------------------- /elasticsearch/Gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: ../core 3 | specs: 4 | testcontainers-core (0.2.0) 5 | base64 (~> 0.3) 6 | docker-api (~> 2.4) 7 | java-properties (~> 0.3.0) 8 | 9 | PATH 10 | remote: . 11 | specs: 12 | testcontainers-elasticsearch (0.2.0) 13 | testcontainers-core (~> 0.1) 14 | 15 | GEM 16 | remote: https://rubygems.org/ 17 | specs: 18 | ast (2.4.3) 19 | base64 (0.3.0) 20 | docker-api (2.4.0) 21 | excon (>= 0.64.0) 22 | multi_json 23 | elastic-transport (8.2.1) 24 | faraday (< 3) 25 | multi_json 26 | elasticsearch (8.7.1) 27 | elastic-transport (~> 8) 28 | elasticsearch-api (= 8.7.1) 29 | elasticsearch-api (8.7.1) 30 | multi_json 31 | excon (0.99.0) 32 | faraday (2.7.4) 33 | faraday-net_http (>= 2.0, < 3.1) 34 | ruby2_keywords (>= 0.0.4) 35 | faraday-net_http (3.0.2) 36 | java-properties (0.3.0) 37 | json (2.15.1) 38 | language_server-protocol (3.17.0.5) 39 | lint_roller (1.1.0) 40 | minitest (5.26.0) 41 | minitest-hooks (1.5.0) 42 | minitest (> 5.3) 43 | multi_json (1.15.0) 44 | parallel (1.27.0) 45 | parser (3.3.9.0) 46 | ast (~> 2.4.1) 47 | racc 48 | prism (1.6.0) 49 | racc (1.8.1) 50 | rainbow (3.1.1) 51 | rake (13.0.6) 52 | regexp_parser (2.11.3) 53 | rubocop (1.80.2) 54 | json (~> 2.3) 55 | language_server-protocol (~> 3.17.0.2) 56 | lint_roller (~> 1.1.0) 57 | parallel (~> 1.10) 58 | parser (>= 3.3.0.2) 59 | rainbow (>= 2.2.2, < 4.0) 60 | regexp_parser (>= 2.9.3, < 3.0) 61 | rubocop-ast (>= 1.46.0, < 2.0) 62 | ruby-progressbar (~> 1.7) 63 | unicode-display_width (>= 2.4.0, < 4.0) 64 | rubocop-ast (1.47.1) 65 | parser (>= 3.3.7.2) 66 | prism (~> 1.4) 67 | rubocop-performance (1.25.0) 68 | lint_roller (~> 1.1) 69 | rubocop (>= 1.75.0, < 2.0) 70 | rubocop-ast (>= 1.38.0, < 2.0) 71 | ruby-progressbar (1.13.0) 72 | ruby2_keywords (0.0.5) 73 | standard (1.51.1) 74 | language_server-protocol (~> 3.17.0.2) 75 | lint_roller (~> 1.0) 76 | rubocop (~> 1.80.2) 77 | standard-custom (~> 1.0.0) 78 | standard-performance (~> 1.8) 79 | standard-custom (1.0.2) 80 | lint_roller (~> 1.0) 81 | rubocop (~> 1.50) 82 | standard-performance (1.8.0) 83 | lint_roller (~> 1.1) 84 | rubocop-performance (~> 1.25.0) 85 | unicode-display_width (3.2.0) 86 | unicode-emoji (~> 4.1) 87 | unicode-emoji (4.1.0) 88 | 89 | PLATFORMS 90 | arm64-darwin-21 91 | ruby 92 | 93 | DEPENDENCIES 94 | elasticsearch (~> 8.7) 95 | minitest (~> 5.0) 96 | minitest-hooks (~> 1.5) 97 | rake (~> 13.0) 98 | standard (~> 1.3) 99 | testcontainers-core! 100 | testcontainers-elasticsearch! 101 | 102 | BUNDLED WITH 103 | 2.4.1 104 | -------------------------------------------------------------------------------- /mysql/test/mysql_container_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "test_helper" 4 | require "mysql2" 5 | 6 | class MysqlContainerTest < TestcontainersTest 7 | def before_all 8 | super 9 | 10 | @container = Testcontainers::MysqlContainer.new 11 | @container.start 12 | @host = @container.host 13 | @port = @container.first_mapped_port 14 | end 15 | 16 | def after_all 17 | if @container&.exists? 18 | @container&.stop if @container&.running? 19 | @container&.remove 20 | end 21 | 22 | super 23 | end 24 | 25 | def test_it_returns_the_default_image 26 | assert_equal "mysql:latest", @container.image 27 | end 28 | 29 | def test_it_supports_custom_image 30 | container = Testcontainers::MysqlContainer.new("mariadb:latest") 31 | assert_equal "mariadb:latest", container.image 32 | end 33 | 34 | def test_it_returns_the_default_port 35 | assert_equal 3306, @container.port 36 | end 37 | 38 | def test_it_is_configured_with_the_default_environment_variables 39 | assert "test", @container.get_env("MYSQL_DATABASE") 40 | assert "test", @container.get_env("MYSQL_USER") 41 | assert "test", @container.get_env("MYSQL_PASSWORD") 42 | assert "test", @container.get_env("MYSQL_ROOT_PASSWORD") 43 | end 44 | 45 | def test_it_has_the_default_port_mapped 46 | assert @container.mapped_port(3306) 47 | end 48 | 49 | def test_it_supports_custom_keyword_arguments 50 | container = Testcontainers::MysqlContainer.new(filesystem_binds: ["#{Dir.pwd}/custom/conf:/etc/mysql/conf.d:rw"]) 51 | assert_equal ["#{Dir.pwd}/custom/conf:/etc/mysql/conf.d:rw"], container.filesystem_binds 52 | end 53 | 54 | def test_it_returns_the_default_database_url 55 | assert_equal "mysql://test:test@#{@host}:#{@port}/test", @container.database_url 56 | end 57 | 58 | def test_it_returns_the_database_url_with_custom_database 59 | assert_equal "mysql://test:test@#{@host}:#{@port}/foo", @container.database_url(database: "foo") 60 | end 61 | 62 | def test_it_returns_the_database_url_with_custom_protocol 63 | assert_equal "mysql2://test:test@#{@host}:#{@port}/test", @container.database_url(protocol: "mysql2") 64 | end 65 | 66 | def test_it_returns_the_database_url_with_custom_username 67 | assert_equal "mysql://foo:test@#{@host}:#{@port}/test", @container.database_url(username: "foo") 68 | end 69 | 70 | def test_it_returns_the_database_url_with_custom_password 71 | assert_equal "mysql://test:bar@#{@host}:#{@port}/test", @container.database_url(password: "bar") 72 | end 73 | 74 | def test_it_returns_the_database_url_with_custom_options 75 | assert_equal "mysql://test:test@#{@host}:#{@port}/test?useSSL=true", @container.database_url(options: {"useSSL" => "true"}) 76 | end 77 | 78 | def test_it_is_reachable 79 | client = Mysql2::Client.new(host: @host, username: "test", password: "test", port: @port, database: "test") 80 | assert_equal({"number" => 1}, client.query("SELECT 1 AS number").first) 81 | end 82 | end 83 | -------------------------------------------------------------------------------- /mariadb/test/mariadb_container_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "test_helper" 4 | require "mysql2" 5 | 6 | class MariadbContainerTest < TestcontainersTest 7 | def before_all 8 | super 9 | 10 | @container = Testcontainers::MariadbContainer.new 11 | @container.start 12 | @host = @container.host 13 | @port = @container.first_mapped_port 14 | end 15 | 16 | def after_all 17 | if @container&.exists? 18 | @container&.stop if @container&.running? 19 | @container&.remove 20 | end 21 | 22 | super 23 | end 24 | 25 | def test_it_returns_the_default_image 26 | assert_equal "mariadb:latest", @container.image 27 | end 28 | 29 | def test_it_supports_custom_image 30 | container = Testcontainers::MariadbContainer.new("mariadb:10.10") 31 | assert_equal "mariadb:10.10", container.image 32 | end 33 | 34 | def test_it_returns_the_default_port 35 | assert_equal 3306, @container.port 36 | end 37 | 38 | def test_it_is_configured_with_the_default_environment_variables 39 | assert "test", @container.get_env("MARIADB_DATABASE") 40 | assert "test", @container.get_env("MARIADB_USER") 41 | assert "test", @container.get_env("MARIADB_PASSWORD") 42 | assert "test", @container.get_env("MARIADB_ROOT_PASSWORD") 43 | end 44 | 45 | def test_it_has_the_default_port_mapped 46 | assert @container.mapped_port(3306) 47 | end 48 | 49 | def test_it_supports_custom_keyword_arguments 50 | container = Testcontainers::MariadbContainer.new(filesystem_binds: ["#{Dir.pwd}/custom/conf:/etc/mysql/conf.d:rw"]) 51 | assert_equal ["#{Dir.pwd}/custom/conf:/etc/mysql/conf.d:rw"], container.filesystem_binds 52 | end 53 | 54 | def test_it_returns_the_default_database_url 55 | assert_equal "mariadb://test:test@#{@host}:#{@port}/test", @container.database_url 56 | end 57 | 58 | def test_it_returns_the_database_url_with_custom_database 59 | assert_equal "mariadb://test:test@#{@host}:#{@port}/foo", @container.database_url(database: "foo") 60 | end 61 | 62 | def test_it_returns_the_database_url_with_custom_protocol 63 | assert_equal "mysql2://test:test@#{@host}:#{@port}/test", @container.database_url(protocol: "mysql2") 64 | end 65 | 66 | def test_it_returns_the_database_url_with_custom_username 67 | assert_equal "mariadb://foo:test@#{@host}:#{@port}/test", @container.database_url(username: "foo") 68 | end 69 | 70 | def test_it_returns_the_database_url_with_custom_password 71 | assert_equal "mariadb://test:bar@#{@host}:#{@port}/test", @container.database_url(password: "bar") 72 | end 73 | 74 | def test_it_returns_the_database_url_with_custom_options 75 | assert_equal "mariadb://test:test@#{@host}:#{@port}/test?useSSL=true", @container.database_url(options: {"useSSL" => "true"}) 76 | end 77 | 78 | def test_it_is_reachable 79 | client = Mysql2::Client.new(host: @host, username: "test", password: "test", port: @port, database: "test") 80 | assert_equal({"number" => 1}, client.query("SELECT 1 AS number").first) 81 | end 82 | end 83 | -------------------------------------------------------------------------------- /selenium/test/selenium_container_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "test_helper" 4 | require "selenium-webdriver" 5 | 6 | class SeleniumContainerTest < TestcontainersTest 7 | def before_all 8 | super 9 | @container = Testcontainers::SeleniumContainer.new 10 | @container.start 11 | @host = @container.host 12 | @port = @container.first_mapped_port 13 | end 14 | 15 | def after_all 16 | if @container&.exists? 17 | @container&.stop if @container&.running? 18 | @container&.remove 19 | end 20 | 21 | super 22 | end 23 | 24 | def test_it_returns_the_default_image 25 | assert_equal "selenium/standalone-firefox:latest", @container.image 26 | end 27 | 28 | def test_it_supports_custom_capabilities_to_build_image 29 | container = Testcontainers::SeleniumContainer.new(capabilities: :chrome) 30 | assert_equal "selenium/standalone-chrome:latest", container.image 31 | end 32 | 33 | def test_it_supports_custom_image 34 | container = Testcontainers::SeleniumContainer.new("selenium/standalone-chrome:114.0.5735.106-chromedriver-114.0.5735.90-20230607") 35 | assert_equal "selenium/standalone-chrome:114.0.5735.106-chromedriver-114.0.5735.90-20230607", container.image 36 | end 37 | 38 | def test_it_returns_the_default_port 39 | assert_equal 4444, @container.port 40 | end 41 | 42 | def test_it_returns_the_default_port_vnc 43 | assert_equal 5900, @container.vnc_port 44 | end 45 | 46 | def test_it_is_configured_with_the_default_environment_variables 47 | assert "localhost", @container.get_env("no_proxy") 48 | assert "true", @container.get_env("START_XVFB") 49 | assert "localhost", @container.get_env("HUB_ENV_no_proxy") 50 | end 51 | 52 | def test_it_has_the_default_port_mapped_vnc 53 | assert @container.mapped_port(5900) 54 | end 55 | 56 | def test_it_has_the_default_port_mapped 57 | assert @container.mapped_port(4444) 58 | end 59 | 60 | def test_it_supports_custom_keyword_arguments 61 | @container = Testcontainers::SeleniumContainer.new(filesystem_binds: ["/dev/shm:/dev/shm:rw"]) 62 | assert_equal ["/dev/shm:/dev/shm:rw"], @container.filesystem_binds 63 | end 64 | 65 | def test_it_returns_the_default_selenium_url 66 | assert "http://#{@host}:#{@port}/wd/hub", @container.selenium_url 67 | end 68 | 69 | def test_it_return_selenium_url_with_costume_protocol 70 | assert_equal "https://#{@host}:#{@port}/wd/hub", @container.selenium_url(protocol: "https://") 71 | end 72 | 73 | def test_it_is_reachable_using_firefox 74 | driver = Selenium::WebDriver.for(:firefox, url: @container.selenium_url) 75 | driver.navigate.to "https://www.google.com" 76 | 77 | assert driver.find_element(class: "gNO89b") 78 | end 79 | 80 | def test_it_is_reachable_using_chrome 81 | container = Testcontainers::SeleniumContainer.new(capabilities: :chrome) 82 | container.start 83 | driver = Selenium::WebDriver.for(:chrome, url: container.selenium_url) 84 | driver.navigate.to "https://www.google.com" 85 | 86 | assert driver.find_element(class: "gNO89b") 87 | end 88 | end 89 | -------------------------------------------------------------------------------- /selenium/README.md: -------------------------------------------------------------------------------- 1 | # Testcontainers module for Selenium 2 | 3 | ## Installation 4 | 5 | Add the library to the test section in your application's Gemfile: 6 | 7 | ```ruby 8 | group :test do 9 | gem 'testcontainers-selenium' 10 | end 11 | ``` 12 | 13 | And then execute: 14 | 15 | ```bash 16 | $ bundle install 17 | ``` 18 | 19 | Or install it yourself as: 20 | 21 | ```bash 22 | $ gem install testcontainers-selenium 23 | ``` 24 | 25 | ## Usage 26 | 27 | To use the library, you first need to require it: 28 | 29 | ```ruby 30 | require "testcontainers/selenium" 31 | ``` 32 | 33 | 34 | ### Creating a Selenium Container 35 | 36 | Create a new instance of the `Testcontainers::SeleniumContainer` class: 37 | 38 | ```ruby 39 | container = Testcontainers::SeleniumContainer.new 40 | ``` 41 | 42 | This creates a new container with the default Selenium configuration for firefox, the vnc password will be `secret`. You can customise by passing arguments to the constructor: 43 | 44 | ```ruby 45 | container = Testcontainers::SeleniumContainer.new(capabilities: :chrome, vnc_no_password: true) 46 | ``` 47 | 48 | ### Starting and Stopping a container 49 | 50 | Start the container 51 | 52 | ```ruby 53 | container.start 54 | ``` 55 | 56 | Stop the container when you're done 57 | 58 | ```ruby 59 | container.stop 60 | ``` 61 | 62 | ### Connecting to the Selenium container 63 | 64 | Once the container is running, you can obtain the connection details using the following methods: 65 | 66 | 67 | ```ruby 68 | host = container.host 69 | post = container.first_mapped_port 70 | ``` 71 | 72 | Or, you can generate a full Selenium URL 73 | 74 | 75 | ```ruby 76 | selenium_url = container.selenium_url 77 | ``` 78 | 79 | ### Examples 80 | 81 | There are complete examples of how to use testcontainers-selenium to create containers, connects to it, and navigate through different browsers: 82 | 83 | 84 | ```ruby 85 | require "testcontainers/selenium" 86 | require "selenium-webdriver" 87 | 88 | container = Testcontainers::SeleniumContainer.new 89 | container.start 90 | 91 | driver = Selenium::WebDriver.for(:firefox, :url => @container.selenium_url) 92 | 93 | driver.navigate.to "https://www.google.com" 94 | 95 | driver.screenshot 96 | ``` 97 | 98 | The previous example creates a container and after create a client for do a connections wiht the google page,finally we take a screenshot from the current page 99 | 100 | ## Contributing 101 | 102 | Bug reports and pull requests are welcome on GitHub at https://github.com/testcontainers/testcontainers-ruby. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/testcontainers/testcontainers-ruby/blob/main/CODE_OF_CONDUCT.md). 103 | 104 | ## License 105 | 106 | The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT). 107 | 108 | ## Code of Conduct 109 | 110 | Everyone interacting in the Testcontainers project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/testcontainers/testcontainers-ruby/blob/main/CODE_OF_CONDUCT.md). 111 | -------------------------------------------------------------------------------- /redpanda/lib/testcontainers/redpanda.rb: -------------------------------------------------------------------------------- 1 | require_relative "redpanda/version" 2 | require "testcontainers" 3 | 4 | module Testcontainers 5 | # RedpandaContainer class is used to manage containers that run a Redpanda 6 | class RedpandaContainer < ::Testcontainers::DockerContainer 7 | # Default port used by the container 8 | REDPANDA_DEFAULT_PORT = 9092 9 | 10 | # Default port used for schema registry 11 | REDPANDA_DEFAULT_SCHEMA_REGISTRY_PORT = 8081 12 | 13 | # Default image used by the container 14 | REDPANDA_DEFAULT_IMAGE = "redpandadata/redpanda:latest" 15 | 16 | # Default path to the startup script 17 | STARTUP_SCRIPT_PATH = "/testcontainers.sh" 18 | 19 | # Initializes a new instance of RedpandaContainer 20 | # 21 | # @param image [String] the image to use 22 | # @param kwargs [Hash] the options to pass to the container. See {DockerContainer#initialize} 23 | # @return [RedpandaContainer] a new instance of RedpandaContainer 24 | def initialize(image = REDPANDA_DEFAULT_IMAGE, **kwargs) 25 | super 26 | end 27 | 28 | # Starts the container 29 | # 30 | # @return [RedpandaContainer] self 31 | def start 32 | with_exposed_ports(REDPANDA_DEFAULT_PORT, REDPANDA_DEFAULT_SCHEMA_REGISTRY_PORT) 33 | with_entrypoint(%w[/bin/sh]) 34 | with_command(["-c", "while [ ! -f #{STARTUP_SCRIPT_PATH} ]; do sleep 0.1; done; #{STARTUP_SCRIPT_PATH}"]) 35 | super 36 | 37 | # Copy the startup script to the container 38 | copy_file_to_container("/tmp" + STARTUP_SCRIPT_PATH, _startup_script) 39 | 40 | # File is copied with root owner and permissions, so we need to change them 41 | exec_as_root(%w[chmod 777] + ["/tmp" + STARTUP_SCRIPT_PATH]) 42 | exec_as_root(%w[chown redpanda:redpanda] + ["/tmp" + STARTUP_SCRIPT_PATH]) 43 | 44 | # Copy the startup script to expected location 45 | exec_as_root(%w[cp] + ["/tmp" + STARTUP_SCRIPT_PATH] + [STARTUP_SCRIPT_PATH]) 46 | 47 | wait_for_logs(/Successfully started Redpanda!/) 48 | self 49 | end 50 | 51 | def port 52 | REDPANDA_DEFAULT_PORT 53 | end 54 | 55 | # Returns the Redpanda connection url (e.g. localhost:9092) 56 | # 57 | # @return [String] the Redpanda connection url 58 | # @raise [ConnectionError] If the connection to the Docker daemon fails. 59 | # @raise [ContainerNotStartedError] If the container has not been started. 60 | def connection_url 61 | "#{host}:#{mapped_port(port)}" 62 | end 63 | 64 | def bootstrap_servers 65 | "PLAINTEXT://#{host}:#{mapped_port(port)}" 66 | end 67 | 68 | def schema_registry_address 69 | "http://#{host}:#{mapped_port(REDPANDA_DEFAULT_SCHEMA_REGISTRY_PORT)}" 70 | end 71 | 72 | private 73 | 74 | def _startup_script 75 | startup_script = StringIO.new 76 | startup_script.print("#!/bin/sh\n") 77 | startup_script.print("/usr/bin/rpk redpanda start --mode=dev-container --smp=1 --memory=1G") 78 | startup_script.print(" --kafka-addr PLAINTEXT://0.0.0.0:29092,OUTSIDE://0.0.0.0:9092") 79 | startup_script.print(" --advertise-kafka-addr PLAINTEXT://127.0.0.1:29092,OUTSIDE://#{host}:#{mapped_port(port)}") 80 | startup_script 81 | end 82 | 83 | def exec_as_root(cmd, options = {}) 84 | exec(cmd, options.merge({"User" => "root"})) 85 | end 86 | end 87 | end 88 | -------------------------------------------------------------------------------- /rabbitmq/test/rabbitmq_container_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "test_helper" 4 | require "bunny" 5 | 6 | class RabbitmqContainerTest < TestcontainersTest 7 | def before_all 8 | super 9 | 10 | @container = Testcontainers::RabbitmqContainer.new 11 | @container.start 12 | @host = @container.host 13 | @port = @container.first_mapped_port 14 | end 15 | 16 | def after_all 17 | if @container&.exists? 18 | @container&.stop if @container&.running? 19 | @container&.remove 20 | end 21 | 22 | super 23 | end 24 | 25 | def test_it_returns_the_default_image 26 | assert_equal "rabbitmq:latest", @container.image 27 | end 28 | 29 | def test_it_supports_custom_image 30 | container = Testcontainers::RabbitmqContainer.new("rabbitmq:management") 31 | assert_equal "rabbitmq:management", container.image 32 | end 33 | 34 | def test_it_returns_the_default_port_for_queues 35 | assert_equal 5672, @container.port 36 | end 37 | 38 | def test_it_returns_the_default_port_for_management_ui 39 | assert_equal 15672, @container.management_ui_port 40 | end 41 | 42 | def test_it_is_configured_with_the_default_environment_variables 43 | assert_equal "rabbitmq", @container.get_env("RABBITMQ_DEFAULT_USER") 44 | assert_equal "rabbitmq", @container.get_env("RABBITMQ_DEFAULT_PASS") 45 | assert_equal "/", @container.get_env("RABBITMQ_DEFAULT_VHOST") 46 | end 47 | 48 | def test_it_has_the_default_port_mapped 49 | assert @container.mapped_port(5672) 50 | end 51 | 52 | def test_it_supports_custom_keyword_arguments 53 | container = Testcontainers::RabbitmqContainer.new(env: {"RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS" => "foo"}) 54 | assert_equal "foo", container.get_env("RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS") 55 | end 56 | 57 | def test_it_returns_the_default_rabbitmq_url 58 | assert_equal "amqp://rabbitmq:rabbitmq@#{@host}:#{@port}", @container.rabbitmq_url 59 | end 60 | 61 | def test_it_returns_the_rabbitmq_url_with_custom_vhost 62 | assert_equal "amqp://rabbitmq:rabbitmq@#{@host}:#{@port}/foo", @container.rabbitmq_url(vhost: "foo") 63 | end 64 | 65 | def test_it_returns_the_rabbitmq_url_with_custom_vhost_with_slash 66 | assert_equal "amqp://rabbitmq:rabbitmq@#{@host}:#{@port}/bar", @container.rabbitmq_url(vhost: "/bar") 67 | end 68 | 69 | def test_it_returns_the_rabbitmq_url_with_custom_protocol 70 | assert_equal "amqps://rabbitmq:rabbitmq@#{@host}:#{@port}", @container.rabbitmq_url(protocol: "amqps://") 71 | end 72 | 73 | def test_it_returns_the_rabbitmq_url_with_custom_username 74 | assert_equal "amqp://foo:rabbitmq@#{@host}:#{@port}", @container.rabbitmq_url(username: "foo") 75 | end 76 | 77 | def test_it_returns_the_rabbitmq_url_with_custom_password 78 | assert_equal "amqp://rabbitmq:bar@#{@host}:#{@port}", @container.rabbitmq_url(password: "bar") 79 | end 80 | 81 | def test_it_is_reachable 82 | connection = Bunny.new(@container.rabbitmq_url) 83 | connection.start 84 | channel = connection.create_channel 85 | queue = channel.queue("hello") 86 | channel.default_exchange.publish("Hello World!", routing_key: queue.name) 87 | 88 | queue.subscribe(manual_ack: true) do |delivery_info, _metadata, payload| 89 | assert_equal "Hello World!", payload 90 | channel.ack(delivery_info.delivery_tag) 91 | end 92 | 93 | sleep 1.0 94 | 95 | channel.close 96 | connection.close 97 | end 98 | end 99 | --------------------------------------------------------------------------------