1pub mod event;
2pub mod point;
3pub mod time;
4pub mod trace;
5
6pub const VERSION: &str = env!("CARGO_PKG_VERSION");
7
8#[cfg(test)]
9mod test {
10 use std::fs::File;
11 use std::io::{prelude::*, BufReader, LineWriter, Write};
12 use std::sync::Mutex;
13
14 use serde_json::{from_str, json, to_string, Value};
15
16 use super::point::{Metadata, TracePoint};
17 use super::trace;
18 use super::VERSION;
19
20 struct WriteReporter<W: Write + Send + 'static> {
21 reporter: Mutex<W>,
22 }
23
24 impl<W: Write + Send + 'static> WriteReporter<W> {
25 fn new(writable: W) -> Box<WriteReporter<W>> {
26 Box::new(WriteReporter {
27 reporter: Mutex::new(writable),
28 })
29 }
30 }
31
32 impl<W: Write + Send + 'static> trace::Trace for WriteReporter<W> {
33 fn report(&self, point: TracePoint) {
34 let mut file = self.reporter.lock().unwrap();
35 file.write_all(to_string(&point).unwrap().as_bytes())
36 .expect("write file failed");
37 file.write_all(b"\n").expect("write file failed");
38 }
39
40 fn metadata(&self) -> Metadata {
41 Metadata {
42 address: "0x0000000000000000000000000000000000000000".to_string(),
43 }
44 }
45
46 fn now(&self) -> u64 {
47 0
48 }
49 }
50
51 #[test]
52 fn test_tracer() -> std::io::Result<()> {
53 trace::set_boxed_tracer(WriteReporter::new(LineWriter::new(
54 File::create("log.log")?,
55 )))
56 .expect("init tracer failed");
57 trace::start_block(1);
58 trace::start_round(0, 1);
59 trace::custom(
60 "broadcast_proposal".to_string(),
61 Some(json!({
62 "hash": "0x00",
63 "block_height": 1,
64 "round_id": 0
65 })),
66 );
67 trace::receive_proposal(
68 "receive_propose".to_string(),
69 1,
70 0,
71 "0x".to_string(),
72 "".to_string(),
73 None,
74 );
75 trace::start_step("propose".to_string(), 0, 1);
76 trace::error("check_failed".to_string(), None);
77
78 let file = File::open("log.log")?;
79 let reader = BufReader::new(file);
80 let events = vec![
81 json!({
82 "timestamp": 0,
83 "event_name": "start_block",
84 "event_type": "keyframe",
85 "tag": {
86 "block_height": 1
87 },
88 "metadata": {
89 "address": "0x0000000000000000000000000000000000000000",
90 "v": VERSION
91 }
92 }),
93 json!({
94 "timestamp": 0,
95 "event_name": "start_round",
96 "event_type": "keyframe",
97 "tag": {
98 "block_height": 1,
99 "round_id": 0
100 },
101 "metadata": {
102 "address": "0x0000000000000000000000000000000000000000",
103 "v": VERSION
104 }
105 }),
106 json!({
107 "timestamp": 0,
108 "event_name": "broadcast_proposal",
109 "event_type": "custom",
110 "tag": {
111 "block_height": 1,
112 "hash": "0x00",
113 "round_id": 0
114 },
115 "metadata": {
116 "address": "0x0000000000000000000000000000000000000000",
117 "v": VERSION
118 }
119 }),
120 json!({
121 "timestamp": 0,
122 "event_name": "receive_propose",
123 "event_type": "propose",
124 "tag": {
125 "block_height": 1,
126 "hash": "",
127 "proposer": "0x",
128 "round_id": 0
129 },
130 "metadata": {
131 "address": "0x0000000000000000000000000000000000000000",
132 "v": VERSION
133 }
134 }),
135 json!({
136 "timestamp": 0,
137 "event_name": "start_step",
138 "event_type": "keyframe",
139 "tag": {
140 "block_height": 1,
141 "round_id": 0,
142 "step_name": "propose"
143 },
144 "metadata": {
145 "address": "0x0000000000000000000000000000000000000000",
146 "v": VERSION
147 }
148 }),
149 json!({
150 "timestamp": 0,
151 "event_name": "check_failed",
152 "event_type": "error",
153 "tag": {},
154 "metadata": {
155 "address": "0x0000000000000000000000000000000000000000",
156 "v": VERSION
157 }
158 }),
159 ];
160
161 for (_i, (line, json)) in reader.lines().zip(events.iter()).enumerate() {
162 let e: Value = from_str(&line?)?;
163 let a: Value = from_str(&to_string(json)?)?;
164 assert_eq!(e, a);
165 }
166 Ok(())
167 }
168}