Skip to content

Commit

Permalink
nltest: properly wrap syscall errors as netlink does
Browse files Browse the repository at this point in the history
  • Loading branch information
mdlayher committed Mar 1, 2019
1 parent 05882cd commit 07fd1a6
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 3 deletions.
7 changes: 7 additions & 0 deletions nltest/errors_others.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
//+build plan9 windows

package nltest

func isSyscallError(_ error) bool {
return false
}
10 changes: 10 additions & 0 deletions nltest/errors_unix.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//+build !plan9,!windows

package nltest

import "golang.org/x/sys/unix"

func isSyscallError(err error) bool {
_, ok := err.(unix.Errno)
return ok
}
13 changes: 10 additions & 3 deletions nltest/nltest.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package nltest
import (
"fmt"
"io"
"os"

"github.com/mdlayher/netlink"
"github.com/mdlayher/netlink/nlenc"
Expand Down Expand Up @@ -166,10 +167,16 @@ func (c *socket) Receive() ([]netlink.Message, error) {
case io.EOF:
// EOF, simulate no replies in multi-part message.
return nil, nil
default:
// Some error occurred and should be passed to the caller.
return nil, c.err
}

// If the error is a system call error, wrap it in os.NewSyscallError
// to simulate what the Linux netlink.Conn does.
if isSyscallError(c.err) {
return nil, os.NewSyscallError("recvmsg", c.err)
}

// Some generic error occurred and should be passed to the caller.
return nil, c.err
}

// Detect multi-part messages.
Expand Down
15 changes: 15 additions & 0 deletions nltest/nltest_linux_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package nltest_test

import (
"os"
"testing"

"github.com/mdlayher/netlink"
Expand All @@ -17,3 +18,17 @@ func TestLinuxDialError(t *testing.T) {
t.Fatalf("expected error is not exist, but got: %v", err)
}
}

func TestLinuxSyscallError(t *testing.T) {
c := nltest.Dial(func(req []netlink.Message) ([]netlink.Message, error) {
return nil, unix.ENOENT
})

_, err := c.Execute(netlink.Message{})
if !netlink.IsNotExist(err) {
t.Fatalf("expected error is not exist, but got: %v", err)
}

// Expect raw system call errors to be wrapped.
_ = err.(*netlink.OpError).Err.(*os.SyscallError)
}

0 comments on commit 07fd1a6

Please sign in to comment.