github.com/m3db/m3@v1.5.1-0.20231129193456-75a402aa583b/src/integration/legacy/cold_write_test.go (about)

     1  // +build cluster_integration
     2  //
     3  // Copyright (c) 2020  Uber Technologies, Inc.
     4  //
     5  // Permission is hereby granted, free of charge, to any person obtaining a copy
     6  // of this software and associated documentation files (the "Software"), to deal
     7  // in the Software without restriction, including without limitation the rights
     8  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     9  // copies of the Software, and to permit persons to whom the Software is
    10  // furnished to do so, subject to the following conditions:
    11  //
    12  // The above copyright notice and this permission notice shall be included in
    13  // all copies or substantial portions of the Software.
    14  //
    15  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    16  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    17  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    18  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    19  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    20  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    21  // THE SOFTWARE.
    22  
    23  package legacy
    24  
    25  import (
    26  	"errors"
    27  	"fmt"
    28  	"regexp"
    29  	"strings"
    30  	"testing"
    31  	"time"
    32  
    33  	"github.com/m3db/m3/src/dbnode/generated/thrift/rpc"
    34  	"github.com/m3db/m3/src/integration/resources"
    35  	"github.com/m3db/m3/src/integration/resources/inprocess"
    36  
    37  	"github.com/stretchr/testify/assert"
    38  	"github.com/stretchr/testify/require"
    39  )
    40  
    41  type dp struct {
    42  	t time.Time
    43  	v float64
    44  }
    45  
    46  func writeReq(ns, id string, dp dp) *rpc.WriteRequest {
    47  	return &rpc.WriteRequest{
    48  		NameSpace: ns,
    49  		ID:        id,
    50  		Datapoint: &rpc.Datapoint{
    51  			Timestamp: dp.t.Unix(),
    52  			Value:     dp.v,
    53  		},
    54  	}
    55  }
    56  
    57  func fetchReq(ns, id string) *rpc.FetchRequest {
    58  	return &rpc.FetchRequest{
    59  		NameSpace:  ns,
    60  		ID:         id,
    61  		RangeStart: 0,
    62  		RangeEnd:   time.Now().Unix(),
    63  	}
    64  }
    65  
    66  func ago(mins time.Duration) time.Time {
    67  	return time.Now().Add(time.Minute * -mins)
    68  }
    69  
    70  func verifyFetch(t *testing.T, res *rpc.FetchResult_, exDps ...dp) {
    71  	dps := res.GetDatapoints()
    72  	require.Equal(t, len(dps), len(exDps))
    73  
    74  	for i, dp := range exDps {
    75  		other := dps[i]
    76  		assert.Equal(t, dp.t.Unix(), other.GetTimestamp())
    77  		assert.Equal(t, dp.v, other.GetValue())
    78  	}
    79  }
    80  
    81  func hasFileVerifier(filter string) resources.GoalStateVerifier {
    82  	return func(out string, err error) error {
    83  		if err != nil {
    84  			return err
    85  		}
    86  
    87  		if len(filter) == 0 {
    88  			return nil
    89  		}
    90  
    91  		re := regexp.MustCompile(filter)
    92  		lines := strings.Split(out, "\n")
    93  		for _, line := range lines {
    94  			if re.MatchString(line) {
    95  				return nil
    96  			}
    97  		}
    98  
    99  		return errors.New("no matches")
   100  	}
   101  }
   102  
   103  func TestColdWritesSimple(t *testing.T) {
   104  	node := m3.Nodes()[0]
   105  	warmDp := dp{t: ago(20), v: 12.3456789}
   106  	req := writeReq(resources.ColdWriteNsName, "foo", warmDp)
   107  	require.NoError(t, node.WritePoint(req))
   108  
   109  	fetch, err := node.Fetch(fetchReq(resources.ColdWriteNsName, "foo"))
   110  	require.NoError(t, err)
   111  	verifyFetch(t, fetch, warmDp)
   112  
   113  	coldDp := dp{t: ago(120), v: 98.7654321}
   114  	req = writeReq(resources.ColdWriteNsName, "foo", coldDp)
   115  	require.NoError(t, node.WritePoint(req))
   116  
   117  	fetch, err = node.Fetch(fetchReq(resources.ColdWriteNsName, "foo"))
   118  	require.NoError(t, err)
   119  	verifyFetch(t, fetch, coldDp, warmDp)
   120  
   121  	dbnode := m3.Nodes()[0].(*inprocess.DBNode)
   122  	cfg := dbnode.Configuration()
   123  
   124  	err = node.GoalStateExec(hasFileVerifier(".*1-checkpoint.db"),
   125  		"find",
   126  		fmt.Sprintf("%s/data/coldWritesRepairAndNoIndex", *cfg.DB.Filesystem.FilePathPrefix),
   127  		"-name",
   128  		"*1-checkpoint.db")
   129  
   130  	assert.NoError(t, err)
   131  
   132  	// TODO(nate): Restarts of inprocess DB nodes currently not working properly.
   133  	// As such, comment out restart. Re-enable once restarts supported.
   134  	/*
   135  		err = node.Restart()
   136  		require.NoError(t, err)
   137  
   138  		err = node.WaitForBootstrap()
   139  		require.NoError(t, err)
   140  	*/
   141  
   142  	fetch, err = node.Fetch(fetchReq(resources.ColdWriteNsName, "foo"))
   143  	require.NoError(t, err)
   144  	verifyFetch(t, fetch, coldDp, warmDp)
   145  }