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

Create a custom DataCollector to gather the data from the test run #269

Open
GeorchW opened this issue Jun 9, 2020 · 2 comments
Open

Create a custom DataCollector to gather the data from the test run #269

GeorchW opened this issue Jun 9, 2020 · 2 comments

Comments

@GeorchW
Copy link
Contributor

GeorchW commented Jun 9, 2020

We regularly have issues with the TRX format, which isn't standardized or stable, and returns all test results at once (instead of streaming them in as the tests finish). Using vstest directly has already been tried in #83, with the disadvantage of introducing a lot of additional complexity (+8k LOC).

However, looking at the docs I think that adding only a custom DataCollector, as described here that serves exactly our needs can be done in maybe a hundred lines of C# code.

For context:

  • The DataCollector API provides some events that are being invoked whenever a test is started/finished/... We just need to subclass it and add some handlers.
  • A DataCollector can be added by extending the command line of dotnet test slightly. The documentation linked above suggests something like
    /collect:"MyDataCollector" /testadapterpath:<Path to MyDataCollector assembly>

The extension could provide a TCP listener to accept the results. They could directly be written as JSON on the DataCollector side, removing the need for an own parser on our side (while still being type-safe thanks to TypeScript's Interfaces).

All in all, I believe that this approach could increase the reliability of the extension while not adding much complexity. I'm just writing this down here to sort my thoughts on it and to enable @stefanforsberg to insert additional ones :-)

@stefanforsberg
Copy link
Collaborator

This looks interesting. A few thought at the top of my head:

  1. How would we distribute the required assembly (that contains our data collector)
  2. Isn't there risk of the underlying behavior changing making our assembly having to update to changes in how the data collecting is performed? Ie, more or less the same situation we are in now?
    3: When you say TCP listener do you mean the language server path?

@GeorchW
Copy link
Contributor Author

GeorchW commented Jun 9, 2020

To your points:

  1. Pretty much the same as we distribute all the other assets. We'll just add a dotnet publish command to the compile command, then distribute the resulting folder along with the rest of the extension. Since the resulting DLL builds on top of .NET Standard 2.0, it should run on pretty much any future version of dotnet.
  2. In principle, yes, but:
    1. We're using the same APIs that VSTest uses internally. It's much less likely for VSTest to change their entire API (and all the tools that they built around it) than it is for them to change a single logger. Basically, we're "closer to the core".
    2. The API surface that we use is smaller. We don't rely on the structure of an XML file, and instead just register on the events that are interesting to us.
    3. If the API is changed, the errors are more obvious to us, since the changes result in mis-matching types. This makes adapting on our side much easier.
  3. No, I mean a straightforward shiny new TCP listener. TCP is a nice way of IPC for small amounts of data (as present in our case), since it works exactly the same on all platforms. When a listener listens on localhost, it is not reachable from the network, and when giving 0 as a port, the OS provides a port for us. We can then give this port to the DataCollector e.g. through an environment variable, to allow the DataCollector to talk back to the extension in "real time" - i.e. each test result can immediately be displayed in the tree, without the need to write a file.
    I've had a similar setup in another project previously; it's a little bit of work to set up, but once it's done it really works like a charm. In that project we had people using Mac, Linux and Windows, but no issues on the IPC.
    (This is not something I've invented, many applications doing IPC use TCP.)

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

No branches or pull requests

2 participants