diff --git a/.circleci/config.yml b/.circleci/config.yml index 7efeec46ea3..51fc68ebdd1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,15 +1,31 @@ version: 2.1 -# Common variables, containers, jobs and steps. -job_defaults: &job_defaults - # TODO: We should move away from using a directory - # TODO: that requires root permission to be created. - # TODO: Changing this requires rebuilding all docker images. - working_directory: /app - shell: /bin/bash --login - test_containers: - - &job_parameters + - &container_base + image: <> + environment: + BUNDLE_GEMFILE: /app/Gemfile + JRUBY_OPTS: --dev # Faster JVM startup: https://github.com/jruby/jruby/wiki/Improving-startup-time#use-the---dev-flag + # Override number of concurrent compiles in grpc gem, see https://github.com/grpc/grpc/pull/28250 and https://github.com/DataDog/dd-trace-rb/issues/1791 + # If you see gem installation failing with "Killed" on CircleCI and `gem install --platform ruby grpc` reproduces the + # issue when you connect to the testing container via ssh, then try lowering this file a notch. + GRPC_RUBY_BUILD_PROCS: 6 + DD_INSTRUMENTATION_TELEMETRY_ENABLED: false + DD_REMOTE_CONFIGURATION_ENABLED: false + TEST_OPENSEARCH_HOST: opensearch + TEST_OPENSEARCH_PORT: 9200 + DD_AGENT_HOST: testagent + DD_TRACE_AGENT_PORT: 9126 + DATADOG_GEM_CI: true + TEST_DATADOG_INTEGRATION: 1 + COVERAGE_BASE_DIR: coverage + - &test_job_default + # TODO: We should move away from using a directory + # TODO: that requires root permission to be created. + # TODO: Changing this requires rebuilding all docker images. + working_directory: /app + shell: /bin/bash --login + resource_class: <> parameters: ruby_version: description: Ruby version @@ -25,98 +41,8 @@ test_containers: description: Use latest version of dependencies during testing type: boolean default: false - resource_class: <> - - &container_base_environment - BUNDLE_GEMFILE: /app/Gemfile - JRUBY_OPTS: --dev # Faster JVM startup: https://github.com/jruby/jruby/wiki/Improving-startup-time#use-the---dev-flag - # Override number of concurrent compiles in grpc gem, see https://github.com/grpc/grpc/pull/28250 and https://github.com/DataDog/dd-trace-rb/issues/1791 - # If you see gem installation failing with "Killed" on CircleCI and `gem install --platform ruby grpc` reproduces the - # issue when you connect to the testing container via ssh, then try lowering this file a notch. - GRPC_RUBY_BUILD_PROCS: 6 - DD_INSTRUMENTATION_TELEMETRY_ENABLED: false - DD_REMOTE_CONFIGURATION_ENABLED: false - TEST_OPENSEARCH_HOST: opensearch - TEST_OPENSEARCH_PORT: 9200 - DD_AGENT_HOST: testagent - DD_TRACE_AGENT_PORT: 9126 - DATADOG_GEM_CI: true - - &container_parameters_environment - - *container_base_environment - - TEST_DATADOG_INTEGRATION: 1 - - COVERAGE_BASE_DIR: coverage - - &container_base - image: <> - environment: - *container_parameters_environment - - &test_job_default - <<: *job_defaults - <<: *job_parameters docker: - *container_base - - &container_postgres - image: postgres:9.6 - environment: - - POSTGRES_PASSWORD=postgres - - POSTGRES_USER=postgres - - POSTGRES_DB=postgres - - &postgres_port 5432 - - &container_presto - # Move to trinodb/trino after https://github.com/treasure-data/presto-client-ruby/issues/64 is resolved. - image: starburstdata/presto:332-e.9 - - &presto_port 8080 - - &container_mysql - image: mysql:8.0 - # As of MySQL 8.0, caching_sha2_password is now the default authentication plugin - # rather than mysql_native_password which was the default in previous versions. - command: --default-authentication-plugin=mysql_native_password - environment: - - MYSQL_ROOT_PASSWORD=root - - MYSQL_PASSWORD=mysql - - MYSQL_USER=mysql - - &mysql_port 3306 - - &opensearch_host opensearch - - &container_opensearch - image: opensearchproject/opensearch:2.8.0 - name: *opensearch_host - environment: - - discovery.type=single-node - - DISABLE_SECURITY_PLUGIN=true - - DISABLE_PERFORMANCE_ANALYZER_AGENT_CLI=true - # Make sure it works on nearly full disk. - - cluster.routing.allocation.disk.threshold_enabled=true - - cluster.routing.allocation.disk.watermark.low=3gb - - cluster.routing.allocation.disk.watermark.high=2gb - - cluster.routing.allocation.disk.watermark.flood_stage=1gb - - cluster.routing.allocation.disk.threshold_enabled=false - - &opensearch_port 9200 - - &container_elasticsearch - image: elasticsearch:8.1.3 - environment: - # Ensure production cluster requirements are not enforced - - discovery.type=single-node - - xpack.security.enabled=false - - ES_JAVA_OPTS=-Xms750m -Xmx750m - - &elasticsearch_port 9200 - - &container_redis - image: redis:6.2 - - &redis_port 6379 - - &container_mongo - image: mongo:3.5 - - &mongo_port 27017 - - &container_memcached - image: memcached:1.5-alpine - - &memcached_port 11211 - - &container_testagent - image: ghcr.io/datadog/dd-apm-test-agent/ddapm-test-agent:v1.12.0 - name: testagent - environment: - - LOG_LEVEL=DEBUG - - TRACE_LANGUAGE=ruby - - PORT=9126 - - DD_POOL_TRACE_CHECK_FAILURES=true - - DD_DISABLE_ERROR_RESPONSES=true - - ENABLED_CHECKS=trace_content_length,trace_stall,meta_tracer_version_header,trace_count_header,trace_peer_service,trace_dd_service - - &testagent_port 9126 check_exact_bundle_cache_hit: &check_exact_bundle_cache_hit run: @@ -151,22 +77,6 @@ step_bundle_install: &step_bundle_install else echo "All required gems were found in cache." fi -step_rubocop: &step_rubocop - run: - name: Delint with Rubocop - # There's no straightforward way to get the number of available processors & CPU threads in CircleCI. - # Currently it always return 18 physical processors and 36 threads, regardless of executor size. - # The workaround is to use `cpu.shares / 1024`: - # https://discuss.circleci.com/t/environment-variable-set-to-the-number-of-available-cpus/32670/4 - command: PARALLEL_PROCESSOR_COUNT=$((`cat /sys/fs/cgroup/cpu/cpu.shares` / 1024)) bundle exec rake rubocop -step_standardrb: &step_standardrb - run: - name: Delint with Standardrb - # There's no straightforward way to get the number of available processors & CPU threads in CircleCI. - # Currently it always return 18 physical processors and 36 threads, regardless of executor size. - # The workaround is to use `cpu.shares / 1024`: - # https://discuss.circleci.com/t/environment-variable-set-to-the-number-of-available-cpus/32670/4 - command: PARALLEL_PROCESSOR_COUNT=$((`cat /sys/fs/cgroup/cpu/cpu.shares` / 1024)) bundle exec rake standard step_appraisal_install: &step_appraisal_install run: name: Install Appraisal gems @@ -244,12 +154,6 @@ filters_all_branches_and_tags: &filters_all_branches_and_tags filters: tags: only: /.*/ -filters_only_release_tags: &filters_only_release_tags - filters: - branches: - ignore: /.*/ - tags: - only: /^v\d+(\.\d+){0,3}(\.(alpha|beta|rc)\d+)?$/ orbs: orb: @@ -324,15 +228,50 @@ orbs: <<: *test_job_default docker: - <<: *container_base - - *container_postgres - - *container_presto - - *container_mysql - - *container_opensearch - - *container_elasticsearch - - *container_redis - - *container_mongo - - *container_memcached - - *container_testagent + - image: postgres:9.6 + environment: + - POSTGRES_PASSWORD=postgres + - POSTGRES_USER=postgres + - POSTGRES_DB=postgres + - image: starburstdata/presto:332-e.9 # Move to trinodb/trino after https://github.com/treasure-data/presto-client-ruby/issues/64 is resolved. + - image: mysql:8.0 + # As of MySQL 8.0, caching_sha2_password is now the default authentication plugin + # rather than mysql_native_password which was the default in previous versions. + command: --default-authentication-plugin=mysql_native_password + environment: + - MYSQL_ROOT_PASSWORD=root + - MYSQL_PASSWORD=mysql + - MYSQL_USER=mysql + - image: opensearchproject/opensearch:2.8.0 + name: opensearch + environment: + - discovery.type=single-node + - DISABLE_SECURITY_PLUGIN=true + - DISABLE_PERFORMANCE_ANALYZER_AGENT_CLI=true + # Make sure it works on nearly full disk. + - cluster.routing.allocation.disk.threshold_enabled=true + - cluster.routing.allocation.disk.watermark.low=3gb + - cluster.routing.allocation.disk.watermark.high=2gb + - cluster.routing.allocation.disk.watermark.flood_stage=1gb + - cluster.routing.allocation.disk.threshold_enabled=false + - image: elasticsearch:8.1.3 + environment: + # Ensure production cluster requirements are not enforced + - discovery.type=single-node + - xpack.security.enabled=false + - ES_JAVA_OPTS=-Xms750m -Xmx750m + - image: redis:6.2 + - image: mongo:3.5 + - image: memcached:1.5-alpine + - image: ghcr.io/datadog/dd-apm-test-agent/ddapm-test-agent:v1.18.0 + name: testagent + environment: + - LOG_LEVEL=DEBUG + - TRACE_LANGUAGE=ruby + - PORT=9126 + - DD_POOL_TRACE_CHECK_FAILURES=true + - DD_DISABLE_ERROR_RESPONSES=true + - ENABLED_CHECKS=trace_content_length,trace_stall,meta_tracer_version_header,trace_count_header,trace_peer_service,trace_dd_service parallelism: 22 steps: - restore_cache: @@ -348,25 +287,25 @@ orbs: echo 'export COVERAGE_DIR="$COVERAGE_BASE_DIR/versions/$CIRCLE_JOB/$CIRCLE_NODE_INDEX"' >> $BASH_ENV # Wait for containers to start - docker-wait: - port: *postgres_port + port: 5432 - docker-wait: - port: *presto_port + port: 8080 - docker-wait: - port: *mysql_port + port: 3306 - docker-wait: - host: *opensearch_host - port: *opensearch_port + host: opensearch + port: 9200 - docker-wait: - port: *elasticsearch_port + port: 9200 - docker-wait: - port: *redis_port + port: 6379 - docker-wait: - port: *mongo_port + port: 27017 - docker-wait: - port: *memcached_port + port: 11211 - docker-wait: host: "testagent" - port: *testagent_port + port: 9126 - *step_run_all_tests - *step_get_test_agent_trace_check_results - store_test_results: @@ -375,17 +314,6 @@ orbs: root: . paths: - coverage - lint: - <<: *test_job_default - steps: - - restore_cache: - keys: - - '{{ .Environment.CIRCLE_CACHE_VERSION }}-bundled-repo-<>-{{ .Environment.CIRCLE_SHA1 }}' - - restore_cache: - keys: - - bundle-{{ .Environment.CIRCLE_CACHE_VERSION }}-{{ checksum ".circleci/images/primary/binary_version" }}-<>-{{ checksum "lib/datadog/version.rb" }}-{{ .Branch }}-{{ checksum ".circleci/bundle_checksum" }} - - *step_rubocop - - *step_standardrb coverage: <<: *test_job_default steps: @@ -513,11 +441,6 @@ workflows: version: 2 build-and-test: jobs: - - orb/lint: - <<: *config-2_7-small - name: lint - requires: - - build-2.7 - orb/coverage: <<: *config-2_7-small name: coverage @@ -661,142 +584,3 @@ workflows: name: test-jruby-9.4 requires: - build-jruby-9.4 - # This workflow runs the same `build` and `test` jobs as above on a schedule. - # Tasks related to housekeeping (e.g. prerelease) are not relevant - # to this daily check, as they are not expected to be impacted here. - edge: - triggers: - - schedule: - cron: "0 0 * * 1-5" # Every weekday - filters: - branches: - only: - - master - jobs: - # Integration - - orb/build_and_test_integration: - name: build_and_test_integration-2.5 - integration_apps: 'rack rails-five rails-six' - ruby_version: '2.5' - <<: *filters_all_branches_and_tags - - orb/build_and_test_integration: - name: build_and_test_integration-2.6 - integration_apps: 'rack rails-five rails-six sinatra2-classic sinatra2-modular' - ruby_version: '2.6' - <<: *filters_all_branches_and_tags - - orb/build_and_test_integration: - name: build_and_test_integration-2.7 - integration_apps: 'rack rails-five rails-six rails-seven sinatra2-classic sinatra2-modular' - ruby_version: '2.7' - <<: *filters_all_branches_and_tags - - orb/build_and_test_integration: - name: build_and_test_integration-3.0 - integration_apps: 'rack rails-six rails-seven sinatra2-classic sinatra2-modular' - ruby_version: '3.0' - <<: *filters_all_branches_and_tags - - orb/build_and_test_integration: - name: build_and_test_integration-3.1 - integration_apps: 'rack rails-six rails-seven sinatra2-classic sinatra2-modular' - ruby_version: '3.1' - <<: *filters_all_branches_and_tags - - orb/build_and_test_integration: - name: build_and_test_integration-3.2 - integration_apps: 'rack rails-six rails-seven sinatra2-classic sinatra2-modular' - ruby_version: '3.2' - <<: *filters_all_branches_and_tags - - orb/build_and_test_integration: - name: build_and_test_integration-3.3 - integration_apps: 'rack rails-six rails-seven sinatra2-classic sinatra2-modular' - ruby_version: '3.3' - <<: *filters_all_branches_and_tags - # ADD NEW RUBIES HERE - - orb/build: - <<: *config-2_5 - name: build-2.5 - edge: true - - orb/test: - <<: *config-2_5 - name: test-2.5 - requires: - - build-2.5 - - orb/build: - <<: *config-2_6 - name: build-2.6 - edge: true - - orb/test: - <<: *config-2_6 - name: test-2.6 - requires: - - build-2.6 - - orb/build: - <<: *config-2_7 - name: build-2.7 - edge: true - - orb/test: - <<: *config-2_7 - name: test-2.7 - requires: - - build-2.7 - - orb/build: - <<: *config-3_0 - name: build-3.0 - edge: true - - orb/test: - <<: *config-3_0 - name: test-3.0 - requires: - - build-3.0 - - orb/build: - <<: *config-3_1 - name: build-3.1 - edge: true - - orb/test: - <<: *config-3_1 - name: test-3.1 - requires: - - build-3.1 - - orb/build: - <<: *config-3_2 - name: build-3.2 - edge: true - - orb/test: - <<: *config-3_2 - name: test-3.2 - requires: - - build-3.2 - - orb/build: - <<: *config-3_3 - name: build-3.3 - edge: true - - orb/test: - <<: *config-3_3 - name: test-3.3 - requires: - - build-3.3 - # ADD NEW RUBIES HERE - - orb/build: - <<: *config-jruby-9_2 - name: build-jruby-9.2 - edge: true - - orb/test: - <<: *config-jruby-9_2 - name: test-jruby-9.2 - requires: - - build-jruby-9.2 - - orb/build: - <<: *config-jruby-9_3 - name: build-jruby-9.3 - edge: true - - orb/test: - <<: *config-jruby-9_3 - name: test-jruby-9.3 - requires: - - build-jruby-9.3 - - orb/build: - <<: *config-jruby-9_4 - name: build-jruby-9.4 - - orb/test: - <<: *config-jruby-9_4 - name: test-jruby-9.4 - requires: - - build-jruby-9.4 diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index e8f10f9cfe9..d3d290b41fe 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -1,20 +1,27 @@ name: Check on: push: - branches: [ '**' ] - pull_request: - # The branches below must be a subset of the branches above - branches: [ '**' ] + jobs: + lint: + runs-on: ubuntu-latest + container: + image: ghcr.io/datadog/images-rb/engines/ruby:3.2 + steps: + - uses: actions/checkout@v4 + - name: Install dependencies + run: bundle install + - run: bundle exec rake rubocop standard + check: name: Check types - runs-on: ubuntu-22.04 + runs-on: ubuntu-latest + container: + image: ghcr.io/datadog/images-rb/engines/ruby:3.2 steps: - uses: actions/checkout@v4 - - uses: ruby/setup-ruby@v1 - with: - ruby-version: '3.2' - bundler-cache: true # runs 'bundle install' and caches installed gems automatically + - name: Install dependencies + run: bundle install - name: Check for stale signature files run: bundle exec rake rbs:stale - name: Check for missing signature files diff --git a/Rakefile b/Rakefile index 652e5c245bd..aa67152a835 100644 --- a/Rakefile +++ b/Rakefile @@ -59,7 +59,8 @@ namespace :test do command = if appraisal_group.empty? "bundle exec rake #{spec_task}" else - "bundle exec appraisal #{ruby_runtime}-#{appraisal_group} rake #{spec_task}" + gemfile = File.join(File.dirname(__FILE__), 'gemfiles', "#{ruby_runtime}-#{appraisal_group}.gemfile".tr('-', '_')) + "env BUNDLE_GEMFILE=#{gemfile} bundle exec rake #{spec_task}" end command += "'[#{spec_arguments}]'" if spec_arguments diff --git a/appraisal/ruby-3.4.rb b/appraisal/ruby-3.4.rb index 4c0cf60bd99..43a4e1eb122 100644 --- a/appraisal/ruby-3.4.rb +++ b/appraisal/ruby-3.4.rb @@ -125,6 +125,9 @@ gem 'sneakers', '>= 2.12.0' gem 'sucker_punch' gem 'que', '>= 1.0.0' + + # When Rack 3+ is used, we need rackup. + gem 'rackup' end [ diff --git a/docs/DevelopmentGuide.md b/docs/DevelopmentGuide.md index 458f2883536..6b21fa33902 100644 --- a/docs/DevelopmentGuide.md +++ b/docs/DevelopmentGuide.md @@ -105,6 +105,24 @@ TEST_METADATA = { } ``` +**Using appraisal** + +`appraisal` command should only be used to update gemfiles in `gemfiles/` +and install dependencies. It should not be used to run tests, since it does not +work in all configurations. To run the tests, use: + +```sh +env BUNDLE_GEMFILE=gemfiles/#{ruby_runtime}_#{appraisal_group}.gemfile rake #{spec_task} +``` + +Note that the file names use underscores while appraisal group and +configuration definitions use dashes. The conversion could be performed as +follows: + +```sh +env BUNDLE_GEMFILE=gemfiles/#{ruby_runtime.tr('-', '_')}_#{appraisal_group.tr('-', '_')}.gemfile rake #{spec_task} +``` + **Working with appraisal groups** Checkout [Apppraisal](https://github.com/thoughtbot/appraisal) to learn the basics. diff --git a/gemfiles/ruby_3.4_contrib.gemfile b/gemfiles/ruby_3.4_contrib.gemfile index 3afda7b1380..aee3ff4df95 100644 --- a/gemfiles/ruby_3.4_contrib.gemfile +++ b/gemfiles/ruby_3.4_contrib.gemfile @@ -43,6 +43,7 @@ gem "sidekiq", "~> 7" gem "sneakers", ">= 2.12.0" gem "sucker_punch" gem "que", ">= 1.0.0" +gem "rackup" group :check do gem "ruby_memcheck", ">= 3" diff --git a/gemfiles/ruby_3.4_contrib.gemfile.lock b/gemfiles/ruby_3.4_contrib.gemfile.lock index d17af5081a1..5054b7d3ce3 100644 --- a/gemfiles/ruby_3.4_contrib.gemfile.lock +++ b/gemfiles/ruby_3.4_contrib.gemfile.lock @@ -113,6 +113,8 @@ GEM rack (>= 3.0.0) rack-test (2.1.0) rack (>= 1.3) + rackup (2.2.0) + rack (>= 3) rainbow (3.1.1) rake (12.3.3) rake-compiler (1.2.7) @@ -247,6 +249,7 @@ DEPENDENCIES pry-stack_explorer que (>= 1.0.0) rack-test + rackup rake (>= 12.3) rake-compiler (~> 1.1, >= 1.1.1) resque diff --git a/spec/datadog/tracing/contrib/suite/integration_spec.rb b/spec/datadog/tracing/contrib/suite/integration_spec.rb index b6279e74baf..eaf37eb1f8a 100644 --- a/spec/datadog/tracing/contrib/suite/integration_spec.rb +++ b/spec/datadog/tracing/contrib/suite/integration_spec.rb @@ -8,7 +8,7 @@ require 'rack' # `Rack::Handler::WEBrick` was extracted to the `rackup` gem in Rack 3.0 -require 'rackup' if Rack::VERSION[0] >= 3 +require 'rackup' if Gem::Version.new(Rack::RELEASE) >= Gem::Version.new('3') require 'webrick' RSpec.describe 'contrib integration testing', :integration do