@@ -27,6 +27,20 @@ class LipsBudgetTest {
2727 assertEquals(10 , perTargetAfterUsage)
2828 }
2929
30+ @Test
31+ fun computePerTargetBudget_Time_FairShare () {
32+ val config = EMConfig ().apply {
33+ stoppingCriterion = EMConfig .StoppingCriterion .TIME
34+ maxTimeInSeconds = 120
35+ }
36+ val time = SearchTimeController ()
37+ val budget = LipsBudget (config, time)
38+
39+ // remaining seconds = 120; uncovered=4 -> 30 each
40+ val perTarget = budget.computePerTargetBudget(uncoveredSize = 4 )
41+ assertEquals(30 , perTarget)
42+ }
43+
3044 @Test
3145 fun computePerTargetBudget_Actions_ZeroUncovered_ReturnsRemaining () {
3246 val config = EMConfig ().apply {
@@ -85,6 +99,33 @@ class LipsBudgetTest {
8599 val shouldSwitch = budget.shouldSwitchTarget(coveredNow = false )
86100 assertTrue(shouldSwitch)
87101 }
102+
103+ @Test
104+ fun updateAndSwitchBudget_Time () {
105+ val config = EMConfig ().apply {
106+ stoppingCriterion = EMConfig .StoppingCriterion .TIME
107+ maxTimeInSeconds = 120
108+ }
109+ val time = SearchTimeController ()
110+ val budget = LipsBudget (config, time)
111+
112+ // initialize per-target remaining seconds and start the timer
113+ budget.budgetLeftForCurrentTarget = 2
114+ time.startSearch()
115+
116+ val startSeconds = time.getElapsedSeconds()
117+ Thread .sleep(1100 )
118+ budget.updatePerTargetBudget(actionsAtGenStart = 0 , secondsAtGenStart = startSeconds)
119+ assertEquals(1 , budget.budgetLeftForCurrentTarget)
120+
121+ val startSeconds2 = time.getElapsedSeconds()
122+ Thread .sleep(1100 )
123+ budget.updatePerTargetBudget(actionsAtGenStart = 0 , secondsAtGenStart = startSeconds2)
124+ assertEquals(0 , budget.budgetLeftForCurrentTarget)
125+
126+ val shouldSwitch = budget.shouldSwitchTarget(coveredNow = false )
127+ assertTrue(shouldSwitch)
128+ }
88129}
89130
90131
0 commit comments