-
Notifications
You must be signed in to change notification settings - Fork 388
Add possibility to run coverlet in standalone mode #781
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
Comments
Some notes:
Maybe this is not doable, in past coverlet registered hits on file directly for every call, but it was very slow so we moved to in ram booking in a int array and at the end we flush to disk, so I think that send coverage for every hits realtime won't work well, think for example a loop that would send n hits for every cycle, it was slow on file, I think will be worst with network, BTW I don't have numbers and I'm speculating, maybe tcp buffering works well also in this case. This is the place where instrumentation start, for every module(found or filtered) we generate an
Some ideas
Take a look at live sample(in PR) https://twitter.com/MarcoRossignoli/status/1201546945589841922 in this case first command instrument dll and generates the instrumentation result and the second command take the instrumentation result and use it to get realtime coverage, because they need to know the mappings.
frequency: send every new records https://github.com/tonerdo/coverlet/blob/528a769c9ab98762935490372e40720ed7219618/src/coverlet.core/Instrumentation/ModuleTrackerTemplate.cs#L52 And the protocol cloud be
Also we need to expose an object model to allow the accounting on server side, pseudo code Instrumentation inst = new Instrumentation(instrumentationResultFilePath);
inst.ReadCoverage(received json);
inst.ShowSomethingSomeWhere(); Or simply send a binary format that server only need to append to some stream(file, memory) something similar to a database transaction log and another command |
@jakubch1 one question, it's not clear to me how do you see "the server side part" that receive the hits: Is implemented in coverlet like a command that stay up on a port until some signal? |
@MarcoRossignoli I will try to create something based on this what you said and I will see if this works. Maybe you are right that we don't need to have this inside coverlet. Basically people can develop what they need. Any other user asked for such thing? During the call you said that sometimes there is issue that report is not generated because testhost process is terminated too fast. Do you have any reports for it? In case of vstest it could work in such way that array with hits could be inside shared memory (accessible by both data collector and testhost) and when data collector gets event that all tests are done it (data collector) could generate report. |
What do you mean?Do you use coverlet as coverage engine or not?
You(vstest old team) and some other users asked for standalone release of coverlet core features #212 (check thumbs up), this is an explorative PR #628
Main issue #210
We don't have issue with collectors because in-process one is synched with test end events, we have that issue with msbuild integration because it's based on process exit event. This is our in-proc implementation https://github.com/tonerdo/coverlet/blob/master/src/coverlet.collector/InProcDataCollection/CoverletInProcDataCollector.cs#L46 Collectors integration is the more resilient way to use coverlet but there are some unsupported features due to vstest platform behaviour:
Aggregate collectors issues https://github.com/tonerdo/coverlet/issues?q=is%3Aissue+is%3Aopen+label%3Adriver-collectors |
I want to try to build something on top of coverlet to check that it allows to replace stuff correctly with different implementation.
I don't understand this. Msbuild integration is internally running vstest so what is the issue?
If I understand correctly this works only for .net Core. So suggestion to use shared memory between OutProcCollector and testhost is still valid. I was checking other threads regarding this issue and Mayank was also suggesting this. By using shared memory and generating report inside data collector you could maybe even not need Coverlet nuget package reference inside test projects. We could make call and discuss this.
I'm planning to work on this feature in near future :) The initial idea is to create something as session inside vstest.console.exe (process will run in client mode like in VS) and vstest.console will gather all coverage reports from test projects executions. On session finish it will group by coverage reports based on data collector uri. Then data collectors will again be invoked to merge reports. We will let you know when we agree on design. |
The issue is that with msbuild version the flush of hits to file is done on process exists and with collectors is done by in-proc collector, so if during process exits vstest plat kill host process msbuild version doesn't flush file correctly.
At the moment yes...because I don't know why collectors wasn't compiled as netstandard2.0 by @vagisha-nidhi , but will support also netfx if we'll compile for netstandard.
Yep a good idea.
This is great! |
We had internal discussion with code coverage experts regarding this. We believe coverlet should use shared memory between testhost and out proc data collector and generate report inside out proc data collector. This is approach which is used in several code coverage solutions that we know. It fixes all issues with crush/fast kill of test host process. |
Maybe I wasn't clear, we don't have any problem with collectors version of coverlet, it works as expected. The problem is with msbuild version, where there is no control on process shutdown. I try to explain better the difference between msbuild and collectors(I call "driver" the way to use coverlet runtime, for instance msbuild is a driver, collectors is a driver) run:
if you want to use msbuild command you have to add
This is the most used way https://nugettrends.com/packages?months=12&ids=coverlet.msbuild today. How it works:
Here the "fast kill" issue on point 3 does not allow to process exit to flush file correctly and we don't have any control on where msbuild task will be hosted so we cannot simply open a shared memory, but to fix this issue with your idea we should span our new process that communicates with testhost and in some way read that data on msbuild task after
if you want to use collectors integration you have to add
How it works:
https://github.com/microsoft/vstest/blob/master/src/vstest.console/Processors/CollectArgumentProcessor.cs#L176 here in-process injection
So in case of collectors integration we have the guarantee of hit file flush because in-process collector listen test end event and force flush and not rely on process exits https://github.com/tonerdo/coverlet/blob/master/src/coverlet.collector/InProcDataCollection/CoverletInProcDataCollector.cs#L57 So there is NO issue with collectors but there is issue with msbuild driver. If it's not clear we should talk via chat or call, it's hard to explain in a issue post. |
When we can have a meeting? I can do it today after 7PM or next week Wednesday or Friday after 6PM. |
@jakubch1 sorry I read now, if you want I'm here...or ok for Wednesday after 6PM. |
I'll chime in with my use case that I think this Issue fits well with. I maintain a web-based business application that doesn't have very many unit tests, but has plenty of automated tests through Selenium in a web browser. I want to assess how well these Selenium web tests cover my business logic. If I could instrument my binaries as @jakubch1 described, I could run the Selenium tests in a browser, look at the coverage report afterward, and inform my QA team of where additional Selenium tests are needed to achieve better coverage. I wouldn't need real-time reporting for my use case. |
Before going down the shared memory road have a look at this comment from the last time it was tried to see if it can be done in a way that doesn't break System.Private.CoreLib: Edit: I'm now caught up and see that this was already noticed in #808, great! |
@jakubch1 I did some attempt with the .NET tool idea and seems to work(with a caveat)
This command will start server with instrumented libs.
CaveatThe only cavet is that server process MUST shutdown in a gracefully way, because today coverlet relies on process exit event to store the hits, so a process kill won't work. public static void Main(string[] args)
{
IHost host = CreateHostBuilder(args).Build();
var appLife = host.Services.GetRequiredService<IHostApplicationLifetime>();
_ = Task.Run(() => host.Run());
Thread.Sleep(TimeSpan.FromMinutes(1.5));
appLife.StopApplication();
} I did a simple test with a simple asp.net core app created with scaffolding but I don't see any reason why shouldn't work with other type of app. |
Hi everyone. We try to following some instructions were discussed here, but we don't got good results. We need get coverage of an assembly .exe(Window form .Net framework 4.6.1 ), in a test project with appium(windows driver), is a UI test project, but we don't know how get coverage of that assembly .exe(we launch .exe from that test) That Windows form app have reference to other assemblies(.dll, someones in .netframework and others in c++) that we need get the coverage too. Do you can give us some idea if is possible get coverage with Coverlet in this enviroment? Thanks in advance. |
Coverlet supports only IL ECMA-335 (.NET) code coverage, we don't support unmanaged environment. |
HI @MarcoRossignoli , that mean even if i exclude that assembly(.dll in c++) i can't get the coverage with the others assemblies? |
No for .NET assemblies should work, are you sure that process after test closes gracefully and not with a kill process?coverlet store data in a processExit event, if process closes without that event there is a possibility of missing data coverage, are you able to provide a repro? |
I tried to follow these steps, but no matter what I do (even with graceful shutdown implemented), I get these errors and a 0% coverage file:
Do you have any ideas? I added the |
Is it possible to add PID as a target? |
@iSuper-Ray Sorry, it's not possible to run against an already executing process, since coverlet works by instrumenting the binaries before they are run. |
I'd like to try implement that, but for it I'd like to discuss what should be the final shape.
Is it sounds as plan that I can start work on - or should something here be changed? |
I like the idea to have everything inside the we could move the "today" commands under the verb
So the fix for current usage will be add
We should find a good verb for the standalone mode
I like the idea to have a "general" verb name and after specify the parameters so it's possible in future add new complex features on top of the "off line" instrumentation
Yes, usually we "try to" instrument all dlls close to the test container so we should have include/exclude dll and folders and exclude win on include.
It's ok
We should by default create hint file in the current directory(we'll have one for every dll istrumented) with a chance to override, I expected that the user will instrument/execute/shutdown/zip(hints/InstrumenterResult) and move in some folder to generate the report(or generate it in place). We have always anyway a small issue with the standalone execution, it will work only if we "gracefully" shutdown the execution or we'll lose the hint(coverlet relies on process exits not a great way, we should move to a second strategy using shared memory). |
You can now use https://www.nuget.org/packages/dotnet-coverage global tool to collect coverage in this scenario. |
It would be great to run coverlet without any tests and collect code coverage for application. What I mean here is to for example having console application, instrument it and then start it (without any vstest or anything). When application finishes collect code coverage.
For example:
Let's assume we have app.exe and references of it ref1.dll and ref2.dll
It would be good to be able to
coverlet instrument app.exe ref1.dll ref2.dll
.\app.exe
It could also work in such way that during application execution it will be "logging" all hits to file:line (it could send it to some "monitor")
And after the process finishes it could generate code coverage report based on such data (by another coverlet produceReport data.txt). Such approach would also give possibility to get coverage report for particular time frame without need of process termination.
Such feature will give possibility to collect code coverage for:
The text was updated successfully, but these errors were encountered: