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 
  26 default: all
  27 
  28 include $(SPEC)
  29 include MakeBase.gmk
  30 include 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 
  38 TEST_RESULTS_DIR := $(BUILD_OUTPUT)/test-results
  39 TEST_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 
  51 ifneq ($(JTREG), )
  52   # Inform the user
  53   $(info Running tests using JTREG control variable '$(JTREG)')
  54 endif
  55 
  56 $(eval $(call ParseKeywordVariable, GTEST, \
  57     KEYWORDS := REPEAT, \
  58     STRING_KEYWORDS := OPTIONS, \
  59 ))
  60 
  61 ifneq ($(GTEST), )
  62   # Inform the user
  63   $(info Running tests using GTEST control variable '$(GTEST)')
  64 endif
  65 
  66 
  67 ################################################################################
  68 # Component-specific Jtreg settings
  69 ################################################################################
  70 
  71 ifeq ($(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
  80 endif
  81 
  82 hotspot_JTREG_MAX_MEM := 0
  83 hotspot_JTREG_ASSERT := false
  84 hotspot_JTREG_NATIVEPATH := $(TEST_IMAGE_DIR)/hotspot/jtreg/native
  85 jdk_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.
 105 define 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   )
 117 endef
 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.
 125 define 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   )
 158 endef
 159 
 160 ifeq ($(TEST), )
 161   $(info No test selection given in TEST!)
 162   $(info Please use e.g. 'run-test TEST=tier1' or 'run-test-tier1')
 163   $(info See common/doc/testing.[md|html] for help)
 164   $(error Cannot continue)
 165 endif
 166 
 167 # Now intelligently convert the test selection given by the user in TEST
 168 # into a list of fully qualified test descriptors of the tests to run.
 169 TESTS_TO_RUN :=
 170 $(foreach test, $(TEST), \
 171   $(eval PARSED_TESTS := $(call ParseCustomTestSelection, $(test))) \
 172   $(if $(strip $(PARSED_TESTS)), , \
 173     $(eval PARSED_TESTS += $(call ParseGtestTestSelection, $(test))) \
 174   ) \
 175   $(if $(strip $(PARSED_TESTS)), , \
 176     $(eval PARSED_TESTS += $(call ParseJtregTestSelection, $(test))) \
 177   ) \
 178   $(if $(strip $(PARSED_TESTS)), , \
 179     $(eval UNKNOWN_TEST := $(test)) \
 180   ) \
 181   $(eval TESTS_TO_RUN += $(PARSED_TESTS)) \
 182 )
 183 
 184 ifneq ($(UNKNOWN_TEST), )
 185   $(info Unknown test selection: '$(UNKNOWN_TEST)')
 186   $(info See common/doc/testing.[md|html] for help)
 187   $(error Cannot continue)
 188 endif
 189 
 190 TESTS_TO_RUN := $(strip $(TESTS_TO_RUN))
 191 
 192 
 193 # Present the result of our parsing to the user
 194 $(info Test selection '$(TEST)', will run:)
 195 $(foreach test, $(TESTS_TO_RUN), $(info * $(test)))
 196 
 197 
 198 ################################################################################
 199 # Functions for setting up rules for running the selected tests
 200 #
 201 # The SetupRun*Test functions all have the same interface:
 202 #
 203 # Parameter 1 is the name of the rule. This is the test id, based on the test
 204 # descriptor, and this is also used as variable prefix, and the targets
 205 # generated are listed in a variable by that name.
 206 #
 207 # Remaining parameters are named arguments. Currently this is only:
 208 #   TEST -- The properly formatted fully qualified test descriptor
 209 #
 210 # After the rule named by the test id has been executed, the following
 211 # variables will be available:
 212 # testid_TOTAL - the total number of tests run
 213 # testid_PASSED - the number of successful tests
 214 # testid_FAILED - the number of failed tests
 215 # testid_ERROR - the number of tests was neither successful or failed
 216 #
 217 ################################################################################
 218 
 219 ### Rules for Gtest
 220 
 221 SetupRunGtestTest = $(NamedParamsMacroTemplate)
 222 define SetupRunGtestTestBody
 223   $1_TEST_RESULTS_DIR := $$(TEST_RESULTS_DIR)/$1
 224   $1_TEST_SUPPORT_DIR := $$(TEST_SUPPORT_DIR)/$1
 225 
 226   $1_TEST_NAME := $$(strip $$(patsubst gtest:%, %, $$($1_TEST)))
 227   ifneq ($$($1_TEST_NAME), all)
 228     $1_GTEST_FILTER := --gtest_filter=$$($1_TEST_NAME)*
 229   endif
 230 
 231   ifneq ($$(GTEST_REPEAT), )
 232     $1_GTEST_REPEAT :=--gtest_repeat=$$(GTEST_REPEAT)
 233   endif
 234 
 235   run-test-$1:
 236         $$(call LogWarn)
 237         $$(call LogWarn, Running test '$$($1_TEST)')
 238         $$(call MakeDir, $$($1_TEST_RESULTS_DIR) $$($1_TEST_SUPPORT_DIR))
 239         $$(call ExecuteWithLog, $$($1_TEST_SUPPORT_DIR)/gtest, \
 240             $$(FIXPATH) $$(TEST_IMAGE_DIR)/hotspot/gtest/server/gtestLauncher \
 241             -jdk $(JDK_IMAGE_DIR) $$($1_GTEST_FILTER) \
 242             --gtest_output=xml:$$($1_TEST_RESULTS_DIR)/gtest.xml \
 243             $$($1_GTEST_REPEAT) $$(GTEST_OPTIONS) \
 244             > >($(TEE) $$($1_TEST_RESULTS_DIR)/gtest.txt) || true )
 245 
 246   $1_RESULT_FILE := $$($1_TEST_RESULTS_DIR)/gtest.txt
 247 
 248   parse-test-$1: run-test-$1
 249         $$(call LogWarn, Finished running test '$$($1_TEST)')
 250         $$(call LogWarn, Test report is stored in $$(strip \
 251             $$(subst $$(TOPDIR)/, , $$($1_TEST_RESULTS_DIR))))
 252         $$(eval $1_TOTAL := $$(shell $$(AWK) '/==========.* tests? from .* \
 253             test cases? ran/ { print $$$$2 }' $$($1_RESULT_FILE)))
 254         $$(eval $1_PASSED := $$(shell $$(AWK) '/\[  PASSED  \] .* tests?./ \
 255             { print $$$$4 }' $$($1_RESULT_FILE)))
 256         $$(eval $1_FAILED := $$(shell $$(AWK) '/\[  FAILED  \] .* tests?, \
 257             listed below/ { print $$$$4 }' $$($1_RESULT_FILE)))
 258         $$(if $$($1_FAILED), , $$(eval $1_FAILED := 0))
 259         $$(eval $1_ERROR := $$(shell \
 260             $$(EXPR) $$($1_TOTAL) - $$($1_PASSED) - $$($1_FAILED)))
 261 
 262   $1: run-test-$1 parse-test-$1
 263 
 264   TARGETS += $1
 265 endef
 266 
 267 ################################################################################
 268 
 269 ### Rules for Jtreg
 270 
 271 # Helper function for SetupRunJtregTest. Set a JTREG_* variable from, in order:
 272 # 1) Specified by user on command line
 273 # 2) Component-specific default
 274 # 3) Generic default
 275 #
 276 # Note: No spaces are allowed around the arguments.
 277 # Arg $1 The test ID (i.e. $1 in SetupRunJtregTest)
 278 # Arg $2 Base variable, e.g. JTREG_JOBS
 279 # Arg $3 The default value (optional)
 280 define SetJtregValue
 281   ifneq ($$($2), )
 282     $1_$2 := $$($2)
 283   else
 284     ifneq ($$($$($1_COMPONENT)_$2), )
 285       $1_$2 := $$($$($1_COMPONENT)_$2)
 286     else
 287       ifneq ($3, )
 288         $1_$2 := $3
 289       endif
 290     endif
 291   endif
 292 endef
 293 
 294 SetupRunJtregTest = $(NamedParamsMacroTemplate)
 295 define SetupRunJtregTestBody
 296   $1_TEST_RESULTS_DIR := $$(TEST_RESULTS_DIR)/$1
 297   $1_TEST_SUPPORT_DIR := $$(TEST_SUPPORT_DIR)/$1
 298 
 299   $1_TEST_NAME := $$(strip $$(patsubst jtreg:%, %, $$($1_TEST)))
 300   $1_COMPONENT := $$(firstword $$(subst /, $$(SPACE), $$($1_TEST_NAME)))
 301 
 302   ifeq ($$(JT_HOME), )
 303     $$(info Error: jtreg framework is not found.)
 304     $$(info Please run configure using --with-jtreg.)
 305     $$(error Cannot continue)
 306   endif
 307 
 308   # Unfortunately, we need different defaults for some JTREG values,
 309   # depending on what component we're running.
 310 
 311   # Convert JTREG_foo into $1_JTREG_foo with a suitable value.
 312   $$(eval $$(call SetJtregValue,$1,JTREG_TEST_MODE,agentvm))
 313   $$(eval $$(call SetJtregValue,$1,JTREG_ASSERT,true))
 314   $$(eval $$(call SetJtregValue,$1,JTREG_MAX_MEM,512m))
 315   $$(eval $$(call SetJtregValue,$1,JTREG_NATIVEPATH))
 316   $$(eval $$(call SetJtregValue,$1,JTREG_BASIC_OPTIONS))
 317 
 318   ifneq ($(TEST_JOBS), 0)
 319     # User has specified TEST_JOBS, use that as fallback default
 320     $$(eval $$(call SetJtregValue,$1,JTREG_JOBS,$$(TEST_JOBS)))
 321   else
 322     # Use JOBS as default (except for hotspot)
 323     $$(eval $$(call SetJtregValue,$1,JTREG_JOBS,$$(JOBS)))
 324   endif
 325 
 326   ifeq ($$(shell $$(EXPR) $$($1_JTREG_JOBS) \> 50), 1)
 327     # Until CODETOOLS-7901892 is fixed, JTreg cannot handle more than 50 jobs
 328     $1_JTREG_JOBS := 50
 329   endif
 330 
 331   # Make sure MaxRAMFraction is high enough to not cause OOM or swapping since
 332   # we may end up with a lot of JVM's
 333   $1_JTREG_MAX_RAM_FRACTION := $$(shell $$(EXPR) $$($1_JTREG_JOBS) \* 4)
 334 
 335   JTREG_TIMEOUT ?= 4
 336   JTREG_VERBOSE ?= fail,error,summary
 337   JTREG_RETAIN ?= fail,error
 338 
 339   ifneq ($$($1_JTREG_MAX_MEM), 0)
 340     $1_JTREG_BASIC_OPTIONS += -vmoption:-Xmx$$($1_JTREG_MAX_MEM)
 341     $1_JTREG_LAUNCHER_OPTIONS += -Xmx$$($1_JTREG_MAX_MEM)
 342   endif
 343 
 344   $1_JTREG_BASIC_OPTIONS += -$$($1_JTREG_TEST_MODE) \
 345       -verbose:$$(JTREG_VERBOSE) -retain:$$(JTREG_RETAIN) \
 346       -concurrency:$$($1_JTREG_JOBS) -timeoutFactor:$$(JTREG_TIMEOUT) \
 347       -vmoption:-XX:MaxRAMFraction=$$($1_JTREG_MAX_RAM_FRACTION)
 348 
 349   $1_JTREG_BASIC_OPTIONS += -automatic -keywords:\!ignore -ignore:quiet
 350 
 351   # Some tests needs to find a boot JDK using the JDK8_HOME variable.
 352   $1_JTREG_BASIC_OPTIONS += -e:JDK8_HOME=$$(BOOT_JDK)
 353 
 354   $1_JTREG_BASIC_OPTIONS += \
 355       $$(addprefix -javaoption:, $$(JTREG_JAVA_OPTIONS)) \
 356       $$(addprefix -vmoption:, $$(JTREG_VM_OPTIONS)) \
 357       #
 358 
 359   ifeq ($$($1_JTREG_ASSERT), true)
 360     $1_JTREG_BASIC_OPTIONS += -ea -esa
 361   endif
 362 
 363   ifneq ($$($1_JTREG_NATIVEPATH), )
 364     $1_JTREG_BASIC_OPTIONS += -nativepath:$$($1_JTREG_NATIVEPATH)
 365   endif
 366 
 367   ifneq ($$(JIB_JAR), )
 368     $1_JTREG_BASIC_OPTIONS += -cpa:$$(JIB_JAR)
 369   endif
 370 
 371   run-test-$1:
 372         $$(call LogWarn)
 373         $$(call LogWarn, Running test '$$($1_TEST)')
 374         $$(call MakeDir, $$($1_TEST_RESULTS_DIR) $$($1_TEST_SUPPORT_DIR))
 375         $$(call ExecuteWithLog, $$($1_TEST_SUPPORT_DIR)/jtreg, \
 376             $$(JAVA) $$($1_JTREG_LAUNCHER_OPTIONS) \
 377                 -Dprogram=jtreg -jar $$(JT_HOME)/lib/jtreg.jar \
 378                 $$($1_JTREG_BASIC_OPTIONS) \
 379                 -testjdk:$$(JDK_IMAGE_DIR) \
 380                 -dir:$$(TOPDIR) \
 381                 -reportDir:$$($1_TEST_RESULTS_DIR) \
 382                 -workDir:$$($1_TEST_SUPPORT_DIR) \
 383                 $$(JTREG_OPTIONS) \
 384                 $$($1_TEST_NAME) || true )
 385 
 386   $1_RESULT_FILE := $$($1_TEST_RESULTS_DIR)/text/stats.txt
 387 
 388   parse-test-$1: run-test-$1
 389         $$(call LogWarn, Finished running test '$$($1_TEST)')
 390         $$(call LogWarn, Test report is stored in $$(strip \
 391             $$(subst $$(TOPDIR)/, , $$($1_TEST_RESULTS_DIR))))
 392         $$(eval $1_PASSED := $$(shell $$(AWK) '{ gsub(/[,;]/, ""); \
 393             for (i=1; i<=NF; i++) { if ($$$$i == "passed:") \
 394             print $$$$(i+1) } }' $$($1_RESULT_FILE)))
 395         $$(if $$($1_PASSED), , $$(eval $1_PASSED := 0))
 396         $$(eval $1_FAILED := $$(shell $$(AWK) '{gsub(/[,;]/, ""); \
 397             for (i=1; i<=NF; i++) { if ($$$$i == "failed:") \
 398             print $$$$(i+1) } }' $$($1_RESULT_FILE)))
 399         $$(if $$($1_FAILED), , $$(eval $1_FAILED := 0))
 400         $$(eval $1_ERROR := $$(shell $$(AWK) '{gsub(/[,;]/, ""); \
 401             for (i=1; i<=NF; i++) { if ($$$$i == "error:") \
 402             print $$$$(i+1) } }' $$($1_RESULT_FILE)))
 403         $$(if $$($1_ERROR), , $$(eval $1_ERROR := 0))
 404         $$(eval $1_TOTAL := $$(shell \
 405             $$(EXPR) $$($1_PASSED) + $$($1_FAILED) + $$($1_ERROR)))
 406 
 407   $1: run-test-$1 parse-test-$1
 408 
 409   TARGETS += $1
 410 endef
 411 
 412 
 413 ################################################################################
 414 # Setup and execute make rules for all selected tests
 415 ################################################################################
 416 
 417 # Helper function to determine which handler to use for the given test
 418 UseGtestTestHandler = \
 419   $(if $(filter gtest:%, $1), true)
 420 
 421 UseJtregTestHandler = \
 422   $(if $(filter jtreg:%, $1), true)
 423 
 424 # Now process each test to run and setup a proper make rule
 425 $(foreach test, $(TESTS_TO_RUN), \
 426   $(eval TEST_ID := $(shell $(ECHO) $(strip $(test)) | \
 427       $(TR) -cs '[a-z][A-Z][0-9]\n' '_')) \
 428   $(eval ALL_TEST_IDS += $(TEST_ID)) \
 429   $(if $(call UseCustomTestHandler, $(test)), \
 430     $(eval $(call SetupRunCustomTest, $(TEST_ID), \
 431         TEST := $(test), \
 432     )) \
 433   ) \
 434   $(if $(call UseGtestTestHandler, $(test)), \
 435     $(eval $(call SetupRunGtestTest, $(TEST_ID), \
 436         TEST := $(test), \
 437     )) \
 438   ) \
 439   $(if $(call UseJtregTestHandler, $(test)), \
 440     $(eval $(call SetupRunJtregTest, $(TEST_ID), \
 441         TEST := $(test), \
 442     )) \
 443   ) \
 444 )
 445 
 446 # Sort also removes duplicates, so if there is any we'll get fewer words.
 447 ifneq ($(words $(ALL_TEST_IDS)), $(words $(sort $(ALL_TEST_IDS))))
 448   $(error Duplicate test specification)
 449 endif
 450 
 451 
 452 ################################################################################
 453 # The main target for RunTests.gmk
 454 ################################################################################
 455 
 456 # The SetupRun*Test functions have populated TARGETS.
 457 
 458 TEST_FAILURE := false
 459 
 460 run-test: $(TARGETS)
 461         # Print a table of the result of all tests run and their result
 462         $(ECHO)
 463         $(ECHO) ==============================
 464         $(ECHO) Test summary
 465         $(ECHO) ==============================
 466         $(PRINTF) "%2s %-49s %5s %5s %5s %5s %2s\n" "  " TEST \
 467             TOTAL PASS FAIL ERROR " "
 468         $(foreach test, $(TESTS_TO_RUN), \
 469           $(eval TEST_ID := $(shell $(ECHO) $(strip $(test)) | \
 470               $(TR) -cs '[a-z][A-Z][0-9]\n' '_')) \
 471           $(if $(filter $($(TEST_ID)_PASSED), $($(TEST_ID)_TOTAL)), \
 472             $(PRINTF) "%2s %-49s %5d %5d %5d %5d %2s\n" "  " "$(test)" \
 473                 $($(TEST_ID)_TOTAL) $($(TEST_ID)_PASSED) $($(TEST_ID)_FAILED) \
 474                 $($(TEST_ID)_ERROR) "  " $(NEWLINE) \
 475           , \
 476             $(PRINTF) "%2s %-49s %5d %5d %5d %5d %2s\n" ">>" "$(test)" \
 477                 $($(TEST_ID)_TOTAL) $($(TEST_ID)_PASSED) $($(TEST_ID)_FAILED) \
 478                 $($(TEST_ID)_ERROR) "<<" $(NEWLINE) \
 479             $(eval TEST_FAILURE := true) \
 480           ) \
 481         )
 482         $(ECHO) ==============================
 483         $(if $(filter true, $(TEST_FAILURE)), \
 484           $(ECHO) TEST FAILURE $(NEWLINE) \
 485           $(TOUCH) $(MAKESUPPORT_OUTPUTDIR)/exit-with-error \
 486         , \
 487           $(ECHO) TEST SUCCESS \
 488         )
 489         $(ECHO)
 490 
 491 ################################################################################
 492 
 493 all: run-test
 494 
 495 .PHONY: default all run-test $(TARGETS)