gclient_transitions_smoketest.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. #!/usr/bin/env vpython3
  2. # Copyright (c) 2020 The Chromium Authors. All rights reserved.
  3. # Use of this source code is governed by a BSD-style license that can be
  4. # found in the LICENSE file.
  5. """Smoke tests for gclient.py.
  6. Shell out 'gclient' and simulate the behavior of bisect bots as they transition
  7. across DEPS changes.
  8. """
  9. import logging
  10. import os
  11. import sys
  12. import unittest
  13. import gclient_smoketest_base
  14. ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
  15. sys.path.insert(0, ROOT_DIR)
  16. import scm
  17. from testing_support import fake_repos
  18. # TODO: Should fix these warnings.
  19. # pylint: disable=line-too-long
  20. class SkiaDEPSTransitionSmokeTest(gclient_smoketest_base.GClientSmokeBase):
  21. """Simulate the behavior of bisect bots as they transition across the Skia
  22. DEPS change."""
  23. FAKE_REPOS_CLASS = fake_repos.FakeRepoSkiaDEPS
  24. def setUp(self):
  25. super(SkiaDEPSTransitionSmokeTest, self).setUp()
  26. self.enabled = self.FAKE_REPOS.set_up_git()
  27. if not self.enabled:
  28. self.skipTest('git fake repos not available')
  29. def testSkiaDEPSChangeGit(self):
  30. # Create an initial checkout:
  31. # - Single checkout at the root.
  32. # - Multiple checkouts in a shared subdirectory.
  33. self.gclient([
  34. 'config', '--spec', 'solutions=['
  35. '{"name": "src",'
  36. ' "url": ' + repr(self.git_base) + '+ "repo_2",'
  37. '}]'
  38. ])
  39. checkout_path = os.path.join(self.root_dir, 'src')
  40. skia = os.path.join(checkout_path, 'third_party', 'skia')
  41. skia_gyp = os.path.join(skia, 'gyp')
  42. skia_include = os.path.join(skia, 'include')
  43. skia_src = os.path.join(skia, 'src')
  44. gyp_git_url = self.git_base + 'repo_3'
  45. include_git_url = self.git_base + 'repo_4'
  46. src_git_url = self.git_base + 'repo_5'
  47. skia_git_url = self.FAKE_REPOS.git_base + 'repo_1'
  48. pre_hash = self.githash('repo_2', 1)
  49. post_hash = self.githash('repo_2', 2)
  50. # Initial sync. Verify that we get the expected checkout.
  51. res = self.gclient(
  52. ['sync', '--deps', 'mac', '--revision',
  53. 'src@%s' % pre_hash])
  54. self.assertEqual(res[2], 0, 'Initial sync failed.')
  55. self.assertEqual(
  56. scm.GIT.Capture(['config', 'remote.origin.url'], skia_gyp),
  57. gyp_git_url)
  58. self.assertEqual(
  59. scm.GIT.Capture(['config', 'remote.origin.url'], skia_include),
  60. include_git_url)
  61. self.assertEqual(
  62. scm.GIT.Capture(['config', 'remote.origin.url'], skia_src),
  63. src_git_url)
  64. # Verify that the sync succeeds. Verify that we have the expected
  65. # merged checkout.
  66. res = self.gclient(
  67. ['sync', '--deps', 'mac', '--revision',
  68. 'src@%s' % post_hash])
  69. self.assertEqual(res[2], 0, 'DEPS change sync failed.')
  70. self.assertEqual(scm.GIT.Capture(['config', 'remote.origin.url'], skia),
  71. skia_git_url)
  72. # Sync again. Verify that we still have the expected merged checkout.
  73. res = self.gclient(
  74. ['sync', '--deps', 'mac', '--revision',
  75. 'src@%s' % post_hash])
  76. self.assertEqual(res[2], 0, 'Subsequent sync failed.')
  77. self.assertEqual(scm.GIT.Capture(['config', 'remote.origin.url'], skia),
  78. skia_git_url)
  79. # Sync back to the original DEPS. Verify that we get the original
  80. # structure.
  81. res = self.gclient(
  82. ['sync', '--deps', 'mac', '--revision',
  83. 'src@%s' % pre_hash])
  84. self.assertEqual(res[2], 0, 'Reverse sync failed.')
  85. self.assertEqual(
  86. scm.GIT.Capture(['config', 'remote.origin.url'], skia_gyp),
  87. gyp_git_url)
  88. self.assertEqual(
  89. scm.GIT.Capture(['config', 'remote.origin.url'], skia_include),
  90. include_git_url)
  91. self.assertEqual(
  92. scm.GIT.Capture(['config', 'remote.origin.url'], skia_src),
  93. src_git_url)
  94. # Sync again. Verify that we still have the original structure.
  95. res = self.gclient(
  96. ['sync', '--deps', 'mac', '--revision',
  97. 'src@%s' % pre_hash])
  98. self.assertEqual(res[2], 0, 'Subsequent sync #2 failed.')
  99. self.assertEqual(
  100. scm.GIT.Capture(['config', 'remote.origin.url'], skia_gyp),
  101. gyp_git_url)
  102. self.assertEqual(
  103. scm.GIT.Capture(['config', 'remote.origin.url'], skia_include),
  104. include_git_url)
  105. self.assertEqual(
  106. scm.GIT.Capture(['config', 'remote.origin.url'], skia_src),
  107. src_git_url)
  108. class BlinkDEPSTransitionSmokeTest(gclient_smoketest_base.GClientSmokeBase):
  109. """Simulate the behavior of bisect bots as they transition across the Blink
  110. DEPS change."""
  111. FAKE_REPOS_CLASS = fake_repos.FakeRepoBlinkDEPS
  112. def setUp(self):
  113. super(BlinkDEPSTransitionSmokeTest, self).setUp()
  114. self.enabled = self.FAKE_REPOS.set_up_git()
  115. if not self.enabled:
  116. self.skipTest('git fake repos not available')
  117. self.checkout_path = os.path.join(self.root_dir, 'src')
  118. self.blink = os.path.join(self.checkout_path, 'third_party', 'WebKit')
  119. self.blink_git_url = self.FAKE_REPOS.git_base + 'repo_2'
  120. self.pre_merge_sha = self.githash('repo_1', 1)
  121. self.post_merge_sha = self.githash('repo_1', 2)
  122. def CheckStatusPreMergePoint(self):
  123. self.assertEqual(
  124. scm.GIT.Capture(['config', 'remote.origin.url'], self.blink),
  125. self.blink_git_url)
  126. self.assertTrue(os.path.exists(join(self.blink, '.git')))
  127. self.assertTrue(os.path.exists(join(self.blink, 'OWNERS')))
  128. with open(join(self.blink, 'OWNERS')) as f:
  129. owners_content = f.read()
  130. self.assertEqual('OWNERS-pre', owners_content, 'OWNERS not updated')
  131. self.assertTrue(
  132. os.path.exists(join(self.blink, 'Source', 'exists_always')))
  133. self.assertTrue(
  134. os.path.exists(
  135. join(self.blink, 'Source', 'exists_before_but_not_after')))
  136. self.assertFalse(
  137. os.path.exists(
  138. join(self.blink, 'Source', 'exists_after_but_not_before')))
  139. def CheckStatusPostMergePoint(self):
  140. # Check that the contents still exists
  141. self.assertTrue(os.path.exists(join(self.blink, 'OWNERS')))
  142. with open(join(self.blink, 'OWNERS')) as f:
  143. owners_content = f.read()
  144. self.assertEqual('OWNERS-post', owners_content,
  145. 'OWNERS not updated')
  146. self.assertTrue(
  147. os.path.exists(join(self.blink, 'Source', 'exists_always')))
  148. # Check that file removed between the branch point are actually deleted.
  149. self.assertTrue(
  150. os.path.exists(
  151. join(self.blink, 'Source', 'exists_after_but_not_before')))
  152. self.assertFalse(
  153. os.path.exists(
  154. join(self.blink, 'Source', 'exists_before_but_not_after')))
  155. # But not the .git folder
  156. self.assertFalse(os.path.exists(join(self.blink, '.git')))
  157. @unittest.skip('flaky')
  158. def testBlinkDEPSChangeUsingGclient(self):
  159. """Checks that {src,blink} repos are consistent when syncing going back and
  160. forth using gclient sync src@revision."""
  161. self.gclient([
  162. 'config', '--spec', 'solutions=['
  163. '{"name": "src",'
  164. ' "url": "' + self.git_base + 'repo_1",'
  165. '}]'
  166. ])
  167. # Go back and forth two times.
  168. for _ in range(2):
  169. res = self.gclient([
  170. 'sync', '--jobs', '1', '--revision',
  171. 'src@%s' % self.pre_merge_sha
  172. ])
  173. self.assertEqual(res[2], 0, 'DEPS change sync failed.')
  174. self.CheckStatusPreMergePoint()
  175. res = self.gclient([
  176. 'sync', '--jobs', '1', '--revision',
  177. 'src@%s' % self.post_merge_sha
  178. ])
  179. self.assertEqual(res[2], 0, 'DEPS change sync failed.')
  180. self.CheckStatusPostMergePoint()
  181. @unittest.skip('flaky')
  182. def testBlinkDEPSChangeUsingGit(self):
  183. """Like testBlinkDEPSChangeUsingGclient, but move the main project using
  184. directly git and not gclient sync."""
  185. self.gclient([
  186. 'config', '--spec', 'solutions=['
  187. '{"name": "src",'
  188. ' "url": "' + self.git_base + 'repo_1",'
  189. ' "managed": False,'
  190. '}]'
  191. ])
  192. # Perform an initial sync to bootstrap the repo.
  193. res = self.gclient(['sync', '--jobs', '1'])
  194. self.assertEqual(res[2], 0, 'Initial gclient sync failed.')
  195. # Go back and forth two times.
  196. for _ in range(2):
  197. subprocess2.check_call(
  198. ['git', 'checkout', '-q', self.pre_merge_sha],
  199. cwd=self.checkout_path)
  200. res = self.gclient(['sync', '--jobs', '1'])
  201. self.assertEqual(res[2], 0, 'gclient sync failed.')
  202. self.CheckStatusPreMergePoint()
  203. subprocess2.check_call(
  204. ['git', 'checkout', '-q', self.post_merge_sha],
  205. cwd=self.checkout_path)
  206. res = self.gclient(['sync', '--jobs', '1'])
  207. self.assertEqual(res[2], 0, 'DEPS change sync failed.')
  208. self.CheckStatusPostMergePoint()
  209. @unittest.skip('flaky')
  210. def testBlinkLocalBranchesArePreserved(self):
  211. """Checks that the state of local git branches are effectively preserved
  212. when going back and forth."""
  213. self.gclient([
  214. 'config', '--spec', 'solutions=['
  215. '{"name": "src",'
  216. ' "url": "' + self.git_base + 'repo_1",'
  217. '}]'
  218. ])
  219. # Initialize to pre-merge point.
  220. self.gclient(['sync', '--revision', 'src@%s' % self.pre_merge_sha])
  221. self.CheckStatusPreMergePoint()
  222. # Create a branch named "foo".
  223. subprocess2.check_call(['git', 'checkout', '-qB', 'foo'],
  224. cwd=self.blink)
  225. # Cross the pre-merge point.
  226. self.gclient(['sync', '--revision', 'src@%s' % self.post_merge_sha])
  227. self.CheckStatusPostMergePoint()
  228. # Go backwards and check that we still have the foo branch.
  229. self.gclient(['sync', '--revision', 'src@%s' % self.pre_merge_sha])
  230. self.CheckStatusPreMergePoint()
  231. subprocess2.check_call(
  232. ['git', 'show-ref', '-q', '--verify', 'refs/heads/foo'],
  233. cwd=self.blink)
  234. if __name__ == '__main__':
  235. if '-v' in sys.argv:
  236. logging.basicConfig(level=logging.DEBUG)
  237. unittest.main()