Beispiel #1
0
 def setUp(self):
     TestCase.setUp(self)
     self._var_verbose = False
     self._var_cygwin_p = (sys.platform.startswith("cygwin")
                           or sys.platform.startswith("linux"))
     self.obj = CygAptSetup(
         self._var_cygwin_p,
         self._var_verbose,
         self._var_arch,
     )
     self.obj.setTmpDir(self._dir_tmp)
     self.obj.setAppName(self._var_exename)
     self.obj.setSetupDir(self._dir_confsetup)
     self.obj.getRC().ROOT = self._dir_mtroot
Beispiel #2
0
 def setUp(self):
     TestCase.setUp(self);
     self._var_verbose = False;
     self._var_cygwin_p = sys.platform.startswith("cygwin");
     self.obj = CygAptSetup(self._var_cygwin_p, self._var_verbose);
     self.obj.setTmpDir(self._dir_tmp);
     self.obj.setAppName(self._var_exename);
     self.obj.setSetupDir(self._dir_confsetup);
     self.obj.getRC().ROOT = self._dir_mtroot;
Beispiel #3
0
    def main(self):
        # parse command line arguments
        cap = CygAptArgParser(scriptname=self.getAppName())
        args = cap.parse()

        # initialize main variables with command line arguments and options
        main_command = args.command
        main_files = args.package[:]
        main_files.insert(0, main_command)
        main_packagename = None
        if len(args.package) > 0:
            main_packagename = args.package[0]
        main_verbose = args.verbose
        main_download_p = args.download_p
        main_mirror = args.mirror
        main_distname = args.distname
        main_noupdate = args.noupdate
        main_nodeps_p = args.nodeps_p
        main_regex_search = args.regex_search
        main_nobarred = args.force
        main_verify = args.verify
        main_nopostinstall = args.nopostinstall
        main_nopostremove = args.nopostremove
        main_downloads = None
        main_dists = 0
        main_installed = 0

        # locate and parse the configuration file
        main_cyg_apt_rc = self.getConfigPath()

        config = None
        if main_cyg_apt_rc:
            config = cautils.parse_rc(main_cyg_apt_rc)
        elif (main_command != "setup"):
            print("{0}: no .{0}: run \"{0} setup\"".format(self.getAppName()),
                  file=sys.stderr)
            return 1

        # create a CygAptSetup instance and its dependencies
        main_cygwin_p = (sys.platform == "cygwin")

        is_64_bit = False
        if main_cygwin_p:
            # Running Cygwin python, so python architecture == Cygwin architecture
            if 2**32 < sys.maxsize:
                is_64_bit = True
        elif config and main_command != 'setup':
            # Running Windows python, so examine cygwin1.dll
            pathMapper = PathMapper(config.ROOT.rstrip('\\/'), main_cygwin_p)
            if cautils.pe_is_64_bit(pathMapper.mapPath("/bin/cygwin1.dll")):
                is_64_bit = True

        if is_64_bit:
            main_arch = 'x86_64'
        else:
            main_arch = 'x86'

        cas = CygAptSetup(main_cygwin_p, main_verbose, main_arch)

        # run command
        if (main_command == "setup"):
            cas.setup(args.force)
            return 0
        elif (main_command == "help"):
            cas.usage(main_cyg_apt_rc)
            return 0
        elif (main_command == "update"):
            cas.update(main_cyg_apt_rc, main_verify, main_mirror=main_mirror)
            return 0

        # make an update if needed
        update_not_needed = [
            "ball",
            "find",
            "help",
            "purge",
            "remove",
            "version",
            "filelist",
            "update",
            "setup",
            "md5",
        ]
        always_update = config.always_update
        always_update = always_update and\
            main_command not in update_not_needed and\
            not main_noupdate
        if always_update:
            cas.update(main_cyg_apt_rc, main_verify, main_mirror=main_mirror)

        if main_command and main_command in dir(CygApt):
            cyg_apt = CygApt(
                main_packagename,
                main_files,
                main_cyg_apt_rc,
                main_cygwin_p,
                main_download_p,
                main_mirror,
                main_downloads,
                main_distname,
                main_nodeps_p,
                main_regex_search,
                main_nobarred,
                main_nopostinstall,
                main_nopostremove,
                main_dists,
                main_installed,
                self.getAppName(),
                main_verbose,
                main_arch,
            )

            getattr(cyg_apt, main_command)()
        else:
            cas.usage(main_cyg_apt_rc)

        return 0
