Run with mutagen on travis.
[rust-lightning] / fuzz / src / msg_targets / utils.rs
1 #![macro_use]
2
3 use lightning::util::ser::Writer;
4 pub struct VecWriter(pub Vec<u8>);
5 impl Writer for VecWriter {
6         fn write_all(&mut self, buf: &[u8]) -> Result<(), ::std::io::Error> {
7                 assert!(self.0.capacity() >= self.0.len() + buf.len());
8                 self.0.extend_from_slice(buf);
9                 Ok(())
10         }
11         fn size_hint(&mut self, size: usize) {
12                 self.0.reserve_exact(size);
13         }
14 }
15
16 // Tests a message that must survive roundtrip exactly, though may not empty the read buffer
17 // entirely
18 #[macro_export]
19 macro_rules! test_msg {
20         ($MsgType: path, $data: ident) => {
21                 {
22                         use lightning::util::ser::{Writeable, Readable};
23                         let mut r = ::std::io::Cursor::new($data);
24                         if let Ok(msg) = <$MsgType as Readable<::std::io::Cursor<&[u8]>>>::read(&mut r) {
25                                 let p = r.position() as usize;
26                                 let mut w = VecWriter(Vec::new());
27                                 msg.write(&mut w).unwrap();
28
29                                 assert_eq!(w.0.len(), p);
30                                 assert_eq!(&r.into_inner()[..p], &w.0[..p]);
31                         }
32                 }
33         }
34 }
35
36 // Tests a message that may lose data on roundtrip, but shoulnd't lose data compared to our
37 // re-serialization.
38 #[macro_export]
39 macro_rules! test_msg_simple {
40         ($MsgType: path, $data: ident) => {
41                 {
42                         use lightning::util::ser::{Writeable, Readable};
43                         let mut r = ::std::io::Cursor::new($data);
44                         if let Ok(msg) = <$MsgType as Readable<::std::io::Cursor<&[u8]>>>::read(&mut r) {
45                                 let mut w = VecWriter(Vec::new());
46                                 msg.write(&mut w).unwrap();
47
48                                 let msg = <$MsgType as Readable<::std::io::Cursor<&[u8]>>>::read(&mut ::std::io::Cursor::new(&w.0)).unwrap();
49                                 let mut w_two = VecWriter(Vec::new());
50                                 msg.write(&mut w_two).unwrap();
51                                 assert_eq!(&w.0[..], &w_two.0[..]);
52                         }
53                 }
54         }
55 }
56
57 // Tests a message that must survive roundtrip exactly, and must exactly empty the read buffer and
58 // split it back out on re-serialization.
59 #[macro_export]
60 macro_rules! test_msg_exact {
61         ($MsgType: path, $data: ident) => {
62                 {
63                         use lightning::util::ser::{Writeable, Readable};
64                         let mut r = ::std::io::Cursor::new($data);
65                         if let Ok(msg) = <$MsgType as Readable<::std::io::Cursor<&[u8]>>>::read(&mut r) {
66                                 let mut w = VecWriter(Vec::new());
67                                 msg.write(&mut w).unwrap();
68                                 assert_eq!(&r.into_inner()[..], &w.0[..]);
69                         }
70                 }
71         }
72 }
73
74 // Tests a message that must survive roundtrip exactly, modulo one "hole" which may be set to 0s on
75 // re-serialization.
76 #[macro_export]
77 macro_rules! test_msg_hole {
78         ($MsgType: path, $data: ident, $hole: expr, $hole_len: expr) => {
79                 {
80                         use lightning::util::ser::{Writeable, Readable};
81                         let mut r = ::std::io::Cursor::new($data);
82                         if let Ok(msg) = <$MsgType as Readable<::std::io::Cursor<&[u8]>>>::read(&mut r) {
83                                 let mut w = VecWriter(Vec::new());
84                                 msg.write(&mut w).unwrap();
85                                 let p = w.0.len() as usize;
86
87                                 assert_eq!(w.0.len(), p);
88                                 assert_eq!(&r.get_ref()[..$hole], &w.0[..$hole]);
89                                 assert_eq!(&r.get_ref()[$hole+$hole_len..p], &w.0[$hole+$hole_len..]);
90                         }
91                 }
92         }
93 }