def testDefaultExceptionHandler(self):
        """Ensures exception handles swallows (retries)"""
        mock_http_content = 'content'.encode('utf8')
        for exception_arg in (http_client.BadStatusLine('line'),
                              http_client.IncompleteRead('partial'),
                              http_client.ResponseNotReady(), socket.error(),
                              socket.gaierror(),
                              httplib2.ServerNotFoundError(), ValueError(),
                              oauth2client.client.HttpAccessTokenRefreshError(
                                  status=503), exceptions.RequestError(),
                              exceptions.BadStatusCodeError({'status': 503},
                                                            mock_http_content,
                                                            'url'),
                              exceptions.RetryAfterError({'status': 429},
                                                         mock_http_content,
                                                         'url', 0)):

            retry_args = http_wrapper.ExceptionRetryArgs(
                http={'connections': {}},
                http_request=_MockHttpRequest(),
                exc=exception_arg,
                num_retries=0,
                max_retry_wait=0,
                total_wait_sec=0)

            # Disable time.sleep for this handler as it is called with
            # a minimum value of 1 second.
            with patch('time.sleep', return_value=None):
                http_wrapper.HandleExceptionsAndRebuildHttpConnections(
                    retry_args)
    def test_jsonrpc_call_bad_status_line(self):
        self.mock_object(
            self.rpc._connection, 'getresponse',
            mock.Mock(side_effect=http_client.BadStatusLine("fake_line")))

        self.assertRaises(exception.QBException, self.rpc.call, 'method',
                          {'param': 'value'})
Example #3
0
 def getresponse(self):
     MockHTTPBadStatusConnection.num_calls += 1
     raise http_client.BadStatusLine("")
