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
Alternate Timeout API for dynamic timeout intervals #2021
Comments
I am trying to figure out what other cases would you need a dynamic timeout. |
Parameterized tests might calculate the timeout based on parameter values. |
So would it be equivalent to doing something like
|
@JustinRChou Yes. That's the |
Here's a prototype of the |
I'd be happy to check out this one. Ready to dive into open-source contribution. :) |
@bmolnar2 Awesome! It's yours. I'm assigning myself to the issue to keep track of it. Let us know if you need anything. |
If I'm reading the history right, this got made into a feature without significant discussion and without selecting among the alternative implementations. The first is important for all features (we have to agree we need them) and the second for anything we mark as |
I don't recall significant discussion on every enhancement, but what sort of discussion would you like to have? Now that we're here, are you asking for @bmolnar2 to leave this for now? If so, it would be nice if the discussion didn't drag on. 😃 |
This issue has been open for 10 months and has been If anyone has objections, let's try to sort them out quickly. |
Basis of my comment was that @jnm2 proposed, @rprouse made it a discussion item and @jnm2 accepted it as a feature without discussing the merits. I construe making something a discussion item as meaning we aren't sure we want to do it. We don't do this with every feature but when somebody - especially the project lead - says it needs discussion, then it means the desirability of the feature is up for discussion and the person who wants it to happen should try to get concurrence. That didn't happen here - it just got promoted to a feature without anyone noticing. If @rprouse sees no problem, I'm not raising one. I'm just describing what I would have expected if I were the person who put a hold on this by marking it for discussion. But if the pipeline means something else I'd like to see it spelled out so I can follow the rules. |
My guess is @rprouse saw that there was discussion and labeled it as such. Maybe I was mistaken, but I don't see an ask for more discussion in the history of this issue. In hindsight, I should have probably tagged the framework team and asked for more comments. Yes, I agree I should ask for more than one person's vote of confidence before I come back, see support, and move it forward. It felt awkward to say, "@OsirisTerje, I see you've used the thumbs-up reaction. Would you please leave a comment also saying you support this so that I can follow the rules and move this to the backlog?" From my perspective, watching a lot of issues, I object that the expectations are too grey to be asking for a high level of precision; I've seen issues move forward with less interaction. Since process and precision is important, let's aim for success and at least spell out explicitly what steps are to be followed at every turn. And I wish we could have these meta-discussions out of issue because frankly they are cross-cutting for us and mainly irrelevant to anyone waiting for the feature. |
I agree we should minimize meta-discussion on issues but when the process hasn't been followed and it comes up, there's no other way to do it. Unfortunately, we don't have a good place to have such discussions without going non-transparent via email. And it's better to have the discussion than waiting for the PR and then having one of us say "we don't need this feature." So, for all those reasons, I'm continuing here. From our Wiki... is:idea An idea about something we might do. We discuss these until they are either dropped or turned into a feature or enhancement we can work on. Discussion These are items that require some discussion, either about whether we want to do them or how they should be implemented. Some items here may require confirmation or design as well. As I always did it and as I understood Rob to be continuing, when the project lead applies the combination of those two items, he is putting the brakes on development. If @rprouse is now using them in a different way, then I want to know that because otherwise I can't collaborate successfully on the project. There's no reason you - the original proposer - can't be the one to re-activate it as a backlog item, but you're supposed to have conducted the discussion and reached consensus first. If we are not clear on this, then the logical extension is that any two committers can add any feature whatsoever to NUnit. Regarding "thumbs up", one never knows what they mean unless they are applied to a simple declarative statement. If you posted a comment that said "I think this has been discussed enough and I suggest we go ahead with option B" then I'd take thumbs up as agreement to that comment. That wasn't the case here. In any case, there has never been any discussion of whether we want a feature like this. All the discussion that took place was about how to implement it, as if it had been labelled If you had called for all of us to chime in on this, I think folks would have responded. I think that it's up to either the proposer or the project lead to help ideas migrate to backlog items... possibly both. I know I would have chimed in and - in fact - would have favored moving ahead. This is a process issue for me and I used your issue to raise it because your reversal of Rob's categorization shocked me when I saw it. |
Points well taken. It's easy enough to slow down and ask more questions if I'm not sure. I can and will certainly do better. |
(And sorry @bmolnar2 for the drama I've caused on this one.) So @nunit/framework-team, we can't think of a good way to make |
@jnm2 Thanks for your gracious reply. You are not actually owed 100% of the blame here, but that's getting too much into the meta. Since this issue, which you created back in January, only has my attention now. I'll start at the beginning. What you are suggesting is some way to do timeouts right in the test code, similar to how we replaced You proposed two alternative syntaxes: Does.Timeout
Does.Not.Timeout
Has.Maxtime
Has.No.Maxtime
Does.Not.Throw.And.MaxTime It's possible to set things up so some of those don't compile, but I think we need to fully specify what will and won't work. It would be OK with me if we allowed only the use directly after Has for the initial implementation, because the other stuff is not really for a new contributor. We don't use either MaxTime or Timeout in syntactic expressions now, but we do use them for attributes. The attributes have entirely different meanings. Timeout says cancel if this takes more than a certain amount of time. MaxTime implies a performance test. It reports the actual time taken and compares it to a target, failing if the target is mixed. We can't use them interchangeably so I guess you have to clarify which of the two behaviors you are looking for. In reading through the comments, I see both suggested at different points. Once we clarify what is desired, we can pick one of those words or - if neither of them fits in fluently - some third word. But the behavior seems to be the first thing to decide. |
I started to go through the various documentations and also gave a try on building the solution. On the latter one, several error occurs, when I build the solution. I may miss some piece of information on that part (after reading Building.md file several times). Can someone reach me out on mail? I made mine public, so you can do. I'll start human static code analyzer in the mean time. :) |
Well, it took me while (also did a windows install), but could build the solution, however only after unloading NetStandard13 and NetStandard16 projects. So I guess, there is are some problems. But anyway, I can spend some quality time finally to get familiar with the problem and the related code. |
@bmolnar2 I'm certainly sorry to hear it took a lot of time for you. Just curious, what's your VS version and update? |
It's 14.0.25431.01 (2015) with Update 3. |
The theory is you shouldn't have to update, but the .NET Standard stuff is pretty confusing. If you think it would make your life easier, updating may solve the issues you're seeing. If you're happy with what you've got going right now, keep it. =) |
So, there are a bunch of tests failing in a clear master branch. Is that normal?
However tests like this are confusing too:
|
Are you trying to run tests on NUnit using the NUnit VS test adapter? That won't work very well for a number of reasons. The tests you are seeing fail are run by NUnit as a part of testing NUnit. We need failing tests, of course, in order to see that they fail correctly. The real tests are found in nunit.framework.tests.dll and nunitlite.tests.dll. To run all tests for all supported runtime at the command-line, use 'build -t Test'. For testing as you work, I'd set up one of the nunitlite.runner projects as the startup project. |
Yep, it was the adapter. |
@bmolnar2 Asking for the sake of making things smoother for first-time contributors: could we have done something to make it easier for you to find https://github.com/nunit/nunit/blob/master/BUILDING.md#running-tests? |
A note under the Running Tests section could help on the latter. |
@jnm2 Oddly, that link seems to tell people to run the slow-tests assembly, which is not a top-level test. @bmolnar2 The Running Tests section of the docs is oriented toward users of NUnit running their own tests. So it doesn't seem like a good place to tell developers of NUnit how to run tests. Maybe a note and a link, however. |
@CharliePoole You're right, I'll fix that. |
@rprouse I raised questions on whether we need this feature. Subsequently, we had meta-discussion of our own procedures and answered technical questions from the person working on it, who has now submitted a PR. I think this illustrates what an happen when we allow things to get away from us. I realize that you expressed a preference for this feature, in the form of On the substance of the feature: I think we all have agreed that there's a need for some more granular way to test the maximum time that things take within a test. We could probably have spent more time on talking about what that should look like, but other kinds of discussions dominated and most of that discussion was between two people. I came in late and raised questions, which I hoped would cause you to block the issue. That hasn't happened, so I've "requested changes" on the PR without actually specifying the changes I want. I have asked some questions as well, about what seem to be strange choices in the code. If we can have a discussion and come to an agreement on the shape of the feature, I'm happy to do a true review and merge code that implements it in that shape. If we don't do that, you can merge it in spite of my negative review and I'll have no further comment. |
@CharliePoole has a point about the semantics of I can see wanting to assert that something runs in a given amount of time (through an assert, or through the Because of that, I am not sure that this implementation is a good addition. I can see the timeout as originally specified, but that is not how this is written. I made a mistake in preferring I am still okay with original syntax of the issue, but only if So, my thoughts,
@bmolnar2 I am sorry for this confusion, I should have been tracking the issues more closely. |
I see two places where this went awry. First, in talking about MaxTime and Timeout as variants of the same thing. Of course, they both specify time limits and so are superficially similar. But the first just times the test, reporting a failure if the max time is exceeded. The second requires additional infrastructure. Some thread has to be waiting to Join on the test thread with a timeout specified. So they are really quite different animals. Second, in making this a constraint... or in only considering Constraints as alternatives. It sounds like either could be done by using an Assert that takes a block of code, like Assert.TimeOut( () => // Or MaxTime
{
// Code being timed
},
timeSpan // or time in ms
); Alternatively, we could try to solve @jnm2 's original problem by making an enhancement to |
I have one alternative proposal since everyone seems to like public static class NUnit.Framework.Does
{
- public static Constraints.ConstraintExpression Not { get; }
+ public static Constraints.DoesNotConstraintExpression Not { get; }
}
+public sealed class NUnit.Framework.Constraints.DoesNotConstraintExpression : ConstraintExpression
+{
+ public Constraint Timeout(int milliseconds);
+} This gets the best of both worlds I think and isn't a big change or a breaking change. |
That allows you to write things like... Does.Not.TImeout(500).StartsWith("Hello!");
Does.Not.Timeout(100).And.Equals(42); Are you intending to support that? Frankly, I see no need. Again... see above... why does this have to be a constraint at all? An expression like Assert.TimeOut(() => { ... }); Is consistent with expressions like |
As Rob said above:
If we don't think that all the syntax under the That said, |
It's a weakness of the syntax we use that we can't detect some errors until runtime. It's not peculiar to Throws. Something like However, we made a In the case of Timeout, I don't see a great value in making it a constraint and thereby complicating the syntax from the user point of view. Giving Somewhere earlier in the discussion, performance testing was mentioned. This would not be for that purpose except as a sort of "performance smoke test". Really for a performance test, we want to be able to grab the timing at various stages and then apply rules to them in order to either fail the test or possibly issue a warning. Probably something for a subsequent issue in any case. |
We have a use case for warning, so that makes me want to go with a constraint for maximum flexibility. Since we can't make |
Closing this issue in favor of a fresh look at #2616. |
There is only one way to specify a timeout as far as I can tell:
TimeoutAttribute
. The fact that it's an attribute means that the timeout time must be a compile-time constant.However, I am searching for a way to override that timeout if a given environment variable is present. If
TF_BUILD
is present, I want to use7000
. Otherwise, I want to use3000
.If you want to stick with attributes, a conditional timeout attribute could be added such as
TimeoutIfEnv("TF_BUILD", 7000)
. However a more flexible API might be an assertion, taking a page fromThrows
:The non-aborting version could be
Has.MaxTime
.There could be a
TimeSpan
overload as well.What are your opinions?
The text was updated successfully, but these errors were encountered: