All checks were successful
Test / Create distribution (push) Successful in 37s
Test / Sandbox (push) Successful in 2m28s
Test / Hakurei (push) Successful in 3m26s
Test / Hpkg (push) Successful in 4m15s
Test / Sandbox (race detector) (push) Successful in 4m24s
Test / Hakurei (race detector) (push) Successful in 5m14s
Test / Flake checks (push) Successful in 1m31s
This is required for securely providing access to PipeWire. This change has already been manually tested and confirmed to work correctly. This unfortunately cannot be upstreamed in its current state as libpipewire-0.3 breaks static linking. Signed-off-by: Ophestra <cat@gensokyo.uk>
158 lines
4.6 KiB
Go
158 lines
4.6 KiB
Go
package pipewire
|
|
|
|
import (
|
|
"errors"
|
|
"os"
|
|
"reflect"
|
|
"syscall"
|
|
"testing"
|
|
|
|
"hakurei.app/container/stub"
|
|
)
|
|
|
|
func TestError(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
testCases := []struct {
|
|
name string
|
|
err Error
|
|
want string
|
|
}{
|
|
{"success", Error{
|
|
Cause: RSuccess,
|
|
}, "success"},
|
|
|
|
{"success errno", Error{
|
|
Cause: RSuccess,
|
|
Errno: stub.UniqueError(0),
|
|
}, "unique error 0 injected by the test suite"},
|
|
|
|
{"pw_main_loop_new", Error{
|
|
Cause: RMainloop,
|
|
Errno: stub.UniqueError(1),
|
|
}, "pw_main_loop_new failed: unique error 1 injected by the test suite"},
|
|
|
|
{"pw_context_new", Error{
|
|
Cause: RContext,
|
|
Errno: stub.UniqueError(2),
|
|
}, "pw_context_new failed: unique error 2 injected by the test suite"},
|
|
|
|
{"pw_context_connect", Error{
|
|
Cause: RConnect,
|
|
Errno: stub.UniqueError(3),
|
|
}, "pw_context_connect failed: unique error 3 injected by the test suite"},
|
|
|
|
{"pw_core_get_registry", Error{
|
|
Cause: RRegistry,
|
|
Errno: stub.UniqueError(4),
|
|
}, "pw_core_get_registry failed: unique error 4 injected by the test suite"},
|
|
|
|
{"not available", Error{
|
|
Cause: RNotAvail,
|
|
}, "no security context object found"},
|
|
|
|
{"not available errno", Error{
|
|
Cause: RNotAvail,
|
|
Errno: syscall.EAGAIN,
|
|
}, "no security context object found"},
|
|
|
|
{"socket", Error{
|
|
Cause: RSocket,
|
|
Errno: stub.UniqueError(5),
|
|
}, "socket: unique error 5 injected by the test suite"},
|
|
|
|
{"bind", Error{
|
|
Cause: RBind,
|
|
Path: "/tmp/hakurei.0/18783d07791f2460dbbcffb76c24c9e6/pipewire",
|
|
Errno: stub.UniqueError(6),
|
|
}, "cannot bind /tmp/hakurei.0/18783d07791f2460dbbcffb76c24c9e6/pipewire: unique error 6 injected by the test suite"},
|
|
|
|
{"listen", Error{
|
|
Cause: RListen,
|
|
Path: "/tmp/hakurei.0/18783d07791f2460dbbcffb76c24c9e6/pipewire",
|
|
Errno: stub.UniqueError(7),
|
|
}, "cannot listen on /tmp/hakurei.0/18783d07791f2460dbbcffb76c24c9e6/pipewire: unique error 7 injected by the test suite"},
|
|
|
|
{"socket invalid", Error{
|
|
Cause: RSocket,
|
|
}, "socket operation failed"},
|
|
|
|
{"pw_security_context_create", Error{
|
|
Cause: RAttach,
|
|
Errno: stub.UniqueError(8),
|
|
}, "pw_security_context_create failed: unique error 8 injected by the test suite"},
|
|
|
|
{"create", Error{
|
|
Cause: RCreate,
|
|
}, "cannot ensure pipewire pathname socket"},
|
|
|
|
{"create path", Error{
|
|
Cause: RCreate,
|
|
Errno: &os.PathError{Op: "create", Path: "/proc/nonexistent", Err: syscall.EEXIST},
|
|
}, "create /proc/nonexistent: file exists"},
|
|
|
|
{"cleanup", Error{
|
|
Cause: RCleanup,
|
|
Path: "/tmp/hakurei.0/18783d07791f2460dbbcffb76c24c9e6/pipewire",
|
|
}, "cannot hang up pipewire security context"},
|
|
|
|
{"cleanup PathError", Error{
|
|
Cause: RCleanup,
|
|
Path: "/tmp/hakurei.0/18783d07791f2460dbbcffb76c24c9e6/pipewire",
|
|
Errno: errors.Join(syscall.EINVAL, &os.PathError{
|
|
Op: "remove",
|
|
Path: "/tmp/hakurei.0/18783d07791f2460dbbcffb76c24c9e6/pipewire",
|
|
Err: stub.UniqueError(9),
|
|
}),
|
|
}, "remove /tmp/hakurei.0/18783d07791f2460dbbcffb76c24c9e6/pipewire: unique error 9 injected by the test suite"},
|
|
|
|
{"cleanup errno", Error{
|
|
Cause: RCleanup,
|
|
Path: "/tmp/hakurei.0/18783d07791f2460dbbcffb76c24c9e6/pipewire",
|
|
Errno: errors.Join(syscall.EINVAL),
|
|
}, "cannot close pipewire close_fd pipe: invalid argument"},
|
|
|
|
{"invalid", Error{
|
|
Cause: 0xbad,
|
|
}, "impossible outcome"},
|
|
|
|
{"invalid errno", Error{
|
|
Cause: 0xbad,
|
|
Errno: stub.UniqueError(9),
|
|
}, "impossible outcome: unique error 9 injected by the test suite"},
|
|
}
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
if got := tc.err.Message(); got != tc.want {
|
|
t.Errorf("Message: %q, want %q", got, tc.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSecurityContextBindValidate(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
t.Run("NUL", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
want := &Error{Cause: RBind, Path: "\x00", Errno: errors.New("argument contains NUL character")}
|
|
if got := securityContextBind("\x00", "\x00", -1); !reflect.DeepEqual(got, want) {
|
|
t.Fatalf("securityContextBind: error = %#v, want %#v", got, want)
|
|
}
|
|
})
|
|
|
|
t.Run("long", func(t *testing.T) {
|
|
t.Parallel()
|
|
// 256 bytes
|
|
const oversizedPath = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
|
|
|
want := &Error{Cause: RBind, Path: oversizedPath, Errno: errors.New("socket pathname too long")}
|
|
if got := securityContextBind(oversizedPath, "", -1); !reflect.DeepEqual(got, want) {
|
|
t.Fatalf("securityContextBind: error = %#v, want %#v", got, want)
|
|
}
|
|
})
|
|
}
|