Skip to content

KAFKA-9974: Fix flaky test by removing unneeded asserts#8646

Merged
guozhangwang merged 5 commits into
apache:trunkfrom
showuon:KAFKA-9974
Jun 16, 2020
Merged

KAFKA-9974: Fix flaky test by removing unneeded asserts#8646
guozhangwang merged 5 commits into
apache:trunkfrom
showuon:KAFKA-9974

Conversation

@showuon

@showuon showuon commented May 11, 2020

Copy link
Copy Markdown
Member

java.lang.AssertionError: Expected: is <0L> but: was <43L> at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20) at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:6) at org.apache.kafka.streams.integration.OptimizedKTableIntegrationTest.shouldApplyUpdatesToStandbyStore(OptimizedKTableIntegrationTest.java:138)

The tests failed at assertThat(listener.startOffset, is(equalTo(0L)));. It looks like that it did a restore before the assert. But we should expect the restore sometimes happen to resume the failed tasks by itself. It should not cause the test failure under this situation.

On the other hands, I checked the original tests in below PR link:
https://github.com/apache/kafka/pull/7238/files#diff-7b659da73450d5bf7a1731b5606e4c83R205
The original tests added the assertThat(listener.startOffset, is(equalTo(0L))); is because in the end of the test, we'll also test the startOffset value. But in the newer version of the test, we don't really care about the startOffset or totalNumRestored value. All we want to test in this test is:
Assert that the current value in store reflects all messages being processed

So, removing the assert can avoid flaky test failure, and also be able to test what the test case want to test.

Committer Checklist (excluded from commit message)

  • Verify design and implementation
  • Verify test coverage and CI build status
  • Verify documentation (including upgrade notes)

@showuon

showuon commented May 11, 2020

Copy link
Copy Markdown
Member Author

Hi @mjsax , could you please check this PR to fix a flaky test when available? Thanks.

@mjsax mjsax added streams tests Test fixes (including flaky tests) labels May 12, 2020
// Assert that no restore has occurred, ensures that when we check later that the restore
// notification actually came from after the rebalance.
assertThat(listener.startOffset, is(equalTo(0L)));
assertThat(listener.totalNumRestored, is(equalTo(0L)));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I am not sure if this is the right fix. Note that "restoring" and "standby task update" are two different things, and a standby task should. never use the "restore" code path what this assertion verifies.

What could explain a restore is the migration of the active task from one instance to the other. However, this should actually not happen either. Could you reproduce the issue locally? We recently worked on rebalancing so maybe the issue is with regard to that.

@showuon showuon May 21, 2020

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Sorry @mjsax , I tried to trace the code to find out why that would happen, but I still can't figure it out. Do you have any suggestion for it? If not, I think we can at least have more clear message output when this assert failure happen again. I'm not sure if the info is enough if the error happened again. And not sure if you have any thoughts about it?

It'll look like this when assert failure.
image

Thanks.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I am not 100% sure about the root cause of the issue... If you have a good suggestion for a better error message, that would be great. I have not idea how we could improve it atm.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think one possible explanation is that when we start the two instances, the rebalances took not just once but twice (once for the first instance, and another time for the second). In between the task may already be processed a bit on the first instance, and then after the second rebalance it was migrated and hence was restored a bit causing the listener to be triggered.

I'd agree with @showuon here that we do not need to strictly forbids restoration not happening when starting the first two instances, just making sure after closing one instance we can restore the other up to the first batch is enough (which is already validated). So I'm fine with removing this listener all together.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

BTW there's another report that line 159 can also fail:

java.lang.AssertionError: Expected: is <true> but: was <false> at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20) at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:6) at org.apache.kafka.streams.integration.OptimizedKTableIntegrationTest.shouldApplyUpdatesToStandbyStore(OptimizedKTableIntegrationTest.java:159)

Which is a bit mystery to me, since I cannot really think of a way how that could happen.

ANyways, for now removing that listener all together seems good to me.

@guozhangwang guozhangwang left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@showuon I did some analysis on the test case itself, left some comments.

// Assert that no restore has occurred, ensures that when we check later that the restore
// notification actually came from after the rebalance.
assertThat(listener.startOffset, is(equalTo(0L)));
assertThat(listener.totalNumRestored, is(equalTo(0L)));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think one possible explanation is that when we start the two instances, the rebalances took not just once but twice (once for the first instance, and another time for the second). In between the task may already be processed a bit on the first instance, and then after the second rebalance it was migrated and hence was restored a bit causing the listener to be triggered.

