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 }