Repository: docker/notary (go)

Issue:
Increase/decrease logging level on notary-signer
For people who would like to try some contribute to Notary :)

For now we have already supported increasing/decreasing logging level on notary server side #748 , and it would be nice to have that functionality also on notary signer side.

Tips: 
What you need to do would like to be:
- Embed  a `setupSignalTrap()` into the notary-signer booting process.
- Add a handler to deal with those captured signals.
- Add some test for your handler
- Add some docs about it  

The infra you might want to use for this feature are:
- `NotarySupportedSignals ` in `const.go`
- `AdjustLogLevel()` to increase/decrease logging in `utils/configuration.go`

Pull request:
Do not support SIGUSR1 and SIGUSR2 syscall handling in windows
Since they don't exist in Windows.  While I was at it, since I had to create a bunch of windows-specific and non-windows-specific files, I moved the signal handling code to `utils` so that it can also be used by the signer (that way we don't have windows/non-windows files for both server and signer).

Technically I think the only change that would have been necessary to make the windows client build is the `const.go` change, and I don't think we care about supporting windows for server/signer, but the server and signer changes are added for completeness (and if we want to run full unit tests in windows).

Unfortunately we don't have any windows CI systems yet.  :|  Although I did add at least cross-compiling to windows to our CI runs.

Addresses part of #551.
Fixes #791.

Note: possibly we want to rebase this to 0.4.0 so that it can be added to 0.4.1 

Patch:
diff --git a/Makefile b/Makefile
index e415c053..c5fcbcc9 100644
--- a/Makefile
+++ b/Makefile
@@ -13,7 +13,7 @@ endif
 CTIMEVAR=-X $(NOTARY_PKG)/version.GitCommit=$(GITCOMMIT) -X $(NOTARY_PKG)/version.NotaryVersion=$(NOTARY_VERSION)
 GO_LDFLAGS=-ldflags "-w $(CTIMEVAR)"
 GO_LDFLAGS_STATIC=-ldflags "-w $(CTIMEVAR) -extldflags -static"
-GOOSES = darwin linux
+GOOSES = darwin linux windows
 NOTARY_BUILDTAGS ?= pkcs11
 NOTARYDIR := /go/src/github.com/docker/notary
 
diff --git a/buildscripts/circle_parallelism.sh b/buildscripts/circle_parallelism.sh
index cc07fdc2..961d90a6 100755
--- a/buildscripts/circle_parallelism.sh
+++ b/buildscripts/circle_parallelism.sh
@@ -8,6 +8,7 @@ case $CIRCLE_NODE_INDEX in
    ;;
 2) SKIPENVCHECK=1 make TESTDB=mysql testdb
    SKIPENVCHECK=1 make TESTDB=mysql integration
+   SKIPENVCHECK=1 make cross  # just trying not to exceed 5 builders
    ;;
 3) SKIPENVCHECK=1 make TESTDB=rethink testdb
    SKIPENVCHECK=1 make TESTDB=rethink integration
diff --git a/buildscripts/cross.sh b/buildscripts/cross.sh
index 840a751a..3e257da3 100755
--- a/buildscripts/cross.sh
+++ b/buildscripts/cross.sh
@@ -7,15 +7,10 @@
 
 GOARCH="amd64"
 
-if [[ "${NOTARY_BUILDTAGS}" == *pkcs11* ]]; then
-	export CGO_ENABLED=1
-else
-	export CGO_ENABLED=0
-fi
-
-
 for os in "$@"; do
 	export GOOS="${os}"
+	BUILDTAGS="${NOTARY_BUILDTAGS}"
+	OUTFILE=notary
 
 	if [[ "${GOOS}" == "darwin" ]]; then
 		export CC="o64-clang"
@@ -24,18 +19,29 @@ for os in "$@"; do
 		# darwin binaries can't be compiled to be completely static with the -static flag
 		LDFLAGS="-s"
 	else
