Class: Mesa

Inherits:
Object
  • Object
show all
Defined in:
lib/mesa_test.rb

Constant Summary collapse

SVN_URI =
'https://subversion.assembla.com/svn/mesa\^mesa/trunk'.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(mesa_dir: , use_svn: true, using_sdk: true) ⇒ Mesa

Returns a new instance of Mesa.



541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
# File 'lib/mesa_test.rb', line 541

def initialize(mesa_dir: ENV['MESA_DIR'], use_svn: true, using_sdk: true)
  # absolute_path ensures that it doesn't matter where commands are executed
  # from
  @mesa_dir = File.absolute_path(mesa_dir)
  @use_svn = use_svn
  @using_sdk = using_sdk
  @update_checksums = false

  # these get populated by calling #load_test_data
  @test_data = {}
  @test_names = {}
  @test_cases = {}

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

  # these can be populated by calling load_svn_data
  @svn_version = nil
  @svn_author = nil
  @svn_log = nil
  load_svn_data if use_svn?
end

Instance Attribute Details

#mesa_dirObject (readonly)

Returns the value of attribute mesa_dir.



476
477
478
# File 'lib/mesa_test.rb', line 476

def mesa_dir
  @mesa_dir
end

#shellObject (readonly)

Returns the value of attribute shell.



476
477
478
# File 'lib/mesa_test.rb', line 476

def shell
  @shell
end

#svn_authorObject (readonly)

Returns the value of attribute svn_author.



476
477
478
# File 'lib/mesa_test.rb', line 476

def svn_author
  @svn_author
end

#svn_logObject (readonly)

Returns the value of attribute svn_log.



476
477
478
# File 'lib/mesa_test.rb', line 476

def svn_log
  @svn_log
end

#svn_versionObject (readonly)

Returns the value of attribute svn_version.



476
477
478
# File 'lib/mesa_test.rb', line 476

def svn_version
  @svn_version
end

#test_casesObject (readonly)

Returns the value of attribute test_cases.



476
477
478
# File 'lib/mesa_test.rb', line 476

def test_cases
  @test_cases
end

#test_dataObject (readonly)

Returns the value of attribute test_data.



476
477
478
# File 'lib/mesa_test.rb', line 476

def test_data
  @test_data
end

#test_namesObject (readonly)

Returns the value of attribute test_names.



476
477
478
# File 'lib/mesa_test.rb', line 476

def test_names
  @test_names
end

#update_checksumsObject

Returns the value of attribute update_checksums.



478
479
480
# File 'lib/mesa_test.rb', line 478

def update_checksums
  @update_checksums
end

#using_sdkObject (readonly)

Returns the value of attribute using_sdk.



476
477
478
# File 'lib/mesa_test.rb', line 476

def using_sdk
  @using_sdk
end

Class Method Details

.add_commit(commits, revision, author) ⇒ Object



504
505
506
507
508
509
# File 'lib/mesa_test.rb', line 504

def self.add_commit(commits, revision, author)
  commits << Commit.new
  commits.last.revision = revision.to_i
  commits.last.author = author
  commits.last.message = []
end

.commits_since(last_tested = DEFAULT_REVISION) ⇒ Object

all commits since the given version number



527
528
529
530
531
# File 'lib/mesa_test.rb', line 527

def self.commits_since(last_tested = DEFAULT_REVISION)
  commits = []
  log_lines_since(last_tested).each { |line| process_line(commits, line) }
  commits.sort_by(&:revision).reverse
end

.download(version_number: nil, new_mesa_dir: nil, use_svn: true, using_sdk: true) ⇒ Object



480
481
482
483
484
485
486
487
488
489
490
491
492
493
# File 'lib/mesa_test.rb', line 480

def self.download(version_number: nil, new_mesa_dir: nil, use_svn: true,
  using_sdk: true)
  new_mesa_dir ||= File.join(ENV['HOME'], 'mesa-test-r' + version_number.to_s)
  svn_command = "svn co -r #{version_number} #{SVN_URI} #{new_mesa_dir}"
  success = bash_execute(svn_command)
  unless success
    raise MesaDirError, 'Encountered a problem in downloading mesa ' \
                        "revision #{version_number}. Perhaps svn isn't " \
                        'working properly?' + "\n\n"\
                        'Tried the following command: ' + svn_command

  end
  Mesa.new(mesa_dir: new_mesa_dir, use_svn: use_svn, using_sdk: using_sdk)
end

.last_non_paxton_revision(last_tested = DEFAULT_REVISION) ⇒ Object



533
534
535
536
537
538
539
# File 'lib/mesa_test.rb', line 533

def self.last_non_paxton_revision(last_tested = DEFAULT_REVISION)
  commits_since(last_tested).each do |commit|
    return commit.revision unless commit.author == 'bill_paxton'
  end
  # give out garbage if no valid commit is found
  nil
end

.log_lines_since(last_tested = DEFAULT_REVISION) ⇒ Object



500
501
502
# File 'lib/mesa_test.rb', line 500

def self.log_lines_since(last_tested = DEFAULT_REVISION)
  log_since(last_tested).split("\n").reject(&:empty?)
end

.log_since(last_tested = DEFAULT_REVISION) ⇒ Object



495
496
497
498
# File 'lib/mesa_test.rb', line 495

def self.log_since(last_tested = DEFAULT_REVISION)
  # svn commit log back to, but excluding, the last revision tested
  `svn log #{SVN_URI} -r #{last_tested + 1}:HEAD`
end

.process_line(commits, line) ⇒ Object



511
512
513
514
515
516
517
518
519
520
521
522
523
524
# File 'lib/mesa_test.rb', line 511

def self.process_line(commits, line)
  last = commits.last
  if line =~ /^-+$/
    # dashed lines separate commits
    # Done with last commit (if it exists), so clean up message
    last.message = last.message.join("\n") unless last.nil?
  elsif line =~ /^r(\d+) \| (\w+) \| .* \| \d+ lines?$/
    # first line of a commit, scrape data and make new commit
    add_commit(commits, $1, $2)
  else
    # add lines to the message (will concatenate later to single String)
    last.message << line.strip
  end
end

Instance Method Details

#check_installationObject

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



663
664
665
666
667
668
# File 'lib/mesa_test.rb', line 663

def check_installation
  unless installed?
    raise MesaDirError, 'Installation check failed (no .mod files found ' \
                        'in the last compiled module).'
  end
end

#check_mod(mod) ⇒ Object

TEST SUITE METHODS

Raises:



676
677
678
679
680
# File 'lib/mesa_test.rb', line 676

def check_mod(mod)
  return if MesaTestCase.modules.include? mod
  raise TestCaseDirError, "Invalid module: #{mod}. Must be one of: " +
                          MesaTestCase.modules.join(', ')
end

#cleanObject



636
637
638
639
640
641
642
643
644
645
646
# File 'lib/mesa_test.rb', line 636

def clean
  with_mesa_dir do
    visit_and_check mesa_dir, MesaDirError, 'E\ccountered a problem in ' \
                              "running `clean` in #{mesa_dir}." do
      puts 'MESA_DIR = ' + ENV['MESA_DIR']
      puts './clean'
      bash_execute('./clean')
    end
  end
  self
end

#data_version_numberObject

read version number from $MESA_DIR/data/version_number



628
629
630
631
632
633
634
# File 'lib/mesa_test.rb', line 628

def data_version_number
  contents = ''
  File.open(File.join(mesa_dir, 'data', 'version_number'), 'r') do |f|
    contents = f.read
  end
  contents.strip.to_i
end

#destroyObject



670
671
672
# File 'lib/mesa_test.rb', line 670

def destroy
  FileUtils.rm_rf mesa_dir
end

#determine_diffObject



568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
# File 'lib/mesa_test.rb', line 568

