Permalink
Browse files

add cleanup package - useful for managing external processes

  • Loading branch information...
1 parent 8b49fe6 commit 8004a15e410a927eadcd0d1cb336d390e1eee4f9 Onsi Fakhouri committed Mar 5, 2014
Showing with 96 additions and 1 deletion.
  1. +55 −0 cleanup/cleanup.go
  2. +13 −0 cleanup/cleanup_suite_test.go
  3. +26 −0 cleanup/cleanup_test.go
  4. +2 −1 ginkgo/main.go
View
@@ -0,0 +1,55 @@
+/*
+The cleanup packages allows you to register cleanup functions.
+These are called whenever the current process receives a SIGINT or SIGTERM
+
+You can also invoke the cleanup functions by calling Cleanup(). You should do this after your tests run
+in your Ginkgo bootstrap if you want the cleanup functions to be called when the process exits.
+
+Unfortunately, it is not possible for cleanup to intercept calls to os.Exit() and perform cleanup befor the
+process exits. Instead of os.Exit, you can use cleanup.Exit()
+
+Cleanup is especially useful when building integration suites that fork off external processes. You can register
+callbacks with this package to tear down these external processes.
+*/
+
+package cleanup
+
+import (
+ "os"
+ "os/signal"
+ "syscall"
+)
+
+var cleanupFuncs []func()
+var capturingSignals bool
+
+//Register a cleanup function. This will be called when:
+//- a call is made to Cleanup()
+//- a call is made to Exit()
+//- the current process receives SIGINT or SIGTERM
+func Register(f func()) {
+ cleanupFuncs = append(cleanupFuncs, f)
+ if !capturingSignals {
+ capturingSignals = true
+ go func() {
+ c := make(chan os.Signal, 1)
+ signal.Notify(c, syscall.SIGINT, syscall.SIGKILL, syscall.SIGTERM)
+
+ <-c
+ Exit(1)
+ }()
+ }
+}
+
+//Cleanup invokes all registered cleanup functions
+func Cleanup() {
+ for _, f := range cleanupFuncs {
+ f()
+ }
+}
+
+//Exit invokes all registered cleanup functions, then exits
+func Exit(status int) {
+ Cleanup()
+ os.Exit(status)
+}
@@ -0,0 +1,13 @@
+package cleanup_test
+
+import (
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+
+ "testing"
+)
+
+func TestCleanup(t *testing.T) {
+ RegisterFailHandler(Fail)
+ RunSpecs(t, "Cleanup Suite")
+}
View
@@ -0,0 +1,26 @@
+package cleanup_test
+
+import (
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/ginkgo/cleanup"
+ . "github.com/onsi/gomega"
+)
+
+var _ = Describe("Cleanup", func() {
+ Context("with cleanup functions registered", func() {
+ var calls []string
+ BeforeEach(func() {
+ Register(func() {
+ calls = append(calls, "A")
+ })
+ Register(func() {
+ calls = append(calls, "B")
+ })
+ })
+
+ It("should call the functions when told to clean up", func() {
+ Cleanup()
+ Ω(calls).Should(Equal([]string{"A", "B"}))
+ })
+ })
+})
View
@@ -83,6 +83,7 @@ import (
"os"
"os/signal"
"runtime"
+ "syscall"
"time"
)
@@ -296,7 +297,7 @@ func watchTests(runner *testRunner) {
func registerSignalHandler(runner *testRunner) {
go func() {
c := make(chan os.Signal, 1)
- signal.Notify(c, os.Interrupt, os.Kill)
+ signal.Notify(c, syscall.SIGINT, syscall.SIGKILL, syscall.SIGTERM)
select {
case sig := <-c:

0 comments on commit 8004a15

Please sign in to comment.