#!/bin/perl ############################################################################################## # Copyright (c) Microsoft # # All rights reserved # # Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file # except in compliance with the License. You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # # THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER # EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF # TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. # # See the Apache Version 2.0 License for specific language governing permissions and # limitations under the License. ############################################################################################## #usage: # perl run_test.pl # test root dir: base directory to look for tests from. # test file: test.cpp to run use Cwd; use Cwd 'abs_path'; use File::Basename; use File::Find; use Safe; use strict; my $cflag_define = '"-D%s=%s"'; # to be used as sprintf($cflag_define, "NAME", "VALUE"); mkdir("conformance-temp"); my $tmpdir = abs_path('./conformance-temp'); my $test_exec = abs_path("$tmpdir/test.out"); my $tests_root = @ARGV[0]; my $test = abs_path(@ARGV[1]); if (!$tests_root) { print "ERROR: Test root dir not provided\n"; exit(1); } $tests_root = abs_path($tests_root); chdir($tests_root); my $CLANG_AMP_HOME="@PROJECT_SOURCE_DIR@"; my $CLANG_AMP_BUILD_DIR="@PROJECT_BINARY_DIR@"; my $RUNTESTSDIR="@RUNTESTSDIR@"; my $CLANG_AMP="$CLANG_AMP_BUILD_DIR/compiler/bin/clang++"; my $SHARED_CXXFLAGS="-std=c++11 -I$CLANG_AMP_HOME/include -I$AMPTESTINC -I/usr/include -I$CLANG_AMP_BUILD_DIR/compiler/lib/clang/3.5.0/include/"; ### Execute tests use constant PASS => 0; use constant SKIP => 1; use constant FAIL => 2; log_message("Test: $test"); # Read test configuration undef %Test::config; if(not defined $Test::config{'definitions'}) { $Test::config{'definitions'} = [{}]; } # Find "expects error" directives in cpp open(TEST_CPP, $test) or &exit_message(1, "Cannot open $test"); $Test::config{'expected_success'} = (grep m@//#\s*Expects\s*(\d*)\s*:\s*(warning|error)@i, ) == 0; close(TEST_CPP); log_message('Compile only: '.bool_str($Test::config{'compile_only'})."\n" .'Expected success: '.bool_str($Test::config{'expected_success'})); # For each set of definitions chdir($tmpdir); foreach my $def_set (@{$Test::config{'definitions'}}) { my $command; if ($Test::config{'compile_only'}) { $command = "\\ $CLANG_AMP -cc1 -fcxx-exceptions -fsyntax-only $SHARED_CXXFLAGS $test"; } else { $command = "\\ $CLANG_AMP $SHARED_CXXFLAGS $test -o $tmpdir/test.out"; } log_message("Command: $command\n" ."Build output:\n" ."<<<"); my $build_exit_code = system($command) >> 8; log_message(">>>\n" ."Build exit code: $build_exit_code"); my $exec_exit_code; if((not $Test::config{'compile_only'}) && $build_exit_code == 0 && $Test::config{'expected_success'}) { log_message("Execution output:\n" .'<<<'); $exec_exit_code = system("$test_exec") >> 8; log_message(">>>\n" ."Execution exit code: $exec_exit_code"); } # Interpret result my $result; if(not $Test::config{'expected_success'}) # Negative test { if($build_exit_code != 0) { $result = PASS; } else { $result = FAIL; } } elsif($Test::config{'compile_only'}) # Compile only test { if($build_exit_code == 0) { $result = PASS; } else { $result = FAIL; } } else # Executable test { if($build_exit_code != 0) { $result = FAIL; } elsif($exec_exit_code == 0) { $result = PASS; } elsif($exec_exit_code == 2) { $result = SKIP; } else { $result = FAIL; } } if($result == PASS) { log_message('Result: passed'); } elsif($result == FAIL) { log_message('Result: failed'); } elsif($result == SKIP) { log_message('Result: skipped'); } else { exit_message(1, "Unexpected result!"); } } log_message("====================================================="); ### Subroutines # Use: exit_message(code, msg) sub exit_message { if(@_ != 2) { die('exit_message expects 2 arguments'); } print("\n".($_[0] == 0 ? 'SUCCESS' : 'FAILURE').": ".$_[1]); exit($_[0]); } # Use: log_message(msg, ...) sub log_message { print "@_\n"; } # Use: bool_str(val) # Returns: string 'true'/'false' sub bool_str { return $_[0] ? 'true' : 'false'; }