Add check for duplicate metric keys (#106)
* Remove vet of test code * Add check for duplicate metric keys
This commit is contained in:
committed by
Rob Parker
parent
bcfef94b08
commit
f8b500e0a1
@@ -25,7 +25,7 @@ import (
|
|||||||
|
|
||||||
func TestDescribe(t *testing.T) {
|
func TestDescribe(t *testing.T) {
|
||||||
|
|
||||||
teardownTestCase := setupTestCase()
|
teardownTestCase := setupTestCase(false)
|
||||||
defer teardownTestCase()
|
defer teardownTestCase()
|
||||||
|
|
||||||
ch := make(chan *prometheus.Desc)
|
ch := make(chan *prometheus.Desc)
|
||||||
@@ -39,7 +39,7 @@ func TestDescribe(t *testing.T) {
|
|||||||
t.Errorf("Received unexpected collect request")
|
t.Errorf("Received unexpected collect request")
|
||||||
}
|
}
|
||||||
|
|
||||||
metrics := initialiseMetrics()
|
metrics, _ := initialiseMetrics(getTestLogger())
|
||||||
responseChannel <- metrics
|
responseChannel <- metrics
|
||||||
|
|
||||||
select {
|
select {
|
||||||
@@ -56,7 +56,7 @@ func TestDescribe(t *testing.T) {
|
|||||||
|
|
||||||
func TestCollect(t *testing.T) {
|
func TestCollect(t *testing.T) {
|
||||||
|
|
||||||
teardownTestCase := setupTestCase()
|
teardownTestCase := setupTestCase(false)
|
||||||
defer teardownTestCase()
|
defer teardownTestCase()
|
||||||
|
|
||||||
exporter := newExporter("qmName")
|
exporter := newExporter("qmName")
|
||||||
@@ -75,8 +75,8 @@ func TestCollect(t *testing.T) {
|
|||||||
t.Errorf("Received unexpected describe request")
|
t.Errorf("Received unexpected describe request")
|
||||||
}
|
}
|
||||||
|
|
||||||
populateTestMetrics(i)
|
populateTestMetrics(i, false)
|
||||||
metrics := initialiseMetrics()
|
metrics, _ := initialiseMetrics(getTestLogger())
|
||||||
updateMetrics(metrics)
|
updateMetrics(metrics)
|
||||||
responseChannel <- metrics
|
responseChannel <- metrics
|
||||||
|
|
||||||
|
|||||||
@@ -59,6 +59,8 @@ func startMetricsGathering(qmName string, log *logger.Logger) error {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
log.Println("Starting metrics gathering")
|
||||||
|
|
||||||
// Start processing metrics
|
// Start processing metrics
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go processMetrics(log, qmName, &wg)
|
go processMetrics(log, qmName, &wg)
|
||||||
|
|||||||
@@ -81,11 +81,12 @@ func processMetrics(log *logger.Logger, qmName string, wg *sync.WaitGroup) {
|
|||||||
first = false
|
first = false
|
||||||
wg.Done()
|
wg.Done()
|
||||||
}
|
}
|
||||||
metrics = initialiseMetrics()
|
metrics, _ = initialiseMetrics(log)
|
||||||
}
|
}
|
||||||
|
|
||||||
// now loop until something goes wrong
|
// Now loop until something goes wrong
|
||||||
for err == nil {
|
for err == nil {
|
||||||
|
|
||||||
// Process publications of metric data
|
// Process publications of metric data
|
||||||
err = mqmetric.ProcessPublications()
|
err = mqmetric.ProcessPublications()
|
||||||
|
|
||||||
@@ -100,19 +101,21 @@ func processMetrics(log *logger.Logger, qmName string, wg *sync.WaitGroup) {
|
|||||||
log.Debugf("Metrics: No requests received within timeout period (%d seconds)", requestTimeout)
|
log.Debugf("Metrics: No requests received within timeout period (%d seconds)", requestTimeout)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
log.Errorf("Metrics Error: %s", err.Error())
|
||||||
|
|
||||||
// Close the connection
|
// Close the connection
|
||||||
mqmetric.EndConnection()
|
mqmetric.EndConnection()
|
||||||
|
|
||||||
//If we're told to keep runnign sleep for a bit before trying again
|
// If we're told to keep running sleep for a bit before trying again
|
||||||
time.Sleep(10 * time.Second)
|
time.Sleep(10 * time.Second)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// initialiseMetrics sets initial details for all available metrics
|
// initialiseMetrics sets initial details for all available metrics
|
||||||
func initialiseMetrics() map[string]*metricData {
|
func initialiseMetrics(log *logger.Logger) (map[string]*metricData, error) {
|
||||||
|
|
||||||
metrics := make(map[string]*metricData)
|
metrics := make(map[string]*metricData)
|
||||||
|
validMetrics := true
|
||||||
|
|
||||||
for _, metricClass := range mqmetric.Metrics.Classes {
|
for _, metricClass := range mqmetric.Metrics.Classes {
|
||||||
for _, metricType := range metricClass.Types {
|
for _, metricType := range metricClass.Types {
|
||||||
@@ -123,12 +126,21 @@ func initialiseMetrics() map[string]*metricData {
|
|||||||
description: metricElement.Description,
|
description: metricElement.Description,
|
||||||
}
|
}
|
||||||
key := makeKey(metricElement)
|
key := makeKey(metricElement)
|
||||||
metrics[key] = &metric
|
if _, exists := metrics[key]; !exists {
|
||||||
|
metrics[key] = &metric
|
||||||
|
} else {
|
||||||
|
log.Errorf("Metrics Error: Found duplicate metric key %s", key)
|
||||||
|
validMetrics = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return metrics
|
|
||||||
|
if !validMetrics {
|
||||||
|
return metrics, fmt.Errorf("Invalid metrics data - found duplicate metric keys")
|
||||||
|
}
|
||||||
|
return metrics, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// updateMetrics updates values for all available metrics
|
// updateMetrics updates values for all available metrics
|
||||||
|
|||||||
@@ -16,19 +16,24 @@ limitations under the License.
|
|||||||
package metrics
|
package metrics
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/ibm-messaging/mq-container/internal/logger"
|
||||||
"github.com/ibm-messaging/mq-golang/mqmetric"
|
"github.com/ibm-messaging/mq-golang/mqmetric"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestInitialiseMetrics(t *testing.T) {
|
func TestInitialiseMetrics(t *testing.T) {
|
||||||
|
|
||||||
teardownTestCase := setupTestCase()
|
teardownTestCase := setupTestCase(false)
|
||||||
defer teardownTestCase()
|
defer teardownTestCase()
|
||||||
|
|
||||||
metrics := initialiseMetrics()
|
metrics, err := initialiseMetrics(getTestLogger())
|
||||||
metric, ok := metrics["ClassName/Type1Name/Element1Name"]
|
metric, ok := metrics["ClassName/Type1Name/Element1Name"]
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Unexpected error %s", err.Error())
|
||||||
|
}
|
||||||
if !ok {
|
if !ok {
|
||||||
t.Error("Expected metric not found in map")
|
t.Error("Expected metric not found in map")
|
||||||
} else {
|
} else {
|
||||||
@@ -55,12 +60,24 @@ func TestInitialiseMetrics(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUpdateMetrics(t *testing.T) {
|
func TestInitialiseMetrics_DuplicateKeys(t *testing.T) {
|
||||||
|
|
||||||
teardownTestCase := setupTestCase()
|
teardownTestCase := setupTestCase(true)
|
||||||
defer teardownTestCase()
|
defer teardownTestCase()
|
||||||
|
|
||||||
metrics := initialiseMetrics()
|
_, err := initialiseMetrics(getTestLogger())
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
t.Error("Expected duplicate keys error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUpdateMetrics(t *testing.T) {
|
||||||
|
|
||||||
|
teardownTestCase := setupTestCase(false)
|
||||||
|
defer teardownTestCase()
|
||||||
|
|
||||||
|
metrics, _ := initialiseMetrics(getTestLogger())
|
||||||
updateMetrics(metrics)
|
updateMetrics(metrics)
|
||||||
|
|
||||||
metric, _ := metrics["ClassName/Type1Name/Element1Name"]
|
metric, _ := metrics["ClassName/Type1Name/Element1Name"]
|
||||||
@@ -90,7 +107,7 @@ func TestUpdateMetrics(t *testing.T) {
|
|||||||
|
|
||||||
func TestMakeKey(t *testing.T) {
|
func TestMakeKey(t *testing.T) {
|
||||||
|
|
||||||
teardownTestCase := setupTestCase()
|
teardownTestCase := setupTestCase(false)
|
||||||
defer teardownTestCase()
|
defer teardownTestCase()
|
||||||
|
|
||||||
expected := "ClassName/Type1Name/Element1Name"
|
expected := "ClassName/Type1Name/Element1Name"
|
||||||
@@ -100,14 +117,14 @@ func TestMakeKey(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func setupTestCase() func() {
|
func setupTestCase(duplicateKey bool) func() {
|
||||||
populateTestMetrics(1)
|
populateTestMetrics(1, duplicateKey)
|
||||||
return func() {
|
return func() {
|
||||||
cleanTestMetrics()
|
cleanTestMetrics()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func populateTestMetrics(testValue int) {
|
func populateTestMetrics(testValue int, duplicateKey bool) {
|
||||||
|
|
||||||
metricClass := new(mqmetric.MonClass)
|
metricClass := new(mqmetric.MonClass)
|
||||||
metricType1 := new(mqmetric.MonType)
|
metricType1 := new(mqmetric.MonType)
|
||||||
@@ -135,6 +152,9 @@ func populateTestMetrics(testValue int) {
|
|||||||
metricType1.Elements = make(map[int]*mqmetric.MonElement)
|
metricType1.Elements = make(map[int]*mqmetric.MonElement)
|
||||||
metricType2.Elements = make(map[int]*mqmetric.MonElement)
|
metricType2.Elements = make(map[int]*mqmetric.MonElement)
|
||||||
metricType1.Elements[0] = metricElement1
|
metricType1.Elements[0] = metricElement1
|
||||||
|
if duplicateKey {
|
||||||
|
metricType1.Elements[1] = metricElement1
|
||||||
|
}
|
||||||
metricType2.Elements[0] = metricElement2
|
metricType2.Elements[0] = metricElement2
|
||||||
metricClass.Types = make(map[int]*mqmetric.MonType)
|
metricClass.Types = make(map[int]*mqmetric.MonType)
|
||||||
metricClass.Types[0] = metricType1
|
metricClass.Types[0] = metricType1
|
||||||
@@ -146,3 +166,8 @@ func populateTestMetrics(testValue int) {
|
|||||||
func cleanTestMetrics() {
|
func cleanTestMetrics() {
|
||||||
mqmetric.Metrics.Classes = make(map[int]*mqmetric.MonClass)
|
mqmetric.Metrics.Classes = make(map[int]*mqmetric.MonClass)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getTestLogger() *logger.Logger {
|
||||||
|
log, _ := logger.NewLogger(os.Stdout, false, false, "test")
|
||||||
|
return log
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user