Exemplo n.º 1
0
    def test_get_previous(self, Image_mock):
        path = self.path_mock
        path.glob.return_value = [
            '0.jpg', '1.jpg', '2.jpg', '3.jpg', '4.jpg', '5.jpg', '6.jpg'
        ]

        img_0 = Mock(name='3.jpg', spec_set=Image.Image)
        img_1 = Mock(name='2.jpg', spec_set=Image.Image)
        img_2 = Mock(name='1.jpg', spec_set=Image.Image)
        img_3 = Mock(name='0.jpg', spec_set=Image.Image)
        Image_mock.open.side_effect = [img_0, img_1, img_2, img_3]
        expect_open = [
            call.open('3.jpg'),
            call.open('2.jpg'),
            call.open('1.jpg'),
            call.open('0.jpg')
        ]

        instance = self.instance
        instance.get(0)

        self.assertEqual(instance.get(-1), img_1)
        self.assertEqual(instance.get(-2), img_2)
        self.assertEqual(instance.get(-3), img_3)
        self.assertIsNone(instance.get(-4))

        self.assertEqual(path.glob.call_count, 1)
        Image_mock.assert_has_calls(expect_open)
Exemplo n.º 2
0
    def test_step_next_limit(self, Image_mock):
        path = self.path_mock
        path.glob.return_value = [
            '0.jpg', '1.jpg', '2.jpg', '3.jpg', '4.jpg', '5.jpg', '6.jpg'
        ]

        img_0 = Mock(name='3.jpg', spec_set=Image.Image)
        img_1 = Mock(name='4.jpg', spec_set=Image.Image)
        img_2 = Mock(name='5.jpg', spec_set=Image.Image)
        img_3 = Mock(name='6.jpg', spec_set=Image.Image)
        Image_mock.open.side_effect = [img_0, img_1, img_2, img_3, img_3]
        expect_open = [
            call.open('3.jpg'),
            call.open('4.jpg'),
            call.open('5.jpg'),
            call.open('6.jpg'),
            call.open('6.jpg')
        ]

        instance = self.instance
        for _ in range(3):
            instance.get(0)
            instance.step_next()
        result_1 = instance.get(0)
        instance.step_next()
        result_2 = instance.get(0)

        Image_mock.assert_has_calls(expect_open)
        self.assertEqual(result_1, img_3)
        self.assertEqual(result_2, img_3)
Exemplo n.º 3
0
    def test_get_0_SkipBadImage(self, Image_mock):
        path = self.path_mock
        path.glob.return_value = ['2.jpg', '0.jpg', '1.jpg', '3.jpg']

        img_bad = Mock(name='img_bad', spec_set=Image.Image)
        img_bad.load.side_effect = OSError('Mock: format invalid')
        img_normal = Mock(name='img_normal', spec_set=Image.Image)

        def _open(fname):
            if not hasattr(_open, 'count'):
                _open.count = 0
                raise FileNotFoundError('Mock: ' + fname + ' not found')
            if _open.count == 0:
                _open.count = 1
                return img_bad
            if _open.count == 1:
                return img_normal

        Image_mock.open.side_effect = _open
        expect_open = [
            call.open('0.jpg'),
            call.open('1.jpg'),
            call.open('2.jpg')
        ]

        result = self.instance.get(0)

        Image_mock.assert_has_calls(expect_open)
        img_bad.load.assert_called_once_with()
        img_normal.load.assert_called_once_with()
        self.assertEqual(result, img_normal)
Exemplo n.º 4
0
def test_mux_with_failure(mux_tr, my_tr, my_ftr):
    mux_tr += my_ftr
    mux_tr += my_tr
    # notice that the mux_tr raises a TransportError wrapping the subtransport's
    # exceptions (in this case, a single MyTransportError).
    with pytest.raises(TransportError) as excinfo:
        mux_tr.start()
    # my_tr starts normally, then is stopped when the other one fails.
    assert my_tr.mock_calls == [call.open(), call.run(), call.close()]
    assert my_ftr.mock_calls == [call.open()]
    assert len(excinfo.value.exceptions) == 1
    assert isinstance(excinfo.value.exceptions[0], MyTransportError)
