/src/test/java/com/atlassian/bamboo/plugins/git/GitCacheDirectoryTest.java

https://bitbucket.org/andsliz/bamboo-git-plugin · Java · 209 lines · 175 code · 34 blank · 0 comment · 2 complexity · 8f3934fd4225138d6626c06dfb3bcbc1 MD5 · raw file

  1. package com.atlassian.bamboo.plugins.git;
  2. import com.atlassian.bamboo.plan.branch.VcsBranch;
  3. import com.atlassian.bamboo.plan.branch.VcsBranchImpl;
  4. import org.testng.Assert;
  5. import org.testng.annotations.DataProvider;
  6. import org.testng.annotations.Test;
  7. import java.io.File;
  8. import java.lang.reflect.Field;
  9. import java.util.concurrent.ArrayBlockingQueue;
  10. import java.util.concurrent.Callable;
  11. import java.util.concurrent.CountDownLatch;
  12. import java.util.concurrent.TimeUnit;
  13. public class GitCacheDirectoryTest extends GitAbstractTest
  14. {
  15. @DataProvider
  16. Object[][] fieldInfluenceOnCacheLocationNonShallow()
  17. {
  18. return new Object[][] {
  19. {"repositoryUrl", true, null},
  20. {"username", true, null},
  21. {"branch", false, VcsBranch.class},
  22. {"password", false, null},
  23. {"sshKey", false, null},
  24. {"sshPassphrase", false, null},
  25. };
  26. }
  27. @Test(dataProvider = "fieldInfluenceOnCacheLocationNonShallow")
  28. public void testFieldInfluenceOnCacheLocatonNonShallow(final String field, final boolean different, final Class<?> clazz) throws Exception
  29. {
  30. doTestFieldInfluenceOnCacheLocaton(field, false, different, clazz);
  31. }
  32. @DataProvider
  33. Object[][] fieldInfluenceOnCacheLocationShallow()
  34. {
  35. return new Object[][] {
  36. {"repositoryUrl", true, null},
  37. {"username", true, null},
  38. {"branch", true, VcsBranch.class},
  39. {"password", false, null},
  40. {"sshKey", false, null},
  41. {"sshPassphrase", false, null},
  42. };
  43. }
  44. @Test(dataProvider = "fieldInfluenceOnCacheLocationShallow")
  45. public void testFieldInfluenceOnCacheLocatonShallow(String field, boolean different, final Class<?> clazz) throws Exception
  46. {
  47. doTestFieldInfluenceOnCacheLocaton(field, true, different, clazz);
  48. }
  49. private void doTestFieldInfluenceOnCacheLocaton(String field, boolean shallow, boolean different, Class<?> clazz) throws Exception
  50. {
  51. GitRepositoryAccessData accessData = createSampleAccessData(shallow);
  52. GitRepositoryAccessData accessData2 = createSampleAccessData(shallow);
  53. Field f = GitRepositoryAccessData.class.getDeclaredField(field);
  54. f.setAccessible(true);
  55. String val = f.get(accessData2).toString();
  56. if (clazz!=null && VcsBranch.class.isAssignableFrom(clazz))
  57. {
  58. f.set(accessData2, new VcsBranchImpl(val + "chg"));
  59. }
  60. else
  61. {
  62. f.set(accessData2, val + "chg");
  63. }
  64. File baseDir = createTempDirectory();
  65. File cache1 = GitCacheDirectory.getCacheDirectory(baseDir, accessData);
  66. File cache2 = GitCacheDirectory.getCacheDirectory(baseDir, accessData2);
  67. Assert.assertEquals(cache1.equals(cache2), !different);
  68. }
  69. @Test
  70. public void testShallowGetsDifferentCache() throws Exception
  71. {
  72. GitRepositoryAccessData accessData = createSampleAccessData(false);
  73. GitRepositoryAccessData accessData2 = createSampleAccessData(true);
  74. File baseDir = createTempDirectory();
  75. File cache1 = GitCacheDirectory.getCacheDirectory(baseDir, accessData);
  76. File cache2 = GitCacheDirectory.getCacheDirectory(baseDir, accessData2);
  77. Assert.assertFalse(cache1.equals(cache2));
  78. }
  79. @Test
  80. public void testShallowGetsDifferentCacheWithEmptyBranch() throws Exception
  81. {
  82. GitRepositoryAccessData accessDataNonShallow = createSampleAccessData(false);
  83. GitRepositoryAccessData accessDataShallow = createSampleAccessData(true);
  84. accessDataNonShallow = GitRepositoryAccessData.builder(accessDataNonShallow).branch(new VcsBranchImpl("")).build();
  85. accessDataShallow = GitRepositoryAccessData.builder(accessDataShallow).branch(new VcsBranchImpl("")).build();
  86. File baseDir = createTempDirectory();
  87. File cache1 = GitCacheDirectory.getCacheDirectory(baseDir, accessDataNonShallow);
  88. File cache2 = GitCacheDirectory.getCacheDirectory(baseDir, accessDataShallow);
  89. Assert.assertFalse(cache1.equals(cache2));
  90. }
  91. private static GitRepositoryAccessData createSampleAccessData(boolean shallow)
  92. {
  93. GitRepositoryAccessData accessData = createAccessData(
  94. "someUrl",
  95. "branch",
  96. "username",
  97. "password",
  98. "sshKey",
  99. "sshPass"
  100. );
  101. return GitRepositoryAccessData.builder(accessData).useShallowClones(shallow).build();
  102. }
  103. @Test(timeOut = 5000)
  104. public void testCallOnSameDirectoryBlocks() throws Exception
  105. {
  106. verifySecondThreadBlocks("repository.url", "repository.url", true);
  107. }
  108. @Test(timeOut = 5000)
  109. public void testCallOnDifferentDirectoryDoesNotBlock() throws Exception
  110. {
  111. verifySecondThreadBlocks("repository.url", "different.url", false);
  112. }
  113. private void verifySecondThreadBlocks(String firstUrl, String secondUrl, boolean blockExpected) throws Exception
  114. {
  115. final GitRepository repository1 = createGitRepository();
  116. setRepositoryProperties(repository1, firstUrl, "");
  117. final GitRepository repository2 = createGitRepository();
  118. repository2.setWorkingDir(repository1.getWorkingDirectory());
  119. setRepositoryProperties(repository2, secondUrl, "");
  120. final ArrayBlockingQueue<Boolean> hasBlocked = new ArrayBlockingQueue<Boolean>(1);
  121. final CountDownLatch firstCalled = new CountDownLatch(1);
  122. final CountDownLatch secondCalled = new CountDownLatch(1);
  123. Thread firstThread = new Thread("First thread") {
  124. @Override
  125. public void run()
  126. {
  127. try
  128. {
  129. File cacheDirectory = repository1.getCacheDirectory();
  130. GitCacheDirectory.getCacheLock(cacheDirectory).withLock(new Callable<Void>()
  131. {
  132. public Void call() throws Exception
  133. {
  134. firstCalled.countDown();
  135. boolean await = secondCalled.await(1000, TimeUnit.MILLISECONDS);
  136. hasBlocked.put(!await); // await false = timeout
  137. return null;
  138. }
  139. });
  140. }
  141. catch (Exception e)
  142. {
  143. throw new RuntimeException(e);
  144. }
  145. }
  146. };
  147. firstThread.start();
  148. Assert.assertTrue(firstCalled.await(1000, TimeUnit.MILLISECONDS), "First thread should be let in promptly");
  149. Thread secondThread = new Thread("Second thread") {
  150. @Override
  151. public void run()
  152. {
  153. try
  154. {
  155. File cacheDirectory = repository2.getCacheDirectory();
  156. GitCacheDirectory.getCacheLock(cacheDirectory).withLock(new Callable<Void>()
  157. {
  158. public Void call() throws Exception
  159. {
  160. secondCalled.countDown();
  161. return null;
  162. }
  163. });
  164. }
  165. catch (Exception e)
  166. {
  167. throw new RuntimeException(e);
  168. }
  169. }
  170. };
  171. secondThread.start();
  172. Assert.assertEquals(hasBlocked.take(), Boolean.valueOf(blockExpected), "Second thread blocking");
  173. Assert.assertTrue(secondCalled.await(2000, TimeUnit.MILLISECONDS), "Second thread should be eventually let in");
  174. }
  175. }