detect bot crashes
This commit is contained in:
parent
e86fbc7275
commit
f7261e165b
4 changed files with 29 additions and 13 deletions
1
planetwars-matchrunner/bots/crash_bot.py
Normal file
1
planetwars-matchrunner/bots/crash_bot.py
Normal file
|
@ -0,0 +1 @@
|
||||||
|
raise RuntimeError("This bot does not run!")
|
|
@ -207,8 +207,9 @@ impl DockerBotRunner {
|
||||||
let result = timeout(request.timeout, resp_fut).await;
|
let result = timeout(request.timeout, resp_fut).await;
|
||||||
let request_response = match result {
|
let request_response = match result {
|
||||||
Ok(Ok(response)) => Ok(response.to_vec()),
|
Ok(Ok(response)) => Ok(response.to_vec()),
|
||||||
// this one happens when a bot output stream ends, map this to Timeout for now
|
// Read failed.
|
||||||
Ok(Err(_read_error)) => Err(RequestError::Timeout),
|
// TODO: better logging for errors
|
||||||
|
Ok(Err(_read_error)) => Err(RequestError::BotTerminated),
|
||||||
Err(_elapsed) => Err(RequestError::Timeout),
|
Err(_elapsed) => Err(RequestError::Timeout),
|
||||||
};
|
};
|
||||||
let request_id = (self.player_id, request.request_id);
|
let request_id = (self.player_id, request.request_id);
|
||||||
|
|
|
@ -163,6 +163,7 @@ impl Future for Request {
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum RequestError {
|
pub enum RequestError {
|
||||||
Timeout,
|
Timeout,
|
||||||
|
BotTerminated,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type RequestResult<T> = Result<T, RequestError>;
|
pub type RequestResult<T> = Result<T, RequestError>;
|
||||||
|
|
|
@ -56,23 +56,20 @@ async fn match_does_run() {
|
||||||
tokio::time::sleep(Duration::from_secs(1)).await
|
tokio::time::sleep(Duration::from_secs(1)).await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn match_ctx_from_bot_spec<B: BotSpec>(bot_spec: B) -> MatchCtx {
|
|
||||||
let event_bus = Arc::new(Mutex::new(EventBus::new()));
|
|
||||||
let (logger, _rx) = mpsc::unbounded_channel();
|
|
||||||
|
|
||||||
let player_handle = bot_spec.run_bot(1, event_bus.clone(), logger.clone()).await;
|
|
||||||
let mut players = HashMap::new();
|
|
||||||
players.insert(1, player_handle);
|
|
||||||
MatchCtx::new(event_bus, players, logger)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// creates a simple match ctx which only holds a single bot
|
/// creates a simple match ctx which only holds a single bot
|
||||||
async fn with_bot_match_ctx<B, F>(bot_spec: B, func: F)
|
async fn with_bot_match_ctx<B, F>(bot_spec: B, func: F)
|
||||||
where
|
where
|
||||||
F: FnOnce(&mut MatchCtx) -> Pin<Box<dyn '_ + Future<Output = ()>>>,
|
F: FnOnce(&mut MatchCtx) -> Pin<Box<dyn '_ + Future<Output = ()>>>,
|
||||||
B: BotSpec,
|
B: BotSpec,
|
||||||
{
|
{
|
||||||
let mut ctx = match_ctx_from_bot_spec(bot_spec).await;
|
let event_bus = Arc::new(Mutex::new(EventBus::new()));
|
||||||
|
let (logger, _rx) = mpsc::unbounded_channel();
|
||||||
|
|
||||||
|
let player_handle = bot_spec.run_bot(1, event_bus.clone(), logger.clone()).await;
|
||||||
|
let mut players = HashMap::new();
|
||||||
|
players.insert(1, player_handle);
|
||||||
|
let mut ctx = MatchCtx::new(event_bus, players, logger);
|
||||||
|
|
||||||
func(&mut ctx).await;
|
func(&mut ctx).await;
|
||||||
ctx.shutdown().await;
|
ctx.shutdown().await;
|
||||||
}
|
}
|
||||||
|
@ -108,3 +105,19 @@ async fn docker_runner_timeout() {
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn docker_runner_crash() {
|
||||||
|
let bot_spec = simple_python_docker_bot_spec("./bots", "crash_bot.py");
|
||||||
|
with_bot_match_ctx(bot_spec, |ctx| {
|
||||||
|
async move {
|
||||||
|
let resp = ctx
|
||||||
|
.request(1, b"sup".to_vec(), Duration::from_millis(200))
|
||||||
|
.await;
|
||||||
|
|
||||||
|
assert_eq!(resp, Err(RequestError::BotTerminated));
|
||||||
|
}
|
||||||
|
.boxed()
|
||||||
|
})
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue