def test_library_change_or_addition_runs_correct_commands(self):
        """Library is required by the 'requirements.txt' file but it doesn't
        exist in 'third_party/python_libs'.
        """
        def mock_get_mismatches():
            return {
                u'flask': (u'1.1.0.1', u'1.1.1.0'),
                u'six': (u'1.15.0', None),
                u'git-dep1': (
                    self.get_git_version_string('git-dep1', 'a'),
                    self.get_git_version_string('git-dep1', 'b')),
                u'git-dep2': (
                    self.get_git_version_string('git-dep2', 'a'), None),
            }

        def mock_validate_metadata_directories():
            pass
        swap_validate_metadata_directories = self.swap(
            install_backend_python_libs, 'validate_metadata_directories',
            mock_validate_metadata_directories)

        swap_get_mismatches = self.swap(
            install_backend_python_libs, 'get_mismatches', mock_get_mismatches)

        with self.swap_check_call, self.swap_Popen, self.open_file_swap:
            with swap_get_mismatches, swap_validate_metadata_directories:
                install_backend_python_libs.main()

        self.assertEqual(
            self.cmd_token_list,
            [
                ['scripts.regenerate_requirements'],
                [
                    'pip', 'install',
                    '%s#egg=git-dep1' % (
                        self.get_git_version_string('git-dep1', 'a')),
                    '--target', common.THIRD_PARTY_PYTHON_LIBS_DIR,
                    '--upgrade', '--no-dependencies',
                ],
                [
                    'pip', 'install',
                    '%s#egg=git-dep2' % (
                        self.get_git_version_string('git-dep2', 'a')),
                    '--target', common.THIRD_PARTY_PYTHON_LIBS_DIR,
                    '--upgrade', '--no-dependencies',
                ],
                [
                    'pip', 'install', '%s==%s' % ('flask', '1.1.0.1'),
                    '--target', common.THIRD_PARTY_PYTHON_LIBS_DIR,
                    '--upgrade', '--no-dependencies',
                ],
                [
                    'pip', 'install', '%s==%s' % ('six', '1.15.0'),
                    '--target', common.THIRD_PARTY_PYTHON_LIBS_DIR,
                    '--upgrade', '--no-dependencies',
                ],
            ]
        )
Exemple #2
0
    def test_main_without_library_mismatches_calls_correct_functions(self):
        check_function_calls = {
            'subprocess_call_is_called': False
        }
        expected_check_function_calls = {
            'subprocess_call_is_called': True
        }
        def mock_call(unused_cmd_tokens, *args, **kwargs):  # pylint: disable=unused-argument
            check_function_calls['subprocess_call_is_called'] = True
            class Ret(python_utils.OBJECT):
                """Return object with required attributes."""

                def __init__(self):
                    self.returncode = 0
                def communicate(self):
                    """Return required method."""
                    return '', ''

            return Ret()

        def mock_get_mismatches():
            return {}

        print_statements = []

        def mock_print(s):
            print_statements.append(s)
        def mock_validate_metadata_directories():
            pass
        swap_validate_metadata_directories = self.swap(
            install_backend_python_libs, 'validate_metadata_directories',
            mock_validate_metadata_directories)
        swap_get_mismatches = self.swap(
            install_backend_python_libs, 'get_mismatches',
            mock_get_mismatches)
        swap_call = self.swap(subprocess, 'check_call', mock_call)
        swap_print = self.swap(python_utils, 'PRINT', mock_print)
        with swap_call, swap_get_mismatches, swap_print, self.open_file_swap:
            with swap_validate_metadata_directories:
                install_backend_python_libs.main()

        self.assertEqual(check_function_calls, expected_check_function_calls)
        self.assertEqual(
            print_statements,
            [
                'Regenerating "requirements.txt" file...',
                'All third-party Python libraries are already installed '
                'correctly.'
            ])
