github.com/m3db/m3@v1.5.0/src/dbnode/storage/series/series_all_test.go (about)

     1  // Copyright (c) 2016 Uber Technologies, Inc.
     2  //
     3  // Permission is hereby granted, free of charge, to any person obtaining a copy
     4  // of this software and associated documentation files (the "Software"), to deal
     5  // in the Software without restriction, including without limitation the rights
     6  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     7  // copies of the Software, and to permit persons to whom the Software is
     8  // furnished to do so, subject to the following conditions:
     9  //
    10  // The above copyright notice and this permission notice shall be included in
    11  // all copies or substantial portions of the Software.
    12  //
    13  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    14  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    15  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    16  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    17  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    18  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    19  // THE SOFTWARE.
    20  
    21  package series
    22  
    23  import (
    24  	"testing"
    25  	"time"
    26  
    27  	"github.com/m3db/m3/src/dbnode/namespace"
    28  	"github.com/m3db/m3/src/dbnode/x/xio"
    29  	xtime "github.com/m3db/m3/src/x/time"
    30  
    31  	"github.com/davecgh/go-spew/spew"
    32  	"github.com/stretchr/testify/require"
    33  )
    34  
    35  var timeDistantFuture = xtime.Now().Add(10 * 365 * 24 * time.Hour)
    36  
    37  func secs(x float64) time.Duration {
    38  	return time.Duration(x * float64(time.Second))
    39  }
    40  
    41  func mins(x float64) time.Duration {
    42  	return time.Duration(x * float64(time.Minute))
    43  }
    44  
    45  type blockData struct {
    46  	start     xtime.UnixNano
    47  	writeType WriteType
    48  	data      [][]DecodedTestValue
    49  }
    50  
    51  type setAnnotation func([]DecodedTestValue) []DecodedTestValue
    52  type requireAnnEqual func(*testing.T, []byte, []byte)
    53  
    54  func decodedReaderValues(results [][]xio.BlockReader,
    55  	opts Options, nsCtx namespace.Context) ([]DecodedTestValue, error) {
    56  	slicesIter := xio.NewReaderSliceOfSlicesFromBlockReadersIterator(results)
    57  	iter := opts.MultiReaderIteratorPool().Get()
    58  	iter.ResetSliceOfSlices(slicesIter, nsCtx.Schema)
    59  	defer iter.Close()
    60  
    61  	var all []DecodedTestValue
    62  	for iter.Next() {
    63  		dp, unit, annotation := iter.Current()
    64  		// Iterator reuse annotation byte slices, so make a copy.
    65  		annotationCopy := append([]byte(nil), annotation...)
    66  		all = append(all, DecodedTestValue{dp.TimestampNanos, dp.Value, unit, annotationCopy})
    67  	}
    68  	if err := iter.Err(); err != nil {
    69  		return nil, err
    70  	}
    71  
    72  	return all, nil
    73  }
    74  
    75  func requireReaderValuesEqual(t *testing.T, values []DecodedTestValue,
    76  	results [][]xio.BlockReader, opts Options,
    77  	nsCtx namespace.Context) {
    78  	decodedValues, err := decodedReaderValues(results, opts, nsCtx)
    79  	require.NoError(t, err)
    80  	requireValuesEqual(t, values, decodedValues, nsCtx)
    81  }
    82  
    83  func requireValuesEqual(
    84  	t *testing.T,
    85  	expected, actual []DecodedTestValue,
    86  	nsCtx namespace.Context,
    87  ) {
    88  	debugValues := struct {
    89  		ExpectedValues []DecodedTestValue
    90  		ActualValues   []DecodedTestValue
    91  	}{
    92  		ExpectedValues: expected,
    93  		ActualValues:   actual,
    94  	}
    95  	require.Len(t, actual, len(expected),
    96  		"length mismatch: values=%+v", spew.Sdump(debugValues))
    97  	for i := 0; i < len(actual); i++ {
    98  		debugValue := struct {
    99  			ExpectedValue DecodedTestValue
   100  			ActualValue   DecodedTestValue
   101  		}{
   102  			ExpectedValue: expected[i],
   103  			ActualValue:   actual[i],
   104  		}
   105  		require.True(t, expected[i].Timestamp.Equal(actual[i].Timestamp),
   106  			"timestamp mismatch: mismatch=%+v values=%+v",
   107  			spew.Sdump(debugValue), spew.Sdump(debugValues))
   108  		require.Equal(t, expected[i].Value, actual[i].Value,
   109  			"value mismatch: mismatch=%+v values=%+v",
   110  			spew.Sdump(debugValue), spew.Sdump(debugValues))
   111  		require.Equal(t, expected[i].Unit, actual[i].Unit,
   112  			"unit mismatch: mismatch=%+v values=%+v",
   113  			spew.Sdump(debugValue), spew.Sdump(debugValues))
   114  		if nsCtx.Schema == nil {
   115  			require.Equal(t, expected[i].Annotation, actual[i].Annotation,
   116  				"annotation mismatch: mismatch=%+v values=%+v",
   117  				spew.Sdump(debugValue), spew.Sdump(debugValues))
   118  		} else {
   119  			testProtoEqual(t, expected[i].Annotation, actual[i].Annotation)
   120  		}
   121  	}
   122  }
   123  
   124  func decodedSegmentValues(results []xio.SegmentReader, opts Options,
   125  	nsCtx namespace.Context) ([]DecodedTestValue, error) {
   126  	iter := opts.MultiReaderIteratorPool().Get()
   127  	return DecodeSegmentValues(results, iter, nsCtx.Schema)
   128  }
   129  
   130  func requireSegmentValuesEqual(t *testing.T, values []DecodedTestValue,
   131  	results []xio.SegmentReader, opts Options,
   132  	nsCtx namespace.Context) {
   133  	decodedValues, err := decodedSegmentValues(results, opts, nsCtx)
   134  
   135  	require.NoError(t, err)
   136  	requireValuesEqual(t, values, decodedValues, nsCtx)
   137  }