Example #4
0
class TestOpenshift(object):
    def test_set_labels_on_build(self, openshift):  # noqa
        labels = openshift.set_labels_on_build(TEST_BUILD,
                                               {TEST_LABEL: TEST_LABEL_VALUE})
        assert labels.json() is not None

    @pytest.mark.parametrize(
        'exc',
        [  # noqa
            requests.ConnectionError('Connection aborted.',
                                     http_client.BadStatusLine("''", )),
        ])
    def test_stream_logs_bad_initial_connection_and_error_in_iter(
            self, openshift, exc):
        response = flexmock(status_code=http_client.OK)
        (response.should_receive('iter_lines').and_return([
            b"{'stream': 'foo\n'}"
        ]).and_raise(requests.exceptions.ConnectionError).and_return(
            [b"{'stream': 'ham\n'}"]))

        wrapped_exc = OsbsNetworkException('http://spam.com',
                                           str(exc),
                                           status_code=None,
                                           cause=exc)
        (flexmock(openshift).should_receive('_get')
         # First: simulate initial connection problem
         .and_raise(wrapped_exc)
         # Next: return a real response
         .and_return(response).and_return(response)
         # we want to call it just as many times so we read all from response,
         # but not more times because it would start again looping from 1st raise
         .and_return(response).times(4))

        mocked_time = (flexmock(time).should_receive('time'))
        # times are tricky, because we use time.time() explicitly in
        # stream logs, BUT also those two log.debug use it
        # so this is caluculated that it will be increasing times for all operations
        # we want, after that it will stop iteration
        for num in range(0, 1500, 100):
            mocked_time.and_return(num)

        logs = openshift.stream_logs(TEST_BUILD)
        assert len([log for log in logs]) == 2

    def test_stream_logs_utf8(self, openshift):  # noqa
        response = flexmock(status_code=http_client.OK)
        (response.should_receive('iter_lines').and_return([
            u"{'stream': 'Uňícode íš hářd\n'}".encode('utf-8')
        ]).and_raise(StopIteration))

        (flexmock(openshift).should_receive('_get').and_return(response))

        logs = openshift.stream_logs(TEST_BUILD)
        assert len([log for log in logs]) == 1

    def test_list_builds(self, openshift):  # noqa
        list_builds = openshift.list_builds()
        assert list_builds is not None
        assert bool(list_builds.json())  # is there at least something

    def test_list_pods(self, openshift):  # noqa
        response = openshift.list_pods(label="openshift.io/build.name=%s" %
                                       TEST_BUILD)
        assert isinstance(response, HttpResponse)

    def test_get_oauth_token(self, openshift):  # noqa
        token = openshift.get_oauth_token()
        assert token is not None

    def test_get_user(self, openshift):  # noqa
        response = openshift.get_user()
        assert response.json() is not None

    def test_watch_resource_and_wait_to_build_timeouts(self, caplog,
                                                       openshift):  # noqa:F811
        class MockResponse(object):
            def __init__(self):
                self.status_code = http_client.OK

            def iter_lines(self):
                return []

            def json(self):
                return {
                    'metadata': {
                        'name': ''
                    },
                    'status': {
                        'phase': 'pending'
                    },
                }

        mock_reponse = MockResponse()
        flexmock(openshift).should_receive('_get').and_return(mock_reponse)
        flexmock(time).should_receive('sleep').and_return(None)
        for change_type, _ in openshift.watch_resource("builds", 12):
            # watch_resource only returns a fresh copy, no updates
            assert change_type is None

        with pytest.raises(OsbsWatchBuildNotFound):
            openshift.wait(12, None)

        with pytest.raises(OsbsException):
            openshift.wait_for_build_to_get_scheduled(12)

        with pytest.raises(OsbsException):
            openshift.wait_for_build_to_finish(12)

        assert any('Retry #143' in log.getMessage() for log in caplog.records)

    @pytest.mark.parametrize('fail', (True, False))  # noqa:F811
    def test_watch_response_hiccup(self, fail, openshift):
        class MockResponse(object):
            def __init__(self, status, lines=None, content=None):
                self.status_code = status
                self.lines = lines or []
                self.content = content

            def iter_lines(self):
                return self.lines

            def json(self):
                return json.loads(self.content)

        test_json = json.dumps({
            "object": "test",
            "type": "test"
        }).encode('utf-8')
        bad_response = MockResponse(http_client.FORBIDDEN, None, "failure")
        good_response = MockResponse(http_client.OK, [test_json])
        fresh_response = MockResponse(http_client.OK, content='"test"')
        flexmock(time).should_receive('sleep').and_return(None)
        if fail:
            (flexmock(openshift).should_receive('_get').and_return(
                bad_response, bad_response, bad_response, bad_response,
                good_response).one_by_one())
            with pytest.raises(OsbsResponseException) as exc:
                for changetype, obj in openshift.watch_resource("builds", 12):
                    continue
            assert str(exc.value).startswith('failure')
        else:
            (flexmock(openshift).should_receive('_get').and_return(
                good_response, fresh_response, bad_response, good_response,
                fresh_response).one_by_one())

            yielded = 0
            expected = [
                (None, 'test'),  # fresh object
                ('test', 'test'),  # update
                (None, 'test'),  # fresh object after reconnect
                ('test', 'test'),  # update
            ]
            for (changetype, obj), (exp_changetype, exp_obj) in zip(
                    openshift.watch_resource("builds", 12), expected):
                yielded += 1
                assert changetype == exp_changetype
                assert obj == exp_obj

            assert yielded == len(expected)

    def test_watch_build(self, openshift):  # noqa
        response = openshift.wait_for_build_to_finish(TEST_BUILD)
        status_lower = response["status"]["phase"].lower()
        assert response["metadata"]["name"] == TEST_BUILD
        assert status_lower in BUILD_FINISHED_STATES
        assert isinstance(TEST_BUILD, six.text_type)
        assert isinstance(status_lower, six.text_type)

    def test_create_build(self, openshift):  # noqa
        response = openshift.create_build({})
        assert response is not None
        assert response.json()["metadata"]["name"] == TEST_BUILD
        assert response.json()["status"]["phase"].lower(
        ) in BUILD_FINISHED_STATES

    def test_cancel_build(self, openshift):  # noqa
        response = openshift.cancel_build(TEST_CANCELLED_BUILD)
        assert response is not None
        assert response.json()["metadata"]["name"] == TEST_CANCELLED_BUILD
        assert response.json()["status"]["phase"].lower(
        ) in BUILD_CANCELLED_STATE

    def test_get_build_config(self, openshift):  # noqa
        mock_response = {"spam": "maps"}
        build_config_name = 'some-build-config-name'
        expected_url = openshift._build_url(
            "build.openshift.io/v1", "buildconfigs/%s/" % build_config_name)
        (flexmock(openshift).should_receive("_get").with_args(
            expected_url).once().and_return(make_json_response(mock_response)))
        response = openshift.get_build_config(build_config_name)
        assert response['spam'] == 'maps'

    def test_get_missing_build_config(self, openshift):  # noqa
        build_config_name = 'some-build-config-name'
        expected_url = openshift._build_url(
            "build.openshift.io/v1", "buildconfigs/%s/" % build_config_name)
        (flexmock(openshift).should_receive("_get").with_args(
            expected_url).once().and_return(HttpResponse(404, {}, b'')))
        with pytest.raises(OsbsResponseException):
            openshift.get_build_config(build_config_name)

    def test_get_build_config_by_labels(self, openshift):  # noqa
        mock_response = {"items": [{"spam": "maps"}]}
        label_selectors = (
            ('label-1', 'value-1'),
            ('label-2', 'value-2'),
        )
        expected_url = openshift._build_url(
            "build.openshift.io/v1",
            "buildconfigs/?labelSelector=label-1%3Dvalue-1%2Clabel-2%3Dvalue-2"
        )
        (flexmock(openshift).should_receive("_get").with_args(
            expected_url).once().and_return(make_json_response(mock_response)))
        response = openshift.get_build_config_by_labels(label_selectors)
        assert response['spam'] == 'maps'

    def test_get_build_config_by_labels_filtered(self, openshift):  # noqa:F811
        mock_response = {
            "items": [{
                "spam": "spam"
            }, {
                "spam": "maps",
                "maps": {
                    "spam": "value-3"
                }
            }]
        }
        label_selectors = (
            ('label-1', 'value-1'),
            ('label-2', 'value-2'),
        )
        expected_url = openshift._build_url(
            "build.openshift.io/v1",
            "buildconfigs/?labelSelector=label-1%3Dvalue-1%2Clabel-2%3Dvalue-2"
        )
        (flexmock(openshift).should_receive("_get").with_args(
            expected_url).once().and_return(make_json_response(mock_response)))
        response = openshift.get_build_config_by_labels_filtered(
            label_selectors, "maps.spam", 'value-3')
        assert response['spam'] == 'maps'

    def test_get_missing_build_config_by_labels(self, openshift):  # noqa:F811
        mock_response = {"items": []}
        label_selectors = (
            ('label-1', 'value-1'),
            ('label-2', 'value-2'),
        )
        expected_url = openshift._build_url(
            "build.openshift.io/v1",
            "buildconfigs/?labelSelector=label-1%3Dvalue-1%2Clabel-2%3Dvalue-2"
        )
        (flexmock(openshift).should_receive("_get").with_args(
            expected_url).once().and_return(make_json_response(mock_response)))

        with pytest.raises(OsbsException) as exc:
            openshift.get_build_config_by_labels(label_selectors)
        assert str(exc.value).startswith('Build config not found')

    def test_get_multiple_build_config_by_labels(self, openshift):  # noqa:F811
        mock_response = {"items": [{"spam": "maps"}, {"eggs": "sgge"}]}
        label_selectors = (
            ('label-1', 'value-1'),
            ('label-2', 'value-2'),
        )
        expected_url = openshift._build_url(
            "build.openshift.io/v1",
            "buildconfigs/?labelSelector=label-1%3Dvalue-1%2Clabel-2%3Dvalue-2"
        )
        (flexmock(openshift).should_receive("_get").with_args(
            expected_url).once().and_return(make_json_response(mock_response)))

        with pytest.raises(OsbsException) as exc:
            openshift.get_build_config_by_labels(label_selectors)
        assert str(exc.value).startswith('More than one build config found')

    @pytest.mark.parametrize(
        ('items', 'filter_value', 'error'),
        [  # noqa:F811
            ([], "value-3", "Build config not found for labels"),
            ([{
                "spam": "maps"
            }], "value-3", "Build config not found for labels"),
            ([{
                "spam": "maps",
                "maps": {
                    "spam": "value-3"
                }
            }, {
                "spam": "maps",
                "maps": {
                    "spam": "value-3"
                }
            }], "value-3", "More than one build config found for labels"),
            ([{
                "spam": "maps",
                "maps": {
                    "spam": "value-3"
                }
            }, {
                "spam": "maps",
                "maps": {
                    "spam": "value-3"
                }
            }], "value-4", "Build config not found for labels"),
            ([], None, "Build config not found for labels"),
            ([{
                "spam": "maps",
                "maps": {
                    "spam": "value-3"
                }
            }, {
                "spam": "maps",
                "maps": {
                    "spam": "value-3"
                }
            }], None, "More than one build config found for labels"),
        ])
    def test_get_build_config_by_labels_filtered_fail(self, openshift, items,
                                                      filter_value, error):
        mock_response = {"items": items}
        label_selectors = (
            ('label-1', 'value-1'),
            ('label-2', 'value-2'),
        )
        expected_url = openshift._build_url(
            "build.openshift.io/v1",
            "buildconfigs/?labelSelector=label-1%3Dvalue-1%2Clabel-2%3Dvalue-2"
        )
        (flexmock(openshift).should_receive("_get").with_args(
            expected_url).once().and_return(make_json_response(mock_response)))

        with pytest.raises(OsbsException) as exc:
            openshift.get_build_config_by_labels_filtered(
                label_selectors, "maps.spam", filter_value)
        assert str(exc.value).startswith(error)

    def test_get_build_config_by_labels_filtered_no_filter(
            self, openshift):  # noqa:F811
        mock_response = {"items": [{"spam": "maps"}]}
        label_selectors = (
            ('label-1', 'value-1'),
            ('label-2', 'value-2'),
        )
        expected_url = openshift._build_url(
            "build.openshift.io/v1",
            "buildconfigs/?labelSelector=label-1%3Dvalue-1%2Clabel-2%3Dvalue-2"
        )
        (flexmock(openshift).should_receive("_get").with_args(
            expected_url).once().and_return(make_json_response(mock_response)))

        response = openshift.get_build_config_by_labels_filtered(
            label_selectors, None, None)
        assert response["spam"] == "maps"

    @pytest.mark.parametrize(
        ('status_codes', 'should_raise'),
        [  # noqa
            ([http_client.OK], False),
            ([http_client.CONFLICT, http_client.CONFLICT, http_client.OK
              ], False),
            ([http_client.CONFLICT, http_client.OK], False),
            ([
                http_client.CONFLICT, http_client.CONFLICT,
                http_client.UNAUTHORIZED
            ], True),
            ([http_client.UNAUTHORIZED], True),
            ([
                http_client.CONFLICT
                for _ in range(OS_CONFLICT_MAX_RETRIES + 1)
            ], True),
        ])
    @pytest.mark.parametrize('update_or_set', ['update', 'set'])
    @pytest.mark.parametrize('attr_type', ['labels', 'annotations'])
    @pytest.mark.parametrize('object_type', ['build', 'build_config'])
    def test_retry_update_attributes(self, openshift, status_codes,
                                     should_raise, update_or_set, attr_type,
                                     object_type):
        try:
            fn = getattr(
                openshift,
                "{update}_{attr}_on_{object}".format(update=update_or_set,
                                                     attr=attr_type,
                                                     object=object_type))
        except AttributeError:
            return  # not every combination is implemented

        get_expectation = (flexmock(openshift).should_receive('_get').times(
            len(status_codes)))
        put_expectation = (flexmock(openshift).should_receive('_put').times(
            len(status_codes)))
        for status_code in status_codes:
            get_response = make_json_response({"metadata": {}})
            put_response = HttpResponse(status_code, headers={}, content=b'')
            get_expectation = get_expectation.and_return(get_response)
            put_expectation = put_expectation.and_return(put_response)

        (flexmock(time).should_receive('sleep').and_return(None))

        args = ('any-object-id', {'key': 'value'})
        if should_raise:
            with pytest.raises(OsbsResponseException):
                fn(*args)
        else:
            fn(*args)

    def test_put_image_stream_tag(self, openshift):  # noqa
        tag_name = 'spam'
        tag_id = 'maps:' + tag_name
        mock_data = {
            'kind': 'ImageStreamTag',
            'apiVersion': 'v1',
            'tag': {
                'name': tag_name
            }
        }

        expected_url = openshift._build_url("image.openshift.io/v1",
                                            'imagestreamtags/' + tag_id)
        (flexmock(openshift).should_receive("_put").with_args(
            expected_url,
            data=json.dumps(mock_data),
            headers={
                "Content-Type": "application/json"
            }).once().and_return(make_json_response(mock_data)))

        openshift.put_image_stream_tag(tag_id, mock_data)

    def _make_tag_template(self):
        # TODO: Just read from inputs folder
        return json.loads(
            dedent('''\
            {
              "kind": "ImageStreamTag",
              "apiVersion": "v1",
              "metadata": {
                "name": "{{IMAGE_STREAM_ID}}:{{TAG_ID}}"
              },
              "tag": {
                "name": "{{TAG_ID}}",
                "from": {
                  "kind": "DockerImage",
                  "name": "{{REPOSITORY}}:{{TAG_ID}}"
                },
                "importPolicy": {}
              }
            }
        '''))

    @pytest.mark.parametrize('existing_scheduled', (True, False, None))  # noqa
    @pytest.mark.parametrize('existing_insecure', (True, False, None))
    @pytest.mark.parametrize('expected_scheduled', (True, False))
    @pytest.mark.parametrize('s_annotations', (
        {
            ANNOTATION_INSECURE_REPO: 'true'
        },
        {
            ANNOTATION_INSECURE_REPO: 'false'
        },
        {
            ANNOTATION_SOURCE_REPO: 'repo_from_annotations.com/spam'
        },
        {
            ANNOTATION_SOURCE_REPO: 'repo_from_annotations.com/spam'
        },
        {
            ANNOTATION_INSECURE_REPO: 'true',
            ANNOTATION_SOURCE_REPO: 'repo_from_annotations.com/spam'
        },
        {
            ANNOTATION_INSECURE_REPO: 'false',
            ANNOTATION_SOURCE_REPO: 'repo_from_annotations.com/spam'
        },
        {},
        None,
    ))
    @pytest.mark.parametrize('status_code', (200, 404, 500))
    @pytest.mark.parametrize(('repository', 'insecure'), (
        (None, None),
        (None, False),
        (None, True),
        ('repo_from_kwargs.com/spam', None),
        ('repo_from_kwargs.com/spam', True),
        ('repo_from_kwargs.com/spam', False),
    ))
    def test_ensure_image_stream_tag(self, existing_scheduled,
                                     existing_insecure, expected_scheduled,
                                     s_annotations, status_code, repository,
                                     insecure, openshift):
        stream_name = 'spam'
        dockerImage_stream_repo = 'repo_from_dockerImageR.com/spam'
        stream_repo = dockerImage_stream_repo
        if repository:
            stream_repo = repository
        elif s_annotations and ANNOTATION_SOURCE_REPO in s_annotations:
            stream_repo = s_annotations[ANNOTATION_SOURCE_REPO]

        expected_insecure = False
        if repository:
            if insecure is not None:
                expected_insecure = insecure
        elif s_annotations:
            expected_insecure = s_annotations.get(
                ANNOTATION_INSECURE_REPO) == 'true'

        stream = {
            'metadata': {
                'name': stream_name
            },
            'spec': {
                'dockerImageRepository': dockerImage_stream_repo
            }
        }
        if s_annotations is not None:
            stream['metadata']['annotations'] = s_annotations

        tag_name = 'maps'
        tag_id = '{}:{}'.format(stream_name, tag_name)

        expected_url = openshift._build_url("image.openshift.io/v1",
                                            'imagestreamtags/' + tag_id)

        def verify_image_stream_tag(*args, **kwargs):
            data = json.loads(kwargs['data'])

            assert (bool(data['tag']['importPolicy'].get('insecure')) ==
                    expected_insecure)
            assert (bool(data['tag']['importPolicy'].get('scheduled')) ==
                    expected_scheduled)

            # Also verify new image stream tags are created properly.
            if status_code == 404:
                assert data['metadata']['name'] == tag_id
                assert data['tag']['name'] == tag_name
                assert (data['tag']['from']['name'] == '{}:{}'.format(
                    stream_repo, tag_name))

            return make_json_response({})

        expected_change = False
        expected_error = status_code == 500

        mock_response = {}

        expectation = (flexmock(openshift).should_receive("_get").with_args(
            expected_url).once())

        if status_code == 200:
            existing_image_stream_tag = {'tag': {'importPolicy': {}}}

            if existing_insecure is not None:
                existing_image_stream_tag['tag']['importPolicy']['insecure'] = \
                    existing_insecure

            if existing_scheduled is not None:
                existing_image_stream_tag['tag']['importPolicy']['scheduled'] = \
                    existing_scheduled

            mock_response = existing_image_stream_tag

            if expected_insecure != bool(existing_insecure) or \
               expected_scheduled != bool(existing_scheduled):
                expected_change = True

            expectation.and_return(make_json_response(mock_response))

        else:
            expectation.and_return(
                HttpResponse(status_code, headers={}, content=b''))

        if status_code == 404:
            expected_change = True

        if expected_change:
            (flexmock(openshift).should_receive("_put").with_args(
                expected_url,
                data=str,
                headers={
                    "Content-Type": "application/json"
                }).replace_with(verify_image_stream_tag).once())

        kwargs = {}
        if repository:
            kwargs['repository'] = repository
        if insecure:
            kwargs['insecure'] = insecure
        if expected_error:
            with pytest.raises(OsbsResponseException):
                openshift.ensure_image_stream_tag(stream, tag_name,
                                                  self._make_tag_template(),
                                                  expected_scheduled, **kwargs)

        else:
            assert (openshift.ensure_image_stream_tag(
                stream, tag_name, self._make_tag_template(),
                expected_scheduled, **kwargs) == expected_change)

    @pytest.mark.parametrize(
        ('status_codes', 'should_raise'),
        [  # noqa
            ([http_client.OK], False),
            ([http_client.CONFLICT, http_client.CONFLICT, http_client.OK
              ], False),
            ([http_client.CONFLICT, http_client.OK], False),
            ([
                http_client.CONFLICT, http_client.CONFLICT,
                http_client.UNAUTHORIZED
            ], True),
            ([http_client.UNAUTHORIZED], True),
            ([
                http_client.CONFLICT
                for _ in range(OS_CONFLICT_MAX_RETRIES + 1)
            ], True),
        ])
    def test_retry_ensure_image_stream_tag(self, openshift, status_codes,
                                           should_raise):
        get_expectation = (flexmock(openshift).should_receive('_get').times(
            len(status_codes)))
        put_expectation = (flexmock(openshift).should_receive('_put').times(
            len(status_codes)))
        for status_code in status_codes:
            get_response = HttpResponse(http_client.NOT_FOUND,
                                        headers={},
                                        content=b'')
            put_response = HttpResponse(status_code, headers={}, content=b'')
            get_expectation = get_expectation.and_return(get_response)
            put_expectation = put_expectation.and_return(put_response)

        (flexmock(time).should_receive('sleep').and_return(None))

        fn = openshift.ensure_image_stream_tag
        args = ({
            'kind': 'ImageStream',
            'metadata': {
                'name': 'imagestream',
            },
            'spec': {
                'dockerImageRepository': 'registry.example.com/repo',
            },
        }, 'tag', {
            'kind': 'ImageStreamTag',
            'metadata': {
                'name': 'imagestream:tag',
            },
            'tag': {
                'name': 'tag',
                'from': {
                    'kind': 'DockerImage',
                    'name': 'registry.example.com/repo:tag',
                },
                'importPolicy': {},
            },
        })

        if should_raise:
            with pytest.raises(OsbsResponseException):
                fn(*args)
        else:
            fn(*args)

    @pytest.mark.parametrize(('kwargs', 'called'), (
        ({
            'use_auth': True,
            'use_kerberos': True
        }, False),
        ({
            'use_auth': True,
            'username': '******',
            'password': '******'
        }, False),
        ({
            'use_auth': True,
            'token': 'foo'
        }, False),
        ({
            'use_auth': False,
            'use_kerberos': True
        }, False),
        ({
            'use_auth': False,
            'username': '******',
            'password': '******'
        }, False),
        ({
            'use_auth': False,
            'token': 'foo'
        }, False),
        ({
            'use_kerberos': True
        }, False),
        ({
            'username': '******',
            'password': '******'
        }, False),
        ({
            'token': 'foo'
        }, False),
        ({
            'use_auth': False
        }, True),
        ({}, True),
    ))
    def test_use_service_account_token(self, kwargs, called):
        openshift_mock = flexmock(Openshift).should_receive(
            'can_use_serviceaccount_token')
        if called:
            openshift_mock.once()
        else:
            openshift_mock.never()
        Openshift(APIS_PREFIX, "/oauth/authorize", **kwargs)

    @pytest.mark.parametrize(
        'tags',
        (  # noqa:F811
            None,
            [],
            ['7.2.username-66'],
            ['7.2.username-66', '7.2.username-67'],
        ))
    @pytest.mark.parametrize(
        ('imagestream_name', 'expect_update', 'expect_import'), (
            (TEST_IMAGESTREAM, True, True),
            (TEST_IMAGESTREAM_NO_TAGS, True, False),
            (TEST_IMAGESTREAM_WITH_ANNOTATION, False, True),
        ))
    def test_import_image(self, openshift, tags, imagestream_name,
                          expect_update, expect_import):
        """
        tests that import_image return True
        regardless if tags were changed
        """
        this_file = inspect.getfile(TestCheckResponse)
        this_dir = os.path.dirname(this_file)

        json_path = os.path.join(this_dir, "mock_jsons",
                                 openshift._con.version, 'imagestream.json')
        with open(json_path) as f:
            template_resource_json = json.load(f)

        source_repo = None
        modified_resource_json = deepcopy(template_resource_json)
        if modified_resource_json['spec'].get('dockerImageRepository'):
            source_repo = modified_resource_json['spec'].pop(
                'dockerImageRepository')
            modified_resource_json['metadata']['annotations'][
                ANNOTATION_SOURCE_REPO] = source_repo
        else:
            source_repo = modified_resource_json['status'].get(
                'dockerImageRepository')

        stream_import = {'metadata': {'name': 'FOO'}, 'spec': {'images': []}}
        stream_import_json = deepcopy(stream_import)
        stream_import_json['metadata']['name'] = imagestream_name
        if not expect_import:
            modified_resource_json['spec']['tags'] = []

        if tags:
            for tag in modified_resource_json['spec']['tags']:
                if tag['name'] in tags:
                    image_import = {
                        'from': tag['from'],
                        'to': {
                            'name': tag['name']
                        },
                        'importPolicy': tag.get('importPolicy'),
                        'referencePolicy': tag.get('referencePolicy'),
                    }
                    stream_import_json['spec']['images'].append(image_import)
        else:
            for tag in modified_resource_json['spec']['tags']:
                image_import = {
                    'from': tag['from'],
                    'to': {
                        'name': tag['name']
                    },
                    'importPolicy': tag.get('importPolicy'),
                    'referencePolicy': tag.get('referencePolicy'),
                }
                stream_import_json['spec']['images'].append(image_import)

        put_url = openshift._build_url("image.openshift.io/v1",
                                       "imagestreams/%s" % imagestream_name)
        post_url = openshift._build_url("image.openshift.io/v1",
                                        "imagestreamimports/")
        (flexmock(openshift).should_call('_put').times(
            1 if expect_update else 0).with_args(
                put_url,
                data=JsonMatcher(modified_resource_json),
                use_json=True))
        (flexmock(openshift).should_call('_post').times(
            1 if expect_import else 0).with_args(
                post_url, data=JsonMatcher(stream_import_json), use_json=True))

        assert openshift.import_image(
            imagestream_name, stream_import, tags=tags) is expect_import

    @pytest.mark.parametrize(
        'tags',
        (  # noqa:F811
            None,
            [],
            ['7.2.username-66'],
            ['7.2.username-66', '7.2.username-67'],
        ))
    @pytest.mark.parametrize(
        ('imagestream_name', 'expect_update', 'remove_tags'), (
            (TEST_IMAGESTREAM, True, False),
            (TEST_IMAGESTREAM_NO_TAGS, True, True),
            (TEST_IMAGESTREAM_WITH_ANNOTATION, True, False),
            (TEST_IMAGESTREAM_WITHOUT_IMAGEREPOSITORY, False, True),
        ))
    @pytest.mark.parametrize('insecure', (True, False))
    def test_import_image_tags(self, openshift, tags, imagestream_name,
                               expect_update, insecure, remove_tags):
        """
        tests that import_image return True
        regardless if tags were changed
        """
        this_file = inspect.getfile(TestCheckResponse)
        this_dir = os.path.dirname(this_file)

        json_path = os.path.join(this_dir, "mock_jsons",
                                 openshift._con.version, 'imagestream.json')
        with open(json_path) as f:
            template_resource_json = json.load(f)

        modified_resource_json = deepcopy(template_resource_json)
        for annotation in ANNOTATION_SOURCE_REPO, ANNOTATION_INSECURE_REPO:
            modified_resource_json['metadata']['annotations'].pop(
                annotation, None)

        source_repo = None
        if modified_resource_json['spec'].get('dockerImageRepository'):
            source_repo = modified_resource_json['spec'].pop(
                'dockerImageRepository')
        else:
            source_repo = modified_resource_json['status'].get(
                'dockerImageRepository')
            modified_resource_json['spec'][
                'dockerImageRepository'] = source_repo
        if modified_resource_json['metadata']['annotations'].get(
                ANNOTATION_SOURCE_REPO):
            modified_resource_json['metadata']['annotations'][
                ANNOTATION_SOURCE_REPO] = source_repo

        if remove_tags:
            modified_resource_json['spec']['tags'] = []
        expect_import = False
        if tags:
            expect_import = True

        stream_import = {'metadata': {'name': 'FOO'}, 'spec': {'images': []}}
        stream_import_json = deepcopy(stream_import)
        stream_import_json['metadata']['name'] = imagestream_name

        if tags:
            for tag in set(tags):
                image_import = {
                    'from': {
                        "kind": "DockerImage",
                        "name": '{}:{}'.format(source_repo, tag)
                    },
                    'to': {
                        'name': tag
                    },
                    'importPolicy': {
                        'insecure': insecure
                    },
                }
                stream_import_json['spec']['images'].append(image_import)

        put_url = openshift._build_url("image.openshift.io/v1",
                                       "imagestreams/%s" % imagestream_name)
        (flexmock(openshift).should_call('_put').times(
            1 if expect_update else 0).with_args(
                put_url,
                data=JsonMatcher(modified_resource_json),
                use_json=True))

        # Load example API response
        this_file = inspect.getfile(TestCheckResponse)
        this_dir = os.path.dirname(this_file)
        json_path = os.path.join(this_dir, "mock_jsons",
                                 openshift._con.version,
                                 'imagestreamimport.json')
        with open(json_path) as f:
            content_json = json.load(f)
        good_resp = HttpResponse(
            200, {}, content=json.dumps(content_json).encode('utf-8'))
        image_status = {'status': 'Failure', 'code': 504, 'reason': 'TimeOut'}
        # Create a bad response by marking the first image as failed
        for key in ('status', 'code', 'reason'):
            content_json['status']['images'][0]['status'][key] = image_status[
                key]
        bad_resp = HttpResponse(
            504, {}, content=json.dumps(content_json).encode('utf-8'))

        post_url = openshift._build_url("image.openshift.io/v1",
                                        "imagestreamimports/")
        if expect_import:
            (flexmock(openshift).should_receive('_post').times(2).with_args(
                post_url, data=JsonMatcher(stream_import_json),
                use_json=True).and_return(bad_resp).and_return(good_resp))
        else:
            (flexmock(openshift).should_call('_post').times(0).with_args(
                post_url, data=JsonMatcher(stream_import_json), use_json=True))

        assert openshift.import_image_tags(imagestream_name, stream_import,
                                           tags, source_repo,
                                           insecure) is expect_import

    @pytest.mark.parametrize(
        ('image_status', 'expect_retry'),
        (  # noqa:F811
            ({
                'status': 'Failure',
                'code': 500,
                'reason': 'InternalError'
            }, True),
            ({
                'status': 'Failure',
                'code': 400,
                'reason': 'BadRequest'
            }, False),
        ))
    def test_import_image_retry(self, openshift, image_status, expect_retry):
        imagestream_name = TEST_IMAGESTREAM

        # Load example API response
        this_file = inspect.getfile(TestCheckResponse)
        this_dir = os.path.dirname(this_file)
        json_path = os.path.join(this_dir, "mock_jsons",
                                 openshift._con.version,
                                 'imagestreamimport.json')
        with open(json_path) as f:
            content_json = json.load(f)

        # Assume mocked data contains a good response
        good_resp = HttpResponse(
            200, {}, content=json.dumps(content_json).encode('utf-8'))

        # Create a bad response by marking the first image as failed
        for key in ('status', 'code', 'reason'):
            content_json['status']['images'][0]['status'][key] = image_status[
                key]
        bad_resp = HttpResponse(
            200, {}, content=json.dumps(content_json).encode('utf-8'))

        # Make time go faster
        flexmock(time).should_receive('sleep')

        stream_import = {'metadata': {'name': 'FOO'}, 'spec': {'images': []}}
        tags = ['7.2.username-66', '7.2.username-67']

        if expect_retry:
            (flexmock(openshift).should_receive('_post').times(3).and_return(
                bad_resp).and_return(bad_resp).and_return(good_resp))
            assert openshift.import_image(
                imagestream_name, stream_import, tags=tags) is True
        else:
            (flexmock(openshift).should_receive('_post').once().and_return(
                bad_resp))
            with pytest.raises(ImportImageFailed):
                openshift.import_image(imagestream_name,
                                       stream_import,
                                       tags=tags)
