Индексы ThinkingSphinx в реальном времени и приемочное тестирование Rspec с безголовым браузером Chrome

Продолжение: ThinkingSphinx и обратный вызов не обновляют индекс после создания записи
Тестирую поиск с rspec и chrome headless.
С индексами SQL я использовал эту спецификацию функции + помощник: https://pastebin.com/9m7WbvN7
Заменены SQL-индексы на реальное время:

ThinkingSphinx::Index.define :review, with: :real_time do
  indexes title, sortable: true
  indexes body
  indexes author.username, as: :author, sortable: true

  has author_id, :type => :integer
  has created_at, :type => :timestamp
  has updated_at, :type => :timestamp
end

В режиме разработки все работает, но тесты стали падать.
Пробовал редактировать sphinx_helper по мануалу: https://freelancing-gods.com/thinking-sphinx/v5/testing.html
Но я потерпел неудачу и получаю сообщение об ошибке:

An error occurred in a `before(:suite)` hook.
Failure/Error: ThinkingSphinx::Test.start_with_autostop
Riddle::CommandFailedError:
  Sphinx command failed to execute

# /gems/riddle-2.4.3/lib/riddle/execute_command.rb:25:in `call'
# /gems/riddle-2.4.3/lib/riddle/execute_command.rb:7:in `call'
# /gems/riddle-2.4.3/lib/riddle/controller.rb:33:in `index'
# /gems/thinking-sphinx-5.5.1/lib/thinking_sphinx/test.rb:13:in `start'
# /gems/thinking-sphinx-5.5.1/lib/thinking_sphinx/test.rb:19:in `start_with_autostop'
# ./spec/sphinx_helper.rb:14:in `block (2 levels) in <top (required)>'

Обновление: добавление порта ничего не изменило.
config/thinking_sphinx.yml:

test:
  mysql41: 9307

Если вы запустите его вручную через rake, файл конфигурации будет создан, и sphinx успешно запустится:

bundle exec rake ts:configure RAILS_ENV=test
Generating configuration to /home/vagrant/data/app/config/test.sphinx.conf

bundle exec rake ts:start RAILS_ENV=test
using config file '/home/vagrant/data/app/config/test.sphinx.conf'...
listening on 127.0.0.1:9307
precaching index 'review_core'
precaching index 'user_core'
precached 2 indexes in 0.002 sec
Started searchd successfully (pid: 6532).

Содержимое test.sphinx.conf такое же, как и development.sphinx.conf, только пути меняются. test.sphinx.conf, кстати, создается при попытке запустить тест https://pastebin.com/GavMg5BB
Если добавить в /gems/thinking-sphinx-5.5.1/lib/thinking_sphinx/test.rb:

def self.start(options = {})
  pp  config.controller

вывод: https://pastebin.com/ta34Ys6k
При запуске теста в log/test.searchd.log ничего не пишется, т.к. sphinx не запускается.

UP2 Это то, что пытается запустить загадка::

# /gems/riddle-2.4.3/lib/riddle/execute_command.rb:7
"indexer --config \"/home/vagrant/data/app/config/test.sphinx.conf\" --all"

Если я попытаюсь сделать это вручную, я получаю: ERROR: nothing to do.

Не заметил сразу ничего неправильного в вашем коде… но можете ли вы подтвердить, что используете другой порт для Sphinx в своей тестовой среде?

pat 12.04.2023 03:54

@pat Я обновил пост, добавил немного информации.

ChildrenofkoRn 12.04.2023 08:55

Команда indexer ничего не сделает, потому что вы используете индексы в реальном времени, а это используется только для индексов, поддерживаемых SQL.

pat 12.04.2023 12:08

… и похоже, что start_with_autostop предполагает использование индексов, поддерживаемых SQL. Вот почему он пытается запустить эту команду! Вместо того, чтобы использовать этот подход, используйте start(index: false) перед каждым соответствующим тестом — вы можете увидеть пример этого подхода здесь: github.com/pat/drumknott-server/blob/main/spec/rails_helper.‌​rb

pat 12.04.2023 12:10

