aboutsummaryrefslogtreecommitdiffhomepage
path: root/internal/app/env_test.go
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2025-10-03 16:59:29 +0900
committerOphestra <cat@gensokyo.uk>2025-10-03 16:59:29 +0900
commita5f0aa3f3077cb7bf3cbf7ac9e707ba165aceb4a (patch)
treef75910d2147ac7c02328d229a8cb8609d2355016 /internal/app/env_test.go
parentdd0bb0a39104a54c26015df807c1eb113331c242 (diff)
internal/app: declutter and merge small files
This should make internal/app easier to work with for the upcoming params to shim. Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'internal/app/env_test.go')
-rw-r--r--internal/app/env_test.go129
1 files changed, 129 insertions, 0 deletions
diff --git a/internal/app/env_test.go b/internal/app/env_test.go
new file mode 100644
index 00000000..04e21344
--- /dev/null
+++ b/internal/app/env_test.go
@@ -0,0 +1,129 @@
+package app
+
+import (
+ "fmt"
+ "reflect"
+ "testing"
+
+ "hakurei.app/container"
+ "hakurei.app/container/stub"
+ "hakurei.app/hst"
+)
+
+func TestEnvPaths(t *testing.T) {
+ testCases := []struct {
+ name string
+ env *EnvPaths
+ want hst.Paths
+
+ wantPanic string
+ }{
+ {"nil", nil, hst.Paths{}, "attempting to use an invalid EnvPaths"},
+ {"zero", new(EnvPaths), hst.Paths{}, "attempting to use an invalid EnvPaths"},
+
+ {"nil tempdir", &EnvPaths{
+ RuntimePath: container.AbsFHSTmp,
+ }, hst.Paths{}, "attempting to use an invalid EnvPaths"},
+
+ {"nil runtime", &EnvPaths{
+ TempDir: container.AbsFHSTmp,
+ }, hst.Paths{
+ TempDir: container.AbsFHSTmp,
+ SharePath: container.AbsFHSTmp.Append("hakurei.3735928559"),
+ RuntimePath: container.AbsFHSTmp.Append("hakurei.3735928559/run/compat"),
+ RunDirPath: container.AbsFHSTmp.Append("hakurei.3735928559/run"),
+ }, ""},
+
+ {"full", &EnvPaths{
+ TempDir: container.AbsFHSTmp,
+ RuntimePath: container.AbsFHSRunUser.Append("1000"),
+ }, hst.Paths{
+ TempDir: container.AbsFHSTmp,
+ SharePath: container.AbsFHSTmp.Append("hakurei.3735928559"),
+ RuntimePath: container.AbsFHSRunUser.Append("1000"),
+ RunDirPath: container.AbsFHSRunUser.Append("1000/hakurei"),
+ }, ""},
+ }
+ for _, tc := range testCases {
+ t.Run(tc.name, func(t *testing.T) {
+ if tc.wantPanic != "" {
+ defer func() {
+ if r := recover(); r != tc.wantPanic {
+ t.Errorf("Copy: panic = %#v, want %q", r, tc.wantPanic)
+ }
+ }()
+ }
+
+ var sc hst.Paths
+ tc.env.Copy(&sc, 0xdeadbeef)
+ if !reflect.DeepEqual(&sc, &tc.want) {
+ t.Errorf("Copy: %#v, want %#v", sc, tc.want)
+ }
+ })
+ }
+}
+
+func TestCopyPaths(t *testing.T) {
+ testCases := []struct {
+ name string
+ env map[string]string
+ tmp string
+ fatal string
+ want EnvPaths
+ }{
+ {"invalid tempdir", nil, "\x00",
+ "invalid TMPDIR: path \"\\x00\" is not absolute", EnvPaths{}},
+ {"empty environment", make(map[string]string), container.Nonexistent,
+ "", EnvPaths{TempDir: container.MustAbs(container.Nonexistent)}},
+ {"invalid XDG_RUNTIME_DIR", map[string]string{"XDG_RUNTIME_DIR": "\x00"}, container.Nonexistent,
+ "", EnvPaths{TempDir: container.MustAbs(container.Nonexistent)}},
+ {"full", map[string]string{"XDG_RUNTIME_DIR": "/\x00"}, container.Nonexistent,
+ "", EnvPaths{TempDir: container.MustAbs(container.Nonexistent), RuntimePath: container.MustAbs("/\x00")}},
+ }
+ for _, tc := range testCases {
+ t.Run(tc.name, func(t *testing.T) {
+ if tc.fatal != "" {
+ defer stub.HandleExit(t)
+ }
+
+ k := copyPathsDispatcher{t: t, env: tc.env, tmp: tc.tmp, expectsFatal: tc.fatal}
+ got := copyPaths(k)
+
+ if tc.fatal != "" {
+ t.Fatalf("copyPaths: expected fatal %q", tc.fatal)
+ }
+
+ if !reflect.DeepEqual(got, &tc.want) {
+ t.Errorf("copyPaths: %#v, want %#v", got, &tc.want)
+ }
+ })
+ }
+}
+
+// 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)
+}