serverless/test/integration/aws/iot-fleet-provisioning.test.js
2024-05-29 11:51:04 -04:00

118 lines
3.5 KiB
JavaScript

'use strict'
const awsRequest = require('@serverless/test/aws-request')
const CloudFormationService = require('aws-sdk').CloudFormation
const IotService = require('aws-sdk').Iot
const LambdaService = require('aws-sdk').Lambda
const hasFailed = require('@serverless/test/has-failed')
const { expect } = require('chai')
const fixtures = require('../../fixtures/programmatic')
const { deployService, removeService } = require('../../utils/integration')
const { resolveIotEndpoint } = require('../../utils/iot')
describe('test/integration/aws/iotFleetProvisioning.test.js', function () {
this.timeout(1000 * 60 * 100) // Involves time-taking deploys
const stage = 'dev'
let stackName
let thingName
let serviceDir
let certificateId
let isDeployed = false
const resolveTemplateName = async () => {
const result = await awsRequest(CloudFormationService, 'describeStacks', {
StackName: stackName,
})
return result.Stacks[0].Outputs.find(
(output) => output.OutputKey === 'ProvisioningTemplateName',
).OutputValue
}
const resolveIoTPolicyName = async () => {
const result = await awsRequest(CloudFormationService, 'describeStacks', {
StackName: stackName,
})
return result.Stacks[0].Outputs.find(
(output) => output.OutputKey === 'IoTPolicyName',
).OutputValue
}
before(async () => {
let serviceConfig
;({ serviceConfig, servicePath: serviceDir } = await fixtures.setup(
'iot-fleet-provisioning',
))
const serviceName = serviceConfig.service
thingName = stackName = `${serviceName}-${stage}`
await deployService(serviceDir)
isDeployed = true
})
after(async function () {
if (!isDeployed) return
if (hasFailed(this.test.parent)) return
if (certificateId) {
const [
{
certificateDescription: { certificateArn },
},
policyName,
] = await Promise.all([
awsRequest(IotService, 'describeCertificate', {
certificateId,
}),
resolveIoTPolicyName(),
])
await Promise.all([
awsRequest(IotService, 'detachThingPrincipal', {
thingName,
principal: certificateArn,
}),
awsRequest(IotService, 'detachPolicy', {
policyName,
target: certificateArn,
}),
awsRequest(IotService, 'updateCertificate', {
certificateId,
newStatus: 'INACTIVE',
}),
])
await Promise.all([
awsRequest(IotService, 'deleteThing', {
thingName,
}),
awsRequest(IotService, 'deleteCertificate', {
certificateId,
}),
])
}
await removeService(serviceDir)
})
it('setup a new IoT Thing with the provisioning template', async () => {
const [{ certificatePem, keyPair }, iotEndpoint] = await Promise.all([
awsRequest(IotService, 'createProvisioningClaim', {
templateName: await resolveTemplateName(),
}),
resolveIotEndpoint(),
])
const { Payload } = await awsRequest(LambdaService, 'invoke', {
FunctionName: `${stackName}-registerDevice`,
InvocationType: 'RequestResponse',
Payload: JSON.stringify({
iotEndpoint,
certificatePem,
privateKey: keyPair.PrivateKey,
}),
})
const payload = JSON.parse(Payload)
;({ certificateId } = payload)
const { thingName: provisionnedThingName, errorMessage } = payload
if (errorMessage)
throw new Error(`Invocation errored with: ${errorMessage}`)
expect(provisionnedThingName).to.equal(thingName)
})
})