package framework import "sync" type CleanupActionHandle *int var cleanupActionsLock sync.Mutex var cleanupActions = map[CleanupActionHandle]func(){} // AddCleanupAction installs a function that will be called in the event of the // whole test being terminated. This allows arbitrary pieces of the overall // test to hook into SynchronizedAfterSuite(). func AddCleanupAction(fn func()) CleanupActionHandle { p := CleanupActionHandle(new(int)) cleanupActionsLock.Lock() defer cleanupActionsLock.Unlock() cleanupActions[p] = fn return p } // RemoveCleanupAction removes a function that was installed by // AddCleanupAction. func RemoveCleanupAction(p CleanupActionHandle) { cleanupActionsLock.Lock() defer cleanupActionsLock.Unlock() delete(cleanupActions, p) } // RunCleanupActions runs all functions installed by AddCleanupAction. It does // not remove them (see RemoveCleanupAction) but it does run unlocked, so they // may remove themselves. func RunCleanupActions() { list := []func(){} func() { cleanupActionsLock.Lock() defer cleanupActionsLock.Unlock() for _, fn := range cleanupActions { list = append(list, fn) } }() // Run unlocked. for _, fn := range list { fn() } }