Commit 6a1017b4 authored by Micael Bergeron's avatar Micael Bergeron

Port the named query spec to WebMock

This commit changes the method to assert for Elastic named queries to
leverage WebMock instead of a custom Faraday middleware.
parent 12a98f61
......@@ -136,6 +136,7 @@ module Elastic
}
end
# rubocop:disable Metrics/AbcSize
def search_blob(query, type: 'blob', page: 1, per: 20, options: {})
page ||= 1
......
......@@ -12,7 +12,7 @@ module Elastic
def build_name(*args)
::Gitlab::Elastic::ExprName
.new(self)
.build(*current, *args)
.build(*contexts.last, *args)
end
def name(*args, &block)
......@@ -28,12 +28,6 @@ module Elastic
end
end
def current
return if contexts.empty?
contexts.last
end
private
def contexts
......
......@@ -9,7 +9,7 @@ module Gitlab
# Takes a hash as returned by `ApplicationSetting#elasticsearch_config`,
# and configures itself based on those parameters
def self.build(config, &block)
def self.build(config)
base_config = {
urls: config[:url],
request_timeout: config[:client_request_timeout],
......@@ -23,11 +23,9 @@ module Gitlab
::Elasticsearch::Client.new(base_config) do |fmid|
fmid.request(:aws_sigv4, credentials_provider: creds, service: 'es', region: region)
yield fmid if block_given?
end
else
::Elasticsearch::Client.new(base_config, &block)
::Elasticsearch::Client.new(base_config)
end
end
......
......@@ -32,12 +32,10 @@ RSpec.describe Elastic::Latest::GitClassProxy, :elastic do
end
end
it "names elasticsearch queries" do |example|
expect_named_queries(example) do |inspector|
subject.elastic_search_as_found_blob('*')
it "names elasticsearch queries" do
subject.elastic_search_as_found_blob('*')
expect(inspector).to have_named_query('doc:is_a:blob')
expect(inspector).to have_named_query('blob:match:search_terms')
end
assert_named_queries('doc:is_a:blob',
'blob:match:search_terms')
end
end
......@@ -32,12 +32,10 @@ RSpec.describe Elastic::Latest::ProjectWikiClassProxy, :elastic do
end
end
it 'names elasticsearch queries' do |example|
expect_named_queries(example) do |inspector|
subject.elastic_search_as_wiki_page('*')
it 'names elasticsearch queries' do
subject.elastic_search_as_wiki_page('*')
expect(inspector).to have_named_query('doc:is_a:wiki_blob')
expect(inspector).to have_named_query('blob:match:search_terms')
end
assert_named_queries('doc:is_a:wiki_blob',
'blob:match:search_terms')
end
end
......@@ -75,14 +75,12 @@ RSpec.describe Issue, :elastic do
expect(described_class.elastic_search('bla-bla', options: { project_ids: :any, public_and_internal_projects: true }).total_count).to eq(3)
end
it "names elasticsearch queries" do |example|
expect_named_queries(example) do |inspector|
described_class.elastic_search('*').total_count
it "names elasticsearch queries" do
described_class.elastic_search('*').total_count
expect(inspector).to have_named_query('doc:is_a:issue')
expect(inspector).to have_named_query('issue:match:search_terms')
expect(inspector).to have_named_query('issue:authorized:project')
end
assert_named_queries('doc:is_a:issue',
'issue:match:search_terms',
'issue:authorized:project')
end
it "searches by iid and scopes to type: issue only" do
......
......@@ -40,14 +40,12 @@ RSpec.describe MergeRequest, :elastic do
expect(described_class.elastic_search('term3', options: { project_ids: :any, public_and_internal_projects: true }).total_count).to eq(1)
end
it "names elasticsearch queries" do |example|
expect_named_queries(example) do |inspector|
described_class.elastic_search('*').total_count
it "names elasticsearch queries" do
described_class.elastic_search('*').total_count
expect(inspector).to have_named_query('doc:is_a:merge_request')
expect(inspector).to have_named_query('merge_request:match:search_terms')
expect(inspector).to have_named_query('merge_request:authorized:project')
end
assert_named_queries('doc:is_a:merge_request',
'merge_request:match:search_terms',
'merge_request:authorized:project')
end
it "searches by iid and scopes to type: merge_request only", :sidekiq_might_not_need_inline do
......
......@@ -55,14 +55,12 @@ RSpec.describe Note, :elastic do
expect(described_class.elastic_search('bla-bla', options: { project_ids: :any }).records).to contain_exactly(outside_note)
end
it "names elasticsearch queries" do |example|
expect_named_queries(example) do |inspector|
described_class.elastic_search('*').total_count
it "names elasticsearch queries" do
described_class.elastic_search('*').total_count
expect(inspector).to have_named_query('doc:is_a:note')
expect(inspector).to have_named_query('note:match:search_terms')
expect(inspector).to have_named_query('note:authorized')
end
assert_named_queries("doc:is_a:note",
"note:match:search_terms",
"note:authorized")
end
it "indexes && searches diff notes" do
......
......@@ -198,13 +198,11 @@ RSpec.describe Project, :elastic do
expect(described_class.elastic_search('tesla', options: { project_ids: project_ids }).total_count).to eq(2)
end
it "names elasticsearch queries" do |example|
expect_named_queries(example) do |inspector|
described_class.elastic_search('*').total_count
it "names elasticsearch queries" do
described_class.elastic_search('*').total_count
expect(inspector).to have_named_query('doc:is_a:project')
expect(inspector).to have_named_query('project:match:search_terms')
end
assert_named_queries('doc:is_a:project',
'project:match:search_terms')
end
it "returns json with all needed elements" do
......
......@@ -31,19 +31,18 @@ RSpec.describe Repository, :elastic do
expect(project.repository.elastic_search(partial_ref + '*')[:commits][:total_count]).to eq(1)
end
it "names elasticsearch queries" do |example|
it "names elasticsearch queries" do
project = create :project, :repository
project.repository.elastic_search('*')
expect_named_queries(example) do |inspector|
project.repository.elastic_search('*')
assert_named_queries('doc:is_a:blob',
'blob:match:search_terms')
expect(inspector).to have_named_query('doc:is_a:blob')
expect(inspector).to have_named_query('doc:is_a:wiki_blob')
expect(inspector).to have_named_query('blob:match:search_terms')
assert_named_queries('doc:is_a:wiki_blob',
'blob:match:search_terms')
expect(inspector).to have_named_query('doc:is_a:commit')
expect(inspector).to have_named_query('commit:match:search_terms')
end
assert_named_queries('doc:is_a:commit',
'commit:match:search_terms')
end
it 'can filter blobs' do
......
......@@ -35,14 +35,12 @@ RSpec.describe Snippet, :elastic do
expect(described_class.elastic_search('test snippet', options: options).total_count).to eq(1)
end
it "names elasticsearch queries" do |example|
expect_named_queries(example) do |inspector|
described_class.elastic_search('*').total_count
it "names elasticsearch queries" do
described_class.elastic_search('*').total_count
expect(inspector).to have_named_query('doc:is_a:snippet')
expect(inspector).to have_named_query('snippet:match:search_terms')
expect(inspector).to have_named_query('snippet:authorized')
end
assert_named_queries('doc:is_a:snippet',
'snippet:match:search_terms',
'snippet:authorized')
end
it 'returns json with all needed elements' do
......
# frozen_string_literal: true
RSpec.configure do |config|
config.before(:each, :elastic) do |example|
config.before(:each, :elastic) do
Elastic::ProcessBookkeepingService.clear_tracking!
Gitlab::Elastic::Helper.default.delete_index
Gitlab::Elastic::Helper.default.create_empty_index(options: { settings: { number_of_replicas: 0 } })
name_inspector = ElasticQueryNameInspector.new
es_config = Gitlab::CurrentSettings.elasticsearch_config
es_client = Gitlab::Elastic::Client.build(es_config) do |faraday|
faraday.use(ElasticQueryInspectorMiddleware, inspector: name_inspector)
end
example.metadata[:query_inspector] = name_inspector
# inject a client that records Elastic named queries
GemExtensions::Elasticsearch::Model::Client.cached_client = es_client
GemExtensions::Elasticsearch::Model::Client.cached_config = es_config
end
config.after(:each, :elastic) do
......
# frozen_string_literal: true
require 'hashie'
class ElasticQueryInspectorMiddleware < Faraday::Middleware
def initialize(app, options = {})
super(app)
@inspector = options.fetch(:inspector)
@env = nil
end
def call(env)
@env = env
return continue! unless is_search?
query = begin
payload = Gitlab::Json.parse(env[:request_body])
payload["query"]
rescue ::JSON::ParserError
nil
end
return continue! unless query.present?
query.extend(Hashie::Extensions::DeepFind)
@inspector.inspect(query)
continue!
end
def continue!
@app.call(@env)
end
def is_search?
@env.url.path.ends_with?("_search")
end
end
# frozen_string_literal: true
class ElasticQueryNameInspector
attr_reader :names
def initialize
@buckets = []
@names = Set.new
end
def inspect(query)
@buckets << query.deep_find_all("_name")
end
def reset!
@buckets = []
end
def names
@buckets.clone
end
def all_names
@buckets.flatten
query.extend(Hashie::Extensions::DeepFind)
@names += query.deep_find_all("_name")
end
def has_named_query?(*names)
names.all? { |name| all_names.include?(name) }
def has_named_query?(*expected_names)
@names.superset?(expected_names.to_set)
end
end
# frozen_string_literal: true
module ElasticsearchHelpers
def expect_named_queries(example, &block)
query_inspector = example.metadata[:query_inspector]
query_inspector.reset!
def assert_named_queries(*expected_names)
es_host = Gitlab::CurrentSettings.elasticsearch_url.first
search_uri =
Addressable::Template.new("#{es_host}/{index}/doc/_search{?params*}")
yield query_inspector
ensure_names_present = lambda do |req|
payload = Gitlab::Json.parse(req.body)
query = payload["query"]
expect(query_inspector.names).not_to be_empty
expect(query_inspector.names).not_to include(be_empty)
return false unless query.present?
inspector = ElasticQueryNameInspector.new
inspector.inspect(query)
inspector.has_named_query?(*expected_names)
rescue ::JSON::ParserError
false
end
a_named_query = a_request(:get, search_uri).with(&ensure_names_present)
message = "Expected a query with the following names: #{expected_names.inspect}"
expect(a_named_query).to have_been_made.at_least_once, message
end
def ensure_elasticsearch_index!
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment