-
Notifications
You must be signed in to change notification settings - Fork 251
/
updater_test.go
129 lines (109 loc) · 4.43 KB
/
updater_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// Copyright 2016 Michal Witkowski. All Rights Reserved.
// See LICENSE for licensing terms.
package configmap_test
import (
"flag"
"os"
"os/exec"
"path"
"path/filepath"
"strings"
"testing"
"time"
"fortio.org/assert"
"fortio.org/fortio/dflag"
"fortio.org/fortio/dflag/configmap"
)
const (
firstGoodDir = "..9989_09_09_07_32_32.099817316"
secondGoodDir = "..9289_09_10_03_32_32.039823124"
badStaticDir = "..1289_09_10_03_32_32.039823124"
)
type updaterTestSuite struct {
assert.TestSuite
tempDir string
flagSet *flag.FlagSet
staticInt *int
dynInt *dflag.DynInt64Value
updater *configmap.Updater
}
func (s *updaterTestSuite) SetupTest() {
var err error
s.tempDir, err = os.MkdirTemp("/tmp", "updater_test")
assert.NoError(s.T(), err, "failed creating temp directory for testing")
s.copyTestDataToDir()
s.linkDataDirTo(firstGoodDir)
s.flagSet = flag.NewFlagSet("updater_test", flag.ContinueOnError)
s.dynInt = dflag.DynInt64(s.flagSet, "some_dynint", 1, "dynamic int for testing")
s.staticInt = s.flagSet.Int("some_int", 1, "static int for testing")
s.updater, err = configmap.New(s.flagSet, path.Join(s.tempDir, "testdata"))
assert.NoError(s.T(), err, "creating a config map must not fail")
}
// Tear down the updater.
func (s *updaterTestSuite) TearDownTest() {
assert.NoError(s.T(), os.RemoveAll(s.tempDir), "clearing up the test dir must not fail")
_ = s.updater.Stop()
time.Sleep(100 * time.Millisecond)
}
func (s *updaterTestSuite) copyTestDataToDir() {
copyCmd := exec.Command("cp", "-a", "testdata", s.tempDir)
assert.NoError(s.T(), copyCmd.Run(), "copying testdata directory to tempdir must not fail")
// We are storing file testdata/9989_09_09_07_32_32.099817316 and renaming it to testdata/..9989_09_09_07_32_32.099817316,
// because go modules don't allow repos with files with .. in their filename. See https://github.com/golang/go/issues/27299.
for _, p := range []string{firstGoodDir, secondGoodDir, badStaticDir} {
pOld := filepath.Join(s.tempDir, "testdata", strings.TrimPrefix(p, ".."))
pNew := filepath.Join(s.tempDir, "testdata", p)
assert.NoError(s.T(), os.Rename(pOld, pNew), "renaming %q to %q failed", pOld, pNew)
}
}
func (s *updaterTestSuite) linkDataDirTo(newDataDir string) {
copyCmd := exec.Command("ln", "-s", "-n", "-f",
path.Join(s.tempDir, "testdata", newDataDir),
path.Join(s.tempDir, "testdata", "..data"))
assert.NoError(s.T(), copyCmd.Run(), "relinking ..data in tempdir must not fail")
}
func (s *updaterTestSuite) TestInitializeFailsOnBadFormedFlag() {
s.linkDataDirTo(badStaticDir)
assert.Error(s.T(), s.updater.Initialize(), "the updater initialize should return error on bad flags")
}
func (s *updaterTestSuite) TestSetupFunction() {
tmpU, err := configmap.Setup(s.flagSet, path.Join(s.tempDir, "testdata"))
assert.NoError(s.T(), err, "setup for a config map must not fail")
assert.Error(s.T(), tmpU.Initialize(), "should error with already started")
assert.Error(s.T(), tmpU.Start(), "should error with already started")
assert.NoError(s.T(), tmpU.Stop(), "stopping the watcher should succeed")
}
func (s *updaterTestSuite) TestInitializeSetsValues() {
assert.NoError(s.T(), s.updater.Initialize(), "the updater initialize should not return errors on good flags")
assert.EqualValues(s.T(), *s.staticInt, 1234, "staticInt should be some_int from first directory")
assert.EqualValues(s.T(), s.dynInt.Get(), int64(10001), "staticInt should be some_int from first directory")
}
func (s *updaterTestSuite) TestDynamicUpdatesPropagate() {
assert.NoError(s.T(), s.updater.Initialize(), "the updater initialize should not return errors on good flags")
assert.NoError(s.T(), s.updater.Start(), "updater start should not return an error")
s.linkDataDirTo(secondGoodDir)
eventually(s.T(), 1*time.Second,
assert.ObjectsAreEqualValues, int64(20002),
func() interface{} { return s.dynInt.Get() },
"some_dynint value should change to the value from secondGoodDir")
}
func TestUpdaterSuite(t *testing.T) {
assert.Run(t, &updaterTestSuite{})
}
type (
assertFunc func(expected, actual interface{}) bool
getter func() interface{}
)
// eventually tries a given Assert function 5 times over the period of time.
func eventually(t *testing.T, duration time.Duration,
af assertFunc, expected interface{}, actual getter, msgFmt string, msgArgs ...interface{},
) {
increment := duration / 5
for i := 0; i < 5; i++ {
time.Sleep(increment)
if af(expected, actual()) {
return
}
}
t.Fatalf(msgFmt, msgArgs...)
}