#!/usr/bin/python
# Copyright 2017 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import logging
import os
import shutil
import subprocess
import tempfile
import unittest

import common
from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib import utils
from autotest_lib.site_utils import lxc
from autotest_lib.site_utils.lxc import utils as lxc_utils


class SharedHostDirTests(lxc_utils.LXCTests):
    """Unit tests for the ContainerBucket class."""

    def setUp(self):
        self.tmpdir = tempfile.mkdtemp()
        self.shared_host_path = os.path.join(self.tmpdir, 'host')


    def tearDown(self):
        shutil.rmtree(self.tmpdir)


    def testHostDirCreationAndCleanup(self):
        """Verifies that the host dir is properly created and cleaned up when
        the container bucket is set up and destroyed.
        """
        # Precondition: host path nonexistent
        self.assertFalse(os.path.isdir(self.shared_host_path))

        host_dir = lxc.SharedHostDir(self.shared_host_path)

        # Verify the host path in the host_dir.
        self.assertEqual(os.path.realpath(host_dir.path),
                         os.path.realpath(self.shared_host_path))
        self.assertTrue(os.path.isdir(self.shared_host_path))

        # Clean up, verify that the path is removed.
        host_dir.cleanup()
        self.assertFalse(os.path.isdir(self.shared_host_path))


    def testHostDirMissing(self):
        """Verifies that a missing host dir does not cause cleanup to crash.
        """
        host_dir = lxc.SharedHostDir(self.shared_host_path)

        # Manually destroy the host path
        utils.run('sudo umount %(path)s && sudo rmdir %(path)s' %
                  {'path': self.shared_host_path})

        # Verify that the host path does not exist.
        self.assertFalse(os.path.exists(self.shared_host_path))
        try:
            host_dir.cleanup()
        except:
            self.fail('SharedHostDir.cleanup crashed.\n%s' %
                      error.format_error())


    def testHostDirNotMounted(self):
        """Verifies that an unmounted host dir does not cause container bucket
        construction to crash.
        """
        # Create the shared host dir, but do not mount it.
        os.makedirs(self.shared_host_path)

        # Setup then destroy the HPM.  This should not emit any exceptions.
        try:
            host_dir = lxc.SharedHostDir(self.shared_host_path)
            host_dir.cleanup()
        except:
            self.fail('SharedHostDir crashed.\n%s' % error.format_error())


    def testHostDirAccess(self):
        """Verifies that sudo is not required to write to the shared host dir.
        """
        try:
            host_dir = lxc.SharedHostDir(self.shared_host_path)
            tempfile.NamedTemporaryFile(dir=host_dir.path)
        except OSError:
            self.fail('Unable to write to shared host dir.\n%s' %
                      error.format_error())
        finally:
            host_dir.cleanup()


class TimeoutTests(lxc_utils.LXCTests):
    """Test the timeouts on the shared host dir class."""

    def setUp(self):
        self.tmpdir = tempfile.mkdtemp()
        self.shared_host_path = os.path.join(self.tmpdir, 'host')


    def tearDown(self):
        shutil.rmtree(self.tmpdir)


    def testTimeout(self):
        """Verifies that cleanup code correctly times out.

        Cleanup can fail because of I/O caches and other similar things keeping
        the mount active.  Test that the cleanup code properly times out in
        these scenarios.
        """
        host_dir = lxc.SharedHostDir(self.shared_host_path)

        # Create a process in the shared dir to force unmounting to fail.
        p = subprocess.Popen(['sleep', '2'], cwd=self.shared_host_path)

        # Cleanup should time out.
        with self.assertRaises(error.CmdError):
            logging.debug('attempting cleanup (should fail)')
            # Use a short timeout so the test doesn't take forever.
            host_dir.cleanup(timeout=1)
            logging.debug('cleanup did not fail')

        # Kill the process occupying the mount.
        p.terminate()

        # Cleanup should succeed.
        try:
            # Use the default timeout so this doesn't raise false errors.
            host_dir.cleanup()
        except error.CmdError as e:
            self.fail('Unexpected cleanup error: %r' % e)


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