Skip to content

Commit b5482c7

Browse files
Protocol tests generate suites with request input setting
1 parent f0948b6 commit b5482c7

File tree

17 files changed

+565
-132
lines changed

17 files changed

+565
-132
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/**
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0.
4+
*/
5+
6+
#pragma once
7+
8+
#include <aws/testing/Testing_EXPORTS.h>
9+
#include <aws/testing/AwsCppSdkGTestSuite.h>s
10+
#include <aws/testing/AwsTestHelpers.h>
11+
12+
13+
#define AWS_PROTOCOL_TEST TEST_F
14+
#define AWS_PROTOCOL_TEST_SUITE Aws::Testing::AwsCppSdkGTestSuite
15+
16+
using JsonValue = Aws::Utils::Json::JsonValue;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/**
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0.
4+
*/
5+
6+
package com.amazonaws.util.awsclientgenerator.domainmodels.protocol_test;
7+
8+
import com.amazonaws.util.awsclientgenerator.domainmodels.c2j_protocol_test.C2jGiven;
9+
import com.amazonaws.util.awsclientgenerator.domainmodels.c2j_protocol_test.C2jInputSerialized;
10+
import com.amazonaws.util.awsclientgenerator.domainmodels.c2j_protocol_test.C2jOutputResponse;
11+
import com.fasterxml.jackson.databind.JsonNode;
12+
import lombok.Data;
13+
14+
import java.util.Optional;
15+
16+
@Data
17+
public class ProtocolTestCase {
18+
19+
// Smithy test case definitions unlike c2j do not differentiate input/output cases
20+
// Using generic, more smithy-like intermediate codegen model.
21+
@Data
22+
public static class Input {
23+
/**
24+
* The input parameters a user would provide.
25+
*/
26+
private JsonNode params;
27+
/**
28+
* The expected serialized HTTP request.
29+
*/
30+
private C2jInputSerialized serialized;
31+
}
32+
33+
@Data
34+
public static class Output {
35+
@Data
36+
public static class SuccessResult {
37+
/**
38+
* A JSON hash representing the structure of the parsed response. Either this or error (not both) must appear in the test case.
39+
*/
40+
private Optional<JsonNode> result;
41+
}
42+
43+
@Data
44+
public static class ErrorResult {
45+
/**
46+
* A JSON hash representing the structure of the parsed error response. Either this or result (not both) must appear in the test case.
47+
*/
48+
private Optional<JsonNode> error;
49+
/**
50+
* A string specifying the AWS error code extracted from the response. Corresponds to the error shape to be unmarshalled and
51+
* should always be set, even when the shape can not be found. Must be present when the error key is present.
52+
*/
53+
private String errorCode;
54+
/**
55+
* A string specifying the error message extracted from the response.
56+
* Should be able to be extracted even when an error shape is not unmarshalled. May only be present when the error key is present.
57+
*/
58+
private String errorMessage;
59+
}
60+
61+
private boolean isError;
62+
63+
// Success or error must be present
64+
Optional<SuccessResult> successResult;
65+
Optional<ErrorResult> errorResult;
66+
67+
/**
68+
* The HTTP response to be parsed
69+
*/
70+
private C2jOutputResponse response;
71+
}
72+
73+
/**
74+
* A test case id.
75+
*/
76+
private String id;
77+
/**
78+
* A test case description.
79+
*/
80+
private String description;
81+
/**
82+
* This corresponds to the JSON object that would define an operation in the service's JSON model.
83+
* Valid keys include http, input, endpoint, and name.
84+
*/
85+
private C2jGiven given;
86+
87+
// Input or output must be present
88+
Optional<Input> input;
89+
Optional<Output> output;
90+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/**
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0.
4+
*/
5+
6+
package com.amazonaws.util.awsclientgenerator.domainmodels.protocol_test;
7+
8+
import com.amazonaws.util.awsclientgenerator.domainmodels.c2j_protocol_test.C2jTestSuite;
9+
import lombok.Data;
10+
11+
import java.util.List;
12+
13+
@Data
14+
public class ProtocolTestModel {
15+
private String name;
16+
private String serviceToUse;
17+
public enum TestSuiteType {
18+
INPUT,
19+
OUTPUT
20+
}
21+
C2jTestSuite.TestSuiteType type;
22+
private List<ProtocolTestSuite> testSuites;
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/**
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0.
4+
*/
5+
6+
package com.amazonaws.util.awsclientgenerator.domainmodels.protocol_test;
7+
8+
import com.amazonaws.util.awsclientgenerator.domainmodels.c2j.C2jMetadata;
9+
import com.amazonaws.util.awsclientgenerator.domainmodels.c2j.C2jShape;
10+
import lombok.Data;
11+
12+
import java.util.List;
13+
import java.util.Map;
14+
15+
@Data
16+
public class ProtocolTestSuite {
17+
/**
18+
* A name for the test suite
19+
*/
20+
private String name;
21+
/**
22+
* A description of the tests
23+
*/
24+
private String description;
25+
/**
26+
* The top level metadata that would correspond to the metadata key in the service's JSON model.
27+
*/
28+
private C2jMetadata metadata;
29+
/**
30+
* A URL string the test cases must use when constructing the request's URL endpoint.
31+
*/
32+
private String clientEndpoint;
33+
/**
34+
* A JSON object of C2jShapes. This would correspond to the top level C2jShapes key in the service's JSON model.
35+
*/
36+
private Map<String, C2jShape> shapes;
37+
/**
38+
* a list of test cases
39+
*/
40+
private List<ProtocolTestCase> cases;
41+
}

tools/code-generation/generator/src/main/java/com/amazonaws/util/awsclientgenerator/generators/MainGenerator.java

+8-3
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,13 @@
1616
import com.amazonaws.util.awsclientgenerator.domainmodels.defaults.BaseOption;
1717
import com.amazonaws.util.awsclientgenerator.domainmodels.defaults.BaseOptionModifier;
1818
import com.amazonaws.util.awsclientgenerator.domainmodels.defaults.DefaultClientConfigs;
19+
import com.amazonaws.util.awsclientgenerator.domainmodels.protocol_test.ProtocolTestModel;
1920
import com.amazonaws.util.awsclientgenerator.generators.cpp.CppDefaultsGenerator;
2021
import com.amazonaws.util.awsclientgenerator.generators.cpp.CppPartitionsGenerator;
2122
import com.amazonaws.util.awsclientgenerator.generators.cpp.CppProtocolTestGenerator;
2223
import com.amazonaws.util.awsclientgenerator.generators.cpp.CppServiceClientTestGenerator;
2324
import com.amazonaws.util.awsclientgenerator.transform.C2jModelToGeneratorModelTransformer;
25+
import com.amazonaws.util.awsclientgenerator.transform.C2jProtocolTestToGeneratorModelTransformer;
2426

2527
import java.io.*;
2628
import java.nio.charset.StandardCharsets;
@@ -108,7 +110,7 @@ public ByteArrayOutputStream generateTestSourceFromModel(C2jServiceModel c2jMode
108110
}
109111

110112
public ByteArrayOutputStream generateProtocolTestSourceFromModel(C2jServiceModel c2jModel,
111-
C2jTestSuite testSuiteModel) throws Exception {
113+
C2jTestSuite c2jTestModel) throws Exception {
112114
SdkSpec spec = new SdkSpec("cpp", c2jModel.getServiceName(), null);
113115
// Transform to intermediate code gen models from input c2j format.
114116
ServiceModel serviceModel = new C2jModelToGeneratorModelTransformer(c2jModel, false).convert();
@@ -122,9 +124,12 @@ public ByteArrayOutputStream generateProtocolTestSourceFromModel(C2jServiceModel
122124
spec.setVersion(serviceModel.getMetadata().getApiVersion());
123125

124126
// TODO: Also transform C2j Protocol test model to an intermediate code gen model
125-
CppProtocolTestGenerator cppTestGenerator = new CppProtocolTestGenerator(serviceModel, testSuiteModel);
127+
128+
C2jProtocolTestToGeneratorModelTransformer testTransformer = new C2jProtocolTestToGeneratorModelTransformer();
129+
ProtocolTestModel testModel = testTransformer.convert(c2jTestModel);
130+
CppProtocolTestGenerator cppTestGenerator = new CppProtocolTestGenerator(serviceModel, testModel);
126131
SdkFileEntry[] apiFiles = cppTestGenerator.generateSourceFiles(serviceModel);
127-
String componentOutputName = String.format("%s", testSuiteModel.getName());
132+
String componentOutputName = String.format("%s", testModel.getName());
128133

129134
return compressFilesToZip(apiFiles, componentOutputName);
130135
}

tools/code-generation/generator/src/main/java/com/amazonaws/util/awsclientgenerator/generators/cpp/CppProtocolTestGenerator.java

+35-8
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@
66
package com.amazonaws.util.awsclientgenerator.generators.cpp;
77

88
import com.amazonaws.util.awsclientgenerator.domainmodels.SdkFileEntry;
9-
import com.amazonaws.util.awsclientgenerator.domainmodels.c2j.C2jServiceModel;
10-
import com.amazonaws.util.awsclientgenerator.domainmodels.c2j_protocol_test.C2jTestSuite;
9+
1110
import com.amazonaws.util.awsclientgenerator.domainmodels.codegeneration.ServiceModel;
1211

12+
import com.amazonaws.util.awsclientgenerator.domainmodels.codegeneration.cpp.CppViewHelper;
13+
import com.amazonaws.util.awsclientgenerator.domainmodels.protocol_test.ProtocolTestModel;
14+
import com.amazonaws.util.awsclientgenerator.domainmodels.protocol_test.ProtocolTestSuite;
1315
import com.amazonaws.util.awsclientgenerator.generators.ClientGenerator;
1416
import com.amazonaws.util.awsclientgenerator.generators.exceptions.SourceGenerationFailedException;
1517
import org.apache.velocity.Template;
@@ -22,20 +24,21 @@
2224
import java.io.IOException;
2325
import java.io.StringWriter;
2426
import java.nio.charset.StandardCharsets;
25-
import java.util.ArrayList;
26-
import java.util.List;
27+
import java.util.*;
28+
import java.util.stream.Collectors;
2729

2830
public class CppProtocolTestGenerator implements ClientGenerator {
2931

3032
private static String CMAKE_LISTS_TEMPLATE = "/com/amazonaws/util/awsclientgenerator/velocity/cpp/protocoltests/ProtocolTestsCMakeLists.vm";
31-
private static String TEST_DRIVER_TEMPLATE = "/com/amazonaws/util/awsclientgenerator/velocity/cpp/protocoltests/ProtocolTestsSource.vm";
33+
private static String RUN_TESTS_TEMPLATE = "/com/amazonaws/util/awsclientgenerator/velocity/cpp/protocoltests/ProtocolTestsRunTestsSrc.vm";
34+
private static String TEST_SUITE_TEMPLATE = "/com/amazonaws/util/awsclientgenerator/velocity/cpp/protocoltests/ProtocolTestsTestSuiteSrc.vm";
3235

3336
protected final VelocityEngine velocityEngine;
3437
private final ServiceModel serviceModel;
35-
private final C2jTestSuite testModel; // TODO: use an intermediate codegen model instead of raw C2J
38+
private final ProtocolTestModel testModel; // TODO: use an intermediate codegen model instead of raw C2J
3639
private final String projectName;
3740

38-
public CppProtocolTestGenerator(ServiceModel serviceModel, C2jTestSuite testSuiteModel) throws Exception {
41+
public CppProtocolTestGenerator(ServiceModel serviceModel, ProtocolTestModel testSuiteModel) throws Exception {
3942
this.serviceModel = serviceModel;
4043
this.testModel = testSuiteModel;
4144
String prefix = testSuiteModel.getType().toString().toLowerCase();
@@ -52,10 +55,32 @@ public CppProtocolTestGenerator(ServiceModel serviceModel, C2jTestSuite testSuit
5255
velocityEngine.init();
5356
}
5457

58+
protected SdkFileEntry generateTestSuiteSourceFile(ProtocolTestSuite testSuite) throws IOException {
59+
VelocityContext context = createContext();
60+
context.put("testSuite", testSuite);
61+
Template template = velocityEngine.getTemplate(TEST_SUITE_TEMPLATE, StandardCharsets.UTF_8.name());
62+
String fileName = String.format("tests/%sTest.cpp", testSuite.getName());
63+
64+
return makeFile(template, context, fileName, true);
65+
}
66+
67+
protected List<SdkFileEntry> generateTestSuiteSourceFiles() throws IOException {
68+
return testModel.getTestSuites().stream()
69+
.map(entry -> {
70+
try {
71+
return generateTestSuiteSourceFile(entry);
72+
} catch (IOException e) {
73+
throw new RuntimeException(e);
74+
}
75+
})
76+
.collect(Collectors.toList());
77+
}
78+
5579
public SdkFileEntry[] generateSourceFiles(ServiceModel dummy) throws Exception {
5680
List<SdkFileEntry> fileList = new ArrayList<>();
5781
fileList.add(generateCmakeFile());
5882
fileList.add(generateTestDriver());
83+
fileList.addAll(generateTestSuiteSourceFiles());
5984

6085
SdkFileEntry[] retArray = new SdkFileEntry[fileList.size()];
6186
return fileList.toArray(retArray);
@@ -69,7 +94,7 @@ private SdkFileEntry generateCmakeFile() throws Exception {
6994

7095
protected SdkFileEntry generateTestDriver() throws Exception {
7196
VelocityContext context = createContext();
72-
Template template = velocityEngine.getTemplate(TEST_DRIVER_TEMPLATE, StandardCharsets.UTF_8.name());
97+
Template template = velocityEngine.getTemplate(RUN_TESTS_TEMPLATE, StandardCharsets.UTF_8.name());
7398
return makeFile(template, context, "RunTests.cpp", true);
7499
}
75100

@@ -81,6 +106,8 @@ protected final VelocityContext createContext() {
81106
context.put("testModel", testModel);
82107
context.put("input.encoding", StandardCharsets.UTF_8.name());
83108
context.put("output.encoding", StandardCharsets.UTF_8.name());
109+
110+
context.put("CppViewHelper", CppViewHelper.class);
84111
return context;
85112
}
86113

0 commit comments

Comments
 (0)