github.com/m3db/m3@v1.5.1-0.20231129193456-75a402aa583b/src/cmd/services/m3dbnode/main/common_test.go (about)

     1  // +build big
     2  //
     3  // Copyright (c) 2017 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 main_test
    24  
    25  import (
    26  	"bytes"
    27  	"encoding/json"
    28  	"fmt"
    29  	"io/ioutil"
    30  	"os"
    31  	"strings"
    32  	"sync/atomic"
    33  	"testing"
    34  	"time"
    35  
    36  	"github.com/m3db/m3/src/cluster/shard"
    37  	"github.com/m3db/m3/src/dbnode/client"
    38  	"github.com/m3db/m3/src/dbnode/namespace"
    39  	"github.com/m3db/m3/src/dbnode/retention"
    40  	"github.com/m3db/m3/src/x/ident"
    41  
    42  	"github.com/gogo/protobuf/proto"
    43  	"github.com/stretchr/testify/assert"
    44  	"github.com/stretchr/testify/require"
    45  )
    46  
    47  const (
    48  	hostID                 = "m3dbtest01"
    49  	serviceName            = "m3dbnode_test"
    50  	serviceEnv             = "test"
    51  	serviceZone            = "local"
    52  	namespaceID            = "metrics"
    53  	lpURL                  = "http://0.0.0.0:2380"
    54  	lcURL                  = "http://0.0.0.0:2379"
    55  	apURL                  = "http://localhost:2380"
    56  	acURL                  = "http://localhost:2379"
    57  	etcdEndpoint           = acURL
    58  	initialClusterHostID   = hostID
    59  	initialClusterEndpoint = apURL
    60  )
    61  
    62  var (
    63  	// NB: access through nextServicePort
    64  	_servicePort uint32 = 9000
    65  )
    66  
    67  func nextServicePort() uint32 {
    68  	return atomic.AddUint32(&_servicePort, 1000)
    69  }
    70  
    71  type cleanup func()
    72  
    73  func tempFile(t *testing.T, name string) (*os.File, cleanup) {
    74  	fd, err := ioutil.TempFile("", name)
    75  	require.NoError(t, err)
    76  
    77  	fname := fd.Name()
    78  	return fd, func() {
    79  		assert.NoError(t, fd.Close())
    80  		assert.NoError(t, os.Remove(fname))
    81  	}
    82  }
    83  
    84  func tempFileTouch(t *testing.T, name string) (string, cleanup) {
    85  	fd, err := ioutil.TempFile("", name)
    86  	require.NoError(t, err)
    87  
    88  	fname := fd.Name()
    89  	require.NoError(t, fd.Close())
    90  	return fname, func() {
    91  		assert.NoError(t, os.Remove(fname))
    92  	}
    93  }
    94  
    95  func tempDir(t *testing.T, name string) (string, cleanup) {
    96  	dir, err := ioutil.TempDir("", name)
    97  	require.NoError(t, err)
    98  	return dir, func() {
    99  		assert.NoError(t, os.RemoveAll(dir))
   100  	}
   101  }
   102  
   103  // yamlArray returns a JSON array which is valid YAML, hehe..
   104  func yamlArray(t *testing.T, values []string) string {
   105  	buff := bytes.NewBuffer(nil)
   106  	err := json.NewEncoder(buff).Encode(values)
   107  	require.NoError(t, err)
   108  	return strings.TrimSpace(buff.String())
   109  }
   110  
   111  func endpoint(ip string, port uint32) string {
   112  	return fmt.Sprintf("%s:%d", ip, port)
   113  }
   114  
   115  func newNamespaceProtoValue(id string) (proto.Message, error) {
   116  	return newNamespaceWithIndexProtoValue(id, false)
   117  }
   118  
   119  func newNamespaceWithIndexProtoValue(id string, indexEnabled bool) (proto.Message, error) {
   120  	md, err := namespace.NewMetadata(
   121  		ident.StringID(id),
   122  		namespace.NewOptions().
   123  			SetBootstrapEnabled(true).
   124  			SetCleanupEnabled(true).
   125  			SetFlushEnabled(true).
   126  			SetRepairEnabled(true).
   127  			SetWritesToCommitLog(true).
   128  			SetRetentionOptions(
   129  				retention.NewOptions().
   130  					SetBlockSize(1*time.Hour).
   131  					SetRetentionPeriod(24*time.Hour)).
   132  			SetIndexOptions(
   133  				namespace.NewIndexOptions().
   134  					SetBlockSize(6*time.Hour).
   135  					SetEnabled(indexEnabled)))
   136  	if err != nil {
   137  		return nil, err
   138  	}
   139  	nsMap, err := namespace.NewMap([]namespace.Metadata{md})
   140  	if err != nil {
   141  		return nil, err
   142  	}
   143  
   144  	registry, err := namespace.ToProto(nsMap)
   145  	if err != nil {
   146  		return nil, err
   147  	}
   148  
   149  	return registry, nil
   150  }
   151  
   152  // waitUntilAllShardsAreAvailable continually polls the session checking to see if the topology.Map
   153  // that the session is currently storing contains a non-zero number of host shard sets, and if so,
   154  // makes sure that all their shard states are Available.
   155  func waitUntilAllShardsAreAvailable(t *testing.T, session client.AdminSession) {
   156  outer:
   157  	for {
   158  		time.Sleep(10 * time.Millisecond)
   159  
   160  		topoMap, err := session.TopologyMap()
   161  		require.NoError(t, err)
   162  
   163  		var (
   164  			hostShardSets = topoMap.HostShardSets()
   165  		)
   166  
   167  		if len(hostShardSets) == 0 {
   168  			// We haven't received an actual topology yet.
   169  			continue
   170  		}
   171  
   172  		for _, hostShardSet := range hostShardSets {
   173  			for _, hostShard := range hostShardSet.ShardSet().All() {
   174  				if hostShard.State() != shard.Available {
   175  					continue outer
   176  				}
   177  			}
   178  		}
   179  
   180  		break
   181  	}
   182  }