<commit_before>class BenchmarkExecution < ActiveRecord::Base
  PROVIDER = 'aws'
  PRIORITY_HIGH = 1
  belongs_to :benchmark_definition
  validates :benchmark_definition, presence: true
  has_many :virtual_machine_instances, dependent: :destroy
  has_many :events, as: :traceable, dependent: :destroy do
    include EventsAsTraceableExtension
  end
  include EventStatusHelper

  def self.actives
    select { |execution| execution.active? }
  end

  # TODO: Consider using the following method signature:
  # + clearer dependencies
  # + testable
  # def prepare(file_system = default_file_system,
  #     driver = default_driver)
  def prepare
    set_driver_and_fs
    @file_system.prepare_vagrantfile_for_driver
    prepare_with(@driver)
    detect_and_create_vm_instances_with(@driver)

    # Schedule StartBenchmarkExecutionJobs with higher priority than PrepareBenchmarkExecutionJobs.
    # Also consider using multiple queues since long running prepare tasks should not block short running start commands.
    Delayed::Job.enqueue(StartBenchmarkExecutionJob.new(id), PRIORITY_HIGH)
  rescue => e
    shutdown_after_failure_timeout
    detect_and_create_vm_instances_with(@driver)
  end

  def shutdown_after_failure_timeout
    timeout = Rails.application.config.failure_timeout
    Delayed::Job.enqueue(ReleaseResourcesJob.new(id), PRIORITY_HIGH, timeout.from_now) if Rails.env.production?
  end

  def detect_and_create_vm_instances_with(driver)
    vm_instances = driver.detect_vm_instances
    vm_instances.each do |vm|
      self.virtual_machine_instances.create(provider_name: vm[:provider_name],
                                            provider_instance_id: vm[:provider_instance_id],
                                            role: vm[:role])
    end
  end

  def prepare_with(driver)
    events.create_with_name!(:started_preparing)
    success = driver.up(PROVIDER)
    if success
      events.create_with_name!(:finished_preparing)
    else
      event = events.create_with_name!(:failed_on_preparing)
      fail event.name
    end
  end

  def prepare_log
    set_driver_and_fs
    @driver.up_log
  end

  def reprovision
    set_driver_and_fs
    reprovision_with(@driver)
    Delayed::Job.enqueue(StartBenchmarkExecutionJob.new(id), PRIORITY_HIGH)
  rescue => e
    shutdown_after_failure_timeout
  end

  def reprovision_with(driver)<commit_msg>Recreate Vagrantfile on reprovision action<commit_after>class BenchmarkExecution < ActiveRecord::Base
  PROVIDER = 'aws'
  PRIORITY_HIGH = 1
  belongs_to :benchmark_definition
  validates :benchmark_definition, presence: true
  has_many :virtual_machine_instances, dependent: :destroy
  has_many :events, as: :traceable, dependent: :destroy do
    include EventsAsTraceableExtension
  end
  include EventStatusHelper

  def self.actives
    select { |execution| execution.active? }
  end

  # TODO: Consider using the following method signature:
  # + clearer dependencies
  # + testable
  # def prepare(file_system = default_file_system,
  #     driver = default_driver)
  def prepare
    set_driver_and_fs
    @file_system.prepare_vagrantfile_for_driver
    prepare_with(@driver)
    detect_and_create_vm_instances_with(@driver)

    # Schedule StartBenchmarkExecutionJobs with higher priority than PrepareBenchmarkExecutionJobs.
    # Also consider using multiple queues since long running prepare tasks should not block short running start commands.
    Delayed::Job.enqueue(StartBenchmarkExecutionJob.new(id), PRIORITY_HIGH)
  rescue => e
    shutdown_after_failure_timeout
    detect_and_create_vm_instances_with(@driver)
  end

  def shutdown_after_failure_timeout
    timeout = Rails.application.config.failure_timeout
    Delayed::Job.enqueue(ReleaseResourcesJob.new(id), PRIORITY_HIGH, timeout.from_now) if Rails.env.production?
  end

  def detect_and_create_vm_instances_with(driver)
    vm_instances = driver.detect_vm_instances
    vm_instances.each do |vm|
      self.virtual_machine_instances.create(provider_name: vm[:provider_name],
                                            provider_instance_id: vm[:provider_instance_id],
                                            role: vm[:role])
    end
  end

  def prepare_with(driver)
    events.create_with_name!(:started_preparing)
    success = driver.up(PROVIDER)
    if success
      events.create_with_name!(:finished_preparing)
    else
      event = events.create_with_name!(:failed_on_preparing)
      fail event.name
    end
  end

  def prepare_log
    set_driver_and_fs
    @driver.up_log
  end

  def reprovision
    set_driver_and_fs
    vagrantfile = @file_system.evaluate_vagrantfile
    @file_system.create_vagrantfile(vagrantfile)
    reprovision_with(@driver)
    Delayed::Job.enqueue(StartBenchmarkExecutionJob.new(id), PRIORITY_HIGH)
  rescue => e
    shutdown_after_failure_timeout
  end

  def reprovision_with(driver)
{'fraction_non_alphanumeric': 0.06542247744052503, 'fraction_numerical': 0.00041017227235438887, 'mean_word_length': 3.9312436804853386, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6866683', 'n_tokens_mistral': 1508, 'n_tokens_neox': 1463, 'n_words': 294}