summaryrefslogtreecommitdiff
path: root/run_unittests.py
diff options
context:
space:
mode:
authorXavier Claessens <xavier.claessens@collabora.com>2020-09-15 12:08:02 -0400
committerNirbheek Chauhan <nirbheek.chauhan@gmail.com>2020-09-18 03:01:15 +0000
commitc203e2f92b118eb1138246b1eefd179161f54aab (patch)
tree68a0b4a2765aef9adcfbc81a6fa73a68416db67b /run_unittests.py
parent6fbf368fdebd7a9c24f8e52bbe69e1e4c25aaac7 (diff)
downloadmeson-c203e2f92b118eb1138246b1eefd179161f54aab.tar.gz
msubprojects: Add basic unit tests
Diffstat (limited to 'run_unittests.py')
-rwxr-xr-xrun_unittests.py167
1 files changed, 165 insertions, 2 deletions
diff --git a/run_unittests.py b/run_unittests.py
index 7757e88eb..29a330d68 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']