def determine_diff
  # automatically determine if update_checksums should be true (don't do
  # diffs or true (DO do diffs). Only works if svn data has ALREADY been
  # loaded

  # don't do anything to @update_checksums if we haven't loaded svn data
  return unless @svn_log

  # by default, DON'T do diffs
  @update_checksums = true

  # list of phrases, which, if present in the log entry, will trigger diffs
  [
    /updated? checksums?/i,
    /checksums? updated?/i,
    /ready for diffs?/i,
  ].each { |trigger| @update_checksums = false if trigger =~ @svn_log }
  if @update_checksums
    shell.say "\nFrom svn log, didn't decide to tak diffs."
  else
    shell.say "From svn log, automatically decided to take diffs." 
  end
  shell.say "log entry: #{@svn_log}"
end

#downloaded?Boolean

Returns:

  • (Boolean)


795
796
797
# File 'lib/mesa_test.rb', line 795

def downloaded?
  check_mesa_dir
end

#each_test_clean(mod: :all) ⇒ Object

based off of ‘$MESA_DIR/star/test_suite/each_test_run_and_diff` from revision 10000



755
756
757
758
759
760
761
762
763
764
# File 'lib/mesa_test.rb', line 755

def each_test_clean(mod: :all)
  if mod == :all
    MesaTestCase.modules.each { |this_mod| each_test_clean mod: this_mod }
  else
    check_mod mod
    test_names[mod].each do |test_name|
      test_cases[mod][test_name].clean
    end
  end
end

#each_test_load_results(mod: :all) ⇒ Object



783
784
785
786
787
788
789
790
791
792
793
# File 'lib/mesa_test.rb', line 783

def each_test_load_results(mod: :all)
  if mod == :all
    MesaTestCase.modules.each do |this_mod|
      each_test_load_results(mod: this_mod)
    end
  else
    test_names[mod].each do |test_name|
      test_cases[mod][test_name].load_results
    end
  end
end

#each_test_run_and_diff(mod: :all, log_results: false) ⇒ Object



766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
# File 'lib/mesa_test.rb', line 766

def each_test_run_and_diff(mod: :all, log_results: false)
  check_installation
  each_test_clean(mod: mod)

  if mod == :all
    MesaTestCase.modules.each do |this_mod|
      each_test_run_and_diff(mod: this_mod, log_results: log_results)
    end
  else
    test_names[mod].each do |test_name|
      test_cases[mod][test_name].do_one
      test_cases[mod][test_name].log_results if log_results
    end
    log_summary(mod: mod) if log_results
  end
end

#find_test_case(test_case_name: nil, mod: :all) ⇒ Object

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



745
746
747
748
749
750
751
# File 'lib/mesa_test.rb', line 745

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

#installObject



648
649
650
651
652
653
654
655
656
657
658
659
660
# File 'lib/mesa_test.rb', line 648

def install
  with_mesa_dir do
    visit_and_check mesa_dir, MesaDirError, 'Encountered a problem in ' \
                              "running `install` in #{mesa_dir}." do
      puts 'MESA_DIR = ' + ENV['MESA_DIR']
      puts './install'
      bash_execute('./install')
    end
  end
  # this should never happen if visit_and_check works properly.
  check_installation
  self
end

#installed?Boolean

Returns:

  • (Boolean)


799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
# File 'lib/mesa_test.rb', line 799

def installed?
  # look for output files in the last-installed module
  # this isn't perfect, but it's a pretty good indicator of completing
  # installation
  install_file = File.join(mesa_dir, 'install')
  # match last line of things like "do_one SOME_MODULE" or "do_one_parallel 
  # SOME_MODULE", after which the "SOME_MODULE" will be stored in $1
  # that is the last module to be compiled by ./install.
  IO.readlines(install_file).select do |line|
    line =~ /^\s*do_one\w*\s+\w+/
  end.last =~ /^\s*do_one\w*\s+(\w+)/
  # module is "installed" if there is a nonzero number of files in the
  # module's make directory of the form SOMETHING.mod
  !Dir.entries(File.join(mesa_dir, $1, 'make')).select do |file|
    File.extname(file) == '.mod'
  end.empty?
end

#load_svn_dataObject



604
605
606
607
608
609
610
611
612
# File 'lib/mesa_test.rb', line 604

def load_svn_data
  # if this number is bad, #version_number will use fallback method
  @svn_version = svn_version_number
  lines = log_entry.split("\n").reject { |line| line =~ /^-+$/ or line.empty?}
  data_line = lines.shift
  revision, author, date, length = data_line.split('|')
  @svn_author = author.strip
  @svn_log = lines.join("\n").strip
end

#load_test_source_data(mod: :all) ⇒ Object

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



689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
# File 'lib/mesa_test.rb', line 689

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
    # load data from the source file
    source_lines = IO.readlines(
      File.join(test_suite_dir(mod: mod), 'do1_test_source')
    )

    # initialize data hash to empty hash and name array to empty array
    @test_data[mod] = {}
    @test_names[mod] = []
    @test_cases[mod] = {}

    # read through each line and find four data, name, success string, final
    # model name, and photo. Either of model name and photo can be "skip"
    source_lines.each do |line|
      no_skip = /^do_one (.+)\s+"([^"]*)"\s+"([^"]+)"\s+(x?\d+|auto)/
      one_skip = /^do_one (.+)\s+"([^"]*)"\s+"([^"]+)"\s+skip/
      two_skip = /^do_one (.+)\s+"([^"]*)"\s+skip\s+skip/
      found_test = false
      if line =~ no_skip
        found_test = true
        @test_data[mod][$1] = { success_string: $2, final_model: $3,
                                photo: $4}
      elsif line =~ one_skip
        found_test = true
        @test_data[mod][$1] = { success_string: $2, final_model: $3,
                                photo: nil }
      elsif line =~ two_skip
        found_test = true
        @test_data[mod][$1] = { success_string: $2, final_model: nil,
                                photo: nil }
      end

      if found_test
        @test_names[mod] << $1 unless @test_names[mod].include? $1
      end
    end

    # make MesaTestCase objects accessible by name
    @test_names[mod].each do |test_name|
      data = @test_data[mod][test_name]
      @test_cases[mod][test_name] = MesaTestCase.new(
        test: test_name, mesa: self, success_string: data[:success_string],
        mod: mod, final_model: data[:final_model], photo: data[:photo]
      )
    end
  end
end

#log_entryObject



600
601
602
# File 'lib/mesa_test.rb', line 600

def log_entry
  `svn log #{mesa_dir} -r #{version_number}`
end

#svn_version_numberObject

get version number from svn (preferred method)



615
616
617
618
619
620
621
622
623
624
625
# File 'lib/mesa_test.rb', line 615

def svn_version_number
  # match output of svn info to a line with the revision, capturing the
  # number, and defaulting to 0 if none is found.
  matches = /Revision\:\s+(\d+)/.match(`svn info #{mesa_dir}`)
  unless matches.nil?
    return matches[1].to_i
  end
  return 0
rescue Errno::ENOENT
  return 0
end

#test_suite_dir(mod: nil) ⇒ Object



682
683
684
685
# File 'lib/mesa_test.rb', line 682

def test_suite_dir(mod: nil)
  check_mod mod
  File.join(mesa_dir, mod.to_s, 'test_suite')
end

#use_svn?Boolean

Returns:

  • (Boolean)


564
565
566
# File 'lib/mesa_test.rb', line 564

def use_svn?
  @use_svn
end

#version_numberObject



593
594
595
596
597
598
# File 'lib/mesa_test.rb', line 593

def version_number
  version = @svn_version || 0
  # fall back to MESA_DIR/data's version number svn didn't work
  version = data_version_number unless version > 0
  version
end