Esempio n. 1
0
async def test_client_installation_HTTP_500(httpserver: httpserver.HTTPServer) -> None:
    httpserver.expect_request("/users/owner/installation").respond_with_data(
        "This is an 5XX error", status=500
    )
    with mock.patch(
        "mergify_engine.config.GITHUB_API_URL",
        httpserver.url_for("/")[:-1],
    ):
        async with github.AsyncGithubInstallationClient(
            github.get_auth(github_types.GitHubLogin("owner"))
        ) as client:
            with pytest.raises(http.HTTPServerSideError) as exc_info:
                await client.get(httpserver.url_for("/"))

    # 5 retries
    assert len(httpserver.log) == 5

    assert exc_info.value.message == "This is an 5XX error"
    assert exc_info.value.status_code == 500
    assert exc_info.value.response.status_code == 500
    assert str(exc_info.value.request.url) == httpserver.url_for(
        "/users/owner/installation"
    )

    httpserver.check_assertions()
Esempio n. 2
0
def test_client_user_token(httpserver: httpserver.HTTPServer) -> None:
    with mock.patch(
            "mergify_engine.config.GITHUB_API_URL",
            httpserver.url_for("/")[:-1],
    ):
        httpserver.expect_request("/users/owner").respond_with_json({
            "login":
            "******",
            "id":
            12345,
        })
        httpserver.expect_request("/",
                                  headers={
                                      "Authorization": "token <user-token>"
                                  }).respond_with_json({"work": True},
                                                       status=200)

        with github.GithubInstallationClient(
                github.get_auth("owner")) as client:
            ret = client.get(
                httpserver.url_for("/"),
                oauth_token="<user-token>")  # type: ignore[call-arg]
            assert ret.json()["work"]

    assert len(httpserver.log) == 2
Esempio n. 3
0
async def test_client_HTTP_500(httpserver: httpserver.HTTPServer) -> None:
    httpserver.expect_request("/").respond_with_data("This is an 5XX error", status=500)

    async with http.AsyncClient() as client:
        with pytest.raises(http.HTTPServerSideError) as exc_info:
            await client.get(httpserver.url_for("/"))

    # 5 retries
    assert len(httpserver.log) == 5

    assert exc_info.value.message == "This is an 5XX error"
    assert exc_info.value.status_code == 500
    assert exc_info.value.response.status_code == 500
    assert str(exc_info.value.request.url) == httpserver.url_for("/")

    httpserver.check_assertions()
Esempio n. 4
0
def test_market_event_forward(_: mock.PropertyMock,
                              httpserver: httpserver.HTTPServer) -> None:

    with open(
            os.path.join(os.path.dirname(__file__), "events",
                         "marketplace.json")) as f:
        data = f.read()

    headers = {
        "X-GitHub-Delivery": str(uuid.uuid4()),
        "X-GitHub-Event": "purchased",
        "X-Hub-Signature":
        f"sha1={utils.compute_hmac(data.encode(), config.WEBHOOK_SECRET)}",
        "User-Agent": "GitHub-Hookshot/044aadd",
        "Content-Type": "application/json",
    }
    httpserver.expect_request("/", method="POST", data=data,
                              headers=headers).respond_with_data("")

    with mock.patch(
            "mergify_engine.config.WEBHOOK_MARKETPLACE_FORWARD_URL",
            httpserver.url_for("/"),
    ):
        with testclient.TestClient(root.app) as client:
            client.post("/marketplace", data=data, headers=headers)

    httpserver.check_assertions()  # type: ignore[no-untyped-call]
Esempio n. 5
0
def test_client_installation_token(httpserver: httpserver.HTTPServer) -> None:
    with mock.patch(
            "mergify_engine.config.GITHUB_API_URL",
            httpserver.url_for("/")[:-1],
    ):
        httpserver.expect_request(
            "/users/owner/installation").respond_with_json({
                "id": 12345,
                "target_type": "User",
                "permissions": {
                    "checks": "write",
                    "contents": "write",
                    "pull_requests": "write",
                },
                "account": {
                    "login": "******",
                    "id": 12345
                },
            })
        httpserver.expect_request(
            "/app/installations/12345/access_tokens").respond_with_json({
                "token":
                "<app_token>",
                "expires_at":
                "2100-12-31T23:59:59Z"
            })

        httpserver.expect_request("/",
                                  headers={
                                      "Authorization":
                                      "token <installation-token>"
                                  }).respond_with_json({"work": True},
                                                       status=200)

        with github.GithubInstallationClient(
                github.get_auth("owner")) as client:
            ret = client.get(httpserver.url_for("/"))
            assert ret.json()["work"]

    assert len(httpserver.log) == 3

    httpserver.check_assertions()