Example #5
0
class TestOpenshift(object):
    def test_set_labels_on_build(self, openshift):  # noqa
        labels = openshift.set_labels_on_build(TEST_BUILD,
                                               {TEST_LABEL: TEST_LABEL_VALUE})
        assert labels.json() is not None

    @pytest.mark.parametrize(
        'exc',
        [  # noqa
            ConnectionError('Connection aborted.',
                            http_client.BadStatusLine("''", )),
        ])
    def test_stream_logs_bad_initial_connection(self, openshift, exc):
        response = flexmock(status_code=http_client.OK)
        (response.should_receive('iter_lines').and_return(
            [b"{'stream': 'foo\n'}"]).and_raise(StopIteration))

        wrapped_exc = OsbsNetworkException('http://spam.com',
                                           str(exc),
                                           status_code=None,
                                           cause=exc)
        (flexmock(openshift).should_receive('_get')
         # First: simulate initial connection problem
         .and_raise(wrapped_exc)
         # Next: return a real response
         .and_return(response))

        (flexmock(time).should_receive('time').and_return(0).and_return(100))

        logs = openshift.stream_logs(TEST_BUILD)
        assert len([log for log in logs]) == 1

    def test_stream_logs_utf8(self, openshift):  # noqa
        response = flexmock(status_code=http_client.OK)
        (response.should_receive('iter_lines').and_return([
            u"{'stream': 'Uňícode íš hářd\n'}".encode('utf-8')
        ]).and_raise(StopIteration))

        (flexmock(openshift).should_receive('_get').and_return(response))

        logs = openshift.stream_logs(TEST_BUILD)
        assert len([log for log in logs]) == 1

    def test_list_builds(self, openshift):  # noqa
        list_builds = openshift.list_builds()
        assert list_builds is not None
        assert bool(list_builds.json())  # is there at least something

    def test_list_pods(self, openshift):  # noqa
        response = openshift.list_pods(label="openshift.io/build.name=%s" %
                                       TEST_BUILD)
        assert isinstance(response, HttpResponse)

    def test_get_oauth_token(self, openshift):  # noqa
        token = openshift.get_oauth_token()
        assert token is not None

    def test_get_user(self, openshift):  # noqa
        l = openshift.get_user()
        assert l.json() is not None

    def test_watch_resource_and_wait_to_build_timeouts(self, caplog,
                                                       openshift):  # noqa:F811
        class MockResponse(object):
            def __init__(self):
                self.status_code = http_client.OK

            def iter_lines(self):
                return []

        mock_reponse = MockResponse()
        flexmock(openshift).should_receive('_get').and_return(mock_reponse)
        flexmock(time).should_receive('sleep').and_return(None)
        for changetype, obj in openshift.watch_resource("builds", 12):
            # watch_resource failed and never yielded, so we shouldn't hit the assert
            assert False

        with pytest.raises(OsbsWatchBuildNotFound):
            openshift.wait(12, None)

        with pytest.raises(OsbsException):
            openshift.wait_for_build_to_finish(12)

        for log in caplog.records():
            if 'Retry #143' in log.getMessage():
                break
        assert 'Retry #143' in log.getMessage()

    def test_watch_build(self, openshift):  # noqa
        response = openshift.wait_for_build_to_finish(TEST_BUILD)
        status_lower = response["status"]["phase"].lower()
        assert response["metadata"]["name"] == TEST_BUILD
        assert status_lower in BUILD_FINISHED_STATES
        assert isinstance(TEST_BUILD, six.text_type)
        assert isinstance(status_lower, six.text_type)

    def test_create_build(self, openshift):  # noqa
        response = openshift.create_build({})
        assert response is not None
        assert response.json()["metadata"]["name"] == TEST_BUILD
        assert response.json()["status"]["phase"].lower(
        ) in BUILD_FINISHED_STATES

    def test_cancel_build(self, openshift):  # noqa
        response = openshift.cancel_build(TEST_CANCELLED_BUILD)
        assert response is not None
        assert response.json()["metadata"]["name"] == TEST_CANCELLED_BUILD
        assert response.json()["status"]["phase"].lower(
        ) in BUILD_CANCELLED_STATE

    def test_get_build_config(self, openshift):  # noqa
        mock_response = {"spam": "maps"}
        build_config_name = 'some-build-config-name'
        expected_url = openshift._build_url("buildconfigs/%s/" %
                                            build_config_name)
        (flexmock(openshift).should_receive("_get").with_args(
            expected_url).once().and_return(make_json_response(mock_response)))
        response = openshift.get_build_config(build_config_name)
        assert response['spam'] == 'maps'

    def test_get_missing_build_config(self, openshift):  # noqa
        build_config_name = 'some-build-config-name'
        expected_url = openshift._build_url("buildconfigs/%s/" %
                                            build_config_name)
        (flexmock(openshift).should_receive("_get").with_args(
            expected_url).once().and_return(HttpResponse(404, {}, b'')))
        with pytest.raises(OsbsResponseException):
            openshift.get_build_config(build_config_name)

    def test_get_build_config_by_labels(self, openshift):  # noqa
        mock_response = {"items": [{"spam": "maps"}]}
        label_selectors = (
            ('label-1', 'value-1'),
            ('label-2', 'value-2'),
        )
        expected_url = openshift._build_url(
            "buildconfigs/?labelSelector=label-1%3Dvalue-1%2Clabel-2%3Dvalue-2"
        )
        (flexmock(openshift).should_receive("_get").with_args(
            expected_url).once().and_return(make_json_response(mock_response)))
        response = openshift.get_build_config_by_labels(label_selectors)
        assert response['spam'] == 'maps'

    def test_get_missing_build_config_by_labels(self, openshift):  # noqa
        mock_response = {"items": []}
        label_selectors = (
            ('label-1', 'value-1'),
            ('label-2', 'value-2'),
        )
        expected_url = openshift._build_url(
            "buildconfigs/?labelSelector=label-1%3Dvalue-1%2Clabel-2%3Dvalue-2"
        )
        (flexmock(openshift).should_receive("_get").with_args(
            expected_url).once().and_return(make_json_response(mock_response)))

        with pytest.raises(OsbsException) as exc:
            openshift.get_build_config_by_labels(label_selectors)
        assert str(exc.value).startswith('Build config not found')

    def test_get_multiple_build_config_by_labels(self, openshift):  # noqa
        mock_response = {"items": [{"spam": "maps"}, {"eggs": "sgge"}]}
        label_selectors = (
            ('label-1', 'value-1'),
            ('label-2', 'value-2'),
        )
        expected_url = openshift._build_url(
            "buildconfigs/?labelSelector=label-1%3Dvalue-1%2Clabel-2%3Dvalue-2"
        )
        (flexmock(openshift).should_receive("_get").with_args(
            expected_url).once().and_return(make_json_response(mock_response)))

        with pytest.raises(OsbsException) as exc:
            openshift.get_build_config_by_labels(label_selectors)
        assert str(exc.value).startswith('More than one build config found')

    @pytest.mark.parametrize(
        ('status_codes', 'should_raise'),
        [  # noqa
            ([http_client.OK], False),
            ([http_client.CONFLICT, http_client.CONFLICT, http_client.OK
              ], False),
            ([http_client.CONFLICT, http_client.OK], False),
            ([
                http_client.CONFLICT, http_client.CONFLICT,
                http_client.UNAUTHORIZED
            ], True),
            ([http_client.UNAUTHORIZED], True),
            ([
                http_client.CONFLICT
                for _ in range(OS_CONFLICT_MAX_RETRIES + 1)
            ], True),
        ])
    @pytest.mark.parametrize('update_or_set', ['update', 'set'])
    @pytest.mark.parametrize('attr_type', ['labels', 'annotations'])
    @pytest.mark.parametrize('object_type', ['build', 'build_config'])
    def test_retry_update_attributes(self, openshift, status_codes,
                                     should_raise, update_or_set, attr_type,
                                     object_type):
        try:
            fn = getattr(
                openshift,
                "{update}_{attr}_on_{object}".format(update=update_or_set,
                                                     attr=attr_type,
                                                     object=object_type))
        except AttributeError:
            return  # not every combination is implemented

        get_expectation = (flexmock(openshift).should_receive('_get').times(
            len(status_codes)))
        put_expectation = (flexmock(openshift).should_receive('_put').times(
            len(status_codes)))
        for status_code in status_codes:
            get_response = make_json_response({"metadata": {}})
            put_response = HttpResponse(status_code, headers={}, content=b'')
            get_expectation = get_expectation.and_return(get_response)
            put_expectation = put_expectation.and_return(put_response)

        (flexmock(time).should_receive('sleep').and_return(None))

        args = ('any-object-id', {'key': 'value'})
        if should_raise:
            with pytest.raises(OsbsResponseException):
                fn(*args)
        else:
            fn(*args)

    def test_put_image_stream_tag(self, openshift):  # noqa
        tag_name = 'spam'
        tag_id = 'maps:' + tag_name
        mock_data = {
            'kind': 'ImageStreamTag',
            'apiVersion': 'v1',
            'tag': {
                'name': tag_name
            }
        }

        expected_url = openshift._build_url('imagestreamtags/' + tag_id)
        (flexmock(openshift).should_receive("_put").with_args(
            expected_url,
            data=json.dumps(mock_data),
            headers={
                "Content-Type": "application/json"
            }).once().and_return(make_json_response(mock_data)))

        openshift.put_image_stream_tag(tag_id, mock_data)

    def _make_tag_template(self):
        # TODO: Just read from inputs folder
        return json.loads(
            dedent('''\
            {
              "kind": "ImageStreamTag",
              "apiVersion": "v1",
              "metadata": {
                "name": "{{IMAGE_STREAM_ID}}:{{TAG_ID}}"
              },
              "tag": {
                "name": "{{TAG_ID}}",
                "from": {
                  "kind": "DockerImage",
                  "name": "{{REPOSITORY}}:{{TAG_ID}}"
                },
                "importPolicy": {}
              }
            }
        '''))

    @pytest.mark.parametrize('existing_scheduled', (True, False, None))  # noqa
    @pytest.mark.parametrize('existing_insecure', (True, False, None))
    @pytest.mark.parametrize('expected_scheduled', (True, False))
    @pytest.mark.parametrize(('s_annotations', 'expected_insecure'), (
        ({
            ANNOTATION_INSECURE_REPO: 'true'
        }, True),
        ({
            ANNOTATION_INSECURE_REPO: 'false'
        }, False),
        ({}, False),
        (None, False),
    ))
    @pytest.mark.parametrize('status_code', (200, 404, 500))
    def test_ensure_image_stream_tag(self, existing_scheduled,
                                     existing_insecure, expected_scheduled,
                                     s_annotations, expected_insecure,
                                     status_code, openshift):
        stream_name = 'spam'
        stream_repo = 'some.registry.com/spam'
        stream = {
            'metadata': {
                'name': stream_name
            },
            'spec': {
                'dockerImageRepository': stream_repo
            }
        }
        if s_annotations is not None:
            stream['metadata']['annotations'] = s_annotations

        tag_name = 'maps'
        tag_id = '{0}:{1}'.format(stream_name, tag_name)

        expected_url = openshift._build_url('imagestreamtags/' + tag_id)

        def verify_image_stream_tag(*args, **kwargs):
            data = json.loads(kwargs['data'])

            assert (bool(data['tag']['importPolicy'].get('insecure')) ==
                    expected_insecure)
            assert (bool(data['tag']['importPolicy'].get('scheduled')) ==
                    expected_scheduled)

            # Also verify new image stream tags are created properly.
            if status_code == 404:
                assert data['metadata']['name'] == tag_id
                assert data['tag']['name'] == tag_name
                assert (data['tag']['from']['name'] == '{0}:{1}'.format(
                    stream_repo, tag_name))

            return make_json_response({})

        expected_change = False
        expected_error = status_code == 500

        mock_response = {}

        expectation = (flexmock(openshift).should_receive("_get").with_args(
            expected_url).once())

        if status_code == 200:
            existing_image_stream_tag = {'tag': {'importPolicy': {}}}

            if existing_insecure is not None:
                existing_image_stream_tag['tag']['importPolicy']['insecure'] = \
                    existing_insecure

            if existing_scheduled is not None:
                existing_image_stream_tag['tag']['importPolicy']['scheduled'] = \
                    existing_scheduled

            mock_response = existing_image_stream_tag

            if expected_insecure != bool(existing_insecure) or \
               expected_scheduled != bool(existing_scheduled):
                expected_change = True

            expectation.and_return(make_json_response(mock_response))

        else:
            expectation.and_return(
                HttpResponse(status_code, headers={}, content=b''))

        if status_code == 404:
            expected_change = True

        if expected_change:
            (flexmock(openshift).should_receive("_put").with_args(
                expected_url,
                data=str,
                headers={
                    "Content-Type": "application/json"
                }).replace_with(verify_image_stream_tag).once())

        if expected_error:
            with pytest.raises(OsbsResponseException):
                openshift.ensure_image_stream_tag(stream, tag_name,
                                                  self._make_tag_template(),
                                                  expected_scheduled)

        else:
            assert (openshift.ensure_image_stream_tag(
                stream, tag_name, self._make_tag_template(),
                expected_scheduled) == expected_change)

    @pytest.mark.parametrize(
        ('status_codes', 'should_raise'),
        [  # noqa
            ([http_client.OK], False),
            ([http_client.CONFLICT, http_client.CONFLICT, http_client.OK
              ], False),
            ([http_client.CONFLICT, http_client.OK], False),
            ([
                http_client.CONFLICT, http_client.CONFLICT,
                http_client.UNAUTHORIZED
            ], True),
            ([http_client.UNAUTHORIZED], True),
            ([
                http_client.CONFLICT
                for _ in range(OS_CONFLICT_MAX_RETRIES + 1)
            ], True),
        ])
    def test_retry_ensure_image_stream_tag(self, openshift, status_codes,
                                           should_raise):
        get_expectation = (flexmock(openshift).should_receive('_get').times(
            len(status_codes)))
        put_expectation = (flexmock(openshift).should_receive('_put').times(
            len(status_codes)))
        for status_code in status_codes:
            get_response = HttpResponse(http_client.NOT_FOUND,
                                        headers={},
                                        content=b'')
            put_response = HttpResponse(status_code, headers={}, content=b'')
            get_expectation = get_expectation.and_return(get_response)
            put_expectation = put_expectation.and_return(put_response)

        (flexmock(time).should_receive('sleep').and_return(None))

        fn = openshift.ensure_image_stream_tag
        args = ({
            'kind': 'ImageStream',
            'metadata': {
                'name': 'imagestream',
            },
            'spec': {
                'dockerImageRepository': 'registry.example.com/repo',
            },
        }, 'tag', {
            'kind': 'ImageStreamTag',
            'metadata': {
                'name': 'imagestream:tag',
            },
            'tag': {
                'name': 'tag',
                'from': {
                    'kind': 'DockerImage',
                    'name': 'registry.example.com/repo:tag',
                },
                'importPolicy': {},
            },
        })

        if should_raise:
            with pytest.raises(OsbsResponseException):
                fn(*args)
        else:
            fn(*args)

    @pytest.mark.parametrize(('kwargs', 'called'), (
        ({
            'use_auth': True,
            'use_kerberos': True
        }, False),
        ({
            'use_auth': True,
            'username': '******',
            'password': '******'
        }, False),
        ({
            'use_auth': True,
            'token': 'foo'
        }, False),
        ({
            'use_auth': False,
            'use_kerberos': True
        }, False),
        ({
            'use_auth': False,
            'username': '******',
            'password': '******'
        }, False),
        ({
            'use_auth': False,
            'token': 'foo'
        }, False),
        ({
            'use_kerberos': True
        }, False),
        ({
            'username': '******',
            'password': '******'
        }, False),
        ({
            'token': 'foo'
        }, False),
        ({
            'use_auth': False
        }, True),
        ({}, True),
    ))
    def test_use_service_account_token(self, kwargs, called):
        openshift_mock = flexmock(Openshift).should_receive(
            'can_use_serviceaccount_token')
        if called:
            openshift_mock.once()
        else:
            openshift_mock.never()
        Openshift(OAPI_PREFIX, API_VER, "/oauth/authorize", **kwargs)

    @pytest.mark.parametrize(
        ('imagestream_name', 'expect_update', 'expect_import'),
        (  # noqa:F811
            (TEST_IMAGESTREAM, True, True),
            (TEST_IMAGESTREAM_NO_TAGS, True, False),
            (TEST_IMAGESTREAM_WITH_ANNOTATION, False, True),
        ))
    def test_import_image(self, openshift, imagestream_name, expect_update,
                          expect_import):
        """
        tests that import_image return True
        regardless if tags were changed
        """
        this_file = inspect.getfile(TestCheckResponse)
        this_dir = os.path.dirname(this_file)

        json_path = os.path.join(this_dir, "mock_jsons",
                                 openshift._con.version, 'imagestream.json')
        with open(json_path) as f:
            template_resource_json = json.load(f)

        initial_resource_json = deepcopy(template_resource_json)

        modified_resource_json = deepcopy(template_resource_json)
        source_repo = modified_resource_json['spec'].pop(
            'dockerImageRepository')
        modified_resource_json['metadata']['annotations'][
            ANNOTATION_SOURCE_REPO] = source_repo
        if not expect_import:
            modified_resource_json['spec']['tags'] = []

        put_url = openshift._build_url("imagestreams/%s" % imagestream_name)
        (flexmock(openshift).should_call('_put').times(
            1 if expect_update else 0).with_args(
                put_url,
                data=JsonMatcher(modified_resource_json),
                use_json=True))

        stream_import = {'metadata': {'name': 'FOO'}, 'spec': {'images': []}}
        assert openshift.import_image(imagestream_name,
                                      stream_import) is expect_import
Example #6
0
 def _urlopen(*args):
     raise http_client.BadStatusLine('line')