github.com/ndau/noms@v1.0.5/go/types/perf/perf_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 perf
     6  
     7  import (
     8  	"io"
     9  	"io/ioutil"
    10  	"math/rand"
    11  	"os"
    12  	"testing"
    13  
    14  	"github.com/ndau/noms/go/perf/suite"
    15  	"github.com/ndau/noms/go/types"
    16  	"github.com/stretchr/testify/assert"
    17  )
    18  
    19  type perfSuite struct {
    20  	suite.PerfSuite
    21  	r  *rand.Rand
    22  	ds string
    23  }
    24  
    25  func (s *perfSuite) SetupSuite() {
    26  	s.r = rand.New(rand.NewSource(0))
    27  }
    28  
    29  func (s *perfSuite) Test01BuildList10mNumbers() {
    30  	assert := s.NewAssert()
    31  	in := make(chan types.Value, 16)
    32  	out := types.NewStreamingList(s.Database, in)
    33  
    34  	for i := 0; i < 1e7; i++ {
    35  		in <- types.Number(s.r.Int63())
    36  	}
    37  	close(in)
    38  
    39  	ds := s.Database.GetDataset("BuildList10mNumbers")
    40  
    41  	var err error
    42  	ds, err = s.Database.CommitValue(ds, <-out)
    43  
    44  	assert.NoError(err)
    45  	s.Database = ds.Database()
    46  }
    47  
    48  func (s *perfSuite) Test02BuildList10mStructs() {
    49  	assert := s.NewAssert()
    50  	in := make(chan types.Value, 16)
    51  	out := types.NewStreamingList(s.Database, in)
    52  
    53  	for i := 0; i < 1e7; i++ {
    54  		in <- types.NewStruct("", types.StructData{
    55  			"number": types.Number(s.r.Int63()),
    56  		})
    57  	}
    58  	close(in)
    59  
    60  	ds := s.Database.GetDataset("BuildList10mStructs")
    61  
    62  	var err error
    63  	ds, err = s.Database.CommitValue(ds, <-out)
    64  
    65  	assert.NoError(err)
    66  	s.Database = ds.Database()
    67  }
    68  
    69  func (s *perfSuite) Test03Read10mNumbers() {
    70  	s.headList("BuildList10mNumbers").IterAll(func(v types.Value, index uint64) {})
    71  }
    72  
    73  func (s *perfSuite) Test04Read10mStructs() {
    74  	s.headList("BuildList10mStructs").IterAll(func(v types.Value, index uint64) {})
    75  }
    76  
    77  func (s *perfSuite) Test05Concat10mValues2kTimes() {
    78  	assert := s.NewAssert()
    79  
    80  	last := func(v types.List) types.Value {
    81  		return v.Get(v.Len() - 1)
    82  	}
    83  
    84  	l1 := s.headList("BuildList10mNumbers")
    85  	l2 := s.headList("BuildList10mStructs")
    86  	l1Len, l2Len := l1.Len(), l2.Len()
    87  	l1Last, l2Last := last(l1), last(l2)
    88  
    89  	l3 := types.NewList(s.Database)
    90  	for i := uint64(0); i < 1e3; i++ { // 1k iterations * 2 concat ops = 2k times
    91  		// Include some basic sanity checks.
    92  		l3 = l3.Concat(l1)
    93  		assert.True(l1Last.Equals(last(l3)))
    94  		assert.Equal(i*(l1Len+l2Len)+l1Len, l3.Len())
    95  		l3 = l3.Concat(l2)
    96  		assert.True(l2Last.Equals(last(l3)))
    97  		assert.Equal((i+1)*(l1Len+l2Len), l3.Len())
    98  	}
    99  
   100  	ds := s.Database.GetDataset("Concat10mValues2kTimes")
   101  	var err error
   102  	ds, err = s.Database.CommitValue(ds, l3)
   103  
   104  	assert.NoError(err)
   105  	s.Database = ds.Database()
   106  }
   107  
   108  func (s *perfSuite) TestBuild500megBlobFromFilesP1() {
   109  	s.testBuild500megBlob(1)
   110  }
   111  
   112  func (s *perfSuite) TestBuild500megBlobFromFilesP2() {
   113  	s.testBuild500megBlob(2)
   114  }
   115  
   116  func (s *perfSuite) TestBuild500megBlobFromFilesP8() {
   117  	s.testBuild500megBlob(8)
   118  }
   119  
   120  func (s *perfSuite) TestBuild500megBlobFromFilesP64() {
   121  	// Note: can't have too many files open.
   122  	s.testBuild500megBlob(64)
   123  }
   124  
   125  func (s *perfSuite) testBuild500megBlob(p int) {
   126  	assert := s.NewAssert()
   127  	size := int(5e8)
   128  
   129  	readers := make([]io.Reader, p)
   130  	defer func() {
   131  		for _, r := range readers {
   132  			f := r.(*os.File)
   133  			err := f.Close()
   134  			assert.NoError(err)
   135  			err = os.Remove(f.Name())
   136  			assert.NoError(err)
   137  		}
   138  	}()
   139  
   140  	s.Pause(func() {
   141  		for i := range readers {
   142  			f, err := ioutil.TempFile("", "testBuildBlob")
   143  			assert.NoError(err)
   144  			_, err = f.Write(s.randomBytes(int64(i), size/p))
   145  			assert.NoError(err)
   146  			err = f.Close()
   147  			assert.NoError(err)
   148  			f, err = os.Open(f.Name())
   149  			assert.NoError(err)
   150  			readers[i] = f
   151  		}
   152  	})
   153  
   154  	b := types.NewBlob(s.Database, readers...)
   155  	assert.Equal(uint64(size), b.Len())
   156  }
   157  
   158  func (s *perfSuite) randomBytes(seed int64, size int) []byte {
   159  	r := rand.New(rand.NewSource(seed))
   160  	randBytes := make([]byte, size)
   161  	_, err := r.Read(randBytes)
   162  	assert.NoError(s.T, err)
   163  	return randBytes
   164  }
   165  
   166  func (s *perfSuite) headList(dsName string) types.List {
   167  	ds := s.Database.GetDataset(dsName)
   168  	return ds.HeadValue().(types.List)
   169  }
   170  
   171  func TestPerf(t *testing.T) {
   172  	suite.Run("types", t, &perfSuite{})
   173  }