#!/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()