@pat Да, спасибо. Я уже пробовал это. Я нашел решение, я напишу о нем позже.

ChildrenofkoRn 12.04.2023 13:28
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
5
70
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ура, я наконец-то разобрался.
Да start_with_autostop (и не только) вызывает индексацию, а она возвращает ошибку Риддла.
Нам тоже не нужно звонить ThinkingSphinx::Test.index.
ThinkingSphinx::Test.run, который раньше оборачивал тест, у нас тоже больше не работает, потому что вызывает ThinkingSphinx::Test.start без аргумента index: false.

Теперь нам просто нужно запустить Sphinx и иметь обратные вызовы ThinkingSphinx в моделях, иначе созданные вами объекты не будут проиндексированы, что имеет смысл. Поскольку теперь у нас есть обратные вызовы для моделей, мы должны поддерживать работу Sphinx во всех тестах, использующих эти модели, иначе мы получим ошибку:

Error connecting to Sphinx via the MySQL protocol. Can't connect to MySQL server on '127.0.0.1:9307' (111).

Поэтому нам нужно, чтобы Sphinx работал в фоновом режиме в течение всего времени тестов, например, например. Редис.
Если мы будем запускать и останавливать Sphinx с каждым спецификационным файлом, то время тестирования заметно увеличится.


Есть несколько решений, которые работают для меня на данный момент:

1. добавить в rails_helper внутри RSpec.configure

  # Starting Sphinx before all tests
  config.before(:suite) do
    ThinkingSphinx::Test.init
    ThinkingSphinx::Test.start(index: false)
  end

  # Stoping ThinkingSphinx after all the tests
  config.after(:suite) do
    ThinkingSphinx::Test.stop
  end

Далее на ваш выбор:

  1. удалите DatabaseCleaner и sphinx_helper (кажется, все работает без них с Rails 6, возможно, руководство, которое я использовал и использую DatabaseCleaner, просто устарело).
  2. Оставить DatabaseCleaner и sphinx_helper, но удалить в нем вызовы ThinkingSphinx, sphinx_helper вызывается в Feature тестах для Sphinx вместо rails_helper.

2. Запускаем Sphinx через Rake-таски в rails_helper:

  # before RSpec.configure
  Rails.application.load_tasks
    
  # inside RSpec.configure
  config.before(:suite) do
    Rake::Task['ts:configure'].invoke
    Rake::Task['ts:start'].invoke
  end

  config.after(:suite) do
    Rake::Task['ts:stop'].invoke
    Rake::Task['ts:clear'].invoke
  end

Далее на ваш выбор: то же, что и в пункте 1.

3. Если вам нужен DatabaseCleaner, вы можете поместить его глобально в rails_helper внутри RSpec.configure:

  config.use_transactional_fixtures = false

  # Starting Sphinx before all tests
  config.before(:suite) do
    DatabaseCleaner.clean_with(:truncation)
    ThinkingSphinx::Test.init
    ThinkingSphinx::Test.start(index: false)
  end

  config.before(:each) do |test|
    # fix ActiveRecord::RecordNotFound in JS tests
    DatabaseCleaner.strategy = test.metadata[:js] ? :truncation : :transaction
    DatabaseCleaner.start
  end

  config.after(:each) do
    DatabaseCleaner.clean
  end

  # Stoping ThinkingSphinx after all the tests.
  config.after(:suite) do
    ThinkingSphinx::Test.stop
  end

sphinx_helper, то просто удалите его.


Во всех Feature-тестах Sphinx необходимо удалить обертку ThinkingSphinx::Test.run, а также sphinx: true и js: true (если вам явно не нужен JS)
Также не забудьте добавить обратный вызов для индексированных моделей:

  ThinkingSphinx::Callbacks.append(
    self, :behaviours => [:real_time]
  )

Также можно добавить удаление папки index после всех тестов и остановку Sphinx:

  config.after(:suite) do
    ThinkingSphinx::Test.stop
    FileUtils.rm_rf("#{Rails.root}/db/sphinx/test")
  end

PS: Если будут новые подробности, я обновлю пост.

Другие вопросы по теме