Beispiel #4
0
    def main(self):
        main_downloads = None;
        main_dists = 0;
        main_installed = 0;
        main_packagename = None;
        main_cyg_apt_rc = None;
        home_cyg_apt_rc = None;
        main_verbose = False;

        main_cygwin_p = (sys.platform == "cygwin");
        cas = CygAptSetup(main_cygwin_p, main_verbose);
        update_not_needed = [
            "ball", "find", "help", "purge", "remove", "version", 
            "filelist", "update", "setup", "md5",
        ];

        ob = CygAptOb(True);
        cas.usage();
        usage = ob.getFlush();

        cap = CygAptArgParser(usage=usage, scriptname=self.getAppName());
        args = cap.parse();

        main_command = args.command;

        main_files = args.package[:];
        main_files.insert(0, main_command);
        if len(args.package) > 0:
            main_packagename = args.package[0];
        else:
            main_packagename = None;

        main_verbose = args.verbose;
        main_download_p = args.download_p;
        main_mirror = args.mirror;
        main_distname = args.distname;
        main_noupdate = args.noupdate;
        main_nodeps_p = args.nodeps_p;
        main_regex_search = args.regex_search;
        main_nobarred = args.force;
        main_verify = args.verify;
        main_nopostinstall = args.nopostinstall;
        main_nopostremove = args.nopostremove;


        cas.setVerbose(main_verbose);

        # Take most of our configuration from .cyg-apt
        # preferring .cyg-apt in current directory over $(HOME)/.cyg-apt
        cwd_cyg_apt_rc = os.path.join(
            os.getcwd(),
            ".{0}".format(self.getAppName())
        );
        if os.path.exists(cwd_cyg_apt_rc):
            main_cyg_apt_rc = cwd_cyg_apt_rc;
        elif "HOME" in os.environ:
            home_cyg_apt_rc = os.path.join(
                os.environ['HOME'],
                ".{0}".format(self.getAppName())
            );
            if os.path.exists(home_cyg_apt_rc):
                main_cyg_apt_rc = home_cyg_apt_rc;


        if main_cyg_apt_rc:
            # Take our configuration from .cyg-apt
            # Command line options can override, but only for this run.
            main_cyg_apt_rc = main_cyg_apt_rc.replace("\\","/");
        elif (main_command != "setup"):
            print(
                "{0}: no .{0}: run \"{0} setup\"".format(self.getAppName()),
                file=sys.stderr
            );
            return 1;

        if (main_command == "setup"):
            cas.setup(args.force);
            return 0;
        elif (main_command == "help"):
            cas.usage(main_cyg_apt_rc);
            return 0;
        elif (main_command == "update"):
            cas.update(main_cyg_apt_rc, main_verify, main_mirror=main_mirror);
            return 0;
        always_update = cautils.parse_rc(main_cyg_apt_rc);
        always_update = always_update and\
            main_command not in update_not_needed and\
            not main_noupdate;
        if always_update:
            cas.update(main_cyg_apt_rc, main_verify, main_mirror=main_mirror);

        if main_command and main_command in dir(CygApt):
            cyg_apt = CygApt(
                main_packagename,
                main_files,
                main_cyg_apt_rc,
                main_cygwin_p,
                main_download_p,
                main_mirror,
                main_downloads,
                main_distname,
                main_nodeps_p,
                main_regex_search,
                main_nobarred,
                main_nopostinstall,
                main_nopostremove,
                main_dists,
                main_installed,
                self.getAppName(),
                main_verbose
            );

            getattr(cyg_apt, main_command)();
        else:
            cas.usage(main_cyg_apt_rc);

        return 0;
