All checks were successful
		
		
	
	Test / Create distribution (push) Successful in 25s
				
			Test / Hakurei (push) Successful in 44s
				
			Test / Sandbox (push) Successful in 41s
				
			Test / Hakurei (race detector) (push) Successful in 44s
				
			Test / Sandbox (race detector) (push) Successful in 41s
				
			Test / Hpkg (push) Successful in 41s
				
			Test / Flake checks (push) Successful in 1m24s
				
			Most tests already had no global state, however parallel was never enabled. This change enables it for all applicable tests. Signed-off-by: Ophestra <cat@gensokyo.uk>
		
			
				
	
	
		
			180 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			180 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package container
 | |
| 
 | |
| import (
 | |
| 	"errors"
 | |
| 	"os"
 | |
| 	"reflect"
 | |
| 	"strconv"
 | |
| 	"syscall"
 | |
| 	"testing"
 | |
| 
 | |
| 	"hakurei.app/container/check"
 | |
| 	"hakurei.app/container/stub"
 | |
| 	"hakurei.app/container/vfs"
 | |
| )
 | |
| 
 | |
| func TestMessageFromError(t *testing.T) {
 | |
| 	t.Parallel()
 | |
| 
 | |
| 	testCases := []struct {
 | |
| 		name   string
 | |
| 		err    error
 | |
| 		want   string
 | |
| 		wantOk bool
 | |
| 	}{
 | |
| 		{"mount", &MountError{
 | |
| 			Source: SourceTmpfsEphemeral,
 | |
| 			Target: "/sysroot/tmp",
 | |
| 			Fstype: FstypeTmpfs,
 | |
| 			Flags:  syscall.MS_NOSUID | syscall.MS_NODEV,
 | |
| 			Data:   zeroString,
 | |
| 			Errno:  syscall.EINVAL,
 | |
| 		}, "cannot mount tmpfs on /sysroot/tmp: invalid argument", true},
 | |
| 
 | |
| 		{"path", &os.PathError{
 | |
| 			Op:   "mount",
 | |
| 			Path: "/sysroot",
 | |
| 			Err:  stub.UniqueError(0xdeadbeef),
 | |
| 		}, "cannot mount /sysroot: unique error 3735928559 injected by the test suite", true},
 | |
| 
 | |
| 		{"absolute", &check.AbsoluteError{Pathname: "etc/mtab"},
 | |
| 			`path "etc/mtab" is not absolute`, true},
 | |
| 
 | |
| 		{"repeat", OpRepeatError("autoetc"),
 | |
| 			"autoetc is not repeatable", true},
 | |
| 
 | |
| 		{"state", OpStateError("overlay"),
 | |
| 			"impossible overlay state reached", true},
 | |
| 
 | |
| 		{"vfs parse", &vfs.DecoderError{Op: "parse", Line: 0xdeadbeef, Err: &strconv.NumError{Func: "Atoi", Num: "meow", Err: strconv.ErrSyntax}},
 | |
| 			`cannot parse mountinfo at line 3735928559: numeric field "meow" invalid syntax`, true},
 | |
| 
 | |
| 		{"tmpfs", TmpfsSizeError(-1),
 | |
| 			"tmpfs size -1 out of bounds", true},
 | |
| 
 | |
| 		{"unsupported", stub.UniqueError(0xdeadbeef), zeroString, false},
 | |
| 	}
 | |
| 	for _, tc := range testCases {
 | |
| 		t.Run(tc.name, func(t *testing.T) {
 | |
| 			t.Parallel()
 | |
| 			got, ok := messageFromError(tc.err)
 | |
| 			if got != tc.want {
 | |
| 				t.Errorf("messageFromError: %q, want %q", got, tc.want)
 | |
| 			}
 | |
| 			if ok != tc.wantOk {
 | |
| 				t.Errorf("messageFromError: ok = %v, want %v", ok, tc.wantOk)
 | |
| 			}
 | |
| 		})
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func TestMountError(t *testing.T) {
 | |
| 	t.Parallel()
 | |
| 
 | |
| 	testCases := []struct {
 | |
| 		name  string
 | |
| 		err   error
 | |
| 		errno syscall.Errno
 | |
| 		want  string
 | |
| 	}{
 | |
| 		{"bind", &MountError{
 | |
| 			Source: "/host/nix/store",
 | |
| 			Target: "/sysroot/nix/store",
 | |
| 			Fstype: FstypeNULL,
 | |
| 			Flags:  syscall.MS_SILENT | syscall.MS_BIND | syscall.MS_REC,
 | |
| 			Data:   zeroString,
 | |
| 			Errno:  syscall.ENOSYS,
 | |
| 		}, syscall.ENOSYS,
 | |
| 			"bind /host/nix/store on /sysroot/nix/store: function not implemented"},
 | |
| 
 | |
| 		{"remount", &MountError{
 | |
| 			Source: SourceNone,
 | |
| 			Target: "/sysroot/nix/store",
 | |
| 			Fstype: FstypeNULL,
 | |
| 			Flags:  syscall.MS_SILENT | syscall.MS_BIND | syscall.MS_REMOUNT,
 | |
| 			Data:   zeroString,
 | |
| 			Errno:  syscall.EPERM,
 | |
| 		}, syscall.EPERM,
 | |
| 			"remount /sysroot/nix/store: operation not permitted"},
 | |
| 
 | |
| 		{"overlay", &MountError{
 | |
| 			Source: SourceOverlay,
 | |
| 			Target: sysrootPath,
 | |
| 			Fstype: FstypeOverlay,
 | |
| 			Data:   `lowerdir=/host/var/lib/planterette/base/debian\:f92c9052`,
 | |
| 			Errno:  syscall.EINVAL,
 | |
| 		}, syscall.EINVAL,
 | |
| 			"mount overlay on /sysroot: invalid argument"},
 | |
| 
 | |
| 		{"fallback", &MountError{
 | |
| 			Source: SourceNone,
 | |
| 			Target: sysrootPath,
 | |
| 			Fstype: FstypeNULL,
 | |
| 			Errno:  syscall.ENOTRECOVERABLE,
 | |
| 		}, syscall.ENOTRECOVERABLE,
 | |
| 			"mount /sysroot: state not recoverable"},
 | |
| 	}
 | |
| 	for _, tc := range testCases {
 | |
| 		t.Run(tc.name, func(t *testing.T) {
 | |
| 			t.Parallel()
 | |
| 			t.Run("is", func(t *testing.T) {
 | |
| 				if !errors.Is(tc.err, tc.errno) {
 | |
| 					t.Errorf("Is: %#v is not %v", tc.err, tc.errno)
 | |
| 				}
 | |
| 			})
 | |
| 			t.Run("error", func(t *testing.T) {
 | |
| 				if got := tc.err.Error(); got != tc.want {
 | |
| 					t.Errorf("Error: %q, want %q", got, tc.want)
 | |
| 				}
 | |
| 			})
 | |
| 		})
 | |
| 	}
 | |
| 
 | |
| 	t.Run("zero", func(t *testing.T) {
 | |
| 		t.Parallel()
 | |
| 		if errors.Is(new(MountError), syscall.Errno(0)) {
 | |
| 			t.Errorf("Is: zero MountError unexpected true")
 | |
| 		}
 | |
| 	})
 | |
| }
 | |
| 
 | |
| func TestErrnoFallback(t *testing.T) {
 | |
| 	t.Parallel()
 | |
| 
 | |
| 	testCases := []struct {
 | |
| 		name      string
 | |
| 		err       error
 | |
| 		wantErrno syscall.Errno
 | |
| 		wantPath  *os.PathError
 | |
| 	}{
 | |
| 		{"mount", &MountError{
 | |
| 			Errno: syscall.ENOTRECOVERABLE,
 | |
| 		}, syscall.ENOTRECOVERABLE, nil},
 | |
| 
 | |
| 		{"path errno", &os.PathError{
 | |
| 			Err: syscall.ETIMEDOUT,
 | |
| 		}, syscall.ETIMEDOUT, nil},
 | |
| 
 | |
| 		{"fallback", stub.UniqueError(0xcafebabe), 0, &os.PathError{
 | |
| 			Op:   "fallback",
 | |
| 			Path: "/proc/nonexistent",
 | |
| 			Err:  stub.UniqueError(0xcafebabe),
 | |
| 		}},
 | |
| 	}
 | |
| 	for _, tc := range testCases {
 | |
| 		t.Run(tc.name, func(t *testing.T) {
 | |
| 			t.Parallel()
 | |
| 			errno, err := errnoFallback(tc.name, Nonexistent, tc.err)
 | |
| 			if errno != tc.wantErrno {
 | |
| 				t.Errorf("errnoFallback: errno = %v, want %v", errno, tc.wantErrno)
 | |
| 			}
 | |
| 			if !reflect.DeepEqual(err, tc.wantPath) {
 | |
| 				t.Errorf("errnoFallback: pathError = %#v, want %#v", err, tc.wantPath)
 | |
| 			}
 | |
| 		})
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // InternalMessageFromError exports messageFromError for other tests.
 | |
| func InternalMessageFromError(err error) (string, bool) { return messageFromError(err) }
 |