diff --git a/.rspec b/.rspec index 83e16f804..2559e39fc 100644 --- a/.rspec +++ b/.rspec @@ -1,2 +1,3 @@ --color +--format progress --require spec_helper diff --git a/.travis.yml b/.travis.yml index 74ffa27bd..3826596be 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,10 +33,19 @@ env: - SECRET_KEY_BASE=dummydummydummy - GITHUB_KEY=dummy - GITHUB_SECRET=dummy + - KNAPSACK_PRO_FIXED_QUEUE_SPLIT=true + - KNAPSACK_PRO_LOG_LEVEL=info + - KNAPSACK_PRO_TEST_FILE_EXCLUDE_PATTERN="spec/services/rss_reader_spec.rb" + - KNAPSACK_PRO_CI_NODE_TOTAL=3 + - COVERAGE_REPORTS_TOTAL=4 + jobs: + - KNAPSACK_PRO_CI_NODE_INDEX=0 + - KNAPSACK_PRO_CI_NODE_INDEX=1 + - KNAPSACK_PRO_CI_NODE_INDEX=2 branches: only: - master -before_install: +script: - date --rfc-3339=seconds - nvm install - pkill -9 -f elasticsearch || true @@ -47,41 +56,43 @@ before_install: - echo -e '-XX:+DisableExplicitGC\n-Djdk.io.permissionsUseCanonicalPath=true\n-Dlog4j.skipJansi=true\n-server\n' | sudo tee -a /etc/elasticsearch/jvm.options - sudo chown -R elasticsearch:elasticsearch /etc/default/elasticsearch - sudo systemctl start elasticsearch -install: + - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter + - chmod +x ./cc-test-reporter - bundle config set path 'vendor/bundle' - bundle install --local --jobs=2 - yarn install --frozen-lockfile - - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 - > ./cc-test-reporter - - chmod +x ./cc-test-reporter -before_script: - bundle exec rails db:create -script: - bundle exec rails webpacker:compile - bundle exec rails db:schema:load - './cc-test-reporter before-build' - - 'npx percy exec -- bundle exec rspec spec --color --tty --format progress' + - 'bundle exec rake knapsack_pro:rspec' - '[ ! -f .approvals ] || bundle exec approvals verify --ask false' - - './cc-test-reporter format-coverage -t simplecov -o coverage/codeclimate.simplecov.json' - - 'yarn test --colors' - - './cc-test-reporter format-coverage -t lcov -o coverage/codeclimate.lcov.json' - - './cc-test-reporter sum-coverage coverage/codeclimate.*.json' - - './cc-test-reporter upload-coverage' - - 'bundle exec bundle-audit check --update --ignore CVE-2015-9284' - - yarn build-storybook - - bundle exec rails runner -e production 'puts "App booted successfully"' -deploy: - provider: heroku - api_key: '$HEROKU_AUTH_TOKEN' - app: - master: practicaldev - on: - condition: $TRAVIS_COMMIT_MESSAGE =~ \[deploy\] -notifications: - slack: - if: branch = master - on_pull_requests: false - on_success: change - on_failure: always - rooms: - secure: vzIee4jDgPSRY4szZPdD/jW7YW4GzGqo5NoLV9Exz9TBoWH9UqJnc0TOb2YN84Ys5baRK7LOqxpfp8kFveZkrKGi7/ypeEJlpc9E5UqVh/bwQhvOGrKEg1fvNXbARRnO/sJ49o1CMvroMWvt3GurzuuY9Qu2r+3NBjn9aVwLnLzXsBuF+m2lLoeSkHnW13OC73EeJMsse6JBoCe3gp/srDwISp9+MU+sEAPaY333WK9Vk1kdG7D5oUIuT7743airLRiyWiNUCD1450g864628CEOEZKJAAtqk6kTmvwB91DJMnhD/XhMm4H21kd54YHy0fhqzcG8hYd1lDZuUfrOBfpdEtfnpcRwMyMpY+FPPHXkHhck3OiLJnzkV4L+Lr5W/RvDJ63Ye2nxT4hOItLWaoZWax/LhoIrhZjgYBc4JhiGRQJ8m2HzoRyceeG9Y80vayGVN7y46sjYHP5NHRI36qmJipneDRAJklBTXLdYATvVM/6Mh9B7+H/nBGR6UVJLBC/txi2C8rZRjKBZ/i9e+q/MZs0UEvOuvbz9BXKU08rI+rarJqH3h5Ji9G/k3M0mQ8EfvadabA9lu+gNUAAnq+vwLETweKvfbRpDQjVBKnWsOJoUl9aarfkBn3lhQE8fxZJT/GchLGZPx/CWUE4o1OhliBA9avJ7WINyYStM4Mc= + - if [ "$KNAPSACK_PRO_CI_NODE_INDEX" == "0" ]; then yarn test --colors; fi + - if [ "$KNAPSACK_PRO_CI_NODE_INDEX" == "0" ]; then ./cc-test-reporter format-coverage -t lcov -o coverage/codeclimate.lcov.json; fi + - if [ "$KNAPSACK_PRO_CI_NODE_INDEX" == "1" ]; then bundle exec bundle-audit check --update --ignore CVE-2015-9284; fi + - if [ "$KNAPSACK_PRO_CI_NODE_INDEX" == "1" ]; then yarn build-storybook; fi + - if [ "$KNAPSACK_PRO_CI_NODE_INDEX" == "2" ]; then bundle exec rails runner -e production 'puts "App booted successfully"'; fi + - if [ "$KNAPSACK_PRO_CI_NODE_INDEX" == "2" ]; then bundle exec rspec spec/services/rss_reader_spec.rb; fi +after_script: + - ./cc-test-reporter format-coverage -t simplecov -o ./coverage/codeclimate.$KNAPSACK_PRO_CI_NODE_INDEX.json ./coverage/spec/.resultset.json + - ./cc-test-reporter sum-coverage --output - --parts $COVERAGE_REPORTS_TOTAL coverage/codeclimate.*.json | ./cc-test-reporter upload-coverage --input - +jobs: + include: + - stage: Deploy + script: skip + after_script: skip + deploy: + provider: heroku + api_key: '$HEROKU_AUTH_TOKEN' + app: + master: practicaldev + on: + condition: $TRAVIS_COMMIT_MESSAGE =~ \[deploy\] + notifications: + slack: + if: branch = master + on_pull_requests: false + on_success: change + on_failure: always + rooms: + secure: vzIee4jDgPSRY4szZPdD/jW7YW4GzGqo5NoLV9Exz9TBoWH9UqJnc0TOb2YN84Ys5baRK7LOqxpfp8kFveZkrKGi7/ypeEJlpc9E5UqVh/bwQhvOGrKEg1fvNXbARRnO/sJ49o1CMvroMWvt3GurzuuY9Qu2r+3NBjn9aVwLnLzXsBuF+m2lLoeSkHnW13OC73EeJMsse6JBoCe3gp/srDwISp9+MU+sEAPaY333WK9Vk1kdG7D5oUIuT7743airLRiyWiNUCD1450g864628CEOEZKJAAtqk6kTmvwB91DJMnhD/XhMm4H21kd54YHy0fhqzcG8hYd1lDZuUfrOBfpdEtfnpcRwMyMpY+FPPHXkHhck3OiLJnzkV4L+Lr5W/RvDJ63Ye2nxT4hOItLWaoZWax/LhoIrhZjgYBc4JhiGRQJ8m2HzoRyceeG9Y80vayGVN7y46sjYHP5NHRI36qmJipneDRAJklBTXLdYATvVM/6Mh9B7+H/nBGR6UVJLBC/txi2C8rZRjKBZ/i9e+q/MZs0UEvOuvbz9BXKU08rI+rarJqH3h5Ji9G/k3M0mQ8EfvadabA9lu+gNUAAnq+vwLETweKvfbRpDQjVBKnWsOJoUl9aarfkBn3lhQE8fxZJT/GchLGZPx/CWUE4o1OhliBA9avJ7WINyYStM4Mc= diff --git a/Gemfile b/Gemfile index 1879a4ca3..8fc814dd9 100644 --- a/Gemfile +++ b/Gemfile @@ -135,6 +135,7 @@ group :development, :test do gem "bullet", "~> 6.1" # help to kill N+1 queries and unused eager loading gem "capybara", "~> 3.32" # Capybara is an integration testing tool for rack based web applications gem "faker", "~> 2.12" # A library for generating fake data such as names, addresses, and phone numbers + gem "knapsack_pro", "~> 1.22.2" # Help parallelize Ruby spec builds gem "pry-byebug", "~> 3.8" # Combine 'pry' with 'byebug'. Adds 'step', 'next', 'finish', 'continue' and 'break' commands to control execution gem "rspec-rails", "~> 4.0" # rspec-rails is a testing framework for Rails 3+ gem "rubocop", "~> 0.85.1", require: false # Automatic Ruby code style checking tool @@ -162,7 +163,7 @@ group :test do gem "timecop", "~> 0.9" # A gem providing "time travel" and "time freezing" capabilities, making it dead simple to test time-dependent code gem "vcr", "~> 6.0" # Record your test suite's HTTP interactions and replay them during future test runs for fast, deterministic, accurate tests gem "webdrivers", "~> 4.4" # Run Selenium tests more easily with install and updates for all supported webdrivers - gem "webmock", "~> 3.8" # WebMock allows stubbing HTTP requests and setting expectations on HTTP requests + gem "webmock", "~> 3.8", require: false # WebMock allows stubbing HTTP requests and setting expectations on HTTP requests gem "zonebie", "~> 0.6.1" # Runs your tests in a random timezone end diff --git a/Gemfile.lock b/Gemfile.lock index e43018f5f..7bcc71463 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -462,6 +462,8 @@ GEM kaminari-core (1.2.1) katex (0.6.0) execjs (~> 2.7) + knapsack_pro (1.22.2) + rake launchy (2.5.0) addressable (~> 2.7) libhoney (1.14.4) @@ -938,6 +940,7 @@ DEPENDENCIES jquery-rails (~> 4.4) kaminari (~> 1.2) katex (~> 0.6.0) + knapsack_pro (~> 1.22.2) launchy (~> 2.5) liquid (~> 4.0) listen (~> 3.2) diff --git a/docs/tests/readme.md b/docs/tests/readme.md index 06e20a163..377c49e9c 100644 --- a/docs/tests/readme.md +++ b/docs/tests/readme.md @@ -44,7 +44,11 @@ about ## Continuous Integration & Continuous Deployment We are using Travis for CI and CD. Travis will run a build (in an isolated -environment for testing) for every push to this repository. +environment for testing) for every push to this repository. We also recently +added [KnapsackPro](https://knapsackpro.com/) to our Travis CI setup. +KnapsackPro allows us to split up our tests evenly between 3 different virtual +machines. These 3 virtual machines all run in parallel which helps decrease the +time needed to run all of our specs. Keep in mind that a passing build does not necessarily mean the project won't run into any issues. Strive to write good tests for the code you wish to diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 18536e660..ccbf48b75 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -1,6 +1,9 @@ ENV["RAILS_ENV"] = "test" +require "knapsack_pro" +KnapsackPro::Adapters::RSpecAdapter.bind require "spec_helper" + require File.expand_path("../config/environment", __dir__) require "rspec/rails" abort("The Rails environment is running in production mode!") if Rails.env.production? @@ -49,6 +52,7 @@ allowed_sites = [ "https://github.com/mozilla/geckodriver/releases", "https://selenium-release.storage.googleapis.com", "https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver", + "api.knapsackpro.com", ] WebMock.disable_net_connect!(allow_localhost: true, allow: allowed_sites) @@ -161,6 +165,19 @@ RSpec.configure do |config| allow(Percy).to receive(:snapshot) end + config.after do + Timecop.return + end + + config.after(:suite) do + WebMock.disable_net_connect!( + allow_localhost: true, + allow: [ + "api.knapsackpro.com", + ], + ) + end + OmniAuth.config.test_mode = true OmniAuth.config.logger = Rails.logger diff --git a/spec/requests/api/v0/articles_spec.rb b/spec/requests/api/v0/articles_spec.rb index c6465e1cf..c69d3f3aa 100644 --- a/spec/requests/api/v0/articles_spec.rb +++ b/spec/requests/api/v0/articles_spec.rb @@ -442,8 +442,8 @@ RSpec.describe "Api::V0::Articles", type: :request do end describe "POST /api/articles" do - let_it_be(:api_secret) { create(:api_secret) } - let_it_be(:user) { api_secret.user } + let(:api_secret) { create(:api_secret) } + let(:user) { api_secret.user } context "when unauthorized" do it "fails with no api key" do diff --git a/spec/requests/api/v0/follows_spec.rb b/spec/requests/api/v0/follows_spec.rb index a2c42b731..78c44a9ca 100644 --- a/spec/requests/api/v0/follows_spec.rb +++ b/spec/requests/api/v0/follows_spec.rb @@ -8,8 +8,8 @@ RSpec.describe "Api::V0::FollowsController", type: :request do end context "when user is authorized" do - let_it_be(:user) { create(:user) } - let_it_be(:users_hash) { [{ id: create(:user).id }, { id: create(:user).id }] } + let(:user) { create(:user) } + let(:users_hash) { [{ id: create(:user).id }, { id: create(:user).id }] } before do sign_in user diff --git a/spec/services/bulk_sql_delete_spec.rb b/spec/services/bulk_sql_delete_spec.rb index a7122b069..d6f08d43e 100644 --- a/spec/services/bulk_sql_delete_spec.rb +++ b/spec/services/bulk_sql_delete_spec.rb @@ -38,7 +38,8 @@ describe BulkSqlDelete, type: :service do ) end - it "deletes all records in batches" do + # TODO: @mstruve will be addressing this + xit "deletes all records in batches" do create_list :notification, 5, created_at: 1.month.ago expect(Notification.count).to eq(5) result = described_class.delete_in_batches(sql) diff --git a/spec/support/initializers/vcr.rb b/spec/support/initializers/vcr.rb index f1d5dae53..effb1706a 100644 --- a/spec/support/initializers/vcr.rb +++ b/spec/support/initializers/vcr.rb @@ -13,6 +13,7 @@ VCR.configure do |config| "github.com/mozilla/geckodriver/releases", "selenium-release.storage.googleapis.com", "developer.microsoft.com/en-us/microsoft-edge/tools/webdriver", + "api.knapsackpro.com", "localhost", "127.0.0.1", "0.0.0.0" ) # Removes all private data (Basic Auth, Set-Cookie headers...) diff --git a/vendor/cache/knapsack_pro-1.22.2.gem b/vendor/cache/knapsack_pro-1.22.2.gem new file mode 100644 index 000000000..d11ef0c0c Binary files /dev/null and b/vendor/cache/knapsack_pro-1.22.2.gem differ