8072395: sun/tools/jmap/heapconfig/LingeredAppTest.java and sun/tools/jmap/heapconfig/JMapHeapConfigTest.java fail due to LingeredApp ERROR: java.io.IOException: Lock is too old. Aborting
authordsamersoff
Wed, 18 Feb 2015 03:45:06 -0800
changeset 29018 7f7b6d9e9461
parent 29017 4d33318f0574
child 29034 17c1e9d67f71
8072395: sun/tools/jmap/heapconfig/LingeredAppTest.java and sun/tools/jmap/heapconfig/JMapHeapConfigTest.java fail due to LingeredApp ERROR: java.io.IOException: Lock is too old. Aborting Summary: Remove lock age check Reviewed-by: sla, dholmes, kevinw
jdk/test/lib/testlibrary/jdk/testlibrary/Platform.java
jdk/test/sun/tools/jmap/heapconfig/JMapHeapConfigTest.java
jdk/test/sun/tools/jmap/heapconfig/LingeredApp.java
jdk/test/sun/tools/jmap/heapconfig/LingeredAppTest.java
--- a/jdk/test/lib/testlibrary/jdk/testlibrary/Platform.java	Wed Feb 18 03:16:48 2015 -0800
+++ b/jdk/test/lib/testlibrary/jdk/testlibrary/Platform.java	Wed Feb 18 03:45:06 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2015, 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
@@ -22,13 +22,20 @@
  */
 
 package jdk.testlibrary;
+import java.util.regex.Pattern;
+import java.io.RandomAccessFile;
+import java.io.FileNotFoundException;
+import java.io.IOException;
 
 public class Platform {
     private static final String osName      = System.getProperty("os.name");
     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 javaVersion = System.getProperty("java.version");
     private static final String osArch      = System.getProperty("os.arch");
     private static final String vmName      = System.getProperty("java.vm.name");
+    private static final String userName    = System.getProperty("user.name");
+    private static final String compiler    = System.getProperty("sun.management.compiler");
 
     public static boolean isClient() {
         return vmName.endsWith(" Client VM");
@@ -38,6 +45,23 @@
         return vmName.endsWith(" Server VM");
     }
 
+    public static boolean isGraal() {
+        return vmName.endsWith(" Graal VM");
+    }
+
+    public static boolean isMinimal() {
+        return vmName.endsWith(" Minimal VM");
+    }
+
+    public static boolean isEmbedded() {
+        return vmName.contains("Embedded");
+    }
+
+    public static boolean isTieredSupported() {
+        return compiler.contains("Tiered Compilers");
+    }
+
+
     public static boolean is32bit() {
         return dataModel.equals("32");
     }
@@ -46,6 +70,18 @@
         return dataModel.equals("64");
     }
 
+    public static boolean isAix() {
+        return isOs("aix");
+    }
+
+    public static boolean isLinux() {
+        return isOs("linux");
+    }
+
+    public static boolean isOSX() {
+        return isOs("mac");
+    }
+
     public static boolean isSolaris() {
         return isOs("sunos");
     }
@@ -54,14 +90,6 @@
         return isOs("win");
     }
 
-    public static boolean isOSX() {
-        return isOs("mac");
-    }
-
-    public static boolean isLinux() {
-        return isOs("linux");
-    }
-
     private static boolean isOs(String osname) {
         return osName.toLowerCase().startsWith(osname.toLowerCase());
     }
