system/acl: update test log messages
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				Test / Create distribution (push) Successful in 33s
				
			
		
			
				
	
				Test / Sandbox (push) Successful in 1m46s
				
			
		
			
				
	
				Test / Hakurei (push) Successful in 3m19s
				
			
		
			
				
	
				Test / Hpkg (push) Successful in 3m45s
				
			
		
			
				
	
				Test / Sandbox (race detector) (push) Successful in 5m5s
				
			
		
			
				
	
				Test / Hakurei (race detector) (push) Successful in 3m8s
				
			
		
			
				
	
				Test / Flake checks (push) Successful in 1m34s
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	Test / Create distribution (push) Successful in 33s
				
			Test / Sandbox (push) Successful in 1m46s
				
			Test / Hakurei (push) Successful in 3m19s
				
			Test / Hpkg (push) Successful in 3m45s
				
			Test / Sandbox (race detector) (push) Successful in 5m5s
				
			Test / Hakurei (race detector) (push) Successful in 3m8s
				
			Test / Flake checks (push) Successful in 1m34s
				
			Most of these were never updated after UpdatePerm was renamed to Update. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
		
							parent
							
								
									08eeafe817
								
							
						
					
					
						commit
						6aa431d57a
					
				| @ -1,156 +0,0 @@ | |||||||
