Skip to content

Commit

Permalink
Test all combinations of create-aws-lambda cli command (#2316)
Browse files Browse the repository at this point in the history
* Test all combinations of create-aws-lambda cli command

And test them all when compiled natively.

* Test invalid paths as well

Previously we skipped testing these which is bad if something changes unexpectedly
  • Loading branch information
timyates authored Feb 9, 2024
1 parent b5491ff commit 95bbfdb
Show file tree
Hide file tree
Showing 4 changed files with 409 additions and 95 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ protected JdkVersion getJdkVersion(LambdaDeployment deployment, LineReader reade
return versions[choice];
}

JdkVersion[] jdkVersionsForDeployment(LambdaDeployment deployment) {
static JdkVersion[] jdkVersionsForDeployment(LambdaDeployment deployment) {
switch (deployment) {
case NATIVE_EXECUTABLE:
return new JdkVersion[]{
Expand All @@ -145,7 +145,7 @@ protected ApplicationType applicationTypeForCodingStyle(CodingStyle codingStyle)
}
}

protected Language[] languagesForDeployment(LambdaDeployment deployment) {
static Language[] languagesForDeployment(LambdaDeployment deployment) {
return deployment == LambdaDeployment.NATIVE_EXECUTABLE ?
Stream.of(Language.values())
.filter(GraalVMFeatureValidator::supports)
Expand Down Expand Up @@ -229,15 +229,15 @@ protected Optional<Feature> getCdk(LineReader reader) {
: Optional.empty();
}

protected List<Feature> apiTriggerFeatures(ApplicationType applicationType, Collection<Feature> features) {
static List<Feature> apiTriggerFeatures(ApplicationType applicationType, Collection<Feature> features) {
return features.stream()
.filter(AwsApiFeature.class::isInstance)
.filter(f -> f.supports(applicationType))
.sorted(Comparator.comparing(Feature::getTitle).reversed())
.collect(Collectors.toList());
.toList();
}

protected List<Feature> triggerFeatures(Collection<Feature> features) {
static List<Feature> triggerFeatures(Collection<Feature> features) {
return features.stream()
.filter(LambdaTrigger.class::isInstance)
.sorted((o1, o2) -> {
Expand All @@ -252,6 +252,6 @@ protected List<Feature> triggerFeatures(Collection<Feature> features) {
}
return o1.getTitle().compareTo(o2.getTitle());
})
.collect(Collectors.toList());
.toList();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,55 @@ package io.micronaut.starter.cli.command
import io.micronaut.context.ApplicationContext
import io.micronaut.starter.application.ApplicationType
import io.micronaut.starter.feature.Feature
import io.micronaut.starter.feature.aws.LambdaTrigger
import spock.lang.Specification
import io.micronaut.starter.feature.architecture.Arm
import io.micronaut.starter.feature.architecture.CpuArchitecture
import io.micronaut.starter.feature.architecture.X86
import io.micronaut.starter.feature.aws.Cdk
import io.micronaut.starter.feature.function.awslambda.AwsLambda
import io.micronaut.starter.feature.graalvm.GraalVM
import io.micronaut.starter.options.BuildTool
import io.micronaut.starter.options.JdkVersion
import io.micronaut.starter.options.Language
import io.micronaut.starter.options.TestFramework
import org.jline.reader.LineReader

import java.util.stream.Collectors
import spock.lang.AutoCleanup
import spock.lang.Shared
import spock.lang.Specification

class CreateLambdaBuilderCommandSpec extends Specification {

@Shared
@AutoCleanup
ApplicationContext applicationContext

@Shared
CreateLambdaBuilderCommand command

def setupSpec() {
applicationContext = ApplicationContext.run();
command = applicationContext.getBean(CreateLambdaBuilderCommand)
}

void "test lambda triggers"() {
given:
ApplicationContext applicationContext = ApplicationContext.run();
CreateLambdaBuilderCommand command = applicationContext.getBean(CreateLambdaBuilderCommand)
Collection<Feature> features = applicationContext.getBeansOfType(LambdaTrigger)
List<Feature> features = applicationContext.getBeansOfType(Feature)

when:
List<String> result = command.triggerFeatures(features)
.stream()
.map(f -> f.getName())
.collect(Collectors.toList());
List<String> result = command.triggerFeatures(features).name

then:
[
result == [
'amazon-api-gateway',
'amazon-api-gateway-http',
'aws-lambda-function-url',
'aws-lambda-scheduled-event',
'aws-lambda-s3-event-notification',
] == result
]

and:
['amazon-api-gateway', 'amazon-api-gateway-http'] == command.apiTriggerFeatures(command.applicationTypeForCodingStyle(CodingStyle.CONTROLLERS), features)*.name
command.apiTriggerFeatures(command.applicationTypeForCodingStyle(CodingStyle.CONTROLLERS), features).name == ['amazon-api-gateway', 'amazon-api-gateway-http']

cleanup:
applicationContext.close()
Expand Down Expand Up @@ -79,92 +98,135 @@ class CreateLambdaBuilderCommandSpec extends Specification {
*1) 11
2) 8
*/
void "test prompt"(List<String> answers, ApplicationType expectedApplicationType, Set<String> expectedFeatures) {
given:
ApplicationContext applicationContext = ApplicationContext.run();
void "#cliOptions.cliCommands -- #cliOptions"(LambdaCliOptions cliOptions) {
when:
CreateLambdaBuilderCommand command = applicationContext.getBean(CreateLambdaBuilderCommand)

when:
def reader = Stub(LineReader) {
readLine(BuilderCommand.PROMPT.get()) >>> answers

readLine(BuilderCommand.PROMPT.get()) >>> cliOptions.cliCommands
}
GenerateOptions options = command.createGenerateOptions(reader)

then:
expectedApplicationType == options.applicationType
expectedFeatures =~ options.features

cleanup:
applicationContext.close()
cliOptions.expectedApplicationType == options.applicationType
cliOptions.features ==~ options.features
cliOptions.language == options.options.language
cliOptions.buildTool == options.options.buildTool
cliOptions.testFramework == options.options.testFramework
cliOptions.javaVersion == options.options.javaVersion

where:
answers | expectedApplicationType | expectedFeatures
[
"1", // with Controller
"1", // Amazon Api Gateway
"1", // FAT JAR
"1", // ARM
"1", // CDK Yes
"1", // Java
"1", // Junit
"1", // Gradle Groovy DSL
"1", // Java 11
] | ApplicationType.DEFAULT | ['amazon-api-gateway', 'arm', 'aws-cdk','aws-lambda']
[
"2", // with Controller
"1", // Amazon Api Gateway
"1", // FAT JAR
"1", // ARM
"1", // CDK Yes
"1", // Java
"1", // Junit
"1", // Gradle Groovy DSL
"1", // Java 11
] | ApplicationType.FUNCTION | ['amazon-api-gateway', 'arm', 'aws-cdk','aws-lambda']
[
"2", // with Controller
"4", // Scheduled event
"1", // FAT JAR
"1", // ARM
"1", // CDK Yes
"1", // Java
"1", // Junit
"1", // Gradle Groovy DSL
"1", // Java 11
] | ApplicationType.FUNCTION | ['aws-lambda-scheduled-event', 'arm', 'aws-cdk','aws-lambda']
[
"1", // with Controller
"1", // Amazon Api Gateway
"2", // FAT JAR
"1", // ARM
"1", // CDK Yes
"1", // Java
"1", // Junit
"1", // Gradle Groovy DSL
"1", // Java 11
] | ApplicationType.DEFAULT | ['amazon-api-gateway', 'arm', 'aws-cdk','aws-lambda','graalvm']
[
"1", // with Controller
"1", // Amazon Api Gateway
"1", // FAT JAR
"2", // x86
"1", // CDK Yes
"1", // Java
"1", // Junit
"1", // Gradle Groovy DSL
"1", // Java 11
] | ApplicationType.DEFAULT | ['amazon-api-gateway', 'x86', 'aws-cdk','aws-lambda']
cliOptions << [CodingStyle.values(), LambdaDeployment.values()].combinations().collectMany { CodingStyle codingStyle, LambdaDeployment deployment ->
combinations(
applicationContext,
codingStyle == CodingStyle.CONTROLLERS ?
CreateLambdaBuilderCommand.apiTriggerFeatures(ApplicationType.DEFAULT, applicationContext.getBeansOfType(Feature)) :
CreateLambdaBuilderCommand.triggerFeatures(applicationContext.getBeansOfType(Feature)),
codingStyle,
deployment
)
}
}

static combinations(ApplicationContext ctx, List<Feature> triggerFeatures, CodingStyle codingStyle, LambdaDeployment deployment) {
[
"1", // with Controller
"1", // Amazon Api Gateway
"1", // FAT JAR
"1", // ARM
"2", // CDK Yes
"1", // Java
"1", // Junit
"1", // Gradle Groovy DSL
"1", // Java 11
] | ApplicationType.DEFAULT | ['amazon-api-gateway','arm','aws-lambda']
triggerFeatures,
[triggerFeatures],
[deployment],
[ctx.getBean(Arm), ctx.getBean(X86)],
[true, false], // cdk
CreateLambdaBuilderCommand.languagesForDeployment(deployment),
[CreateLambdaBuilderCommand.languagesForDeployment(deployment)],
[TestFramework.JUNIT, TestFramework.SPOCK, TestFramework.KOTEST],
[BuildTool.GRADLE, BuildTool.GRADLE_KOTLIN, BuildTool.MAVEN],
CreateLambdaBuilderCommand.jdkVersionsForDeployment(deployment),
[CreateLambdaBuilderCommand.jdkVersionsForDeployment(deployment)]
].combinations().collect { new LambdaCliOptions(codingStyle, *it) }
}

private static class LambdaCliOptions {

final CodingStyle codingStyle
final Feature apiFeature
final LambdaDeployment lambdaDeployment
final CpuArchitecture cpuArchitecture
final boolean cdk
final Language language
final TestFramework testFramework
final BuildTool buildTool
final JdkVersion javaVersion

final List<Feature> allApiFeatures
final List<Language> allLanguages
final List<JdkVersion> allJdkVersions

LambdaCliOptions(
CodingStyle codingStyle,
Feature apiFeatures,
List<Feature> allApiFeatures,
LambdaDeployment lambdaDeployment,
CpuArchitecture cpuArchitecture,
boolean cdk,
Language language,
Language[] allLanguages,
TestFramework testFramework,
BuildTool buildTool,
JdkVersion javaVersion,
JdkVersion[] allJdkVersions
) {
this.codingStyle = codingStyle
this.apiFeature = apiFeatures
this.allApiFeatures = allApiFeatures
this.lambdaDeployment = lambdaDeployment
this.cpuArchitecture = cpuArchitecture
this.cdk = cdk
this.language = language
this.allLanguages = allLanguages.toList()
this.testFramework = testFramework
this.buildTool = buildTool
this.javaVersion = javaVersion
this.allJdkVersions = allJdkVersions.toList()
}

List<String> getFeatures() {
List<String> features = [
AwsLambda.FEATURE_NAME_AWS_LAMBDA,
apiFeature.getName(),
]
if (lambdaDeployment == LambdaDeployment.NATIVE_EXECUTABLE) {
features += [GraalVM.FEATURE_NAME_GRAALVM]
}
features += [cpuArchitecture.getName()]
if (cdk) {
features += [Cdk.NAME]
}
return features
}

ApplicationType getExpectedApplicationType() {
if (codingStyle != CodingStyle.HANDLER) {
return ApplicationType.DEFAULT
}
return ApplicationType.FUNCTION
}

List<String> getCliCommands() {
[
"${codingStyle.ordinal() + 1}".toString(),
"${allApiFeatures.indexOf(apiFeature) + 1}".toString(),
"${lambdaDeployment.ordinal() + 1}".toString(),
cpuArchitecture instanceof Arm ? "1" : "2",
cdk ? "1" : "2",
"${allLanguages.indexOf(language) + 1}".toString(),
"${testFramework.ordinal() + 1}".toString(),
"${buildTool.ordinal() + 1}".toString(),
"${allJdkVersions.indexOf(javaVersion) + 1}".toString()
]
}

@Override
String toString() {
"${codingStyle} ${apiFeature?.name} ${lambdaDeployment} ${cpuArchitecture.name} cdk:${cdk} $language $testFramework $buildTool $javaVersion"
}
}
}
Loading

0 comments on commit 95bbfdb

Please sign in to comment.