mirror of
https://github.com/Control-D-Inc/ctrld.git
synced 2026-10-12 01:58:46 +02:00
The journal records the network state of the host and each change of that state. The support team reads one file to see the interfaces, the routes, the resolvers, and the recoveries around an incident. The same file shows the health of the query path. A change that touches only AirDrop or virtual interfaces runs no DNS work.
142 lines
4.3 KiB
Go
142 lines
4.3 KiB
Go
package cli
|
|
|
|
import (
|
|
"io"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/rs/zerolog"
|
|
|
|
"github.com/Control-D-Inc/ctrld"
|
|
)
|
|
|
|
// Test_needInternalLogging_silent is a regression test for
|
|
// https://github.com/Control-D-Inc/ctrld/issues/320: running with --silent must
|
|
// not enable internal logging, otherwise ctrld creates and writes
|
|
// <homedir>/ctrld.log (and, when verbose==0, resets the global level back to
|
|
// debug) despite the user asking for silence.
|
|
func Test_needInternalLogging_silent(t *testing.T) {
|
|
origSilent, origCdUID := silent, cdUID
|
|
t.Cleanup(func() { silent, cdUID = origSilent, origCdUID })
|
|
|
|
tests := []struct {
|
|
name string
|
|
silent bool
|
|
cdUID string
|
|
logPath string
|
|
want bool
|
|
}{
|
|
{"silent suppresses internal logging in cd mode", true, "test-uid", "", false},
|
|
{"cd mode enables internal logging", false, "test-uid", "", true},
|
|
{"non-cd mode disabled", false, "", "", false},
|
|
{"explicit log path disables internal logging", false, "test-uid", "/var/log/ctrld.log", false},
|
|
}
|
|
for _, tt := range tests {
|
|
tt := tt
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
silent = tt.silent
|
|
cdUID = tt.cdUID
|
|
p := &prog{cfg: &ctrld.Config{}}
|
|
p.cfg.Service.LogPath = tt.logPath
|
|
if got := p.needInternalLogging(); got != tt.want {
|
|
t.Fatalf("needInternalLogging() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// Test_initInternalLogging_silentCreatesNoFile drives the real initInternalLogging
|
|
// path and asserts that a --silent --cd run does not create <homedir>/ctrld.log,
|
|
// which is the observable failure reported in
|
|
// https://github.com/Control-D-Inc/ctrld/issues/320.
|
|
func Test_initInternalLogging_silentCreatesNoFile(t *testing.T) {
|
|
origSilent, origCdUID, origHomedir := silent, cdUID, homedir
|
|
t.Cleanup(func() { silent, cdUID, homedir = origSilent, origCdUID, origHomedir })
|
|
|
|
dir := t.TempDir()
|
|
homedir = dir
|
|
cdUID = "test-uid" // cd mode, which would otherwise enable internal logging
|
|
silent = true
|
|
stubHeaderSnapshotSources(t)
|
|
|
|
p := &prog{cfg: &ctrld.Config{}}
|
|
p.initInternalLogging(nil)
|
|
|
|
for _, name := range []string{logFileName, journalLogFileName} {
|
|
path := filepath.Join(dir, name)
|
|
if _, err := os.Stat(path); !os.IsNotExist(err) {
|
|
t.Fatalf("silent mode must not create %s (stat err = %v)", path, err)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Test_initInternalLogging_createsJournalFile drives a cd mode run and asserts
|
|
// that the journal file holds the retained lines only, while the debug file
|
|
// holds every line.
|
|
func Test_initInternalLogging_createsJournalFile(t *testing.T) {
|
|
origSilent, origCdUID, origHomedir, origVerbose := silent, cdUID, homedir, verbose
|
|
origMainLog, origProxyLog := mainLog.Load(), ctrld.ProxyLogger.Load()
|
|
origLevel := zerolog.GlobalLevel()
|
|
t.Cleanup(func() {
|
|
silent, cdUID, homedir, verbose = origSilent, origCdUID, origHomedir, origVerbose
|
|
mainLog.Store(origMainLog)
|
|
ctrld.ProxyLogger.Store(origProxyLog)
|
|
zerolog.SetGlobalLevel(origLevel)
|
|
})
|
|
if origMainLog == nil {
|
|
discard := zerolog.New(io.Discard)
|
|
mainLog.Store(&discard)
|
|
}
|
|
|
|
dir := t.TempDir()
|
|
homedir = dir
|
|
cdUID = "test-uid"
|
|
silent = false
|
|
verbose = 0
|
|
stubHeaderSnapshotSources(t)
|
|
|
|
p := &prog{cfg: &ctrld.Config{}}
|
|
p.initInternalLogging(nil)
|
|
t.Cleanup(func() {
|
|
p.internalLogWriter.closeLogFile()
|
|
p.internalJournalWriter.closeLogFile()
|
|
})
|
|
|
|
debugPath := filepath.Join(dir, logFileName)
|
|
journalPath := filepath.Join(dir, journalLogFileName)
|
|
for _, path := range []string{debugPath, journalPath} {
|
|
if _, err := os.Stat(path); err != nil {
|
|
t.Fatalf("stat %s: %v", path, err)
|
|
}
|
|
}
|
|
|
|
const (
|
|
warnMsg = "retained warn line"
|
|
markedMsg = "retained marked info line"
|
|
plainMsg = "dropped plain info line"
|
|
)
|
|
logger := mainLog.Load()
|
|
logger.Warn().Msg(warnMsg)
|
|
journal(logger.Info()).Msg(markedMsg)
|
|
logger.Info().Msg(plainMsg)
|
|
|
|
journalText := rotatingFileTestContent(t, journalPath)
|
|
for _, msg := range []string{warnMsg, markedMsg} {
|
|
if !strings.Contains(journalText, msg) {
|
|
t.Fatalf("journal file misses %q: %s", msg, journalText)
|
|
}
|
|
}
|
|
if strings.Contains(journalText, plainMsg) {
|
|
t.Fatalf("journal file kept %q: %s", plainMsg, journalText)
|
|
}
|
|
|
|
debugText := rotatingFileTestContent(t, debugPath)
|
|
for _, msg := range []string{warnMsg, markedMsg, plainMsg} {
|
|
if !strings.Contains(debugText, msg) {
|
|
t.Fatalf("debug file misses %q: %s", msg, debugText)
|
|
}
|
|
}
|
|
}
|