From 0f44c81e820945c29bd5860ef20485843e32461f Mon Sep 17 00:00:00 2001
From: Simon McVittie <smcv@collabora.com>
Date: Wed, 10 Jun 2020 18:23:37 +0100
Subject: [PATCH] tests: Test --copy-runtime-into and --only-prepare

To make this a little faster, we only generate locales in two of the six
tests (combining them asymmetrically so that we generate locales once
with and once without --copy-runtime-into, and once for each runtime
we are running from), and skip checking that locales were generated
correctly in the other tests.

Signed-off-by: Simon McVittie <smcv@collabora.com>
---
 tests/containers.py | 108 +++++++++++++++++++++++++++++++++-----------
 tests/invocation.py |   8 ++++
 2 files changed, 89 insertions(+), 27 deletions(-)

diff --git a/tests/containers.py b/tests/containers.py
index ae474cfc4..cb0edc9dd 100755
--- a/tests/containers.py
+++ b/tests/containers.py
@@ -83,6 +83,7 @@ import os
 import shutil
 import subprocess
 import sys
+import tempfile
 import unittest
 
 try:
@@ -122,9 +123,8 @@ class TestContainers(BaseTest):
             stdout=2,
             stderr=2,
         ).returncode != 0:
-            # Right now this means we will skip all the tests, but in
-            # future we will be able to do some tests that just do the
-            # setup and do not actually go as far as running the container.
+            # We can only do tests that just do setup and don't actually
+            # try to run the container.
             cls.bwrap = None
         else:
             cls.bwrap = bwrap
@@ -334,9 +334,11 @@ class TestContainers(BaseTest):
         test_name: str,
         scout: str,
         *,
-        locales: bool = False
+        copy: bool = False,
+        locales: bool = False,
+        only_prepare: bool = False
     ) -> None:
-        if self.bwrap is None:
+        if self.bwrap is None and not only_prepare:
             self.skipTest('Unable to run bwrap (in a container?)')
 
         if not os.path.isdir(scout):
@@ -354,30 +356,65 @@ class TestContainers(BaseTest):
             '--verbose',
         ]
 
+        var = os.path.join(self.containers_dir, 'var')
+        os.makedirs(var, exist_ok=True)
+
         if not locales:
             argv.append('--no-generate-locales')
 
-        argv.extend([
-            '--',
-            'env',
-            'TEST_INSIDE_SCOUT_ARTIFACTS=' + artifacts,
-            'TEST_INSIDE_SCOUT_LOCALES=' + ('1' if locales else ''),
-            'python3.5',
-            os.path.join(self.artifacts, 'tmp', 'inside-scout.py'),
-        ])
-
-        with tee_file_and_stderr(
-            os.path.join(artifacts, 'inside-scout.log')
-        ) as tee:
-            completed = self.run_subprocess(
-                argv,
-                cwd=self.artifacts,
-                stdout=tee.stdin,
-                stderr=tee.stdin,
-                universal_newlines=True,
-            )
+        with tempfile.TemporaryDirectory(prefix='test-', dir=var) as temp:
+            if copy:
+                argv.extend(['--copy-runtime-into', temp])
+
+            if only_prepare:
+                argv.append('--only-prepare')
+            else:
+                argv.extend([
+                    '--',
+                    'env',
+                    'TEST_INSIDE_SCOUT_ARTIFACTS=' + artifacts,
+                    'TEST_INSIDE_SCOUT_LOCALES=' + ('1' if locales else ''),
+                    'python3.5',
+                    os.path.join(self.artifacts, 'tmp', 'inside-scout.py'),
+                ])
+
+            with tee_file_and_stderr(
+                os.path.join(artifacts, 'inside-scout.log')
+            ) as tee:
+                completed = self.run_subprocess(
+                    argv,
+                    cwd=self.artifacts,
+                    stdout=tee.stdin,
+                    stderr=tee.stdin,
+                    universal_newlines=True,
+                )
 
-        self.assertEqual(completed.returncode, 0)
+            self.assertEqual(completed.returncode, 0)
+
+            if copy:
+                members = set(os.listdir(temp))
+                members.discard('.ref')
+                self.assertEqual(len(members), 1)
+                tree = os.path.join(temp, members.pop())
+
+                with open(
+                    os.path.join(artifacts, 'contents.txt'),
+                    'w',
+                ) as writer:
+                    self.run_subprocess([
+                        'find',
+                        '.',
+                        '-ls',
+                    ], cwd=tree, stderr=2, stdout=writer)
+
+                self.assertTrue(os.path.isdir(os.path.join(tree, 'bin')))
+                self.assertTrue(os.path.isdir(os.path.join(tree, 'etc')))
+                self.assertTrue(os.path.isdir(os.path.join(tree, 'lib')))
+                self.assertTrue(os.path.isdir(os.path.join(tree, 'usr')))
+                self.assertFalse(
+                    os.path.isdir(os.path.join(tree, 'usr', 'usr'))
+                )
+                self.assertTrue(os.path.isdir(os.path.join(tree, 'sbin')))
 
     def test_scout_sysroot(self) -> None:
         scout = os.path.join(self.containers_dir, 'scout_sysroot')
@@ -385,12 +422,29 @@ class TestContainers(BaseTest):
         if os.path.isdir(os.path.join(scout, 'files')):
             scout = os.path.join(scout, 'files')
 
-        self._test_scout('scout_sysroot', scout, locales=True)
+        with self.subTest('only-prepare'):
+            self._test_scout(
+                'scout_sysroot_prep', scout,
+                copy=True, only_prepare=True,
+            )
+
+        with self.subTest('copy'):
+            self._test_scout('scout_sysroot_copy', scout, copy=True)
+
+        with self.subTest('transient'):
+            self._test_scout('scout_sysroot', scout, locales=True)
 
     def test_scout_usr(self) -> None:
         scout = os.path.join(self.containers_dir, 'scout', 'files')
 
-        self._test_scout('scout', scout, locales=True)
+        with self.subTest('only-prepare'):
+            self._test_scout('scout_prep', scout, copy=True, only_prepare=True)
+
+        with self.subTest('copy'):
+            self._test_scout('scout_copy', scout, copy=True, locales=True)
+
+        with self.subTest('transient'):
+            self._test_scout('scout', scout)
 
 
 if __name__ == '__main__':
diff --git a/tests/invocation.py b/tests/invocation.py
index 44248abdd..7d8a7f737 100644
--- a/tests/invocation.py
+++ b/tests/invocation.py
@@ -64,6 +64,14 @@ class TestInvocation(BaseTest):
         )
         self.assertEqual(completed.returncode, 2)
 
+    def test_only_prepare_exclusive(self) -> None:
+        completed = run_subprocess(
+            [self.pv_wrap, '--only-prepare', '--test'],
+            stdout=2,
+            stderr=2,
+        )
+        self.assertEqual(completed.returncode, 2)
+
 
 if __name__ == '__main__':
     assert sys.version_info >= (3, 4), \
-- 
GitLab