Revision: 6332
Author: j...@google.com
Date: Thu Oct  8 15:44:08 2009
Log: Fix a problem where JL's batching changes were botched in the process  
of
merging, filter out annoying log spam when JUnit changes to the next module
(basically the JSNI call Window.Location.replace never returns and we get a
dropped connection).

http://code.google.com/p/google-web-toolkit/source/detail?r=6332

Modified:
  /changes/jat/abstractui/dev/core/src/com/google/gwt/dev/HostedModeBase.java
   
/changes/jat/abstractui/dev/core/test/com/google/gwt/dev/shell/BrowserChannelServerTest.java
   
/changes/jat/abstractui/dev/oophm/src/com/google/gwt/dev/shell/BrowserChannel.java
   
/changes/jat/abstractui/dev/oophm/src/com/google/gwt/dev/shell/BrowserChannelServer.java
   
/changes/jat/abstractui/dev/oophm/src/com/google/gwt/dev/shell/BrowserListener.java
  /changes/jat/abstractui/user/src/com/google/gwt/junit/BatchingStrategy.java
  /changes/jat/abstractui/user/src/com/google/gwt/junit/JUnitShell.java

=======================================
---  
/changes/jat/abstractui/dev/core/src/com/google/gwt/dev/HostedModeBase.java     
 
Thu Oct  8 14:16:26 2009
+++  
/changes/jat/abstractui/dev/core/src/com/google/gwt/dev/HostedModeBase.java     
 
Thu Oct  8 15:44:08 2009
@@ -62,6 +62,7 @@
  import java.util.Map;
  import java.util.Random;
  import java.util.Set;
+import java.util.concurrent.Semaphore;

  /**
   * The main executable class for the hosted mode shell. This class must  
not have
@@ -316,7 +317,7 @@
        return true;
      }
    }
-
+
    /**
     * Handles the -noserver command line flag.
     */
@@ -607,7 +608,7 @@

      void setNoServer(boolean isNoServer);
    }
-
+
    /**
     * Controls what port to use.
     *
@@ -716,7 +717,7 @@
     */
    private Set<String> alreadySeenModules = new HashSet<String>();

-  private final Object blockUntilDone = new Object();
+  private final Semaphore blockUntilDone = new Semaphore(0);

    private BrowserWidgetHostImpl browserHost = new  
UiBrowserWidgetHostImpl();

@@ -785,9 +786,7 @@
          launchStartupUrls(getTopLogger());
        }

