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  }