class GroongaQueryLog::Command::RunRegressionTest::GroongaServer

Attributes

host[R]
port[R]

Public Class Methods

new(groonga, groonga_options, groonga_env, database_path, options) click to toggle source
# File lib/groonga-query-log/command/run-regression-test.rb, line 574
def initialize(groonga,
               groonga_options,
               groonga_env,
               database_path,
               options)
  @input_directory = options[:input_directory] || Pathname.new(".")
  @working_directory = options[:working_directory] || Pathname.new(".")
  @groonga = groonga
  @groonga_options = groonga_options
  @groonga_env = groonga_env
  @database_path = @working_directory + database_path
  @host = "127.0.0.1"
  @port = find_unused_port
  @options = options
  @pid = nil
end

Public Instance Methods

ensure_database() click to toggle source
# File lib/groonga-query-log/command/run-regression-test.rb, line 633
def ensure_database
  if @options[:recreate_database]
    FileUtils.rm_rf(@database_path.dirname.to_s)
  end
  return if @database_path.exist?

  FileUtils.mkdir_p(@database_path.dirname.to_s)
  create_db_command = [@groonga, "-n", @database_path.to_s, "quit"]
  unless system(*create_db_command)
    create_db_command_line = create_db_command.join(" ")
    raise "Failed to run: #{create_db_command_line}"
  end

  load_files.each do |load_file|
    filter_command = nil
    case load_file.extname
    when ".rb"
      env = {
        "GROONGA_LOG_PATH" => log_path.to_s,
      }
      command = [
        RbConfig.ruby,
        load_file.to_s,
        @database_path.to_s,
      ]
    when ".zst"
      env = {}
      command = [
        @groonga,
        "--log-path", log_path.to_s,
        @database_path.to_s,
      ]
      filter_command = [
        "zstdcat",
        load_file.to_s,
      ]
    else
      env = {}
      command = [
        @groonga,
        "--log-path", log_path.to_s,
        "--file", load_file.to_s,
        @database_path.to_s,
      ]
    end
    command_line = command.join(" ")
    if filter_command
      filter_command_line = filter_command.join(" ")
      command_line = "#{filter_command_line} | #{command_line}"
    end
    puts("Running...: #{command_line}")
    status = nil
    if filter_command
      IO.pipe do |input, output|
        filter_pid = spawn(*filter_command, out: output)
        output.close
        pid = spawn(env, *command, in: input)
        input.close
        begin
          pid, status = Process.waitpid2(pid)
          filter_pid, _filter_status = Process.waitpid2(filter_pid)
        rescue Interrupt
          Process.kill(:TERM, pid)
          Process.kill(:TERM, filter_pid)
          pid, status = Process.waitpid2(pid)
          filter_pid, _filter_status = Process.waitpid2(filter_pid)
        end
      end
    else
      pid = spawn(env, *command)
      begin
        pid, status = Process.waitpid2(pid)
      rescue Interrupt
        Process.kill(:TERM, pid)
        pid, status = Process.waitpid2(pid)
      end
    end
    unless status.success?
      raise "Failed to run: #{command_line}"
    end
  end
end
n_leaked_objects() click to toggle source
# File lib/groonga-query-log/command/run-regression-test.rb, line 731
def n_leaked_objects
  n = 0
  File.open(log_path, encoding: "UTF-8") do |log|
    log.each_line do |line|
      next unless line.valid_encoding?
      case line
      when /grn_fin \((\d+)\)/
        n += Integer($1, 10)
      end
    end
  end
  n
end
run() click to toggle source
# File lib/groonga-query-log/command/run-regression-test.rb, line 591
def run
  return unless @options[:run_queries]

  spawn_args = []
  spawn_args << @groonga_env if @groonga_env
  spawn_args << @groonga
  spawn_args.concat(@groonga_options)
  spawn_args.concat(["--bind-address", @host])
  spawn_args.concat(["--port", @port.to_s])
  spawn_args.concat(["--protocol", "http"])
  spawn_args.concat(["--log-path", log_path.to_s])
  if @options[:output_query_log]
    spawn_args.concat(["--query-log-path", query_log_path.to_s])
  end
  spawn_args << "-s"
  spawn_args << @database_path.to_s
  @pid = spawn(*spawn_args)

  begin
    n_retries = 60
    begin
      send_command("status")
    rescue SystemCallError
      sleep(1)
      n_retries -= 1
      raise if n_retries.zero?
      retry
    end

    if @options[:warm_up]
      send_command("dump?dump_records=no")
      warm_up_commands = @options[:warm_up_commands] || []
      warm_up_commands.each do |command|
        send_command(command)
      end
    end
  rescue
    shutdown
    raise
  end
end
shutdown() click to toggle source
# File lib/groonga-query-log/command/run-regression-test.rb, line 720
def shutdown
  return if @pid.nil?
  begin
    send_command("shutdown")
  rescue SystemCallError
    Process.kill(:KILL, @pid)
  end
  Process.waitpid(@pid)
  @pid = nil
end
use_persistent_cache?() click to toggle source
# File lib/groonga-query-log/command/run-regression-test.rb, line 716
def use_persistent_cache?
  @groonga_options.include?("--cache-base-path")
end

Private Instance Methods

data_files() click to toggle source
# File lib/groonga-query-log/command/run-regression-test.rb, line 785
def data_files
  Pathname.glob("#{@input_directory}/data/**/*.{grn,grn.zst,rb}").sort
end
find_unused_port() click to toggle source
# File lib/groonga-query-log/command/run-regression-test.rb, line 746
def find_unused_port
  server = TCPServer.new(@host, 0)
  begin
    server.addr[1]
  ensure
    server.close
  end
end
index_files() click to toggle source
# File lib/groonga-query-log/command/run-regression-test.rb, line 781
def index_files
  Pathname.glob("#{@input_directory}/indexes/**/*.{grn,grn.zst,rb}").sort
end
load_files() click to toggle source
# File lib/groonga-query-log/command/run-regression-test.rb, line 770
def load_files
  files = schema_files
  files += data_files if @options[:load_data]
  files += index_files
  files
end
log_path() click to toggle source
# File lib/groonga-query-log/command/run-regression-test.rb, line 755
def log_path
  @database_path.dirname + "groonga.log"
end
query_log_path() click to toggle source
# File lib/groonga-query-log/command/run-regression-test.rb, line 759
def query_log_path
  @database_path.dirname + "query.log"
end
schema_files() click to toggle source
# File lib/groonga-query-log/command/run-regression-test.rb, line 777
def schema_files
  Pathname.glob("#{@input_directory}/schema/**/*.{grn,grn.zst,rb}").sort
end
send_command(name) click to toggle source
# File lib/groonga-query-log/command/run-regression-test.rb, line 763
def send_command(name)
  Net::HTTP.start(@host, @port) do |http|
    response = http.get("/d/#{name}")
    response.body
  end
end