Exemplo n.º 5
0
    def test_open_first_fork_child_second_fork_child_and_pitfile(self):
        self.os_mock.fork = MagicMock(side_effect=[0, 0])
        self.daemoncontext.pidfile = Mock()
        terminate = getattr(self.daemoncontext, 'terminate')
        self.daemoncontext.signal_map = {
            self.signal_mock.SIGTSTP: None,
            self.signal_mock.SIGTTIN: None,
            self.signal_mock.SIGTTOU: None,
            self.signal_mock.SIGTERM: 'terminate'
        }

        self.daemoncontext.open()

        self.os_mock.assert_has_calls([
            call.getuid(),
            call.getgid(),
            call.chdir('/'),
            call.setgid(54321),
            call.setuid(12345),
            call.umask(0),
            call.fork(),
            call.setsid(),
            call.fork(),
            call.close(0),
            call.open(self.os_mock.devnull, self.os_mock.O_RDWR),
            call.dup2(self.os_mock.open(), self.sys_mock.stdin.fileno()),
            call.open(self.os_mock.devnull, self.os_mock.O_RDWR),
            call.dup2(self.os_mock.open(), self.sys_mock.stdout.fileno()),
            call.open(self.os_mock.devnull, self.os_mock.O_RDWR),
            call.dup2(self.os_mock.open(), self.sys_mock.stderr.fileno())
        ])
        self.resource_mock.assert_has_calls([
            call.setrlimit(self.resource_mock.RLIMIT_CORE, (0, 0)),
            call.getrlimit(2048)
        ])
        self.signal_mock.assert_has_calls([
            call.signal(self.signal_mock.SIGTSTP, self.signal_mock.SIG_IGN),
            call.signal(self.signal_mock.SIGTERM, terminate),
            call.signal(self.signal_mock.SIGTTIN, self.signal_mock.SIG_IGN),
            call.signal(self.signal_mock.SIGTTOU, self.signal_mock.SIG_IGN)
        ],
                                          any_order=True)
        self.sys_mock.assert_has_calls([
            call.stdin.fileno(),
            call.stdout.fileno(),
            call.stderr.fileno(),
            call.stdin.fileno(),
            call.stdout.fileno(),
            call.stderr.fileno()
        ])
        self.daemoncontext.pidfile.assert_has_calls([call.acquire()])
Exemplo n.º 6
0
    def test_get_0_AllBadImage(self, Image_mock):
        path = self.path_mock
        path.glob.return_value = ['2.jpg', '0.jpg', '1.jpg', '3.jpg']

        Image_mock.open.side_effect = FileNotFoundError('Mock: not found')
        expect_open = [
            call.open('0.jpg'),
            call.open('1.jpg'),
            call.open('2.jpg'),
            call.open('3.jpg')
        ]

        result = self.instance.get(0)

        Image_mock.assert_has_calls(expect_open)
        self.assertIsNone(result)
Exemplo n.º 7
0
 def test_redirect_stream_None(self):
     file = Mock()
     file.fileno.return_value = 123
     pep3143daemon.daemon.redirect_stream(file, None)
     self.os_mock.assert_has_calls(
         [call.open(self.os_mock.devnull, self.os_mock.O_RDWR),
          call.dup2(self.os_mock.open(), 123)])
Exemplo n.º 8
0
    def test_open_first_fork_child_second_fork_child_and_pitfile(self):
        self.os_mock.fork = MagicMock(side_effect=[0, 0])
        self.daemoncontext.pidfile = Mock()
        terminate = getattr(self.daemoncontext, 'terminate')
        self.daemoncontext.signal_map = {
            self.signal_mock.SIGTSTP: None,
            self.signal_mock.SIGTTIN: None,
            self.signal_mock.SIGTTOU: None,
            self.signal_mock.SIGTERM: 'terminate'}

        self.daemoncontext.open()

        self.os_mock.assert_has_calls(
            [call.getuid(),
             call.getgid(),
             call.chdir('/'),
             call.setgid(54321),
             call.setuid(12345),
             call.umask(0),
             call.fork(),
             call.setsid(),
             call.fork(),
             call.close(0),
             call.open(self.os_mock.devnull, self.os_mock.O_RDWR),
             call.dup2(self.os_mock.open(), self.sys_mock.stdin.fileno()),
             call.open(self.os_mock.devnull, self.os_mock.O_RDWR),
             call.dup2(self.os_mock.open(), self.sys_mock.stdout.fileno()),
             call.open(self.os_mock.devnull, self.os_mock.O_RDWR),
             call.dup2(self.os_mock.open(), self.sys_mock.stderr.fileno())])
        self.resource_mock.assert_has_calls(
            [call.setrlimit(self.resource_mock.RLIMIT_CORE, (0, 0)),
             call.getrlimit(2048)])
        self.signal_mock.assert_has_calls(
            [call.signal(self.signal_mock.SIGTSTP, self.signal_mock.SIG_IGN),
             call.signal(self.signal_mock.SIGTERM, terminate),
             call.signal(self.signal_mock.SIGTTIN, self.signal_mock.SIG_IGN),
             call.signal(self.signal_mock.SIGTTOU, self.signal_mock.SIG_IGN)], any_order=True)
        self.sys_mock.assert_has_calls(
            [call.stdin.fileno(),
             call.stdout.fileno(),
             call.stderr.fileno(),
             call.stdin.fileno(),
             call.stdout.fileno(),
             call.stderr.fileno()])
        self.daemoncontext.pidfile.assert_has_calls(
            [call.acquire()]
        )
