Beispiel #1
0
 def test_freeze_error(self):
     with self.assertRaises(pip_checker.PipError) as e:
         pip_checker.check(
             pip_command=[self._fake_pip_path, '--freeze-returncode=1'],
             packages=['six'],
             clean=True)
     self.assertIn('freeze', e.exception.command)
Beispiel #2
0
 def test_uninstall_error(self):
     with self.assertRaises(pip_checker.PipError) as e:
         pip_checker.check(pip_command=[
             self._fake_pip_path, '--expected-install-args=-U,six',
             '--uninstall-returncode=1', '--freeze-output=six==1.2.3\n'
         ],
                           packages=['six'],
                           clean=True)
     self.assertIn('uninstall', e.exception.command)
Beispiel #3
0
    def test_check_warning(self, mock_docker, mock__call_pypi_json_api):
        mock_docker.return_value = MockDockerClient()
        expected_list_output = [{
            'name': 'six',
            'version': '1.2.3',
            'latest_version': '1.2.4',
        }]
        expected_dependency_info = {
            'six': {
                'installed_version': '1.2.3',
                'installed_version_time': '2018-05-10T15:00:00',
                'latest_version': '1.2.4',
                'current_time': '2018-06-13T16:13:33.744591',
                'latest_version_time': '2018-06-13T18:29:51',
                'is_latest': False
            }
        }

        mock_datetime = mock.Mock()
        mock_now = mock.Mock()
        mock_now.isoformat.return_value = '2018-06-13T16:13:33.744591'
        mock_datetime.datetime.now.return_value = mock_now

        patch = mock.patch('pip_checker.datetime', mock_datetime)

        mock__call_pypi_json_api.return_value = {
            'releases': {
                '1.2.4': [
                    {
                        'upload_time': '2018-06-13T18:29:51',
                    },
                ],
                '1.2.3': [
                    {
                        'upload_time': '2018-05-10T15:00:00',
                    }
                ],
            },
        }

        with patch:
            check_result = pip_checker.check(
                pip_command=[
                    self._fake_pip_path,
                    '--check-returncode=1',
                    '--check-output=bad-check',
                    '--freeze-output=six==1.2.3\n',
                    '--list-output={}'.format(
                        json.dumps(expected_list_output))
                ],
                packages=['six'])
        expected_check_result = pip_checker.PipCheckResult(
                packages=['six'],
                result_type=pip_checker.PipCheckResultType.CHECK_WARNING,
                result_text='bad-check',
                dependency_info=expected_dependency_info)

        self.assertEqual(
            check_result,
            expected_check_result)
    def test_all_whitelists_pip_install(self):
        py2_pkgs, py3_pkgs = [], []
        for pkg in configs.WHITELIST_PKGS:
            if pkg not in configs.PKG_PY_VERSION_NOT_SUPPORTED[2]:
                py2_pkgs.append(pkg)
            if pkg not in configs.PKG_PY_VERSION_NOT_SUPPORTED[3]:
                py3_pkgs.append(pkg)

        for url, pkg in configs.WHITELIST_URLS.items():
            if pkg not in configs.PKG_PY_VERSION_NOT_SUPPORTED[2]:
                py2_pkgs.append(url)
            if pkg not in configs.PKG_PY_VERSION_NOT_SUPPORTED[3]:
                py3_pkgs.append(url)

        args = [
            # ('python', py2_pkgs),
            ('python3', py3_pkgs),
        ]
        for command, packages in args:
            pip_result = pip_checker.check([command, '-m', 'pip'],
                                           packages,
                                           clean=True)
            self.assertIsNotNone(pip_result)

            results = dict(result=pip_result.result_type.name,
                           packages=pip_result.packages,
                           description=pip_result.result_text,
                           dependency_info=pip_result.dependency_info)
            if results['result'] == 'INSTALL_ERROR':
                logging.warning(command)
                logging.warning(results['description'])
            self.assertFalse(results['result'] == 'INSTALL_ERROR')
def check():
    packages = flask.request.args.getlist('package')
    if not packages:
        return flask.make_response(
            "Request must specify at least one 'package' parameter", 400)

    sanitized_packages = _sanitize_packages(packages)
    unsupported_packages = frozenset(packages) - frozenset(sanitized_packages)
    if unsupported_packages:
        return flask.make_response(
            'Request contains unrecognized packages: {}'.format(
                ', '.join(unsupported_packages)), 400)

    python_version = flask.request.args.get('python-version')
    if not python_version:
        return flask.make_response(
            "Request must specify 'python-version' parameter", 400)
    if python_version not in PYTHON_VERSION_TO_COMMAND:
        return flask.make_response(
            'Invalid Python version specified. Must be one of: {}'.format(
                ', '.join(PYTHON_VERSION_TO_COMMAND), 400))

    python_command = PYTHON_VERSION_TO_COMMAND[python_version]

    try:
        pip_result = pip_checker.check(python_command, packages)
    except pip_checker.PipCheckerError as pip_error:
        return flask.make_response(pip_error.error_msg, 500)

    return flask.jsonify(result=pip_result.result_type.name,
                         packages=pip_result.packages,
                         description=pip_result.result_text,
                         dependency_info=pip_result.dependency_info)
Beispiel #6
0
    def test_success_with_clean(self, mock__call_pypi_json_api):
        expected_list_output = [{
            'name': 'six',
            'version': '1.2.3',
            'latest_version': '1.2.4',
        }]
        expected_dependency_info = {
            'six': {
                'installed_version': '1.2.3',
                'installed_version_time': '2018-05-10T15:00:00',
                'latest_version': '1.2.4',
                'current_time': '2018-06-13T16:13:33.744591',
                'latest_version_time': '2018-06-13T18:29:51',
                'is_latest': False
            }
        }

        mock_datetime = mock.Mock()
        mock_now = mock.Mock()
        mock_now.isoformat.return_value = '2018-06-13T16:13:33.744591'
        mock_datetime.datetime.now.return_value = mock_now

        patch = mock.patch('pip_checker.datetime', mock_datetime)

        mock__call_pypi_json_api.return_value = {
            'releases': {
                '1.2.4': [
                    {
                        'upload_time': '2018-06-13T18:29:51',
                    },
                ],
                '1.2.3': [{
                    'upload_time': '2018-05-10T15:00:00',
                }],
            },
        }

        with patch:
            check_result = pip_checker.check(pip_command=[
                self._fake_pip_path, '--expected-install-args=-U,six',
                '--uninstall-returncode=0', '--freeze-output=six==1.2.3\n',
                '--list-output={}'.format(json.dumps(expected_list_output))
            ],
                                             packages=['six'],
                                             clean=True)
        expected_check_result = pip_checker.PipCheckResult(
            packages=['six'],
            result_type=pip_checker.PipCheckResultType.SUCCESS,
            result_text=None,
            dependency_info=expected_dependency_info)

        self.assertEqual(check_result, expected_check_result)
Beispiel #7
0
 def test_install_failure(self):
     check_result = pip_checker.check(pip_command=[
         self._fake_pip_path, '--expected-install-args=-U,six',
         '--install-returncode=1', '--install-output=bad-install'
     ],
                                      packages=['six'])
     self.assertEqual(
         check_result,
         pip_checker.PipCheckResult(
             packages=['six'],
             result_type=pip_checker.PipCheckResultType.INSTALL_ERROR,
             result_text='bad-install',
             dependency_info=None))
Beispiel #8
0
    def _check(self, start_response, python_version, packages):
        if not packages:
            start_response('400 Bad Request',
                           [('Content-Type', 'text/plain; charset=utf-8')])
            return [b'Request must specify at least one package']

        if not python_version:
            start_response('400 Bad Request',
                           [('Content-Type', 'text/plain; charset=utf-8')])
            return [b'Request must specify the Python version to use']

        if python_version not in self._python_version_to_interpreter:
            start_response('400 Bad Request',
                           [('Content-Type', 'text/plain; charset=utf-8')])
            return [
                b'Invalid Python version specified. Must be one of: %s' %
                (', '.join(
                    self._python_version_to_interpreter).encode('utf-8'))
            ]
        python_command = self._python_version_to_interpreter[python_version]

        if self._install_once:
            self._shutdown()

        try:
            pip_result = pip_checker.check([python_command, '-m', 'pip'],
                                           packages,
                                           clean=self._clean)
        except pip_checker.PipError as pip_error:
            start_response('500 Internal Server Error',
                           [('Content-Type', 'text/plain; charset=utf-8')])
            with open(pip_error.stderr_path, 'r') as f:
                error_text = f.read()
            logging.error('pip command ("%s") failed with:\n%s\n',
                          pip_error.command_string, error_text)
            return [
                b'pip command ("%s") ' %
                pip_error.command_string.encode('utf-8'), b'failed with:\n',
                error_text.encode('utf-8'), b'\n'
            ]
        results = dict(result=pip_result.result_type.name,
                       packages=pip_result.packages,
                       description=pip_result.result_text,
                       dependency_info=pip_result.dependency_info)

        start_response('200 OK', [('Content-Type', 'application/json')])
        return [json.dumps(results).encode('utf-8')]
Beispiel #9
0
    def _check(self, start_response, python_version, packages):
        if not packages:
            start_response('400 Bad Request',
                           [('Content-Type', 'text/plain; charset=utf-8')])
            return [b'Request must specify at least one package']

        sanitized_packages = _sanitize_packages(packages)

        if sanitized_packages != packages:
            start_response('400 Bad Request',
                           [('Content-Type', 'text/plain; charset=utf-8')])
            return [b'Request contains third party github head packages.']

        if not python_version:
            start_response('400 Bad Request',
                           [('Content-Type', 'text/plain; charset=utf-8')])
            return [b'Request must specify the Python version to use']

        if python_version not in PYTHON_VERSION_TO_COMMAND:
            start_response('400 Bad Request',
                           [('Content-Type', 'text/plain; charset=utf-8')])
            return [
                b'Invalid Python version specified. Must be one of: %s' %
                (', '.join(PYTHON_VERSION_TO_COMMAND).encode('utf-8'))
            ]
        python_command = PYTHON_VERSION_TO_COMMAND[python_version]

        try:
            pip_result = pip_checker.check(python_command, packages)
        except pip_checker.PipCheckerError as pip_error:
            start_response('500 Internal Server Error',
                           [('Content-Type', 'text/plain; charset=utf-8')])
            logging.error('Command failed with:\n%s\n', pip_error.error_msg)
            return [b'pip command failed with:\n', pip_error.error_msg, b'\n']
        results = dict(result=pip_result.result_type.name,
                       packages=pip_result.packages,
                       description=pip_result.result_text,
                       dependency_info=pip_result.dependency_info)

        start_response('200 OK', [('Content-Type', 'application/json')])
        return [json.dumps(results).encode('utf-8')]