go.temporal.io/server@v1.23.0/common/tqname/tqname_test.go (about)

     1  // The MIT License
     2  //
     3  // Copyright (c) 2020 Temporal Technologies Inc.  All rights reserved.
     4  //
     5  // Copyright (c) 2020 Uber Technologies, Inc.
     6  //
     7  // Permission is hereby granted, free of charge, to any person obtaining a copy
     8  // of this software and associated documentation files (the "Software"), to deal
     9  // in the Software without restriction, including without limitation the rights
    10  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    11  // copies of the Software, and to permit persons to whom the Software is
    12  // furnished to do so, subject to the following conditions:
    13  //
    14  // The above copyright notice and this permission notice shall be included in
    15  // all copies or substantial portions of the Software.
    16  //
    17  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    18  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    19  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    20  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    21  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    22  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    23  // THE SOFTWARE.
    24  
    25  package tqname
    26  
    27  import (
    28  	"strconv"
    29  	"testing"
    30  
    31  	"github.com/stretchr/testify/assert"
    32  	"github.com/stretchr/testify/require"
    33  )
    34  
    35  func TestParse(t *testing.T) {
    36  	a := assert.New(t)
    37  
    38  	n, err := Parse("my-basic-tq-name")
    39  	a.NoError(err)
    40  	a.Equal("my-basic-tq-name", n.BaseNameString())
    41  	a.Equal(0, n.Partition())
    42  	a.Equal("", n.VersionSet())
    43  	a.Equal("my-basic-tq-name", n.FullName())
    44  	a.True(n.IsRoot())
    45  	_, err = n.Parent(5)
    46  	a.Equal(ErrNoParent, err)
    47  
    48  	n, err = Parse("/_sys/my-basic-tq-name/23")
    49  	a.NoError(err)
    50  	a.Equal("my-basic-tq-name", n.BaseNameString())
    51  	a.Equal(23, n.Partition())
    52  	a.Equal("", n.VersionSet())
    53  	a.Equal("/_sys/my-basic-tq-name/23", n.FullName())
    54  	a.False(n.IsRoot())
    55  	a.Equal(4, mustParent(n, 5).Partition())
    56  	a.Equal(0, mustParent(n, 32).Partition())
    57  
    58  	n, err = Parse("/_sys/my-basic-tq-name/verxyz:23")
    59  	a.NoError(err)
    60  	a.Equal("my-basic-tq-name", n.BaseNameString())
    61  	a.Equal(23, n.Partition())
    62  	a.Equal("verxyz", n.VersionSet())
    63  	a.Equal("/_sys/my-basic-tq-name/verxyz:23", n.FullName())
    64  }
    65  
    66  func TestFromBaseName(t *testing.T) {
    67  	a := assert.New(t)
    68  
    69  	n, err := FromBaseName("my-basic-tq-name")
    70  	a.NoError(err)
    71  	a.Equal("my-basic-tq-name", n.BaseNameString())
    72  	a.Equal(0, n.Partition())
    73  	a.Equal("", n.VersionSet())
    74  
    75  	_, err = FromBaseName("/_sys/my-basic-tq-name/23")
    76  	a.Error(err)
    77  }
    78  
    79  func TestWithPartition(t *testing.T) {
    80  	a := assert.New(t)
    81  
    82  	n, err := FromBaseName("tq")
    83  	a.NoError(err)
    84  	n = n.WithPartition(23)
    85  	a.Equal("tq", n.BaseNameString())
    86  	a.Equal(23, n.Partition())
    87  	a.Equal("/_sys/tq/23", n.FullName())
    88  	a.False(n.IsRoot())
    89  }
    90  
    91  func TestWithVersionSet(t *testing.T) {
    92  	a := assert.New(t)
    93  
    94  	n, err := FromBaseName("tq")
    95  	a.NoError(err)
    96  	n = n.WithVersionSet("abc3")
    97  	a.Equal("tq", n.BaseNameString())
    98  	a.Equal(0, n.Partition())
    99  	a.Equal("/_sys/tq/abc3:0", n.FullName())
   100  }
   101  
   102  func TestWithPartitionAndVersionSet(t *testing.T) {
   103  	a := assert.New(t)
   104  
   105  	n, err := FromBaseName("tq")
   106  	a.NoError(err)
   107  	n = n.WithPartition(11).WithVersionSet("abc3")
   108  	a.Equal("tq", n.BaseNameString())
   109  	a.Equal(11, n.Partition())
   110  	a.Equal("abc3", n.VersionSet())
   111  	a.Equal("/_sys/tq/abc3:11", n.FullName())
   112  }
   113  
   114  func TestValidTaskQueueNames(t *testing.T) {
   115  	testCases := []struct {
   116  		input     string
   117  		baseName  string
   118  		partition int
   119  	}{
   120  		{"0", "0", 0},
   121  		{"list0", "list0", 0},
   122  		{"/list0", "/list0", 0},
   123  		{"/list0/", "/list0/", 0},
   124  		{"__temporal_sys/list0", "__temporal_sys/list0", 0},
   125  		{"__temporal_sys/list0/", "__temporal_sys/list0/", 0},
   126  		{"/__temporal_sys_list0", "/__temporal_sys_list0", 0},
   127  		{"/_sys/list0/1", "list0", 1},
   128  		{"/_sys//list0//41", "/list0/", 41},
   129  		{"/_sys//_sys/sys/0/41", "/_sys/sys/0", 41},
   130  	}
   131  
   132  	for _, tc := range testCases {
   133  		t.Run(tc.input, func(t *testing.T) {
   134  			tn, err := Parse(tc.input)
   135  			require.NoError(t, err)
   136  			require.Equal(t, tc.partition, tn.partition)
   137  			require.Equal(t, tc.partition == 0, tn.IsRoot())
   138  			require.Equal(t, tc.baseName, tn.baseName)
   139  			require.Equal(t, tc.baseName, tn.BaseNameString())
   140  			require.Equal(t, tc.input, tn.FullName())
   141  		})
   142  	}
   143  }
   144  
   145  func TestTaskQueueParentName(t *testing.T) {
   146  	const invalid = "__invalid__"
   147  	testCases := []struct {
   148  		name   string
   149  		degree int
   150  		output string
   151  	}{
   152  		/* unexpected input */
   153  		{"list0", 0, invalid},
   154  		/* 1-ary tree */
   155  		{"list0", 1, invalid},
   156  		{"/_sys/list0/1", 1, "list0"},
   157  		{"/_sys/list0/2", 1, "/_sys/list0/1"},
   158  		/* 2-ary tree */
   159  		{"list0", 2, invalid},
   160  		{"/_sys/list0/1", 2, "list0"},
   161  		{"/_sys/list0/2", 2, "list0"},
   162  		{"/_sys/list0/3", 2, "/_sys/list0/1"},
   163  		{"/_sys/list0/4", 2, "/_sys/list0/1"},
   164  		{"/_sys/list0/5", 2, "/_sys/list0/2"},
   165  		{"/_sys/list0/6", 2, "/_sys/list0/2"},
   166  		/* 3-ary tree */
   167  		{"/_sys/list0/1", 3, "list0"},
   168  		{"/_sys/list0/2", 3, "list0"},
   169  		{"/_sys/list0/3", 3, "list0"},
   170  		{"/_sys/list0/4", 3, "/_sys/list0/1"},
   171  		{"/_sys/list0/5", 3, "/_sys/list0/1"},
   172  		{"/_sys/list0/6", 3, "/_sys/list0/1"},
   173  		{"/_sys/list0/7", 3, "/_sys/list0/2"},
   174  		{"/_sys/list0/10", 3, "/_sys/list0/3"},
   175  	}
   176  
   177  	for _, tc := range testCases {
   178  		t.Run(tc.name+"#"+strconv.Itoa(tc.degree), func(t *testing.T) {
   179  			tn, err := Parse(tc.name)
   180  			require.NoError(t, err)
   181  			parent, err := tn.Parent(tc.degree)
   182  			if tc.output == invalid {
   183  				require.Equal(t, ErrNoParent, err)
   184  			} else {
   185  				require.Equal(t, tc.output, parent.FullName())
   186  			}
   187  		})
   188  	}
   189  }
   190  
   191  func TestInvalidTaskqueueNames(t *testing.T) {
   192  	inputs := []string{
   193  		"/_sys/",
   194  		"/_sys/0",
   195  		"/_sys//1",
   196  		"/_sys//0",
   197  		"/_sys/list0",
   198  		"/_sys/list0/0",
   199  		"/_sys/list0/-1",
   200  		"/_sys/list0/abc",
   201  		"/_sys/list0:verxyz:23",
   202  	}
   203  	for _, name := range inputs {
   204  		t.Run(name, func(t *testing.T) {
   205  			_, err := Parse(name)
   206  			require.Error(t, err)
   207  		})
   208  	}
   209  }
   210  
   211  func mustParent(tn Name, n int) Name {
   212  	parent, err := tn.Parent(n)
   213  	if err != nil {
   214  		panic(err)
   215  	}
   216  	return parent
   217  }