#
# Copyright (C) 2015 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

"""Unittests for classes in package.py"""


import unittest

from bsp import package
from bsp import status
from bsp import subpackage
from core import user_config_stub
from core import util_stub
from test import stubs


class PackageTest(unittest.TestCase):

    def setUp(self):
        self.stub_os = stubs.StubOs()
        self.stub_open = stubs.StubOpen(self.stub_os)
        self.stub_hashlib = stubs.StubHashlib()
        self.stub_shutil = stubs.StubShutil(self.stub_os)
        self.stub_subprocess = stubs.StubSubprocess(stub_os=self.stub_os,
                                                    stub_open=self.stub_open)
        self.stub_user_config = user_config_stub.StubUserConfig()
        self.stub_util = util_stub.StubUtil()

        package.os = self.stub_os
        package.open = self.stub_open.open
        package.shutil = self.stub_shutil
        package.hashlib = self.stub_hashlib
        package.tool.subprocess = self.stub_subprocess
        package.user_config = self.stub_user_config
        package.util = self.stub_util

        self.subpackages = {
            'subpackage1': subpackage.Subpackage('subpackage1', 'subdir1',
                                                 ['license1', 'license2']),
            'subpackage2': subpackage.Subpackage('subpackage2', 'sub/dir2',
                                                 ['license2', 'license3'])
        }
        self.pkg = package.Package('name', 'remote', 'version',
                                   self.subpackages)

        # Special packages for downloading
        self.tar_package = package.TarPackage('name', 'remote', 'hash',
                                              self.subpackages)
        self.git_package = package.GitPackage('name', 'remote', 'branch:hash',
                                              self.subpackages)

    # Helpers for subpackage status.
    def setup_missing_subpackage(self):
        # Package dir is there, but subpackage is not.
        self.stub_os.path.should_be_dir.append(self.pkg.directory)

    def setup_installed_subpackage(self, name):
        # Like missing, but subpackage is present.
        self.setup_missing_subpackage()
        subdir_path = self.stub_os.path.join(self.pkg.directory,
                                             self.pkg.subpackages[name].subdir)
        self.stub_os.path.should_be_dir.append(subdir_path)
        self.stub_os.path.should_exist.append(subdir_path)

    def setup_unknown_subpackage(self, name, path):
        # Like installed, but with a file at path.
        self.setup_installed_subpackage(name)
        self.stub_os.path.should_exist.append(path)

    def setup_linked_subpackage(self, name, path):
        # Like unknown, but with a link to the right place.
        self.setup_unknown_subpackage(name, path)
        self.stub_os.path.should_link[path] = self.stub_os.path.join(
            self.pkg.directory, self.pkg.subpackages[name].subdir)

    def setup_broken_link_subpackage(self, name, path):
        # Like missing, but with a link to the missing dir.
        self.setup_missing_subpackage()
        self.stub_os.path.should_exist.append(path)
        self.stub_os.path.should_link[path] = self.stub_os.path.join(
            self.pkg.directory, self.pkg.subpackages[name].subdir)

    def test_from_dict(self):
        package_dict = {
            'package_type': 'git',
            'remote': 'github',
            'version': 'branch:deadbeef',
            'subpackages': {
                'subpackage_1': {
                    'subdir': 'sub1',
                    'licenses': ['license.txt']
                },
                'subpackage_2': {
                    'subdir': 'sub2',
                    'licenses': []
                }
            }
        }
        pkg = package.Package.from_dict(package_dict, 'package_1')
        self.assertIsInstance(pkg, package.Package)
        self.assertEqual(len(pkg.subpackages), 2)
        self.assertTrue('subpackage_1' in pkg.subpackages)
        self.assertEqual(pkg.remote, 'github')
        self.assertEqual(pkg.version, 'branch:deadbeef')

        # Check git vs. tar packages.
        self.assertIsInstance(pkg, package.GitPackage)
        package_dict['package_type'] = 'tar'
        pkg = package.Package.from_dict(package_dict, 'package_1')
        self.assertIsInstance(pkg, package.TarPackage)

    def test_from_dict_invalid(self):
        package_dict = {
            'package_type': 'not_git_or_tar',
            'remote': 'github',
            'version': 'branch:deadbeef',
            'subpackages': {
                'subpackage_1': {
                    'subdir': 'sub1',
                    'licenses': ['license.txt']
                },
                'subpackage_2': {
                    'subdir': 'sub2',
                    'licenses': []
                }
            }
        }
        # Type must be git or tar.
        with self.assertRaises(ValueError):
            package.Package.from_dict(package_dict, 'package_1')

    def test_path(self):
        self.assertEqual(
            self.pkg.directory,
            self.stub_os.path.join(self.stub_user_config.USER_CONFIG.bsp_dir,
                                   self.pkg.name,
                                   'source_versions',
                                   self.pkg.version))
        # If we update the user config, bsp dir should update accordingly;
        # it shouldn't be cached.
        self.stub_user_config.USER_CONFIG.bsp_dir = '/who/knows/where'
        self.assertEqual(
            self.pkg.directory,
            self.stub_os.path.join(self.stub_user_config.USER_CONFIG.bsp_dir,
                                   self.pkg.name,
                                   'source_versions',
                                   self.pkg.version))


    def test_downloaded(self):
        self.stub_os.path.should_be_dir = [self.pkg.directory]
        self.assertTrue(self.pkg.is_downloaded())

    def test_not_downloaded(self):
        self.assertFalse(self.pkg.is_downloaded())

    def test_subpackage_status_nonexistent_subpackage(self):
        # Should get some sort of error about 'not_a_subpackage'
        # not being a real subpackage of pkg.
        with self.assertRaisesRegexp(package.NoSuchSubpackageError,
                                     'not_a_subpackage'):
            self.pkg.subpackage_status('not_a_subpackage', 'path')

    def test_subpackage_status_not_installed(self):
        self.assertEqual(self.pkg.subpackage_status('subpackage1', 'path')[0],
                         status.NOT_INSTALLED)
        # Not installed with no path: still not installed.
        self.assertEqual(self.pkg.subpackage_status('subpackage1')[0],
                         status.NOT_INSTALLED)

    def test_subpackage_status_installed(self):
        self.setup_installed_subpackage('subpackage1')
        self.assertEqual(self.pkg.subpackage_status('subpackage1', 'path')[0],
                         status.INSTALLED)
        # Installed with no path: still installed.
        self.assertEqual(self.pkg.subpackage_status('subpackage1')[0],
                         status.INSTALLED)


    def test_subpackage_status_linked(self):
        self.setup_linked_subpackage('subpackage1', 'link')
        self.assertEqual(self.pkg.subpackage_status('subpackage1', 'link')[0],
                         status.LINKED)
        # Linked with no path: just installed.
        self.assertEqual(self.pkg.subpackage_status('subpackage1')[0],
                         status.INSTALLED)


    def test_subpackage_status_missing(self):
        self.setup_missing_subpackage()
        self.assertEqual(self.pkg.subpackage_status('subpackage1', 'path')[0],
                         status.MISSING)
        # Missing with no path: still missing.
        self.assertEqual(self.pkg.subpackage_status('subpackage1')[0],
                         status.MISSING)

    def test_subpackage_status_broken_link(self):
        self.setup_broken_link_subpackage('subpackage1', 'link')
        self.assertEqual(self.pkg.subpackage_status('subpackage1', 'link')[0],
                         status.UNRECOGNIZED)
        # Broken link because missing, with no path: just missing.
        self.assertEqual(self.pkg.subpackage_status('subpackage1')[0],
                         status.MISSING)

    def test_subpackage_status_unknown(self):
        self.setup_unknown_subpackage('subpackage1', '???')
        self.assertEqual(self.pkg.subpackage_status('subpackage1', '???')[0],
                         status.UNRECOGNIZED)
        # Unknown but installed, with no path: just installed.
        self.assertEqual(self.pkg.subpackage_status('subpackage1')[0],
                         status.INSTALLED)

    def test_subpackage_status_incorrect_version(self):
        self.setup_installed_subpackage('subpackage1')
        self.pkg.version = 'different_version'
        # Different versions are treated as completely different BSPs for now.
        self.assertEqual(self.pkg.subpackage_status('subpackage1', 'path')[0],
                         status.NOT_INSTALLED)
        # Still not installed with no path.
        self.assertEqual(self.pkg.subpackage_status('subpackage1')[0],
                         status.NOT_INSTALLED)

    def test_tarball_version(self):
        file1 = stubs.StubFile('file1')
        self.stub_os.path.should_exist = ['file1']
        self.stub_open.files = {'file1': file1}
        self.stub_hashlib.should_return = '<hash_of_file1>'
        self.assertEqual(package.TarPackage.get_tarball_version('file1'),
                         '<hash_of_file1>')

    def test_tarball_invalid_version(self):
        self.stub_os.path.should_exist = []
        with self.assertRaises(package.VersionError):
            package.TarPackage.get_tarball_version('file1')

    def test_already_downloaded(self):
        self.stub_os.path.should_be_dir = [self.pkg.directory]
        # Shouldn't do any downloading - no dirs should be made.
        self.stub_os.should_makedirs = []
        self.pkg.download()

    def test_download_exception(self):
        # pkg is the abstract Package class,
        # download isn't fully implemented
        self.stub_os.should_makedirs = [self.pkg.directory]
        with self.assertRaises(NotImplementedError):
            self.pkg.download()
        # downloaded failed, should clean up the download directory.
        self.assertFalse(self.stub_os.path.exists(self.pkg.directory))

    def test_git_download_shallow(self):
        self.stub_os.should_makedirs = [self.git_package.directory]
        # Note: we don't test that tmp_dir/.git exists, because that's
        # hard to write cleanly; so we assume it is created and exists
        # as expected by clone/rev-parse.
        ls_remote = self.stub_subprocess.AddCommand(ret_out='hash')
        clone = self.stub_subprocess.AddFileCommand(pos_out=[-1])
        rev_parse = self.stub_subprocess.AddCommand(ret_out='hash')

        self.git_package.download()
        self.assertTrue(self.stub_os.path.exists(self.git_package.directory))
        ls_remote.AssertCallContained(['git', 'ls-remote'])
        clone.AssertCallContained(['git', 'clone'])
        rev_parse.AssertCallContained(['git', 'rev-parse'])

    def test_git_download_full(self):
        self.stub_os.should_makedirs = [self.git_package.directory]
        # Note: we don't test that tmp_dir/.git exists, because that's
        # hard to write cleanly; so we assume it is created and exists
        # as expected by clone/rev-parse.
        ls_remote = self.stub_subprocess.AddCommand(ret_out='wronghash')
        clone = self.stub_subprocess.AddFileCommand(pos_out=[-1])
        reset = self.stub_subprocess.AddCommand()
        rev_parse = self.stub_subprocess.AddCommand(ret_out='hash')

        self.git_package.download()
        self.assertTrue(self.stub_os.path.exists(self.git_package.directory))
        ls_remote.AssertCallContained(['git', 'ls-remote'])
        clone.AssertCallContained(['git', 'clone'])
        reset.AssertCallContained(['git', 'reset'])
        rev_parse.AssertCallContained(['git', 'rev-parse'])

    def test_git_failed_lsremote(self):
        self.stub_os.should_makedirs = [self.git_package.directory]
        ls_remote = self.stub_subprocess.AddCommand(ret_code=-1)

        with self.assertRaises(package.RemoteError):
            self.git_package.download()
        # Leave in a clean state
        self.assertFalse(self.stub_os.path.exists(self.git_package.directory))
        ls_remote.AssertCallContained(['git', 'ls-remote'])

    def test_git_failed_download(self):
        self.stub_os.should_makedirs = [self.git_package.directory]
        ls_remote = self.stub_subprocess.AddCommand(ret_out='hash')
        clone = self.stub_subprocess.AddFileCommand(pos_out=[-1],
                                                    ret_code=-1)

        with self.assertRaises(package.DownloadError):
            self.git_package.download()
        # Leave in a clean state
        self.assertFalse(self.stub_os.path.exists(self.git_package.directory))
        ls_remote.AssertCallContained(['git', 'ls-remote'])
        clone.AssertCallContained(['git', 'clone'])

    def test_git_failed_reset(self):
        self.stub_os.should_makedirs = [self.git_package.directory]
        # Note: we don't test that tmp_dir/.git exists, because that's
        # hard to write cleanly; so we assume it is created and exists
        # as expected by clone/rev-parse.
        ls_remote = self.stub_subprocess.AddCommand(ret_out='wronghash')
        clone = self.stub_subprocess.AddFileCommand(pos_out=[-1])
        reset = self.stub_subprocess.AddCommand(ret_code=-1)

        with self.assertRaises(package.VersionError):
            self.git_package.download()
        # Leave in a clean state
        self.assertFalse(self.stub_os.path.exists(self.git_package.directory))
        ls_remote.AssertCallContained(['git', 'ls-remote'])
        clone.AssertCallContained(['git', 'clone'])
        reset.AssertCallContained(['git', 'reset'])

    def test_git_wrong_version(self):
        self.stub_os.should_makedirs = [self.git_package.directory]
        # Note: we don't test that tmp_dir/.git exists, because that's
        # hard to write cleanly; so we assume it is created and exists
        # as expected by clone/rev-parse.
        ls_remote = self.stub_subprocess.AddCommand(ret_out='hash')
        clone = self.stub_subprocess.AddFileCommand(pos_out=[-1])
        rev_parse = self.stub_subprocess.AddCommand(ret_out='wronghash')

        with self.assertRaises(package.VersionError):
            self.git_package.download()
        # Leave in a clean state
        self.assertFalse(self.stub_os.path.exists(self.git_package.directory))
        ls_remote.AssertCallContained(['git', 'ls-remote'])
        clone.AssertCallContained(['git', 'clone'])
        rev_parse.AssertCallContained(['git', 'rev-parse'])

    def test_git_tarball(self):
        self.stub_os.should_makedirs = [self.git_package.directory]
        # Some sort of error about no tarballs for git packages
        with self.assertRaisesRegexp(ValueError, 'tarball'):
            self.git_package.download(tarball='file')
        # Leave in a clean state
        self.assertFalse(self.stub_os.path.exists(self.git_package.directory))

    def test_tar_download(self):
        self.stub_os.should_makedirs = [self.tar_package.directory]
        curl = self.stub_subprocess.AddFileCommand(out_args=['-o'])
        # Again, side effects of popen are hard to encode, so this doesn't
        # reflect that the '-C' output directory will get populated by tar.
        tar = self.stub_subprocess.AddFileCommand(in_args=['-C', '-xzf'])
        self.stub_hashlib.should_return = self.tar_package.version

        self.tar_package.download()
        self.assertTrue(self.stub_os.path.exists(self.tar_package.directory))
        curl.AssertCallContained(['curl', '-o'])
        tar.AssertCallContained(['tar', '-C', '-xzf'])

    def test_tar_failed_download(self):
        self.stub_os.should_makedirs = [self.tar_package.directory]
        curl = self.stub_subprocess.AddFileCommand(out_args=['-o'], ret_code=-1)
        self.stub_hashlib.should_return = self.tar_package.version

        with self.assertRaises(package.DownloadError):
            self.tar_package.download()
        # Leave in a clean state
        self.assertFalse(self.stub_os.path.exists(self.tar_package.directory))
        curl.AssertCallContained(['curl', '-o'])

    def test_tar_wrong_version(self):
        self.stub_os.should_makedirs = [self.tar_package.directory]
        curl = self.stub_subprocess.AddFileCommand(out_args=['-o'])
        self.stub_hashlib.should_return = '0xWRONG'

        with self.assertRaisesRegexp(package.VersionError,
                                     'incorrect version 0xWRONG'):
            self.tar_package.download()
        # Leave in a clean state
        self.assertFalse(self.stub_os.path.exists(self.tar_package.directory))
        curl.AssertCallContained(['curl', '-o'])

    def test_tar_bad_unzip(self):
        self.stub_os.should_makedirs = [self.tar_package.directory]
        curl = self.stub_subprocess.AddFileCommand(out_args=['-o'])
        tar = self.stub_subprocess.AddFileCommand(in_args=['-C', '-xzf'],
                                                  ret_code=-1)
        self.stub_hashlib.should_return = self.tar_package.version

        with self.assertRaises(package.UnzipError):
            self.tar_package.download()
        # Leave in a clean state
        self.assertFalse(self.stub_os.path.exists(self.tar_package.directory))
        curl.AssertCallContained(['curl', '-o'])
        tar.AssertCallContained(['tar', '-C', '-xzf'])

    def test_tar_tarball(self):
        self.stub_os.path.should_exist = ['tar_file']
        self.stub_open.files['tar_file'] = stubs.StubFile()
        self.stub_os.should_makedirs = [self.tar_package.directory]
        tar = self.stub_subprocess.AddFileCommand(in_args=['-C', '-xzf'])
        self.stub_hashlib.should_return = self.tar_package.version

        self.tar_package.download('tar_file')
        self.assertTrue(self.stub_os.path.exists(self.tar_package.directory))
        # Make sure the tar file is still where it was.
        self.assertTrue(self.stub_os.path.exists('tar_file'))
        tar.AssertCallContained(['tar', '-C', '-xzf'])

    def test_uninstall(self):
        dirs = [self.pkg.directory,
                self.stub_os.path.join(self.pkg.directory, 'subdir1'),
                self.stub_os.path.join(self.pkg.directory, 'subdir2'),
                self.stub_os.path.join(self.pkg.directory, 'subdir2',
                                       'deeper')]
        self.stub_os.path.should_be_dir.extend(dirs)
        self.stub_os.path.should_exist.extend(dirs)
        files = [self.stub_os.path.join(dirname, 'a_file') for dirname in dirs]
        self.stub_os.path.should_exist.extend(files)

        self.assertTrue(self.pkg.is_downloaded())
        self.pkg.uninstall()
        for f in files:
            self.assertFalse(self.stub_os.path.exists(f))
        for d in dirs:
            self.assertFalse(self.stub_os.path.exists(d))
            self.assertFalse(self.stub_os.path.isdir(d))
        self.assertFalse(self.pkg.is_downloaded())

    def test_get_licenses(self):
        licenses = self.pkg.get_licenses(['subpackage1', 'subpackage2'])
        expected_names = ['name.subpackage1 - license1',
                          'name.subpackage1 - license2',
                          'name.subpackage2 - license2',
                          'name.subpackage2 - license3']

        for l in licenses:
            self.assertTrue(l.name in expected_names)
            expected_names.remove(l.name)
        self.assertEqual(expected_names, [])

    def test_get_some_licenses(self):
        licenses = self.pkg.get_licenses(['subpackage2'])
        expected_names = ['name.subpackage2 - license2',
                          'name.subpackage2 - license3']

        for l in licenses:
            self.assertTrue(l.name in expected_names)
            expected_names.remove(l.name)
        self.assertEqual(expected_names, [])

    def test_get_no_licenses(self):
        licenses = self.pkg.get_licenses([])
        self.assertEqual(licenses, [])

    def test_link_subpackage(self):
        _, subpackage_ = self.pkg.subpackages.items()[0]
        subpackage_dir = self.stub_os.path.join(self.pkg.directory,
                                                subpackage_.subdir)
        self.stub_os.path.should_be_dir = [self.pkg.directory, subpackage_dir]
        self.stub_os.path.should_exist.append(subpackage_dir)
        self.stub_os.should_create_link = [(subpackage_dir, 'link_origin')]

        self.pkg.link_subpackage('subpackage1', 'link_origin')
        # Correct link should be created.
        self.assertTrue(self.stub_os.path.islink('link_origin'))
        self.assertEqual(self.stub_os.readlink('link_origin'),
                         subpackage_dir)

    def test_link_not_downloaded(self):
        with self.assertRaises(package.NotDownloadedError):
            self.pkg.link_subpackage('subpackage1', 'link_origin')
        # No link should be created.
        self.assertFalse(self.stub_os.path.exists('link_origin'))

    def test_link_missing(self):
        self.stub_os.path.should_be_dir = [self.pkg.directory]

        with self.assertRaises(package.MissingDirectoryError):
            self.pkg.link_subpackage('subpackage1', 'link_origin')
        # No link should be created.
        self.assertFalse(self.stub_os.path.exists('link_origin'))

    def test_link_fail(self):
        _, subpackage_ = self.pkg.subpackages.items()[0]
        subpackage_dir = self.stub_os.path.join(self.pkg.directory,
                                                subpackage_.subdir)
        self.stub_os.path.should_be_dir = [self.pkg.directory, subpackage_dir]
        self.stub_os.path.should_exist.append(subpackage_dir)

        with self.assertRaises(package.SubpackageLinkError):
            self.pkg.link_subpackage('subpackage1', 'link_origin')
        # No link should be created.
        self.assertFalse(self.stub_os.path.exists('link_origin'))

    def test_link_overwrite(self):
        (_, subpackage_) = self.pkg.subpackages.items()[0]
        subpackage_dir = self.stub_os.path.join(self.pkg.directory,
                                                subpackage_.subdir)
        self.stub_os.path.should_be_dir = [self.pkg.directory, subpackage_dir]
        self.stub_os.path.should_exist += [subpackage_dir, 'link_origin']

        # Should still be a link error. The caller needs to check for this.
        with self.assertRaises(package.SubpackageLinkError):
            self.pkg.link_subpackage('subpackage1', 'link_origin')
        # No link should be created, the file should still be there.
        self.assertTrue(self.stub_os.path.exists('link_origin'))
        self.assertFalse(self.stub_os.path.islink('link_origin'))

    def test_unlink(self):
        _, subpackage_ = self.pkg.subpackages.items()[0]
        subpackage_dir = self.stub_os.path.join(self.pkg.directory,
                                                subpackage_.subdir)
        self.stub_os.path.should_be_dir = [self.pkg.directory, subpackage_dir]
        self.stub_os.path.should_exist += [subpackage_dir, 'link_origin']
        self.stub_os.path.should_link['link_origin'] = subpackage_dir

        self.pkg.unlink_subpackage('subpackage1', 'link_origin')
        # Should be unlinked.
        self.assertFalse(self.stub_os.path.islink('link_origin'))
        self.assertFalse(self.stub_os.path.exists('link_origin'))

    def test_unlink_wrong_link(self):
        _, subpackage_ = self.pkg.subpackages.items()[0]
        subpackage_dir = self.stub_os.path.join(self.pkg.directory,
                                                subpackage_.subdir)
        self.stub_os.path.should_be_dir = [self.pkg.directory, subpackage_dir]
        self.stub_os.path.should_exist += [subpackage_dir, 'link_origin',
                                           'somewhere_else']
        self.stub_os.path.should_link['link_origin'] = 'somewhere_else'

        with self.assertRaises(package.SubpackageUnlinkError):
            self.pkg.unlink_subpackage('subpackage1', 'link_origin')
        # Original link should be in place.
        self.assertTrue(self.stub_os.path.exists('link_origin'))
        self.assertTrue(self.stub_os.path.islink('link_origin'))
        self.assertEqual(self.stub_os.readlink('link_origin'),
                         'somewhere_else')

    def test_unlink_no_link(self):
        _, subpackage_ = self.pkg.subpackages.items()[0]
        subpackage_dir = self.stub_os.path.join(self.pkg.directory,
                                                subpackage_.subdir)
        self.stub_os.path.should_be_dir = [self.pkg.directory, subpackage_dir]
        self.stub_os.path.should_exist += [subpackage_dir, 'link_origin']

        with self.assertRaises(package.SubpackageUnlinkError):
            self.pkg.unlink_subpackage('subpackage1', 'link_origin')
        # Original lack of link should be in place.
        self.assertTrue(self.stub_os.path.exists('link_origin'))
        self.assertFalse(self.stub_os.path.islink('link_origin'))

    def test_unlink_dead_link(self):
        _, subpackage_ = self.pkg.subpackages.items()[0]
        subpackage_dir = self.stub_os.path.join(self.pkg.directory,
                                                subpackage_.subdir)
        self.stub_os.path.should_be_dir = [self.pkg.directory, subpackage_dir]
        # Dead links don't exist for os.path purposes.
        self.stub_os.path.should_exist += [subpackage_dir]
        self.stub_os.path.should_link['link_origin'] = 'somewhere_else'

        with self.assertRaises(package.SubpackageUnlinkError):
            self.pkg.unlink_subpackage('subpackage1', 'link_origin')
        # Original dead link should be in place.
        self.assertTrue(self.stub_os.path.islink('link_origin'))
        self.assertEqual(self.stub_os.readlink('link_origin'),
                         'somewhere_else')

    def test_unlink_nothing(self):
        _, subpackage_ = self.pkg.subpackages.items()[0]
        subpackage_dir = self.stub_os.path.join(self.pkg.directory,
                                                subpackage_.subdir)
        self.stub_os.path.should_be_dir = [self.pkg.directory, subpackage_dir]
        self.stub_os.path.should_exist += [subpackage_dir]

        with self.assertRaises(package.SubpackageUnlinkError):
            self.pkg.unlink_subpackage('subpackage1', 'link_origin')
        # Should still be nothing.
        self.assertFalse(self.stub_os.path.islink('link_origin'))
        self.assertFalse(self.stub_os.path.exists('link_origin'))
