diff --git a/dom/webtransport/test/xpcshell/test_simple_conn.js b/dom/webtransport/test/xpcshell/test_simple_conn.js deleted file mode 100644 index c9e4a61ef254..000000000000 --- a/dom/webtransport/test/xpcshell/test_simple_conn.js +++ /dev/null @@ -1,165 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -// Some basic WebTransport tests for: -// * session rejection and redirection -// * session and stream creation -// * reading from incoming streams (uni) -// -// keep eslint happy until it knows about WebTransport -/* global WebTransport:false */ - -"use strict"; - -var h3Port; -var host; - -registerCleanupFunction(async () => { - Services.prefs.clearUserPref("network.dns.localDomains"); - Services.prefs.clearUserPref("network.webtransport.enabled"); - Services.prefs.clearUserPref("network.webtransport.datagrams.enabled"); - Services.prefs.clearUserPref("network.webtransport.redirect.enabled"); -}); - -var { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm"); - -function readFile(file) { - let fstream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance( - Ci.nsIFileInputStream - ); - fstream.init(file, -1, 0, 0); - let data = NetUtil.readInputStreamToString(fstream, fstream.available()); - fstream.close(); - return data; -} - -function addCertFromFile(certdb, filename, trustString) { - let certFile = do_get_file(filename, false); - let pem = readFile(certFile) - .replace(/-----BEGIN CERTIFICATE-----/, "") - .replace(/-----END CERTIFICATE-----/, "") - .replace(/[\r\n]/g, ""); - certdb.addCertFromBase64(pem, trustString); -} - -add_setup(async function setup() { - Services.prefs.setCharPref("network.dns.localDomains", "foo.example.com"); - Services.prefs.setBoolPref("network.webtransport.enabled", true); - Services.prefs.setBoolPref("network.webtransport.datagrams.enabled", true); - Services.prefs.setBoolPref("network.webtransport.redirect.enabled", true); - - h3Port = Services.env.get("MOZHTTP3_PORT"); - Assert.notEqual(h3Port, null); - Assert.notEqual(h3Port, ""); - host = "foo.example.com:" + h3Port; - do_get_profile(); - - let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( - Ci.nsIX509CertDB - ); - // `../unit/` so that unit_ipc tests can use as well - addCertFromFile( - certdb, - "../../../../netwerk/test/unit/http2-ca.pem", - "CTu,u,u" - ); -}); - -add_task(async function test_webtransport_create() { - const wt = new WebTransport("https://" + host + "/success"); - registerCleanupFunction(async () => { - wt.close(); - await wt.closed; - }); - await wt.ready; - wt.close(); - await wt.closed; -}); - -add_task(async function test_redirect_wt() { - let wt = new WebTransport("https://" + host + "/redirect"); - registerCleanupFunction(async () => { - wt.close(); - await wt.ready.catch(e => e); - await wt.closed.catch(e => e); - }); - const e1 = await wt.ready.catch(e => e); - const e2 = await wt.closed.catch(e => e); - - info("redirect ready error: " + e1); - Assert.equal(e1, "WebTransportError: WebTransport connection rejected"); - Assert.equal(e2, "WebTransportError: WebTransport connection rejected"); -}); - -add_task(async function test_reject_wt() { - let wt = new WebTransport("https://" + host + "/reject"); - registerCleanupFunction(async () => { - wt.close(); - await wt.ready.catch(e => e); - await wt.closed.catch(e => e); - }); - const e1 = await wt.ready.catch(e => e); - const e2 = await wt.closed.catch(e => e); - Assert.equal(e1, "WebTransportError: WebTransport connection rejected"); - Assert.equal(e2, "WebTransportError: WebTransport connection rejected"); -}); - -add_task(async function test_immediate_server_close() { - let wt = new WebTransport("https://" + host + "/closeafter0ms"); - registerCleanupFunction(async () => { - wt.close(); - await wt.closed; - }); - await wt.ready; - await wt.closed; - Assert.ok(true); -}); - -add_task(async function test_delayed_server_close() { - let wt = new WebTransport("https://" + host + "/closeafter100ms"); - registerCleanupFunction(async () => { - wt.close(); - await wt.closed; - }); - await wt.ready; - await wt.closed; - Assert.ok(true); -}); - -add_task(async function test_wt_stream_create_bidi() { - let wt = new WebTransport("https://" + host + "/success"); - registerCleanupFunction(async () => { - wt.close(); - await wt.closed; - }); - await wt.ready; - - let bds = await wt.createBidirectionalStream(); - await bds.writable.close(); - await bds.readable.cancel(); - Assert.notEqual(bds, null); - - wt.close(); - await wt.closed; -}); - -add_task(async function test_wt_stream_create_uni() { - let wt = new WebTransport("https://" + host + "/success"); - registerCleanupFunction(async () => { - wt.close(); - await wt.closed; - }); - await wt.ready; - - let uds = await wt.createUnidirectionalStream(); - Assert.notEqual(uds, null); - await uds.close(); - - wt.close(); - await wt.closed; -}); - -// TODO: datagram test -// TODO: getStats tests -// TODO: fix the crash discussed in bug 1822154 diff --git a/dom/webtransport/test/xpcshell/test_simple_stream.js b/dom/webtransport/test/xpcshell/test_simple_stream.js deleted file mode 100644 index ebc40fc5f745..000000000000 --- a/dom/webtransport/test/xpcshell/test_simple_stream.js +++ /dev/null @@ -1,198 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -// keep eslint happy until it knows about WebTransport -/* global WebTransport:false */ -/* global TextDecoderStream:false */ -/* global TextEncoderStream:false */ - -// Using multiple files to reduce racing -// This file tests reading/writing to incoming/outgoing streams (uni & bidi) -// -"use strict"; - -var h3Port; -var host; - -registerCleanupFunction(async () => { - Services.prefs.clearUserPref("network.dns.localDomains"); - Services.prefs.clearUserPref("network.webtransport.enabled"); - Services.prefs.clearUserPref("network.webtransport.datagrams.enabled"); - Services.prefs.clearUserPref("network.webtransport.redirect.enabled"); -}); - -var { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm"); - -function readFile(file) { - let fstream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance( - Ci.nsIFileInputStream - ); - fstream.init(file, -1, 0, 0); - let data = NetUtil.readInputStreamToString(fstream, fstream.available()); - fstream.close(); - return data; -} - -function addCertFromFile(certdb, filename, trustString) { - let certFile = do_get_file(filename, false); - let pem = readFile(certFile) - .replace(/-----BEGIN CERTIFICATE-----/, "") - .replace(/-----END CERTIFICATE-----/, "") - .replace(/[\r\n]/g, ""); - certdb.addCertFromBase64(pem, trustString); -} - -add_setup(async function setup() { - Services.prefs.setCharPref("network.dns.localDomains", "foo.example.com"); - Services.prefs.setBoolPref("network.webtransport.enabled", true); - Services.prefs.setBoolPref("network.webtransport.datagrams.enabled", true); - Services.prefs.setBoolPref("network.webtransport.redirect.enabled", true); - - h3Port = Services.env.get("MOZHTTP3_PORT"); - Assert.notEqual(h3Port, null); - Assert.notEqual(h3Port, ""); - host = "foo.example.com:" + h3Port; - do_get_profile(); - - let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( - Ci.nsIX509CertDB - ); - // `../unit/` so that unit_ipc tests can use as well - addCertFromFile( - certdb, - "../../../../netwerk/test/unit/http2-ca.pem", - "CTu,u,u" - ); -}); - -// Read all chunks from |readable_stream|, decode chunks to a utf-8 string, then -// return the string. (borrowed from wpt tests) -async function read_stream_as_string(readable_stream) { - const decoder = new TextDecoderStream(); - const decode_stream = readable_stream.pipeThrough(decoder); - const reader = decode_stream.getReader(); - - let chunks = ""; - while (true) { - const { value: chunk, done } = await reader.read(); - if (done) { - break; - } - chunks += chunk; - } - reader.releaseLock(); - return chunks; -} - -add_task(async function test_wt_incoming_unidi_stream() { - // trigger stream creation server side and default echo - let wt = new WebTransport( - "https://" + host + "/create_unidi_stream_and_hello" - ); - registerCleanupFunction(async () => { - wt.close(); - await wt.closed; - }); - await wt.ready; - - const streams = await wt.incomingUnidirectionalStreams; - const stream_reader = streams.getReader(); - const { value: recv_stream } = await stream_reader.read(); - let str = await read_stream_as_string(recv_stream); - stream_reader.releaseLock(); - Assert.equal(str, "qwerty"); - - wt.close(); - await wt.closed; -}); - -add_task(async function test_wt_incoming_and_outgoing_unidi_stream() { - // create the client's incoming stream from the server side - // we need it to listen to the echo back - let wt = new WebTransport("https://" + host + "/create_unidi_stream"); - registerCleanupFunction(async () => { - wt.close(); - await wt.closed; - }); - await wt.ready; - - // send hello to server - let expected = "uni_hello"; - let writableStream = await wt.createUnidirectionalStream(); // only triggers NewStream OnWrite - let wsDefaultWriter = writableStream.getWriter(); - await wsDefaultWriter.ready; - let data = new TextEncoder().encode(expected); - await wsDefaultWriter.write(data); // triggers Http3ServerEvent::Data - await wsDefaultWriter.close(); - wsDefaultWriter.releaseLock(); - - // read the echo - const streams = await wt.incomingUnidirectionalStreams; - const stream_reader = streams.getReader(); - const { value: recv_stream } = await stream_reader.read(); - let str = await read_stream_as_string(recv_stream); - Assert.equal(str, expected); - stream_reader.releaseLock(); - await recv_stream.closed; - - wt.close(); - await wt.closed; -}); - -add_task(async function test_wt_outgoing_bidi_stream() { - let wt = new WebTransport("https://" + host + "/success"); - registerCleanupFunction(async () => { - wt.close(); - await wt.closed; - }); - await wt.ready; - - // write to server - let wtbds = await wt.createBidirectionalStream(); - let writableStream = wtbds.writable; - let wsDefaultWriter = writableStream.getWriter(); - await wsDefaultWriter.ready; - let expected = "xyzhello"; - let data = new TextEncoder().encode(expected); - await wsDefaultWriter.write(data); - await wsDefaultWriter.close(); - wsDefaultWriter.releaseLock(); - - // string goes through server and is echo'd back here - const str = await read_stream_as_string(wtbds.readable); - Assert.equal(str, expected); - - wt.close(); - await wt.closed; -}); - -add_task(async function test_wt_incoming_bidi_stream() { - let wt = new WebTransport( - "https://" + host + "/create_bidi_stream_and_hello" - ); - registerCleanupFunction(async () => { - wt.close(); - await wt.closed; - }); - // await wt.ready; // seems to cause hang, so disable - // hang occurs roughly once per --verify run - - const stream_reader = wt.incomingBidirectionalStreams.getReader(); - const { value: bidi_stream } = await stream_reader.read(); - stream_reader.releaseLock(); - - // Write a message to the writable end, and close it. - const encoder = new TextEncoderStream(); - encoder.readable.pipeTo(bidi_stream.writable); - const writer = encoder.writable.getWriter(); - await writer.write("dummy"); // prevents a hang in .only() - await writer.close(); - writer.releaseLock(); - - const str = await read_stream_as_string(bidi_stream.readable); - Assert.equal(str, "asdfg"); - - wt.close(); - await wt.closed; -}); diff --git a/dom/webtransport/test/xpcshell/xpcshell.ini b/dom/webtransport/test/xpcshell/xpcshell.ini index 457e2e488063..816e096aa0a1 100644 --- a/dom/webtransport/test/xpcshell/xpcshell.ini +++ b/dom/webtransport/test/xpcshell/xpcshell.ini @@ -9,15 +9,3 @@ skip-if = os == 'android' || socketprocess_networking os == 'win' && msix # https://bugzilla.mozilla.org/show_bug.cgi?id=1807925 -[test_simple_conn.js] -skip-if = - os == 'android' - socketprocess_networking - os == 'win' && msix # https://bugzilla.mozilla.org/show_bug.cgi?id=1807925 -run-sequentially = http3server -[test_simple_stream.js] -skip-if = - os == 'android' - socketprocess_networking - os == 'win' && msix # https://bugzilla.mozilla.org/show_bug.cgi?id=1807925 -run-sequentially = http3server diff --git a/netwerk/test/http3server/src/main.rs b/netwerk/test/http3server/src/main.rs index b4de9ac03d06..c796207cc132 100644 --- a/netwerk/test/http3server/src/main.rs +++ b/netwerk/test/http3server/src/main.rs @@ -69,9 +69,8 @@ struct Http3TestServer { responses: HashMap>, current_connection_hash: u64, sessions_to_close: HashMap>, - sessions_to_create_stream: Vec<(WebTransportRequest, StreamType, bool)>, + sessions_to_create_stream: Vec<(WebTransportRequest, StreamType)>, webtransport_bidi_stream: HashSet, - webtransport_uni_stream: Vec, } impl ::std::fmt::Display for Http3TestServer { @@ -90,7 +89,6 @@ impl Http3TestServer { sessions_to_close: HashMap::new(), sessions_to_create_stream: Vec::new(), webtransport_bidi_stream: HashSet::new(), - webtransport_uni_stream: Vec::new(), } } @@ -152,25 +150,10 @@ impl Http3TestServer { let mut session = tuple.0; let mut wt_server_stream = session.create_stream(tuple.1).unwrap(); if tuple.1 == StreamType::UniDi { - if tuple.2 { - wt_server_stream.send_data(b"qwerty").unwrap(); - wt_server_stream.stream_close_send().unwrap(); - } else { - // relaying Http3ServerEvent::Data to uni streams - // slows down netwerk/test/unit/test_webtransport_simple.js - // to the point of failure. Only do so when necessary. - self.webtransport_uni_stream.push(wt_server_stream); - } + let content = b"0123456789".to_vec(); + wt_server_stream.send_data(&content).unwrap(); } else { - if tuple.2 { - wt_server_stream.send_data(b"asdfg").unwrap(); - wt_server_stream.stream_close_send().unwrap(); - wt_server_stream - .stream_stop_sending(Error::HttpNoError.code()) - .unwrap(); - } else { - self.webtransport_bidi_stream.insert(wt_server_stream); - } + self.webtransport_bidi_stream.insert(wt_server_stream); } } } @@ -383,24 +366,10 @@ impl HttpServer for Http3TestServer { data, fin, } => { - // echo bidirectional input back to client - if stream.stream_id().is_bidi() { - if self.webtransport_bidi_stream.contains(&stream) { - self.new_response(stream, data); - } + if self.webtransport_bidi_stream.contains(&stream) { + self.new_response(stream, data); break; } - - // echo unidirectional input to back to client - if stream.stream_id().is_uni() { - if !self.webtransport_uni_stream.is_empty() { - let mut s = self.webtransport_uni_stream.pop().unwrap(); - s.send_data(&data).unwrap(); - s.stream_close_send().unwrap(); - } - break; - } - if let Some(r) = self.posts.get_mut(&stream) { *r += data.len(); } @@ -476,11 +445,6 @@ impl HttpServer for Http3TestServer { session .response(&WebTransportSessionAcceptAction::Accept) .unwrap(); - let now = Instant::now(); - if !self.sessions_to_close.contains_key(&now) { - self.sessions_to_close.insert(now, Vec::new()); - } - self.sessions_to_close.get_mut(&now).unwrap().push(session); } else if path == "/closeafter100ms" { session .response(&WebTransportSessionAcceptAction::Accept) @@ -494,48 +458,17 @@ impl HttpServer for Http3TestServer { .unwrap() .push(session); } else if path == "/create_unidi_stream" { - // keeping the sever state as small as possible - // seems to reduce racing in dom tests - self.webtransport_uni_stream.clear(); session .response(&WebTransportSessionAcceptAction::Accept) .unwrap(); - self.sessions_to_create_stream.push(( - session, - StreamType::UniDi, - false, - )); - } else if path == "/create_unidi_stream_and_hello" { - // keeping the sever state as small as possible - // seems to reduce racing in dom tests - self.webtransport_uni_stream.clear(); - session - .response(&WebTransportSessionAcceptAction::Accept) - .unwrap(); - self.sessions_to_create_stream.push(( - session, - StreamType::UniDi, - true, - )); + self.sessions_to_create_stream + .push((session, StreamType::UniDi)); } else if path == "/create_bidi_stream" { session .response(&WebTransportSessionAcceptAction::Accept) .unwrap(); - self.sessions_to_create_stream.push(( - session, - StreamType::BiDi, - false, - )); - } else if path == "/create_bidi_stream_and_hello" { - self.webtransport_bidi_stream.clear(); - session - .response(&WebTransportSessionAcceptAction::Accept) - .unwrap(); - self.sessions_to_create_stream.push(( - session, - StreamType::BiDi, - true, - )); + self.sessions_to_create_stream + .push((session, StreamType::BiDi)); } else { session .response(&WebTransportSessionAcceptAction::Accept) @@ -554,7 +487,7 @@ impl HttpServer for Http3TestServer { Http3ServerEvent::WebTransport(WebTransportServerEvent::SessionClosed { session, reason, - headers: _, + headers: _ }) => { qdebug!( "WebTransportServerEvent::SessionClosed {:?} {:?}", @@ -563,12 +496,8 @@ impl HttpServer for Http3TestServer { ); } Http3ServerEvent::WebTransport(WebTransportServerEvent::NewStream(stream)) => { - // new stream could be from client-outgoing unidirectional - // or bidirectional, only need to relay echo back with bidi if !stream.stream_info.is_http() { - if stream.stream_id().is_bidi() { - self.webtransport_bidi_stream.insert(stream); - } + self.webtransport_bidi_stream.insert(stream); } } Http3ServerEvent::WebTransport(WebTransportServerEvent::Datagram { diff --git a/netwerk/test/unit/test_webtransport_simple.js b/netwerk/test/unit/test_webtransport_simple.js index 0e3be4c52c01..93c2d2ab58e4 100644 --- a/netwerk/test/unit/test_webtransport_simple.js +++ b/netwerk/test/unit/test_webtransport_simple.js @@ -180,11 +180,11 @@ async function test_closed(path) { } add_task(async function test_closed_0ms() { - await test_closed("/closeafter0ms"); + test_closed("/closeafter0ms"); }); add_task(async function test_closed_100ms() { - await test_closed("/closeafter100ms"); + test_closed("/closeafter100ms"); }); add_task(async function test_wt_stream_create() { @@ -250,7 +250,6 @@ add_task(async function test_wt_stream_send_and_stats() { webTransport.closeSession(0, ""); }); -// strangely unidi/bidi works with debug --verify in test_webtransport_simple.js add_task(async function test_wt_receive_stream_and_stats() { let webTransport = NetUtil.newWebTransport().QueryInterface( Ci.nsIWebTransport @@ -267,7 +266,7 @@ add_task(async function test_wt_receive_stream_and_stats() { listener.streamAvailable = resolve; }); webTransport.asyncConnect( - NetUtil.newURI(`https://${host}/create_unidi_stream_and_hello`), + NetUtil.newURI(`https://${host}/create_unidi_stream`), Services.scriptSecurityManager.getSystemPrincipal(), Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL, listener @@ -286,7 +285,7 @@ add_task(async function test_wt_receive_stream_and_stats() { }); info("data: " + data); - Assert.equal(data, "qwerty"); + Assert.equal(data, "0123456789"); let stats = await receiveStreamStatsPromise(stream); Assert.equal(stats.bytesReceived, data.length);