mirror of
https://github.com/containers/gvisor-tap-vsock.git
synced 2025-10-05 16:56:50 +08:00
132 lines
2.7 KiB
Go
132 lines
2.7 KiB
Go
//go:build windows
|
|
// +build windows
|
|
|
|
package e2e
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"syscall"
|
|
"testing"
|
|
"time"
|
|
|
|
. "github.com/onsi/ginkgo"
|
|
. "github.com/onsi/gomega"
|
|
"github.com/sirupsen/logrus"
|
|
)
|
|
|
|
const (
|
|
WM_QUIT = 0x12
|
|
)
|
|
|
|
var (
|
|
tmpDir string
|
|
binDir string
|
|
keyFile string
|
|
winSshProxy string
|
|
tidFile string
|
|
)
|
|
|
|
func TestSuite(t *testing.T) {
|
|
RegisterFailHandler(Fail)
|
|
RunSpecs(t, "win-sshproxy suite")
|
|
}
|
|
|
|
func init() {
|
|
flag.StringVar(&tmpDir, "tmpDir", "../tmp", "temporary working directory")
|
|
flag.StringVar(&binDir, "bin", "../bin", "directory with compiled binaries")
|
|
_ = os.MkdirAll(tmpDir, 0755)
|
|
keyFile = filepath.Join(tmpDir, "id.key")
|
|
_ = os.WriteFile(keyFile, []byte(fakeHostKey), 0600)
|
|
winSshProxy = filepath.Join(binDir, "win-sshproxy.exe")
|
|
tidFile = filepath.Join(tmpDir, "win-sshproxy.tid")
|
|
}
|
|
|
|
var _ = BeforeSuite(func() {
|
|
startMockServer()
|
|
})
|
|
|
|
var _ = AfterSuite(func() {
|
|
stopMockServer()
|
|
})
|
|
|
|
func startProxy() error {
|
|
os.Remove(tidFile)
|
|
cmd := exec.Command(winSshProxy, "-debug", "test", tmpDir, "npipe:////./pipe/fake_docker_engine", "ssh://localhost:2134/run/podman/podman.sock", keyFile)
|
|
return cmd.Start()
|
|
}
|
|
|
|
func readTid() (uint32, uint32, error) {
|
|
contents, err := os.ReadFile(tidFile)
|
|
if err != nil {
|
|
return 0, 0, err
|
|
}
|
|
|
|
var pid, tid uint32
|
|
_, err = fmt.Sscanf(string(contents), "%d:%d", &pid, &tid)
|
|
if err != nil {
|
|
return 0, 0, err
|
|
}
|
|
return pid, tid, nil
|
|
}
|
|
|
|
func sendQuit(tid uint32) {
|
|
user32 := syscall.NewLazyDLL("user32.dll")
|
|
postMessage := user32.NewProc("PostThreadMessageW")
|
|
_, _, err := postMessage.Call(uintptr(tid), WM_QUIT, 0, 0)
|
|
if err != nil {
|
|
logrus.Errorf("Error posting quit message: %v", err)
|
|
}
|
|
}
|
|
|
|
func stopProxy(noKill bool) error {
|
|
pid, tid, err := readTid()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
proc, err := os.FindProcess(int(pid))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
sendQuit(tid)
|
|
state := waitTimeout(proc, 20*time.Second)
|
|
if state == nil || !state.Exited() {
|
|
if noKill {
|
|
return fmt.Errorf("proxy did not exit on request")
|
|
}
|
|
_ = proc.Kill()
|
|
state = waitTimeout(proc, 20*time.Second)
|
|
}
|
|
|
|
if state == nil || !state.Exited() {
|
|
return fmt.Errorf("Stop proxy failed: %d", pid)
|
|
}
|
|
|
|
_ = os.Remove(tidFile)
|
|
return nil
|
|
}
|
|
|
|
func waitTimeout(proc *os.Process, timeout time.Duration) *os.ProcessState {
|
|
return doTimeout(func(complete chan *os.ProcessState) {
|
|
state, _ := proc.Wait()
|
|
complete <- state
|
|
}, timeout)
|
|
}
|
|
|
|
func doTimeout(action func(complete chan *os.ProcessState), timeout time.Duration) *os.ProcessState {
|
|
complete := make(chan *os.ProcessState)
|
|
|
|
go action(complete)
|
|
select {
|
|
case <-time.After(timeout):
|
|
return nil
|
|
|
|
case state := <-complete:
|
|
return state
|
|
}
|
|
}
|