I have multiple E2E tests (written in Java) which share login details, each test during runtime will query the locker API for login details which is running on its own dedicated server.
Below is my implementation of my locker API in Go, it was working for me but wanted to make sure there are no bugs.
type service struct {
lockstatus []string // stores test_id denoting which test took the lock
data []*LoginDetails // stores login details
mu []sync.Mutex // stores locks for "data" slice
}
func (s *service) AcquireLoginDetails(req *Request, resp *Response) error {
foundLoginDetails := false
for i := range s.mu {
// for i, lock := range s.mu <- lock is copied here so will use s.mu[i] directly
if s.mu[i].TryLock() {
// skip to next lock if current lock is already taken
if s.lockstatus[i] != "" {
s.mu[i].Unlock()
continue
} else {
// use this index to acquire lock for the requested test
foundLoginDetails = true
s.lockstatus[i] = req.GetTestID()
resp.SetUserID(s.LoginDetails[i].UserID)
resp.SetPassword(s.LoginDetails[i].Password)
}
s.mu[i].Unlock()
if foundLoginDetails { break } // stop searching for further login details
}
}
if !foundLoginDetails {
return error_explaining_we_failed_to_acquire_lock
}
return nil
}
func (s *service) ReleaseLoginDetails(req *Request, resp *Response) error {
foundLoginDetails := false
for i, testID := range s.lockstatus {
if testID == req.GetTestID() {
s.mu[i].Lock()
foundLoginDetails = true
s.lockstatus[i] = ""
s.mu[i].Unlock()
break
}
}
if !foundLoginDetails {
return error_explaining_we_failed_to_release_lock
}
return nil
}
```