Exemplo n.º 9
0
 def test_redirect_stream_None(self):
     file = Mock()
     file.fileno.return_value = 123
     pep3143daemon.daemon.redirect_stream(file, None)
     self.os_mock.assert_has_calls([
         call.open(self.os_mock.devnull, self.os_mock.O_RDWR),
         call.dup2(self.os_mock.open(), 123)
     ])
Exemplo n.º 10
0
    def test_should_open_channel_before_sending_message(self):
        # When
        self.producer.publish(self.first_queue, self.message)

        # Then
        method_calls = self.channel.method_calls
        assert call.open() == method_calls[3]
        call_send_message = call.send_message(
            self.exchange_name, self.first_queue, self.message)
        assert call_send_message == method_calls[4]
Exemplo n.º 11
0
    def test_get_0_Normal(self, Image_mock):
        path = self.path_mock
        path.glob.return_value = ['2.jpg', '0.jpg', '1.jpg', '3.jpg']

        img = Mock(name='0.jpg', spec_set=Image.Image)
        Image_mock.open.return_value = img
        expect_open = [call.open('0.jpg')]

        result = self.instance.get(0)

        Image_mock.assert_has_calls(expect_open)
        img.load.assert_called_once_with()
        self.assertEqual(result, img)
Exemplo n.º 12
0
    def test_get_previous(self, Image_mock):
        path = self.path_mock
        path.glob.return_value = ['2.jpg', '0.jpg', '1.jpg', '3.jpg']

        Image_mock.open.return_value = Mock(name='0.jpg', spec_set=Image.Image)
        expect_open = [call.open('0.jpg')]

        instance = self.instance
        instance.get(0)

        self.assertIsNone(instance.get(-1))

        self.assertEqual(path.glob.call_count, 1)
        Image_mock.assert_has_calls(expect_open)
Exemplo n.º 13
0
    def test_unlink_previous(self, Image_mock):
        path = self.path_mock
        path.glob.return_value = [
            '0.jpg', '1.jpg', '3.jpg', '4.jpg', '5.jpg', '6.jpg'
        ]

        img = Mock(name='3.jpg', spec_set=Image.Image)
        Image_mock.open.return_value = img

        result = self.instance.get(0)

        self.assertEqual(path.glob.call_count, 1)
        Image_mock.assert_has_calls([call.open('3.jpg')])
        self.assertEqual(result, img)
Exemplo n.º 14
0
    def test_remove_bad_from_cache(self, Image_mock):
        path = self.path_mock
        path.glob.return_value = [
            '0.jpg', '1.jpg', '2.jpg', '3.jpg', '4.jpg', '5.jpg', '6.jpg'
        ]

        img_bad = Mock(name='img_bad', spec_set=Image.Image)
        img_bad.load.side_effect = OSError('Mock: format invalid')
        img_get_0 = Mock(name='img_normal', spec_set=Image.Image)
        img_get_1 = Mock(name='img_normal', spec_set=Image.Image)

        def _open(fname):
            if not hasattr(_open, 'count'):
                _open.count = 0
                return img_bad
            if _open.count == 0:
                _open.count = 1
                return img_get_0
            if _open.count == 1:
                _open.count = 2
                return img_get_1

        Image_mock.open.side_effect = _open
        expect_open = [
            call.open('3.jpg'),
            call.open('4.jpg'),
            call.open('5.jpg')
        ]

        get_0 = self.instance.get(0)
        get_1 = self.instance.get(1)

        self.assertEqual(path.glob.call_count, 1)
        Image_mock.assert_has_calls(expect_open)
        self.assertEqual(get_0, img_get_0)
        self.assertEqual(get_1, img_get_1)
