Skip to content

Commit 9f8a137

Browse files
committed
add integration tests with multithreading
1 parent 2590cb2 commit 9f8a137

File tree

2 files changed

+169
-2
lines changed

2 files changed

+169
-2
lines changed

tests/handle.rs

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
use std::{path::Path, thread};
2+
3+
use eccodes::{CodesHandle, KeyType, ProductKind};
4+
use fallible_iterator::FallibleIterator;
5+
6+
#[test]
7+
fn thread_safety() {
8+
thread::spawn(|| loop {
9+
let file_path = Path::new("./data/iceland.grib");
10+
11+
let mut handle = CodesHandle::new_from_file(file_path, ProductKind::GRIB).unwrap();
12+
let current_message = handle.next().unwrap().unwrap();
13+
14+
for _ in 0..100 {
15+
let _ = current_message.read_key("name").unwrap();
16+
17+
let str_key = current_message.read_key("name").unwrap();
18+
19+
match str_key.value {
20+
KeyType::Str(_) => {}
21+
_ => panic!("Incorrect variant of string key"),
22+
}
23+
24+
assert_eq!(str_key.name, "name");
25+
}
26+
27+
drop(current_message);
28+
drop(handle);
29+
});
30+
31+
for _ in 0..1000 {
32+
let file_path = Path::new("./data/iceland.grib");
33+
34+
let mut handle = CodesHandle::new_from_file(file_path, ProductKind::GRIB).unwrap();
35+
let current_message = handle.next().unwrap().unwrap();
36+
37+
let long_key = current_message
38+
.read_key("numberOfPointsAlongAParallel")
39+
.unwrap();
40+
41+
match long_key.value {
42+
KeyType::Int(_) => {}
43+
_ => panic!("Incorrect variant of long key"),
44+
}
45+
46+
assert_eq!(long_key.name, "numberOfPointsAlongAParallel");
47+
48+
drop(current_message);
49+
drop(handle);
50+
}
51+
}

tests/index.rs

+118-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
#![cfg(feature = "ec_index")]
22

3-
use std::path::Path;
3+
use std::{path::Path, thread};
44

55
use eccodes::{codes_index::Select, CodesHandle, CodesIndex, KeyType, ProductKind};
66
use fallible_iterator::FallibleIterator;
7+
use rand::Rng;
78

89
#[test]
910
fn iterate_handle_from_index() {
@@ -78,4 +79,119 @@ fn collect_index_iterator() {
7879
let level = handle.collect::<Vec<_>>().unwrap();
7980

8081
assert_eq!(level.len(), 5);
81-
}
82+
}
83+
84+
#[test]
85+
fn add_file_error() {
86+
for _ in 0..100 {
87+
// running multiple times to catch segfaults
88+
let keys = vec!["shortName", "typeOfLevel", "level", "stepType"];
89+
let index = CodesIndex::new_from_keys(&keys).unwrap();
90+
let grib_path = Path::new("./data/xxx.grib");
91+
let index = index.add_grib_file(grib_path);
92+
93+
assert!(index.is_err());
94+
}
95+
}
96+
97+
#[test]
98+
fn add_file_while_index_open() {
99+
thread::spawn(|| {
100+
let file_path = Path::new("./data/iceland-surface.idx");
101+
let mut index_op = CodesIndex::read_from_file(file_path).unwrap();
102+
103+
loop {
104+
index_op = index_op
105+
.select("shortName", "2t")
106+
.unwrap()
107+
.select("typeOfLevel", "surface")
108+
.unwrap()
109+
.select("level", 0)
110+
.unwrap()
111+
.select("stepType", "instant")
112+
.unwrap();
113+
}
114+
});
115+
116+
let keys = vec!["shortName", "typeOfLevel", "level", "stepType"];
117+
let grib_path = Path::new("./data/iceland-surface.grib");
118+
let index = CodesIndex::new_from_keys(&keys)
119+
.unwrap()
120+
.add_grib_file(grib_path);
121+
122+
assert!(index.is_ok());
123+
}
124+
125+
#[test]
126+
fn add_file_to_read_index() {
127+
let file_path = Path::new("./data/iceland-surface.idx");
128+
let grib_path = Path::new("./data/iceland-surface.grib");
129+
130+
let _index = CodesIndex::read_from_file(file_path)
131+
.unwrap()
132+
.add_grib_file(grib_path)
133+
.unwrap()
134+
.select("shortName", "2t")
135+
.unwrap()
136+
.select("typeOfLevel", "surface")
137+
.unwrap()
138+
.select("level", 0)
139+
.unwrap()
140+
.select("stepType", "instant")
141+
.unwrap();
142+
}
143+
144+
#[test]
145+
fn simulatenous_index_destructors() {
146+
let h1 = thread::spawn(|| {
147+
let mut rng = rand::thread_rng();
148+
149+
for _ in 0..1000 {
150+
let sleep_time = rng.gen_range(12..50); // randomizing sleep time to hopefully catch segfaults
151+
152+
let file_path = Path::new("./data/iceland-surface.idx");
153+
let index_op = CodesIndex::read_from_file(file_path)
154+
.unwrap()
155+
.select("shortName", "2t")
156+
.unwrap()
157+
.select("typeOfLevel", "surface")
158+
.unwrap()
159+
.select("level", 0)
160+
.unwrap()
161+
.select("stepType", "instant")
162+
.unwrap();
163+
164+
thread::sleep(std::time::Duration::from_millis(sleep_time));
165+
drop(index_op);
166+
}
167+
});
168+
169+
let h2 = thread::spawn(|| {
170+
let mut rng = rand::thread_rng();
171+
172+
for _ in 0..1000 {
173+
let sleep_time = rng.gen_range(24..65); // randomizing sleep time to hopefully catch segfaults
174+
175+
let keys = vec!["shortName", "typeOfLevel", "level", "stepType"];
176+
let grib_path = Path::new("./data/iceland-surface.grib");
177+
let index = CodesIndex::new_from_keys(&keys)
178+
.unwrap()
179+
.add_grib_file(grib_path)
180+
.unwrap()
181+
.select("shortName", "2t")
182+
.unwrap()
183+
.select("typeOfLevel", "surface")
184+
.unwrap()
185+
.select("level", 0)
186+
.unwrap()
187+
.select("stepType", "instant")
188+
.unwrap();
189+
190+
thread::sleep(std::time::Duration::from_millis(sleep_time));
191+
drop(index);
192+
}
193+
});
194+
195+
h1.join().unwrap();
196+
h2.join().unwrap();
197+
}

0 commit comments

Comments
 (0)