diff --git a/.gitignore b/.gitignore new file mode 100755 index 0000000000..df55881466 --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +# java .class files +*.class + +# misc auto generated folders +bin +test_output_* + +# misc auto generated files +autoGenTest.mk +TestConfig/jvmTest.mk +TestConfig/specToPlat.mk +TestConfig/*.log +TestConfig/tempTestTargetResult +TestConfig/failedtargets.mk +.DS_Store diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000000..ae61b5e802 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,40 @@ +#!groovy +pipeline { + agent any + environment { + JAVA_BIN='$WORKSPACE/openjdkbinary/j2sdk-image/jre/bin' + JCL_VERSION='current' + OPENJDK_TEST='$WORKSPACE/openjdk-test' + JAVA_VERSION='SE80' + SPEC='linux_x86-64_cmprssptrs' + } + stages { + stage('Setup') { + steps { + sh 'chmod 755 $OPENJDK_TEST/maketest.sh' + sh 'chmod 755 $OPENJDK_TEST/get.sh' + sh '$OPENJDK_TEST/get.sh $WORKSPACE $OPENJDK_TEST' + } + } + stage('BuildAndRun') { + steps { + echo 'Building and running tests...' + sh 'printenv' + sh '$OPENJDK_TEST/maketest.sh $OPENJDK_TEST' + } + } + stage('Deploy') { + steps { + echo 'Deploying....' + step([$class: "TapPublisher", testResults: "**/*.tap"]) + archiveArtifacts artifacts: '**/*.tap', fingerprint: true + } + } + } + post { + always { + deleteDir() + } + } + +} diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000..8f71f43fee --- /dev/null +++ b/LICENSE @@ -0,0 +1,202 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + 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 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/NOTICE b/NOTICE new file mode 100644 index 0000000000..8cab3205f9 --- /dev/null +++ b/NOTICE @@ -0,0 +1,2 @@ +Portions of this software are +(C) Copyright IBM Corporation 2017 diff --git a/OpenJDK_Playlist/build.xml b/OpenJDK_Playlist/build.xml new file mode 100644 index 0000000000..41eb02ff76 --- /dev/null +++ b/OpenJDK_Playlist/build.xml @@ -0,0 +1,26 @@ + + + + + stage openjdk test make files + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenJDK_Playlist/playlist.xml b/OpenJDK_Playlist/playlist.xml new file mode 100644 index 0000000000..a8764e14e3 --- /dev/null +++ b/OpenJDK_Playlist/playlist.xml @@ -0,0 +1,33 @@ + + + + + OpenJDK_stackWalker + $(JAVA_COMMAND) $(CMPRSSPTRS) -Xmx512m -jar $(Q)$(JTREG_DIR)$(D)lib$(D)jtreg.jar$(Q) \ + -agentvm -a -ea -esa -v:fail,error,time -retain:fail,error -ignore:quiet -timeoutFactor:4 -vmoptions:$(Q)-Xmx512m $(JVM_OPTIONS)$(Q) \ + -w $(Q)$(TEST_RESROOT)$(D)work$(Q) \ + -r $(Q)$(TEST_RESROOT)$(D)report$(Q) \ + -jdk:$(Q)$(JDK_HOME)$(Q) \ + -exclude:$(Q)$(JTREG_TEST_DIR)$(D)ProblemList.txt$(Q) \ + $(Q)$(JTREG_TEST_DIR)$(D)java$(D)lang$(D)StackWalker$(Q); \ + $(TEST_STATUS) + + SE90 + + + openjdk + + + \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000000..f1a45665be --- /dev/null +++ b/README.md @@ -0,0 +1,147 @@ +# User Stories for AdoptOpenJDK Tests +0. Configure environment: + * required environment variables and default values + + cd /test/TestConfig + export JAVA_BIN=/location_of_JVM_under_test + export SPEC=platform_on_which_to_test + export JAVA_VERSION=[SE80|SE90] (SE90 default value) + make -f run_configure.mk + +1. Add tests: + * for Java8/Java9 functionality + + Check out /test/TestExample for the format to use. + We prefer to write Java unit and FV tests with TestNG. We + leverage TestNG groups to create test make targets. + + This means that minimally your test source code should + belong to either level.sanity or level.extended group. + * for a Java9 only features + +2. Compile tests: + * compile and run all tests + + make test + * only compile but do not run tests + + make compile + +3. Run tests: + * all tests + + make test (to compile & run) + make runtest (to run all tests without recompiling them) + * sanity tests + + make sanity + * openjdk regression tests + + make openjdk + This target will run all or a subset of the OpenJDK regression tests, + you can add or subtract directories of tests by changing the contents of the + OpenJDK_Playlist/playlist.xml file + * extended tests + + make extended + * a specific individual test + + make _testExampleExtended_SE80_0 + * a directory of tests (WIP) + * against a Java8 SDK + + Same general instructions for Configure environment, and make test, but export JAVA_VERSION=SE80 + explicitly before run_configuration.mk step. + * against a Java9 SDK + + No special steps to accomplish this, as JAVA_VERSION=SE90 by default, so simply need to Configure environment + and run make test. + + * rerun the failed tests from the last run + + make failed + * with a different set of JVM options + + There are 3 ways to add options to your test run. + 1) One-time override: If you simply want to add an option for a one-time run, + you can override the original options by using JVM_OPTIONS="your options". + 2) One-time append: If you want to append options to the set that are already there, + use EXTRA_OPTIONS="your extra options". For example, + make _testExampleExtended_SE80_0 EXTRA_OPTIONS=-Xint + will append to those options already in the make target. + 3) New options for future test runs: If you wish to add a particular set + of options for a tests to be included in future builds, you can add a variant in + the playlist.xml file for that test. +4. Exclude tests: + * temporarily on all platforms + + Add a line in the /test/TestConfig/default_exclude.txt file. + The format of the exclude file includes 3 pieces of information, name of test, defect number, platforms to exclude. + To exclude on all platforms, use generic-all. For example: + + net.adoptopenjdk.test.example.MyTest:aTestExample 141 generic-all + + Note that we additionally added support to exclude individual methods of a test class, by using + :methodName behind the class name. In the example, only the aTestExample method from that class will + be excluded (on all platforms/specs). + * temporarily on specific platforms or architectures + + Same as excluding on all platforms, you add a line to the default_exclude.txt file, but with specific + specs to exclude, for example: + + net.adoptopenjdk.test.example.MyTest: 141 linux_x86-64 + + This example would exclude all test methods of the TestOperatingSystemMXBean from running + on the linux_x86-64 platform. Note: the defect numbers should be valid git issue numbers, + so that when issue is resolved this exclusion can be removed. + * permanently on all or specific platforms/archs + + For tests that should NEVER run on particular platforms or architectures, we should not use + the default_exclude.txt file. To disable those tests, we annotate the test class to be disabled. + To exclude MyTest from running on the aix platform, for example: + + @Test(groups={ "level.sanity", "component.jit", "disabled.os.aix" }) + public class MyTest { + ... + + We currently support the following exclusion groups: + disabled.os. (i.e. disabled.os.aix) + disabled.arch. (i.e. disabled.arch.ppc) + disabled.bits. (i.e. disabled.bits.64) + disabled.spec. (i.e. disabled.spec.linux_x86-64) +5. View results: + * in the console + + Java tests take advantage of the testNG logger. If you want your test to print output, + you are required to use the testng logger (and not System.out.print statements). + In this way, we can not only direct that output to console, but also to various other output clients. + At the end of a test run, the results are summarized to show which tests passed / failed / skipped. + This gives you a quick view of the test names and numbers in each category (passed/failed/skipped). + If you've piped the output to a file, or if you like scrolling up, you can search for and find + the specific output of the tests that failed (exceptions or any other logging that the test produces). + * in html files + + Html (and xml) output from the tests are created and stored in a test_output_xxxtimestamp + folder in the TestConfig directory (or from where you ran "make test"). The output is + organized by tests, each test having its own set of output. If you open the index.html + file in a web browser, you will be able to see which tests passed, failed or were skipped, + along with other information like execution time and error messages, exceptions + and logs from the individual test methods. + * Jenkins CI tool + + + The summarized results are also captured in *.tap files so that they can be viewed in Jenkins + using the TAP (Test Anything Protocol) plugin. +6. Attach a debugger: + * to a particular test + + The command line that is run for each particular test is echo-ed to the console, so you can easily + copy the command that is run. You can then run the command directly (which is a direct call to the + java executable, adding any additional options, including those to attach a debugger. +7. Move test into different make targets (layers): + * from extended to sanity (or vice versa) + + Change the group annotated at the top of the test class from "level.extended" to + "level.sanity" and the test will be automatically switched from the extended target + to the sanity target. + diff --git a/TestConfig/makefile b/TestConfig/makefile new file mode 100755 index 0000000000..08a80e6f17 --- /dev/null +++ b/TestConfig/makefile @@ -0,0 +1,268 @@ +# 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 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# +# Makefile to run various JVM tests +# + +$(info Running make $(MAKE_VERSION)) + +.PHONY: test clean compile help runtest rmResultFile resultsSummary + +.DEFAULT_GOAL := test + +help: + @echo "This makefile is used to build and execute JVM tests. You should specify the following" + @echo "variables before using this script:" + @echo "JAVA_BIN Path to java bin dir which will be used to built and executed JVM tests" + @echo "SPEC Should match the current platform (e.g. SPEC=linux_x86-64, SPEC=linux_x86, SPEC=linux_x86-64_cmprssptrs)" + +CD = cd +ECHO = echo +MKDIR = mkdir +PWD = pwd + +ifndef JAVA_BIN +$(error Please provide JAVA_BIN value.) +else +export JAVA_BIN:=$(JAVA_BIN) +$(info set JAVA_BIN to $(JAVA_BIN)) +endif + +ifndef SPEC +$(error Please provide SPEC that matches the current platform (e.g. SPEC=linux_x86-64)) +else +export SPEC:=$(SPEC) +$(info set SPEC to $(SPEC)) +endif + +ifndef JAVA_VERSION +export JAVA_VERSION:=SE90 +else +export JAVA_VERSION:=$(JAVA_VERSION) +endif +$(info set JAVA_VERSION to $(JAVA_VERSION)) + +Q=" +D=/ + +ifneq (,$(findstring win,$(SPEC))) +P=; +else +P=: +endif + +ifndef SRC_ROOT +SRC_ROOT := $(shell $(PWD))$(D).. +SRC_ROOT := $(subst \,/,$(SRC_ROOT)) +endif +$(info set SRC_ROOT to $(SRC_ROOT)) + +ifndef BUILD_ROOT +BUILD_ROOT := $(SRC_ROOT)$(D)..$(D)jvmtest +BUILD_ROOT := $(subst \,/,$(BUILD_ROOT)) +endif +$(info set BUILD_ROOT to $(BUILD_ROOT)) + +# set default values +JVM_TEST_ROOT := $(SRC_ROOT) +TEST_GROUP=level.* + +# removing " +JAVA_BIN_TMP := $(subst ",,$(JAVA_BIN)) +JDK_HOME := $(JAVA_BIN_TMP)$(D).. +ifeq ($(JAVA_VERSION),SE80) +JDK_HOME := $(JAVA_BIN_TMP)$(D)..$(D).. +endif + +ifdef JTREG_DIR +# removing " +JTREG_DIR := $(subst ",,$(JTREG_DIR)) +endif + +ifdef JTREG_TEST_DIR +# removing " +JTREG_TEST_DIR := $(subst ",,$(JTREG_TEST_DIR)) +endif + +####################################### +# Set OS, ARCH and BITS based on SPEC +####################################### +WORD_LIST:= $(subst _, ,$(SPEC)) +OS:=os.$(word 1,$(WORD_LIST)) +ARCH_INFO:=$(word 2,$(WORD_LIST)) + +BITS=bits.32 +ARCH=arch.$(ARCH_INFO) +ifneq (,$(findstring -64,$(ARCH_INFO))) + BITS=bits.64 + ARCH:=arch.$(subst -64,,$(ARCH_INFO)) +else + ifneq (,$(findstring 390,$(ARCH_INFO))) + BITS=bits.31 + endif +endif + +ifneq ($(DEBUG),) +$(info OS is set to $(OS), ARCH is set to $(ARCH) and BITS is set to $(BITS)) +endif + +DEFAULT_EXCLUDE=d.*.$(SPEC),d.*.$(ARCH),d.*.$(OS),d.*.$(BITS),d.*.generic-all +ifneq ($(DEBUG),) +$(info DEFAULT_EXCLUDE is set to $(DEFAULT_EXCLUDE)) +endif + +JAVA_COMMAND:=$(Q)$(JAVA_BIN_TMP)$(D)java$(Q) + +####################################### +# Setting AIX specific Macro ADD_JVM_LIB_DIR_ON_AIX, AIX need LIBPATH containing VM directory +####################################### +ifneq (,$(findstring aix,$(SPEC))) + JAVA_LIB_DIR:=$(JAVA_BIN)$(D)..$(D)lib + ifneq (,$(findstring cmprssptrs,$(SPEC))) + ADD_JVM_LIB_DIR_ON_AIX=export LIBPATH=$(Q)$(JAVA_LIB_DIR)$(D)ppc64$(D)compressedrefs$(P)$(LIBPATH)$(Q); + else + ifneq (,$(findstring 64,$(SPEC))) + ADD_JVM_LIB_DIR_ON_AIX=export LIBPATH=$(Q)$(JAVA_LIB_DIR)$(D)ppc64$(D)default$(P)$(LIBPATH)$(Q); + else + ADD_JVM_LIB_DIR_ON_AIX=export LIBPATH=$(Q)$(JAVA_LIB_DIR)$(D)ppc$(D)default$(P)$(LIBPATH)$(Q); + endif + endif +endif + +ifneq ($(DEBUG),) +$(info ADD_JVM_LIB_DIR_ON_AIX is set to $(ADD_JVM_LIB_DIR_ON_AIX)) +endif + +####################################### +# common dir and jars +####################################### +LIB_DIR=$(JVM_TEST_ROOT)$(D)TestConfig$(D)lib +TESTNG=$(LIB_DIR)$(D)TestNG$(D)testng.jar$(P)$(LIB_DIR)$(D)TestNG$(D)jcommander.jar +JUNIT=$(LIB_DIR)$(D)junit-4.10.jar +RESOURCES_DIR=$(JVM_TEST_ROOT)$(D)TestConfig$(D)resources + +####################################### +# cmdlinetester jars +####################################### +CMDLINETESTER_JAR =$(Q)$(JVM_TEST_ROOT)$(D)cmdline_options_tester$(D)$(JAVA_VERSION)$(D)cmdlinetester.jar$(Q) +CMDLINETESTER_RESJAR=$(Q)$(JVM_TEST_ROOT)$(D)cmdline_options_testresources$(D)$(JAVA_VERSION)$(D)cmdlinetestresources.jar$(Q) + +####################################### +# testng report dir +####################################### +TIMESTAMP := $(shell perl $(JVM_TEST_ROOT)$(D)TestConfig$(D)scripts$(D)testKitGen$(D)resultsSummary$(D)getTimeStamp.pl -v) +TESTOUTPUT = $(shell $(PWD))$(D)test_output_$(TIMESTAMP) +REPORTDIR = $(Q)$(TESTOUTPUT)$(D)$@$(Q) + +####################################### +# TEST_STATUS +####################################### +TEST_STATUS=if [ $$? -eq 0 ] ; then $(ECHO) $(Q)$@$(Q)$(Q)_PASSED$(Q); else $(ECHO) $(Q)$@$(Q)$(Q)_FAILED$(Q); fi | tee -a TestTargetResult +ifneq ($(DEBUG),) +$(info TEST_STATUS is $(TEST_STATUS)) +endif +TEST_SKIP_STATUS=@$(ECHO) $@_SKIPPED | tee -a TestTargetResult + +####################################### +# include sub makefile +####################################### +-include $(JVM_TEST_ROOT)$(D)TestConfig$(D)extraSettings +include $(JVM_TEST_ROOT)$(D)TestConfig$(D)specToPlat.mk +include $(JVM_TEST_ROOT)$(D)TestConfig$(D)jvmTest.mk +include $(JVM_TEST_ROOT)$(D)autoGenTest.mk + +####################################### +# generic target +####################################### +_TESTTARGET = $(firstword $(MAKECMDGOALS)) +TESTTARGET = $(patsubst _%,%,$(_TESTTARGET)) +ifneq ($(DEBUG),) +$(info _TESTTARGET is $(_TESTTARGET)) +$(info TESTTARGET is $(TESTTARGET)) +endif + +.PHONY: _$(TESTTARGET) $(TESTTARGET) +$(TESTTARGET): JVM_TEST_ROOT := $(BUILD_ROOT) +_$(TESTTARGET): setup_$(TESTTARGET) $(TESTTARGET) + @$(ECHO) $@ done + +setup_%: + @$(ECHO) + @$(ECHO) Running test _$(TESTTARGET) + $(JAVA_COMMAND) -version + +####################################### +# test_dir target +####################################### +TEST_DIRTARGET = $(firstword $(MAKECMDGOALS)) +DIRTARGET = $(patsubst test_%,%,$(_TESTTARGET)) +ifneq ($(DEBUG),) +$(info _TESTTARGET is $(_TESTTARGET)) +$(info TESTTARGET is $(TESTTARGET)) +endif + +.PHONY: test_$(DIRTARGET) +$(DIRTARGET): JVM_TEST_ROOT := $(BUILD_ROOT) +test_$(DIRTARGET): rmResultFile $(DIRTARGET)_$(JAVA_VERSION) resultsSummary + +test: compile runtest + @$(ECHO) "All Tests Completed" + +ifndef JCL_VERSION +export JCL_VERSION:=latest +else +export JCL_VERSION:=$(JCL_VERSION) +endif +$(info set JAVA_VERSION to $(JAVA_VERSION)) +# compile all tests under $(SRC_ROOT) +compile: + ant -f $(SRC_ROOT)$(D)TestConfig$(D)scripts$(D)build_test.xml -DSRC_ROOT=$(SRC_ROOT) -DBUILD_ROOT=$(BUILD_ROOT) -DJAVA_BIN=$(JAVA_BIN) -DJAVA_VERSION=$(JAVA_VERSION) -DJCL_VERSION=$(JCL_VERSION) + +####################################### +# failed target +####################################### +FAILEDTAGETS = $(shell $(PWD))$(D)failedtargets.mk + +-include $(FAILEDTAGETS) + +####################################### +# result Summary +####################################### +TEMPRESULTFILE=TestTargetResult +TAPRESULTFILE=TestTargetResult.tap + +rmResultFile: + $(RM) $(Q)$(TEMPRESULTFILE)$(Q) + +resultsSummary: + @perl $(JVM_TEST_ROOT)$(D)TestConfig$(D)scripts$(D)testKitGen$(D)resultsSummary$(D)resultsSum.pl --failuremk=$(Q)$(FAILEDTAGETS)$(Q) --resultFile=$(Q)$(TEMPRESULTFILE)$(Q) --tapFile=$(Q)$(TAPRESULTFILE)$(Q) + +sanity: JVM_TEST_ROOT := $(BUILD_ROOT) +sanity: rmResultFile sanity_$(JAVA_VERSION) resultsSummary + +extended: JVM_TEST_ROOT := $(BUILD_ROOT) +extended: rmResultFile extended_$(JAVA_VERSION) resultsSummary + +openjdk: JVM_TEST_ROOT := $(BUILD_ROOT) +openjdk: rmResultFile openjdk_$(JAVA_VERSION) resultsSummary + +runtest: rmResultFile sanity_$(JAVA_VERSION) extended_$(JAVA_VERSION) openjdk_$(JAVA_VERSION) resultsSummary +.NOTPARALLEL: extended sanity openjdk runtest rmResultFile resultsSummary + +# cleanup +clean: + $(RM) -r $(BUILD_ROOT) + $(RM) -r $(SRC_ROOT)$(D)TestConfig$(D)test_output_* + $(RM) $(TEMPRESULTFILE) + $(RM) $(TAPRESULTFILE) + $(RM) $(FAILEDTAGETS) \ No newline at end of file diff --git a/TestConfig/playlist.xsd b/TestConfig/playlist.xsd new file mode 100644 index 0000000000..551c70d848 --- /dev/null +++ b/TestConfig/playlist.xsd @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/TestConfig/resources/excludes/default_exclude.txt b/TestConfig/resources/excludes/default_exclude.txt new file mode 100644 index 0000000000..6466ad3038 --- /dev/null +++ b/TestConfig/resources/excludes/default_exclude.txt @@ -0,0 +1,4 @@ +# Exclude tests temporarily + +#testClass[:testMethod] defectNumber platform +net.adoptopenjdk.test.example.ImportantTest:aSanityExample 00000 linux_x86-64_cmprssptrs \ No newline at end of file diff --git a/TestConfig/resources/log4testng.properties b/TestConfig/resources/log4testng.properties new file mode 100644 index 0000000000..d92c54aa4d --- /dev/null +++ b/TestConfig/resources/log4testng.properties @@ -0,0 +1,13 @@ +# Log log4testng's own behavior +log4testng.debug=false + +# All Logger in packages below org.testng will log WARN level and above +log4testng.logger.org.testng=WARN + +# Log INFO level and above, available levels are TRACE, DEBUG, INFO, WARN, ERROR and FATAL. +log4testng.rootLogger=INFO + +# The org.testng.reporters.EmailableReporter Logger will log TRACE level and above +# Currently we don't have tests using this logger. +log4testng.logger.org.testng.reporters.EmailableReporter=TRACE + diff --git a/TestConfig/run_configure.mk b/TestConfig/run_configure.mk new file mode 100644 index 0000000000..5dfc9dda79 --- /dev/null +++ b/TestConfig/run_configure.mk @@ -0,0 +1,43 @@ +# 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 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +.PHONY: autogen clean help + +.DEFAULT_GOAL := autogen + +help: + @echo "This makefile is used to run perl script which generates makefiles for JVM tests before being built and executed." + @echo "OPTS=help Display help information for more options." + +CURRENT_DIR := $(shell pwd) +OPTS= + +D=/ + +ifneq (,$(findstring Win,$(OS))) +CURRENT_DIR := $(subst \,/,$(CURRENT_DIR)) +endif + +autogen: + cd $(CURRENT_DIR)$(D)scripts$(D)testKitGen; \ + perl testKitGen.pl $(OPTS); \ + cd $(CURRENT_DIR); + +AUTOGEN_FILES = $(wildcard $(CURRENT_DIR)$(D)jvmTest.mk) +AUTOGEN_FILES += $(wildcard $(CURRENT_DIR)$(D)..$(D)*$(D)autoGenTest.mk) + +clean: +ifneq (,$(findstring .mk,$(AUTOGEN_FILES))) + $(RM) $(AUTOGEN_FILES); +else + @echo "Nothing to clean"; +endif \ No newline at end of file diff --git a/TestConfig/scripts/build_test.xml b/TestConfig/scripts/build_test.xml new file mode 100755 index 0000000000..9c2373ebb8 --- /dev/null +++ b/TestConfig/scripts/build_test.xml @@ -0,0 +1,117 @@ + + + + + Compile Java Test Projects + + + + + + + + JAVA_BIN is ${JAVA_BIN} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${JAVA_VERSION} ${JAVA_BIN} is missing + + + + + + + + + + + + + + set JAVA_BIN=${JAVA_BIN} + + + + + + + \ No newline at end of file diff --git a/TestConfig/scripts/testKitGen/makeGenTool/mkgen.pl b/TestConfig/scripts/testKitGen/makeGenTool/mkgen.pl new file mode 100755 index 0000000000..88ccb51921 --- /dev/null +++ b/TestConfig/scripts/testKitGen/makeGenTool/mkgen.pl @@ -0,0 +1,547 @@ +# 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 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +use strict; +use warnings; +use Data::Dumper; +use feature 'say'; + +my @allGroups = ( "sanity", "extended", "promotion", "openjdk" ); + +my $headerComments = + "########################################################\n" + . "# This is an auto generated file. Please do NOT modify!\n" + . "########################################################\n" + . "\n"; + +my $mkName = "autoGenTest.mk"; +my $projectRootDir = ''; +my $JCL_VERSION = ''; +my $allSubsets = ''; +my $output = ''; +my $graphSpecs = ''; +my $modes_hs = ''; +my $sp_hs = ''; +my %tests = (); + +sub runmkgen { + $projectRootDir = $_[0]; + $allSubsets = $_[1]; + $output = $_[2]; + $graphSpecs = $_[3]; + my $modesxml = $_[4]; + my $ottawacsv = $_[5]; + my $includeModesService = 1; + + if ( exists $ENV{'JCL_VERSION'} ) { + $JCL_VERSION = $ENV{'JCL_VERSION'}; + } else { + $JCL_VERSION = "latest"; + } + print "JCL_VERSION is $JCL_VERSION\n"; + + eval qq{require "modesService.pl"; 1;} or $includeModesService = 0; + my $serviceResponse; + if ($includeModesService) { + $serviceResponse = eval { + $modes_hs = getDataFromService('http://testmgmt.stage1.mybluemix.net/modesDictionaryService/getAllModes', "mode"); + $sp_hs = getDataFromService('http://testmgmt.stage1.mybluemix.net/modesDictionaryService/getSpecPlatMapping', 'spec'); + }; + } + + if (!(($serviceResponse) && (%{$modes_hs}) && (%{$sp_hs}))) { + print "Warning: Cannot get data from modes service! Getting data from modes.xml and ottawa.csv...\n"; + require "parseFiles.pl"; + my $data = getFileData($modesxml, $ottawacsv); + $modes_hs = $data->{'modes'}; + $sp_hs = $data->{'specPlatMapping'}; + } + + generateOnDir(); + + my $specToPlatmk = $projectRootDir . "/TestConfig/specToPlat.mk"; + my $jvmTestmk = $projectRootDir . "/TestConfig/jvmTest.mk"; + if ($output) { + my $outputdir = $output . '/TestConfig'; + make_path($outputdir); + $specToPlatmk = $outputdir . "/specToPlat.mk"; + $jvmTestmk = $outputdir . "/jvmTest.mk"; + } + + specToPlatGen( $specToPlatmk, $graphSpecs ); + print "\nGenerated $specToPlatmk!\n"; + + jvmTestGen( $jvmTestmk, \%tests, $allSubsets ); + print "Generated $jvmTestmk!\n"; + return \%tests; +} + +sub generateOnDir { + my @currentdirs = @_; + my $absolutedir = $projectRootDir; + if (@currentdirs) { + $absolutedir .= '/' . join('/', @currentdirs); + } + my $playlistXML; + my @subdirsHavePlaylist = (); + opendir( my $dir, $absolutedir ); + while ( my $entry = readdir $dir ) { + next if $entry eq '.' or $entry eq '..'; + # temporarily exclude projects for CCM build (i.e., when JCL_VERSION is latest) + my $disabledDir = "cmdline_options_tester cmdline_options_testresources cmdLineTests JLM_Tests Jsr292 Jsr335"; + if (($JCL_VERSION ne "latest") or ($disabledDir !~ $entry )) { + my $projectDir = $absolutedir . '/' . $entry; + if (( -f $projectDir ) && ( $entry eq 'playlist.xml' )) { + $playlistXML = $projectDir; + } elsif (-d $projectDir) { + push (@currentdirs, $entry); + if (generateOnDir(@currentdirs) == 1) { + push (@subdirsHavePlaylist, $entry); + } + pop @currentdirs; + } + } + } + closedir $dir; + + if ($playlistXML) { + print "\nGenerating make file based on $playlistXML...\n"; + generate($playlistXML, $absolutedir, \@currentdirs, \@subdirsHavePlaylist); + return 1; + } elsif (@subdirsHavePlaylist) { + print "\nGenerating make file based on subdirs...\n"; + my $makeFile = $absolutedir . "/" . $mkName; + subdir2make($makeFile, \@currentdirs, \@subdirsHavePlaylist, $allSubsets); + return 1; + } + + return 0; +} + +sub generate { + my ($playlistXML, $absolutedir, $currentdirs, $subdirsHavePlaylist) = @_; + + my $projectName = $currentdirs->[-1]; + my $makeFile = $absolutedir . "/" . $mkName; + + if ($output) { + my $outputdir = $output . '/' . join('/', @{$currentdirs}); + make_path($outputdir); + $makeFile = $outputdir . "/" . $mkName; + } + + my $project = xml2make( $playlistXML, $makeFile, $currentdirs, $subdirsHavePlaylist ); + + $tests{$projectName} = $project; +} + +sub xml2make { + my ( $playlistXML, $makeFile, $currentdirs, $subdirsHavePlaylist ) + = @_; + my $tests = parseXML($playlistXML); + my $testgroups = + genMK( $makeFile, $tests, $currentdirs, $subdirsHavePlaylist ); + return $testgroups; +} + +sub parseXML { + my ($playlistXML) = @_; + open( my $fhIn, '<', $playlistXML ) or die "Cannot open file $_[0]!"; + my @tests = (); + while ( my $line = <$fhIn> ) { + my %test; + my $testlines; + if ( $line =~ /\/ ) { + $testlines .= $line; + while ( my $testline = <$fhIn> ) { + $testlines .= $testline; + if ( $testline =~ /\<\/test\>/ ) { + last; + } + } + + $test{'testCaseName'} = + getElementByTag( $testlines, 'testCaseName' ); + $test{'command'} = getElementByTag( $testlines, 'command' ); + $test{'platformRequirements'} = + getElementByTag( $testlines, 'platformRequirements' ); + + my $variations = getElementByTag( $testlines, 'variations' ); + my $variation = getElementsByTag( $testlines, 'variation' ); + if ( !@{$variation} ) { + $variation = ['']; + } + $test{'variation'} = $variation; + + my $tags = getElementByTag( $testlines, 'tags' ); + my $tag = getElementsByTag( $testlines, 'tag' ); + foreach my $eachtag ( @{$tag} ) { + if ( grep(/^$eachtag$/, @allGroups) ) { + $test{'group'} = $eachtag; + last; + } + } + # defaults to 'sanity' + if (!defined $test{'group'}) { + $test{'group'} = 'sanity'; + } + + my $subset = getElementsByTag( $testlines, 'subset' ); + foreach my $eachsubset ( @{$subset} ) { + if ( grep(/^$eachsubset$/, @{$allSubsets}) ) { + push (@{$test{'subsets'}}, $eachsubset) + } else { + die "Error: unrecognized subset " . $eachsubset . " defined for test " . $test{'testCaseName'} . "."; + } + } + # defaults to all subsets + if (!defined $test{'subsets'}) { + $test{'subsets'} = $allSubsets; + } + + push( @tests, \%test ); + } + } + close $fhIn; + return \@tests; +} + +sub getElementByTag { + my ($element) = $_[0] =~ /\<$_[1]\>(.*)\<\/$_[1]\>/s; + return $element; +} + +sub getElementsByTag { + my (@elements) = $_[0] =~ /\<$_[1]\>(.*?)\<\/$_[1]\>/sg; + return \@elements; +} + +sub genMK { + my ( $makeFile, $tests, $currentdirs, $subdirsHavePlaylist ) = @_; + open( my $fhOut, '>', $makeFile ) or die "Cannot create make file $makeFile!"; + my %project = (); + print $fhOut $headerComments; + + my %testgroups = (); + foreach my $test ( @{ $tests } ) { + my $count = 0; + my $group = $test->{'group'}; + foreach my $var ( @{ $test->{'variation'} } ) { + my $jvmoptions = ' ' . $var . ' '; + $jvmoptions =~ s/\ NoOptions\ //x; + + my %invalidSpecs_hs = (); + + while ( my ($mode) = $jvmoptions =~ /\ Mode(.*?)\ /x ) { + $mode = lc $mode; + my $vardoc = $modes_hs->{$mode}; + + my $clArg_arr = $vardoc->{'clArg'}; + if ( !$clArg_arr ) { + die "Error: Cannot find mode $mode in database!"; + } + + my $clArgs = join(' ', @{$clArg_arr}); + $clArgs =~ s/\ $//x; + $jvmoptions =~ s/Mode$mode/$clArgs/; + + my $invalidSpecs_arr = $vardoc->{'invalidSpecs'}; + foreach my $invalidSpec ( @{$invalidSpecs_arr} ) { + $invalidSpecs_hs{$invalidSpec} = 1; + } + } + $jvmoptions =~ s/^\s+|\s+$//g; + + my $invalidSpecs = ''; + foreach my $invalidSpec ( sort keys %invalidSpecs_hs ) { + $invalidSpecs .= $invalidSpec . ' '; + } + + $invalidSpecs =~ s/^\s+|\s+$//g; + + my @allInvalidSpecs = getAllInvalidSpecs( $invalidSpecs, + $test->{'platformRequirements'}, $graphSpecs ); + + foreach my $subset (@{$test->{'subsets'}}) { + + # generate make target + my $name = $test->{'testCaseName'}; + # append subset in the test name when the test has more than one subset + if (scalar(@{$test->{'subsets'}}) > 1) { + $name .= "_$subset"; + } + $name .= "_$count"; + + my $condition = undef; + if (@allInvalidSpecs) { + my $string = join( ' ', @allInvalidSpecs ); + $condition = "$name\_INVALID_PLATFORM_CHECK"; + print $fhOut "$condition=\$(filter $string, \$(SPEC))\n"; + } + + my $jvmtestroot = "\$(JVM_TEST_ROOT)\$(D)" . join("\$(D)", @{$currentdirs}) . "\$(D)$subset"; + print $fhOut "$name: TEST_RESROOT=$jvmtestroot\n"; + + if ($jvmoptions) { + print $fhOut "$name: JVM_OPTIONS=\$(CMPRSSPTRS) $jvmoptions \$(EXTRA_OPTIONS)\n"; + } else { + print $fhOut "$name: JVM_OPTIONS=\$(CMPRSSPTRS) \$(EXTRA_OPTIONS)\n"; + } + + print $fhOut "$name: TEST_GROUP=level.$group\n"; + + my $indent .= "\t"; + print $fhOut "$name:\n"; + print $fhOut "$indent\@echo \"\";\n"; + print $fhOut "$indent\@echo \"===============================================\";\n"; + print $fhOut "$indent\@echo \"Running test \$\@ ...\";\n"; + print $fhOut "$indent\@echo \"===============================================\";\n"; + if ($condition) { + print $fhOut "ifeq (\$($condition),)\n"; + } + + if ($jvmoptions) { + print $fhOut "$indent\@echo \"test with $var\";\n"; + } + else { + print $fhOut "$indent\@echo \"test with NoOptions\";\n"; + } + my $command = $test->{'command'}; + print $fhOut "$indent$command\n"; + if ($condition) { + print $fhOut "else\n"; + print $fhOut "$indent\$(TEST_SKIP_STATUS)\n"; + print $fhOut "endif\n"; + } + print $fhOut "\n"; + + my %testElement = (); + $testElement{"name"} = $name; + $testElement{"invalidSpecs"} = \@allInvalidSpecs; + + #push test name to subset group + push(@{$testgroups{$group}{$subset}}, \%testElement); + } + $count++; + } + } + + my $dirtarget = join('.', @{$currentdirs}); + foreach my $subdir (sort @{$subdirsHavePlaylist}) { + my $currdirstr = join("\$(D)", @{$currentdirs}); + if ($currdirstr) { + $currdirstr .= "\$(D)"; + } + print $fhOut "include \$(JVM_TEST_ROOT)\$(D)" . $currdirstr . "$subdir\$(D)autoGenTest.mk\n"; + } + + foreach my $eachsubset (sort @{$allSubsets}) { + my $isempty = 1; + my $dirtarget_subset = $dirtarget . "_" . $eachsubset; + print $fhOut "\n.PHONY: $dirtarget_subset\n\n"; + print $fhOut "$dirtarget_subset: "; + foreach my $subdir (sort @{$subdirsHavePlaylist}) { + print $fhOut "\\\n" . $dirtarget . "." . $subdir . "_" . $eachsubset . " "; + $isempty = 0; + } + foreach my $eachgroup (sort keys %testgroups) { + if ($testgroups{$eachgroup}{$eachsubset}) { + foreach my $eachtestelement (sort {$a->{"name"} cmp $b->{"name"}} @{$testgroups{$eachgroup}{$eachsubset}}) { + print $fhOut "\\\n$eachtestelement->{\"name\"} "; + $isempty = 0; + } + } + } + if ($isempty == 1) { + print $fhOut ";"; + } + + print $fhOut "\n"; + } + + $project{'testgroups'} = \%testgroups; + + close $fhOut; + print "Generated $makeFile!\n"; + + return \%project; +} + +# return an array of invalid specs +sub getAllInvalidSpecs { + my @invalidSpecPerMode = (); + my @platformRequirements = (); + my @specs = (); + my @invalidSpecs = (); + if ( defined $_[0] ) { + @invalidSpecPerMode = split( ' ', $_[0] ); + } + if ( defined $_[1] ) { + @platformRequirements = split( /,/, $_[1] ); + } + if ( defined $_[2] ) { + @specs = split( ',', $_[2] ); + } + + foreach my $pr (@platformRequirements) { + $pr =~ s/^\s+|\s+$//g; + my ( $key, $value ) = split( /\./, $pr ); + + # copy @specs into @specArray + my @specArray = @specs; + foreach my $i ( 0 .. $#specArray ) { + if ( $specArray[$i] ) { + my $tmpVal = $specArray[$i]; + + # special case, specs with 32 or 31 bits do not have 32 or 31 in the name (i.e. aix_ppc) + if ( $tmpVal !~ /-64/ ) { + if ( $tmpVal =~ /390/ ) { + $tmpVal = $specArray[$i] . "-31"; + } + else { + $tmpVal = $specArray[$i] . "-32"; + } + } + + if ( $key =~ /^\^/ ) { + if ( $tmpVal =~ /$value/ ) { + push @invalidSpecs, $specArray[$i]; + + # remove the element from @specs + my $index = 0; + $index++ until $specs[$index] eq $specArray[$i]; + splice( @specs, $index, 1 ); + } + } + else { + if ( $tmpVal !~ /$value/ ) { + push @invalidSpecs, $specArray[$i]; + + # remove the element from @specs + my $index = 0; + $index++ until $specs[$index] eq $specArray[$i]; + splice( @specs, $index, 1 ); + } + } + } + } + + # reset @specsArray + @specArray = @specs; + } + + # find intersection of runable specs and invalid specs + my %specs = map { $_ => 1 } @specs; + my @intersect = grep { $specs{$_} } @invalidSpecPerMode; + push( @invalidSpecs, @intersect ); + return @invalidSpecs; +} + +sub specToPlatGen { + my ( $specToPlatmk ) = @_; + open( my $fhOut, '>', $specToPlatmk ) or die "Cannot create file $specToPlatmk!"; + print $fhOut $headerComments; + + print $fhOut "PLATFORM=\n"; + my $spec2platform = ''; + my @graphSpecs_arr = split( ',', $graphSpecs ); + foreach my $graphSpec (@graphSpecs_arr) { + if ( defined $sp_hs->{$graphSpec} ) { + $spec2platform .= "ifeq" . " (\$(SPEC),$graphSpec)\n\tPLATFORM=" . $sp_hs->{$graphSpec}->{"platform"} . "\nendif\n\n"; + } else { + print "\nWarning: cannot find spec $graphSpec in ModesDictionaryService or ottawa.csv file!\n"; + } + } + print $fhOut $spec2platform; +} + +sub jvmTestGen { + my ( $jvmTestmk, $tests ) = @_; + my %container = (); + + open( my $fhOut, '>', $jvmTestmk ) or die "Cannot create file $jvmTestmk!"; + print $fhOut $headerComments; + + foreach my $projectName (sort keys %{$tests}) { + my $testGroups = $tests->{$projectName}->{'testgroups'}; + foreach my $group (@allGroups) { + if ( $testGroups->{$group} ) { + my %subgroups = %{$testGroups->{$group}}; + foreach my $subset ( sort keys %subgroups ) { + if (defined $subgroups{$subset}) { + splice @{$container{$group}{$subset}}, 0, 0, @{$subgroups{$subset}}; + } + } + } + } + } + + foreach my $group ( sort keys %container ) { + foreach my $testsubset ( @{$allSubsets} ) { + my $targetName = $group . "_" . $testsubset; + print $fhOut $targetName . ":"; + my $testElement = $container{$group}{$testsubset}; + if (defined $testElement) { + foreach my $value ( sort {$a->{"name"} cmp $b->{"name"}} @{$testElement} ) { + print $fhOut " \\\n" . $value->{"name"}; + } + } else { + print $fhOut " ;"; + } + print $fhOut "\n\n"; + } + } + + close $fhOut; +} + +sub subdir2make { + my ($makeFile, $currentdirs, $subdirsHavePlaylist) = @_; + open( my $fhOut, '>', $makeFile ) or die "Cannot create make file $makeFile!"; + my $mkname = basename($makeFile); + my %project = (); + print $fhOut $headerComments; + + foreach my $subdir (sort @{$subdirsHavePlaylist}) { + my $currdirstr = join("\$(D)", @{$currentdirs}); + if ($currdirstr) { + $currdirstr .= "\$(D)"; + } + print $fhOut "include \$(JVM_TEST_ROOT)\$(D)" . $currdirstr . "$subdir\$(D)$mkname\n"; + } + + print $fhOut "\n"; + + my $dirtarget = 'alltargets'; + if (@{$currentdirs}) { + $dirtarget = join('.', @{$currentdirs}); + } + + foreach my $eachsubset (sort @{$allSubsets}) { + my $dirtarget_subset = $dirtarget . "_" . $eachsubset; + print $fhOut "\n.PHONY: $dirtarget_subset\n\n"; + print $fhOut "$dirtarget_subset: "; + foreach my $subdir (sort @{$subdirsHavePlaylist}) { + if ($dirtarget eq 'alltargets') { + print $fhOut "\\\n" . $subdir . "_" . $eachsubset . " "; + } else { + print $fhOut "\\\n" . $dirtarget . "." . $subdir . "_" . $eachsubset . " "; + } + } + print $fhOut "\n"; + } + + close $fhOut; + print "Generated $makeFile!\n"; +} + +1; diff --git a/TestConfig/scripts/testKitGen/makeGenTool/modesService.pl b/TestConfig/scripts/testKitGen/makeGenTool/modesService.pl new file mode 100755 index 0000000000..f1fbc6b157 --- /dev/null +++ b/TestConfig/scripts/testKitGen/makeGenTool/modesService.pl @@ -0,0 +1,32 @@ +# 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 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +use strict; +use warnings; +use JSON; + +sub getDataFromService { + my %vars; + my ($url, $key) = @_; + my $curl='curl --silent --max-time 120 ' . $url; + my $jsonData = qx{$curl}; + if ($? != 0) { + print "Failed to execute curl with error code: $?.\n"; + } + my $data = from_json($jsonData); + foreach my $element (@{$data}) { + $vars{ $element->{$key} } = $element; + } + return \%vars; +} + +1; \ No newline at end of file diff --git a/TestConfig/scripts/testKitGen/makeGenTool/parseFiles.pl b/TestConfig/scripts/testKitGen/makeGenTool/parseFiles.pl new file mode 100644 index 0000000000..076b577814 --- /dev/null +++ b/TestConfig/scripts/testKitGen/makeGenTool/parseFiles.pl @@ -0,0 +1,158 @@ +# 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 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +use strict; +use warnings; +use Data::Dumper; +use feature 'say'; +use Text::CSV; + +# specs that are specified in this array will be ignored. +# That is, all modes will not run on these specs even if these specs exist. +# This array should be mainly used for specs that we do not care any more +# but still exist in ottawa.csv (i.e., Linux PPC BE). +my @ignoredSpecs = + qw(linux_x86-32_hrt linux_x86-64_cmprssptrs_gcnext linux_ppc_purec linux_ppc-64_purec linux_ppc-64_cmprssptrs_purec linux_x86-64_cmprssptrs_cloud); + +sub getFileData { + my ( $modesxml, $ottawacsv ) = @_; + my $modes = parseModesXML($modesxml); + my $data = parseOttawaCSV($ottawacsv, $modes); + return $data; +} + +sub parseOttawaCSV { + my ( $file, $modes ) = @_; + my %results = (); + my %specPlatMapping = (); + my @specs = (); + my @capabilities = (); + my $lineNum = 0; + my $fhIn; + + if (!open( $fhIn, '<', $file )) { + say "Cannot open ottawa.csv. You can provide the file with option --ottawaCsv=."; + return; + } + my $csv = Text::CSV->new( { sep_char => ',' } ); + while ( my $line = <$fhIn> ) { + if ( $csv->parse($line) ) { + my @fields = $csv->fields(); + + # Since the spec line has an empty title, we cannot do string match. We assume the second line is spec. + if ( $lineNum++ == 1 ) { + push( @specs, @fields ); + } + elsif ( $fields[0] =~ /^plat$/ ) { + foreach my $i ( 1 .. $#fields ) { + my %spm = (); + $spm{'spec'} = $specs[$i]; + $spm{'platform'} = $fields[$i]; + $specPlatMapping{ $spm{'spec'} } = \%spm; + } + } + elsif ( $fields[0] =~ /^capabilities$/ ) { + push( @capabilities, @fields ); + } + elsif ( $fields[0] =~ /^variation:(.*)/ ) { + my $modeNum = $1; + + # remove string Mode if it exists + $modeNum =~ s/^Mode//; + foreach my $mode (keys %{$modes}) { + if ( $mode =~ /^$modeNum$/ ) { + my @invalidSpecs = (); + foreach my $j ( 1 .. $#fields ) { + if ( $fields[$j] =~ /^no$/ ) { + push( @invalidSpecs, $specs[$j] ); + } + } + + # remove @ignoredSpecs from @invalidSpecs array + my %ignoredSpecs = map +( $_ => 1 ), + @ignoredSpecs; + @invalidSpecs = grep !$ignoredSpecs{$_}, + @invalidSpecs; + + # if @invalidSpecs array is empty, set it to none + # Otherwise, set $modes[$i]{'invalidSpecs'} = @invalidSpecs + if (!@invalidSpecs) { + push( @invalidSpecs, "none" ); + } + #update invalidSpecs values + $modes->{$mode}{'invalidSpecs'} = \@invalidSpecs; + last; + } + } + } + } + else { + warn "Line could not be parsed: $line\n"; + } + } + close $fhIn; + $results{'modes'} = $modes; + $results{'specPlatMapping'} = \%specPlatMapping; + return \%results; +} + +sub parseModesXML { + my %modes = (); + my $file = $_[0]; + my $fhIn; + if (!open( $fhIn, '<', $file )) { + say "Cannot open modes.xml. You can provide the file with option --modeXml=."; + return; + } + while ( my $line = <$fhIn> ) { + + # matching line + if ( $line =~ /(mode)\W*number.*"(.+?)"/ ) { + my %mode = (); + $mode{$1} = $2; + + my @keys = ( "description", "clArg" ); + my @args = (); + + # read next line in the file + while ( my $nextLine = <$fhIn> ) { + foreach my $i ( 0 .. $#keys ) { + if ( $nextLine =~ /($keys[$i])>(.+?)(<\/$keys[$i])/ ) { + my $value = $2; + + # clArg line - -Xgcpolicy:optthruput + if ( $keys[$i] =~ /$keys[1]/ ) { + push( @args, $value ); + } + else { + $mode{ $keys[$i] } = $value; + } + $mode{'invalidSpecs'} = undef; + } + } + if ( $nextLine =~ /<\/mode/ ) { + + # add args array into mode hash + $mode{ $keys[1] } = \@args; + + # break out the loop + last; + } + } + + # add mode into modes hash + $modes{ $mode{'mode'} } = \%mode; + } + } + close $fhIn; + return \%modes; +} diff --git a/TestConfig/scripts/testKitGen/resultsSummary/getTimeStamp.pl b/TestConfig/scripts/testKitGen/resultsSummary/getTimeStamp.pl new file mode 100644 index 0000000000..736521e73f --- /dev/null +++ b/TestConfig/scripts/testKitGen/resultsSummary/getTimeStamp.pl @@ -0,0 +1,17 @@ +# 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 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +use strict; +use warnings; + +my $epoc = time(); +print "$epoc"; \ No newline at end of file diff --git a/TestConfig/scripts/testKitGen/resultsSummary/resultsSum.pl b/TestConfig/scripts/testKitGen/resultsSummary/resultsSum.pl new file mode 100644 index 0000000000..ef7fd8e116 --- /dev/null +++ b/TestConfig/scripts/testKitGen/resultsSummary/resultsSum.pl @@ -0,0 +1,141 @@ +# 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 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +use strict; +use warnings; + +my $resultFile; +my $failuremkarg; +my $tapFile; + +for (my $i = 0; $i < scalar(@ARGV); $i++) { + my $arg = $ARGV[$i]; + if ($arg =~ /^\-\-failuremk=/) { + ($failuremkarg) = $arg =~ /^\-\-failuremk=(.*)/; + } elsif ($arg =~ /^\-\-resultFile=/) { + ($resultFile) = $arg =~ /^\-\-resultFile=(.*)/; + } elsif ($arg =~ /^\-\-tapFile=/) { + ($tapFile) = $arg =~ /^\-\-tapFile=(.*)/; + } +} + +if (!$failuremkarg) { + die "Please specify a vaild file path using --failuremk= option!"; +} + +my $failures = resultReporter(); +failureMkGen($failuremkarg, $failures); + +sub resultReporter { + my $numOfFailed = 0; + my $numOfPassed = 0; + my $numOfSkipped = 0; + my $numOfTotal = 0; + my @passed; + my @failed; + my @skipped; + my $tapString = ''; + + open(my $fhIn, '<', $resultFile) or die "Cannot open file $resultFile!"; + + print "\n\n"; + + while ( my $result = <$fhIn> ) { + $result =~ s/\R//; + if ($result =~ /_PASSED$/) { + $result =~ s/_PASSED$//; + push (@passed, $result); + $numOfPassed++; + $numOfTotal++; + $tapString .= "ok " . $numOfTotal . " - " . $result . "\n"; + } elsif ($result =~ /_FAILED$/) { + $result =~ s/_FAILED$//; + push (@failed, $result); + $numOfFailed++; + $numOfTotal++; + $tapString .= "not ok " . $numOfTotal . " - " . $result . "\n"; + } elsif ($result =~ /_SKIPPED$/) { + $result =~ s/_SKIPPED$//; + push (@skipped, $result); + $numOfSkipped++; + $numOfTotal++; + $tapString .= "ok " . $numOfTotal . " - " . $result . " # skip\n"; + } else { + print("Warning: detect non test result input!\n"); + } + } + + #generate tap output + if ($tapFile) { + open(my $fhOut, '>', $tapFile) or die "Cannot open file $tapFile!"; + print $fhOut "1.." . $numOfTotal . "\n"; + print $fhOut $tapString; + close $fhOut; + } + + #generate console output + print "TEST TARGETS SUMMARY\n"; + print "+++++++++++++++++++++++++++++++++++++++++++++++\n"; + print "TOTAL: $numOfTotal PASS: $numOfPassed FAIL: $numOfFailed SKIP: $numOfSkipped\n"; + + if ($numOfPassed != 0) { + printTests(\@passed, "PASSED"); + } + + if ($numOfFailed == 0) { + print "\n"; + print "ALL TESTS PASSED\n"; + } else { + printTests(\@failed, "FAILED"); + } + + if ($numOfSkipped != 0) { + printTests(\@skipped, "SKIPPED"); + } + + print "+++++++++++++++++++++++++++++++++++++++++++++++\n"; + + close $fhIn; + + unlink($resultFile); + + return \@failed; +} + +sub printTests() { + my ($tests, $tag) = @_; + print "\n"; + print "$tag test targets:\n\t"; + print join("\n\t", @{$tests}); + print "\n"; +} + +sub failureMkGen { + my $failureMkFile = $_[0]; + my $failureTargets = $_[1]; + if (@$failureTargets) { + open( my $fhOut, '>', $failureMkFile ) or die "Cannot create make file $failureMkFile!"; + my $headerComments = + "########################################################\n" + . "# This is an auto generated file. Please do NOT modify!\n" + . "########################################################\n" + . "\n"; + print $fhOut $headerComments; + print $fhOut "failed:"; + print $fhOut " \\\nrmResultFile"; + foreach my $target (@$failureTargets) { + print $fhOut " \\\n" . $target; + } + print $fhOut " \\\nresultsSummary"; + close $fhOut; + } +} \ No newline at end of file diff --git a/TestConfig/scripts/testKitGen/testKitGen.pl b/TestConfig/scripts/testKitGen/testKitGen.pl new file mode 100644 index 0000000000..6672e2fd87 --- /dev/null +++ b/TestConfig/scripts/testKitGen/testKitGen.pl @@ -0,0 +1,85 @@ +# 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 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +use Cwd; +use strict; +use warnings; +use lib "./makeGenTool"; +require "mkgen.pl"; +use File::Basename; +use File::Path qw/make_path/; +use Data::Dumper; +use feature 'say'; + +my $all = 0; +my $projectRootDir = ''; +my $modesxml = "../../resources/modes.xml"; +my $ottawacsv = "../../resources/ottawa.csv"; +my $graphSpecs = ''; +my $output = ''; +my @allSubsets = ( "SE80", "SE90" ); + +foreach my $argv (@ARGV) { + if ( $argv =~ /^\-\-graphSpecs=/ ) { + ($graphSpecs) = $argv =~ /^\-\-graphSpecs=(.*)/; + } + elsif ( $argv =~ /^\-\-projectRootDir=/ ) { + ($projectRootDir) = $argv =~ /^\-\-projectRootDir=(.*)/; + } + elsif ( $argv =~ /^\-\-output=/ ) { + ($output) = $argv =~ /^\-\-output=(.*)/; + } + elsif ( $argv =~ /^\-\-modesXml=/) { + ($modesxml) = $argv =~ /^\-\-modesXml=(.*)/; + } + elsif ( $argv =~ /^\-\-ottawaCsv=/) { + ($ottawacsv) = $argv =~ /^\-\-ottawaCsv=(.*)/; + } + else { + print +"This program will search projectRootDir provided and find/parse playlist.xml to generate \n" + . "makefile (per project)\n" + . "jvmTest.mk and specToPlat.mk - under TestConfig\n"; + print "Options:\n" + . "--graphSpecs= Comma separated specs that the build will run on.\n" + . "--output= Path to output makefiles.\n" + . "--projectRootDir= Root path for searching playlist.xml.\n" + . "--modesXml= Path to modes.xml file.\n" + . " If the modesXml is not provided, the program will try to find modes.xml under projectRootDir/TestConfig/resources.\n" + . "--ottawaCsv= Path to ottawa.csv file.\n" + . " If the ottawaCsv is not provided, the program will try to find ottawa.csv under projectRootDir/TEST_Playlists/playlistgen.\n"; + die "Please specify valid options!"; + } +} + +if ( !$projectRootDir ) { + $projectRootDir = getcwd . "/../../.."; + if ( -e $projectRootDir ) { + print +"projectRootDir is not provided. Set projectRootDir = $projectRootDir\n"; + } + else { + die +"Please specify a valid project directory using option \"--projectRootDir=\"."; + } +} + +if ( !$graphSpecs ) { + $graphSpecs = + "aix_ppc,aix_ppc-64,aix_ppc-64_purec,aix_ppc_purec,linux_390,linux_390-64,linux_390-64_cs,linux_390-64_purec,linux_390_purec,linux_arm,linux_ppc-64_le,linux_ppc-64_le_purec,linux_x86,linux_x86-64,linux_x86-64_purec,linux_x86_purec,win_x86,win_x86-64,win_x86-64_purec,win_x86_purec,zos_390,zos_390-64,zos_390-64_purec,zos_390_purec"; + print "graphSpecs is not provided. Set graphSpecs = $graphSpecs\n"; +} + +# run make file generator +my $tests = runmkgen( $projectRootDir, \@allSubsets, $output, $graphSpecs, $modesxml, $ottawacsv ); + +print "\nTEST AUTO GEN SUCCESSFUL\n"; \ No newline at end of file diff --git a/TestExample/.gitignore b/TestExample/.gitignore new file mode 100644 index 0000000000..6d194bea00 --- /dev/null +++ b/TestExample/.gitignore @@ -0,0 +1,4 @@ +*.class + +/bin/ +/test-output/ \ No newline at end of file diff --git a/TestExample/.settings/org.eclipse.jdt.core.prefs b/TestExample/.settings/org.eclipse.jdt.core.prefs new file mode 100755 index 0000000000..d6fc284148 --- /dev/null +++ b/TestExample/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,100 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled +org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore +org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull +org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault +org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable +org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.autoboxing=warning +org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning +org.eclipse.jdt.core.compiler.problem.deadCode=warning +org.eclipse.jdt.core.compiler.problem.deprecation=warning +org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled +org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled +org.eclipse.jdt.core.compiler.problem.discouragedReference=error +org.eclipse.jdt.core.compiler.problem.emptyStatement=warning +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore +org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning +org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled +org.eclipse.jdt.core.compiler.problem.fieldHiding=warning +org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning +org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning +org.eclipse.jdt.core.compiler.problem.forbiddenReference=error +org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning +org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled +org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning +org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning +org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning +org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning +org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning +org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore +org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning +org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled +org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=warning +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning +org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=warning +org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning +org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning +org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning +org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error +org.eclipse.jdt.core.compiler.problem.nullReference=warning +org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error +org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning +org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning +org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore +org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning +org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning +org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore +org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning +org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning +org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning +org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore +org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=warning +org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore +org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore +org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning +org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled +org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=warning +org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning +org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning +org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore +org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning +org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled +org.eclipse.jdt.core.compiler.problem.unusedImport=warning +org.eclipse.jdt.core.compiler.problem.unusedLabel=warning +org.eclipse.jdt.core.compiler.problem.unusedLocal=warning +org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameter=warning +org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning +org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning +org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/TestExample/build.xml b/TestExample/build.xml new file mode 100755 index 0000000000..69d777a867 --- /dev/null +++ b/TestExample/build.xml @@ -0,0 +1,60 @@ + + + + + Test Example + + + + + + + + + + + + + + + + + + Ant version is ${ant.version} + ============COMPILER SETTINGS============ + ===fork: yes + ===executable: ${compiler.javac} + ===debug: on + ===destdir: ${dist} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TestExample/playlist.xml b/TestExample/playlist.xml new file mode 100644 index 0000000000..73a32d8887 --- /dev/null +++ b/TestExample/playlist.xml @@ -0,0 +1,56 @@ + + + + + SanityTestExample + + -Xint + + $(JAVA_COMMAND) $(JVM_OPTIONS) \ + -cp $(Q)$(RESOURCES_DIR)$(P)$(TESTNG)$(P)$(TEST_RESROOT)$(D)TestExample.jar$(Q) \ + org.testng.TestNG -d $(REPORTDIR) $(Q)$(TEST_RESROOT)$(D)testng.xml$(Q) -testnames exampleTest \ + -groups $(TEST_GROUP) \ + -excludegroups $(DEFAULT_EXCLUDE); \ + $(TEST_STATUS) + os.linux,arch.x86,bits.64 + + sanity + + + SE80 + SE90 + + + + ExtendedTestExample + + -Xint + + $(JAVA_COMMAND) $(JVM_OPTIONS) \ + -cp $(Q)$(RESOURCES_DIR)$(P)$(TESTNG)$(P)$(TEST_RESROOT)$(D)TestExample.jar$(Q) \ + org.testng.TestNG -d $(REPORTDIR) $(Q)$(TEST_RESROOT)$(D)testng.xml$(Q) -testnames exampleTest \ + -groups $(TEST_GROUP) \ + -excludegroups $(DEFAULT_EXCLUDE); \ + $(TEST_STATUS) + os.linux,arch.x86,bits.64 + + extended + + + SE80 + SE90 + + + \ No newline at end of file diff --git a/TestExample/src/net/adoptopenjdk/test/example/ImportantTest.java b/TestExample/src/net/adoptopenjdk/test/example/ImportantTest.java new file mode 100644 index 0000000000..e6a7a90e34 --- /dev/null +++ b/TestExample/src/net/adoptopenjdk/test/example/ImportantTest.java @@ -0,0 +1,31 @@ +/******************************************************************************* +* 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 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +package net.adoptopenjdk.test.example; + +import org.testng.AssertJUnit; +import org.testng.annotations.Test; +import org.testng.log4testng.Logger; + +@Test(groups={ "level.sanity" }) +public class ImportantTest { + + private static Logger logger = Logger.getLogger(ImportantTest.class); + @Test + public void aSanityExample() { + logger.info("running aSanityExample: CS should pass all sanity tests."); + AssertJUnit.assertEquals(4, 2+2); + } +} + diff --git a/TestExample/src/net/adoptopenjdk/test/example/SimpleTest.java b/TestExample/src/net/adoptopenjdk/test/example/SimpleTest.java new file mode 100644 index 0000000000..dbd933d7bb --- /dev/null +++ b/TestExample/src/net/adoptopenjdk/test/example/SimpleTest.java @@ -0,0 +1,30 @@ +/******************************************************************************* +* 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 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +package net.adoptopenjdk.test.example; + +import org.testng.AssertJUnit; +import org.testng.annotations.Test; +import org.testng.log4testng.Logger; + +@Test(groups={ "level.extended" }) +public class SimpleTest { + + private static Logger logger = Logger.getLogger(SimpleTest.class); + @Test + public void aExtendedExample() { + logger.info("running aExtendedExample: INFO and above level logging enabled"); + AssertJUnit.assertEquals(4, 2+2); + } +} diff --git a/TestExample/testng.xml b/TestExample/testng.xml new file mode 100755 index 0000000000..fa10921e8e --- /dev/null +++ b/TestExample/testng.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + diff --git a/Utils/src/net/adoptopenjdk/test/util/ExcludeData.java b/Utils/src/net/adoptopenjdk/test/util/ExcludeData.java new file mode 100644 index 0000000000..9fcb0503a8 --- /dev/null +++ b/Utils/src/net/adoptopenjdk/test/util/ExcludeData.java @@ -0,0 +1,42 @@ +/******************************************************************************* +* 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 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +package net.adoptopenjdk.test.util; + +import java.util.ArrayList; + +public class ExcludeData { + private String methodsToExclude; + private String className; + private String defectNumber; + private ArrayList excludeGroupNames; + + public ExcludeData(String methodsToExclude, String className, String defectNumber, ArrayList excludeGroupNames) { + this.methodsToExclude = methodsToExclude; + this.className = className; + this.defectNumber = defectNumber; + this.excludeGroupNames = new ArrayList (excludeGroupNames); + } + + public String getMethodsToExclude() { return methodsToExclude;} + public String getClassName() { return className;} + public String getDefectNumber() { return defectNumber;} + public ArrayList getExcludeGroupNames() { return excludeGroupNames;} + + public void setMethodsToExclude(String methodsToExclude) { this.methodsToExclude = methodsToExclude; } + public void setClassName(String className) { this.className = className; } + public void setDefectNumber(String defectNumber) { this.defectNumber = defectNumber; } + public void setMethodsToExclude(ArrayList excludeGroupNames) {this.excludeGroupNames = excludeGroupNames; } + +} \ No newline at end of file diff --git a/Utils/src/net/adoptopenjdk/test/util/IncludeExcludeTestAnnotationTransformer.java b/Utils/src/net/adoptopenjdk/test/util/IncludeExcludeTestAnnotationTransformer.java new file mode 100644 index 0000000000..062e075aa4 --- /dev/null +++ b/Utils/src/net/adoptopenjdk/test/util/IncludeExcludeTestAnnotationTransformer.java @@ -0,0 +1,123 @@ +/******************************************************************************* +* 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 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +package net.adoptopenjdk.test.util; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; + +import org.testng.IAnnotationTransformer; +import org.testng.annotations.ITestAnnotation; +import org.testng.log4testng.Logger; + +public class IncludeExcludeTestAnnotationTransformer implements IAnnotationTransformer { + static private ArrayList excludeDatas = new ArrayList(); + private static final Logger logger = Logger.getLogger(IncludeExcludeTestAnnotationTransformer.class); + static { + String line = null; + String excludeFile = System.getenv("EXCLUDE_FILE"); + if (null == excludeFile) { + excludeFile = IncludeExcludeTestAnnotationTransformer.class.getClassLoader().getResource("excludes/default_exclude.txt").getFile(); + } + logger.info("exclude file is " + excludeFile); + try { + FileReader fileReader = new FileReader(excludeFile); + BufferedReader bufferedReader = new BufferedReader(fileReader); + while ((line = bufferedReader.readLine()) != null) { + if (line.startsWith("#") || line.matches("\\s") || line.isEmpty()) { + // comment to ignore - as the problems list from OpenJDK + } else { + // parse the line and populate the array lists + String[] lineParts = line.split("\\s+"); + // expect to exclude all methods with the name that follows : at the start of a line + if (-1 != line.indexOf("*")) { + // TODO exclude all Test classes under the package? + } else { + String[] tests = lineParts[0].split(":"); + String fileName = tests[0]; + String methodsToExclude = ""; + if (tests.length > 1) { + methodsToExclude = tests[1]; + } else { //exclude class level + methodsToExclude = "ALL"; + } + String defectNumber = lineParts[1]; + String[] excludeGroups = lineParts[2].split(";"); + for (int i = 0; i < excludeGroups.length; i++) { + excludeGroups[i] = "disabled." + excludeGroups[i]; + } + ArrayList excludeGroupNames = new ArrayList (Arrays.asList(excludeGroups)); + excludeDatas.add(new ExcludeData(methodsToExclude, fileName, defectNumber, excludeGroupNames)); + } + } + } + bufferedReader.close(); + } catch(FileNotFoundException ex) { + logger.info("Unable to open file " + excludeFile); + } catch(IOException ex) { + logger.info("Error reading file " + excludeFile); + } + } + + @Override + public void transform(ITestAnnotation annotation, Class testClass, Constructor testConstructor, Method testMethod) { + // if testClass is not null, check if exclude file indicates disabling entire file, then change annotation of the test class + if (null != testClass) { + for (ExcludeData excludeData : excludeDatas) { + if (excludeData.getMethodsToExclude().equals("ALL") && + testClass.getName().equals(excludeData.getClassName())) { + logger.debug("Disabled test class name is " + testClass.getName()); + String[] intialGroup = annotation.getGroups(); + ArrayList groups = new ArrayList (Arrays.asList(annotation.getGroups())); + groups.addAll(excludeData.getExcludeGroupNames()); + annotation.setGroups(groups.toArray(new String[0])); + } + } + } + + /* if testMethod is not null, check: + * 1. if exclude file indicates disabling entire file ( as there in no rules if testClass or testMethod is not Null, + * have to check again) + * 2. if exclude file indicate disable specific method + */ + if (null != testMethod) { + String testMethodClass = testMethod.getDeclaringClass().getName(); + for (ExcludeData excludeData : excludeDatas) { + if (excludeData.getMethodsToExclude().equals("ALL") && + testMethodClass.equals(excludeData.getClassName())) { + String[] intialGroup = annotation.getGroups(); + ArrayList groups = new ArrayList (Arrays.asList(annotation.getGroups())); + groups.addAll(excludeData.getExcludeGroupNames()); + annotation.setGroups(groups.toArray(new String[0])); + logger.debug("Disabled test method is " + testMethod.getName()); + } else if (testMethodClass.equals(excludeData.getClassName()) && + testMethod.getName().equals(excludeData.getMethodsToExclude())) { + String[] intialGroup = annotation.getGroups(); + ArrayList groups = new ArrayList (Arrays.asList(annotation.getGroups())); + groups.addAll(excludeData.getExcludeGroupNames()); + annotation.setGroups(groups.toArray(new String[0])); + String[] testGroups = annotation.getGroups(); + logger.info("disable method is " + testMethod.getName() + "diabled annotation " + Arrays.toString(testGroups)); + } + } + } + } +} diff --git a/get.sh b/get.sh new file mode 100644 index 0000000000..ff51835b16 --- /dev/null +++ b/get.sh @@ -0,0 +1,42 @@ +#!/bin/bash +# +# 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 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +echo 'Get binary openjdk...' +cd $1 +mkdir openjdkbinary +cd openjdkbinary +download_url=`curl https://api.github.com/repos/AdoptOpenJDK/openjdk-releases/releases/latest | jq -r '.assets[] | select(.browser_download_url | contains("x64_Linux_jdk")) | {url: .browser_download_url} | select (.url | contains("tar.gz")) | .[]'` +wget "${download_url}" +#wget https://github.com/AdoptOpenJDK/openjdk-releases/releases/download/jdk8u152-b01/OpenJDK8_x64_Linux_jdk8u152-b01.tar.gz +jar_file_url=$download_url +jar_file_name=${jar_file_url##*/} +tar -zxvf $jar_file_name +#tar -zxvf OpenJDK8_x64_Linux_jdk8u152-b01.tar.gz + +cd $2/TestConfig +mkdir lib +cd lib +echo 'Get third party libs...' +wget http://download.forge.ow2.org/asm/asm-5.0.1.jar +wget https://downloads.sourceforge.net/project/junit/junit/4.10/junit-4.10.jar +mv asm-5.0.1.jar asm-all-5.0.1.jar + +mkdir TestNG +cd TestNG +wget http://central.maven.org/maven2/org/testng/testng/6.10/testng-6.10.jar +wget http://central.maven.org/maven2/com/beust/jcommander/1.48/jcommander-1.48.jar +mv testng-6.10.jar testng.jar +mv jcommander-1.48.jar jcommander.jar + + diff --git a/maketest.sh b/maketest.sh new file mode 100644 index 0000000000..01d2ccee48 --- /dev/null +++ b/maketest.sh @@ -0,0 +1,16 @@ +#!/bin/bash +# 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 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +cd $1/TestConfig +make -f run_configure.mk +make test