collector_test.go 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. // Copyright (c) 2017 Arista Networks, Inc.
  2. // Use of this source code is governed by the Apache License 2.0
  3. // that can be found in the COPYING file.
  4. package main
  5. import (
  6. "testing"
  7. "notabug.org/themusicgod1/goarista/test"
  8. "github.com/openconfig/reference/rpc/openconfig"
  9. "github.com/prometheus/client_golang/prometheus"
  10. )
  11. func makeMetrics(cfg *Config, expValues map[source]float64) map[source]*labelledMetric {
  12. expMetrics := map[source]*labelledMetric{}
  13. for k, v := range expValues {
  14. desc, labels := cfg.getDescAndLabels(k)
  15. if desc == nil || labels == nil {
  16. panic("cfg.getDescAndLabels returned nil")
  17. }
  18. expMetrics[k] = &labelledMetric{
  19. metric: prometheus.MustNewConstMetric(desc, prometheus.GaugeValue, v, labels...),
  20. labels: labels,
  21. }
  22. }
  23. return expMetrics
  24. }
  25. func makeResponse(notif *openconfig.Notification) *openconfig.SubscribeResponse {
  26. return &openconfig.SubscribeResponse{
  27. Response: &openconfig.SubscribeResponse_Update{Update: notif},
  28. }
  29. }
  30. func TestUpdate(t *testing.T) {
  31. config := []byte(`
  32. devicelabels:
  33. 10.1.1.1:
  34. lab1: val1
  35. lab2: val2
  36. '*':
  37. lab1: val3
  38. lab2: val4
  39. subscriptions:
  40. - /Sysdb/environment/cooling/status
  41. - /Sysdb/environment/power/status
  42. - /Sysdb/bridging/igmpsnooping/forwarding/forwarding/status
  43. metrics:
  44. - name: intfCounter
  45. path: /Sysdb/(lag|slice/phy/.+)/intfCounterDir/(?P<intf>.+)/intfCounter
  46. help: Per-Interface Bytes/Errors/Discards Counters
  47. - name: fanSpeed
  48. path: /Sysdb/environment/cooling/status/fan/speed/value
  49. help: Fan Speed
  50. - name: igmpSnoopingInf
  51. path: /Sysdb/igmpsnooping/vlanStatus/(?P<vlan>.+)/ethGroup/(?P<mac>.+)/intf/(?P<intf>.+)
  52. help: IGMP snooping status`)
  53. cfg, err := parseConfig(config)
  54. if err != nil {
  55. t.Fatalf("Unexpected error: %v", err)
  56. }
  57. coll := newCollector(cfg)
  58. notif := &openconfig.Notification{
  59. Prefix: &openconfig.Path{Element: []string{"Sysdb"}},
  60. Update: []*openconfig.Update{
  61. {
  62. Path: &openconfig.Path{
  63. Element: []string{"lag", "intfCounterDir", "Ethernet1", "intfCounter"},
  64. },
  65. Value: &openconfig.Value{
  66. Type: openconfig.Type_JSON,
  67. Value: []byte("42"),
  68. },
  69. },
  70. {
  71. Path: &openconfig.Path{
  72. Element: []string{"environment", "cooling", "status", "fan", "speed"},
  73. },
  74. Value: &openconfig.Value{
  75. Type: openconfig.Type_JSON,
  76. Value: []byte("{\"value\": 45}"),
  77. },
  78. },
  79. {
  80. Path: &openconfig.Path{
  81. Element: []string{"igmpsnooping", "vlanStatus", "2050", "ethGroup",
  82. "01:00:5e:01:01:01", "intf", "Cpu"},
  83. },
  84. Value: &openconfig.Value{
  85. Type: openconfig.Type_JSON,
  86. Value: []byte("true"),
  87. },
  88. },
  89. },
  90. }
  91. expValues := map[source]float64{
  92. {
  93. addr: "10.1.1.1",
  94. path: "/Sysdb/lag/intfCounterDir/Ethernet1/intfCounter",
  95. }: 42,
  96. {
  97. addr: "10.1.1.1",
  98. path: "/Sysdb/environment/cooling/status/fan/speed/value",
  99. }: 45,
  100. {
  101. addr: "10.1.1.1",
  102. path: "/Sysdb/igmpsnooping/vlanStatus/2050/ethGroup/01:00:5e:01:01:01/intf/Cpu",
  103. }: 1,
  104. }
  105. coll.update("10.1.1.1:6042", makeResponse(notif))
  106. expMetrics := makeMetrics(cfg, expValues)
  107. if !test.DeepEqual(expMetrics, coll.metrics) {
  108. t.Errorf("Mismatched metrics: %v", test.Diff(expMetrics, coll.metrics))
  109. }
  110. // Update one value, and one path which is not a metric
  111. notif = &openconfig.Notification{
  112. Prefix: &openconfig.Path{Element: []string{"Sysdb"}},
  113. Update: []*openconfig.Update{
  114. {
  115. Path: &openconfig.Path{
  116. Element: []string{"lag", "intfCounterDir", "Ethernet1", "intfCounter"},
  117. },
  118. Value: &openconfig.Value{
  119. Type: openconfig.Type_JSON,
  120. Value: []byte("52"),
  121. },
  122. },
  123. {
  124. Path: &openconfig.Path{
  125. Element: []string{"environment", "doesntexist", "status"},
  126. },
  127. Value: &openconfig.Value{
  128. Type: openconfig.Type_JSON,
  129. Value: []byte("{\"value\": 45}"),
  130. },
  131. },
  132. },
  133. }
  134. src := source{
  135. addr: "10.1.1.1",
  136. path: "/Sysdb/lag/intfCounterDir/Ethernet1/intfCounter",
  137. }
  138. expValues[src] = 52
  139. coll.update("10.1.1.1:6042", makeResponse(notif))
  140. expMetrics = makeMetrics(cfg, expValues)
  141. if !test.DeepEqual(expMetrics, coll.metrics) {
  142. t.Errorf("Mismatched metrics: %v", test.Diff(expMetrics, coll.metrics))
  143. }
  144. // Same path, different device
  145. notif = &openconfig.Notification{
  146. Prefix: &openconfig.Path{Element: []string{"Sysdb"}},
  147. Update: []*openconfig.Update{
  148. {
  149. Path: &openconfig.Path{
  150. Element: []string{"lag", "intfCounterDir", "Ethernet1", "intfCounter"},
  151. },
  152. Value: &openconfig.Value{
  153. Type: openconfig.Type_JSON,
  154. Value: []byte("42"),
  155. },
  156. },
  157. },
  158. }
  159. src.addr = "10.1.1.2"
  160. expValues[src] = 42
  161. coll.update("10.1.1.2:6042", makeResponse(notif))
  162. expMetrics = makeMetrics(cfg, expValues)
  163. if !test.DeepEqual(expMetrics, coll.metrics) {
  164. t.Errorf("Mismatched metrics: %v", test.Diff(expMetrics, coll.metrics))
  165. }
  166. // Delete a path
  167. notif = &openconfig.Notification{
  168. Prefix: &openconfig.Path{Element: []string{"Sysdb"}},
  169. Delete: []*openconfig.Path{
  170. {
  171. Element: []string{"lag", "intfCounterDir", "Ethernet1", "intfCounter"},
  172. },
  173. },
  174. }
  175. src.addr = "10.1.1.1"
  176. delete(expValues, src)
  177. coll.update("10.1.1.1:6042", makeResponse(notif))
  178. expMetrics = makeMetrics(cfg, expValues)
  179. if !test.DeepEqual(expMetrics, coll.metrics) {
  180. t.Errorf("Mismatched metrics: %v", test.Diff(expMetrics, coll.metrics))
  181. }
  182. // Non-numeric update
  183. notif = &openconfig.Notification{
  184. Prefix: &openconfig.Path{Element: []string{"Sysdb"}},
  185. Update: []*openconfig.Update{
  186. {
  187. Path: &openconfig.Path{
  188. Element: []string{"lag", "intfCounterDir", "Ethernet1", "intfCounter"},
  189. },
  190. Value: &openconfig.Value{
  191. Type: openconfig.Type_JSON,
  192. Value: []byte("\"test\""),
  193. },
  194. },
  195. },
  196. }
  197. coll.update("10.1.1.1:6042", makeResponse(notif))
  198. if !test.DeepEqual(expMetrics, coll.metrics) {
  199. t.Errorf("Mismatched metrics: %v", test.Diff(expMetrics, coll.metrics))
  200. }
  201. }