Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(172)

Unified Diff: tests/standalone/src/io/WebSocketProtocolProcessorTest.dart

Issue 10173021: Add web socket protocol processor test (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« runtime/bin/websocket_impl.dart ('K') | « runtime/bin/websocket_impl.dart ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tests/standalone/src/io/WebSocketProtocolProcessorTest.dart
diff --git a/tests/standalone/src/io/WebSocketProtocolProcessorTest.dart b/tests/standalone/src/io/WebSocketProtocolProcessorTest.dart
new file mode 100644
index 0000000000000000000000000000000000000000..a605885b590cacdad706919e0cdf986c7627ccc8
--- /dev/null
+++ b/tests/standalone/src/io/WebSocketProtocolProcessorTest.dart
@@ -0,0 +1,218 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#source("../../../../runtime/bin/websocket.dart");
+#source("../../../../runtime/bin/websocket_impl.dart");
+
+class WebSocketFrame {
+ WebSocketFrame(int opcode, List<int> data);
+}
+
+// Class that when hooked up to the web socket protocol processor will
+// collect the message and expect it to be equal to the
+// expectedMessage field when fully received.
+class WebSocketMessageCollector {
+ WebSocketMessageCollector(_WebSocketProtocolProcessor this.processor,
+ [List<int> this.expectedMessage = null]) {
+ processor.onMessageStart = onMessageStart;
+ processor.onMessageData = onMessageData;
+ processor.onMessageEnd = onMessageEnd;
+ processor.onClosed = onClosed;
+ }
+
+ void onMessageStart(int type) {
+ data = new List<int>();
+ }
+
+ void onMessageData(List<int> buffer, int index, int count) {
+ data.addAll(buffer.getRange(index, count));
+ }
+
+ void onMessageEnd() {
+ messageCount++;
+ Expect.listEquals(expectedMessage, data);
+ data = null;
+ }
+
+ void onClosed(int status, String reason) {
+ closeCount++;
+ }
+
+ void onError(e) {
+ Expect.fail("Unexpected error $e");
+ }
+
+ _WebSocketProtocolProcessor processor;
+ List<int> expectedMessage;
+
+ List<int> data;
+ int messageCount = 0;
+ int closeCount = 0;
+}
+
+
+// Web socket constants.
+final int FRAME_OPCODE_TEXT = 1;
+final int FRAME_OPCODE_BINARY = 2;
+
+
+// Function for building a web socket frame.
+List<int> createFrame(bool fin,
+ int opcode,
+ int maskingKey,
+ List<int> data,
+ int offset,
+ int count) {
+ int frameSize = 2;
+ if (count > 125) frameSize += 2;
+ if (count > 65535) frameSize += 6;
+ frameSize += count;
+ // No masking.
+ assert(maskingKey == null);
+ List<int> frame = new List<int>(frameSize);
+ int frameIndex = 0;
+ frame[frameIndex++] = (fin ? 0x80 : 0x00) | opcode;
+ if (count < 126) {
+ frame[frameIndex++] = count;
+ } else if (count < 65536) {
+ frame[frameIndex++] = 126;
+ frame[frameIndex++] = count >> 8;
+ frame[frameIndex++] = count & 0xFF;
+ } else {
+ frame[frameIndex++] = 127;
+ for (int i = 0; i < 8; i++) {
+ frame[frameIndex++] = count >> ((7 - i) * 8) & 0xFF;
+ }
+ }
+ frame.setRange(frameIndex, count, data, offset);
+ return frame;
+}
+
+
+// Test processing messages which are sent in a single frame.
+void testFullMessages() {
+ // Use the same web socket protocol processor for all frames.
+ _WebSocketProtocolProcessor processor = new _WebSocketProtocolProcessor();
+ WebSocketMessageCollector mc = new WebSocketMessageCollector(processor);
+
+ int messageCount = 0;
+
+ void testMessage(int opcode, List<int> message) {
+ mc.expectedMessage = message;
+ List<int> frame = createFrame(
+ true, opcode, null, message, 0, message.length);
+
+ // Update the processor with one big chunk.
+ messageCount++;
+ processor.update(frame, 0, frame.length);
+ Expect.isNull(mc.data);
+ Expect.equals(0, processor._state);
+
+ // Update the processor one byte at the time.
+ messageCount++;
+ for (int i = 0; i < frame.length; i++) {
+ processor.update(frame, i, 1);
+ }
+ Expect.equals(0, processor._state);
+ Expect.isNull(mc.data);
+
+ // Update the processor two bytes at the time.
+ messageCount++;
+ for (int i = 0; i < frame.length; i += 2) {
+ processor.update(frame, i, i + 1 < frame.length ? 2 : 1);
+ }
+ Expect.equals(0, processor._state);
+ Expect.isNull(mc.data);
+ }
+
+ void runTest(int from, int to, int step) {
+ for (int messageLength = from; messageLength < to; messageLength += step) {
+ List<int> message = new List<int>(messageLength);
+ for (int i = 0; i < messageLength; i++) message[i] = i & 0xFF;
+ testMessage(FRAME_OPCODE_TEXT, message);
+ testMessage(FRAME_OPCODE_BINARY, message);
+ }
+ }
+
+ // Test different message sizes.
+ runTest(0, 10, 1);
+ runTest(120, 130, 1);
+ runTest(0, 1000, 100);
+ runTest(65534, 65537, 1);
+ print("Messages test, messages $messageCount");
+ Expect.equals(messageCount, mc.messageCount);
+ Expect.equals(0, mc.closeCount);
+}
+
+
+// Test processing of frames which are split into fragments.
+void testFragmentedMessages() {
+ // Use the same web socket protocol processor for all frames.
+ _WebSocketProtocolProcessor processor = new _WebSocketProtocolProcessor();
+ WebSocketMessageCollector mc = new WebSocketMessageCollector(processor);
+
+ int messageCount = 0;
+ int frameCount = 0;
+
+ void testFragmentMessage(int opcode, List<int> message, int fragmentSize) {
+ messageCount++;
+ int messageIndex = 0;
+ int remaining = message.length;
+ bool firstFrame = true;
+ bool lastFrame = false;
+ while (!lastFrame) {
+ int payloadSize = Math.min(fragmentSize, remaining);
+ lastFrame = payloadSize == remaining;
+ List<int> frame = createFrame(lastFrame,
+ firstFrame ? opcode : 0x00,
+ null,
+ message,
+ messageIndex,
+ payloadSize);
+ frameCount++;
+ messageIndex += payloadSize;
+ processor.update(frame, 0, frame.length);
+ remaining -= payloadSize;
+ firstFrame = false;
+ }
+ }
+
+ void testMessageFragmentation(int opcode, List<int> message) {
+ mc.expectedMessage = message;
+
+ // Test with fragmenting the message in different fragment sizes.
+ if (message.length <= 10) {
+ for (int i = 1; i < 10; i++) {
+ testFragmentMessage(opcode, message, i);
+ }
+ } else {
+ testFragmentMessage(opcode, message, 1);
+ testFragmentMessage(opcode, message, 10);
+ testFragmentMessage(opcode, message, 100);
+ }
+ }
+
+ void runTest(int from, int to, int step) {
+ for (int messageLength = from; messageLength < to; messageLength += step) {
+ List<int> message = new List<int>(messageLength);
+ for (int i = 0; i < messageLength; i++) message[i] = i & 0xFF;
+ testMessageFragmentation(FRAME_OPCODE_TEXT, message);
+ testMessageFragmentation(FRAME_OPCODE_BINARY, message);
+ }
+ }
+
+ // Test different message sizes.
+ runTest(0, 10, 1);
+ runTest(120, 130, 1);
+ runTest(0, 1000, 100);
+ runTest(65534, 65537, 1);
+ print("Fragment messages test, messages $messageCount, frames $frameCount");
+ Expect.equals(messageCount, mc.messageCount);
+ Expect.equals(0, mc.closeCount);
+}
+
+void main() {
+ testFullMessages();
+ testFragmentedMessages();
+}
« runtime/bin/websocket_impl.dart ('K') | « runtime/bin/websocket_impl.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698