| #!/usr/bin/env vpython3 |
| # Copyright (c) 2022 The Chromium Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| """Smoke tests for gclient.py and the no-sync experiment |
| |
| Shell out 'gclient' and run git tests. |
| """ |
| |
| import json |
| import logging |
| import os |
| import sys |
| import unittest |
| |
| import gclient_smoketest_base |
| import gclient |
| |
| ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) |
| sys.path.insert(0, ROOT_DIR) |
| |
| import subprocess2 |
| from testing_support import fake_repos |
| |
| |
| def write(filename, content): |
| """Writes the content of a file and create the directories as needed.""" |
| filename = os.path.abspath(filename) |
| dirname = os.path.dirname(filename) |
| if not os.path.isdir(dirname): |
| os.makedirs(dirname) |
| with open(filename, 'w') as f: |
| f.write(content) |
| |
| |
| class GClientSmokeGIT(gclient_smoketest_base.GClientSmokeBase): |
| """Smoke tests for the no-sync experiment.""" |
| |
| FAKE_REPOS_CLASS = fake_repos.FakeRepoNoSyncDEPS |
| |
| def setUp(self): |
| super(GClientSmokeGIT, self).setUp() |
| self.env['PATH'] = (os.path.join(ROOT_DIR, 'testing_support') + |
| os.pathsep + self.env['PATH']) |
| self.enabled = self.FAKE_REPOS.set_up_git() |
| if not self.enabled: |
| self.skipTest('git fake repos not available') |
| |
| def testNoSync_SkipSyncNoDEPSChange(self): |
| """No DEPS changes will skip sync""" |
| config_template = ''.join([ |
| 'solutions = [{' |
| ' "name" : "src",' |
| ' "url" : %(git_base)r + "repo_1",' |
| ' "deps_file" : "DEPS",' |
| ' "managed" : True,' |
| ' "custom_vars" : %(custom_vars)s,' |
| '}]' |
| ]) |
| self.gclient([ |
| 'config', '--spec', config_template % { |
| 'git_base': self.git_base, |
| 'custom_vars': { |
| 'mac': True |
| } |
| } |
| ]) |
| |
| output_json = os.path.join(self.root_dir, 'output.json') |
| |
| revision_1 = self.FAKE_REPOS.git_hashes['repo_1'][1][0] # DEPS 1 |
| revision_2 = self.FAKE_REPOS.git_hashes['repo_1'][2][0] # DEPS 1 |
| patch_ref = self.FAKE_REPOS.git_hashes['repo_1'][3][0] # DEPS 2 |
| |
| # Previous run did a sync at revision_1 |
| write(os.path.join(self.root_dir, gclient.PREVIOUS_SYNC_COMMITS_FILE), |
| json.dumps({'src': revision_1})) |
| write(os.path.join(self.root_dir, gclient.PREVIOUS_CUSTOM_VARS_FILE), |
| json.dumps({'src': { |
| 'mac': True |
| }})) |
| |
| # We checkout src at revision_2 which has a different DEPS |
| # but that should not matter because patch_ref and revision_1 |
| # have the same DEPS |
| self.gclient([ |
| 'sync', '--output-json', output_json, '--revision', |
| 'src@%s' % revision_2, '--patch-ref', |
| '%srepo_1@refs/heads/main:%s' % (self.git_base, patch_ref), |
| '--experiment', 'no-sync' |
| ]) |
| |
| with open(output_json) as f: |
| output_json = json.load(f) |
| expected = { |
| 'solutions': { |
| 'src/': { |
| 'revision': revision_2, |
| 'scm': 'git', |
| 'url': '%srepo_1' % self.git_base, |
| 'was_processed': True, |
| 'was_synced': False, |
| }, |
| }, |
| } |
| self.assertEqual(expected, output_json) |
| |
| def testNoSync_NoSyncNotEnablted(self): |
| """No DEPS changes will skip sync""" |
| config_template = ''.join([ |
| 'solutions = [{' |
| ' "name" : "src",' |
| ' "url" : %(git_base)r + "repo_1",' |
| ' "deps_file" : "DEPS",' |
| ' "managed" : True,' |
| ' "custom_vars" : %(custom_vars)s,' |
| '}]' |
| ]) |
| self.gclient([ |
| 'config', '--spec', config_template % { |
| 'git_base': self.git_base, |
| 'custom_vars': { |
| 'mac': True |
| } |
| } |
| ]) |
| |
| output_json = os.path.join(self.root_dir, 'output.json') |
| |
| revision_1 = self.FAKE_REPOS.git_hashes['repo_1'][1][0] # DEPS 1 |
| revision_2 = self.FAKE_REPOS.git_hashes['repo_1'][2][0] # DEPS 1 |
| patch_ref = self.FAKE_REPOS.git_hashes['repo_1'][3][0] # DEPS 2 |
| |
| # Previous run did a sync at revision_1 |
| write(os.path.join(self.root_dir, gclient.PREVIOUS_SYNC_COMMITS_FILE), |
| json.dumps({'src': revision_1})) |
| write(os.path.join(self.root_dir, gclient.PREVIOUS_CUSTOM_VARS_FILE), |
| json.dumps({'src': { |
| 'mac': True |
| }})) |
| |
| self.gclient([ |
| 'sync', '--output-json', output_json, '--revision', |
| 'src@%s' % revision_2, '--patch-ref', |
| '%srepo_1@refs/heads/main:%s' % (self.git_base, patch_ref) |
| ]) |
| |
| with open(output_json) as f: |
| output_json = json.load(f) |
| repo2_rev = self.FAKE_REPOS.git_hashes['repo_2'][1][0] |
| expected = { |
| 'solutions': { |
| 'src/': { |
| 'revision': revision_2, |
| 'scm': 'git', |
| 'url': '%srepo_1' % self.git_base, |
| 'was_processed': True, |
| 'was_synced': True, |
| }, |
| 'src/repo2/': { |
| 'revision': repo2_rev, |
| 'scm': 'git', |
| 'url': '%srepo_2@%s' % (self.git_base, repo2_rev[:7]), |
| 'was_processed': True, |
| 'was_synced': True, |
| }, |
| }, |
| } |
| self.assertEqual(expected, output_json) |
| |
| def testNoSync_CustomVarsDiff(self): |
| """We do not skip syncs if there are different custom_vars""" |
| config_template = ''.join([ |
| 'solutions = [{' |
| ' "name" : "src",' |
| ' "url" : %(git_base)r + "repo_1",' |
| ' "deps_file" : "DEPS",' |
| ' "managed" : True,' |
| ' "custom_vars" : %(custom_vars)s,' |
| '}]' |
| ]) |
| self.gclient([ |
| 'config', '--spec', config_template % { |
| 'git_base': self.git_base, |
| 'custom_vars': { |
| 'mac': True |
| } |
| } |
| ]) |
| |
| output_json = os.path.join(self.root_dir, 'output.json') |
| |
| revision_1 = self.FAKE_REPOS.git_hashes['repo_1'][1][0] # DEPS 1 |
| revision_2 = self.FAKE_REPOS.git_hashes['repo_1'][2][0] # DEPS 2 |
| patch_ref = self.FAKE_REPOS.git_hashes['repo_1'][3][0] # DEPS 1 |
| |
| # Previous run did a sync at revision_1 |
| write(os.path.join(self.root_dir, gclient.PREVIOUS_SYNC_COMMITS_FILE), |
| json.dumps({'src': revision_1})) |
| # No PREVIOUS_CUSTOM_VARS |
| |
| # We checkout src at revision_2 which has a different DEPS |
| # but that should not matter because patch_ref and revision_1 |
| # have the same DEPS |
| self.gclient([ |
| 'sync', '--output-json', output_json, '--revision', |
| 'src@%s' % revision_2, '--patch-ref', |
| '%srepo_1@refs/heads/main:%s' % (self.git_base, patch_ref), |
| '--experiment', 'no-sync' |
| ]) |
| |
| with open(output_json) as f: |
| output_json = json.load(f) |
| repo2_rev = self.FAKE_REPOS.git_hashes['repo_2'][1][0] |
| expected = { |
| 'solutions': { |
| 'src/': { |
| 'revision': revision_2, |
| 'scm': 'git', |
| 'url': '%srepo_1' % self.git_base, |
| 'was_processed': True, |
| 'was_synced': True, |
| }, |
| 'src/repo2/': { |
| 'revision': repo2_rev, |
| 'scm': 'git', |
| 'url': '%srepo_2@%s' % (self.git_base, repo2_rev[:7]), |
| 'was_processed': True, |
| 'was_synced': True, |
| }, |
| }, |
| } |
| self.assertEqual(expected, output_json) |
| |
| def testNoSync_DEPSDiff(self): |
| """We do not skip syncs if there are DEPS changes.""" |
| self.gclient(['config', self.git_base + 'repo_1', '--name', 'src']) |
| |
| output_json = os.path.join(self.root_dir, 'output.json') |
| |
| revision_1 = self.FAKE_REPOS.git_hashes['repo_1'][1][0] # DEPS 1 |
| revision_2 = self.FAKE_REPOS.git_hashes['repo_1'][2][0] # DEPS 2 |
| patch_ref = self.FAKE_REPOS.git_hashes['repo_1'][3][0] # DEPS 1 |
| |
| # Previous run did a sync at revision_1 |
| write(os.path.join(self.root_dir, gclient.PREVIOUS_SYNC_COMMITS_FILE), |
| json.dumps({'src': revision_2})) |
| |
| # We checkout src at revision_1 which has the same DEPS |
| # but that should not matter because patch_ref and revision_2 |
| # have different DEPS |
| self.gclient([ |
| 'sync', '--output-json', output_json, '--revision', |
| 'src@%s' % revision_1, '--patch-ref', |
| '%srepo_1@refs/heads/main:%s' % (self.git_base, patch_ref), |
| '--experiment', 'no-sync' |
| ]) |
| |
| with open(output_json) as f: |
| output_json = json.load(f) |
| repo2_rev = self.FAKE_REPOS.git_hashes['repo_2'][1][0] |
| expected = { |
| 'solutions': { |
| 'src/': { |
| 'revision': revision_1, |
| 'scm': 'git', |
| 'url': '%srepo_1' % self.git_base, |
| 'was_processed': True, |
| 'was_synced': True, |
| }, |
| 'src/repo2/': { |
| 'revision': repo2_rev, |
| 'scm': 'git', |
| 'url': '%srepo_2@%s' % (self.git_base, repo2_rev[:7]), |
| 'was_processed': True, |
| 'was_synced': True, |
| }, |
| }, |
| } |
| self.assertEqual(expected, output_json) |
| |
| |
| if __name__ == '__main__': |
| if '-v' in sys.argv: |
| logging.basicConfig(level=logging.DEBUG) |
| unittest.main() |