+		# no building with Cgo.  Also no building with pkcs11
+		if [[ "${GOOS}" == "windows" ]]; then
+			BUILDTAGS=
+			OUTFILE=notary.exe
+		fi
 		unset CC
 		unset CXX
 		LDFLAGS="-extldflags -static"
 	fi
 
+	if [[ "${BUILDTAGS}" == *pkcs11* ]]; then
+		export CGO_ENABLED=1
+	else
+		export CGO_ENABLED=0
+	fi
+
 	mkdir -p "${NOTARYDIR}/cross/${GOOS}/${GOARCH}";
 
 	set -x;
 	go build \
-		-o "${NOTARYDIR}/cross/${GOOS}/${GOARCH}/notary" \
+		-o "${NOTARYDIR}/cross/${GOOS}/${GOARCH}/${OUTFILE}" \
 		-a \
-		-tags "${NOTARY_BUILDTAGS}" \
+		-tags "${BUILDTAGS}" \
 		-ldflags "-w ${CTIMEVAR} ${LDFLAGS}"  \
 		./cmd/notary;
 	set +x;
diff --git a/cmd/notary-server/config.go b/cmd/notary-server/config.go
index 91eb6c0c..daff0855 100644
--- a/cmd/notary-server/config.go
+++ b/cmd/notary-server/config.go
@@ -3,12 +3,9 @@ package main
 import (
 	"crypto/tls"
 	"fmt"
-	"os"
-	"os/signal"
 	"path"
 	"strconv"
 	"strings"
-	"syscall"
 	"time"
 
 	"github.com/Sirupsen/logrus"
@@ -293,31 +290,3 @@ func parseServerConfig(configFilePath string, hRegister healthRegister, doBootst
 		ConsistentCacheControlConfig: consistentCache,
 	}, nil
 }
-
-func setupSignalTrap() {
-	c := make(chan os.Signal, 1)
-	signal.Notify(c, notary.NotarySupportedSignals...)
-	go func() {
-		for {
-			signalHandle(<-c)
-		}
-	}()
-}
-
-// signalHandle will increase/decrease the logging level via the signal we get.
-func signalHandle(sig os.Signal) {
-	switch sig {
-	case syscall.SIGUSR1:
-		if err := utils.AdjustLogLevel(true); err != nil {
-			fmt.Printf("Attempt to increase log level failed, will remain at %s level, error: %s\n", logrus.GetLevel(), err)
-			return
-		}
-	case syscall.SIGUSR2:
-		if err := utils.AdjustLogLevel(false); err != nil {
-			fmt.Printf("Attempt to decrease log level failed, will remain at %s level, error: %s\n", logrus.GetLevel(), err)
-			return
-		}
-	}
-
-	fmt.Println("Successfully setting log level to ", logrus.GetLevel())
-}
diff --git a/cmd/notary-server/main.go b/cmd/notary-server/main.go
index c2cdf56e..232e486c 100644
--- a/cmd/notary-server/main.go
+++ b/cmd/notary-server/main.go
@@ -7,10 +7,12 @@ import (
 	"net/http"
 	_ "net/http/pprof"
 	"os"
+	"os/signal"
 
 	"github.com/Sirupsen/logrus"
 	"github.com/docker/distribution/health"
 	"github.com/docker/notary/server"
+	"github.com/docker/notary/utils"
 	"github.com/docker/notary/version"
 )
 
@@ -61,7 +63,10 @@ func main() {
 		logrus.Fatal(err.Error())
 	}
 
