class Mesa

Attributes

github_protocol[R]
mesa_dir[R]
mirror_dir[R]
names_to_numbers[R]
shell[R]
test_case_names[R]
test_cases[R]

Public Class Methods

checkout(sha: nil, work_dir: nil, mirror_dir: nil, github_protocol: :ssh) click to toggle source
# File lib/mesa_test.rb, line 521
def self.checkout(sha: nil, work_dir: nil, mirror_dir: nil,
                  github_protocol: :ssh)
  m = Mesa.new(mesa_dir: work_dir, mirror_dir: mirror_dir,
               github_protocol: github_protocol)   
  m.checkout(new_sha: sha)
  m
end
new(mesa_dir: ENV['MESA_DIR'], mirror_dir: nil, github_protocol: :ssh) click to toggle source
# File lib/mesa_test.rb, line 529
def initialize(mesa_dir: ENV['MESA_DIR'], mirror_dir: nil,
               github_protocol: :ssh)
  # absolute_path ensures that it doesn't matter where commands are executed
  # from
  @mesa_dir = File.absolute_path(mesa_dir)
  @mirror_dir = File.absolute_path(mirror_dir)

  # don't worry about validity of github protocol until it is needed in a
  # checkout. This way you can have garbage in there if you never really need
  # it.
  @github_protocol = if github_protocol.respond_to? :to_sym
                       github_protocol.to_sym
                     else
                       github_protocol
                     end

  # these get populated by calling #load_test_data
  @test_cases = {}
  @test_case_names = {}
  @names_to_numbers = {}

  # way to output colored text
  @shell = Thor::Shell::Color.new
end

Public Instance Methods

build_log_64() click to toggle source

base 64-encoded contents of build.log

# File lib/mesa_test.rb, line 697
def build_log_64
  build_log = File.join(mesa_dir, 'build.log')
  return '' unless File.exist?(build_log)

  b64_file(build_log)
end
check_installation() click to toggle source

throw an error unless it seems like it's properly compiled

# File lib/mesa_test.rb, line 689
def check_installation
  return if installed?

  raise MesaDirError, 'Installation check failed (build.log doesn\'t '\
                      'show a successful installation).'
end
check_mod(mod) click to toggle source

TEST SUITE METHODS

# File lib/mesa_test.rb, line 723
def check_mod(mod)
  return if MesaTestCase.modules.include? mod

  raise TestCaseDirError, "Invalid module: #{mod}. Must be one of: " +
                          MesaTestCase.modules.join(', ')
end
checkout(new_sha: 'HEAD') click to toggle source
# File lib/mesa_test.rb, line 554
def checkout(new_sha: 'HEAD')
  # before anything confirm that git-lfs has been installed
  shell.say "\nEnsuring that git-lfs is installed... ", :blue
  command = 'git lfs help >> /dev/null 2>&1'
  if bash_execute(command)
    shell.say "yes", :green
  else
    shell.say "no", :red
    raise(GitHubError, "The command #{command} returned with an error "\
                       'status, indicating that git-lfs is not installed. '\
                       'Make sure it is installed and try again.')
  end

  # set up mirror if it doesn't exist
  unless dir_or_symlink_exists?(mirror_dir)
    shell.say "\nCreating initial mirror at #{mirror_dir}. "\
              'This might take awhile...', :blue
    FileUtils.mkdir_p mirror_dir
    case github_protocol
    when :ssh
      command = "git clone --mirror #{GITHUB_SSH} #{mirror_dir}"
      shell.say command
      # fail loudly if this doesn't work
      unless bash_execute(command)
        # nuke the mirror directory since it is probably bogus (make this
        # code fire off the next time checkout is done)
        shell.say "Failed. Removing the [potentially corrupted] mirror.", :red
        command = "rm -rf #{mirror_dir}"
        shell.say command
        bash_execute(command)

        raise(GitHubError, 'Error while executing the following command:'\
                           "#{command}. Perhaps you haven't set up "\
                           'ssh keys with your GitHub account?')
      end
    when :https
      command = "git clone --mirror #{GITHUB_HTTPS} #{mirror_dir}"
      shell.say command
      # fail loudly if this doesn't work
      unless bash_execute(command)
        # nuke the mirror directory since it is probably bogus (make this
        # code fire off the next time checkout is done)
        shell.say "Failed. Removing the [potentially corrupted] mirror.", :red
        command = "rm -rf #{mirror_dir}"
        shell.say command
        bash_execute(command)

        raise(GitHubError, 'Error while executing the following command: '\
                           "#{command}. Perhaps you need to configure "\
                           'global GitHub account settings for https '\
                           'authentication to work properly?')
      end
    else
      raise(GitHubError, "Invalid GitHub protocol: \"#{github_protocol}\"")
    end
  end

  update_mirror

  # ensure "work" directory is removed from worktree
  remove

  # create "work" directory with proper commit
  shell.say "\nSetting up worktree repo...", :blue
  FileUtils.mkdir_p mesa_dir
  command = "git -C #{mirror_dir} worktree add #{mesa_dir} #{new_sha}"
  shell.say command
  return if bash_execute(command)

  raise(GitHubError, 'Failed while executing the following command: '\
                     "\"#{command}\".")
end
clean() click to toggle source
# File lib/mesa_test.rb, line 662
def clean
  with_mesa_dir do
    visit_and_check mesa_dir, MesaDirError, 'E\countered a problem in ' \
                              "running `clean` in #{mesa_dir}." do
      shell.say('MESA_DIR = ' + ENV['MESA_DIR'])
      shell.say './clean'
      bash_execute('./clean')
    end
  end
  self
end
compiler_hash() click to toggle source

sourced from $MESA_DIR/testhub.yml, which should be created after installation

# File lib/mesa_test.rb, line 706
def compiler_hash
  data_file = File.join(mesa_dir, 'testhub.yml')
  res = {
          compiler: 'Unknown',
          sdk_version: 'Unknown',
          math_backend: 'Unknown'
        }
  if File.exist? data_file
    res = res.merge(YAML.safe_load(File.read(data_file)) || {})
    # currently version_number is reported, but we don't need that in Git land
    res.delete('version_number') # returns the value, not the updated hash
    res
  end
end
downloaded?() click to toggle source
# File lib/mesa_test.rb, line 798
def downloaded?
  check_mesa_dir
end
each_test_run(mod: :all) click to toggle source
# File lib/mesa_test.rb, line 784
def each_test_run(mod: :all)
  check_installation

  if mod == :all
    MesaTestCase.modules.each do |this_mod|
      each_test_run(mod: this_mod)
    end
  else
    visit_dir(test_suite_dir(mod: mod)) do
      bash_execute('./each_test_run')
    end
  end
end
find_test_case(test_case_name: nil, mod: :all) click to toggle source

can accept a number (in string form) as a name for indexed access

# File lib/mesa_test.rb, line 776
def find_test_case(test_case_name: nil, mod: :all)
  if /\A[0-9]+\z/ =~ test_case_name
    find_test_case_by_number(test_number: test_case_name.to_i, mod: mod)
  else
    find_test_case_by_name(test_case_name: test_case_name, mod: mod)
  end
end
git_sha() click to toggle source
# File lib/mesa_test.rb, line 654
def git_sha
  bashticks("git -C #{mesa_dir} rev-parse HEAD")
end
install() click to toggle source
# File lib/mesa_test.rb, line 674
def install
  with_mesa_dir do
    visit_and_check mesa_dir, MesaDirError, 'Encountered a problem in ' \
                              "running `install` in #{mesa_dir}." do
      shell.say('MESA_DIR = ' + ENV['MESA_DIR'])
      shell.say './install'
      bash_execute('./install')
    end
  end
  # this should never happen if visit_and_check works properly.
  check_installation
  self
end
install_attempted?() click to toggle source
# File lib/mesa_test.rb, line 811
def install_attempted?
  File.exist? File.join(mesa_dir, 'testhub.yml')
end
installed?() click to toggle source
# File lib/mesa_test.rb, line 802
def installed?
  # assume build log reflects installation status; does not account for
  # mucking with modules after the fact
  build_log = File.join(mesa_dir, 'build.log')
  downloaded? && File.exist?(build_log) && File.read(build_log).include?(
    'MESA installation was successful'
  )
end
load_test_source_data(mod: :all) click to toggle source

load data from the `do1_test_source` file that gets used in a lot of testing

# File lib/mesa_test.rb, line 737
def load_test_source_data(mod: :all)
  # allow for brainless loading of all module data
  if mod == :all
    MesaTestCase.modules.each do |this_mod|
      load_test_source_data(mod: this_mod)
    end
  else
    check_mod mod

    # convert output of +list_tests+ to a dictionary that maps
    # names to numbers since +each_test_run+ only knows about numbers
    @names_to_numbers[mod] = {}
    @test_case_names[mod] = []
    @test_cases[mod] = {}
    visit_dir(test_suite_dir(mod: mod), quiet: true) do
      bashticks('./list_tests').split("\n").each do |line|
        num, tc_name = line.strip.split
        @names_to_numbers[mod][tc_name.strip] = num.to_i
        @test_case_names[mod] << tc_name.strip
        begin
          @test_cases[mod][tc_name.strip] = MesaTestCase.new(
            test: tc_name.strip,
            mod: mod,
            position: num.to_i,
            mesa: self
          )
        rescue TestCaseDirError
          shell.say "No such test case #{tc_name.strip}. Skipping loading it.", :red
        end
      end
    end
  end
end
remove() click to toggle source
# File lib/mesa_test.rb, line 638
def remove
  return unless File.exist? mesa_dir
  shell.say "\nRemoving work directory from worktree (clearing old data)...",
            :blue
  command = "git -C #{mirror_dir} worktree remove --force #{mesa_dir}"
  shell.say command
  return if bash_execute(command)

  shell.say "Failed. Simply trying to remove the directory.", :red
  command = "rm -rf #{mesa_dir}"
  shell.say command
  # fail loudly (the "true" tells bash_execute to raise an exception if
  # the command fails)
  bash_execute(command, true)
end
sha() click to toggle source
# File lib/mesa_test.rb, line 658
def sha
  git_sha
end
test_case_count(mod: :all) click to toggle source
# File lib/mesa_test.rb, line 771
def test_case_count(mod: :all)
  all_names_ordered(mod: mod).count
end
test_suite_dir(mod: nil) click to toggle source
# File lib/mesa_test.rb, line 730
def test_suite_dir(mod: nil)
  check_mod mod
  File.join(mesa_dir, mod.to_s, 'test_suite')
end
update_mirror() click to toggle source
# File lib/mesa_test.rb, line 627
def update_mirror
  shell.say "\nFetching MESA history...", :blue
  command = "git -C #{mirror_dir} fetch origin --prune"
  shell.say command
  # fail loudly
  return if bash_execute(command)

  raise(GitHubError, 'Failed while executing the following command: '\
                     "\"#{command}\".")
end

Private Instance Methods

all_names_ordered(mod: :all) click to toggle source
# File lib/mesa_test.rb, line 843
def all_names_ordered(mod: :all)
  load_test_source_data unless @names_to_numbers
  if mod == :all
    # build up list by first constructing each modules list and then
    # concatenating them
    MesaTestCase.modules.inject([]) do |res, this_mod|
      res += all_names_ordered(mod: this_mod)
    end
  else
    check_mod mod
    res = Array.new(@names_to_numbers[mod].length, '')

    # values of the hash give their order, keys are the names, so
    # we assign keys to positions in the array according to their value
    @names_to_numbers[mod].each_pair do |key, val|
      res[val - 1] = key # +list_tests+ gives 1-indexed positions
    end
    res
  end
end
check_mesa_dir() click to toggle source

verify that mesa_dir is valid by checking for existence of test_suite directory for each module (somewhat arbitrary)

