Skip to content
This repository was archived by the owner on Dec 29, 2022. It is now read-only.

Commit 5223549

Browse files
committed
Refactored integration tests
1 parent 8a2bcca commit 5223549

File tree

3 files changed

+189
-199
lines changed

3 files changed

+189
-199
lines changed

tests/support/harness.rs

Lines changed: 0 additions & 165 deletions
This file was deleted.

tests/support/mod.rs

Lines changed: 186 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,201 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
use serde_json;
1112
use std::env;
1213
use std::fs;
13-
use std::io::prelude::*;
14+
use std::io::{self, BufRead, BufReader, Read, Write};
15+
use std::mem;
1416
use std::path::{Path, PathBuf};
15-
use std::process::{Command, Stdio};
17+
use std::process::{Child, ChildStdin, ChildStdout, Command, Stdio};
1618
use std::str;
19+
use std::sync::{Arc, Condvar, Mutex};
20+
use std::thread;
21+
use std::time::Duration;
22+
1723

1824
use support::paths::TestPathExt;
1925

20-
pub mod harness;
2126
pub mod paths;
2227

28+
/// Executes `func` and panics if it takes longer than `dur`.
29+
pub fn timeout<F>(dur: Duration, func: F)
30+
where F: FnOnce() + Send + 'static {
31+
let pair = Arc::new((Mutex::new(false), Condvar::new()));
32+
let pair2 = pair.clone();
33+
34+
thread::spawn(move|| {
35+
let &(ref lock, ref cvar) = &*pair2;
36+
func();
37+
let mut finished = lock.lock().unwrap();
38+
*finished = true;
39+
// We notify the condvar that the value has changed.
40+
cvar.notify_one();
41+
});
42+
43+
// Wait for the test to finish.
44+
let &(ref lock, ref cvar) = &*pair;
45+
let mut finished = lock.lock().unwrap();
46+
// As long as the value inside the `Mutex` is false, we wait.
47+
while !*finished {
48+
let result = cvar.wait_timeout(finished, dur).unwrap();
49+
if result.1.timed_out() {
50+
panic!("Timed out")
51+
}
52+
finished = result.0
53+
}
54+
}
55+
56+
#[derive(Clone, Debug)]
57+
pub struct ExpectedMessage {
58+
id: Option<u64>,
59+
contains: Vec<String>,
60+
}
61+
62+
impl ExpectedMessage {
63+
pub fn new(id: Option<u64>) -> ExpectedMessage {
64+
ExpectedMessage {
65+
id: id,
66+
contains: vec![],
67+
}
68+
}
69+
70+
pub fn expect_contains(&mut self, s: &str) -> &mut ExpectedMessage {
71+
self.contains.push(s.to_owned());
72+
self
73+
}
74+
}
75+
76+
pub fn read_message<R: Read>(reader: &mut BufReader<R>) -> io::Result<String> {
77+
let mut content_length = None;
78+
// Read the headers
79+
loop {
80+
let mut header = String::new();
81+
reader.read_line(&mut header)?;
82+
if header.len() == 0 {
83+
panic!("eof")
84+
}
85+
if header == "\r\n" {
86+
// This is the end of the headers
87+
break;
88+
}
89+
let parts: Vec<&str> = header.splitn(2, ": ").collect();
90+
if parts[0] == "Content-Length" {
91+
content_length = Some(parts[1].trim().parse::<usize>().unwrap())
92+
}
93+
}
94+
95+
// Read the actual message
96+
let content_length = content_length.expect("did not receive Content-Length header");
97+
let mut msg = vec![0; content_length];
98+
reader.read_exact(&mut msg)?;
99+
let result = String::from_utf8_lossy(&msg).into_owned();
100+
Ok(result)
101+
}
102+
103+
pub fn expect_messages<R: Read>(reader: &mut BufReader<R>, expected: &[&ExpectedMessage]) {
104+
let mut results: Vec<String> = Vec::new();
105+
while results.len() < expected.len() {
106+
let msg = read_message(reader).unwrap();
107+
results.push(msg);
108+
}
109+
110+
println!(
111+
"expect_messages:\n results: {:#?},\n expected: {:#?}",
112+
results,
113+
expected
114+
);
115+
assert_eq!(results.len(), expected.len());
116+
for (found, expected) in results.iter().zip(expected.iter()) {
117+
let values: serde_json::Value = serde_json::from_str(found).unwrap();
118+
assert!(
119+
values
120+
.get("jsonrpc")
121+
.expect("Missing jsonrpc field")
122+
.as_str()
123+
.unwrap() == "2.0",
124+
"Bad jsonrpc field"
125+
);
126+
if let Some(id) = expected.id {
127+
assert_eq!(
128+
values
129+
.get("id")
130+
.expect("Missing id field")
131+
.as_u64()
132+
.unwrap(),
133+
id,
134+
"Unexpected id"
135+
);
136+
}
137+
for c in expected.contains.iter() {
138+
found
139+
.find(c)
140+
.expect(&format!("Could not find `{}` in `{}`", c, found));
141+
}
142+
}
143+
}
144+
145+
pub struct RlsHandle {
146+
child: Child,
147+
stdin: ChildStdin,
148+
stdout: BufReader<ChildStdout>,
149+
}
150+
151+
impl RlsHandle {
152+
pub fn new(mut child: Child) -> RlsHandle {
153+
let stdin = mem::replace(&mut child.stdin, None).unwrap();
154+
let stdout = mem::replace(&mut child.stdout, None).unwrap();
155+
let stdout = BufReader::new(stdout);
156+
157+
RlsHandle {
158+
child,
159+
stdin,
160+
stdout,
161+
}
162+
}
163+
164+
pub fn send_string(&mut self, s: &str) -> io::Result<usize> {
165+
let full_msg = format!("Content-Length: {}\r\n\r\n{}", s.len(), s);
166+
self.stdin.write(full_msg.as_bytes())
167+
}
168+
pub fn send(&mut self, j: serde_json::Value) -> io::Result<usize> {
169+
self.send_string(&j.to_string())
170+
}
171+
pub fn notify(&mut self, method: &str, params: serde_json::Value) -> io::Result<usize> {
172+
self.send(json!({
173+
"jsonrpc": "2.0",
174+
"method": method,
175+
"params": params,
176+
}))
177+
}
178+
pub fn request(&mut self, id: u64, method: &str, params: serde_json::Value) -> io::Result<usize> {
179+
self.send(json!({
180+
"jsonrpc": "2.0",
181+
"id": id,
182+
"method": method,
183+
"params": params,
184+
}))
185+
}
186+
pub fn shutdown_exit(&mut self) {
187+
self.request(99999, "shutdown", json!({})).unwrap();
188+
189+
self.expect_messages(&[
190+
&ExpectedMessage::new(Some(99999)),
191+
]);
192+
193+
self.notify("exit", json!({})).unwrap();
194+
195+
let ecode = self.child.wait()
196+
.expect("failed to wait on child rls process");
197+
198+
assert!(ecode.success());
199+
}
200+
201+
pub fn expect_messages(&mut self, expected: &[&ExpectedMessage]) {
202+
expect_messages(&mut self.stdout, expected);
203+
}
204+
}
205+
23206
#[derive(PartialEq,Clone)]
24207
struct FileBuilder {
25208
path: PathBuf,

0 commit comments

Comments
 (0)