提交 776937ce 编写于 作者: R robm

Merge

......@@ -2,19 +2,41 @@
# Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
# The Universal Permissive License (UPL), Version 1.0
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
# Subject to the condition set forth below, permission is hereby granted to
# any person obtaining a copy of this software, associated documentation
# and/or data (collectively the "Software"), free of charge and under any
# and all copyright rights in the Software, and any and all patent rights
# owned or freely licensable by each licensor hereunder covering either (i)
# the unmodified Software as contributed to or provided by such licensor,
# or (ii) the Larger Works (as defined below), to deal in both
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
# (a) the Software, and
#
# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file
# if one is included with the Software (each a “Larger Work” to which the
# Software is contributed by such licensors),
#
# without restriction, including without limitation the rights to copy,
# create derivative works of, display, perform, and distribute the Software
# and make, use, sell, offer for sale, import, export, have made, and have
# sold the Software and the Larger Work(s), and to sublicense the foregoing
# rights on either these or other terms.
#
# This license is subject to the following condition:
#
# The above copyright notice and either this complete permission notice or
# at a minimum a reference to the UPL must be included in all copies or
# substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
# NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
# USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
......
Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
This code is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License version 2 only, as
published by the Free Software Foundation.
This code is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
version 2 for more details (a copy is included in the LICENSE file that
accompanied this code).
You should have received a copy of the GNU General Public License version
2 along with this work; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
The Universal Permissive License (UPL), Version 1.0
Subject to the condition set forth below, permission is hereby granted to
any person obtaining a copy of this software, associated documentation
and/or data (collectively the "Software"), free of charge and under any
and all copyright rights in the Software, and any and all patent rights
owned or freely licensable by each licensor hereunder covering either (i)
the unmodified Software as contributed to or provided by such licensor,
or (ii) the Larger Works (as defined below), to deal in both
(a) the Software, and
(b) any piece of software and/or hardware listed in the lrgrwrks.txt file
if one is included with the Software (each a “Larger Work” to which the
Software is contributed by such licensors),
without restriction, including without limitation the rights to copy,
create derivative works of, display, perform, and distribute the Software
and make, use, sell, offer for sale, import, export, have made, and have
sold the Software and the Larger Work(s), and to sublicense the foregoing
rights on either these or other terms.
This license is subject to the following condition:
The above copyright notice and either this complete permission notice or
at a minimum a reference to the UPL must be included in all copies or
substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
or visit www.oracle.com if you need additional information or have any
questions.
......
......@@ -2,19 +2,41 @@
* Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
* The Universal Permissive License (UPL), Version 1.0
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
* Subject to the condition set forth below, permission is hereby granted to
* any person obtaining a copy of this software, associated documentation
* and/or data (collectively the "Software"), free of charge and under any
* and all copyright rights in the Software, and any and all patent rights
* owned or freely licensable by each licensor hereunder covering either (i)
* the unmodified Software as contributed to or provided by such licensor,
* or (ii) the Larger Works (as defined below), to deal in both
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
* (a) the Software, and
*
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file
* if one is included with the Software (each a “Larger Work” to which the
* Software is contributed by such licensors),
*
* without restriction, including without limitation the rights to copy,
* create derivative works of, display, perform, and distribute the Software
* and make, use, sell, offer for sale, import, export, have made, and have
* sold the Software and the Larger Work(s), and to sublicense the foregoing
* rights on either these or other terms.
*
* This license is subject to the following condition:
*
* The above copyright notice and either this complete permission notice or
* at a minimum a reference to the UPL must be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
* NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
......
......@@ -2,19 +2,41 @@
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
* The Universal Permissive License (UPL), Version 1.0
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
* Subject to the condition set forth below, permission is hereby granted to
* any person obtaining a copy of this software, associated documentation
* and/or data (collectively the "Software"), free of charge and under any
* and all copyright rights in the Software, and any and all patent rights
* owned or freely licensable by each licensor hereunder covering either (i)
* the unmodified Software as contributed to or provided by such licensor,
* or (ii) the Larger Works (as defined below), to deal in both
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
* (a) the Software, and
*
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file
* if one is included with the Software (each a “Larger Work” to which the
* Software is contributed by such licensors),
*
* without restriction, including without limitation the rights to copy,
* create derivative works of, display, perform, and distribute the Software
* and make, use, sell, offer for sale, import, export, have made, and have
* sold the Software and the Larger Work(s), and to sublicense the foregoing
* rights on either these or other terms.
*
* This license is subject to the following condition:
*
* The above copyright notice and either this complete permission notice or
* at a minimum a reference to the UPL must be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
* NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
......
......@@ -2,19 +2,41 @@
* Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
* The Universal Permissive License (UPL), Version 1.0
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
* Subject to the condition set forth below, permission is hereby granted to
* any person obtaining a copy of this software, associated documentation
* and/or data (collectively the "Software"), free of charge and under any
* and all copyright rights in the Software, and any and all patent rights
* owned or freely licensable by each licensor hereunder covering either (i)
* the unmodified Software as contributed to or provided by such licensor,
* or (ii) the Larger Works (as defined below), to deal in both
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
* (a) the Software, and
*
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file
* if one is included with the Software (each a “Larger Work” to which the
* Software is contributed by such licensors),
*
* without restriction, including without limitation the rights to copy,
* create derivative works of, display, perform, and distribute the Software
* and make, use, sell, offer for sale, import, export, have made, and have
* sold the Software and the Larger Work(s), and to sublicense the foregoing
* rights on either these or other terms.
*
* This license is subject to the following condition:
*
* The above copyright notice and either this complete permission notice or
* at a minimum a reference to the UPL must be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
* NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
......
......@@ -160,6 +160,7 @@ WB_END
#ifdef LINUX
#include "utilities/elfFile.hpp"
#include "osContainer_linux.hpp"
#endif
WB_ENTRY(jlong, WB_GetCompressedOopsMaxHeapSize(JNIEnv* env, jobject o)) {
......@@ -1028,6 +1029,15 @@ WB_ENTRY(jboolean, WB_CheckLibSpecifiesNoexecstack(JNIEnv* env, jobject o, jstri
return ret;
WB_END
WB_ENTRY(jboolean, WB_IsContainerized(JNIEnv* env, jobject o))
LINUX_ONLY(return OSContainer::is_containerized();)
return false;
WB_END
WB_ENTRY(void, WB_PrintOsInfo(JNIEnv* env, jobject o))
os::print_os_info(tty);
WB_END
#define CC (char*)
static JNINativeMethod methods[] = {
......@@ -1141,6 +1151,8 @@ static JNINativeMethod methods[] = {
{CC"forceSafepoint", CC"()V", (void*)&WB_ForceSafepoint },
{CC"checkLibSpecifiesNoexecstack", CC"(Ljava/lang/String;)Z",
(void*)&WB_CheckLibSpecifiesNoexecstack},
{CC"isContainerized", CC"()Z", (void*)&WB_IsContainerized },
{CC"printOsInfo", CC"()V", (void*)&WB_PrintOsInfo },
};
#undef CC
......
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
public class AttemptOOM {
private static MyObj[] data;
public static void main(String[] args) throws Exception {
System.out.println("Entering AttemptOOM main");
// each MyObj will allocate 1024 byte array
int sizeInMb = Integer.parseInt(args[0]);
data = new MyObj[sizeInMb*1024];
System.out.println("data.length = " + data.length);
for (int i=0; i < data.length; i++) {
data[i] = new MyObj(1024);
}
System.out.println("AttemptOOM allocation successful");
}
private static class MyObj {
private byte[] myData;
MyObj(int size) {
myData = new byte[size];
}
}
}
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Optional;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import com.oracle.java.testlibrary.Asserts;
// A simple CPU sets reader and parser
public class CPUSetsReader {
public static String PROC_SELF_STATUS_PATH="/proc/self/status";
// Test the parser
public static void test() {
assertParse("0-7", "0,1,2,3,4,5,6,7");
assertParse("1,3,6", "1,3,6");
assertParse("0,2-4,6,10-11", "0,2,3,4,6,10,11");
assertParse("0", "0");
}
private static void assertParse(String cpuSet, String expectedResult) {
Asserts.assertEquals(listToString(parseCpuSet(cpuSet)), expectedResult);
}
public static String readFromProcStatus(String setType) {
String path = PROC_SELF_STATUS_PATH;
Optional<String> o = Optional.empty();
System.out.println("readFromProcStatus() entering for: " + setType);
try (Stream<String> stream = Files.lines(Paths.get(path))) {
o = stream
.filter(line -> line.contains(setType))
.findFirst();
} catch (IOException e) {
return null;
}
if (!o.isPresent()) {
return null; // entry not found
}
String[] parts = o.get().replaceAll("\\s","").split(":");
// Should be 2 parts, before and after ":"
Asserts.assertEquals(parts.length, 2);
String result = parts[1];
System.out.println("readFromProcStatus() returning: " + result);
return result;
}
public static List<Integer> parseCpuSet(String value) {
ArrayList<Integer> result = new ArrayList<Integer>();
try {
String[] commaSeparated = value.split(",");
for (String item : commaSeparated) {
if (item.contains("-")) {
addRange(result, item);
} else {
result.add(Integer.parseInt(item));
}
}
} catch (Exception e) {
System.err.println("Exception in getMaxCpuSets(): " + e);
return null;
}
return result;
}
private static void addRange(ArrayList<Integer> list, String s) {
String[] range = s.split("-");
if ( range.length != 2 ) {
throw new RuntimeException("Range should only contain two items, but contains "
+ range.length + " items");
}
int min = Integer.parseInt(range[0]);
int max = Integer.parseInt(range[1]);
if (min >= max) {
String msg = String.format("min is greater or equals to max, min = %d, max = %d",
min, max);
throw new RuntimeException(msg);
}
for (int i = min; i <= max; i++) {
list.add(i);
}
}
// Convert list of integers to string with comma-separated values
public static String listToString(List<Integer> list) {
return listToString(list, Integer.MAX_VALUE);
}
// Convert list of integers to a string with comma-separated values;
// include up to maxCount.
public static String listToString(List<Integer> list, int maxCount) {
return list.stream()
.limit(maxCount)
.map(Object::toString)
.collect(Collectors.joining(","));
}
}
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import sun.hotspot.WhiteBox;
public class CheckContainerized {
public static String OUTSIDE_OF_CONTAINER =
"CheckContainerized: Running outside of a container";
public static String INSIDE_A_CONTAINER =
"CheckContainerized: Running inside a container";
public static void main(String[] args) {
System.out.println("CheckContainerized: Entering");
WhiteBox wb = WhiteBox.getWhiteBox();
if (wb.isContainerized()) {
System.out.println(INSIDE_A_CONTAINER);
} else {
System.out.println(OUTSIDE_OF_CONTAINER);
}
}
}
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @summary Basic (sanity) test for JDK-under-test inside a docker image.
* @library /testlibrary
* @build HelloDocker
* @run driver DockerBasicTest
*/
import com.oracle.java.testlibrary.Utils;
import com.oracle.java.testlibrary.Platform;
import com.oracle.java.testlibrary.DockerTestUtils;
import com.oracle.java.testlibrary.DockerRunOptions;
public class DockerBasicTest {
private static final String imageNameAndTag = "jdk8-internal:test";
// Diganostics: set to false to examine image after the test
private static final boolean removeImageAfterTest = true;
public static void main(String[] args) throws Exception {
if (!DockerTestUtils.canTestDocker()) {
return;
}
DockerTestUtils.buildJdkDockerImage(imageNameAndTag, "Dockerfile-BasicTest", "jdk-docker");
try {
testJavaVersion();
testHelloDocker();
} finally {
if (removeImageAfterTest)
DockerTestUtils.removeDockerImage(imageNameAndTag);
}
}
private static void testJavaVersion() throws Exception {
DockerRunOptions opts =
new DockerRunOptions(imageNameAndTag, "/jdk/bin/java", "-version");
DockerTestUtils.dockerRunJava(opts)
.shouldHaveExitValue(0)
.shouldContain(Platform.vmName);
}
private static void testHelloDocker() throws Exception {
DockerRunOptions opts =
new DockerRunOptions(imageNameAndTag, "/jdk/bin/java", "HelloDocker")
.addJavaOpts("-cp", "/test-classes/")
.addDockerOpts("--volume", Utils.TEST_CLASSES + ":/test-classes/");
DockerTestUtils.dockerRunJava(opts)
.shouldHaveExitValue(0)
.shouldContain("Hello Docker");
}
}
FROM oraclelinux:7.2
MAINTAINER mikhailo.seledtsov@oracle.com
COPY /jdk /jdk
ENV JAVA_HOME=/jdk
CMD ["/bin/bash"]
# Use generic ubuntu Linux on AArch64
FROM aarch64/ubuntu
COPY /jdk /jdk
ENV JAVA_HOME=/jdk
CMD ["/bin/bash"]
# test on x86_64 uses Oracle Linux but we do not have this for ppc64le
# so use some other Linux where OpenJDK works
# FROM oraclelinux:7.2
FROM ppc64le/ubuntu
COPY /jdk /jdk
ENV JAVA_HOME=/jdk
CMD ["/bin/bash"]
FROM s390x/ubuntu
COPY /jdk /jdk
ENV JAVA_HOME=/jdk
CMD ["/bin/bash"]
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
public class HelloDocker {
public static void main(String args[]) {
System.out.println("Hello Docker");
}
}
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import sun.hotspot.WhiteBox;
public class PrintContainerInfo {
public static void main(String[] args) {
System.out.println("PrintContainerInfo: Entering");
WhiteBox wb = WhiteBox.getWhiteBox();
wb.printOsInfo();
}
}
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @summary Test JVM's CPU resource awareness when running inside docker container
* @library /testlibrary
* @run driver TestCPUAwareness
*/
import java.util.List;
import com.oracle.java.testlibrary.Common;
import com.oracle.java.testlibrary.DockerTestUtils;
import com.oracle.java.testlibrary.DockerRunOptions;
public class TestCPUAwareness {
private static final String imageName = Common.imageName("cpu");
private static final int availableCPUs = Runtime.getRuntime().availableProcessors();
public static void main(String[] args) throws Exception {
if (!DockerTestUtils.canTestDocker()) {
return;
}
System.out.println("Test Environment: detected availableCPUs = " + availableCPUs);
DockerTestUtils.buildJdkDockerImage(imageName, "Dockerfile-BasicTest", "jdk-docker");
try {
// cpuset, period, shares, expected Active Processor Count
testComboWithCpuSets();
// cpu shares - it should be safe to use CPU shares exceeding available CPUs
testCpuShares(256, 1);
testCpuShares(2048, 2);
testCpuShares(4096, 4);
// leave one CPU for system and tools, otherwise this test may be unstable
int maxNrOfAvailableCpus = availableCPUs - 1;
for (int i=1; i < maxNrOfAvailableCpus; i = i * 2) {
testCpus(i, i);
}
// If ActiveProcessorCount is set, the VM should use it, regardless of other
// container settings, host settings or available CPUs on the host.
testActiveProcessorCount(1, 1);
testActiveProcessorCount(2, 2);
// cpu quota and period
testCpuQuotaAndPeriod(50*1000, 100*1000);
testCpuQuotaAndPeriod(100*1000, 100*1000);
testCpuQuotaAndPeriod(150*1000, 100*1000);
testCpuQuotaAndPeriod(400*1000, 100*1000);
} finally {
DockerTestUtils.removeDockerImage(imageName);
}
}
private static void testComboWithCpuSets() throws Exception {
String cpuSetStr = CPUSetsReader.readFromProcStatus("Cpus_allowed_list");
System.out.println("cpuSetStr = " + cpuSetStr);
if (cpuSetStr == null) {
System.out.printf("The cpuset test cases are skipped");
} else {
List<Integer> cpuSet = CPUSetsReader.parseCpuSet(cpuSetStr);
// Test subset of cpuset with one element
if (cpuSet.size() >= 1) {
String testCpuSet = CPUSetsReader.listToString(cpuSet, 1);
testAPCCombo(testCpuSet, 200*1000, 100*1000, 4*1024, true, 1);
}
// Test subset of cpuset with two elements
if (cpuSet.size() >= 2) {
String testCpuSet = CPUSetsReader.listToString(cpuSet, 2);
testAPCCombo(testCpuSet, 200*1000, 100*1000, 4*1024, true, 2);
testAPCCombo(testCpuSet, 200*1000, 100*1000, 1023, true, 2);
testAPCCombo(testCpuSet, 200*1000, 100*1000, 1023, false, 1);
}
// Test subset of cpuset with three elements
if (cpuSet.size() >= 3) {
String testCpuSet = CPUSetsReader.listToString(cpuSet, 3);
testAPCCombo(testCpuSet, 100*1000, 100*1000, 2*1024, true, 1);
testAPCCombo(testCpuSet, 200*1000, 100*1000, 1023, true, 2);
testAPCCombo(testCpuSet, 200*1000, 100*1000, 1023, false, 1);
}
}
}
private static void testActiveProcessorCount(int valueToSet, int expectedValue) throws Exception {
Common.logNewTestCase("Test ActiveProcessorCount: valueToSet = " + valueToSet);
DockerRunOptions opts = Common.newOpts(imageName)
.addJavaOpts("-XX:ActiveProcessorCount=" + valueToSet, "-XX:+UnlockDiagnosticVMOptions", "-XX:+PrintActiveCpus");
Common.run(opts)
.shouldMatch("active processor count set by user.*" + expectedValue);
}
private static void testCpus(int valueToSet, int expectedTraceValue) throws Exception {
Common.logNewTestCase("test cpus: " + valueToSet);
DockerRunOptions opts = Common.newOpts(imageName)
.addDockerOpts("--cpus", "" + valueToSet);
Common.run(opts)
.shouldMatch("active_processor_count.*" + expectedTraceValue);
}
// Expected active processor count can not exceed available CPU count
private static int adjustExpectedAPCForAvailableCPUs(int expectedAPC) {
if (expectedAPC > availableCPUs) {
expectedAPC = availableCPUs;
System.out.println("Adjusted expectedAPC = " + expectedAPC);
}
return expectedAPC;
}
private static void testCpuQuotaAndPeriod(int quota, int period)
throws Exception {
Common.logNewTestCase("test cpu quota and period: ");
System.out.println("quota = " + quota);
System.out.println("period = " + period);
int expectedAPC = (int) Math.ceil((float) quota / (float) period);
System.out.println("expectedAPC = " + expectedAPC);
expectedAPC = adjustExpectedAPCForAvailableCPUs(expectedAPC);
DockerRunOptions opts = Common.newOpts(imageName)
.addDockerOpts("--cpu-period=" + period)
.addDockerOpts("--cpu-quota=" + quota);
Common.run(opts)
.shouldMatch("CPU Period is.*" + period)
.shouldMatch("CPU Quota is.*" + quota)
.shouldMatch("active_processor_count.*" + expectedAPC);
}
// Test correctess of automatically selected active processor cound
private static void testAPCCombo(String cpuset, int quota, int period, int shares,
boolean usePreferContainerQuotaForCPUCount,
int expectedAPC) throws Exception {
Common.logNewTestCase("test APC Combo");
System.out.println("cpuset = " + cpuset);
System.out.println("quota = " + quota);
System.out.println("period = " + period);
System.out.println("shares = " + period);
System.out.println("usePreferContainerQuotaForCPUCount = " + usePreferContainerQuotaForCPUCount);
System.out.println("expectedAPC = " + expectedAPC);
expectedAPC = adjustExpectedAPCForAvailableCPUs(expectedAPC);
DockerRunOptions opts = Common.newOpts(imageName)
.addDockerOpts("--cpuset-cpus", "" + cpuset)
.addDockerOpts("--cpu-period=" + period)
.addDockerOpts("--cpu-quota=" + quota)
.addDockerOpts("--cpu-shares=" + shares);
if (!usePreferContainerQuotaForCPUCount) opts.addJavaOpts("-XX:-PreferContainerQuotaForCPUCount");
Common.run(opts)
.shouldMatch("active_processor_count.*" + expectedAPC);
}
private static void testCpuShares(int shares, int expectedAPC) throws Exception {
Common.logNewTestCase("test cpu shares, shares = " + shares);
System.out.println("expectedAPC = " + expectedAPC);
expectedAPC = adjustExpectedAPCForAvailableCPUs(expectedAPC);
DockerRunOptions opts = Common.newOpts(imageName)
.addDockerOpts("--cpu-shares=" + shares);
Common.run(opts)
.shouldMatch("CPU Shares is.*" + shares)
.shouldMatch("active_processor_count.*" + expectedAPC);
}
}
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @summary Test JVM's awareness of cpu sets (cpus and mems)
* @library /testlibrary /testlibrary/whitebox
* @build AttemptOOM CPUSetsReader sun.hotspot.WhiteBox PrintContainerInfo
* @run driver ClassFileInstaller -jar whitebox.jar sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission
* @run driver TestCPUSets
*/
import java.util.List;
import com.oracle.java.testlibrary.Common;
import com.oracle.java.testlibrary.DockerRunOptions;
import com.oracle.java.testlibrary.DockerTestUtils;
import com.oracle.java.testlibrary.Asserts;
import com.oracle.java.testlibrary.Platform;
import com.oracle.java.testlibrary.Utils;
import com.oracle.java.testlibrary.OutputAnalyzer;
public class TestCPUSets {
private static final String imageName = Common.imageName("cpusets");
public static void main(String[] args) throws Exception {
if (!DockerTestUtils.canTestDocker()) {
return;
}
Common.prepareWhiteBox();
DockerTestUtils.buildJdkDockerImage(imageName, "Dockerfile-BasicTest", "jdk-docker");
try {
// Sanity test the cpu sets reader and parser
CPUSetsReader.test();
testTheSet("Cpus_allowed_list");
testTheSet("Mems_allowed_list");
} finally {
DockerTestUtils.removeDockerImage(imageName);
}
}
private static void testTheSet(String setType) throws Exception {
String cpuSetStr = CPUSetsReader.readFromProcStatus(setType);
if (cpuSetStr == null) {
System.out.printf("The %s test is skipped %n", setType);
} else {
List<Integer> cpuSet = CPUSetsReader.parseCpuSet(cpuSetStr);
// Test subset of one, full subset, and half of the subset
testCpuSet(CPUSetsReader.listToString(cpuSet, 1));
if (cpuSet.size() > 1) {
testCpuSet(CPUSetsReader.listToString(cpuSet));
}
if (cpuSet.size() > 2) {
testCpuSet(CPUSetsReader.listToString(cpuSet, cpuSet.size()/2 ));
}
}
}
private static DockerRunOptions commonOpts() {
DockerRunOptions opts = new DockerRunOptions(imageName, "/jdk/bin/java",
"PrintContainerInfo");
opts.addDockerOpts("--volume", Utils.TEST_CLASSES + ":/test-classes/");
opts.addJavaOpts("-XX:+UnlockDiagnosticVMOptions", "-XX:+PrintContainerInfo", "-cp", "/test-classes/");
Common.addWhiteBoxOpts(opts);
return opts;
}
private static void checkResult(List<String> lines, String lineMarker, String value) {
boolean lineMarkerFound = false;
for (String line : lines) {
if (line.contains(lineMarker)) {
lineMarkerFound = true;
String[] parts = line.split(":");
System.out.println("DEBUG: line = " + line);
System.out.println("DEBUG: parts.length = " + parts.length);
Asserts.assertEquals(parts.length, 2);
String set = parts[1].replaceAll("\\s","");
String actual = CPUSetsReader.listToString(CPUSetsReader.parseCpuSet(set));
Asserts.assertEquals(actual, value);
break;
}
}
Asserts.assertTrue(lineMarkerFound);
}
private static void testCpuSet(String value) throws Exception {
Common.logNewTestCase("cpusets.cpus, value = " + value);
DockerRunOptions opts = commonOpts();
opts.addDockerOpts("--cpuset-cpus=" + value);
List<String> lines = Common.run(opts).asLines();
checkResult(lines, "cpuset.cpus is:", value);
}
private static void testMemSet(String value) throws Exception {
Common.logNewTestCase("cpusets.mems, value = " + value);
DockerRunOptions opts = commonOpts();
opts.addDockerOpts("--cpuset-mems=" + value);
List<String> lines = Common.run(opts).asLines();
checkResult(lines, "cpuset.mems is:", value);
}
}
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @summary Test JVM's memory resource awareness when running inside docker container
* @library /testlibrary /testlibrary/whitebox
* @build AttemptOOM sun.hotspot.WhiteBox PrintContainerInfo
* @run driver ClassFileInstaller -jar whitebox.jar sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission
* @run driver TestMemoryAwareness
*/
import com.oracle.java.testlibrary.Common;
import com.oracle.java.testlibrary.DockerRunOptions;
import com.oracle.java.testlibrary.DockerTestUtils;
public class TestMemoryAwareness {
private static final String imageName = Common.imageName("memory");
public static void main(String[] args) throws Exception {
if (!DockerTestUtils.canTestDocker()) {
return;
}
Common.prepareWhiteBox();
DockerTestUtils.buildJdkDockerImage(imageName, "Dockerfile-BasicTest", "jdk-docker");
try {
testMemoryLimit("100m", "104857600");
testMemoryLimit("500m", "524288000");
testMemoryLimit("1g", "1073741824");
testMemoryLimit("4g", "4294967296");
testMemorySoftLimit("500m", "524288000");
testMemorySoftLimit("1g", "1073741824");
// Add extra 10 Mb to allocator limit, to be sure to cause OOM
testOOM("256m", 256 + 10);
} finally {
DockerTestUtils.removeDockerImage(imageName);
}
}
private static void testMemoryLimit(String valueToSet, String expectedTraceValue)
throws Exception {
Common.logNewTestCase("memory limit: " + valueToSet);
DockerRunOptions opts = Common.newOpts(imageName)
.addDockerOpts("--memory", valueToSet);
Common.run(opts)
.shouldMatch("Memory Limit is:.*" + expectedTraceValue);
}
private static void testMemorySoftLimit(String valueToSet, String expectedTraceValue)
throws Exception {
Common.logNewTestCase("memory soft limit: " + valueToSet);
DockerRunOptions opts = Common.newOpts(imageName, "PrintContainerInfo");
Common.addWhiteBoxOpts(opts);
opts.addDockerOpts("--memory-reservation=" + valueToSet);
Common.run(opts)
.shouldMatch("Memory Soft Limit.*" + expectedTraceValue);
}
// provoke OOM inside the container, see how VM reacts
private static void testOOM(String dockerMemLimit, int sizeToAllocInMb) throws Exception {
Common.logNewTestCase("OOM");
DockerRunOptions opts = Common.newOpts(imageName, "AttemptOOM")
.addDockerOpts("--memory", dockerMemLimit, "--memory-swap", dockerMemLimit);
opts.classParams.add("" + sizeToAllocInMb);
DockerTestUtils.dockerRunJava(opts)
.shouldHaveExitValue(1)
.shouldContain("Entering AttemptOOM main")
.shouldNotContain("AttemptOOM allocation successful")
.shouldContain("java.lang.OutOfMemoryError");
}
}
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @summary Test miscellanous functionality related to JVM running in docker container
* @library /testlibrary /testlibrary/whitebox
* @build CheckContainerized sun.hotspot.WhiteBox PrintContainerInfo
* @run driver ClassFileInstaller -jar whitebox.jar sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission
* @run driver TestMisc
*/
import com.oracle.java.testlibrary.Common;
import com.oracle.java.testlibrary.DockerTestUtils;
import com.oracle.java.testlibrary.DockerRunOptions;
import com.oracle.java.testlibrary.OutputAnalyzer;
import com.oracle.java.testlibrary.ProcessTools;
public class TestMisc {
private static final String imageName = Common.imageName("misc");
public static void main(String[] args) throws Exception {
if (!DockerTestUtils.canTestDocker()) {
return;
}
Common.prepareWhiteBox();
DockerTestUtils.buildJdkDockerImage(imageName, "Dockerfile-BasicTest", "jdk-docker");
try {
testMinusContainerSupport();
testIsContainerized();
testPrintContainerInfo();
} finally {
DockerTestUtils.removeDockerImage(imageName);
}
}
private static void testMinusContainerSupport() throws Exception {
Common.logNewTestCase("Test related flags: '-UseContainerSupport'");
DockerRunOptions opts = new DockerRunOptions(imageName, "/jdk/bin/java", "-version");
opts.addJavaOpts("-XX:+UnlockDiagnosticVMOptions", "-XX:-UseContainerSupport", "-XX:+PrintContainerInfo");
Common.run(opts)
.shouldContain("Container Support not enabled");
}
private static void testIsContainerized() throws Exception {
Common.logNewTestCase("Test is_containerized() inside a docker container");
DockerRunOptions opts = Common.newOpts(imageName, "CheckContainerized");
Common.addWhiteBoxOpts(opts);
Common.run(opts)
.shouldContain(CheckContainerized.INSIDE_A_CONTAINER);
}
private static void testPrintContainerInfo() throws Exception {
Common.logNewTestCase("Test print_container_info()");
DockerRunOptions opts = Common.newOpts(imageName, "PrintContainerInfo");
Common.addWhiteBoxOpts(opts);
checkContainerInfo(Common.run(opts));
}
private static void checkContainerInfo(OutputAnalyzer out) throws Exception {
String[] expectedToContain = new String[] {
"cpuset.cpus",
"cpuset.mems",
"CPU Shares",
"CPU Quota",
"CPU Period",
"OSContainer::active_processor_count",
"Memory Limit",
"Memory Soft Limit",
"Memory Usage",
"Maximum Memory Usage",
"memory_max_usage_in_bytes"
};
for (String s : expectedToContain) {
out.shouldContain(s);
}
}
}
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -21,28 +21,229 @@
* questions.
*/
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.ByteArrayInputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
* Dump a class file for a class on the class path in the current directory
* Dump a class file for a class on the class path in the current directory, or
* in the specified JAR file. This class is usually used when you build a class
* from a test library, but want to use this class in a sub-process.
*
* For example, to build the following library class:
* test/lib/sun/hotspot/WhiteBox.java
*
* You would use the following tags:
*
* @library /test/lib
* @build sun.hotspot.WhiteBox
*
* JTREG would build the class file under
* ${JTWork}/classes/test/lib/sun/hotspot/WhiteBox.class
*
* With you run your main test class using "@run main MyMainClass", JTREG would setup the
* -classpath to include "${JTWork}/classes/test/lib/", so MyMainClass would be able to
* load the WhiteBox class.
*
* However, if you run a sub process, and do not wish to use the exact same -classpath,
* You can use ClassFileInstaller to ensure that WhiteBox is available in the current
* directory of your test:
*
* @run main ClassFileInstaller sun.hotspot.WhiteBox
*
* Or, you can use the -jar option to store the class in the specified JAR file. If a relative
* path name is given, the JAR file would be relative to the current directory of
*
* @run main ClassFileInstaller -jar myjar.jar sun.hotspot.WhiteBox
*/
public class ClassFileInstaller {
/**
* You can enable debug tracing of ClassFileInstaller by running JTREG with
* jtreg -DClassFileInstaller.debug=true ... <names of tests>
*/
public static boolean DEBUG = Boolean.getBoolean("ClassFileInstaller.debug");
/**
* @param args The names of the classes to dump
* @throws Exception
*/
public static void main(String... args) throws Exception {
for (String arg : args) {
ClassLoader cl = ClassFileInstaller.class.getClassLoader();
if (args.length > 1 && args[0].equals("-jar")) {
if (args.length < 2) {
throw new RuntimeException("Usage: ClassFileInstaller <options> <classes>\n" +
"where possible options include:\n" +
" -jar <path> Write to the JAR file <path>");
}
writeJar(args[1], null, args, 2, args.length);
} else {
if (DEBUG) {
System.out.println("ClassFileInstaller: Writing to " + System.getProperty("user.dir"));
}
for (String arg : args) {
writeClassToDisk(arg);
}
}
}
public static class Manifest {
private InputStream in;
private Manifest(InputStream in) {
this.in = in;
}
static Manifest fromSourceFile(String fileName) throws Exception {
String pathName = System.getProperty("test.src") + File.separator + fileName;
return new Manifest(new FileInputStream(pathName));
}
// Example:
// String manifest = "Premain-Class: RedefineClassHelper\n" +
// "Can-Redefine-Classes: true\n";
// ClassFileInstaller.writeJar("redefineagent.jar",
// ClassFileInstaller.Manifest.fromString(manifest),
// "RedefineClassHelper");
static Manifest fromString(String manifest) throws Exception {
return new Manifest(new ByteArrayInputStream(manifest.getBytes()));
}
public InputStream getInputStream() {
return in;
}
}
private static void writeJar(String jarFile, Manifest manifest, String classes[], int from, int to) throws Exception {
if (DEBUG) {
System.out.println("ClassFileInstaller: Writing to " + getJarPath(jarFile));
}
(new File(jarFile)).delete();
FileOutputStream fos = new FileOutputStream(jarFile);
ZipOutputStream zos = new ZipOutputStream(fos);
// The manifest must be the first or second entry. See comments in JarInputStream
// constructor and JDK-5046178.
if (manifest != null) {
writeToDisk(zos, "META-INF/MANIFEST.MF", manifest.getInputStream());
}
for (int i=from; i<to; i++) {
writeClassToDisk(zos, classes[i]);
}
zos.close();
fos.close();
}
/*
* You can call ClassFileInstaller.writeJar() from your main test class instead of
* using "@run ClassFileInstaller -jar ...". E.g.,
*
* String jarPath = ClassFileInstaller.getJarPath("myjar.jar", "sun.hotspot.WhiteBox")
*
* If you call this API, make sure you build ClassFileInstaller with the following tags:
*
* @library testlibrary
* @build ClassFileInstaller
*/
public static String writeJar(String jarFile, String... classes) throws Exception {
writeJar(jarFile, null, classes, 0, classes.length);
return getJarPath(jarFile);
}
// Convert dotted class name to a path to a class file
String pathName = arg.replace('.', '/').concat(".class");
InputStream is = cl.getResourceAsStream(pathName);
public static String writeJar(String jarFile, Manifest manifest, String... classes) throws Exception {
writeJar(jarFile, manifest, classes, 0, classes.length);
return getJarPath(jarFile);
}
/**
* This returns the absolute path to the file specified in "@ClassFileInstaller -jar myjar.jar",
* In your test program, instead of using the JAR file name directly:
*
* String jarPath = "myjar.jar";
*
* you should call this function, like:
*
* String jarPath = ClassFileInstaller.getJarPath("myjar.jar")
*
* The reasons are:
* (1) Using absolute path makes it easy to cut-and-paste from the JTR file and rerun your
* test in any directory.
* (2) In the future, we may make the JAR file name unique to avoid clobbering
* during parallel JTREG execution.
*
*/
public static String getJarPath(String jarFileName) {
return new File(jarFileName).getAbsolutePath();
}
public static void writeClassToDisk(String className) throws Exception {
writeClassToDisk((ZipOutputStream)null, className);
}
private static void writeClassToDisk(ZipOutputStream zos, String className) throws Exception {
writeClassToDisk(zos, className, "");
}
public static void writeClassToDisk(String className, String prependPath) throws Exception {
writeClassToDisk(null, className, prependPath);
}
private static void writeClassToDisk(ZipOutputStream zos, String className, String prependPath) throws Exception {
ClassLoader cl = ClassFileInstaller.class.getClassLoader();
// Convert dotted class name to a path to a class file
String pathName = className.replace('.', '/').concat(".class");
InputStream is = cl.getResourceAsStream(pathName);
if (is == null) {
throw new RuntimeException("Failed to find " + pathName);
}
if (prependPath.length() > 0) {
pathName = prependPath + "/" + pathName;
}
writeToDisk(zos, pathName, is);
}
public static void writeClassToDisk(String className, byte[] bytecode) throws Exception {
writeClassToDisk(null, className, bytecode);
}
private static void writeClassToDisk(ZipOutputStream zos, String className, byte[] bytecode) throws Exception {
writeClassToDisk(zos, className, bytecode, "");
}
public static void writeClassToDisk(String className, byte[] bytecode, String prependPath) throws Exception {
writeClassToDisk(null, className, bytecode, prependPath);
}
private static void writeClassToDisk(ZipOutputStream zos, String className, byte[] bytecode, String prependPath) throws Exception {
// Convert dotted class name to a path to a class file
String pathName = className.replace('.', '/').concat(".class");
if (prependPath.length() > 0) {
pathName = prependPath + "/" + pathName;
}
writeToDisk(zos, pathName, new ByteArrayInputStream(bytecode));
}
private static void writeToDisk(ZipOutputStream zos, String pathName, InputStream is) throws Exception {
if (DEBUG) {
System.out.println("ClassFileInstaller: Writing " + pathName);
}
if (zos != null) {
ZipEntry ze = new ZipEntry(pathName);
zos.putNextEntry(ze);
byte[] buf = new byte[1024];
int len;
while ((len = is.read(buf))>0){
zos.write(buf, 0, len);
}
} else {
// Create the class file's package directory
Path p = Paths.get(pathName);
if (pathName.contains("/")) {
......@@ -51,5 +252,6 @@ public class ClassFileInstaller {
// Create the class file
Files.copy(is, p, StandardCopyOption.REPLACE_EXISTING);
}
is.close();
}
}
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.oracle.java.testlibrary;
/*
* Methods and definitions common to docker tests container in this directory
*/
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import com.oracle.java.testlibrary.DockerTestUtils;
import com.oracle.java.testlibrary.DockerRunOptions;
import com.oracle.java.testlibrary.Utils;
import com.oracle.java.testlibrary.OutputAnalyzer;
public class Common {
public static final String imageNameAndTag = "jdk-internal:test";
public static String imageName(String suffix) {
return imageNameAndTag + "-" + suffix;
}
public static void prepareWhiteBox() throws Exception {
Path whiteboxPath = Paths.get(Utils.TEST_CLASSES, "whitebox.jar");
if( !Files.exists(whiteboxPath) ) {
Files.copy(Paths.get(new File("whitebox.jar").getAbsolutePath()),
Paths.get(Utils.TEST_CLASSES, "whitebox.jar"));
}
}
// create simple commonly used options
public static DockerRunOptions newOpts(String imageNameAndTag) {
return new DockerRunOptions(imageNameAndTag, "/jdk/bin/java", "-version")
.addJavaOpts("-XX:+UnlockDiagnosticVMOptions", "-XX:+PrintContainerInfo");
}
// create commonly used options with class to be launched inside container
public static DockerRunOptions newOpts(String imageNameAndTag, String testClass) {
DockerRunOptions opts =
new DockerRunOptions(imageNameAndTag, "/jdk/bin/java", testClass);
opts.addDockerOpts("--volume", Utils.TEST_CLASSES + ":/test-classes/");
opts.addJavaOpts("-XX:+UnlockDiagnosticVMOptions", "-XX:+PrintContainerInfo", "-cp", "/test-classes/");
return opts;
}
public static DockerRunOptions addWhiteBoxOpts(DockerRunOptions opts) {
opts.addJavaOpts("-Xbootclasspath/a:/test-classes/whitebox.jar",
"-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI");
return opts;
}
// most common type of run and checks
public static OutputAnalyzer run(DockerRunOptions opts) throws Exception {
return DockerTestUtils.dockerRunJava(opts)
.shouldHaveExitValue(0).shouldContain("Initializing Container Support");
}
// log beginning of a test case
public static void logNewTestCase(String msg) {
System.out.println("========== NEW TEST CASE: " + msg);
}
}
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.oracle.java.testlibrary;
import java.util.ArrayList;
import java.util.Collections;
// This class represents options for running java inside docker containers
// in test environment.
public class DockerRunOptions {
public String imageNameAndTag;
public ArrayList<String> dockerOpts = new ArrayList<String>();
public String command; // normally a full path to java
public ArrayList<String> javaOpts = new ArrayList<String>();
public String classToRun; // class or "-version"
public ArrayList<String> classParams = new ArrayList<String>();
public boolean tty = true;
public boolean removeContainerAfterUse = true;
public boolean appendTestJavaOptions = true;
public boolean retainChildStdout = false;
/**
* Convenience constructor for most common use cases in testing.
* @param imageNameAndTag a string representing name and tag for the
* docker image to run, as "name:tag"
* @param javaCmd a java command to run (e.g. /jdk/bin/java)
* @param classToRun a class to run, or "-version"
* @param javaOpts java options to use
*
* @return Default docker run options
*/
public DockerRunOptions(String imageNameAndTag, String javaCmd,
String classToRun, String... javaOpts) {
this.imageNameAndTag = imageNameAndTag;
this.command = javaCmd;
this.classToRun = classToRun;
this.addJavaOpts(javaOpts);
}
public DockerRunOptions addDockerOpts(String... opts) {
Collections.addAll(dockerOpts, opts);
return this;
}
public DockerRunOptions addJavaOpts(String... opts) {
Collections.addAll(javaOpts, opts);
return this;
}
}
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.oracle.java.testlibrary;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.FileVisitResult;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.StandardCopyOption;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import com.oracle.java.testlibrary.Utils;
import com.oracle.java.testlibrary.Platform;
import com.oracle.java.testlibrary.OutputAnalyzer;
import com.oracle.java.testlibrary.ProcessTools;
public class DockerTestUtils {
private static final String FS = File.separator;
private static boolean isDockerEngineAvailable = false;
private static boolean wasDockerEngineChecked = false;
// Diagnostics: set to true to enable more diagnostic info
private static final boolean DEBUG = false;
/**
* Optimized check of whether the docker engine is available in a given
* environment. Checks only once, then remembers the result in a singleton.
*
* @return true if docker engine is available
* @throws Exception
*/
public static boolean isDockerEngineAvailable() throws Exception {
if (wasDockerEngineChecked)
return isDockerEngineAvailable;
isDockerEngineAvailable = isDockerEngineAvailableCheck();
wasDockerEngineChecked = true;
return isDockerEngineAvailable;
}
/**
* Convenience method, will check if docker engine is available and usable;
* will print the appropriate message when not available.
*
* @return true if docker engine is available
* @throws Exception
*/
public static boolean canTestDocker() throws Exception {
if (isDockerEngineAvailable()) {
return true;
} else {
System.out.println("Docker engine is not available on this system");
System.out.println("This test is SKIPPED");
return false;
}
}
/**
* Simple check - is docker engine available, accessible and usable.
* Run basic docker command: 'docker ps' - list docker instances.
* If docker engine is available and accesible then true is returned
* and we can proceed with testing docker.
*
* @return true if docker engine is available and usable
* @throws Exception
*/
private static boolean isDockerEngineAvailableCheck() throws Exception {
try {
execute("docker", "ps")
.shouldHaveExitValue(0)
.shouldContain("CONTAINER")
.shouldContain("IMAGE");
} catch (Exception e) {
return false;
}
return true;
}
/**
* Build a docker image that contains JDK under test.
* The jdk will be placed under the "/jdk/" folder inside the docker file system.
*
* @param imageName name of the image to be created, including version tag
* @param dockerfile name of the dockerfile residing in the test source;
* we check for a platform specific dockerfile as well
* and use this one in case it exists
* @param buildDirName name of the docker build/staging directory, which will
* be created in the jtreg's scratch folder
* @throws Exception
*/
public static void
buildJdkDockerImage(String imageName, String dockerfile, String buildDirName)
throws Exception {
Path buildDir = Paths.get(".", buildDirName);
if (Files.exists(buildDir)) {
throw new RuntimeException("The docker build directory already exists: " + buildDir);
}
// check for the existance of a platform specific docker file as well
String platformSpecificDockerfile = dockerfile + "-" + Platform.getOsArch();
if (Files.exists(Paths.get(Utils.TEST_SRC, platformSpecificDockerfile))) {
dockerfile = platformSpecificDockerfile;
}
Path jdkSrcDir = Paths.get(Utils.TEST_JDK);
Path jdkDstDir = buildDir.resolve("jdk");
Files.createDirectories(jdkDstDir);
// Copy JDK-under-test tree to the docker build directory.
// This step is required for building a docker image.
Files.walkFileTree(jdkSrcDir, new CopyFileVisitor(jdkSrcDir, jdkDstDir));
buildDockerImage(imageName, Paths.get(Utils.TEST_SRC, dockerfile), buildDir);
}
/**
* Build a docker image based on given docker file and docker build directory.
*
* @param imageName name of the image to be created, including version tag
* @param dockerfile path to the Dockerfile to be used for building the docker
* image. The specified dockerfile will be copied to the docker build
* directory as 'Dockerfile'
* @param buildDir build directory; it should already contain all the content
* needed to build the docker image.
* @throws Exception
*/
public static void
buildDockerImage(String imageName, Path dockerfile, Path buildDir) throws Exception {
// Copy docker file to the build dir
Files.copy(dockerfile, buildDir.resolve("Dockerfile"));
// Build the docker
execute("docker", "build", "--no-cache", "--tag", imageName, buildDir.toString())
.shouldHaveExitValue(0)
.shouldContain("Successfully built");
}
/**
* Run Java inside the docker image with specified parameters and options.
*
* @param DockerRunOptions optins for running docker
*
* @return output of the run command
* @throws Exception
*/
public static OutputAnalyzer dockerRunJava(DockerRunOptions opts) throws Exception {
ArrayList<String> cmd = new ArrayList<>();
cmd.add("docker");
cmd.add("run");
if (opts.tty)
cmd.add("--tty=true");
if (opts.removeContainerAfterUse)
cmd.add("--rm");
cmd.addAll(opts.dockerOpts);
cmd.add(opts.imageNameAndTag);
cmd.add(opts.command);
cmd.addAll(opts.javaOpts);
if (opts.appendTestJavaOptions) {
Collections.addAll(cmd, Utils.getTestJavaOpts());
}
cmd.add(opts.classToRun);
cmd.addAll(opts.classParams);
return execute(cmd);
}
/**
* Remove docker image
*
* @param DockerRunOptions optins for running docker
* @return output of the command
* @throws Exception
*/
public static OutputAnalyzer removeDockerImage(String imageNameAndTag) throws Exception {
return execute("docker", "rmi", "--force", imageNameAndTag);
}
/**
* Convenience method - express command as sequence of strings
*
* @param command to execute
* @return The output from the process
* @throws Exception
*/
public static OutputAnalyzer execute(List<String> command) throws Exception {
return execute(command.toArray(new String[command.size()]));
}
/**
* Execute a specified command in a process, report diagnostic info.
*
* @param command to be executed
* @return The output from the process
* @throws Exception
*/
public static OutputAnalyzer execute(String... command) throws Exception {
ProcessBuilder pb = new ProcessBuilder(command);
System.out.println("[COMMAND]\n" + Utils.getCommandLine(pb));
long started = System.currentTimeMillis();
OutputAnalyzer output = new OutputAnalyzer(pb.start());
System.out.println("[ELAPSED: " + (System.currentTimeMillis() - started) + " ms]");
System.out.println("[STDERR]\n" + output.getStderr());
System.out.println("[STDOUT]\n" + output.getStdout());
return output;
}
private static class CopyFileVisitor extends SimpleFileVisitor<Path> {
private final Path src;
private final Path dst;
public CopyFileVisitor(Path src, Path dst) {
this.src = src;
this.dst = dst;
}
@Override
public FileVisitResult preVisitDirectory(Path file,
BasicFileAttributes attrs) throws IOException {
Path dstDir = dst.resolve(src.relativize(file));
if (!dstDir.toFile().exists()) {
Files.createDirectories(dstDir);
}
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(Path file,
BasicFileAttributes attrs) throws IOException {
if (!file.toFile().isFile()) {
return FileVisitResult.CONTINUE;
}
Path dstFile = dst.resolve(src.relativize(file));
Files.copy(file, dstFile, StandardCopyOption.COPY_ATTRIBUTES);
return FileVisitResult.CONTINUE;
}
}
}
/*
* Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -32,7 +32,7 @@ public class Platform {
private static final String dataModel = System.getProperty("sun.arch.data.model");
private static final String vmVersion = System.getProperty("java.vm.version");
private static final String osArch = System.getProperty("os.arch");
private static final String vmName = System.getProperty("java.vm.name");
public static final String vmName = System.getProperty("java.vm.name");
private static final String userName = System.getProperty("user.name");
public static boolean isClient() {
......
/*
* Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -61,6 +61,15 @@ public final class Utils {
*/
public static final String JAVA_OPTIONS = System.getProperty("test.java.opts", "").trim();
public static final String TEST_JDK = System.getProperty("test.jdk");
public static final String COMPILE_JDK= System.getProperty("compile.jdk", TEST_JDK);
public static final String TEST_SRC = System.getProperty("test.src", "").trim();
public static final String TEST_CLASSES = System.getProperty("test.classes", ".");
private static Unsafe unsafe = null;
/**
......
......@@ -238,4 +238,9 @@ public class WhiteBox {
// Returns true on linux if library has the noexecstack flag set.
public native boolean checkLibSpecifiesNoexecstack(String libfilename);
// Container testing
public native boolean isContainerized();
public native void printOsInfo();
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册