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

Avoid infinite sleep loop if multiple fork names come back from GitHub API #52

Merged
merged 3 commits into from
Jun 3, 2019

Conversation

VijayKumarMidde
Copy link
Contributor

@VijayKumarMidde VijayKumarMidde commented May 16, 2019

When we try to fork a repo and fail for some reason, we were still adding that repo to parentReposAlreadyChecked as it would help us to avoid trying to create a fork and failing multiple times, when we are updating multiple Dockerfiles in the same repository. But this is not completely correct as we add the (repo, dockerfile) first to pathToDockerfilesInParentRepo and then we check. Consider the following case:

If contentsWithImage is ['seanhuitest/helloworld-docker-child', 'vmidde/helloworld-docker-child', 'vmidde/helloworld-docker-child',]. In this case we have two Dockerfiles in vmidde/helloworld-docker-child repository which needs to be updated. Also assume that vmidde/helloworld-docker-child is unforkable.

In this case, when we first visit vmidde/helloworld-docker-child while iterating we add and remove vmidde/helloworld-docker-child from pathToDockerfilesInParentRepo. In the same iteration we also add vmidde/helloworld-docker-child to parentReposAlreadyChecked. When we visit vmidde/helloworld-docker-child for the second time, we first add vmidde/helloworld-docker-child to pathToDockerfilesInParentRepo and we never remove it because it is already checked in the previous iteration.

To fix this issue, I'm simply not adding a repo to parentReposAlreadyChecked if we are unable to fork the repo.

@coveralls
Copy link

coveralls commented May 16, 2019

Coverage Status

Coverage increased (+0.2%) to 71.812% when pulling ed42074 on VijayKumarMidde:master into a7878be on salesforce:master.

GHRepository fork = dockerfileGitHubUtil.closeOutdatedPullRequestAndFork(parent);
if (fork == null) {
log.info("Could not fork {}", parentRepoName);
pathToDockerfilesInParentRepo.remove(parentRepoName, c.getPath());
imagesFoundInParentRepo.remove(parentRepoName, image);
Copy link
Contributor

@justinharringa justinharringa May 16, 2019

Choose a reason for hiding this comment

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

This seems to be what really affects the logic. It seems like you reverted the name of parentReposAlreadyChecked as well as the comment here https://github.com/salesforce/dockerfile-image-update/pull/52/files#diff-850febb926ac48d58dc0962f42249092R118

Copy link
Contributor Author

@VijayKumarMidde VijayKumarMidde May 16, 2019

Choose a reason for hiding this comment

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

I'm not sure if I understand you completely. Are you saying with this fix, the logic is being affected?

Copy link
Contributor

Choose a reason for hiding this comment

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

@VijayKumarMidde I don't think renaming parentReposAlreadyChecked to parentReposForked or putting parentReposForked.add(parentRepoName) in the else has any effect. We also lost part of the comment: https://github.com/salesforce/dockerfile-image-update/pull/52/files#diff-850febb926ac48d58dc0962f42249092L118

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@justinharringa If you don't mind, can you please elaborate why you think putting parentReposForked.add(parentRepoName) in the else doesn't have any effect? Thanks!

Copy link
Contributor

Choose a reason for hiding this comment

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

It's not returned and doesn't modify anything that is passed in. What effect did it have moving it into the else?

Copy link
Contributor Author

@VijayKumarMidde VijayKumarMidde May 29, 2019

Choose a reason for hiding this comment

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

@afalko imagesFoundInParentRepo is passed as an empty Map to this function. This function was updating imagesFoundInParentRepo before these changes.

I think we can't use another form of Map with fork path as the key because in some cases we may need to update multiple Dockerfiles present in a repo.

Copy link
Contributor

Choose a reason for hiding this comment

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

@afalko seems like some of this should be refactored to remove duplication and move more towards immutable calls. I could see some of these things being pulled into first-class objects rather than passing around a bunch of MultiMaps but that might be a tall order for this PR? Definitely open to ideas though.

Copy link
Contributor

Choose a reason for hiding this comment

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

(part of what I meant to say was that the mutation of the MultiMap is something that has been here for a while and wasn't introduced by Vijay)

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yeh, maybe file an issue for that and move forward here

Copy link
Contributor

Choose a reason for hiding this comment

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

I opened #71

}

@Test
public void testForkRepositoriesFound_unableToforkRepo() throws Exception {
Copy link
Contributor

Choose a reason for hiding this comment

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

Please either add a comment on what this is testing. It seems like it would take some time to figure out what went wrong with this test if it started failing.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added comments.

@@ -109,6 +109,49 @@ public void testForkRepositoriesFound() throws Exception {
assertEquals(repoMap.size(), 3);
}

@Test
public void testForkRepositoriesFound_unableToforkRepo() throws Exception {
Copy link
Contributor

Choose a reason for hiding this comment

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

Same. What are we testing? What is the expected result here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added comments.

GHRepository contentRepo1 = mock(GHRepository.class);
when(contentRepo1.getFullName()).thenReturn("1");

GHRepository contentRepo2 = mock(GHRepository.class);
Copy link
Contributor

Choose a reason for hiding this comment

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

Better name for this? duplicateContentRepo1 maybe?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sounds good. I will update.

Copy link
Contributor

@justinharringa justinharringa left a comment

Choose a reason for hiding this comment

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

Awaiting simplification of logic (see comments)

@VijayKumarMidde
Copy link
Contributor Author

Awaiting simplification of logic (see comments)

Updated PR.

log.info("Forking {}", parentRepoName);
GHRepository fork = dockerfileGitHubUtil.closeOutdatedPullRequestAndFork(parent);
if (fork == null) {
if (fork != null) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you flip this to avoid negative conditionals?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@justinharringa Updated PR.

GHRepository fork = dockerfileGitHubUtil.closeOutdatedPullRequestAndFork(parent);
if (fork == null) {
if (fork != null) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you flip this to avoid negative conditionals?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@justinharringa Updated PR.

// fork the parent if not already forked or we couldn't fork
if (!parentReposAlreadyChecked.contains(parentRepoName)) {
// fork the parent if not already forked
if (!parentReposForked.contains(parentRepoName)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you make this a positive assertion?

Suggested change
if (!parentReposForked.contains(parentRepoName)) {
if (parentReposForked.contains(parentRepoName) == false) {

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@justinharringa Updated PR.

afalko
afalko previously approved these changes Jun 3, 2019
Copy link
Contributor

@justinharringa justinharringa left a comment

Choose a reason for hiding this comment

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

@justinharringa justinharringa changed the title Do not add a repo to parentReposForked if unable to fork Avoid infinite sleep loop if multiple fork names come back from GitHub API Jun 3, 2019
@justinharringa justinharringa merged commit a6e1ce7 into salesforce:master Jun 3, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants