File: suite_test.go

package info (click to toggle)
golang-github-containers-gvisor-tap-vsocks 0.8.1-3
  • links: PTS, VCS
  • area: main
  • in suites: experimental, forky, sid, trixie
  • size: 800 kB
  • sloc: sh: 95; makefile: 59
file content (123 lines) | stat: -rw-r--r-- 2,536 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
// +build windows

package e2e

import (
	"flag"
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"syscall"
	"testing"
	"time"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

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
	fmt.Sscanf(string(contents), "%d:%d", &pid, &tid)
	return pid, tid, nil
}

func sendQuit(tid uint32) {
	user32 := syscall.NewLazyDLL("user32.dll")
	postMessage := user32.NewProc("PostThreadMessageW")
	postMessage.Call(uintptr(tid), WM_QUIT, 0, 0)
}

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
	}
}