github.com/m3db/m3@v1.5.0/src/cluster/services/leader/services_test.go (about) 1 // Copyright (c) 2017 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 leader 22 23 import ( 24 "testing" 25 "time" 26 27 "github.com/stretchr/testify/assert" 28 "github.com/stretchr/testify/require" 29 "go.etcd.io/etcd/client/v3/concurrency" 30 31 "github.com/m3db/m3/src/cluster/services" 32 ) 33 34 // nolint: unparam 35 func overrideOpts(t *testing.T, s string) services.CampaignOptions { 36 opts, err := services.NewCampaignOptions() 37 require.NoError(t, err) 38 return opts.SetLeaderValue(s) 39 } 40 41 func TestNewService(t *testing.T) { 42 tc := newTestCluster(t) 43 defer tc.close() 44 45 svc, err := NewService(tc.etcdClient(), tc.options()) 46 assert.NoError(t, err) 47 assert.NotNil(t, svc) 48 } 49 50 func TestService_Campaign(t *testing.T) { 51 tc := newTestCluster(t) 52 defer tc.close() 53 54 svc := tc.service() 55 56 sc, err := svc.Campaign("", overrideOpts(t, "foo1")) 57 assert.NoError(t, err) 58 assert.NoError(t, waitForStates(sc, true, followerS, leaderS)) 59 60 sc2, err := svc.Campaign("1", overrideOpts(t, "foo1")) 61 assert.NoError(t, err) 62 assert.NoError(t, waitForStates(sc2, true, followerS, leaderS)) 63 64 for _, eid := range []string{"", "1"} { 65 ld, err := svc.Leader(eid) 66 assert.NoError(t, err) 67 assert.Equal(t, "foo1", ld) 68 } 69 } 70 71 func TestService_Resign(t *testing.T) { 72 tc := newTestCluster(t) 73 defer tc.close() 74 75 svc := tc.service() 76 sc, err := svc.Campaign("e", overrideOpts(t, "foo1")) 77 assert.NoError(t, err) 78 assert.NoError(t, waitForStates(sc, true, followerS, leaderS)) 79 80 err = svc.Resign("zzz") 81 assert.Error(t, err) 82 83 err = svc.Resign("e") 84 assert.NoError(t, err) 85 assert.NoError(t, waitForStates(sc, false, followerS)) 86 } 87 88 func TestService_Leader(t *testing.T) { 89 tc := newTestCluster(t) 90 defer tc.close() 91 92 svc := tc.service() 93 94 sc, err := svc.Campaign("", overrideOpts(t, "foo1")) 95 assert.NoError(t, err) 96 assert.NoError(t, waitForStates(sc, true, followerS, leaderS)) 97 98 _, err = svc.Leader("z") 99 assert.Equal(t, concurrency.ErrElectionNoLeader, err) 100 101 ld, err := svc.Leader("") 102 assert.NoError(t, err) 103 assert.Equal(t, "foo1", ld) 104 } 105 106 func TestService_Observe(t *testing.T) { 107 tc := newTestCluster(t) 108 defer tc.close() 109 110 svc := tc.service() 111 112 oc1, err := svc.Observe("e1") 113 assert.NoError(t, err) 114 115 sc1, err := svc.Campaign("e1", overrideOpts(t, "l1")) 116 assert.NoError(t, err) 117 assert.NoError(t, waitForStates(sc1, true, followerS, leaderS)) 118 119 select { 120 case <-time.After(time.Second): 121 t.Error("expected to receive client update") 122 case v := <-oc1: 123 assert.Equal(t, "l1", v) 124 } 125 126 oc2, err := svc.Observe("e2") 127 assert.NoError(t, err) 128 129 sc2, err := svc.Campaign("e2", overrideOpts(t, "l1")) 130 assert.NoError(t, err) 131 assert.NoError(t, waitForStates(sc2, true, followerS, leaderS)) 132 133 select { 134 case <-time.After(time.Second): 135 t.Error("expected to receive client update") 136 case v := <-oc2: 137 assert.Equal(t, "l1", v) 138 } 139 } 140 141 func TestService_Close(t *testing.T) { 142 tc := newTestCluster(t) 143 defer tc.close() 144 145 opts, err := services.NewCampaignOptions() 146 require.NoError(t, err) 147 148 svc := tc.service() 149 150 sc1, err := svc.Campaign("1", overrideOpts(t, "foo1")) 151 assert.NoError(t, err) 152 assert.NoError(t, waitForStates(sc1, true, followerS, leaderS)) 153 154 sc2, err := svc.Campaign("2", opts) 155 assert.NoError(t, err) 156 assert.NoError(t, waitForStates(sc2, true, followerS, leaderS)) 157 158 assert.NoError(t, svc.Close()) 159 160 waitForStates(sc1, false, followerS) 161 waitForStates(sc2, false, followerS) 162 163 assert.NoError(t, svc.Close()) 164 assert.Error(t, svc.Resign("")) 165 166 _, err = svc.Campaign("", opts) 167 assert.Error(t, err) 168 169 _, err = svc.Leader("") 170 assert.Error(t, err) 171 }