mirror of
https://github.com/prometheus-community/windows_exporter.git
synced 2026-10-17 18:19:04 +02:00
193 lines
5.2 KiB
Go
193 lines
5.2 KiB
Go
// SPDX-License-Identifier: Apache-2.0
|
|
//
|
|
// Copyright The Prometheus Authors
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
//go:build windows
|
|
|
|
package log
|
|
|
|
import (
|
|
"log/slog"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/prometheus/common/promslog"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func newConfig(t *testing.T, file string, rotation Rotation) *Config {
|
|
t.Helper()
|
|
|
|
allowedFile := &AllowedFile{}
|
|
require.NoError(t, allowedFile.Set(file))
|
|
|
|
return &Config{Config: &promslog.Config{}, File: allowedFile, Rotation: rotation}
|
|
}
|
|
|
|
func TestNewFileWithoutRotation(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
path := filepath.Join(t.TempDir(), "windows_exporter.log")
|
|
|
|
logger, closer, err := New(newConfig(t, path, Rotation{}))
|
|
require.NoError(t, err)
|
|
require.NotNil(t, closer)
|
|
|
|
logger.Info("hello")
|
|
require.NoError(t, closer.Close())
|
|
|
|
data, err := os.ReadFile(path)
|
|
require.NoError(t, err)
|
|
require.Contains(t, string(data), "hello")
|
|
}
|
|
|
|
func writeMegabytes(logger *slog.Logger, megabytes int) {
|
|
message := strings.Repeat("x", 1024)
|
|
for range megabytes * 1100 {
|
|
logger.Info(message)
|
|
}
|
|
}
|
|
|
|
func TestNewFileWithSizeRotation(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
dir := t.TempDir()
|
|
path := filepath.Join(dir, "windows_exporter.log")
|
|
|
|
logger, closer, err := New(newConfig(t, path, Rotation{MaxSize: 1}))
|
|
require.NoError(t, err)
|
|
require.NotNil(t, closer)
|
|
|
|
writeMegabytes(logger, 2)
|
|
require.NoError(t, closer.Close())
|
|
|
|
entries, err := os.ReadDir(dir)
|
|
require.NoError(t, err)
|
|
require.GreaterOrEqual(t, len(entries), 2, "expected the active log file and at least one backup")
|
|
|
|
info, err := os.Stat(path)
|
|
require.NoError(t, err)
|
|
require.LessOrEqual(t, info.Size(), int64(1024*1024))
|
|
}
|
|
|
|
func TestNewFileMaxBackups(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
dir := t.TempDir()
|
|
path := filepath.Join(dir, "windows_exporter.log")
|
|
|
|
logger, closer, err := New(newConfig(t, path, Rotation{MaxSize: 1, MaxBackups: 2}))
|
|
require.NoError(t, err)
|
|
|
|
// Rotates at least four times; only the two newest backups are kept.
|
|
writeMegabytes(logger, 5)
|
|
require.NoError(t, closer.Close())
|
|
|
|
entries, err := os.ReadDir(dir)
|
|
require.NoError(t, err)
|
|
require.Len(t, entries, 3, "expected the active log file and two backups")
|
|
}
|
|
|
|
func TestNewFileUnwritable(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// The parent of the log file is a file, so the log file can't be created.
|
|
parent := filepath.Join(t.TempDir(), "not-a-directory")
|
|
require.NoError(t, os.WriteFile(parent, nil, 0o600))
|
|
|
|
path := filepath.Join(parent, "windows_exporter.log")
|
|
|
|
for name, rotation := range map[string]Rotation{
|
|
"without rotation": {},
|
|
"with rotation": {MaxSize: 1},
|
|
} {
|
|
t.Run(name, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
_, _, err := New(newConfig(t, path, rotation))
|
|
require.ErrorContains(t, err, "failed to open log file")
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestNewRotationValidation(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
path := filepath.Join(t.TempDir(), "windows_exporter.log")
|
|
|
|
for name, tc := range map[string]struct {
|
|
file string
|
|
rotation Rotation
|
|
err string
|
|
}{
|
|
"stream": {"stdout", Rotation{MaxSize: 10}, "requires log.file to be a file path"},
|
|
"no max size": {path, Rotation{MaxBackups: 3}, "requires log.rotation.max-size"},
|
|
"negative size": {path, Rotation{MaxSize: -1}, "max-size must not be negative"},
|
|
"negative backups": {path, Rotation{MaxSize: 1, MaxBackups: -1}, "max-backups must not be negative"},
|
|
} {
|
|
t.Run(name, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
_, _, err := New(newConfig(t, tc.file, tc.rotation))
|
|
require.ErrorContains(t, err, tc.err)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestAllowedFileSetEventLogIsLazy(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
path := filepath.Join(t.TempDir(), "windows_exporter.log")
|
|
|
|
// The service default is replaced by --log.file: Set must not open the
|
|
// event log, or the handle would never be closed.
|
|
file := &AllowedFile{}
|
|
require.NoError(t, file.Set(eventLogFile))
|
|
require.Nil(t, file.w)
|
|
require.False(t, file.isPath())
|
|
|
|
require.NoError(t, file.Set(path))
|
|
require.True(t, file.isPath())
|
|
|
|
logger, closer, err := New(&Config{Config: &promslog.Config{}, File: file})
|
|
require.NoError(t, err)
|
|
|
|
logger.Info("hello")
|
|
require.NoError(t, closer.Close())
|
|
require.Contains(t, readFile(t, path), "hello")
|
|
}
|
|
|
|
func TestNewEventLog(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
logger, closer, err := New(newConfig(t, eventLogFile, Rotation{}))
|
|
require.NoError(t, err)
|
|
require.NotNil(t, logger)
|
|
require.NotNil(t, closer, "the event log handle must be released")
|
|
require.NoError(t, closer.Close())
|
|
|
|
_, _, err = New(newConfig(t, eventLogFile, Rotation{MaxSize: 1}))
|
|
require.ErrorContains(t, err, "requires log.file to be a file path")
|
|
}
|
|
|
|
func TestNewStreamHasNoCloser(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
_, closer, err := New(newConfig(t, "stderr", Rotation{}))
|
|
require.NoError(t, err)
|
|
require.Nil(t, closer)
|
|
}
|