Beispiel #5
0
class TestSetup(TestCase):
    def setUp(self):
        TestCase.setUp(self);
        self._var_verbose = False;
        self._var_cygwin_p = (
            sys.platform.startswith("cygwin")
            or sys.platform.startswith("linux")
        );
        self.obj = CygAptSetup(
            self._var_cygwin_p,
            self._var_verbose,
            self._var_arch,
        );
        self.obj.setTmpDir(self._dir_tmp);
        self.obj.setAppName(self._var_exename);
        self.obj.setSetupDir(self._dir_confsetup);
        self.obj.getRC().ROOT = self._dir_mtroot;

    def test__init__(self):
        self.assertTrue(isinstance(self.obj, CygAptSetup));
        self.assertEqual(self.obj.getCygwinPlatform(), self._var_cygwin_p);
        self.assertEqual(self.obj.getVerbose(), self._var_verbose);

    def testGetSetupRc(self):
        badlocation = os.path.join(self._var_tmpdir, "not_exist_file");
        last_cache, last_mirror = self.obj.getSetupRc(badlocation);
        self.assertEqual(last_cache, None);
        self.assertEqual(last_mirror, None);

        last_cache, last_mirror = self.obj.getSetupRc(self._dir_confsetup);
        self.assertEqual(last_cache, self._dir_execache);
        self.assertEqual(last_mirror, self._var_mirror);

    def testGetPre17Last(self):
        location = self._var_tmpdir;
        last_mirror = "http://cygwin.uib.no/";
        last_cache = os.path.join(self._var_tmpdir, "last_cache");
        os.mkdir(last_cache);
        lm_file = os.path.join(self._var_tmpdir, "last-mirror");
        lc_file = os.path.join(self._var_tmpdir, "last-cache");
        lm_stream = open(lm_file, 'w');
        lm_stream.write(last_mirror);
        lm_stream.close();
        lc_stream = open(lc_file, 'w');
        lc_stream.write(last_cache);
        lc_stream.close();

        rlast_cache, rlast_mirror = self.obj._getPre17Last(location);
        self.assertEqual(last_cache, rlast_cache);
        self.assertEqual(last_mirror, rlast_mirror);

    def testUpdateWithGoodMirrorSignature(self):
        if not self._var_cygwin_p:
            self.skipTest("requires cygwin or linux");

        self._writeUserConfig(self._file_user_config);

        self.obj._gpgImport(self.obj.GPG_CYG_PUBLIC_RING_URI);
        self.obj.update(self._file_user_config, True, self._var_mirror_http);

    def testUpdateWithBadMirrorSignature(self):
        if not self._var_cygwin_p:
            self.skipTest("requires cygwin or linux");

        self._writeUserConfig(self._file_user_config);
        self.obj._gpgImport(self.obj.GPG_CYG_PUBLIC_RING_URI);

        message = '^{0}$'.format(re.escape(
            "{0}{1}{2}/setup.bz2 not signed by Cygwin's public key."
            " Use -X to ignore signatures."
            "".format(
            self._var_mirror,
            '' if self._var_mirror.endswith('/') else '/',
            self._var_setupIni.getArchitecture(),
        )));

        with self.assertRaisesRegexp(SignatureException, message):
            self.obj.update(self._file_user_config, True);

    @dataProvider('getUpdateWithoutVerifySignatureWithAnyEndSlashCountData')
    def testUpdateWithoutVerifySignatureWithAnyEndSlashCount(self, mirrorEndSlashCount):
        if not self._var_cygwin_p:
            self.skipTest("requires cygwin or linux");

        self._var_mirror = self._var_mirror.rstrip('/')+'/'*mirrorEndSlashCount;
        self._writeUserConfig(self._file_user_config);

        self.obj.update(self._file_user_config, False);

        self._assertUpdate();

    def getUpdateWithoutVerifySignatureWithAnyEndSlashCountData(self):
        return [
            [0],
            [1],
        ];

    @dataProvider('getUpdateWithoutVerifySignatureAndWithValidArchitectureData')
    def testUpdateWithoutVerifySignatureAndWithValidArchitecture(self, arch):
        if not self._var_cygwin_p:
            self.skipTest("requires cygwin or linux");

        self._var_arch = arch;
        self._var_setupIni = SetupIniProvider(self, self._var_arch);
        self.obj.setArchitecture(self._var_arch);

        self._writeUserConfig(self._file_user_config);

        self.obj.update(self._file_user_config, False);

        self._assertUpdate();

    def getUpdateWithoutVerifySignatureAndWithValidArchitectureData(self):
        return [
            ["x86"],
            ["x86_64"],
        ];

    def testUpdateWithoutMirror(self):
        if not self._var_cygwin_p:
            self.skipTest("requires cygwin or linux");

        self._var_mirror = "";
        self._writeUserConfig(self._file_user_config);

        message = '^{0}$'.format(re.escape(
            'A mirror must be specified on the configuration file "{0}"'
            ' or with the command line option "--mirror".'
            ' See cygwin.com/mirrors.html for the list of mirrors.'
            ''.format(self._file_user_config),
        ));

        with self.assertRaisesRegexp(UnexpectedValueException, message):
            self.obj.update(self._file_user_config, False);

    def testUpdateWithSetupIniFieldWarnDeprecationWarning(self):
        if not self._var_cygwin_p:
            self.skipTest("requires cygwin");

        self._writeUserConfig(self._file_user_config, keepBC=True);

        self._assertDeprecatedWarning(
            "The configuration field `setup_ini` is deprecated since version"
            " 1.1 and will be removed in 2.0.",
            self.obj.update,
            self._file_user_config,
            False,
        );

        self._assertUpdate(keepBC=True);

    def testUpdateWithoutSetupIniFieldNotWarnDeprecationWarning(self):
        if not self._var_cygwin_p:
            self.skipTest("requires cygwin");

        self._writeUserConfig(self._file_user_config);

        self._assertNotDeprecatedWarning(
            "The configuration field `setup_ini` is deprecated since version"
            " 1.1 and will be removed in 2.0.",
            self.obj.update,
            self._file_user_config,
            False,
        );

    def testSetup(self):
        if not self._var_cygwin_p:
            self.assertRaises(PlatformException, self.obj.setup);
            return;

        # env HOME not exists
        os.environ.pop('HOME');
        self.assertRaises(EnvironementException, self.obj.setup);
        os.environ['HOME'] = self._dir_user;

        # config file already isset
        f = open(self._file_user_config, 'w');
        f.close();
        self.assertRaises(PathExistsException, self.obj.setup);
        self.assertTrue(os.path.exists(self._file_user_config));

        os.remove(self._file_user_config);

        # next
        # mirror end with one slash
        self._var_mirror = self._var_mirror_http.rstrip('/')+'/';
        self._writeSetupRc(self._file_setup_rc);
        self.obj._gpgImport(self.obj.GPG_CYG_PUBLIC_RING_URI);
        self.obj.setup();

        # create a default user configuration file
        self.assertTrue(os.path.isfile(self._file_user_config));
        with open(self._file_user_config, 'r') as f :
            self.assertEqual("\n".join([
                "# The distribution, current previous or test [curr, prev, test].",
                '# Usually you want the "curr" version of a package.',
                'distname="curr"',
                "",
                "# Your package cache as a POSIX path: example /e/home/cygwin_package_cache",
                'cache="{self[_dir_execache]}"',
                "",
                "# Packages which cyg-apt can't change under Cygwin since it depends on them.",
                "# Run cyg-apt under DOS with -f (force) option to change these packages.",
                "# Treat Cygwin core packages with CAUTION.",
                'barred=""',
                "",
                "# URL of your Cygwin mirror: example http://mirror.internode.on.net/pub/cygwin/",
                'mirror="{self[_var_mirror]}"',
                "",
                "# Always update setup.ini before any command that uses it. cyg-apt will be",
                "# faster and use less bandwidth if False but you will have to run the update",
                "# command manually.",
                'always_update="False"',
                "",
                "# setup.ini lists available packages and is downloaded from the top level",
                "# of the downloaded mirror. Standard location is /etc/setup/setup.ini,",
                "# seutp-2.ini for Cygwin 1.7 Beta",
                "# Deprecated since version 1.1 and will be removed in 2.0.",
                '# setup_ini="{self[_file_setup_ini]}"',
                "",
                "# The root of your Cygwin installation as a windows path",
                'ROOT="{self[_dir_mtroot]}"',
                "",
                "",
            ]).format(self=vars(self)), f.read());

        # create setup.ini on `/etc/setup/`
        self.assertFalse(os.path.isfile(self._file_setup_ini));

        # create setup.ini on `<cachedir>/<mirror>/<arch>/`
        setupIniPath = os.path.join(
            self._getDownloadDir(),
            self._var_arch,
            "setup.ini",
        );
        self.assertTrue(os.path.isfile(setupIniPath));

        # mirror end without slash
        self._var_mirror = self._var_mirror_http.rstrip('/');
        self._writeSetupRc(self._file_setup_rc);
        # fail if setupIniPath will be rewrite
        os.chmod(setupIniPath, 0o000);
        self.obj.setup(True);

    def testSetupNotWarnDeprecationWarning(self):
        if not self._var_cygwin_p:
            self.skipTest("requires cygwin");

        self._var_mirror = self._var_mirror_http;
        self._writeSetupRc(self._file_setup_rc);
        self.obj._gpgImport(self.obj.GPG_CYG_PUBLIC_RING_URI);

        self._assertNotDeprecatedWarning(
            "The configuration field `setup_ini` is deprecated since version"
            " 1.1 and will be removed in 2.0.",
            self.obj.setup,
        );

    def testWriteInstalled(self):
        if not sys.platform.startswith("cygwin"):
            self.skipTest("requires cygwin");

        real_installed_db = self._file_installed_db.replace(self._var_tmpdir, "");
        self.obj._writeInstalled(self._file_installed_db);
        self.assertTrue(os.path.exists(self._file_installed_db));
        f = open(self._file_installed_db);
        ret = f.readlines();
        ret.sort();
        f.close();
        f = open(real_installed_db);
        expected = f.readlines();
        expected.sort();
        f.close();
        self.assertEqual(ret, expected);

    def testGpgImport(self):
        if not self._var_cygwin_p:
            self.skipTest("requires cygwin or linux");

        self.obj._gpgImport(self.obj.GPG_CYG_PUBLIC_RING_URI);

        cmd = " ".join([
            "gpg",
            "--no-secmem-warning",
            "--list-public-keys",
            "--fingerprint",
        ]);
        p = Process(cmd);
        p.mustRun();
        lines = p.getOutput().splitlines(True);
        findout = False;
        for line in lines:
            if isinstance(line, bytes):
                marker = self.obj.GPG_GOOD_FINGER.encode();
            else:
                marker = self.obj.GPG_GOOD_FINGER;
            if marker in line:
                findout = True;
                break;

        self.assertTrue(findout);

    def testUsage(self):
        self.obj.usage();

    def testUsageNotContainMd5Command(self):
        try:
            self.testUsageContainCommand("md5");
        except self.failureException :
            pass;
        else:
            self.fail("Failed asserting that usage does not contain md5 command.");

    @dataProvider('getUsageContainCommandData')
    def testUsageContainCommand(self, command):
        ob = CygAptOb(True);
        try:
            self.obj.usage();
        finally:
            ret = ob.getClean();

        self.assertTrue("    {0}".format(command) in ret);

    def getUsageContainCommandData(self):
        return [
            ['postinstall'],
            ['postremove'],
            ['checksum'],
        ];

    def _assertUpdate(self, keepBC=False):
        """Asserts that the local setup.ini has been updated.

        @raise AssertionError: When the assertion is not verify.
        """
        onCache = os.path.join(
            self._getDownloadDir(),
            self._var_setupIni.getArchitecture(),
            "setup.ini"
        );

        self.assertTrue(os.path.isfile(onCache), onCache+" not exists.");

        expected = self._var_setupIni.contents;

        with open(onCache, 'r') as f :
            actual = f.read();
        self.assertEqual(expected, actual);

        if not keepBC :
            return;

        # BC layer for `setup_ini` configuration field
        onEtc = self._file_setup_ini;
        self.assertTrue(os.path.isfile(onEtc), onEtc+" not exists.");
        with open(onEtc, 'r') as f :
            actual = f.read();
        self.assertEqual(expected, actual);
