Pull request: all: fix windows tempdir

Merge in DNS/adguard-home from try-fixing-windows-tests to master

Squashed commit of the following:

commit 25a43db5d53f24b98921efa21d8d2f231992e761
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Fri Mar 26 21:19:00 2021 +0300

    all: fix windows tempdir
This commit is contained in:
Ainar Garipov 2021-03-29 11:40:04 +03:00
parent 179b76da77
commit ffb503976b
7 changed files with 48 additions and 135 deletions

View File

@ -1,13 +0,0 @@
package aghtest
import (
"testing"
)
// PrepareTestDir returns the full path to temporary created directory and
// registers the appropriate cleanup for *t.
func PrepareTestDir(t *testing.T) (dir string) {
t.Helper()
return prepareTestDir(t)
}

View File

@ -1,13 +0,0 @@
// +build !windows
package aghtest
import (
"testing"
)
func prepareTestDir(t *testing.T) (dir string) {
t.Helper()
return t.TempDir()
}

View File

@ -1,63 +0,0 @@
// +build windows
package aghtest
import (
"io/ioutil"
"os"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
const (
maxRetryDur = 1000 * time.Millisecond
retryDur = 5 * time.Millisecond
)
func prepareTestDir(t *testing.T) (dir string) {
// Windows, including the version of Windows Server that Github Actions
// uses, apparently likes to overly eagerly inspect new directories with
// its Windows Defender. Disabling it might require additional
// workarounds, and until we've figured it out, just retry the deletion
// until the error goes away.
//
// The code is largely inspired by the one that has been introduced into
// the go command itself. We should probably make a proposal to use the
// same mechanism in t.TempDir.
//
// See https://go-review.googlesource.com/c/go/+/172337.
//
// See https://github.com/golang/go/issues/44919.
t.Helper()
wd, err := os.Getwd()
require.NoError(t, err)
dir, err = ioutil.TempDir(wd, "agh-test")
require.NoError(t, err)
require.NotEmpty(t, dir)
t.Cleanup(func() {
start := time.Now()
for {
err = os.RemoveAll(dir)
if err == nil {
break
}
if time.Since(start) >= maxRetryDur {
break
}
time.Sleep(retryDur)
}
assert.NoError(t, err, "after %s", time.Since(start))
})
return dir
}

View File

@ -28,7 +28,7 @@ func TestQueryLog(t *testing.T) {
FileEnabled: true,
Interval: 1,
MemSize: 100,
BaseDir: aghtest.PrepareTestDir(t),
BaseDir: t.TempDir(),
})
// Add disk entries.
@ -130,7 +130,7 @@ func TestQueryLogOffsetLimit(t *testing.T) {
Enabled: true,
Interval: 1,
MemSize: 100,
BaseDir: aghtest.PrepareTestDir(t),
BaseDir: t.TempDir(),
})
const (
@ -204,7 +204,7 @@ func TestQueryLogMaxFileScanEntries(t *testing.T) {
FileEnabled: true,
Interval: 1,
MemSize: 100,
BaseDir: aghtest.PrepareTestDir(t),
BaseDir: t.TempDir(),
})
const entNum = 10
@ -232,7 +232,7 @@ func TestQueryLogFileDisabled(t *testing.T) {
FileEnabled: false,
Interval: 1,
MemSize: 2,
BaseDir: aghtest.PrepareTestDir(t),
BaseDir: t.TempDir(),
})
addEntry(l, "example1.org", net.IPv4(1, 1, 1, 1), net.IPv4(2, 2, 2, 1))

View File

