FRDM K64F Metronome

Committer:
ram54288
Date:
Sun May 14 18:37:05 2017 +0000
Revision:
0:dbad57390bd1
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ram54288 0:dbad57390bd1 1 #!/usr/bin/ruby
ram54288 0:dbad57390bd1 2 #
ram54288 0:dbad57390bd1 3 # unity_to_junit.rb
ram54288 0:dbad57390bd1 4 #
ram54288 0:dbad57390bd1 5 require 'fileutils'
ram54288 0:dbad57390bd1 6 require 'optparse'
ram54288 0:dbad57390bd1 7 require 'ostruct'
ram54288 0:dbad57390bd1 8 require 'set'
ram54288 0:dbad57390bd1 9
ram54288 0:dbad57390bd1 10 require 'pp'
ram54288 0:dbad57390bd1 11
ram54288 0:dbad57390bd1 12 VERSION = 1.0
ram54288 0:dbad57390bd1 13
ram54288 0:dbad57390bd1 14 class ArgvParser
ram54288 0:dbad57390bd1 15
ram54288 0:dbad57390bd1 16 #
ram54288 0:dbad57390bd1 17 # Return a structure describing the options.
ram54288 0:dbad57390bd1 18 #
ram54288 0:dbad57390bd1 19 def self.parse(args)
ram54288 0:dbad57390bd1 20 # The options specified on the command line will be collected in *options*.
ram54288 0:dbad57390bd1 21 # We set default values here.
ram54288 0:dbad57390bd1 22 options = OpenStruct.new
ram54288 0:dbad57390bd1 23 options.results_dir = "."
ram54288 0:dbad57390bd1 24 options.root_path = "."
ram54288 0:dbad57390bd1 25 options.out_file = "results.xml"
ram54288 0:dbad57390bd1 26
ram54288 0:dbad57390bd1 27 opts = OptionParser.new do |opts|
ram54288 0:dbad57390bd1 28 opts.banner = "Usage: unity_to_junit.rb [options]"
ram54288 0:dbad57390bd1 29
ram54288 0:dbad57390bd1 30 opts.separator ""
ram54288 0:dbad57390bd1 31 opts.separator "Specific options:"
ram54288 0:dbad57390bd1 32
ram54288 0:dbad57390bd1 33 opts.on("-r", "--results <dir>", "Look for Unity Results files here.") do |results|
ram54288 0:dbad57390bd1 34 #puts "results #{results}"
ram54288 0:dbad57390bd1 35 options.results_dir = results
ram54288 0:dbad57390bd1 36 end
ram54288 0:dbad57390bd1 37
ram54288 0:dbad57390bd1 38 opts.on("-p", "--root_path <path>", "Prepend this path to files in results.") do |root_path|
ram54288 0:dbad57390bd1 39 options.root_path = root_path
ram54288 0:dbad57390bd1 40 end
ram54288 0:dbad57390bd1 41
ram54288 0:dbad57390bd1 42 opts.on("-o", "--output <filename>", "XML file to generate.") do |out_file|
ram54288 0:dbad57390bd1 43 #puts "out_file: #{out_file}"
ram54288 0:dbad57390bd1 44 options.out_file = out_file
ram54288 0:dbad57390bd1 45 end
ram54288 0:dbad57390bd1 46
ram54288 0:dbad57390bd1 47 opts.separator ""
ram54288 0:dbad57390bd1 48 opts.separator "Common options:"
ram54288 0:dbad57390bd1 49
ram54288 0:dbad57390bd1 50 # No argument, shows at tail. This will print an options summary.
ram54288 0:dbad57390bd1 51 opts.on_tail("-h", "--help", "Show this message") do
ram54288 0:dbad57390bd1 52 puts opts
ram54288 0:dbad57390bd1 53 exit
ram54288 0:dbad57390bd1 54 end
ram54288 0:dbad57390bd1 55
ram54288 0:dbad57390bd1 56 # Another typical switch to print the version.
ram54288 0:dbad57390bd1 57 opts.on_tail("--version", "Show version") do
ram54288 0:dbad57390bd1 58 puts "unity_to_junit.rb version #{VERSION}"
ram54288 0:dbad57390bd1 59 exit
ram54288 0:dbad57390bd1 60 end
ram54288 0:dbad57390bd1 61 end
ram54288 0:dbad57390bd1 62
ram54288 0:dbad57390bd1 63 opts.parse!(args)
ram54288 0:dbad57390bd1 64 options
ram54288 0:dbad57390bd1 65 end # parse()
ram54288 0:dbad57390bd1 66
ram54288 0:dbad57390bd1 67 end # class OptparseExample
ram54288 0:dbad57390bd1 68
ram54288 0:dbad57390bd1 69 class UnityToJUnit
ram54288 0:dbad57390bd1 70 include FileUtils::Verbose
ram54288 0:dbad57390bd1 71 attr_reader :report, :total_tests, :failures, :ignored
ram54288 0:dbad57390bd1 72
ram54288 0:dbad57390bd1 73 def initialize
ram54288 0:dbad57390bd1 74 @report = ''
ram54288 0:dbad57390bd1 75 @unit_name = ''
ram54288 0:dbad57390bd1 76 end
ram54288 0:dbad57390bd1 77
ram54288 0:dbad57390bd1 78 def run
ram54288 0:dbad57390bd1 79 # Clean up result file names
ram54288 0:dbad57390bd1 80 results = @targets.map {|target| target.gsub(/\\/,"/")}
ram54288 0:dbad57390bd1 81 #puts "Output File: #{@out_file}"
ram54288 0:dbad57390bd1 82 f = File.new(@out_file, "w")
ram54288 0:dbad57390bd1 83 write_xml_header(f)
ram54288 0:dbad57390bd1 84 write_suites_header( f )
ram54288 0:dbad57390bd1 85 results.each do |result_file|
ram54288 0:dbad57390bd1 86 lines = File.readlines(result_file).map { |line| line.chomp }
ram54288 0:dbad57390bd1 87 if lines.length == 0
ram54288 0:dbad57390bd1 88 raise "Empty test result file: #{result_file}"
ram54288 0:dbad57390bd1 89 else
ram54288 0:dbad57390bd1 90 result_output = get_details(result_file, lines)
ram54288 0:dbad57390bd1 91 tests,failures,ignored = parse_test_summary(lines)
ram54288 0:dbad57390bd1 92 result_output[:counts][:total] = tests
ram54288 0:dbad57390bd1 93 result_output[:counts][:failed] = failures
ram54288 0:dbad57390bd1 94 result_output[:counts][:ignored] = ignored
ram54288 0:dbad57390bd1 95 result_output[:counts][:passed] = (result_output[:counts][:total] - result_output[:counts][:failed] - result_output[:counts][:ignored])
ram54288 0:dbad57390bd1 96 end
ram54288 0:dbad57390bd1 97 #use line[0] from the test output to get the test_file path and name
ram54288 0:dbad57390bd1 98 test_file_str = lines[0].gsub("\\","/")
ram54288 0:dbad57390bd1 99 test_file_str = test_file_str.split(":")
ram54288 0:dbad57390bd1 100 test_file = if (test_file_str.length < 2)
ram54288 0:dbad57390bd1 101 result_file
ram54288 0:dbad57390bd1 102 else
ram54288 0:dbad57390bd1 103 test_file_str[0] + ':' + test_file_str[1]
ram54288 0:dbad57390bd1 104 end
ram54288 0:dbad57390bd1 105 result_output[:source][:path] = File.dirname(test_file)
ram54288 0:dbad57390bd1 106 result_output[:source][:file] = File.basename(test_file)
ram54288 0:dbad57390bd1 107
ram54288 0:dbad57390bd1 108 # save result_output
ram54288 0:dbad57390bd1 109 @unit_name = File.basename(test_file, ".*")
ram54288 0:dbad57390bd1 110
ram54288 0:dbad57390bd1 111 write_suite_header( result_output[:counts], f)
ram54288 0:dbad57390bd1 112 write_failures( result_output, f )
ram54288 0:dbad57390bd1 113 write_tests( result_output, f )
ram54288 0:dbad57390bd1 114 write_ignored( result_output, f )
ram54288 0:dbad57390bd1 115 write_suite_footer( f )
ram54288 0:dbad57390bd1 116 end
ram54288 0:dbad57390bd1 117 write_suites_footer( f )
ram54288 0:dbad57390bd1 118 f.close
ram54288 0:dbad57390bd1 119 end
ram54288 0:dbad57390bd1 120
ram54288 0:dbad57390bd1 121 def set_targets(target_array)
ram54288 0:dbad57390bd1 122 @targets = target_array
ram54288 0:dbad57390bd1 123 end
ram54288 0:dbad57390bd1 124
ram54288 0:dbad57390bd1 125 def set_root_path(path)
ram54288 0:dbad57390bd1 126 @root = path
ram54288 0:dbad57390bd1 127 end
ram54288 0:dbad57390bd1 128 def set_out_file(filename)
ram54288 0:dbad57390bd1 129 @out_file = filename
ram54288 0:dbad57390bd1 130 end
ram54288 0:dbad57390bd1 131 def usage(err_msg=nil)
ram54288 0:dbad57390bd1 132 puts "\nERROR: "
ram54288 0:dbad57390bd1 133 puts err_msg if err_msg
ram54288 0:dbad57390bd1 134 puts "Usage: unity_to_junit.rb [options]"
ram54288 0:dbad57390bd1 135 puts ""
ram54288 0:dbad57390bd1 136 puts "Specific options:"
ram54288 0:dbad57390bd1 137 puts " -r, --results <dir> Look for Unity Results files here."
ram54288 0:dbad57390bd1 138 puts " -p, --root_path <path> Prepend this path to files in results."
ram54288 0:dbad57390bd1 139 puts " -o, --output <filename> XML file to generate."
ram54288 0:dbad57390bd1 140 puts ""
ram54288 0:dbad57390bd1 141 puts "Common options:"
ram54288 0:dbad57390bd1 142 puts " -h, --help Show this message"
ram54288 0:dbad57390bd1 143 puts " --version Show version"
ram54288 0:dbad57390bd1 144
ram54288 0:dbad57390bd1 145 exit 1
ram54288 0:dbad57390bd1 146 end
ram54288 0:dbad57390bd1 147
ram54288 0:dbad57390bd1 148 protected
ram54288 0:dbad57390bd1 149 def get_details(result_file, lines)
ram54288 0:dbad57390bd1 150 results = get_results_structure
ram54288 0:dbad57390bd1 151 lines.each do |line|
ram54288 0:dbad57390bd1 152 line = line.gsub("\\","/")
ram54288 0:dbad57390bd1 153 src_file,src_line,test_name,status,msg = line.split(/:/)
ram54288 0:dbad57390bd1 154 line_out = ((@root and (@root != 0)) ? "#{@root}#{line}" : line ).gsub(/\//, "\\")
ram54288 0:dbad57390bd1 155 case(status)
ram54288 0:dbad57390bd1 156 when 'IGNORE' then results[:ignores] << {:test => test_name, :line => src_line, :message => msg}
ram54288 0:dbad57390bd1 157 when 'FAIL' then results[:failures] << {:test => test_name, :line => src_line, :message => msg}
ram54288 0:dbad57390bd1 158 when 'PASS' then results[:successes] << {:test => test_name, :line => src_line, :message => msg}
ram54288 0:dbad57390bd1 159 end
ram54288 0:dbad57390bd1 160 end
ram54288 0:dbad57390bd1 161 return results
ram54288 0:dbad57390bd1 162 end
ram54288 0:dbad57390bd1 163
ram54288 0:dbad57390bd1 164 def parse_test_summary(summary)
ram54288 0:dbad57390bd1 165 if summary.find { |v| v =~ /(\d+) Tests (\d+) Failures (\d+) Ignored/ }
ram54288 0:dbad57390bd1 166 [$1.to_i,$2.to_i,$3.to_i]
ram54288 0:dbad57390bd1 167 else
ram54288 0:dbad57390bd1 168 raise "Couldn't parse test results: #{summary}"
ram54288 0:dbad57390bd1 169 end
ram54288 0:dbad57390bd1 170 end
ram54288 0:dbad57390bd1 171 def here; File.expand_path(File.dirname(__FILE__)); end
ram54288 0:dbad57390bd1 172
ram54288 0:dbad57390bd1 173 private
ram54288 0:dbad57390bd1 174
ram54288 0:dbad57390bd1 175 def get_results_structure
ram54288 0:dbad57390bd1 176 return {
ram54288 0:dbad57390bd1 177 :source => {:path => '', :file => ''},
ram54288 0:dbad57390bd1 178 :successes => [],
ram54288 0:dbad57390bd1 179 :failures => [],
ram54288 0:dbad57390bd1 180 :ignores => [],
ram54288 0:dbad57390bd1 181 :counts => {:total => 0, :passed => 0, :failed => 0, :ignored => 0},
ram54288 0:dbad57390bd1 182 :stdout => [],
ram54288 0:dbad57390bd1 183 }
ram54288 0:dbad57390bd1 184 end
ram54288 0:dbad57390bd1 185
ram54288 0:dbad57390bd1 186 def write_xml_header( stream )
ram54288 0:dbad57390bd1 187 stream.puts "<?xml version='1.0' encoding='utf-8' ?>"
ram54288 0:dbad57390bd1 188 end
ram54288 0:dbad57390bd1 189
ram54288 0:dbad57390bd1 190 def write_suites_header( stream )
ram54288 0:dbad57390bd1 191 stream.puts "<testsuites>"
ram54288 0:dbad57390bd1 192 end
ram54288 0:dbad57390bd1 193
ram54288 0:dbad57390bd1 194 def write_suite_header( counts, stream )
ram54288 0:dbad57390bd1 195 stream.puts "\t<testsuite errors=\"0\" skipped=\"#{counts[:ignored]}\" failures=\"#{counts[:failed]}\" tests=\"#{counts[:total]}\" name=\"unity\">"
ram54288 0:dbad57390bd1 196 end
ram54288 0:dbad57390bd1 197
ram54288 0:dbad57390bd1 198 def write_failures( results, stream )
ram54288 0:dbad57390bd1 199 result = results[:failures]
ram54288 0:dbad57390bd1 200 result.each do |item|
ram54288 0:dbad57390bd1 201 filename = File.join(results[:source][:path], File.basename(results[:source][:file], '.*'))
ram54288 0:dbad57390bd1 202 stream.puts "\t\t<testcase classname=\"#{@unit_name}\" name=\"#{item[:test]}\" time=\"0\">"
ram54288 0:dbad57390bd1 203 stream.puts "\t\t\t<failure message=\"#{item[:message]}\" type=\"Assertion\"/>"
ram54288 0:dbad57390bd1 204 stream.puts "\t\t\t<system-err>&#xD;[File] #{filename}&#xD;[Line] #{item[:line]}&#xD;</system-err>"
ram54288 0:dbad57390bd1 205 stream.puts "\t\t</testcase>"
ram54288 0:dbad57390bd1 206 end
ram54288 0:dbad57390bd1 207 end
ram54288 0:dbad57390bd1 208
ram54288 0:dbad57390bd1 209 def write_tests( results, stream )
ram54288 0:dbad57390bd1 210 result = results[:successes]
ram54288 0:dbad57390bd1 211 result.each do |item|
ram54288 0:dbad57390bd1 212 filename = File.join(results[:source][:path], File.basename(results[:source][:file], '.*'))
ram54288 0:dbad57390bd1 213 stream.puts "\t\t<testcase classname=\"#{@unit_name}\" name=\"#{item[:test]}\" time=\"0\" />"
ram54288 0:dbad57390bd1 214 end
ram54288 0:dbad57390bd1 215 end
ram54288 0:dbad57390bd1 216
ram54288 0:dbad57390bd1 217 def write_ignored( results, stream )
ram54288 0:dbad57390bd1 218 result = results[:ignores]
ram54288 0:dbad57390bd1 219 result.each do |item|
ram54288 0:dbad57390bd1 220 filename = File.join(results[:source][:path], File.basename(results[:source][:file], '.*'))
ram54288 0:dbad57390bd1 221 puts "Writing ignored tests for test harness: #{filename}"
ram54288 0:dbad57390bd1 222 stream.puts "\t\t<testcase classname=\"#{@unit_name}\" name=\"#{item[:test]}\" time=\"0\">"
ram54288 0:dbad57390bd1 223 stream.puts "\t\t\t<skipped message=\"#{item[:message]}\" type=\"Assertion\"/>"
ram54288 0:dbad57390bd1 224 stream.puts "\t\t\t<system-err>&#xD;[File] #{filename}&#xD;[Line] #{item[:line]}&#xD;</system-err>"
ram54288 0:dbad57390bd1 225 stream.puts "\t\t</testcase>"
ram54288 0:dbad57390bd1 226 end
ram54288 0:dbad57390bd1 227 end
ram54288 0:dbad57390bd1 228
ram54288 0:dbad57390bd1 229 def write_suite_footer( stream )
ram54288 0:dbad57390bd1 230 stream.puts "\t</testsuite>"
ram54288 0:dbad57390bd1 231 end
ram54288 0:dbad57390bd1 232
ram54288 0:dbad57390bd1 233 def write_suites_footer( stream )
ram54288 0:dbad57390bd1 234 stream.puts "</testsuites>"
ram54288 0:dbad57390bd1 235 end
ram54288 0:dbad57390bd1 236 end #UnityToJUnit
ram54288 0:dbad57390bd1 237
ram54288 0:dbad57390bd1 238 if __FILE__ == $0
ram54288 0:dbad57390bd1 239 #parse out the command options
ram54288 0:dbad57390bd1 240 options = ArgvParser.parse(ARGV)
ram54288 0:dbad57390bd1 241
ram54288 0:dbad57390bd1 242 #create an instance to work with
ram54288 0:dbad57390bd1 243 utj = UnityToJUnit.new
ram54288 0:dbad57390bd1 244 begin
ram54288 0:dbad57390bd1 245 #look in the specified or current directory for result files
ram54288 0:dbad57390bd1 246 targets = "#{options.results_dir.gsub(/\\/, '/')}**/*.test*"
ram54288 0:dbad57390bd1 247
ram54288 0:dbad57390bd1 248 results = Dir[targets]
ram54288 0:dbad57390bd1 249 raise "No *.testpass, *.testfail, or *.testresults files found in '#{targets}'" if results.empty?
ram54288 0:dbad57390bd1 250 utj.set_targets(results)
ram54288 0:dbad57390bd1 251
ram54288 0:dbad57390bd1 252 #set the root path
ram54288 0:dbad57390bd1 253 utj.set_root_path(options.root_path)
ram54288 0:dbad57390bd1 254
ram54288 0:dbad57390bd1 255 #set the output XML file name
ram54288 0:dbad57390bd1 256 #puts "Output File from options: #{options.out_file}"
ram54288 0:dbad57390bd1 257 utj.set_out_file(options.out_file)
ram54288 0:dbad57390bd1 258
ram54288 0:dbad57390bd1 259 #run the summarizer
ram54288 0:dbad57390bd1 260 puts utj.run
ram54288 0:dbad57390bd1 261 rescue Exception => e
ram54288 0:dbad57390bd1 262 utj.usage e.message
ram54288 0:dbad57390bd1 263 end
ram54288 0:dbad57390bd1 264 end