github.com/m3db/m3@v1.5.1-0.20231129193456-75a402aa583b/src/msg/topic/topic_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 topic
    22  
    23  import (
    24  	"testing"
    25  	"time"
    26  
    27  	"github.com/m3db/m3/src/cluster/services"
    28  
    29  	"github.com/stretchr/testify/require"
    30  )
    31  
    32  func TestTopicAddConsumer(t *testing.T) {
    33  	cs1 := NewConsumerService().
    34  		SetConsumptionType(Shared).
    35  		SetServiceID(services.NewServiceID().
    36  			SetName("s1").
    37  			SetEnvironment("env1").
    38  			SetZone("zone1"),
    39  		)
    40  	cs2 := NewConsumerService().
    41  		SetConsumptionType(Shared).
    42  		SetServiceID(services.NewServiceID().
    43  			SetName("s2").
    44  			SetEnvironment("env2").
    45  			SetZone("zone2"),
    46  		)
    47  	tpc := NewTopic().
    48  		SetName("testName").
    49  		SetNumberOfShards(1024).
    50  		SetVersion(5).
    51  		SetConsumerServices(
    52  			[]ConsumerService{cs1},
    53  		)
    54  
    55  	_, err := tpc.AddConsumerService(
    56  		NewConsumerService().
    57  			SetConsumptionType(Shared).
    58  			SetServiceID(services.NewServiceID().
    59  				SetName("s1").
    60  				SetEnvironment("env1").
    61  				SetZone("zone1"),
    62  			),
    63  	)
    64  	require.Error(t, err)
    65  	require.Contains(t, err.Error(), cs1.ServiceID().String())
    66  
    67  	tpc, err = tpc.AddConsumerService(cs2)
    68  	require.NoError(t, err)
    69  	require.Equal(t, []ConsumerService{cs1, cs2}, tpc.ConsumerServices())
    70  }
    71  
    72  func TestTopicRemoveConsumer(t *testing.T) {
    73  	cs1 := NewConsumerService().
    74  		SetConsumptionType(Shared).
    75  		SetServiceID(services.NewServiceID().
    76  			SetName("s1").
    77  			SetEnvironment("env1").
    78  			SetZone("zone1"),
    79  		)
    80  	cs2 := NewConsumerService().
    81  		SetConsumptionType(Shared).
    82  		SetServiceID(services.NewServiceID().
    83  			SetName("s2").
    84  			SetEnvironment("env2").
    85  			SetZone("zone2"),
    86  		)
    87  	tpc := NewTopic().
    88  		SetName("testName").
    89  		SetNumberOfShards(1024).
    90  		SetVersion(5).
    91  		SetConsumerServices(
    92  			[]ConsumerService{cs1},
    93  		)
    94  
    95  	_, err := tpc.RemoveConsumerService(cs2.ServiceID())
    96  	require.Error(t, err)
    97  	require.Contains(t, err.Error(), cs2.ServiceID().String())
    98  
    99  	tpc, err = tpc.RemoveConsumerService(
   100  		services.NewServiceID().
   101  			SetName("s1").
   102  			SetEnvironment("env1").
   103  			SetZone("zone1"),
   104  	)
   105  	require.NoError(t, err)
   106  	require.Empty(t, tpc.ConsumerServices())
   107  }
   108  
   109  func TestTopicUpdateConsumer(t *testing.T) {
   110  	cs1 := NewConsumerService().
   111  		SetConsumptionType(Shared).
   112  		SetServiceID(services.NewServiceID().
   113  			SetName("s1").
   114  			SetEnvironment("env1").
   115  			SetZone("zone1"),
   116  		)
   117  	tpc := NewTopic().
   118  		SetName("testName").
   119  		SetNumberOfShards(1024).
   120  		SetConsumerServices(
   121  			[]ConsumerService{cs1},
   122  		)
   123  
   124  	_, err := tpc.UpdateConsumerService(cs1.SetConsumptionType(Replicated))
   125  	require.Error(t, err)
   126  	require.Contains(t, err.Error(), "could not change consumption type")
   127  
   128  	_, err = tpc.UpdateConsumerService(cs1.SetServiceID(services.NewServiceID().SetName("foo")))
   129  	require.Error(t, err)
   130  	require.Contains(t, err.Error(), "could not find consumer service")
   131  
   132  	require.Equal(t, []ConsumerService{cs1}, tpc.ConsumerServices())
   133  	cs2 := NewConsumerService().
   134  		SetConsumptionType(Shared).
   135  		SetServiceID(services.NewServiceID().
   136  			SetName("s1").
   137  			SetEnvironment("env1").
   138  			SetZone("zone1"),
   139  		).SetMessageTTLNanos(500)
   140  	tpc, err = tpc.UpdateConsumerService(cs2)
   141  	require.NoError(t, err)
   142  	require.Equal(t, []ConsumerService{cs2}, tpc.ConsumerServices())
   143  	require.Equal(t, int64(0), cs1.MessageTTLNanos())
   144  	require.Equal(t, int64(500), cs2.MessageTTLNanos())
   145  }
   146  
   147  func TestTopicString(t *testing.T) {
   148  	cs1 := NewConsumerService().
   149  		SetConsumptionType(Shared).
   150  		SetServiceID(services.NewServiceID().
   151  			SetName("s1").
   152  			SetEnvironment("env1").
   153  			SetZone("zone1"),
   154  		)
   155  	cs2 := NewConsumerService().
   156  		SetConsumptionType(Shared).
   157  		SetServiceID(services.NewServiceID().
   158  			SetName("s2").
   159  			SetEnvironment("env2").
   160  			SetZone("zone2"),
   161  		).
   162  		SetMessageTTLNanos(int64(time.Minute))
   163  	tpc := NewTopic().
   164  		SetName("testName").
   165  		SetNumberOfShards(1024).
   166  		SetVersion(5).
   167  		SetConsumerServices(
   168  			[]ConsumerService{cs1, cs2},
   169  		)
   170  	str := `
   171  {
   172  	version: 5
   173  	name: testName
   174  	numOfShards: 1024
   175  	consumerServices: {
   176  		{service: [name: s1, env: env1, zone: zone1], consumption type: shared}
   177  		{service: [name: s2, env: env2, zone: zone2], consumption type: shared, ttl: 1m0s}
   178  	}
   179  }
   180  `
   181  	require.Equal(t, str, tpc.String())
   182  }
   183  
   184  func TestTopicValidation(t *testing.T) {
   185  	topic := NewTopic()
   186  	err := topic.Validate()
   187  	require.Error(t, err)
   188  	require.Equal(t, errEmptyName, err)
   189  
   190  	topic = topic.SetName("name")
   191  	err = topic.Validate()
   192  	require.Error(t, err)
   193  	require.Equal(t, errZeroShards, err)
   194  
   195  	topic = topic.SetNumberOfShards(1024)
   196  	err = topic.Validate()
   197  	require.NoError(t, err)
   198  
   199  	cs1 := NewConsumerService().
   200  		SetConsumptionType(Shared).
   201  		SetServiceID(services.NewServiceID().
   202  			SetName("s1").
   203  			SetEnvironment("env1").
   204  			SetZone("zone1"),
   205  		)
   206  	topic = topic.SetConsumerServices([]ConsumerService{
   207  		cs1, cs1,
   208  	})
   209  	err = topic.Validate()
   210  	require.Error(t, err)
   211  	require.Contains(t, err.Error(), "duplicated consumer")
   212  
   213  	topic = topic.SetConsumerServices([]ConsumerService{
   214  		cs1, cs1.SetConsumptionType(Replicated),
   215  	})
   216  	err = topic.Validate()
   217  	require.Error(t, err)
   218  	require.Contains(t, err.Error(), "duplicated consumer")
   219  
   220  	topic = topic.SetConsumerServices([]ConsumerService{
   221  		cs1,
   222  	})
   223  	err = topic.Validate()
   224  	require.NoError(t, err)
   225  }
   226  
   227  func TestConsumerService(t *testing.T) {
   228  	sid := services.NewServiceID().SetName("s").SetEnvironment("env").SetZone("zone")
   229  	cs := NewConsumerService().SetConsumptionType(Shared).SetServiceID(sid).SetMessageTTLNanos(int64(time.Second))
   230  	require.Equal(t, sid, cs.ServiceID())
   231  	require.Equal(t, Shared, cs.ConsumptionType())
   232  	require.Equal(t, int64(time.Second), cs.MessageTTLNanos())
   233  	require.Equal(t, "{service: [name: s, env: env, zone: zone], consumption type: shared, ttl: 1s}", cs.String())
   234  }