Esempio n. 6
0
async def test_client_401_raise_ratelimit(
        httpserver: httpserver.HTTPServer) -> None:
    owner = github_types.GitHubLogin("owner")
    repo = "repo"

    httpserver.expect_request("/users/owner/installation").respond_with_json({
        "id":
        12345,
        "target_type":
        "User",
        "permissions": {
            "checks": "write",
            "contents": "write",
            "pull_requests": "write",
        },
        "account": {
            "login": "******",
            "id": 12345
        },
    })
    httpserver.expect_request(
        "/app/installations/12345/access_tokens").respond_with_json(
            {
                "token": "<token>",
                "expires_at": "2100-12-31T23:59:59Z"
            },
            headers={
                "X-RateLimit-Remaining": 5000,
                "X-RateLimit-Reset": 1234567890
            },
        )

    httpserver.expect_oneshot_request(
        "/repos/owner/repo/pull/1").respond_with_json(
            {"message": "quota !"},
            status=403,
            headers={
                "X-RateLimit-Remaining": 0,
                "X-RateLimit-Reset": 1234567890
            },
        )

    with mock.patch(
            "mergify_engine.config.GITHUB_API_URL",
            httpserver.url_for("/")[:-1],
    ):
        async with github.aget_client(owner) as client:
            with pytest.raises(exceptions.RateLimited):
                await client.item(f"/repos/{owner}/{repo}/pull/1")

    httpserver.check_assertions()
Esempio n. 7
0
def test_client_installation_HTTP_301(
        httpserver: httpserver.HTTPServer) -> None:
    httpserver.expect_request("/users/owner/installation").respond_with_data(
        status=301,
        headers={
            "Location": httpserver.url_for("/repositories/12345/installation")
        },
    )
    httpserver.expect_request(
        "/repositories/12345/installation").respond_with_json(
            {"message": "Repository not found"}, status=404)
    with mock.patch(
            "mergify_engine.config.GITHUB_API_URL",
            httpserver.url_for("/")[:-1],
    ):
        with github.GithubInstallationClient(
                github.get_auth("owner")) as client:
            with pytest.raises(exceptions.MergifyNotInstalled):
                client.get(httpserver.url_for("/"))

    assert len(httpserver.log) == 2

    httpserver.check_assertions()
Esempio n. 8
0
async def test_send_seats(httpserver: httpserver.HTTPServer) -> None:
    httpserver.expect_request(
        "/on-premise/report",
        method="POST",
        json={"seats": 5, "write_users": 5, "active_users": 2, "engine_version": "dev"},
    ).respond_with_data("Accepted", status=201)
    with mock.patch(
        "mergify_engine.config.SUBSCRIPTION_BASE_URL",
        httpserver.url_for("/")[:-1],
    ):
        await count_seats.send_seats(count_seats.SeatsCountResultT(5, 2))

    assert len(httpserver.log) == 1

    httpserver.check_assertions()  # type: ignore [no-untyped-call]
Esempio n. 9
0
def test_client_temporary_HTTP_500(httpserver: httpserver.HTTPServer) -> None:
    httpserver.expect_oneshot_request("/").respond_with_data(
        "This is an 5XX error", status=500)
    httpserver.expect_oneshot_request("/").respond_with_data(
        "This is an 5XX error", status=500)
    httpserver.expect_oneshot_request("/").respond_with_data(
        "This is an 5XX error", status=500)
    httpserver.expect_request("/").respond_with_data("It works now !",
                                                     status=200)

    with http.Client() as client:
        client.get(httpserver.url_for("/"))

    # 4 retries
    assert len(httpserver.log) == 4

    httpserver.check_assertions()
Esempio n. 10
0
async def _do_test_client_retry_429(
    httpserver: httpserver.HTTPServer, retry_after: str, expected_seconds: int
) -> None:
    records = []

    def record_date(_):
        records.append(datetime.datetime.utcnow())
        return Response("It works now !", 200)

    httpserver.expect_oneshot_request("/").respond_with_data(
        "This is an 429 error", status=429, headers={"Retry-After": retry_after}
    )
    httpserver.expect_request("/").respond_with_handler(record_date)

    async with http.AsyncClient() as client:
        now = datetime.datetime.utcnow()
        await client.get(httpserver.url_for("/"))

    assert len(httpserver.log) == 2
    elapsed_seconds = (records[0] - now).total_seconds()
    assert expected_seconds - 1 < elapsed_seconds <= expected_seconds + 1
    httpserver.check_assertions()
Esempio n. 11
0
async def github_server(
    httpserver: httpserver.HTTPServer, monkeypatch: pytest.MonkeyPatch
) -> typing.AsyncGenerator[httpserver.HTTPServer, None]:
    monkeypatch.setattr(config, "GITHUB_API_URL", httpserver.url_for("/")[:-1])
    monkeypatch.setattr(github.CachedToken, "STORAGE", {})

    httpserver.expect_request("/users/owner/installation").respond_with_json(
        {
            "id": 12345,
            "target_type": "User",
            "permissions": {
                "checks": "write",
                "contents": "write",
                "pull_requests": "write",
            },
            "account": {"login": "******", "id": 12345},
        }
    )
    httpserver.expect_request(
        "/app/installations/12345/access_tokens"
    ).respond_with_json({"token": "<app_token>", "expires_at": "2100-12-31T23:59:59Z"})

    yield httpserver