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

     1  //go:build integration
     2  // +build integration
     3  
     4  // Copyright (c) 2022 Uber Technologies, Inc.
     5  //
     6  // Permission is hereby granted, free of charge, to any person obtaining a copy
     7  // of this software and associated documentation files (the "Software"), to deal
     8  // in the Software without restriction, including without limitation the rights
     9  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    10  // copies of the Software, and to permit persons to whom the Software is
    11  // furnished to do so, subject to the following conditions:
    12  //
    13  // The above copyright notice and this permission notice shall be included in
    14  // all copies or substantial portions of the Software.
    15  //
    16  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    17  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    18  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    19  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    20  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    21  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    22  // THE SOFTWARE.
    23  
    24  package integration
    25  
    26  import (
    27  	"sync"
    28  	"sync/atomic"
    29  	"testing"
    30  
    31  	httpserver "github.com/m3db/m3/src/aggregator/server/http"
    32  	xtest "github.com/m3db/m3/src/x/test"
    33  
    34  	"github.com/stretchr/testify/assert"
    35  	"github.com/stretchr/testify/require"
    36  )
    37  
    38  func TestMultiServerFollowerHealthInit(t *testing.T) {
    39  	if testing.Short() {
    40  		t.SkipNow()
    41  	}
    42  
    43  	testParams := newTestServerSetups(t)
    44  	servers := testParams.servers
    45  
    46  	// Start the servers.
    47  	log := xtest.NewLogger(t)
    48  	log.Info("test forwarding pipeline")
    49  	for i, server := range servers {
    50  		require.NoError(t, server.startServer())
    51  		log.Sugar().Infof("server %d is now up", i)
    52  	}
    53  
    54  	// Stop the servers.
    55  	for i, server := range servers {
    56  		i := i
    57  		server := server
    58  		defer func() {
    59  			require.NoError(t, server.stopServer())
    60  			log.Sugar().Infof("server %d is now down", i)
    61  		}()
    62  	}
    63  
    64  	// Waiting for two leaders to come up.
    65  	var (
    66  		leaders    = make(map[int]struct{})
    67  		leaderCh   = make(chan int, len(servers)/2)
    68  		numLeaders int32
    69  		wg         sync.WaitGroup
    70  	)
    71  	wg.Add(len(servers) / 2)
    72  	for i, server := range servers {
    73  		i, server := i, server
    74  		go func() {
    75  			if err := server.waitUntilLeader(); err == nil {
    76  				res := int(atomic.AddInt32(&numLeaders, 1))
    77  				if res <= len(servers)/2 {
    78  					leaderCh <- i
    79  					wg.Done()
    80  				}
    81  			}
    82  		}()
    83  	}
    84  	wg.Wait()
    85  	close(leaderCh)
    86  
    87  	for i := range leaderCh {
    88  		leaders[i] = struct{}{}
    89  		log.Sugar().Infof("server %d has become the leader", i)
    90  	}
    91  	log.Sugar().Infof("%d servers have become leaders", len(leaders))
    92  
    93  	for _, server := range servers {
    94  		var resp httpserver.StatusResponse
    95  		require.NoError(t, server.getStatusResponse(httpserver.StatusPath, &resp))
    96  
    97  		// No data has been written to the aggregators yet, but all servers (including the
    98  		// followers) should be able to lead.
    99  		assert.True(t, resp.Status.FlushStatus.CanLead)
   100  	}
   101  }