#!/usr/bin/python2

"""Tests for site_sysinfo."""

__author__ = 'dshi@google.com (Dan Shi)'

import cPickle as pickle
import filecmp
import os
import random
import shutil
import tempfile
import unittest

import common
from autotest_lib.client.bin import site_sysinfo
from autotest_lib.client.common_lib import autotemp


class diffable_logdir_test(unittest.TestCase):
    """Tests for methods in class diffable_logdir."""


    def setUp(self):
        """Initialize a temp direcotry with test files."""
        self.tempdir = autotemp.tempdir(unique_id='diffable_logdir')
        self.src_dir = os.path.join(self.tempdir.name, 'src')
        self.dest_dir = os.path.join(self.tempdir.name, 'dest')

        self.existing_files = ['existing_file_'+str(i) for i in range(3)]
        self.existing_files_folder = ['', 'sub', 'sub/sub2']
        self.existing_files_path = [os.path.join(self.src_dir, folder, f)
                                    for f,folder in zip(self.existing_files,
                                                self.existing_files_folder)]
        self.new_files = ['new_file_'+str(i) for i in range(2)]
        self.new_files_folder = ['sub', 'sub/sub3']
        self.new_files_path = [os.path.join(self.src_dir, folder, f)
                                    for f,folder in zip(self.new_files,
                                                self.new_files_folder)]

        # Create some file with random data in source directory.
        for p in self.existing_files_path:
            self.append_text_to_file(str(random.random()), p)

        self.existing_fifo_path = os.path.join(
            self.src_dir,'sub/sub2/existing_fifo')
        os.mkfifo(self.existing_fifo_path)


    def tearDown(self):
        """Clearn up."""
        self.tempdir.clean()


    def append_text_to_file(self, text, file_path):
        """Append text to the end of a file, create the file if not existed.

        @param text: text to be appended to a file.
        @param file_path: path to the file.

        """
        dir_name = os.path.dirname(file_path)
        if not os.path.exists(dir_name):
            os.makedirs(dir_name)
        with open(file_path, 'a') as f:
            f.write(text)


    def assert_trees_equal(self, dir1, dir2, ignore=None):
        """Assert two directory trees contain the same files.

        @param dir1: the left comparison directory.
        @param dir2: the right comparison directory.
        @param ignore: filenames to ignore (in any directory).

        """
        dircmps = []
        dircmps.append(filecmp.dircmp(dir1, dir2, ignore))
        while dircmps:
            dcmp = dircmps.pop()
            self.assertEqual(dcmp.left_list, dcmp.right_list)
            self.assertEqual([], dcmp.diff_files)
            dircmps.extend(dcmp.subdirs.values())


    def test_diffable_logdir_success(self):
        """Test the diff function to save new data from a directory."""
        info = site_sysinfo.diffable_logdir(self.src_dir,
                                            keep_file_hierarchy=False,
                                            append_diff_in_name=False)
        # Run the first time to collect file status.
        info.run(log_dir=None, collect_init_status=True)

        # Add new files to the test directory.
        for file_name, file_path in zip(self.new_files,
                                         self.new_files_path):
            self.append_text_to_file(file_name, file_path)

        # Temp file for existing_file_2, used to hold on the inode. If the
        # file is deleted and recreated, its inode might not change.
        existing_file_2 = self.existing_files_path[2]
        existing_file_2_tmp =  existing_file_2 + '_tmp'
        os.rename(existing_file_2, existing_file_2_tmp)

        # Append data to existing file.
        for file_name, file_path in zip(self.existing_files,
                                         self.existing_files_path):
            self.append_text_to_file(file_name, file_path)

        # Remove the tmp file.
        os.remove(existing_file_2_tmp)

        # Add a new FIFO
        new_fifo_path = os.path.join(self.src_dir, 'sub/sub2/new_fifo')
        os.mkfifo(new_fifo_path)

        # Run the second time to do diff.
        info.run(self.dest_dir, collect_init_status=False, collect_all=True)

        # Validate files in dest_dir.
        for file_name, file_path in zip(self.existing_files+self.new_files,
                                self.existing_files_path+self.new_files_path):
            file_path = file_path.replace('src', 'dest')
            with open(file_path, 'r') as f:
                self.assertEqual(file_name, f.read())

        # Assert that FIFOs are not in the diff.
        self.assertFalse(
                os.path.exists(self.existing_fifo_path.replace('src', 'dest')),
                msg='Existing FIFO present in diff sysinfo')
        self.assertFalse(
                os.path.exists(new_fifo_path.replace('src', 'dest')),
                msg='New FIFO present in diff sysinfo')

        # With collect_all=True, full sysinfo should also be present.
        full_sysinfo_path = self.dest_dir + self.src_dir
        self.assertTrue(os.path.exists(full_sysinfo_path),
                        msg='Full sysinfo not present')

        # Assert that the full sysinfo is present.
        self.assertNotEqual(self.src_dir, full_sysinfo_path)
        self.assert_trees_equal(self.src_dir, full_sysinfo_path)


