diff --git a/src/code.cloudfoundry.org/inigo/cell/assets/fake_app/main.go b/src/code.cloudfoundry.org/inigo/cell/assets/fake_app/main.go index b7e76bc2a..3e6aa9a5b 100644 --- a/src/code.cloudfoundry.org/inigo/cell/assets/fake_app/main.go +++ b/src/code.cloudfoundry.org/inigo/cell/assets/fake_app/main.go @@ -1,3 +1,5 @@ +//go:build !windows + package main import ( @@ -5,6 +7,7 @@ import ( "net/http" "os" "strconv" + "syscall" "time" ) @@ -35,9 +38,7 @@ func main() { go func() { time.Sleep(ExitDelay) if exitCode == SigabrtExitCode { - // Simulate SIGABRT behavior cross-platform - // Use panic to simulate abnormal termination (similar to SIGABRT) - panic("simulated SIGABRT exit") + syscall.Kill(syscall.Getpid(), syscall.SIGABRT) } else { os.Exit(exitCode) } diff --git a/src/code.cloudfoundry.org/inigo/cell/assets/fake_app_test.go b/src/code.cloudfoundry.org/inigo/cell/assets/fake_app_test.go index 4f5a84e37..fb374afe8 100644 --- a/src/code.cloudfoundry.org/inigo/cell/assets/fake_app_test.go +++ b/src/code.cloudfoundry.org/inigo/cell/assets/fake_app_test.go @@ -1,3 +1,5 @@ +//go:build !windows + package assets_test import ( @@ -5,7 +7,7 @@ import ( "net/http" "os/exec" "path/filepath" - "runtime" + "syscall" "time" . "github.com/onsi/ginkgo/v2" @@ -27,10 +29,6 @@ var _ = Describe("Fake App Exit Behavior", Serial, func() { AfterEach(func() { gexec.CleanupBuildArtifacts() - // On Windows, add a small delay to ensure ports are released - if runtime.GOOS == "windows" { - time.Sleep(500 * time.Millisecond) - } }) DescribeTable("fake app should exit with correct exit codes", @@ -66,9 +64,13 @@ var _ = Describe("Fake App Exit Behavior", Serial, func() { // Verify exit code actualExitCode := session.ExitCode() if exitCode == 134 { - // SIGABRT simulation via panic results in exit code 2 cross-platform - Expect(actualExitCode).To(Equal(2), - fmt.Sprintf("Expected panic exit code 2 for SIGABRT simulation, got %d", actualExitCode)) + // SIGABRT can result in different exit codes depending on system + Expect(actualExitCode).To(SatisfyAny( + Equal(134), // Direct SIGABRT exit code + Equal(2), // Common SIGABRT exit code + Equal(128+int(syscall.SIGABRT)), // 128 + signal number + BeNumerically("<", 0), // Negative signal codes + ), fmt.Sprintf("Expected SIGABRT-related exit code, got %d", actualExitCode)) } else { Expect(actualExitCode).To(Equal(exitCode)) } @@ -157,14 +159,8 @@ var _ = Describe("Fake App Exit Behavior", Serial, func() { // Send SIGTERM to simulate natural shutdown session.Terminate() - // Cross-platform exit code handling - if runtime.GOOS == "windows" { - // Windows doesn't have SIGTERM, process exits naturally - Eventually(session, 10*time.Second).Should(gexec.Exit(42)) - } else { - // Unix systems: SIGTERM results in exit code 143 (128 + 15) - Eventually(session, 10*time.Second).Should(gexec.Exit(143)) - } + // Should exit with code 42 + Eventually(session, 10*time.Second).Should(gexec.Exit(143)) }) }) }) diff --git a/src/code.cloudfoundry.org/inigo/cell/assets/fake_proxy/main.go b/src/code.cloudfoundry.org/inigo/cell/assets/fake_proxy/main.go index deddd65df..ffbbfdad4 100644 --- a/src/code.cloudfoundry.org/inigo/cell/assets/fake_proxy/main.go +++ b/src/code.cloudfoundry.org/inigo/cell/assets/fake_proxy/main.go @@ -1,3 +1,5 @@ +//go:build !windows + package main import ( @@ -6,6 +8,7 @@ import ( "net/http" "os" "strconv" + "syscall" "time" ) @@ -59,9 +62,7 @@ func main() { go func() { time.Sleep(ExitDelay) if exitCode == SigabrtExitCode { - // Simulate SIGABRT behavior cross-platform - // Use panic to simulate abnormal termination (similar to SIGABRT) - panic("simulated SIGABRT exit") + syscall.Kill(syscall.Getpid(), syscall.SIGABRT) } else { os.Exit(exitCode) } diff --git a/src/code.cloudfoundry.org/inigo/cell/assets/fake_proxy_test.go b/src/code.cloudfoundry.org/inigo/cell/assets/fake_proxy_test.go index 5e673fca1..96f54fb91 100644 --- a/src/code.cloudfoundry.org/inigo/cell/assets/fake_proxy_test.go +++ b/src/code.cloudfoundry.org/inigo/cell/assets/fake_proxy_test.go @@ -1,3 +1,5 @@ +//go:build !windows + package assets_test import ( @@ -5,7 +7,7 @@ import ( "net/http" "os/exec" "path/filepath" - "runtime" + "syscall" "time" . "github.com/onsi/ginkgo/v2" @@ -27,10 +29,6 @@ var _ = Describe("Fake Proxy Exit Behavior", Serial, func() { AfterEach(func() { gexec.CleanupBuildArtifacts() - // On Windows, add a small delay to ensure ports are released - if runtime.GOOS == "windows" { - time.Sleep(500 * time.Millisecond) - } }) // Helper function for normal exit codes @@ -88,10 +86,14 @@ var _ = Describe("Fake Proxy Exit Behavior", Serial, func() { // Verify process exits Eventually(session, 10*time.Second).Should(gexec.Exit()) - // Verify SIGABRT simulation exit code (panic results in exit code 2) + // Verify SIGABRT exit code (can vary by system) actualExitCode := session.ExitCode() - Expect(actualExitCode).To(Equal(2), - fmt.Sprintf("Expected panic exit code 2 for SIGABRT simulation, got %d", actualExitCode)) + Expect(actualExitCode).To(SatisfyAny( + Equal(134), // Direct SIGABRT exit code + Equal(2), // Common SIGABRT exit code + Equal(128+int(syscall.SIGABRT)), // 128 + signal number + BeNumerically("<", 0), // Negative signal codes + ), fmt.Sprintf("Expected SIGABRT-related exit code, got %d", actualExitCode)) } // Use ordered specs to prevent port conflicts @@ -173,13 +175,7 @@ var _ = Describe("Fake Proxy Exit Behavior", Serial, func() { // Send SIGTERM to simulate natural shutdown session.Terminate() - // Cross-platform exit code handling - if runtime.GOOS == "windows" { - // Windows doesn't have SIGTERM, process exits naturally - Eventually(session, 10*time.Second).Should(gexec.Exit(42)) - } else { - // Unix systems: SIGTERM results in exit code 143 (128 + 15) - Eventually(session, 10*time.Second).Should(gexec.Exit(143)) - } + // Should exit with code 42 + Eventually(session, 10*time.Second).Should(gexec.Exit(143)) }) }) diff --git a/src/code.cloudfoundry.org/inigo/cell/codependency_test.go b/src/code.cloudfoundry.org/inigo/cell/codependency_test.go index 4ab83f8a9..76e051ddc 100644 --- a/src/code.cloudfoundry.org/inigo/cell/codependency_test.go +++ b/src/code.cloudfoundry.org/inigo/cell/codependency_test.go @@ -1,3 +1,5 @@ +//go:build !windows + package cell_test import ( @@ -7,7 +9,6 @@ import ( "os" "os/exec" "path/filepath" - "runtime" "time" "code.cloudfoundry.org/durationjson" @@ -25,60 +26,20 @@ import ( "github.com/tedsuo/ifrit/grouper" ) -// Cross-platform build configuration -func getBuildConfig() (goos, goarch, binSuffix string) { - // Build for the target platform (Linux containers on Linux/macOS, Windows containers on Windows) - if runtime.GOOS == "windows" { - return "windows", "amd64", ".exe" - } - return "linux", "amd64", "" -} - -// Cross-platform shell command configuration -func getShellCommand(command string) (shell string, args []string) { - if runtime.GOOS == "windows" { - return "cmd", []string{"/C", command} - } - return "sh", []string{"-c", command} -} - -// Cross-platform temp directory -func getTempDir() string { - if runtime.GOOS == "windows" { - return "C:\\temp" - } - return "/tmp" -} - -// Cross-platform file permissions (noop on Windows) -func setExecutablePermissions(path string) error { - if runtime.GOOS == "windows" { - return nil // Windows doesn't use Unix permissions - } - return os.Chmod(path, 0755) -} - func buildFakeApp() (string, string) { // Build the fake app from the assets directory fakeAppPath := filepath.Join(".", "assets", "fake_app") // Create temporary output file tempDir := world.TempDirWithParent("", "fake-app-build") - goos, goarch, binSuffix := getBuildConfig() - binPath := filepath.Join(tempDir, "fake-app"+binSuffix) - - buildFlags := []string{"build", "-a", "-o", binPath} - // Only add static linking flags for Linux builds - if goos == "linux" { - buildFlags = append(buildFlags, "-tags", "netgo", "-ldflags", "-extldflags=-static") - } + binPath := filepath.Join(tempDir, "fake-app") - cmd := exec.Command("go", buildFlags...) + cmd := exec.Command("go", "build", "-a", "-tags", "netgo", "-ldflags", "-extldflags=-static", "-o", binPath) cmd.Dir = fakeAppPath // Set working directory to the source directory cmd.Env = append(os.Environ(), "CGO_ENABLED=0", - "GOOS="+goos, - "GOARCH="+goarch) + "GOOS=linux", + "GOARCH=amd64") err := cmd.Run() Expect(err).NotTo(HaveOccurred()) @@ -88,47 +49,38 @@ func buildFakeApp() (string, string) { func buildFakeProxy() string { dir := world.TempDirWithParent(suiteTempDir, "fake-proxy") - // Set directory permissions (no-op on Windows) - setExecutablePermissions(dir) + err := os.Chmod(dir, 0777) + Expect(err).NotTo(HaveOccurred()) // Build the fake proxy from the assets directory fakeProxyPath := filepath.Join(".", "assets", "fake_proxy") // Create temporary build output file - goos, goarch, binSuffix := getBuildConfig() - tempBinPath := filepath.Join(dir, "fake-proxy-temp"+binSuffix) - - buildFlags := []string{"build", "-a", "-o", tempBinPath} - // Only add static linking flags for Linux builds - if goos == "linux" { - buildFlags = append(buildFlags, "-tags", "netgo", "-ldflags", "-extldflags=-static") - } + tempBinPath := filepath.Join(dir, "fake-proxy-temp") - cmd := exec.Command("go", buildFlags...) + cmd := exec.Command("go", "build", "-a", "-tags", "netgo", "-ldflags", "-extldflags=-static", "-o", tempBinPath) cmd.Dir = fakeProxyPath // Set working directory to the source directory cmd.Env = append(os.Environ(), "CGO_ENABLED=0", - "GOOS="+goos, - "GOARCH="+goarch) + "GOOS=linux", + "GOARCH=amd64") - _, err := cmd.CombinedOutput() + _, err = cmd.CombinedOutput() Expect(err).NotTo(HaveOccurred()) - // Copy to envoy name (for compatibility with rep expectations) - envoyPath := filepath.Join(dir, "envoy"+binSuffix) + envoyPath := filepath.Join(dir, "envoy") srcFile, err := os.Open(tempBinPath) Expect(err).NotTo(HaveOccurred()) defer srcFile.Close() - newEnvoy, err := os.OpenFile(envoyPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644) + newEnvoy, err := os.OpenFile(envoyPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0755) Expect(err).NotTo(HaveOccurred()) defer newEnvoy.Close() _, err = io.Copy(newEnvoy, srcFile) Expect(err).NotTo(HaveOccurred()) - // Set executable permissions (no-op on Windows) - err = setExecutablePermissions(envoyPath) + err = os.Chmod(envoyPath, 0755) Expect(err).NotTo(HaveOccurred()) // Verify the fake-proxy binary was created correctly @@ -165,12 +117,11 @@ var _ = Describe("Codependency", Serial, func() { fakeAppContents, err := os.ReadFile(fakeAppPath) Expect(err).NotTo(HaveOccurred()) - _, _, binSuffix := getBuildConfig() archive_helper.CreateZipArchive( filepath.Join(fileServerStaticDir, "lrp.zip"), []archive_helper.ArchiveFile{ { - Name: "fake-app" + binSuffix, + Name: "fake-app", Body: string(fakeAppContents), Mode: 0755, }, @@ -223,30 +174,23 @@ var _ = Describe("Codependency", Serial, func() { func(processToExit string, exitCode int) { fakeProxyDir = buildFakeProxy() - // Get cross-platform configuration - _, _, binSuffix := getBuildConfig() - tempDir := getTempDir() - monitorShell, monitorArgs := getShellCommand("exit 0") - mainShell, mainArgs := getShellCommand(fmt.Sprintf("PORT=8080 %s%cfake-app%s", tempDir, filepath.Separator, binSuffix)) - sidecarShell, sidecarArgs := getShellCommand(fmt.Sprintf("PORT=8081 %s%cfake-app%s", tempDir, filepath.Separator, binSuffix)) - // Construct DesiredLRP lrp := helpers.DefaultLRPCreateRequest(componentMaker.Addresses(), processGuid, "log-guid", 1) lrp.Setup = models.WrapAction(&models.DownloadAction{ User: "vcap", From: fmt.Sprintf("http://%s/v1/static/%s", componentMaker.Addresses().FileServer, "lrp.zip"), - To: tempDir, + To: "/tmp", }) lrp.Monitor = models.WrapAction(&models.RunAction{ User: "vcap", - Path: monitorShell, - Args: monitorArgs, + Path: "sh", + Args: []string{"-c", "exit 0"}, }) lrp.Action = models.WrapAction(&models.RunAction{ User: "vcap", - Path: mainShell, - Args: mainArgs, + Path: "sh", + Args: []string{"-c", "PORT=8080 /tmp/fake-app"}, }) lrp.Ports = []uint32{8080, 8081} @@ -254,8 +198,8 @@ var _ = Describe("Codependency", Serial, func() { { Action: models.WrapAction(&models.RunAction{ User: "vcap", - Path: sidecarShell, - Args: sidecarArgs, + Path: "sh", + Args: []string{"-c", "PORT=8081 /tmp/fake-app"}, }), MemoryMb: 128, },