diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/e2e/sharing_test.go | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/tests/e2e/sharing_test.go b/tests/e2e/sharing_test.go new file mode 100644 index 0000000..b0971f9 --- /dev/null +++ b/tests/e2e/sharing_test.go @@ -0,0 +1,108 @@ +package e2e + +import ( + "bufio" + "fmt" + "os" + "os/exec" + "path/filepath" + "strings" + "testing" +) + +func TestNamespaceSharing(t *testing.T) { + binaryPath, err := GetBinaryPath() + if err != nil { + t.Skipf("Skipping test: %v", err) + } + + tmpRuntimeDir := t.TempDir() + tmpConfigDir := t.TempDir() + profile := "sharing-test" + + // Write a valid dummy profile so it doesn't run in bare isolation + profilesDir := filepath.Join(tmpConfigDir, "wg-wrap", "profiles") + if err := os.MkdirAll(profilesDir, 0755); err != nil { + t.Fatal(err) + } + profileConfPath := filepath.Join(profilesDir, profile+".conf") + conf := `[Interface] +Address = 10.0.0.2/24 +PrivateKey = 0000000000000000000000000000000000000000000000000000000000000000 +DNS = 1.1.1.1 + +[Peer] +PublicKey = 0000000000000000000000000000000000000000000000000000000000000000 +AllowedIPs = 0.0.0.0/0 +Endpoint = 1.1.1.1:51820 +` + if err := os.WriteFile(profileConfPath, []byte(conf), 0644); err != nil { + t.Fatal(err) + } + + pidsDir := filepath.Join(tmpRuntimeDir, "profiles", profile, "pids") + + // Start Process A running a command that outputs its netns and sleeps + cmdA := exec.Command(binaryPath, "--profile", profile, "--", "sh", "-c", "readlink /proc/self/ns/net && sleep 5") + cmdA.Env = append(os.Environ(), + fmt.Sprintf("XDG_RUNTIME_DIR=%s", tmpRuntimeDir), + fmt.Sprintf("XDG_CONFIG_HOME=%s", tmpConfigDir), + ) + + outA, err := cmdA.StdoutPipe() + if err != nil { + t.Fatalf("Failed to create stdout pipe for Process A: %v", err) + } + + if err := cmdA.Start(); err != nil { + t.Fatalf("Failed to start Process A: %v", err) + } + defer func() { _ = cmdA.Process.Kill() }() + + // Wait for Process A to output its netns ID line by line + var parsedNetnsA string + scannerA := bufio.NewScanner(outA) + for scannerA.Scan() { + line := strings.TrimSpace(scannerA.Text()) + if strings.HasPrefix(line, "net:[") { + parsedNetnsA = line + break + } + } + + if parsedNetnsA == "" { + t.Fatalf("Failed to get netns ID from Process A") + } + + // Wait for Process A's PID to be registered on the host + waitForPids(t, pidsDir, 1) + + // Start Process B to check its netns ID + cmdB := exec.Command(binaryPath, "--profile", profile, "--", "readlink", "/proc/self/ns/net") + cmdB.Env = append(os.Environ(), + fmt.Sprintf("XDG_RUNTIME_DIR=%s", tmpRuntimeDir), + fmt.Sprintf("XDG_CONFIG_HOME=%s", tmpConfigDir), + ) + + outB, err := cmdB.CombinedOutput() + if err != nil { + t.Fatalf("Process B failed to execute: %v\nOutput: %s", err, string(outB)) + } + + var parsedNetnsB string + for _, line := range strings.Split(string(outB), "\n") { + trimmed := strings.TrimSpace(line) + if strings.HasPrefix(trimmed, "net:[") { + parsedNetnsB = trimmed + break + } + } + + if parsedNetnsB == "" { + t.Fatalf("Invalid netns ID format from Process B: %q", string(outB)) + } + + if parsedNetnsA != parsedNetnsB { + t.Errorf("BUG: Process A and Process B do not share the same network namespace!\nProcess A: %s\nProcess B: %s", parsedNetnsA, parsedNetnsB) + } +} |
