github.com/fafucoder/cilium@v1.6.11/pkg/endpoint/endpoint_test.go (about) 1 // Copyright 2016-2019 Authors of Cilium 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // +build !privileged_tests 16 17 package endpoint 18 19 import ( 20 "context" 21 "reflect" 22 "testing" 23 "time" 24 25 "github.com/cilium/cilium/common/addressing" 26 "github.com/cilium/cilium/pkg/completion" 27 "github.com/cilium/cilium/pkg/datapath" 28 "github.com/cilium/cilium/pkg/endpoint/regeneration" 29 "github.com/cilium/cilium/pkg/identity" 30 "github.com/cilium/cilium/pkg/identity/cache" 31 ciliumio "github.com/cilium/cilium/pkg/k8s/apis/cilium.io" 32 "github.com/cilium/cilium/pkg/kvstore" 33 pkgLabels "github.com/cilium/cilium/pkg/labels" 34 "github.com/cilium/cilium/pkg/lock" 35 "github.com/cilium/cilium/pkg/metrics" 36 monitorAPI "github.com/cilium/cilium/pkg/monitor/api" 37 "github.com/cilium/cilium/pkg/policy" 38 "github.com/cilium/cilium/pkg/policy/api" 39 "github.com/cilium/cilium/pkg/revert" 40 41 "github.com/prometheus/client_golang/prometheus" 42 . "gopkg.in/check.v1" 43 ) 44 45 var ( 46 IPv6Addr, _ = addressing.NewCiliumIPv6("beef:beef:beef:beef:aaaa:aaaa:1111:1112") 47 IPv4Addr, _ = addressing.NewCiliumIPv4("10.11.12.13") 48 ) 49 50 // Hook up gocheck into the "go test" runner. 51 func Test(t *testing.T) { TestingT(t) } 52 53 type EndpointSuite struct { 54 repo *policy.Repository 55 56 // Metrics 57 collectors []prometheus.Collector 58 } 59 60 // suite can be used by testing.T benchmarks or tests as a mock regeneration.Owner 61 var suite = EndpointSuite{repo: policy.NewPolicyRepository()} 62 var _ = Suite(&suite) 63 64 func (s *EndpointSuite) SetUpSuite(c *C) { 65 s.repo = policy.NewPolicyRepository() 66 67 // Register metrics once before running the suite 68 _, s.collectors = metrics.CreateConfiguration([]string{"cilium_endpoint_state"}) 69 metrics.MustRegister(s.collectors...) 70 } 71 72 func (s *EndpointSuite) TearDownSuite(c *C) { 73 // Unregister the metrics after the suite has finished 74 for _, c := range s.collectors { 75 metrics.Unregister(c) 76 } 77 } 78 79 func (s *EndpointSuite) GetPolicyRepository() *policy.Repository { 80 return s.repo 81 } 82 83 func (s *EndpointSuite) UpdateProxyRedirect(e regeneration.EndpointUpdater, l4 *policy.L4Filter, wg *completion.WaitGroup) (uint16, error, revert.FinalizeFunc, revert.RevertFunc) { 84 return 0, nil, nil, nil 85 } 86 87 func (s *EndpointSuite) RemoveProxyRedirect(e regeneration.EndpointInfoSource, id string, wg *completion.WaitGroup) (error, revert.FinalizeFunc, revert.RevertFunc) { 88 return nil, nil, nil 89 } 90 91 func (s *EndpointSuite) UpdateNetworkPolicy(e regeneration.EndpointUpdater, policy *policy.L4Policy, 92 proxyWaitGroup *completion.WaitGroup) (error, revert.RevertFunc) { 93 return nil, nil 94 } 95 96 func (s *EndpointSuite) RemoveNetworkPolicy(e regeneration.EndpointInfoSource) {} 97 98 func (s *EndpointSuite) QueueEndpointBuild(ctx context.Context, epID uint64) (func(), error) { 99 return nil, nil 100 } 101 102 func (s *EndpointSuite) RemoveFromEndpointQueue(epID uint64) {} 103 104 func (s *EndpointSuite) GetCompilationLock() *lock.RWMutex { 105 return nil 106 } 107 108 func (s *EndpointSuite) SendNotification(typ monitorAPI.AgentNotification, text string) error { 109 return nil 110 } 111 112 func (s *EndpointSuite) Datapath() datapath.Datapath { 113 return nil 114 } 115 116 func (s *EndpointSuite) GetNodeSuffix() string { 117 return "" 118 } 119 120 func (s *EndpointSuite) UpdateIdentities(added, deleted cache.IdentityCache) {} 121 122 type testIdentityAllocator struct{} 123 124 func (t *testIdentityAllocator) UpdateIdentities(added, deleted cache.IdentityCache) {} 125 126 func (t *testIdentityAllocator) GetNodeSuffix() string { return "foo" } 127 128 func (s *EndpointSuite) SetUpTest(c *C) { 129 /* Required to test endpoint CEP policy model */ 130 kvstore.SetupDummy("etcd") 131 identity.InitWellKnownIdentities() 132 // The nils are only used by k8s CRD identities. We default to kvstore. 133 <-cache.InitIdentityAllocator(&testIdentityAllocator{}, nil, nil) 134 } 135 136 func (s *EndpointSuite) TearDownTest(c *C) { 137 cache.Close() 138 kvstore.Client().Close() 139 } 140 141 func (s *EndpointSuite) TestEndpointStatus(c *C) { 142 eps := NewEndpointStatus() 143 144 c.Assert(eps.String(), Equals, "OK") 145 146 sts := &statusLogMsg{ 147 Status: Status{ 148 Code: OK, 149 Msg: "BPF Program compiled", 150 Type: BPF, 151 }, 152 Timestamp: time.Now(), 153 } 154 eps.addStatusLog(sts) 155 c.Assert(eps.String(), Equals, "OK") 156 157 sts = &statusLogMsg{ 158 Status: Status{ 159 Code: Failure, 160 Msg: "BPF Program failed to compile", 161 Type: BPF, 162 }, 163 Timestamp: time.Now(), 164 } 165 eps.addStatusLog(sts) 166 c.Assert(eps.String(), Equals, "Failure") 167 168 sts = &statusLogMsg{ 169 Status: Status{ 170 Code: OK, 171 Msg: "Policy compiled", 172 Type: Policy, 173 }, 174 Timestamp: time.Now(), 175 } 176 eps.addStatusLog(sts) 177 c.Assert(eps.String(), Equals, "Failure") 178 179 // An OK message with priority Other can't hide a High Failure message. 180 for i := 0; i <= maxLogs; i++ { 181 st := &statusLogMsg{ 182 Status: Status{ 183 Code: OK, 184 Msg: "Other thing compiled", 185 Type: Other, 186 }, 187 Timestamp: time.Now(), 188 } 189 eps.addStatusLog(st) 190 } 191 eps.addStatusLog(sts) 192 c.Assert(eps.String(), Equals, "Failure") 193 194 sts = &statusLogMsg{ 195 Status: Status{ 196 Code: Failure, 197 Msg: "Policy failed", 198 Type: Policy, 199 }, 200 Timestamp: time.Now(), 201 } 202 eps.addStatusLog(sts) 203 c.Assert(eps.String(), Equals, "Failure") 204 205 sts = &statusLogMsg{ 206 Status: Status{ 207 Code: OK, 208 Msg: "BPF Program compiled", 209 Type: BPF, 210 }, 211 Timestamp: time.Now(), 212 } 213 eps.addStatusLog(sts) 214 // BPF might be ok but the policy is still in fail mode. 215 c.Assert(eps.String(), Equals, "Failure") 216 217 sts = &statusLogMsg{ 218 Status: Status{ 219 Code: Failure, 220 Msg: "Policy failed", 221 Type: Policy, 222 }, 223 Timestamp: time.Now(), 224 } 225 eps.addStatusLog(sts) 226 c.Assert(eps.String(), Equals, "Failure") 227 228 sts = &statusLogMsg{ 229 Status: Status{ 230 Code: OK, 231 Msg: "Policy compiled", 232 Type: Policy, 233 }, 234 Timestamp: time.Now(), 235 } 236 eps.addStatusLog(sts) 237 c.Assert(eps.String(), Equals, "OK") 238 } 239 240 func (s *EndpointSuite) TestEndpointUpdateLabels(c *C) { 241 e := NewEndpointWithState(s, 100, StateCreating) 242 243 // Test that inserting identity labels works 244 rev := e.replaceIdentityLabels(pkgLabels.Map2Labels(map[string]string{"foo": "bar", "zip": "zop"}, "cilium")) 245 c.Assert(rev, Not(Equals), 0) 246 c.Assert(string(e.OpLabels.OrchestrationIdentity.SortedList()), Equals, "cilium:foo=bar;cilium:zip=zop;") 247 // Test that nothing changes 248 rev = e.replaceIdentityLabels(pkgLabels.Map2Labels(map[string]string{"foo": "bar", "zip": "zop"}, "cilium")) 249 c.Assert(rev, Equals, 0) 250 c.Assert(string(e.OpLabels.OrchestrationIdentity.SortedList()), Equals, "cilium:foo=bar;cilium:zip=zop;") 251 // Remove one label, change the source and value of the other. 252 rev = e.replaceIdentityLabels(pkgLabels.Map2Labels(map[string]string{"foo": "zop"}, "nginx")) 253 c.Assert(rev, Not(Equals), 0) 254 c.Assert(string(e.OpLabels.OrchestrationIdentity.SortedList()), Equals, "nginx:foo=zop;") 255 256 // Test that inserting information labels works 257 e.replaceInformationLabels(pkgLabels.Map2Labels(map[string]string{"foo": "bar", "zip": "zop"}, "cilium")) 258 c.Assert(string(e.OpLabels.OrchestrationInfo.SortedList()), Equals, "cilium:foo=bar;cilium:zip=zop;") 259 // Remove one label, change the source and value of the other. 260 e.replaceInformationLabels(pkgLabels.Map2Labels(map[string]string{"foo": "zop"}, "nginx")) 261 c.Assert(string(e.OpLabels.OrchestrationInfo.SortedList()), Equals, "nginx:foo=zop;") 262 } 263 264 func (s *EndpointSuite) TestEndpointState(c *C) { 265 e := NewEndpointWithState(s, 100, StateCreating) 266 e.UnconditionalLock() 267 defer e.Unlock() 268 269 assertStateTransition(c, e, e.SetStateLocked, StateCreating, StateCreating, false) 270 assertStateTransition(c, e, e.SetStateLocked, StateCreating, StateWaitingForIdentity, true) 271 assertStateTransition(c, e, e.SetStateLocked, StateCreating, StateReady, false) 272 assertStateTransition(c, e, e.SetStateLocked, StateCreating, StateWaitingToRegenerate, false) 273 assertStateTransition(c, e, e.SetStateLocked, StateCreating, StateRegenerating, false) 274 assertStateTransition(c, e, e.SetStateLocked, StateCreating, StateDisconnecting, true) 275 assertStateTransition(c, e, e.SetStateLocked, StateCreating, StateDisconnected, false) 276 277 assertStateTransition(c, e, e.SetStateLocked, StateWaitingForIdentity, StateCreating, false) 278 assertStateTransition(c, e, e.SetStateLocked, StateWaitingForIdentity, StateWaitingForIdentity, false) 279 280 assertStateTransition(c, e, e.SetStateLocked, StateWaitingForIdentity, StateReady, true) 281 282 assertStateTransition(c, e, e.SetStateLocked, StateWaitingForIdentity, StateWaitingToRegenerate, false) 283 assertStateTransition(c, e, e.SetStateLocked, StateWaitingToRegenerate, StateRegenerating, false) 284 assertStateTransition(c, e, e.SetStateLocked, StateRegenerating, StateDisconnecting, true) 285 286 assertStateTransition(c, e, e.SetStateLocked, StateWaitingForIdentity, StateDisconnected, false) 287 288 assertStateTransition(c, e, e.SetStateLocked, StateReady, StateCreating, false) 289 assertStateTransition(c, e, e.SetStateLocked, StateReady, StateWaitingForIdentity, true) 290 assertStateTransition(c, e, e.SetStateLocked, StateReady, StateReady, false) 291 assertStateTransition(c, e, e.SetStateLocked, StateReady, StateWaitingToRegenerate, true) 292 assertStateTransition(c, e, e.SetStateLocked, StateReady, StateRegenerating, false) 293 assertStateTransition(c, e, e.SetStateLocked, StateReady, StateDisconnecting, true) 294 assertStateTransition(c, e, e.SetStateLocked, StateReady, StateDisconnected, false) 295 296 assertStateTransition(c, e, e.SetStateLocked, StateWaitingToRegenerate, StateCreating, false) 297 assertStateTransition(c, e, e.SetStateLocked, StateWaitingToRegenerate, StateWaitingForIdentity, true) 298 assertStateTransition(c, e, e.SetStateLocked, StateWaitingToRegenerate, StateReady, false) 299 assertStateTransition(c, e, e.SetStateLocked, StateWaitingToRegenerate, StateWaitingToRegenerate, false) 300 assertStateTransition(c, e, e.SetStateLocked, StateWaitingToRegenerate, StateRegenerating, false) 301 assertStateTransition(c, e, e.SetStateLocked, StateWaitingToRegenerate, StateDisconnecting, true) 302 assertStateTransition(c, e, e.SetStateLocked, StateWaitingToRegenerate, StateDisconnected, false) 303 304 assertStateTransition(c, e, e.SetStateLocked, StateRegenerating, StateCreating, false) 305 assertStateTransition(c, e, e.SetStateLocked, StateRegenerating, StateWaitingForIdentity, true) 306 assertStateTransition(c, e, e.SetStateLocked, StateRegenerating, StateReady, false) 307 assertStateTransition(c, e, e.SetStateLocked, StateRegenerating, StateWaitingToRegenerate, true) 308 assertStateTransition(c, e, e.SetStateLocked, StateRegenerating, StateRegenerating, false) 309 assertStateTransition(c, e, e.SetStateLocked, StateRegenerating, StateDisconnecting, true) 310 assertStateTransition(c, e, e.SetStateLocked, StateRegenerating, StateDisconnected, false) 311 312 assertStateTransition(c, e, e.SetStateLocked, StateDisconnecting, StateCreating, false) 313 assertStateTransition(c, e, e.SetStateLocked, StateDisconnecting, StateWaitingForIdentity, false) 314 assertStateTransition(c, e, e.SetStateLocked, StateDisconnecting, StateReady, false) 315 assertStateTransition(c, e, e.SetStateLocked, StateDisconnecting, StateWaitingToRegenerate, false) 316 assertStateTransition(c, e, e.SetStateLocked, StateDisconnecting, StateRegenerating, false) 317 assertStateTransition(c, e, e.SetStateLocked, StateDisconnecting, StateDisconnecting, false) 318 assertStateTransition(c, e, e.SetStateLocked, StateDisconnecting, StateDisconnected, true) 319 320 assertStateTransition(c, e, e.SetStateLocked, StateDisconnected, StateCreating, false) 321 assertStateTransition(c, e, e.SetStateLocked, StateDisconnected, StateWaitingForIdentity, false) 322 assertStateTransition(c, e, e.SetStateLocked, StateDisconnected, StateReady, false) 323 assertStateTransition(c, e, e.SetStateLocked, StateDisconnected, StateWaitingToRegenerate, false) 324 assertStateTransition(c, e, e.SetStateLocked, StateDisconnected, StateRegenerating, false) 325 assertStateTransition(c, e, e.SetStateLocked, StateDisconnected, StateDisconnecting, false) 326 assertStateTransition(c, e, e.SetStateLocked, StateDisconnected, StateDisconnected, false) 327 328 // State transitions involving the "Invalid" state 329 assertStateTransition(c, e, e.SetStateLocked, "", StateInvalid, false) 330 assertStateTransition(c, e, e.SetStateLocked, StateWaitingForIdentity, StateInvalid, true) 331 assertStateTransition(c, e, e.SetStateLocked, StateInvalid, StateInvalid, false) 332 333 // Builder-specific transitions 334 335 // Builder can't transition to ready from waiting-to-regenerate 336 // as (another) build is pending 337 assertStateTransition(c, e, e.BuilderSetStateLocked, StateWaitingToRegenerate, StateReady, false) 338 // Only builder knows when bpf regeneration starts 339 assertStateTransition(c, e, e.SetStateLocked, StateWaitingToRegenerate, StateRegenerating, false) 340 assertStateTransition(c, e, e.BuilderSetStateLocked, StateWaitingToRegenerate, StateRegenerating, true) 341 342 // Builder does not trigger the need for regeneration 343 assertStateTransition(c, e, e.BuilderSetStateLocked, StateRegenerating, StateWaitingToRegenerate, false) 344 // Builder transitions to ready state after build is done 345 assertStateTransition(c, e, e.BuilderSetStateLocked, StateRegenerating, StateReady, true) 346 347 // Check that direct transition from restoring --> regenerating is valid. 348 assertStateTransition(c, e, e.BuilderSetStateLocked, StateRestoring, StateRegenerating, true) 349 350 // Typical lifecycle 351 assertStateTransition(c, e, e.SetStateLocked, StateCreating, StateWaitingForIdentity, true) 352 assertStateTransition(c, e, e.SetStateLocked, "", StateWaitingForIdentity, true) 353 // Initial build does not change the state 354 assertStateTransition(c, e, e.BuilderSetStateLocked, StateWaitingForIdentity, StateRegenerating, false) 355 assertStateTransition(c, e, e.BuilderSetStateLocked, StateWaitingForIdentity, StateReady, false) 356 // identity arrives 357 assertStateTransition(c, e, e.SetStateLocked, StateWaitingForIdentity, StateReady, true) 358 // a build is triggered after the identity is set 359 assertStateTransition(c, e, e.SetStateLocked, StateReady, StateWaitingToRegenerate, true) 360 // build starts 361 assertStateTransition(c, e, e.BuilderSetStateLocked, StateWaitingToRegenerate, StateRegenerating, true) 362 // another change arrives while building 363 assertStateTransition(c, e, e.SetStateLocked, StateRegenerating, StateWaitingToRegenerate, true) 364 // Builder's transition to ready fails due to the queued build 365 assertStateTransition(c, e, e.BuilderSetStateLocked, StateWaitingToRegenerate, StateReady, false) 366 // second build starts 367 assertStateTransition(c, e, e.BuilderSetStateLocked, StateWaitingToRegenerate, StateRegenerating, true) 368 // second build finishes 369 assertStateTransition(c, e, e.BuilderSetStateLocked, StateRegenerating, StateReady, true) 370 // endpoint is being deleted 371 assertStateTransition(c, e, e.SetStateLocked, StateReady, StateDisconnecting, true) 372 // parallel disconnect fails 373 assertStateTransition(c, e, e.SetStateLocked, StateDisconnecting, StateDisconnecting, false) 374 assertStateTransition(c, e, e.SetStateLocked, StateDisconnecting, StateDisconnected, true) 375 376 // Restoring state 377 assertStateTransition(c, e, e.SetStateLocked, StateRestoring, StateWaitingToRegenerate, false) 378 assertStateTransition(c, e, e.SetStateLocked, StateRestoring, StateDisconnecting, true) 379 380 assertStateTransition(c, e, e.SetStateLocked, StateRestoring, StateRestoring, true) 381 382 // Invalid state 383 assertStateTransition(c, e, e.BuilderSetStateLocked, StateInvalid, StateReady, false) 384 assertStateTransition(c, e, e.BuilderSetStateLocked, StateWaitingToRegenerate, StateInvalid, false) 385 } 386 387 func assertStateTransition(c *C, 388 e *Endpoint, stateSetter func(string, string) bool, 389 from, to string, 390 success bool) { 391 392 e.state = from 393 394 currStateOldMetric := getMetricValue(e.state) 395 newStateOldMetric := getMetricValue(to) 396 got := stateSetter(to, "test") 397 currStateNewMetric := getMetricValue(from) 398 newStateNewMetric := getMetricValue(e.state) 399 400 c.Assert(got, Equals, success) 401 402 // Do not assert on metrics if the endpoint is not expected to transition. 403 if !success { 404 return 405 } 406 407 // If the state transition moves from itself to itself, we expect the 408 // metrics to be unchanged. 409 if from == to { 410 c.Assert(currStateOldMetric, Equals, currStateNewMetric) 411 c.Assert(newStateOldMetric, Equals, newStateNewMetric) 412 } else { 413 // Blank states don't have metrics so we skip over that; metric should 414 // be unchanged. 415 if from != "" { 416 c.Assert(currStateOldMetric-1, Equals, currStateNewMetric) 417 } else { 418 c.Assert(currStateOldMetric, Equals, currStateNewMetric) 419 } 420 421 // Don't assert on state transition that ends up in a final state, as 422 // the metric is not incremented in this case; metric should be 423 // unchanged. 424 if !isFinalState(to) { 425 c.Assert(newStateOldMetric+1, Equals, newStateNewMetric) 426 } else { 427 c.Assert(newStateOldMetric, Equals, newStateNewMetric) 428 } 429 } 430 } 431 432 func isFinalState(state string) bool { 433 return (state == StateDisconnected || state == StateInvalid) 434 } 435 436 func getMetricValue(state string) int64 { 437 return int64(metrics.GetGaugeValue(metrics.EndpointStateCount.WithLabelValues(state))) 438 } 439 440 func (s *EndpointSuite) TestWaitForPolicyRevision(c *C) { 441 e := &Endpoint{policyRevision: 0} 442 443 ctx, cancel := context.WithTimeout(context.Background(), time.Duration(1*time.Second)) 444 445 cbRan := false 446 <-e.WaitForPolicyRevision(ctx, 0, func(time.Time) { cbRan = true }) 447 // shouldn't get a timeout when waiting for policy revision already reached 448 c.Assert(ctx.Err(), IsNil) 449 // Should see a callback when waiting for a policy revision already reached 450 c.Assert(cbRan, Equals, true) 451 452 cancel() 453 454 e.policyRevision = 1 455 456 ctx, cancel = context.WithTimeout(context.Background(), time.Duration(1*time.Second)) 457 cbRan = false 458 459 <-e.WaitForPolicyRevision(ctx, 0, func(time.Time) { cbRan = true }) 460 // shouldn't get a timeout when waiting for policy revision already reached 461 c.Assert(ctx.Err(), IsNil) 462 // Should see a callback because the channel returned 463 c.Assert(cbRan, Equals, true) 464 465 cancel() 466 467 e.policyRevision = 1 468 469 ctx, cancel = context.WithCancel(context.Background()) 470 cbRan = false 471 472 ch := e.WaitForPolicyRevision(ctx, 2, func(time.Time) { cbRan = true }) 473 cancel() 474 // context was prematurely closed on purpose the error should be nil 475 c.Assert(ctx.Err(), Equals, context.Canceled) 476 // Should not see a callback when we don't close the channel 477 c.Assert(cbRan, Equals, false) 478 479 e.setPolicyRevision(3) 480 481 select { 482 case <-ch: 483 default: 484 c.Fatalf("channel should have been closed since the wanted policy revision was reached") 485 } 486 487 // Number of policy revision signals should be 0 488 c.Assert(len(e.policyRevisionSignals), Equals, 0) 489 490 e.state = StateDisconnected 491 492 ctx, cancel = context.WithCancel(context.Background()) 493 cbRan = false 494 ch = e.WaitForPolicyRevision(ctx, 99, func(time.Time) { cbRan = true }) 495 cancel() 496 select { 497 case <-ch: 498 default: 499 c.Fatalf("channel should have been closed since the endpoint is in disconnected state") 500 } 501 // Should see a callback because the channel was closed 502 c.Assert(cbRan, Equals, true) 503 504 // Number of policy revision signals should be 0 505 c.Assert(len(e.policyRevisionSignals), Equals, 0) 506 507 e.state = StateCreating 508 ctx, cancel = context.WithCancel(context.Background()) 509 ch = e.WaitForPolicyRevision(ctx, 99, func(time.Time) { cbRan = true }) 510 511 e.cleanPolicySignals() 512 513 select { 514 case <-ch: 515 default: 516 c.Fatalf("channel should have been closed since all policy signals were closed") 517 } 518 // Should see a callback because the channel was closed 519 c.Assert(cbRan, Equals, true) 520 cancel() 521 522 // Number of policy revision signals should be 0 523 c.Assert(len(e.policyRevisionSignals), Equals, 0) 524 } 525 526 func (s *EndpointSuite) TestProxyID(c *C) { 527 e := &Endpoint{ID: 123, policyRevision: 0} 528 529 id := e.ProxyID(&policy.L4Filter{Port: 8080, Protocol: api.ProtoTCP, Ingress: true}) 530 endpointID, ingress, protocol, port, err := policy.ParseProxyID(id) 531 c.Assert(endpointID, Equals, uint16(123)) 532 c.Assert(ingress, Equals, true) 533 c.Assert(protocol, Equals, "TCP") 534 c.Assert(port, Equals, uint16(8080)) 535 c.Assert(err, IsNil) 536 } 537 538 func TestEndpoint_GetK8sPodLabels(t *testing.T) { 539 type fields struct { 540 OpLabels pkgLabels.OpLabels 541 } 542 tests := []struct { 543 name string 544 fields fields 545 want pkgLabels.Labels 546 }{ 547 { 548 name: "has all k8s labels", 549 fields: fields{ 550 OpLabels: pkgLabels.OpLabels{ 551 OrchestrationInfo: pkgLabels.Map2Labels(map[string]string{"foo": "bar"}, pkgLabels.LabelSourceK8s), 552 }, 553 }, 554 want: pkgLabels.Map2Labels(map[string]string{"foo": "bar"}, pkgLabels.LabelSourceK8s), 555 }, 556 { 557 name: "the namespace labels, service account and namespace should be ignored as they don't belong to pod labels", 558 fields: fields{ 559 OpLabels: pkgLabels.OpLabels{ 560 OrchestrationInfo: pkgLabels.Map2Labels(map[string]string{ 561 "foo": "bar", 562 ciliumio.PodNamespaceMetaLabels + ".env": "prod", 563 ciliumio.PolicyLabelServiceAccount: "default", 564 ciliumio.PodNamespaceLabel: "default", 565 }, pkgLabels.LabelSourceK8s), 566 }, 567 }, 568 want: pkgLabels.Map2Labels(map[string]string{"foo": "bar"}, pkgLabels.LabelSourceK8s), 569 }, 570 { 571 name: "labels with other source than k8s should also be ignored", 572 fields: fields{ 573 OpLabels: pkgLabels.OpLabels{ 574 OrchestrationInfo: pkgLabels.Map2Labels(map[string]string{ 575 "foo": "bar", 576 ciliumio.PodNamespaceMetaLabels + ".env": "prod", 577 }, pkgLabels.LabelSourceK8s), 578 OrchestrationIdentity: pkgLabels.Map2Labels(map[string]string{ 579 "foo2": "bar", 580 ciliumio.PodNamespaceMetaLabels + ".env": "prod2", 581 }, pkgLabels.LabelSourceAny), 582 }, 583 }, 584 want: pkgLabels.Map2Labels(map[string]string{"foo": "bar"}, pkgLabels.LabelSourceK8s), 585 }, 586 } 587 for _, tt := range tests { 588 t.Run(tt.name, func(t *testing.T) { 589 e := &Endpoint{ 590 mutex: lock.RWMutex{}, 591 OpLabels: tt.fields.OpLabels, 592 } 593 if got := e.GetK8sPodLabels(); !reflect.DeepEqual(got, tt.want) { 594 t.Errorf("Endpoint.GetK8sPodLabels() = %v, want %v", got, tt.want) 595 } 596 }) 597 } 598 } 599 600 func (s *EndpointSuite) TestK8sPodNameIsSet(c *C) { 601 e := Endpoint{} 602 c.Assert(e.K8sNamespaceAndPodNameIsSet(), Equals, false) 603 e.K8sPodName = "foo" 604 e.K8sNamespace = "default" 605 c.Assert(e.K8sNamespaceAndPodNameIsSet(), Equals, true) 606 }