Stub `ForkedStorageCheck.storage_available?` by default in all specs
While looking to see what I could do to speed up the spec/features/security/*
specs, I ran them with bin/rspec-stackprof
and noticed this:
gitlab-ce master % ES bin/rspec-stackprof spec/features/security/project/public_access_spec.rb
Finished in 2 minutes 6.4 seconds (files took 5.16 seconds to load)
306 examples, 0 failures
Randomized with seed 22643
==================================
Mode: wall(1000)
Samples: 107374 (12.97% miss rate)
GC: 10300 (9.59%)
==================================
TOTAL (pct) SAMPLES (pct) FRAME
19766 (18.4%) 19718 (18.4%) Gitlab::Git::Storage::ForkedStorageCheck#timeout_check
10278 (9.6%) 5730 (5.3%) ActionView::PathResolver#find_template_paths
8443 (7.9%) 4217 (3.9%) ActionDispatch::Journey::Formatter#missing_keys
8590 (8.0%) 2956 (2.8%) Sprockets::Cache::FileStore#get
2811 (2.6%) 2530 (2.4%) Peek::PGInstrumented#async_exec
2757 (2.6%) 2289 (2.1%) Peek::PGInstrumented#exec_prepared
6627 (6.2%) 1828 (1.7%) ActiveSupport::FileUpdateChecker#max_mtime
1775 (1.7%) 1698 (1.6%) GRPC::ActiveCall#request_response
1629 (1.5%) 1629 (1.5%) #<Module:0x007ffcc0812ee0>.distance
1615 (1.5%) 1516 (1.4%) GRPC::ActiveCall#remote_read
1522 (1.4%) 1167 (1.1%) Time#to_time
969 (0.9%) 969 (0.9%) URI::RFC3986_Parser#split
1150 (1.1%) 935 (0.9%) ActiveRecord::LazyAttributeHash#[]
1016 (0.9%) 865 (0.8%) ActionDispatch::Journey::Path::Pattern#match
760 (0.7%) 760 (0.7%) ThreadSafe::NonConcurrentCacheBackend#[]
695 (0.6%) 695 (0.6%) #<Module:0x007ffcc00a66c0>.load_with_autoloading
608 (0.6%) 608 (0.6%) ActiveSupport::PerThreadRegistry#instance
587 (0.5%) 587 (0.5%) Gon.public_method_name?
793 (0.7%) 565 (0.5%) ActiveSupport::FileUpdateChecker#watched
560 (0.5%) 560 (0.5%) Sprockets::PathUtils#stat
So I benchmarked the method with 250 iterations, and then compared it against a stub of the method that just returns true
straight away:
n = 250
path = File.expand_path("../tmp/tests/repositories", __dir__)
Benchmark.bm(20) do |x|
x.report("unstubbed") do
n.times { Gitlab::Git::Storage::ForkedStorageCheck.storage_available?(path, 5) }
end
x.report("stubbed") do
allow(Gitlab::Git::Storage::ForkedStorageCheck)
.to receive(:storage_available?).and_return(true)
n.times { Gitlab::Git::Storage::ForkedStorageCheck.storage_available?(path, 5) }
end
end
# user system total real
# unstubbed 0.410000 0.350000 90.710000 ( 93.097250)
# stubbed 0.010000 0.000000 0.010000 ( 0.011941)
Obviously a pretty big difference.
This MR stubs that method globally in the test suite unless an example includes the check_storage_availability
metadata.
Here's the "after" for that file:
Finished in 1 minute 39.1 seconds (files took 5.75 seconds to load)
306 examples, 0 failures
Randomized with seed 4500
==================================
Mode: wall(1000)
Samples: 81576 (16.17% miss rate)
GC: 8437 (10.34%)
==================================
TOTAL (pct) SAMPLES (pct) FRAME
10197 (12.5%) 5662 (6.9%) ActionView::PathResolver#find_template_paths
8651 (10.6%) 4321 (5.3%) ActionDispatch::Journey::Formatter#missing_keys
7985 (9.8%) 2705 (3.3%) Sprockets::Cache::FileStore#get
2674 (3.3%) 2359 (2.9%) Peek::PGInstrumented#async_exec
2610 (3.2%) 2159 (2.6%) Peek::PGInstrumented#exec_prepared
6240 (7.6%) 1734 (2.1%) ActiveSupport::FileUpdateChecker#max_mtime
1710 (2.1%) 1637 (2.0%) GRPC::ActiveCall#request_response
1532 (1.9%) 1532 (1.9%) #<Module:0x007fae2180aee0>.distance
1575 (1.9%) 1500 (1.8%) GRPC::ActiveCall#remote_read
1406 (1.7%) 1054 (1.3%) Time#to_time
929 (1.1%) 929 (1.1%) URI::RFC3986_Parser#split
971 (1.2%) 829 (1.0%) ActionDispatch::Journey::Path::Pattern#match
983 (1.2%) 790 (1.0%) ActiveRecord::LazyAttributeHash#[]
692 (0.8%) 692 (0.8%) #<Module:0x007fae208a66c0>.load_with_autoloading
682 (0.8%) 682 (0.8%) ThreadSafe::NonConcurrentCacheBackend#[]
790 (1.0%) 566 (0.7%) ActiveSupport::FileUpdateChecker#watched
554 (0.7%) 554 (0.7%) Sprockets::PathUtils#stat
533 (0.7%) 533 (0.7%) Gon.public_method_name?
4147 (5.1%) 532 (0.7%) Sprockets::Cache::FileStore#safe_open
564 (0.7%) 529 (0.6%) ActiveRecord::Inheritance::ClassMethods#base_class
This should provide a not-insignificant improvement to the speed of any test that uses an on-disk repository.
@reprazent What do you think about this? Should we be stubbing something further up the call chain, like disabling the Feature.enabled?
check, which we globally set to true
?