Exemplo n.º 15
0
def test_failing_start(my_ftr):
    with pytest.raises(MyTransportError):
        my_ftr.start()
    assert my_ftr.mock_calls == [call.open()]
Exemplo n.º 16
0
def test_succeeding_start(my_tr):
    my_tr.start()
    my_tr.stop()
    assert my_tr.mock_calls == [call.open(), call.run(), call.close()]
Exemplo n.º 17
0
def verify_open_path(tc: unittest.TestCase, s: Path, *args, **kwargs):
    tc.assertTrue(
        all(x in s.mock_calls for x in
            [call.open(*args, **kwargs), call.open().__enter__(),
             call.open().__exit__(None, None, None)]))
def test_release_major(clone_from_github_mock, check_output_mock, open_mock,
                       date_mock, expanduser_mock):
    repo_mock = Mock()
    repo_mock.latest_tag.return_value = '20.1.0'
    repo_mock.authors_since.return_value = ['*****@*****.**', '*****@*****.**']
    repo_mock.diff_name_status.return_value = [
        ('apis/foo/v1.ts', _git.Status.ADDED),
        ('apis/bar/v1.ts', _git.Status.DELETED),
        ('apis/baz/v1.ts', _git.Status.UPDATED),
    ]
    side_effect = common.clone_from_github_mock_side_effect(repo_mock)
    clone_from_github_mock.side_effect = side_effect
    check_output_mock.return_value = '20.1.0'
    open_package_json_mock = mock_open(read_data=('{"version": "20.1.0"}'))
    open_changelog_md_mock = mock_open(read_data='...\n')
    open_npmrc_mock = mock_open()
    open_index_md_mock = mock_open(read_data=('...\n\n'
                                              '### ...\n\n'
                                              '* [v20.1.0 (latest)](...)\n'
                                              '...\n'))
    open_mock.side_effect = [
        open_package_json_mock.return_value,
        open_package_json_mock.return_value,
        open_changelog_md_mock.return_value,
        open_changelog_md_mock.return_value, open_npmrc_mock.return_value,
        open_index_md_mock.return_value, open_index_md_mock.return_value
    ]
    date_mock.today.return_value.strftime.return_value = '1 September 2017'
    expanduser_mock.side_effect = lambda x: '/home/test' + x[1:]

    manager = Mock()
    manager.attach_mock(clone_from_github_mock, 'clone_from_github')
    manager.attach_mock(check_output_mock, 'check_output')
    manager.attach_mock(open_mock, 'open')
    manager.attach_mock(repo_mock, 'repo')
    manager.attach_mock(open_package_json_mock, 'open_package_json')
    manager.attach_mock(open_changelog_md_mock, 'open_changelog_md')
    manager.attach_mock(open_npmrc_mock, 'open_npmrc')
    manager.attach_mock(open_index_md_mock, 'open_index_md')

    google_api_nodejs_client.release('/tmp', common.GITHUB_ACCOUNT,
                                     _NPM_ACCOUNT)
    assert manager.mock_calls == [
        call.clone_from_github('google/google-api-nodejs-client',
                               '/tmp/google-api-nodejs-client',
                               github_account=common.GITHUB_ACCOUNT),
        call.repo.latest_tag(),
        call.repo.authors_since('20.1.0'),
        call.check_output(['npm', 'view', 'googleapis', 'version']),
        call.repo.diff_name_status(rev='20.1.0'),
        call.open('/tmp/google-api-nodejs-client/package.json'),
        call.open_package_json().__enter__(),
        call.open_package_json().read(),
        call.open_package_json().__exit__(None, None, None),
        call.open('/tmp/google-api-nodejs-client/package.json', 'w'),
        call.open_package_json().__enter__(),
        call.open_package_json().write('{\n  "version": "21.0.0"\n}'),
        call.open_package_json().__exit__(None, None, None),
        call.open('/tmp/google-api-nodejs-client/CHANGELOG.md'),
        call.open_changelog_md().__enter__(),
        call.open_changelog_md().read(),
        call.open_changelog_md().__exit__(None, None, None),
        call.open('/tmp/google-api-nodejs-client/CHANGELOG.md', 'w'),
        call.open_changelog_md().__enter__(),
        call.open_changelog_md().write(('##### 21.0.0 - 1 September 2017\n\n'
                                        '###### Breaking changes\n'
                                        '- Deleted `bar`\n\n'
                                        '###### Backwards compatible changes\n'
                                        '- Added `foo`\n'
                                        '- Updated `baz`\n\n'
                                        '...\n')),
        call.open_changelog_md().__exit__(None, None, None),
        call.check_output(['npm', 'install'],
                          cwd='/tmp/google-api-nodejs-client'),
        call.check_output(['make', 'build'],
                          cwd='/tmp/google-api-nodejs-client'),
        call.check_output(['make', 'test'],
                          cwd='/tmp/google-api-nodejs-client'),
        call.repo.commit('21.0.0', 'Alice', '*****@*****.**'),
        call.repo.tag('21.0.0'),
        call.repo.push(),
        call.repo.push(tags=True),
        call.open('/home/test/.npmrc', 'w'),
        call.open_npmrc().__enter__(),
        call.open_npmrc().write(
            '//registry.npmjs.org/:_authToken=auth_token\n'),
        call.open_npmrc().__exit__(None, None, None),
        call.check_output(['npm', 'publish'],
                          cwd='/tmp/google-api-nodejs-client'),
        call.check_output(['make', 'docs'],
                          cwd='/tmp/google-api-nodejs-client'),
        call.repo.checkout('gh-pages'),
        call.check_output(['rm', '-rf', 'latest'],
                          cwd='/tmp/google-api-nodejs-client'),
        call.check_output(['cp', '-r', 'doc/googleapis/21.0.0', 'latest'],
                          cwd='/tmp/google-api-nodejs-client'),
        call.check_output(['cp', '-r', 'doc/googleapis/21.0.0', '21.0.0'],
                          cwd='/tmp/google-api-nodejs-client'),
        call.open('/tmp/google-api-nodejs-client/index.md'),
        call.open_index_md().__enter__(),
        call.open_index_md().readlines(),
        call.open_index_md().__exit__(None, None, None),
        call.open('/tmp/google-api-nodejs-client/index.md', 'w'),
        call.open_index_md().__enter__(),
        call.open_index_md().write(
            ('...\n\n'
             '### ...\n\n'
             '* [v21.0.0 (latest)]'
             '(http://google.github.io/google-api-nodejs-client/21.0.0'
             '/index.html)\n'
             '* [v20.1.0](...)\n'
             '...\n')),
        call.open_index_md().__exit__(None, None, None),
        call.repo.add(['latest', '21.0.0']),
        call.repo.commit('21.0.0', 'Alice', '*****@*****.**'),
        call.repo.push(branch='gh-pages'),
        call.repo.checkout('master')
    ]
