2  * ============LICENSE_START=======================================================
 
   3  * dcaegen2-collectors-veshv
 
   4  * ================================================================================
 
   5  * Copyright (C) 2018 NOKIA
 
   6  * ================================================================================
 
   7  * Licensed under the Apache License, Version 2.0 (the "License");
 
   8  * you may not use this file except in compliance with the License.
 
   9  * You may obtain a copy of the License at
 
  11  *      http://www.apache.org/licenses/LICENSE-2.0
 
  13  * Unless required by applicable law or agreed to in writing, software
 
  14  * distributed under the License is distributed on an "AS IS" BASIS,
 
  15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
  16  * See the License for the specific language governing permissions and
 
  17  * limitations under the License.
 
  18  * ============LICENSE_END=========================================================
 
  20 package org.onap.dcae.collectors.veshv.main
 
  23 import io.micrometer.core.instrument.Counter
 
  24 import io.micrometer.core.instrument.Gauge
 
  25 import io.micrometer.core.instrument.search.RequiredSearch
 
  26 import io.micrometer.prometheus.PrometheusConfig
 
  27 import io.micrometer.prometheus.PrometheusMeterRegistry
 
  28 import org.assertj.core.api.Assertions.assertThat
 
  29 import org.assertj.core.data.Percentage
 
  30 import org.jetbrains.spek.api.Spek
 
  31 import org.jetbrains.spek.api.dsl.describe
 
  32 import org.jetbrains.spek.api.dsl.it
 
  33 import org.jetbrains.spek.api.dsl.on
 
  34 import org.onap.dcae.collectors.veshv.main.metrics.MicrometerMetrics
 
  35 import org.onap.dcae.collectors.veshv.main.metrics.MicrometerMetrics.Companion.PREFIX
 
  36 import org.onap.dcae.collectors.veshv.model.MessageDropCause.INVALID_MESSAGE
 
  37 import org.onap.dcae.collectors.veshv.model.MessageDropCause.ROUTE_NOT_FOUND
 
  40  * @author Piotr Jaszczyk <piotr.jaszczyk@nokia.com>
 
  43 object MicrometerMetricsTest : Spek({
 
  44     val doublePrecision = Percentage.withPercentage(0.5)
 
  45     lateinit var registry: PrometheusMeterRegistry
 
  46     lateinit var cut: MicrometerMetrics
 
  49         registry = PrometheusMeterRegistry(PrometheusConfig.DEFAULT)
 
  50         cut = MicrometerMetrics(registry)
 
  53     fun registrySearch() = RequiredSearch.`in`(registry)
 
  55     fun <M, T> verifyMeter(search: RequiredSearch, map: (RequiredSearch) -> M, verifier: (M) -> T) =
 
  59                     { ex -> assertThat(ex).doesNotThrowAnyException() },
 
  63     fun <T> verifyGauge(name: String, verifier: (Gauge) -> T) =
 
  64             verifyMeter(registrySearch().name(name), RequiredSearch::gauge, verifier)
 
  66     fun <T> verifyCounter(search: RequiredSearch, verifier: (Counter) -> T) =
 
  67             verifyMeter(search, RequiredSearch::counter, verifier)
 
  69     fun <T> verifyCounter(name: String, verifier: (Counter) -> T) =
 
  70             verifyCounter(registrySearch().name(name), verifier)
 
  72     fun verifyAllCountersAreUnchangedBut(vararg changedCounters: String) {
 
  74                 .filter { it is Counter }
 
  75                 .map { it as Counter }
 
  76                 .filterNot { it.id.name in changedCounters }
 
  78                     assertThat(it.count()).describedAs(it.id.toString()).isCloseTo(0.0, doublePrecision)
 
  82     describe("notifyBytesReceived") {
 
  84         on("$PREFIX.data.received.bytes counter") {
 
  85             val counterName = "$PREFIX.data.received.bytes"
 
  87             it("should increment counter") {
 
  89                 cut.notifyBytesReceived(bytes)
 
  91                 verifyCounter(counterName) {
 
  92                     assertThat(it.count()).isCloseTo(bytes.toDouble(), doublePrecision)
 
  96             it("should leave all other counters unchanged") {
 
  97                 cut.notifyBytesReceived(128)
 
  98                 verifyAllCountersAreUnchangedBut(counterName)
 
 103     describe("notifyMessageReceived") {
 
 104         on("$PREFIX.messages.received.count counter") {
 
 105             val counterName = "$PREFIX.messages.received.count"
 
 107             it("should increment counter") {
 
 108                 cut.notifyMessageReceived(777)
 
 110                 verifyCounter(counterName) {
 
 111                     assertThat(it.count()).isCloseTo(1.0, doublePrecision)
 
 116         on("$PREFIX.messages.received.bytes counter") {
 
 117             val counterName = "$PREFIX.messages.received.bytes"
 
 119             it("should increment counter") {
 
 121                 cut.notifyMessageReceived(bytes)
 
 123                 verifyCounter(counterName) {
 
 124                     assertThat(it.count()).isCloseTo(bytes.toDouble(), doublePrecision)
 
 129         it("should leave all other counters unchanged") {
 
 130             cut.notifyMessageReceived(128)
 
 131             verifyAllCountersAreUnchangedBut(
 
 132                     "$PREFIX.messages.received.count",
 
 133                     "$PREFIX.messages.received.bytes"
 
 138     describe("notifyMessageSent") {
 
 139         val topicName1 = "PERF3GPP"
 
 140         val topicName2 = "CALLTRACE"
 
 142         on("$PREFIX.messages.sent.count.total counter") {
 
 143             val counterName = "$PREFIX.messages.sent.count.total"
 
 145             it("should increment counter") {
 
 146                 cut.notifyMessageSent(topicName1)
 
 148                 verifyCounter(counterName) {
 
 149                     assertThat(it.count()).isCloseTo(1.0, doublePrecision)
 
 151                 verifyAllCountersAreUnchangedBut(counterName, "$PREFIX.messages.sent.count.topic")
 
 155         on("$PREFIX.messages.sent.topic.count counter") {
 
 156             val counterName = "$PREFIX.messages.sent.count.topic"
 
 157             it("should handle counters for different topics") {
 
 158                 cut.notifyMessageSent(topicName1)
 
 159                 cut.notifyMessageSent(topicName2)
 
 160                 cut.notifyMessageSent(topicName2)
 
 162                 verifyCounter(registrySearch().name(counterName).tag("topic", topicName1)) {
 
 163                     assertThat(it.count()).isCloseTo(1.0, doublePrecision)
 
 166                 verifyCounter(registrySearch().name(counterName).tag("topic", topicName2)) {
 
 167                     assertThat(it.count()).isCloseTo(2.0, doublePrecision)
 
 173     describe("notifyMessageDropped") {
 
 175         on("$PREFIX.messages.dropped.count.total counter") {
 
 176             val counterName = "$PREFIX.messages.dropped.count.total"
 
 177             it("should increment counter") {
 
 178                 cut.notifyMessageDropped(ROUTE_NOT_FOUND)
 
 179                 cut.notifyMessageDropped(INVALID_MESSAGE)
 
 181                 verifyCounter(counterName) {
 
 182                     assertThat(it.count()).isCloseTo(2.0, doublePrecision)
 
 184                 verifyAllCountersAreUnchangedBut(counterName, "$PREFIX.messages.dropped.count.cause")
 
 188         on("$PREFIX.messages.dropped.count.cause counter") {
 
 189             val counterName = "$PREFIX.messages.dropped.count.cause"
 
 190             it("should handle counters for different drop reasons") {
 
 191                 cut.notifyMessageDropped(ROUTE_NOT_FOUND)
 
 192                 cut.notifyMessageDropped(INVALID_MESSAGE)
 
 193                 cut.notifyMessageDropped(INVALID_MESSAGE)
 
 195                 verifyCounter(registrySearch().name(counterName).tag("cause", ROUTE_NOT_FOUND.tag)) {
 
 196                     assertThat(it.count()).isCloseTo(1.0, doublePrecision)
 
 199                 verifyCounter(registrySearch().name(counterName).tag("cause", INVALID_MESSAGE.tag)) {
 
 200                     assertThat(it.count()).isCloseTo(2.0, doublePrecision)
 
 206     describe("processing gauge") {
 
 207         it("should show difference between sent and received messages") {
 
 209             on("positive difference") {
 
 210                 cut.notifyMessageReceived(128)
 
 211                 cut.notifyMessageReceived(256)
 
 212                 cut.notifyMessageReceived(256)
 
 213                 cut.notifyMessageSent("perf3gpp")
 
 214                 verifyGauge("messages.processing.count") {
 
 215                     assertThat(it.value()).isCloseTo(2.0, doublePrecision)
 
 219             on("zero difference") {
 
 220                 cut.notifyMessageReceived(128)
 
 221                 cut.notifyMessageSent("perf3gpp")
 
 222                 verifyGauge("messages.processing.count") {
 
 223                     assertThat(it.value()).isCloseTo(0.0, doublePrecision)
 
 227             on("negative difference") {
 
 228                 cut.notifyMessageReceived(128)
 
 229                 cut.notifyMessageSent("fault")
 
 230                 cut.notifyMessageSent("perf3gpp")
 
 231                 verifyGauge("messages.processing.count") {
 
 232                     assertThat(it.value()).isCloseTo(0.0, doublePrecision)