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 }