-      synchronized (blockUntilDone) {
-        blockUntilDone.wait();
-      }
+      blockUntilDone.acquire();
      } catch (Exception e) {
        e.printStackTrace();
      } finally {
@@ -999,9 +998,7 @@
    }

    protected final void setDone() {
-    synchronized (blockUntilDone) {
-      blockUntilDone.notifyAll();
-    }
+    blockUntilDone.release();
    }

    protected final void setHeadless(boolean headlessMode) {
=======================================
---  
/changes/jat/abstractui/dev/core/test/com/google/gwt/dev/shell/BrowserChannelServerTest.java
     
Wed Oct  7 09:24:31 2009
+++  
/changes/jat/abstractui/dev/core/test/com/google/gwt/dev/shell/BrowserChannelServerTest.java
     
Thu Oct  8 15:44:08 2009
@@ -53,7 +53,7 @@
      public TestBrowserChannelServer(TreeLogger logger,
          InputStream inputStream, OutputStream outputStream,
          SessionHandler handler) throws IOException {
-      super(logger, inputStream, outputStream, handler);
+      super(logger, inputStream, outputStream, handler, true);
      }

      @Override
=======================================
---  
/changes/jat/abstractui/dev/oophm/src/com/google/gwt/dev/shell/BrowserChannel.java
       
Thu Oct  8 08:49:57 2009
+++  
/changes/jat/abstractui/dev/oophm/src/com/google/gwt/dev/shell/BrowserChannel.java
       
Thu Oct  8 15:44:08 2009
@@ -25,17 +25,30 @@
  import java.io.BufferedOutputStream;
  import java.io.DataInputStream;
  import java.io.DataOutputStream;
+import java.io.EOFException;
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.OutputStream;
  import java.io.UnsupportedEncodingException;
  import java.net.Socket;
+import java.net.SocketException;
  import java.util.Set;

  /**
   *
   */
  public abstract class BrowserChannel {
+
+  /**
+   * An error indicating that the remote side died and we should unroll the
+   * call stack as painlessly as possible to allow cleanup.
+   */
+  public static class RemoteDeathError extends Error {
+
+    public RemoteDeathError(Throwable cause) {
+      super("Remote connection lost", cause);
+    }
+  }

    /**
     * Class representing a reference to a Java object.
@@ -1314,11 +1327,15 @@

      public static void send(BrowserChannel channel, boolean isException,
          Value returnValue) throws IOException {
-      final DataOutputStream stream = channel.getStreamToOtherSide();
-      stream.writeByte(MessageType.RETURN.getId());
-      stream.writeBoolean(isException);
-      channel.writeValue(stream, returnValue);
-      stream.flush();
+      try {
+        final DataOutputStream stream = channel.getStreamToOtherSide();
+        stream.writeByte(MessageType.RETURN.getId());
+        stream.writeBoolean(isException);
+        channel.writeValue(stream, returnValue);
+        stream.flush();
+      } catch (SocketException e) {
+        throw new RemoteDeathError(e);
+      }
      }

      public static void send(BrowserChannel channel,
@@ -1630,28 +1647,35 @@
    public void reactToMessages(SessionHandler handler) throws IOException,
        BrowserChannelException {
      do {
-      getStreamToOtherSide().flush();
-      MessageType messageType =  
Message.readMessageType(getStreamFromOtherSide());
-      switch (messageType) {
-        case FREE_VALUE:
-          final FreeMessage freeMsg = FreeMessage.receive(this);
-          handler.freeValue(this, freeMsg.getIds());
-          break;
-        case INVOKE:
-          final InvokeOnServerMessage imsg =  
InvokeOnServerMessage.receive(this);
-          ExceptionOrReturnValue result = handler.invoke(this,  
imsg.getThis(),
-              imsg.getMethodDispatchId(), imsg.getArgs());
-          sendFreedValues();
-          ReturnMessage.send(this, result);
-          break;
-        case INVOKE_SPECIAL:
-          handleInvokeSpecial(handler);
-          break;
-        case QUIT:
-          return;
-        default:
-          throw new BrowserChannelException("Invalid message type "
-              + messageType);
+      try {
+        getStreamToOtherSide().flush();
+        MessageType messageType = Message.readMessageType(
+            getStreamFromOtherSide());
+        switch (messageType) {
+          case FREE_VALUE:
+            final FreeMessage freeMsg = FreeMessage.receive(this);
+            handler.freeValue(this, freeMsg.getIds());
+            break;
+          case INVOKE:
+            InvokeOnServerMessage imsg =  
InvokeOnServerMessage.receive(this);
+            ExceptionOrReturnValue result = handler.invoke(this,  
imsg.getThis(),
+                imsg.getMethodDispatchId(), imsg.getArgs());
+            sendFreedValues();
+            ReturnMessage.send(this, result);
+            break;
+          case INVOKE_SPECIAL:
+            handleInvokeSpecial(handler);
+            break;
+          case QUIT:
+            return;
+          default:
+            throw new BrowserChannelException("Invalid message type "
+                + messageType);
+        }
+      } catch (SocketException e) {
+        throw new RemoteDeathError(e);
+      } catch (EOFException e) {
+        throw new RemoteDeathError(e);
        }
      } while (true);
    }
@@ -1659,28 +1683,39 @@
    public ReturnMessage reactToMessagesWhileWaitingForReturn(
        SessionHandler handler) throws IOException, BrowserChannelException {
      do {
-      getStreamToOtherSide().flush();
-      MessageType messageType =  
Message.readMessageType(getStreamFromOtherSide());
-      switch (messageType) {
-        case FREE_VALUE:
-          final FreeMessage freeMsg = FreeMessage.receive(this);
-          handler.freeValue(this, freeMsg.getIds());
-          break;
-        case RETURN:
-          return ReturnMessage.receive(this);
-        case INVOKE:
-          final InvokeOnServerMessage imsg =  
InvokeOnServerMessage.receive(this);
-          ExceptionOrReturnValue result = handler.invoke(this,  
imsg.getThis(),
-              imsg.getMethodDispatchId(), imsg.getArgs());
-          sendFreedValues();
-          ReturnMessage.send(this, result);
-          break;
-        case INVOKE_SPECIAL:
-          handleInvokeSpecial(handler);
-          break;
-        default:
-          throw new BrowserChannelException("Invalid message type "
-              + messageType + " received waiting for return.");
+      try {
+        getStreamToOtherSide().flush();
+        MessageType messageType = Message.readMessageType(
+            getStreamFromOtherSide());
+        switch (messageType) {
+          case FREE_VALUE:
+            final FreeMessage freeMsg = FreeMessage.receive(this);
+            handler.freeValue(this, freeMsg.getIds());
+            break;
+          case RETURN:
+            return ReturnMessage.receive(this);
+          case INVOKE:
+            InvokeOnServerMessage imsg =  
InvokeOnServerMessage.receive(this);
+            ExceptionOrReturnValue result = handler.invoke(this,  
imsg.getThis(),
+                imsg.getMethodDispatchId(), imsg.getArgs());
+            sendFreedValues();
+            ReturnMessage.send(this, result);
+            break;
+          case INVOKE_SPECIAL:
+            handleInvokeSpecial(handler);
+            break;
+          case QUIT:
+            // if we got an unexpected QUIT here, the remote plugin  
probably
+            // realized it was dying and had time to close the socket  
properly.
+            throw new RemoteDeathError(null);
+          default:
+            throw new BrowserChannelException("Invalid message type "
+                + messageType + " received waiting for return.");
+        }
+      } catch (SocketException e) {
+        throw new RemoteDeathError(e);
+      } catch (EOFException e) {
+        throw new RemoteDeathError(e);
        }
      } while (true);
    }
=======================================
---  
/changes/jat/abstractui/dev/oophm/src/com/google/gwt/dev/shell/BrowserChannelServer.java
         
Thu Oct  8 08:49:57 2009
+++  
/changes/jat/abstractui/dev/oophm/src/com/google/gwt/dev/shell/BrowserChannelServer.java
         
Thu Oct  8 15:44:08 2009
@@ -64,7 +64,9 @@

    private static final Object cacheLock = new Object();

-  private SessionHandler handler;
+  private final SessionHandler handler;
+
+  private final boolean ignoreRemoteDeath;

    private final ServerObjectsTable javaObjectsInBrowser = new  
ServerObjectsTable();

@@ -77,10 +79,11 @@
    private int protocolVersion = -1;

    public BrowserChannelServer(TreeLogger initialLogger, Socket socket,
-      SessionHandler handler) throws IOException {
+      SessionHandler handler, boolean ignoreRemoteDeath) throws  
IOException {
      super(socket, new ServerObjectRefFactory());
      this.handler = handler;
      this.logger = initialLogger;
+    this.ignoreRemoteDeath = ignoreRemoteDeath;
      Thread thread = new Thread(this);
      thread.setDaemon(true);
      thread.setName("Hosted mode worker");
@@ -89,10 +92,12 @@

    // @VisibleForTesting
    BrowserChannelServer(TreeLogger initialLogger, InputStream inputStream,
-      OutputStream outputStream, SessionHandler handler) throws  
IOException {
+      OutputStream outputStream, SessionHandler handler,
+      boolean ignoreRemoteDeath) throws IOException {
      super(inputStream, outputStream, new ServerObjectRefFactory());
      this.handler = handler;
      this.logger = initialLogger;
+    this.ignoreRemoteDeath = ignoreRemoteDeath;
      Thread thread = new Thread(this);
      thread.setDaemon(true);
      thread.setName("Hosted mode worker");
@@ -334,6 +339,10 @@
        // send LoadModule response
        ReturnMessage.send(this, false, new Value());
        reactToMessages(handler);
+    } catch (RemoteDeathError e) {
+      if (!ignoreRemoteDeath ) {
+        logger.log(TreeLogger.ERROR, e.getMessage(), e);
+      }
      } finally {
        handler.unloadModule(this, moduleName);
      }
=======================================
---  
/changes/jat/abstractui/dev/oophm/src/com/google/gwt/dev/shell/BrowserListener.java
      
Sun Sep 20 12:33:31 2009
+++  
/changes/jat/abstractui/dev/oophm/src/com/google/gwt/dev/shell/BrowserListener.java
      
Thu Oct  8 15:44:08 2009
@@ -36,6 +36,8 @@

    private Thread listenThread;

+  private boolean ignoreRemoteDeath = false;
+
    /**
     * Listens for new connections from browsers.
     */
@@ -64,7 +66,7 @@
                }

                BrowserChannelServer server = new  
BrowserChannelServer(branch,
-                  sock, handler);
+                  sock, handler, ignoreRemoteDeath);
                /*
                 * This object is special-cased by the SessionHandler, used  
for
                 * methods needed by the client like  
hasMethod/hasProperty/etc.
@@ -115,4 +117,15 @@
        listenThread.start();
      }
    }
-}
+
+  /**
+   * Set any created BrowserChannelServers to ignore remote deaths.
+   *
+   * <p>This is most commonly wanted by JUnitShell.
+   *
+   * @param ignoreRemoteDeath
+   */
+  public void setIgnoreRemoteDeath(boolean ignoreRemoteDeath) {
+    this.ignoreRemoteDeath  = ignoreRemoteDeath;
+  }
+}
=======================================
---  
/changes/jat/abstractui/user/src/com/google/gwt/junit/BatchingStrategy.java     
 
Fri Oct  2 08:37:20 2009
+++  
/changes/jat/abstractui/user/src/com/google/gwt/junit/BatchingStrategy.java     
 
Thu Oct  8 15:44:08 2009
@@ -49,11 +49,11 @@
      Set<TestInfo> toExecute =  
GWTTestCase.getTestsForModule(syntheticModuleName).getTests();
      Set<TestInfo> toRemove = new HashSet<TestInfo>();
      // TODO(jat): merge problem?
-//    for (TestInfo info : toExecute) {
-//      if (JUnitShell.mustNotExecuteTest(info.)) {
-//        toRemove.add(info);
-//      }
-//    }
+    for (TestInfo info : toExecute) {
+      if (JUnitShell.mustNotExecuteTest(info)) {
+        toRemove.add(info);
+      }
+    }
      toExecute.removeAll(toRemove);
      return toExecute;
    }
=======================================
--- /changes/jat/abstractui/user/src/com/google/gwt/junit/JUnitShell.java       
 
Thu Oct  8 14:16:26 2009
+++ /changes/jat/abstractui/user/src/com/google/gwt/junit/JUnitShell.java       
 
Thu Oct  8 15:44:08 2009
@@ -361,19 +361,34 @@
     * @return the list of remote user agents
     */
    public static String[] getRemoteUserAgents() {
-    return getUnitTestShell().remoteUserAgents;
+    if (unitTestShell == null) {
+      return null;
+    }
+    return unitTestShell.remoteUserAgents;
    }

    /**
     * Checks if a testCase should not be executed. Currently, a test is  
either
     * executed on all clients (mentioned in this test) or on no clients.
     *
-   * @param testCase current testCase.
+   * @param testInfo the test info to check
     * @return true iff the test should not be executed on any of the  
specified
     *         clients.
     */
