Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

parallel_test gem experimentation #5628

Merged
merged 1 commit into from
May 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Continuous Integration

on:
push:
branches:
- main
paths-ignore:
- "doc/**"
- "**/*.md"
pull_request:
branches:
- main

jobs:
rspec:
strategy:
fail-fast: false
matrix:
groups: ["[0, 1, 2, 3]", "[4, 5, 6, 7]", "[8, 9, 10, 11]"]
uses: ./.github/workflows/rspec.yml
secrets: inherit
with:
groups: ${{ matrix.groups }}
group_count: 12 # the total number of test groups, must match the groups listed in the matrix.groups
parallel_processes_count: 4 # the number of parallel processes to run tests in worker, must match the size of the
# inner arrays in the matrix.groups
combine_and_report:
uses: ./.github/workflows/combine_and_report.yml
needs: [rspec]
secrets: inherit
47 changes: 47 additions & 0 deletions .github/workflows/combine_and_report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
on:
workflow_call:
jobs:
combine_and_report:
runs-on: ubuntu-latest
steps:
- name: Checkout Project
uses: actions/checkout@v4
- name: Download artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
- name: Decompress chunk test reports
run: |
find artifacts -name "test_reports*.zip" -exec unzip -d test_reports {} \;
find test_reports -name "**/test_reports*.zip" -exec unzip -d test_reports {} \;
- name: Merge parallel runtime log parts
if: github.repository == github.event.pull_request.head.repo.full_name
run: |
cat artifacts/**/parallel_runtime_rspec*.log > parallel_runtime.log
- name: Upload log file to Azure Blob Storage
if: github.repository == github.event.pull_request.head.repo.full_name
env:
AZURE_STORAGE_KEY: ${{ secrets.STORAGE_ACCESS_KEY }}
AZURE_STORAGE_ACCOUNT: ${{ secrets.ACCOUNT_NAME }}
STORAGE_CONTAINER: ${{ secrets.STORAGE_CONTAINER }}
run: |
az storage blob upload \
-c $STORAGE_CONTAINER \
--file parallel_runtime.log \
-n parallel_runtime.log \
--overwrite true

- name: Test Summary
id: test_summary
uses: test-summary/action@v2
with:
paths: |
test_reports/**/rspec*.xml
- name: Set job status
# In this step we set the status of the job. Normally in case of failures, the next steps fail, so we have to
# use `if: always()` to make sure the next steps run.
if: ${{ steps.test_summary.outputs.failed > 0 }}
uses: actions/github-script@v6
with:
script: |
core.setFailed('There are test failures')
3 changes: 3 additions & 0 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ on:
paths-ignore:
- "doc/**"
- "**/*.md"
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
docker:
Expand Down
112 changes: 89 additions & 23 deletions .github/workflows/rspec.yml
Original file line number Diff line number Diff line change
@@ -1,22 +1,31 @@
name: rspec

on:
push:
branches:
- main
paths-ignore:
- "doc/**"
- "**/*.md"
pull_request:
branches:
- main
workflow_call:
inputs:
groups:
required: true
type: string
group_count:
required: true
type: number
parallel_processes_count:
required: true
type: number
env:
GROUPS_COMMA: ${{ join(fromJSON(inputs.groups), ',') }}
GROUPS_UNDERSCORE: ${{ join(fromJSON(inputs.groups), '_') }}

jobs:
rspec:
name: RSpec Groups ${{ inputs.groups }}
runs-on: ubuntu-latest
timeout-minutes: 10
env:
RAILS_ENV: test

BUNDLE_WITHOUT: "development"
CI_TOTAL_JOBS: ${{ inputs.group_count }}
CI_JOB_INDEX: ${{ inputs.groups }}
services:
db:
image: postgres:14.8
Expand All @@ -29,21 +38,42 @@ jobs:
--health-interval 10s
--health-timeout 5s
--health-retries 5

steps:
- uses: actions/checkout@v4

- name: Download parallel runtime log from Azure Blob Storage
if: github.repository == github.event.pull_request.head.repo.full_name
env:
AZURE_STORAGE_KEY: ${{ secrets.STORAGE_ACCESS_KEY }}
AZURE_STORAGE_ACCOUNT: ${{ secrets.ACCOUNT_NAME }}
STORAGE_CONTAINER: ${{ secrets.STORAGE_CONTAINER }}
run: |
echo $STORAGE_CONTAINER
echo ${{ secrets.STORAGE_CONTAINER }}
az storage blob download \
-c $STORAGE_CONTAINER \
--file old_parallel_runtime.log \
-n parallel_runtime.log

- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
bundler-cache: true

- name: Set up JS
uses: actions/setup-node@v4
with:
node-version: lts/gallium
cache: 'yarn'
- run: yarn

- name: Install PostgreSQL client
run: |
sudo apt-get -yqq install libpq-dev

- name: Build App
- name: Setup Parallel Database
env:
RAILS_ENV: test
POSTGRES_HOST: localhost
DATABASE_HOST: localhost
POSTGRES_USER: postgres
Expand All @@ -52,32 +82,68 @@ jobs:
POSTGRES_HOST_AUTH_METHOD: trust
POSTGRES_PORT: 5432
run: |
yarn
bundle exec rake db:create
bundle exec rake db:schema:load
echo "setting up database"
bundle exec rake parallel:create
bundle exec rake parallel:rake[db:schema:load]
echo "done"

- name: Build App
run: |
bundle exec rails css:build
bundle exec rails javascript:build

- name: Run rspec and upload code coverage
- name: Run rspec group ${{ inputs.group }}
env:
RAILS_ENV: test
POSTGRES_HOST: localhost
DATABASE_HOST: localhost
POSTGRES_USER: postgres
CASA_DATABASE_PASSWORD: password
POSTGRES_PASSWORD: password
POSTGRES_HOST_AUTH_METHOD: trust
POSTGRES_PORT: 5432
RUN_SIMPLECOV: true
CC_TEST_REPORTER_ID: 31464536e34ab26588cb951d0fa6b5898abdf401dbe912fd47274df298e432ac
continue-on-error: true
run: |
curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
chmod +x ./cc-test-reporter
./cc-test-reporter before-build
RUBYOPT='-W:no-deprecated -W:no-experimental' bundle exec rspec

RUBYOPT='-W:no-deprecated -W:no-experimental' bundle exec parallel_rspec \
-n "${CI_TOTAL_JOBS}" \
--only-group "${CI_JOB_INDEX}" \
--runtime-log old_parallel_runtime.log \
--verbose-command ./spec

./cc-test-reporter after-build --exit-code $?
cat tmp/spec_summary.log

- name: Compress reports
run: |
zip -r test_reports_${{ env.GROUPS_UNDERSCORE }}.zip tmp/reports

- name: Compress log
if: github.repository == github.event.pull_request.head.repo.full_name
run: |
mv tmp/parallel_runtime.log parallel_runtime_rspec_${{ env.GROUPS_UNDERSCORE }}.log

- name: Upload test reports
uses: actions/upload-artifact@v4
with:
name: test_reports_${{ env.GROUPS_UNDERSCORE }}.zip
path: test_reports_${{ env.GROUPS_UNDERSCORE }}.zip

- name: Upload file parallel tests runtime log
if: github.repository == github.event.pull_request.head.repo.full_name
uses: actions/upload-artifact@v4
with:
name: parallel_runtime_rspec_${{ env.GROUPS_UNDERSCORE }}.log
path: parallel_runtime_rspec_${{ env.GROUPS_UNDERSCORE }}.log

