Skip to content
This repository has been archived by the owner on May 12, 2021. It is now read-only.

Commit

Permalink
console: Add debug console test
Browse files Browse the repository at this point in the history
Changed `setupDebugConsole()` to use a global `var` of supported shells
and to accept the debug console path as a parameter. This allows the
new unit test to modify its behaviour.

Note that to allow the goroutine started by `setupDebugConsole()` to be
stopped, the function now requires a `context` parameter. That required
`realMain()` to call the debug console setup after starting tracing (to
allow the tracing context to be passed to it). This also has the
attractive side-effect of allowing the debug console setup itself to be
traced.

Signed-off-by: James O. D. Hunt <[email protected]>
  • Loading branch information
jodh-intel committed Jul 18, 2019
1 parent d167490 commit 5163bab
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 10 deletions.
29 changes: 19 additions & 10 deletions agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ const (
)

var (
// List of shells that are tried (in order) to setup a debug console
supportedShells = []string{bashPath, shPath}

meminfo = "/proc/meminfo"

// cgroup fs is mounted at /sys/fs when systemd is the init process
Expand Down Expand Up @@ -1211,13 +1214,13 @@ func cgroupsMount() error {
return ioutil.WriteFile(cgroupMemoryUseHierarchyPath, []byte{'1'}, cgroupMemoryUseHierarchyMode)
}

func setupDebugConsole() error {
func setupDebugConsole(ctx context.Context, debugConsolePath string) error {
if !debugConsole {
return nil
}

var shellPath string
for _, s := range []string{bashPath, shPath} {
for _, s := range supportedShells {
var err error
if _, err = os.Stat(s); err == nil {
shellPath = s
Expand All @@ -1227,7 +1230,7 @@ func setupDebugConsole() error {
}

if shellPath == "" {
return errors.New("Shell not found")
return fmt.Errorf("No available shells (checked %v)", supportedShells)
}

cmd := exec.Command(shellPath)
Expand All @@ -1251,9 +1254,15 @@ func setupDebugConsole() error {

go func() {
for {
dcmd := *cmd
if err := dcmd.Run(); err != nil {
agentLog.WithError(err).Warn("failed to start debug console")
select {
case <-ctx.Done():
// stop the thread
return
default:
dcmd := *cmd
if err := dcmd.Run(); err != nil {
agentLog.WithError(err).Warn("failed to start debug console")
}
}
}
}()
Expand Down Expand Up @@ -1336,15 +1345,15 @@ func realMain() error {
return fmt.Errorf("failed to setup logger: %v", err)
}

if err := setupDebugConsole(); err != nil {
agentLog.WithError(err).Error("failed to setup debug console")
}

rootSpan, rootContext, err = setupTracing(agentName)
if err != nil {
return fmt.Errorf("failed to setup tracing: %v", err)
}

if err := setupDebugConsole(rootContext, debugConsolePath); err != nil {
agentLog.WithError(err).Error("failed to setup debug console")
}

// Set the sandbox context now that the context contains the tracing
// information.
s.ctx = rootContext
Expand Down
83 changes: 83 additions & 0 deletions agent_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,14 @@ func createFile(file, contents string) error {
return createFileWithPerms(file, contents, testFileMode)
}

func createEmptyFile(file string) error {
return createFile(file, "")
}

func createEmptyFileWithPerms(file string, perms os.FileMode) error {
return createFileWithPerms(file, "", perms)
}

func skipUnlessRoot(t *testing.T) {
if os.Getuid() != 0 {
t.Skip("Test disabled as requires root user")
Expand Down Expand Up @@ -621,3 +629,78 @@ func TestGetMemory(t *testing.T) {
assert.Equal(d.expectedResult, mem, msg)
}
}

func TestSetupDebugConsole(t *testing.T) {
assert := assert.New(t)

dir, err := ioutil.TempDir("", "")
assert.NoError(err)
defer os.RemoveAll(dir)

sh := filepath.Join(dir, "sh")
console := filepath.Join(dir, "console")

savedDebugConsole := debugConsole
savedSupportedShells := supportedShells

defer func() {
debugConsole = savedDebugConsole
supportedShells = savedSupportedShells
}()

type testData struct {
consolePath string
shells []string
debugConsole bool
createConsole bool
createShells bool
expectError bool
}

data := []testData{
{"", []string{}, false, false, false, false},
{"", []string{}, true, false, false, true},
{"", []string{sh}, true, false, false, true},
{"", []string{sh}, true, false, true, true},
{console, []string{sh}, true, false, true, true},
{console, []string{}, true, true, false, true},

{console, []string{sh}, true, true, true, false},
}

for i, d := range data {
msg := fmt.Sprintf("test[%d]: %+v\n", i, d)

// override
debugConsole = d.debugConsole
supportedShells = d.shells

if d.createConsole {
err = createEmptyFile(d.consolePath)
assert.NoError(err, msg)
} else {
os.Remove(d.consolePath)
}

for _, shell := range d.shells {
if d.createShells {
err = createEmptyFile(shell)
assert.NoError(err, msg)
} else {
os.Remove(shell)
}
}

ctx, cancel := context.WithCancel(context.Background())
defer cancel()

err := setupDebugConsole(ctx, d.consolePath)

if d.expectError {
assert.Error(err, msg)
continue
}

assert.NoError(err, msg)
}
}

0 comments on commit 5163bab

Please sign in to comment.