Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add threshold for statistics #465

Draft
wants to merge 10 commits into
base: dev
Choose a base branch
from

Conversation

pavlogrushetsky
Copy link

@pavlogrushetsky pavlogrushetsky commented May 15, 2022

This is a draft PR for #355 (Add threshold for statistics). The work is still in progress, and the PR is rather for review and conversation about the overall approach.

Some other things TODO:

  • Implementing thresholds for DataTransferStats
  • Implementing logic for displaying the thresholds status in the load test outputs
  • Specifying thresholds through the configuration files
  • Adding comments to the new methods in the contracts
  • Covering the changes with the tests

I would appreciate any feedback on this draft implementation 🙇‍♂️.

examples/FSharpDev/HttpTests/SimpleHttpTest.fs Outdated Show resolved Hide resolved
src/NBomber.Contracts/Metrics.fs Outdated Show resolved Hide resolved
src/NBomber.Contracts/Stats.fs Outdated Show resolved Hide resolved
Comment on lines +73 to +81
let private printThresholdStats (scnStats: ScenarioStats) =
let headers = ["threshold"; "status"]
let rows =
scnStats.ThresholdStats
|> Option.map (ReportHelper.ThresholdStats.createTableRows Console.okEscColor Console.errorEscColor)
|> Option.defaultValue List.empty

[ Console.addLine $"thresholds for scenario: {Console.okColor scnStats.ScenarioName}"
Console.addTable headers rows ]
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's how it looks like:

image

I'm not sure if this would be sufficient, and if not, I'm not sure at the moment how we could print a string representation for the thresholds predicates.

Copy link
Contributor

@AntyaDev AntyaDev May 23, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For F# we could use https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/code-quotations
But on the other hand, it will be a deal-breaker for C#.
I am not sure but maybe this project can help here https://mbraceproject.github.io/FsPickler/
I don't exactly know if it is possible to somehow fetch the AST representation of the Threshold function/delegate but it would be awesome.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, we could have an additional API that will accept the optional string argument that the user will fill, and it will be printed if it's not empty. But maybe, for now, we can leave all this "Fetching Meta Info" machinery as for v2?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @pavlogrushetsky
You can take a look how this library is working for F#
https://github.com/SwensenSoftware/unquote

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! I will take a look.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@AntyaDev It looks like I could utilize Unquote library 😀. I've played with it a little bit, and was able to specify a threshold using quotation expression. The work is still in progress, but I think, I would need to separate Threshold model to have one in Contracts with function union cases (like int -> bool), and one in DomainTypes with Quotations.Expr union cases (like Quotations.Expr<int -> bool>). This would allow us to keep the consumer code as simple as possible, to not to have something like the following:

|> Scenario.withThresholds [
    RequestAllCount(<@ fun x -> x = 3 @>)
]

and instead be able to specify thresholds using plain functions:

|> Scenario.withThresholds [
    RequestAllCount(fun x -> x = 3)
]

I would just need to translate Contracts.Threshold model to DomainTypes.Threshold model, like you do for Scenario.

@AntyaDev Please, let me know if this makes sense to you.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it sounds reasonable!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @AntyaDev 👋 I've played a bit with quotation expressions, and it turned out that the text representation for the decompiled predicates isn't really human-readable. I think, it's not worth implementing something very complicated, at least at this point.

So, I've added an ability to override a default threshold description. Here is how it looks in C#:

image

In F#, it looks a little bit ugly:

image

To improve this syntax for F# users, I've implemented a simple computation expression, so that it would be possible to specify a description as a real optional parameter, like the following:

image

I've also improved the console output to make it more human readable. Here is an example:

image

@AntyaDev Please, let me know what you think about this 😅

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks very good, I like how F# and C# look like.
Btw what was the issue with F# quotations? I thought that you would not be able to use it for C# and to use it for F#, you should wrap the predicate into <@ predicate @>

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Btw what was the issue with F# quotations? I thought that you would not be able to use it for C# and to use it for F#, you should wrap the predicate into <@ predicate @>

Yep, I was able to wrap the predicates in <@ @> in the domain logic and keep using just plain lambdas like fun x -> x > 10 in both C# and F#, and the thresholds evaluation logic worked good. And main reason to do this was to get a string representation for those quotation expressions, but it turned out that it is not really human readable when I tried to de-compile them.

@pavlogrushetsky
Copy link
Author

pavlogrushetsky commented May 20, 2022

@AntyaDev One more question 😅 Would the following functionality make sense to you?:

  • Specifying thresholds through the configuration files

@AntyaDev
Copy link
Contributor

"Specifying thresholds through the configuration files" - seems can be skipped for now :)
I used to add such things iteratively.

@pavlogrushetsky
Copy link
Author

"Specifying thresholds through the configuration files" - seems can be skipped for now :) I used to add such things iteratively.

Great! Makes sense to me, thank you!

@AntyaDev
Copy link
Contributor

AntyaDev commented Jul 4, 2022

Hi @pavlogrushetsky
Any news?

@pavlogrushetsky
Copy link
Author

Hi @pavlogrushetsky Any news?

Oh, I've been busy recently, sorry. I'll try to push something this week.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants