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>
		
			
				
	
	
		
			400 lines
		
	
	
		
			9.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			400 lines
		
	
	
		
			9.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package check_test
 | |
| 
 | |
| import (
 | |
| 	"bytes"
 | |
| 	"encoding/gob"
 | |
| 	"encoding/json"
 | |
| 	"errors"
 | |
| 	"reflect"
 | |
| 	"strings"
 | |
| 	"syscall"
 | |
| 	"testing"
 | |
| 	_ "unsafe"
 | |
| 
 | |
| 	. "hakurei.app/container/check"
 | |
| )
 | |
| 
 | |
| //go:linkname unsafeAbs hakurei.app/container/check.unsafeAbs
 | |
| func unsafeAbs(_ string) *Absolute
 | |
| 
 | |
| func TestAbsoluteError(t *testing.T) {
 | |
| 	t.Parallel()
 | |
| 
 | |
| 	testCases := []struct {
 | |
| 		name string
 | |
| 
 | |
| 		err error
 | |
| 		cmp error
 | |
| 		ok  bool
 | |
| 	}{
 | |
| 		{"EINVAL", new(AbsoluteError), syscall.EINVAL, true},
 | |
| 		{"not EINVAL", new(AbsoluteError), syscall.EBADE, false},
 | |
| 		{"ne val", new(AbsoluteError), &AbsoluteError{Pathname: "etc"}, false},
 | |
| 		{"equals", &AbsoluteError{Pathname: "etc"}, &AbsoluteError{Pathname: "etc"}, true},
 | |
| 	}
 | |
| 
 | |
| 	for _, tc := range testCases {
 | |
| 		if got := errors.Is(tc.err, tc.cmp); got != tc.ok {
 | |
| 			t.Errorf("Is: %v, want %v", got, tc.ok)
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	t.Run("string", func(t *testing.T) {
 | |
| 		t.Parallel()
 | |
| 
 | |
| 		want := `path "etc" is not absolute`
 | |
| 		if got := (&AbsoluteError{Pathname: "etc"}).Error(); got != want {
 | |
| 			t.Errorf("Error: %q, want %q", got, want)
 | |
| 		}
 | |
| 	})
 | |
| }
 | |
| 
 | |
| func TestNewAbs(t *testing.T) {
 | |
| 	t.Parallel()
 | |
| 
 | |
| 	testCases := []struct {
 | |
| 		name string
 | |
| 
 | |
| 		pathname string
 | |
| 		want     *Absolute
 | |
| 		wantErr  error
 | |
| 	}{
 | |
| 		{"good", "/etc", MustAbs("/etc"), nil},
 | |
| 		{"not absolute", "etc", nil, &AbsoluteError{Pathname: "etc"}},
 | |
| 		{"zero", "", nil, &AbsoluteError{Pathname: ""}},
 | |
| 	}
 | |
| 
 | |
| 	for _, tc := range testCases {
 | |
| 		t.Run(tc.name, func(t *testing.T) {
 | |
| 			t.Parallel()
 | |
| 
 | |
| 			got, err := NewAbs(tc.pathname)
 | |
| 			if !reflect.DeepEqual(got, tc.want) {
 | |
| 				t.Errorf("NewAbs: %#v, want %#v", got, tc.want)
 | |
| 			}
 | |
| 			if !errors.Is(err, tc.wantErr) {
 | |
| 				t.Errorf("NewAbs: error = %v, want %v", err, tc.wantErr)
 | |
| 			}
 | |
| 		})
 | |
| 	}
 | |
| 
 | |
| 	t.Run("must", func(t *testing.T) {
 | |
| 		t.Parallel()
 | |
| 
 | |
| 		defer func() {
 | |
| 			wantPanic := `path "etc" is not absolute`
 | |
| 
 | |
| 			if r := recover(); r != wantPanic {
 | |
| 				t.Errorf("MustAbs: panic = %v; want %v", r, wantPanic)
 | |
| 			}
 | |
| 		}()
 | |
| 
 | |
| 		MustAbs("etc")
 | |
| 	})
 | |
| }
 | |
| 
 | |
| func TestAbsoluteString(t *testing.T) {
 | |
| 	t.Run("passthrough", func(t *testing.T) {
 | |
| 		t.Parallel()
 | |
| 
 | |
| 		pathname := "/etc"
 | |
| 		if got := unsafeAbs(pathname).String(); got != pathname {
 | |
| 			t.Errorf("String: %q, want %q", got, pathname)
 | |
| 		}
 | |
| 	})
 | |
| 
 | |
| 	t.Run("zero", func(t *testing.T) {
 | |
| 		t.Parallel()
 | |
| 
 | |
| 		defer func() {
 | |
| 			wantPanic := "attempted use of zero Absolute"
 | |
| 
 | |
| 			if r := recover(); r != wantPanic {
 | |
| 				t.Errorf("String: panic = %v, want %v", r, wantPanic)
 | |
| 			}
 | |
| 		}()
 | |
| 
 | |
| 		panic(new(Absolute).String())
 | |
| 	})
 | |
| }
 | |
| 
 | |
| func TestAbsoluteIs(t *testing.T) {
 | |
| 	t.Parallel()
 | |
| 
 | |
| 	testCases := []struct {
 | |
| 		name string
 | |
| 		a, v *Absolute
 | |
| 		want bool
 | |
| 	}{
 | |
| 		{"nil", (*Absolute)(nil), (*Absolute)(nil), true},
 | |
| 		{"nil a", (*Absolute)(nil), MustAbs("/"), false},
 | |
| 		{"nil v", MustAbs("/"), (*Absolute)(nil), false},
 | |
| 		{"zero", new(Absolute), new(Absolute), false},
 | |
| 		{"zero a", new(Absolute), MustAbs("/"), false},
 | |
| 		{"zero v", MustAbs("/"), new(Absolute), false},
 | |
| 		{"equals", MustAbs("/"), MustAbs("/"), true},
 | |
| 	}
 | |
| 	for _, tc := range testCases {
 | |
| 		t.Run(tc.name, func(t *testing.T) {
 | |
| 			t.Parallel()
 | |
| 
 | |
| 			if got := tc.a.Is(tc.v); got != tc.want {
 | |
| 				t.Errorf("Is: %v, want %v", got, tc.want)
 | |
| 			}
 | |
| 		})
 | |
| 	}
 | |
| }
 | |
| 
 | |
| type sCheck struct {
 | |
| 	Pathname *Absolute `json:"val"`
 | |
| 	Magic    int       `json:"magic"`
 | |
| }
 | |
| 
 | |
| func TestCodecAbsolute(t *testing.T) {
 | |
| 	t.Parallel()
 | |
| 
 | |
| 	testCases := []struct {
 | |
| 		name string
 | |
| 		a    *Absolute
 | |
| 
 | |
| 		wantErr error
 | |
| 
 | |
| 		gob, sGob   string
 | |
| 		json, sJson string
 | |
| 	}{
 | |
| 		{"nil", nil, nil,
 | |
| 			"\x00", "\x00",
 | |
| 			`null`, `{"val":null,"magic":3236757504}`},
 | |
| 
 | |
| 		{"good", MustAbs("/etc"),
 | |
| 			nil,
 | |
| 			"\t\x7f\x05\x01\x02\xff\x82\x00\x00\x00\b\xff\x80\x00\x04/etc",
 | |
| 			",\xff\x83\x03\x01\x01\x06sCheck\x01\xff\x84\x00\x01\x02\x01\bPathname\x01\xff\x80\x00\x01\x05Magic\x01\x04\x00\x00\x00\t\x7f\x05\x01\x02\xff\x82\x00\x00\x00\x10\xff\x84\x01\x04/etc\x01\xfb\x01\x81\xda\x00\x00\x00",
 | |
| 
 | |
| 			`"/etc"`, `{"val":"/etc","magic":3236757504}`},
 | |
| 		{"not absolute", nil,
 | |
| 			&AbsoluteError{Pathname: "etc"},
 | |
| 			"\t\x7f\x05\x01\x02\xff\x82\x00\x00\x00\a\xff\x80\x00\x03etc",
 | |
| 			",\xff\x83\x03\x01\x01\x06sCheck\x01\xff\x84\x00\x01\x02\x01\bPathname\x01\xff\x80\x00\x01\x05Magic\x01\x04\x00\x00\x00\t\x7f\x05\x01\x02\xff\x82\x00\x00\x00\x0f\xff\x84\x01\x03etc\x01\xfb\x01\x81\xda\x00\x00\x00",
 | |
| 
 | |
| 			`"etc"`, `{"val":"etc","magic":3236757504}`},
 | |
| 		{"zero", nil,
 | |
| 			new(AbsoluteError),
 | |
| 			"\t\x7f\x05\x01\x02\xff\x82\x00\x00\x00\x04\xff\x80\x00\x00",
 | |
| 			",\xff\x83\x03\x01\x01\x06sCheck\x01\xff\x84\x00\x01\x02\x01\bPathname\x01\xff\x80\x00\x01\x05Magic\x01\x04\x00\x00\x00\t\x7f\x05\x01\x02\xff\x82\x00\x00\x00\f\xff\x84\x01\x00\x01\xfb\x01\x81\xda\x00\x00\x00",
 | |
| 			`""`, `{"val":"","magic":3236757504}`},
 | |
| 	}
 | |
| 
 | |
| 	for _, tc := range testCases {
 | |
| 		t.Run(tc.name, func(t *testing.T) {
 | |
| 			t.Parallel()
 | |
| 
 | |
| 			t.Run("gob", func(t *testing.T) {
 | |
| 				if tc.gob == "\x00" && tc.sGob == "\x00" {
 | |
| 					// these values mark the current test to skip gob
 | |
| 					return
 | |
| 				}
 | |
| 				t.Parallel()
 | |
| 
 | |
| 				t.Run("encode", func(t *testing.T) {
 | |
| 					t.Parallel()
 | |
| 
 | |
| 					// encode is unchecked
 | |
| 					if errors.Is(tc.wantErr, syscall.EINVAL) {
 | |
| 						return
 | |
| 					}
 | |
| 
 | |
| 					{
 | |
| 						buf := new(bytes.Buffer)
 | |
| 						err := gob.NewEncoder(buf).Encode(tc.a)
 | |
| 						if !errors.Is(err, tc.wantErr) {
 | |
| 							t.Errorf("Encode: error = %v, want %v", err, tc.wantErr)
 | |
| 						}
 | |
| 						if tc.wantErr != nil {
 | |
| 							goto checkSEncode
 | |
| 						}
 | |
| 						if buf.String() != tc.gob {
 | |
| 							t.Errorf("Encode:\n%q\nwant:\n%q", buf.String(), tc.gob)
 | |
| 						}
 | |
| 					}
 | |
| 
 | |
| 				checkSEncode:
 | |
| 					{
 | |
| 						buf := new(bytes.Buffer)
 | |
| 						err := gob.NewEncoder(buf).Encode(&sCheck{tc.a, syscall.MS_MGC_VAL})
 | |
| 						if !errors.Is(err, tc.wantErr) {
 | |
| 							t.Errorf("Encode: error = %v, want %v", err, tc.wantErr)
 | |
| 						}
 | |
| 						if tc.wantErr != nil {
 | |
| 							return
 | |
| 						}
 | |
| 						if buf.String() != tc.sGob {
 | |
| 							t.Errorf("Encode:\n%q\nwant:\n%q", buf.String(), tc.sGob)
 | |
| 						}
 | |
| 					}
 | |
| 				})
 | |
| 
 | |
| 				t.Run("decode", func(t *testing.T) {
 | |
| 					t.Parallel()
 | |
| 
 | |
| 					{
 | |
| 						var gotA *Absolute
 | |
| 						err := gob.NewDecoder(strings.NewReader(tc.gob)).Decode(&gotA)
 | |
| 						if !errors.Is(err, tc.wantErr) {
 | |
| 							t.Errorf("Decode: error = %v, want %v", err, tc.wantErr)
 | |
| 						}
 | |
| 						if tc.wantErr != nil {
 | |
| 							goto checkSDecode
 | |
| 						}
 | |
| 						if !reflect.DeepEqual(tc.a, gotA) {
 | |
| 							t.Errorf("Decode: %#v, want %#v", tc.a, gotA)
 | |
| 						}
 | |
| 					}
 | |
| 
 | |
| 				checkSDecode:
 | |
| 					{
 | |
| 						var gotSCheck sCheck
 | |
| 						err := gob.NewDecoder(strings.NewReader(tc.sGob)).Decode(&gotSCheck)
 | |
| 						if !errors.Is(err, tc.wantErr) {
 | |
| 							t.Errorf("Decode: error = %v, want %v", err, tc.wantErr)
 | |
| 						}
 | |
| 						if tc.wantErr != nil {
 | |
| 							return
 | |
| 						}
 | |
| 						want := sCheck{tc.a, syscall.MS_MGC_VAL}
 | |
| 						if !reflect.DeepEqual(gotSCheck, want) {
 | |
| 							t.Errorf("Decode: %#v, want %#v", gotSCheck, want)
 | |
| 						}
 | |
| 					}
 | |
| 				})
 | |
| 
 | |
| 			})
 | |
| 
 | |
| 			t.Run("json", func(t *testing.T) {
 | |
| 				t.Parallel()
 | |
| 
 | |
| 				t.Run("marshal", func(t *testing.T) {
 | |
| 					t.Parallel()
 | |
| 
 | |
| 					// marshal is unchecked
 | |
| 					if errors.Is(tc.wantErr, syscall.EINVAL) {
 | |
| 						return
 | |
| 					}
 | |
| 
 | |
| 					{
 | |
| 						d, err := json.Marshal(tc.a)
 | |
| 						if !errors.Is(err, tc.wantErr) {
 | |
| 							t.Errorf("Marshal: error = %v, want %v", err, tc.wantErr)
 | |
| 						}
 | |
| 						if tc.wantErr != nil {
 | |
| 							goto checkSMarshal
 | |
| 						}
 | |
| 						if string(d) != tc.json {
 | |
| 							t.Errorf("Marshal:\n%s\nwant:\n%s", string(d), tc.json)
 | |
| 						}
 | |
| 					}
 | |
| 
 | |
| 				checkSMarshal:
 | |
| 					{
 | |
| 						d, err := json.Marshal(&sCheck{tc.a, syscall.MS_MGC_VAL})
 | |
| 						if !errors.Is(err, tc.wantErr) {
 | |
| 							t.Errorf("Marshal: error = %v, want %v", err, tc.wantErr)
 | |
| 						}
 | |
| 						if tc.wantErr != nil {
 | |
| 							return
 | |
| 						}
 | |
| 						if string(d) != tc.sJson {
 | |
| 							t.Errorf("Marshal:\n%s\nwant:\n%s", string(d), tc.sJson)
 | |
| 						}
 | |
| 					}
 | |
| 				})
 | |
| 
 | |
| 				t.Run("unmarshal", func(t *testing.T) {
 | |
| 					t.Parallel()
 | |
| 
 | |
| 					{
 | |
| 						var gotA *Absolute
 | |
| 						err := json.Unmarshal([]byte(tc.json), &gotA)
 | |
| 						if !errors.Is(err, tc.wantErr) {
 | |
| 							t.Errorf("Unmarshal: error = %v, want %v", err, tc.wantErr)
 | |
| 						}
 | |
| 						if tc.wantErr != nil {
 | |
| 							goto checkSUnmarshal
 | |
| 						}
 | |
| 						if !reflect.DeepEqual(tc.a, gotA) {
 | |
| 							t.Errorf("Unmarshal: %#v, want %#v", tc.a, gotA)
 | |
| 						}
 | |
| 					}
 | |
| 
 | |
| 				checkSUnmarshal:
 | |
| 					{
 | |
| 						var gotSCheck sCheck
 | |
| 						err := json.Unmarshal([]byte(tc.sJson), &gotSCheck)
 | |
| 						if !errors.Is(err, tc.wantErr) {
 | |
| 							t.Errorf("Unmarshal: error = %v, want %v", err, tc.wantErr)
 | |
| 						}
 | |
| 						if tc.wantErr != nil {
 | |
| 							return
 | |
| 						}
 | |
| 						want := sCheck{tc.a, syscall.MS_MGC_VAL}
 | |
| 						if !reflect.DeepEqual(gotSCheck, want) {
 | |
| 							t.Errorf("Unmarshal: %#v, want %#v", gotSCheck, want)
 | |
| 						}
 | |
| 					}
 | |
| 				})
 | |
| 			})
 | |
| 		})
 | |
| 	}
 | |
| 
 | |
| 	t.Run("json passthrough", func(t *testing.T) {
 | |
| 		t.Parallel()
 | |
| 
 | |
| 		wantErr := "invalid character ':' looking for beginning of value"
 | |
| 		if err := new(Absolute).UnmarshalJSON([]byte(":3")); err == nil || err.Error() != wantErr {
 | |
| 			t.Errorf("UnmarshalJSON: error = %v, want %s", err, wantErr)
 | |
| 		}
 | |
| 	})
 | |
| }
 | |
| 
 | |
| func TestAbsoluteWrap(t *testing.T) {
 | |
| 	t.Parallel()
 | |
| 
 | |
| 	t.Run("join", func(t *testing.T) {
 | |
| 		t.Parallel()
 | |
| 
 | |
| 		want := "/etc/nix/nix.conf"
 | |
| 		if got := MustAbs("/etc").Append("nix", "nix.conf"); got.String() != want {
 | |
| 			t.Errorf("Append: %q, want %q", got, want)
 | |
| 		}
 | |
| 	})
 | |
| 
 | |
| 	t.Run("dir", func(t *testing.T) {
 | |
| 		t.Parallel()
 | |
| 
 | |
| 		want := "/"
 | |
| 		if got := MustAbs("/etc").Dir(); got.String() != want {
 | |
| 			t.Errorf("Dir: %q, want %q", got, want)
 | |
| 		}
 | |
| 	})
 | |
| 
 | |
| 	t.Run("sort", func(t *testing.T) {
 | |
| 		t.Parallel()
 | |
| 
 | |
| 		want := []*Absolute{MustAbs("/etc"), MustAbs("/proc"), MustAbs("/sys")}
 | |
| 		got := []*Absolute{MustAbs("/proc"), MustAbs("/sys"), MustAbs("/etc")}
 | |
| 		SortAbs(got)
 | |
| 		if !reflect.DeepEqual(got, want) {
 | |
| 			t.Errorf("SortAbs: %#v, want %#v", got, want)
 | |
| 		}
 | |
| 	})
 | |
| 
 | |
| 	t.Run("compact", func(t *testing.T) {
 | |
| 		t.Parallel()
 | |
| 
 | |
| 		want := []*Absolute{MustAbs("/etc"), MustAbs("/proc"), MustAbs("/sys")}
 | |
| 		if got := CompactAbs([]*Absolute{MustAbs("/etc"), MustAbs("/proc"), MustAbs("/proc"), MustAbs("/sys")}); !reflect.DeepEqual(got, want) {
 | |
| 			t.Errorf("CompactAbs: %#v, want %#v", got, want)
 | |
| 		}
 | |
| 	})
 | |
| }
 |