Backed out changeset 4220319b4afd (bug 1818828) for causing xpcshell failures in netwerk/test/unit/test_http3_large_post.js. CLOSED TREE

This commit is contained in:
Stanca Serban 2023-03-14 18:32:38 +02:00
parent 91bfd0f972
commit 0542b29ed5
5 changed files with 16 additions and 463 deletions

View File

@ -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

View File

@ -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;
});

View File

@ -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

View File

@ -69,9 +69,8 @@ struct Http3TestServer {
responses: HashMap<Http3OrWebTransportStream, Vec<u8>>,
current_connection_hash: u64,
sessions_to_close: HashMap<Instant, Vec<WebTransportRequest>>,
sessions_to_create_stream: Vec<(WebTransportRequest, StreamType, bool)>,
sessions_to_create_stream: Vec<(WebTransportRequest, StreamType)>,
webtransport_bidi_stream: HashSet<Http3OrWebTransportStream>,
webtransport_uni_stream: Vec<Http3OrWebTransportStream>,
}
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 {

View File

@ -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);