diff options
author | glebius <glebius@FreeBSD.org> | 2015-10-26 11:35:40 +0000 |
---|---|---|
committer | glebius <glebius@FreeBSD.org> | 2015-10-26 11:35:40 +0000 |
commit | c62812877398840dae0ba74b03e9e6a43cc56fc5 (patch) | |
tree | 304551aa93f09787d4f56a966c6409faf1b1bcb0 /contrib/ntp/sntp/unity | |
parent | 9e809ce638c9be9ffb800ced1b91c0e8997f4c9e (diff) | |
download | FreeBSD-src-c62812877398840dae0ba74b03e9e6a43cc56fc5.zip FreeBSD-src-c62812877398840dae0ba74b03e9e6a43cc56fc5.tar.gz |
Upgrade NTP to 4.2.8p4.
Security: FreeBSD-SA-15:25.ntp
Security: CVE-2015-7871
Security: CVE-2015-7855
Security: CVE-2015-7854
Security: CVE-2015-7853
Security: CVE-2015-7852
Security: CVE-2015-7851
Security: CVE-2015-7850
Security: CVE-2015-7849
Security: CVE-2015-7848
Security: CVE-2015-7701
Security: CVE-2015-7703
Security: CVE-2015-7704, CVE-2015-7705
Security: CVE-2015-7691, CVE-2015-7692, CVE-2015-7702
Diffstat (limited to 'contrib/ntp/sntp/unity')
-rw-r--r-- | contrib/ntp/sntp/unity/Makefile.am | 4 | ||||
-rw-r--r-- | contrib/ntp/sntp/unity/Makefile.in | 7 | ||||
-rw-r--r-- | contrib/ntp/sntp/unity/auto/generate_test_runner.rb | 311 | ||||
-rwxr-xr-x | contrib/ntp/sntp/unity/auto/parseOutput.rb | 191 | ||||
-rwxr-xr-x | contrib/ntp/sntp/unity/auto/type_sanitizer.rb | 8 | ||||
-rwxr-xr-x | contrib/ntp/sntp/unity/auto/unity_test_summary.py | 135 | ||||
-rw-r--r-- | contrib/ntp/sntp/unity/auto/unity_test_summary.rb | 73 | ||||
-rw-r--r-- | contrib/ntp/sntp/unity/unity.c | 4 | ||||
-rw-r--r-- | contrib/ntp/sntp/unity/unity_config.h | 12 | ||||
-rw-r--r-- | contrib/ntp/sntp/unity/unity_internals.h | 12 |
10 files changed, 615 insertions, 142 deletions
diff --git a/contrib/ntp/sntp/unity/Makefile.am b/contrib/ntp/sntp/unity/Makefile.am index a09e36e..31029ff 100644 --- a/contrib/ntp/sntp/unity/Makefile.am +++ b/contrib/ntp/sntp/unity/Makefile.am @@ -6,18 +6,20 @@ CLEANFILES = noinst_LIBRARIES = libunity.a libunity_a_CFLAGS = \ - -DUNITY_INCLUDE_DOUBLE \ + -DUNITY_INCLUDE_CONFIG_H \ $(NULL) libunity_a_SOURCES = \ ../libpkgver/colcomp.c \ unity.c \ unity.h \ + unity_config.h \ unity_internals.h \ unity_fixture.c \ unity_fixture.h \ unity_fixture_internals.h \ unity_fixture_malloc_overrides.h \ + unity_config.h \ $(NULL) include $(top_srcdir)/depsver.mf diff --git a/contrib/ntp/sntp/unity/Makefile.in b/contrib/ntp/sntp/unity/Makefile.in index 956ff1e..a5758b4 100644 --- a/contrib/ntp/sntp/unity/Makefile.in +++ b/contrib/ntp/sntp/unity/Makefile.in @@ -213,6 +213,7 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BUILD_THREAD = @BUILD_THREAD@ CALC_TICKADJ_DB = @CALC_TICKADJ_DB@ CALC_TICKADJ_DL = @CALC_TICKADJ_DL@ CALC_TICKADJ_DS = @CALC_TICKADJ_DS@ @@ -221,6 +222,7 @@ CALC_TICKADJ_NI = @CALC_TICKADJ_NI@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ +CFLAGS_LIBEVENT = @CFLAGS_LIBEVENT@ CFLAGS_NTP = @CFLAGS_NTP@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ @@ -274,6 +276,7 @@ LIBTOOL_DEPS = @LIBTOOL_DEPS@ LIB_SYSLOG = @LIB_SYSLOG@ LIPO = @LIPO@ LN_S = @LN_S@ +LTHREAD_LIBS = @LTHREAD_LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ @@ -443,18 +446,20 @@ BUILT_SOURCES = .deps-ver CLEANFILES = .deps-ver noinst_LIBRARIES = libunity.a libunity_a_CFLAGS = \ - -DUNITY_INCLUDE_DOUBLE \ + -DUNITY_INCLUDE_CONFIG_H \ $(NULL) libunity_a_SOURCES = \ ../libpkgver/colcomp.c \ unity.c \ unity.h \ + unity_config.h \ unity_internals.h \ unity_fixture.c \ unity_fixture.h \ unity_fixture_internals.h \ unity_fixture_malloc_overrides.h \ + unity_config.h \ $(NULL) SNTP_INCS = -I$(top_srcdir)/../include \ diff --git a/contrib/ntp/sntp/unity/auto/generate_test_runner.rb b/contrib/ntp/sntp/unity/auto/generate_test_runner.rb index c115fad..5b1d451 100644 --- a/contrib/ntp/sntp/unity/auto/generate_test_runner.rb +++ b/contrib/ntp/sntp/unity/auto/generate_test_runner.rb @@ -2,28 +2,44 @@ # Unity Project - A Test Framework for C # Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams # [Released under MIT License. Please refer to license.txt for details] -# ========================================== +# ========================================== +$QUICK_RUBY_VERSION = RUBY_VERSION.split('.').inject(0){|vv,v| vv * 100 + v.to_i } File.expand_path(File.join(File.dirname(__FILE__),'colour_prompt')) class UnityTestRunnerGenerator def initialize(options = nil) - @options = { :includes => [], :plugins => [], :framework => :unity } + @options = UnityTestRunnerGenerator.default_options + case(options) when NilClass then @options when String then @options.merge!(UnityTestRunnerGenerator.grab_config(options)) when Hash then @options.merge!(options) else raise "If you specify arguments, it should be a filename or a hash of options" end + require "#{File.expand_path(File.dirname(__FILE__))}/type_sanitizer" + end + + def self.default_options + { + :includes => [], + :plugins => [], + :framework => :unity, + :test_prefix => "test|spec|should", + :setup_name => "setUp", + :teardown_name => "tearDown", + } end - + + def self.grab_config(config_file) - options = { :includes => [], :plugins => [], :framework => :unity } + options = self.default_options + unless (config_file.nil? or config_file.empty?) require 'yaml' yaml_guts = YAML.load_file(config_file) - options.merge!(yaml_guts[:unity] ? yaml_guts[:unity] : yaml_guts[:cmock]) + options.merge!(yaml_guts[:unity] || yaml_guts[:cmock]) raise "No :unity or :cmock section found in #{config_file}" unless options end return(options) @@ -31,126 +47,167 @@ class UnityTestRunnerGenerator def run(input_file, output_file, options=nil) tests = [] - includes = [] + testfile_includes = [] used_mocks = [] - + + @options.merge!(options) unless options.nil? module_name = File.basename(input_file) - + + #pull required data from source file - File.open(input_file, 'r') do |input| - tests = find_tests(input) - includes = find_includes(input) - used_mocks = find_mocks(includes) - end + source = File.read(input_file) + source = source.force_encoding("ISO-8859-1").encode("utf-8", :replace => nil) if ($QUICK_RUBY_VERSION > 10900) + tests = find_tests(source) + headers = find_includes(source) + testfile_includes = headers[:local] + headers[:system] + used_mocks = find_mocks(testfile_includes) + #build runner file + generate(input_file, output_file, tests, used_mocks, testfile_includes) + + #determine which files were used to return them + all_files_used = [input_file, output_file] + all_files_used += testfile_includes.map {|filename| filename + '.c'} unless testfile_includes.empty? + all_files_used += @options[:includes] unless @options[:includes].empty? + return all_files_used.uniq + end + + def generate(input_file, output_file, tests, used_mocks, testfile_includes) File.open(output_file, 'w') do |output| - create_header(output, used_mocks) + create_header(output, used_mocks, testfile_includes) create_externs(output, tests, used_mocks) create_mock_management(output, used_mocks) create_suite_setup_and_teardown(output) create_reset(output, used_mocks) - create_main(output, input_file, tests) + create_main(output, input_file, tests, used_mocks) end - - all_files_used = [input_file, output_file] - all_files_used += includes.map {|filename| filename + '.c'} unless includes.empty? - all_files_used += @options[:includes] unless @options[:includes].empty? - return all_files_used.uniq + + + + + end - - def find_tests(input_file) - tests_raw = [] - tests_args = [] + + + def find_tests(source) + + tests_and_line_numbers = [] - - input_file.rewind - source_raw = input_file.read - source_scrubbed = source_raw.gsub(/\/\/.*$/, '') # remove line comments + + + + + source_scrubbed = source.gsub(/\/\/.*$/, '') # remove line comments source_scrubbed = source_scrubbed.gsub(/\/\*.*?\*\//m, '') # remove block comments lines = source_scrubbed.split(/(^\s*\#.*$) # Treat preprocessor directives as a logical line | (;|\{|\}) /x) # Match ;, {, and } as end of lines lines.each_with_index do |line, index| #find tests - if line =~ /^((?:\s*TEST_CASE\s*\(.*?\)\s*)*)\s*void\s+(test.*?)\s*\(\s*(.*)\s*\)/ + if line =~ /^((?:\s*TEST_CASE\s*\(.*?\)\s*)*)\s*void\s+((?:#{@options[:test_prefix]}).*)\s*\(\s*(.*)\s*\)/ + arguments = $1 name = $2 call = $3 - args = (@options[:use_param_tests] and $1) ? ($1.gsub(/\s*TEST_CASE\s*\(\s*/,'').strip.split(/\s*\)/).compact) : nil - tests_and_line_numbers << { :name => name, :args => args, :call => call, :line_number => 0 } - tests_args = [] + args = nil + if (@options[:use_param_tests] and !arguments.empty?) + args = [] + arguments.scan(/\s*TEST_CASE\s*\((.*)\)\s*$/) {|a| args << a[0]} + end + tests_and_line_numbers << { :test => name, :args => args, :call => call, :line_number => 0 } + end end + tests_and_line_numbers.uniq! {|v| v[:test] } #determine line numbers and create tests to run - source_lines = source_raw.split("\n") + source_lines = source.split("\n") source_index = 0; tests_and_line_numbers.size.times do |i| source_lines[source_index..-1].each_with_index do |line, index| - if (line =~ /#{tests_and_line_numbers[i][:name]}/) + if (line =~ /#{tests_and_line_numbers[i][:test]}/) source_index += index tests_and_line_numbers[i][:line_number] = source_index + 1 break end end end - + + return tests_and_line_numbers end - def find_includes(input_file) - input_file.rewind - includes = [] - input_file.readlines.each do |line| - scan_results = line.scan(/^\s*#include\s+\"\s*(.+)\.[hH]\s*\"/) - includes << scan_results[0][0] if (scan_results.size > 0) - end + def find_includes(source) + + #remove comments (block and line, in three steps to ensure correct precedence) + source.gsub!(/\/\/(?:.+\/\*|\*(?:$|[^\/])).*$/, '') # remove line comments that comment out the start of blocks + source.gsub!(/\/\*.*?\*\//m, '') # remove block comments + source.gsub!(/\/\/.*$/, '') # remove line comments (all that remain) + + #parse out includes + + includes = { + + :local => source.scan(/^\s*#include\s+\"\s*(.+)\.[hH]\s*\"/).flatten, + :system => source.scan(/^\s*#include\s+<\s*(.+)\s*>/).flatten.map { |inc| "<#{inc}>" } + } + + return includes end - + + def find_mocks(includes) mock_headers = [] includes.each do |include_file| mock_headers << File.basename(include_file) if (include_file =~ /^mock/i) end - return mock_headers + return mock_headers end - - def create_header(output, mocks) + + + def create_header(output, mocks, testfile_includes=[]) output.puts('/* AUTOGENERATED FILE. DO NOT EDIT. */') create_runtest(output, mocks) output.puts("\n//=======Automagically Detected Files To Include=====") output.puts("#include \"#{@options[:framework].to_s}.h\"") output.puts('#include "cmock.h"') unless (mocks.empty?) - @options[:includes].flatten.uniq.compact.each do |includes| - output.puts("#include \"#{includes.gsub('.h','')}.h\"") + @options[:includes].flatten.uniq.compact.each do |inc| + output.puts("#include #{inc.include?('<') ? inc : "\"#{inc.gsub('.h','')}.h\""}") end output.puts('#include <setjmp.h>') output.puts('#include <stdio.h>') output.puts('#include "CException.h"') if @options[:plugins].include?(:cexception) + testfile_includes.delete_if{|inc| inc =~ /(unity|cmock)/} + testrunner_includes = testfile_includes - mocks + testrunner_includes.each do |inc| + output.puts("#include #{inc.include?('<') ? inc : "\"#{inc.gsub('.h','')}.h\""}") + end mocks.each do |mock| output.puts("#include \"#{mock.gsub('.h','')}.h\"") end if @options[:enforce_strict_ordering] - output.puts('') - output.puts('int GlobalExpectCount;') - output.puts('int GlobalVerifyOrder;') - output.puts('char* GlobalOrderError;') + output.puts('') + output.puts('int GlobalExpectCount;') + output.puts('int GlobalVerifyOrder;') + output.puts('char* GlobalOrderError;') end end - + + def create_externs(output, tests, mocks) output.puts("\n//=======External Functions This Runner Calls=====") - output.puts("extern void setUp(void);") - output.puts("extern void tearDown(void);") - output.puts("void resetTest(void);") + output.puts("extern void #{@options[:setup_name]}(void);") + output.puts("extern void #{@options[:teardown_name]}(void);") + tests.each do |test| - output.puts("extern void #{test[:name]}(#{test[:call]});") + output.puts("extern void #{test[:test]}(#{test[:call] || 'void'});") end output.puts('') end - + + def create_mock_management(output, mocks) unless (mocks.empty?) output.puts("\n//=======Mock Management=====") @@ -158,30 +215,34 @@ class UnityTestRunnerGenerator output.puts("{") if @options[:enforce_strict_ordering] output.puts(" GlobalExpectCount = 0;") - output.puts(" GlobalVerifyOrder = 0;") - output.puts(" GlobalOrderError = NULL;") + output.puts(" GlobalVerifyOrder = 0;") + output.puts(" GlobalOrderError = NULL;") end mocks.each do |mock| - output.puts(" #{mock}_Init();") + mock_clean = TypeSanitizer.sanitize_c_identifier(mock) + output.puts(" #{mock_clean}_Init();") end output.puts("}\n") output.puts("static void CMock_Verify(void)") output.puts("{") mocks.each do |mock| - output.puts(" #{mock}_Verify();") + mock_clean = TypeSanitizer.sanitize_c_identifier(mock) + output.puts(" #{mock_clean}_Verify();") end output.puts("}\n") output.puts("static void CMock_Destroy(void)") output.puts("{") mocks.each do |mock| - output.puts(" #{mock}_Destroy();") + mock_clean = TypeSanitizer.sanitize_c_identifier(mock) + output.puts(" #{mock_clean}_Destroy();") end output.puts("}\n") end end - + + def create_suite_setup_and_teardown(output) unless (@options[:suite_setup].nil?) output.puts("\n//=======Suite Setup=====") @@ -198,78 +259,91 @@ class UnityTestRunnerGenerator output.puts("}") end end - + + def create_runtest(output, used_mocks) cexception = @options[:plugins].include? :cexception va_args1 = @options[:use_param_tests] ? ', ...' : '' va_args2 = @options[:use_param_tests] ? '__VA_ARGS__' : '' output.puts("\n//=======Test Runner Used To Run Each Test Below=====") - output.puts("#define RUN_TEST_NO_ARGS") if @options[:use_param_tests] + output.puts("#define RUN_TEST_NO_ARGS") if @options[:use_param_tests] output.puts("#define RUN_TEST(TestFunc, TestLineNum#{va_args1}) \\") output.puts("{ \\") output.puts(" Unity.CurrentTestName = #TestFunc#{va_args2.empty? ? '' : " \"(\" ##{va_args2} \")\""}; \\") output.puts(" Unity.CurrentTestLineNumber = TestLineNum; \\") output.puts(" Unity.NumberOfTests++; \\") + output.puts(" CMock_Init(); \\") unless (used_mocks.empty?) output.puts(" if (TEST_PROTECT()) \\") output.puts(" { \\") output.puts(" CEXCEPTION_T e; \\") if cexception output.puts(" Try { \\") if cexception - output.puts(" CMock_Init(); \\") unless (used_mocks.empty?) - output.puts(" setUp(); \\") + output.puts(" #{@options[:setup_name]}(); \\") + + output.puts(" TestFunc(#{va_args2}); \\") - output.puts(" CMock_Verify(); \\") unless (used_mocks.empty?) + output.puts(" } Catch(e) { TEST_ASSERT_EQUAL_HEX32_MESSAGE(CEXCEPTION_NONE, e, \"Unhandled Exception!\"); } \\") if cexception output.puts(" } \\") - output.puts(" CMock_Destroy(); \\") unless (used_mocks.empty?) + output.puts(" if (TEST_PROTECT() && !TEST_IS_IGNORED) \\") output.puts(" { \\") - output.puts(" tearDown(); \\") + output.puts(" #{@options[:teardown_name]}(); \\") + output.puts(" CMock_Verify(); \\") unless (used_mocks.empty?) + output.puts(" } \\") + output.puts(" CMock_Destroy(); \\") unless (used_mocks.empty?) output.puts(" UnityConcludeTest(); \\") output.puts("}\n") end - + + def create_reset(output, used_mocks) output.puts("\n//=======Test Reset Option=====") - output.puts("void resetTest()") + output.puts("void resetTest(void);") + output.puts("void resetTest(void)") + output.puts("{") output.puts(" CMock_Verify();") unless (used_mocks.empty?) output.puts(" CMock_Destroy();") unless (used_mocks.empty?) - output.puts(" tearDown();") - output.puts(" CMock_Init();") unless (used_mocks.empty?) - output.puts(" setUp();") + output.puts(" #{@options[:teardown_name]}();") + + output.puts(" CMock_Init();") unless (used_mocks.empty?) + output.puts(" #{@options[:setup_name]}();") + output.puts("}") end - - def create_main(output, filename, tests) - output.puts("\nchar *progname;\n") + + + def create_main(output, filename, tests, used_mocks) + output.puts("\nchar const *progname;\n") output.puts("\n\n//=======MAIN=====") - + output.puts("int main(int argc, char *argv[])") output.puts("{") - #new stuff added - #output.puts("\nu_long current_time = 4; // needed by authkeys. Used only in to calculate lifetime.\n"); - - output.puts(" progname = argv[0];\n") - #not necessary after all - #output.puts(" init_lib();\n") - #output.puts(" init_auth();\n") + output.puts(" progname = argv[0];\n") + + + + + + output.puts(" suite_setup();") unless @options[:suite_setup].nil? - output.puts(" Unity.TestFile = \"#{filename}\";") + output.puts(" UnityBegin(\"#{filename}\");") if (@options[:use_param_tests]) tests.each do |test| if ((test[:args].nil?) or (test[:args].empty?)) - output.puts(" RUN_TEST(#{test[:name]}, #{test[:line_number]}, RUN_TEST_NO_ARGS);") + output.puts(" RUN_TEST(#{test[:test]}, #{test[:line_number]}, RUN_TEST_NO_ARGS);") else - test[:args].each {|args| output.puts(" RUN_TEST(#{test[:name]}, #{test[:line_number]}, #{args});")} + test[:args].each {|args| output.puts(" RUN_TEST(#{test[:test]}, #{test[:line_number]}, #{args});")} end end else - tests.each { |test| output.puts(" RUN_TEST(#{test[:name]}, #{test[:line_number]});") } + tests.each { |test| output.puts(" RUN_TEST(#{test[:test]}, #{test[:line_number]});") } end output.puts() + output.puts(" CMock_Guts_MemFreeFinal();") unless used_mocks.empty? output.puts(" return #{@options[:suite_teardown].nil? ? "" : "suite_teardown"}(UnityEnd());") output.puts("}") end @@ -279,31 +353,56 @@ end if ($0 == __FILE__) options = { :includes => [] } yaml_file = nil - - #parse out all the options first - ARGV.reject! do |arg| + + + #parse out all the options first (these will all be removed as we go) + ARGV.reject! do |arg| case(arg) - when '-cexception' + when '-cexception' options[:plugins] = [:cexception]; true - when /\w+\.yml/ + when /\.*\.ya?ml/ + options = UnityTestRunnerGenerator.grab_config(arg); true + when /\.*\.h/ + options[:includes] << arg; true + when /--(\w+)=\"?(.*)\"?/ + options[$1.to_sym] = $2; true else false end - end - + end + + #make sure there is at least one parameter left (the input file) if !ARGV[0] - puts ["usage: ruby #{__FILE__} (yaml) (options) input_test_file output_test_runner (includes)", - " blah.yml - will use config options in the yml file (see docs)", - " -cexception - include cexception support"].join("\n") + puts ["\nusage: ruby #{__FILE__} (files) (options) input_test_file (output)", + "\n input_test_file - this is the C file you want to create a runner for", + " output - this is the name of the runner file to generate", + " defaults to (input_test_file)_Runner", + " files:", + " *.yml / *.yaml - loads configuration from here in :unity or :cmock", + " *.h - header files are added as #includes in runner", + " options:", + + " -cexception - include cexception support", + " --setup_name=\"\" - redefine setUp func name to something else", + " --teardown_name=\"\" - redefine tearDown func name to something else", + " --test_prefix=\"\" - redefine test prefix from default test|spec|should", + " --suite_setup=\"\" - code to execute for setup of entire suite", + " --suite_teardown=\"\" - code to execute for teardown of entire suite", + " --use_param_tests=1 - enable parameterized tests (disabled by default)", + ].join("\n") exit 1 end - + + #create the default test runner name if not specified ARGV[1] = ARGV[0].gsub(".c","_Runner.c") if (!ARGV[1]) - - #everything else is an include file - options[:includes] = (ARGV.slice(2..-1).flatten.compact) if (ARGV.size > 2) - + + + + + + UnityTestRunnerGenerator.new(options).run(ARGV[0], ARGV[1]) end + diff --git a/contrib/ntp/sntp/unity/auto/parseOutput.rb b/contrib/ntp/sntp/unity/auto/parseOutput.rb new file mode 100755 index 0000000..7ea180f --- /dev/null +++ b/contrib/ntp/sntp/unity/auto/parseOutput.rb @@ -0,0 +1,191 @@ +#============================================================ +# Author: John Theofanopoulos +# A simple parser. Takes the output files generated during the build process and +# extracts information relating to the tests. +# +# Notes: +# To capture an output file under VS builds use the following: +# devenv [build instructions] > Output.txt & type Output.txt +# +# To capture an output file under GCC/Linux builds use the following: +# make | tee Output.txt +# +# To use this parser use the following command +# ruby parseOutput.rb [options] [file] +# options: -xml : produce a JUnit compatible XML file +# file : file to scan for results +#============================================================ + + +class ParseOutput +# The following flag is set to true when a test is found or false otherwise. + @testFlag + @xmlOut + @arrayList + @totalTests + @classIndex + +# Set the flag to indicate if there will be an XML output file or not + def setXmlOutput() + @xmlOut = true + end + +# if write our output to XML + def writeXmlOuput() + output = File.open("report.xml", "w") + output << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + @arrayList.each do |item| + output << item << "\n" + end + output << "</testsuite>\n" + end + +# This function will try and determine when the suite is changed. This is +# is the name that gets added to the classname parameter. + def testSuiteVerify(testSuiteName) + if @testFlag == false + @testFlag = true; + # Split the path name + testName = testSuiteName.split("/") + # Remove the extension + baseName = testName[testName.size - 1].split(".") + @testSuite = "test." + baseName[0] + printf "New Test: %s\n", @testSuite + end + end + + +# Test was flagged as having passed so format the output + def testPassed(array) + lastItem = array.length - 1 + testName = array[lastItem - 1] + testSuiteVerify(array[@className]) + printf "%-40s PASS\n", testName + if @xmlOut == true + @arrayList.push " <testcase classname=\"" + @testSuite + "\" name=\"" + testName + "\"/>" + end + end + +# Test was flagged as being ingored so format the output + def testIgnored(array) + lastItem = array.length - 1 + testName = array[lastItem - 2] + reason = array[lastItem].chomp + testSuiteVerify(array[@className]) + printf "%-40s IGNORED\n", testName + if @xmlOut == true + @arrayList.push " <testcase classname=\"" + @testSuite + "\" name=\"" + testName + "\">" + @arrayList.push " <skipped type=\"TEST IGNORED\"> " + reason + " </skipped>" + @arrayList.push " </testcase>" + end + end + +# Test was flagged as having failed so format the line + def testFailed(array) + lastItem = array.length - 1 + testName = array[lastItem - 2] + reason = array[lastItem].chomp + " at line: " + array[lastItem - 3] + testSuiteVerify(array[@className]) + printf "%-40s FAILED\n", testName + if @xmlOut == true + @arrayList.push " <testcase classname=\"" + @testSuite + "\" name=\"" + testName + "\">" + @arrayList.push " <failure type=\"ASSERT FAILED\"> " + reason + " </failure>" + @arrayList.push " </testcase>" + end + end + + +# Figure out what OS we are running on. For now we are assuming if it's not Windows it must +# be Unix based. + def detectOS() + myOS = RUBY_PLATFORM.split("-") + if myOS.size == 2 + if myOS[1] == "mingw32" + @className = 1 + else + @className = 0 + end + else + @className = 0 + end + + end + +# Main function used to parse the file that was captured. + def process(name) + @testFlag = false + @arrayList = Array.new + + detectOS() + + puts "Parsing file: " + name + + + testPass = 0 + testFail = 0 + testIgnore = 0 + puts "" + puts "=================== RESULTS =====================" + puts "" + File.open(name).each do |line| + # Typical test lines look like this: + # <path>/<test_file>.c:36:test_tc1000_opsys:FAIL: Expected 1 Was 0 + # <path>/<test_file>.c:112:test_tc5004_initCanChannel:IGNORE: Not Yet Implemented + # <path>/<test_file>.c:115:test_tc5100_initCanVoidPtrs:PASS + # + # where path is different on Unix vs Windows devices (Windows leads with a drive letter) + lineArray = line.split(":") + lineSize = lineArray.size + # If we were able to split the line then we can look to see if any of our target words + # were found. Case is important. + if lineSize >= 4 + # Determine if this test passed + if line.include? ":PASS" + testPassed(lineArray) + testPass += 1 + elsif line.include? ":FAIL:" + testFailed(lineArray) + testFail += 1 + elsif line.include? ":IGNORE:" + testIgnored(lineArray) + testIgnore += 1 + # If none of the keywords are found there are no more tests for this suite so clear + # the test flag + else + @testFlag = false + end + else + @testFlag = false + end + end + puts "" + puts "=================== SUMMARY =====================" + puts "" + puts "Tests Passed : " + testPass.to_s + puts "Tests Failed : " + testFail.to_s + puts "Tests Ignored : " + testIgnore.to_s + @totalTests = testPass + testFail + testIgnore + if @xmlOut == true + heading = "<testsuite tests=\"" + @totalTests.to_s + "\" failures=\"" + testFail.to_s + "\"" + " skips=\"" + testIgnore.to_s + "\">" + @arrayList.insert(0, heading) + writeXmlOuput() + end + + # return result + end + + end + +# If the command line has no values in, used a default value of Output.txt +parseMyFile = ParseOutput.new + +if ARGV.size >= 1 + ARGV.each do |a| + if a == "-xml" + parseMyFile.setXmlOutput(); + else + parseMyFile.process(a) + break + end + end +end diff --git a/contrib/ntp/sntp/unity/auto/type_sanitizer.rb b/contrib/ntp/sntp/unity/auto/type_sanitizer.rb new file mode 100755 index 0000000..7c2c0ac --- /dev/null +++ b/contrib/ntp/sntp/unity/auto/type_sanitizer.rb @@ -0,0 +1,8 @@ +module TypeSanitizer + + def self.sanitize_c_identifier(unsanitized) + # convert filename to valid C identifier by replacing invalid chars with '_' + return unsanitized.gsub(/[-\/\\\.\,\s]/, "_") + end + +end diff --git a/contrib/ntp/sntp/unity/auto/unity_test_summary.py b/contrib/ntp/sntp/unity/auto/unity_test_summary.py new file mode 100755 index 0000000..c64f6c5 --- /dev/null +++ b/contrib/ntp/sntp/unity/auto/unity_test_summary.py @@ -0,0 +1,135 @@ +#! python3 +# ========================================== +# Unity Project - A Test Framework for C +# Copyright (c) 2015 Alexander Mueller / XelaRellum@web.de +# [Released under MIT License. Please refer to license.txt for details] +# Based on the ruby script by Mike Karlesky, Mark VanderVoord, Greg Williams +# ========================================== +import sys +import os +import re +from glob import glob + +class UnityTestSummary: + def __init__(self): + self.report = '' + self.total_tests = 0 + self.failures = 0 + self.ignored = 0 + + def run(self): + # Clean up result file names + results = [] + for target in self.targets: + results.append(target.replace('\\', '/')) + + # Dig through each result file, looking for details on pass/fail: + failure_output = [] + ignore_output = [] + + for result_file in results: + lines = list(map(lambda line: line.rstrip(), open(result_file, "r").read().split('\n'))) + if len(lines) == 0: + raise Exception("Empty test result file: %s" % result_file) + + details = self.get_details(result_file, lines) + failures = details['failures'] + ignores = details['ignores'] + if len(failures) > 0: failure_output.append('\n'.join(failures)) + if len(ignores) > 0: ignore_output.append('n'.join(ignores)) + tests,failures,ignored = self.parse_test_summary('\n'.join(lines)) + self.total_tests += tests + self.failures += failures + self.ignored += ignored + + if self.ignored > 0: + self.report += "\n" + self.report += "--------------------------\n" + self.report += "UNITY IGNORED TEST SUMMARY\n" + self.report += "--------------------------\n" + self.report += "\n".join(ignore_output) + + if self.failures > 0: + self.report += "\n" + self.report += "--------------------------\n" + self.report += "UNITY FAILED TEST SUMMARY\n" + self.report += "--------------------------\n" + self.report += '\n'.join(failure_output) + + self.report += "\n" + self.report += "--------------------------\n" + self.report += "OVERALL UNITY TEST SUMMARY\n" + self.report += "--------------------------\n" + self.report += "{total_tests} TOTAL TESTS {failures} TOTAL FAILURES {ignored} IGNORED\n".format(total_tests = self.total_tests, failures=self.failures, ignored=self.ignored) + self.report += "\n" + + return self.report + + def set_targets(self, target_array): + self.targets = target_array + + def set_root_path(self, path): + self.root = path + + def usage(self, err_msg=None): + print("\nERROR: ") + if err_msg: + print(err_msg) + print("\nUsage: unity_test_summary.rb result_file_directory/ root_path/") + print(" result_file_directory - The location of your results files.") + print(" Defaults to current directory if not specified.") + print(" Should end in / if specified.") + print(" root_path - Helpful for producing more verbose output if using relative paths.") + sys.exit(1) + + def get_details(self, result_file, lines): + results = { 'failures': [], 'ignores': [], 'successes': [] } + for line in lines: + parts = line.split(':') + if len(parts) != 5: + continue + src_file,src_line,test_name,status,msg = parts + if len(self.root) > 0: + line_out = "%s%s" % (self.root, line) + else: + line_out = line + if status == 'IGNORE': + results['ignores'].append(line_out) + elif status == 'FAIL': + results['failures'].append(line_out) + elif status == 'PASS': + results['successes'].append(line_out) + return results + + def parse_test_summary(self, summary): + m = re.search(r"([0-9]+) Tests ([0-9]+) Failures ([0-9]+) Ignored", summary) + if not m: + raise Exception("Couldn't parse test results: %s" % summary) + + return int(m.group(1)), int(m.group(2)), int(m.group(3)) + + +if __name__ == '__main__': + uts = UnityTestSummary() + try: + #look in the specified or current directory for result files + if len(sys.argv) > 1: + targets_dir = sys.argv[1] + else: + targets_dir = './' + targets = list(map(lambda x: x.replace('\\', '/'), glob(targets_dir + '*.test*'))) + if len(targets) == 0: + raise Exception("No *.testpass or *.testfail files found in '%s'" % targets_dir) + uts.set_targets(targets) + + #set the root path + if len(sys.argv) > 2: + root_path = sys.argv[2] + else: + root_path = os.path.split(__file__)[0] + uts.set_root_path(root_path) + + #run the summarizer + print(uts.run()) + except Exception as e: + uts.usage(e) diff --git a/contrib/ntp/sntp/unity/auto/unity_test_summary.rb b/contrib/ntp/sntp/unity/auto/unity_test_summary.rb index 69ec2e8..78d727e 100644 --- a/contrib/ntp/sntp/unity/auto/unity_test_summary.rb +++ b/contrib/ntp/sntp/unity/auto/unity_test_summary.rb @@ -2,7 +2,7 @@ # Unity Project - A Test Framework for C # Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams # [Released under MIT License. Please refer to license.txt for details] -# ========================================== +# ========================================== #!/usr/bin/ruby # @@ -15,22 +15,24 @@ class UnityTestSummary include FileUtils::Verbose attr_reader :report, :total_tests, :failures, :ignored - - def initialize + + def initialize(opts = {}) @report = '' @total_tests = 0 @failures = 0 @ignored = 0 + + end - + def run # Clean up result file names results = @targets.map {|target| target.gsub(/\\/,'/')} - - # Dig through each result file, looking for details on pass/fail: + + # Dig through each result file, looking for details on pass/fail: failure_output = [] ignore_output = [] - + results.each do |result_file| lines = File.readlines(result_file).map { |line| line.chomp } if lines.length == 0 @@ -45,7 +47,7 @@ class UnityTestSummary @ignored += ignored end end - + if @ignored > 0 @report += "\n" @report += "--------------------------\n" @@ -53,7 +55,7 @@ class UnityTestSummary @report += "--------------------------\n" @report += ignore_output.flatten.join("\n") end - + if @failures > 0 @report += "\n" @report += "--------------------------\n" @@ -61,7 +63,7 @@ class UnityTestSummary @report += "--------------------------\n" @report += failure_output.flatten.join("\n") end - + @report += "\n" @report += "--------------------------\n" @report += "OVERALL UNITY TEST SUMMARY\n" @@ -69,32 +71,33 @@ class UnityTestSummary @report += "#{@total_tests} TOTAL TESTS #{@failures} TOTAL FAILURES #{@ignored} IGNORED\n" @report += "\n" end - + def set_targets(target_array) @targets = target_array end - + def set_root_path(path) @root = path end def usage(err_msg=nil) + puts "\nERROR: " puts err_msg if err_msg - puts "Usage: unity_test_summary.rb" + puts "\nUsage: unity_test_summary.rb result_file_directory/ root_path/" + puts " result_file_directory - The location of your results files." + puts " Defaults to current directory if not specified." + puts " Should end in / if specified." + puts " root_path - Helpful for producing more verbose output if using relative paths." exit 1 end - + protected - - @@targets=nil - @@path=nil - @@root=nil def get_details(result_file, lines) results = { :failures => [], :ignores => [], :successes => [] } lines.each do |line| src_file,src_line,test_name,status,msg = line.split(/:/) - line_out = ((@root and (@root != 0)) ? "#{@root}#{line}" : line ).gsub(/\//, "\\") + line_out = ((@root && (@root != 0)) ? "#{@root}#{line}" : line ).gsub(/\//, "\\") case(status) when 'IGNORE' then results[:ignores] << line_out when 'FAIL' then results[:failures] << line_out @@ -103,9 +106,9 @@ class UnityTestSummary end return results end - + def parse_test_summary(summary) - if summary[-3..-1].join("\n") =~ /(\d+) Tests (\d+) Failures (\d+) Ignored/ + if summary.find { |v| v =~ /(\d+) Tests (\d+) Failures (\d+) Ignored/ } [$1.to_i,$2.to_i,$3.to_i] else raise "Couldn't parse test results: #{summary}" @@ -113,14 +116,34 @@ class UnityTestSummary end def here; File.expand_path(File.dirname(__FILE__)); end - + end if $0 == __FILE__ - script = UnityTestSummary.new + + #parse out the command options + opts, args = ARGV.partition {|v| v =~ /^--\w+/} + opts.map! {|v| v[2..-1].to_sym } + + #create an instance to work with + uts = UnityTestSummary.new(opts) + begin - script.run + #look in the specified or current directory for result files + args[0] ||= './' + targets = "#{ARGV[0].gsub(/\\/, '/')}**/*.test*" + results = Dir[targets] + raise "No *.testpass, *.testfail, or *.testresults files found in '#{targets}'" if results.empty? + uts.set_targets(results) + + #set the root path + args[1] ||= Dir.pwd + '/' + uts.set_root_path(ARGV[1]) + + #run the summarizer + puts uts.run rescue Exception => e - script.usage e.message + uts.usage e.message end end + diff --git a/contrib/ntp/sntp/unity/unity.c b/contrib/ntp/sntp/unity/unity.c index cbdef3b..0161f8f 100644 --- a/contrib/ntp/sntp/unity/unity.c +++ b/contrib/ntp/sntp/unity/unity.c @@ -327,16 +327,14 @@ void UnityConcludeTest(void) } printf("| "); - printf(Unity.XFAILMessage); + printf("%s", Unity.XFAILMessage); Unity.XFAILMessage = NULL; } else { printf(" - EXPECTED FAIL!"); } - } - else if (Unity.CurrentTestIgnored) diff --git a/contrib/ntp/sntp/unity/unity_config.h b/contrib/ntp/sntp/unity/unity_config.h new file mode 100644 index 0000000..25418bd --- /dev/null +++ b/contrib/ntp/sntp/unity/unity_config.h @@ -0,0 +1,12 @@ +/* unity_config.h */ + +#ifndef UNITY_CONFIG_H +#define UNITY_CONFIG_H + +#define UNITY_INCLUDE_DOUBLE + +#ifndef HAVE_STDINT_H +# define UNITY_EXCLUDE_STDINT_H +#endif + +#endif /* UNITY_CONFIG_H */ diff --git a/contrib/ntp/sntp/unity/unity_internals.h b/contrib/ntp/sntp/unity/unity_internals.h index a38e101..c2aabc3 100644 --- a/contrib/ntp/sntp/unity/unity_internals.h +++ b/contrib/ntp/sntp/unity/unity_internals.h @@ -82,22 +82,22 @@ // UNITY_INT_WIDTH. #ifndef UNITY_POINTER_WIDTH #ifdef UINTPTR_MAX - #if (UINTPTR_MAX <= 0xFFFF) + #if (UINTPTR_MAX+0 <= 0xFFFF) #define UNITY_POINTER_WIDTH (16) - #elif (UINTPTR_MAX <= 0xFFFFFFFF) + #elif (UINTPTR_MAX+0 <= 0xFFFFFFFF) #define UNITY_POINTER_WIDTH (32) - #elif (UINTPTR_MAX <= 0xFFFFFFFFFFFFFFFF) + #elif (UINTPTR_MAX+0 <= 0xFFFFFFFFFFFFFFFF) #define UNITY_POINTER_WIDTH (64) #endif #endif #endif #ifndef UNITY_POINTER_WIDTH #ifdef INTPTR_MAX - #if (INTPTR_MAX <= 0x7FFF) + #if (INTPTR_MAX+0 <= 0x7FFF) #define UNITY_POINTER_WIDTH (16) - #elif (INTPTR_MAX <= 0x7FFFFFFF) + #elif (INTPTR_MAX+0 <= 0x7FFFFFFF) #define UNITY_POINTER_WIDTH (32) - #elif (INTPTR_MAX <= 0x7FFFFFFFFFFFFFFF) + #elif (INTPTR_MAX+0 <= 0x7FFFFFFFFFFFFFFF) #define UNITY_POINTER_WIDTH (64) #endif #endif |