Commit 9d985106 authored by Jérome Perrin's avatar Jérome Perrin

testing/testcase: snapshot symlinks and directories

Directories were ignored by mistake, we found out that several files
that would help us diagnosing problems were missing, because we only
snapshot etc/* which did not snapshot recursive directories such as
etc/promise or etc/service.

Symlinks were copied (the target was copied), because they matched the
isfile check, but if the symlink target was not existent, this caused
errors.

Also rename _snapshot_instance_file to _copySnapshot as it is no longer
treating files only
parent c20aaaac
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
import unittest import unittest
import os import os
import fnmatch
import glob import glob
import logging import logging
import shutil import shutil
...@@ -295,8 +296,6 @@ class SlapOSInstanceTestCase(unittest.TestCase): ...@@ -295,8 +296,6 @@ class SlapOSInstanceTestCase(unittest.TestCase):
'etc/supervisord.conf', 'etc/supervisord.conf',
'etc/supervisord.conf.d/*', 'etc/supervisord.conf.d/*',
'*/etc/*', '*/etc/*',
'*/etc/service/*',
'*/etc/run/*',
'*/var/log/*', '*/var/log/*',
'*/.*log', '*/.*log',
) )
...@@ -394,19 +393,33 @@ class SlapOSInstanceTestCase(unittest.TestCase): ...@@ -394,19 +393,33 @@ class SlapOSInstanceTestCase(unittest.TestCase):
# copy log files from standalone # copy log files from standalone
for standalone_log in glob.glob(os.path.join( for standalone_log in glob.glob(os.path.join(
cls._base_directory, 'var', 'log', '*')): cls._base_directory, 'var', 'log', '*')):
cls._snapshot_instance_file(standalone_log, name) cls._copySnapshot(standalone_log, name)
# copy config and log files from partitions # copy config and log files from partitions
for pattern in cls._save_instance_file_pattern_list: for (dirpath, dirnames, filenames) in os.walk(cls.slap.instance_directory):
for f in glob.glob(os.path.join(cls.slap.instance_directory, pattern)): for dirname in list(dirnames):
cls._snapshot_instance_file(f, name) dirabspath = os.path.join(dirpath, dirname)
if any(fnmatch.fnmatch(
dirabspath,
pattern,
) for pattern in cls._save_instance_file_pattern_list):
cls._copySnapshot(dirabspath, name)
# don't recurse, since _copySnapshot is already recursive
dirnames.remove(dirname)
for filename in filenames:
fileabspath = os.path.join(dirpath, filename)
if any(fnmatch.fnmatch(
fileabspath,
pattern,
) for pattern in cls._save_instance_file_pattern_list):
cls._copySnapshot(fileabspath, name)
def tearDown(self): def tearDown(self):
self._storeSnapshot(self.id()) self._storeSnapshot(self.id())
@classmethod @classmethod
def _snapshot_instance_file(cls, source_file_name, name): def _copySnapshot(cls, source_file_name, name):
"""Save a file for later inspection. """Save a file, symbolic link or directory for later inspection.
The path are made relative to slapos root directory and The path are made relative to slapos root directory and
we keep the same directory structure. we keep the same directory structure.
...@@ -423,12 +436,24 @@ class SlapOSInstanceTestCase(unittest.TestCase): ...@@ -423,12 +436,24 @@ class SlapOSInstanceTestCase(unittest.TestCase):
cls._test_file_snapshot_directory, cls._test_file_snapshot_directory,
cls.software_id, cls.software_id,
name, name,
relative_path) relative_path,
)
destination_dirname = os.path.dirname(destination) destination_dirname = os.path.dirname(destination)
mkdir_p(destination_dirname) mkdir_p(destination_dirname)
if os.path.isfile(source_file_name): if os.path.islink(
source_file_name) and not os.path.exists(source_file_name):
cls.logger.debug(
"copy broken symlink %s as %s", source_file_name, destination)
with open(destination, 'w') as f:
f.write('broken symink to {}\n'.format(os.readlink(source_file_name)))
elif os.path.isfile(source_file_name):
cls.logger.debug("copy %s as %s", source_file_name, destination) cls.logger.debug("copy %s as %s", source_file_name, destination)
shutil.copy(source_file_name, destination) shutil.copy(source_file_name, destination)
elif os.path.isdir(source_file_name):
cls.logger.debug("copy directory %s as %s", source_file_name, destination)
# we copy symlinks as symlinks, so that this does not fail when
# we copy a directory containing broken symlinks.
shutil.copytree(source_file_name, destination, symlinks=True)
# implementation methods # implementation methods
@classmethod @classmethod
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment