github.com/attic-labs/noms@v0.0.0-20210827224422-e5fa29d95e8b/go/perf/suite/suite_test.go (about) 1 // Copyright 2016 Attic Labs, Inc. All rights reserved. 2 // Licensed under the Apache License, version 2.0: 3 // http://www.apache.org/licenses/LICENSE-2.0 4 5 package suite 6 7 import ( 8 "io/ioutil" 9 "os" 10 "testing" 11 "time" 12 13 "github.com/attic-labs/noms/go/spec" 14 "github.com/attic-labs/noms/go/types" 15 "github.com/stretchr/testify/assert" 16 ) 17 18 type testSuite struct { 19 PerfSuite 20 tempFileName, tempDir string 21 setupTest, tearDownTest int 22 setupRep, tearDownRep int 23 setupSuite, tearDownSuite int 24 foo, bar, abc, def, nothing, testimate int 25 } 26 27 func (s *testSuite) TestNonEmptyPaths() { 28 assert := s.NewAssert() 29 assert.NotEqual("", s.AtticLabs) 30 assert.NotEqual("", s.Testdata) 31 assert.NotEqual("", s.DatabaseSpec) 32 } 33 34 func (s *testSuite) TestDatabase() { 35 assert := s.NewAssert() 36 val := types.Bool(true) 37 r := s.Database.WriteValue(val) 38 assert.True(s.Database.ReadValue(r.TargetHash()).Equals(val)) 39 } 40 41 func (s *testSuite) TestTempFile() { 42 s.tempFileName = s.TempFile().Name() 43 s.tempDir = s.TempDir() 44 } 45 46 func (s *testSuite) TestGlob() { 47 assert := s.NewAssert() 48 f := s.TempFile() 49 f.Close() 50 51 create := func(suffix string) { 52 f, err := os.Create(f.Name() + suffix) 53 assert.NoError(err) 54 f.Close() 55 } 56 57 create("a") 58 create(".a") 59 create(".b") 60 61 glob := s.OpenGlob(f.Name() + ".*") 62 assert.Equal(2, len(glob)) 63 assert.Equal(f.Name()+".a", glob[0].(*os.File).Name()) 64 assert.Equal(f.Name()+".b", glob[1].(*os.File).Name()) 65 66 s.CloseGlob(glob) 67 b := make([]byte, 16) 68 _, err := glob[0].Read(b) 69 assert.Error(err) 70 _, err = glob[1].Read(b) 71 assert.Error(err) 72 } 73 74 func (s *testSuite) TestPause() { 75 s.Pause(func() { 76 s.waitForSmidge() 77 }) 78 } 79 80 func (s *testSuite) TestFoo() { 81 s.foo++ 82 s.waitForSmidge() 83 } 84 85 func (s *testSuite) TestBar() { 86 s.bar++ 87 s.waitForSmidge() 88 } 89 90 func (s *testSuite) Test01Abc() { 91 s.abc++ 92 s.waitForSmidge() 93 } 94 95 func (s *testSuite) Test02Def() { 96 s.def++ 97 s.waitForSmidge() 98 } 99 100 func (s *testSuite) testNothing() { 101 s.nothing++ 102 s.waitForSmidge() 103 } 104 105 func (s *testSuite) Testimate() { 106 s.testimate++ 107 s.waitForSmidge() 108 } 109 110 func (s *testSuite) SetupTest() { 111 s.setupTest++ 112 } 113 114 func (s *testSuite) TearDownTest() { 115 s.tearDownTest++ 116 } 117 118 func (s *testSuite) SetupRep() { 119 s.setupRep++ 120 } 121 122 func (s *testSuite) TearDownRep() { 123 s.tearDownRep++ 124 } 125 126 func (s *testSuite) SetupSuite() { 127 s.setupSuite++ 128 } 129 130 func (s *testSuite) TearDownSuite() { 131 s.tearDownSuite++ 132 } 133 134 func (s *testSuite) waitForSmidge() { 135 // Tests should call this to make sure the measurement shows up as > 0, not that it shows up as a millisecond. 136 <-time.After(time.Millisecond) 137 } 138 139 func TestSuite(t *testing.T) { 140 runTestSuite(t, false) 141 } 142 143 func TestSuiteWithMem(t *testing.T) { 144 t.Skip("Flaky on Jenkins") 145 runTestSuite(t, true) 146 } 147 148 func runTestSuite(t *testing.T, mem bool) { 149 assert := assert.New(t) 150 151 // Write test results to our own temporary LDB database. 152 ldbDir, err := ioutil.TempDir("", "suite.TestSuite") 153 assert.NoError(err) 154 defer os.RemoveAll(ldbDir) 155 156 flagVal, repeatFlagVal, memFlagVal := *perfFlag, *perfRepeatFlag, *perfMemFlag 157 *perfFlag, *perfRepeatFlag, *perfMemFlag = ldbDir, 3, mem 158 defer func() { 159 *perfFlag, *perfRepeatFlag, *perfMemFlag = flagVal, repeatFlagVal, memFlagVal 160 }() 161 162 s := &testSuite{} 163 Run("ds", t, s) 164 165 expectedTests := []string{ 166 "Abc", 167 "Bar", 168 "Database", 169 "Def", 170 "Foo", 171 "Glob", 172 "NonEmptyPaths", 173 "Pause", 174 "TempFile", 175 } 176 177 // The temp file and dir should have been cleaned up. 178 _, err = os.Stat(s.tempFileName) 179 assert.NotNil(err) 180 _, err = os.Stat(s.tempDir) 181 assert.NotNil(err) 182 183 // The correct number of Setup/TearDown calls should have been run. 184 assert.Equal(1, s.setupSuite) 185 assert.Equal(1, s.tearDownSuite) 186 assert.Equal(*perfRepeatFlag, s.setupRep) 187 assert.Equal(*perfRepeatFlag, s.tearDownRep) 188 assert.Equal(*perfRepeatFlag*len(expectedTests), s.setupTest) 189 assert.Equal(*perfRepeatFlag*len(expectedTests), s.tearDownTest) 190 191 // The results should have been written to the "ds" dataset. 192 sp, err := spec.ForDataset(ldbDir + "::ds") 193 assert.NoError(err) 194 defer sp.Close() 195 head := sp.GetDataset().HeadValue().(types.Struct) 196 197 // These tests mostly assert that the structure of the results is correct. Specific values are hard. 198 199 getOrFail := func(s types.Struct, f string) types.Value { 200 val, ok := s.MaybeGet(f) 201 assert.True(ok) 202 return val 203 } 204 205 env, ok := getOrFail(head, "environment").(types.Struct) 206 assert.True(ok) 207 208 getOrFail(env, "diskUsages") 209 getOrFail(env, "cpus") 210 getOrFail(env, "mem") 211 getOrFail(env, "host") 212 getOrFail(env, "partitions") 213 214 // Todo: re-enable this code once demo-server gets build without CodePipeline 215 // This fails with CodePipeline because the source code is brought into 216 // Jenkins as a zip file rather than as a git repo. 217 //nomsRevision := getOrFail(head, "nomsRevision") 218 //assert.True(ok) 219 //assert.True(string(nomsRevision.(types.String)) != "") 220 //getOrFail(head, "testdataRevision") 221 222 reps, ok := getOrFail(head, "reps").(types.List) 223 assert.True(ok) 224 assert.Equal(*perfRepeatFlag, int(reps.Len())) 225 226 reps.IterAll(func(rep types.Value, _ uint64) { 227 i := 0 228 229 rep.(types.Map).IterAll(func(k, timesVal types.Value) { 230 if assert.True(i < len(expectedTests)) { 231 assert.Equal(expectedTests[i], string(k.(types.String))) 232 } 233 234 times := timesVal.(types.Struct) 235 assert.True(getOrFail(times, "elapsed").(types.Number) > 0) 236 assert.True(getOrFail(times, "total").(types.Number) > 0) 237 238 paused := getOrFail(times, "paused").(types.Number) 239 if k == types.String("Pause") { 240 assert.True(paused > 0) 241 } else { 242 assert.True(paused == 0) 243 } 244 245 i++ 246 }) 247 248 assert.Equal(i, len(expectedTests)) 249 }) 250 } 251 252 func TestPrefixFlag(t *testing.T) { 253 t.Skip("Flaky on Jenkins") 254 assert := assert.New(t) 255 256 // Write test results to a temporary database. 257 ldbDir, err := ioutil.TempDir("", "suite.TestSuite") 258 assert.NoError(err) 259 defer os.RemoveAll(ldbDir) 260 261 flagVal, prefixFlagVal := *perfFlag, *perfPrefixFlag 262 *perfFlag, *perfPrefixFlag = ldbDir, "foo/" 263 defer func() { 264 *perfFlag, *perfPrefixFlag = flagVal, prefixFlagVal 265 }() 266 267 Run("my-prefix/test", t, &PerfSuite{}) 268 269 // The results should have been written to "foo/my-prefix/test" not "my-prefix/test". 270 sp, err := spec.ForDataset(ldbDir + "::my-prefix/test") 271 assert.NoError(err) 272 defer sp.Close() 273 _, ok := sp.GetDataset().MaybeHead() 274 assert.False(ok) 275 276 sp, err = spec.ForDataset(ldbDir + "::foo/my-prefix/test") 277 assert.NoError(err) 278 defer sp.Close() 279 _, ok = sp.GetDataset().HeadValue().(types.Struct) 280 assert.True(ok) 281 } 282 283 func TestRunFlag(t *testing.T) { 284 t.Skip("Flaky on Jenkins") 285 assert := assert.New(t) 286 287 type expect struct { 288 foo, bar, abc, def, nothing, testimate int 289 } 290 291 run := func(re string, exp expect) { 292 flagVal, memFlagVal, runFlagVal := *perfFlag, *perfMemFlag, *perfRunFlag 293 *perfFlag, *perfMemFlag, *perfRunFlag = "mem", true, re 294 defer func() { 295 *perfFlag, *perfMemFlag, *perfRunFlag = flagVal, memFlagVal, runFlagVal 296 }() 297 s := testSuite{} 298 Run("test", t, &s) 299 assert.Equal(exp, expect{s.foo, s.bar, s.abc, s.def, s.nothing, s.testimate}) 300 } 301 302 run("", expect{foo: 1, bar: 1, abc: 1, def: 1}) 303 run(".", expect{foo: 1, bar: 1, abc: 1, def: 1}) 304 run("test", expect{foo: 1, bar: 1, abc: 1, def: 1}) 305 run("^test", expect{foo: 1, bar: 1, abc: 1, def: 1}) 306 run("Test", expect{foo: 1, bar: 1, abc: 1, def: 1}) 307 run("^Test", expect{foo: 1, bar: 1, abc: 1, def: 1}) 308 309 run("f", expect{foo: 1, def: 1}) 310 run("^f", expect{foo: 1}) 311 run("testf", expect{foo: 1}) 312 run("^testf", expect{foo: 1}) 313 run("testF", expect{foo: 1}) 314 run("^testF", expect{foo: 1}) 315 316 run("F", expect{foo: 1, def: 1}) 317 run("^F", expect{foo: 1}) 318 run("Testf", expect{foo: 1}) 319 run("^Testf", expect{foo: 1}) 320 run("TestF", expect{foo: 1}) 321 run("^TestF", expect{foo: 1}) 322 323 run("ef", expect{def: 1}) 324 run("def", expect{def: 1}) 325 run("ddef", expect{}) 326 run("testdef", expect{}) 327 run("test01def", expect{}) 328 run("test02def", expect{def: 1}) 329 run("Test02def", expect{def: 1}) 330 run("test02Def", expect{def: 1}) 331 run("Test02Def", expect{def: 1}) 332 333 run("z", expect{}) 334 run("testz", expect{}) 335 run("Testz", expect{}) 336 337 run("[fa]", expect{foo: 1, bar: 1, abc: 1, def: 1}) 338 run("[fb]", expect{foo: 1, bar: 1, abc: 1, def: 1}) 339 run("[fc]", expect{foo: 1, abc: 1, def: 1}) 340 run("test[fa]", expect{foo: 1}) 341 run("test[fb]", expect{foo: 1, bar: 1}) 342 run("test[fc]", expect{foo: 1}) 343 run("Test[fa]", expect{foo: 1}) 344 run("Test[fb]", expect{foo: 1, bar: 1}) 345 run("Test[fc]", expect{foo: 1}) 346 347 run("foo|bar", expect{foo: 1, bar: 1}) 348 run("FOO|bar", expect{foo: 1, bar: 1}) 349 run("Testfoo|bar", expect{foo: 1, bar: 1}) 350 run("TestFOO|bar", expect{foo: 1, bar: 1}) 351 352 run("Testfoo|Testbar", expect{foo: 1, bar: 1}) 353 run("TestFOO|Testbar", expect{foo: 1, bar: 1}) 354 355 run("footest", expect{}) 356 run("nothing", expect{}) 357 }