github.com/m3db/m3@v1.5.1-0.20231129193456-75a402aa583b/src/aggregator/tools/deploy/validator_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 deploy
    22  
    23  import (
    24  	"errors"
    25  	"testing"
    26  
    27  	"github.com/m3db/m3/src/aggregator/aggregator"
    28  	"github.com/m3db/m3/src/x/sync"
    29  
    30  	"github.com/golang/mock/gomock"
    31  	"github.com/stretchr/testify/require"
    32  )
    33  
    34  func TestValidatorForFollowerStatusError(t *testing.T) {
    35  	ctrl := gomock.NewController(t)
    36  	defer ctrl.Finish()
    37  
    38  	errStatus := errors.New("status error")
    39  	client := NewMockAggregatorClient(ctrl)
    40  	client.EXPECT().Status(gomock.Any()).Return(aggregator.RuntimeStatus{}, errStatus).AnyTimes()
    41  
    42  	workers := sync.NewWorkerPool(2)
    43  	workers.Init()
    44  	f := newValidatorFactory(client, workers)
    45  	validator := f.ValidatorFor(instanceMetadata{}, nil, followerTarget)
    46  	require.Equal(t, errStatus, validator())
    47  }
    48  
    49  func TestValidatorForFollowerNotFollowerState(t *testing.T) {
    50  	ctrl := gomock.NewController(t)
    51  	defer ctrl.Finish()
    52  
    53  	client := NewMockAggregatorClient(ctrl)
    54  	client.EXPECT().
    55  		Status(gomock.Any()).
    56  		Return(aggregator.RuntimeStatus{
    57  			FlushStatus: aggregator.FlushStatus{
    58  				ElectionState: aggregator.LeaderState,
    59  			},
    60  		}, nil).
    61  		AnyTimes()
    62  
    63  	workers := sync.NewWorkerPool(2)
    64  	workers.Init()
    65  	f := newValidatorFactory(client, workers)
    66  	validator := f.ValidatorFor(instanceMetadata{}, nil, followerTarget)
    67  	require.Error(t, validator())
    68  }
    69  
    70  func TestValidatorForFollowerSuccess(t *testing.T) {
    71  	ctrl := gomock.NewController(t)
    72  	defer ctrl.Finish()
    73  
    74  	client := NewMockAggregatorClient(ctrl)
    75  	client.EXPECT().
    76  		Status(gomock.Any()).
    77  		Return(aggregator.RuntimeStatus{
    78  			FlushStatus: aggregator.FlushStatus{
    79  				ElectionState: aggregator.FollowerState,
    80  			},
    81  		}, nil).
    82  		AnyTimes()
    83  
    84  	workers := sync.NewWorkerPool(2)
    85  	workers.Init()
    86  	f := newValidatorFactory(client, workers)
    87  	validator := f.ValidatorFor(instanceMetadata{}, nil, followerTarget)
    88  	require.NoError(t, validator())
    89  }
    90  
    91  func TestValidatorForLeaderStatusError(t *testing.T) {
    92  	ctrl := gomock.NewController(t)
    93  	defer ctrl.Finish()
    94  
    95  	errStatus := errors.New("status error")
    96  	client := NewMockAggregatorClient(ctrl)
    97  	client.EXPECT().
    98  		Status(gomock.Any()).
    99  		Return(aggregator.RuntimeStatus{}, errStatus).
   100  		AnyTimes()
   101  
   102  	workers := sync.NewWorkerPool(2)
   103  	workers.Init()
   104  	f := newValidatorFactory(client, workers)
   105  	validator := f.ValidatorFor(instanceMetadata{}, nil, leaderTarget)
   106  	require.Equal(t, errStatus, validator())
   107  }
   108  
   109  func TestValidatorForLeaderNotLeaderState(t *testing.T) {
   110  	ctrl := gomock.NewController(t)
   111  	defer ctrl.Finish()
   112  
   113  	client := NewMockAggregatorClient(ctrl)
   114  	client.EXPECT().
   115  		Status(gomock.Any()).
   116  		Return(aggregator.RuntimeStatus{
   117  			FlushStatus: aggregator.FlushStatus{
   118  				ElectionState: aggregator.FollowerState,
   119  			},
   120  		}, nil).
   121  		AnyTimes()
   122  
   123  	workers := sync.NewWorkerPool(2)
   124  	workers.Init()
   125  	f := newValidatorFactory(client, workers)
   126  	validator := f.ValidatorFor(instanceMetadata{}, nil, leaderTarget)
   127  	require.Error(t, validator())
   128  }
   129  
   130  func TestValidatorForLeaderNoLeaderFound(t *testing.T) {
   131  	ctrl := gomock.NewController(t)
   132  	defer ctrl.Finish()
   133  
   134  	group := &instanceGroup{
   135  		LeaderID: "instance2",
   136  	}
   137  	instance := instanceMetadata{PlacementInstanceID: "instance1"}
   138  	client := NewMockAggregatorClient(ctrl)
   139  	client.EXPECT().
   140  		Status(gomock.Any()).
   141  		Return(aggregator.RuntimeStatus{
   142  			FlushStatus: aggregator.FlushStatus{
   143  				ElectionState: aggregator.FollowerState,
   144  			},
   145  		}, nil).
   146  		AnyTimes()
   147  
   148  	workers := sync.NewWorkerPool(2)
   149  	workers.Init()
   150  	f := newValidatorFactory(client, workers)
   151  	validator := f.ValidatorFor(instance, group, leaderTarget)
   152  	require.Error(t, validator())
   153  }
   154  
   155  func TestValidatorForLeaderFollowerCannotLead(t *testing.T) {
   156  	ctrl := gomock.NewController(t)
   157  	defer ctrl.Finish()
   158  
   159  	group := &instanceGroup{
   160  		LeaderID: "instance1",
   161  		All: []instanceMetadata{
   162  			{PlacementInstanceID: "instance1"},
   163  			{PlacementInstanceID: "instance2"},
   164  		},
   165  	}
   166  	instance := instanceMetadata{PlacementInstanceID: "instance1"}
   167  	client := NewMockAggregatorClient(ctrl)
   168  	client.EXPECT().
   169  		Status(gomock.Any()).
   170  		Return(aggregator.RuntimeStatus{
   171  			FlushStatus: aggregator.FlushStatus{
   172  				ElectionState: aggregator.FollowerState,
   173  				CanLead:       false,
   174  			},
   175  		}, nil).
   176  		AnyTimes()
   177  
   178  	workers := sync.NewWorkerPool(2)
   179  	workers.Init()
   180  	f := newValidatorFactory(client, workers)
   181  	validator := f.ValidatorFor(instance, group, leaderTarget)
   182  	require.Error(t, validator())
   183  }
   184  
   185  func TestValidatorForLeaderFollowerSuccess(t *testing.T) {
   186  	ctrl := gomock.NewController(t)
   187  	defer ctrl.Finish()
   188  
   189  	group := &instanceGroup{
   190  		LeaderID: "instance1",
   191  		All: []instanceMetadata{
   192  			{PlacementInstanceID: "instance1", APIEndpoint: "instance1:1234/api"},
   193  			{PlacementInstanceID: "instance2", APIEndpoint: "instance2:1234/api"},
   194  		},
   195  	}
   196  	instance := instanceMetadata{
   197  		PlacementInstanceID: "instance1",
   198  		APIEndpoint:         "instance1:1234/api",
   199  	}
   200  	client := NewMockAggregatorClient(ctrl)
   201  	client.EXPECT().
   202  		Status(gomock.Any()).
   203  		DoAndReturn(func(instance string) (aggregator.RuntimeStatus, error) {
   204  			if instance == "instance1:1234/api" {
   205  				return aggregator.RuntimeStatus{
   206  					FlushStatus: aggregator.FlushStatus{
   207  						ElectionState: aggregator.LeaderState,
   208  						CanLead:       true,
   209  					},
   210  				}, nil
   211  			}
   212  			return aggregator.RuntimeStatus{
   213  				FlushStatus: aggregator.FlushStatus{
   214  					ElectionState: aggregator.FollowerState,
   215  					CanLead:       true,
   216  				},
   217  			}, nil
   218  		}).
   219  		AnyTimes()
   220  
   221  	workers := sync.NewWorkerPool(2)
   222  	workers.Init()
   223  	f := newValidatorFactory(client, workers)
   224  	validator := f.ValidatorFor(instance, group, leaderTarget)
   225  	require.NoError(t, validator())
   226  }