container/check: move absolute pathname
All checks were successful
Test / Create distribution (push) Successful in 34s
Test / Hpkg (push) Successful in 4m3s
Test / Sandbox (race detector) (push) Successful in 4m26s
Test / Hakurei (race detector) (push) Successful in 5m19s
Test / Sandbox (push) Successful in 1m28s
Test / Hakurei (push) Successful in 2m16s
Test / Flake checks (push) Successful in 1m37s
All checks were successful
Test / Create distribution (push) Successful in 34s
Test / Hpkg (push) Successful in 4m3s
Test / Sandbox (race detector) (push) Successful in 4m26s
Test / Hakurei (race detector) (push) Successful in 5m19s
Test / Sandbox (push) Successful in 1m28s
Test / Hakurei (push) Successful in 2m16s
Test / Flake checks (push) Successful in 1m37s
This allows use of absolute pathname values without importing container. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
@@ -16,6 +16,7 @@ import (
|
||||
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/bits"
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/hst"
|
||||
"hakurei.app/internal/app/state"
|
||||
"hakurei.app/system"
|
||||
@@ -695,7 +696,7 @@ func (k *stubNixOS) cmdOutput(cmd *exec.Cmd) ([]byte, error) {
|
||||
func (k *stubNixOS) overflowUid(container.Msg) int { return 65534 }
|
||||
func (k *stubNixOS) overflowGid(container.Msg) int { return 65534 }
|
||||
|
||||
func (k *stubNixOS) mustHsuPath() *container.Absolute { return m("/proc/nonexistent/hsu") }
|
||||
func (k *stubNixOS) mustHsuPath() *check.Absolute { return m("/proc/nonexistent/hsu") }
|
||||
|
||||
func (k *stubNixOS) fatalf(format string, v ...any) { panic(fmt.Sprintf(format, v...)) }
|
||||
|
||||
@@ -703,8 +704,8 @@ func (k *stubNixOS) isVerbose() bool { return true }
|
||||
func (k *stubNixOS) verbose(v ...any) { log.Print(v...) }
|
||||
func (k *stubNixOS) verbosef(format string, v ...any) { log.Printf(format, v...) }
|
||||
|
||||
func m(pathname string) *container.Absolute {
|
||||
return container.MustAbs(pathname)
|
||||
func m(pathname string) *check.Absolute {
|
||||
return check.MustAbs(pathname)
|
||||
}
|
||||
|
||||
func f(c hst.FilesystemConfig) hst.FilesystemConfigJSON {
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"path/filepath"
|
||||
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/internal"
|
||||
)
|
||||
|
||||
@@ -57,7 +58,7 @@ type syscallDispatcher interface {
|
||||
overflowGid(msg container.Msg) int
|
||||
|
||||
// mustHsuPath provides [internal.MustHsuPath].
|
||||
mustHsuPath() *container.Absolute
|
||||
mustHsuPath() *check.Absolute
|
||||
|
||||
// fatalf provides [log.Fatalf].
|
||||
fatalf(format string, v ...any)
|
||||
@@ -92,6 +93,6 @@ func (direct) cmdOutput(cmd *exec.Cmd) ([]byte, error) { return cmd.Output() }
|
||||
func (direct) overflowUid(msg container.Msg) int { return container.OverflowUid(msg) }
|
||||
func (direct) overflowGid(msg container.Msg) int { return container.OverflowGid(msg) }
|
||||
|
||||
func (direct) mustHsuPath() *container.Absolute { return internal.MustHsuPath() }
|
||||
func (direct) mustHsuPath() *check.Absolute { return internal.MustHsuPath() }
|
||||
|
||||
func (direct) fatalf(format string, v ...any) { log.Fatalf(format, v...) }
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"os/exec"
|
||||
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/check"
|
||||
)
|
||||
|
||||
type panicDispatcher struct{}
|
||||
@@ -22,5 +23,5 @@ func (panicDispatcher) lookupGroupId(string) (string, error) { panic("unreachab
|
||||
func (panicDispatcher) cmdOutput(*exec.Cmd) ([]byte, error) { panic("unreachable") }
|
||||
func (panicDispatcher) overflowUid(container.Msg) int { panic("unreachable") }
|
||||
func (panicDispatcher) overflowGid(container.Msg) int { panic("unreachable") }
|
||||
func (panicDispatcher) mustHsuPath() *container.Absolute { panic("unreachable") }
|
||||
func (panicDispatcher) mustHsuPath() *check.Absolute { panic("unreachable") }
|
||||
func (panicDispatcher) fatalf(string, ...any) { panic("unreachable") }
|
||||
|
||||
@@ -3,16 +3,16 @@ package app
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"hakurei.app/container"
|
||||
"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 *container.Absolute
|
||||
TempDir *check.Absolute
|
||||
// RuntimePath is copied from $XDG_RUNTIME_DIR.
|
||||
RuntimePath *container.Absolute
|
||||
RuntimePath *check.Absolute
|
||||
}
|
||||
|
||||
// Copy expands [EnvPaths] into [hst.Paths].
|
||||
@@ -43,7 +43,7 @@ func copyPaths(k syscallDispatcher) *EnvPaths {
|
||||
|
||||
var env EnvPaths
|
||||
|
||||
if tempDir, err := container.NewAbs(k.tempdir()); err != nil {
|
||||
if tempDir, err := check.NewAbs(k.tempdir()); err != nil {
|
||||
k.fatalf("invalid TMPDIR: %v", err)
|
||||
panic("unreachable")
|
||||
} else {
|
||||
@@ -51,7 +51,7 @@ func copyPaths(k syscallDispatcher) *EnvPaths {
|
||||
}
|
||||
|
||||
r, _ := k.lookupEnv(xdgRuntimeDir)
|
||||
if a, err := container.NewAbs(r); err == nil {
|
||||
if a, err := check.NewAbs(r); err == nil {
|
||||
env.RuntimePath = a
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/container/stub"
|
||||
"hakurei.app/hst"
|
||||
)
|
||||
@@ -74,11 +75,11 @@ func TestCopyPaths(t *testing.T) {
|
||||
{"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)}},
|
||||
"", EnvPaths{TempDir: check.MustAbs(container.Nonexistent)}},
|
||||
{"invalid XDG_RUNTIME_DIR", map[string]string{"XDG_RUNTIME_DIR": "\x00"}, container.Nonexistent,
|
||||
"", EnvPaths{TempDir: container.MustAbs(container.Nonexistent)}},
|
||||
"", EnvPaths{TempDir: check.MustAbs(container.Nonexistent)}},
|
||||
{"full", map[string]string{"XDG_RUNTIME_DIR": "/\x00"}, container.Nonexistent,
|
||||
"", EnvPaths{TempDir: container.MustAbs(container.Nonexistent), RuntimePath: container.MustAbs("/\x00")}},
|
||||
"", EnvPaths{TempDir: check.MustAbs(container.Nonexistent), RuntimePath: check.MustAbs("/\x00")}},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"strconv"
|
||||
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/hst"
|
||||
"hakurei.app/internal/app/state"
|
||||
"hakurei.app/system"
|
||||
@@ -51,7 +52,7 @@ type outcomeState struct {
|
||||
*EnvPaths
|
||||
|
||||
// Matched paths to cover. Populated by spFilesystemOp.
|
||||
HidePaths []*container.Absolute
|
||||
HidePaths []*check.Absolute
|
||||
|
||||
// Copied via populateLocal.
|
||||
k syscallDispatcher
|
||||
@@ -95,14 +96,14 @@ func (s *outcomeState) populateLocal(k syscallDispatcher, msg container.Msg) err
|
||||
// instancePath returns a path formatted for outcomeStateSys.instance.
|
||||
// This method must only be called from outcomeOp.toContainer if
|
||||
// outcomeOp.toSystem has already called outcomeStateSys.instance.
|
||||
func (s *outcomeState) instancePath() *container.Absolute {
|
||||
func (s *outcomeState) instancePath() *check.Absolute {
|
||||
return s.sc.SharePath.Append(s.id.String())
|
||||
}
|
||||
|
||||
// runtimePath returns a path formatted for outcomeStateSys.runtime.
|
||||
// This method must only be called from outcomeOp.toContainer if
|
||||
// outcomeOp.toSystem has already called outcomeStateSys.runtime.
|
||||
func (s *outcomeState) runtimePath() *container.Absolute {
|
||||
func (s *outcomeState) runtimePath() *check.Absolute {
|
||||
return s.sc.RunDirPath.Append(s.id.String())
|
||||
}
|
||||
|
||||
@@ -112,9 +113,9 @@ type outcomeStateSys struct {
|
||||
// Whether XDG_RUNTIME_DIR is used post hsu.
|
||||
useRuntimeDir bool
|
||||
// Process-specific directory in TMPDIR, nil if unused.
|
||||
sharePath *container.Absolute
|
||||
sharePath *check.Absolute
|
||||
// Process-specific directory in XDG_RUNTIME_DIR, nil if unused.
|
||||
runtimeSharePath *container.Absolute
|
||||
runtimeSharePath *check.Absolute
|
||||
|
||||
sys *system.I
|
||||
*outcomeState
|
||||
@@ -134,7 +135,7 @@ func (state *outcomeStateSys) ensureRuntimeDir() {
|
||||
|
||||
// instance returns the pathname to a process-specific directory within TMPDIR.
|
||||
// This directory must only hold entries bound to [system.Process].
|
||||
func (state *outcomeStateSys) instance() *container.Absolute {
|
||||
func (state *outcomeStateSys) instance() *check.Absolute {
|
||||
if state.sharePath != nil {
|
||||
return state.sharePath
|
||||
}
|
||||
@@ -145,7 +146,7 @@ func (state *outcomeStateSys) instance() *container.Absolute {
|
||||
|
||||
// runtime returns the pathname to a process-specific directory within XDG_RUNTIME_DIR.
|
||||
// This directory must only hold entries bound to [system.Process].
|
||||
func (state *outcomeStateSys) runtime() *container.Absolute {
|
||||
func (state *outcomeStateSys) runtime() *check.Absolute {
|
||||
if state.runtimeSharePath != nil {
|
||||
return state.runtimeSharePath
|
||||
}
|
||||
@@ -169,7 +170,7 @@ type outcomeStateParams struct {
|
||||
|
||||
// Inner XDG_RUNTIME_DIR default formatting of `/run/user/%d` via mapped uid.
|
||||
// Populated by spRuntimeOp.
|
||||
runtimeDir *container.Absolute
|
||||
runtimeDir *check.Absolute
|
||||
|
||||
as hst.ApplyState
|
||||
*outcomeState
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"time"
|
||||
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/hst"
|
||||
"hakurei.app/internal"
|
||||
"hakurei.app/internal/app/state"
|
||||
@@ -215,7 +216,7 @@ type finaliseProcess struct {
|
||||
waitDelay time.Duration
|
||||
|
||||
// Copied from the RunDirPath field of [hst.Paths].
|
||||
runDirPath *container.Absolute
|
||||
runDirPath *check.Absolute
|
||||
|
||||
// Copied from outcomeState.
|
||||
identity *stringPair[int]
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/bits"
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/container/seccomp"
|
||||
"hakurei.app/hst"
|
||||
"hakurei.app/system/dbus"
|
||||
@@ -183,7 +184,7 @@ func (s spFilesystemOp) toSystem(state *outcomeStateSys, _ *hst.Config) error {
|
||||
}
|
||||
}
|
||||
|
||||
hidePathSource := make([]*container.Absolute, 0, hidePathSourceCount)
|
||||
hidePathSource := make([]*check.Absolute, 0, hidePathSourceCount)
|
||||
|
||||
// fs append
|
||||
for _, c := range filesystem {
|
||||
@@ -234,8 +235,8 @@ func (s spFilesystemOp) toSystem(state *outcomeStateSys, _ *hst.Config) error {
|
||||
// copy matched paths for shim
|
||||
for i, ok := range hidePathMatch {
|
||||
if ok {
|
||||
if a, err := container.NewAbs(hidePaths[i]); err != nil {
|
||||
var absoluteError *container.AbsoluteError
|
||||
if a, err := check.NewAbs(hidePaths[i]); err != nil {
|
||||
var absoluteError *check.AbsoluteError
|
||||
if !errors.As(err, &absoluteError) {
|
||||
return newWithMessageError(absoluteError.Error(), absoluteError)
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
"os"
|
||||
"syscall"
|
||||
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/hst"
|
||||
)
|
||||
|
||||
@@ -45,13 +45,13 @@ func (s *spPulseOp) toSystem(state *outcomeStateSys, _ *hst.Config) error {
|
||||
state.sys.Link(pulseSocket, state.runtime().Append("pulse"))
|
||||
|
||||
// publish current user's pulse cookie for target user
|
||||
var paCookiePath *container.Absolute
|
||||
var paCookiePath *check.Absolute
|
||||
{
|
||||
const paLocateStep = "locate PulseAudio cookie"
|
||||
|
||||
// from environment
|
||||
if p, ok := state.k.lookupEnv("PULSE_COOKIE"); ok {
|
||||
if a, err := container.NewAbs(p); err != nil {
|
||||
if a, err := check.NewAbs(p); err != nil {
|
||||
return &hst.AppError{Step: paLocateStep, Err: err}
|
||||
} else {
|
||||
// this takes precedence, do not verify whether the file is accessible
|
||||
@@ -62,7 +62,7 @@ func (s *spPulseOp) toSystem(state *outcomeStateSys, _ *hst.Config) error {
|
||||
|
||||
// $HOME/.pulse-cookie
|
||||
if p, ok := state.k.lookupEnv("HOME"); ok {
|
||||
if a, err := container.NewAbs(p); err != nil {
|
||||
if a, err := check.NewAbs(p); err != nil {
|
||||
return &hst.AppError{Step: paLocateStep, Err: err}
|
||||
} else {
|
||||
paCookiePath = a.Append(".pulse-cookie")
|
||||
@@ -83,7 +83,7 @@ func (s *spPulseOp) toSystem(state *outcomeStateSys, _ *hst.Config) error {
|
||||
|
||||
// $XDG_CONFIG_HOME/pulse/cookie
|
||||
if p, ok := state.k.lookupEnv("XDG_CONFIG_HOME"); ok {
|
||||
if a, err := container.NewAbs(p); err != nil {
|
||||
if a, err := check.NewAbs(p); err != nil {
|
||||
return &hst.AppError{Step: paLocateStep, Err: err}
|
||||
} else {
|
||||
paCookiePath = a.Append("pulse", "cookie")
|
||||
@@ -161,7 +161,7 @@ func (s *spPulseOp) toContainer(state *outcomeStateParams) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *spPulseOp) commonPaths(state *outcomeState) (pulseRuntimeDir, pulseSocket *container.Absolute) {
|
||||
func (s *spPulseOp) commonPaths(state *outcomeState) (pulseRuntimeDir, pulseSocket *check.Absolute) {
|
||||
// PulseAudio runtime directory (usually `/run/user/%d/pulse`)
|
||||
pulseRuntimeDir = state.sc.RuntimePath.Append("pulse")
|
||||
// PulseAudio socket (usually `/run/user/%d/pulse/native`)
|
||||
|
||||
@@ -2,6 +2,7 @@ package app
|
||||
|
||||
import (
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/hst"
|
||||
"hakurei.app/system"
|
||||
"hakurei.app/system/acl"
|
||||
@@ -37,7 +38,7 @@ func (s spRuntimeOp) toContainer(state *outcomeStateParams) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s spRuntimeOp) commonPaths(state *outcomeState) (runtimeDir, runtimeDirInst *container.Absolute) {
|
||||
func (s spRuntimeOp) commonPaths(state *outcomeState) (runtimeDir, runtimeDirInst *check.Absolute) {
|
||||
runtimeDir = state.sc.SharePath.Append("runtime")
|
||||
runtimeDirInst = runtimeDir.Append(state.identity.String())
|
||||
return
|
||||
|
||||
@@ -2,6 +2,7 @@ package app
|
||||
|
||||
import (
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/hst"
|
||||
"hakurei.app/system"
|
||||
"hakurei.app/system/acl"
|
||||
@@ -26,7 +27,7 @@ func (s spTmpdirOp) toContainer(state *outcomeStateParams) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s spTmpdirOp) commonPaths(state *outcomeState) (tmpdir, tmpdirInst *container.Absolute) {
|
||||
func (s spTmpdirOp) commonPaths(state *outcomeState) (tmpdir, tmpdirInst *check.Absolute) {
|
||||
tmpdir = state.sc.SharePath.Append("tmpdir")
|
||||
tmpdirInst = tmpdir.Append(state.identity.String())
|
||||
return
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/hst"
|
||||
"hakurei.app/system/acl"
|
||||
"hakurei.app/system/wayland"
|
||||
@@ -10,16 +10,16 @@ import (
|
||||
// spWaylandOp exports the Wayland display server to the container.
|
||||
type spWaylandOp struct {
|
||||
// Path to host wayland socket. Populated during toSystem if DirectWayland is true.
|
||||
SocketPath *container.Absolute
|
||||
SocketPath *check.Absolute
|
||||
}
|
||||
|
||||
func (s *spWaylandOp) toSystem(state *outcomeStateSys, config *hst.Config) error {
|
||||
// outer wayland socket (usually `/run/user/%d/wayland-%d`)
|
||||
var socketPath *container.Absolute
|
||||
var socketPath *check.Absolute
|
||||
if name, ok := state.k.lookupEnv(wayland.WaylandDisplay); !ok {
|
||||
state.msg.Verbose(wayland.WaylandDisplay + " is not set, assuming " + wayland.FallbackName)
|
||||
socketPath = state.sc.RuntimePath.Append(wayland.FallbackName)
|
||||
} else if a, err := container.NewAbs(name); err != nil {
|
||||
} else if a, err := check.NewAbs(name); err != nil {
|
||||
socketPath = state.sc.RuntimePath.Append(name)
|
||||
} else {
|
||||
socketPath = a
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/check"
|
||||
"hakurei.app/hst"
|
||||
"hakurei.app/system/acl"
|
||||
)
|
||||
@@ -29,13 +30,13 @@ func (s *spX11Op) toSystem(state *outcomeStateSys, _ *hst.Config) error {
|
||||
|
||||
// the socket file at `/tmp/.X11-unix/X%d` is typically owned by the priv user
|
||||
// and not accessible by the target user
|
||||
var socketPath *container.Absolute
|
||||
var socketPath *check.Absolute
|
||||
if len(s.Display) > 1 && s.Display[0] == ':' { // `:%d`
|
||||
if n, err := strconv.Atoi(s.Display[1:]); err == nil && n >= 0 {
|
||||
socketPath = absX11SocketDir.Append("X" + strconv.Itoa(n))
|
||||
}
|
||||
} else if len(s.Display) > 5 && strings.HasPrefix(s.Display, "unix:") { // `unix:%s`
|
||||
if a, err := container.NewAbs(s.Display[5:]); err == nil {
|
||||
if a, err := check.NewAbs(s.Display[5:]); err == nil {
|
||||
socketPath = a
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,11 +6,11 @@ var (
|
||||
version = compPoison
|
||||
)
|
||||
|
||||
// check validates string value set at compile time.
|
||||
func check(s string) (string, bool) { return s, s != compPoison && s != "" }
|
||||
// checkComp validates string value set at compile time.
|
||||
func checkComp(s string) (string, bool) { return s, s != compPoison && s != "" }
|
||||
|
||||
func Version() string {
|
||||
if v, ok := check(version); ok {
|
||||
if v, ok := checkComp(version); ok {
|
||||
return v
|
||||
}
|
||||
return "impure"
|
||||
|
||||
@@ -3,7 +3,7 @@ package internal
|
||||
import (
|
||||
"log"
|
||||
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/check"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -12,15 +12,15 @@ var (
|
||||
)
|
||||
|
||||
// MustHakureiPath returns the absolute path to hakurei, configured at compile time.
|
||||
func MustHakureiPath() *container.Absolute { return mustCheckPath(log.Fatal, "hakurei", hmain) }
|
||||
func MustHakureiPath() *check.Absolute { return mustCheckPath(log.Fatal, "hakurei", hmain) }
|
||||
|
||||
// MustHsuPath returns the absolute path to hakurei, configured at compile time.
|
||||
func MustHsuPath() *container.Absolute { return mustCheckPath(log.Fatal, "hsu", hsu) }
|
||||
func MustHsuPath() *check.Absolute { return mustCheckPath(log.Fatal, "hsu", hsu) }
|
||||
|
||||
// mustCheckPath checks a pathname against compPoison, then [container.NewAbs], calling fatal if either step fails.
|
||||
func mustCheckPath(fatal func(v ...any), name, pathname string) *container.Absolute {
|
||||
func mustCheckPath(fatal func(v ...any), name, pathname string) *check.Absolute {
|
||||
if pathname != compPoison && pathname != "" {
|
||||
if a, err := container.NewAbs(pathname); err != nil {
|
||||
if a, err := check.NewAbs(pathname); err != nil {
|
||||
fatal(err.Error())
|
||||
return nil // unreachable
|
||||
} else {
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/container/check"
|
||||
)
|
||||
|
||||
func TestMustCheckPath(t *testing.T) {
|
||||
@@ -35,7 +35,7 @@ func TestMustCheckPath(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
if got := mustCheckPath(fatal, "test", tc.pathname); got != nil && !reflect.DeepEqual(got, container.MustAbs(tc.pathname)) {
|
||||
if got := mustCheckPath(fatal, "test", tc.pathname); got != nil && !reflect.DeepEqual(got, check.MustAbs(tc.pathname)) {
|
||||
t.Errorf("mustCheckPath: %q", got)
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user