gclient_no_sync_smoketest.py 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. #!/usr/bin/env vpython3
  2. # Copyright (c) 2022 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 and the no-sync experiment
  6. Shell out 'gclient' and run git tests.
  7. """
  8. import json
  9. import logging
  10. import os
  11. import sys
  12. import unittest
  13. import gclient_smoketest_base
  14. import gclient
  15. ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
  16. sys.path.insert(0, ROOT_DIR)
  17. import subprocess2
  18. from testing_support import fake_repos
  19. def write(filename, content):
  20. """Writes the content of a file and create the directories as needed."""
  21. filename = os.path.abspath(filename)
  22. dirname = os.path.dirname(filename)
  23. if not os.path.isdir(dirname):
  24. os.makedirs(dirname)
  25. with open(filename, 'w') as f:
  26. f.write(content)
  27. class GClientSmokeGIT(gclient_smoketest_base.GClientSmokeBase):
  28. """Smoke tests for the no-sync experiment."""
  29. FAKE_REPOS_CLASS = fake_repos.FakeRepoNoSyncDEPS
  30. def setUp(self):
  31. super(GClientSmokeGIT, self).setUp()
  32. self.env['PATH'] = (os.path.join(ROOT_DIR, 'testing_support') +
  33. os.pathsep + self.env['PATH'])
  34. self.enabled = self.FAKE_REPOS.set_up_git()
  35. if not self.enabled:
  36. self.skipTest('git fake repos not available')
  37. def testNoSync_SkipSyncNoDEPSChange(self):
  38. """No DEPS changes will skip sync"""
  39. config_template = ''.join([
  40. 'solutions = [{'
  41. ' "name" : "src",'
  42. ' "url" : %(git_base)r + "repo_1",'
  43. ' "deps_file" : "DEPS",'
  44. ' "managed" : True,'
  45. ' "custom_vars" : %(custom_vars)s,'
  46. '}]'
  47. ])
  48. self.gclient([
  49. 'config', '--spec', config_template % {
  50. 'git_base': self.git_base,
  51. 'custom_vars': {
  52. 'mac': True
  53. }
  54. }
  55. ])
  56. output_json = os.path.join(self.root_dir, 'output.json')
  57. revision_1 = self.FAKE_REPOS.git_hashes['repo_1'][1][0] # DEPS 1
  58. revision_2 = self.FAKE_REPOS.git_hashes['repo_1'][2][0] # DEPS 1
  59. patch_ref = self.FAKE_REPOS.git_hashes['repo_1'][3][0] # DEPS 2
  60. # Previous run did a sync at revision_1
  61. write(os.path.join(self.root_dir, gclient.PREVIOUS_SYNC_COMMITS_FILE),
  62. json.dumps({'src': revision_1}))
  63. write(os.path.join(self.root_dir, gclient.PREVIOUS_CUSTOM_VARS_FILE),
  64. json.dumps({'src': {
  65. 'mac': True
  66. }}))
  67. # We checkout src at revision_2 which has a different DEPS
  68. # but that should not matter because patch_ref and revision_1
  69. # have the same DEPS
  70. self.gclient([
  71. 'sync', '--output-json', output_json, '--revision',
  72. 'src@%s' % revision_2, '--patch-ref',
  73. '%srepo_1@refs/heads/main:%s' % (self.git_base, patch_ref),
  74. '--experiment', 'no-sync'
  75. ])
  76. with open(output_json) as f:
  77. output_json = json.load(f)
  78. expected = {
  79. 'solutions': {
  80. 'src/': {
  81. 'revision': revision_2,
  82. 'scm': 'git',
  83. 'url': '%srepo_1' % self.git_base,
  84. 'was_processed': True,
  85. 'was_synced': False,
  86. },
  87. },
  88. }
  89. self.assertEqual(expected, output_json)
  90. def testNoSync_NoSyncNotEnablted(self):
  91. """No DEPS changes will skip sync"""
  92. config_template = ''.join([
  93. 'solutions = [{'
  94. ' "name" : "src",'
  95. ' "url" : %(git_base)r + "repo_1",'
  96. ' "deps_file" : "DEPS",'
  97. ' "managed" : True,'
  98. ' "custom_vars" : %(custom_vars)s,'
  99. '}]'
  100. ])
  101. self.gclient([
  102. 'config', '--spec', config_template % {
  103. 'git_base': self.git_base,
  104. 'custom_vars': {
  105. 'mac': True
  106. }
  107. }
  108. ])
  109. output_json = os.path.join(self.root_dir, 'output.json')
  110. revision_1 = self.FAKE_REPOS.git_hashes['repo_1'][1][0] # DEPS 1
  111. revision_2 = self.FAKE_REPOS.git_hashes['repo_1'][2][0] # DEPS 1
  112. patch_ref = self.FAKE_REPOS.git_hashes['repo_1'][3][0] # DEPS 2
  113. # Previous run did a sync at revision_1
  114. write(os.path.join(self.root_dir, gclient.PREVIOUS_SYNC_COMMITS_FILE),
  115. json.dumps({'src': revision_1}))
  116. write(os.path.join(self.root_dir, gclient.PREVIOUS_CUSTOM_VARS_FILE),
  117. json.dumps({'src': {
  118. 'mac': True
  119. }}))
  120. self.gclient([
  121. 'sync', '--output-json', output_json, '--revision',
  122. 'src@%s' % revision_2, '--patch-ref',
  123. '%srepo_1@refs/heads/main:%s' % (self.git_base, patch_ref)
  124. ])
  125. with open(output_json) as f:
  126. output_json = json.load(f)
  127. repo2_rev = self.FAKE_REPOS.git_hashes['repo_2'][1][0]
  128. expected = {
  129. 'solutions': {
  130. 'src/': {
  131. 'revision': revision_2,
  132. 'scm': 'git',
  133. 'url': '%srepo_1' % self.git_base,
  134. 'was_processed': True,
  135. 'was_synced': True,
  136. },
  137. 'src/repo2/': {
  138. 'revision': repo2_rev,
  139. 'scm': 'git',
  140. 'url': '%srepo_2@%s' % (self.git_base, repo2_rev[:7]),
  141. 'was_processed': True,
  142. 'was_synced': True,
  143. },
  144. },
  145. }
  146. self.assertEqual(expected, output_json)
  147. def testNoSync_CustomVarsDiff(self):
  148. """We do not skip syncs if there are different custom_vars"""
  149. config_template = ''.join([
  150. 'solutions = [{'
  151. ' "name" : "src",'
  152. ' "url" : %(git_base)r + "repo_1",'
  153. ' "deps_file" : "DEPS",'
  154. ' "managed" : True,'
  155. ' "custom_vars" : %(custom_vars)s,'
  156. '}]'
  157. ])
  158. self.gclient([
  159. 'config', '--spec', config_template % {
  160. 'git_base': self.git_base,
  161. 'custom_vars': {
  162. 'mac': True
  163. }
  164. }
  165. ])
  166. output_json = os.path.join(self.root_dir, 'output.json')
  167. revision_1 = self.FAKE_REPOS.git_hashes['repo_1'][1][0] # DEPS 1
  168. revision_2 = self.FAKE_REPOS.git_hashes['repo_1'][2][0] # DEPS 2
  169. patch_ref = self.FAKE_REPOS.git_hashes['repo_1'][3][0] # DEPS 1
  170. # Previous run did a sync at revision_1
  171. write(os.path.join(self.root_dir, gclient.PREVIOUS_SYNC_COMMITS_FILE),
  172. json.dumps({'src': revision_1}))
  173. # No PREVIOUS_CUSTOM_VARS
  174. # We checkout src at revision_2 which has a different DEPS
  175. # but that should not matter because patch_ref and revision_1
  176. # have the same DEPS
  177. self.gclient([
  178. 'sync', '--output-json', output_json, '--revision',
  179. 'src@%s' % revision_2, '--patch-ref',
  180. '%srepo_1@refs/heads/main:%s' % (self.git_base, patch_ref),
  181. '--experiment', 'no-sync'
  182. ])
  183. with open(output_json) as f:
  184. output_json = json.load(f)
  185. repo2_rev = self.FAKE_REPOS.git_hashes['repo_2'][1][0]
  186. expected = {
  187. 'solutions': {
  188. 'src/': {
  189. 'revision': revision_2,
  190. 'scm': 'git',
  191. 'url': '%srepo_1' % self.git_base,
  192. 'was_processed': True,
  193. 'was_synced': True,
  194. },
  195. 'src/repo2/': {
  196. 'revision': repo2_rev,
  197. 'scm': 'git',
  198. 'url': '%srepo_2@%s' % (self.git_base, repo2_rev[:7]),
  199. 'was_processed': True,
  200. 'was_synced': True,
  201. },
  202. },
  203. }
  204. self.assertEqual(expected, output_json)
  205. def testNoSync_DEPSDiff(self):
  206. """We do not skip syncs if there are DEPS changes."""
  207. self.gclient(['config', self.git_base + 'repo_1', '--name', 'src'])
  208. output_json = os.path.join(self.root_dir, 'output.json')
  209. revision_1 = self.FAKE_REPOS.git_hashes['repo_1'][1][0] # DEPS 1
  210. revision_2 = self.FAKE_REPOS.git_hashes['repo_1'][2][0] # DEPS 2
  211. patch_ref = self.FAKE_REPOS.git_hashes['repo_1'][3][0] # DEPS 1
  212. # Previous run did a sync at revision_1
  213. write(os.path.join(self.root_dir, gclient.PREVIOUS_SYNC_COMMITS_FILE),
  214. json.dumps({'src': revision_2}))
  215. # We checkout src at revision_1 which has the same DEPS
  216. # but that should not matter because patch_ref and revision_2
  217. # have different DEPS
  218. self.gclient([
  219. 'sync', '--output-json', output_json, '--revision',
  220. 'src@%s' % revision_1, '--patch-ref',
  221. '%srepo_1@refs/heads/main:%s' % (self.git_base, patch_ref),
  222. '--experiment', 'no-sync'
  223. ])
  224. with open(output_json) as f:
  225. output_json = json.load(f)
  226. repo2_rev = self.FAKE_REPOS.git_hashes['repo_2'][1][0]
  227. expected = {
  228. 'solutions': {
  229. 'src/': {
  230. 'revision': revision_1,
  231. 'scm': 'git',
  232. 'url': '%srepo_1' % self.git_base,
  233. 'was_processed': True,
  234. 'was_synced': True,
  235. },
  236. 'src/repo2/': {
  237. 'revision': repo2_rev,
  238. 'scm': 'git',
  239. 'url': '%srepo_2@%s' % (self.git_base, repo2_rev[:7]),
  240. 'was_processed': True,
  241. 'was_synced': True,
  242. },
  243. },
  244. }
  245. self.assertEqual(expected, output_json)
  246. if __name__ == '__main__':
  247. if '-v' in sys.argv:
  248. logging.basicConfig(level=logging.DEBUG)
  249. unittest.main()