Add N+1 query shared example for MCP tool specs

What does this MR do and why?

Adds an 'an MCP tool that avoids N+1 queries' shared example for MCP tool service specs, and adopts it in list_projects, search_labels and list_merge_requests. A tool that returns a list can start running queries for each record without any spec noticing. The example runs the tool, adds records, and requires the query count to grow by exactly threshold: (default 0).

All three tools already run policy queries for each record on master, and the count differs by edition. Each CE spec runs the example only in FOSS, and a new spec under ee/spec covers EE. Each example has a threshold equal to the measured increase and a # TODO: link to the tracking issue. Because the match is exact, the fix MR fails until it lowers or removes the threshold. Once both editions reach zero, the EE example goes away and the CE gate is removed. The GraphQL integration dev doc and the gitlab-mcp-tool-builder skill now tell tool authors to use the example.

Design notes and measurements
  • Each call runs with a fresh request store, Rails cache and BatchLoader executor, as GraphqlHelpers#run_with_clean_state does. doc/development/database/query_recorder.md recommends the :request_store and :use_sql_query_cache tags. In a service spec those share one request store across the warm-up, control and measured calls, and the memoized state from the warm-up hid queries in the control. The example raises when the spec is tagged :request_store.
  • A warm-up call runs before the control so one-time caches don't inflate the control count.
  • match_query_count(control).with_threshold(n) passes only when the measured call runs exactly control + n queries, counting cached queries. exceed_query_limit and issue_same_number_of_queries_as also pass after a fix, which would leave a stale threshold.
  • Both calls must return isError: false, and expect(result).not_to eq(control_result) fails the example if the added records never reach the response.
  • CE specs run in both editions, so the CE example sits in context 'when CE edition', unless: Gitlab.ee?. as-if-foss jobs don't load ee/spec.
Tool EE increase (2 records) FOSS increase Cause Issue
list_projects +4 0 needs_new_sso_session loads each root ancestor and its SAML provider #502245
list_merge_requests (group) +8 +2 Policy conditions while authorizing each merge request's project. In CE, project_features. #635534
search_labels (group) +4 0 GroupPolicy conditions read each label group's root ancestor #635535 (closed)

The two new issues each carry a fix that was tested locally. With it applied, the matching EE example passes without threshold:.

References

Follow-up: #635891 adds the example to the other MCP tools that return more than one record.

Screenshots or screen recordings

No UI changes.

How to set up and validate locally

This MR changes only specs, a dev doc and a skill, so the specs are the validation.

  1. Run the CE and EE specs in EE. All pass, and only the three ee/spec N+1 examples run:

    bundle exec rspec spec/services/mcp/tools/projects/list_projects_service_spec.rb spec/services/mcp/tools/labels/search_service_spec.rb spec/services/mcp/tools/merge_requests/list_merge_requests_service_spec.rb ee/spec/services/ee/mcp/tools/projects/list_projects_service_spec.rb ee/spec/services/ee/mcp/tools/labels/search_service_spec.rb ee/spec/services/ee/mcp/tools/merge_requests/list_merge_requests_service_spec.rb
  2. Run the three CE specs with FOSS_ONLY=1. All pass, and the CE N+1 examples run with thresholds 0, 0 and 2.

  3. In ee/spec/services/ee/mcp/tools/merge_requests/list_merge_requests_service_spec.rb, change threshold: 8 to threshold: 10 and rerun that file. It fails with Expected exactly 15 (+10) queries, got 23.

  4. Restore threshold: 8, apply the diff under "Possible fixes" in #635534, and rerun. It fails with Expected exactly 20 (+8) queries, got 20, so the fix MR has to drop the threshold.

  5. Remove threshold: 8 and rerun. It passes.

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Edited by Terri Chu

Merge request reports

Loading
Loading