diff --git a/daemon/sdnotify.go b/daemon/sdnotify.go index b92b1911..a6167380 100644 --- a/daemon/sdnotify.go +++ b/daemon/sdnotify.go @@ -2,30 +2,37 @@ package daemon import ( - "errors" "net" "os" ) -var SdNotifyNoSocket = errors.New("No socket") - // SdNotify sends a message to the init daemon. It is common to ignore the error. -func SdNotify(state string) error { +// It returns one of the following: +// (false, nil) - notification not supported (i.e. NOTIFY_SOCKET is unset) +// (false, err) - notification supported, but failure happened (e.g. error connecting to NOTIFY_SOCKET or while sending data) +// (true, nil) - notification supported, data has been sent +func SdNotify(state string) (sent bool, err error) { socketAddr := &net.UnixAddr{ Name: os.Getenv("NOTIFY_SOCKET"), Net: "unixgram", } + // NOTIFY_SOCKET not set if socketAddr.Name == "" { - return SdNotifyNoSocket + return false, nil } conn, err := net.DialUnix(socketAddr.Net, nil, socketAddr) + // Error connecting to NOTIFY_SOCKET if err != nil { - return err + return false, err } defer conn.Close() _, err = conn.Write([]byte(state)) - return err + // Error sending the message + if err != nil { + return false, err + } + return true, nil } diff --git a/daemon/sdnotify_test.go b/daemon/sdnotify_test.go new file mode 100644 index 00000000..aa36dd36 --- /dev/null +++ b/daemon/sdnotify_test.go @@ -0,0 +1,75 @@ +// Copyright 2016 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package daemon + +import ( + "io/ioutil" + "net" + "os" + "testing" +) + +// TestSdNotify +func TestSdNotify(t *testing.T) { + notificationSupportedDataSent := "Notification supported, data sent" + notificationSupportedFailure := "Notification supported, but failure happened" + notificationNotSupported := "Notification not supported" + + testDir, e := ioutil.TempDir("/tmp/", "test-") + if e != nil { + panic(e) + } + defer os.RemoveAll(testDir) + + notifySocket := testDir + "/notify-socket.sock" + laddr := net.UnixAddr{ + Name: notifySocket, + Net: "unixgram", + } + _, e = net.ListenUnixgram("unixgram", &laddr) + if e != nil { + panic(e) + } + + // (true, nil) - notification supported, data has been sent + e = os.Setenv("NOTIFY_SOCKET", notifySocket) + if e != nil { + panic(e) + } + sent, err := SdNotify(notificationSupportedDataSent) + if !sent || err != nil { + t.Errorf("TEST: %s FAILED", notificationSupportedDataSent) + } + + // (false, err) - notification supported, but failure happened + e = os.Setenv("NOTIFY_SOCKET", testDir+"/not-exist.sock") + if e != nil { + panic(e) + } + sent, err = SdNotify(notificationSupportedFailure) + if sent && err == nil { + t.Errorf("TEST: %s FAILED", notificationSupportedFailure) + } + + // (false, nil) - notification not supported + e = os.Unsetenv("NOTIFY_SOCKET") + if e != nil { + panic(e) + } + sent, err = SdNotify(notificationNotSupported) + if sent || err != nil { + t.Errorf("TEST: %s FAILED", notificationNotSupported) + } +} diff --git a/test b/test index a791d351..00ec9ad1 100755 --- a/test +++ b/test @@ -27,7 +27,7 @@ if [ -z "$GOPATH" ]; then go get -u github.com/coreos/pkg/dlopen fi -TESTABLE="activation journal login1 machine1 unit" +TESTABLE="activation daemon journal login1 machine1 unit" FORMATTABLE="$TESTABLE sdjournal dbus" if [ -e "/run/systemd/system/" ]; then TESTABLE="${TESTABLE} sdjournal"