system/dbus: use syscall dispatcher
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				Test / Create distribution (push) Successful in 1m4s
				
			
		
			
				
	
				Test / Sandbox (push) Successful in 5m35s
				
			
		
			
				
	
				Test / Sandbox (race detector) (push) Successful in 8m16s
				
			
		
			
				
	
				Test / Hakurei (push) Successful in 10m43s
				
			
		
			
				
	
				Test / Hpkg (push) Successful in 11m20s
				
			
		
			
				
	
				Test / Hakurei (race detector) (push) Successful in 12m54s
				
			
		
			
				
	
				Test / Flake checks (push) Successful in 3m5s
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	Test / Create distribution (push) Successful in 1m4s
				
			Test / Sandbox (push) Successful in 5m35s
				
			Test / Sandbox (race detector) (push) Successful in 8m16s
				
			Test / Hakurei (push) Successful in 10m43s
				
			Test / Hpkg (push) Successful in 11m20s
				
			Test / Hakurei (race detector) (push) Successful in 12m54s
				
			Test / Flake checks (push) Successful in 3m5s
				
			This allows dbus op methods and builder to be instrumented. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
		
							parent
							
								
									e603b688ca
								
							
						
					
					
						commit
						05db06c87b
					
				| @ -43,10 +43,10 @@ func (sys *I) ProxyDBus(session, system *dbus.Config, sessionPath, systemPath st | |||||||
| 	d.system = system != nil | 	d.system = system != nil | ||||||
| 
 | 
 | ||||||
| 	var sessionBus, systemBus dbus.ProxyPair | 	var sessionBus, systemBus dbus.ProxyPair | ||||||
| 	sessionBus[0], systemBus[0] = dbus.Address() | 	sessionBus[0], systemBus[0] = sys.dbusAddress() | ||||||
| 	sessionBus[1], systemBus[1] = sessionPath, systemPath | 	sessionBus[1], systemBus[1] = sessionPath, systemPath | ||||||
| 	d.out = &linePrefixWriter{println: log.Println, prefix: "(dbus) ", buf: new(strings.Builder)} | 	d.out = &linePrefixWriter{println: log.Println, prefix: "(dbus) ", buf: new(strings.Builder)} | ||||||
| 	if final, err := dbus.Finalise(sessionBus, systemBus, session, system); err != nil { | 	if final, err := sys.dbusFinalise(sessionBus, systemBus, session, system); err != nil { | ||||||
| 		if errors.Is(err, syscall.EINVAL) { | 		if errors.Is(err, syscall.EINVAL) { | ||||||
| 			return nil, newOpErrorMessage("dbus", err, | 			return nil, newOpErrorMessage("dbus", err, | ||||||
| 				"message bus proxy configuration contains NUL byte", false) | 				"message bus proxy configuration contains NUL byte", false) | ||||||
| @ -54,14 +54,14 @@ func (sys *I) ProxyDBus(session, system *dbus.Config, sessionPath, systemPath st | |||||||
| 		return nil, newOpErrorMessage("dbus", err, | 		return nil, newOpErrorMessage("dbus", err, | ||||||
| 			fmt.Sprintf("cannot finalise message bus proxy: %v", err), false) | 			fmt.Sprintf("cannot finalise message bus proxy: %v", err), false) | ||||||
| 	} else { | 	} else { | ||||||
| 		if msg.IsVerbose() { | 		if sys.isVerbose() { | ||||||
| 			msg.Verbose("session bus proxy:", session.Args(sessionBus)) | 			sys.verbose("session bus proxy:", session.Args(sessionBus)) | ||||||
| 			if system != nil { | 			if system != nil { | ||||||
| 				msg.Verbose("system bus proxy:", system.Args(systemBus)) | 				sys.verbose("system bus proxy:", system.Args(systemBus)) | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			// this calls the argsWt String method | 			// this calls the argsWt String method | ||||||
| 			msg.Verbose("message bus proxy final args:", final.WriterTo) | 			sys.verbose("message bus proxy final args:", final.WriterTo) | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		d.final = final | 		d.final = final | ||||||
| @ -85,29 +85,32 @@ type DBusProxyOp struct { | |||||||
| func (d *DBusProxyOp) Type() Enablement { return Process } | func (d *DBusProxyOp) Type() Enablement { return Process } | ||||||
| 
 | 
 | ||||||
| func (d *DBusProxyOp) apply(sys *I) error { | func (d *DBusProxyOp) apply(sys *I) error { | ||||||
| 	msg.Verbosef("session bus proxy on %q for upstream %q", d.final.Session[1], d.final.Session[0]) | 	sys.verbosef("session bus proxy on %q for upstream %q", d.final.Session[1], d.final.Session[0]) | ||||||
| 	if d.system { | 	if d.system { | ||||||
| 		msg.Verbosef("system bus proxy on %q for upstream %q", d.final.System[1], d.final.System[0]) | 		sys.verbosef("system bus proxy on %q for upstream %q", d.final.System[1], d.final.System[0]) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	d.proxy = dbus.New(sys.ctx, d.final, d.out) | 	d.proxy = dbus.New(sys.ctx, d.final, d.out) | ||||||
| 	if err := d.proxy.Start(); err != nil { | 	if err := sys.dbusProxyStart(d.proxy); err != nil { | ||||||
| 		d.out.Dump() | 		d.out.Dump() | ||||||
| 		return newOpErrorMessage("dbus", err, | 		return newOpErrorMessage("dbus", err, | ||||||
| 			fmt.Sprintf("cannot start message bus proxy: %v", err), false) | 			fmt.Sprintf("cannot start message bus proxy: %v", err), false) | ||||||
| 	} | 	} | ||||||
| 	msg.Verbose("starting message bus proxy", d.proxy) | 	sys.verbose("starting message bus proxy", d.proxy) | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (d *DBusProxyOp) revert(*I, *Criteria) error { | func (d *DBusProxyOp) revert(sys *I, _ *Criteria) error { | ||||||
| 	// criteria ignored here since dbus is always process-scoped | 	// criteria ignored here since dbus is always process-scoped | ||||||
| 	msg.Verbose("terminating message bus proxy") | 	sys.verbose("terminating message bus proxy") | ||||||
| 	d.proxy.Close() | 	sys.dbusProxyClose(d.proxy) | ||||||
| 	defer msg.Verbose("message bus proxy exit") | 
 | ||||||
| 	err := d.proxy.Wait() | 	exitMessage := "message bus proxy exit" | ||||||
|  | 	defer func() { sys.verbose(exitMessage) }() | ||||||
|  | 
 | ||||||
|  | 	err := sys.dbusProxyWait(d.proxy) | ||||||
| 	if errors.Is(err, context.Canceled) { | 	if errors.Is(err, context.Canceled) { | ||||||
| 		msg.Verbose("message bus proxy canceled upstream") | 		exitMessage = "message bus proxy canceled upstream" | ||||||
| 		err = nil | 		err = nil | ||||||
| 	} | 	} | ||||||
| 	return newOpErrorMessage("dbus", err, | 	return newOpErrorMessage("dbus", err, | ||||||
|  | |||||||
| @ -1,13 +1,384 @@ | |||||||
| package system | package system | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
|  | 	"context" | ||||||
| 	"reflect" | 	"reflect" | ||||||
| 	"slices" | 	"slices" | ||||||
|  | 	"strconv" | ||||||
| 	"strings" | 	"strings" | ||||||
| 	"syscall" | 	"syscall" | ||||||
| 	"testing" | 	"testing" | ||||||
|  | 
 | ||||||
|  | 	"hakurei.app/container/stub" | ||||||
|  | 	"hakurei.app/helper" | ||||||
|  | 	"hakurei.app/system/dbus" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | func TestDBusProxyOp(t *testing.T) { | ||||||
|  | 	checkOpBehaviour(t, []opBehaviourTestCase{ | ||||||
|  | 		{"dbusProxyStart", 0xdeadbeef, 0xff, &DBusProxyOp{ | ||||||
|  | 			final:  dbusNewFinalSample(4), | ||||||
|  | 			out:    new(linePrefixWriter), // panics on write | ||||||
|  | 			system: true, | ||||||
|  | 		}, []stub.Call{ | ||||||
|  | 			call("verbosef", stub.ExpectArgs{"session bus proxy on %q for upstream %q", []any{"/tmp/hakurei.0/99dd71ee2146369514e0d10783368f8f/bus", "unix:path=/run/user/1000/bus"}}, nil, nil), | ||||||
|  | 			call("verbosef", stub.ExpectArgs{"system bus proxy on %q for upstream %q", []any{"/tmp/hakurei.0/99dd71ee2146369514e0d10783368f8f/system_bus_socket", "unix:path=/run/dbus/system_bus_socket"}}, nil, nil), | ||||||
|  | 			call("dbusProxyStart", stub.ExpectArgs{dbusNewFinalSample(4)}, nil, stub.UniqueError(2)), | ||||||
|  | 		}, &OpError{ | ||||||
|  | 			Op: "dbus", Err: stub.UniqueError(2), | ||||||
|  | 			Msg: "cannot start message bus proxy: unique error 2 injected by the test suite", | ||||||
|  | 		}, nil, nil}, | ||||||
|  | 
 | ||||||
|  | 		{"dbusProxyWait", 0xdeadbeef, 0xff, &DBusProxyOp{ | ||||||
|  | 			final: dbusNewFinalSample(3), | ||||||
|  | 		}, []stub.Call{ | ||||||
|  | 			call("verbosef", stub.ExpectArgs{"session bus proxy on %q for upstream %q", []any{"/tmp/hakurei.0/99dd71ee2146369514e0d10783368f8f/bus", "unix:path=/run/user/1000/bus"}}, nil, nil), | ||||||
|  | 			call("dbusProxyStart", stub.ExpectArgs{dbusNewFinalSample(3)}, nil, nil), | ||||||
|  | 			call("verbose", stub.ExpectArgs{[]any{"starting message bus proxy", ignoreValue{}}}, nil, nil), | ||||||
|  | 		}, nil, []stub.Call{ | ||||||
|  | 			call("verbose", stub.ExpectArgs{[]any{"terminating message bus proxy"}}, nil, nil), | ||||||
|  | 			call("dbusProxyClose", stub.ExpectArgs{dbusNewFinalSample(3)}, nil, nil), | ||||||
|  | 			call("dbusProxyWait", stub.ExpectArgs{dbusNewFinalSample(3)}, nil, stub.UniqueError(1)), | ||||||
|  | 			call("verbose", stub.ExpectArgs{[]any{"message bus proxy exit"}}, nil, nil), | ||||||
|  | 		}, &OpError{ | ||||||
|  | 			Op: "dbus", Err: stub.UniqueError(1), Revert: true, | ||||||
|  | 			Msg: "message bus proxy error: unique error 1 injected by the test suite", | ||||||
|  | 		}}, | ||||||
|  | 
 | ||||||
|  | 		{"success dbusProxyWait cancel", 0xdeadbeef, 0xff, &DBusProxyOp{ | ||||||
|  | 			final:  dbusNewFinalSample(2), | ||||||
|  | 			system: true, | ||||||
|  | 		}, []stub.Call{ | ||||||
|  | 			call("verbosef", stub.ExpectArgs{"session bus proxy on %q for upstream %q", []any{"/tmp/hakurei.0/99dd71ee2146369514e0d10783368f8f/bus", "unix:path=/run/user/1000/bus"}}, nil, nil), | ||||||
|  | 			call("verbosef", stub.ExpectArgs{"system bus proxy on %q for upstream %q", []any{"/tmp/hakurei.0/99dd71ee2146369514e0d10783368f8f/system_bus_socket", "unix:path=/run/dbus/system_bus_socket"}}, nil, nil), | ||||||
|  | 			call("dbusProxyStart", stub.ExpectArgs{dbusNewFinalSample(2)}, nil, nil), | ||||||
|  | 			call("verbose", stub.ExpectArgs{[]any{"starting message bus proxy", ignoreValue{}}}, nil, nil), | ||||||
|  | 		}, nil, []stub.Call{ | ||||||
|  | 			call("verbose", stub.ExpectArgs{[]any{"terminating message bus proxy"}}, nil, nil), | ||||||
|  | 			call("dbusProxyClose", stub.ExpectArgs{dbusNewFinalSample(2)}, nil, nil), | ||||||
|  | 			call("dbusProxyWait", stub.ExpectArgs{dbusNewFinalSample(2)}, nil, context.Canceled), | ||||||
|  | 			call("verbose", stub.ExpectArgs{[]any{"message bus proxy canceled upstream"}}, nil, nil), | ||||||
|  | 		}, nil}, | ||||||
|  | 
 | ||||||
|  | 		{"success", 0xdeadbeef, 0xff, &DBusProxyOp{ | ||||||
|  | 			final:  dbusNewFinalSample(1), | ||||||
|  | 			system: true, | ||||||
|  | 		}, []stub.Call{ | ||||||
|  | 			call("verbosef", stub.ExpectArgs{"session bus proxy on %q for upstream %q", []any{"/tmp/hakurei.0/99dd71ee2146369514e0d10783368f8f/bus", "unix:path=/run/user/1000/bus"}}, nil, nil), | ||||||
|  | 			call("verbosef", stub.ExpectArgs{"system bus proxy on %q for upstream %q", []any{"/tmp/hakurei.0/99dd71ee2146369514e0d10783368f8f/system_bus_socket", "unix:path=/run/dbus/system_bus_socket"}}, nil, nil), | ||||||
|  | 			call("dbusProxyStart", stub.ExpectArgs{dbusNewFinalSample(1)}, nil, nil), | ||||||
|  | 			call("verbose", stub.ExpectArgs{[]any{"starting message bus proxy", ignoreValue{}}}, nil, nil), | ||||||
|  | 		}, nil, []stub.Call{ | ||||||
|  | 			call("verbose", stub.ExpectArgs{[]any{"terminating message bus proxy"}}, nil, nil), | ||||||
|  | 			call("dbusProxyClose", stub.ExpectArgs{dbusNewFinalSample(1)}, nil, nil), | ||||||
|  | 			call("dbusProxyWait", stub.ExpectArgs{dbusNewFinalSample(1)}, nil, nil), | ||||||
|  | 			call("verbose", stub.ExpectArgs{[]any{"message bus proxy exit"}}, nil, nil), | ||||||
|  | 		}, nil}, | ||||||
|  | 	}) | ||||||
|  | 
 | ||||||
|  | 	checkOpsBuilder(t, "ProxyDBus", []opsBuilderTestCase{ | ||||||
|  | 		{"nil session", 0xcafebabe, func(t *testing.T, sys *I) { | ||||||
|  | 			wantErr := &OpError{ | ||||||
|  | 				Op: "dbus", Err: ErrDBusConfig, | ||||||
|  | 				Msg: "attempted to create message bus proxy args without session bus config", | ||||||
|  | 			} | ||||||
|  | 			if f, err := sys.ProxyDBus(nil, new(dbus.Config), "", ""); !reflect.DeepEqual(err, wantErr) { | ||||||
|  | 				t.Errorf("ProxyDBus: error = %v, want %v", err, wantErr) | ||||||
|  | 			} else if f != nil { | ||||||
|  | 				t.Errorf("ProxyDBus: f = %p", f) | ||||||
|  | 			} | ||||||
|  | 		}, nil, stub.Expect{}}, | ||||||
|  | 
 | ||||||
|  | 		{"dbusFinalise NUL", 0xcafebabe, func(_ *testing.T, sys *I) { | ||||||
|  | 			defer func() { | ||||||
|  | 				want := "message bus proxy configuration contains NUL byte" | ||||||
|  | 				if r := recover(); r != want { | ||||||
|  | 					t.Errorf("MustProxyDBus: panic = %v, want %v", r, want) | ||||||
|  | 				} | ||||||
|  | 			}() | ||||||
|  | 
 | ||||||
|  | 			sys.MustProxyDBus( | ||||||
|  | 				"/tmp/hakurei.0/99dd71ee2146369514e0d10783368f8f/bus", &dbus.Config{ | ||||||
|  | 					// use impossible value here as an implicit assert that it goes through the stub | ||||||
|  | 					Talk: []string{"session\x00"}, Filter: true, | ||||||
|  | 				}, "/tmp/hakurei.0/99dd71ee2146369514e0d10783368f8f/system_bus_socket", &dbus.Config{ | ||||||
|  | 					// use impossible value here as an implicit assert that it goes through the stub | ||||||
|  | 					Talk: []string{"system\x00"}, Filter: true, | ||||||
|  | 				}) | ||||||
|  | 		}, nil, stub.Expect{Calls: []stub.Call{ | ||||||
|  | 			call("dbusAddress", stub.ExpectArgs{}, [2]string{"unix:path=/run/user/1000/bus", "unix:path=/run/dbus/system_bus_socket"}, nil), | ||||||
|  | 			call("dbusFinalise", stub.ExpectArgs{ | ||||||
|  | 				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.Config{Talk: []string{"session\x00"}, Filter: true}, | ||||||
|  | 				&dbus.Config{Talk: []string{"system\x00"}, Filter: true}, | ||||||
|  | 			}, (*dbus.Final)(nil), syscall.EINVAL), | ||||||
|  | 		}}}, | ||||||
|  | 
 | ||||||
|  | 		{"dbusFinalise", 0xcafebabe, func(_ *testing.T, sys *I) { | ||||||
|  | 			wantErr := &OpError{ | ||||||
|  | 				Op: "dbus", Err: stub.UniqueError(0), | ||||||
|  | 				Msg: "cannot finalise message bus proxy: unique error 0 injected by the test suite", | ||||||
|  | 			} | ||||||
|  | 			if f, err := sys.ProxyDBus( | ||||||
|  | 				&dbus.Config{ | ||||||
|  | 					// use impossible value here as an implicit assert that it goes through the stub | ||||||
|  | 					Talk: []string{"session\x00"}, Filter: true, | ||||||
|  | 				}, &dbus.Config{ | ||||||
|  | 					// use impossible value here as an implicit assert that it goes through the stub | ||||||
|  | 					Talk: []string{"system\x00"}, Filter: true, | ||||||
|  | 				}, | ||||||
|  | 				"/tmp/hakurei.0/99dd71ee2146369514e0d10783368f8f/bus", | ||||||
|  | 				"/tmp/hakurei.0/99dd71ee2146369514e0d10783368f8f/system_bus_socket"); !reflect.DeepEqual(err, wantErr) { | ||||||
|  | 				t.Errorf("ProxyDBus: error = %v", err) | ||||||
|  | 			} else if f != nil { | ||||||
|  | 				t.Errorf("ProxyDBus: f = %p", f) | ||||||
|  | 			} | ||||||
|  | 		}, nil, stub.Expect{Calls: []stub.Call{ | ||||||
|  | 			call("dbusAddress", stub.ExpectArgs{}, [2]string{"unix:path=/run/user/1000/bus", "unix:path=/run/dbus/system_bus_socket"}, nil), | ||||||
|  | 			call("dbusFinalise", stub.ExpectArgs{ | ||||||
|  | 				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.Config{Talk: []string{"session\x00"}, Filter: true}, | ||||||
|  | 				&dbus.Config{Talk: []string{"system\x00"}, Filter: true}, | ||||||
|  | 			}, (*dbus.Final)(nil), stub.UniqueError(0)), | ||||||
|  | 		}}}, | ||||||
|  | 
 | ||||||
|  | 		{"full", 0xcafebabe, func(_ *testing.T, sys *I) { | ||||||
|  | 			sys.MustProxyDBus( | ||||||
|  | 				"/tmp/hakurei.0/99dd71ee2146369514e0d10783368f8f/bus", &dbus.Config{ | ||||||
|  | 					// use impossible value here as an implicit assert that it goes through the stub | ||||||
|  | 					Talk: []string{"session\x00"}, Filter: true, | ||||||
|  | 				}, "/tmp/hakurei.0/99dd71ee2146369514e0d10783368f8f/system_bus_socket", &dbus.Config{ | ||||||
|  | 					// use impossible value here as an implicit assert that it goes through the stub | ||||||
|  | 					Talk: []string{"system\x00"}, Filter: true, | ||||||
|  | 				}) | ||||||
|  | 		}, []Op{ | ||||||
|  | 			&DBusProxyOp{ | ||||||
|  | 				final:  dbusNewFinalSample(0), | ||||||
|  | 				system: true, | ||||||
|  | 			}, | ||||||
|  | 		}, stub.Expect{Calls: []stub.Call{ | ||||||
|  | 			call("dbusAddress", stub.ExpectArgs{}, [2]string{"unix:path=/run/user/1000/bus", "unix:path=/run/dbus/system_bus_socket"}, nil), | ||||||
|  | 			call("dbusFinalise", stub.ExpectArgs{ | ||||||
|  | 				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.Config{Talk: []string{"session\x00"}, Filter: true}, | ||||||
|  | 				&dbus.Config{Talk: []string{"system\x00"}, Filter: true}, | ||||||
|  | 			}, dbusNewFinalSample(0), 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{"system bus proxy:", []string{"unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/99dd71ee2146369514e0d10783368f8f/system_bus_socket", "--filter", "--talk=system\x00"}}}, nil, nil), | ||||||
|  | 			call("verbose", stub.ExpectArgs{[]any{"message bus proxy final args:", helper.MustNewCheckedArgs([]string{"unique", "value", "0", "injected", "by", "the", "test", "suite"})}}, nil, nil), | ||||||
|  | 		}}}, | ||||||
|  | 	}) | ||||||
|  | 
 | ||||||
|  | 	checkOpIs(t, []opIsTestCase{ | ||||||
|  | 		{"nil", (*DBusProxyOp)(nil), (*DBusProxyOp)(nil), false}, | ||||||
|  | 		{"zero", new(DBusProxyOp), new(DBusProxyOp), false}, | ||||||
|  | 
 | ||||||
|  | 		{"system differs", &DBusProxyOp{final: &dbus.Final{ | ||||||
|  | 			Session: dbus.ProxyPair{"unix:path=/run/user/1000/bus", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/bus"}, | ||||||
|  | 			System:  dbus.ProxyPair{"unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/system_bus_socket"}, | ||||||
|  | 
 | ||||||
|  | 			SessionUpstream: []dbus.AddrEntry{{Method: "unix", Values: [][2]string{{"path", "/run/user/1000/bus"}}}}, | ||||||
|  | 			SystemUpstream:  []dbus.AddrEntry{{Method: "unix", Values: [][2]string{{"unix", "/run/dbus/system_bus_socket"}}}}, | ||||||
|  | 
 | ||||||
|  | 			WriterTo: helper.MustNewCheckedArgs([]string{ | ||||||
|  | 				"--filter", "unix:path=/run/user/1000/bus", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/bus", | ||||||
|  | 				"--filter", "unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/system_bus_socket", | ||||||
|  | 			}), | ||||||
|  | 		}, system: false, | ||||||
|  | 		}, &DBusProxyOp{final: &dbus.Final{ | ||||||
|  | 			Session: dbus.ProxyPair{"unix:path=/run/user/1000/bus", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/bus"}, | ||||||
|  | 			System:  dbus.ProxyPair{"unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/system_bus_socket"}, | ||||||
|  | 
 | ||||||
|  | 			SessionUpstream: []dbus.AddrEntry{{Method: "unix", Values: [][2]string{{"path", "/run/user/1000/bus"}}}}, | ||||||
|  | 			SystemUpstream:  []dbus.AddrEntry{{Method: "unix", Values: [][2]string{{"unix", "/run/dbus/system_bus_socket"}}}}, | ||||||
|  | 
 | ||||||
|  | 			WriterTo: helper.MustNewCheckedArgs([]string{ | ||||||
|  | 				"--filter", "unix:path=/run/user/1000/bus", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/bus", | ||||||
|  | 				"--filter", "unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/system_bus_socket", | ||||||
|  | 			}), | ||||||
|  | 		}, system: true, | ||||||
|  | 		}, false}, | ||||||
|  | 
 | ||||||
|  | 		{"wt differs", &DBusProxyOp{final: &dbus.Final{ | ||||||
|  | 			Session: dbus.ProxyPair{"unix:path=/run/user/1000/bus", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/bus"}, | ||||||
|  | 			System:  dbus.ProxyPair{"unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/system_bus_socket"}, | ||||||
|  | 
 | ||||||
|  | 			SessionUpstream: []dbus.AddrEntry{{Method: "unix", Values: [][2]string{{"path", "/run/user/1000/bus"}}}}, | ||||||
|  | 			SystemUpstream:  []dbus.AddrEntry{{Method: "unix", Values: [][2]string{{"unix", "/run/dbus/system_bus_socket"}}}}, | ||||||
|  | 
 | ||||||
|  | 			WriterTo: helper.MustNewCheckedArgs([]string{ | ||||||
|  | 				"--filter", "unix:path=/run/user/1001/bus", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/bus", | ||||||
|  | 				"--filter", "unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/system_bus_socket", | ||||||
|  | 			}), | ||||||
|  | 		}, system: true, | ||||||
|  | 		}, &DBusProxyOp{final: &dbus.Final{ | ||||||
|  | 			Session: dbus.ProxyPair{"unix:path=/run/user/1000/bus", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/bus"}, | ||||||
|  | 			System:  dbus.ProxyPair{"unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/system_bus_socket"}, | ||||||
|  | 
 | ||||||
|  | 			SessionUpstream: []dbus.AddrEntry{{Method: "unix", Values: [][2]string{{"path", "/run/user/1000/bus"}}}}, | ||||||
|  | 			SystemUpstream:  []dbus.AddrEntry{{Method: "unix", Values: [][2]string{{"unix", "/run/dbus/system_bus_socket"}}}}, | ||||||
|  | 
 | ||||||
|  | 			WriterTo: helper.MustNewCheckedArgs([]string{ | ||||||
|  | 				"--filter", "unix:path=/run/user/1000/bus", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/bus", | ||||||
|  | 				"--filter", "unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/system_bus_socket", | ||||||
|  | 			}), | ||||||
|  | 		}, system: true, | ||||||
|  | 		}, false}, | ||||||
|  | 
 | ||||||
|  | 		{"final system upstream differs", &DBusProxyOp{final: &dbus.Final{ | ||||||
|  | 			Session: dbus.ProxyPair{"unix:path=/run/user/1000/bus", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/bus"}, | ||||||
|  | 			System:  dbus.ProxyPair{"unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/system_bus_socket"}, | ||||||
|  | 
 | ||||||
|  | 			SessionUpstream: []dbus.AddrEntry{{Method: "unix", Values: [][2]string{{"path", "/run/user/1000/bus"}}}}, | ||||||
|  | 			SystemUpstream:  []dbus.AddrEntry{{Method: "unix", Values: [][2]string{{"unix", "/run/dbus/system_bus_socket\x00"}}}}, | ||||||
|  | 
 | ||||||
|  | 			WriterTo: helper.MustNewCheckedArgs([]string{ | ||||||
|  | 				"--filter", "unix:path=/run/user/1000/bus", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/bus", | ||||||
|  | 				"--filter", "unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/system_bus_socket", | ||||||
|  | 			}), | ||||||
|  | 		}, system: true, | ||||||
|  | 		}, &DBusProxyOp{final: &dbus.Final{ | ||||||
|  | 			Session: dbus.ProxyPair{"unix:path=/run/user/1000/bus", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/bus"}, | ||||||
|  | 			System:  dbus.ProxyPair{"unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/system_bus_socket"}, | ||||||
|  | 
 | ||||||
|  | 			SessionUpstream: []dbus.AddrEntry{{Method: "unix", Values: [][2]string{{"path", "/run/user/1000/bus"}}}}, | ||||||
|  | 			SystemUpstream:  []dbus.AddrEntry{{Method: "unix", Values: [][2]string{{"unix", "/run/dbus/system_bus_socket"}}}}, | ||||||
|  | 
 | ||||||
|  | 			WriterTo: helper.MustNewCheckedArgs([]string{ | ||||||
|  | 				"--filter", "unix:path=/run/user/1000/bus", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/bus", | ||||||
|  | 				"--filter", "unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/system_bus_socket", | ||||||
|  | 			}), | ||||||
|  | 		}, system: true, | ||||||
|  | 		}, false}, | ||||||
|  | 
 | ||||||
|  | 		{"final session upstream differs", &DBusProxyOp{final: &dbus.Final{ | ||||||
|  | 			Session: dbus.ProxyPair{"unix:path=/run/user/1000/bus", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/bus"}, | ||||||
|  | 			System:  dbus.ProxyPair{"unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/system_bus_socket"}, | ||||||
|  | 
 | ||||||
|  | 			SessionUpstream: []dbus.AddrEntry{{Method: "unix", Values: [][2]string{{"path", "/run/user/1001/bus"}}}}, | ||||||
|  | 			SystemUpstream:  []dbus.AddrEntry{{Method: "unix", Values: [][2]string{{"unix", "/run/dbus/system_bus_socket"}}}}, | ||||||
|  | 
 | ||||||
|  | 			WriterTo: helper.MustNewCheckedArgs([]string{ | ||||||
|  | 				"--filter", "unix:path=/run/user/1000/bus", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/bus", | ||||||
|  | 				"--filter", "unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/system_bus_socket", | ||||||
|  | 			}), | ||||||
|  | 		}, system: true, | ||||||
|  | 		}, &DBusProxyOp{final: &dbus.Final{ | ||||||
|  | 			Session: dbus.ProxyPair{"unix:path=/run/user/1000/bus", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/bus"}, | ||||||
|  | 			System:  dbus.ProxyPair{"unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/system_bus_socket"}, | ||||||
|  | 
 | ||||||
|  | 			SessionUpstream: []dbus.AddrEntry{{Method: "unix", Values: [][2]string{{"path", "/run/user/1000/bus"}}}}, | ||||||
|  | 			SystemUpstream:  []dbus.AddrEntry{{Method: "unix", Values: [][2]string{{"unix", "/run/dbus/system_bus_socket"}}}}, | ||||||
|  | 
 | ||||||
|  | 			WriterTo: helper.MustNewCheckedArgs([]string{ | ||||||
|  | 				"--filter", "unix:path=/run/user/1000/bus", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/bus", | ||||||
|  | 				"--filter", "unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/system_bus_socket", | ||||||
|  | 			}), | ||||||
|  | 		}, system: true, | ||||||
|  | 		}, false}, | ||||||
|  | 
 | ||||||
|  | 		{"final system differs", &DBusProxyOp{final: &dbus.Final{ | ||||||
|  | 			Session: dbus.ProxyPair{"unix:path=/run/user/1000/bus", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/bus"}, | ||||||
|  | 			System:  dbus.ProxyPair{"unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.1/b186c281d9e83a39afdc66d964ef99c6/system_bus_socket"}, | ||||||
|  | 
 | ||||||
|  | 			SessionUpstream: []dbus.AddrEntry{{Method: "unix", Values: [][2]string{{"path", "/run/user/1000/bus"}}}}, | ||||||
|  | 			SystemUpstream:  []dbus.AddrEntry{{Method: "unix", Values: [][2]string{{"unix", "/run/dbus/system_bus_socket"}}}}, | ||||||
|  | 
 | ||||||
|  | 			WriterTo: helper.MustNewCheckedArgs([]string{ | ||||||
|  | 				"--filter", "unix:path=/run/user/1000/bus", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/bus", | ||||||
|  | 				"--filter", "unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/system_bus_socket", | ||||||
|  | 			}), | ||||||
|  | 		}, system: true, | ||||||
|  | 		}, &DBusProxyOp{final: &dbus.Final{ | ||||||
|  | 			Session: dbus.ProxyPair{"unix:path=/run/user/1000/bus", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/bus"}, | ||||||
|  | 			System:  dbus.ProxyPair{"unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/system_bus_socket"}, | ||||||
|  | 
 | ||||||
|  | 			SessionUpstream: []dbus.AddrEntry{{Method: "unix", Values: [][2]string{{"path", "/run/user/1000/bus"}}}}, | ||||||
|  | 			SystemUpstream:  []dbus.AddrEntry{{Method: "unix", Values: [][2]string{{"unix", "/run/dbus/system_bus_socket"}}}}, | ||||||
|  | 
 | ||||||
|  | 			WriterTo: helper.MustNewCheckedArgs([]string{ | ||||||
|  | 				"--filter", "unix:path=/run/user/1000/bus", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/bus", | ||||||
|  | 				"--filter", "unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/system_bus_socket", | ||||||
|  | 			}), | ||||||
|  | 		}, system: true, | ||||||
|  | 		}, false}, | ||||||
|  | 
 | ||||||
|  | 		{"final session differs", &DBusProxyOp{final: &dbus.Final{ | ||||||
|  | 			Session: dbus.ProxyPair{"unix:path=/run/user/1001/bus", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/bus"}, | ||||||
|  | 			System:  dbus.ProxyPair{"unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/system_bus_socket"}, | ||||||
|  | 
 | ||||||
|  | 			SessionUpstream: []dbus.AddrEntry{{Method: "unix", Values: [][2]string{{"path", "/run/user/1000/bus"}}}}, | ||||||
|  | 			SystemUpstream:  []dbus.AddrEntry{{Method: "unix", Values: [][2]string{{"unix", "/run/dbus/system_bus_socket"}}}}, | ||||||
|  | 
 | ||||||
|  | 			WriterTo: helper.MustNewCheckedArgs([]string{ | ||||||
|  | 				"--filter", "unix:path=/run/user/1000/bus", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/bus", | ||||||
|  | 				"--filter", "unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/system_bus_socket", | ||||||
|  | 			}), | ||||||
|  | 		}, system: true, | ||||||
|  | 		}, &DBusProxyOp{final: &dbus.Final{ | ||||||
|  | 			Session: dbus.ProxyPair{"unix:path=/run/user/1000/bus", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/bus"}, | ||||||
|  | 			System:  dbus.ProxyPair{"unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/system_bus_socket"}, | ||||||
|  | 
 | ||||||
|  | 			SessionUpstream: []dbus.AddrEntry{{Method: "unix", Values: [][2]string{{"path", "/run/user/1000/bus"}}}}, | ||||||
|  | 			SystemUpstream:  []dbus.AddrEntry{{Method: "unix", Values: [][2]string{{"unix", "/run/dbus/system_bus_socket"}}}}, | ||||||
|  | 
 | ||||||
|  | 			WriterTo: helper.MustNewCheckedArgs([]string{ | ||||||
|  | 				"--filter", "unix:path=/run/user/1000/bus", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/bus", | ||||||
|  | 				"--filter", "unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/system_bus_socket", | ||||||
|  | 			}), | ||||||
|  | 		}, system: true, | ||||||
|  | 		}, false}, | ||||||
|  | 
 | ||||||
|  | 		{"equals", &DBusProxyOp{final: &dbus.Final{ | ||||||
|  | 			Session: dbus.ProxyPair{"unix:path=/run/user/1000/bus", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/bus"}, | ||||||
|  | 			System:  dbus.ProxyPair{"unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/system_bus_socket"}, | ||||||
|  | 
 | ||||||
|  | 			SessionUpstream: []dbus.AddrEntry{{Method: "unix", Values: [][2]string{{"path", "/run/user/1000/bus"}}}}, | ||||||
|  | 			SystemUpstream:  []dbus.AddrEntry{{Method: "unix", Values: [][2]string{{"unix", "/run/dbus/system_bus_socket"}}}}, | ||||||
|  | 
 | ||||||
|  | 			WriterTo: helper.MustNewCheckedArgs([]string{ | ||||||
|  | 				"--filter", "unix:path=/run/user/1000/bus", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/bus", | ||||||
|  | 				"--filter", "unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/system_bus_socket", | ||||||
|  | 			}), | ||||||
|  | 		}, system: true, | ||||||
|  | 		}, &DBusProxyOp{final: &dbus.Final{ | ||||||
|  | 			Session: dbus.ProxyPair{"unix:path=/run/user/1000/bus", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/bus"}, | ||||||
|  | 			System:  dbus.ProxyPair{"unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/system_bus_socket"}, | ||||||
|  | 
 | ||||||
|  | 			SessionUpstream: []dbus.AddrEntry{{Method: "unix", Values: [][2]string{{"path", "/run/user/1000/bus"}}}}, | ||||||
|  | 			SystemUpstream:  []dbus.AddrEntry{{Method: "unix", Values: [][2]string{{"unix", "/run/dbus/system_bus_socket"}}}}, | ||||||
|  | 
 | ||||||
|  | 			WriterTo: helper.MustNewCheckedArgs([]string{ | ||||||
|  | 				"--filter", "unix:path=/run/user/1000/bus", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/bus", | ||||||
|  | 				"--filter", "unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/system_bus_socket", | ||||||
|  | 			}), | ||||||
|  | 		}, system: true, | ||||||
|  | 		}, true}, | ||||||
|  | 	}) | ||||||
|  | 
 | ||||||
|  | 	checkOpMeta(t, []opMetaTestCase{ | ||||||
|  | 		{"dbus", new(DBusProxyOp), | ||||||
|  | 			Process, "/proc/nonexistent", | ||||||
|  | 			"(invalid dbus proxy)"}, | ||||||
|  | 	}) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func dbusNewFinalSample(v int) *dbus.Final { | ||||||
|  | 	return &dbus.Final{ | ||||||
|  | 		Session: dbus.ProxyPair{"unix:path=/run/user/1000/bus", "/tmp/hakurei.0/99dd71ee2146369514e0d10783368f8f/bus"}, | ||||||
|  | 		System:  dbus.ProxyPair{"unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/99dd71ee2146369514e0d10783368f8f/system_bus_socket"}, | ||||||
|  | 
 | ||||||
|  | 		SessionUpstream: []dbus.AddrEntry{{Method: "unix", Values: [][2]string{{"path", "/run/user/1000/bus"}}}}, | ||||||
|  | 		SystemUpstream:  []dbus.AddrEntry{{Method: "unix", Values: [][2]string{{"path", "/run/dbus/system_bus_socket"}}}}, | ||||||
|  | 
 | ||||||
|  | 		WriterTo: helper.MustNewCheckedArgs([]string{"unique", "value", strconv.Itoa(v), "injected", "by", "the", "test", "suite"}), | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func TestLinePrefixWriter(t *testing.T) { | func TestLinePrefixWriter(t *testing.T) { | ||||||
| 	testCases := []struct { | 	testCases := []struct { | ||||||
| 		name    string | 		name    string | ||||||
|  | |||||||
| @ -1,6 +1,9 @@ | |||||||
| package system | package system | ||||||
| 
 | 
 | ||||||
| import "hakurei.app/system/acl" | import ( | ||||||
|  | 	"hakurei.app/system/acl" | ||||||
|  | 	"hakurei.app/system/dbus" | ||||||
|  | ) | ||||||
| 
 | 
 | ||||||
| // syscallDispatcher provides methods that make state-dependent system calls as part of their behaviour. | // syscallDispatcher provides methods that make state-dependent system calls as part of their behaviour. | ||||||
| // syscallDispatcher is embedded in [I], so all methods must be unexported. | // syscallDispatcher is embedded in [I], so all methods must be unexported. | ||||||
| @ -13,6 +16,18 @@ type syscallDispatcher interface { | |||||||
| 	// aclUpdate provides [acl.Update]. | 	// aclUpdate provides [acl.Update]. | ||||||
| 	aclUpdate(name string, uid int, perms ...acl.Perm) error | 	aclUpdate(name string, uid int, perms ...acl.Perm) error | ||||||
| 
 | 
 | ||||||
|  | 	// dbusAddress provides [dbus.Address]. | ||||||
|  | 	dbusAddress() (session, system string) | ||||||
|  | 	// dbusFinalise provides [dbus.Finalise]. | ||||||
|  | 	dbusFinalise(sessionBus, systemBus dbus.ProxyPair, session, system *dbus.Config) (final *dbus.Final, err error) | ||||||
|  | 	// dbusProxyStart provides the Start method of [dbus.Proxy]. | ||||||
|  | 	dbusProxyStart(proxy *dbus.Proxy) error | ||||||
|  | 	// dbusProxyClose provides the Close method of [dbus.Proxy]. | ||||||
|  | 	dbusProxyClose(proxy *dbus.Proxy) | ||||||
|  | 	// dbusProxyWait provides the Wait method of [dbus.Proxy]. | ||||||
|  | 	dbusProxyWait(proxy *dbus.Proxy) error | ||||||
|  | 
 | ||||||
|  | 	isVerbose() bool | ||||||
| 	verbose(v ...any) | 	verbose(v ...any) | ||||||
| 	verbosef(format string, v ...any) | 	verbosef(format string, v ...any) | ||||||
| } | } | ||||||
| @ -26,5 +41,18 @@ func (k direct) aclUpdate(name string, uid int, perms ...acl.Perm) error { | |||||||
| 	return acl.Update(name, uid, perms...) | 	return acl.Update(name, uid, perms...) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func (k direct) dbusAddress() (session, system string) { | ||||||
|  | 	return dbus.Address() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (k direct) dbusFinalise(sessionBus, systemBus dbus.ProxyPair, session, system *dbus.Config) (final *dbus.Final, err error) { | ||||||
|  | 	return dbus.Finalise(sessionBus, systemBus, session, system) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (k direct) dbusProxyStart(proxy *dbus.Proxy) error { return proxy.Start() } | ||||||
|  | func (k direct) dbusProxyClose(proxy *dbus.Proxy)       { proxy.Close() } | ||||||
|  | func (k direct) dbusProxyWait(proxy *dbus.Proxy) error  { return proxy.Wait() } | ||||||
|  | 
 | ||||||
|  | func (k direct) isVerbose() bool                { return msg.IsVerbose() } | ||||||
| func (direct) verbose(v ...any)                 { msg.Verbose(v...) } | func (direct) verbose(v ...any)                 { msg.Verbose(v...) } | ||||||
| func (direct) verbosef(format string, v ...any) { msg.Verbosef(format, v...) } | func (direct) verbosef(format string, v ...any) { msg.Verbosef(format, v...) } | ||||||
|  | |||||||
| @ -1,12 +1,15 @@ | |||||||
| package system | package system | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
|  | 	"os" | ||||||
| 	"reflect" | 	"reflect" | ||||||
| 	"slices" | 	"slices" | ||||||
| 	"testing" | 	"testing" | ||||||
|  | 	"unsafe" | ||||||
| 
 | 
 | ||||||
| 	"hakurei.app/container/stub" | 	"hakurei.app/container/stub" | ||||||
| 	"hakurei.app/system/acl" | 	"hakurei.app/system/acl" | ||||||
|  | 	"hakurei.app/system/dbus" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // call initialises a [stub.Call]. | // call initialises a [stub.Call]. | ||||||
| @ -197,9 +200,85 @@ func (k *kstub) aclUpdate(name string, uid int, perms ...acl.Perm) error { | |||||||
| 		stub.CheckArgReflect(k.Stub, "perms", perms, 2)) | 		stub.CheckArgReflect(k.Stub, "perms", perms, 2)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func (k *kstub) dbusAddress() (session, system string) { | ||||||
|  | 	k.Helper() | ||||||
|  | 	ret := k.Expects("dbusAddress").Ret.([2]string) | ||||||
|  | 	return ret[0], ret[1] | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (k *kstub) dbusFinalise(sessionBus, systemBus dbus.ProxyPair, session, system *dbus.Config) (final *dbus.Final, err error) { | ||||||
|  | 	k.Helper() | ||||||
|  | 	expect := k.Expects("dbusFinalise") | ||||||
|  | 
 | ||||||
|  | 	final = expect.Ret.(*dbus.Final) | ||||||
|  | 	err = expect.Error( | ||||||
|  | 		stub.CheckArg(k.Stub, "sessionBus", sessionBus, 0), | ||||||
|  | 		stub.CheckArg(k.Stub, "systemBus", systemBus, 1), | ||||||
|  | 		stub.CheckArgReflect(k.Stub, "session", session, 2), | ||||||
|  | 		stub.CheckArgReflect(k.Stub, "system", system, 3)) | ||||||
|  | 	if err != nil { | ||||||
|  | 		final = nil | ||||||
|  | 	} | ||||||
|  | 	return | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (k *kstub) dbusProxyStart(proxy *dbus.Proxy) error { | ||||||
|  | 	k.Helper() | ||||||
|  | 	return k.dbusProxySCW(k.Expects("dbusProxyStart"), proxy) | ||||||
|  | } | ||||||
|  | func (k *kstub) dbusProxyClose(proxy *dbus.Proxy) { | ||||||
|  | 	k.Helper() | ||||||
|  | 	if k.dbusProxySCW(k.Expects("dbusProxyClose"), proxy) != nil { | ||||||
|  | 		k.Fail() | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | func (k *kstub) dbusProxyWait(proxy *dbus.Proxy) error { | ||||||
|  | 	k.Helper() | ||||||
|  | 	return k.dbusProxySCW(k.Expects("dbusProxyWait"), proxy) | ||||||
|  | } | ||||||
|  | func (k *kstub) dbusProxySCW(expect *stub.Call, proxy *dbus.Proxy) error { | ||||||
|  | 	k.Helper() | ||||||
|  | 	v := reflect.ValueOf(proxy).Elem() | ||||||
|  | 
 | ||||||
|  | 	if ctxV := v.FieldByName("ctx"); ctxV.IsNil() { | ||||||
|  | 		k.Errorf("proxy: ctx = %s", ctxV.String()) | ||||||
|  | 		return os.ErrInvalid | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	finalV := v.FieldByName("final") | ||||||
|  | 	if gotFinal := reflect.NewAt(finalV.Type(), unsafe.Pointer(finalV.UnsafeAddr())).Elem().Interface().(*dbus.Final); !reflect.DeepEqual(gotFinal, expect.Args[0]) { | ||||||
|  | 		k.Errorf("proxy: final = %#v, want %#v", gotFinal, expect.Args[0]) | ||||||
|  | 		return os.ErrInvalid | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	outputV := v.FieldByName("output") | ||||||
|  | 	if _, ok := reflect.NewAt(outputV.Type(), unsafe.Pointer(outputV.UnsafeAddr())).Elem().Interface().(*linePrefixWriter); !ok { | ||||||
|  | 		k.Errorf("proxy: output = %s", outputV.String()) | ||||||
|  | 		return os.ErrInvalid | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return expect.Err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (k *kstub) isVerbose() bool { k.Helper(); return k.Expects("isVerbose").Ret.(bool) } | ||||||
|  | 
 | ||||||
|  | // ignoreValue marks a value to be ignored by the test suite. | ||||||
|  | type ignoreValue struct{} | ||||||
|  | 
 | ||||||
| func (k *kstub) verbose(v ...any) { | func (k *kstub) verbose(v ...any) { | ||||||
| 	k.Helper() | 	k.Helper() | ||||||
| 	if k.Expects("verbose").Error( | 	expect := k.Expects("verbose") | ||||||
|  | 
 | ||||||
|  | 	// translate ignores in v | ||||||
|  | 	if want, ok := expect.Args[0].([]any); ok && len(v) == len(want) { | ||||||
|  | 		for i, a := range want { | ||||||
|  | 			if _, ok = a.(ignoreValue); ok { | ||||||
|  | 				v[i] = ignoreValue{} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if expect.Error( | ||||||
| 		stub.CheckArgReflect(k.Stub, "v", v, 0)) != nil { | 		stub.CheckArgReflect(k.Stub, "v", v, 0)) != nil { | ||||||
| 		k.FailNow() | 		k.FailNow() | ||||||
| 	} | 	} | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user