I'd agree with @showuon here that we do not need to strictly forbids restoration not happening when starting the first two instances, just making sure after closing one instance we can restore the other up to the first batch is enough (which is already validated). So I'm fine with removing this listener all together.

// Assert that no restore has occurred, ensures that when we check later that the restore
// notification actually came from after the rebalance.
assertThat(listener.startOffset, is(equalTo(0L)));
assertThat(listener.totalNumRestored, is(equalTo(0L)));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

BTW there's another report that line 159 can also fail:

java.lang.AssertionError: Expected: is <true> but: was <false> at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20) at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:6) at org.apache.kafka.streams.integration.OptimizedKTableIntegrationTest.shouldApplyUpdatesToStandbyStore(OptimizedKTableIntegrationTest.java:159)

Which is a bit mystery to me, since I cannot really think of a way how that could happen.

ANyways, for now removing that listener all together seems good to me.

@showuon

showuon commented Jun 15, 2020

Copy link
Copy Markdown
Member Author

Thanks for the suggestion, @guozhangwang , I've removed the listeners in this commit e82aa88. I agree we can fix it in this way first, and keep monitoring it. Thanks.

@guozhangwang

Copy link
Copy Markdown
Contributor

test this

@showuon

showuon commented Jun 16, 2020

Copy link
Copy Markdown
Member Author

JDK 8 and Scala 2.12
failed kafka.admin.ReassignPartitionsUnitTest.testModifyBrokerThrottles
--> traced in KAFKA-10155, PR: #8853

JDK 14 and Scala 2.13
failed org.apache.kafka.streams.integration.HighAvailabilityTaskAssignorIntegrationTest.shouldScaleOutWithWarmupTasksAndPersistentStores
--> passed locally
kafka.admin.ReassignPartitionsUnitTest.testModifyBrokerThrottles
--> traced in KAFKA-10155, PR: #8853

JDK 11 and Scala 2.13
org.apache.kafka.connect.mirror.MirrorConnectorsIntegrationTest.testReplication
--> passed locally
kafka.api.PlaintextConsumerTest.testLowMaxFetchSizeForRequestAndPartition
kafka.api.PlaintextConsumerTest.testLowMaxFetchSizeForRequestAndPartition
--> traced in KAFKA-8460 KAFKA-8264
kafka.admin.ReassignPartitionsUnitTest.testModifyBrokerThrottles
kafka.admin.ReassignPartitionsUnitTest.testModifyBrokerThrottles
--> traced in KAFKA-10155, PR: #8853

@guozhangwang

Copy link
Copy Markdown
Contributor

test this

1 similar comment
@guozhangwang

Copy link
Copy Markdown
Contributor

test this

@guozhangwang
guozhangwang merged commit e5bb535 into apache:trunk Jun 16, 2020
guozhangwang pushed a commit that referenced this pull request Jun 16, 2020
The tests failed at assertThat(listener.startOffset, is(equalTo(0L)));. It looks like that it did a restore before the assert. But we should expect the restore sometimes happen to resume the failed tasks by itself. It should not cause the test failure under this situation.

On the other hands, the original tests added the assertThat(listener.startOffset, is(equalTo(0L))); is because in the end of the test, we'll also test the startOffset value. But in the newer version of the test, we don't really care about the startOffset or totalNumRestored value. All we want to test in this test is:
Assert that the current value in store reflects all messages being processed

So, removing the assert can avoid flaky test failure, and also be able to test what the test case want to test.

Reviewers: Matthias J. Sax <matthias@confluent.io>, Guozhang Wang <wangguoz@gmail.com>
@guozhangwang

Copy link
Copy Markdown
Contributor

Cherry-picked to 2.6.

Kvicii pushed a commit to Kvicii/kafka that referenced this pull request Jun 17, 2020
* 'trunk' of github.com:apache/kafka:
  KAFKA-10150: task state transitions/management and committing cleanup (apache#8856)
  KAFKA-10169: Error message when transit to Aborting / AbortableError / FatalError (apache#8880)
  KAFKA-9974: Fix flaky test by removing unneeded asserts (apache#8646)
  MINOR: Documentation for KIP-585 (apache#8839)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

streams tests Test fixes (including flaky tests)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants