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

     1  // Copyright (c) 2018 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 integration
    22  
    23  import (
    24  	"testing"
    25  
    26  	"github.com/golang/mock/gomock"
    27  	"github.com/stretchr/testify/require"
    28  	"go.uber.org/goleak"
    29  
    30  	"github.com/m3db/m3/src/msg/topic"
    31  	"github.com/m3db/m3/src/x/test"
    32  )
    33  
    34  const (
    35  	maxProducers = 2
    36  	maxRF        = 3
    37  )
    38  
    39  func TestSharedConsumer(t *testing.T) {
    40  	t.Parallel()
    41  
    42  	if testing.Short() {
    43  		t.SkipNow() // Just skip if we're doing a short run
    44  	}
    45  
    46  	ctrl := gomock.NewController(test.Reporter{t})
    47  	defer ctrl.Finish()
    48  
    49  	for i := 1; i <= maxProducers; i++ {
    50  		s := newTestSetup(t, ctrl, i, []consumerServiceConfig{
    51  			{ct: topic.Shared, isSharded: true, instances: 5, replicas: 2},
    52  			{ct: topic.Shared, isSharded: false, instances: 5, replicas: 2},
    53  		})
    54  
    55  		s.Run(t, ctrl)
    56  		s.VerifyConsumers(t)
    57  	}
    58  }
    59  
    60  func TestReplicatedConsumer(t *testing.T) {
    61  	t.Parallel()
    62  
    63  	if testing.Short() {
    64  		t.SkipNow() // Just skip if we're doing a short run
    65  	}
    66  
    67  	ctrl := gomock.NewController(test.Reporter{t})
    68  	defer ctrl.Finish()
    69  
    70  	for i := 1; i <= maxProducers; i++ {
    71  		s := newTestSetup(t, ctrl, i, []consumerServiceConfig{
    72  			{ct: topic.Replicated, isSharded: true, instances: 5, replicas: 2},
    73  		})
    74  
    75  		s.Run(t, ctrl)
    76  		s.VerifyConsumers(t)
    77  	}
    78  }
    79  
    80  func TestSharedAndReplicatedConsumers(t *testing.T) {
    81  	t.Parallel()
    82  
    83  	if testing.Short() {
    84  		t.SkipNow() // Just skip if we're doing a short run
    85  	}
    86  
    87  	ctrl := gomock.NewController(test.Reporter{t})
    88  	defer ctrl.Finish()
    89  
    90  	for i := 1; i <= maxProducers; i++ {
    91  		for j := 1; j <= maxRF; j++ {
    92  			s := newTestSetup(t, ctrl, i, []consumerServiceConfig{
    93  				{ct: topic.Shared, isSharded: true, instances: 5, replicas: j},
    94  				{ct: topic.Shared, isSharded: false, instances: 5, replicas: j},
    95  				{ct: topic.Replicated, isSharded: true, instances: 5, replicas: j},
    96  			})
    97  
    98  			s.Run(t, ctrl)
    99  			s.VerifyConsumers(t)
   100  		}
   101  	}
   102  }
   103  
   104  func TestSharedConsumerWithDeadInstance(t *testing.T) {
   105  	t.Parallel()
   106  
   107  	if testing.Short() {
   108  		t.SkipNow() // Just skip if we're doing a short run
   109  	}
   110  
   111  	ctrl := gomock.NewController(test.Reporter{t})
   112  	defer ctrl.Finish()
   113  
   114  	for i := 1; i <= maxProducers; i++ {
   115  		s := newTestSetup(t, ctrl, i, []consumerServiceConfig{
   116  			{ct: topic.Shared, isSharded: true, instances: 5, replicas: 2},
   117  			{ct: topic.Shared, isSharded: false, instances: 5, replicas: 2},
   118  		})
   119  
   120  		s.ScheduleOperations(
   121  			10,
   122  			func() { s.KillInstance(t, 0) },
   123  		)
   124  
   125  		s.ScheduleOperations(
   126  			20,
   127  			func() { s.KillInstance(t, 1) },
   128  		)
   129  		s.Run(t, ctrl)
   130  		s.VerifyConsumers(t)
   131  		testConsumers := s.consumerServices[0].testConsumers
   132  		require.True(t, testConsumers[len(testConsumers)-1].numConsumed() <= s.TotalMessages()*10/100)
   133  		testConsumers = s.consumerServices[1].testConsumers
   134  		require.True(t, testConsumers[len(testConsumers)-1].numConsumed() <= s.TotalMessages()*20/100)
   135  	}
   136  }
   137  
   138  func TestSharedConsumerWithDeadConnection(t *testing.T) {
   139  	t.Parallel()
   140  
   141  	if testing.Short() {
   142  		t.SkipNow() // Just skip if we're doing a short run
   143  	}
   144  
   145  	ctrl := gomock.NewController(test.Reporter{t})
   146  	defer ctrl.Finish()
   147  
   148  	for i := 1; i <= maxProducers; i++ {
   149  		s := newTestSetup(t, ctrl, i, []consumerServiceConfig{
   150  			{ct: topic.Shared, isSharded: true, instances: 5, replicas: 2},
   151  			{ct: topic.Shared, isSharded: false, instances: 5, replicas: 2},
   152  		})
   153  
   154  		s.ScheduleOperations(
   155  			10,
   156  			func() { s.KillConnection(t, 0) },
   157  		)
   158  		s.ScheduleOperations(
   159  			20,
   160  			func() { s.KillConnection(t, 0) },
   161  		)
   162  		s.Run(t, ctrl)
   163  		s.VerifyConsumers(t)
   164  	}
   165  }
   166  
   167  func TestReplicatedConsumerWithDeadConnection(t *testing.T) {
   168  	t.Parallel()
   169  
   170  	if testing.Short() {
   171  		t.SkipNow() // Just skip if we're doing a short run
   172  	}
   173  
   174  	ctrl := gomock.NewController(test.Reporter{t})
   175  	defer ctrl.Finish()
   176  
   177  	for i := 1; i <= maxProducers; i++ {
   178  		s := newTestSetup(t, ctrl, i, []consumerServiceConfig{
   179  			{ct: topic.Replicated, isSharded: true, instances: 5, replicas: 2},
   180  		})
   181  
   182  		s.ScheduleOperations(
   183  			10,
   184  			func() { s.KillConnection(t, 0) },
   185  		)
   186  		s.ScheduleOperations(
   187  			20,
   188  			func() { s.KillConnection(t, 0) },
   189  		)
   190  		s.Run(t, ctrl)
   191  		s.VerifyConsumers(t)
   192  	}
   193  }
   194  
   195  func TestSharedAndReplicatedConsumerWithDeadConnection(t *testing.T) {
   196  	t.Parallel()
   197  
   198  	if testing.Short() {
   199  		t.SkipNow() // Just skip if we're doing a short run
   200  	}
   201  
   202  	ctrl := gomock.NewController(test.Reporter{t})
   203  	defer ctrl.Finish()
   204  
   205  	for i := 1; i <= maxProducers; i++ {
   206  		for j := 1; j <= maxRF; j++ {
   207  			s := newTestSetup(t, ctrl, i, []consumerServiceConfig{
   208  				{ct: topic.Shared, isSharded: true, instances: 5, replicas: j},
   209  				{ct: topic.Shared, isSharded: false, instances: 5, replicas: j},
   210  				{ct: topic.Replicated, isSharded: true, instances: 5, replicas: j},
   211  			})
   212  
   213  			s.ScheduleOperations(
   214  				10,
   215  				func() { s.KillConnection(t, 0) },
   216  			)
   217  			s.ScheduleOperations(
   218  				20,
   219  				func() { s.KillConnection(t, 1) },
   220  			)
   221  			s.ScheduleOperations(
   222  				30,
   223  				func() { s.KillConnection(t, 0) },
   224  			)
   225  			s.ScheduleOperations(
   226  				40,
   227  				func() { s.KillConnection(t, 1) },
   228  			)
   229  			s.Run(t, ctrl)
   230  			s.VerifyConsumers(t)
   231  		}
   232  	}
   233  }
   234  
   235  func TestSharedConsumerAddInstances(t *testing.T) {
   236  	t.Parallel()
   237  
   238  	if testing.Short() {
   239  		t.SkipNow() // Just skip if we're doing a short run
   240  	}
   241  
   242  	ctrl := gomock.NewController(test.Reporter{t})
   243  	defer ctrl.Finish()
   244  
   245  	for i := 1; i <= maxProducers; i++ {
   246  		s := newTestSetup(t, ctrl, i, []consumerServiceConfig{
   247  			{ct: topic.Shared, isSharded: true, instances: 5, replicas: 2},
   248  			{ct: topic.Shared, isSharded: false, instances: 5, replicas: 2},
   249  		})
   250  
   251  		s.ScheduleOperations(
   252  			10,
   253  			func() { s.AddInstance(t, 0) },
   254  		)
   255  		s.ScheduleOperations(
   256  			20,
   257  			func() { s.AddInstance(t, 0) },
   258  		)
   259  		s.Run(t, ctrl)
   260  		s.VerifyConsumers(t)
   261  	}
   262  }
   263  
   264  func TestReplicatedConsumerAddInstances(t *testing.T) {
   265  	t.Parallel()
   266  
   267  	if testing.Short() {
   268  		t.SkipNow() // Just skip if we're doing a short run
   269  	}
   270  
   271  	ctrl := gomock.NewController(test.Reporter{t})
   272  	defer ctrl.Finish()
   273  
   274  	for i := 1; i <= maxProducers; i++ {
   275  		s := newTestSetup(t, ctrl, i, []consumerServiceConfig{
   276  			{ct: topic.Replicated, isSharded: true, instances: 5, replicas: 2},
   277  		})
   278  
   279  		s.ScheduleOperations(
   280  			10,
   281  			func() { s.AddInstance(t, 0) },
   282  		)
   283  		s.ScheduleOperations(
   284  			20,
   285  			func() { s.AddInstance(t, 0) },
   286  		)
   287  		s.Run(t, ctrl)
   288  		s.VerifyConsumers(t)
   289  	}
   290  }
   291  
   292  func TestSharedAndReplicatedConsumerAddInstances(t *testing.T) {
   293  	t.Parallel()
   294  
   295  	if testing.Short() {
   296  		t.SkipNow() // Just skip if we're doing a short run
   297  	}
   298  
   299  	ctrl := gomock.NewController(test.Reporter{t})
   300  	defer ctrl.Finish()
   301  
   302  	for i := 1; i <= maxProducers; i++ {
   303  		for j := 1; j <= maxRF; j++ {
   304  			s := newTestSetup(t, ctrl, i, []consumerServiceConfig{
   305  				{ct: topic.Shared, isSharded: true, instances: 5, replicas: j},
   306  				{ct: topic.Shared, isSharded: false, instances: 5, replicas: j},
   307  				{ct: topic.Replicated, isSharded: true, instances: 5, replicas: j},
   308  			})
   309  
   310  			s.ScheduleOperations(
   311  				10,
   312  				func() { s.AddInstance(t, 0) },
   313  			)
   314  			s.ScheduleOperations(
   315  				20,
   316  				func() { s.AddInstance(t, 1) },
   317  			)
   318  			s.ScheduleOperations(
   319  				30,
   320  				func() { s.AddInstance(t, 0) },
   321  			)
   322  			s.ScheduleOperations(
   323  				40,
   324  				func() { s.AddInstance(t, 1) },
   325  			)
   326  			s.Run(t, ctrl)
   327  			s.VerifyConsumers(t)
   328  		}
   329  	}
   330  }
   331  
   332  func TestSharedConsumerRemoveInstances(t *testing.T) {
   333  	t.Parallel()
   334  
   335  	if testing.Short() {
   336  		t.SkipNow() // Just skip if we're doing a short run
   337  	}
   338  
   339  	ctrl := gomock.NewController(test.Reporter{t})
   340  	defer ctrl.Finish()
   341  
   342  	for i := 1; i <= maxProducers; i++ {
   343  		s := newTestSetup(t, ctrl, i, []consumerServiceConfig{
   344  			{ct: topic.Shared, isSharded: true, instances: 5, replicas: 2},
   345  			{ct: topic.Shared, isSharded: false, instances: 5, replicas: 2},
   346  		})
   347  
   348  		s.ScheduleOperations(
   349  			10,
   350  			func() { s.RemoveInstance(t, 0) },
   351  		)
   352  		s.ScheduleOperations(
   353  			20,
   354  			func() { s.RemoveInstance(t, 0) },
   355  		)
   356  		s.Run(t, ctrl)
   357  		s.VerifyConsumers(t)
   358  	}
   359  }
   360  
   361  func TestReplicatedConsumerRemoveInstances(t *testing.T) {
   362  	t.Parallel()
   363  
   364  	if testing.Short() {
   365  		t.SkipNow() // Just skip if we're doing a short run
   366  	}
   367  
   368  	ctrl := gomock.NewController(test.Reporter{t})
   369  	defer ctrl.Finish()
   370  
   371  	for i := 1; i <= maxProducers; i++ {
   372  		s := newTestSetup(t, ctrl, i, []consumerServiceConfig{
   373  			{ct: topic.Replicated, isSharded: true, instances: 5, replicas: 2},
   374  		})
   375  
   376  		s.ScheduleOperations(
   377  			10,
   378  			func() { s.RemoveInstance(t, 0) },
   379  		)
   380  		s.ScheduleOperations(
   381  			20,
   382  			func() { s.RemoveInstance(t, 0) },
   383  		)
   384  		s.Run(t, ctrl)
   385  		s.VerifyConsumers(t)
   386  	}
   387  }
   388  
   389  func TestSharedAndReplicatedConsumerRemoveInstances(t *testing.T) {
   390  	t.Parallel()
   391  
   392  	if testing.Short() {
   393  		t.SkipNow() // Just skip if we're doing a short run
   394  	}
   395  
   396  	ctrl := gomock.NewController(test.Reporter{t})
   397  	defer ctrl.Finish()
   398  
   399  	for i := 1; i <= maxProducers; i++ {
   400  		for j := 1; j <= maxRF; j++ {
   401  			s := newTestSetup(t, ctrl, i, []consumerServiceConfig{
   402  				{ct: topic.Shared, isSharded: true, instances: 5, replicas: j},
   403  				{ct: topic.Shared, isSharded: false, instances: 5, replicas: j},
   404  				{ct: topic.Replicated, isSharded: true, instances: 5, replicas: j},
   405  			})
   406  
   407  			s.ScheduleOperations(
   408  				10,
   409  				func() { s.RemoveInstance(t, 0) },
   410  			)
   411  			s.ScheduleOperations(
   412  				20,
   413  				func() { s.RemoveInstance(t, 1) },
   414  			)
   415  			s.ScheduleOperations(
   416  				30,
   417  				func() { s.RemoveInstance(t, 0) },
   418  			)
   419  			s.ScheduleOperations(
   420  				40,
   421  				func() { s.RemoveInstance(t, 1) },
   422  			)
   423  			s.Run(t, ctrl)
   424  			s.VerifyConsumers(t)
   425  		}
   426  	}
   427  }
   428  
   429  func TestSharedConsumerReplaceInstances(t *testing.T) {
   430  	t.Parallel()
   431  
   432  	if testing.Short() {
   433  		t.SkipNow() // Just skip if we're doing a short run
   434  	}
   435  
   436  	ctrl := gomock.NewController(test.Reporter{t})
   437  	defer ctrl.Finish()
   438  
   439  	for i := 1; i <= maxProducers; i++ {
   440  		s := newTestSetup(t, ctrl, i, []consumerServiceConfig{
   441  			{ct: topic.Shared, isSharded: true, instances: 5, replicas: 2},
   442  			{ct: topic.Shared, isSharded: false, instances: 5, replicas: 2},
   443  		})
   444  
   445  		s.ScheduleOperations(
   446  			10,
   447  			func() { s.ReplaceInstance(t, 0) },
   448  		)
   449  		s.ScheduleOperations(
   450  			20,
   451  			func() { s.ReplaceInstance(t, 0) },
   452  		)
   453  		s.Run(t, ctrl)
   454  		s.VerifyConsumers(t)
   455  	}
   456  }
   457  
   458  func TestReplicatedConsumerReplaceInstances(t *testing.T) {
   459  	t.Parallel()
   460  
   461  	if testing.Short() {
   462  		t.SkipNow() // Just skip if we're doing a short run
   463  	}
   464  
   465  	ctrl := gomock.NewController(test.Reporter{t})
   466  	defer ctrl.Finish()
   467  
   468  	for i := 1; i <= maxProducers; i++ {
   469  		s := newTestSetup(t, ctrl, i, []consumerServiceConfig{
   470  			{ct: topic.Replicated, isSharded: true, instances: 5, replicas: 2},
   471  		})
   472  
   473  		s.ScheduleOperations(
   474  			10,
   475  			func() { s.ReplaceInstance(t, 0) },
   476  		)
   477  		s.ScheduleOperations(
   478  			20,
   479  			func() { s.ReplaceInstance(t, 0) },
   480  		)
   481  		s.Run(t, ctrl)
   482  		s.VerifyConsumers(t)
   483  	}
   484  }
   485  
   486  func TestSharedAndReplicatedConsumerReplaceInstances(t *testing.T) {
   487  	t.Parallel()
   488  
   489  	if testing.Short() {
   490  		t.SkipNow() // Just skip if we're doing a short run
   491  	}
   492  
   493  	ctrl := gomock.NewController(test.Reporter{t})
   494  	defer ctrl.Finish()
   495  
   496  	for i := 1; i <= maxProducers; i++ {
   497  		for j := 1; j <= maxRF; j++ {
   498  			s := newTestSetup(t, ctrl, i, []consumerServiceConfig{
   499  				{ct: topic.Shared, isSharded: true, instances: 5, replicas: j},
   500  				{ct: topic.Shared, isSharded: false, instances: 5, replicas: j},
   501  				{ct: topic.Replicated, isSharded: true, instances: 5, replicas: j},
   502  			})
   503  
   504  			s.ScheduleOperations(
   505  				10,
   506  				func() { s.ReplaceInstance(t, 0) },
   507  			)
   508  			s.ScheduleOperations(
   509  				20,
   510  				func() { s.ReplaceInstance(t, 1) },
   511  			)
   512  			s.ScheduleOperations(
   513  				30,
   514  				func() { s.ReplaceInstance(t, 0) },
   515  			)
   516  			s.ScheduleOperations(
   517  				40,
   518  				func() { s.ReplaceInstance(t, 1) },
   519  			)
   520  			s.Run(t, ctrl)
   521  			s.VerifyConsumers(t)
   522  		}
   523  	}
   524  }
   525  
   526  func TestRemoveConsumerService(t *testing.T) {
   527  	t.Parallel()
   528  
   529  	if testing.Short() {
   530  		t.SkipNow() // Just skip if we're doing a short run
   531  	}
   532  
   533  	ctrl := gomock.NewController(test.Reporter{t})
   534  	defer ctrl.Finish()
   535  
   536  	for i := 1; i <= maxProducers; i++ {
   537  		s := newTestSetup(t, ctrl, i, []consumerServiceConfig{
   538  			{ct: topic.Shared, isSharded: true, instances: 5, replicas: 2},
   539  			{ct: topic.Shared, isSharded: false, instances: 1, replicas: 1},
   540  			{ct: topic.Replicated, isSharded: true, instances: 5, replicas: 2},
   541  		})
   542  
   543  		s.ScheduleOperations(
   544  			20,
   545  			func() { s.RemoveConsumerService(t, 2) },
   546  		)
   547  		s.Run(t, ctrl)
   548  		s.VerifyConsumers(t)
   549  		require.Equal(t, msgPerShard*numberOfShards, s.consumerServices[0].numConsumed())
   550  		require.Equal(t, msgPerShard*numberOfShards, s.consumerServices[1].numConsumed())
   551  	}
   552  }
   553  
   554  func TestAddConsumerService(t *testing.T) {
   555  	t.Parallel()
   556  
   557  	if testing.Short() {
   558  		t.SkipNow() // Just skip if we're doing a short run
   559  	}
   560  
   561  	ctrl := gomock.NewController(test.Reporter{t})
   562  	defer ctrl.Finish()
   563  
   564  	for i := 1; i <= maxProducers; i++ {
   565  		s := newTestSetup(t, ctrl, i, []consumerServiceConfig{
   566  			{ct: topic.Shared, isSharded: true, instances: 5, replicas: 2},
   567  			{ct: topic.Replicated, isSharded: true, instances: 5, replicas: 2},
   568  		})
   569  
   570  		s.ScheduleOperations(
   571  			20,
   572  			func() {
   573  				s.AddConsumerService(t, consumerServiceConfig{ct: topic.Shared, isSharded: false, instances: 1, replicas: 1, lateJoin: true})
   574  			},
   575  		)
   576  		s.Run(t, ctrl)
   577  		require.Equal(t, s.ExpectedNumMessages(), s.consumerServices[0].numConsumed())
   578  		require.Equal(t, s.ExpectedNumMessages(), s.consumerServices[1].numConsumed())
   579  		require.True(t, s.consumerServices[2].numConsumed() <= s.ExpectedNumMessages()*80/100)
   580  	}
   581  }
   582  
   583  func TestMain(m *testing.M) {
   584  	goleak.VerifyTestMain(m, goleak.IgnoreCurrent())
   585  }