mirror of
https://github.com/hashicorp/vault.git
synced 2025-08-21 22:51:09 +02:00
* initial implementation of unseal trace * close file if we fail to start the trace didn't bother to check the error from traceFile.Close() * use reloadable config instead of env var * license * remove leftover * allow setting custom dir and remove new package * bring back StartDebugTrace after talking to Kuba it sounds like it's a good idea to try to move stuff out of core, so even if there's no immediate need for a generic debug trace function it's still fair to add it * track postUnseal instead of unsealInternal also some usability improvements from manual testing * address PR comments * address security review there were concerns about using the /tmp directory because of permissions, or having a default dir at all, so now it's required to set a dir in order to generate the traces. * add unit tests to StartDebugTrace * move back to default dir * document new parameters * add tiny integration test * avoid column in trace filename sounds like it might be forbidden in Windows and possibly cause problems in some MacOS applications. * address PR feedback * add go doc to test CI was complaining about missing comments on the new test function. It feels a bit silly to require this of tests but whatever XD * fix tests
112 lines
3.4 KiB
Go
112 lines
3.4 KiB
Go
// Copyright (c) HashiCorp, Inc.
|
|
// SPDX-License-Identifier: BUSL-1.1
|
|
|
|
package trace
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"runtime"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
// TestStartDebugTrace tests the debug trace functionality creating real
|
|
// files and traces.
|
|
func TestStartDebugTrace(t *testing.T) {
|
|
t.Run("error_on_non_existent_dir", func(t *testing.T) {
|
|
_, _, err := StartDebugTrace("non-existent-dir", "filePrefix")
|
|
require.Error(t, err)
|
|
require.Contains(t, err.Error(), "does not exist")
|
|
})
|
|
|
|
t.Run("error_on_non_dir", func(t *testing.T) {
|
|
f, err := os.CreateTemp("", "")
|
|
require.NoError(t, err)
|
|
require.NoError(t, f.Close())
|
|
_, _, err = StartDebugTrace(f.Name(), "")
|
|
require.Error(t, err)
|
|
require.Contains(t, err.Error(), "is not a directory")
|
|
})
|
|
|
|
t.Run("error_on_failed_to_create_trace_file", func(t *testing.T) {
|
|
noWriteFolder := filepath.Join(os.TempDir(), "no-write-permissions")
|
|
// create folder without write permission
|
|
err := os.Mkdir(noWriteFolder, 0o000)
|
|
t.Cleanup(func() {
|
|
os.RemoveAll(noWriteFolder)
|
|
})
|
|
require.NoError(t, err)
|
|
_, _, err = StartDebugTrace(noWriteFolder, "")
|
|
require.Error(t, err)
|
|
require.Contains(t, err.Error(), "failed to create trace file")
|
|
})
|
|
|
|
t.Run("error_trying_to_start_second_concurrent_trace", func(t *testing.T) {
|
|
dir, err := os.MkdirTemp("", "")
|
|
require.NoError(t, err)
|
|
t.Cleanup(func() {
|
|
os.RemoveAll(dir)
|
|
})
|
|
_, stop, err := StartDebugTrace(dir, "filePrefix")
|
|
require.NoError(t, err)
|
|
_, stopNil, err := StartDebugTrace(dir, "filePrefix")
|
|
require.Error(t, err)
|
|
require.Contains(t, err.Error(), "failed to start trace")
|
|
require.NoError(t, stop())
|
|
require.Nil(t, stopNil)
|
|
})
|
|
|
|
t.Run("error_when_stating_tmp_dir_with_restricted_permissions", func(t *testing.T) {
|
|
// this test relies on setting TMPDIR so skip it if we're not on a Unix system
|
|
if runtime.GOOS == "windows" {
|
|
t.Skip("skipping test on Windows")
|
|
}
|
|
|
|
tmpMissingPermissions := filepath.Join(t.TempDir(), "missing_permissions")
|
|
err := os.Mkdir(tmpMissingPermissions, 0o000)
|
|
require.NoError(t, err)
|
|
t.Setenv("TMPDIR", tmpMissingPermissions)
|
|
_, _, err = StartDebugTrace("", "filePrefix")
|
|
require.Error(t, err)
|
|
require.Contains(t, err.Error(), "failed to stat trace directory")
|
|
})
|
|
|
|
t.Run("successful_trace_generates_non_empty_file", func(t *testing.T) {
|
|
dir, err := os.MkdirTemp("", "")
|
|
require.NoError(t, err)
|
|
t.Cleanup(func() {
|
|
os.RemoveAll(dir)
|
|
})
|
|
file, stop, err := StartDebugTrace(dir, "filePrefix")
|
|
require.NoError(t, err)
|
|
require.NoError(t, stop())
|
|
f, err := os.Stat(file)
|
|
require.NoError(t, err)
|
|
require.Greater(t, f.Size(), int64(0))
|
|
})
|
|
|
|
t.Run("successful_creation_of_tmp_dir", func(t *testing.T) {
|
|
os.RemoveAll(filepath.Join(os.TempDir(), "vault-traces"))
|
|
file, stop, err := StartDebugTrace("", "filePrefix")
|
|
require.NoError(t, err)
|
|
require.NoError(t, stop())
|
|
require.Contains(t, file, filepath.Join(os.TempDir(), "vault-traces", "filePrefix"))
|
|
f, err := os.Stat(file)
|
|
require.NoError(t, err)
|
|
require.Greater(t, f.Size(), int64(0))
|
|
})
|
|
|
|
t.Run("successful_trace_with_existing_tmp_dir", func(t *testing.T) {
|
|
os.Mkdir(filepath.Join(os.TempDir(), "vault-traces"), 0o700)
|
|
file, stop, err := StartDebugTrace("", "filePrefix")
|
|
require.NoError(t, err)
|
|
require.NoError(t, stop())
|
|
require.Contains(t, file, filepath.Join(os.TempDir(), "vault-traces", "filePrefix"))
|
|
f, err := os.Stat(file)
|
|
require.NoError(t, err)
|
|
require.Greater(t, f.Size(), int64(0))
|
|
})
|
|
}
|