# File lib/mesa_test.rb, line 819
def check_mesa_dir
  MesaTestCase.modules.inject(true) do |res, mod|
    res && dir_or_symlink_exists?(test_suite_dir(mod: mod))
  end
end
find_test_case_by_name(test_case_name: nil, mod: :all) click to toggle source
# File lib/mesa_test.rb, line 864
def find_test_case_by_name(test_case_name: nil, mod: :all)
  load_test_source_data unless @names_to_numbers
  if mod == :all
    # look through all loaded modules for desired test case name, only
    # return a test case if a single case is found with that name
    case all_names_ordered.count(test_case_name)
    when 1
      # it exists in exactly one module, but we need to find the module
      # and then return the +MesaTestCase+ object
      MesaTestCase.modules.each do |this_mod|
        if @test_case_names[this_mod].include? test_case_name
          # found it, return the appropriate object
          return @test_cases[this_mod][test_case_name]
        end
      end
      raise 'Weird problem: found test case in overall names, but '\
        "not in any particular module. This shouldn't happen."
    when 0
      raise(TestCaseDirError, "Could not find test case #{test_case_name} "\
                              'in any module.')
    else
      raise(TestCaseDirError, 'Found multiple test cases named '\
        "#{test_case_name} in multiple modules. Indicate the module you "\
        'want to search.')
    end
    # append this array to the end of the exisitng one
  else
    # module specified; check it and return the proper test case (may be nil
    # if the test case doesn't exist)
    check_mod mod
    if @test_case_names[mod].include? test_case_name
      # happy path: test case exists in the specified module
      return @test_cases[mod][test_case_name]
    else
      raise TestCaseDirError.new('Could not find test case ' \
        "#{test_case_name} in the #{mod} module.")
    end
  end
end
find_test_case_by_number(test_number: nil, mod: :all) click to toggle source
# File lib/mesa_test.rb, line 904
def find_test_case_by_number(test_number: nil, mod: :all)
  # this will be the index in the name array of the proper module of
  # the desired test case
  # input numbers are 1-indexed, but we'll fix that later
  if test_number < 1 || test_number > test_case_count(mod: mod)
    raise TestCaseDirError.new('Invalid test case number for searching '\
      "in module #{mod}. Must be between 1 and #{test_case_count(mod: mod)}.")
  end

  if mod == :all
    # can get the name easily, now need to find the module
    test_case_name = all_names_ordered[test_number - 1]
    MesaTestCase.modules.each do |mod|
      if test_number <= test_case_count(mod: mod)
        # test must live in this module; we have everything
        return MesaTestCase.new(
          test: test_case_name,
          mod: mod,
          mesa: self,
          position: @names_to_numbers[mod][test_case_name]
        )
      else
        # number was too big, so decrement by this modules case count
        # and move on to next one
        test_number -= test_case_count(mod: mod)
      end
    end
    # should return before we get here, but fail hard if we do
    raise TestCaseDirError.new('Unknown problem in loading test case #' +
      test_number + '.') 
  else
    # module was specified, so we can get at everything right away
    check_mod mod
    return MesaTestCase.new(
      test: all_names_ordered(mod: mod)[test_number - 1],
      mod: mod,
      mesa: self,
      position: test_number
    )
  end
end
with_mesa_dir() { || ... } click to toggle source

change MESA_DIR for the execution of the block and then revert to the original value

# File lib/mesa_test.rb, line 827
def with_mesa_dir
  # change MESA_DIR, holding on to old value
  orig_mesa_dir = ENV['MESA_DIR']
  ENV['MESA_DIR'] = mesa_dir
  shell.say "Temporarily changed MESA_DIR to #{ENV['MESA_DIR']}.", :blue

  # do the stuff
  begin
    yield
  # make sure we undo MESA_DIR change
  ensure
    ENV['MESA_DIR'] = orig_mesa_dir
    shell.say "Changed MESA_DIR back to #{ENV['MESA_DIR']}.", :blue
  end
end