Exemplo n.º 19
0
def test_mux_add_after_start(mux_tr, my_tr):
    mux_tr.start()
    mux_tr += my_tr
    mux_tr -= my_tr
    mux_tr.stop()
    assert my_tr.mock_calls == [call.open(), call.run(), call.close()]
def test_release_invalid_index_md(clone_from_github_mock,
                                  check_output_mock,
                                  open_mock,
                                  date_mock,
                                  expanduser_mock):
    repo_mock = Mock()
    repo_mock.latest_tag.return_value = '20.1.0'
    repo_mock.authors_since.return_value = ['*****@*****.**', '*****@*****.**']
    repo_mock.diff_name_status.return_value = [
        ('apis/foo/v1.ts', _git.Status.ADDED),
        ('apis/baz/v1.ts', _git.Status.UPDATED),
    ]
    side_effect = common.clone_from_github_mock_side_effect(repo_mock)
    clone_from_github_mock.side_effect = side_effect
    check_output_mock.return_value = '20.1.0'
    open_package_json_mock = mock_open(read_data=('{"version": "20.1.0"}'))
    open_changelog_md_mock = mock_open(read_data='...\n')
    open_npmrc_mock = mock_open()
    open_index_md_mock = mock_open(read_data=('...\n'))
    open_mock.side_effect = [
        open_package_json_mock.return_value,
        open_package_json_mock.return_value,
        open_changelog_md_mock.return_value,
        open_changelog_md_mock.return_value,
        open_npmrc_mock.return_value,
        open_index_md_mock.return_value,
    ]
    date_mock.today.return_value.strftime.return_value = '1 September 2017'
    expanduser_mock.side_effect = lambda x: '/home/test' + x[1:]

    manager = Mock()
    manager.attach_mock(clone_from_github_mock, 'clone_from_github')
    manager.attach_mock(check_output_mock, 'check_output')
    manager.attach_mock(open_mock, 'open')
    manager.attach_mock(repo_mock, 'repo')
    manager.attach_mock(open_package_json_mock, 'open_package_json')
    manager.attach_mock(open_changelog_md_mock, 'open_changelog_md')
    manager.attach_mock(open_npmrc_mock, 'open_npmrc')
    manager.attach_mock(open_index_md_mock, 'open_index_md')

    with pytest.raises(Exception) as excinfo:
        google_api_nodejs_client.release(
            '/tmp', common.GITHUB_ACCOUNT, _NPM_ACCOUNT)
    assert str(excinfo.value) == 'index.md has an unexpected format'
    assert manager.mock_calls == [
        call.clone_from_github('google/google-api-nodejs-client',
                               '/tmp/google-api-nodejs-client',
                               github_account=common.GITHUB_ACCOUNT),
        call.repo.latest_tag(),
        call.repo.authors_since('20.1.0'),
        call.check_output(['npm', 'view', 'googleapis', 'version']),
        call.repo.diff_name_status(rev='20.1.0'),
        call.open('/tmp/google-api-nodejs-client/package.json'),
        call.open_package_json().__enter__(),
        call.open_package_json().read(),
        call.open_package_json().__exit__(None, None, None),
        call.open('/tmp/google-api-nodejs-client/package.json', 'w'),
        call.open_package_json().__enter__(),
        call.open_package_json().write('{\n  "version": "20.2.0"\n}'),
        call.open_package_json().__exit__(None, None, None),
        call.open('/tmp/google-api-nodejs-client/CHANGELOG.md'),
        call.open_changelog_md().__enter__(),
        call.open_changelog_md().read(),
        call.open_changelog_md().__exit__(None, None, None),
        call.open('/tmp/google-api-nodejs-client/CHANGELOG.md', 'w'),
        call.open_changelog_md().__enter__(),
        call.open_changelog_md().write(('##### 20.2.0 - 1 September 2017\n\n'
                                        '###### Backwards compatible changes\n'
                                        '- Added `foo`\n'
                                        '- Updated `baz`\n\n'
                                        '...\n')),
        call.open_changelog_md().__exit__(None, None, None),
        call.check_output(['npm', 'install'],
                          cwd='/tmp/google-api-nodejs-client'),
        call.check_output(['node', '--max_old_space_size=2000', '/usr/bin/npm',
                           'run', 'build'],
                          cwd='/tmp/google-api-nodejs-client'),
        call.check_output(['npm', 'run', 'test'],
                          cwd='/tmp/google-api-nodejs-client'),
        call.repo.commit('20.2.0', 'Alice', '*****@*****.**'),
        call.repo.tag('20.2.0'),
        call.repo.push(),
        call.repo.push(tags=True),
        call.open('/home/test/.npmrc', 'w'),
        call.open_npmrc().__enter__(),
        call.open_npmrc().write(
            '//registry.npmjs.org/:_authToken=auth_token\n'),
        call.open_npmrc().__exit__(None, None, None),
        call.check_output(['npm', 'publish'],
                          cwd='/tmp/google-api-nodejs-client'),
        call.check_output(['npm', 'run', 'doc'],
                          cwd='/tmp/google-api-nodejs-client'),
        call.repo.checkout('gh-pages'),
        call.check_output(['rm', '-rf', 'latest'],
                          cwd='/tmp/google-api-nodejs-client'),
        call.check_output(['cp', '-r', 'doc/googleapis/20.2.0', 'latest'],
                          cwd='/tmp/google-api-nodejs-client'),
        call.check_output(['cp', '-r', 'doc/googleapis/20.2.0', '20.2.0'],
                          cwd='/tmp/google-api-nodejs-client'),
        call.open('/tmp/google-api-nodejs-client/index.md'),
        call.open_index_md().__enter__(),
        call.open_index_md().readlines(),
        call.open_index_md().__exit__(None, None, None),
    ]
def test_release_patch(clone_from_github_mock, check_output_mock, open_mock,
                       expanduser_mock, chmod_mock):
    repo_mock = Mock()
    repo_mock.latest_tag.return_value = '0.13.6'
    repo_mock.authors_since.return_value = ['*****@*****.**', '*****@*****.**']
    repo_mock.diff_name_status.return_value = [
        ('generated/google/apis/foo_v1.rb', _git.Status.ADDED),
        ('generated/google/apis/baz_v1.rb', _git.Status.UPDATED),
    ]
    side_effect = common.clone_from_github_mock_side_effect(repo_mock)
    clone_from_github_mock.side_effect = side_effect
    check_output_mock.return_value = 'google-api-client (0.13.6)'
    open_version_rb_mock = mock_open(
        read_data=('...\n'
                   'module Google\n'
                   '    module Apis\n'
                   '        # Client library version\n'
                   '        VERSION = \'0.13.6\'\n'
                   '    ...\n'))
    open_changelog_md_mock = mock_open(read_data='...\n')
    open_credentials_mock = mock_open()
    open_mock.side_effect = [
        open_version_rb_mock.return_value, open_version_rb_mock.return_value,
        open_changelog_md_mock.return_value,
        open_changelog_md_mock.return_value, open_credentials_mock.return_value
    ]
    expanduser_mock.side_effect = lambda x: '/home/test' + x[1:]

    manager = Mock()
    manager.attach_mock(clone_from_github_mock, 'clone_from_github')
    manager.attach_mock(check_output_mock, 'check_output')
    manager.attach_mock(open_mock, 'open')
    manager.attach_mock(repo_mock, 'repo')
    manager.attach_mock(chmod_mock, 'chmod')
    manager.attach_mock(open_version_rb_mock, 'open_version_rb')
    manager.attach_mock(open_changelog_md_mock, 'open_changelog_md')
    manager.attach_mock(open_credentials_mock, 'open_credentials')

    google_api_ruby_client.release('/tmp', common.GITHUB_ACCOUNT,
                                   _RUBYGEMS_ACCOUNT)
    assert manager.mock_calls == [
        call.clone_from_github('google/google-api-ruby-client',
                               '/tmp/google-api-ruby-client',
                               github_account=common.GITHUB_ACCOUNT),
        call.repo.latest_tag(),
        call.repo.authors_since('0.13.6'),
        call.check_output(['gem', 'search', '-r', '^google-api-client$']),
        call.repo.diff_name_status(rev='0.13.6'),
        call.open('/tmp/google-api-ruby-client/lib/google/apis/version.rb'),
        call.open_version_rb().__enter__(),
        call.open_version_rb().read(),
        call.open_version_rb().__exit__(None, None, None),
        call.open('/tmp/google-api-ruby-client/lib/google/apis/version.rb',
                  'w'),
        call.open_version_rb().__enter__(),
        call.open_version_rb().write(('...\n'
                                      'module Google\n'
                                      '    module Apis\n'
                                      '        # Client library version\n'
                                      '        VERSION = \'0.13.7\'\n'
                                      '    ...\n')),
        call.open_version_rb().__exit__(None, None, None),
        call.open('/tmp/google-api-ruby-client/CHANGELOG.md'),
        call.open_changelog_md().__enter__(),
        call.open_changelog_md().read(),
        call.open_changelog_md().__exit__(None, None, None),
        call.open('/tmp/google-api-ruby-client/CHANGELOG.md', 'w'),
        call.open_changelog_md().__enter__(),
        call.open_changelog_md().write(('# 0.13.7\n'
                                        '* Backwards compatible changes:\n'
                                        '  * Added `foo_v1`\n'
                                        '  * Updated `baz_v1`\n\n'
                                        '...\n')),
        call.open_changelog_md().__exit__(None, None, None),
        call.check_output(['bundle', 'install', '--path', 'vendor/bundle'],
                          cwd='/tmp/google-api-ruby-client'),
        call.check_output(['bundle', 'exec', 'rake', 'spec'],
                          cwd='/tmp/google-api-ruby-client'),
        call.repo.commit('0.13.7', 'Alice', '*****@*****.**'),
        call.repo.tag('0.13.7'),
        call.repo.push(),
        call.repo.push(tags=True),
        call.check_output(['./script/package'],
                          cwd='/tmp/google-api-ruby-client'),
        call.open('/home/test/.gem/credentials', 'w'),
        call.open_credentials().__enter__(),
        call.open_credentials().write('---\n:rubygems_api_key: api_key\n'),
        call.open_credentials().__exit__(None, None, None),
        call.chmod('/home/test/.gem/credentials', 0o600),
        call.check_output(['gem', 'push', 'pkg/google-api-client-0.13.7.gem'],
                          cwd='/tmp/google-api-ruby-client')
    ]