| package acl_test |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"bufio" |  | ||||||
| 	"bytes" |  | ||||||
| 	"errors" |  | ||||||
| 	"fmt" |  | ||||||
| 	"io" |  | ||||||
| 	"os/exec" |  | ||||||
| 	"strconv" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| type ( |  | ||||||
| 	getFAclInvocation struct { |  | ||||||
| 		cmd *exec.Cmd |  | ||||||
| 		val []*getFAclResp |  | ||||||
| 		pe  []error |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	getFAclResp struct { |  | ||||||
| 		typ  fAclType |  | ||||||
| 		cred int32 |  | ||||||
| 		val  fAclPerm |  | ||||||
| 
 |  | ||||||
| 		raw []byte |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	fAclPerm uintptr |  | ||||||
| 	fAclType uint8 |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| const fAclBufSize = 16 |  | ||||||
| 
 |  | ||||||
| const ( |  | ||||||
| 	fAclPermRead fAclPerm = 1 << iota |  | ||||||
| 	fAclPermWrite |  | ||||||
| 	fAclPermExecute |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| const ( |  | ||||||
| 	fAclTypeUser fAclType = iota |  | ||||||
| 	fAclTypeGroup |  | ||||||
| 	fAclTypeMask |  | ||||||
| 	fAclTypeOther |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| func (c *getFAclInvocation) run(name string) error { |  | ||||||
| 	if c.cmd != nil { |  | ||||||
| 		panic("attempted to run twice") |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	c.cmd = exec.Command("getfacl", "--omit-header", "--absolute-names", "--numeric", name) |  | ||||||
| 
 |  | ||||||
| 	scanErr := make(chan error, 1) |  | ||||||
| 	if p, err := c.cmd.StdoutPipe(); err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} else { |  | ||||||
| 		go c.parse(p, scanErr) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if err := c.cmd.Start(); err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return errors.Join(<-scanErr, c.cmd.Wait()) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (c *getFAclInvocation) parse(pipe io.Reader, scanErr chan error) { |  | ||||||
| 	c.val = make([]*getFAclResp, 0, 4+fAclBufSize) |  | ||||||
| 
 |  | ||||||
| 	s := bufio.NewScanner(pipe) |  | ||||||
| 	for s.Scan() { |  | ||||||
| 		fields := bytes.SplitN(s.Bytes(), []byte{':'}, 3) |  | ||||||
| 		if len(fields) != 3 { |  | ||||||
| 			continue |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		resp := getFAclResp{} |  | ||||||
| 
 |  | ||||||
| 		switch string(fields[0]) { |  | ||||||
| 		case "user": |  | ||||||
| 			resp.typ = fAclTypeUser |  | ||||||
| 		case "group": |  | ||||||
| 			resp.typ = fAclTypeGroup |  | ||||||
| 		case "mask": |  | ||||||
| 			resp.typ = fAclTypeMask |  | ||||||
| 		case "other": |  | ||||||
| 			resp.typ = fAclTypeOther |  | ||||||
| 		default: |  | ||||||
| 			c.pe = append(c.pe, fmt.Errorf("unknown type %s", string(fields[0]))) |  | ||||||
| 			continue |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		if len(fields[1]) == 0 { |  | ||||||
| 			resp.cred = -1 |  | ||||||
| 		} else { |  | ||||||
| 			if cred, err := strconv.Atoi(string(fields[1])); err != nil { |  | ||||||
| 				c.pe = append(c.pe, err) |  | ||||||
| 				continue |  | ||||||
| 			} else { |  | ||||||
| 				resp.cred = int32(cred) |  | ||||||
| 				if resp.cred < 0 { |  | ||||||
| 					c.pe = append(c.pe, fmt.Errorf("credential %d out of range", resp.cred)) |  | ||||||
| 					continue |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		if len(fields[2]) != 3 { |  | ||||||
| 			c.pe = append(c.pe, fmt.Errorf("invalid perm length %d", len(fields[2]))) |  | ||||||
| 			continue |  | ||||||
| 		} else { |  | ||||||
| 			switch fields[2][0] { |  | ||||||
| 			case 'r': |  | ||||||
| 				resp.val |= fAclPermRead |  | ||||||
| 			case '-': |  | ||||||
| 			default: |  | ||||||
| 				c.pe = append(c.pe, fmt.Errorf("invalid perm %v", fields[2][0])) |  | ||||||
| 				continue |  | ||||||
| 			} |  | ||||||
| 			switch fields[2][1] { |  | ||||||
| 			case 'w': |  | ||||||
| 				resp.val |= fAclPermWrite |  | ||||||
| 			case '-': |  | ||||||
| 			default: |  | ||||||
| 				c.pe = append(c.pe, fmt.Errorf("invalid perm %v", fields[2][1])) |  | ||||||
| 				continue |  | ||||||
| 			} |  | ||||||
| 			switch fields[2][2] { |  | ||||||
| 			case 'x': |  | ||||||
| 				resp.val |= fAclPermExecute |  | ||||||
| 			case '-': |  | ||||||
| 			default: |  | ||||||
| 				c.pe = append(c.pe, fmt.Errorf("invalid perm %v", fields[2][2])) |  | ||||||
| 				continue |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		resp.raw = make([]byte, len(s.Bytes())) |  | ||||||
| 		copy(resp.raw, s.Bytes()) |  | ||||||
| 		c.val = append(c.val, &resp) |  | ||||||
| 	} |  | ||||||
| 	scanErr <- s.Err() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (r *getFAclResp) String() string { |  | ||||||
| 	if r.raw != nil && len(r.raw) > 0 { |  | ||||||
| 		return string(r.raw) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return "(user-initialised resp value)" |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (r *getFAclResp) equals(typ fAclType, cred int32, val fAclPerm) bool { |  | ||||||
| 	return r.typ == typ && r.cred == cred && r.val == val |  | ||||||
| } |  | ||||||
| @ -1,10 +1,16 @@ | |||||||
| package acl_test | package acl_test | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
|  | 	"bufio" | ||||||
|  | 	"bytes" | ||||||
| 	"errors" | 	"errors" | ||||||
|  | 	"fmt" | ||||||
|  | 	"io" | ||||||
| 	"os" | 	"os" | ||||||
|  | 	"os/exec" | ||||||
| 	"path" | 	"path" | ||||||
| 	"reflect" | 	"reflect" | ||||||
|  | 	"strconv" | ||||||
| 	"testing" | 	"testing" | ||||||
| 
 | 
 | ||||||
| 	"hakurei.app/system/acl" | 	"hakurei.app/system/acl" | ||||||
| @ -17,7 +23,7 @@ var ( | |||||||
| 	cred = int32(os.Geteuid()) | 	cred = int32(os.Geteuid()) | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func TestUpdatePerm(t *testing.T) { | func TestUpdate(t *testing.T) { | ||||||
| 	if os.Getenv("GO_TEST_SKIP_ACL") == "1" { | 	if os.Getenv("GO_TEST_SKIP_ACL") == "1" { | ||||||
| 		t.Log("acl test skipped") | 		t.Log("acl test skipped") | ||||||
| 		t.SkipNow() | 		t.SkipNow() | ||||||
| @ -48,19 +54,19 @@ func TestUpdatePerm(t *testing.T) { | |||||||
| 
 | 
 | ||||||
| 	t.Run("default clear mask", func(t *testing.T) { | 	t.Run("default clear mask", func(t *testing.T) { | ||||||
| 		if err := acl.Update(testFilePath, uid); err != nil { | 		if err := acl.Update(testFilePath, uid); err != nil { | ||||||
| 			t.Fatalf("UpdatePerm: error = %v", err) | 			t.Fatalf("Update: error = %v", err) | ||||||
| 		} | 		} | ||||||
| 		if cur = getfacl(t, testFilePath); len(cur) != 4 { | 		if cur = getfacl(t, testFilePath); len(cur) != 4 { | ||||||
| 			t.Fatalf("UpdatePerm: %v", cur) | 			t.Fatalf("Update: %v", cur) | ||||||
| 		} | 		} | ||||||
| 	}) | 	}) | ||||||
| 
 | 
 | ||||||
| 	t.Run("default clear consistency", func(t *testing.T) { | 	t.Run("default clear consistency", func(t *testing.T) { | ||||||
| 		if err := acl.Update(testFilePath, uid); err != nil { | 		if err := acl.Update(testFilePath, uid); err != nil { | ||||||
| 			t.Fatalf("UpdatePerm: error = %v", err) | 			t.Fatalf("Update: error = %v", err) | ||||||
| 		} | 		} | ||||||
| 		if val := getfacl(t, testFilePath); !reflect.DeepEqual(val, cur) { | 		if val := getfacl(t, testFilePath); !reflect.DeepEqual(val, cur) { | ||||||
| 			t.Fatalf("UpdatePerm: %v, want %v", val, cur) | 			t.Fatalf("Update: %v, want %v", val, cur) | ||||||
| 		} | 		} | ||||||
| 	}) | 	}) | ||||||
| 
 | 
 | ||||||
| @ -77,26 +83,171 @@ func testUpdate(t *testing.T, testFilePath, name string, cur []*getFAclResp, val | |||||||
| 	t.Run(name, func(t *testing.T) { | 	t.Run(name, func(t *testing.T) { | ||||||
| 		t.Cleanup(func() { | 		t.Cleanup(func() { | ||||||
| 			if err := acl.Update(testFilePath, uid); err != nil { | 			if err := acl.Update(testFilePath, uid); err != nil { | ||||||
| 				t.Fatalf("UpdatePerm: error = %v", err) | 				t.Fatalf("Update: error = %v", err) | ||||||
| 			} | 			} | ||||||
| 			if v := getfacl(t, testFilePath); !reflect.DeepEqual(v, cur) { | 			if v := getfacl(t, testFilePath); !reflect.DeepEqual(v, cur) { | ||||||
| 				t.Fatalf("UpdatePerm: %v, want %v", v, cur) | 				t.Fatalf("Update: %v, want %v", v, cur) | ||||||
| 			} | 			} | ||||||
| 		}) | 		}) | ||||||
| 
 | 
 | ||||||
| 		if err := acl.Update(testFilePath, uid, perms...); err != nil { | 		if err := acl.Update(testFilePath, uid, perms...); err != nil { | ||||||
| 			t.Fatalf("UpdatePerm: error = %v", err) | 			t.Fatalf("Update: error = %v", err) | ||||||
| 		} | 		} | ||||||
| 		r := respByCred(getfacl(t, testFilePath), fAclTypeUser, cred) | 		r := respByCred(getfacl(t, testFilePath), fAclTypeUser, cred) | ||||||
| 		if r == nil { | 		if r == nil { | ||||||
| 			t.Fatalf("UpdatePerm did not add an ACL entry") | 			t.Fatalf("Update did not add an ACL entry") | ||||||
| 		} | 		} | ||||||
| 		if !r.equals(fAclTypeUser, cred, val) { | 		if !r.equals(fAclTypeUser, cred, val) { | ||||||
| 			t.Fatalf("UpdatePerm(%s) = %s", name, r) | 			t.Fatalf("Update(%s) = %s", name, r) | ||||||
| 		} | 		} | ||||||
| 	}) | 	}) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | type ( | ||||||
|  | 	getFAclInvocation struct { | ||||||
|  | 		cmd *exec.Cmd | ||||||
|  | 		val []*getFAclResp | ||||||
|  | 		pe  []error | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	getFAclResp struct { | ||||||
|  | 		typ  fAclType | ||||||
|  | 		cred int32 | ||||||
|  | 		val  fAclPerm | ||||||
|  | 
 | ||||||
|  | 		raw []byte | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	fAclPerm uintptr | ||||||
|  | 	fAclType uint8 | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | const fAclBufSize = 16 | ||||||
|  | 
 | ||||||
|  | const ( | ||||||
|  | 	fAclPermRead fAclPerm = 1 << iota | ||||||
|  | 	fAclPermWrite | ||||||
|  | 	fAclPermExecute | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | const ( | ||||||
|  | 	fAclTypeUser fAclType = iota | ||||||
|  | 	fAclTypeGroup | ||||||
|  | 	fAclTypeMask | ||||||
|  | 	fAclTypeOther | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func (c *getFAclInvocation) run(name string) error { | ||||||
|  | 	if c.cmd != nil { | ||||||
|  | 		panic("attempted to run twice") | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	c.cmd = exec.Command("getfacl", "--omit-header", "--absolute-names", "--numeric", name) | ||||||
|  | 
 | ||||||
|  | 	scanErr := make(chan error, 1) | ||||||
|  | 	if p, err := c.cmd.StdoutPipe(); err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} else { | ||||||
|  | 		go c.parse(p, scanErr) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if err := c.cmd.Start(); err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return errors.Join(<-scanErr, c.cmd.Wait()) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (c *getFAclInvocation) parse(pipe io.Reader, scanErr chan error) { | ||||||
|  | 	c.val = make([]*getFAclResp, 0, 4+fAclBufSize) | ||||||
|  | 
 | ||||||
|  | 	s := bufio.NewScanner(pipe) | ||||||
|  | 	for s.Scan() { | ||||||
|  | 		fields := bytes.SplitN(s.Bytes(), []byte{':'}, 3) | ||||||
|  | 		if len(fields) != 3 { | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		resp := getFAclResp{} | ||||||
|  | 
 | ||||||
|  | 		switch string(fields[0]) { | ||||||
|  | 		case "user": | ||||||
|  | 			resp.typ = fAclTypeUser | ||||||
|  | 		case "group": | ||||||
|  | 			resp.typ = fAclTypeGroup | ||||||
|  | 		case "mask": | ||||||
|  | 			resp.typ = fAclTypeMask | ||||||
|  | 		case "other": | ||||||
|  | 			resp.typ = fAclTypeOther | ||||||
|  | 		default: | ||||||
|  | 			c.pe = append(c.pe, fmt.Errorf("unknown type %s", string(fields[0]))) | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if len(fields[1]) == 0 { | ||||||
|  | 			resp.cred = -1 | ||||||
|  | 		} else { | ||||||
|  | 			if cred, err := strconv.Atoi(string(fields[1])); err != nil { | ||||||
|  | 				c.pe = append(c.pe, err) | ||||||
|  | 				continue | ||||||
|  | 			} else { | ||||||
|  | 				resp.cred = int32(cred) | ||||||
|  | 				if resp.cred < 0 { | ||||||
|  | 					c.pe = append(c.pe, fmt.Errorf("credential %d out of range", resp.cred)) | ||||||
|  | 					continue | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if len(fields[2]) != 3 { | ||||||
|  | 			c.pe = append(c.pe, fmt.Errorf("invalid perm length %d", len(fields[2]))) | ||||||
|  | 			continue | ||||||
|  | 		} else { | ||||||
|  | 			switch fields[2][0] { | ||||||
|  | 			case 'r': | ||||||
|  | 				resp.val |= fAclPermRead | ||||||
|  | 			case '-': | ||||||
|  | 			default: | ||||||
|  | 				c.pe = append(c.pe, fmt.Errorf("invalid perm %v", fields[2][0])) | ||||||
|  | 				continue | ||||||
|  | 			} | ||||||
|  | 			switch fields[2][1] { | ||||||
|  | 			case 'w': | ||||||
|  | 				resp.val |= fAclPermWrite | ||||||
|  | 			case '-': | ||||||
|  | 			default: | ||||||
|  | 				c.pe = append(c.pe, fmt.Errorf("invalid perm %v", fields[2][1])) | ||||||
|  | 				continue | ||||||
|  | 			} | ||||||
|  | 			switch fields[2][2] { | ||||||
|  | 			case 'x': | ||||||
|  | 				resp.val |= fAclPermExecute | ||||||
|  | 			case '-': | ||||||
|  | 			default: | ||||||
|  | 				c.pe = append(c.pe, fmt.Errorf("invalid perm %v", fields[2][2])) | ||||||
|  | 				continue | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		resp.raw = make([]byte, len(s.Bytes())) | ||||||
|  | 		copy(resp.raw, s.Bytes()) | ||||||
|  | 		c.val = append(c.val, &resp) | ||||||
|  | 	} | ||||||
|  | 	scanErr <- s.Err() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (r *getFAclResp) String() string { | ||||||
|  | 	if r.raw != nil && len(r.raw) > 0 { | ||||||
|  | 		return string(r.raw) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return "(user-initialised resp value)" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (r *getFAclResp) equals(typ fAclType, cred int32, val fAclPerm) bool { | ||||||
|  | 	return r.typ == typ && r.cred == cred && r.val == val | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func getfacl(t *testing.T, name string) []*getFAclResp { | func getfacl(t *testing.T, name string) []*getFAclResp { | ||||||
| 	c := new(getFAclInvocation) | 	c := new(getFAclInvocation) | ||||||
| 	if err := c.run(name); err != nil { | 	if err := c.run(name); err != nil { | ||||||
|  | |||||||
							
								
								
									
										30
									
								
								system/acl/perms_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								system/acl/perms_test.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,30 @@ | |||||||
|  | package acl_test | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"testing" | ||||||
|  | 
 | ||||||
|  | 	"hakurei.app/system/acl" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func TestPerms(t *testing.T) { | ||||||
|  | 	testCases := []struct { | ||||||
|  | 		name  string | ||||||
|  | 		perms acl.Perms | ||||||
|  | 	}{ | ||||||
|  | 		{"---", acl.Perms{}}, | ||||||
|  | 		{"r--", acl.Perms{acl.Read}}, | ||||||
|  | 		{"-w-", acl.Perms{acl.Write}}, | ||||||
|  | 		{"--x", acl.Perms{acl.Execute}}, | ||||||
|  | 		{"rw-", acl.Perms{acl.Read, acl.Read, acl.Write}}, | ||||||
|  | 		{"r-x", acl.Perms{acl.Read, acl.Execute, acl.Execute}}, | ||||||
|  | 		{"-wx", acl.Perms{acl.Write, acl.Write, acl.Execute, acl.Execute}}, | ||||||
|  | 		{"rwx", acl.Perms{acl.Read, acl.Write, acl.Execute}}, | ||||||
|  | 	} | ||||||
|  | 	for _, tc := range testCases { | ||||||
|  | 		t.Run(tc.name, func(t *testing.T) { | ||||||
|  | 			if got := tc.perms.String(); got != tc.name { | ||||||
|  | 				t.Errorf("String: %q, want %q", got, tc.name) | ||||||
|  | 			} | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | } | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user