class LogdirTestCase(unittest.TestCase):
    """Tests logdir.run"""

    def setUp(self):
        self.tempdir = tempfile.mkdtemp()
        self.addCleanup(shutil.rmtree, self.tempdir)

        self.from_dir = os.path.join(self.tempdir, 'from')
        self.to_dir = os.path.join(self.tempdir, 'to')
        os.mkdir(self.from_dir)
        os.mkdir(self.to_dir)

    def _destination_path(self, relative_path, from_dir=None):
        """The expected destination path for a subdir of the source directory"""
        if from_dir is None:
            from_dir = self.from_dir
        return '%s%s' % (self.to_dir, os.path.join(from_dir, relative_path))

    def test_run_recreates_absolute_source_path(self):
        """When copying files, the absolute path from the source is recreated
        in the destination folder.
        """
        os.mkdir(os.path.join(self.from_dir, 'fubar'))
        logdir = site_sysinfo.logdir(self.from_dir)
        logdir.run(self.to_dir)
        destination_path= self._destination_path('fubar')
        self.assertTrue(os.path.exists(destination_path),
                        msg='Failed to copy to %s' % destination_path)

    def test_run_skips_symlinks(self):
        os.mkdir(os.path.join(self.from_dir, 'real'))
        os.symlink(os.path.join(self.from_dir, 'real'),
                   os.path.join(self.from_dir, 'symlink'))

        logdir = site_sysinfo.logdir(self.from_dir)
        logdir.run(self.to_dir)

        destination_path_real = self._destination_path('real')
        self.assertTrue(os.path.exists(destination_path_real),
                        msg='real directory was not copied to %s' %
                        destination_path_real)
        destination_path_link = self._destination_path('symlink')
        self.assertFalse(
                os.path.exists(destination_path_link),
                msg='symlink was copied to %s' % destination_path_link)

    def test_run_resolves_symlinks_to_source_root(self):
        """run tries hard to get to the source directory before copying.

        Within the source folder, we skip any symlinks, but we first try to
        resolve symlinks to the source root itself.
        """
        os.mkdir(os.path.join(self.from_dir, 'fubar'))
        from_symlink = os.path.join(self.tempdir, 'from_symlink')
        os.symlink(self.from_dir, from_symlink)

        logdir = site_sysinfo.logdir(from_symlink)
        logdir.run(self.to_dir)

        destination_path = self._destination_path('fubar')
        self.assertTrue(os.path.exists(destination_path),
                        msg='Failed to copy to %s' % destination_path)

    def test_run_excludes_common_patterns(self):
        os.mkdir(os.path.join(self.from_dir, 'autoserv2344'))
        # Create empty file.
        open(os.path.join(self.from_dir, 'system.journal'), 'w').close()
        deeper_subdir = os.path.join('prefix', 'autoserv', 'suffix')
        os.makedirs(os.path.join(self.from_dir, deeper_subdir))

        logdir = site_sysinfo.logdir(self.from_dir)
        logdir.run(self.to_dir)

        destination_path = self._destination_path('autoserv2344')
        self.assertFalse(os.path.exists(destination_path),
                         msg='Copied banned file to %s' % destination_path)
        destination_path = self._destination_path(deeper_subdir)
        self.assertFalse(os.path.exists(destination_path),
                         msg='Copied banned file to %s' % destination_path)
        destination_path = self._destination_path('system.journal')
        self.assertFalse(os.path.exists(destination_path),
                         msg='Copied banned file to %s' % destination_path)

    def test_run_ignores_exclude_patterns_in_leading_dirs(self):
        """Exclude patterns should only be applied to path suffixes within
        from_dir, not to the root directory itself.
        """
        exclude_pattern_dir = os.path.join(self.from_dir, 'autoserv2344')
        os.makedirs(os.path.join(exclude_pattern_dir, 'fubar'))
        logdir = site_sysinfo.logdir(exclude_pattern_dir)
        logdir.run(self.to_dir)
        destination_path = self._destination_path('fubar',
                                                  from_dir=exclude_pattern_dir)
        self.assertTrue(os.path.exists(destination_path),
                        msg='Failed to copy to %s' % destination_path)

    def test_pickle_unpickle_equal(self):
        """Sanity check pickle-unpickle round-trip."""
        logdir = site_sysinfo.logdir(
                self.from_dir,
                excludes=(site_sysinfo.logdir.DEFAULT_EXCLUDES + ('a',)))
        # base_job uses protocol 2 to pickle. We follow suit.
        logdir_pickle = pickle.dumps(logdir, protocol=2)
        unpickled_logdir = pickle.loads(logdir_pickle)

        self.assertEqual(unpickled_logdir, logdir)

    def test_pickle_enforce_required_attributes(self):
        """Some attributes from this object should never be dropped.

        When running a client test against an older build, we pickle the objects
        of this class from newer version of the class and unpicle to older
        versions of the class. The older versions require some attributes to be
        present.
        """
        logdir = site_sysinfo.logdir(
                self.from_dir,
                excludes=(site_sysinfo.logdir.DEFAULT_EXCLUDES + ('a',)))
        # base_job uses protocol 2 to pickle. We follow suit.
        logdir_pickle = pickle.dumps(logdir, protocol=2)
        logdir = pickle.loads(logdir_pickle)

        self.assertEqual(logdir.additional_exclude, 'a')

    def test_pickle_enforce_required_attributes_default(self):
        """Some attributes from this object should never be dropped.

        When running a client test against an older build, we pickle the objects
        of this class from newer version of the class and unpicle to older
        versions of the class. The older versions require some attributes to be
        present.
        """
        logdir = site_sysinfo.logdir(self.from_dir)
        # base_job uses protocol 2 to pickle. We follow suit.
        logdir_pickle = pickle.dumps(logdir, protocol=2)
        logdir = pickle.loads(logdir_pickle)

        self.assertEqual(logdir.additional_exclude, None)

    def test_unpickle_handle_missing__excludes(self):
        """Sanely handle missing _excludes attribute from pickles

        This can happen when running brand new version of this class that
        introduced this attribute from older server side code in prod.
        """
        logdir = site_sysinfo.logdir(self.from_dir)
        delattr(logdir, '_excludes')
        # base_job uses protocol 2 to pickle. We follow suit.
        logdir_pickle = pickle.dumps(logdir, protocol=2)
        logdir = pickle.loads(logdir_pickle)

        self.assertEqual(logdir._excludes,
                         site_sysinfo.logdir.DEFAULT_EXCLUDES)

    def test_unpickle_handle_missing__excludes_default(self):
        """Sanely handle missing _excludes attribute from pickles

        This can happen when running brand new version of this class that
        introduced this attribute from older server side code in prod.
        """
        logdir = site_sysinfo.logdir(
                self.from_dir,
                excludes=(site_sysinfo.logdir.DEFAULT_EXCLUDES + ('a',)))
        delattr(logdir, '_excludes')
        # base_job uses protocol 2 to pickle. We follow suit.
        logdir_pickle = pickle.dumps(logdir, protocol=2)
        logdir = pickle.loads(logdir_pickle)

        self.assertEqual(
                logdir._excludes,
                (site_sysinfo.logdir.DEFAULT_EXCLUDES + ('a',)))


if __name__ == '__main__':
    unittest.main()
