All checks were successful
		
		
	
	Test / Hpkg (push) Successful in 4m11s
				
			Test / Sandbox (race detector) (push) Successful in 4m13s
				
			Test / Hakurei (race detector) (push) Successful in 5m3s
				
			Test / Flake checks (push) Successful in 1m30s
				
			Test / Create distribution (push) Successful in 36s
				
			Test / Sandbox (push) Successful in 2m16s
				
			Test / Hakurei (push) Successful in 3m16s
				
			This increases flexibility of how caller wants to handle the I/O. Also makes it no longer rely on finalizer. Signed-off-by: Ophestra <cat@gensokyo.uk>
		
			
				
	
	
		
			126 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			126 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package container_test
 | 
						|
 | 
						|
import (
 | 
						|
	"encoding/gob"
 | 
						|
	"errors"
 | 
						|
	"os"
 | 
						|
	"slices"
 | 
						|
	"strconv"
 | 
						|
	"syscall"
 | 
						|
	"testing"
 | 
						|
 | 
						|
	"hakurei.app/container"
 | 
						|
)
 | 
						|
 | 
						|
func TestSetupReceive(t *testing.T) {
 | 
						|
	t.Run("not set", func(t *testing.T) {
 | 
						|
		const key = "TEST_ENV_NOT_SET"
 | 
						|
		{
 | 
						|
			v, ok := os.LookupEnv(key)
 | 
						|
			t.Cleanup(func() {
 | 
						|
				if ok {
 | 
						|
					if err := os.Setenv(key, v); err != nil {
 | 
						|
						t.Fatalf("Setenv: error = %v", err)
 | 
						|
					}
 | 
						|
				} else {
 | 
						|
					if err := os.Unsetenv(key); err != nil {
 | 
						|
						t.Fatalf("Unsetenv: error = %v", err)
 | 
						|
					}
 | 
						|
				}
 | 
						|
			})
 | 
						|
		}
 | 
						|
 | 
						|
		if _, err := container.Receive(key, nil, nil); !errors.Is(err, container.ErrReceiveEnv) {
 | 
						|
			t.Errorf("Receive: error = %v, want %v", err, container.ErrReceiveEnv)
 | 
						|
		}
 | 
						|
	})
 | 
						|
 | 
						|
	t.Run("format", func(t *testing.T) {
 | 
						|
		const key = "TEST_ENV_FORMAT"
 | 
						|
		t.Setenv(key, "")
 | 
						|
 | 
						|
		if _, err := container.Receive(key, nil, nil); !errors.Is(err, strconv.ErrSyntax) {
 | 
						|
			t.Errorf("Receive: error = %v, want %v", err, strconv.ErrSyntax)
 | 
						|
		}
 | 
						|
	})
 | 
						|
 | 
						|
	t.Run("range", func(t *testing.T) {
 | 
						|
		const key = "TEST_ENV_RANGE"
 | 
						|
		t.Setenv(key, "-1")
 | 
						|
 | 
						|
		if _, err := container.Receive(key, nil, nil); !errors.Is(err, syscall.EDOM) {
 | 
						|
			t.Errorf("Receive: error = %v, want %v", err, syscall.EDOM)
 | 
						|
		}
 | 
						|
	})
 | 
						|
 | 
						|
	t.Run("setup receive", func(t *testing.T) {
 | 
						|
		check := func(t *testing.T, useNilFdp bool) {
 | 
						|
			const key = "TEST_SETUP_RECEIVE"
 | 
						|
			payload := []int{syscall.MS_MGC_VAL, syscall.MS_MGC_MSK, syscall.MS_ASYNC, syscall.MS_ACTIVE}
 | 
						|
 | 
						|
			encoderDone := make(chan error, 1)
 | 
						|
			extraFiles := make([]*os.File, 0, 1)
 | 
						|
			deadline, _ := t.Deadline()
 | 
						|
			if fd, f, err := container.Setup(&extraFiles); err != nil {
 | 
						|
				t.Fatalf("Setup: error = %v", err)
 | 
						|
			} else if fd != 3 {
 | 
						|
				t.Fatalf("Setup: fd = %d, want 3", fd)
 | 
						|
			} else {
 | 
						|
				if err = f.SetDeadline(deadline); err != nil {
 | 
						|
					t.Fatal(err.Error())
 | 
						|
				}
 | 
						|
				go func() { encoderDone <- gob.NewEncoder(f).Encode(payload) }()
 | 
						|
			}
 | 
						|
 | 
						|
			if len(extraFiles) != 1 {
 | 
						|
				t.Fatalf("extraFiles: len = %v, want 1", len(extraFiles))
 | 
						|
			}
 | 
						|
 | 
						|
			var dupFd int
 | 
						|
			if fd, err := syscall.Dup(int(extraFiles[0].Fd())); err != nil {
 | 
						|
				t.Fatalf("Dup: error = %v", err)
 | 
						|
			} else {
 | 
						|
				syscall.CloseOnExec(fd)
 | 
						|
				dupFd = fd
 | 
						|
				t.Setenv(key, strconv.Itoa(fd))
 | 
						|
			}
 | 
						|
 | 
						|
			var (
 | 
						|
				gotPayload []int
 | 
						|
				fdp        *uintptr
 | 
						|
			)
 | 
						|
			if !useNilFdp {
 | 
						|
				fdp = new(uintptr)
 | 
						|
			}
 | 
						|
			var closeFile func() error
 | 
						|
			if f, err := container.Receive(key, &gotPayload, fdp); err != nil {
 | 
						|
				t.Fatalf("Receive: error = %v", err)
 | 
						|
			} else {
 | 
						|
				closeFile = f
 | 
						|
 | 
						|
				if !slices.Equal(payload, gotPayload) {
 | 
						|
					t.Errorf("Receive: %#v, want %#v", gotPayload, payload)
 | 
						|
				}
 | 
						|
			}
 | 
						|
			if !useNilFdp {
 | 
						|
				if int(*fdp) != dupFd {
 | 
						|
					t.Errorf("Fd: %d, want %d", *fdp, dupFd)
 | 
						|
				}
 | 
						|
			}
 | 
						|
 | 
						|
			if err := <-encoderDone; err != nil {
 | 
						|
				t.Errorf("Encode: error = %v", err)
 | 
						|
			}
 | 
						|
 | 
						|
			if closeFile != nil {
 | 
						|
				if err := closeFile(); err != nil {
 | 
						|
					t.Errorf("Close: error = %v", err)
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		t.Run("fp", func(t *testing.T) { check(t, false) })
 | 
						|
		t.Run("nil", func(t *testing.T) { check(t, true) })
 | 
						|
	})
 | 
						|
}
 |