diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..851aa0c --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,29 @@ +name: CI + +on: + workflow_dispatch: + push: + branches: + - main + pull_request: + branches: + - main + schedule: + - cron: "0 0 * * *" + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number }} # Ensure that only one instance of this workflow is running per Pull Request + cancel-in-progress: true # Cancel any previous runs of this workflow + +jobs: + unit_tests: + runs-on: ubuntu-22.04 + steps: + - name: Configure git + run: 'git config --global init.defaultBranch main' + - uses: actions/checkout + - uses: ruby/setup-ruby + with: + ruby-version: '3.3' + - run: bundle + - run: bin/rails test diff --git a/Gemfile b/Gemfile index 2e94896..f5c2921 100644 --- a/Gemfile +++ b/Gemfile @@ -22,6 +22,12 @@ group :development, :test do gem "debug", platforms: %i[ mri mingw x64_mingw ] end +group :test do + gem 'minitest' + gem 'opentelemetry-test-helpers' + gem 'rack-test' +end + # OpenTelemetry gems with logging-related enhancements gem 'opentelemetry-api', git: 'https://github.com/kaylareopelle/opentelemetry-ruby', diff --git a/Gemfile.lock b/Gemfile.lock index 344fb3e..23efd0c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -395,6 +395,7 @@ GEM opentelemetry-api (~> 1.1) opentelemetry-semantic_conventions (1.10.0) opentelemetry-api (~> 1.0) + opentelemetry-test-helpers (0.4.0) psych (5.1.2) stringio puma (5.6.8) @@ -462,6 +463,7 @@ PLATFORMS DEPENDENCIES debug + minitest opentelemetry-api! opentelemetry-exporter-otlp! opentelemetry-exporter-otlp-logs! @@ -470,7 +472,9 @@ DEPENDENCIES opentelemetry-logs-api! opentelemetry-logs-sdk! opentelemetry-sdk! + opentelemetry-test-helpers puma (~> 5.0) + rack-test rails (~> 7.0.8) sqlite3 (~> 1.4) tzinfo-data diff --git a/test/controllers/test_controller_controller_test.rb b/test/controllers/test_controller_controller_test.rb new file mode 100644 index 0000000..b883536 --- /dev/null +++ b/test/controllers/test_controller_controller_test.rb @@ -0,0 +1,27 @@ +require "test_helper" + +class TestControllerControllerTest < ActionDispatch::IntegrationTest + test "OTel LogRecord emitted for Rails logs" do + get "/" + + assert_equal 200, status + assert_emitted /Completed 200 OK in/ + assert_emitted /Processing by TestController#index as HTML/ + end + + test "OTel LogRecord emitted for custom Ruby Logger" do + get "/" + + assert_equal 200, status + assert_emitted /Reporting from Ruby Logger/ + end + + def assert_emitted(body_regex) + emitted_log_records = LOGS_EXPORTER.emitted_log_records + + log_bodies = emitted_log_records.map(&:body) + + matches = log_bodies.select { |lb| lb.match?(body_regex) } + refute_empty matches + end +end diff --git a/test/test_helper.rb b/test/test_helper.rb new file mode 100644 index 0000000..c78b9e3 --- /dev/null +++ b/test/test_helper.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +ENV["OTEL_LOGS_EXPORTER"] = "console" +ENV["OTEL_TRACES_EXPORTER"] = "none" +ENV["OTEL_METRICS_EXPORTER"] = "none" +ENV["RAILS_ENV"] ||= "test" + +require_relative "../config/environment" +require "rails/test_help" +require "opentelemetry-test-helpers" + +LOGS_EXPORTER = OpenTelemetry::SDK::Logs::Export::InMemoryLogRecordExporter.new +LOG_RECORD_PROCESSOR = OpenTelemetry::SDK::Logs::Export::SimpleLogRecordProcessor.new(LOGS_EXPORTER) + +OpenTelemetry::SDK.configure do |c| + c.error_handler = ->(exception:, message:) { raise(exception || message) } + c.logger = Logger.new($stderr, level: ENV.fetch('OTEL_LOG_LEVEL', 'fatal').to_sym) + c.add_log_record_processor LOG_RECORD_PROCESSOR +end + +class ActiveSupport::TestCase + # Run tests in parallel with specified workers + parallelize(workers: :number_of_processors) + + # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order. + fixtures :all + + # Add more helper methods to be used by all tests here... +end