1# ========================================== 2# Unity Project - A Test Framework for C 3# Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams 4# [Released under MIT License. Please refer to license.txt for details] 5# ========================================== 6 7require 'yaml' 8require 'fileutils' 9require 'rbconfig' 10require_relative '../../auto/unity_test_summary' 11require_relative '../../auto/generate_test_runner' 12require_relative '../../auto/colour_reporter' 13 14$is_windows = (RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/) 15 16C_EXTENSION = '.c'.freeze 17 18def load_configuration(config_file) 19 return if $configured 20 21 $cfg_file = "#{__dir__}/../../test/targets/#{config_file}" unless config_file =~ /[\\|\/]/ 22 $cfg = YAML.load(File.read($cfg_file)) 23 $colour_output = false unless $cfg['colour'] 24 $configured = true if config_file != DEFAULT_CONFIG_FILE 25end 26 27def configure_clean 28 CLEAN.include($cfg['compiler']['build_path'] + '*.*') unless $cfg['compiler']['build_path'].nil? 29end 30 31def configure_toolchain(config_file = DEFAULT_CONFIG_FILE) 32 config_file += '.yml' unless config_file =~ /\.yml$/ 33 config_file = config_file unless config_file =~ /[\\|\/]/ 34 load_configuration(config_file) 35 configure_clean 36end 37 38def tackit(strings) 39 result = if strings.is_a?(Array) 40 "\"#{strings.join}\"" 41 else 42 strings 43 end 44 result 45end 46 47def squash(prefix, items) 48 result = '' 49 items.each { |item| result += " #{prefix}#{tackit(item)}" } 50 result 51end 52 53def build_compiler_fields 54 command = tackit($cfg['compiler']['path']) 55 defines = if $cfg['compiler']['defines']['items'].nil? 56 '' 57 else 58 squash($cfg['compiler']['defines']['prefix'], $cfg['compiler']['defines']['items']) 59 end 60 options = squash('', $cfg['compiler']['options']) 61 includes = squash($cfg['compiler']['includes']['prefix'], $cfg['compiler']['includes']['items']) 62 includes = includes.gsub(/\\ /, ' ').gsub(/\\\"/, '"').gsub(/\\$/, '') # Remove trailing slashes (for IAR) 63 64 { command: command, defines: defines, options: options, includes: includes } 65end 66 67def compile(file, _defines = []) 68 compiler = build_compiler_fields 69 unity_include = $cfg['compiler']['includes']['prefix'] + '../../src' 70 cmd_str = "#{compiler[:command]}#{compiler[:defines]}#{compiler[:options]}#{compiler[:includes]} #{unity_include} #{file} " \ 71 "#{$cfg['compiler']['object_files']['prefix']}#{$cfg['compiler']['object_files']['destination']}" \ 72 "#{File.basename(file, C_EXTENSION)}#{$cfg['compiler']['object_files']['extension']}" 73 74 execute(cmd_str) 75end 76 77def build_linker_fields 78 command = tackit($cfg['linker']['path']) 79 options = if $cfg['linker']['options'].nil? 80 '' 81 else 82 squash('', $cfg['linker']['options']) 83 end 84 includes = if $cfg['linker']['includes'].nil? || $cfg['linker']['includes']['items'].nil? 85 '' 86 else 87 squash($cfg['linker']['includes']['prefix'], $cfg['linker']['includes']['items']) 88 end.gsub(/\\ /, ' ').gsub(/\\\"/, '"').gsub(/\\$/, '') # Remove trailing slashes (for IAR) 89 90 { command: command, options: options, includes: includes } 91end 92 93def link_it(exe_name, obj_list) 94 linker = build_linker_fields 95 cmd_str = "#{linker[:command]}#{linker[:options]}#{linker[:includes]} " + 96 (obj_list.map { |obj| "#{$cfg['linker']['object_files']['path']}#{obj} " }).join + 97 $cfg['linker']['bin_files']['prefix'] + ' ' + 98 $cfg['linker']['bin_files']['destination'] + 99 exe_name + $cfg['linker']['bin_files']['extension'] 100 execute(cmd_str) 101end 102 103def build_simulator_fields 104 return nil if $cfg['simulator'].nil? 105 106 command = if $cfg['simulator']['path'].nil? 107 '' 108 else 109 (tackit($cfg['simulator']['path']) + ' ') 110 end 111 pre_support = if $cfg['simulator']['pre_support'].nil? 112 '' 113 else 114 squash('', $cfg['simulator']['pre_support']) 115 end 116 post_support = if $cfg['simulator']['post_support'].nil? 117 '' 118 else 119 squash('', $cfg['simulator']['post_support']) 120 end 121 { command: command, pre_support: pre_support, post_support: post_support } 122end 123 124def execute(command_string, verbose = true) 125 report command_string 126 output = `#{command_string}`.chomp 127 report(output) if verbose && !output.nil? && !output.empty? 128 129 raise "Command failed. (Returned #{$?.exitstatus})" if $?.exitstatus != 0 130 131 output 132end 133 134def report_summary 135 summary = UnityTestSummary.new 136 summary.root = __dir__ 137 results_glob = "#{$cfg['compiler']['build_path']}*.test*" 138 results_glob.tr!('\\', '/') 139 results = Dir[results_glob] 140 summary.targets = results 141 summary.run 142end 143 144def run_tests 145 report 'Running Unity system tests...' 146 147 # Tack on TEST define for compiling unit tests 148 load_configuration($cfg_file) 149 test_defines = ['TEST'] 150 $cfg['compiler']['defines']['items'] = [] if $cfg['compiler']['defines']['items'].nil? 151 $cfg['compiler']['defines']['items'] << "UNITY_FIXTURE_NO_EXTRAS" 152 153 # Get a list of all source files needed 154 src_files = Dir["#{__dir__}/src/*.c"] 155 src_files += Dir["#{__dir__}/test/*.c"] 156 src_files += Dir["#{__dir__}/test/main/*.c"] 157 src_files << '../../src/unity.c' 158 159 # Build object files 160 src_files.each { |f| compile(f, test_defines) } 161 obj_list = src_files.map { |f| File.basename(f.ext($cfg['compiler']['object_files']['extension'])) } 162 163 # Link the test executable 164 test_base = 'framework_test' 165 link_it(test_base, obj_list) 166 167 # Execute unit test and generate results file 168 simulator = build_simulator_fields 169 executable = $cfg['linker']['bin_files']['destination'] + test_base + $cfg['linker']['bin_files']['extension'] 170 cmd_str = if simulator.nil? 171 executable + ' -v -r' 172 else 173 "#{simulator[:command]} #{simulator[:pre_support]} #{executable} #{simulator[:post_support]}" 174 end 175 output = execute(cmd_str) 176 test_results = $cfg['compiler']['build_path'] + test_base 177 test_results += if output.match(/OK$/m).nil? 178 '.testfail' 179 else 180 '.testpass' 181 end 182 File.open(test_results, 'w') { |f| f.print output } 183end 184