Beispiel #6
0
    def setUp(self):
        TestCase.setUp(self);

        self._var_verbose = False;
        self._var_cygwin_p = sys.platform.startswith("cygwin");

        if not self._var_cygwin_p:
            self.skipTest("requires cygwin");

        setup = CygAptSetup(self._var_cygwin_p, self._var_verbose);
        setup.setTmpDir(self._dir_tmp);
        setup.setAppName(self._var_exename);
        setup.setSetupDir(self._dir_confsetup);
        setup.getRC().ROOT = self._dir_mtroot;

        setup._gpgImport(setup.GPG_CYG_PUBLIC_RING_URI);
        setup.setup();

        f = open(self._file_setup_ini, 'w');
        f.write(self._var_setupIni.contents);
        f.close();

        f = open(self._file_installed_db, 'w');
        f.write(CygApt.INSTALLED_DB_MAGIC);
        f.close();

        self._var_packagename = self._var_setupIni.pkg.name;
        self._var_files = ["", self._var_packagename];
        self._var_download_p = False;
        self._var_downloads = None;
        self._var_distname = None;
        self._var_nodeps_p = False;
        self._var_regex_search = False;
        self._var_nobarred = False;
        self._var_nopostinstall = False;
        self._var_nopostremove = False;
        self._var_dists = 0;
        self._var_installed = 0;

        self.obj = CygApt(
            self._var_packagename,
            self._var_files,
            self._file_user_config,
            self._var_cygwin_p,
            self._var_download_p,
            self._var_mirror,
            self._var_downloads,
            self._var_distname,
            self._var_nodeps_p,
            self._var_regex_search,
            self._var_nobarred,
            self._var_nopostinstall,
            self._var_nopostremove,
            self._var_dists,
            self._var_installed,
            self._var_exename,
            self._var_verbose
        );

        # set attributes
        rc = ConfigStructure();
        rc.cache = self._dir_execache;
        rc.distname = 'curr';
        rc.setup_ini = self._file_setup_ini;
        rc.ROOT = self._dir_mtroot;
        rc.always_update = False;
        rc.mirror = self._var_mirror;
        self.obj.setRC(rc);

        self.obj.setDownlaodDir(self._dir_downloads);
        self.obj.setInstalledDbFile(self._file_installed_db);
        self.obj.setSetupDir(self._dir_confsetup);

        pm = PathMapper("", False);
        pm.setRoot(self._dir_mtroot[:-1]);
        pm.setMountRoot(self._dir_mtroot);
        pm.setMap({self._dir_mtroot:self._dir_mtroot});

        expected = self._dir_mtroot;
        ret = pm.mapPath(self._dir_mtroot);
        self.assertEqual(ret, expected);
        expected = os.path.join(self._dir_mtroot, "diranme");
        ret = pm.mapPath(expected);
        self.assertEqual(ret, expected);

        self.obj.setPathMapper(pm);

        self.obj.setDists(self._var_setupIni.dists.__dict__);

        self.obj.CYG_POSTINSTALL_DIR = self._dir_postinstall;
        self.obj.CYG_PREREMOVE_DIR = self._dir_preremove;
        self.obj.CYG_POSTREMOVE_DIR = self._dir_postremove;

        self.obj.setDosBash("/usr/bin/bash");
        self.obj.setDosLn("/usr/bin/ln");

        self.obj.setPrefixRoot(self._dir_mtroot[:-1]);
        self.obj.setAbsRoot(self._dir_mtroot);
        self.obj.setInstalled({0:{}});

        self.obj.FORCE_BARRED = [self._var_setupIni.barredpkg.name];
