Skip to content

Commit e8b7bd3

Browse files
committed
tests: fix deadlock by introducing a starting state and removing lock while TestServer is starting
Signed-off-by: Avis Lowha <high.avis.lowha@gmail.com>
1 parent 16fd547 commit e8b7bd3

File tree

1 file changed

+34
-11
lines changed

1 file changed

+34
-11
lines changed

tests/cluster.go

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ import (
5858
// TestServer states.
5959
const (
6060
Initial int32 = iota
61+
Starting
6162
Running
6263
Stop
6364
Destroy
@@ -142,13 +143,33 @@ func NewTestServer(ctx context.Context, cfg *config.Config, services []string, h
142143
// Run starts to run a TestServer.
143144
func (s *TestServer) Run() error {
144145
s.Lock()
145-
defer s.Unlock()
146146
if s.state != Initial && s.state != Stop {
147+
s.Unlock()
147148
return errors.Errorf("server(state%d) cannot run", s.state)
148149
}
149-
if err := s.server.Run(); err != nil {
150+
// Immediately set state to Starting and unlock
151+
s.state = Starting
152+
s.Unlock()
153+
154+
// Run the server which is a slow operation
155+
err := s.server.Run()
156+
157+
s.Lock()
158+
defer s.Unlock()
159+
160+
if err != nil {
161+
// If the server is destroyed or stopped while Run(), return nil
162+
if s.state == Destroy || s.state == Stop {
163+
return nil
164+
}
165+
s.state = Stop
150166
return err
151167
}
168+
// Close and return nil if the server is destroyed or stopped
169+
if s.state == Destroy || s.state == Stop {
170+
s.server.Close()
171+
return nil
172+
}
152173
s.state = Running
153174
return nil
154175
}
@@ -157,12 +178,16 @@ func (s *TestServer) Run() error {
157178
func (s *TestServer) Stop() error {
158179
s.Lock()
159180
defer s.Unlock()
160-
if s.state != Running {
161-
return errors.Errorf("server(state%d) cannot stop", s.state)
181+
if s.state == Starting {
182+
s.state = Stop
183+
return nil
162184
}
163-
s.server.Close()
164-
s.state = Stop
165-
return nil
185+
if s.state == Running {
186+
s.server.Close()
187+
s.state = Stop
188+
return nil
189+
}
190+
return errors.Errorf("server(state%d) cannot stop", s.state)
166191
}
167192

168193
// Destroy is used to destroy a TestServer.
@@ -172,11 +197,9 @@ func (s *TestServer) Destroy() error {
172197
if s.state == Running {
173198
s.server.Close()
174199
}
175-
if err := os.RemoveAll(s.server.GetConfig().DataDir); err != nil {
176-
return err
177-
}
200+
// Set state to Destroy before RemoveAll and removed redundant if err != nil check, linter fix
178201
s.state = Destroy
179-
return nil
202+
return os.RemoveAll(s.server.GetConfig().DataDir)
180203
}
181204

182205
// ResetPDLeader resigns the leader of the server.

0 commit comments

Comments
 (0)