summaryrefslogtreecommitdiffstats
path: root/third_party/rust/neqo-http3/tests/priority.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/neqo-http3/tests/priority.rs')
-rw-r--r--third_party/rust/neqo-http3/tests/priority.rs148
1 files changed, 148 insertions, 0 deletions
diff --git a/third_party/rust/neqo-http3/tests/priority.rs b/third_party/rust/neqo-http3/tests/priority.rs
new file mode 100644
index 0000000000..cdec161058
--- /dev/null
+++ b/third_party/rust/neqo-http3/tests/priority.rs
@@ -0,0 +1,148 @@
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::time::Instant;
+
+use neqo_common::event::Provider;
+use neqo_crypto::AuthenticationStatus;
+use neqo_http3::{
+ Header, Http3Client, Http3ClientEvent, Http3Server, Http3ServerEvent, Http3State, Priority,
+};
+use test_fixture::*;
+
+fn exchange_packets(client: &mut Http3Client, server: &mut Http3Server) {
+ let mut out = None;
+ loop {
+ out = client.process(out.as_ref(), now()).dgram();
+ let client_done = out.is_none();
+ out = server.process(out.as_ref(), now()).dgram();
+ if out.is_none() && client_done {
+ break;
+ }
+ }
+}
+
+// Perform only Quic transport handshake.
+fn connect_with(client: &mut Http3Client, server: &mut Http3Server) {
+ assert_eq!(client.state(), Http3State::Initializing);
+ let out = client.process(None, now());
+ assert_eq!(client.state(), Http3State::Initializing);
+
+ let out = server.process(out.as_dgram_ref(), now());
+ let out = client.process(out.as_dgram_ref(), now());
+ let out = server.process(out.as_dgram_ref(), now());
+ assert!(out.as_dgram_ref().is_none());
+
+ let authentication_needed = |e| matches!(e, Http3ClientEvent::AuthenticationNeeded);
+ assert!(client.events().any(authentication_needed));
+ client.authenticated(AuthenticationStatus::Ok, now());
+
+ let out = client.process(out.as_dgram_ref(), now());
+ let connected = |e| matches!(e, Http3ClientEvent::StateChange(Http3State::Connected));
+ assert!(client.events().any(connected));
+
+ assert_eq!(client.state(), Http3State::Connected);
+ // Exchange H3 setttings
+ let out = server.process(out.as_dgram_ref(), now());
+ let out = client.process(out.as_dgram_ref(), now());
+ let out = server.process(out.as_dgram_ref(), now());
+ let out = client.process(out.as_dgram_ref(), now());
+ _ = server.process(out.as_dgram_ref(), now());
+}
+
+fn connect() -> (Http3Client, Http3Server) {
+ let mut client = default_http3_client();
+ let mut server = default_http3_server();
+ connect_with(&mut client, &mut server);
+ (client, server)
+}
+
+#[test]
+fn priority_update() {
+ let (mut client, mut server) = connect();
+ let stream_id = client
+ .fetch(
+ Instant::now(),
+ "GET",
+ &("https", "something.com", "/"),
+ &[],
+ Priority::new(4, true),
+ )
+ .unwrap();
+ exchange_packets(&mut client, &mut server);
+
+ // get event of the above request, skipping events of the connection setup
+ let header_event = loop {
+ let event = server.next_event().unwrap();
+ if matches!(event, Http3ServerEvent::Headers { .. }) {
+ break event;
+ }
+ };
+
+ match header_event {
+ Http3ServerEvent::Headers {
+ stream: _,
+ headers,
+ fin,
+ } => {
+ let expected_headers = &[
+ Header::new(":method", "GET"),
+ Header::new(":scheme", "https"),
+ Header::new(":authority", "something.com"),
+ Header::new(":path", "/"),
+ Header::new("priority", "u=4,i"),
+ ];
+ assert_eq!(&headers, expected_headers);
+ assert!(!fin);
+ }
+ other => panic!("unexpected server event: {:?}", other),
+ }
+
+ let update_priority = Priority::new(3, false);
+ client.priority_update(stream_id, update_priority).unwrap();
+ exchange_packets(&mut client, &mut server);
+
+ let found = server.events().any(|e| {
+ if let Http3ServerEvent::PriorityUpdate {
+ stream_id: update_id,
+ priority,
+ } = e
+ {
+ assert_eq!(update_id, stream_id);
+ assert_eq!(priority, update_priority);
+ true
+ } else {
+ false
+ }
+ });
+ assert!(found);
+}
+
+#[test]
+fn priority_update_dont_send_for_cancelled_stream() {
+ let (mut client, mut server) = connect();
+ let stream_id = client
+ .fetch(
+ Instant::now(),
+ "GET",
+ &("https", "something.com", "/"),
+ &[],
+ Priority::new(5, false),
+ )
+ .unwrap();
+ exchange_packets(&mut client, &mut server);
+
+ let update_priority = Priority::new(6, false);
+ client.priority_update(stream_id, update_priority).unwrap();
+ client.cancel_fetch(stream_id, 11).unwrap();
+ exchange_packets(&mut client, &mut server);
+
+ while let Some(event) = server.next_event() {
+ if matches!(event, Http3ServerEvent::PriorityUpdate { .. }) {
+ panic!("Priority update sent on cancelled stream");
+ }
+ }
+}