-
Notifications
You must be signed in to change notification settings - Fork 4.5k
[BEAM-670] BigQueryServicesImpl: fix issues in insertAll and add better tests #1018
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
Conversation
| * Tests that {@link DatasetServiceImpl#insertAll} fails gracefully when persistent issues. | ||
| */ | ||
| @Test | ||
| public void testInsertFailsGracefully() throws Exception { |
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.
this is the test that catches the issue with reusing the backoff multiple times instead of using the cached nextBackoffMillis.
| } | ||
| try { | ||
| Thread.sleep(backoff.nextBackOffMillis()); | ||
| Thread.sleep(nextBackoffMillis); |
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.
Pass in a sleeper so that the tests don't actually call Thread.sleep
| when(response.getContentType()).thenReturn(Json.MEDIA_TYPE); | ||
| when(response.getStatusCode()).thenReturn(200).thenReturn(200); | ||
| when(response.getContent()) | ||
| .thenAnswer(new Answer<InputStream>() { |
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.
You can chain thenReturn calls and verify response.getContent is only called twice.
So:
thenReturn(toStream(bFailed).thenReturn(toStream(allRowsSucceeded));
| expectedLogs.verifyInfo("Retrying 1 failed inserts to BigQuery"); | ||
| } | ||
|
|
||
| // A very-short BackOff to use in tests. |
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.
Really, you want to mock/fake out the sleeper, check out FastNanoClockAndSleeper
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 using MockSleeper -- FastNanoClockAndSleeper seems overkill
|
|
||
| when(response.getContentType()).thenReturn(Json.MEDIA_TYPE); | ||
| when(response.getStatusCode()).thenReturn(200); | ||
| when(response.getContent()).thenAnswer(new Answer<InputStream>() { |
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.
ditto on using chained thenReturn
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
|
PTAL |
lukecwik
left a 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.
Minor comment and then LGTM
| // Return row 1 failing, then we retry row 1 as row 0, and row 0 persistently fails. | ||
| when(response.getContent()) | ||
| .thenReturn(toStream(row1Failed)) | ||
| .thenReturn(toStream(row0Failed)) |
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.
Whatever the last thenReturn is used will be used for all subsequent calls so no point in repeating .thenReturn(toStream(row0Failed)) 3 times.
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.
InputStream is not reusable, so can't reuse last value returned.
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.
As discussed, the multiple thenReturns are because the input is consumed since its an InputStream
| verify(response, times(2)).getStatusCode(); | ||
| verify(response, times(2)).getContent(); | ||
| verify(response, times(2)).getContentType(); | ||
| expectedLogs.verifyInfo("Retrying 1 failed inserts to BigQuery"); |
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.
Ah you are verifying this through log message. I was trying to verify this through a mock of the BQ client req/response and that was not as easy.
|
LGTM |
|
Travis is a flake (3/4 passed, 4th went into never land), Jenkins passed. Merging. |
| return toStream(row0Failed); | ||
| } | ||
| }); | ||
|
|
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.
remove extraneous new line
R: @lukecwik
CC: @vikkyrk