Skip to content

Instantly share code, notes, and snippets.

@lawrencejones
Created March 14, 2017 20:30
Show Gist options
  • Save lawrencejones/60c326e658817d54fdb7600b9428b8c0 to your computer and use it in GitHub Desktop.
Save lawrencejones/60c326e658817d54fdb7600b9428b8c0 to your computer and use it in GitHub Desktop.
func TestSupervise_ensureServiceRunning_cannotCheckMoreThanOnceConcurrently(testing *testing.T) {
authServiceOne := createAuthService()
authServiceTwo := createAuthService()
lockfile, err := generateTempLockfile(); if err != nil {
testing.Fatalf("failed to generate testing lockfile: %s\n", err)
return
}
// We need to use Name() here so that each lock is associated with a different
// file descriptor, otherwise flock will be re-entrant.
authServiceOne.SetLock(lockfile.Name())
authServiceTwo.SetLock(lockfile.Name())
deploying := make(chan int, 1)
enqueueCheck := func(n int, service *ensemble.Service) chan bool {
wait := make(chan bool, 1)
go ensureServiceRunning(service, &TestServiceManager{
ServiceManager: createServiceManager(),
deployMethod: func(s *ensemble.Service) error {
deploying <- n
<-wait
return nil
},
})
return wait
}
waitOne := enqueueCheck(1, authServiceOne)
// Ensure that the first check has entered the mutex
currentlyDeploying := <-deploying; if currentlyDeploying != 1 {
testing.Fatalf("received unexpected service deployment: %d\n", currentlyDeploying)
}
waitTwo := enqueueCheck(2, authServiceTwo)
time.Sleep(100 * time.Millisecond) // if we weren't locked on the file, then the second check would've processed
select {
case currentlyDeploying, ok := <-deploying:
if ok { testing.Fatalf("check %d deployed before first check had finished", currentlyDeploying) }
default:
}
waitOne <- true
currentlyDeploying = <-deploying; if currentlyDeploying != 2 {
testing.Fatalf("received unexpected service deployment: %d\n", currentlyDeploying)
}
waitTwo <- true
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment