fix(battle-node): BattleSession crash safety, fresh-key per push, phase guards
- Wrap HandleMsgEventAsync / HandleAliveEventAsync bodies in try/catch(Exception) logging at Error, eliminating async-void unobserved-exception crash risk (Issue 1). - Replace deterministic seq-based key generator with RandomNumberGenerator.GetInt32 so each EncodeAndSendAsync call uses a fresh random key (Issue 2). - Add `when Phase == …` guards to InitNetwork / Loaded / Swap cases in ComputeResponses; add default arm that logs+drops out-of-order URIs (Issue 3). - Widen SendSioAckAsync arg from int to long; drop (int) cast at call site; boundary cast to int is now checked() for defensive overflow detection (Issue 4). - Update RunAsync doc comment (was stale Task-13 placeholder) (Issue 5). - Add Kill and out-of-order-Swap-before-Loaded tests (Issue 6). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -61,4 +61,25 @@ public class BattleSessionDispatchTests
|
||||
Assert.That(noStock, Is.True);
|
||||
Assert.That(s.Phase, Is.EqualTo(BattleSessionPhase.Terminal));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Kill_PushesBattleFinishNoContest_TransitionsToTerminal()
|
||||
{
|
||||
var s = NewSession();
|
||||
var responses = s.ComputeResponses(NewEnvelope(NetworkBattleUri.Kill));
|
||||
var (env, noStock) = responses.Single();
|
||||
Assert.That(env.Uri, Is.EqualTo(NetworkBattleUri.BattleFinish));
|
||||
Assert.That(noStock, Is.True);
|
||||
Assert.That(s.Phase, Is.EqualTo(BattleSessionPhase.Terminal));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Swap_ArrivingBeforeLoaded_ProducesNoResponseAndDoesNotAdvancePhase()
|
||||
{
|
||||
var s = NewSession();
|
||||
// Skip Loaded — fire Swap straight out of AwaitingInitNetwork.
|
||||
var responses = s.ComputeResponses(NewEnvelope(NetworkBattleUri.Swap));
|
||||
Assert.That(responses, Is.Empty);
|
||||
Assert.That(s.Phase, Is.EqualTo(BattleSessionPhase.AwaitingInitNetwork));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user