main_test.go 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. package nebula
  2. import (
  3. "testing"
  4. "github.com/slackhq/nebula/config"
  5. "github.com/slackhq/nebula/test"
  6. "github.com/slackhq/nebula/util"
  7. "github.com/stretchr/testify/assert"
  8. )
  9. func TestChooseIRQFreeCPUs(t *testing.T) {
  10. irq := map[int]bool{0: true, 1: true, 2: true, 3: true}
  11. // Plenty of IRQ-free CPUs: take the first `routines` of them in order.
  12. assert.Equal(t, []int{4, 5}, chooseIRQFreeCPUs([]int{0, 1, 2, 3, 4, 5, 6}, irq, 2))
  13. // Exactly enough.
  14. assert.Equal(t, []int{4, 5, 6}, chooseIRQFreeCPUs([]int{0, 1, 2, 3, 4, 5, 6}, irq, 3))
  15. // Not enough IRQ-free CPUs: nil, caller keeps the old default rather
  16. // than doubling readers up on shared cores.
  17. assert.Nil(t, chooseIRQFreeCPUs([]int{0, 1, 2, 3, 4}, irq, 2))
  18. // No IRQ info at all behaves like a plain prefix of allowed.
  19. assert.Equal(t, []int{0, 1}, chooseIRQFreeCPUs([]int{0, 1, 2}, map[int]bool{}, 2))
  20. // Non-contiguous allowed set (cgroup cpuset) with holes.
  21. assert.Equal(t, []int{9, 12}, chooseIRQFreeCPUs([]int{1, 3, 9, 12}, map[int]bool{1: true, 3: true}, 2))
  22. }
  23. func TestParseCpuAffinity(t *testing.T) {
  24. l := test.NewLogger()
  25. // newConfig returns a config.C with tun.cpu_affinity set to v. A nil v
  26. // leaves the key unset.
  27. newConfig := func(v any) *config.C {
  28. c := config.NewC(l)
  29. if v != nil {
  30. c.Settings["tun"] = map[string]any{"cpu_affinity": v}
  31. }
  32. return c
  33. }
  34. // unset -> nil (listenIn falls back to spreading across the allowed set)
  35. assert.Nil(t, parseCpuAffinity(newConfig(nil), l, 1))
  36. // Pick a CPU we're actually allowed to run on so a valid list survives
  37. // validation regardless of the host's affinity mask.
  38. allowed, _ := util.AllowedCPUs()
  39. validCPU := 0
  40. if len(allowed) > 0 {
  41. validCPU = allowed[0]
  42. }
  43. // valid list -> parsed through unchanged
  44. assert.Equal(t, []int{validCPU, validCPU}, parseCpuAffinity(newConfig([]any{validCPU, validCPU}), l, 2))
  45. // a negative entry is out of range on every platform -> disables the override
  46. assert.Nil(t, parseCpuAffinity(newConfig([]any{validCPU, -1}), l, 2))
  47. // a non-integer entry -> disables the override
  48. assert.Nil(t, parseCpuAffinity(newConfig([]any{validCPU, "not-a-cpu"}), l, 2))
  49. // a CPU id outside the allowed set -> disables the override. Only assertable
  50. // where we can enumerate the allowed set (e.g. linux); 1<<20 is far beyond
  51. // any representable CPU id so it can never be in the mask.
  52. if len(allowed) > 0 {
  53. assert.Nil(t, parseCpuAffinity(newConfig([]any{1 << 20}), l, 1))
  54. }
  55. }