@@ -43,11 +43,13 @@ var validStateTransitions = map[State][]State{
43
43
44
44
func TestLockAcquisitionAndRelease (t * testing.T ) {
45
45
sm := New (StateNew , validStateTransitions )
46
+ assert .False (t , sm .IsLockAcquired ())
46
47
47
48
// Test valid lock acquisition
48
49
lock , err := sm .AcquireLock ()
49
50
assert .NoError (t , err )
50
51
assert .NotNil (t , lock )
52
+ assert .True (t , sm .IsLockAcquired ())
51
53
52
54
// Test transition with lock
53
55
err = sm .Transition (lock , StateInstallationConfigured )
@@ -56,120 +58,118 @@ func TestLockAcquisitionAndRelease(t *testing.T) {
56
58
57
59
// Release lock
58
60
lock .Release ()
61
+ assert .False (t , sm .IsLockAcquired ())
59
62
60
63
// Test double lock acquisition
61
64
lock , err = sm .AcquireLock ()
62
65
assert .NoError (t , err )
63
66
assert .NotNil (t , lock )
67
+ assert .True (t , sm .IsLockAcquired ())
64
68
65
69
err = sm .Transition (lock , StatePreflightsRunning )
66
70
assert .NoError (t , err )
67
71
68
72
// Release lock
69
73
lock .Release ()
70
74
assert .Equal (t , StatePreflightsRunning , sm .CurrentState ())
75
+ assert .False (t , sm .IsLockAcquired ())
71
76
}
72
77
73
78
func TestDoubleLockAcquisition (t * testing.T ) {
74
79
sm := New (StateNew , validStateTransitions )
80
+ assert .False (t , sm .IsLockAcquired ())
75
81
76
82
lock1 , err := sm .AcquireLock ()
77
83
assert .NoError (t , err )
84
+ assert .True (t , sm .IsLockAcquired ())
78
85
79
86
// Try to acquire second lock while first is held
80
87
lock2 , err := sm .AcquireLock ()
81
88
assert .Error (t , err , "second lock acquisition should fail while first is held" )
82
89
assert .Nil (t , lock2 )
83
90
assert .Contains (t , err .Error (), "lock already acquired" )
91
+ assert .True (t , sm .IsLockAcquired ())
84
92
85
93
// Release first lock
86
94
lock1 .Release ()
95
+ assert .False (t , sm .IsLockAcquired ())
87
96
88
97
// Now second lock should work
89
98
lock2 , err = sm .AcquireLock ()
90
99
assert .NoError (t , err )
91
100
assert .NotNil (t , lock2 )
101
+ assert .True (t , sm .IsLockAcquired ())
92
102
93
103
// Release second lock
94
104
lock2 .Release ()
105
+ assert .False (t , sm .IsLockAcquired ())
95
106
}
96
107
97
108
func TestLockReleaseAfterTransition (t * testing.T ) {
98
109
sm := New (StateNew , validStateTransitions )
110
+ assert .False (t , sm .IsLockAcquired ())
99
111
100
112
lock , err := sm .AcquireLock ()
101
113
assert .NoError (t , err )
114
+ assert .True (t , sm .IsLockAcquired ())
102
115
103
116
err = sm .Transition (lock , StateInstallationConfigured )
104
117
assert .NoError (t , err )
118
+ assert .True (t , sm .IsLockAcquired ())
105
119
106
120
// Release lock after transition
107
121
lock .Release ()
122
+ assert .False (t , sm .IsLockAcquired ())
108
123
109
124
// State should remain changed
110
125
assert .Equal (t , StateInstallationConfigured , sm .CurrentState ())
111
126
}
112
127
113
128
func TestDoubleLockRelease (t * testing.T ) {
114
129
sm := New (StateNew , validStateTransitions )
130
+ assert .False (t , sm .IsLockAcquired ())
115
131
116
132
lock , err := sm .AcquireLock ()
117
133
assert .NoError (t , err )
134
+ assert .True (t , sm .IsLockAcquired ())
118
135
119
136
// Release lock
120
137
lock .Release ()
138
+ assert .False (t , sm .IsLockAcquired ())
121
139
122
140
// Acquire another lock
123
141
lock2 , err := sm .AcquireLock ()
124
142
assert .NoError (t , err )
125
143
assert .NotNil (t , lock2 )
144
+ assert .True (t , sm .IsLockAcquired ())
126
145
127
146
// Second release should not actually do anything
128
147
lock .Release ()
148
+ assert .True (t , sm .IsLockAcquired ())
129
149
130
150
// Should not be able to acquire lock after as the other lock is still held
131
151
nilLock , err := sm .AcquireLock ()
132
152
assert .Error (t , err , "should not be able to acquire lock after as the other lock is still held" )
133
153
assert .Nil (t , nilLock )
154
+ assert .True (t , sm .IsLockAcquired ())
134
155
135
156
// Release the second lock
136
157
lock2 .Release ()
158
+ assert .False (t , sm .IsLockAcquired ())
137
159
138
160
// Should be able to acquire lock after the other lock is released
139
161
lock3 , err := sm .AcquireLock ()
140
162
assert .NoError (t , err )
141
163
assert .NotNil (t , lock3 )
164
+ assert .True (t , sm .IsLockAcquired ())
142
165
143
166
lock3 .Release ()
144
- }
145
-
146
- func TestConcurrentLockBlocking (t * testing.T ) {
147
- sm := New (StateNew , validStateTransitions )
148
-
149
- // Start first lock acquisition
150
- lock1 , err := sm .AcquireLock ()
151
- assert .NoError (t , err )
152
- assert .NotNil (t , lock1 )
153
-
154
- // Try to acquire second lock while first is held
155
- lock2 , err := sm .AcquireLock ()
156
- assert .Error (t , err , "second lock should fail while first is held" )
157
- assert .Nil (t , lock2 )
158
- assert .Contains (t , err .Error (), "lock already acquired" )
159
-
160
- // Release first lock
161
- lock1 .Release ()
162
-
163
- // Now second lock should work
164
- lock2 , err = sm .AcquireLock ()
165
- assert .NoError (t , err )
166
- assert .NotNil (t , lock2 )
167
-
168
- lock2 .Release ()
167
+ assert .False (t , sm .IsLockAcquired ())
169
168
}
170
169
171
170
func TestRaceConditionMultipleGoroutines (t * testing.T ) {
172
171
sm := New (StateNew , validStateTransitions )
172
+ assert .False (t , sm .IsLockAcquired ())
173
173
174
174
var wg sync.WaitGroup
175
175
successCount := 0
@@ -203,10 +203,13 @@ func TestRaceConditionMultipleGoroutines(t *testing.T) {
203
203
// Only one transition should succeed
204
204
assert .Equal (t , 1 , successCount , "only one transition should succeed" )
205
205
assert .Equal (t , StateInstallationConfigured , sm .CurrentState ())
206
+ // There should be no lock acquired at the end
207
+ assert .False (t , sm .IsLockAcquired ())
206
208
}
207
209
208
210
func TestRaceConditionReadWrite (t * testing.T ) {
209
211
sm := New (StateNew , validStateTransitions )
212
+ assert .False (t , sm .IsLockAcquired ())
210
213
211
214
var wg sync.WaitGroup
212
215
@@ -257,6 +260,8 @@ func TestRaceConditionReadWrite(t *testing.T) {
257
260
finalState := sm .CurrentState ()
258
261
assert .True (t , finalState == StateInstallationConfigured || finalState == StatePreflightsRunning ,
259
262
"final state should be one of the expected states" )
263
+ // There should be no lock acquired at the end
264
+ assert .False (t , sm .IsLockAcquired ())
260
265
}
261
266
262
267
func TestIsFinalState (t * testing.T ) {
@@ -309,11 +314,13 @@ func TestFinalStateTransitionBlocking(t *testing.T) {
309
314
310
315
func TestMultiStateTransitionWithLock (t * testing.T ) {
311
316
sm := New (StateNew , validStateTransitions )
317
+ assert .False (t , sm .IsLockAcquired ())
312
318
313
319
// Acquire lock and transition through multiple states
314
320
lock , err := sm .AcquireLock ()
315
321
assert .NoError (t , err )
316
322
assert .NotNil (t , lock )
323
+ assert .True (t , sm .IsLockAcquired ())
317
324
318
325
// Transition 1: New -> StateInstallationConfigured
319
326
err = sm .Transition (lock , StateInstallationConfigured )
@@ -335,18 +342,22 @@ func TestMultiStateTransitionWithLock(t *testing.T) {
335
342
assert .NoError (t , err )
336
343
assert .Equal (t , StateInfrastructureInstalling , sm .CurrentState ())
337
344
345
+ assert .True (t , sm .IsLockAcquired ())
338
346
// Release the lock
339
347
lock .Release ()
348
+ assert .False (t , sm .IsLockAcquired ())
340
349
341
350
// State should be the final state in the transition chain
342
351
assert .Equal (t , StateInfrastructureInstalling , sm .CurrentState (), "state should be the final transitioned state after lock release" )
343
352
}
344
353
345
354
func TestInvalidTransition (t * testing.T ) {
346
355
sm := New (StateNew , validStateTransitions )
356
+ assert .False (t , sm .IsLockAcquired ())
347
357
348
358
lock , err := sm .AcquireLock ()
349
359
assert .NoError (t , err )
360
+ assert .True (t , sm .IsLockAcquired ())
350
361
351
362
// Try invalid transition
352
363
err = sm .Transition (lock , StateSucceeded )
@@ -356,12 +367,15 @@ func TestInvalidTransition(t *testing.T) {
356
367
// State should remain unchanged
357
368
assert .Equal (t , StateNew , sm .CurrentState ())
358
369
370
+ assert .True (t , sm .IsLockAcquired ())
359
371
lock .Release ()
372
+ assert .False (t , sm .IsLockAcquired ())
360
373
}
361
374
362
375
func TestTransitionWithoutLock (t * testing.T ) {
363
376
sm := New (StateNew , validStateTransitions )
364
377
378
+ assert .False (t , sm .IsLockAcquired ())
365
379
err := sm .Transition (nil , StateInstallationConfigured )
366
380
assert .Error (t , err , "transition should be invalid" )
367
381
assert .Contains (t , err .Error (), "lock not acquired" )
@@ -370,6 +384,7 @@ func TestTransitionWithoutLock(t *testing.T) {
370
384
func TestValidateTransitionWithoutLock (t * testing.T ) {
371
385
sm := New (StateNew , validStateTransitions )
372
386
387
+ assert .False (t , sm .IsLockAcquired ())
373
388
err := sm .ValidateTransition (nil , StateInstallationConfigured )
374
389
assert .Error (t , err , "transition should be invalid" )
375
390
assert .Contains (t , err .Error (), "lock not acquired" )
0 commit comments