summaryrefslogtreecommitdiff
path: root/internal/namespace/bootstrap_test.go
blob: eff04e28e08556d89fd9f5df9517ef7ef52d1c5c (plain)
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
//go:build linux

package namespace

import (
	"os"
	"strings"
	"testing"
)

func TestPrepareBootstrap(t *testing.T) {
	t.Parallel()

	// We are testing the environment and argument preparation.
	// This will actually open some FDs (memfd, netns, socket),
	// which is fine for an integration-style unit test.
	config, err := PrepareBootstrap()
	if err != nil {
		t.Fatalf("PrepareBootstrap failed: %v", err)
	}

	// 1. Verify ExecPath is correct (should be a fd in /proc/self/fd)
	if !strings.HasPrefix(config.ExecPath, "/proc/self/fd/") {
		t.Errorf("expected ExecPath to be in /proc/self/fd/, got %s", config.ExecPath)
	}

	// 2. Verify Arguments are preserved and expanded
	if len(config.Args) == 0 || config.Args[0] == "" {
		t.Error("args should not be empty")
	}

	// 3. Verify Host NetNS FD is present in Env
	foundNetNs := false
	for _, env := range config.Env {
		if strings.HasPrefix(env, "WG_WRAP_HOST_NETNS_FD=") {
			foundNetNs = true
			break
		}
	}
	if !foundNetNs {
		t.Error("WG_WRAP_HOST_NETNS_FD missing from environment")
	}

	// 4. Verify Host Socket FD is present in Env
	foundSocket := false
	for _, env := range config.Env {
		if strings.HasPrefix(env, "WG_WRAP_HOST_SOCKET_FD=") {
			foundSocket = true
			break
		}
	}
	if !foundSocket {
		t.Error("WG_WRAP_HOST_SOCKET_FD missing from environment")
	}

	// 5. Verify FDs are tracked for cleanup
	if len(config.Fds) < 2 {
		t.Errorf("expected at least 2 FDs (launcher, netns), got %d", len(config.Fds))
	}
}

func TestPrepareBootstrapJoin(t *testing.T) {
	t.Parallel()

	targetPid := 1234
	config, err := PrepareBootstrapJoin(targetPid)
	if err != nil {
		t.Fatalf("PrepareBootstrapJoin failed: %v", err)
	}

	// 1. Verify Join PID is present in Env
	foundJoinPid := false
	expectedPidEnv := "WG_WRAP_JOIN_PID=1234"
	for _, env := range config.Env {
		if env == expectedPidEnv {
			foundJoinPid = true
			break
		}
	}
	if !foundJoinPid {
		t.Errorf("expected %s in environment", expectedPidEnv)
	}

	// 2. Verify Joined flag is present
	foundJoined := false
	for _, env := range config.Env {
		if env == "WG_WRAP_JOINED=1" {
			foundJoined = true
			break
		}
	}
	if !foundJoined {
		t.Error("WG_WRAP_JOINED=1 missing from environment")
	}
}

func TestPrepareBootstrap_NullByteValidation(t *testing.T) {
	// Temporarily inject a null byte into os.Args to test validation
	// Note: os.Args is a slice, so we can modify it.
	oldArgs := os.Args
	defer func() { os.Args = oldArgs }()

	os.Args = append(os.Args, "bad\x00arg")

	_, err := PrepareBootstrap()
	if err == nil {
		t.Error("expected error when argument contains null byte, got nil")
	} else if !strings.Contains(err.Error(), "contains null byte") {
		t.Errorf("expected null byte error, got: %v", err)
	}
}