From f83b8bd42c2a82b3ef9a8d93621b3955f0a8d0ca Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Thu, 26 Jan 2017 21:31:43 +0000 Subject: [PATCH] Add the rspec_profiling gem and documentation to the GitLab development environment --- Gemfile | 1 + Gemfile.lock | 7 ++++++ config/initializers/rspec_profiling.rb | 14 +++++++++++ doc/development/performance.md | 35 ++++++++++++++++++++++++++ spec/spec_helper.rb | 4 +++ 5 files changed, 61 insertions(+) create mode 100644 config/initializers/rspec_profiling.rb diff --git a/Gemfile b/Gemfile index dc8f23d07c6..37a7666602f 100644 --- a/Gemfile +++ b/Gemfile @@ -280,6 +280,7 @@ group :development, :test do gem 'rspec-retry', '~> 0.4.5' gem 'spinach-rails', '~> 0.2.1' gem 'spinach-rerun-reporter', '~> 0.0.2' + gem 'rspec_profiling' # Prevent occasions where minitest is not bundled in packaged versions of ruby (see #3826) gem 'minitest', '~> 5.7.0' diff --git a/Gemfile.lock b/Gemfile.lock index 133e47e1ea4..671d7788a86 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -642,6 +642,11 @@ GEM rspec-retry (0.4.5) rspec-core rspec-support (3.5.0) + rspec_profiling (0.0.4) + activerecord + pg + rails + sqlite3 rubocop (0.46.0) parser (>= 2.3.1.1, < 3.0) powerpack (~> 0.1) @@ -743,6 +748,7 @@ GEM actionpack (>= 4.0) activesupport (>= 4.0) sprockets (>= 3.0.0) + sqlite3 (1.3.11) stackprof (0.2.10) state_machines (0.4.0) state_machines-activemodel (0.4.0) @@ -965,6 +971,7 @@ DEPENDENCIES rqrcode-rails3 (~> 0.1.7) rspec-rails (~> 3.5.0) rspec-retry (~> 0.4.5) + rspec_profiling rubocop (~> 0.46.0) rubocop-rspec (~> 1.9.1) ruby-fogbugz (~> 0.2.1) diff --git a/config/initializers/rspec_profiling.rb b/config/initializers/rspec_profiling.rb new file mode 100644 index 00000000000..f462e654b2c --- /dev/null +++ b/config/initializers/rspec_profiling.rb @@ -0,0 +1,14 @@ +module RspecProfilingConnection + def establish_connection + ::RspecProfiling::Collectors::PSQL::Result.establish_connection(ENV['RSPEC_PROFILING_POSTGRES_URL']) + end +end + +if Rails.env.test? + RspecProfiling.configure do |config| + if ENV['RSPEC_PROFILING_POSTGRES_URL'] + RspecProfiling::Collectors::PSQL.prepend(RspecProfilingConnection) + config.collector = RspecProfiling::Collectors::PSQL + end + end +end diff --git a/doc/development/performance.md b/doc/development/performance.md index f936a49a2aa..c1f129e576c 100644 --- a/doc/development/performance.md +++ b/doc/development/performance.md @@ -211,6 +211,41 @@ suite first. See the [StackProf documentation](https://github.com/tmm1/stackprof/blob/master/README.md) for details. +## RSpec profiling + +GitLab's development environment also includes the +[rspec_profiling](https://github.com/foraker/rspec_profiling) gem, which is used +to collect data on spec execution times. This is useful for analyzing the +performance of the test suite itself, or seeing how the performance of a spec +may have changed over time. + +To activate profiling in your local environment, run the following: + +``` +$ export RSPEC_PROFILING=yes +$ rake rspec_profiling:install +``` + +This creates an SQLite3 database in `tmp/rspec_profiling`, into which statistics +are saved every time you run specs with the `RSPEC_PROFILING` environment +variable set. + +Ad-hoc investigation of the collected results can be performed in an interactive +shell: + +``` +$ rake rspec_profiling:console +irb(main):001:0> results.count +=> 231 +irb(main):002:0> results.last.attributes.keys +=> ["id", "commit", "date", "file", "line_number", "description", "time", "status", "exception", "query_count", "query_time", "request_count", "request_time", "created_at", "updated_at"] +irb(main):003:0> results.where(status: "passed").average(:time).to_s +=> "0.211340155844156" +``` +These results can also be placed into a PostgreSQL database by setting the +`RSPEC_PROFILING_POSTGRES_URL` variable. This is used to profile the test suite +when running in the CI environment. + ## Importance of Changes When working on performance improvements, it's important to always ask yourself diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index e160c11111b..ab38dac65c5 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -9,6 +9,10 @@ require 'rspec/rails' require 'shoulda/matchers' require 'rspec/retry' +if ENV['RSPEC_PROFILING_POSTGRES_URL'] || ENV['RSPEC_PROFILING'] + require 'rspec_profiling/rspec' +end + if ENV['CI'] && !ENV['NO_KNAPSACK'] require 'knapsack' Knapsack::Adapters::RSpecAdapter.bind