@@ -71,7 +99,8 @@
     }
 
     public static boolean isDebugBuild() {
-        return vmVersion.toLowerCase().contains("debug");
+        return (vmVersion.toLowerCase().contains("debug") ||
+                javaVersion.toLowerCase().contains("debug"));
     }
 
     public static String getVMVersion() {
@@ -80,33 +109,101 @@
 
     // Returns true for sparc and sparcv9.
     public static boolean isSparc() {
-        return isArch("sparc");
+        return isArch("sparc.*");
     }
 
     public static boolean isARM() {
-        return isArch("arm");
+        return isArch("arm.*");
     }
 
     public static boolean isPPC() {
-        return isArch("ppc");
+        return isArch("ppc.*");
     }
 
     public static boolean isX86() {
-        // On Linux it's 'i386', Windows 'x86'
-        return (isArch("i386") || isArch("x86"));
+        // On Linux it's 'i386', Windows 'x86' without '_64' suffix.
+        return isArch("(i386)|(x86(?!_64))");
     }
 
     public static boolean isX64() {
         // On OSX it's 'x86_64' and on other (Linux, Windows and Solaris) platforms it's 'amd64'
-        return (isArch("amd64") || isArch("x86_64"));
+        return isArch("(amd64)|(x86_64)");
     }
 
-    private static boolean isArch(String archname) {
-        return osArch.toLowerCase().startsWith(archname.toLowerCase());
+    private static boolean isArch(String archnameRE) {
+        return Pattern.compile(archnameRE, Pattern.CASE_INSENSITIVE)
+                .matcher(osArch)
+                .matches();
     }
 
     public static String getOsArch() {
         return osArch;
     }
 
+    /**
+     * Return a boolean for whether we expect to be able to attach
+     * the SA to our own processes on this system.
+     */
+    public static boolean shouldSAAttach()
+                               throws IOException {
+
+        if (isAix()) {
+            return false;   // SA not implemented.
+        } else if (isLinux()) {
+            return canPtraceAttachLinux();
+        } else if (isOSX()) {
+            return canAttachOSX();
+        } else {
+            // Other platforms expected to work:
+            return true;
+        }
+    }
+
+    /**
+     * On Linux, first check the SELinux boolean "deny_ptrace" and return false
+     * as we expect to be denied if that is "1".
+     */
+    public static boolean canPtraceAttachLinux()
+                               throws IOException {
+
+        // SELinux deny_ptrace:
+        try(RandomAccessFile file = new RandomAccessFile("/sys/fs/selinux/booleans/deny_ptrace", "r")) {
+            if (file.readByte() != '0') {
+                return false;
+            }
+        }
+        catch(FileNotFoundException ex) {
+            // Ignored
+        }
+
+        // YAMA enhanced security ptrace_scope:
+        // 0 - a process can PTRACE_ATTACH to any other process running under the same uid
+        // 1 - restricted ptrace: a process must be a children of the inferior or user is root
+        // 2 - only processes with CAP_SYS_PTRACE may use ptrace or user is root
+        // 3 - no attach: no processes may use ptrace with PTRACE_ATTACH
+
+        try(RandomAccessFile file = new RandomAccessFile("/proc/sys/kernel/yama/ptrace_scope", "r")) {
+            byte yama_scope = file.readByte();
+            if (yama_scope == '3') {
+                return false;
+            }
+
+            if (!userName.equals("root") && yama_scope != '0') {
+                return false;
+            }
+        }
+        catch(FileNotFoundException ex) {
+            // Ignored
+        }
+
+        // Otherwise expect to be permitted:
+        return true;
+    }
+
+    /**
+     * On OSX, expect permission to attach only if we are root.
+     */
+    public static boolean canAttachOSX() {
+        return userName.equals("root");
+    }
 }
--- a/jdk/test/sun/tools/jmap/heapconfig/JMapHeapConfigTest.java	Wed Feb 18 03:16:48 2015 -0800
+++ b/jdk/test/sun/tools/jmap/heapconfig/JMapHeapConfigTest.java	Wed Feb 18 03:45:06 2015 -0800
@@ -37,6 +37,7 @@
 import java.util.List;
 import java.util.Map;
 import jdk.testlibrary.Utils;
+import jdk.testlibrary.Platform;
 
 public class JMapHeapConfigTest {
 
@@ -109,9 +110,21 @@
         }
     }
 
-    public static void main(String[] args) {
+    public static void main(String[] args) throws Exception {
         System.out.println("Starting JMapHeapConfigTest");
 
+        if (!Platform.shouldSAAttach()) {
+            // Silently skip the test if we don't have enough permissions to attach
+            System.err.println("Error! Insufficient permissions to attach.");
+            return;
+        }
+
+        if (!LingeredApp.isLastModifiedWorking()) {
+            // Exact behaviour of the test depends to operating system and the test nature,
+            // so just print the warning and continue
+            System.err.println("Warning! Last modified time doesn't work.");
+        }
+
         boolean mx_found = false;
         List<String> jvmOptions = Utils.getVmOptions();
         for (String option : jvmOptions) {
--- a/jdk/test/sun/tools/jmap/heapconfig/LingeredApp.java	Wed Feb 18 03:16:48 2015 -0800
+++ b/jdk/test/sun/tools/jmap/heapconfig/LingeredApp.java	Wed Feb 18 03:45:06 2015 -0800
@@ -363,6 +363,41 @@
     }
 
     /**
+     * LastModified time might not work correctly in some cases it might
+     * cause later failures
+     */
+
+    public static boolean isLastModifiedWorking() {
+        boolean sane = true;
+        try {
+            long lm = lastModified(".");
+            if (lm == 0) {
+                System.err.println("SANITY Warning! The lastModifiedTime() doesn't work on this system, it returns 0");
+                sane = false;
+            }
+
+            long now = epoch();
+            if (lm > now) {
+                System.err.println("SANITY Warning! The Clock is wrong on this system lastModifiedTime() > getTime()");
+                sane = false;
+            }
+
+            setLastModified(".", epoch());
+            long lm1 = lastModified(".");
+            if (lm1 <= lm) {
+                System.err.println("SANITY Warning! The setLastModified doesn't work on this system");
+                sane = false;
+            }
+        }
+        catch(IOException e) {
+            System.err.println("SANITY Warning! IOException during sanity check " + e);
+            sane = false;
+        }
+
+        return sane;
+    }
+
+    /**
      * This part is the application it self
      */
     public static void main(String args[]) {
@@ -378,16 +413,8 @@
             Path path = Paths.get(theLockFileName);
 
             while (Files.exists(path)) {
-                long lm = lastModified(theLockFileName);
-                long now = epoch();
-
-                // A bit of paranoja, don't allow test app to run more than an hour
-                if (now - lm > 3600) {
-                    throw new IOException("Lock is too old. Aborting");
-                }
-
-                // Touch lock to indicate our rediness
-                setLastModified(theLockFileName, now);
+                // Touch the lock to indicate our readiness
+                setLastModified(theLockFileName, epoch());
                 Thread.sleep(spinDelay);
             }
 
--- a/jdk/test/sun/tools/jmap/heapconfig/LingeredAppTest.java	Wed Feb 18 03:16:48 2015 -0800
+++ b/jdk/test/sun/tools/jmap/heapconfig/LingeredAppTest.java	Wed Feb 18 03:45:06 2015 -0800
@@ -31,8 +31,6 @@
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.logging.Level;
-import java.util.logging.Logger;
 
 public class LingeredAppTest {