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 | ||||
| 
 | ||||
| 	var sessionBus, systemBus dbus.ProxyPair | ||||
| 	sessionBus[0], systemBus[0] = dbus.Address() | ||||
| 	sessionBus[0], systemBus[0] = sys.dbusAddress() | ||||
| 	sessionBus[1], systemBus[1] = sessionPath, systemPath | ||||
| 	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) { | ||||
| 			return nil, newOpErrorMessage("dbus", err, | ||||
| 				"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, | ||||
| 			fmt.Sprintf("cannot finalise message bus proxy: %v", err), false) | ||||
| 	} else { | ||||
| 		if msg.IsVerbose() { | ||||
| 			msg.Verbose("session bus proxy:", session.Args(sessionBus)) | ||||
| 		if sys.isVerbose() { | ||||
| 			sys.verbose("session bus proxy:", session.Args(sessionBus)) | ||||
| 			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 | ||||
| 			msg.Verbose("message bus proxy final args:", final.WriterTo) | ||||
| 			sys.verbose("message bus proxy final args:", final.WriterTo) | ||||
| 		} | ||||
| 
 | ||||
| 		d.final = final | ||||
| @ -85,29 +85,32 @@ type DBusProxyOp struct { | ||||
| func (d *DBusProxyOp) Type() Enablement { return Process } | ||||
| 
 | ||||
| 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 { | ||||
| 		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) | ||||
| 	if err := d.proxy.Start(); err != nil { | ||||
| 	if err := sys.dbusProxyStart(d.proxy); err != nil { | ||||
| 		d.out.Dump() | ||||
| 		return newOpErrorMessage("dbus", err, | ||||
| 			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 | ||||
| } | ||||
| 
 | ||||
| func (d *DBusProxyOp) revert(*I, *Criteria) error { | ||||
| func (d *DBusProxyOp) revert(sys *I, _ *Criteria) error { | ||||
| 	// criteria ignored here since dbus is always process-scoped | ||||
| 	msg.Verbose("terminating message bus proxy") | ||||
| 	d.proxy.Close() | ||||
| 	defer msg.Verbose("message bus proxy exit") | ||||
| 	err := d.proxy.Wait() | ||||
| 	sys.verbose("terminating message bus proxy") | ||||
| 	sys.dbusProxyClose(d.proxy) | ||||
| 
 | ||||
| 	exitMessage := "message bus proxy exit" | ||||
| 	defer func() { sys.verbose(exitMessage) }() | ||||
| 
 | ||||
| 	err := sys.dbusProxyWait(d.proxy) | ||||
| 	if errors.Is(err, context.Canceled) { | ||||
| 		msg.Verbose("message bus proxy canceled upstream") | ||||
| 		exitMessage = "message bus proxy canceled upstream" | ||||
| 		err = nil | ||||
| 	} | ||||
| 	return newOpErrorMessage("dbus", err, | ||||
|  | ||||
| @ -1,13 +1,384 @@ | ||||
| package system | ||||
| 
 | ||||
| import ( | ||||
| 	"context" | ||||
| 	"reflect" | ||||
| 	"slices" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| 	"syscall" | ||||
| 	"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) { | ||||
| 	testCases := []struct { | ||||
| 		name    string | ||||
|  | ||||
| @ -1,6 +1,9 @@ | ||||
| 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 is embedded in [I], so all methods must be unexported. | ||||
| @ -13,6 +16,18 @@ type syscallDispatcher interface { | ||||
| 	// aclUpdate provides [acl.Update]. | ||||
| 	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) | ||||
| 	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...) | ||||
| } | ||||
| 
 | ||||
| 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) verbosef(format string, v ...any) { msg.Verbosef(format, v...) } | ||||
|  | ||||
| @ -1,12 +1,15 @@ | ||||
| package system | ||||
| 
 | ||||
| import ( | ||||
| 	"os" | ||||
| 	"reflect" | ||||
| 	"slices" | ||||
| 	"testing" | ||||
| 	"unsafe" | ||||
| 
 | ||||
| 	"hakurei.app/container/stub" | ||||
| 	"hakurei.app/system/acl" | ||||
| 	"hakurei.app/system/dbus" | ||||
| ) | ||||
| 
 | ||||
| // 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)) | ||||
| } | ||||
| 
 | ||||
| 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) { | ||||
| 	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 { | ||||
| 		k.FailNow() | ||||
| 	} | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user