hst/dbus: move dbus config struct
Some checks failed
Test / Create distribution (push) Failing after 26s
Test / Sandbox (race detector) (push) Failing after 42s
Test / Sandbox (push) Failing after 42s
Test / Hakurei (race detector) (push) Failing after 49s
Test / Hakurei (push) Failing after 49s
Test / Hpkg (push) Failing after 46s
Test / Flake checks (push) Has been skipped
Some checks failed
Test / Create distribution (push) Failing after 26s
Test / Sandbox (race detector) (push) Failing after 42s
Test / Sandbox (push) Failing after 42s
Test / Hakurei (race detector) (push) Failing after 49s
Test / Hakurei (push) Failing after 49s
Test / Hpkg (push) Failing after 46s
Test / Flake checks (push) Has been skipped
This allows holding a xdg-dbus-proxy configuration without importing system/dbus. It also makes more sense in the project structure since the config struct is part of the hst API however the rest of the implementation is not. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
parent
3ce63e95d7
commit
be194272d9
@ -21,7 +21,7 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// MustProxyDBus calls ProxyDBus and panics if an error is returned.
|
// MustProxyDBus calls ProxyDBus and panics if an error is returned.
|
||||||
func (sys *I) MustProxyDBus(sessionPath *container.Absolute, session *dbus.Config, systemPath *container.Absolute, system *dbus.Config) *I {
|
func (sys *I) MustProxyDBus(sessionPath *container.Absolute, session *hst.BusConfig, systemPath *container.Absolute, system *hst.BusConfig) *I {
|
||||||
if err := sys.ProxyDBus(session, system, sessionPath, systemPath); err != nil {
|
if err := sys.ProxyDBus(session, system, sessionPath, systemPath); err != nil {
|
||||||
panic(err.Error())
|
panic(err.Error())
|
||||||
} else {
|
} else {
|
||||||
@ -31,7 +31,7 @@ func (sys *I) MustProxyDBus(sessionPath *container.Absolute, session *dbus.Confi
|
|||||||
|
|
||||||
// ProxyDBus finalises configuration ahead of time and starts xdg-dbus-proxy via [dbus] and terminates it on revert.
|
// ProxyDBus finalises configuration ahead of time and starts xdg-dbus-proxy via [dbus] and terminates it on revert.
|
||||||
// This [Op] is always [Process] scoped.
|
// This [Op] is always [Process] scoped.
|
||||||
func (sys *I) ProxyDBus(session, system *dbus.Config, sessionPath, systemPath *container.Absolute) error {
|
func (sys *I) ProxyDBus(session, system *hst.BusConfig, sessionPath, systemPath *container.Absolute) error {
|
||||||
d := new(dbusProxyOp)
|
d := new(dbusProxyOp)
|
||||||
|
|
||||||
// session bus is required as otherwise this is effectively a very expensive noop
|
// session bus is required as otherwise this is effectively a very expensive noop
|
||||||
@ -56,9 +56,9 @@ func (sys *I) ProxyDBus(session, system *dbus.Config, sessionPath, systemPath *c
|
|||||||
fmt.Sprintf("cannot finalise message bus proxy: %v", err), false)
|
fmt.Sprintf("cannot finalise message bus proxy: %v", err), false)
|
||||||
} else {
|
} else {
|
||||||
if sys.msg.IsVerbose() {
|
if sys.msg.IsVerbose() {
|
||||||
sys.msg.Verbose("session bus proxy:", session.Args(sessionBus))
|
sys.msg.Verbose("session bus proxy:", dbus.Args(session, sessionBus))
|
||||||
if system != nil {
|
if system != nil {
|
||||||
sys.msg.Verbose("system bus proxy:", system.Args(systemBus))
|
sys.msg.Verbose("system bus proxy:", dbus.Args(system, systemBus))
|
||||||
}
|
}
|
||||||
|
|
||||||
// this calls the argsWt String method
|
// this calls the argsWt String method
|
||||||
|
@ -1,64 +1,50 @@
|
|||||||
package dbus
|
package dbus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"hakurei.app/hst"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ProxyPair is an upstream dbus address and a downstream socket path.
|
// ProxyPair is an upstream dbus address and a downstream socket path.
|
||||||
type ProxyPair [2]string
|
type ProxyPair [2]string
|
||||||
|
|
||||||
type Config struct {
|
// interfacesAll returns an iterator over all interfaces specified in c.
|
||||||
// See set 'see' policy for NAME (--see=NAME)
|
func interfacesAll(c *hst.BusConfig) func(yield func(string) bool) {
|
||||||
See []string `json:"see"`
|
return func(yield func(string) bool) {
|
||||||
// Talk set 'talk' policy for NAME (--talk=NAME)
|
for _, iface := range c.See {
|
||||||
Talk []string `json:"talk"`
|
if !yield(iface) {
|
||||||
// Own set 'own' policy for NAME (--own=NAME)
|
return
|
||||||
Own []string `json:"own"`
|
}
|
||||||
|
|
||||||
// Call set RULE for calls on NAME (--call=NAME=RULE)
|
|
||||||
Call map[string]string `json:"call"`
|
|
||||||
// Broadcast set RULE for broadcasts from NAME (--broadcast=NAME=RULE)
|
|
||||||
Broadcast map[string]string `json:"broadcast"`
|
|
||||||
|
|
||||||
Log bool `json:"log,omitempty"`
|
|
||||||
Filter bool `json:"filter"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Config) interfaces(yield func(string) bool) {
|
|
||||||
for _, iface := range c.See {
|
|
||||||
if !yield(iface) {
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
for _, iface := range c.Talk {
|
||||||
for _, iface := range c.Talk {
|
if !yield(iface) {
|
||||||
if !yield(iface) {
|
return
|
||||||
return
|
}
|
||||||
}
|
}
|
||||||
}
|
for _, iface := range c.Own {
|
||||||
for _, iface := range c.Own {
|
if !yield(iface) {
|
||||||
if !yield(iface) {
|
return
|
||||||
return
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
for iface := range c.Call {
|
for iface := range c.Call {
|
||||||
if !yield(iface) {
|
if !yield(iface) {
|
||||||
return
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
for iface := range c.Broadcast {
|
||||||
for iface := range c.Broadcast {
|
if !yield(iface) {
|
||||||
if !yield(iface) {
|
return
|
||||||
return
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Config) checkInterfaces(segment string) error {
|
// checkInterfaces checks [hst.BusConfig] for invalid interfaces based on an undocumented check in xdg-dbus-error,
|
||||||
for iface := range c.interfaces {
|
// returning [BadInterfaceError] if one is encountered.
|
||||||
|
func checkInterfaces(c *hst.BusConfig, segment string) error {
|
||||||
|
for iface := range interfacesAll(c) {
|
||||||
/*
|
/*
|
||||||
xdg-dbus-proxy fails without output when this condition is not met:
|
xdg-dbus-proxy fails without output when this condition is not met:
|
||||||
char *dot = strrchr (filter->interface, '.');
|
char *dot = strrchr (filter->interface, '.');
|
||||||
@ -83,7 +69,8 @@ func (c *Config) checkInterfaces(segment string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Config) Args(bus ProxyPair) (args []string) {
|
// Args returns the xdg-dbus-proxy arguments equivalent of [hst.BusConfig].
|
||||||
|
func Args(c *hst.BusConfig, bus ProxyPair) (args []string) {
|
||||||
argc := 2 + len(c.See) + len(c.Talk) + len(c.Own) + len(c.Call) + len(c.Broadcast)
|
argc := 2 + len(c.See) + len(c.Talk) + len(c.Own) + len(c.Call) + len(c.Broadcast)
|
||||||
if c.Log {
|
if c.Log {
|
||||||
argc++
|
argc++
|
||||||
@ -119,25 +106,9 @@ func (c *Config) Args(bus ProxyPair) (args []string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Config) Load(r io.Reader) error { return json.NewDecoder(r).Decode(&c) }
|
// NewConfig returns the address of a new [hst.BusConfig] with optional defaults.
|
||||||
|
func NewConfig(id string, defaults, mpris bool) *hst.BusConfig {
|
||||||
// NewConfigFromFile opens the target config file at path and parses its contents into *Config.
|
c := hst.BusConfig{
|
||||||
func NewConfigFromFile(path string) (*Config, error) {
|
|
||||||
if f, err := os.Open(path); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
c := new(Config)
|
|
||||||
err1 := c.Load(f)
|
|
||||||
err = f.Close()
|
|
||||||
|
|
||||||
return c, errors.Join(err1, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewConfig returns a reference to a Config struct with optional defaults.
|
|
||||||
// If id is an empty string own defaults are omitted.
|
|
||||||
func NewConfig(id string, defaults, mpris bool) (c *Config) {
|
|
||||||
c = &Config{
|
|
||||||
Call: make(map[string]string),
|
Call: make(map[string]string),
|
||||||
Broadcast: make(map[string]string),
|
Broadcast: make(map[string]string),
|
||||||
|
|
||||||
@ -158,5 +129,5 @@ func NewConfig(id string, defaults, mpris bool) (c *Config) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return &c
|
||||||
}
|
}
|
||||||
|
@ -1,26 +1,24 @@
|
|||||||
package dbus_test
|
package dbus_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"slices"
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"hakurei.app/hst"
|
||||||
"hakurei.app/system/dbus"
|
"hakurei.app/system/dbus"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestConfig_Args(t *testing.T) {
|
func TestConfig_Args(t *testing.T) {
|
||||||
for _, tc := range makeTestCases() {
|
for _, tc := range testCasesExt {
|
||||||
if tc.wantErr {
|
if tc.wantErr {
|
||||||
// args does not check for nulls
|
// args does not check for nulls
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Run("build arguments for "+tc.id, func(t *testing.T) {
|
t.Run("build arguments for "+tc.id, func(t *testing.T) {
|
||||||
if got := tc.c.Args(tc.bus); !slices.Equal(got, tc.want) {
|
if got := dbus.Args(tc.c, tc.bus); !slices.Equal(got, tc.want) {
|
||||||
t.Errorf("Args(%q) = %v, want %v",
|
t.Errorf("Args(%q) = %v, want %v",
|
||||||
tc.bus,
|
tc.bus,
|
||||||
got, tc.want)
|
got, tc.want)
|
||||||
@ -29,74 +27,36 @@ func TestConfig_Args(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewConfigFromFile(t *testing.T) {
|
|
||||||
for _, tc := range makeTestCases() {
|
|
||||||
name := new(strings.Builder)
|
|
||||||
name.WriteString("parse configuration file for application ")
|
|
||||||
name.WriteString(tc.id)
|
|
||||||
if tc.wantErr {
|
|
||||||
name.WriteString(" with unexpected results")
|
|
||||||
}
|
|
||||||
|
|
||||||
samplePath := path.Join("testdata", tc.id+".json")
|
|
||||||
|
|
||||||
t.Run(name.String(), func(t *testing.T) {
|
|
||||||
got, err := dbus.NewConfigFromFile(samplePath)
|
|
||||||
if errors.Is(err, os.ErrNotExist) != tc.wantErrF {
|
|
||||||
t.Errorf("NewConfigFromFile(%q) error = %v, wantErrF %v",
|
|
||||||
samplePath,
|
|
||||||
err, tc.wantErrF)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if tc.wantErrF {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if !tc.wantErr && !reflect.DeepEqual(got, tc.c) {
|
|
||||||
t.Errorf("NewConfigFromFile(%q) got = %v, want %v",
|
|
||||||
samplePath,
|
|
||||||
got, tc.c)
|
|
||||||
}
|
|
||||||
if tc.wantErr && reflect.DeepEqual(got, tc.c) {
|
|
||||||
t.Errorf("NewConfigFromFile(%q) got = %v, wantErr %v",
|
|
||||||
samplePath,
|
|
||||||
got, tc.wantErr)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNewConfig(t *testing.T) {
|
func TestNewConfig(t *testing.T) {
|
||||||
ids := [...]string{"org.chromium.Chromium", "dev.vencord.Vesktop"}
|
ids := [...]string{"org.chromium.Chromium", "dev.vencord.Vesktop"}
|
||||||
|
|
||||||
type newTestCase struct {
|
type newTestCase struct {
|
||||||
id string
|
id string
|
||||||
args [2]bool
|
args [2]bool
|
||||||
want *dbus.Config
|
want *hst.BusConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
// populate tests from IDs in generic tests
|
// populate tests from IDs in generic tests
|
||||||
tcs := make([]newTestCase, 0, (len(ids)+1)*4)
|
tcs := make([]newTestCase, 0, (len(ids)+1)*4)
|
||||||
// tests for defaults without id
|
// tests for defaults without id
|
||||||
tcs = append(tcs,
|
tcs = append(tcs,
|
||||||
newTestCase{"", [2]bool{false, false}, &dbus.Config{
|
newTestCase{"", [2]bool{false, false}, &hst.BusConfig{
|
||||||
Call: make(map[string]string),
|
Call: make(map[string]string),
|
||||||
Broadcast: make(map[string]string),
|
Broadcast: make(map[string]string),
|
||||||
Filter: true,
|
Filter: true,
|
||||||
}},
|
}},
|
||||||
newTestCase{"", [2]bool{false, true}, &dbus.Config{
|
newTestCase{"", [2]bool{false, true}, &hst.BusConfig{
|
||||||
Call: make(map[string]string),
|
Call: make(map[string]string),
|
||||||
Broadcast: make(map[string]string),
|
Broadcast: make(map[string]string),
|
||||||
Filter: true,
|
Filter: true,
|
||||||
}},
|
}},
|
||||||
newTestCase{"", [2]bool{true, false}, &dbus.Config{
|
newTestCase{"", [2]bool{true, false}, &hst.BusConfig{
|
||||||
Talk: []string{"org.freedesktop.DBus", "org.freedesktop.Notifications"},
|
Talk: []string{"org.freedesktop.DBus", "org.freedesktop.Notifications"},
|
||||||
Call: map[string]string{"org.freedesktop.portal.*": "*"},
|
Call: map[string]string{"org.freedesktop.portal.*": "*"},
|
||||||
Broadcast: map[string]string{"org.freedesktop.portal.*": "@/org/freedesktop/portal/*"},
|
Broadcast: map[string]string{"org.freedesktop.portal.*": "@/org/freedesktop/portal/*"},
|
||||||
Filter: true,
|
Filter: true,
|
||||||
}},
|
}},
|
||||||
newTestCase{"", [2]bool{true, true}, &dbus.Config{
|
newTestCase{"", [2]bool{true, true}, &hst.BusConfig{
|
||||||
Talk: []string{"org.freedesktop.DBus", "org.freedesktop.Notifications"},
|
Talk: []string{"org.freedesktop.DBus", "org.freedesktop.Notifications"},
|
||||||
Call: map[string]string{"org.freedesktop.portal.*": "*"},
|
Call: map[string]string{"org.freedesktop.portal.*": "*"},
|
||||||
Broadcast: map[string]string{"org.freedesktop.portal.*": "@/org/freedesktop/portal/*"},
|
Broadcast: map[string]string{"org.freedesktop.portal.*": "@/org/freedesktop/portal/*"},
|
||||||
@ -105,24 +65,24 @@ func TestNewConfig(t *testing.T) {
|
|||||||
)
|
)
|
||||||
for _, id := range ids {
|
for _, id := range ids {
|
||||||
tcs = append(tcs,
|
tcs = append(tcs,
|
||||||
newTestCase{id, [2]bool{false, false}, &dbus.Config{
|
newTestCase{id, [2]bool{false, false}, &hst.BusConfig{
|
||||||
Call: make(map[string]string),
|
Call: make(map[string]string),
|
||||||
Broadcast: make(map[string]string),
|
Broadcast: make(map[string]string),
|
||||||
Filter: true,
|
Filter: true,
|
||||||
}},
|
}},
|
||||||
newTestCase{id, [2]bool{false, true}, &dbus.Config{
|
newTestCase{id, [2]bool{false, true}, &hst.BusConfig{
|
||||||
Call: make(map[string]string),
|
Call: make(map[string]string),
|
||||||
Broadcast: make(map[string]string),
|
Broadcast: make(map[string]string),
|
||||||
Filter: true,
|
Filter: true,
|
||||||
}},
|
}},
|
||||||
newTestCase{id, [2]bool{true, false}, &dbus.Config{
|
newTestCase{id, [2]bool{true, false}, &hst.BusConfig{
|
||||||
Talk: []string{"org.freedesktop.DBus", "org.freedesktop.Notifications"},
|
Talk: []string{"org.freedesktop.DBus", "org.freedesktop.Notifications"},
|
||||||
Own: []string{id + ".*"},
|
Own: []string{id + ".*"},
|
||||||
Call: map[string]string{"org.freedesktop.portal.*": "*"},
|
Call: map[string]string{"org.freedesktop.portal.*": "*"},
|
||||||
Broadcast: map[string]string{"org.freedesktop.portal.*": "@/org/freedesktop/portal/*"},
|
Broadcast: map[string]string{"org.freedesktop.portal.*": "@/org/freedesktop/portal/*"},
|
||||||
Filter: true,
|
Filter: true,
|
||||||
}},
|
}},
|
||||||
newTestCase{id, [2]bool{true, true}, &dbus.Config{
|
newTestCase{id, [2]bool{true, true}, &hst.BusConfig{
|
||||||
Talk: []string{"org.freedesktop.DBus", "org.freedesktop.Notifications"},
|
Talk: []string{"org.freedesktop.DBus", "org.freedesktop.Notifications"},
|
||||||
Own: []string{id + ".*", "org.mpris.MediaPlayer2." + id + ".*"},
|
Own: []string{id + ".*", "org.mpris.MediaPlayer2." + id + ".*"},
|
||||||
Call: map[string]string{"org.freedesktop.portal.*": "*"},
|
Call: map[string]string{"org.freedesktop.portal.*": "*"},
|
||||||
|
@ -22,7 +22,7 @@ func TestFinalise(t *testing.T) {
|
|||||||
err, syscall.EBADE)
|
err, syscall.EBADE)
|
||||||
}
|
}
|
||||||
|
|
||||||
for id, tc := range testCasePairs() {
|
for id, tc := range testCasePairs {
|
||||||
t.Run("create final for "+id, func(t *testing.T) {
|
t.Run("create final for "+id, func(t *testing.T) {
|
||||||
var wt io.WriterTo
|
var wt io.WriterTo
|
||||||
if v, err := dbus.Finalise(tc[0].bus, tc[1].bus, tc[0].c, tc[1].c); (errors.Is(err, syscall.EINVAL)) != tc[0].wantErr {
|
if v, err := dbus.Finalise(tc[0].bus, tc[1].bus, tc[0].c, tc[1].c); (errors.Is(err, syscall.EINVAL)) != tc[0].wantErr {
|
||||||
@ -105,7 +105,7 @@ func testProxyFinaliseStartWaitCloseString(t *testing.T, useSandbox bool) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
for id, tc := range testCasePairs() {
|
for id, tc := range testCasePairs {
|
||||||
// this test does not test errors
|
// this test does not test errors
|
||||||
if tc[0].wantErr {
|
if tc[0].wantErr {
|
||||||
continue
|
continue
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
|
|
||||||
"hakurei.app/container"
|
"hakurei.app/container"
|
||||||
"hakurei.app/helper"
|
"hakurei.app/helper"
|
||||||
|
"hakurei.app/hst"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ProxyName is the file name or path to the proxy program.
|
// ProxyName is the file name or path to the proxy program.
|
||||||
@ -66,23 +67,23 @@ type Final struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Finalise creates a checked argument writer for [Proxy].
|
// Finalise creates a checked argument writer for [Proxy].
|
||||||
func Finalise(sessionBus, systemBus ProxyPair, session, system *Config) (final *Final, err error) {
|
func Finalise(sessionBus, systemBus ProxyPair, session, system *hst.BusConfig) (final *Final, err error) {
|
||||||
if session == nil && system == nil {
|
if session == nil && system == nil {
|
||||||
return nil, syscall.EBADE
|
return nil, syscall.EBADE
|
||||||
}
|
}
|
||||||
|
|
||||||
var args []string
|
var args []string
|
||||||
if session != nil {
|
if session != nil {
|
||||||
if err = session.checkInterfaces("session"); err != nil {
|
if err = checkInterfaces(session, "session"); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
args = append(args, session.Args(sessionBus)...)
|
args = append(args, Args(session, sessionBus)...)
|
||||||
}
|
}
|
||||||
if system != nil {
|
if system != nil {
|
||||||
if err = system.checkInterfaces("system"); err != nil {
|
if err = checkInterfaces(system, "system"); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
args = append(args, system.Args(systemBus)...)
|
args = append(args, Args(system, systemBus)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
final = &Final{Session: sessionBus, System: systemBus}
|
final = &Final{Session: sessionBus, System: systemBus}
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
package dbus_test
|
package dbus_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"sync"
|
"hakurei.app/hst"
|
||||||
|
|
||||||
"hakurei.app/system/dbus"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -14,7 +12,7 @@ const (
|
|||||||
|
|
||||||
var samples = []dbusTestCase{
|
var samples = []dbusTestCase{
|
||||||
{
|
{
|
||||||
"org.chromium.Chromium", &dbus.Config{
|
"org.chromium.Chromium", &hst.BusConfig{
|
||||||
See: nil,
|
See: nil,
|
||||||
Talk: []string{"org.freedesktop.Notifications", "org.freedesktop.FileManager1", "org.freedesktop.ScreenSaver",
|
Talk: []string{"org.freedesktop.Notifications", "org.freedesktop.FileManager1", "org.freedesktop.ScreenSaver",
|
||||||
"org.freedesktop.secrets", "org.kde.kwalletd5", "org.kde.kwalletd6", "org.gnome.SessionManager"},
|
"org.freedesktop.secrets", "org.kde.kwalletd5", "org.kde.kwalletd6", "org.gnome.SessionManager"},
|
||||||
@ -45,7 +43,7 @@ var samples = []dbusTestCase{
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"org.chromium.Chromium+", &dbus.Config{
|
"org.chromium.Chromium+", &hst.BusConfig{
|
||||||
See: nil,
|
See: nil,
|
||||||
Talk: []string{"org.bluez", "org.freedesktop.Avahi", "org.freedesktop.UPower"},
|
Talk: []string{"org.bluez", "org.freedesktop.Avahi", "org.freedesktop.UPower"},
|
||||||
Own: nil,
|
Own: nil,
|
||||||
@ -66,7 +64,7 @@ var samples = []dbusTestCase{
|
|||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"dev.vencord.Vesktop", &dbus.Config{
|
"dev.vencord.Vesktop", &hst.BusConfig{
|
||||||
See: nil,
|
See: nil,
|
||||||
Talk: []string{"org.freedesktop.Notifications", "org.kde.StatusNotifierWatcher"},
|
Talk: []string{"org.freedesktop.Notifications", "org.kde.StatusNotifierWatcher"},
|
||||||
Own: []string{"dev.vencord.Vesktop.*", "org.mpris.MediaPlayer2.dev.vencord.Vesktop.*"},
|
Own: []string{"dev.vencord.Vesktop.*", "org.mpris.MediaPlayer2.dev.vencord.Vesktop.*"},
|
||||||
@ -89,7 +87,7 @@ var samples = []dbusTestCase{
|
|||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"uk.gensokyo.CrashTestDummy", &dbus.Config{
|
"uk.gensokyo.CrashTestDummy", &hst.BusConfig{
|
||||||
See: []string{"uk.gensokyo.CrashTestDummy1"},
|
See: []string{"uk.gensokyo.CrashTestDummy1"},
|
||||||
Talk: []string{"org.freedesktop.Notifications"},
|
Talk: []string{"org.freedesktop.Notifications"},
|
||||||
Own: []string{"uk.gensokyo.CrashTestDummy.*", "org.mpris.MediaPlayer2.uk.gensokyo.CrashTestDummy.*"},
|
Own: []string{"uk.gensokyo.CrashTestDummy.*", "org.mpris.MediaPlayer2.uk.gensokyo.CrashTestDummy.*"},
|
||||||
@ -112,7 +110,7 @@ var samples = []dbusTestCase{
|
|||||||
"--log"},
|
"--log"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"uk.gensokyo.CrashTestDummy1", &dbus.Config{
|
"uk.gensokyo.CrashTestDummy1", &hst.BusConfig{
|
||||||
See: []string{"uk.gensokyo.CrashTestDummy"},
|
See: []string{"uk.gensokyo.CrashTestDummy"},
|
||||||
Talk: []string{"org.freedesktop.Notifications"},
|
Talk: []string{"org.freedesktop.Notifications"},
|
||||||
Own: []string{"uk.gensokyo.CrashTestDummy1.*", "org.mpris.MediaPlayer2.uk.gensokyo.CrashTestDummy1.*"},
|
Own: []string{"uk.gensokyo.CrashTestDummy1.*", "org.mpris.MediaPlayer2.uk.gensokyo.CrashTestDummy1.*"},
|
||||||
@ -138,7 +136,7 @@ var samples = []dbusTestCase{
|
|||||||
|
|
||||||
type dbusTestCase struct {
|
type dbusTestCase struct {
|
||||||
id string
|
id string
|
||||||
c *dbus.Config
|
c *hst.BusConfig
|
||||||
wantErr bool
|
wantErr bool
|
||||||
wantErrF bool
|
wantErrF bool
|
||||||
bus [2]string
|
bus [2]string
|
||||||
@ -146,83 +144,71 @@ type dbusTestCase struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
testCasesV []dbusTestCase
|
testCasesExt = func() []dbusTestCase {
|
||||||
testCasePairsV map[string][2]dbusTestCase
|
testCases := make([]dbusTestCase, len(samples)*2)
|
||||||
|
for i := range samples {
|
||||||
|
testCases[i] = samples[i]
|
||||||
|
|
||||||
testCaseOnce sync.Once
|
fi := &testCases[len(samples)+i]
|
||||||
)
|
*fi = samples[i]
|
||||||
|
|
||||||
func makeTestCases() []dbusTestCase {
|
// create null-injected test cases
|
||||||
testCaseOnce.Do(testCaseGenerate)
|
fi.wantErr = true
|
||||||
return testCasesV
|
injectNulls := func(t *[]string) {
|
||||||
}
|
f := make([]string, len(*t))
|
||||||
|
for i := range f {
|
||||||
|
f[i] = "\x00" + (*t)[i] + "\x00"
|
||||||
|
}
|
||||||
|
*t = f
|
||||||
|
}
|
||||||
|
|
||||||
func testCasePairs() map[string][2]dbusTestCase {
|
fi.c = new(hst.BusConfig)
|
||||||
testCaseOnce.Do(testCaseGenerate)
|
*fi.c = *samples[i].c
|
||||||
return testCasePairsV
|
injectNulls(&fi.c.See)
|
||||||
}
|
injectNulls(&fi.c.Talk)
|
||||||
|
injectNulls(&fi.c.Own)
|
||||||
func injectNulls(t *[]string) {
|
|
||||||
f := make([]string, len(*t))
|
|
||||||
for i := range f {
|
|
||||||
f[i] = "\x00" + (*t)[i] + "\x00"
|
|
||||||
}
|
|
||||||
*t = f
|
|
||||||
}
|
|
||||||
|
|
||||||
func testCaseGenerate() {
|
|
||||||
// create null-injected test cases
|
|
||||||
testCasesV = make([]dbusTestCase, len(samples)*2)
|
|
||||||
for i := range samples {
|
|
||||||
testCasesV[i] = samples[i]
|
|
||||||
testCasesV[len(samples)+i] = samples[i]
|
|
||||||
testCasesV[len(samples)+i].c = new(dbus.Config)
|
|
||||||
*testCasesV[len(samples)+i].c = *samples[i].c
|
|
||||||
|
|
||||||
// inject nulls
|
|
||||||
fi := &testCasesV[len(samples)+i]
|
|
||||||
fi.wantErr = true
|
|
||||||
|
|
||||||
injectNulls(&fi.c.See)
|
|
||||||
injectNulls(&fi.c.Talk)
|
|
||||||
injectNulls(&fi.c.Own)
|
|
||||||
}
|
|
||||||
|
|
||||||
// enumerate test case pairs
|
|
||||||
var pc int
|
|
||||||
for _, tc := range samples {
|
|
||||||
if tc.id != "" {
|
|
||||||
pc++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
testCasePairsV = make(map[string][2]dbusTestCase, pc)
|
|
||||||
for i, tc := range testCasesV {
|
|
||||||
if tc.id == "" {
|
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
|
return testCases
|
||||||
|
}()
|
||||||
|
|
||||||
// skip already enumerated system bus test
|
testCasePairs = func() map[string][2]dbusTestCase {
|
||||||
if tc.id[len(tc.id)-1] == '+' {
|
// enumerate test case pairs
|
||||||
continue
|
var pc int
|
||||||
}
|
for _, tc := range samples {
|
||||||
|
if tc.id != "" {
|
||||||
ftp := [2]dbusTestCase{tc}
|
pc++
|
||||||
|
|
||||||
// system proxy tests always place directly after its user counterpart with id ending in +
|
|
||||||
if i+1 < len(testCasesV) && testCasesV[i+1].id[len(testCasesV[i+1].id)-1] == '+' {
|
|
||||||
// attach system bus config
|
|
||||||
ftp[1] = testCasesV[i+1]
|
|
||||||
|
|
||||||
// check for misplaced/mismatching tests
|
|
||||||
if ftp[0].wantErr != ftp[1].wantErr || ftp[0].id+"+" != ftp[1].id {
|
|
||||||
panic("mismatching session/system pairing")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pairs := make(map[string][2]dbusTestCase, pc)
|
||||||
|
for i, tc := range testCasesExt {
|
||||||
|
if tc.id == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
k := tc.id
|
// skip already enumerated system bus test
|
||||||
if tc.wantErr {
|
if tc.id[len(tc.id)-1] == '+' {
|
||||||
k = "malformed_" + k
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
ftp := [2]dbusTestCase{tc}
|
||||||
|
|
||||||
|
// system proxy tests always place directly after its user counterpart with id ending in +
|
||||||
|
if i+1 < len(testCasesExt) && testCasesExt[i+1].id[len(testCasesExt[i+1].id)-1] == '+' {
|
||||||
|
// attach system bus config
|
||||||
|
ftp[1] = testCasesExt[i+1]
|
||||||
|
|
||||||
|
// check for misplaced/mismatching tests
|
||||||
|
if ftp[0].wantErr != ftp[1].wantErr || ftp[0].id+"+" != ftp[1].id {
|
||||||
|
panic("mismatching session/system pairing")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
k := tc.id
|
||||||
|
if tc.wantErr {
|
||||||
|
k = "malformed_" + k
|
||||||
|
}
|
||||||
|
pairs[k] = ftp
|
||||||
}
|
}
|
||||||
testCasePairsV[k] = ftp
|
return pairs
|
||||||
}
|
}()
|
||||||
}
|
)
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
|
|
||||||
"hakurei.app/container/stub"
|
"hakurei.app/container/stub"
|
||||||
"hakurei.app/helper"
|
"hakurei.app/helper"
|
||||||
|
"hakurei.app/hst"
|
||||||
"hakurei.app/system/dbus"
|
"hakurei.app/system/dbus"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -82,7 +83,7 @@ func TestDBusProxyOp(t *testing.T) {
|
|||||||
Op: "dbus", Err: ErrDBusConfig,
|
Op: "dbus", Err: ErrDBusConfig,
|
||||||
Msg: "attempted to create message bus proxy args without session bus config",
|
Msg: "attempted to create message bus proxy args without session bus config",
|
||||||
}
|
}
|
||||||
if err := sys.ProxyDBus(nil, new(dbus.Config), nil, nil); !reflect.DeepEqual(err, wantErr) {
|
if err := sys.ProxyDBus(nil, new(hst.BusConfig), nil, nil); !reflect.DeepEqual(err, wantErr) {
|
||||||
t.Errorf("ProxyDBus: error = %v, want %v", err, wantErr)
|
t.Errorf("ProxyDBus: error = %v, want %v", err, wantErr)
|
||||||
}
|
}
|
||||||
}, nil, stub.Expect{}},
|
}, nil, stub.Expect{}},
|
||||||
@ -96,10 +97,10 @@ func TestDBusProxyOp(t *testing.T) {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
sys.MustProxyDBus(
|
sys.MustProxyDBus(
|
||||||
m("/tmp/hakurei.0/99dd71ee2146369514e0d10783368f8f/bus"), &dbus.Config{
|
m("/tmp/hakurei.0/99dd71ee2146369514e0d10783368f8f/bus"), &hst.BusConfig{
|
||||||
// use impossible value here as an implicit assert that it goes through the stub
|
// use impossible value here as an implicit assert that it goes through the stub
|
||||||
Talk: []string{"session\x00"}, Filter: true,
|
Talk: []string{"session\x00"}, Filter: true,
|
||||||
}, m("/tmp/hakurei.0/99dd71ee2146369514e0d10783368f8f/system_bus_socket"), &dbus.Config{
|
}, m("/tmp/hakurei.0/99dd71ee2146369514e0d10783368f8f/system_bus_socket"), &hst.BusConfig{
|
||||||
// use impossible value here as an implicit assert that it goes through the stub
|
// use impossible value here as an implicit assert that it goes through the stub
|
||||||
Talk: []string{"system\x00"}, Filter: true,
|
Talk: []string{"system\x00"}, Filter: true,
|
||||||
})
|
})
|
||||||
@ -108,8 +109,8 @@ func TestDBusProxyOp(t *testing.T) {
|
|||||||
call("dbusFinalise", stub.ExpectArgs{
|
call("dbusFinalise", stub.ExpectArgs{
|
||||||
dbus.ProxyPair{"unix:path=/run/user/1000/bus", "/tmp/hakurei.0/99dd71ee2146369514e0d10783368f8f/bus"},
|
dbus.ProxyPair{"unix:path=/run/user/1000/bus", "/tmp/hakurei.0/99dd71ee2146369514e0d10783368f8f/bus"},
|
||||||
dbus.ProxyPair{"unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/99dd71ee2146369514e0d10783368f8f/system_bus_socket"},
|
dbus.ProxyPair{"unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/99dd71ee2146369514e0d10783368f8f/system_bus_socket"},
|
||||||
&dbus.Config{Talk: []string{"session\x00"}, Filter: true},
|
&hst.BusConfig{Talk: []string{"session\x00"}, Filter: true},
|
||||||
&dbus.Config{Talk: []string{"system\x00"}, Filter: true},
|
&hst.BusConfig{Talk: []string{"system\x00"}, Filter: true},
|
||||||
}, (*dbus.Final)(nil), syscall.EINVAL),
|
}, (*dbus.Final)(nil), syscall.EINVAL),
|
||||||
}}},
|
}}},
|
||||||
|
|
||||||
@ -119,10 +120,10 @@ func TestDBusProxyOp(t *testing.T) {
|
|||||||
Msg: "cannot finalise message bus proxy: unique error 0 injected by the test suite",
|
Msg: "cannot finalise message bus proxy: unique error 0 injected by the test suite",
|
||||||
}
|
}
|
||||||
if err := sys.ProxyDBus(
|
if err := sys.ProxyDBus(
|
||||||
&dbus.Config{
|
&hst.BusConfig{
|
||||||
// use impossible value here as an implicit assert that it goes through the stub
|
// use impossible value here as an implicit assert that it goes through the stub
|
||||||
Talk: []string{"session\x00"}, Filter: true,
|
Talk: []string{"session\x00"}, Filter: true,
|
||||||
}, &dbus.Config{
|
}, &hst.BusConfig{
|
||||||
// use impossible value here as an implicit assert that it goes through the stub
|
// use impossible value here as an implicit assert that it goes through the stub
|
||||||
Talk: []string{"system\x00"}, Filter: true,
|
Talk: []string{"system\x00"}, Filter: true,
|
||||||
},
|
},
|
||||||
@ -135,17 +136,17 @@ func TestDBusProxyOp(t *testing.T) {
|
|||||||
call("dbusFinalise", stub.ExpectArgs{
|
call("dbusFinalise", stub.ExpectArgs{
|
||||||
dbus.ProxyPair{"unix:path=/run/user/1000/bus", "/tmp/hakurei.0/99dd71ee2146369514e0d10783368f8f/bus"},
|
dbus.ProxyPair{"unix:path=/run/user/1000/bus", "/tmp/hakurei.0/99dd71ee2146369514e0d10783368f8f/bus"},
|
||||||
dbus.ProxyPair{"unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/99dd71ee2146369514e0d10783368f8f/system_bus_socket"},
|
dbus.ProxyPair{"unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/99dd71ee2146369514e0d10783368f8f/system_bus_socket"},
|
||||||
&dbus.Config{Talk: []string{"session\x00"}, Filter: true},
|
&hst.BusConfig{Talk: []string{"session\x00"}, Filter: true},
|
||||||
&dbus.Config{Talk: []string{"system\x00"}, Filter: true},
|
&hst.BusConfig{Talk: []string{"system\x00"}, Filter: true},
|
||||||
}, (*dbus.Final)(nil), stub.UniqueError(0)),
|
}, (*dbus.Final)(nil), stub.UniqueError(0)),
|
||||||
}}},
|
}}},
|
||||||
|
|
||||||
{"full", 0xcafebabe, func(_ *testing.T, sys *I) {
|
{"full", 0xcafebabe, func(_ *testing.T, sys *I) {
|
||||||
sys.MustProxyDBus(
|
sys.MustProxyDBus(
|
||||||
m("/tmp/hakurei.0/99dd71ee2146369514e0d10783368f8f/bus"), &dbus.Config{
|
m("/tmp/hakurei.0/99dd71ee2146369514e0d10783368f8f/bus"), &hst.BusConfig{
|
||||||
// use impossible value here as an implicit assert that it goes through the stub
|
// use impossible value here as an implicit assert that it goes through the stub
|
||||||
Talk: []string{"session\x00"}, Filter: true,
|
Talk: []string{"session\x00"}, Filter: true,
|
||||||
}, m("/tmp/hakurei.0/99dd71ee2146369514e0d10783368f8f/system_bus_socket"), &dbus.Config{
|
}, m("/tmp/hakurei.0/99dd71ee2146369514e0d10783368f8f/system_bus_socket"), &hst.BusConfig{
|
||||||
// use impossible value here as an implicit assert that it goes through the stub
|
// use impossible value here as an implicit assert that it goes through the stub
|
||||||
Talk: []string{"system\x00"}, Filter: true,
|
Talk: []string{"system\x00"}, Filter: true,
|
||||||
})
|
})
|
||||||
@ -159,8 +160,8 @@ func TestDBusProxyOp(t *testing.T) {
|
|||||||
call("dbusFinalise", stub.ExpectArgs{
|
call("dbusFinalise", stub.ExpectArgs{
|
||||||
dbus.ProxyPair{"unix:path=/run/user/1000/bus", "/tmp/hakurei.0/99dd71ee2146369514e0d10783368f8f/bus"},
|
dbus.ProxyPair{"unix:path=/run/user/1000/bus", "/tmp/hakurei.0/99dd71ee2146369514e0d10783368f8f/bus"},
|
||||||
dbus.ProxyPair{"unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/99dd71ee2146369514e0d10783368f8f/system_bus_socket"},
|
dbus.ProxyPair{"unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/99dd71ee2146369514e0d10783368f8f/system_bus_socket"},
|
||||||
&dbus.Config{Talk: []string{"session\x00"}, Filter: true},
|
&hst.BusConfig{Talk: []string{"session\x00"}, Filter: true},
|
||||||
&dbus.Config{Talk: []string{"system\x00"}, Filter: true},
|
&hst.BusConfig{Talk: []string{"system\x00"}, Filter: true},
|
||||||
}, dbusNewFinalSample(0), nil),
|
}, dbusNewFinalSample(0), nil),
|
||||||
call("isVerbose", stub.ExpectArgs{}, true, nil),
|
call("isVerbose", stub.ExpectArgs{}, true, nil),
|
||||||
call("verbose", stub.ExpectArgs{[]any{"session bus proxy:", []string{"unix:path=/run/user/1000/bus", "/tmp/hakurei.0/99dd71ee2146369514e0d10783368f8f/bus", "--filter", "--talk=session\x00"}}}, nil, nil),
|
call("verbose", stub.ExpectArgs{[]any{"session bus proxy:", []string{"unix:path=/run/user/1000/bus", "/tmp/hakurei.0/99dd71ee2146369514e0d10783368f8f/bus", "--filter", "--talk=session\x00"}}}, nil, nil),
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"hakurei.app/hst"
|
||||||
"hakurei.app/system/acl"
|
"hakurei.app/system/acl"
|
||||||
"hakurei.app/system/dbus"
|
"hakurei.app/system/dbus"
|
||||||
"hakurei.app/system/internal/xcb"
|
"hakurei.app/system/internal/xcb"
|
||||||
@ -50,7 +51,7 @@ type syscallDispatcher interface {
|
|||||||
// dbusAddress provides [dbus.Address].
|
// dbusAddress provides [dbus.Address].
|
||||||
dbusAddress() (session, system string)
|
dbusAddress() (session, system string)
|
||||||
// dbusFinalise provides [dbus.Finalise].
|
// dbusFinalise provides [dbus.Finalise].
|
||||||
dbusFinalise(sessionBus, systemBus dbus.ProxyPair, session, system *dbus.Config) (final *dbus.Final, err error)
|
dbusFinalise(sessionBus, systemBus dbus.ProxyPair, session, system *hst.BusConfig) (final *dbus.Final, err error)
|
||||||
// dbusProxyStart provides the Start method of [dbus.Proxy].
|
// dbusProxyStart provides the Start method of [dbus.Proxy].
|
||||||
dbusProxyStart(proxy *dbus.Proxy) error
|
dbusProxyStart(proxy *dbus.Proxy) error
|
||||||
// dbusProxyClose provides the Close method of [dbus.Proxy].
|
// dbusProxyClose provides the Close method of [dbus.Proxy].
|
||||||
@ -85,7 +86,7 @@ func (k direct) dbusAddress() (session, system string) {
|
|||||||
return dbus.Address()
|
return dbus.Address()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (k direct) dbusFinalise(sessionBus, systemBus dbus.ProxyPair, session, system *dbus.Config) (final *dbus.Final, err error) {
|
func (k direct) dbusFinalise(sessionBus, systemBus dbus.ProxyPair, session, system *hst.BusConfig) (final *dbus.Final, err error) {
|
||||||
return dbus.Finalise(sessionBus, systemBus, session, system)
|
return dbus.Finalise(sessionBus, systemBus, session, system)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -305,7 +305,7 @@ func (k *kstub) dbusAddress() (session, system string) {
|
|||||||
return ret[0], ret[1]
|
return ret[0], ret[1]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (k *kstub) dbusFinalise(sessionBus, systemBus dbus.ProxyPair, session, system *dbus.Config) (final *dbus.Final, err error) {
|
func (k *kstub) dbusFinalise(sessionBus, systemBus dbus.ProxyPair, session, system *hst.BusConfig) (final *dbus.Final, err error) {
|
||||||
k.Helper()
|
k.Helper()
|
||||||
expect := k.Expects("dbusFinalise")
|
expect := k.Expects("dbusFinalise")
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user