-
Notifications
You must be signed in to change notification settings - Fork 389
SystemIOFile Adapter #550
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
SystemIOFile Adapter #550
Conversation
update fork
Update fork
Update fork
Update fork
I think you need to align to master yesterday I changed one behaviour of logs and amended tests #548 |
@daveMueller for the moment I would avoid to update collectors code, because could live alone(I mean the infrastructure to load coverage core), so could you revert all changes under |
{ | ||
_logger.LogError("Result of instrumentation task not found"); | ||
return false; | ||
} | ||
|
||
var coverage = new Coverage(CoveragePrepareResult.Deserialize(new FileStream(InstrumenterState.ItemSpec, FileMode.Open)), this._logger, (IInstrumentationHelper)DependencyInjection.Current.GetService(typeof(IInstrumentationHelper))); | ||
var coverage = new Coverage(CoveragePrepareResult.Deserialize(new FileStream(InstrumenterState.ItemSpec, FileMode.Open)), this._logger, (IInstrumentationHelper)DependencyInjection.Current.GetService(typeof(IInstrumentationHelper)), fileSystem); |
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 not also for new FileStream(InstrumenterState.ItemSpec, FileMode.Open)
?
And we should surround by a using
to close handle asap(my past error).
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.
Done
@@ -30,7 +30,7 @@ public void TestCoverage() | |||
|
|||
// TODO: Find a way to mimick hits | |||
|
|||
var coverage = new Coverage(Path.Combine(directory.FullName, Path.GetFileName(module)), Array.Empty<string>(), Array.Empty<string>(), Array.Empty<string>(), Array.Empty<string>(), Array.Empty<string>(), false, false, string.Empty, false, _mockLogger.Object, _instrumentationHelper); | |||
var coverage = new Coverage(Path.Combine(directory.FullName, Path.GetFileName(module)), Array.Empty<string>(), Array.Empty<string>(), Array.Empty<string>(), Array.Empty<string>(), Array.Empty<string>(), false, false, string.Empty, false, _mockLogger.Object, new Mock<IFileSystem>().Object, _instrumentationHelper); |
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.
move mock instantiation of mock under private readonly Mock<ILogger> _mockLogger = new Mock<ILogger>();
and reuse
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.
Done
|
||
Stream OpenRead(string path); | ||
|
||
void Copy(string sourceFileName, string destFileName); |
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?Where is used?
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.
Sorry this was used in the coverlet.collector
and I missed to revert it.
{ | ||
_logger.LogError("Result of instrumentation task not found"); | ||
return false; | ||
} | ||
|
||
var coverage = new Coverage(CoveragePrepareResult.Deserialize(new FileStream(InstrumenterState.ItemSpec, FileMode.Open)), this._logger, (IInstrumentationHelper)DependencyInjection.Current.GetService(typeof(IInstrumentationHelper))); | ||
var coverage = new Coverage(CoveragePrepareResult.Deserialize(new FileStream(InstrumenterState.ItemSpec, FileMode.Open)), this._logger, fileSystem, (IInstrumentationHelper)DependencyInjection.Current.GetService(typeof(IInstrumentationHelper))); |
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.
also for new FileStream(InstrumenterState.ItemSpec, FileMode.Open)
and surround by using please(my past error)
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 I changed it but I don't know how to surround this by a using.
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.
something like
Coverage coverage = null;
using(Stream instrumenterStateStream = fileSystem.NewFileStream(InstrumenterState.ItemSpec, FileMode.Open))
{
coverage = new Coverage(CoveragePrepareResult.Deserialize(instrumenterStateStream), this._logger, fileSystem,...
}
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.
Done
_logger, | ||
(IFileSystem) DependencyInjection.Current.GetService(typeof(IFileSystem)), | ||
(IInstrumentationHelper) DependencyInjection.Current.GetService(typeof(IInstrumentationHelper))); | ||
|
||
CoveragePrepareResult prepareResult = coverage.PrepareModules(); | ||
InstrumenterState = new TaskItem(System.IO.Path.GetTempFileName()); | ||
using (var instrumentedStateFile = new FileStream(InstrumenterState.ItemSpec, FileMode.Open, FileAccess.Write)) |
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.
also for new FileStream(InstrumenterState.ItemSpec, FileMode.Open, FileAccess.Write)
and surround by using please(my past error)
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.
Done
string coverletLib = Directory.GetFiles(Directory.GetCurrentDirectory(), "coverlet.core.dll").First(); | ||
var instrumentationHelperMock = new Mock<IInstrumentationHelper>(); |
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 you've changed this test?
Here I want to test InstrumentationHelper
logic and I have to mock only file system to simulate "file not found".
Revert please.
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 don't exactly know what you mean or how I can make this test run again by only mocking the FileSystem. When I revert the test to how it was before the test fails. This is because I now also use the FileSystem adapter for the streams. Thus I also must setup e.g. _fileSystem.OpenRead()
....
And wouldn't it be better to test the InstrumentationHelper
logic in the class InstrumentationHelperTests
.
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.
And wouldn't it be better to test the InstrumentationHelper logic in the class InstrumentationHelperTests.
Here we have a bit of integration...I mean we need to test the interaction between InstrumentationHelper and Instrumenter.
You should do partial mock of concrete implementation and redefine only Exists
something like
https://stackoverflow.com/questions/4769928/using-moq-to-mock-only-some-methods
var mock = new Mock<YourTestClass>();
mock.CallBase = true;
mock.Setup(x => x.GetCurrentUser()).Returns(lUnauthorizedUser);
mockedTest.Object.MyMethod();
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 this test we need to simulate to find pdb file but return false when we try to understand if sources are present on local hard drive, so we did it with coverlet.core.dll
to avoid new dependency and we need to return false also if we have sources in local.
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 done. Thanks for the information with the partial mock. 👍
@daveMueller because you added two new constructor to
These two constructor accept different set of parameters but both use file system, so we need only to pass new service. |
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.
These two constructor accept different set of parameters but both use file system, so we need only to pass new service.
Yes sorry. I felt really ashamed when I saw your commit this morning. I was probably way to tired yesterday night. Sorry.
You don't have to apologize, you're great contributor!We're all human and happen also to me when I work in the night...actually also in the morning 😄 YOUR HELP HERE IS VERY WELCOME! |
@@ -136,7 +136,9 @@ public InstrumenterResult Instrument() | |||
|
|||
private void InstrumentModule() | |||
{ | |||
using (var stream = new FileStream(_module, FileMode.Open, FileAccess.ReadWrite)) | |||
var fileSystem = (IFileSystem)DependencyInjection.Current.GetService(typeof(IFileSystem)); |
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.
We shoud avoid DependencyInjection
reference in code...we need to inject throught contructor and update al callers.
The idea is to have testabililty and the possibility to "change every implementation" also for DependencyInjection
(the container).
So the principle here is to have a "container" where we register dependences, and in our case is DependencyInjection
class.
And we inject every dependence in constructors...the only place where we directly use DependencyInjection class is when we don't have an "instance", but we removed all statics for this reason(testability).
DependencyInjection is only the place where we chose the implementation and keep them aligned in every driver(collector, msbuild, console).
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.
Done
@@ -72,6 +73,8 @@ public static void RecordSingleHit(int hitLocationIndex) | |||
|
|||
public static void UnloadModule(object sender, EventArgs e) | |||
{ | |||
var fileSystem = (IFileSystem)DependencyInjection.Current.GetService(typeof(IFileSystem)); |
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.
Revert update in this file please.
This is a key piece of instrumentation, this class is injected inside users dll so we have to try to pollute less possible and use "runtime" only class.
In this case is not a problem..I mean core lib and instrumented lib are in same directory so we don't have issue with load...but I don't know how this evolve in future so I prefer keep this class(tracker) "light".
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.
FYI I'm trying to get logs also for it #553
And the idea si to enable instrumentation throught enviroment variables, this is the only static part needed today.
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 done, reverted the changes.
{ | ||
_logger.LogError("Result of instrumentation task not found"); | ||
return false; | ||
} | ||
|
||
var coverage = new Coverage(CoveragePrepareResult.Deserialize(new FileStream(InstrumenterState.ItemSpec, FileMode.Open)), this._logger, (IInstrumentationHelper)DependencyInjection.Current.GetService(typeof(IInstrumentationHelper))); | ||
var coverage = new Coverage( |
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.
format inline please here the contructor parameter is not so bad, I mean keep old formatting 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.
Done
src/coverlet.core/Coverage.cs
Outdated
_instrumentationHelper = instrumentationHelper; | ||
|
||
_identifier = Guid.NewGuid().ToString(); | ||
_results = new List<InstrumenterResult>(); | ||
} | ||
|
||
public Coverage(CoveragePrepareResult prepareResult, ILogger logger, IInstrumentationHelper instrumentationHelper) | ||
public Coverage(CoveragePrepareResult prepareResult, ILogger logger, IFileSystem fileSystem, IInstrumentationHelper instrumentationHelper) |
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.
please keep IFileSystem
as last parameter we'll add new service at the end of the signature as a rule of thumb
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.
Done
Coverage coverage = null; | ||
using (Stream instrumenterStateStream = fileSystem.NewFileStream(InstrumenterState.ItemSpec, FileMode.Open)) | ||
{ | ||
coverage = new Coverage(CoveragePrepareResult.Deserialize(instrumenterStateStream), this._logger, fileSystem, (IInstrumentationHelper)DependencyInjection.Current.GetService(typeof(IInstrumentationHelper))); |
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.
file system service for last param due to above comment
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.
Done
@@ -30,7 +31,7 @@ public void TestCoverage() | |||
|
|||
// TODO: Find a way to mimick hits | |||
|
|||
var coverage = new Coverage(Path.Combine(directory.FullName, Path.GetFileName(module)), Array.Empty<string>(), Array.Empty<string>(), Array.Empty<string>(), Array.Empty<string>(), Array.Empty<string>(), false, false, string.Empty, false, _mockLogger.Object, _instrumentationHelper); | |||
var coverage = new Coverage(Path.Combine(directory.FullName, Path.GetFileName(module)), Array.Empty<string>(), Array.Empty<string>(), Array.Empty<string>(), Array.Empty<string>(), Array.Empty<string>(), false, false, string.Empty, false, _mockLogger.Object, _mockFileSystem.Object, _instrumentationHelper); |
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.
fix constructors param order here and below
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.
Done
InstrumentationHelper instrumentationHelper = new InstrumentationHelper(new ProcessExitHandler(), new RetryHelper(), mockFileSystem.Object); | ||
Mock<FileSystem> partialMockFileSystem = new Mock<FileSystem>(); | ||
partialMockFileSystem.CallBase = true; | ||
partialMockFileSystem.Setup(fs => fs.Exists(It.IsAny<string>())).Returns((string path) => |
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.
well done!
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.
LGTM Thank's Dave!
closes #543