1
0
Fork 0
pull/1486/head
Bethany 2023-08-07 16:26:07 -07:00
parent 6552cb9722
commit af1621025d
2 changed files with 51 additions and 44 deletions

View File

@ -6,20 +6,15 @@ import { createArtifactTwirpClient } from "../src/internal/shared/artifact-twirp
import * as core from "@actions/core" import * as core from "@actions/core"
const mockPost = jest.fn((statusCode: number, body: string) => { const mockPost = jest.fn()
const msg = new http.IncomingMessage(new net.Socket())
msg.statusCode = statusCode
return {
message: msg,
readBody: () => {return Promise.resolve(body)}
}
})
jest.mock("@actions/http-client", () => { jest.mock("@actions/http-client", () => {
return jest.fn().mockImplementation(() => { return {
HttpClient: jest.fn().mockImplementation(() => {
return { return {
post: mockPost post: mockPost
} }
}) })
}
}) })
describe("artifact-http-client", () => { describe("artifact-http-client", () => {
@ -35,7 +30,7 @@ describe("artifact-http-client", () => {
beforeEach(() => { beforeEach(() => {
mockPost.mockClear(); mockPost.mockClear();
(HttpClient as unknown as jest.Mock).mockClear()
}) })
it("should successfully create a client", () => { it("should successfully create a client", () => {
@ -58,7 +53,16 @@ describe("artifact-http-client", () => {
} }
}) })
*/ */
const client = createArtifactTwirpClient("upload", new HttpClient()) mockPost.mockImplementationOnce(() => {
const msg = new http.IncomingMessage(new net.Socket())
msg.statusCode = 200
return {
message: msg,
readBody: () => {return Promise.resolve(`{"ok": true, "signedUploadUrl": "http://localhost:8080/upload"}`)}
}
})
const client = createArtifactTwirpClient("upload")
const artifact = await client.CreateArtifact( const artifact = await client.CreateArtifact(
{ {
workflowRunBackendId: "1234", workflowRunBackendId: "1234",
@ -68,7 +72,7 @@ describe("artifact-http-client", () => {
} }
) )
expect(mockHttpClient).toHaveBeenCalledTimes(1) expect(mockPost).toHaveBeenCalledTimes(1)
expect(artifact).toBeDefined() expect(artifact).toBeDefined()
expect(artifact.ok).toBe(true) expect(artifact.ok).toBe(true)
expect(artifact.signedUploadUrl).toBe("http://localhost:8080/upload") expect(artifact.signedUploadUrl).toBe("http://localhost:8080/upload")
@ -92,18 +96,21 @@ describe("artifact-http-client", () => {
} }
}) })
*/ */
mockPost.mockImplementationOnce(() => {
const msgFailed = new http.IncomingMessage(new net.Socket()) const msgFailed = new http.IncomingMessage(new net.Socket())
msgFailed.statusCode = 500 msgFailed.statusCode = 500
const msgSucceeded = new http.IncomingMessage(new net.Socket()) return {
msgSucceeded.statusCode = 200
const mockPost = jest.fn()
mockPost.mockReturnValueOnce({
message: msgFailed, message: msgFailed,
readBody: () => {return Promise.resolve(`{"ok": false}`)} readBody: () => {return Promise.resolve(`{"ok": false}`)}
}).mockReturnValue({ }
}).mockImplementationOnce(() => {
const msgSucceeded = new http.IncomingMessage(new net.Socket())
msgSucceeded.statusCode = 200
return {
message: msgSucceeded, message: msgSucceeded,
readBody: () => {return Promise.resolve(`{"ok": true, "signedUploadUrl": "http://localhost:8080/upload"}`)} readBody: () => {return Promise.resolve(`{"ok": true, "signedUploadUrl": "http://localhost:8080/upload"}`)}
}
}) })
/* /*
@ -124,8 +131,6 @@ describe("artifact-http-client", () => {
readBody: () => {return Promise.resolve(`{"ok": true, "signedUploadUrl": "http://localhost:8080/lol/upload"}`)} readBody: () => {return Promise.resolve(`{"ok": true, "signedUploadUrl": "http://localhost:8080/lol/upload"}`)}
} }
}) })
*/
jest.mock("@actions/http-client", () => { jest.mock("@actions/http-client", () => {
return jest.fn().mockImplementation(() => { return jest.fn().mockImplementation(() => {
return { return {
@ -133,7 +138,6 @@ describe("artifact-http-client", () => {
} }
}) })
}) })
/*
jest.mock("@actions/http-client", () => { jest.mock("@actions/http-client", () => {
return { return {
HttpClient: jest.fn().mockImplementation(() => { HttpClient: jest.fn().mockImplementation(() => {
@ -152,7 +156,7 @@ describe("artifact-http-client", () => {
}) })
*/ */
const client = createArtifactTwirpClient("upload", new HttpClient()) const client = createArtifactTwirpClient("upload")
const artifact = await client.CreateArtifact( const artifact = await client.CreateArtifact(
{ {
workflowRunBackendId: "1234", workflowRunBackendId: "1234",

View File

@ -21,18 +21,14 @@ class ArtifactHttpClient implements Rpc {
private baseRetryIntervalMilliseconds: number = 3000 private baseRetryIntervalMilliseconds: number = 3000
private retryMultiplier: number = 1.5 private retryMultiplier: number = 1.5
constructor(userAgent: string, httpClient?: HttpClient) { constructor(userAgent: string) {
const token = getRuntimeToken() const token = getRuntimeToken()
this.baseUrl = getResultsServiceUrl() this.baseUrl = getResultsServiceUrl()
if (httpClient) {
this.httpClient = httpClient
} else {
this.httpClient = new HttpClient( this.httpClient = new HttpClient(
userAgent, userAgent,
[new BearerCredentialHandler(token)], [new BearerCredentialHandler(token)],
) )
} }
}
// This function satisfies the Rpc interface. It is compatible with the JSON // This function satisfies the Rpc interface. It is compatible with the JSON
// JSON generated client. // JSON generated client.
@ -79,11 +75,18 @@ class ArtifactHttpClient implements Rpc {
throw new Error(errorMessage) throw new Error(errorMessage)
} }
if (attempt + 1 === this.maxAttempts) {
info(`Final attempt failed with error: ${errorMessage}`)
break
}
const retryTimeMilliseconds = this.getExponentialRetryTimeMilliseconds(attempt)
info( info(
`Attempt ${attempt + 1} of ${this.maxAttempts} failed with error: ${errorMessage}. Retrying request...` `Attempt ${attempt + 1} of ${this.maxAttempts} failed with error: ${errorMessage}. Retrying request in ${retryTimeMilliseconds} ms...`
) )
await this.sleep(this.getExponentialRetryTimeMilliseconds(attempt)) await this.sleep(retryTimeMilliseconds)
attempt++ attempt++
} }
@ -131,7 +134,7 @@ class ArtifactHttpClient implements Rpc {
} }
} }
export function createArtifactTwirpClient(type: "upload" | "download", httpClient?: HttpClient): ArtifactServiceClientJSON { export function createArtifactTwirpClient(type: "upload" | "download"): ArtifactServiceClientJSON {
const client = new ArtifactHttpClient(`@actions/artifact-${type}`, httpClient) const client = new ArtifactHttpClient(`@actions/artifact-${type}`)
return new ArtifactServiceClientJSON(client) return new ArtifactServiceClientJSON(client)
} }