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

GuardDog: Test: Fix race in mocked time source. #719

Merged
merged 4 commits into from
Apr 8, 2017

Conversation

dnoe
Copy link
Contributor

@dnoe dnoe commented Apr 7, 2017

The guard dog test made additional EXPECT_CALLs to update the time the
mocked time source should return after the mocked object was passed to
the GD thread. Doing additional EXPECT_CALLs in this way is NOT thread
safe and resulted in 0.5-1% of tests failing when many were executed in
parallel.

The solution is to make the expect call action be to invoke a lambda
that shares access to a safe atomic updated in the main test thread.

The guard dog test made additional EXPECT_CALLs to update the time the
mocked time source should return after the mocked object was passed to
the GD thread.  Doing additional EXPECT_CALLs in this way is NOT thread
safe and resulted in 0.5-1% of tests failing when many were executed in
parallel.

The solution is to make the expect call action be to invoke a lambda
that shares access to a safe atomic updated in the main test thread.

/**
* This does everything but the final forceCheckForTest() that should cause
* death for the single kill case.
*/
void SetupForDeath() {
InSequence s;
EXPECT_CALL(time_source_, currentSystemTime()).WillRepeatedly(testing::Return(time_point_));
EXPECT_CALL(time_source_, currentSystemTime())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: EXPECT_CALL() with WillRepeatedly is an anti-pattern in that it doesn't actually expect anything since 0 times will pass. I would make this ON_CALL(...).WillByDefault(...). (Same for all below).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could also likely move this into fixture constructor to avoid duplication.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, I'll fix this.

: config_kill_(1000, 1000, 100, 1000), config_multikill_(1000, 1000, 1000, 500) {}

void SetupMockTimeSource() {
ON_CALL(time_source_, currentSystemTime())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just put this directly in constructor, then you don't have to call from each test.

};

TEST_F(GuardDogMissTest, MissTest) {
// This test checks the actual collected statistics after doing some timer
// advances that should and shouldn't increment the counters.
EXPECT_CALL(time_source_, currentSystemTime()).WillRepeatedly(testing::Return(time_point_));
ON_CALL(time_source_, currentSystemTime())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should go in constructor of GuardDogMissTest

Copy link
Member

@htuch htuch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. @mattklein123 SIGILL due to corrupted vtable or however gmock is doing its mocking?

@dnoe
Copy link
Contributor Author

dnoe commented Apr 7, 2017

That's my guess. Consider this sequence:

  1. Initial EXPECT_CALL sets up mock time source object for call to get the beginning-of-test time value
  2. GuardDogImpl object is constructed. Thread is launched and it starts to run.
  3. Meanwhile in the test main thread the EXPECT_CALL to update to the "later" time state is executed

If step 2 begins executing before the loop reaches the call to currentSystemTime() then it will be following a wild address when calling currentSystemTime().

@mattklein123
Copy link
Member

Beyond this change I also think that #717 was involved in odd crashes.

@mattklein123 mattklein123 merged commit 96edf4f into envoyproxy:master Apr 8, 2017
rshriram pushed a commit to rshriram/envoy that referenced this pull request Oct 30, 2018
* Strip out "spiffe://" in the identity

* Addressed some review comments.

* Addressed review comments.
rshriram pushed a commit to rshriram/envoy that referenced this pull request Oct 30, 2018
* Revert "Strip out "spiffe://" in the identity (envoyproxy#719)"

This reverts commit 99a482f.

* Revert "Revert "Remove -release in filename when doing release build of proxy (envoyproxy#704)" (envoyproxy#723)"

This reverts commit 13669ce.

* Revert "Not to send legacy quota for v2 config. (envoyproxy#722)"

This reverts commit aaf25ca.
nezdolik pushed a commit to nezdolik/envoy that referenced this pull request May 4, 2024
Like _free_base, _free_dbg is called by CRT internal functions or
operator delete in Debug mode.

This closes envoyproxy#719 and closes envoyproxy#894.

[alkondratenko@gmail.com: trivial formatting fixes]
[alkondratenko@gmail.com: build free_dbg even in release builds]
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

Successfully merging this pull request may close these issues.

None yet

3 participants