Skip to content

Commit 91b99b5

Browse files
afq984Chromeos LUCI
authored andcommitted
audio_processor: Add test for abnormally terminated worker
This proves that ManagedBlockingSeqPacketProcessor gracefully fails (instead of hangs) if the worker process is terminated abnormally. BUG=b:446725446 TEST=bazel test //audio_processor:integration_tests_tests/peer audio_processor: Add test for abnormally terminated worker Change-Id: I1547fca70eb9471835538ed356d42522ff437fa8 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/adhd/+/7207128 Reviewed-by: Yu-Hsuan Hsu <yuhsuan@chromium.org> Reviewed-by: Hung-Hsien Chen <hunghsienchen@chromium.org> Commit-Queue: Li-Yu Yu <aaronyu@google.com> Tested-by: chromeos-cop-builder@chromeos-cop.iam.gserviceaccount.com <chromeos-cop-builder@chromeos-cop.iam.gserviceaccount.com>
1 parent 35f470b commit 91b99b5

File tree

3 files changed

+111
-0
lines changed

3 files changed

+111
-0
lines changed

audio_processor/c/bad_plugin.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,15 @@ static enum status failing_run(struct plugin_processor* p,
2525
return ErrOther;
2626
}
2727

28+
static enum status abort_run(struct plugin_processor* p,
29+
const struct multi_slice* in,
30+
struct multi_slice* out) {
31+
(void)p;
32+
(void)in;
33+
(void)out;
34+
abort();
35+
}
36+
2837
static enum status get_output_frame_rate_48k(struct plugin_processor* p,
2938
size_t* frame_rate) {
3039
*frame_rate = 48000;
@@ -149,3 +158,30 @@ enum status bad_plugin_failing_get_output_frame_rate_create(
149158
*out = p;
150159
return StatusOk;
151160
}
161+
162+
enum status bad_plugin_abort_create(
163+
struct plugin_processor** out,
164+
const struct plugin_processor_config* config) {
165+
(void)out;
166+
(void)config;
167+
abort();
168+
}
169+
170+
enum status bad_plugin_abort_run_create(
171+
struct plugin_processor** out,
172+
const struct plugin_processor_config* config) {
173+
(void)config;
174+
static const struct plugin_processor_ops ops = {
175+
.run = abort_run,
176+
.destroy = free_destroy,
177+
.get_output_frame_rate = get_output_frame_rate_48k,
178+
};
179+
180+
struct plugin_processor* p = calloc(1, sizeof(*p));
181+
if (!p) {
182+
return ErrOutOfMemory;
183+
}
184+
p->ops = &ops;
185+
*out = p;
186+
return StatusOk;
187+
}

audio_processor/c/bad_plugin.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,14 @@ enum status bad_plugin_failing_get_output_frame_rate_create(
4242
struct plugin_processor** out,
4343
const struct plugin_processor_config* config);
4444

45+
enum status bad_plugin_abort_create(
46+
struct plugin_processor** out,
47+
const struct plugin_processor_config* config);
48+
49+
enum status bad_plugin_abort_run_create(
50+
struct plugin_processor** out,
51+
const struct plugin_processor_config* config);
52+
4553
#ifdef __cplusplus
4654
}
4755
#endif

audio_processor/tests/peer.rs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,70 @@ fn test_peer_ffi_negate() {
8080
let output = processor.process(input.as_multi_slice()).unwrap();
8181
assert_eq!(output.into_raw(), [[-1., -2., -3., -4.]]);
8282
}
83+
84+
#[test]
85+
#[cfg(feature = "bazel")]
86+
fn test_peer_ffi_abort_create() {
87+
let audio_worker_executable = env!("CARGO_BIN_EXE_audio-worker");
88+
let factory =
89+
AudioWorkerSubprocessFactory::default().with_executable_path(audio_worker_executable);
90+
let test_plugin_path = std::env::var("LIBTEST_PLUGINS_SO").expect("LIBTEST_PLUGINS_SO not set");
91+
92+
let result = ManagedBlockingSeqPacketProcessor::new(
93+
&factory,
94+
Format {
95+
channels: 1,
96+
block_size: 4,
97+
frame_rate: 48000,
98+
},
99+
config::Processor::Plugin {
100+
path: test_plugin_path.into(),
101+
constructor: "bad_plugin_abort_create".to_string(),
102+
},
103+
);
104+
105+
let err_msg = match result {
106+
Ok(_) => panic!("Expected an error, but got Ok"),
107+
Err(e) => {
108+
format!("{e:#}")
109+
}
110+
};
111+
assert_eq!(
112+
err_msg,
113+
"BlockingSeqPacketProcessor::new: recv init message reply: empty message"
114+
);
115+
}
116+
117+
#[test]
118+
#[cfg(feature = "bazel")]
119+
fn test_peer_ffi_abort_run() {
120+
let audio_worker_executable = env!("CARGO_BIN_EXE_audio-worker");
121+
let factory =
122+
AudioWorkerSubprocessFactory::default().with_executable_path(audio_worker_executable);
123+
let test_plugin_path = std::env::var("LIBTEST_PLUGINS_SO").expect("LIBTEST_PLUGINS_SO not set");
124+
125+
let mut processor = ManagedBlockingSeqPacketProcessor::new(
126+
&factory,
127+
Format {
128+
channels: 1,
129+
block_size: 4,
130+
frame_rate: 48000,
131+
},
132+
config::Processor::Plugin {
133+
path: test_plugin_path.into(),
134+
constructor: "bad_plugin_abort_run_create".to_string(),
135+
},
136+
)
137+
.unwrap();
138+
139+
let mut input = MultiBuffer::from(vec![vec![1., 2., 3., 4.]]);
140+
let result = processor.process(input.as_multi_slice());
141+
142+
let err_msg = match result {
143+
Ok(_) => panic!("Expected an error, but got Ok"),
144+
Err(e) => {
145+
format!("{e:#}")
146+
}
147+
};
148+
assert_eq!(err_msg, "unrecoverable error: empty message");
149+
}

0 commit comments

Comments
 (0)