-
Notifications
You must be signed in to change notification settings - Fork 35
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
proposal and preview for mutagen v0.2 #149
Conversation
Now, the code about a single mutator is in a single file
I have done quite a few changes to the architecture since the first commit. I am quite happy with the current state.
|
|
||
It also will only see the bare AST, no inferred types, no control flow or data flow, unless we analyse them ourselves. But not only that, we want to be *fast*. This means we want to avoid doing one compile run per mutation, so we try to bake in all mutations into the code once and select them at runtime via a mutation count. This means we must avoid mutations that break the code so it no longer compiles. |
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.
Why are we losing this information? I feel it is a crucial piece to understand the design decisions for mutagen, which haven't really changed with your redesign.
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 information is indeed important. I thought I kept this information somewhere. I will add this paragraph back into the documentation and the readme.
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.
In the newest commits this section is back in the readme. The documents about the architecture and design decisions also contain paragraphs on this topic.
README.md
Outdated
|
||
You can run `cargo mutagen -- --coverage` in order to reduce the time it takes to run the mutated code. When running on this mode, it runs the testsuite at the beginning of the process and checks which tests are hitting mutated code. Then, for each mutation, instead of running the whole testsuite again, it executes only the tests that are affected by the current mutation. This mode is specially useful when the testsuite is slow or when the mutated code affects a little part of it. | ||
*Use `mutagen` as `dev-dependency`, unless otherwise necessary.* Compiling `mutagen` is time-intensive and library-users should not have to download `mutagen` as a dependency. |
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.
Perhaps we should advise users to use sccache
?
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 have no experience with that. I wanted to say that if a library uses mutagen
, users of that library should not have to compile mutagen since it is only used for internal tests.
For testing purposes, the compile-time is fine. I guess I have to rewrite this section to avoid confusion about this topic.
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.
Updated in the newest commits. I think the new version is the best reason for using mutagen as a dev-dependency: "ensures nothing will land in released code"
In the newest commit, I implemented another mutator that mutates comparison operators or At this stage, it is still possible to change the architecture of everything. Do you have any requests / suggestions? |
type Output = <L as Add<R>>::Output; | ||
|
||
default fn may_sub(self, _r: R) -> <L as Add<R>>::Output { | ||
panic!("not sub"); |
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.
Why do we panic here?
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.
As far as I understand:
- If the optimistic assumption fails, the mutant should not be considered survived.
- To be able to kill the mutant, the test suite has to fail.
- To fail the test suite, the code must have some different behavior when activating the mutant.
- I believe panicking is the only/easiest way to cause behavior that is different from the non-mutated case. However, I am open to other options.
In the future, I would like to read the output of the test-binary and detect if a certain panic-message has been printed. Based on that, the mutant could be considered "failed" instead of "killed" or "survived".
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.
Ok, that makes sense. I had envisioned a backchannel (an mmap, socket or simple file) to inform the test runner of the ineffective mutation on the no-mutation-run, so the runner could mark the mutation as ineffective. However, there is actually a tri-state at play here, because such a mutation could be within a generic function that monomorphizes to any number of ineffective mutations. Thus, we should be able to both mark an optimistic mutation as (potentially) ineffective and as effective (at least we should do so if it was marked as ineffective before and succeeds nonetheless).
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 should add that in-band messaging is inherently problematic and I would oppose misusing panics for that purpose. What if a user has a custom panic message that is inadvertently parsed as a killed mutant?
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 see that using panics might not be the cleanest solution. I will work on some backchannel for coverage-analysis. The information about optimistic assumptions can be included there.
However, I think that not necessarily part of a first working release, which I would like to finish in early September.
I did not think about optimistic mutantions in generic functions. I will investigate some issues here.
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'm fine with that. Currently we just write a file on the nonmutated run, but there are likely faster and leaner solutions.
Sorry for letting you wait for so long. I was on vacation. This looks pretty good so far, I only commented on a few questions I had. I think this should be ready to merge once we reach feature parity with the previous version. Or would you like this to be merged sooner? |
Your suggestion is very promising. However, the that approach duplicates the input expressions, which is not allowed when the expressions move something out of a variable. I've not been able to use this idea to get a working transformation in all cases. |
I am quite happy with the current layout of the report and consider this as done for now. For the time being, I am also happy with the mutators implemented so far. I implemented mutators for numeric operations After that, I would like to publish the current state as |
I'm currently very short on time, but will review soon. I'd also like to see some docs regarding open tasks for the future. |
I wrote a short list of in beyond mutagen-0.2. These tasks could give a roadmap for the mid-term future of mutagen. |
👍 |
During my work for mutagen-applied, I found some more issues when applying mutagen to the crate There is a line The previos version rewrote the statement into I introduced a fix by generating the following code: This also fixes the issues discussed above for |
I just realized a major issue. Currently, we suggest adding As I understand it: It is impossible for the macro I see several ways to resolve this. I am also happy to discuss other approaches.
short example for a possible suggested
I am not sure where to go with this and which direction is the least dangerous or most useful. |
I would take the current approach and lobby the rust devs to set the In other news, David Tolnay has documented a way to hack together specialization on stable. I'm currently trying to introduce this to overflower, and it would fit well with mutagen, too. |
I am fine with the current approach. I am currently refactoring the runner to respect coverage measures of each testsuite individually. However, I believe that the choice to disable the I will try David Tolnay's method. However, we still require |
I uncovered another issue. (see Post in users.rust-lang). This means that type inference rules can cause compilation errors in code that is not transformed by the mutagen. How should we deal with this? |
I did some improvements on the printed report and the running mechanism. My tests on mutagen-applied have been successful. Integrating mutagen into an existing project is not completely automatic and requires minimal amount of manual intervention in some cases. However, this effort is far smaller than the analysis of the mutationtest report, which is obviously a manual process. I would like to merge and publish my proposed version of mutagen as v0.2. Is this possible within November? |
I finally found the time to review this. Good job and thank you! |
As discussed in #142, this is a proposal for a modular architecture, which is the base for
mutagen v0.2
. I reviewed all parts of the code and tried to move code that works fine to the new system.This is a minimal implementation to demonstrate the effectiveness of the architecture. The steps towards releasing
mutagen v0.2
are:Are there any other major tasks for this PR?