diff options
author | Xavier Claessens <xavier.claessens@collabora.com> | 2020-09-15 12:08:02 -0400 |
---|---|---|
committer | Nirbheek Chauhan <nirbheek.chauhan@gmail.com> | 2020-09-18 03:01:15 +0000 |
commit | c203e2f92b118eb1138246b1eefd179161f54aab (patch) | |
tree | 68a0b4a2765aef9adcfbc81a6fa73a68416db67b | |
parent | 6fbf368fdebd7a9c24f8e52bbe69e1e4c25aaac7 (diff) | |
download | meson-c203e2f92b118eb1138246b1eefd179161f54aab.zip meson-c203e2f92b118eb1138246b1eefd179161f54aab.tar.gz meson-c203e2f92b118eb1138246b1eefd179161f54aab.tar.bz2 |
msubprojects: Add basic unit tests
-rwxr-xr-x | run_unittests.py | 167 |
1 files changed, 165 insertions, 2 deletions
diff --git a/run_unittests.py b/run_unittests.py index 7757e88..29a330d 100755 --- a/run_unittests.py +++ b/run_unittests.py @@ -58,7 +58,7 @@ from mesonbuild.mesonlib import ( BuildDirLock, LibType, MachineChoice, PerMachine, Version, is_windows, is_osx, is_cygwin, is_dragonflybsd, is_openbsd, is_haiku, is_sunos, windows_proof_rmtree, python_command, version_compare, split_args, - quote_arg, relpath, is_linux + quote_arg, relpath, is_linux, git, GIT ) from mesonbuild.environment import detect_ninja from mesonbuild.mesonlib import MesonException, EnvironmentException @@ -8956,6 +8956,169 @@ class TAPParserTests(unittest.TestCase): self.assert_test(events, number=2, name='', result=TestResult.FAIL) self.assert_last(events) +class SubprojectsCommandTests(BasePlatformTests): + def setUp(self): + super().setUp() + self.root_dir = Path(self.builddir) + + self.project_dir = self.root_dir / 'src' + self._create_project(self.project_dir) + + self.subprojects_dir = self.project_dir / 'subprojects' + os.makedirs(str(self.subprojects_dir)) + + def _create_project(self, path, project_name='dummy'): + os.makedirs(str(path), exist_ok=True) + with open(str(path / 'meson.build'), 'w') as f: + f.write("project('{}')".format(project_name)) + + def _git(self, cmd, workdir): + return git(cmd, str(workdir), check=True)[1].strip() + + def _git_config(self, workdir): + self._git(['config', 'user.name', 'Meson Test'], workdir) + self._git(['config', 'user.email', 'meson.test@example.com'], workdir) + + def _git_remote(self, cmd, name): + return self._git(cmd, self.root_dir / name) + + def _git_local(self, cmd, name): + return self._git(cmd, self.subprojects_dir / name) + + def _git_create_repo(self, path): + self._create_project(path) + self._git(['init'], path) + self._git_config(path) + self._git(['add', '.'], path) + self._git(['commit', '-m', 'Initial commit'], path) + + def _git_create_remote_repo(self, name): + self._git_create_repo(self.root_dir / name) + + def _git_create_local_repo(self, name): + self._git_create_repo(self.subprojects_dir / name) + + def _git_create_remote_commit(self, name, branch): + self._git_remote(['checkout', branch], name) + self._git_remote(['commit', '--allow-empty', '-m', 'initial {} commit'.format(branch)], name) + + def _git_create_remote_branch(self, name, branch): + self._git_remote(['checkout', '-b', branch], name) + self._git_remote(['commit', '--allow-empty', '-m', 'initial {} commit'.format(branch)], name) + + def _git_create_remote_tag(self, name, tag): + self._git_remote(['commit', '--allow-empty', '-m', 'tag {} commit'.format(tag)], name) + self._git_remote(['tag', tag], name) + + def _wrap_create_git(self, name, revision='master'): + path = self.root_dir / name + with open(str((self.subprojects_dir / name).with_suffix('.wrap')), 'w') as f: + f.write(textwrap.dedent( + ''' + [wrap-git] + url={} + revision={} + '''.format(os.path.abspath(str(path)), revision))) + + def _wrap_create_file(self, name, tarball='dummy.tar.gz'): + path = self.root_dir / tarball + with open(str((self.subprojects_dir / name).with_suffix('.wrap')), 'w') as f: + f.write(textwrap.dedent( + ''' + [wrap-file] + source_url={} + '''.format(os.path.abspath(str(path))))) + + def _subprojects_cmd(self, args): + return self._run(self.meson_command + ['subprojects'] + args, workdir=str(self.project_dir)) + + def test_git_update(self): + subp_name = 'sub1' + + # Create a fake remote git repository and a wrap file. Checks that + # "meson subprojects download" works. + self._git_create_remote_repo(subp_name) + self._wrap_create_git(subp_name) + self._subprojects_cmd(['download']) + self.assertPathExists(str(self.subprojects_dir / subp_name)) + self._git_config(self.subprojects_dir / subp_name) + + # Create a new remote branch and update the wrap file. Checks that + # "meson subprojects update --reset" checkout the new branch. + self._git_create_remote_branch(subp_name, 'newbranch') + self._wrap_create_git(subp_name, 'newbranch') + self._subprojects_cmd(['update', '--reset']) + self.assertEqual(self._git_local(['branch', '--show-current'], subp_name), 'newbranch') + self.assertEqual(self._git_local(['rev-parse', 'HEAD'], subp_name), self._git_remote(['rev-parse', 'newbranch'], subp_name)) + + # Update remote newbranch. Checks the new commit is pulled into existing + # local newbranch. Make sure it does not print spurious 'git stash' message. + self._git_create_remote_commit(subp_name, 'newbranch') + out = self._subprojects_cmd(['update', '--reset']) + self.assertNotIn('No local changes to save', out) + self.assertEqual(self._git_local(['branch', '--show-current'], subp_name), 'newbranch') + self.assertEqual(self._git_local(['rev-parse', 'HEAD'], subp_name), self._git_remote(['rev-parse', 'newbranch'], subp_name)) + + # Update remote newbranch and switch to another branch. Checks that it + # switch current branch to newbranch and pull latest commit. + self._git_local(['checkout', 'master'], subp_name) + self._git_create_remote_commit(subp_name, 'newbranch') + self._subprojects_cmd(['update', '--reset']) + self.assertEqual(self._git_local(['branch', '--show-current'], subp_name), 'newbranch') + self.assertEqual(self._git_local(['rev-parse', 'HEAD'], subp_name), self._git_remote(['rev-parse', 'newbranch'], subp_name)) + + # Stage some local changes then update. Checks that local changes got + # stashed. + self._create_project(self.subprojects_dir / subp_name, 'new_project_name') + self._git_local(['add', '.'], subp_name) + self._git_create_remote_commit(subp_name, 'newbranch') + self._subprojects_cmd(['update', '--reset']) + self.assertEqual(self._git_local(['branch', '--show-current'], subp_name), 'newbranch') + self.assertEqual(self._git_local(['rev-parse', 'HEAD'], subp_name), self._git_remote(['rev-parse', 'newbranch'], subp_name)) + self.assertTrue(self._git_local(['stash', 'list'], subp_name)) + + # Create a new remote tag and update the wrap file. Checks that + # "meson subprojects update --reset" checkout the new tag in detached mode. + self._git_create_remote_tag(subp_name, 'newtag') + self._wrap_create_git(subp_name, 'newtag') + self._subprojects_cmd(['update', '--reset']) + self.assertEqual(self._git_local(['branch', '--show-current'], subp_name), '') + self.assertEqual(self._git_local(['rev-parse', 'HEAD'], subp_name), self._git_remote(['rev-parse', 'newtag'], subp_name)) + + # Create a new remote commit and update the wrap file with the commit id. + # Checks that "meson subprojects update --reset" checkout the new commit + # in detached mode. + self._git_local(['checkout', 'master'], subp_name) + self._git_create_remote_commit(subp_name, 'newbranch') + new_commit = self._git_remote(['rev-parse', 'HEAD'], subp_name) + self._wrap_create_git(subp_name, new_commit) + self._subprojects_cmd(['update', '--reset']) + self.assertEqual(self._git_local(['branch', '--show-current'], subp_name), '') + self.assertEqual(self._git_local(['rev-parse', 'HEAD'], subp_name), new_commit) + + @skipIfNoExecutable('true') + def test_foreach(self): + self._create_project(self.subprojects_dir / 'sub_file') + self._wrap_create_file('sub_file') + self._git_create_local_repo('sub_git_no_wrap') + + def ran_in(s): + ret = [] + prefix = 'Executing command in ' + for l in s.splitlines(): + if l.startswith(prefix): + ret.append(l[len(prefix):]) + return sorted(ret) + + dummy_cmd = ['true'] + out = self._subprojects_cmd(['foreach'] + dummy_cmd) + self.assertEqual(ran_in(out), sorted(['./subprojects/sub_git_no_wrap', './subprojects/sub_file'])) + out = self._subprojects_cmd(['foreach', '--types', 'git,file'] + dummy_cmd) + self.assertEqual(ran_in(out), sorted(['./subprojects/sub_git_no_wrap', './subprojects/sub_file'])) + out = self._subprojects_cmd(['foreach', '--types', 'file'] + dummy_cmd) + self.assertEqual(ran_in(out), ['./subprojects/sub_file']) + out = self._subprojects_cmd(['foreach', '--types', 'git'] + dummy_cmd) + self.assertEqual(ran_in(out), ['./subprojects/sub_git_no_wrap']) def _clang_at_least(compiler, minver: str, apple_minver: str) -> bool: """ @@ -9030,7 +9193,7 @@ def main(): unset_envs() cases = ['InternalTests', 'DataTests', 'AllPlatformTests', 'FailureTests', 'PythonTests', 'NativeFileTests', 'RewriterTests', 'CrossFileTests', - 'TAPParserTests', + 'TAPParserTests', 'SubprojectsCommandTests', 'LinuxlikeTests', 'LinuxCrossArmTests', 'LinuxCrossMingwTests', 'WindowsTests', 'DarwinTests'] |