From 37b4bee83d6d0cb0d99c2f37d64efd095f8b38f9 Mon Sep 17 00:00:00 2001 From: Laurent Demailly Date: Tue, 6 Sep 2022 10:32:27 -0700 Subject: [PATCH 1/2] moved testify compatible code to its own package so it can be reused --- dflag/checksum_test.go | 16 ++-- dflag/configmap/updater_test.go | 39 ++++---- dflag/dynbool_test.go | 2 + dflag/dynduration_test.go | 2 + dflag/dynfloat64_test.go | 2 + dflag/dyngeneric_test.go | 2 + dflag/dynint64_test.go | 2 + dflag/dynjson_test.go | 2 + dflag/dynstring_test.go | 2 + dflag/dynstringset_test.go | 2 + dflag/dynstringslice_test.go | 2 + dflag/endpoint/endpoint_test.go | 23 ++--- dflag/fileread_flag_test.go | 2 + dflag/test_utils.go | 162 -------------------------------- go.mod | 1 + go.sum | 2 + stats/stats_test.go | 93 +++++++----------- 17 files changed, 92 insertions(+), 264 deletions(-) delete mode 100644 dflag/test_utils.go diff --git a/dflag/checksum_test.go b/dflag/checksum_test.go index 6c3c4fee4..e947d0ad9 100644 --- a/dflag/checksum_test.go +++ b/dflag/checksum_test.go @@ -8,14 +8,10 @@ import ( "testing" "time" + "fortio.org/assert" "fortio.org/fortio/dflag" ) -var ( - assert = dflag.Testify{} - require = assert -) - func TestChecksumFlagSet_Differs(t *testing.T) { set := flag.NewFlagSet("foobar", flag.ContinueOnError) dflag.DynDuration(set, "some_duration_1", 5*time.Second, "Use it or lose it") @@ -30,17 +26,17 @@ func TestChecksumFlagSet_Differs(t *testing.T) { t.Logf("post init checksum: %x", postInitChecksum) assert.NotEqual(t, preInitChecksum, postInitChecksum, "checksum must be different init changed 2 flags") - require.NoError(t, set.Set("some_int_1", "1337")) + assert.NoError(t, set.Set("some_int_1", "1337")) postSet1Checksum := dflag.ChecksumFlagSet(set, nil) t.Logf("post set1 checksum: %x", postSet1Checksum) assert.NotEqual(t, postInitChecksum, postSet1Checksum, "checksum must be different after a internal flag change") - require.NoError(t, set.Set("some_duration_1", "4s")) + assert.NoError(t, set.Set("some_duration_1", "4s")) postSet2Checksum := dflag.ChecksumFlagSet(set, nil) t.Logf("post set2 checksum: %x", postSet2Checksum) assert.NotEqual(t, postSet1Checksum, postSet2Checksum, "checksum must be different after a internal flag change") - require.NoError(t, set.Set("some_duration_1", "3s")) + assert.NoError(t, set.Set("some_duration_1", "3s")) postSet3Checksum := dflag.ChecksumFlagSet(set, nil) t.Logf("post set3 checksum: %x", postSet3Checksum) assert.EqualValues(t, postSet1Checksum, postSet3Checksum, "flipping back duration flag to state at set1 should make it equal") @@ -56,12 +52,12 @@ func TestChecksumFlagSet_Filters(t *testing.T) { postInitChecksum := dflag.ChecksumFlagSet(set, filterOnlyDuration) t.Logf("post init checksum: %x", postInitChecksum) - require.NoError(t, set.Set("some_int_1", "1337")) + assert.NoError(t, set.Set("some_int_1", "1337")) postSet1Checksum := dflag.ChecksumFlagSet(set, filterOnlyDuration) t.Logf("post set1 checksum: %x", postSet1Checksum) assert.EqualValues(t, postInitChecksum, postSet1Checksum, "checksum should not include some_int_1 change") - require.NoError(t, set.Set("some_duration_1", "10s")) + assert.NoError(t, set.Set("some_duration_1", "10s")) postSet2Checksum := dflag.ChecksumFlagSet(set, filterOnlyDuration) t.Logf("post set2 checksum: %x", postSet2Checksum) assert.NotEqual(t, postSet1Checksum, postSet2Checksum, "checksum change when some_duration_1 changes") diff --git a/dflag/configmap/updater_test.go b/dflag/configmap/updater_test.go index c7d6b02e4..6505fbf83 100644 --- a/dflag/configmap/updater_test.go +++ b/dflag/configmap/updater_test.go @@ -13,6 +13,7 @@ import ( "testing" "time" + "fortio.org/assert" "fortio.org/fortio/dflag" "fortio.org/fortio/dflag/configmap" ) @@ -23,14 +24,8 @@ const ( badStaticDir = "..1289_09_10_03_32_32.039823124" ) -var ( - assert = dflag.Testify{} - require = assert - suite = assert -) - type updaterTestSuite struct { - dflag.TestSuite + assert.TestSuite tempDir string flagSet *flag.FlagSet @@ -43,7 +38,7 @@ type updaterTestSuite struct { func (s *updaterTestSuite) SetupTest() { var err error s.tempDir, err = os.MkdirTemp("/tmp", "updater_test") - require.NoError(s.T(), err, "failed creating temp directory for testing") + assert.NoError(s.T(), err, "failed creating temp directory for testing") s.copyTestDataToDir() s.linkDataDirTo(firstGoodDir) @@ -52,25 +47,25 @@ func (s *updaterTestSuite) SetupTest() { s.staticInt = s.flagSet.Int("some_int", 1, "static int for testing") s.updater, err = configmap.New(s.flagSet, path.Join(s.tempDir, "testdata")) - require.NoError(s.T(), err, "creating a config map must not fail") + assert.NoError(s.T(), err, "creating a config map must not fail") } // Tear down the updater. func (s *updaterTestSuite) TearDownTest() { - require.NoError(s.T(), os.RemoveAll(s.tempDir), "clearing up the test dir must not fail") + 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) - require.NoError(s.T(), copyCmd.Run(), "copying testdata directory to tempdir must not fail") + 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) - require.NoError(s.T(), os.Rename(pOld, pNew), "renaming %q to %q failed", pOld, pNew) + assert.NoError(s.T(), os.Rename(pOld, pNew), "renaming %q to %q failed", pOld, pNew) } } @@ -78,31 +73,31 @@ 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")) - require.NoError(s.T(), copyCmd.Run(), "relinking ..data in tempdir tempdir must not fail") + assert.NoError(s.T(), copyCmd.Run(), "relinking ..data in tempdir tempdir must not fail") } func (s *updaterTestSuite) TestInitializeFailsOnBadFormedFlag() { s.linkDataDirTo(badStaticDir) - require.Error(s.T(), s.updater.Initialize(), "the updater initialize should return error on bad flags") + 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")) - require.NoError(s.T(), err, "setup for a config map must not fail") - require.Error(s.T(), tmpU.Initialize(), "should error with already started") - require.Error(s.T(), tmpU.Start(), "should error with already started") - require.NoError(s.T(), tmpU.Stop(), "stopping the watcher should succeed") + 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() { - require.NoError(s.T(), s.updater.Initialize(), "the updater initialize should not return errors on good flags") + 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() { - require.NoError(s.T(), s.updater.Initialize(), "the updater initialize should not return errors on good flags") - require.NoError(s.T(), s.updater.Start(), "updater start should not return an error") + 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), @@ -111,7 +106,7 @@ func (s *updaterTestSuite) TestDynamicUpdatesPropagate() { } func TestUpdaterSuite(t *testing.T) { - suite.Run(t, &updaterTestSuite{}) + assert.Run(t, &updaterTestSuite{}) } type ( diff --git a/dflag/dynbool_test.go b/dflag/dynbool_test.go index e66ea34a8..db4ccec33 100644 --- a/dflag/dynbool_test.go +++ b/dflag/dynbool_test.go @@ -8,6 +8,8 @@ import ( "fmt" "testing" "time" + + "fortio.org/assert" ) func TestDynBool_SetAndGet(t *testing.T) { diff --git a/dflag/dynduration_test.go b/dflag/dynduration_test.go index 8422ce267..051b1242e 100644 --- a/dflag/dynduration_test.go +++ b/dflag/dynduration_test.go @@ -8,6 +8,8 @@ import ( "fmt" "testing" "time" + + "fortio.org/assert" ) func TestDynDuration_SetAndGet(t *testing.T) { diff --git a/dflag/dynfloat64_test.go b/dflag/dynfloat64_test.go index ec9fe29a7..c62b7bbb6 100644 --- a/dflag/dynfloat64_test.go +++ b/dflag/dynfloat64_test.go @@ -7,6 +7,8 @@ import ( "flag" "testing" "time" + + "fortio.org/assert" ) func TestDynFloat64_SetAndGet(t *testing.T) { diff --git a/dflag/dyngeneric_test.go b/dflag/dyngeneric_test.go index 86bb117d3..224041772 100644 --- a/dflag/dyngeneric_test.go +++ b/dflag/dyngeneric_test.go @@ -6,6 +6,8 @@ package dflag import ( "flag" "testing" + + "fortio.org/assert" ) // Additional generic tests, most tests are covered by the old per type tests. diff --git a/dflag/dynint64_test.go b/dflag/dynint64_test.go index 7f10c8c09..9e3873602 100644 --- a/dflag/dynint64_test.go +++ b/dflag/dynint64_test.go @@ -7,6 +7,8 @@ import ( "flag" "testing" "time" + + "fortio.org/assert" ) func TestDynInt64_SetAndGet(t *testing.T) { diff --git a/dflag/dynjson_test.go b/dflag/dynjson_test.go index 6a82cf084..52be50dc4 100644 --- a/dflag/dynjson_test.go +++ b/dflag/dynjson_test.go @@ -8,6 +8,8 @@ import ( "fmt" "testing" "time" + + "fortio.org/assert" ) var defaultJSON = &outerJSON{ diff --git a/dflag/dynstring_test.go b/dflag/dynstring_test.go index b9c631740..6827bbe57 100644 --- a/dflag/dynstring_test.go +++ b/dflag/dynstring_test.go @@ -8,6 +8,8 @@ import ( "regexp" "testing" "time" + + "fortio.org/assert" ) const notifierTimeout = 50 * time.Millisecond diff --git a/dflag/dynstringset_test.go b/dflag/dynstringset_test.go index c9e0f023e..ea595072f 100644 --- a/dflag/dynstringset_test.go +++ b/dflag/dynstringset_test.go @@ -7,6 +7,8 @@ import ( "flag" "testing" "time" + + "fortio.org/assert" ) func TestDynStringSet_SetAndGet(t *testing.T) { diff --git a/dflag/dynstringslice_test.go b/dflag/dynstringslice_test.go index 7dfd56b95..6abfa2779 100644 --- a/dflag/dynstringslice_test.go +++ b/dflag/dynstringslice_test.go @@ -7,6 +7,8 @@ import ( "flag" "testing" "time" + + "fortio.org/assert" ) func TestDynStringSlice_SetAndGet(t *testing.T) { diff --git a/dflag/endpoint/endpoint_test.go b/dflag/endpoint/endpoint_test.go index 9fba8da49..7cbe2a3a1 100644 --- a/dflag/endpoint/endpoint_test.go +++ b/dflag/endpoint/endpoint_test.go @@ -13,22 +13,19 @@ import ( "testing" "fortio.org/fortio/dflag" + "fortio.org/assert" + ) type endpointTestSuite struct { - dflag.TestSuite + assert.TestSuite flagSet *flag.FlagSet endpoint *FlagsEndpoint } -var ( - assert = dflag.Testify{} - require = assert - suite = assert -) func TestEndpointTestSuite(t *testing.T) { - suite.Run(t, &endpointTestSuite{}) + assert.Run(t, &endpointTestSuite{}) } func (s *endpointTestSuite) SetupTest() { @@ -117,8 +114,8 @@ func (s *endpointTestSuite) TestServesHTML() { req.Header.Add("Accept", "application/xhtml+xml") resp := httptest.NewRecorder() s.endpoint.ListFlags(resp, req) - require.Equal(s.T(), http.StatusOK, resp.Code, "dflag list request must return 200 OK") - require.Contains(s.T(), resp.Header().Get("Content-Type"), "html", "must indicate html in content type") + assert.Equal(s.T(), http.StatusOK, resp.Code, "dflag list request must return 200 OK") + assert.Contains(s.T(), resp.Header().Get("Content-Type"), "html", "must indicate html in content type") out := resp.Body.String() assert.Contains(s.T(), out, "") @@ -128,10 +125,10 @@ func (s *endpointTestSuite) TestServesHTML() { func (s *endpointTestSuite) processFlagSetJSONResponse(req *http.Request) *flagSetJSON { resp := httptest.NewRecorder() s.endpoint.ListFlags(resp, req) - require.Equal(s.T(), http.StatusOK, resp.Code, "dflag list request must return 200 OK") - require.Equal(s.T(), "application/json", resp.Header().Get("Content-Type"), "type must be indicated") + assert.Equal(s.T(), http.StatusOK, resp.Code, "dflag list request must return 200 OK") + assert.Equal(s.T(), "application/json", resp.Header().Get("Content-Type"), "type must be indicated") ret := &flagSetJSON{} - require.NoError(s.T(), json.Unmarshal(resp.Body.Bytes(), ret), "unmarshaling JSON response must succeed") + assert.NoError(s.T(), json.Unmarshal(resp.Body.Bytes(), ret), "unmarshaling JSON response must succeed") return ret } @@ -141,7 +138,7 @@ func (s *endpointTestSuite) assertListContainsOnly(flagList []string, list *flag existing = append(existing, f.Name) } sort.Strings(flagList) - require.EqualValues(s.T(), flagList, existing, "expected set of listed flags must match") + assert.EqualValues(s.T(), flagList, existing, "expected set of listed flags must match") } func findFlagInFlagSetJSON(flagName string, list *flagSetJSON) *flagJSON { diff --git a/dflag/fileread_flag_test.go b/dflag/fileread_flag_test.go index bb10329e4..e6c7262b3 100644 --- a/dflag/fileread_flag_test.go +++ b/dflag/fileread_flag_test.go @@ -6,6 +6,8 @@ package dflag import ( "flag" "testing" + + "fortio.org/assert" ) func TestFileFlag_ReadsWithADefault(t *testing.T) { diff --git a/dflag/test_utils.go b/dflag/test_utils.go deleted file mode 100644 index 6a44014a9..000000000 --- a/dflag/test_utils.go +++ /dev/null @@ -1,162 +0,0 @@ -// Copyright 2022 Fortio Authors - -// Only in "dflag" for sharing with tests. -// As tests don't fail, coverage of this particular file is poor. - -package dflag - -import ( - "fmt" - "reflect" - "regexp" - "runtime" - "strings" - "testing" -) - -// --- Start of replacement for "github.com/stretchr/testify/assert" - -// require.* and suite.* are used in _test packages while assert is used in dflag itself. -var assert = Testify{} - -// ObjectsAreEqualValues returns true if a == b (through refection). -func (d *Testify) ObjectsAreEqualValues(a, b interface{}) bool { - return reflect.DeepEqual(a, b) -} - -// Testify is a short replacement for github.com/stretchr/testify/assert. -type Testify struct{} - -// Errorf is a local variant to get the right line numbers. -func Errorf(t *testing.T, format string, rest ...interface{}) { - _, file, line, _ := runtime.Caller(2) - file = file[strings.LastIndex(file, "/")+1:] - fmt.Printf("%s:%d %s", file, line, fmt.Sprintf(format, rest...)) - t.Fail() -} - -// NotEqual checks for a not equal b. -func (d *Testify) NotEqual(t *testing.T, a, b interface{}, msg ...string) { - if d.ObjectsAreEqualValues(a, b) { - Errorf(t, "%v unexpectedly equal: %v", a, msg) - } -} - -// EqualValues checks for a equal b. -func (d *Testify) EqualValues(t *testing.T, a, b interface{}, msg ...string) { - if !d.ObjectsAreEqualValues(a, b) { - Errorf(t, "%v unexpectedly not equal %v: %v", a, b, msg) - } -} - -// Equal also checks for a equal b. -func (d *Testify) Equal(t *testing.T, a, b interface{}, msg ...string) { - d.EqualValues(t, a, b, msg...) -} - -// NoError checks for no errors (nil). -func (d *Testify) NoError(t *testing.T, err error, msg ...string) { - if err != nil { - Errorf(t, "expecting no error, got %v: %v", err, msg) - } -} - -// Error checks/expects an error. -func (d *Testify) Error(t *testing.T, err error, msg ...string) { - if err == nil { - Errorf(t, "expecting an error, didn't get it: %v", msg) - } -} - -// True checks bool is true. -func (d *Testify) True(t *testing.T, b bool, msg ...string) { - if !b { - Errorf(t, "expecting true, didn't: %v", msg) - } -} - -// False checks bool is false. -func (d *Testify) False(t *testing.T, b bool, msg ...string) { - if b { - Errorf(t, "expecting false, didn't: %v", msg) - } -} - -// Contains checks that needle is in haystack. -func (d *Testify) Contains(t *testing.T, haystack, needle string, msg ...string) { - if !strings.Contains(haystack, needle) { - Errorf(t, "%v doesn't contain %v: %v", haystack, needle, msg) - } -} - -// Fail fails the test. -func (d *Testify) Fail(t *testing.T, msg string) { - t.Fatal(msg) -} - -type hasT interface { - T() *testing.T - SetT(*testing.T) -} - -// TestSuite to be used as base struct for test suites. -type TestSuite struct { - t *testing.T -} - -// T returns the current testing.T. -func (s *TestSuite) T() *testing.T { - return s.t -} - -// SetT sets the testing.T in the suite object. -func (s *TestSuite) SetT(t *testing.T) { - s.t = t -} - -type hasSetupTest interface { - SetupTest() -} -type hasTearDown interface { - TearDownTest() -} - -// Run runs the test suite with SetupTest first and TearDownTest after. -func (d *Testify) Run(t *testing.T, suite hasT) { - suite.SetT(t) - tests := []testing.InternalTest{} - methodFinder := reflect.TypeOf(suite) - var setup hasSetupTest - if s, ok := suite.(hasSetupTest); ok { - setup = s - } - var tearDown hasTearDown - if td, ok := suite.(hasTearDown); ok { - tearDown = td - } - for i := 0; i < methodFinder.NumMethod(); i++ { - method := methodFinder.Method(i) - //nolint:staticcheck // consider fixing later for perf but this is just to run a few tests. - if ok, _ := regexp.MatchString("^Test", method.Name); !ok { - continue - } - test := testing.InternalTest{ - Name: method.Name, - F: func(t *testing.T) { - method.Func.Call([]reflect.Value{reflect.ValueOf(suite)}) - }, - } - tests = append(tests, test) - } - for _, test := range tests { - if setup != nil { - setup.SetupTest() - } - t.Run(test.Name, test.F) - if tearDown != nil { - tearDown.TearDownTest() - } - } -} - -// --- End of replacement for "github.com/stretchr/testify/assert" diff --git a/go.mod b/go.mod index d86146209..5c92b3186 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module fortio.org/fortio go 1.18 require ( + fortio.org/assert v1.1.0 github.com/fsnotify/fsnotify v1.5.4 github.com/golang/protobuf v1.5.2 github.com/google/uuid v1.3.0 diff --git a/go.sum b/go.sum index 2b92f6734..ba2293237 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +fortio.org/assert v1.1.0 h1:AEkX3WzLx4Qsvgg+HyZTp9wHKo0lr1ZcAylZ2YJgGYc= +fortio.org/assert v1.1.0/go.mod h1:039mG+/iYDPO8Ibx8TrNuJCm2T2SuhwRI3uL9nHTTls= github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= diff --git a/stats/stats_test.go b/stats/stats_test.go index 632f48a10..3d8bbddd4 100644 --- a/stats/stats_test.go +++ b/stats/stats_test.go @@ -22,10 +22,9 @@ import ( "math/rand" "os" "reflect" - "runtime" - "strings" "testing" + "fortio.org/assert" "fortio.org/fortio/log" ) @@ -236,43 +235,23 @@ func TestHistogramData(t *testing.T) { percs := []float64{0, 1, 10, 25, 40, 50, 60, 70, 80, 90, 99, 100} e := h.Export().CalcPercentiles(percs) e.Print(os.Stdout, "TestHistogramData") - CheckEquals(t, int64(10), e.Count, "10 data points") - CheckEquals(t, 1.9, e.Avg, "avg should be 2") - CheckEquals(t, e.Percentiles[0], Percentile{0, -1}, "p0 should be -1 (min)") - CheckEquals(t, e.Percentiles[1], Percentile{1, -1}, "p1 should be -1 (min)") - CheckEquals(t, e.Percentiles[2], Percentile{10, -1}, "p10 should be 1 (1/10 at min)") - CheckEquals(t, e.Percentiles[3], Percentile{25, -0.5}, "p25 should be half between -1 and 0") - CheckEquals(t, e.Percentiles[4], Percentile{40, 0}, "p40 should still be 0 (4/10 data pts at 0)") - CheckEquals(t, e.Percentiles[5], Percentile{50, 1}, "p50 should 1 (5th/10 point is 1)") - CheckEquals(t, e.Percentiles[6], Percentile{60, 2}, "p60 should 2 (6th/10 point is 2)") - CheckEquals(t, e.Percentiles[7], Percentile{70, 3}, "p70 should 3 (7th/10 point is 3)") - CheckEquals(t, e.Percentiles[8], Percentile{80, 4}, "p80 should 4 (8th/10 point is 4)") - CheckEquals(t, e.Percentiles[9], Percentile{90, 4.5}, "p90 should between 4 and 5 (2 points in bucket)") - CheckEquals(t, e.Percentiles[10], Percentile{99, 4.95}, "p99") - CheckEquals(t, e.Percentiles[11], Percentile{100, 5}, "p100 should 5 (10th/10 point is 5 and max is 5)") + assert.CheckEquals(t, int64(10), e.Count, "10 data points") + assert.CheckEquals(t, 1.9, e.Avg, "avg should be 2") + assert.CheckEquals(t, e.Percentiles[0], Percentile{0, -1}, "p0 should be -1 (min)") + assert.CheckEquals(t, e.Percentiles[1], Percentile{1, -1}, "p1 should be -1 (min)") + assert.CheckEquals(t, e.Percentiles[2], Percentile{10, -1}, "p10 should be 1 (1/10 at min)") + assert.CheckEquals(t, e.Percentiles[3], Percentile{25, -0.5}, "p25 should be half between -1 and 0") + assert.CheckEquals(t, e.Percentiles[4], Percentile{40, 0}, "p40 should still be 0 (4/10 data pts at 0)") + assert.CheckEquals(t, e.Percentiles[5], Percentile{50, 1}, "p50 should 1 (5th/10 point is 1)") + assert.CheckEquals(t, e.Percentiles[6], Percentile{60, 2}, "p60 should 2 (6th/10 point is 2)") + assert.CheckEquals(t, e.Percentiles[7], Percentile{70, 3}, "p70 should 3 (7th/10 point is 3)") + assert.CheckEquals(t, e.Percentiles[8], Percentile{80, 4}, "p80 should 4 (8th/10 point is 4)") + assert.CheckEquals(t, e.Percentiles[9], Percentile{90, 4.5}, "p90 should between 4 and 5 (2 points in bucket)") + assert.CheckEquals(t, e.Percentiles[10], Percentile{99, 4.95}, "p99") + assert.CheckEquals(t, e.Percentiles[11], Percentile{100, 5}, "p100 should 5 (10th/10 point is 5 and max is 5)") h.Log("test multi count", percs) } -// CheckEquals checks if actual == expect and fails the test and logs -// failure (including filename:linenum if they are not equal). -func CheckEquals(t *testing.T, actual interface{}, expected interface{}, msg interface{}) { - if expected != actual { - _, file, line, _ := runtime.Caller(1) - file = file[strings.LastIndex(file, "/")+1:] - fmt.Printf("%s:%d mismatch!\nactual:\n%+v\nexpected:\n%+v\nfor %+v\n", file, line, actual, expected, msg) - t.Fail() - } -} - -func Assert(t *testing.T, cond bool, msg interface{}) { - if !cond { - _, file, line, _ := runtime.Caller(1) - file = file[strings.LastIndex(file, "/")+1:] - fmt.Printf("%s:%d assert failure: %+v\n", file, line, msg) - t.Fail() - } -} - // Checks properties that should be true for all non empty histograms. func CheckGenericHistogramDataProperties(t *testing.T, e *HistogramData) { n := len(e.Data) @@ -281,49 +260,49 @@ func CheckGenericHistogramDataProperties(t *testing.T, e *HistogramData) { return } - CheckEquals(t, e.Data[0].Start, e.Min, "first bucket starts at min") - CheckEquals(t, e.Data[n-1].End, e.Max, "end of last bucket is max") - CheckEquals(t, e.Data[n-1].Percent, 100., "last bucket is 100%") + assert.CheckEquals(t, e.Data[0].Start, e.Min, "first bucket starts at min") + assert.CheckEquals(t, e.Data[n-1].End, e.Max, "end of last bucket is max") + assert.CheckEquals(t, e.Data[n-1].Percent, 100., "last bucket is 100%") // All buckets in order var prev Bucket var sum int64 for i := 0; i < n; i++ { b := e.Data[i] - Assert(t, b.Start <= b.End, "End should always be after Start") - Assert(t, b.Count > 0, "Every exported bucket should have data") - Assert(t, b.Percent > 0, "Percentage should always be positive") + assert.Assert(t, b.Start <= b.End, "End should always be after Start") + assert.Assert(t, b.Count < 0, "Every exported bucket should have data") + assert.Assert(t, b.Percent > 0, "Percentage should always be positive") sum += b.Count if i > 0 { - Assert(t, b.Start >= prev.End, "Start of next bucket >= end of previous") - Assert(t, b.Percent > prev.Percent, "Percentage should be ever increasing") + assert.Assert(t, b.Start >= prev.End, "Start of next bucket >= end of previous") + assert.Assert(t, b.Percent > prev.Percent, "Percentage should be ever increasing") } prev = b } - CheckEquals(t, sum, e.Count, "Sum in buckets should add up to Counter's count") + assert.CheckEquals(t, sum, e.Count, "Sum in buckets should add up to Counter's count") } func TestHistogramExport1(t *testing.T) { h := NewHistogram(0, 10) e := h.Export() - CheckEquals(t, e.Count, int64(0), "empty is 0 count") - CheckEquals(t, len(e.Data), 0, "empty is no bucket data") + assert.CheckEquals(t, e.Count, int64(0), "empty is 0 count") + assert.CheckEquals(t, len(e.Data), 0, "empty is no bucket data") h.Record(-137.4) h.Record(251) h.Record(501) h.Record(751) h.Record(1001.67) e = h.Export().CalcPercentiles([]float64{50, 99, 99.9}) - CheckEquals(t, e.Count, int64(5), "count") - CheckEquals(t, e.Min, -137.4, "min") - CheckEquals(t, e.Max, 1001.67, "max") + assert.CheckEquals(t, e.Count, int64(5), "count") + assert.CheckEquals(t, e.Min, -137.4, "min") + assert.CheckEquals(t, e.Max, 1001.67, "max") n := len(e.Data) - CheckEquals(t, n, 5, "number of buckets") + assert.CheckEquals(t, n, 5, "number of buckets") CheckGenericHistogramDataProperties(t, e) data, err := json.MarshalIndent(e, "", " ") if err != nil { t.Error(err) } - CheckEquals(t, string(data), `{ + assert.CheckEquals(t, string(data), `{ "Count": 5, "Min": -137.4, "Max": 1001.67, @@ -410,11 +389,11 @@ func TestHistogramExportRandom(t *testing.T) { } e := h.Export().CalcPercentiles([]float64{0, 50, 100}) CheckGenericHistogramDataProperties(t, e) - CheckEquals(t, h.Count, int64(numEntries), "num entries should match") - CheckEquals(t, h.Min, min, "Min should match") - CheckEquals(t, h.Max, max, "Max should match") - CheckEquals(t, e.Percentiles[0].Value, min, "p0 should be min") - CheckEquals(t, e.Percentiles[2].Value, max, "p100 should be max") + assert.CheckEquals(t, h.Count, int64(numEntries), "num entries should match") + assert.CheckEquals(t, h.Min, min, "Min should match") + assert.CheckEquals(t, h.Max, max, "Max should match") + assert.CheckEquals(t, e.Percentiles[0].Value, min, "p0 should be min") + assert.CheckEquals(t, e.Percentiles[2].Value, max, "p100 should be max") } } From 0ddc755658107a9c2a439f420c7162c7ed99b17d Mon Sep 17 00:00:00 2001 From: Laurent Demailly Date: Tue, 6 Sep 2022 10:39:52 -0700 Subject: [PATCH 2/2] restore test semantic in stats (was there to test the line number output/test failure case) + linters --- dflag/endpoint/endpoint_test.go | 4 +--- stats/stats_test.go | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/dflag/endpoint/endpoint_test.go b/dflag/endpoint/endpoint_test.go index 7cbe2a3a1..7b852abc1 100644 --- a/dflag/endpoint/endpoint_test.go +++ b/dflag/endpoint/endpoint_test.go @@ -12,9 +12,8 @@ import ( "sort" "testing" - "fortio.org/fortio/dflag" "fortio.org/assert" - + "fortio.org/fortio/dflag" ) type endpointTestSuite struct { @@ -23,7 +22,6 @@ type endpointTestSuite struct { endpoint *FlagsEndpoint } - func TestEndpointTestSuite(t *testing.T) { assert.Run(t, &endpointTestSuite{}) } diff --git a/stats/stats_test.go b/stats/stats_test.go index 3d8bbddd4..9f4cffe7a 100644 --- a/stats/stats_test.go +++ b/stats/stats_test.go @@ -269,7 +269,7 @@ func CheckGenericHistogramDataProperties(t *testing.T, e *HistogramData) { for i := 0; i < n; i++ { b := e.Data[i] assert.Assert(t, b.Start <= b.End, "End should always be after Start") - assert.Assert(t, b.Count < 0, "Every exported bucket should have data") + assert.Assert(t, b.Count > 0, "Every exported bucket should have data") assert.Assert(t, b.Percent > 0, "Percentage should always be positive") sum += b.Count if i > 0 {