Conversation
| _, | ||
| _, | ||
| _, | ||
| _, |
There was a problem hiding this comment.
@pmj I asked this on IM but if I stick
reinterpret_cast<int*>(KAUTH_RESULT_DEFER),
in this parameter I get a failure. I'm guessing ref compare instead of value compare.
How do you think we should handle this?
There was a problem hiding this comment.
Are you trying to check the input value or simulate setting the output parameter?
Neither is currently supported, and I'm not sure what syntax would really work for this type of thing. The best I can think of is to put the check or output parameter setting straight in the mock function itself.
There was a problem hiding this comment.
@pmj that makes sense. I'm not sure we need the to test for that value explicitly since we validated the message was sent. What do you think?
We can certainly test it in the mock if absolutely necessary.
|
/azp run GitHub VFSForGit Mac Functional Tests |
|
No pipelines are associated with this pull request. |
055ddf9 to
0b3e215
Compare
|
|
||
| int proc_rele(proc_t p) | ||
| { | ||
| return 1; |
There was a problem hiding this comment.
Why did you decide to return 1 here for proc_rele?
There was a problem hiding this comment.
Any number will actually due since we don't test the result in code.
The results here will seem a bit odd, but hopefully make a lot more sense when we unit tests CurrentProcessWasSpawnedByRegularUser.
| struct PlaceholderValue | ||
| {}; | ||
|
|
||
| extern PlaceholderValue _; |
There was a problem hiding this comment.
Could you add a comment here describing what PlaceholderValue and _ are for and when to use them?
There was a problem hiding this comment.
Sure, that commit was thrown together as quickly as possible so that @jeschu1 had something to work with, I think there are a few things there that could be improved. I'll try and get that done soon.
There was a problem hiding this comment.
Apologies for bringing this up again, but could you add a few more details (and possibly rename PlaceholderValue)? Someone new to the code might think that PlaceholderValue is related to file placeholders based on its name.
Maybe something like:
namespace KextMock
{
struct ParameterPlaceholderValue
{};
// Matches with any parameter value
// ParameterPlaceholderValue can be used:
// - When calling kext functions, for parameters values that do not matter to the test
// - When checking if a function was called (i.e. DidCallFunction). ParameterPlaceholderValue is
// a match for all parameter values.
extern ParameterPlaceholderValue _;
There was a problem hiding this comment.
Updating with suggested comment
| } | ||
| } | ||
|
|
||
| -(void) testWriteFile { |
There was a problem hiding this comment.
Minor naming suggestion:
If the some of the more generic test names were slightly more detailed it might make it easier to find test(s) of interest when looking for specific coverage:
Examples
testWriteFile->testWriteDataVnodeOpEmptyFiletestWriteFileFull->testWriteDataVnodeOpFullFile
What got me thinking about this was when I read the implementation of testWriteFileFull I was surprised to see that it wasn't checking that the MessageType_KtoU_NotifyFileModified message was sent. After realizing that these first tests were only for vnode operations it made sense, but it got me wondering if the test names should include VnodeOp or FileOp (or perhaps the tests should be in different classes?).
There was a problem hiding this comment.
This is a good point. I haven't fully decided on seperate files or the same files for both types. My plan is to revisit decision when I go full force on FileOp tests (seperate PR). Hence for now I'd like to punt the naming to a future (but not distance future PR).
| _, | ||
| _, | ||
| _)); | ||
| } |
There was a problem hiding this comment.
Could we check nextCallSequenceNumber to ensure that the above callback was the only callback called (and that it was only called once)?
| } | ||
|
|
||
| - (void) testOpenInVirtualizationRoot { | ||
| // A file that is already in the virtual root, should not recieve a creation request |
There was a problem hiding this comment.
This comment doesn't quite match the code (now that we have the more generic XCTAssertFalse(MockCalls::DidCallFunction(ProviderMessaging_TrySendRequestAndWaitForResponse)) check), maybe update it to something like:
// KAUTH_FILEOP_OPEN should not trigger any callbacks for files that are already flagged as in the virtualization root.
There was a problem hiding this comment.
I see this comment was marked as resolved, but it looks like the comment was not updated.
There was a problem hiding this comment.
Cause I put the comment on the wrong place. I'm updated with 2 superior comments.
pmj
left a comment
There was a problem hiding this comment.
I've just checked the "real" implementation, and it seems kauthResult is effectively an output parameter, so the mock version should definitely write to it. kauthError is in/out, only some code paths write to it, and it can be assumed the caller already initialised it.
| struct PlaceholderValue | ||
| {}; | ||
|
|
||
| extern PlaceholderValue _; |
There was a problem hiding this comment.
Apologies for bringing this up again, but could you add a few more details (and possibly rename PlaceholderValue)? Someone new to the code might think that PlaceholderValue is related to file placeholders based on its name.
Maybe something like:
namespace KextMock
{
struct ParameterPlaceholderValue
{};
// Matches with any parameter value
// ParameterPlaceholderValue can be used:
// - When calling kext functions, for parameters values that do not matter to the test
// - When checking if a function was called (i.e. DidCallFunction). ParameterPlaceholderValue is
// a match for all parameter values.
extern ParameterPlaceholderValue _;
| } | ||
|
|
||
| - (void) testOpenInVirtualizationRoot { | ||
| // A file that is already in the virtual root, should not recieve a creation request |
There was a problem hiding this comment.
I see this comment was marked as resolved, but it looks like the comment was not updated.
| _, | ||
| _, | ||
| nullptr)); | ||
| XCTAssertTrue( |
There was a problem hiding this comment.
If the callSequenceNumber work is planned for a follow up PR, could you file a work item for it?
|
|
||
| // Allow any value to match | ||
| // Matches with any parameter value | ||
| // ParameterPlaceholderValue can be used: |
There was a problem hiding this comment.
Unless you're renaming the class to ParameterPlaceholderValue all of the ParameterPlaceholderValue in the comment should be replaced with PlaceholderValue.
| { | ||
| int callCount = 0; | ||
| std::pair<typename RecordedCallMap::const_iterator, typename RecordedCallMap::const_iterator> foundCalls = this->recordedCalls.equal_range(function); | ||
| for (typename RecordedCallMap::const_iterator foundCall = foundCalls.first; foundCall != foundCalls.second; ++foundCall) |
There was a problem hiding this comment.
Rather than writing the loop yourself you can use std::distance to get the count:
return distance(foundCalls.first, foundCalls.second);
| int SpecificFunctionCallRecorder<R, ARGS...>::CallCount(FunctionPointerType function) | ||
| { | ||
| int callCount = 0; | ||
| std::pair<typename RecordedCallMap::const_iterator, typename RecordedCallMap::const_iterator> foundCalls = this->recordedCalls.equal_range(function); |
There was a problem hiding this comment.
I know some of my code has declarations like this as well, but I'm thinking it's less readable than auto at this point. We don't have to go for auto, there are a few in-between options which I think would also be preferable over the status quo:
- I think the latest C++ standard allows partial type declarations, so in this case, I believe
std::pair foundCalls = …;should work. This at least makes it obvious we're getting apair- and pretty much all operations on STL containers return iterators in some form, so not spelling those out in detail seems sensible. - Locally Typedef'ing the iterator type to something much shorter.
There was a problem hiding this comment.
I think the latest C++ standard allows partial type declarations, so in this case, I believe std::pair foundCalls = …; should work. This at least makes it obvious we're getting a pair - and pretty much all operations on STL containers return iterators in some form, so not spelling those out in detail seems sensible.
Cool I did not know about this feature 👍
I know some of my code has declarations like this as well, but I'm thinking it's less readable than auto at this point.
I agree on this point, and template programming is one spot where things can get messy without auto.
If the above approach does not work out I'm good with using auto here with some descriptive variable names.
This incorporates
Also highlighting two areas we should unit test in the future