You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2013/08/05 15:40:47 UTC

svn commit: r1510475 - /tomcat/trunk/test/org/apache/catalina/nonblocking/TestNonBlockingAPI.java

Author: markt
Date: Mon Aug  5 13:40:46 2013
New Revision: 1510475

URL: http://svn.apache.org/r1510475
Log:
More refactoring of validation trying to debug failures on OSX with NIO.

Modified:
    tomcat/trunk/test/org/apache/catalina/nonblocking/TestNonBlockingAPI.java

Modified: tomcat/trunk/test/org/apache/catalina/nonblocking/TestNonBlockingAPI.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/catalina/nonblocking/TestNonBlockingAPI.java?rev=1510475&r1=1510474&r2=1510475&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/catalina/nonblocking/TestNonBlockingAPI.java (original)
+++ tomcat/trunk/test/org/apache/catalina/nonblocking/TestNonBlockingAPI.java Mon Aug  5 13:40:46 2013
@@ -53,16 +53,25 @@ import org.apache.tomcat.util.buf.ByteCh
 
 public class TestNonBlockingAPI extends TomcatBaseTest {
 
-    private static final byte[] CHUNK = new byte[1024 * 1024];
-    private static final long WRITE_SIZE  = CHUNK.length * 5;
+    private static final int CHUNK_SIZE = 1024 * 1024;
+    private static final int WRITE_SIZE  = CHUNK_SIZE * 5;
+    private static final byte[] DATA = new byte[WRITE_SIZE];
+
 
     static {
-        byte[] seq = new byte[] {'0', '1', '2', '3', '4', '5', '6', '7',
-                '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
-        int i = 0;
-        while (i < CHUNK.length) {
-            System.arraycopy(seq, 0, CHUNK, i, 16);
-            i += 16;
+        // Use this sequence for padding to make it easier to spot errors
+        byte[] padding = new byte[] {'z', 'y', 'x', 'w', 'v', 'u', 't', 's',
+                'r', 'q', 'p', 'o', 'n', 'm', 'l', 'k'};
+        int blockSize = padding.length;
+
+        for (int i = 0; i < WRITE_SIZE / blockSize; i++) {
+            String hex = String.format("%01X", Integer.valueOf(i));
+            int hexSize = hex.length();
+            int padSize = blockSize - hexSize;
+
+            System.arraycopy(padding, 0, DATA, i * blockSize, padSize);
+            System.arraycopy(
+                    hex.getBytes(), 0, DATA, i * blockSize + padSize, hexSize);
         }
     }
 
@@ -137,7 +146,7 @@ public class TestNonBlockingAPI extends 
         // Validate the result.
         // Response line
         String resultString = result.toString();
-        System.out.println("Read " + resultString.length() + " bytes");
+        System.out.println("Client read " + resultString.length() + " bytes");
         int lineStart = 0;
         int lineEnd = resultString.indexOf('\n', 0);
         String line = resultString.substring(lineStart, lineEnd + 1);
@@ -183,26 +192,46 @@ public class TestNonBlockingAPI extends 
                 System.out.println(line.substring(0, 32));
             } else {
                 System.out.println(line);
-                }
+            }
             if (chunkSize + 2 != line.length()) {
                 System.out.println("Chunk wrong length. Was " + line.length() +
                         " Expected " + (chunkSize + 2));
-                // look for failed position
-                int pos = 0;
-                String seq = "0123456789ABCDEF";
-                // Assume starts with 0
-                while (pos + seq.length() < line.length() &&
-                        line.subSequence(pos, pos + seq.length()).equals(seq)) {
-                    pos += seq.length();
-                }
-                if (pos + seq.length() < line.length()) {
-                    System.out.println("Failed at position " + pos + " " +
-                            line.substring(pos, pos + seq.length()));
-                } else {
-                    System.out.println("Failed at position " + pos + " " +
-                            line.substring(pos));
+
+                byte[] resultBytes = resultString.getBytes();
+
+                // Find error
+                boolean found = false;
+                for (int i = totalBodyRead; i < (totalBodyRead + line.length()); i++) {
+                    if (DATA[i] != resultBytes[lineStart + i - totalBodyRead]) {
+                        int dataStart = i - 16;
+                        if (dataStart < 0) {
+                            dataStart = 0;
+                        }
+                        int dataEnd = i + 16;
+                        if (dataEnd > DATA.length) {
+                            dataEnd = DATA.length;
+                        }
+                        int resultStart = lineStart + i - totalBodyRead - 16;
+                        if (resultStart < 0) {
+                            resultStart = 0;
+                        }
+                        int resultEnd = lineStart + i - totalBodyRead + 16;
+                        if (resultEnd > resultString.length()) {
+                            resultEnd = resultString.length();
+                        }
+                        System.out.println("Mis-match tx: " + new String(
+                                DATA, dataStart, dataEnd - dataStart));
+                        System.out.println("Mis-match rx: " +
+                                resultString.substring(resultStart, resultEnd));
+                        found = true;
+                        break;
+                    }
+                }
+                if (!found) {
+                    System.out.println("No mismatch. Data truncated");
                 }
             }
+
             Assert.assertTrue(line.endsWith("\r\n"));
             Assert.assertEquals(chunkSize + 2, line.length());
 
@@ -474,7 +503,7 @@ public class TestNonBlockingAPI extends 
 
     private class TestWriteListener implements WriteListener {
         AsyncContext ctx;
-        long bytesToDownload = TestNonBlockingAPI.WRITE_SIZE;
+        int written = 0;
         public volatile boolean onErrorInvoked = false;
 
         public TestWriteListener(AsyncContext ctx) {
@@ -484,18 +513,20 @@ public class TestNonBlockingAPI extends 
         @Override
         public void onWritePossible() {
             try {
-                long left = Math.max(bytesToDownload, 0);
                 long start = System.currentTimeMillis();
                 long end = System.currentTimeMillis();
-                long before = left;
-                while (left > 0 && ctx.getResponse().getOutputStream().isReady()) {
-                    ctx.getResponse().getOutputStream().write(CHUNK);
-                    bytesToDownload -= CHUNK.length;
-                    left = Math.max(bytesToDownload, 0);
+                int before = written;
+                while (written < WRITE_SIZE &&
+                        ctx.getResponse().getOutputStream().isReady()) {
+                    ctx.getResponse().getOutputStream().write(
+                            DATA, written, CHUNK_SIZE);
+                    written += CHUNK_SIZE;
                 }
-                System.out.println("Write took:" + (end - start) + " ms. Bytes before=" + before + " after=" + left);
+                System.out.println("Write took:" + (end - start) +
+                        " ms. Bytes before=" + before + " after=" + written);
                 // only call complete if we have emptied the buffer
-                if (left == 0 && ctx.getResponse().getOutputStream().isReady()) {
+                if (ctx.getResponse().getOutputStream().isReady() &&
+                        written == WRITE_SIZE) {
                     // it is illegal to call complete
                     // if there is a write in progress
                     ctx.complete();



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org