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

Unified Diff: LayoutTests/http/tests/websocket/resources/close-common.js

Issue 913273004: [OBSOLETE] De-flake the websocket/close.html layout test (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Hack around Mac timeouts. Created 5 years, 9 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
Index: LayoutTests/http/tests/websocket/resources/close-common.js
diff --git a/LayoutTests/http/tests/websocket/resources/close-common.js b/LayoutTests/http/tests/websocket/resources/close-common.js
new file mode 100644
index 0000000000000000000000000000000000000000..00fa3bff586a1bf7268b10e7aacefbf1acd1a8cb
--- /dev/null
+++ b/LayoutTests/http/tests/websocket/resources/close-common.js
@@ -0,0 +1,258 @@
+// Variables used in js-test.js assertions.
+var exceptionName;
+var exceptionMessage;
+var exceptionProto;
+var closeEvent;
+
+// Constants.
+const invalidAccessErr = "InvalidAccessError";
+const syntaxErr = "SyntaxError";
+const normalClosure = 1000;
+const abnormalClosure = 1006;
+const url = "ws://127.0.0.1:8880/close";
+const ws_handlers = ["onopen", "onerror", "onclose", "onmessage"];
+
+// An explicit timeout is used so that we can capture the test output.
+var timeout;
+
+const badCodesTestCodes = [
+ 999, 1001, 2999, 5000, 65536 + 1000, 0x100000000 + 1000, 2999.9, NaN, "0", "100", 1/0, -1/0, 0/0,
+];
+
+const badReasonTestReasons = [
+ "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234", // 124 Byte
+ "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012\u00a9", // length is 123, but 124 Byte in UTF-8
+];
+
+function createFailHandler(name, ws, reject)
+{
+ return function() {
+ removeAllHandlers(ws);
+ reject(name + " was called.");
+ };
+}
+
+function setDefaultHandlers(ws, reject)
+{
+ ws_handlers.forEach(function(handler) {
+ ws[handler] = createFailHandler(handler, ws, reject);
+ });
+}
+
+// Ensure that the WebSocket can be garbage collected.
+function removeAllHandlers(ws)
+{
+ ws_handlers.forEach(function(handler) {
+ ws[handler] = undefined;
+ });
+}
+
+// Verify that close() throws an exception when an invalid close code is passed.
+function badCodesTest()
+{
+ return new Promise(function(resolve, reject) {
+ debug("badCodesTest: started");
+ var ws = new WebSocket(url);
+ setDefaultHandlers(ws, reject);
+ for (var test_code of badCodesTestCodes) {
+ debug("badCodesTest: " + test_code);
+ try {
+ ws.close(test_code);
+ reject("Exception not thrown for code " + test_code);
+ return;
+ } catch (e) {
+ exceptionName = e.name;
+ exceptionMessage = e.message;
+ exceptionProto = Object.getPrototypeOf(e);
+ shouldBeTrue("exceptionProto === DOMException.prototype");
+ shouldBeEqualToString("exceptionName", invalidAccessErr);
+ var expectedCode = test_code;
+ if (!expectedCode)
+ expectedCode = 0;
+ else if (expectedCode > 65535)
+ expectedCode = 65535;
+ else if (expectedCode < 0)
+ expectedCode = 0;
+ expectedCode = Math.floor(expectedCode);
+ shouldBeEqualToString("exceptionMessage", "Failed to execute 'close' on 'WebSocket': The code must be either 1000, or between 3000 and 4999. " + expectedCode + " is neither.");
+ }
+ }
+ removeAllHandlers(ws);
+ resolve();
+ });
+}
+
+// Verify that passing a valid code does not throw an exception.
+function goodCodeTest()
+{
+ return new Promise(function(resolve, reject) {
+ debug("goodCodeTest: started");
+ var ws = new WebSocket(url);
+ setDefaultHandlers(ws, reject);
+ ws.onclose = function(e) {
+ closeEvent = e;
+ shouldBeEqualToNumber("closeEvent.code", abnormalClosure);
+ resolve();
+ };
+ ws.onerror = function() {
+ testPassed("onerror was called.");
+ };
+ ws.close(1000.0);
+ });
+}
+
+// Verify that unpaired surrogates in the reason string are converted to U+FFFD
+// before sending to the remote server.
+function invalidUnicodeReasonTest()
+{
+ return new Promise(function(resolve, reject) {
+ debug("invalidUnicodeReasonTest: started");
+ var ws = new WebSocket(url);
+ setDefaultHandlers(ws, reject);
+ ws.onopen = function() {
+ // 0xD834 is an unpaired surrogate.
+ var invalidString = String.fromCharCode(0xD834);
+ ws.close(1000, invalidString);
+ };
+ ws.onclose = function(e) {
+ closeEvent = e;
+ shouldBeTrue("closeEvent.wasClean");
+ shouldBeEqualToString("closeEvent.reason", "\uFFFD");
+ resolve();
+ };
+ });
+}
+
+// Verify that invalid reason strings passed to close() result in an exception
+// being thrown.
+function badReasonTest()
+{
+ return new Promise(function(resolve, reject) {
+ debug("badReasonTest: started");
+ var ws = new WebSocket(url);
+ setDefaultHandlers(ws, reject);
+ for (var test_reason of badReasonTestReasons) {
+ debug("badReasonTest: " + test_reason);
+ try {
+ ws.close(normalClosure, test_reason);
+ reject("Exception not thrown for bad reason " + test_reason);
+ return;
+ } catch (e) {
+ exceptionName = e.name;
+ exceptionProto = Object.getPrototypeOf(e);
+ shouldBeTrue("exceptionProto === DOMException.prototype");
+ shouldBeEqualToString("exceptionName", syntaxErr);
+ }
+ }
+ removeAllHandlers(ws);
+ resolve();
+ });
+}
+
+// Verify that a valid reason code passed to close() does not result in an
+// exception.
+function goodReasonTest()
+{
+ return new Promise(function(resolve, reject) {
+ debug("goodReasonTest: started");
+ var ws = new WebSocket(url);
+ setDefaultHandlers(ws, reject);
+ ws.onclose = function(e) {
+ closeEvent = e;
+ shouldBeEqualToNumber("closeEvent.code", abnormalClosure);
+ resolve();
+ };
+ ws.onerror = function() {
+ testPassed("onerror was called.");
+ };
+ // 123 byte reason should not throw.
+ ws.close(normalClosure, "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123");
+ });
+}
+
+// Verify that valid close codes and reasons are correctly send to the
+// WebSocket server.
+function codeAndReasonTest()
+{
+ const codes = [
+ 1000,
+ 3000,
+ 4000,
+ 4999
+ ];
+ const reasons = [
+ "OK, Bye!",
+ "3000",
+ "code is 4000",
+ "\u00a9 Google"
+ ];
+ return new Promise(function(resolve, reject) {
+ debug("codeAndReasonTest: started");
+ // Tests are run in series to produce deterministic output.
+ var promise = Promise.resolve();
+ for (var id = 0; id < codes.length; ++id) {
+ promise = promise.then(codeAndReasonSingleCase(codes[id], reasons[id]));
+ }
+ promise.then(resolve);
+ });
+}
+
+// (Return a function which returns a Promise to) handle a single code/reason
+// pair for the codeAndReasonTest.
+function codeAndReasonSingleCase(test_code, test_reason)
+{
+ return function() {
+ return new Promise(function(resolve, reject) {
+ debug("codeAndReasonTest: " + test_code + ", '" + test_reason + "'");
+ var ws = new WebSocket(url);
+ setDefaultHandlers(ws, reject);
+ ws.onopen = function() {
+ ws.close(test_code, test_reason);
+ };
+ ws.onclose = function(e) {
+ closeEvent = e;
+ shouldBeTrue("closeEvent.wasClean");
+ shouldBeEqualToNumber("closeEvent.code", test_code);
+ shouldBeEqualToString("closeEvent.reason", test_reason);
+ resolve();
+ };
+ });
+ };
+}
+
+function cleanup()
+{
+ clearTimeout(timeout);
+ finishJSTest();
+}
+
+function onTimeout()
+{
+ handleRejection("Timeout");
+}
+
+function handleRejection(reason)
+{
+ if (reason instanceof Error) {
+ // Get a stack trace if an exception fired.
+ testFailed(reason.stack);
+ } else {
+ testFailed(reason);
+ }
+ cleanup();
+}
+
+function testClose()
+{
+ // Set an explicit timeout in order to keep text output on failure.
+ timeout = setTimeout(onTimeout, 5000);
+ // Tests are run in series to produce deterministic output.
+ badCodesTest()
+ .then(goodCodeTest)
+ .then(invalidUnicodeReasonTest)
+ .then(badReasonTest)
+ .then(goodReasonTest)
+ .then(codeAndReasonTest)
+ .then(cleanup)
+ .catch(handleRejection);
+}

Powered by Google App Engine
This is Rietveld 408576698