From ea15717c54a8075357f1f301af9a5d4ee395e7e9 Mon Sep 17 00:00:00 2001 From: Agis Anastasopoulos Date: Wed, 22 Jul 2020 19:32:13 +0300 Subject: [PATCH] Test suite run with concurrent workers Part of #1 --- .travis.yml | 15 ++++--- .../passing_concurrent/spec/a_spec.rb | 5 +++ .../passing_concurrent/spec/b_spec.rb | 5 +++ .../passing_concurrent/spec/c_spec.rb | 5 +++ .../passing_concurrent/spec/d_spec.rb | 5 +++ .../passing_concurrent/spec/e_spec.rb | 5 +++ .../passing_concurrent/spec/shared.rb | 6 +++ test/test_concurrent_workers.rb | 44 +++++++++++++++++++ test/test_helpers.rb | 11 ++++- 9 files changed, 94 insertions(+), 7 deletions(-) create mode 100644 test/sample_suites/passing_concurrent/spec/a_spec.rb create mode 100644 test/sample_suites/passing_concurrent/spec/b_spec.rb create mode 100644 test/sample_suites/passing_concurrent/spec/c_spec.rb create mode 100644 test/sample_suites/passing_concurrent/spec/d_spec.rb create mode 100644 test/sample_suites/passing_concurrent/spec/e_spec.rb create mode 100644 test/sample_suites/passing_concurrent/spec/shared.rb create mode 100644 test/test_concurrent_workers.rb diff --git a/.travis.yml b/.travis.yml index c2c5480..20d4089 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,12 +13,15 @@ rvm: - 2.7 - ruby-head env: - - RSPEC_CORE=3.8.0 - - RSPEC_CORE=3.8.1 - - RSPEC_CORE=3.8.2 - - RSPEC_CORE=3.9.0 - - RSPEC_CORE=3.9.1 - - RSPEC_CORE=3.9.2 + global: + #- RSPECQ_DEBUG= + jobs: + - RSPEC_CORE=3.8.0 + - RSPEC_CORE=3.8.1 + - RSPEC_CORE=3.8.2 + - RSPEC_CORE=3.9.0 + - RSPEC_CORE=3.9.1 + - RSPEC_CORE=3.9.2 jobs: allow_failures: diff --git a/test/sample_suites/passing_concurrent/spec/a_spec.rb b/test/sample_suites/passing_concurrent/spec/a_spec.rb new file mode 100644 index 0000000..a1fef25 --- /dev/null +++ b/test/sample_suites/passing_concurrent/spec/a_spec.rb @@ -0,0 +1,5 @@ +require_relative "shared" + +RSpec.describe do + it_behaves_like "kinda slow example" +end diff --git a/test/sample_suites/passing_concurrent/spec/b_spec.rb b/test/sample_suites/passing_concurrent/spec/b_spec.rb new file mode 100644 index 0000000..a1fef25 --- /dev/null +++ b/test/sample_suites/passing_concurrent/spec/b_spec.rb @@ -0,0 +1,5 @@ +require_relative "shared" + +RSpec.describe do + it_behaves_like "kinda slow example" +end diff --git a/test/sample_suites/passing_concurrent/spec/c_spec.rb b/test/sample_suites/passing_concurrent/spec/c_spec.rb new file mode 100644 index 0000000..a1fef25 --- /dev/null +++ b/test/sample_suites/passing_concurrent/spec/c_spec.rb @@ -0,0 +1,5 @@ +require_relative "shared" + +RSpec.describe do + it_behaves_like "kinda slow example" +end diff --git a/test/sample_suites/passing_concurrent/spec/d_spec.rb b/test/sample_suites/passing_concurrent/spec/d_spec.rb new file mode 100644 index 0000000..a1fef25 --- /dev/null +++ b/test/sample_suites/passing_concurrent/spec/d_spec.rb @@ -0,0 +1,5 @@ +require_relative "shared" + +RSpec.describe do + it_behaves_like "kinda slow example" +end diff --git a/test/sample_suites/passing_concurrent/spec/e_spec.rb b/test/sample_suites/passing_concurrent/spec/e_spec.rb new file mode 100644 index 0000000..a1fef25 --- /dev/null +++ b/test/sample_suites/passing_concurrent/spec/e_spec.rb @@ -0,0 +1,5 @@ +require_relative "shared" + +RSpec.describe do + it_behaves_like "kinda slow example" +end diff --git a/test/sample_suites/passing_concurrent/spec/shared.rb b/test/sample_suites/passing_concurrent/spec/shared.rb new file mode 100644 index 0000000..ec9636b --- /dev/null +++ b/test/sample_suites/passing_concurrent/spec/shared.rb @@ -0,0 +1,6 @@ +RSpec.shared_examples "kinda slow example" do + it do + sleep 2 + expect(true).to be true + end +end diff --git a/test/test_concurrent_workers.rb b/test/test_concurrent_workers.rb new file mode 100644 index 0000000..701707e --- /dev/null +++ b/test/test_concurrent_workers.rb @@ -0,0 +1,44 @@ +require "test_helpers" + +class TestConcurrentWorkers < RSpecQTest + # The 'passing_concurrent' suite contains 5 spec files each containing a + # single example taking 2". We spawn that many workers so we expect roughly + # 2 second total execution time. We some more to account for fork and + # rspec boot and other setup overheads + def test_passing_suite + build_id = rand_id + pids = [] + job_count = 5 + + start = Process.clock_gettime(Process::CLOCK_MONOTONIC) + + job_count.times do + pids << start_worker(build_id: build_id, suite: "passing_concurrent") + end + + pids.each { |p| Process.wait(p) } + + elapsed = Process.clock_gettime(Process::CLOCK_MONOTONIC) - start + + assert_operator elapsed, :<, 5 + + queue = RSpecQ::Queue.new(build_id, "foo", REDIS_HOST) + + assert_queue_well_formed(queue) + assert queue.build_successful? + assert_equal job_count, queue.example_count + assert_equal job_count, queue.redis.zcard(queue.key_worker_heartbeats) + end + + def test_flakey_suite + skip + end + + def test_failing_suite_with_requeues + skip + end + + def test_passing_suite_with_faulty_worker + skip + end +end diff --git a/test/test_helpers.rb b/test/test_helpers.rb index 6e7483f..7b738e1 100644 --- a/test/test_helpers.rb +++ b/test/test_helpers.rb @@ -4,6 +4,7 @@ module TestHelpers REDIS_HOST = "127.0.0.1".freeze + EXEC_CMD = "bundle exec rspecq" def rand_id SecureRandom.hex(4) @@ -23,7 +24,7 @@ def exec_build(path, args="") build_id = rand_id Dir.chdir(suite_path(path)) do - out = `bundle exec rspecq --worker #{worker_id} --build #{build_id} #{args}` + out = `#{EXEC_CMD} --worker #{worker_id} --build #{build_id} #{args}` puts out if ENV["RSPECQ_DEBUG"] end @@ -57,6 +58,14 @@ def assert_processed_jobs(exp, queue) def suite_path(path) File.join("test", "sample_suites", path) end + + def start_worker(build_id:, worker_id: rand_id, suite:) + Process.spawn( + "#{EXEC_CMD} -w #{worker_id} -b #{build_id}", + chdir: suite_path(suite), + out: (ENV["RSPECQ_DEBUG"] ? :out : "/dev/null"), + ) + end end # To be subclassed from all test cases.