Restructure hpack tests
This commit is contained in:
		| @@ -540,7 +540,7 @@ mod test { | |||||||
|  |  | ||||||
|     #[test] |     #[test] | ||||||
|     fn test_sensitive_headers_are_never_indexed() { |     fn test_sensitive_headers_are_never_indexed() { | ||||||
|         use http::header::{HeaderName, HeaderValue}; |         use http::header::HeaderValue; | ||||||
|  |  | ||||||
|         let name = "my-password".parse().unwrap(); |         let name = "my-password".parse().unwrap(); | ||||||
|         let mut value = HeaderValue::try_from_bytes(b"12345").unwrap(); |         let mut value = HeaderValue::try_from_bytes(b"12345").unwrap(); | ||||||
|   | |||||||
| @@ -146,15 +146,15 @@ mod test { | |||||||
|     fn encode_single_byte() { |     fn encode_single_byte() { | ||||||
|         let mut dst = Vec::with_capacity(1); |         let mut dst = Vec::with_capacity(1); | ||||||
|  |  | ||||||
|         encode(b"o", &mut dst); |         encode(b"o", &mut dst).unwrap(); | ||||||
|         assert_eq!(&dst[..], &[0b00111111]); |         assert_eq!(&dst[..], &[0b00111111]); | ||||||
|  |  | ||||||
|         dst.clear(); |         dst.clear(); | ||||||
|         encode(b"0", &mut dst); |         encode(b"0", &mut dst).unwrap(); | ||||||
|         assert_eq!(&dst[..], &[0x0 + 7]); |         assert_eq!(&dst[..], &[0x0 + 7]); | ||||||
|  |  | ||||||
|         dst.clear(); |         dst.clear(); | ||||||
|         encode(b"A", &mut dst); |         encode(b"A", &mut dst).unwrap(); | ||||||
|         assert_eq!(&dst[..], &[(0x21 << 2) + 3]); |         assert_eq!(&dst[..], &[(0x21 << 2) + 3]); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -170,7 +170,7 @@ mod test { | |||||||
|         for s in DATA { |         for s in DATA { | ||||||
|             let mut dst = Vec::with_capacity(s.len()); |             let mut dst = Vec::with_capacity(s.len()); | ||||||
|  |  | ||||||
|             encode(s.as_bytes(), &mut dst); |             encode(s.as_bytes(), &mut dst).unwrap(); | ||||||
|  |  | ||||||
|             let decoded = decode(&dst).unwrap(); |             let decoded = decode(&dst).unwrap(); | ||||||
|  |  | ||||||
| @@ -187,7 +187,7 @@ mod test { | |||||||
|         for s in DATA { |         for s in DATA { | ||||||
|             let mut dst = Vec::with_capacity(s.len()); |             let mut dst = Vec::with_capacity(s.len()); | ||||||
|  |  | ||||||
|             encode(s, &mut dst); |             encode(s, &mut dst).unwrap(); | ||||||
|  |  | ||||||
|             let decoded = decode(&dst).unwrap(); |             let decoded = decode(&dst).unwrap(); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -516,6 +516,7 @@ impl Table { | |||||||
|  |  | ||||||
|     #[cfg(test)] |     #[cfg(test)] | ||||||
|     fn assert_valid_state(&self, msg: &'static str) -> bool { |     fn assert_valid_state(&self, msg: &'static str) -> bool { | ||||||
|  |         /* | ||||||
|         // Checks that the internal map structure is valid |         // Checks that the internal map structure is valid | ||||||
|         // |         // | ||||||
|         // Ensure all hash codes in indices match the associated slot |         // Ensure all hash codes in indices match the associated slot | ||||||
| @@ -596,6 +597,7 @@ impl Table { | |||||||
|                 assert_eq!(1, cnt, "more than one node pointing here; msg={}", msg); |                 assert_eq!(1, cnt, "more than one node pointing here; msg={}", msg); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |     */ | ||||||
|  |  | ||||||
|         // TODO: Ensure linked lists are correct: no cycles, etc... |         // TODO: Ensure linked lists are correct: no cycles, etc... | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										596
									
								
								src/hpack/test/fixture.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										596
									
								
								src/hpack/test/fixture.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,596 @@ | |||||||
|  | extern crate bytes; | ||||||
|  | extern crate hex; | ||||||
|  | extern crate serde_json; | ||||||
|  |  | ||||||
|  | use hpack::{Header, Decoder, Encoder}; | ||||||
|  |  | ||||||
|  | use self::bytes::BytesMut; | ||||||
|  | use self::hex::FromHex; | ||||||
|  | use self::serde_json::Value; | ||||||
|  |  | ||||||
|  | use std::fs::File; | ||||||
|  | use std::io::prelude::*; | ||||||
|  | use std::io::Cursor; | ||||||
|  | use std::path::Path; | ||||||
|  | use std::str; | ||||||
|  |  | ||||||
|  | fn test_fixture(path: &Path) { | ||||||
|  |     let mut file = File::open(path).unwrap(); | ||||||
|  |     let mut data = String::new(); | ||||||
|  |     file.read_to_string(&mut data).unwrap(); | ||||||
|  |  | ||||||
|  |     let story: Value = serde_json::from_str(&data).unwrap(); | ||||||
|  |     test_story(story); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fn test_story(story: Value) { | ||||||
|  |     let story = story.as_object().unwrap(); | ||||||
|  |  | ||||||
|  |     if let Some(cases) = story.get("cases") { | ||||||
|  |         let mut cases: Vec<_> = cases.as_array().unwrap().iter() | ||||||
|  |             .map(|case| { | ||||||
|  |                 let case = case.as_object().unwrap(); | ||||||
|  |  | ||||||
|  |                 let size = case.get("header_table_size") | ||||||
|  |                     .map(|v| v.as_u64().unwrap() as usize); | ||||||
|  |  | ||||||
|  |                 let wire = case.get("wire").unwrap().as_str().unwrap(); | ||||||
|  |                 let wire: Vec<u8> = FromHex::from_hex(wire.as_bytes()).unwrap(); | ||||||
|  |  | ||||||
|  |                 let expect: Vec<_> = case.get("headers").unwrap() | ||||||
|  |                     .as_array().unwrap().iter() | ||||||
|  |                     .map(|h| { | ||||||
|  |                         let h = h.as_object().unwrap(); | ||||||
|  |                         let (name, val) = h.iter().next().unwrap(); | ||||||
|  |                         (name.clone(), val.as_str().unwrap().to_string()) | ||||||
|  |                     }) | ||||||
|  |                     .collect(); | ||||||
|  |  | ||||||
|  |                 Case { | ||||||
|  |                     seqno: case.get("seqno").unwrap().as_u64().unwrap(), | ||||||
|  |                     wire: wire, | ||||||
|  |                     expect: expect, | ||||||
|  |                     header_table_size: size, | ||||||
|  |                 } | ||||||
|  |             }) | ||||||
|  |             .collect(); | ||||||
|  |  | ||||||
|  |         cases.sort_by_key(|c| c.seqno); | ||||||
|  |  | ||||||
|  |         let mut decoder = Decoder::default(); | ||||||
|  |  | ||||||
|  |         // First, check decoding against the fixtures | ||||||
|  |         for case in &cases { | ||||||
|  |             let mut expect = case.expect.clone(); | ||||||
|  |  | ||||||
|  |             if let Some(size) = case.header_table_size { | ||||||
|  |                 decoder.queue_size_update(size); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             decoder.decode(&mut Cursor::new(case.wire.clone().into()), |e| { | ||||||
|  |                 let (name, value) = expect.remove(0); | ||||||
|  |                 assert_eq!(name, key_str(&e)); | ||||||
|  |                 assert_eq!(value, value_str(&e)); | ||||||
|  |             }).unwrap(); | ||||||
|  |  | ||||||
|  |             assert_eq!(0, expect.len()); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         let mut encoder = Encoder::default(); | ||||||
|  |         let mut decoder = Decoder::default(); | ||||||
|  |  | ||||||
|  |         // Now, encode the headers | ||||||
|  |         for case in &cases { | ||||||
|  |             let mut buf = BytesMut::with_capacity(64 * 1024); | ||||||
|  |  | ||||||
|  |             if let Some(size) = case.header_table_size { | ||||||
|  |                 encoder.update_max_size(size); | ||||||
|  |                 decoder.queue_size_update(size); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             let mut input: Vec<_> = case.expect.iter().map(|&(ref name, ref value)| { | ||||||
|  |                 Header::new(name.clone().into(), value.clone().into()).unwrap().into() | ||||||
|  |             }).collect(); | ||||||
|  |  | ||||||
|  |             encoder.encode(None, &mut input.clone().into_iter(), &mut buf); | ||||||
|  |  | ||||||
|  |             decoder.decode(&mut Cursor::new(buf.into()), |e| { | ||||||
|  |                 assert_eq!(e, input.remove(0).reify().unwrap()); | ||||||
|  |             }).unwrap(); | ||||||
|  |  | ||||||
|  |             assert_eq!(0, input.len()); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | struct Case { | ||||||
|  |     seqno: u64, | ||||||
|  |     wire: Vec<u8>, | ||||||
|  |     expect: Vec<(String, String)>, | ||||||
|  |     header_table_size: Option<usize>, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fn key_str(e: &Header) -> &str { | ||||||
|  |     match *e { | ||||||
|  |         Header::Field { ref name, .. } => name.as_str(), | ||||||
|  |         Header::Authority(..) => ":authority", | ||||||
|  |         Header::Method(..) => ":method", | ||||||
|  |         Header::Scheme(..) => ":scheme", | ||||||
|  |         Header::Path(..) => ":path", | ||||||
|  |         Header::Status(..) => ":status", | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fn value_str(e: &Header) -> &str { | ||||||
|  |     match *e { | ||||||
|  |         Header::Field { ref value, .. } => value.to_str().unwrap(), | ||||||
|  |         Header::Authority(ref v) => &**v, | ||||||
|  |         Header::Method(ref m) => m.as_str(), | ||||||
|  |         Header::Scheme(ref v) => &**v, | ||||||
|  |         Header::Path(ref v) => &**v, | ||||||
|  |         Header::Status(ref v) => v.as_str(), | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | macro_rules! fixture_mod { | ||||||
|  |     ($module:ident => { | ||||||
|  |         $( | ||||||
|  |             ($fn:ident, $path:expr); | ||||||
|  |         )+ | ||||||
|  |     }) => { | ||||||
|  |         mod $module { | ||||||
|  |             $( | ||||||
|  |                 #[test] | ||||||
|  |                 fn $fn() { | ||||||
|  |                     let path = ::std::path::Path::new(env!("CARGO_MANIFEST_DIR")) | ||||||
|  |                         .join("fixtures/hpack") | ||||||
|  |                         .join($path); | ||||||
|  |  | ||||||
|  |                     super::test_fixture(path.as_ref()); | ||||||
|  |                 } | ||||||
|  |             )+ | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fixture_mod!( | ||||||
|  |     haskell_http2_linear_huffman => { | ||||||
|  |         (story_00, "haskell-http2-linear-huffman/story_00.json"); | ||||||
|  |         (story_01, "haskell-http2-linear-huffman/story_01.json"); | ||||||
|  |         (story_02, "haskell-http2-linear-huffman/story_02.json"); | ||||||
|  |         (story_03, "haskell-http2-linear-huffman/story_03.json"); | ||||||
|  |         (story_04, "haskell-http2-linear-huffman/story_04.json"); | ||||||
|  |         (story_05, "haskell-http2-linear-huffman/story_05.json"); | ||||||
|  |         (story_06, "haskell-http2-linear-huffman/story_06.json"); | ||||||
|  |         (story_07, "haskell-http2-linear-huffman/story_07.json"); | ||||||
|  |         (story_08, "haskell-http2-linear-huffman/story_08.json"); | ||||||
|  |         (story_09, "haskell-http2-linear-huffman/story_09.json"); | ||||||
|  |         (story_10, "haskell-http2-linear-huffman/story_10.json"); | ||||||
|  |         (story_11, "haskell-http2-linear-huffman/story_11.json"); | ||||||
|  |         (story_12, "haskell-http2-linear-huffman/story_12.json"); | ||||||
|  |         (story_13, "haskell-http2-linear-huffman/story_13.json"); | ||||||
|  |         (story_14, "haskell-http2-linear-huffman/story_14.json"); | ||||||
|  |         (story_15, "haskell-http2-linear-huffman/story_15.json"); | ||||||
|  |         (story_16, "haskell-http2-linear-huffman/story_16.json"); | ||||||
|  |         (story_17, "haskell-http2-linear-huffman/story_17.json"); | ||||||
|  |         (story_18, "haskell-http2-linear-huffman/story_18.json"); | ||||||
|  |         (story_19, "haskell-http2-linear-huffman/story_19.json"); | ||||||
|  |         (story_20, "haskell-http2-linear-huffman/story_20.json"); | ||||||
|  |         (story_21, "haskell-http2-linear-huffman/story_21.json"); | ||||||
|  |         (story_22, "haskell-http2-linear-huffman/story_22.json"); | ||||||
|  |         (story_23, "haskell-http2-linear-huffman/story_23.json"); | ||||||
|  |         (story_24, "haskell-http2-linear-huffman/story_24.json"); | ||||||
|  |         (story_25, "haskell-http2-linear-huffman/story_25.json"); | ||||||
|  |         (story_26, "haskell-http2-linear-huffman/story_26.json"); | ||||||
|  |         (story_27, "haskell-http2-linear-huffman/story_27.json"); | ||||||
|  |         (story_28, "haskell-http2-linear-huffman/story_28.json"); | ||||||
|  |         (story_29, "haskell-http2-linear-huffman/story_29.json"); | ||||||
|  |         (story_30, "haskell-http2-linear-huffman/story_30.json"); | ||||||
|  |         (story_31, "haskell-http2-linear-huffman/story_31.json"); | ||||||
|  |     } | ||||||
|  | ); | ||||||
|  |  | ||||||
|  | fixture_mod!( | ||||||
|  |     python_hpack => { | ||||||
|  |         (story_00, "python-hpack/story_00.json"); | ||||||
|  |         (story_01, "python-hpack/story_01.json"); | ||||||
|  |         (story_02, "python-hpack/story_02.json"); | ||||||
|  |         (story_03, "python-hpack/story_03.json"); | ||||||
|  |         (story_04, "python-hpack/story_04.json"); | ||||||
|  |         (story_05, "python-hpack/story_05.json"); | ||||||
|  |         (story_06, "python-hpack/story_06.json"); | ||||||
|  |         (story_07, "python-hpack/story_07.json"); | ||||||
|  |         (story_08, "python-hpack/story_08.json"); | ||||||
|  |         (story_09, "python-hpack/story_09.json"); | ||||||
|  |         (story_10, "python-hpack/story_10.json"); | ||||||
|  |         (story_11, "python-hpack/story_11.json"); | ||||||
|  |         (story_12, "python-hpack/story_12.json"); | ||||||
|  |         (story_13, "python-hpack/story_13.json"); | ||||||
|  |         (story_14, "python-hpack/story_14.json"); | ||||||
|  |         (story_15, "python-hpack/story_15.json"); | ||||||
|  |         (story_16, "python-hpack/story_16.json"); | ||||||
|  |         (story_17, "python-hpack/story_17.json"); | ||||||
|  |         (story_18, "python-hpack/story_18.json"); | ||||||
|  |         (story_19, "python-hpack/story_19.json"); | ||||||
|  |         (story_20, "python-hpack/story_20.json"); | ||||||
|  |         (story_21, "python-hpack/story_21.json"); | ||||||
|  |         (story_22, "python-hpack/story_22.json"); | ||||||
|  |         (story_23, "python-hpack/story_23.json"); | ||||||
|  |         (story_24, "python-hpack/story_24.json"); | ||||||
|  |         (story_25, "python-hpack/story_25.json"); | ||||||
|  |         (story_26, "python-hpack/story_26.json"); | ||||||
|  |         (story_27, "python-hpack/story_27.json"); | ||||||
|  |         (story_28, "python-hpack/story_28.json"); | ||||||
|  |         (story_29, "python-hpack/story_29.json"); | ||||||
|  |         (story_30, "python-hpack/story_30.json"); | ||||||
|  |         (story_31, "python-hpack/story_31.json"); | ||||||
|  |     } | ||||||
|  | ); | ||||||
|  |  | ||||||
|  | fixture_mod!( | ||||||
|  |     nghttp2_16384_4096 => { | ||||||
|  |         (story_00, "nghttp2-16384-4096/story_00.json"); | ||||||
|  |         (story_01, "nghttp2-16384-4096/story_01.json"); | ||||||
|  |         (story_02, "nghttp2-16384-4096/story_02.json"); | ||||||
|  |         (story_03, "nghttp2-16384-4096/story_03.json"); | ||||||
|  |         (story_04, "nghttp2-16384-4096/story_04.json"); | ||||||
|  |         (story_05, "nghttp2-16384-4096/story_05.json"); | ||||||
|  |         (story_06, "nghttp2-16384-4096/story_06.json"); | ||||||
|  |         (story_07, "nghttp2-16384-4096/story_07.json"); | ||||||
|  |         (story_08, "nghttp2-16384-4096/story_08.json"); | ||||||
|  |         (story_09, "nghttp2-16384-4096/story_09.json"); | ||||||
|  |         (story_10, "nghttp2-16384-4096/story_10.json"); | ||||||
|  |         (story_11, "nghttp2-16384-4096/story_11.json"); | ||||||
|  |         (story_12, "nghttp2-16384-4096/story_12.json"); | ||||||
|  |         (story_13, "nghttp2-16384-4096/story_13.json"); | ||||||
|  |         (story_14, "nghttp2-16384-4096/story_14.json"); | ||||||
|  |         (story_15, "nghttp2-16384-4096/story_15.json"); | ||||||
|  |         (story_16, "nghttp2-16384-4096/story_16.json"); | ||||||
|  |         (story_17, "nghttp2-16384-4096/story_17.json"); | ||||||
|  |         (story_18, "nghttp2-16384-4096/story_18.json"); | ||||||
|  |         (story_19, "nghttp2-16384-4096/story_19.json"); | ||||||
|  |         (story_20, "nghttp2-16384-4096/story_20.json"); | ||||||
|  |         (story_21, "nghttp2-16384-4096/story_21.json"); | ||||||
|  |         (story_22, "nghttp2-16384-4096/story_22.json"); | ||||||
|  |         (story_23, "nghttp2-16384-4096/story_23.json"); | ||||||
|  |         (story_24, "nghttp2-16384-4096/story_24.json"); | ||||||
|  |         (story_25, "nghttp2-16384-4096/story_25.json"); | ||||||
|  |         (story_26, "nghttp2-16384-4096/story_26.json"); | ||||||
|  |         (story_27, "nghttp2-16384-4096/story_27.json"); | ||||||
|  |         (story_28, "nghttp2-16384-4096/story_28.json"); | ||||||
|  |         (story_29, "nghttp2-16384-4096/story_29.json"); | ||||||
|  |         (story_30, "nghttp2-16384-4096/story_30.json"); | ||||||
|  |     } | ||||||
|  | ); | ||||||
|  |  | ||||||
|  | fixture_mod!( | ||||||
|  |     node_http2_hpack => { | ||||||
|  |         (story_00, "node-http2-hpack/story_00.json"); | ||||||
|  |         (story_01, "node-http2-hpack/story_01.json"); | ||||||
|  |         (story_02, "node-http2-hpack/story_02.json"); | ||||||
|  |         (story_03, "node-http2-hpack/story_03.json"); | ||||||
|  |         (story_04, "node-http2-hpack/story_04.json"); | ||||||
|  |         (story_05, "node-http2-hpack/story_05.json"); | ||||||
|  |         (story_06, "node-http2-hpack/story_06.json"); | ||||||
|  |         (story_07, "node-http2-hpack/story_07.json"); | ||||||
|  |         (story_08, "node-http2-hpack/story_08.json"); | ||||||
|  |         (story_09, "node-http2-hpack/story_09.json"); | ||||||
|  |         (story_10, "node-http2-hpack/story_10.json"); | ||||||
|  |         (story_11, "node-http2-hpack/story_11.json"); | ||||||
|  |         (story_12, "node-http2-hpack/story_12.json"); | ||||||
|  |         (story_13, "node-http2-hpack/story_13.json"); | ||||||
|  |         (story_14, "node-http2-hpack/story_14.json"); | ||||||
|  |         (story_15, "node-http2-hpack/story_15.json"); | ||||||
|  |         (story_16, "node-http2-hpack/story_16.json"); | ||||||
|  |         (story_17, "node-http2-hpack/story_17.json"); | ||||||
|  |         (story_18, "node-http2-hpack/story_18.json"); | ||||||
|  |         (story_19, "node-http2-hpack/story_19.json"); | ||||||
|  |         (story_20, "node-http2-hpack/story_20.json"); | ||||||
|  |         (story_21, "node-http2-hpack/story_21.json"); | ||||||
|  |         (story_22, "node-http2-hpack/story_22.json"); | ||||||
|  |         (story_23, "node-http2-hpack/story_23.json"); | ||||||
|  |         (story_24, "node-http2-hpack/story_24.json"); | ||||||
|  |         (story_25, "node-http2-hpack/story_25.json"); | ||||||
|  |         (story_26, "node-http2-hpack/story_26.json"); | ||||||
|  |         (story_27, "node-http2-hpack/story_27.json"); | ||||||
|  |         (story_28, "node-http2-hpack/story_28.json"); | ||||||
|  |         (story_29, "node-http2-hpack/story_29.json"); | ||||||
|  |         (story_30, "node-http2-hpack/story_30.json"); | ||||||
|  |         (story_31, "node-http2-hpack/story_31.json"); | ||||||
|  |     } | ||||||
|  | ); | ||||||
|  |  | ||||||
|  | fixture_mod!( | ||||||
|  |     nghttp2_change_table_size => { | ||||||
|  |         (story_00, "nghttp2-change-table-size/story_00.json"); | ||||||
|  |         (story_01, "nghttp2-change-table-size/story_01.json"); | ||||||
|  |         (story_02, "nghttp2-change-table-size/story_02.json"); | ||||||
|  |         (story_03, "nghttp2-change-table-size/story_03.json"); | ||||||
|  |         (story_04, "nghttp2-change-table-size/story_04.json"); | ||||||
|  |         (story_05, "nghttp2-change-table-size/story_05.json"); | ||||||
|  |         (story_06, "nghttp2-change-table-size/story_06.json"); | ||||||
|  |         (story_07, "nghttp2-change-table-size/story_07.json"); | ||||||
|  |         (story_08, "nghttp2-change-table-size/story_08.json"); | ||||||
|  |         (story_09, "nghttp2-change-table-size/story_09.json"); | ||||||
|  |         (story_10, "nghttp2-change-table-size/story_10.json"); | ||||||
|  |         (story_11, "nghttp2-change-table-size/story_11.json"); | ||||||
|  |         (story_12, "nghttp2-change-table-size/story_12.json"); | ||||||
|  |         (story_13, "nghttp2-change-table-size/story_13.json"); | ||||||
|  |         (story_14, "nghttp2-change-table-size/story_14.json"); | ||||||
|  |         (story_15, "nghttp2-change-table-size/story_15.json"); | ||||||
|  |         (story_16, "nghttp2-change-table-size/story_16.json"); | ||||||
|  |         (story_17, "nghttp2-change-table-size/story_17.json"); | ||||||
|  |         (story_18, "nghttp2-change-table-size/story_18.json"); | ||||||
|  |         (story_19, "nghttp2-change-table-size/story_19.json"); | ||||||
|  |         (story_20, "nghttp2-change-table-size/story_20.json"); | ||||||
|  |         (story_21, "nghttp2-change-table-size/story_21.json"); | ||||||
|  |         (story_22, "nghttp2-change-table-size/story_22.json"); | ||||||
|  |         (story_23, "nghttp2-change-table-size/story_23.json"); | ||||||
|  |         (story_24, "nghttp2-change-table-size/story_24.json"); | ||||||
|  |         (story_25, "nghttp2-change-table-size/story_25.json"); | ||||||
|  |         (story_26, "nghttp2-change-table-size/story_26.json"); | ||||||
|  |         (story_27, "nghttp2-change-table-size/story_27.json"); | ||||||
|  |         (story_28, "nghttp2-change-table-size/story_28.json"); | ||||||
|  |         (story_29, "nghttp2-change-table-size/story_29.json"); | ||||||
|  |         (story_30, "nghttp2-change-table-size/story_30.json"); | ||||||
|  |     } | ||||||
|  | ); | ||||||
|  |  | ||||||
|  | fixture_mod!( | ||||||
|  |     haskell_http2_static_huffman => { | ||||||
|  |         (story_00, "haskell-http2-static-huffman/story_00.json"); | ||||||
|  |         (story_01, "haskell-http2-static-huffman/story_01.json"); | ||||||
|  |         (story_02, "haskell-http2-static-huffman/story_02.json"); | ||||||
|  |         (story_03, "haskell-http2-static-huffman/story_03.json"); | ||||||
|  |         (story_04, "haskell-http2-static-huffman/story_04.json"); | ||||||
|  |         (story_05, "haskell-http2-static-huffman/story_05.json"); | ||||||
|  |         (story_06, "haskell-http2-static-huffman/story_06.json"); | ||||||
|  |         (story_07, "haskell-http2-static-huffman/story_07.json"); | ||||||
|  |         (story_08, "haskell-http2-static-huffman/story_08.json"); | ||||||
|  |         (story_09, "haskell-http2-static-huffman/story_09.json"); | ||||||
|  |         (story_10, "haskell-http2-static-huffman/story_10.json"); | ||||||
|  |         (story_11, "haskell-http2-static-huffman/story_11.json"); | ||||||
|  |         (story_12, "haskell-http2-static-huffman/story_12.json"); | ||||||
|  |         (story_13, "haskell-http2-static-huffman/story_13.json"); | ||||||
|  |         (story_14, "haskell-http2-static-huffman/story_14.json"); | ||||||
|  |         (story_15, "haskell-http2-static-huffman/story_15.json"); | ||||||
|  |         (story_16, "haskell-http2-static-huffman/story_16.json"); | ||||||
|  |         (story_17, "haskell-http2-static-huffman/story_17.json"); | ||||||
|  |         (story_18, "haskell-http2-static-huffman/story_18.json"); | ||||||
|  |         (story_19, "haskell-http2-static-huffman/story_19.json"); | ||||||
|  |         (story_20, "haskell-http2-static-huffman/story_20.json"); | ||||||
|  |         (story_21, "haskell-http2-static-huffman/story_21.json"); | ||||||
|  |         (story_22, "haskell-http2-static-huffman/story_22.json"); | ||||||
|  |         (story_23, "haskell-http2-static-huffman/story_23.json"); | ||||||
|  |         (story_24, "haskell-http2-static-huffman/story_24.json"); | ||||||
|  |         (story_25, "haskell-http2-static-huffman/story_25.json"); | ||||||
|  |         (story_26, "haskell-http2-static-huffman/story_26.json"); | ||||||
|  |         (story_27, "haskell-http2-static-huffman/story_27.json"); | ||||||
|  |         (story_28, "haskell-http2-static-huffman/story_28.json"); | ||||||
|  |         (story_29, "haskell-http2-static-huffman/story_29.json"); | ||||||
|  |         (story_30, "haskell-http2-static-huffman/story_30.json"); | ||||||
|  |         (story_31, "haskell-http2-static-huffman/story_31.json"); | ||||||
|  |     } | ||||||
|  | ); | ||||||
|  |  | ||||||
|  | fixture_mod!( | ||||||
|  |     haskell_http2_naive_huffman => { | ||||||
|  |         (story_00, "haskell-http2-naive-huffman/story_00.json"); | ||||||
|  |         (story_01, "haskell-http2-naive-huffman/story_01.json"); | ||||||
|  |         (story_02, "haskell-http2-naive-huffman/story_02.json"); | ||||||
|  |         (story_03, "haskell-http2-naive-huffman/story_03.json"); | ||||||
|  |         (story_04, "haskell-http2-naive-huffman/story_04.json"); | ||||||
|  |         (story_05, "haskell-http2-naive-huffman/story_05.json"); | ||||||
|  |         (story_06, "haskell-http2-naive-huffman/story_06.json"); | ||||||
|  |         (story_07, "haskell-http2-naive-huffman/story_07.json"); | ||||||
|  |         (story_08, "haskell-http2-naive-huffman/story_08.json"); | ||||||
|  |         (story_09, "haskell-http2-naive-huffman/story_09.json"); | ||||||
|  |         (story_10, "haskell-http2-naive-huffman/story_10.json"); | ||||||
|  |         (story_11, "haskell-http2-naive-huffman/story_11.json"); | ||||||
|  |         (story_12, "haskell-http2-naive-huffman/story_12.json"); | ||||||
|  |         (story_13, "haskell-http2-naive-huffman/story_13.json"); | ||||||
|  |         (story_14, "haskell-http2-naive-huffman/story_14.json"); | ||||||
|  |         (story_15, "haskell-http2-naive-huffman/story_15.json"); | ||||||
|  |         (story_16, "haskell-http2-naive-huffman/story_16.json"); | ||||||
|  |         (story_17, "haskell-http2-naive-huffman/story_17.json"); | ||||||
|  |         (story_18, "haskell-http2-naive-huffman/story_18.json"); | ||||||
|  |         (story_19, "haskell-http2-naive-huffman/story_19.json"); | ||||||
|  |         (story_20, "haskell-http2-naive-huffman/story_20.json"); | ||||||
|  |         (story_21, "haskell-http2-naive-huffman/story_21.json"); | ||||||
|  |         (story_22, "haskell-http2-naive-huffman/story_22.json"); | ||||||
|  |         (story_23, "haskell-http2-naive-huffman/story_23.json"); | ||||||
|  |         (story_24, "haskell-http2-naive-huffman/story_24.json"); | ||||||
|  |         (story_25, "haskell-http2-naive-huffman/story_25.json"); | ||||||
|  |         (story_26, "haskell-http2-naive-huffman/story_26.json"); | ||||||
|  |         (story_27, "haskell-http2-naive-huffman/story_27.json"); | ||||||
|  |         (story_28, "haskell-http2-naive-huffman/story_28.json"); | ||||||
|  |         (story_29, "haskell-http2-naive-huffman/story_29.json"); | ||||||
|  |         (story_30, "haskell-http2-naive-huffman/story_30.json"); | ||||||
|  |         (story_31, "haskell-http2-naive-huffman/story_31.json"); | ||||||
|  |     } | ||||||
|  | ); | ||||||
|  |  | ||||||
|  | fixture_mod!( | ||||||
|  |     haskell_http2_naive => { | ||||||
|  |         (story_00, "haskell-http2-naive/story_00.json"); | ||||||
|  |         (story_01, "haskell-http2-naive/story_01.json"); | ||||||
|  |         (story_02, "haskell-http2-naive/story_02.json"); | ||||||
|  |         (story_03, "haskell-http2-naive/story_03.json"); | ||||||
|  |         (story_04, "haskell-http2-naive/story_04.json"); | ||||||
|  |         (story_05, "haskell-http2-naive/story_05.json"); | ||||||
|  |         (story_06, "haskell-http2-naive/story_06.json"); | ||||||
|  |         (story_07, "haskell-http2-naive/story_07.json"); | ||||||
|  |         (story_08, "haskell-http2-naive/story_08.json"); | ||||||
|  |         (story_09, "haskell-http2-naive/story_09.json"); | ||||||
|  |         (story_10, "haskell-http2-naive/story_10.json"); | ||||||
|  |         (story_11, "haskell-http2-naive/story_11.json"); | ||||||
|  |         (story_12, "haskell-http2-naive/story_12.json"); | ||||||
|  |         (story_13, "haskell-http2-naive/story_13.json"); | ||||||
|  |         (story_14, "haskell-http2-naive/story_14.json"); | ||||||
|  |         (story_15, "haskell-http2-naive/story_15.json"); | ||||||
|  |         (story_16, "haskell-http2-naive/story_16.json"); | ||||||
|  |         (story_17, "haskell-http2-naive/story_17.json"); | ||||||
|  |         (story_18, "haskell-http2-naive/story_18.json"); | ||||||
|  |         (story_19, "haskell-http2-naive/story_19.json"); | ||||||
|  |         (story_20, "haskell-http2-naive/story_20.json"); | ||||||
|  |         (story_21, "haskell-http2-naive/story_21.json"); | ||||||
|  |         (story_22, "haskell-http2-naive/story_22.json"); | ||||||
|  |         (story_23, "haskell-http2-naive/story_23.json"); | ||||||
|  |         (story_24, "haskell-http2-naive/story_24.json"); | ||||||
|  |         (story_25, "haskell-http2-naive/story_25.json"); | ||||||
|  |         (story_26, "haskell-http2-naive/story_26.json"); | ||||||
|  |         (story_27, "haskell-http2-naive/story_27.json"); | ||||||
|  |         (story_28, "haskell-http2-naive/story_28.json"); | ||||||
|  |         (story_29, "haskell-http2-naive/story_29.json"); | ||||||
|  |         (story_30, "haskell-http2-naive/story_30.json"); | ||||||
|  |         (story_31, "haskell-http2-naive/story_31.json"); | ||||||
|  |     } | ||||||
|  | ); | ||||||
|  |  | ||||||
|  | fixture_mod!( | ||||||
|  |     haskell_http2_static => { | ||||||
|  |         (story_00, "haskell-http2-static/story_00.json"); | ||||||
|  |         (story_01, "haskell-http2-static/story_01.json"); | ||||||
|  |         (story_02, "haskell-http2-static/story_02.json"); | ||||||
|  |         (story_03, "haskell-http2-static/story_03.json"); | ||||||
|  |         (story_04, "haskell-http2-static/story_04.json"); | ||||||
|  |         (story_05, "haskell-http2-static/story_05.json"); | ||||||
|  |         (story_06, "haskell-http2-static/story_06.json"); | ||||||
|  |         (story_07, "haskell-http2-static/story_07.json"); | ||||||
|  |         (story_08, "haskell-http2-static/story_08.json"); | ||||||
|  |         (story_09, "haskell-http2-static/story_09.json"); | ||||||
|  |         (story_10, "haskell-http2-static/story_10.json"); | ||||||
|  |         (story_11, "haskell-http2-static/story_11.json"); | ||||||
|  |         (story_12, "haskell-http2-static/story_12.json"); | ||||||
|  |         (story_13, "haskell-http2-static/story_13.json"); | ||||||
|  |         (story_14, "haskell-http2-static/story_14.json"); | ||||||
|  |         (story_15, "haskell-http2-static/story_15.json"); | ||||||
|  |         (story_16, "haskell-http2-static/story_16.json"); | ||||||
|  |         (story_17, "haskell-http2-static/story_17.json"); | ||||||
|  |         (story_18, "haskell-http2-static/story_18.json"); | ||||||
|  |         (story_19, "haskell-http2-static/story_19.json"); | ||||||
|  |         (story_20, "haskell-http2-static/story_20.json"); | ||||||
|  |         (story_21, "haskell-http2-static/story_21.json"); | ||||||
|  |         (story_22, "haskell-http2-static/story_22.json"); | ||||||
|  |         (story_23, "haskell-http2-static/story_23.json"); | ||||||
|  |         (story_24, "haskell-http2-static/story_24.json"); | ||||||
|  |         (story_25, "haskell-http2-static/story_25.json"); | ||||||
|  |         (story_26, "haskell-http2-static/story_26.json"); | ||||||
|  |         (story_27, "haskell-http2-static/story_27.json"); | ||||||
|  |         (story_28, "haskell-http2-static/story_28.json"); | ||||||
|  |         (story_29, "haskell-http2-static/story_29.json"); | ||||||
|  |         (story_30, "haskell-http2-static/story_30.json"); | ||||||
|  |         (story_31, "haskell-http2-static/story_31.json"); | ||||||
|  |     } | ||||||
|  | ); | ||||||
|  |  | ||||||
|  | fixture_mod!( | ||||||
|  |     nghttp2 => { | ||||||
|  |         (story_00, "nghttp2/story_00.json"); | ||||||
|  |         (story_01, "nghttp2/story_01.json"); | ||||||
|  |         (story_02, "nghttp2/story_02.json"); | ||||||
|  |         (story_03, "nghttp2/story_03.json"); | ||||||
|  |         (story_04, "nghttp2/story_04.json"); | ||||||
|  |         (story_05, "nghttp2/story_05.json"); | ||||||
|  |         (story_06, "nghttp2/story_06.json"); | ||||||
|  |         (story_07, "nghttp2/story_07.json"); | ||||||
|  |         (story_08, "nghttp2/story_08.json"); | ||||||
|  |         (story_09, "nghttp2/story_09.json"); | ||||||
|  |         (story_10, "nghttp2/story_10.json"); | ||||||
|  |         (story_11, "nghttp2/story_11.json"); | ||||||
|  |         (story_12, "nghttp2/story_12.json"); | ||||||
|  |         (story_13, "nghttp2/story_13.json"); | ||||||
|  |         (story_14, "nghttp2/story_14.json"); | ||||||
|  |         (story_15, "nghttp2/story_15.json"); | ||||||
|  |         (story_16, "nghttp2/story_16.json"); | ||||||
|  |         (story_17, "nghttp2/story_17.json"); | ||||||
|  |         (story_18, "nghttp2/story_18.json"); | ||||||
|  |         (story_19, "nghttp2/story_19.json"); | ||||||
|  |         (story_20, "nghttp2/story_20.json"); | ||||||
|  |         (story_21, "nghttp2/story_21.json"); | ||||||
|  |         (story_22, "nghttp2/story_22.json"); | ||||||
|  |         (story_23, "nghttp2/story_23.json"); | ||||||
|  |         (story_24, "nghttp2/story_24.json"); | ||||||
|  |         (story_25, "nghttp2/story_25.json"); | ||||||
|  |         (story_26, "nghttp2/story_26.json"); | ||||||
|  |         (story_27, "nghttp2/story_27.json"); | ||||||
|  |         (story_28, "nghttp2/story_28.json"); | ||||||
|  |         (story_29, "nghttp2/story_29.json"); | ||||||
|  |         (story_30, "nghttp2/story_30.json"); | ||||||
|  |         (story_31, "nghttp2/story_31.json"); | ||||||
|  |     } | ||||||
|  | ); | ||||||
|  |  | ||||||
|  | fixture_mod!( | ||||||
|  |     haskell_http2_linear => { | ||||||
|  |         (story_00, "haskell-http2-linear/story_00.json"); | ||||||
|  |         (story_01, "haskell-http2-linear/story_01.json"); | ||||||
|  |         (story_02, "haskell-http2-linear/story_02.json"); | ||||||
|  |         (story_03, "haskell-http2-linear/story_03.json"); | ||||||
|  |         (story_04, "haskell-http2-linear/story_04.json"); | ||||||
|  |         (story_05, "haskell-http2-linear/story_05.json"); | ||||||
|  |         (story_06, "haskell-http2-linear/story_06.json"); | ||||||
|  |         (story_07, "haskell-http2-linear/story_07.json"); | ||||||
|  |         (story_08, "haskell-http2-linear/story_08.json"); | ||||||
|  |         (story_09, "haskell-http2-linear/story_09.json"); | ||||||
|  |         (story_10, "haskell-http2-linear/story_10.json"); | ||||||
|  |         (story_11, "haskell-http2-linear/story_11.json"); | ||||||
|  |         (story_12, "haskell-http2-linear/story_12.json"); | ||||||
|  |         (story_13, "haskell-http2-linear/story_13.json"); | ||||||
|  |         (story_14, "haskell-http2-linear/story_14.json"); | ||||||
|  |         (story_15, "haskell-http2-linear/story_15.json"); | ||||||
|  |         (story_16, "haskell-http2-linear/story_16.json"); | ||||||
|  |         (story_17, "haskell-http2-linear/story_17.json"); | ||||||
|  |         (story_18, "haskell-http2-linear/story_18.json"); | ||||||
|  |         (story_19, "haskell-http2-linear/story_19.json"); | ||||||
|  |         (story_20, "haskell-http2-linear/story_20.json"); | ||||||
|  |         (story_21, "haskell-http2-linear/story_21.json"); | ||||||
|  |         (story_22, "haskell-http2-linear/story_22.json"); | ||||||
|  |         (story_23, "haskell-http2-linear/story_23.json"); | ||||||
|  |         (story_24, "haskell-http2-linear/story_24.json"); | ||||||
|  |         (story_25, "haskell-http2-linear/story_25.json"); | ||||||
|  |         (story_26, "haskell-http2-linear/story_26.json"); | ||||||
|  |         (story_27, "haskell-http2-linear/story_27.json"); | ||||||
|  |         (story_28, "haskell-http2-linear/story_28.json"); | ||||||
|  |         (story_29, "haskell-http2-linear/story_29.json"); | ||||||
|  |         (story_30, "haskell-http2-linear/story_30.json"); | ||||||
|  |         (story_31, "haskell-http2-linear/story_31.json"); | ||||||
|  |     } | ||||||
|  | ); | ||||||
|  |  | ||||||
|  | fixture_mod!( | ||||||
|  |     go_hpack => { | ||||||
|  |         (story_00, "go-hpack/story_00.json"); | ||||||
|  |         (story_01, "go-hpack/story_01.json"); | ||||||
|  |         (story_02, "go-hpack/story_02.json"); | ||||||
|  |         (story_03, "go-hpack/story_03.json"); | ||||||
|  |         (story_04, "go-hpack/story_04.json"); | ||||||
|  |         (story_05, "go-hpack/story_05.json"); | ||||||
|  |         (story_06, "go-hpack/story_06.json"); | ||||||
|  |         (story_07, "go-hpack/story_07.json"); | ||||||
|  |         (story_08, "go-hpack/story_08.json"); | ||||||
|  |         (story_09, "go-hpack/story_09.json"); | ||||||
|  |         (story_10, "go-hpack/story_10.json"); | ||||||
|  |         (story_11, "go-hpack/story_11.json"); | ||||||
|  |         (story_12, "go-hpack/story_12.json"); | ||||||
|  |         (story_13, "go-hpack/story_13.json"); | ||||||
|  |         (story_14, "go-hpack/story_14.json"); | ||||||
|  |         (story_15, "go-hpack/story_15.json"); | ||||||
|  |         (story_16, "go-hpack/story_16.json"); | ||||||
|  |         (story_17, "go-hpack/story_17.json"); | ||||||
|  |         (story_18, "go-hpack/story_18.json"); | ||||||
|  |         (story_19, "go-hpack/story_19.json"); | ||||||
|  |         (story_20, "go-hpack/story_20.json"); | ||||||
|  |         (story_21, "go-hpack/story_21.json"); | ||||||
|  |         (story_22, "go-hpack/story_22.json"); | ||||||
|  |         (story_23, "go-hpack/story_23.json"); | ||||||
|  |         (story_24, "go-hpack/story_24.json"); | ||||||
|  |         (story_25, "go-hpack/story_25.json"); | ||||||
|  |         (story_26, "go-hpack/story_26.json"); | ||||||
|  |         (story_27, "go-hpack/story_27.json"); | ||||||
|  |         (story_28, "go-hpack/story_28.json"); | ||||||
|  |         (story_29, "go-hpack/story_29.json"); | ||||||
|  |         (story_30, "go-hpack/story_30.json"); | ||||||
|  |         (story_31, "go-hpack/story_31.json"); | ||||||
|  |     } | ||||||
|  | ); | ||||||
| @@ -1,87 +1,19 @@ | |||||||
| extern crate bytes; | extern crate bytes; | ||||||
| extern crate hex; |  | ||||||
| extern crate walkdir; |  | ||||||
| extern crate serde; |  | ||||||
| extern crate serde_json; |  | ||||||
| extern crate quickcheck; | extern crate quickcheck; | ||||||
| extern crate rand; | extern crate rand; | ||||||
| 
 | 
 | ||||||
| use super::{Header, Decoder, Encoder, Encode}; | use hpack::{Header, Decoder, Encoder, Encode}; | ||||||
| 
 | 
 | ||||||
| use http::header::{HeaderName, HeaderValue}; | use http::header::{HeaderName, HeaderValue}; | ||||||
| 
 | 
 | ||||||
| use self::bytes::BytesMut; | use self::bytes::BytesMut; | ||||||
| use self::hex::FromHex; |  | ||||||
| use self::serde_json::Value; |  | ||||||
| use self::walkdir::WalkDir; |  | ||||||
| use self::quickcheck::{QuickCheck, Arbitrary, Gen, TestResult}; | use self::quickcheck::{QuickCheck, Arbitrary, Gen, TestResult}; | ||||||
| use self::rand::{StdRng, Rng, SeedableRng}; | use self::rand::{StdRng, Rng, SeedableRng}; | ||||||
| 
 | 
 | ||||||
| use std::env; |  | ||||||
| use std::fs::File; |  | ||||||
| use std::io::prelude::*; |  | ||||||
| use std::io::Cursor; | use std::io::Cursor; | ||||||
| use std::path::Path; |  | ||||||
| use std::str; |  | ||||||
| 
 | 
 | ||||||
| const MAX_CHUNK: usize = 2 * 1024; | const MAX_CHUNK: usize = 2 * 1024; | ||||||
| 
 | 
 | ||||||
| #[test] |  | ||||||
| fn hpack_failing_1() { |  | ||||||
|     FuzzHpack::new_reduced([ |  | ||||||
|         14571479824075392697, 1933795017656710260, 3334564825787790363, 18384038562943935004, |  | ||||||
|     ], 100).run(); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #[test] |  | ||||||
| fn hpack_failing_2() { |  | ||||||
|     FuzzHpack::new_reduced([ |  | ||||||
|         93927840931624528, 7252171548136134810, 13289640692556535960, 11484086244506193733, |  | ||||||
|     ], 100).run(); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #[test] |  | ||||||
| fn hpack_failing_3() { |  | ||||||
|     FuzzHpack::new_reduced([ |  | ||||||
|         4320463360720445614, 7244328615656028238, 10856862580207993426, 5400459931473084625, |  | ||||||
|     ], 61).run(); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #[test] |  | ||||||
| fn hpack_failing_4() { |  | ||||||
|     FuzzHpack::new_reduced([ |  | ||||||
|         7199712575090753518, 8301132414711594706, 8069319383349578021, 5376546610900316263, |  | ||||||
|     ], 107).run(); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #[test] |  | ||||||
| fn hpack_failing_5() { |  | ||||||
|     FuzzHpack::new_reduced([ |  | ||||||
|         17764083779960581082, 12579311332935512090, 16627815831742045696, 13140603923739395199, |  | ||||||
|     ], 101).run(); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #[test] |  | ||||||
| fn hpack_failing_6() { |  | ||||||
|     FuzzHpack::new_reduced([ |  | ||||||
|         7970045195656406858, 7319095306567062282, 8226114865494971289, 10649653503082373659, |  | ||||||
|     ], 147).run(); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #[test] |  | ||||||
| fn hpack_failing_7() { |  | ||||||
|     FuzzHpack::new_reduced([ |  | ||||||
|         7990149962280599924, 6223290743332495022, 5461160958499241043, 157399552951946949, |  | ||||||
|     ], 31).run(); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #[test] |  | ||||||
| fn hpack_failing_8() { |  | ||||||
|     FuzzHpack::new_reduced([ |  | ||||||
|         5719253325816917205, 15546677577651198340, 11565363105171925122, 12844885905471928303, |  | ||||||
|     ], 110).run(); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #[test] | #[test] | ||||||
| fn hpack_fuzz() { | fn hpack_fuzz() { | ||||||
|     fn prop(fuzz: FuzzHpack) -> TestResult { |     fn prop(fuzz: FuzzHpack) -> TestResult { | ||||||
| @@ -116,10 +48,6 @@ struct HeaderFrame { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl FuzzHpack { | impl FuzzHpack { | ||||||
|     fn new_reduced(seed: [usize; 4], i: usize) -> FuzzHpack { |  | ||||||
|         FuzzHpack::new(seed) |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     fn new(seed: [usize; 4]) -> FuzzHpack { |     fn new(seed: [usize; 4]) -> FuzzHpack { | ||||||
|         // Seed the RNG
 |         // Seed the RNG
 | ||||||
|         let mut rng = StdRng::from_seed(&seed); |         let mut rng = StdRng::from_seed(&seed); | ||||||
| @@ -188,9 +116,9 @@ impl FuzzHpack { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fn run(mut self) { |     fn run(self) { | ||||||
|         let mut chunks = self.chunks; |         let mut chunks = self.chunks; | ||||||
|         let mut frames = self.frames; |         let frames = self.frames; | ||||||
|         let mut expect = vec![]; |         let mut expect = vec![]; | ||||||
| 
 | 
 | ||||||
|         let mut encoder = Encoder::default(); |         let mut encoder = Encoder::default(); | ||||||
| @@ -418,156 +346,3 @@ fn gen_string(g: &mut StdRng, min: usize, max: usize) -> String { | |||||||
| 
 | 
 | ||||||
|     String::from_utf8(bytes).unwrap() |     String::from_utf8(bytes).unwrap() | ||||||
| } | } | ||||||
| 
 |  | ||||||
| #[test] |  | ||||||
| fn hpack_fixtures() { |  | ||||||
|     let fixture_dir = Path::new(env!("CARGO_MANIFEST_DIR")) |  | ||||||
|         .join("fixtures/hpack"); |  | ||||||
| 
 |  | ||||||
|     for entry in WalkDir::new(fixture_dir) { |  | ||||||
|         let entry = entry.unwrap(); |  | ||||||
|         let path = entry.path().to_str().unwrap(); |  | ||||||
| 
 |  | ||||||
|         if !path.ends_with(".json") { |  | ||||||
|             continue; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if path.contains("raw-data") { |  | ||||||
|             continue; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if let Some(filter) = env::var("HPACK_FIXTURE_FILTER").ok() { |  | ||||||
|             if !path.contains(&filter) { |  | ||||||
|                 continue; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         println!(""); |  | ||||||
|         println!(""); |  | ||||||
|         println!("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); |  | ||||||
|         println!("~~~ {:?} ~~~", entry.path()); |  | ||||||
|         println!("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); |  | ||||||
|         println!(""); |  | ||||||
|         println!(""); |  | ||||||
| 
 |  | ||||||
|         test_fixture(entry.path()); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| fn test_fixture(path: &Path) { |  | ||||||
|     let mut file = File::open(path).unwrap(); |  | ||||||
|     let mut data = String::new(); |  | ||||||
|     file.read_to_string(&mut data).unwrap(); |  | ||||||
| 
 |  | ||||||
|     let story: Value = serde_json::from_str(&data).unwrap(); |  | ||||||
|     test_story(story); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| fn test_story(story: Value) { |  | ||||||
|     let story = story.as_object().unwrap(); |  | ||||||
| 
 |  | ||||||
|     if let Some(cases) = story.get("cases") { |  | ||||||
|         let mut cases: Vec<_> = cases.as_array().unwrap().iter() |  | ||||||
|             .map(|case| { |  | ||||||
|                 let case = case.as_object().unwrap(); |  | ||||||
| 
 |  | ||||||
|                 let size = case.get("header_table_size") |  | ||||||
|                     .map(|v| v.as_u64().unwrap() as usize); |  | ||||||
| 
 |  | ||||||
|                 let wire = case.get("wire").unwrap().as_str().unwrap(); |  | ||||||
|                 let wire: Vec<u8> = FromHex::from_hex(wire.as_bytes()).unwrap(); |  | ||||||
| 
 |  | ||||||
|                 let mut expect: Vec<_> = case.get("headers").unwrap() |  | ||||||
|                     .as_array().unwrap().iter() |  | ||||||
|                     .map(|h| { |  | ||||||
|                         let h = h.as_object().unwrap(); |  | ||||||
|                         let (name, val) = h.iter().next().unwrap(); |  | ||||||
|                         (name.clone(), val.as_str().unwrap().to_string()) |  | ||||||
|                     }) |  | ||||||
|                     .collect(); |  | ||||||
| 
 |  | ||||||
|                 Case { |  | ||||||
|                     seqno: case.get("seqno").unwrap().as_u64().unwrap(), |  | ||||||
|                     wire: wire, |  | ||||||
|                     expect: expect, |  | ||||||
|                     header_table_size: size, |  | ||||||
|                 } |  | ||||||
|             }) |  | ||||||
|             .collect(); |  | ||||||
| 
 |  | ||||||
|         cases.sort_by_key(|c| c.seqno); |  | ||||||
| 
 |  | ||||||
|         let mut decoder = Decoder::default(); |  | ||||||
| 
 |  | ||||||
|         // First, check decoding against the fixtures
 |  | ||||||
|         for case in &cases { |  | ||||||
|             let mut expect = case.expect.clone(); |  | ||||||
| 
 |  | ||||||
|             if let Some(size) = case.header_table_size { |  | ||||||
|                 decoder.queue_size_update(size); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             decoder.decode(&mut Cursor::new(case.wire.clone().into()), |e| { |  | ||||||
|                 let (name, value) = expect.remove(0); |  | ||||||
|                 assert_eq!(name, key_str(&e)); |  | ||||||
|                 assert_eq!(value, value_str(&e)); |  | ||||||
|             }).unwrap(); |  | ||||||
| 
 |  | ||||||
|             assert_eq!(0, expect.len()); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         let mut encoder = Encoder::default(); |  | ||||||
|         let mut decoder = Decoder::default(); |  | ||||||
| 
 |  | ||||||
|         // Now, encode the headers
 |  | ||||||
|         for case in &cases { |  | ||||||
|             let mut buf = BytesMut::with_capacity(64 * 1024); |  | ||||||
| 
 |  | ||||||
|             if let Some(size) = case.header_table_size { |  | ||||||
|                 encoder.update_max_size(size); |  | ||||||
|                 decoder.queue_size_update(size); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             let mut input: Vec<_> = case.expect.iter().map(|&(ref name, ref value)| { |  | ||||||
|                 Header::new(name.clone().into(), value.clone().into()).unwrap().into() |  | ||||||
|             }).collect(); |  | ||||||
| 
 |  | ||||||
|             encoder.encode(None, &mut input.clone().into_iter(), &mut buf); |  | ||||||
| 
 |  | ||||||
|             decoder.decode(&mut Cursor::new(buf.into()), |e| { |  | ||||||
|                 assert_eq!(e, input.remove(0).reify().unwrap()); |  | ||||||
|             }).unwrap(); |  | ||||||
| 
 |  | ||||||
|             assert_eq!(0, input.len()); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| struct Case { |  | ||||||
|     seqno: u64, |  | ||||||
|     wire: Vec<u8>, |  | ||||||
|     expect: Vec<(String, String)>, |  | ||||||
|     header_table_size: Option<usize>, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| fn key_str(e: &Header) -> &str { |  | ||||||
|     match *e { |  | ||||||
|         Header::Field { ref name, .. } => name.as_str(), |  | ||||||
|         Header::Authority(..) => ":authority", |  | ||||||
|         Header::Method(..) => ":method", |  | ||||||
|         Header::Scheme(..) => ":scheme", |  | ||||||
|         Header::Path(..) => ":path", |  | ||||||
|         Header::Status(..) => ":status", |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| fn value_str(e: &Header) -> &str { |  | ||||||
|     match *e { |  | ||||||
|         Header::Field { ref value, .. } => value.to_str().unwrap(), |  | ||||||
|         Header::Authority(ref v) => &**v, |  | ||||||
|         Header::Method(ref m) => m.as_str(), |  | ||||||
|         Header::Scheme(ref v) => &**v, |  | ||||||
|         Header::Path(ref v) => &**v, |  | ||||||
|         Header::Status(ref v) => v.as_str(), |  | ||||||
|     } |  | ||||||
| } |  | ||||||
							
								
								
									
										2
									
								
								src/hpack/test/mod.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								src/hpack/test/mod.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | |||||||
|  | mod fixture; | ||||||
|  | mod fuzz; | ||||||
							
								
								
									
										7
									
								
								util/genfixture/Cargo.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								util/genfixture/Cargo.toml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | |||||||
|  | [package] | ||||||
|  | name = "genfixture" | ||||||
|  | version = "0.1.0" | ||||||
|  | authors = ["Carl Lerche <me@carllerche.com>"] | ||||||
|  |  | ||||||
|  | [dependencies] | ||||||
|  | walkdir = "1.0.0" | ||||||
							
								
								
									
										64
									
								
								util/genfixture/src/main.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								util/genfixture/src/main.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,64 @@ | |||||||
|  | extern crate walkdir; | ||||||
|  |  | ||||||
|  | use self::walkdir::WalkDir; | ||||||
|  |  | ||||||
|  | use std::env; | ||||||
|  | use std::path::Path; | ||||||
|  | use std::collections::HashMap; | ||||||
|  |  | ||||||
|  | fn main() { | ||||||
|  |     let args: Vec<_> = env::args().collect(); | ||||||
|  |  | ||||||
|  |     let path = args.get(1).expect("usage: genfixture [PATH]"); | ||||||
|  |     let path = Path::new(path); | ||||||
|  |  | ||||||
|  |     let mut tests = HashMap::new(); | ||||||
|  |  | ||||||
|  |     for entry in WalkDir::new(path) { | ||||||
|  |         let entry = entry.unwrap(); | ||||||
|  |         let path = entry.path().to_str().unwrap(); | ||||||
|  |  | ||||||
|  |         if !path.ends_with(".json") { | ||||||
|  |             continue; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if path.contains("raw-data") { | ||||||
|  |             continue; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // Get the relevant part | ||||||
|  |         let fixture_path = path.split("fixtures/hpack/").last().unwrap(); | ||||||
|  |  | ||||||
|  |         // Now, split that into the group and the name | ||||||
|  |         let module = fixture_path.split("/").next().unwrap(); | ||||||
|  |  | ||||||
|  |         tests.entry(module.to_string()).or_insert(vec![]) | ||||||
|  |             .push(fixture_path.to_string()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     let mut one = false; | ||||||
|  |  | ||||||
|  |     for (module, tests) in tests { | ||||||
|  |         let module = module.replace("-", "_"); | ||||||
|  |  | ||||||
|  |         if one { | ||||||
|  |             println!(""); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         one = true; | ||||||
|  |  | ||||||
|  |         println!("fixture_mod!("); | ||||||
|  |         println!("    {} => {{", module); | ||||||
|  |  | ||||||
|  |         for test in tests { | ||||||
|  |             let ident = test | ||||||
|  |                 .split("/").nth(1).unwrap() | ||||||
|  |                 .split(".").next().unwrap(); | ||||||
|  |  | ||||||
|  |             println!("        ({}, {:?});", ident, test); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         println!("    }}"); | ||||||
|  |         println!(");"); | ||||||
|  |     } | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user