86 lines
2.7 KiB
Go
86 lines
2.7 KiB
Go
package lifecycle
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"testing/synctest"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
agentctl "github.com/kandev/kandev/internal/agent/runtime/agentctl"
|
|
"github.com/kandev/kandev/internal/agentctl/types/streams"
|
|
"github.com/kandev/kandev/internal/common/constants"
|
|
)
|
|
|
|
func TestCoalescedExecutionContextDoesNotConsumeLaunchBudgetDuringPreparation(t *testing.T) {
|
|
synctest.Test(t, func(t *testing.T) {
|
|
manager := &Manager{stopCh: make(chan struct{})}
|
|
sharedCtx, cancel := manager.coalescedExecutionContext(context.Background())
|
|
defer cancel()
|
|
|
|
if _, ok := sharedCtx.Deadline(); ok {
|
|
t.Fatal("coalesced execution context must not have a launch deadline")
|
|
}
|
|
|
|
// Simulate environment creation before the runtime launch phase begins.
|
|
<-time.After(constants.SetupScriptTimeout)
|
|
launchCtx, launchCancel := withLaunchPhaseTimeout(sharedCtx)
|
|
defer launchCancel()
|
|
|
|
deadline, ok := launchCtx.Deadline()
|
|
if !ok {
|
|
t.Fatal("launch phase context must have a deadline")
|
|
}
|
|
if got := time.Until(deadline); got != constants.AgentLaunchTimeout {
|
|
t.Fatalf("launch phase budget = %s, want %s", got, constants.AgentLaunchTimeout)
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestPreparationContextRetainsItsIndependentBudget(t *testing.T) {
|
|
synctest.Test(t, func(t *testing.T) {
|
|
base := context.Background()
|
|
launchCtx, launchCancel := withLaunchPhaseTimeout(base)
|
|
defer launchCancel()
|
|
|
|
prepareParent := preparationContext(launchCtx)
|
|
if _, ok := prepareParent.Deadline(); ok {
|
|
t.Fatal("preparation parent must not inherit the launch deadline")
|
|
}
|
|
|
|
prepareCtx, prepareCancel := context.WithTimeout(prepareParent, constants.SetupScriptTimeout)
|
|
defer prepareCancel()
|
|
deadline, ok := prepareCtx.Deadline()
|
|
if !ok {
|
|
t.Fatal("preparation context must have a deadline")
|
|
}
|
|
if got := time.Until(deadline); got != constants.SetupScriptTimeout {
|
|
t.Fatalf("preparation budget = %s, want %s", got, constants.SetupScriptTimeout)
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestFinishContextResetReturnsEventsBufferedDuringFinalization(t *testing.T) {
|
|
execution := &AgentExecution{}
|
|
require.NoError(t, execution.beginContextReset())
|
|
|
|
buffered := agentctl.AgentEvent{
|
|
Type: streams.EventTypeSessionModels,
|
|
SessionID: "new-session",
|
|
}
|
|
stale := agentctl.AgentEvent{
|
|
Type: streams.EventTypeSessionStatus,
|
|
SessionID: "old-session",
|
|
}
|
|
require.True(t, execution.bufferOrDropContextResetEvent(buffered))
|
|
require.True(t, execution.bufferOrDropContextResetEvent(stale))
|
|
|
|
final := execution.finishContextReset("new-session")
|
|
require.Equal(t, []agentctl.AgentEvent{buffered}, final)
|
|
require.False(t, execution.bufferOrDropContextResetEvent(agentctl.AgentEvent{
|
|
Type: streams.EventTypeSessionStatus,
|
|
SessionID: "new-session",
|
|
}))
|
|
}
|