Beispiel #7
0
class TestSetup(TestCase):
    def setUp(self):
        TestCase.setUp(self)
        self._var_verbose = False
        self._var_cygwin_p = (sys.platform.startswith("cygwin")
                              or sys.platform.startswith("linux"))
        self.obj = CygAptSetup(
            self._var_cygwin_p,
            self._var_verbose,
            self._var_arch,
        )
        self.obj.setTmpDir(self._dir_tmp)
        self.obj.setAppName(self._var_exename)
        self.obj.setSetupDir(self._dir_confsetup)
        self.obj.getRC().ROOT = self._dir_mtroot

    def test__init__(self):
        self.assertTrue(isinstance(self.obj, CygAptSetup))
        self.assertEqual(self.obj.getCygwinPlatform(), self._var_cygwin_p)
        self.assertEqual(self.obj.getVerbose(), self._var_verbose)

    def testGetSetupRc(self):
        badlocation = os.path.join(self._var_tmpdir, "not_exist_file")
        last_cache, last_mirror = self.obj.getSetupRc(badlocation)
        self.assertEqual(last_cache, None)
        self.assertEqual(last_mirror, None)

        last_cache, last_mirror = self.obj.getSetupRc(self._dir_confsetup)
        self.assertEqual(last_cache, self._dir_execache)
        self.assertEqual(last_mirror, self._var_mirror)

    def testGetPre17Last(self):
        location = self._var_tmpdir
        last_mirror = "http://cygwin.uib.no/"
        last_cache = os.path.join(self._var_tmpdir, "last_cache")
        os.mkdir(last_cache)
        lm_file = os.path.join(self._var_tmpdir, "last-mirror")
        lc_file = os.path.join(self._var_tmpdir, "last-cache")
        lm_stream = open(lm_file, 'w')
        lm_stream.write(last_mirror)
        lm_stream.close()
        lc_stream = open(lc_file, 'w')
        lc_stream.write(last_cache)
        lc_stream.close()

        rlast_cache, rlast_mirror = self.obj._getPre17Last(location)
        self.assertEqual(last_cache, rlast_cache)
        self.assertEqual(last_mirror, rlast_mirror)

    def testUpdateWithGoodMirrorSignature(self):
        if not self._var_cygwin_p:
            self.skipTest("requires cygwin or linux")

        self._writeUserConfig(self._file_user_config)

        self.obj._gpgImport(self.obj.GPG_CYG_PUBLIC_RING_URI)
        self.obj.update(self._file_user_config, True, self._var_mirror_http)

    def testUpdateWithBadMirrorSignature(self):
        if not self._var_cygwin_p:
            self.skipTest("requires cygwin or linux")

        self._writeUserConfig(self._file_user_config)
        self.obj._gpgImport(self.obj.GPG_CYG_PUBLIC_RING_URI)

        message = '^{0}$'.format(
            re.escape("{0}{1}{2}/setup.bz2 not signed by Cygwin's public key."
                      " Use -X to ignore signatures."
                      "".format(
                          self._var_mirror,
                          '' if self._var_mirror.endswith('/') else '/',
                          self._var_setupIni.getArchitecture(),
                      )))

        with self.assertRaisesRegexp(SignatureException, message):
            self.obj.update(self._file_user_config, True)

    @dataProvider('getUpdateWithoutVerifySignatureWithAnyEndSlashCountData')
    def testUpdateWithoutVerifySignatureWithAnyEndSlashCount(
            self, mirrorEndSlashCount):
        if not self._var_cygwin_p:
            self.skipTest("requires cygwin or linux")

        self._var_mirror = self._var_mirror.rstrip(
            '/') + '/' * mirrorEndSlashCount
        self._writeUserConfig(self._file_user_config)

        self.obj.update(self._file_user_config, False)

        self._assertUpdate()

    def getUpdateWithoutVerifySignatureWithAnyEndSlashCountData(self):
        return [
            [0],
            [1],
        ]

    @dataProvider('getUpdateWithoutVerifySignatureAndWithValidArchitectureData'
                  )
    def testUpdateWithoutVerifySignatureAndWithValidArchitecture(self, arch):
        if not self._var_cygwin_p:
            self.skipTest("requires cygwin or linux")

        self._var_arch = arch
        self._var_setupIni = SetupIniProvider(self, self._var_arch)
        self.obj.setArchitecture(self._var_arch)

        self._writeUserConfig(self._file_user_config)

        self.obj.update(self._file_user_config, False)

        self._assertUpdate()

    def getUpdateWithoutVerifySignatureAndWithValidArchitectureData(self):
        return [
            ["x86"],
            ["x86_64"],
        ]

    def testUpdateWithoutMirror(self):
        if not self._var_cygwin_p:
            self.skipTest("requires cygwin or linux")

        self._var_mirror = ""
        self._writeUserConfig(self._file_user_config)

        message = '^{0}$'.format(
            re.escape(
                'A mirror must be specified on the configuration file "{0}"'
                ' or with the command line option "--mirror".'
                ' See cygwin.com/mirrors.html for the list of mirrors.'
                ''.format(self._file_user_config), ))

        with self.assertRaisesRegexp(UnexpectedValueException, message):
            self.obj.update(self._file_user_config, False)

    def testUpdateWithSetupIniFieldWarnDeprecationWarning(self):
        if not self._var_cygwin_p:
            self.skipTest("requires cygwin")

        self._writeUserConfig(self._file_user_config, keepBC=True)

        self._assertDeprecatedWarning(
            "The configuration field `setup_ini` is deprecated since version"
            " 1.1 and will be removed in 2.0.",
            self.obj.update,
            self._file_user_config,
            False,
        )

        self._assertUpdate(keepBC=True)

    def testUpdateWithoutSetupIniFieldNotWarnDeprecationWarning(self):
        if not self._var_cygwin_p:
            self.skipTest("requires cygwin")

        self._writeUserConfig(self._file_user_config)

        self._assertNotDeprecatedWarning(
            "The configuration field `setup_ini` is deprecated since version"
            " 1.1 and will be removed in 2.0.",
            self.obj.update,
            self._file_user_config,
            False,
        )

    def testSetup(self):
        if not self._var_cygwin_p:
            self.assertRaises(PlatformException, self.obj.setup)
            return

        # env HOME not exists
        os.environ.pop('HOME')
        self.assertRaises(EnvironementException, self.obj.setup)
        os.environ['HOME'] = self._dir_user

        # config file already isset
        f = open(self._file_user_config, 'w')
        f.close()
        self.assertRaises(PathExistsException, self.obj.setup)
        self.assertTrue(os.path.exists(self._file_user_config))

        os.remove(self._file_user_config)

        # next
        # mirror end with one slash
        self._var_mirror = self._var_mirror_http.rstrip('/') + '/'
        self._writeSetupRc(self._file_setup_rc)
        self.obj._gpgImport(self.obj.GPG_CYG_PUBLIC_RING_URI)
        self.obj.setup()

        # create a default user configuration file
        self.assertTrue(os.path.isfile(self._file_user_config))
        with open(self._file_user_config, 'r') as f:
            self.assertEqual(
                "\n".join([
                    "# The distribution, current previous or test [curr, prev, test].",
                    '# Usually you want the "curr" version of a package.',
                    'distname="curr"',
                    "",
                    "# Your package cache as a POSIX path: example /e/home/cygwin_package_cache",
                    'cache="{self[_dir_execache]}"',
                    "",
                    "# Packages which cyg-apt can't change under Cygwin since it depends on them.",
                    "# Run cyg-apt under DOS with -f (force) option to change these packages.",
                    "# Treat Cygwin core packages with CAUTION.",
                    'barred=""',
                    "",
                    "# URL of your Cygwin mirror: example http://mirror.internode.on.net/pub/cygwin/",
                    'mirror="{self[_var_mirror]}"',
                    "",
                    "# Always update setup.ini before any command that uses it. cyg-apt will be",
                    "# faster and use less bandwidth if False but you will have to run the update",
                    "# command manually.",
                    'always_update="False"',
                    "",
                    "# setup.ini lists available packages and is downloaded from the top level",
                    "# of the downloaded mirror. Standard location is /etc/setup/setup.ini,",
                    "# seutp-2.ini for Cygwin 1.7 Beta",
                    "# Deprecated since version 1.1 and will be removed in 2.0.",
                    '# setup_ini="{self[_file_setup_ini]}"',
                    "",
                    "# The root of your Cygwin installation as a windows path",
                    'ROOT="{self[_dir_mtroot]}"',
                    "",
                    "",
                ]).format(self=vars(self)), f.read())

        # create setup.ini on `/etc/setup/`
        self.assertFalse(os.path.isfile(self._file_setup_ini))

        # create setup.ini on `<cachedir>/<mirror>/<arch>/`
        setupIniPath = os.path.join(
            self._getDownloadDir(),
            self._var_arch,
            "setup.ini",
        )
        self.assertTrue(os.path.isfile(setupIniPath))

        # mirror end without slash
        self._var_mirror = self._var_mirror_http.rstrip('/')
        self._writeSetupRc(self._file_setup_rc)
        # fail if setupIniPath will be rewrite
        os.chmod(setupIniPath, 0o000)
        self.obj.setup(True)

    def testSetupNotWarnDeprecationWarning(self):
        if not self._var_cygwin_p:
            self.skipTest("requires cygwin")

        self._var_mirror = self._var_mirror_http
        self._writeSetupRc(self._file_setup_rc)
        self.obj._gpgImport(self.obj.GPG_CYG_PUBLIC_RING_URI)

        self._assertNotDeprecatedWarning(
            "The configuration field `setup_ini` is deprecated since version"
            " 1.1 and will be removed in 2.0.",
            self.obj.setup,
        )

    def testWriteInstalled(self):
        if not sys.platform.startswith("cygwin"):
            self.skipTest("requires cygwin")

        real_installed_db = self._file_installed_db.replace(
            self._var_tmpdir, "")
        self.obj._writeInstalled(self._file_installed_db)
        self.assertTrue(os.path.exists(self._file_installed_db))
        f = open(self._file_installed_db)
        ret = f.readlines()
        ret.sort()
        f.close()
        f = open(real_installed_db)
        expected = f.readlines()
        expected.sort()
        f.close()
        self.assertEqual(ret, expected)

    def testGpgImport(self):
        if not self._var_cygwin_p:
            self.skipTest("requires cygwin or linux")

        self.obj._gpgImport(self.obj.GPG_CYG_PUBLIC_RING_URI)

        cmd = " ".join([
            "gpg",
            "--no-secmem-warning",
            "--list-public-keys",
            "--fingerprint",
        ])
        p = Process(cmd)
        p.mustRun()
        lines = p.getOutput().splitlines(True)
        findout = False
        for line in lines:
            if isinstance(line, bytes):
                marker = self.obj.GPG_GOOD_FINGER.encode()
            else:
                marker = self.obj.GPG_GOOD_FINGER
            if marker in line:
                findout = True
                break

        self.assertTrue(findout)

    def testUsage(self):
        self.obj.usage()

    def testUsageNotContainMd5Command(self):
        try:
            self.testUsageContainCommand("md5")
        except self.failureException:
            pass
        else:
            self.fail(
                "Failed asserting that usage does not contain md5 command.")

    @dataProvider('getUsageContainCommandData')
    def testUsageContainCommand(self, command):
        ob = CygAptOb(True)
        try:
            self.obj.usage()
        finally:
            ret = ob.getClean()

        self.assertTrue("    {0}".format(command) in ret)

    def getUsageContainCommandData(self):
        return [
            ['postinstall'],
            ['postremove'],
            ['checksum'],
        ]

    def _assertUpdate(self, keepBC=False):
        """Asserts that the local setup.ini has been updated.

        @raise AssertionError: When the assertion is not verify.
        """
        onCache = os.path.join(self._getDownloadDir(),
                               self._var_setupIni.getArchitecture(),
                               "setup.ini")

        self.assertTrue(os.path.isfile(onCache), onCache + " not exists.")

        expected = self._var_setupIni.contents

        with open(onCache, 'r') as f:
            actual = f.read()
        self.assertEqual(expected, actual)

        if not keepBC:
            return

        # BC layer for `setup_ini` configuration field
        onEtc = self._file_setup_ini
        self.assertTrue(os.path.isfile(onEtc), onEtc + " not exists.")
        with open(onEtc, 'r') as f:
            actual = f.read()
        self.assertEqual(expected, actual)
