1
0
Fork 0
mirror of https://github.com/actions/upload-artifact synced 2024-12-22 14:32:44 +00:00

add tests for merge artifact

This commit is contained in:
Rob Herley 2024-01-19 17:40:33 -05:00
parent fd1ae7b288
commit d5febab9d6
No known key found for this signature in database
GPG key ID: D1602042C3543B06
2 changed files with 245 additions and 78 deletions

175
__tests__/merge.test.ts Normal file
View file

@ -0,0 +1,175 @@
import * as core from '@actions/core'
import artifact from '@actions/artifact'
import {run} from '../src/merge/merge-artifact'
import {Inputs} from '../src/merge/constants'
import * as search from '../src/shared/search'
const fixtures = {
artifactName: 'my-merged-artifact',
tmpDirectory: '/tmp/merge-artifact',
filesToUpload: [
'/some/artifact/path/file-a.txt',
'/some/artifact/path/file-b.txt',
'/some/artifact/path/file-c.txt'
],
artifacts: [
{
name: 'my-artifact-a',
id: 1,
size: 100,
createdAt: new Date('2024-01-01T00:00:00Z')
},
{
name: 'my-artifact-b',
id: 2,
size: 100,
createdAt: new Date('2024-01-01T00:00:00Z')
},
{
name: 'my-artifact-c',
id: 3,
size: 100,
createdAt: new Date('2024-01-01T00:00:00Z')
}
]
}
jest.mock('@actions/github', () => ({
context: {
repo: {
owner: 'actions',
repo: 'toolkit'
},
runId: 123,
serverUrl: 'https://github.com'
}
}))
jest.mock('@actions/core')
jest.mock('fs/promises', () => ({
mkdtemp: jest.fn().mockResolvedValue('/tmp/merge-artifact'),
rm: jest.fn().mockResolvedValue(undefined)
}))
/* eslint-disable no-unused-vars */
const mockInputs = (overrides?: Partial<{[K in Inputs]?: any}>) => {
const inputs = {
[Inputs.Into]: 'my-merged-artifact',
[Inputs.Pattern]: '*',
[Inputs.SeparateDirectories]: false,
[Inputs.RetentionDays]: 0,
[Inputs.CompressionLevel]: 6,
[Inputs.DeleteMerged]: false,
...overrides
}
;(core.getInput as jest.Mock).mockImplementation((name: string) => {
return inputs[name]
})
;(core.getBooleanInput as jest.Mock).mockImplementation((name: string) => {
return inputs[name]
})
return inputs
}
describe('merge', () => {
beforeEach(async () => {
mockInputs()
jest
.spyOn(artifact, 'listArtifacts')
.mockResolvedValue({artifacts: fixtures.artifacts})
jest.spyOn(artifact, 'downloadArtifact').mockResolvedValue({
downloadPath: fixtures.tmpDirectory
})
jest.spyOn(search, 'findFilesToUpload').mockResolvedValue({
filesToUpload: fixtures.filesToUpload,
rootDirectory: fixtures.tmpDirectory
})
jest.spyOn(artifact, 'uploadArtifact').mockResolvedValue({
size: 123,
id: 1337
})
jest
.spyOn(artifact, 'deleteArtifact')
.mockImplementation(async artifactName => {
const artifact = fixtures.artifacts.find(a => a.name === artifactName)
if (!artifact) throw new Error(`Artifact ${artifactName} not found`)
return {id: artifact.id}
})
})
it('merges artifacts', async () => {
await run()
for (const a of fixtures.artifacts) {
expect(artifact.downloadArtifact).toHaveBeenCalledWith(a.id, {
path: fixtures.tmpDirectory
})
}
expect(artifact.uploadArtifact).toHaveBeenCalledWith(
fixtures.artifactName,
fixtures.filesToUpload,
fixtures.tmpDirectory,
{compressionLevel: 6}
)
})
it('fails if no artifacts found', async () => {
mockInputs({[Inputs.Pattern]: 'this-does-not-match'})
expect(run()).rejects.toThrow()
expect(artifact.uploadArtifact).not.toBeCalled()
expect(artifact.downloadArtifact).not.toBeCalled()
})
it('supports custom compression level', async () => {
mockInputs({
[Inputs.CompressionLevel]: 2
})
await run()
expect(artifact.uploadArtifact).toHaveBeenCalledWith(
fixtures.artifactName,
fixtures.filesToUpload,
fixtures.tmpDirectory,
{compressionLevel: 2}
)
})
it('supports custom retention days', async () => {
mockInputs({
[Inputs.RetentionDays]: 7
})
await run()
expect(artifact.uploadArtifact).toHaveBeenCalledWith(
fixtures.artifactName,
fixtures.filesToUpload,
fixtures.tmpDirectory,
{retentionDays: 7, compressionLevel: 6}
)
})
it('supports deleting artifacts after merge', async () => {
mockInputs({
[Inputs.DeleteMerged]: true
})
await run()
for (const a of fixtures.artifacts) {
expect(artifact.deleteArtifact).toHaveBeenCalledWith(a.name)
}
})
})

View file

@ -17,7 +17,6 @@ export const chunk = <T>(arr: T[], n: number): T[][] =>
}, [] as T[][]) }, [] as T[][])
export async function run(): Promise<void> { export async function run(): Promise<void> {
try {
const inputs = getInputs() const inputs = getInputs()
const tmpDir = await mkdtemp('merge-artifact') const tmpDir = await mkdtemp('merge-artifact')
@ -38,9 +37,7 @@ export async function run(): Promise<void> {
core.info(`Preparing to download the following artifacts:`) core.info(`Preparing to download the following artifacts:`)
artifacts.forEach(artifact => { artifacts.forEach(artifact => {
core.info( core.info(`- ${artifact.name} (ID: ${artifact.id}, Size: ${artifact.size})`)
`- ${artifact.name} (ID: ${artifact.id}, Size: ${artifact.size})`
)
}) })
const downloadPromises = artifacts.map(artifact => const downloadPromises = artifacts.map(artifact =>
@ -93,9 +90,4 @@ export async function run(): Promise<void> {
`Unable to remove temporary directory: ${(error as Error).message}` `Unable to remove temporary directory: ${(error as Error).message}`
) )
} }
} catch (error) {
core.setFailed((error as Error).message)
} }
}
run()