-
-
Notifications
You must be signed in to change notification settings - Fork 27
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
Incremental runs #174
Incremental runs #174
Conversation
src/output.rs
Outdated
|
||
/// Caught and unviable scenario outcomes | ||
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)] | ||
pub struct PositiveOutcomes { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This structure is probably not that helpful, we will probably remove it and just pass around a Vec of PositiveOutcome.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed it
} | ||
} | ||
|
||
impl TryFrom<&ScenarioOutcome> for PositiveOutcome { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This bit is currently broken, we are working to fix it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed now
That sounds like a reasonable high level plan. This seems like a feature where it would be good to write the user facing doc in |
0f8c89c
to
0a6ba34
Compare
pub fn calculate_hash(&self) -> MutantHash { | ||
// We need the hashes to be stable across restarts, so that they can be serialized | ||
// consistently. | ||
let mut s = SipHasher::new(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is deprecated and the warning says we should use DefaultHasher, but the doc says:
The internal algorithm is not specified, and so it and its hashes should not be relied upon over releases.
https://doc.rust-lang.org/std/collections/hash_map/struct.DefaultHasher.html
and in this case, we need the hashes to be stable since they are persisted on disk.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we could just avoid the serialized format depending on a hash algorithm: could you store them in the originally generated order or even just sorted by location and name?
Actually, it makes more sense to just remove the incremental file once we have every mutant resulting in a positive outcome. |
We call positive outcomes scenarios where mutants were caught or unviable. These positive outcomes are now stored for use in incremental runs. Co-authored-by: Jared Norris <jared-norris@users.noreply.github.com>
0a6ba34
to
23c83dd
Compare
This sounds just great. I wonder if the "incremental" name is going to be confusing with the I can't immediately think of a better name, although maybe it should just be more explicit, something like "--already-failing", though that's still not great.
Sounds good. |
We had a similar debate when choosing the name; I think it can be improved upon. Maybe |
Maybe |
Hello, would this be possible on the txt files alone or would it require the jsons? Or would it be another mechanism to track these? |
Can you say more about why you'd want that? I think jsons are probably a better thing for computers to read: we can add more fields in future, etc. |
Let me know if/when you want a code review |
Our existing workflow consists of two phases: Logging and Tracking. Tracking Phase
Logging Phase
This logging approach ensures that mutant outputs remain human-readable and easily accessible. Simultaneously, it optimizes References
Logging
The current struggle is related only to the |
Hey @sourcefrog , sorry for the long silence, we have been quite busy lately. Some of the TODO points are still unimplemented, but feel free to share any feedback you may have on the current state. |
Ack, I'll come back and have a look at this |
Hi @cl3joly, thanks for starting on this, it's very nice and encouraging to see the energy about Mutants and about this feature. I think the high level description in your original post is just right: once people have some missed mutants, they should be able to repeatedly run with I realized that, in doing these iterations it's pretty likely that the user might interrupt one cargo-mutants run and it's important that, when that happens, we don't forget about any known positive results. The other thing I thought of looking at this PR thread is that as you edit the code to fix gaps, it's fairly likely that some mutant line numbers will change, so we probably don't want to match on them in saying which mutants are already covered: probably just matching on the type/function name is enough. I think, looking at the implementation, it is maybe getting a bit little complex than is necessary, although that is totally understandable for someone new to the codebase. I think @ASuciuX was on the right track in #174 (comment) to say maybe we can do this just with the existing text files in (In fact, maybe a good initial stand-alone step would be to add an option that runs only mutants explicitly named in some file, or excludes mutants named in some other files, optionally disregarding line/col. That's basically #204. That would support the use case someone mentioned of wanting to do some external filtering and processing of which ones to run. I'm inclined to split that off as a standalone feature, as a kind of step beyond the regex based filters.) One complication, maybe handled in your PR, I'm not sure, is that even if we're interrupted we shouldn't forget that some things were already caught or unviable... |
@sourcefrog Thanks for the review!
That’s a great point.
Right, that makes sense. The above point requires quite an extensive rework of this PR. That’s a fair thing from you to ask, as a maintainer. However, to be transparent, I don’t think I’ll have time to work on it in the next few weeks. If anyone wants to pick this up, please feel free. If not, when I have some time, I’ll come back to this PR to improve it based on your feedback. I hope that works for you @sourcefrog |
Yep, understandable. If I have free time I may pick this up, based on the ideas developed in your work. If I start on it I'll comment here to avoid duplication, and you can do that too if you come back to it. |
I'll close this and continue in #354. Thanks again for getting it started. |
This is a work in progress PR to add incremental runs (#53). @jared-norris is working with me on this as a part of a hackathon at our company.
TODO
High level description
Our vision of the use case for incremental builds is that you will add some code, try to cover it and you will have, say, 10 unviable mutants, 7 caught mutants and 3 uncaught mutants. You will then add tests, trying to catch those 3 mutants and you will run
cargo mutants
multiple time, catching more and more, until all mutants are either unviable or caught. That last part, where you keep adding tests, is where there is an opportunity to do incremental builds, where only the 3 uncaught mutants will be tried, ignoring the 10 unviable and the 7 caught mutants.We are adding a flag to run
cargo mutants
incrementally.mutants.out
tomutants.out.old
.