Beispiel #8
0
class TestSetup(TestCase):
    def setUp(self):
        TestCase.setUp(self);
        self._var_verbose = False;
        self._var_cygwin_p = sys.platform.startswith("cygwin");
        self.obj = CygAptSetup(self._var_cygwin_p, self._var_verbose);
        self.obj.setTmpDir(self._dir_tmp);
        self.obj.setAppName(self._var_exename);
        self.obj.setSetupDir(self._dir_confsetup);
        self.obj.getRC().ROOT = self._dir_mtroot;

    def test__init__(self):
        self.assertTrue(isinstance(self.obj, CygAptSetup));
        self.assertEqual(self.obj.getCygwinPlatform(), self._var_cygwin_p);
        self.assertEqual(self.obj.getVerbose(), self._var_verbose);

    def testGetSetupRc(self):
        if not self._var_cygwin_p:
            self.skipTest("requires cygwin");

        badlocation = os.path.join(self._var_tmpdir, "not_exist_file");
        last_cache, last_mirror = self.obj.getSetupRc(badlocation);
        self.assertEqual(last_cache, None);
        self.assertEqual(last_mirror, None);

        last_cache, last_mirror = self.obj.getSetupRc(self._dir_confsetup);
        self.assertEqual(last_cache, self._dir_execache);
        self.assertEqual(last_mirror, self._var_mirror_http);

    def testGetPre17Last(self):
        if not self._var_cygwin_p:
            self.skipTest("requires cygwin");

        location = self._var_tmpdir;
        last_mirror = "http://cygwin.xl-mirror.nl/";
        last_cache = os.path.join(self._var_tmpdir, "last_cache");
        os.mkdir(last_cache);
        lm_file = os.path.join(self._var_tmpdir, "last-mirror");
        lc_file = os.path.join(self._var_tmpdir, "last-cache");
        lm_stream = open(lm_file, 'w');
        lm_stream.write(last_mirror);
        lm_stream.close();
        lc_stream = open(lc_file, 'w');
        lc_stream.write(last_cache);
        lc_stream.close();

        rlast_cache, rlast_mirror = self.obj._getPre17Last(location);
        self.assertEqual(last_cache, rlast_cache);
        self.assertEqual(last_mirror, rlast_mirror);

    def testUpdate(self):
        if not self._var_cygwin_p:
            self.skipTest("requires cygwin");

        self.obj._gpgImport(self.obj.GPG_CYG_PUBLIC_RING_URI);
        self.obj.setup();

        self.obj.update(self._file_user_config, True);

    def testSetup(self):
        if not self._var_cygwin_p:
            self.assertRaises(PlatformException, self.obj.setup);
            return;

        # env HOME not exists
        os.environ.pop('HOME');
        self.assertRaises(EnvironementException, self.obj.setup);
        os.environ['HOME'] = self._dir_user;

        # config file already isset
        f = open(self._file_user_config, 'w');
        f.close();
        self.assertRaises(PathExistsException, self.obj.setup);
        self.assertTrue(os.path.exists(self._file_user_config));

        os.remove(self._file_user_config);

        # next
        self.obj._gpgImport(self.obj.GPG_CYG_PUBLIC_RING_URI);
        self.obj.setup();

    def testWriteInstalled(self):
        if not self._var_cygwin_p:
            self.skipTest("requires cygwin");

        real_installed_db = self._file_installed_db.replace(self._var_tmpdir, "");
        self.obj._writeInstalled(self._file_installed_db);
        self.assertTrue(os.path.exists(self._file_installed_db));
        f = open(self._file_installed_db);
        ret = f.readlines().sort();
        f.close();
        f = open(real_installed_db);
        expected = f.readlines().sort();
        f.close();
        self.assertEqual(ret, expected);

    def testGpgImport(self):
        if not self._var_cygwin_p:
            self.skipTest("requires cygwin");

        self.obj._gpgImport(self.obj.GPG_CYG_PUBLIC_RING_URI);

        cmd = " ".join([
            "gpg",
            "--no-secmem-warning",
            "--list-public-keys",
            "--fingerprint",
        ]);
        p = subprocess.Popen(cmd, shell=True,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE);
        if p.wait():
            raise RuntimeError(p.stderr.read());
        lines = p.stdout.readlines();
        findout = False;
        for line in lines:
            if isinstance(line, bytes):
                marker = self.obj.GPG_GOOD_FINGER.encode();
            else:
                marker = self.obj.GPG_GOOD_FINGER;
            if marker in line:
                findout = True;
                break;

        self.assertTrue(findout);

    def testUsage(self):
        self.obj.usage();