Exemple #3
0
    def test_main_adds_comment_to_start_of_requirements(self):
        check_function_calls = {
            'subprocess_call_is_called': False
        }
        expected_check_function_calls = {
            'subprocess_call_is_called': True
        }
        def mock_call(unused_cmd_tokens, *args, **kwargs):  # pylint: disable=unused-argument
            check_function_calls['subprocess_call_is_called'] = True
            class Ret(python_utils.OBJECT):
                """Return object with required attributes."""

                def __init__(self):
                    self.returncode = 0
                def communicate(self):
                    """Return required method."""
                    return '', ''

            return Ret()

        def mock_get_mismatches():
            return {}
        def mock_validate_metadata_directories():
            pass
        swap_validate_metadata_directories = self.swap(
            install_backend_python_libs, 'validate_metadata_directories',
            mock_validate_metadata_directories)
        swap_get_mismatches = self.swap(
            install_backend_python_libs, 'get_mismatches', mock_get_mismatches)
        swap_call = self.swap(subprocess, 'check_call', mock_call)

        expected_lines = [
            '# Developers: Please do not modify this auto-generated file.'
            ' If\n# you want to add, remove, upgrade, or downgrade libraries,'
            '\n# please change the `requirements.in` file, and then follow\n#'
            ' the instructions there to regenerate this file.\n'
        ]
        self.assertEqual(self.file_arr, [])

        with self.swap_check_call, self.open_file_swap, swap_call:
            with swap_get_mismatches, swap_validate_metadata_directories:
                install_backend_python_libs.main()

        self.assertEqual(
            self.file_arr,
            expected_lines
        )

        self.assertEqual(check_function_calls, expected_check_function_calls)
    def test_large_number_of_discrepancies_results_in_clean_install(self):
        """Test that the function reinstalls all of the libraries from scratch
        when 5 or more mismatches are found.
        """
        removed_dirs = []
        def mock_remove_dir(directory):
            removed_dirs.append(directory)
        def mock_get_mismatches():
            return {
                u'flask': (u'1.1.1', None),
                u'six': (u'1.15.0', None),
                u'simplejson': (None, u'3.16.0'),
                u'bleach': (u'3.1.4', u'3.1.5'),
                u'callbacks': (u'0.3.0', u'0.2.0'),
            }
        def mock_validate_metadata_directories():
            pass
        swap_validate_metadata_directories = self.swap(
            install_backend_python_libs, 'validate_metadata_directories',
            mock_validate_metadata_directories)
        swap_get_mismatches = self.swap(
            install_backend_python_libs, 'get_mismatches', mock_get_mismatches)

        swap_remove_dir = self.swap(shutil, 'rmtree', mock_remove_dir)
        with self.swap_check_call, self.swap_Popen, swap_remove_dir:
            with self.open_file_swap, swap_get_mismatches:
                with swap_validate_metadata_directories:
                    install_backend_python_libs.main()

        self.assertEqual(
            removed_dirs,
            [
                common.THIRD_PARTY_PYTHON_LIBS_DIR
            ]
        )

        self.assertEqual(
            self.cmd_token_list,
            [
                ['scripts.regenerate_requirements'],
                [
                    'pip', 'install', '--target',
                    common.THIRD_PARTY_PYTHON_LIBS_DIR,
                    '--no-dependencies', '-r',
                    common.COMPILED_REQUIREMENTS_FILE_PATH,
                    '--upgrade'
                ]
            ]
        )
    def test_library_removal_runs_correct_commands(self):
        """Library exists in the 'third_party/python_libs' directory but it is
        not required in the 'requirements.txt' file.
        """
        removed_dirs = []
        def mock_remove_dir(directory):
            removed_dirs.append(directory)

        def mock_get_mismatches():
            return {
                u'flask': (None, u'10.0.1'),
                u'six': (None, u'10.13.0.1')
            }

        def mock_validate_metadata_directories():
            pass

        swap_validate_metadata_directories = self.swap(
            install_backend_python_libs, 'validate_metadata_directories',
            mock_validate_metadata_directories)
        swap_get_mismatches = self.swap(
            install_backend_python_libs, 'get_mismatches', mock_get_mismatches)
        swap_remove_dir = self.swap(shutil, 'rmtree', mock_remove_dir)

        with self.swap_check_call, self.swap_Popen, swap_remove_dir:
            with self.open_file_swap, swap_get_mismatches:
                with swap_validate_metadata_directories:
                    install_backend_python_libs.main()

        self.assertEqual(
            removed_dirs,
            [
                common.THIRD_PARTY_PYTHON_LIBS_DIR
            ]
        )

        self.assertEqual(
            self.cmd_token_list,
            [
                ['scripts.regenerate_requirements'],
                [
                    'pip', 'install', '--target',
                    common.THIRD_PARTY_PYTHON_LIBS_DIR,
                    '--no-dependencies',
                    '-r', common.COMPILED_REQUIREMENTS_FILE_PATH,
                    '--upgrade'
                ]
            ]
        )