-	setupSignalTrap()
+	c := utils.SetupSignalTrap(utils.LogLevelSignalHandle)
+	if c != nil {
+		defer signal.Stop(c)
+	}
 
 	if flagStorage.doBootstrap {
 		err = bootstrap(ctx)
diff --git a/cmd/notary-signer/main.go b/cmd/notary-signer/main.go
index d15f124a..d7459fc6 100644
--- a/cmd/notary-signer/main.go
+++ b/cmd/notary-signer/main.go
@@ -6,8 +6,10 @@ import (
 	"log"
 	"net/http"
 	"os"
+	"os/signal"
 
 	"github.com/Sirupsen/logrus"
+	"github.com/docker/notary/utils"
 	"github.com/docker/notary/version"
 	_ "github.com/go-sql-driver/mysql"
 )
@@ -66,6 +68,11 @@ func main() {
 		log.Println("RPC server listening on", signerConfig.GRPCAddr)
 	}
 
+	c := utils.SetupSignalTrap(utils.LogLevelSignalHandle)
+	if c != nil {
+		defer signal.Stop(c)
+	}
+
 	grpcServer.Serve(lis)
 }
 
diff --git a/const.go b/const.go
index 19752072..0c4d4037 100644
--- a/const.go
+++ b/const.go
@@ -1,10 +1,6 @@
 package notary
 