-  public static boolean mustNotExecuteTest(TestCase testCase) {
-    return  
getUnitTestShell().mustNotExecuteTest(getBannedPlatforms(testCase));
+  public static boolean mustNotExecuteTest(TestInfo testInfo) {
+    if (unitTestShell == null) {
+      throw new IllegalStateException(
+          "mustNotExecuteTest cannot be called before runTest()");
+    }
+    try {
+      Class<?> testClass = TestCase.class.getClassLoader().loadClass(
+          testInfo.getTestClass());
+      return unitTestShell.mustNotExecuteTest(getBannedPlatforms(testClass,
+          testInfo.getTestMethod()));
+    } catch (ClassNotFoundException e) {
+      throw new IllegalArgumentException("Could not load test class: "
+          + testInfo.getTestClass());
+    }
    }

    /**
@@ -453,16 +468,19 @@
    }

    /**
-   * returns the set of banned {...@code Platform} for a test method.
+   * Returns the set of banned {...@code Platform} for a test method.
+   *
+   * @param testClass the testClass
+   * @param methodName the name of the test method
     */
-  private static Set<Platform> getBannedPlatforms(TestCase testCase) {
-    Class<?> testClass = testCase.getClass();
+  private static Set<Platform> getBannedPlatforms(Class<?> testClass,
+      String methodName) {
      Set<Platform> bannedSet = EnumSet.noneOf(Platform.class);
      if (testClass.isAnnotationPresent(DoNotRunWith.class)) {
         
bannedSet.addAll(Arrays.asList(testClass.getAnnotation(DoNotRunWith.class).value()));
      }
      try {
-      Method testMethod = testClass.getMethod(testCase.getName());
+      Method testMethod = testClass.getMethod(methodName);
        if (testMethod.isAnnotationPresent(DoNotRunWith.class)) {
          bannedSet.addAll(Arrays.asList(testMethod.getAnnotation(
              DoNotRunWith.class).value()));
@@ -659,6 +677,7 @@
    protected void ensureCodeServerListener() {
      if (developmentMode) {
        super.ensureCodeServerListener();
+      listener.setIgnoreRemoteDeath(true);
      }
    }

@@ -903,7 +922,8 @@
    private void runTestImpl(GWTTestCase testCase, TestResult testResult)
        throws UnableToCompleteException {

-    if (mustNotExecuteTest(testCase)) {
+    if (mustNotExecuteTest(getBannedPlatforms(testCase.getClass(),
+        testCase.getName()))) {
        return;
      }


--~--~---------~--~----~------------~-------~--~----~
http://groups.google.com/group/Google-Web-Toolkit-Contributors
-~----------~----~----~----~------~----~------~--~---

Reply via email to