RunTests.gmk revision 2518:459d61aa3b54
1# 2# Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. 3# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4# 5# This code is free software; you can redistribute it and/or modify it 6# under the terms of the GNU General Public License version 2 only, as 7# published by the Free Software Foundation. Oracle designates this 8# particular file as subject to the "Classpath" exception as provided 9# by Oracle in the LICENSE file that accompanied this code. 10# 11# This code is distributed in the hope that it will be useful, but WITHOUT 12# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14# version 2 for more details (a copy is included in the LICENSE file that 15# accompanied this code). 16# 17# You should have received a copy of the GNU General Public License version 18# 2 along with this work; if not, write to the Free Software Foundation, 19# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20# 21# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22# or visit www.oracle.com if you need additional information or have any 23# questions. 24# 25 26default: all 27 28include $(SPEC) 29include MakeBase.gmk 30include FindTests.gmk 31 32# We will always run multiple tests serially 33.NOTPARALLEL: 34 35# Hook to include the corresponding custom file, if present. 36$(eval $(call IncludeCustomExtension, , RunTests.gmk)) 37 38TEST_RESULTS_DIR := $(BUILD_OUTPUT)/test-results 39TEST_SUPPORT_DIR := $(BUILD_OUTPUT)/test-support 40 41 42################################################################################ 43# Parse control variables 44################################################################################ 45 46$(eval $(call ParseKeywordVariable, JTREG, \ 47 KEYWORDS := JOBS TIMEOUT TEST_MODE ASSERT VERBOSE RETAIN MAX_MEM, \ 48 STRING_KEYWORDS := OPTIONS JAVA_OPTIONS VM_OPTIONS, \ 49)) 50 51ifneq ($(JTREG), ) 52 # Inform the user 53 $(info Running tests using JTREG control variable '$(JTREG)') 54endif 55 56$(eval $(call ParseKeywordVariable, GTEST, \ 57 KEYWORDS := REPEAT, \ 58 STRING_KEYWORDS := OPTIONS, \ 59)) 60 61ifneq ($(GTEST), ) 62 # Inform the user 63 $(info Running tests using GTEST control variable '$(GTEST)') 64endif 65 66 67################################################################################ 68# Component-specific Jtreg settings 69################################################################################ 70 71ifeq ($(TEST_JOBS), 0) 72 # If TEST_JOBS is not specified, hotspot fallback default is 73 # min(num_cores / 2, 12). 74 hotspot_JTREG_JOBS := $(shell $(EXPR) $(NUM_CORES) / 2) 75 ifeq ($(hotspot_JTREG_JOBS), 0) 76 hotspot_JTREG_JOBS := 1 77 else ifeq ($(shell $(EXPR) $(hotspot_JTREG_JOBS) \> 12), 1) 78 hotspot_JTREG_JOBS := 12 79 endif 80endif 81 82hotspot_JTREG_MAX_MEM := 0 83hotspot_JTREG_ASSERT := false 84hotspot_JTREG_NATIVEPATH := $(TEST_IMAGE_DIR)/hotspot/jtreg/native 85jdk_JTREG_NATIVEPATH := $(TEST_IMAGE_DIR)/jdk/jtreg/native 86 87 88################################################################################ 89# Parse test selection 90# 91# The user has given a test selection in the TEST variable. We must parse it 92# and determine what that means in terms of actual calls to the test framework. 93# 94# The parse functions take as argument a test specification as given by the 95# user, and returns a fully qualified test descriptor if it was a match, or 96# nothing if not. A single test specification can result in multiple test 97# descriptors being returned. A valid test descriptor must always be accepted 98# and returned identically. 99################################################################################ 100 101# Helper function to determine if a test specification is a Gtest test 102# 103# It is a Gtest test if it is either "gtest", or "gtest:" followed by an optional 104# test filter string. 105define ParseGtestTestSelection 106 $(if $(filter gtest%, $1), \ 107 $(if $(filter gtest, $1), \ 108 gtest:all \ 109 , \ 110 $(if $(filter gtest:, $1), \ 111 gtest:all \ 112 , \ 113 $1 \ 114 ) \ 115 ) \ 116 ) 117endef 118 119# Helper function to determine if a test specification is a Jtreg test 120# 121# It is a Jtreg test if it optionally begins with jtreg:, and then is either 122# an unspecified group name (possibly prefixed by :), or a group in a 123# specified <component>/test directory, or a path to a test or test directory, 124# either absolute or relative to TOPDIR. 125define ParseJtregTestSelection 126 $(eval TEST_NAME := $(strip $(patsubst jtreg:%, %, $1))) \ 127 $(if $(or $(findstring :, $(TEST_NAME)), $(findstring /, $(TEST_NAME))), , \ 128 $(eval TEST_NAME := :$(TEST_NAME)) \ 129 ) \ 130 $(if $(findstring :, $(TEST_NAME)), \ 131 $(if $(filter :%, $(TEST_NAME)), \ 132 $(foreach component, $(JTREG_COMPONENTS), \ 133 $(if $(filter $(patsubst :%, %, $(TEST_NAME)), \ 134 $($(component)_JTREG_TEST_GROUPS)), \ 135 jtreg:$(component)/test:$(patsubst :%,%,$(TEST_NAME)) \ 136 ) \ 137 ) \ 138 , \ 139 $(eval COMPONENT := $(word 1, $(subst /, $(SPACE), $(TEST_NAME)))) \ 140 $(eval GROUP := $(word 2, $(subst :, $(SPACE), $(TEST_NAME)))) \ 141 $(if $(filter $(COMPONENT), $(JTREG_COMPONENTS)), \ 142 $(if $(filter $(GROUP), $($(COMPONENT)_JTREG_TEST_GROUPS)), \ 143 jtreg:$(TEST_NAME) \ 144 ) \ 145 ) \ 146 ) \ 147 , \ 148 $(if $(filter /%, $(TEST_NAME)), \ 149 $(if $(wildcard $(TEST_NAME)), \ 150 jtreg:$(TEST_NAME) \ 151 ) \ 152 , \ 153 $(if $(wildcard $(TOPDIR)/$(TEST_NAME)), \ 154 jtreg:$(TEST_NAME) \ 155 ) \ 156 ) \ 157 ) 158endef 159 160ifeq ($(TEST), ) 161 $(info No test selection given in TEST!) 162 $(info Please use e.g. 'run-test TEST=tier1' or 'run-test-tier1') 163 $(error Cannot continue) 164endif 165 166# Now intelligently convert the test selection given by the user in TEST 167# into a list of fully qualified test descriptors of the tests to run. 168TESTS_TO_RUN := 169$(foreach test, $(TEST), \ 170 $(eval PARSED_TESTS := $(call ParseCustomTestSelection, $(test))) \ 171 $(if $(strip $(PARSED_TESTS)), , \ 172 $(eval PARSED_TESTS += $(call ParseGtestTestSelection, $(test))) \ 173 ) \ 174 $(if $(strip $(PARSED_TESTS)), , \ 175 $(eval PARSED_TESTS += $(call ParseJtregTestSelection, $(test))) \ 176 ) \ 177 $(if $(strip $(PARSED_TESTS)), , \ 178 $(eval UNKNOWN_TEST := $(test)) \ 179 ) \ 180 $(eval TESTS_TO_RUN += $(PARSED_TESTS)) \ 181) 182 183ifneq ($(UNKNOWN_TEST), ) 184 $(info Unknown test selection: '$(UNKNOWN_TEST)') 185 $(error Cannot continue) 186endif 187 188TESTS_TO_RUN := $(strip $(TESTS_TO_RUN)) 189 190 191# Present the result of our parsing to the user 192$(info Test selection '$(TEST)', will run:) 193$(foreach test, $(TESTS_TO_RUN), $(info * $(test))) 194 195 196################################################################################ 197# Functions for setting up rules for running the selected tests 198# 199# The SetupRun*Test functions all have the same interface: 200# 201# Parameter 1 is the name of the rule. This is the test id, based on the test 202# descriptor, and this is also used as variable prefix, and the targets 203# generated are listed in a variable by that name. 204# 205# Remaining parameters are named arguments. Currently this is only: 206# TEST -- The properly formatted fully qualified test descriptor 207# 208# After the rule named by the test id has been executed, the following 209# variables will be available: 210# testid_TOTAL - the total number of tests run 211# testid_PASSED - the number of successful tests 212# testid_FAILED - the number of failed tests 213# testid_ERROR - the number of tests was neither successful or failed 214# 215################################################################################ 216 217### Rules for Gtest 218 219SetupRunGtestTest = $(NamedParamsMacroTemplate) 220define SetupRunGtestTestBody 221 $1_TEST_RESULTS_DIR := $$(TEST_RESULTS_DIR)/$1 222 $1_TEST_SUPPORT_DIR := $$(TEST_SUPPORT_DIR)/$1 223 224 $1_TEST_NAME := $$(strip $$(patsubst gtest:%, %, $$($1_TEST))) 225 ifneq ($$($1_TEST_NAME), all) 226 $1_GTEST_FILTER := --gtest_filter=$$($1_TEST_NAME)* 227 endif 228 229 ifneq ($$(GTEST_REPEAT), ) 230 $1_GTEST_REPEAT :=--gtest_repeat=$$(GTEST_REPEAT) 231 endif 232 233 run-test-$1: 234 $$(call LogWarn) 235 $$(call LogWarn, Running test '$$($1_TEST)') 236 $$(call MakeDir, $$($1_TEST_RESULTS_DIR) $$($1_TEST_SUPPORT_DIR)) 237 $$(call ExecuteWithLog, $$($1_TEST_SUPPORT_DIR)/gtest, \ 238 $$(FIXPATH) $$(TEST_IMAGE_DIR)/hotspot/gtest/server/gtestLauncher \ 239 -jdk $(JDK_IMAGE_DIR) $$($1_GTEST_FILTER) \ 240 --gtest_output=xml:$$($1_TEST_RESULTS_DIR)/gtest.xml \ 241 $$($1_GTEST_REPEAT) $$(GTEST_OPTIONS) \ 242 > >($(TEE) $$($1_TEST_RESULTS_DIR)/gtest.txt) || true ) 243 244 $1_RESULT_FILE := $$($1_TEST_RESULTS_DIR)/gtest.txt 245 246 parse-test-$1: run-test-$1 247 $$(call LogWarn, Finished running test '$$($1_TEST)') 248 $$(call LogWarn, Test report is stored in $$(strip \ 249 $$(subst $$(TOPDIR)/, , $$($1_TEST_RESULTS_DIR)))) 250 $$(eval $1_TOTAL := $$(shell $$(AWK) '/==========.* tests? from .* \ 251 test cases? ran/ { print $$$$2 }' $$($1_RESULT_FILE))) 252 $$(eval $1_PASSED := $$(shell $$(AWK) '/\[ PASSED \] .* tests?./ \ 253 { print $$$$4 }' $$($1_RESULT_FILE))) 254 $$(eval $1_FAILED := $$(shell $$(AWK) '/\[ FAILED \] .* tests?, \ 255 listed below/ { print $$$$4 }' $$($1_RESULT_FILE))) 256 $$(if $$($1_FAILED), , $$(eval $1_FAILED := 0)) 257 $$(eval $1_ERROR := $$(shell \ 258 $$(EXPR) $$($1_TOTAL) - $$($1_PASSED) - $$($1_FAILED))) 259 260 $1: run-test-$1 parse-test-$1 261 262 TARGETS += $1 263endef 264 265################################################################################ 266 267### Rules for Jtreg 268 269# Helper function for SetupRunJtregTest. Set a JTREG_* variable from, in order: 270# 1) Specified by user on command line 271# 2) Component-specific default 272# 3) Generic default 273# 274# Note: No spaces are allowed around the arguments. 275# Arg $1 The test ID (i.e. $1 in SetupRunJtregTest) 276# Arg $2 Base variable, e.g. JTREG_JOBS 277# Arg $3 The default value (optional) 278define SetJtregValue 279 ifneq ($$($2), ) 280 $1_$2 := $$($2) 281 else 282 ifneq ($$($$($1_COMPONENT)_$2), ) 283 $1_$2 := $$($$($1_COMPONENT)_$2) 284 else 285 ifneq ($3, ) 286 $1_$2 := $3 287 endif 288 endif 289 endif 290endef 291 292SetupRunJtregTest = $(NamedParamsMacroTemplate) 293define SetupRunJtregTestBody 294 $1_TEST_RESULTS_DIR := $$(TEST_RESULTS_DIR)/$1 295 $1_TEST_SUPPORT_DIR := $$(TEST_SUPPORT_DIR)/$1 296 297 $1_TEST_NAME := $$(strip $$(patsubst jtreg:%, %, $$($1_TEST))) 298 $1_COMPONENT := $$(firstword $$(subst /, $$(SPACE), $$($1_TEST_NAME))) 299 300 # Unfortunately, we need different defaults for some JTREG values, 301 # depending on what component we're running. 302 303 # Convert JTREG_foo into $1_JTREG_foo with a suitable value. 304 $$(eval $$(call SetJtregValue,$1,JTREG_TEST_MODE,agentvm)) 305 $$(eval $$(call SetJtregValue,$1,JTREG_ASSERT,true)) 306 $$(eval $$(call SetJtregValue,$1,JTREG_MAX_MEM,512m)) 307 $$(eval $$(call SetJtregValue,$1,JTREG_NATIVEPATH)) 308 $$(eval $$(call SetJtregValue,$1,JTREG_BASIC_OPTIONS)) 309 310 ifneq ($(TEST_JOBS), 0) 311 # User has specified TEST_JOBS, use that as fallback default 312 $$(eval $$(call SetJtregValue,$1,JTREG_JOBS,$$(TEST_JOBS))) 313 else 314 # Use JOBS as default (except for hotspot) 315 $$(eval $$(call SetJtregValue,$1,JTREG_JOBS,$$(JOBS))) 316 endif 317 318 ifeq ($$(shell $$(EXPR) $$($1_JTREG_JOBS) \> 50), 1) 319 # Until CODETOOLS-7901892 is fixed, JTreg cannot handle more than 50 jobs 320 $1_JTREG_JOBS := 50 321 endif 322 323 # Make sure MaxRAMFraction is high enough to not cause OOM or swapping since 324 # we may end up with a lot of JVM's 325 $1_JTREG_MAX_RAM_FRACTION := $$(shell $$(EXPR) $$($1_JTREG_JOBS) \* 4) 326 327 JTREG_TIMEOUT ?= 4 328 JTREG_VERBOSE ?= fail,error,summary 329 JTREG_RETAIN ?= fail,error 330 331 ifneq ($$($1_JTREG_MAX_MEM), 0) 332 $1_JTREG_BASIC_OPTIONS += -vmoption:-Xmx$$($1_JTREG_MAX_MEM) 333 $1_JTREG_LAUNCHER_OPTIONS += -Xmx$$($1_JTREG_MAX_MEM) 334 endif 335 336 $1_JTREG_BASIC_OPTIONS += -$$($1_JTREG_TEST_MODE) \ 337 -verbose:$$(JTREG_VERBOSE) -retain:$$(JTREG_RETAIN) \ 338 -concurrency:$$($1_JTREG_JOBS) -timeoutFactor:$$(JTREG_TIMEOUT) \ 339 -vmoption:-XX:MaxRAMFraction=$$($1_JTREG_MAX_RAM_FRACTION) 340 341 $1_JTREG_BASIC_OPTIONS += -automatic -keywords:\!ignore -ignore:quiet 342 343 # Some tests needs to find a boot JDK using the JDK8_HOME variable. 344 $1_JTREG_BASIC_OPTIONS += -e:JDK8_HOME=$$(BOOT_JDK) 345 346 $1_JTREG_BASIC_OPTIONS += \ 347 $$(addprefix -javaoption:, $$(JTREG_JAVA_OPTIONS)) \ 348 $$(addprefix -vmoption:, $$(JTREG_VM_OPTIONS)) \ 349 # 350 351 ifeq ($$($1_JTREG_ASSERT), true) 352 $1_JTREG_BASIC_OPTIONS += -ea -esa 353 endif 354 355 ifneq ($$($1_JTREG_NATIVEPATH), ) 356 $1_JTREG_BASIC_OPTIONS += -nativepath:$$($1_JTREG_NATIVEPATH) 357 endif 358 359 run-test-$1: 360 $$(call LogWarn) 361 $$(call LogWarn, Running test '$$($1_TEST)') 362 $$(call MakeDir, $$($1_TEST_RESULTS_DIR) $$($1_TEST_SUPPORT_DIR)) 363 $$(call ExecuteWithLog, $$($1_TEST_SUPPORT_DIR)/jtreg, \ 364 $$(JAVA) $$($1_JTREG_LAUNCHER_OPTIONS) \ 365 -Dprogram=jtreg -jar $$(JT_HOME)/lib/jtreg.jar \ 366 $$($1_JTREG_BASIC_OPTIONS) \ 367 -testjdk:$$(JDK_IMAGE_DIR) \ 368 -dir:$$(TOPDIR) \ 369 -reportDir:$$($1_TEST_RESULTS_DIR) \ 370 -workDir:$$($1_TEST_SUPPORT_DIR) \ 371 $$(JTREG_OPTIONS) \ 372 $$($1_TEST_NAME) || true ) 373 374 $1_RESULT_FILE := $$($1_TEST_RESULTS_DIR)/text/stats.txt 375 376 parse-test-$1: run-test-$1 377 $$(call LogWarn, Finished running test '$$($1_TEST)') 378 $$(call LogWarn, Test report is stored in $$(strip \ 379 $$(subst $$(TOPDIR)/, , $$($1_TEST_RESULTS_DIR)))) 380 $$(eval $1_PASSED := $$(shell $$(AWK) '{ gsub(/[,;]/, ""); \ 381 for (i=1; i<=NF; i++) { if ($$$$i == "passed:") \ 382 print $$$$(i+1) } }' $$($1_RESULT_FILE))) 383 $$(if $$($1_PASSED), , $$(eval $1_PASSED := 0)) 384 $$(eval $1_FAILED := $$(shell $$(AWK) '{gsub(/[,;]/, ""); \ 385 for (i=1; i<=NF; i++) { if ($$$$i == "failed:") \ 386 print $$$$(i+1) } }' $$($1_RESULT_FILE))) 387 $$(if $$($1_FAILED), , $$(eval $1_FAILED := 0)) 388 $$(eval $1_ERROR := $$(shell $$(AWK) '{gsub(/[,;]/, ""); \ 389 for (i=1; i<=NF; i++) { if ($$$$i == "error:") \ 390 print $$$$(i+1) } }' $$($1_RESULT_FILE))) 391 $$(if $$($1_ERROR), , $$(eval $1_ERROR := 0)) 392 $$(eval $1_TOTAL := $$(shell \ 393 $$(EXPR) $$($1_PASSED) + $$($1_FAILED) + $$($1_ERROR))) 394 395 $1: run-test-$1 parse-test-$1 396 397 TARGETS += $1 398endef 399 400 401################################################################################ 402# Setup and execute make rules for all selected tests 403################################################################################ 404 405# Helper function to determine which handler to use for the given test 406UseGtestTestHandler = \ 407 $(if $(filter gtest:%, $1), true) 408 409UseJtregTestHandler = \ 410 $(if $(filter jtreg:%, $1), true) 411 412# Now process each test to run and setup a proper make rule 413$(foreach test, $(TESTS_TO_RUN), \ 414 $(eval TEST_ID := $(shell $(ECHO) $(strip $(test)) | \ 415 $(TR) -cs '[a-z][A-Z][0-9]\n' '_')) \ 416 $(eval ALL_TEST_IDS += $(TEST_ID)) \ 417 $(if $(call UseCustomTestHandler, $(test)), \ 418 $(eval $(call SetupRunCustomTest, $(TEST_ID), \ 419 TEST := $(test), \ 420 )) \ 421 ) \ 422 $(if $(call UseGtestTestHandler, $(test)), \ 423 $(eval $(call SetupRunGtestTest, $(TEST_ID), \ 424 TEST := $(test), \ 425 )) \ 426 ) \ 427 $(if $(call UseJtregTestHandler, $(test)), \ 428 $(eval $(call SetupRunJtregTest, $(TEST_ID), \ 429 TEST := $(test), \ 430 )) \ 431 ) \ 432) 433 434# Sort also removes duplicates, so if there is any we'll get fewer words. 435ifneq ($(words $(ALL_TEST_IDS)), $(words $(sort $(ALL_TEST_IDS)))) 436 $(error Duplicate test specification) 437endif 438 439 440################################################################################ 441# The main target for RunTests.gmk 442################################################################################ 443 444# The SetupRun*Test functions have populated TARGETS. 445 446TEST_FAILURE := false 447 448run-test: $(TARGETS) 449 # Print a table of the result of all tests run and their result 450 $(ECHO) 451 $(ECHO) ============================== 452 $(ECHO) Test summary 453 $(ECHO) ============================== 454 $(PRINTF) "%2s %-49s %5s %5s %5s %5s %2s\n" " " TEST \ 455 TOTAL PASS FAIL ERROR " " 456 $(foreach test, $(TESTS_TO_RUN), \ 457 $(eval TEST_ID := $(shell $(ECHO) $(strip $(test)) | \ 458 $(TR) -cs '[a-z][A-Z][0-9]\n' '_')) \ 459 $(if $(filter $($(TEST_ID)_PASSED), $($(TEST_ID)_TOTAL)), \ 460 $(PRINTF) "%2s %-49s %5d %5d %5d %5d %2s\n" " " "$(test)" \ 461 $($(TEST_ID)_TOTAL) $($(TEST_ID)_PASSED) $($(TEST_ID)_FAILED) \ 462 $($(TEST_ID)_ERROR) " " $(NEWLINE) \ 463 , \ 464 $(PRINTF) "%2s %-49s %5d %5d %5d %5d %2s\n" ">>" "$(test)" \ 465 $($(TEST_ID)_TOTAL) $($(TEST_ID)_PASSED) $($(TEST_ID)_FAILED) \ 466 $($(TEST_ID)_ERROR) "<<" $(NEWLINE) \ 467 $(eval TEST_FAILURE := true) \ 468 ) \ 469 ) 470 $(ECHO) ============================== 471 $(if $(filter true, $(TEST_FAILURE)), \ 472 $(ECHO) TEST FAILURE $(NEWLINE) \ 473 $(TOUCH) $(MAKESUPPORT_OUTPUTDIR)/exit-with-error \ 474 , \ 475 $(ECHO) TEST SUCCESS \ 476 ) 477 $(ECHO) 478 479################################################################################ 480 481all: run-test 482 483.PHONY: default all run-test $(TARGETS) 484