-import (
-	"os"
-	"syscall"
-	"time"
-)
+import "time"
 
 // application wide constants
 const (
@@ -72,11 +68,3 @@ var NotaryDefaultExpiries = map[string]time.Duration{
 	"snapshot":  NotarySnapshotExpiry,
 	"timestamp": NotaryTimestampExpiry,
 }
-
-// NotarySupportedSignals contains the signals we would like to capture:
-// - SIGUSR1, indicates a increment of the log level.
-// - SIGUSR2, indicates a decrement of the log level.
-var NotarySupportedSignals = []os.Signal{
-	syscall.SIGUSR1,
-	syscall.SIGUSR2,
-}
diff --git a/const_nowindows.go b/const_nowindows.go
new file mode 100644
index 00000000..67551717
--- /dev/null
+++ b/const_nowindows.go
@@ -0,0 +1,16 @@
+// +build !windows
+
+package notary
+
+import (
+	"os"
+	"syscall"
+)
+
+// NotarySupportedSignals contains the signals we would like to capture:
+// - SIGUSR1, indicates a increment of the log level.
+// - SIGUSR2, indicates a decrement of the log level.
+var NotarySupportedSignals = []os.Signal{
+	syscall.SIGUSR1,
+	syscall.SIGUSR2,
+}
diff --git a/const_windows.go b/const_windows.go
new file mode 100644
index 00000000..e2dff0e4
--- /dev/null
+++ b/const_windows.go
@@ -0,0 +1,8 @@
+// +build windows
+
+package notary
+
+import "os"
+
+// NotarySupportedSignals does not contain any signals, because SIGUSR1/2 are not supported on windows
+var NotarySupportedSignals = []os.Signal{}
diff --git a/docs/reference/server-config.md b/docs/reference/server-config.md
index 2143bbe5..d1cab23b 100644
--- a/docs/reference/server-config.md
+++ b/docs/reference/server-config.md
@@ -362,10 +362,12 @@ Example:
 </table>
 
 ## Hot logging level reload
-We don't support completely reloading notary configuration files yet at present. What we support for now is:
+We don't support completely reloading notary configuration files yet at present. What we support for Linux and OSX now is:
 - increase logging level by signaling `SIGUSR1`
 - decrease logging level by signaling `SIGUSR2`
 
+No signals and no dynamic logging level changes are supported for Windows yet.
+
 Example:
 
 To increase logging level
diff --git a/docs/reference/signer-config.md b/docs/reference/signer-config.md
index 7ced28e1..f5c35e0a 100644
--- a/docs/reference/signer-config.md
+++ b/docs/reference/signer-config.md
@@ -210,6 +210,44 @@ The environment variables for the older passwords are optional, but Notary
 Signer will not be able to decrypt older keys if they are not provided, and
 attempts to sign data using those keys will fail.
 
+## Hot logging level reload
+We don't support completely reloading notary signer configuration files yet at present. What we support for Linux and OSX now is:
+- increase logging level by signaling `SIGUSR1`
+- decrease logging level by signaling `SIGUSR2`
+
+No signals and no dynamic logging level changes are supported for Windows yet.
+
+Example:
+
+To increase logging level
+```
+$ kill -s SIGUSR1 PID
+
+or
+
+$ docker exec -i CONTAINER_ID kill -s SIGUSR1 PID
+```
+
+To decrease logging level
+```
+$ kill -s SIGUSR2 PID
+
+or
+
+$ docker exec -i CONTAINER_ID kill -s SIGUSR2 PID
+```
+PID is the process id of `notary-signer` and it may not the PID 1 process if you are running
+the container with some kind of wrapper startup script or something.
+
+You can get the PID of `notary-signer` through
+```
+$ docker exec CONTAINER_ID ps aux
+
+or
+
+$ ps aux | grep "notary-signer -config" | grep -v "grep"
+```
+
 
 ## Related information
 
diff --git a/utils/configuration.go b/utils/configuration.go
index f94b73a2..cc97810d 100644
--- a/utils/configuration.go
+++ b/utils/configuration.go
@@ -5,6 +5,8 @@ package utils
 import (
 	"crypto/tls"
 	"fmt"
+	"os"
+	"os/signal"
 	"path/filepath"
 	"strings"
 
@@ -244,3 +246,20 @@ func AdjustLogLevel(increment bool) error {
 	logrus.SetLevel(lvl)
 	return nil
 }
+
+// SetupSignalTrap is a utility to trap supported signals hand handle them (currently by increasing logging)
+func SetupSignalTrap(handler func(os.Signal)) chan os.Signal {
+	if len(notary.NotarySupportedSignals) == 0 {
+		return nil
+
+	}
+	c := make(chan os.Signal, 1)
+	signal.Notify(c, notary.NotarySupportedSignals...)
+	go func() {
+		for {
+			handler(<-c)
+		}
+	}()
+
+	return c
+}
diff --git a/utils/configuration_nowindows.go b/utils/configuration_nowindows.go
new file mode 100644
index 00000000..dc586a66
--- /dev/null
+++ b/utils/configuration_nowindows.go
@@ -0,0 +1,29 @@
+// +build !windows
+
+package utils
+
+import (
+	"fmt"
+	"os"
+	"syscall"
+
+	"github.com/Sirupsen/logrus"
+)
+
+// LogLevelSignalHandle will increase/decrease the logging level via the signal we get.
+func LogLevelSignalHandle(sig os.Signal) {
+	switch sig {
+	case syscall.SIGUSR1:
+		if err := AdjustLogLevel(true); err != nil {
+			fmt.Printf("Attempt to increase log level failed, will remain at %s level, error: %s\n", logrus.GetLevel(), err)
+			return
+		}
+	case syscall.SIGUSR2:
+		if err := AdjustLogLevel(false); err != nil {
+			fmt.Printf("Attempt to decrease log level failed, will remain at %s level, error: %s\n", logrus.GetLevel(), err)
+			return
+		}
+	}
+
+	fmt.Println("Successfully setting log level to", logrus.GetLevel())
+}
diff --git a/utils/configuration_windows.go b/utils/configuration_windows.go
new file mode 100644
index 00000000..bb43c7e3
--- /dev/null
+++ b/utils/configuration_windows.go
@@ -0,0 +1,9 @@
+// +build windows
+
+package utils
+
+import "os"
+
+// LogLevelSignalHandle will do nothing, because we aren't currently supporting signal handling in windows
+func LogLevelSignalHandle(sig os.Signal) {
+}


Test patch:
diff --git a/buildscripts/covertest.py b/buildscripts/covertest.py
index ee2f22e6..99fec410 100755
--- a/buildscripts/covertest.py
+++ b/buildscripts/covertest.py
@@ -32,7 +32,7 @@ def get_coverprofile_filename(pkg, buildtags):
         buildtags = "." + buildtags.replace(' ', '.')
     return pkg.replace('/', '-').replace(' ', '_') + buildtags + ".coverage.txt"
 
-def run_test_with_coverage(buildtags="", coverdir=".cover", pkgs=None, opts="", covermode="count"):
+def run_test_with_coverage(buildtags="", coverdir=".cover", pkgs=None, opts="", covermode="atomic"):
     """
     Run go test with coverage over the the given packages, with the following options
     """
diff --git a/cmd/notary-server/main_test.go b/cmd/notary-server/main_test.go
index 14fbd69b..4bcc0c3f 100644
--- a/cmd/notary-server/main_test.go
+++ b/cmd/notary-server/main_test.go
@@ -6,14 +6,11 @@ import (
 	"fmt"
 	"io/ioutil"
 	"os"
-	"path/filepath"
 	"reflect"
 	"strings"
-	"syscall"
 	"testing"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/distribution/health"
 	"github.com/docker/notary"
 	"github.com/docker/notary/server/storage"
@@ -416,30 +413,3 @@ func TestSampleConfig(t *testing.T) {
 	// once for the DB, once for the trust service
 	require.Equal(t, registerCalled, 2)
 }
-
-func TestSignalHandle(t *testing.T) {
-	tempdir, err := ioutil.TempDir("", "test-signal-handle")
-	require.NoError(t, err)
-	defer os.RemoveAll(tempdir)
-	f, err := os.Create(filepath.Join(tempdir, "testSignalHandle.json"))
-	require.NoError(t, err)
-
-	f.WriteString(`{"logging": {"level": "info"}}`)
-
-	v := viper.New()
-	utils.SetupViper(v, "envPrefix")
-	err = utils.ParseViper(v, f.Name())
-	require.NoError(t, err)
-
-	// Info + SIGUSR1 -> Debug
-	signalHandle(syscall.SIGUSR1)
-	require.Equal(t, logrus.GetLevel(), logrus.DebugLevel)
-
-	// Debug + SIGUSR1 -> Debug
-	signalHandle(syscall.SIGUSR1)
-	require.Equal(t, logrus.GetLevel(), logrus.DebugLevel)
-
-	// Debug + SIGUSR2-> Info
-	signalHandle(syscall.SIGUSR2)
-	require.Equal(t, logrus.GetLevel(), logrus.InfoLevel)
-}
diff --git a/cmd/notary/main_test.go b/cmd/notary/main_test.go
index 5b9f916e..3d8541ec 100644
--- a/cmd/notary/main_test.go
+++ b/cmd/notary/main_test.go
@@ -8,6 +8,7 @@ import (
 	"net/http/httptest"
 	"os"
 	"path/filepath"
+	"strconv"
 	"strings"
 	"testing"
 	"time"
@@ -343,10 +344,10 @@ func TestConfigFileTLSCanBeRelativeToConfigOrAbsolute(t *testing.T) {
 		"remote_server": {
 			"url": "%s",
 			"root_ca": "root-ca.crt",
-			"tls_client_cert": "%s",
+			"tls_client_cert": %s,
 			"tls_client_key": "notary-server.key"
 		}
-	}`, s.URL, filepath.Join(tempDir, "notary-server.crt"))
+	}`, s.URL, strconv.Quote(filepath.Join(tempDir, "notary-server.crt")))
 	configFile.Close()
 
 	// copy the certs to be relative to the config directory
diff --git a/utils/configuration_nowindows_test.go b/utils/configuration_nowindows_test.go
new file mode 100644
index 00000000..eb02e64d
--- /dev/null
+++ b/utils/configuration_nowindows_test.go
@@ -0,0 +1,24 @@
+// +build !windows
+
+package utils
+
+import (
+	"syscall"
+	"testing"
+
+	"github.com/Sirupsen/logrus"
+	"github.com/stretchr/testify/require"
+)
+
+func TestLogLevelSignalHandle(t *testing.T) {
+	signalOperation := map[bool]syscall.Signal{
+		optIncrement: syscall.SIGUSR1,
+		optDecrement: syscall.SIGUSR2,
+	}
+
+	for _, expt := range logLevelExpectations {
+		logrus.SetLevel(expt.startLevel)
+		LogLevelSignalHandle(signalOperation[expt.increment])
+		require.Equal(t, expt.endLevel, logrus.GetLevel())
+	}
+}
diff --git a/utils/configuration_test.go b/utils/configuration_test.go
index bf0c5f71..fb77c854 100644
--- a/utils/configuration_test.go
+++ b/utils/configuration_test.go
@@ -6,8 +6,10 @@ import (
 	"fmt"
 	"io/ioutil"
 	"os"
+	"os/signal"
 	"path/filepath"
 	"reflect"
+	"syscall"
 	"testing"
 
 	"github.com/Sirupsen/logrus"
@@ -490,73 +492,84 @@ func TestParseViperWithValidFile(t *testing.T) {
 	require.Equal(t, "debug", v.GetString("logging.level"))
 }
 
+type logLevelTests struct {
+	startLevel logrus.Level
+	endLevel   logrus.Level
+	increment  bool
+}
+
+const (
+	optIncrement = true
+	optDecrement = false
+)
+
+var logLevelExpectations = []logLevelTests{
+	// highest: Debug, lowest: Panic.  Incrementing brings everything up one level, except debug which is max level
+	{startLevel: logrus.DebugLevel, increment: optIncrement, endLevel: logrus.DebugLevel},
+	{startLevel: logrus.InfoLevel, increment: optIncrement, endLevel: logrus.DebugLevel},
+	{startLevel: logrus.WarnLevel, increment: optIncrement, endLevel: logrus.InfoLevel},
+	{startLevel: logrus.ErrorLevel, increment: optIncrement, endLevel: logrus.WarnLevel},
+	{startLevel: logrus.FatalLevel, increment: optIncrement, endLevel: logrus.ErrorLevel},
+	{startLevel: logrus.PanicLevel, increment: optIncrement, endLevel: logrus.FatalLevel},
+
+	// highest: Debug, lowest: Panic.  Decrementing brings everything down one level, except panic which is min level
+	{startLevel: logrus.DebugLevel, increment: optDecrement, endLevel: logrus.InfoLevel},
+	{startLevel: logrus.InfoLevel, increment: optDecrement, endLevel: logrus.WarnLevel},
+	{startLevel: logrus.WarnLevel, increment: optDecrement, endLevel: logrus.ErrorLevel},
+	{startLevel: logrus.ErrorLevel, increment: optDecrement, endLevel: logrus.FatalLevel},
+	{startLevel: logrus.FatalLevel, increment: optDecrement, endLevel: logrus.PanicLevel},
+	{startLevel: logrus.PanicLevel, increment: optDecrement, endLevel: logrus.PanicLevel},
+}
+
 func TestAdjustLogLevel(t *testing.T) {
+	for _, expt := range logLevelExpectations {
+		logrus.SetLevel(expt.startLevel)
+		err := AdjustLogLevel(expt.increment)
+
+		if expt.startLevel == expt.endLevel {
+			require.Error(t, err) // because if it didn't change, that means AdjustLogLevel failed
+		} else {
+			require.NoError(t, err)
+		}
 
-	// To indicate increment or decrement the logging level
-	optIncrement := true
-	optDecrement := false
+		require.Equal(t, expt.endLevel, logrus.GetLevel())
+	}
+}
 
-	// Debug is the highest level for now, so we expected a error here
-	logrus.SetLevel(logrus.DebugLevel)
-	err := AdjustLogLevel(optIncrement)
-	require.Error(t, err)
-	// Debug -> Info
-	logrus.SetLevel(logrus.DebugLevel)
-	err = AdjustLogLevel(optDecrement)
-	require.NoError(t, err)
-	require.Equal(t, logrus.InfoLevel, logrus.GetLevel())
+func testSetSignalTrap(t *testing.T) {
+	var signalsPassedOn map[string]struct{}
 
-	// Info -> Debug
-	logrus.SetLevel(logrus.InfoLevel)
-	err = AdjustLogLevel(optIncrement)
-	require.NoError(t, err)
-	require.Equal(t, logrus.DebugLevel, logrus.GetLevel())
-	// Info -> Warn
-	logrus.SetLevel(logrus.InfoLevel)
-	err = AdjustLogLevel(optDecrement)
-	require.NoError(t, err)
-	require.Equal(t, logrus.WarnLevel, logrus.GetLevel())
+	signalHandler := func(s os.Signal) {
+		signalsPassedOn := make(map[string]struct{})
+		signalsPassedOn[s.String()] = struct{}{}
+	}
+	c := SetupSignalTrap(signalHandler)
 
-	// Warn -> Info
-	logrus.SetLevel(logrus.WarnLevel)
-	err = AdjustLogLevel(optIncrement)
-	require.NoError(t, err)
-	require.Equal(t, logrus.InfoLevel, logrus.GetLevel())
-	// Warn -> Error
-	logrus.SetLevel(logrus.WarnLevel)
-	err = AdjustLogLevel(optDecrement)
-	require.NoError(t, err)
-	require.Equal(t, logrus.ErrorLevel, logrus.GetLevel())
+	if len(notary.NotarySupportedSignals) == 0 { // currently, windows only
+		require.Nil(t, c)
+	} else {
+		require.NotNil(t, c)
+		defer signal.Stop(c)
+	}
 
-	// Error -> Warn
-	logrus.SetLevel(logrus.ErrorLevel)
-	err = AdjustLogLevel(optIncrement)
-	require.NoError(t, err)
-	require.Equal(t, logrus.WarnLevel, logrus.GetLevel())
-	// Error -> Fatal
-	logrus.SetLevel(logrus.ErrorLevel)
-	err = AdjustLogLevel(optDecrement)
-	require.NoError(t, err)
-	require.Equal(t, logrus.FatalLevel, logrus.GetLevel())
+	for _, s := range notary.NotarySupportedSignals {
+		syscallSignal, ok := s.(syscall.Signal)
+		require.True(t, ok)
+		require.NoError(t, syscall.Kill(syscall.Getpid(), syscallSignal))
+		require.Len(t, signalsPassedOn, 0)
+		require.NotNil(t, signalsPassedOn[s.String()])
+	}
+}
 
-	// Fatal -> Error
-	logrus.SetLevel(logrus.FatalLevel)
-	err = AdjustLogLevel(optIncrement)
-	require.NoError(t, err)
-	require.Equal(t, logrus.ErrorLevel, logrus.GetLevel())
-	// Fatal -> Panic
-	logrus.SetLevel(logrus.FatalLevel)
-	err = AdjustLogLevel(optDecrement)
-	require.NoError(t, err)
-	require.Equal(t, logrus.PanicLevel, logrus.GetLevel())
+// TODO: undo this extra indirection, needed for mocking notary.NotarySupportedSignals being empty, when we have
+// a windows CI system running
+func TestSetSignalTrap(t *testing.T) {
+	testSetSignalTrap(t)
+}
 
-	// Panic -> Fatal
-	logrus.SetLevel(logrus.PanicLevel)
-	err = AdjustLogLevel(optIncrement)
-	require.NoError(t, err)
-	require.Equal(t, logrus.FatalLevel, logrus.GetLevel())
-	// Panic is the lowest level for now, so we expected a error here
-	logrus.SetLevel(logrus.PanicLevel)
-	err = AdjustLogLevel(optDecrement)
-	require.Error(t, err)
+func TestSetSignalTrapMockWindows(t *testing.T) {
+	old := notary.NotarySupportedSignals
+	notary.NotarySupportedSignals = nil
+	testSetSignalTrap(t)
+	notary.NotarySupportedSignals = old
 }