On 30.03.21 17:42, Aaron Gable wrote: > > Suppose I have a `CounterVec` that I call `requestsCounter`, with labels > `method` (whose values are only `GET` and `POST`) and `success` (whose > values are only `true` and `false`). Maybe I have a set of unittests which > implement a purposefully-broken handler, and I'd like to assert that we > incremented the counter for unsuccessful requests the appropriate number of > times, _regardless_ of whether those requests were GETs or POSTs.
In very general, I'd break this down, following the philosophy of letting a unit test just exercise the code it is supposed to test. With your current approach, you are almost doing and end-to-end test by invoking the whole `Collect` and `Write` machinery. I guess that's fine for true end-to-end tests. (See https://pkg.go.dev/github.com/prometheus/client_golang@v1.10.0/prometheus/testutil for utilities to write those tests.) In your case, as you said, you want to know if "we incremented the counter for unsuccessful requests the appropriate number of times". Ideally, you inject a CounterVec mock that doesn't really do anything with the metrics, but just records that the right counter child was retrieved and the appropriate increments were performed on it. Go doesn't lend itself to this kind of monkey-patching, and the client_golang library misses good support for this kind of approach right now, which has to do with certain design problems that cannot be fixed without a breaking change, see https://github.com/prometheus/client_golang/issues/230 . But it's still possible. In your case, your code probably would have to act on an interface, which is designed in a way that both `CounterVec` as well as your injected mock are implementing it. > Unfortunately this fails, because the curried `MetricVec` still sends *all* > metrics to the `.Collect()` channel, even those that would be excluded by > the curried labels. Yeah, that's another design problem of the library. The excuse is that currying was introduced relatively late in the design process. In an ideal world (and in v2 of the library), the curried CounterVec wouldn't even have a `Collect` method. You could also follow the "inject a mock" approach half-way and inject a CounterVec that only contains the relevant metrics instead of using the full CounterVec with all the other metrics plus currying. > The only real solution that I see here is to perform the currying ourselves > -- rather than passing a curried `MetricVec` into the `AssertMetricEquals` > function, pass a set of `Labels` into it and do the filtering ourselves > based on the contents of `iom.Label`. This would be functionally the same > as the "very hacky and weird" workaround in #834. Yes, in case you want to stick with the "let's collect the metrics and inspect the protobuf" approach, that's probably the most straightforward way to go. -- Björn Rabenstein [PGP-ID] 0x851C3DA17D748D03 [email] bjo...@rabenste.in -- You received this message because you are subscribed to the Google Groups "Prometheus Developers" group. To unsubscribe from this group and stop receiving emails from it, send an email to prometheus-developers+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/prometheus-developers/20210331203601.GU2627%40jahnn.