diff options
Diffstat (limited to 'spec/models/preloaders/environments/deployment_preloader_spec.rb')
-rw-r--r-- | spec/models/preloaders/environments/deployment_preloader_spec.rb | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/spec/models/preloaders/environments/deployment_preloader_spec.rb b/spec/models/preloaders/environments/deployment_preloader_spec.rb new file mode 100644 index 00000000000..c1812d45628 --- /dev/null +++ b/spec/models/preloaders/environments/deployment_preloader_spec.rb @@ -0,0 +1,65 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Preloaders::Environments::DeploymentPreloader do + let_it_be(:user) { create(:user) } + let_it_be(:project, reload: true) { create(:project, :repository) } + + let_it_be(:pipeline) { create(:ci_pipeline, user: user, project: project, sha: project.commit.sha) } + let_it_be(:ci_build_a) { create(:ci_build, user: user, project: project, pipeline: pipeline) } + let_it_be(:ci_build_b) { create(:ci_build, user: user, project: project, pipeline: pipeline) } + let_it_be(:ci_build_c) { create(:ci_build, user: user, project: project, pipeline: pipeline) } + + let_it_be(:environment_a) { create(:environment, project: project, state: :available) } + let_it_be(:environment_b) { create(:environment, project: project, state: :available) } + + before do + create(:deployment, :success, project: project, environment: environment_a, deployable: ci_build_a) + create(:deployment, :success, project: project, environment: environment_a, deployable: ci_build_b) + create(:deployment, :success, project: project, environment: environment_b, deployable: ci_build_c) + end + + def preload_association(association_name) + described_class.new(project.environments) + .execute_with_union(association_name, deployment_associations) + end + + def deployment_associations + { + user: [], + deployable: { + pipeline: { + manual_actions: [] + } + } + } + end + + it 'does not trigger N+1 queries' do + control = ActiveRecord::QueryRecorder.new { preload_association(:last_deployment) } + + ci_build_d = create(:ci_build, user: user, project: project, pipeline: pipeline) + create(:deployment, :success, project: project, environment: environment_b, deployable: ci_build_d) + + expect { preload_association(:last_deployment) }.not_to exceed_query_limit(control) + end + + it 'batch loads the dependent associations' do + preload_association(:last_deployment) + + expect do + project.environments.first.last_deployment.deployable.pipeline.manual_actions + end.not_to exceed_query_limit(0) + end + + # Example query scoped with IN clause for `last_deployment` association preload: + # SELECT DISTINCT ON (environment_id) deployments.* FROM "deployments" WHERE "deployments"."status" IN (1, 2, 3, 4, 6) AND "deployments"."environment_id" IN (35, 34, 33) ORDER BY environment_id, deployments.id DESC + it 'avoids scoping with IN clause during preload' do + control = ActiveRecord::QueryRecorder.new { preload_association(:last_deployment) } + + default_preload_query = control.occurrences_by_line_method.first[1][:occurrences].any? { |i| i.include?('"deployments"."environment_id" IN') } + + expect(default_preload_query).to be(false) + end +end |