8005472: com/sun/jmx/remote/NotificationMarshalVersions/TestSerializationMismatch.sh failed on windows
authorjbachorik
Tue, 28 May 2013 15:57:45 +0200
changeset 17720 2337b09003f5
parent 17719 ba3677303a76
child 17721 1d6516794d05
8005472: com/sun/jmx/remote/NotificationMarshalVersions/TestSerializationMismatch.sh failed on windows Reviewed-by: chegar, smarks, dfuchs
jdk/test/ProblemList.txt
jdk/test/com/sun/jmx/remote/NotificationMarshalVersions/Client/Client.java
jdk/test/com/sun/jmx/remote/NotificationMarshalVersions/Server/Server.java
jdk/test/com/sun/jmx/remote/NotificationMarshalVersions/TestSerializationMismatch.java
jdk/test/com/sun/jmx/remote/NotificationMarshalVersions/TestSerializationMismatch.sh
--- a/jdk/test/ProblemList.txt	Mon May 27 17:10:32 2013 +0200
+++ b/jdk/test/ProblemList.txt	Tue May 28 15:57:45 2013 +0200
@@ -151,9 +151,6 @@
 # 6959636
 javax/management/loading/LibraryLoader/LibraryLoaderTest.java	windows-all
 
-# 8005472
-com/sun/jmx/remote/NotificationMarshalVersions/TestSerializationMismatch.sh windows-all
-
 ############################################################################
 
 # jdk_math
--- a/jdk/test/com/sun/jmx/remote/NotificationMarshalVersions/Client/Client.java	Mon May 27 17:10:32 2013 +0200
+++ b/jdk/test/com/sun/jmx/remote/NotificationMarshalVersions/Client/Client.java	Tue May 28 15:57:45 2013 +0200
@@ -1,47 +1,78 @@
 
-import java.nio.charset.Charset;
-import java.nio.file.FileSystems;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.StandardWatchEventKinds;
-import java.nio.file.WatchEvent;
-import java.nio.file.WatchService;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
 import javax.management.MBeanServerConnection;
 import javax.management.Notification;
 import javax.management.NotificationListener;
 import javax.management.ObjectName;
+import javax.management.remote.JMXConnectionNotification;
 import javax.management.remote.JMXConnector;
 import javax.management.remote.JMXConnectorFactory;
 import javax.management.remote.JMXServiceURL;
 
 public class Client {
-    public static void main(String[] argv) throws Exception {
-        if (argv.length != 1) throw new IllegalArgumentException("Expecting exactly one jmx url argument");
+    public static void run(String url) throws Exception {
+        final int notifEmittedCnt = 10;
+        final CountDownLatch counter = new CountDownLatch(notifEmittedCnt);
+        final Set<Long> seqSet = Collections.synchronizedSet(new HashSet<Long>());
+        final AtomicBoolean duplNotification = new AtomicBoolean();
 
-        JMXServiceURL serverUrl = new JMXServiceURL(argv[0]);
+        JMXServiceURL serverUrl = new JMXServiceURL(url);
 
         ObjectName name = new ObjectName("test", "foo", "bar");
         JMXConnector jmxConnector = JMXConnectorFactory.connect(serverUrl);
         System.out.println("client connected");
         jmxConnector.addConnectionNotificationListener(new NotificationListener() {
+            @Override
             public void handleNotification(Notification notification, Object handback) {
-                System.err.println("no!" + notification);
+                System.out.println("connection notification: " + notification);
+                if (!seqSet.add(notification.getSequenceNumber())) {
+                    duplNotification.set(true);
+                }
+                if (notification.getType().equals(JMXConnectionNotification.NOTIFS_LOST)) {
+                    long lostNotifs = ((Long)((JMXConnectionNotification)notification).getUserData()).longValue();
+                    for(int i=0;i<lostNotifs;i++) {
+                        counter.countDown();
+                    }
+                }
             }
         }, null, null);
         MBeanServerConnection jmxServer = jmxConnector.getMBeanServerConnection();
 
         jmxServer.addNotificationListener(name, new NotificationListener() {
+            @Override
             public void handleNotification(Notification notification, Object handback) {
-                System.out.println("client got:" + notification);
+                System.out.println("client got: " + notification);
+                if (!seqSet.add(notification.getSequenceNumber())) {
+                    duplNotification.set(true);
+                }
+                counter.countDown();
             }
         }, null, null);
 
-        for(int i=0;i<10;i++) {
-            System.out.println("client invoking foo");
+        System.out.println("client invoking foo (" + notifEmittedCnt + " times)");
+        for(int i=0;i<notifEmittedCnt;i++) {
+            System.out.print(".");
             jmxServer.invoke(name, "foo", new Object[]{}, new String[]{});
-            Thread.sleep(50);
         }
-
-        System.err.println("happy!");
+        System.out.println();
+        try {
+            System.out.println("waiting for " + notifEmittedCnt + " notifications to arrive");
+            if (!counter.await(30, TimeUnit.SECONDS)) {
+                throw new InterruptedException();
+            }
+            if (duplNotification.get()) {
+                System.out.println("ERROR: received duplicated notifications");
+                throw new Error("received duplicated notifications");
+            }
+            System.out.println("\nshutting down client");
+        } catch (InterruptedException e) {
+            System.out.println("ERROR: notification processing thread interrupted");
+            throw new Error("notification thread interrupted unexpectedly");
+        }
     }
 }
--- a/jdk/test/com/sun/jmx/remote/NotificationMarshalVersions/Server/Server.java	Mon May 27 17:10:32 2013 +0200
+++ b/jdk/test/com/sun/jmx/remote/NotificationMarshalVersions/Server/Server.java	Tue May 28 15:57:45 2013 +0200
@@ -1,11 +1,6 @@
+import java.io.File;
 import java.lang.management.ManagementFactory;
 import java.net.BindException;
-import java.nio.charset.Charset;
-import java.nio.file.FileSystem;
-import java.nio.file.FileSystems;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.StandardOpenOption;
 import java.rmi.registry.LocateRegistry;
 import java.rmi.server.ExportException;
 import java.util.Random;
@@ -16,7 +11,7 @@
 import javax.management.remote.JMXServiceURL;
 
 public class Server {
-    public static void main(String[] argv) throws Exception {
+    public static String start() throws Exception {
         int serverPort = 12345;
         ObjectName name = new ObjectName("test", "foo", "bar");
         MBeanServer jmxServer = ManagementFactory.getPlatformMBeanServer();
@@ -40,7 +35,7 @@
         JMXServiceURL serverUrl = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:" + serverPort + "/test");
         JMXConnectorServer jmxConnector = JMXConnectorServerFactory.newJMXConnectorServer(serverUrl, null, jmxServer);
         jmxConnector.start();
-        System.out.println(serverUrl);
-        System.err.println("server listening on " + serverUrl);
+
+        return serverUrl.toString();
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/jmx/remote/NotificationMarshalVersions/TestSerializationMismatch.java	Tue May 28 15:57:45 2013 +0200
@@ -0,0 +1,123 @@
+
+import java.io.File;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Arrays;
+
+/**
+ * @test
+ * @summary Tests for the RMI unmarshalling errors not to cause silent failure.
+ * @author Jaroslav Bachorik
+ * @bug 6937053 8005472
+ *
+ * @run clean TestSerializationMismatch
+ * @run main TestSerializationMismatch
+ *
+ */
+public class TestSerializationMismatch {
+    static final String clientDir = "Client";
+    static final String serverDir = "Server";
+    static final String testSrc = System.getProperty("test.src");
+    static final String testSrcDir = testSrc != null ? testSrc : ".";
+    static final String testSrcClientDir = testSrcDir + File.separator + clientDir + File.separator;
+    static final String testSrcServerDir = testSrcDir + File.separator + serverDir + File.separator;
+    static final String testClasses = System.getProperty("test.classes");
+    static final String testClassesDir = testClasses != null ? testClasses : ".";
+    static final String testClassesClientDir = testClassesDir + File.separator + clientDir + File.separator;
+    static final String testClassesServerDir = testClassesDir + File.separator + serverDir + File.separator;
+
+    static final boolean debug = true;
+
+    public static void main(String[] args) throws Exception {
+        setup();
+
+        compileClient();
+        compileServer();
+
+        debug("starting server");
+        String url = startServer();
+        debug("server started and listening on " + url);
+        debug("starting client");
+        startClient(url);
+    }
+
+    static void setup() {
+        debug("setting up the output dirs");
+        cleanupDir(testClassesClientDir);
+        cleanupDir(testClassesServerDir);
+    }
+
+    static void cleanupDir(String path) {
+        debug("cleaning " + path);
+        File dir = new File(path);
+        if (dir.exists()) {
+            for(File src : dir.listFiles()) {
+                boolean rslt = src.delete();
+                debug((rslt == false ? "not " : "") + "deleted " + src);
+            }
+        } else {
+            dir.mkdirs();
+        }
+    }
+
+    static void compileClient() {
+        debug("compiling client");
+        compile("-d" , testClassesClientDir,
+            "-sourcepath", testSrcClientDir,
+            testSrcClientDir + "Client.java",
+            testSrcClientDir + "ConfigKey.java",
+            testSrcClientDir + "TestNotification.java");
+    }
+
+    static void compileServer() {
+        debug("compiling server");
+        compile("-d" , testClassesServerDir,
+            "-sourcepath", testSrcServerDir,
+            testSrcServerDir + "Server.java",
+            testSrcServerDir + "ConfigKey.java",
+            testSrcServerDir + "TestNotification.java",
+            testSrcServerDir + "Ste.java",
+            testSrcServerDir + "SteMBean.java");
+    }
+
+    static String startServer() throws Exception {
+        ClassLoader serverCL = customCL(testClassesServerDir);
+
+        Class serverClz = serverCL.loadClass("Server");
+        Method startMethod = serverClz.getMethod("start");
+        return (String)startMethod.invoke(null);
+    }
+
+    static void startClient(String url) throws Exception {
+        ClassLoader clientCL = customCL(testClassesClientDir);
+
+        Thread.currentThread().setContextClassLoader(clientCL);
+        Class clientClz = clientCL.loadClass("Client");
+        Method runMethod = clientClz.getMethod("run", String.class);
+        runMethod.invoke(null, url);
+    }
+
+    static ClassLoader customCL(String classDir) throws Exception {
+        return new URLClassLoader(
+            new URL[]{
+                new File(classDir).toURI().toURL()
+            },
+            TestSerializationMismatch.class.getClassLoader()
+        );
+    }
+
+    static void debug(Object message) {
+        if (debug) {
+            System.out.println(message);
+        }
+    }
+
+    /* run javac <args> */
+    static void compile(String... args) {
+        debug("Running: javac " + Arrays.toString(args));
+        if (com.sun.tools.javac.Main.compile(args) != 0) {
+            throw new RuntimeException("javac failed: args=" + Arrays.toString(args));
+        }
+    }
+}
--- a/jdk/test/com/sun/jmx/remote/NotificationMarshalVersions/TestSerializationMismatch.sh	Mon May 27 17:10:32 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,93 +0,0 @@
-#
-# Copyright (c) 2005, 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  Tests for the RMI unmarshalling errors not to cause silent failure.
-# @author   Jaroslav Bachorik
-# @bug      6937053
-#
-# @run shell TestSerializationMismatch.sh
-#
-
-#set -x
-
-#Set appropriate jdk
-#
-
-if [ ! -z "${TESTJAVA}" ] ; then
-     jdk="$TESTJAVA"
-else
-     echo "--Error: TESTJAVA must be defined as the pathname of a jdk to test."
-     exit 1
-fi
-
-SERVER_TESTCLASSES=$TESTCLASSES/Server
-CLIENT_TESTCLASSES=$TESTCLASSES/Client
-
-URL_PATH=$SERVER_TESTCLASSES/jmxurl
-
-rm $URL_PATH
-
-mkdir -p $SERVER_TESTCLASSES
-mkdir -p $CLIENT_TESTCLASSES
-
-$TESTJAVA/bin/javac -d $CLIENT_TESTCLASSES $TESTSRC/Client/ConfigKey.java $TESTSRC/Client/TestNotification.java $TESTSRC/Client/Client.java
-$TESTJAVA/bin/javac -d $SERVER_TESTCLASSES $TESTSRC/Server/ConfigKey.java $TESTSRC/Server/TestNotification.java $TESTSRC/Server/SteMBean.java $TESTSRC/Server/Ste.java $TESTSRC/Server/Server.java
-
-startServer()
-{
-   ($TESTJAVA/bin/java -classpath $SERVER_TESTCLASSES Server) 1>$URL_PATH &
-   SERVER_PID=$!
-}
-
-runClient() 
-{
-   while true
-   do
-      [ -f $URL_PATH ] && break
-      sleep 2
-   done
-   read JMXURL < $URL_PATH
-   
-   HAS_ERRORS=`($TESTJAVA/bin/java -classpath $CLIENT_TESTCLASSES Client $JMXURL) 2>&1 | grep -i "SEVERE: Failed to fetch notification, stopping thread. Error is: java.rmi.UnmarshalException"`
-}
-
-startServer
-
-runClient
-
-sleep 1 # wait for notifications to arrive
-
-kill "$SERVER_PID"
-
-if [ -z "$HAS_ERRORS" ]
-then
-  echo "Test PASSED"
-  exit 0
-fi
-
-echo "Test FAILED"
-echo $HAS_ERRORS 1>&2
-exit 1
-