Beispiel #9
0
    def main(self):
        # parse command line arguments
        cap = CygAptArgParser(scriptname=self.getAppName());
        args = cap.parse();

        # initialize main variables with command line arguments and options
        main_command = args.command;
        main_files = args.package[:];
        main_files.insert(0, main_command);
        main_packagename = None;
        if len(args.package) > 0:
            main_packagename = args.package[0];
        main_verbose = args.verbose;
        main_download_p = args.download_p;
        main_mirror = args.mirror;
        main_distname = args.distname;
        main_noupdate = args.noupdate;
        main_nodeps_p = args.nodeps_p;
        main_regex_search = args.regex_search;
        main_nobarred = args.force;
        main_verify = args.verify;
        main_nopostinstall = args.nopostinstall;
        main_nopostremove = args.nopostremove;
        main_downloads = None;
        main_dists = 0;
        main_installed = 0;

        # locate and parse the configuration file
        main_cyg_apt_rc = self.getConfigPath();

        config = None;
        if main_cyg_apt_rc:
            config = cautils.parse_rc(main_cyg_apt_rc);
        elif (main_command != "setup"):
            print(
                "{0}: no .{0}: run \"{0} setup\"".format(self.getAppName()),
                file=sys.stderr
            );
            return 1;

        # create a CygAptSetup instance and its dependencies
        main_cygwin_p = (sys.platform == "cygwin");

        is_64_bit = False;
        if main_cygwin_p :
            # Running Cygwin python, so python architecture == Cygwin architecture
            if 2**32 < sys.maxsize :
                is_64_bit = True;
        elif config and main_command != 'setup' :
            # Running Windows python, so examine cygwin1.dll
            pathMapper = PathMapper(config.ROOT.rstrip('\\/'), main_cygwin_p);
            if cautils.pe_is_64_bit(pathMapper.mapPath("/bin/cygwin1.dll")) :
                is_64_bit = True;

        if is_64_bit :
            main_arch = 'x86_64';
        else:
            main_arch = 'x86';

        cas = CygAptSetup(main_cygwin_p, main_verbose, main_arch);

        # run command
        if (main_command == "setup"):
            cas.setup(args.force);
            return 0;
        elif (main_command == "help"):
            cas.usage(main_cyg_apt_rc);
            return 0;
        elif (main_command == "update"):
            cas.update(main_cyg_apt_rc, main_verify, main_mirror=main_mirror);
            return 0;

        # make an update if needed
        update_not_needed = [
            "ball", "find", "help", "purge", "remove", "version",
            "filelist", "update", "setup", "md5",
        ];
        always_update = config.always_update;
        always_update = always_update and\
            main_command not in update_not_needed and\
            not main_noupdate;
        if always_update:
            cas.update(main_cyg_apt_rc, main_verify, main_mirror=main_mirror);

        if main_command and main_command in dir(CygApt):
            cyg_apt = CygApt(
                main_packagename,
                main_files,
                main_cyg_apt_rc,
                main_cygwin_p,
                main_download_p,
                main_mirror,
                main_downloads,
                main_distname,
                main_nodeps_p,
                main_regex_search,
                main_nobarred,
                main_nopostinstall,
                main_nopostremove,
                main_dists,
                main_installed,
                self.getAppName(),
                main_verbose,
                main_arch,
            );

            getattr(cyg_apt, main_command)();
        else:
            cas.usage(main_cyg_apt_rc);

        return 0;