internal/env: relocate from app
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				Test / Create distribution (push) Successful in 32s
				
			
		
			
				
	
				Test / Sandbox (push) Successful in 2m8s
				
			
		
			
				
	
				Test / Hakurei (push) Successful in 3m10s
				
			
		
			
				
	
				Test / Hpkg (push) Successful in 4m1s
				
			
		
			
				
	
				Test / Sandbox (race detector) (push) Successful in 4m7s
				
			
		
			
				
	
				Test / Hakurei (race detector) (push) Successful in 4m53s
				
			
		
			
				
	
				Test / Flake checks (push) Successful in 1m27s
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	Test / Create distribution (push) Successful in 32s
				
			Test / Sandbox (push) Successful in 2m8s
				
			Test / Hakurei (push) Successful in 3m10s
				
			Test / Hpkg (push) Successful in 4m1s
				
			Test / Sandbox (race detector) (push) Successful in 4m7s
				
			Test / Hakurei (race detector) (push) Successful in 4m53s
				
			Test / Flake checks (push) Successful in 1m27s
				
			This package is much cleaner to stub independently, and makes no sense to lump into app. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
		
							parent
							
								
									274686d10d
								
							
						
					
					
						commit
						a52f7038e5
					
				| @ -20,6 +20,7 @@ import ( | |||||||
| 	"hakurei.app/internal" | 	"hakurei.app/internal" | ||||||
| 	"hakurei.app/internal/app" | 	"hakurei.app/internal/app" | ||||||
| 	"hakurei.app/internal/app/state" | 	"hakurei.app/internal/app/state" | ||||||
|  | 	"hakurei.app/internal/env" | ||||||
| 	"hakurei.app/message" | 	"hakurei.app/message" | ||||||
| 	"hakurei.app/system/dbus" | 	"hakurei.app/system/dbus" | ||||||
| ) | ) | ||||||
| @ -320,7 +321,7 @@ func buildCommand(ctx context.Context, msg message.Msg, early *earlyHardeningErr | |||||||
| 		var flagShort bool | 		var flagShort bool | ||||||
| 		c.NewCommand("ps", "List active instances", func(args []string) error { | 		c.NewCommand("ps", "List active instances", func(args []string) error { | ||||||
| 			var sc hst.Paths | 			var sc hst.Paths | ||||||
| 			app.CopyPaths().Copy(&sc, new(app.Hsu).MustID(nil)) | 			env.CopyPaths().Copy(&sc, new(app.Hsu).MustID(nil)) | ||||||
| 			printPs(os.Stdout, time.Now().UTC(), state.NewMulti(msg, sc.RunDirPath), flagShort, flagJSON) | 			printPs(os.Stdout, time.Now().UTC(), state.NewMulti(msg, sc.RunDirPath), flagShort, flagJSON) | ||||||
| 			return errSuccess | 			return errSuccess | ||||||
| 		}).Flag(&flagShort, "short", command.BoolFlag(false), "Print instance id") | 		}).Flag(&flagShort, "short", command.BoolFlag(false), "Print instance id") | ||||||
|  | |||||||
| @ -13,6 +13,7 @@ import ( | |||||||
| 	"hakurei.app/hst" | 	"hakurei.app/hst" | ||||||
| 	"hakurei.app/internal/app" | 	"hakurei.app/internal/app" | ||||||
| 	"hakurei.app/internal/app/state" | 	"hakurei.app/internal/app/state" | ||||||
|  | 	"hakurei.app/internal/env" | ||||||
| 	"hakurei.app/message" | 	"hakurei.app/message" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| @ -83,7 +84,7 @@ func shortIdentifierString(s string) string { | |||||||
| func tryIdentifier(msg message.Msg, name string) (config *hst.Config, entry *hst.State) { | func tryIdentifier(msg message.Msg, name string) (config *hst.Config, entry *hst.State) { | ||||||
| 	return tryIdentifierEntries(msg, name, func() map[hst.ID]*hst.State { | 	return tryIdentifierEntries(msg, name, func() map[hst.ID]*hst.State { | ||||||
| 		var sc hst.Paths | 		var sc hst.Paths | ||||||
| 		app.CopyPaths().Copy(&sc, new(app.Hsu).MustID(nil)) | 		env.CopyPaths().Copy(&sc, new(app.Hsu).MustID(nil)) | ||||||
| 		s := state.NewMulti(msg, sc.RunDirPath) | 		s := state.NewMulti(msg, sc.RunDirPath) | ||||||
| 		if entries, err := state.Join(s); err != nil { | 		if entries, err := state.Join(s); err != nil { | ||||||
| 			msg.GetLogger().Printf("cannot join store: %v", err) // not fatal | 			msg.GetLogger().Printf("cannot join store: %v", err) // not fatal | ||||||
|  | |||||||
| @ -14,6 +14,7 @@ import ( | |||||||
| 	"hakurei.app/internal" | 	"hakurei.app/internal" | ||||||
| 	"hakurei.app/internal/app" | 	"hakurei.app/internal/app" | ||||||
| 	"hakurei.app/internal/app/state" | 	"hakurei.app/internal/app/state" | ||||||
|  | 	"hakurei.app/internal/env" | ||||||
| 	"hakurei.app/message" | 	"hakurei.app/message" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| @ -23,7 +24,7 @@ func printShowSystem(output io.Writer, short, flagJSON bool) { | |||||||
| 	defer t.MustFlush() | 	defer t.MustFlush() | ||||||
| 
 | 
 | ||||||
| 	info := &hst.Info{Version: internal.Version(), User: new(app.Hsu).MustID(nil)} | 	info := &hst.Info{Version: internal.Version(), User: new(app.Hsu).MustID(nil)} | ||||||
| 	app.CopyPaths().Copy(&info.Paths, info.User) | 	env.CopyPaths().Copy(&info.Paths, info.User) | ||||||
| 
 | 
 | ||||||
| 	if flagJSON { | 	if flagJSON { | ||||||
| 		encodeJSON(log.Fatal, output, short, info) | 		encodeJSON(log.Fatal, output, short, info) | ||||||
|  | |||||||
| @ -1,59 +0,0 @@ | |||||||
| package app |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"strconv" |  | ||||||
| 
 |  | ||||||
| 	"hakurei.app/container/check" |  | ||||||
| 	"hakurei.app/hst" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // EnvPaths holds paths copied from the environment and is used to create [hst.Paths]. |  | ||||||
| type EnvPaths struct { |  | ||||||
| 	// TempDir is returned by [os.TempDir]. |  | ||||||
| 	TempDir *check.Absolute |  | ||||||
| 	// RuntimePath is copied from $XDG_RUNTIME_DIR. |  | ||||||
| 	RuntimePath *check.Absolute |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Copy expands [EnvPaths] into [hst.Paths]. |  | ||||||
| func (env *EnvPaths) Copy(v *hst.Paths, userid int) { |  | ||||||
| 	if env == nil || env.TempDir == nil || v == nil { |  | ||||||
| 		panic("attempting to use an invalid EnvPaths") |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	v.TempDir = env.TempDir |  | ||||||
| 	v.SharePath = env.TempDir.Append("hakurei." + strconv.Itoa(userid)) |  | ||||||
| 
 |  | ||||||
| 	if env.RuntimePath == nil { |  | ||||||
| 		// fall back to path in share since hakurei has no hard XDG dependency |  | ||||||
| 		v.RunDirPath = v.SharePath.Append("run") |  | ||||||
| 		v.RuntimePath = v.RunDirPath.Append("compat") |  | ||||||
| 	} else { |  | ||||||
| 		v.RuntimePath = env.RuntimePath |  | ||||||
| 		v.RunDirPath = env.RuntimePath.Append("hakurei") |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // CopyPaths returns a populated [EnvPaths]. |  | ||||||
| func CopyPaths() *EnvPaths { return copyPaths(direct{}) } |  | ||||||
| 
 |  | ||||||
| // copyPaths returns a populated [EnvPaths]. |  | ||||||
| func copyPaths(k syscallDispatcher) *EnvPaths { |  | ||||||
| 	const xdgRuntimeDir = "XDG_RUNTIME_DIR" |  | ||||||
| 
 |  | ||||||
| 	var env EnvPaths |  | ||||||
| 
 |  | ||||||
| 	if tempDir, err := check.NewAbs(k.tempdir()); err != nil { |  | ||||||
| 		k.fatalf("invalid TMPDIR: %v", err) |  | ||||||
| 		panic("unreachable") |  | ||||||
| 	} else { |  | ||||||
| 		env.TempDir = tempDir |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	r, _ := k.lookupEnv(xdgRuntimeDir) |  | ||||||
| 	if a, err := check.NewAbs(r); err == nil { |  | ||||||
| 		env.RuntimePath = a |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return &env |  | ||||||
| } |  | ||||||
| @ -8,6 +8,7 @@ import ( | |||||||
| 	"hakurei.app/container" | 	"hakurei.app/container" | ||||||
| 	"hakurei.app/container/check" | 	"hakurei.app/container/check" | ||||||
| 	"hakurei.app/hst" | 	"hakurei.app/hst" | ||||||
|  | 	"hakurei.app/internal/env" | ||||||
| 	"hakurei.app/message" | 	"hakurei.app/message" | ||||||
| 	"hakurei.app/system" | 	"hakurei.app/system" | ||||||
| 	"hakurei.app/system/acl" | 	"hakurei.app/system/acl" | ||||||
| @ -58,7 +59,7 @@ type outcomeState struct { | |||||||
| 
 | 
 | ||||||
| 	// Copied from [EnvPaths] per-process. | 	// Copied from [EnvPaths] per-process. | ||||||
| 	sc hst.Paths | 	sc hst.Paths | ||||||
| 	*EnvPaths | 	*env.Paths | ||||||
| 
 | 
 | ||||||
| 	// Copied via populateLocal. | 	// Copied via populateLocal. | ||||||
| 	k syscallDispatcher | 	k syscallDispatcher | ||||||
| @ -72,7 +73,7 @@ func (s *outcomeState) valid() bool { | |||||||
| 		s.Shim.valid() && | 		s.Shim.valid() && | ||||||
| 		s.ID != nil && | 		s.ID != nil && | ||||||
| 		s.Container != nil && | 		s.Container != nil && | ||||||
| 		s.EnvPaths != nil | 		s.Paths != nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // newOutcomeState returns the address of a new outcomeState with its exported fields populated via syscallDispatcher. | // newOutcomeState returns the address of a new outcomeState with its exported fields populated via syscallDispatcher. | ||||||
| @ -82,7 +83,7 @@ func newOutcomeState(k syscallDispatcher, msg message.Msg, id *hst.ID, config *h | |||||||
| 		ID:        id, | 		ID:        id, | ||||||
| 		Identity:  config.Identity, | 		Identity:  config.Identity, | ||||||
| 		UserID:    hsu.MustID(msg), | 		UserID:    hsu.MustID(msg), | ||||||
| 		EnvPaths:  copyPaths(k), | 		Paths:     env.CopyPathsFunc(k.fatalf, k.tempdir, func(key string) string { v, _ := k.lookupEnv(key); return v }), | ||||||
| 		Container: config.Container, | 		Container: config.Container, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -4,6 +4,7 @@ import ( | |||||||
| 	"testing" | 	"testing" | ||||||
| 
 | 
 | ||||||
| 	"hakurei.app/hst" | 	"hakurei.app/hst" | ||||||
|  | 	"hakurei.app/internal/env" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func TestOutcomeStateValid(t *testing.T) { | func TestOutcomeStateValid(t *testing.T) { | ||||||
| @ -16,11 +17,11 @@ func TestOutcomeStateValid(t *testing.T) { | |||||||
| 	}{ | 	}{ | ||||||
| 		{"nil", nil, false}, | 		{"nil", nil, false}, | ||||||
| 		{"zero", new(outcomeState), false}, | 		{"zero", new(outcomeState), false}, | ||||||
| 		{"shim", &outcomeState{Shim: &shimParams{PrivPID: -1, Ops: []outcomeOp{}}, Container: new(hst.ContainerConfig), EnvPaths: new(EnvPaths)}, false}, | 		{"shim", &outcomeState{Shim: &shimParams{PrivPID: -1, Ops: []outcomeOp{}}, Container: new(hst.ContainerConfig), Paths: new(env.Paths)}, false}, | ||||||
| 		{"id", &outcomeState{Shim: &shimParams{PrivPID: 1, Ops: []outcomeOp{}}, Container: new(hst.ContainerConfig), EnvPaths: new(EnvPaths)}, false}, | 		{"id", &outcomeState{Shim: &shimParams{PrivPID: 1, Ops: []outcomeOp{}}, Container: new(hst.ContainerConfig), Paths: new(env.Paths)}, false}, | ||||||
| 		{"container", &outcomeState{Shim: &shimParams{PrivPID: 1, Ops: []outcomeOp{}}, ID: new(hst.ID), EnvPaths: new(EnvPaths)}, false}, | 		{"container", &outcomeState{Shim: &shimParams{PrivPID: 1, Ops: []outcomeOp{}}, ID: new(hst.ID), Paths: new(env.Paths)}, false}, | ||||||
| 		{"envpaths", &outcomeState{Shim: &shimParams{PrivPID: 1, Ops: []outcomeOp{}}, ID: new(hst.ID), Container: new(hst.ContainerConfig)}, false}, | 		{"envpaths", &outcomeState{Shim: &shimParams{PrivPID: 1, Ops: []outcomeOp{}}, ID: new(hst.ID), Container: new(hst.ContainerConfig)}, false}, | ||||||
| 		{"valid", &outcomeState{Shim: &shimParams{PrivPID: 1, Ops: []outcomeOp{}}, ID: new(hst.ID), Container: new(hst.ContainerConfig), EnvPaths: new(EnvPaths)}, true}, | 		{"valid", &outcomeState{Shim: &shimParams{PrivPID: 1, Ops: []outcomeOp{}}, ID: new(hst.ID), Container: new(hst.ContainerConfig), Paths: new(env.Paths)}, true}, | ||||||
| 	} | 	} | ||||||
| 	for _, tc := range testCases { | 	for _, tc := range testCases { | ||||||
| 		t.Run(tc.name, func(t *testing.T) { | 		t.Run(tc.name, func(t *testing.T) { | ||||||
|  | |||||||
| @ -14,6 +14,7 @@ import ( | |||||||
| 	"hakurei.app/container/seccomp" | 	"hakurei.app/container/seccomp" | ||||||
| 	"hakurei.app/container/stub" | 	"hakurei.app/container/stub" | ||||||
| 	"hakurei.app/hst" | 	"hakurei.app/hst" | ||||||
|  | 	"hakurei.app/internal/env" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func TestShimEntrypoint(t *testing.T) { | func TestShimEntrypoint(t *testing.T) { | ||||||
| @ -128,7 +129,7 @@ func TestShimEntrypoint(t *testing.T) { | |||||||
| 				Container: hst.Template().Container, | 				Container: hst.Template().Container, | ||||||
| 				Mapuid:    1000, | 				Mapuid:    1000, | ||||||
| 				Mapgid:    100, | 				Mapgid:    100, | ||||||
| 				EnvPaths:  &EnvPaths{TempDir: fhs.AbsTmp, RuntimePath: fhs.AbsRunUser.Append("1000")}, | 				Paths:     &env.Paths{TempDir: fhs.AbsTmp, RuntimePath: fhs.AbsRunUser.Append("1000")}, | ||||||
| 			}, nil}, nil, nil), | 			}, nil}, nil, nil), | ||||||
| 			call("swapVerbose", stub.ExpectArgs{true}, false, nil), | 			call("swapVerbose", stub.ExpectArgs{true}, false, nil), | ||||||
| 			call("verbosef", stub.ExpectArgs{"process share directory at %q, runtime directory at %q", []any{m("/tmp/hakurei.10"), m("/run/user/1000/hakurei")}}, nil, nil), | 			call("verbosef", stub.ExpectArgs{"process share directory at %q, runtime directory at %q", []any{m("/tmp/hakurei.10"), m("/run/user/1000/hakurei")}}, nil, nil), | ||||||
|  | |||||||
							
								
								
									
										66
									
								
								internal/env/env.go
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								internal/env/env.go
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,66 @@ | |||||||
|  | // Package env provides the [Paths] struct for efficiently building paths from the environment. | ||||||
|  | package env | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"log" | ||||||
|  | 	"os" | ||||||
|  | 	"strconv" | ||||||
|  | 
 | ||||||
|  | 	"hakurei.app/container/check" | ||||||
|  | 	"hakurei.app/hst" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Paths holds paths copied from the environment and is used to create [hst.Paths]. | ||||||
|  | type Paths struct { | ||||||
|  | 	// TempDir is returned by [os.TempDir]. | ||||||
|  | 	TempDir *check.Absolute | ||||||
|  | 	// RuntimePath is copied from $XDG_RUNTIME_DIR. | ||||||
|  | 	RuntimePath *check.Absolute | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Copy expands [Paths] into [hst.Paths]. | ||||||
|  | func (env *Paths) Copy(v *hst.Paths, userid int) { | ||||||
|  | 	if env == nil || env.TempDir == nil || v == nil { | ||||||
|  | 		panic("attempting to use an invalid Paths") | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	v.TempDir = env.TempDir | ||||||
|  | 	v.SharePath = env.TempDir.Append("hakurei." + strconv.Itoa(userid)) | ||||||
|  | 
 | ||||||
|  | 	if env.RuntimePath == nil { | ||||||
|  | 		// fall back to path in share since hakurei has no hard XDG dependency | ||||||
|  | 		v.RunDirPath = v.SharePath.Append("run") | ||||||
|  | 		v.RuntimePath = v.RunDirPath.Append("compat") | ||||||
|  | 	} else { | ||||||
|  | 		v.RuntimePath = env.RuntimePath | ||||||
|  | 		v.RunDirPath = env.RuntimePath.Append("hakurei") | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // CopyPaths returns a populated [Paths]. | ||||||
|  | func CopyPaths() *Paths { return CopyPathsFunc(log.Fatalf, os.TempDir, os.Getenv) } | ||||||
|  | 
 | ||||||
|  | // CopyPathsFunc returns a populated [Paths], | ||||||
|  | // using the provided [log.Fatalf], [os.TempDir], [os.Getenv] functions. | ||||||
|  | func CopyPathsFunc( | ||||||
|  | 	fatalf func(format string, v ...any), | ||||||
|  | 	tempdir func() string, | ||||||
|  | 	getenv func(key string) string, | ||||||
|  | ) *Paths { | ||||||
|  | 	const xdgRuntimeDir = "XDG_RUNTIME_DIR" | ||||||
|  | 
 | ||||||
|  | 	var env Paths | ||||||
|  | 
 | ||||||
|  | 	if tempDir, err := check.NewAbs(tempdir()); err != nil { | ||||||
|  | 		fatalf("invalid TMPDIR: %v", err) | ||||||
|  | 		panic("unreachable") | ||||||
|  | 	} else { | ||||||
|  | 		env.TempDir = tempDir | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if a, err := check.NewAbs(getenv(xdgRuntimeDir)); err == nil { | ||||||
|  | 		env.RuntimePath = a | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return &env | ||||||
|  | } | ||||||
| @ -1,4 +1,4 @@ | |||||||
| package app | package env_test | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
| @ -10,26 +10,27 @@ import ( | |||||||
| 	"hakurei.app/container/fhs" | 	"hakurei.app/container/fhs" | ||||||
| 	"hakurei.app/container/stub" | 	"hakurei.app/container/stub" | ||||||
| 	"hakurei.app/hst" | 	"hakurei.app/hst" | ||||||
|  | 	"hakurei.app/internal/env" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func TestEnvPaths(t *testing.T) { | func TestPaths(t *testing.T) { | ||||||
| 	t.Parallel() | 	t.Parallel() | ||||||
| 
 | 
 | ||||||
| 	testCases := []struct { | 	testCases := []struct { | ||||||
| 		name string | 		name string | ||||||
| 		env  *EnvPaths | 		env  *env.Paths | ||||||
| 		want hst.Paths | 		want hst.Paths | ||||||
| 
 | 
 | ||||||
| 		wantPanic string | 		wantPanic string | ||||||
| 	}{ | 	}{ | ||||||
| 		{"nil", nil, hst.Paths{}, "attempting to use an invalid EnvPaths"}, | 		{"nil", nil, hst.Paths{}, "attempting to use an invalid Paths"}, | ||||||
| 		{"zero", new(EnvPaths), hst.Paths{}, "attempting to use an invalid EnvPaths"}, | 		{"zero", new(env.Paths), hst.Paths{}, "attempting to use an invalid Paths"}, | ||||||
| 
 | 
 | ||||||
| 		{"nil tempdir", &EnvPaths{ | 		{"nil tempdir", &env.Paths{ | ||||||
| 			RuntimePath: fhs.AbsTmp, | 			RuntimePath: fhs.AbsTmp, | ||||||
| 		}, hst.Paths{}, "attempting to use an invalid EnvPaths"}, | 		}, hst.Paths{}, "attempting to use an invalid Paths"}, | ||||||
| 
 | 
 | ||||||
| 		{"nil runtime", &EnvPaths{ | 		{"nil runtime", &env.Paths{ | ||||||
| 			TempDir: fhs.AbsTmp, | 			TempDir: fhs.AbsTmp, | ||||||
| 		}, hst.Paths{ | 		}, hst.Paths{ | ||||||
| 			TempDir:     fhs.AbsTmp, | 			TempDir:     fhs.AbsTmp, | ||||||
| @ -38,7 +39,7 @@ func TestEnvPaths(t *testing.T) { | |||||||
| 			RunDirPath:  fhs.AbsTmp.Append("hakurei.3735928559/run"), | 			RunDirPath:  fhs.AbsTmp.Append("hakurei.3735928559/run"), | ||||||
| 		}, ""}, | 		}, ""}, | ||||||
| 
 | 
 | ||||||
| 		{"full", &EnvPaths{ | 		{"full", &env.Paths{ | ||||||
| 			TempDir:     fhs.AbsTmp, | 			TempDir:     fhs.AbsTmp, | ||||||
| 			RuntimePath: fhs.AbsRunUser.Append("1000"), | 			RuntimePath: fhs.AbsRunUser.Append("1000"), | ||||||
| 		}, hst.Paths{ | 		}, hst.Paths{ | ||||||
| @ -76,16 +77,16 @@ func TestCopyPaths(t *testing.T) { | |||||||
| 		env   map[string]string | 		env   map[string]string | ||||||
| 		tmp   string | 		tmp   string | ||||||
| 		fatal string | 		fatal string | ||||||
| 		want  EnvPaths | 		want  env.Paths | ||||||
| 	}{ | 	}{ | ||||||
| 		{"invalid tempdir", nil, "\x00", | 		{"invalid tempdir", nil, "\x00", | ||||||
| 			"invalid TMPDIR: path \"\\x00\" is not absolute", EnvPaths{}}, | 			"invalid TMPDIR: path \"\\x00\" is not absolute", env.Paths{}}, | ||||||
| 		{"empty environment", make(map[string]string), container.Nonexistent, | 		{"empty environment", make(map[string]string), container.Nonexistent, | ||||||
| 			"", EnvPaths{TempDir: check.MustAbs(container.Nonexistent)}}, | 			"", env.Paths{TempDir: check.MustAbs(container.Nonexistent)}}, | ||||||
| 		{"invalid XDG_RUNTIME_DIR", map[string]string{"XDG_RUNTIME_DIR": "\x00"}, container.Nonexistent, | 		{"invalid XDG_RUNTIME_DIR", map[string]string{"XDG_RUNTIME_DIR": "\x00"}, container.Nonexistent, | ||||||
| 			"", EnvPaths{TempDir: check.MustAbs(container.Nonexistent)}}, | 			"", env.Paths{TempDir: check.MustAbs(container.Nonexistent)}}, | ||||||
| 		{"full", map[string]string{"XDG_RUNTIME_DIR": "/\x00"}, container.Nonexistent, | 		{"full", map[string]string{"XDG_RUNTIME_DIR": "/\x00"}, container.Nonexistent, | ||||||
| 			"", EnvPaths{TempDir: check.MustAbs(container.Nonexistent), RuntimePath: check.MustAbs("/\x00")}}, | 			"", env.Paths{TempDir: check.MustAbs(container.Nonexistent), RuntimePath: check.MustAbs("/\x00")}}, | ||||||
| 	} | 	} | ||||||
| 	for _, tc := range testCases { | 	for _, tc := range testCases { | ||||||
| 		t.Run(tc.name, func(t *testing.T) { | 		t.Run(tc.name, func(t *testing.T) { | ||||||
| @ -94,8 +95,16 @@ func TestCopyPaths(t *testing.T) { | |||||||
| 				defer stub.HandleExit(t) | 				defer stub.HandleExit(t) | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			k := copyPathsDispatcher{t: t, env: tc.env, tmp: tc.tmp, expectsFatal: tc.fatal} | 			got := env.CopyPathsFunc(func(format string, v ...any) { | ||||||
| 			got := copyPaths(k) | 				if tc.fatal == "" { | ||||||
|  | 					t.Fatalf("unexpected call to fatalf: format = %q, v = %#v", format, v) | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				if got := fmt.Sprintf(format, v...); got != tc.fatal { | ||||||
|  | 					t.Fatalf("fatalf: %q, want %q", got, tc.fatal) | ||||||
|  | 				} | ||||||
|  | 				panic(stub.PanicExit) | ||||||
|  | 			}, func() string { return tc.tmp }, func(key string) string { return tc.env[key] }) | ||||||
| 
 | 
 | ||||||
| 			if tc.fatal != "" { | 			if tc.fatal != "" { | ||||||
| 				t.Fatalf("copyPaths: expected fatal %q", tc.fatal) | 				t.Fatalf("copyPaths: expected fatal %q", tc.fatal) | ||||||
| @ -107,31 +116,3 @@ func TestCopyPaths(t *testing.T) { | |||||||
| 		}) | 		}) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 |  | ||||||
| // copyPathsDispatcher implements enough of syscallDispatcher for all copyPaths code paths. |  | ||||||
| type copyPathsDispatcher struct { |  | ||||||
| 	env map[string]string |  | ||||||
| 	tmp string |  | ||||||
| 
 |  | ||||||
| 	// must be checked at the conclusion of the test |  | ||||||
| 	expectsFatal string |  | ||||||
| 
 |  | ||||||
| 	t *testing.T |  | ||||||
| 	panicDispatcher |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (k copyPathsDispatcher) tempdir() string { return k.tmp } |  | ||||||
| func (k copyPathsDispatcher) lookupEnv(key string) (value string, ok bool) { |  | ||||||
| 	value, ok = k.env[key] |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| func (k copyPathsDispatcher) fatalf(format string, v ...any) { |  | ||||||
| 	if k.expectsFatal == "" { |  | ||||||
| 		k.t.Fatalf("unexpected call to fatalf: format = %q, v = %#v", format, v) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if got := fmt.Sprintf(format, v...); got != k.expectsFatal { |  | ||||||
| 		k.t.Fatalf("fatalf: %q, want %q", got, k.expectsFatal) |  | ||||||
| 	} |  | ||||||
| 	panic(stub.PanicExit) |  | ||||||
| } |  | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user