- name: Archive selenium screenshots
if: ${{ failure() }}
- name: Upload Selenium Screenshots
uses: actions/upload-artifact@v4
with:
name: selenium-screenshots
path: |
${{ github.workspace }}/tmp/capybara/*.png
${{ github.workspace }}/tmp/capybara/*.html
name: screenshots_${{ env.GROUPS_UNDERSCORE }}
path: ${{ github.workspace }}/tmp/screenshots${{ env.GROUPS_UNDERSCORE }}/
if-no-files-found: ignore
5 changes: 5 additions & 0 deletions .rspec_parallel
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
--format RspecJunitFormatter
--out tmp/reports/rspec_<%= ENV["GROUPS_UNDERSCORE"] %>_<%= ENV["TEST_ENV_NUMBER"] %>.xml
--format ParallelTests::RSpec::RuntimeLogger --out tmp/parallel_runtime.log
--format ParallelTests::RSpec::SummaryLogger --out tmp/spec_summary.log
--format ParallelTests::RSpec::FailuresLogger --out tmp/failing_specs.log
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ group :development, :test do
gem "rswag-specs"
gem "shoulda-matchers"
gem "standard", "~> 1.35.1"
gem "parallel_tests"
gem "rspec_junit_formatter"
end

group :development do
Expand Down
11 changes: 6 additions & 5 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,8 @@ GEM
bigdecimal (>= 3.0)
orm_adapter (0.5.0)
parallel (1.24.0)
parallel_tests (4.7.1)
parallel
paranoia (2.6.3)
activerecord (>= 5.1, < 7.2)
parser (3.3.1.0)
Expand Down Expand Up @@ -434,6 +436,8 @@ GEM
rspec-mocks (~> 3.12)
rspec-support (~> 3.12)
rspec-support (3.12.1)
rspec_junit_formatter (0.6.0)
rspec-core (>= 2, < 4, != 2.12.0)
rswag-api (2.13.0)
activesupport (>= 3.1, < 7.2)
railties (>= 3.1, < 7.2)
Expand Down Expand Up @@ -555,15 +559,10 @@ GEM
zeitwerk (2.6.13)

PLATFORMS
arm64-darwin-20
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why remove these?

arm64-darwin-21
arm64-darwin-22
ruby
x86_64-darwin-18
x86_64-darwin-19
x86_64-darwin-20
x86_64-darwin-21
x86_64-darwin-22
x86_64-linux

DEPENDENCIES
Expand Down Expand Up @@ -607,6 +606,7 @@ DEPENDENCIES
net-smtp
noticed
oj
parallel_tests
paranoia
pdf-forms
pg
Expand All @@ -623,6 +623,7 @@ DEPENDENCIES
request_store
rexml
rspec-rails
rspec_junit_formatter
rswag-api
rswag-specs
rswag-ui
Expand Down
2 changes: 1 addition & 1 deletion config/database.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ development:

test:
<<: *default
database: casa_test
database: casa_test<%= ENV["TEST_ENV_NUMBER"] %>
host: <%= ENV.fetch("DATABASE_HOST") { } %>

production:
Expand Down
2 changes: 1 addition & 1 deletion config/storage.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
test:
service: Disk
root: <%= Rails.root.join("tmp/storage") %>
root: <%= Rails.root.join("tmp/storage#{ENV['TEST_ENV_NUMBER']}") %>

local:
service: Disk
Expand Down
2 changes: 1 addition & 1 deletion spec/lib/tasks/emancipation_checklist_reminder_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
require "rake"
Rake.application.rake_require "tasks/emancipation_checklist_reminder"

RSpec.describe "lib/tasks/emancipation_checklist_reminder.rake" do
RSpec.describe "lib/tasks/emancipation_checklist_reminder.rake", ci_only: true do
let(:rake_task) { Rake::Task["emancipation_checklist_reminder"].invoke }

before do
Expand Down
2 changes: 1 addition & 1 deletion spec/lib/tasks/volunteer_birthday_reminder_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
require "rake"
Rake.application.rake_require "tasks/volunteer_birthday_reminder"

RSpec.describe "lib/tasks/volunteer_birthday_reminder.rake" do
RSpec.describe "lib/tasks/volunteer_birthday_reminder.rake", ci_only: true do
let(:rake_task) { Rake::Task["volunteer_birthday_reminder"].invoke }

before do
Expand Down
9 changes: 9 additions & 0 deletions spec/rails_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,13 @@
def pre_transition_aged_youth_age
Date.current - CasaCase::TRANSITION_AGE.years
end

config.around do |example|
Capybara.server_port = 7654 + ENV["TEST_ENV_NUMBER"].to_i
example.run
end

unless ENV["GITHUB_ACTIONS"]
config.filter_run_excluding :ci_only
end
end
2 changes: 2 additions & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
if ENV["RUN_SIMPLECOV"]
require "simplecov"
SimpleCov.start do
command_name "Job #{ENV["TEST_ENV_NUMBER"]}" if ENV["TEST_ENV_NUMBER"]

add_filter "/spec/"
add_filter "/lib/tasks/auto_annotate_models.rake"
add_group "Models", "/app/models"
Expand Down
10 changes: 10 additions & 0 deletions spec/support/capybara.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,16 @@
# disable CSS transitions and js animations
Capybara.disable_animation = true

Capybara::Screenshot.autosave_on_failure = true

module Capybara
module Screenshot
def self.capybara_tmp_path
Rails.root.join("tmp", "screenshots#{ENV["GROUPS_UNDERSCORE"]}")
end
end
end

options = Selenium::WebDriver::Chrome::Options.new
options.add_argument("--disable-gpu")
options.add_argument("--ignore-certificate-errors")
Expand Down
Loading