@ -12,11 +12,46 @@ import (
"testing"
"time"
"github.com/AdguardTeam/AdGuardHome/internal/aghtest"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
// prepareTestFile prepares one test query log file with the specified lines
// count.
func prepareTestFile(t *testing.T, dir string, linesNum int) (name string) {
t.Helper()
f, err := ioutil.TempFile(dir, "*.txt")
require.NoError(t, err)
// Use defer and not t.Cleanup to make sure that the file is closed
// after this function is done.
defer func() {
derr := f.Close()
require.NoError(t, derr)
}()
const ans = `"AAAAAAABAAEAAAAAB2V4YW1wbGUDb3JnAAABAAEHZXhhbXBsZQNvcmcAAAEAAQAAAAAABAECAwQ="`
const format = `{"IP":%q,"T":%q,"QH":"example.org","QT":"A","QC":"IN",` +
`"Answer":` + ans + `,"Result":{},"Elapsed":0,"Upstream":"upstream"}` + "\n"
var lineIP uint32
lineTime := time.Date(2020, 2, 18, 19, 36, 35, 920973000, time.UTC)
for i := 0; i < linesNum; i++ {
lineIP++
lineTime = lineTime.Add(time.Second)
ip := make(net.IP, 4)
binary.BigEndian.PutUint32(ip, lineIP)
line := fmt.Sprintf(format, ip, lineTime.Format(time.RFC3339Nano))
_, err = f.WriteString(line)
require.NoError(t, err)
}
return f.Name()
}
// prepareTestFiles prepares several test query log files, each with the
// specified lines count.
func prepareTestFiles(t *testing.T, filesNum, linesNum int) []string {
@ -26,55 +61,22 @@ func prepareTestFiles(t *testing.T, filesNum, linesNum int) []string {
return []string{}
}
const strV = "\"%s\""
const nl = "\n"
const format = `{"IP":` + strV + `,"T":` + strV + `,` +
`"QH":"example.org","QT":"A","QC":"IN",` +
`"Answer":"AAAAAAABAAEAAAAAB2V4YW1wbGUDb3JnAAABAAEHZXhhbXBsZQNvcmcAAAEAAQAAAAAABAECAwQ=",` +
`"Result":{},"Elapsed":0,"Upstream":"upstream"}` + nl
lineTime, _ := time.Parse(time.RFC3339Nano, "2020-02-18T22:36:35.920973+03:00")
lineIP := uint32(0)
dir := aghtest.PrepareTestDir(t)
dir := t.TempDir()
files := make([]string, filesNum)
for j := range files {
f, err := ioutil.TempFile(dir, "*.txt")
require.Nil(t, err)
files[filesNum-j-1] = f.Name()
for i := 0; i < linesNum; i++ {
lineIP++
lineTime = lineTime.Add(time.Second)
ip := make(net.IP, 4)
binary.BigEndian.PutUint32(ip, lineIP)
line := fmt.Sprintf(format, ip, lineTime.Format(time.RFC3339Nano))
_, err = f.WriteString(line)
require.Nil(t, err)
}
for i := range files {
files[filesNum-i-1] = prepareTestFile(t, dir, linesNum)
}
return files
}
// prepareTestFile prepares a test query log file with the specified number of
// lines.
func prepareTestFile(t *testing.T, linesCount int) string {
t.Helper()
return prepareTestFiles(t, 1, linesCount)[0]
}
// newTestQLogFile creates new *QLogFile for tests and registers the required
// cleanup functions.
func newTestQLogFile(t *testing.T, linesNum int) (file *QLogFile) {
t.Helper()
testFile := prepareTestFile(t, linesNum)
testFile := prepareTestFiles(t, 1, linesNum)[0]
// Create the new QLogFile instance.
file, err := NewQLogFile(testFile)
@ -283,7 +285,7 @@ func TestQLogFile(t *testing.T) {
}
func NewTestQLogFileData(t *testing.T, data string) (file *QLogFile) {
f, err := ioutil.TempFile(aghtest.PrepareTestDir(t), "*.txt")
f, err := ioutil.TempFile(t.TempDir(), "*.txt")
require.Nil(t, err)
t.Cleanup(func() {
assert.Nil(t, f.Close())

View File

@ -100,7 +100,7 @@ func TestUpdateGetVersion(t *testing.T) {
}
func TestUpdate(t *testing.T) {
wd := aghtest.PrepareTestDir(t)
wd := t.TempDir()
assert.Nil(t, ioutil.WriteFile(filepath.Join(wd, "AdGuardHome"), []byte("AdGuardHome"), 0o755))
assert.Nil(t, ioutil.WriteFile(filepath.Join(wd, "README.md"), []byte("README.md"), 0o644))
@ -166,7 +166,7 @@ func TestUpdate(t *testing.T) {
}
func TestUpdateWindows(t *testing.T) {
wd := aghtest.PrepareTestDir(t)
wd := t.TempDir()
assert.Nil(t, ioutil.WriteFile(filepath.Join(wd, "AdGuardHome.exe"), []byte("AdGuardHome.exe"), 0o755))
assert.Nil(t, ioutil.WriteFile(filepath.Join(wd, "README.md"), []byte("README.md"), 0o644))

View File

@ -21,7 +21,7 @@ func TestMain(m *testing.M) {
func prepareTestFile(t *testing.T) (f *os.File) {
t.Helper()
dir := aghtest.PrepareTestDir(t)
dir := t.TempDir()
f, err := ioutil.TempFile(dir, "")
require.Nil(t, err)