Files
nomad/drivers/shared/executor/utils_test.go
Tim Gross 6b8ddff1fa windows: set job object for executor and children (#24214)
On Windows, if the `raw_exec` driver's executor exits, the child processes are
not also killed. Create a Windows "job object" (not to be confused with a Nomad
job) and add the executor to it. Child processes of the executor will inherit
the job automatically. When the handle to the job object is freed (on executor
exit), the job itself is destroyed and this causes all processes in that job to
exit.

Fixes: https://github.com/hashicorp/nomad/issues/23668
Ref: https://learn.microsoft.com/en-us/windows/win32/procthread/job-objects
2024-10-16 09:20:26 -04:00

79 lines
1.8 KiB
Go

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package executor
import (
"bytes"
"io"
"os"
"sync"
"testing"
"github.com/hashicorp/nomad/client/allocdir"
"github.com/stretchr/testify/require"
)
func TestUtils_IsolationMode(t *testing.T) {
private := IsolationModePrivate
host := IsolationModeHost
blank := ""
for _, tc := range []struct {
plugin, task, exp string
}{
{plugin: private, task: private, exp: private},
{plugin: private, task: host, exp: host},
{plugin: private, task: blank, exp: private}, // default to private
{plugin: host, task: private, exp: private},
{plugin: host, task: host, exp: host},
{plugin: host, task: blank, exp: host}, // default to host
} {
result := IsolationMode(tc.plugin, tc.task)
require.Equal(t, tc.exp, result)
}
}
type testExecCmd struct {
command *ExecCommand
allocDir *allocdir.AllocDir
stdout *bytes.Buffer
stderr *bytes.Buffer
outputCopyDone *sync.WaitGroup
}
// configureTLogging configures a test command executor with buffer as
// Std{out|err} but using os.Pipe so it mimics non-test case where cmd is set
// with files as Std{out|err} the buffers can be used to read command output
func configureTLogging(t *testing.T, testcmd *testExecCmd) {
t.Helper()
var stdout, stderr bytes.Buffer
var copyDone sync.WaitGroup
stdoutPr, stdoutPw, err := os.Pipe()
require.NoError(t, err)
stderrPr, stderrPw, err := os.Pipe()
require.NoError(t, err)
copyDone.Add(2)
go func() {
defer copyDone.Done()
io.Copy(&stdout, stdoutPr)
}()
go func() {
defer copyDone.Done()
io.Copy(&stderr, stderrPr)
}()
testcmd.stdout = &stdout
testcmd.stderr = &stderr
testcmd.outputCopyDone = &copyDone
testcmd.command.stdout = stdoutPw
testcmd.command.stderr = stderrPw
return
}