Skip to content

Commit ca1d219

Browse files
committed
agdcslog: add tests
1 parent 2febb2a commit ca1d219

File tree

4 files changed

+96
-47
lines changed

4 files changed

+96
-47
lines changed

internal/agdcslog/agdcslog_test.go

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"context"
66
"log/slog"
77
"os"
8+
"os/exec"
89
"strconv"
910
"strings"
1011
"sync"
@@ -22,22 +23,35 @@ const testTimeout = 1 * time.Second
2223

2324
const testServiceName = "AdGuardDNSClientTest"
2425

25-
func requireIntegration(t *testing.T) {
26-
t.Helper()
26+
// requireIntegration skips the test unless TEST_AGDCSLOG parses to true.
27+
func requireIntegration(tb testing.TB) {
28+
tb.Helper()
2729

2830
const envName = "TEST_AGDCSLOG"
2931

3032
val := os.Getenv(envName)
3133
if val == "" {
32-
t.Skip()
34+
tb.Skip("skipping: env is not set")
3335
}
3436

3537
ok, err := strconv.ParseBool(val)
3638
if err != nil || !ok {
37-
t.Skip()
39+
tb.Skip("skipping: unexpected value")
40+
}
41+
}
42+
43+
// requireLogReader skips the test unless there is a system log reader.
44+
func requireLogReader(tb testing.TB) {
45+
tb.Helper()
46+
47+
_, err := exec.LookPath(cmdLogReader)
48+
if err != nil {
49+
tb.Skip("skipping: no system log reader")
3850
}
3951
}
4052

53+
// integrationSystemLogger returns a slog.Logger configured for system logging
54+
// in integration tests.
4155
func integrationSystemLogger(t *testing.T) (l *slog.Logger) {
4256
t.Helper()
4357

@@ -54,6 +68,31 @@ func integrationSystemLogger(t *testing.T) (l *slog.Logger) {
5468
return slog.New(h)
5569
}
5670

71+
func TestSystemLogger_integration(t *testing.T) {
72+
requireIntegration(t)
73+
requireLogReader(t)
74+
75+
l := integrationSystemLogger(t)
76+
77+
since := time.Now()
78+
sinceStr := since.Format(time.DateTime)
79+
80+
msg := strconv.FormatInt(since.UnixNano(), 10)
81+
82+
ctx := testutil.ContextWithTimeout(t, testTimeout)
83+
l.DebugContext(ctx, msg)
84+
85+
require.EventuallyWithT(t, func(ct *assert.CollectT) {
86+
findCtx, cancel := context.WithTimeout(ctx, testTimeout)
87+
defer cancel()
88+
89+
ok, err := findInLog(findCtx, sinceStr, msg)
90+
require.NoError(ct, err)
91+
92+
assert.True(ct, ok)
93+
}, testTimeout, testTimeout/10)
94+
}
95+
5796
// testLogger is a mock implementation of [agdcslog.SystemLogger] interface for
5897
// tests.
5998
//

internal/agdcslog/syslog_darwin_test.go

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,30 @@
33
package agdcslog_test
44

55
import (
6-
"testing"
6+
"bytes"
7+
"context"
8+
"fmt"
9+
"strings"
710

8-
"github.com/stretchr/testify/require"
11+
"github.com/AdguardTeam/golibs/osutil/executil"
912
)
1013

11-
func TestSystemLogger_integration(t *testing.T) {
12-
requireIntegration(t)
14+
// cmdLogReader is the name of the system log reader.
15+
const cmdLogReader = "log"
1316

14-
l := integrationSystemLogger(t)
15-
require.NotNil(t, l)
17+
// findInLog searches the macOS unified log for the message.
18+
func findInLog(ctx context.Context, since, msg string) (ok bool, err error) {
19+
var stdOut, stdErr bytes.Buffer
20+
21+
err = executil.Run(ctx, executil.SystemCommandConstructor{}, &executil.CommandConfig{
22+
Path: cmdLogReader,
23+
Args: []string{"show", "--style", "syslog", "--start", since, "--debug"},
24+
Stdout: &stdOut,
25+
Stderr: &stdErr,
26+
})
27+
if err != nil {
28+
return false, fmt.Errorf("log search failed: %w; stderr=%q", err, &stdErr)
29+
}
30+
31+
return strings.Contains(stdOut.String(), msg), nil
1632
}

internal/agdcslog/syslog_linux_test.go

Lines changed: 6 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -7,50 +7,25 @@ import (
77
"context"
88
"fmt"
99
"strings"
10-
"testing"
11-
"time"
1210

1311
"github.com/AdguardTeam/golibs/osutil/executil"
14-
"github.com/AdguardTeam/golibs/testutil"
15-
"github.com/stretchr/testify/assert"
16-
"github.com/stretchr/testify/require"
1712
)
1813

19-
func TestSystemLogger_integration(t *testing.T) {
20-
requireIntegration(t)
14+
// cmdLogReader is the name of the system log reader.
15+
const cmdLogReader = "journalctl"
2116

22-
l := integrationSystemLogger(t)
23-
24-
since := time.Now()
25-
sinceStr := since.Format(time.DateTime)
26-
27-
msg := fmt.Sprintf("%d", since.UnixNano())
28-
29-
ctx := testutil.ContextWithTimeout(t, testTimeout)
30-
l.DebugContext(ctx, msg)
31-
32-
require.EventuallyWithT(t, func(ct *assert.CollectT) {
33-
findCtx, cancel := context.WithTimeout(ctx, testTimeout)
34-
defer cancel()
35-
36-
ok, err := findInJournald(findCtx, sinceStr, msg)
37-
require.NoError(ct, err)
38-
39-
assert.True(ct, ok)
40-
}, testTimeout, testTimeout/10)
41-
}
42-
43-
func findInJournald(ctx context.Context, since, msg string) (ok bool, err error) {
17+
// findInLog searches the systemd journal for the message.
18+
func findInLog(ctx context.Context, since, msg string) (ok bool, err error) {
4419
var stdOut, stdErr bytes.Buffer
4520

4621
err = executil.Run(ctx, executil.SystemCommandConstructor{}, &executil.CommandConfig{
47-
Path: "journalctl",
22+
Path: cmdLogReader,
4823
Args: []string{"-o", "cat", "-t", testServiceName, "--since", since, "--no-pager"},
4924
Stdout: &stdOut,
5025
Stderr: &stdErr,
5126
})
5227
if err != nil {
53-
return false, fmt.Errorf("journalctl failed: %w; stderr=%q", err, &stdErr)
28+
return false, fmt.Errorf("log search failed: %w; stderr=%q", err, &stdErr)
5429
}
5530

5631
return strings.Contains(stdOut.String(), msg), nil

internal/agdcslog/syslog_windows_test.go

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,33 @@
33
package agdcslog_test
44

55
import (
6-
"testing"
6+
"bytes"
7+
"context"
8+
"fmt"
9+
"strings"
710

8-
"github.com/stretchr/testify/require"
11+
"github.com/AdguardTeam/golibs/osutil/executil"
912
)
1013

11-
func TestSystemLogger_integration(t *testing.T) {
12-
requireIntegration(t)
14+
// cmdLogReader is the name of the system log reader.
15+
const cmdLogReader = "wevtutil"
1316

14-
l := integrationSystemLogger(t)
15-
require.NotNil(t, l)
17+
// findInLog searches the Windows Application event log for the message.
18+
func findInLog(ctx context.Context, _, msg string) (ok bool, err error) {
19+
var stdOut, stdErr bytes.Buffer
20+
21+
ms := testTimeout.Milliseconds()
22+
query := fmt.Sprintf(`*[System[TimeCreated[timediff(@SystemTime) <= %d]]]`, ms)
23+
24+
err = executil.Run(ctx, executil.SystemCommandConstructor{}, &executil.CommandConfig{
25+
Path: cmdLogReader,
26+
Args: []string{"qe", "Application", "/rd:true", "/f:text", "/q:" + query},
27+
Stdout: &stdOut,
28+
Stderr: &stdErr,
29+
})
30+
if err != nil {
31+
return false, fmt.Errorf("log search failed: %w; stderr=%q", err, &stdErr)
32+
}
33+
34+
return strings.Contains(stdOut.String(), msg), nil
1635
}

0 commit comments

Comments
 (0)