Exemple #6
0
    def test_library_version_change_is_handled_correctly(self):
        directory_names = [
            'webencodings-1.1.1.dist-info', 'webencodings-1.0.1.dist-info',
            'webencodings', 'flask', 'flask-1.1.1.dist-info',
            'flask-10.0.1.dist-info', 'six', 'six-1.15.0.dist-info',
            'six-10.13.0.egg-info', 'google_cloud_datastore-1.15.0.dist-info',
            'google_cloud_datastore-1.13.0.dist-info', 'google'
        ]

        def mock_list_dir(path):  # pylint: disable=unused-argument
            return directory_names

        paths_to_delete = []

        def mock_rm(path):
            paths_to_delete.append(
                path[len(common.THIRD_PARTY_PYTHON_LIBS_DIR) + 1:])

        def mock_is_dir(path):  # pylint: disable=unused-argument
            return True

        def mock_get_mismatches():
            return {
                u'flask': (u'1.1.1', u'10.0.1'),
                u'six': (u'1.15.0', u'10.13.0'),
                u'webencodings': (u'1.1.1', u'1.0.1'),
                u'google-cloud-datastore': (u'1.15.0', u'1.13.0')
            }

        def mock_validate_metadata_directories():
            pass

        swap_validate_metadata_directories = self.swap(
            install_backend_python_libs, 'validate_metadata_directories',
            mock_validate_metadata_directories)
        swap_get_mismatches = self.swap(install_backend_python_libs,
                                        'get_mismatches', mock_get_mismatches)
        swap_rm_tree = self.swap(shutil, 'rmtree', mock_rm)
        swap_list_dir = self.swap(os, 'listdir', mock_list_dir)
        swap_is_dir = self.swap(os.path, 'isdir', mock_is_dir)

        with self.swap_check_call, self.swap_Popen, swap_get_mismatches:
            with swap_validate_metadata_directories, self.open_file_swap:
                with swap_rm_tree, swap_list_dir, swap_is_dir:
                    install_backend_python_libs.main()

        self.assertEqual(self.cmd_token_list,
                         [['scripts.regenerate_requirements'],
                          [
                              'pip',
                              'install',
                              '%s==%s' % ('flask', '1.1.1'),
                              '--target',
                              common.THIRD_PARTY_PYTHON_LIBS_DIR,
                              '--upgrade',
                              '--no-dependencies',
                          ],
                          [
                              'pip',
                              'install',
                              '%s==%s' % ('webencodings', '1.1.1'),
                              '--target',
                              common.THIRD_PARTY_PYTHON_LIBS_DIR,
                              '--upgrade',
                              '--no-dependencies',
                          ],
                          [
                              'pip',
                              'install',
                              '%s==%s' % ('six', '1.15.0'),
                              '--target',
                              common.THIRD_PARTY_PYTHON_LIBS_DIR,
                              '--upgrade',
                              '--no-dependencies',
                          ],
                          [
                              'pip',
                              'install',
                              '%s==%s' % ('google-cloud-datastore', '1.15.0'),
                              '--target',
                              common.THIRD_PARTY_PYTHON_LIBS_DIR,
                              '--upgrade',
                              '--no-dependencies',
                          ]])
        self.assertEqual(paths_to_delete, [
            u'flask-10.0.1.dist-info', u'webencodings-1.0.1.dist-info',
            u'six-10.13.0.egg-info', u'google_cloud_datastore-1.13.0.dist-info'
        ])