github.com/adityamillind98/nomad@v0.11.8/command/agent/consul/client_test.go (about) 1 package consul 2 3 import ( 4 "reflect" 5 "testing" 6 7 "github.com/hashicorp/consul/api" 8 "github.com/stretchr/testify/require" 9 ) 10 11 var ( 12 // the service as known by nomad 13 wanted = api.AgentServiceRegistration{ 14 Kind: "", 15 ID: "aca4c175-1778-5ef4-0220-2ab434147d35", 16 Name: "myservice", 17 Tags: []string{"a", "b"}, 18 Port: 9000, 19 Address: "1.1.1.1", 20 EnableTagOverride: true, 21 Meta: map[string]string{"foo": "1"}, 22 Connect: &api.AgentServiceConnect{ 23 Native: false, 24 SidecarService: &api.AgentServiceRegistration{ 25 Kind: "connect-proxy", 26 ID: "_nomad-task-8e8413af-b5bb-aa67-2c24-c146c45f1ec9-group-mygroup-myservice-9001-sidecar-proxy", 27 Name: "name-sidecar-proxy", 28 Tags: []string{"x", "y", "z"}, 29 }, 30 }, 31 } 32 33 // the service (and + connect proxy) as known by consul 34 existing = &api.AgentService{ 35 Kind: "", 36 ID: "aca4c175-1778-5ef4-0220-2ab434147d35", 37 Service: "myservice", 38 Tags: []string{"a", "b"}, 39 Port: 9000, 40 Address: "1.1.1.1", 41 EnableTagOverride: true, 42 Meta: map[string]string{"foo": "1"}, 43 } 44 45 sidecar = &api.AgentService{ 46 Kind: "connect-proxy", 47 ID: "_nomad-task-8e8413af-b5bb-aa67-2c24-c146c45f1ec9-group-mygroup-myservice-9001-sidecar-proxy", 48 Service: "myservice-sidecar-proxy", 49 Tags: []string{"x", "y", "z"}, 50 } 51 ) 52 53 func TestSyncLogic_agentServiceUpdateRequired(t *testing.T) { 54 t.Parallel() 55 56 // By default wanted and existing match. Each test should modify wanted in 57 // 1 way, and / or configure the type of sync operation that is being 58 // considered, then evaluate the result of the update-required algebra. 59 60 type asr = api.AgentServiceRegistration 61 type tweaker func(w asr) *asr // create a conveniently modifiable copy 62 63 try := func( 64 t *testing.T, 65 exp bool, 66 reason syncReason, 67 tweak tweaker) { 68 result := agentServiceUpdateRequired(reason, tweak(wanted), existing, sidecar) 69 require.Equal(t, exp, result) 70 } 71 72 t.Run("matching", func(t *testing.T) { 73 try(t, false, syncNewOps, func(w asr) *asr { 74 return &w 75 }) 76 }) 77 78 t.Run("different kind", func(t *testing.T) { 79 try(t, true, syncNewOps, func(w asr) *asr { 80 w.Kind = "other" 81 return &w 82 }) 83 }) 84 85 t.Run("different id", func(t *testing.T) { 86 try(t, true, syncNewOps, func(w asr) *asr { 87 w.ID = "_other" 88 return &w 89 }) 90 }) 91 92 t.Run("different port", func(t *testing.T) { 93 try(t, true, syncNewOps, func(w asr) *asr { 94 w.Port = 9001 95 return &w 96 }) 97 }) 98 99 t.Run("different address", func(t *testing.T) { 100 try(t, true, syncNewOps, func(w asr) *asr { 101 w.Address = "2.2.2.2" 102 return &w 103 }) 104 }) 105 106 t.Run("different name", func(t *testing.T) { 107 try(t, true, syncNewOps, func(w asr) *asr { 108 w.Name = "bob" 109 return &w 110 }) 111 }) 112 113 t.Run("different enable_tag_override", func(t *testing.T) { 114 try(t, true, syncNewOps, func(w asr) *asr { 115 w.EnableTagOverride = false 116 return &w 117 }) 118 }) 119 120 t.Run("different meta", func(t *testing.T) { 121 try(t, true, syncNewOps, func(w asr) *asr { 122 w.Meta = map[string]string{"foo": "2"} 123 return &w 124 }) 125 }) 126 127 t.Run("different tags syncNewOps eto=true", func(t *testing.T) { 128 // sync is required even though eto=true, because NewOps indicates the 129 // service definition in nomad has changed (e.g. job run a modified job) 130 try(t, true, syncNewOps, func(w asr) *asr { 131 w.Tags = []string{"other", "tags"} 132 return &w 133 }) 134 }) 135 136 t.Run("different tags syncPeriodic eto=true", func(t *testing.T) { 137 // sync is not required since eto=true and this is a periodic sync 138 // with consul - in which case we keep Consul's definition of the tags 139 try(t, false, syncPeriodic, func(w asr) *asr { 140 w.Tags = []string{"other", "tags"} 141 return &w 142 }) 143 }) 144 145 t.Run("different sidecar tags on syncPeriodic eto=true", func(t *testing.T) { 146 try(t, false, syncPeriodic, func(w asr) *asr { 147 // like the parent service, the sidecar's tags do not get enforced 148 // if ETO is true and this is a periodic sync 149 w.Connect.SidecarService.Tags = []string{"other", "tags"} 150 return &w 151 }) 152 }) 153 154 t.Run("different sidecar tags on syncNewOps eto=true", func(t *testing.T) { 155 try(t, true, syncNewOps, func(w asr) *asr { 156 // like the parent service, the sidecar's tags always get enforced 157 // regardless of ETO if this is a sync due to applied operations 158 w.Connect.SidecarService.Tags = []string{"other", "tags"} 159 return &w 160 }) 161 }) 162 163 // for remaining tests, EnableTagOverride = false 164 wanted.EnableTagOverride = false 165 existing.EnableTagOverride = false 166 167 t.Run("different tags syncPeriodic eto=false", func(t *testing.T) { 168 // sync is required because eto=false and the tags do not match 169 try(t, true, syncPeriodic, func(w asr) *asr { 170 w.Tags = []string{"other", "tags"} 171 return &w 172 }) 173 }) 174 175 t.Run("different tags syncNewOps eto=false", func(t *testing.T) { 176 // sync is required because eto=false and the tags do not match 177 try(t, true, syncNewOps, func(w asr) *asr { 178 w.Tags = []string{"other", "tags"} 179 return &w 180 }) 181 }) 182 183 t.Run("different sidecar tags on syncPeriodic eto=false", func(t *testing.T) { 184 // like the parent service, sync is required because eto=false and the 185 // sidecar's tags do not match 186 try(t, true, syncPeriodic, func(w asr) *asr { 187 w.Connect.SidecarService.Tags = []string{"other", "tags"} 188 return &w 189 }) 190 }) 191 192 t.Run("different sidecar tags syncNewOps eto=false", func(t *testing.T) { 193 // like the parent service, sync is required because eto=false and the 194 // sidecar's tags do not match 195 try(t, true, syncNewOps, func(w asr) *asr { 196 w.Connect.SidecarService.Tags = []string{"other", "tags"} 197 return &w 198 }) 199 }) 200 } 201 202 func TestSyncLogic_maybeTweakTags(t *testing.T) { 203 t.Parallel() 204 205 differentPointers := func(a, b []string) bool { 206 return &(a) != &(b) 207 } 208 209 try := func(inConsul, inConsulSC []string, eto bool) { 210 wanted := &api.AgentServiceRegistration{ 211 Tags: []string{"original"}, 212 Connect: &api.AgentServiceConnect{ 213 SidecarService: &api.AgentServiceRegistration{ 214 Tags: []string{"original-sidecar"}, 215 }, 216 }, 217 EnableTagOverride: eto, 218 } 219 220 existing := &api.AgentService{Tags: inConsul} 221 sidecar := &api.AgentService{Tags: inConsulSC} 222 223 maybeTweakTags(wanted, existing, sidecar) 224 225 switch eto { 226 case false: 227 require.Equal(t, []string{"original"}, wanted.Tags) 228 require.Equal(t, []string{"original-sidecar"}, wanted.Connect.SidecarService.Tags) 229 require.True(t, differentPointers(wanted.Tags, wanted.Connect.SidecarService.Tags)) 230 case true: 231 require.Equal(t, inConsul, wanted.Tags) 232 require.Equal(t, inConsulSC, wanted.Connect.SidecarService.Tags) 233 require.True(t, differentPointers(wanted.Tags, wanted.Connect.SidecarService.Tags)) 234 } 235 } 236 237 try([]string{"original"}, []string{"original-sidecar"}, true) 238 try([]string{"original"}, []string{"original-sidecar"}, false) 239 try([]string{"modified"}, []string{"original-sidecar"}, true) 240 try([]string{"modified"}, []string{"original-sidecar"}, false) 241 try([]string{"original"}, []string{"modified-sidecar"}, true) 242 try([]string{"original"}, []string{"modified-sidecar"}, false) 243 try([]string{"modified"}, []string{"modified-sidecar"}, true) 244 try([]string{"modified"}, []string{"modified-sidecar"}, false) 245 } 246 247 func TestSyncLogic_maybeTweakTags_emptySC(t *testing.T) { 248 t.Parallel() 249 250 // Check the edge cases where the connect service is deleted on the nomad 251 // side (i.e. are we checking multiple nil pointers). 252 253 try := func(asr *api.AgentServiceRegistration) { 254 maybeTweakTags(asr, existing, sidecar) 255 require.False(t, reflect.DeepEqual([]string{"original"}, asr.Tags)) 256 } 257 258 try(&api.AgentServiceRegistration{ 259 Tags: []string{"original"}, 260 EnableTagOverride: true, 261 Connect: nil, // ooh danger! 262 }) 263 264 try(&api.AgentServiceRegistration{ 265 Tags: []string{"original"}, 266 EnableTagOverride: true, 267 Connect: &api.AgentServiceConnect{ 268 SidecarService: nil, // ooh danger! 269 }, 270 }) 271 }