xref: /aosp_15_r20/external/aws-crt-java/src/test/java/software/amazon/awssdk/crt/test/CrtTestFixture.java (revision 3c7ae9de214676c52d19f01067dc1a404272dc11)
1 /**
2  * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3  * SPDX-License-Identifier: Apache-2.0.
4  */
5 
6 package software.amazon.awssdk.crt.test;
7 
8 import software.amazon.awssdk.crt.CRT;
9 import software.amazon.awssdk.crt.Log;
10 import software.amazon.awssdk.crt.Log.LogSubject;
11 import software.amazon.awssdk.crt.CrtPlatform;
12 import software.amazon.awssdk.crt.CrtResource;
13 import software.amazon.awssdk.crt.auth.credentials.DefaultChainCredentialsProvider.DefaultChainCredentialsProviderBuilder;
14 import software.amazon.awssdk.crt.io.ClientBootstrap;
15 import software.amazon.awssdk.crt.io.EventLoopGroup;
16 import software.amazon.awssdk.crt.io.HostResolver;
17 import software.amazon.awssdk.crt.io.TlsContext;
18 import software.amazon.awssdk.crt.io.TlsContextOptions;
19 import software.amazon.awssdk.crt.auth.credentials.Credentials;
20 import software.amazon.awssdk.crt.auth.credentials.DefaultChainCredentialsProvider;
21 
22 import org.junit.Before;
23 import org.junit.BeforeClass;
24 import org.junit.After;
25 import org.junit.Assume;
26 
27 import java.util.Optional;
28 
29 public class CrtTestFixture {
30 
31     private CrtTestContext context;
32 
getContext()33     public final CrtTestContext getContext() {
34         return context;
35     }
36 
SetPropertyFromEnv(String name)37     private static void SetPropertyFromEnv(String name) {
38         String propertyValue = System.getenv(name);
39         if (propertyValue != null) {
40             System.setProperty(name, propertyValue);
41         }
42     }
43 
44     // Setup System properties from environment variables set by builder for use by
45     // unit tests.
SetupTestProperties()46     private static void SetupTestProperties() {
47         SetPropertyFromEnv("AWS_TEST_IS_CI");
48         SetPropertyFromEnv("AWS_TEST_MQTT311_ROOT_CA");
49         SetPropertyFromEnv("ENDPOINT");
50         SetPropertyFromEnv("REGION");
51 
52         // Cognito
53         SetPropertyFromEnv("AWS_TEST_MQTT311_COGNITO_ENDPOINT");
54         SetPropertyFromEnv("AWS_TEST_MQTT311_COGNITO_IDENTITY");
55 
56         // Proxy
57         SetPropertyFromEnv("AWS_TEST_HTTP_PROXY_HOST");
58         SetPropertyFromEnv("AWS_TEST_HTTP_PROXY_PORT");
59         SetPropertyFromEnv("AWS_TEST_HTTPS_PROXY_HOST");
60         SetPropertyFromEnv("AWS_TEST_HTTPS_PROXY_PORT");
61         SetPropertyFromEnv("AWS_TEST_HTTP_PROXY_BASIC_HOST");
62         SetPropertyFromEnv("AWS_TEST_HTTP_PROXY_BASIC_PORT");
63 
64         // Static credential related
65         SetPropertyFromEnv("AWS_TEST_MQTT311_ROLE_CREDENTIAL_ACCESS_KEY");
66         SetPropertyFromEnv("AWS_TEST_MQTT311_ROLE_CREDENTIAL_SECRET_ACCESS_KEY");
67         SetPropertyFromEnv("AWS_TEST_MQTT311_ROLE_CREDENTIAL_SESSION_TOKEN");
68 
69         // Custom Key Ops
70         SetPropertyFromEnv("AWS_TEST_MQTT311_CUSTOM_KEY_OPS_KEY");
71         SetPropertyFromEnv("AWS_TEST_MQTT311_CUSTOM_KEY_OPS_CERT");
72 
73         // MQTT311 Codebuild/Direct connections data
74         SetPropertyFromEnv("AWS_TEST_MQTT311_DIRECT_MQTT_HOST");
75         SetPropertyFromEnv("AWS_TEST_MQTT311_DIRECT_MQTT_PORT");
76         SetPropertyFromEnv("AWS_TEST_MQTT311_DIRECT_MQTT_BASIC_AUTH_HOST");
77         SetPropertyFromEnv("AWS_TEST_MQTT311_DIRECT_MQTT_BASIC_AUTH_PORT");
78         SetPropertyFromEnv("AWS_TEST_MQTT311_DIRECT_MQTT_TLS_HOST");
79         SetPropertyFromEnv("AWS_TEST_MQTT311_DIRECT_MQTT_TLS_PORT");
80 
81         // MQTT311 Codebuild/Websocket connections data
82         SetPropertyFromEnv("AWS_TEST_MQTT311_WS_MQTT_HOST");
83         SetPropertyFromEnv("AWS_TEST_MQTT311_WS_MQTT_PORT");
84         SetPropertyFromEnv("AWS_TEST_MQTT311_WS_MQTT_BASIC_AUTH_HOST");
85         SetPropertyFromEnv("AWS_TEST_MQTT311_WS_MQTT_BASIC_AUTH_PORT");
86         SetPropertyFromEnv("AWS_TEST_MQTT311_WS_MQTT_TLS_HOST");
87         SetPropertyFromEnv("AWS_TEST_MQTT311_WS_MQTT_TLS_PORT");
88 
89         // MQTT311 Codebuild misc connections data
90         SetPropertyFromEnv("AWS_TEST_MQTT311_BASIC_AUTH_USERNAME");
91         SetPropertyFromEnv("AWS_TEST_MQTT311_BASIC_AUTH_PASSWORD");
92         SetPropertyFromEnv("AWS_TEST_MQTT311_CERTIFICATE_FILE");
93         SetPropertyFromEnv("AWS_TEST_MQTT311_KEY_FILE");
94 
95         // MQTT311 IoT Endpoint, Key, Cert
96         SetPropertyFromEnv("AWS_TEST_MQTT311_IOT_CORE_HOST");
97         SetPropertyFromEnv("AWS_TEST_MQTT311_IOT_CORE_RSA_CERT");
98         SetPropertyFromEnv("AWS_TEST_MQTT311_IOT_CORE_RSA_KEY");
99         SetPropertyFromEnv("AWS_TEST_MQTT311_IOT_CORE_ECC_CERT");
100         SetPropertyFromEnv("AWS_TEST_MQTT311_IOT_CORE_ECC_KEY");
101 
102         // MQTT311 Proxy
103         SetPropertyFromEnv("AWS_TEST_MQTT311_PROXY_HOST");
104         SetPropertyFromEnv("AWS_TEST_MQTT311_PROXY_PORT");
105 
106         // MQTT311 Keystore
107         SetPropertyFromEnv("AWS_TEST_MQTT311_IOT_CORE_KEYSTORE_FORMAT");
108         SetPropertyFromEnv("AWS_TEST_MQTT311_IOT_CORE_KEYSTORE_FILE");
109         SetPropertyFromEnv("AWS_TEST_MQTT311_IOT_CORE_KEYSTORE_PASSWORD");
110         SetPropertyFromEnv("AWS_TEST_MQTT311_IOT_CORE_KEYSTORE_CERT_ALIAS");
111         SetPropertyFromEnv("AWS_TEST_MQTT311_IOT_CORE_KEYSTORE_CERT_PASSWORD");
112 
113         // MQTT311 PKCS12
114         SetPropertyFromEnv("AWS_TEST_MQTT311_IOT_CORE_PKCS12_KEY");
115         SetPropertyFromEnv("AWS_TEST_MQTT311_IOT_CORE_PKCS12_KEY_PASSWORD");
116 
117         // PKCS11
118         SetPropertyFromEnv("AWS_TEST_PKCS11_LIB");
119         SetPropertyFromEnv("AWS_TEST_PKCS11_TOKEN_LABEL");
120         SetPropertyFromEnv("AWS_TEST_PKCS11_PIN");
121         SetPropertyFromEnv("AWS_TEST_PKCS11_PKEY_LABEL");
122         SetPropertyFromEnv("AWS_TEST_PKCS11_CERT_FILE");
123         SetPropertyFromEnv("AWS_TEST_PKCS11_CA_FILE");
124 
125         // MQTT311 X509
126         SetPropertyFromEnv("AWS_TEST_MQTT311_IOT_CORE_X509_CERT");
127         SetPropertyFromEnv("AWS_TEST_MQTT311_IOT_CORE_X509_KEY");
128         SetPropertyFromEnv("AWS_TEST_MQTT311_IOT_CORE_X509_ENDPOINT");
129         SetPropertyFromEnv("AWS_TEST_MQTT311_IOT_CORE_X509_ROLE_ALIAS");
130         SetPropertyFromEnv("AWS_TEST_MQTT311_IOT_CORE_X509_THING_NAME");
131 
132         // MQTT311 Windows Cert Store
133         SetPropertyFromEnv("AWS_TEST_MQTT311_IOT_CORE_WINDOWS_PFX_CERT_NO_PASS");
134         SetPropertyFromEnv("AWS_TEST_MQTT311_IOT_CORE_WINDOWS_CERT_STORE");
135 
136         // MQTT5 Codebuild/Direct connections data
137         SetPropertyFromEnv("AWS_TEST_MQTT5_DIRECT_MQTT_HOST");
138         SetPropertyFromEnv("AWS_TEST_MQTT5_DIRECT_MQTT_PORT");
139         SetPropertyFromEnv("AWS_TEST_MQTT5_DIRECT_MQTT_BASIC_AUTH_HOST");
140         SetPropertyFromEnv("AWS_TEST_MQTT5_DIRECT_MQTT_BASIC_AUTH_PORT");
141         SetPropertyFromEnv("AWS_TEST_MQTT5_DIRECT_MQTT_TLS_HOST");
142         SetPropertyFromEnv("AWS_TEST_MQTT5_DIRECT_MQTT_TLS_PORT");
143 
144         // MQTT5 Codebuild/Websocket connections data
145         SetPropertyFromEnv("AWS_TEST_MQTT5_WS_MQTT_HOST");
146         SetPropertyFromEnv("AWS_TEST_MQTT5_WS_MQTT_PORT");
147         SetPropertyFromEnv("AWS_TEST_MQTT5_WS_MQTT_BASIC_AUTH_HOST");
148         SetPropertyFromEnv("AWS_TEST_MQTT5_WS_MQTT_BASIC_AUTH_PORT");
149         SetPropertyFromEnv("AWS_TEST_MQTT5_WS_MQTT_TLS_HOST");
150         SetPropertyFromEnv("AWS_TEST_MQTT5_WS_MQTT_TLS_PORT");
151 
152         // MQTT5 Codebuild misc connections data
153         SetPropertyFromEnv("AWS_TEST_MQTT5_BASIC_AUTH_USERNAME");
154         SetPropertyFromEnv("AWS_TEST_MQTT5_BASIC_AUTH_PASSWORD");
155         SetPropertyFromEnv("AWS_TEST_MQTT5_CERTIFICATE_FILE");
156         SetPropertyFromEnv("AWS_TEST_MQTT5_KEY_FILE");
157 
158         // MQTT5 Proxy
159         SetPropertyFromEnv("AWS_TEST_MQTT5_PROXY_HOST");
160         SetPropertyFromEnv("AWS_TEST_MQTT5_PROXY_PORT");
161 
162         // MQTT5 Endpoint/Host credential
163         SetPropertyFromEnv("AWS_TEST_MQTT5_IOT_CORE_HOST");
164         SetPropertyFromEnv("AWS_TEST_MQTT5_IOT_CORE_REGION");
165         SetPropertyFromEnv("AWS_TEST_MQTT5_IOT_CORE_RSA_CERT");
166         SetPropertyFromEnv("AWS_TEST_MQTT5_IOT_CORE_RSA_KEY");
167 
168         // MQTT5 Static credential related
169         SetPropertyFromEnv("AWS_TEST_MQTT5_ROLE_CREDENTIAL_ACCESS_KEY");
170         SetPropertyFromEnv("AWS_TEST_MQTT5_ROLE_CREDENTIAL_SECRET_ACCESS_KEY");
171         SetPropertyFromEnv("AWS_TEST_MQTT5_ROLE_CREDENTIAL_SESSION_TOKEN");
172 
173         // MQTT5 Cognito
174         SetPropertyFromEnv("AWS_TEST_MQTT5_COGNITO_ENDPOINT");
175         SetPropertyFromEnv("AWS_TEST_MQTT5_COGNITO_IDENTITY");
176 
177         // MQTT5 Keystore
178         SetPropertyFromEnv("AWS_TEST_MQTT5_IOT_CORE_KEYSTORE_FORMAT");
179         SetPropertyFromEnv("AWS_TEST_MQTT5_IOT_CORE_KEYSTORE_FILE");
180         SetPropertyFromEnv("AWS_TEST_MQTT5_IOT_CORE_KEYSTORE_PASSWORD");
181         SetPropertyFromEnv("AWS_TEST_MQTT5_IOT_CORE_KEYSTORE_CERT_ALIAS");
182         SetPropertyFromEnv("AWS_TEST_MQTT5_IOT_CORE_KEYSTORE_CERT_PASSWORD");
183 
184         // MQTT5 PKCS12
185         SetPropertyFromEnv("AWS_TEST_MQTT5_IOT_CORE_PKCS12_KEY");
186         SetPropertyFromEnv("AWS_TEST_MQTT5_IOT_CORE_PKCS12_KEY_PASSWORD");
187 
188         // MQTT5 X509
189         SetPropertyFromEnv("AWS_TEST_MQTT5_IOT_CORE_X509_CERT");
190         SetPropertyFromEnv("AWS_TEST_MQTT5_IOT_CORE_X509_KEY");
191         SetPropertyFromEnv("AWS_TEST_MQTT5_IOT_CORE_X509_ENDPOINT");
192         SetPropertyFromEnv("AWS_TEST_MQTT5_IOT_CORE_X509_ROLE_ALIAS");
193         SetPropertyFromEnv("AWS_TEST_MQTT5_IOT_CORE_X509_THING_NAME");
194 
195         // MQTT5 Windows Cert Store
196         SetPropertyFromEnv("AWS_TEST_MQTT5_IOT_CORE_WINDOWS_PFX_CERT_NO_PASS");
197         SetPropertyFromEnv("AWS_TEST_MQTT5_IOT_CORE_WINDOWS_CERT_STORE");
198 
199         // MQTT5 Custom Key Ops (so we don't have to make a new file just for a single
200         // test)
201         SetPropertyFromEnv("AWS_TEST_MQTT5_CUSTOM_KEY_OPS_CERT");
202         SetPropertyFromEnv("AWS_TEST_MQTT5_CUSTOM_KEY_OPS_KEY");
203 
204         SetPropertyFromEnv("AWS_TEST_BASIC_AUTH_USERNAME");
205         SetPropertyFromEnv("AWS_TEST_BASIC_AUTH_PASSWORD");
206     }
207 
208     /* The function will be run once before any of the test methods in the class */
209     @BeforeClass
setupOnce()210     public static void setupOnce() {
211         // We only want to see the CRT logs if the test fails.
212         // Surefire has a redirectTestOutputToFile option, but that doesn't
213         // capture what the CRT logger writes to stdout or stderr.
214         // Our workaround is to have the CRT logger write to log.txt.
215         // We clear the file for each new test by restarting the logger.
216         // We stop all tests when one fails (see FailFastListener) so that
217         // a valuable log.txt isn't overwritten.
218         if (System.getProperty("aws.crt.aws_trace_log_per_test") != null) {
219             Log.initLoggingToFile(Log.LogLevel.Trace, "log.txt");
220         }
221         CrtPlatform platform = CRT.getPlatformImpl();
222         if (platform != null) {
223             platform.setupOnce();
224         }else {
225             SetupTestProperties();
226         }
227     }
228 
229     /* The setup function will be run before every test */
230     @Before
setup()231     public void setup() {
232         Log.log(Log.LogLevel.Debug, LogSubject.JavaCrtGeneral, "CrtTestFixture setup begin");
233 
234         // TODO this CrtTestContext should be removed as we are using System Properties
235         // for tests now.
236         context = new CrtTestContext();
237     }
238 
239     @After
tearDown()240     public void tearDown() {
241         Log.log(Log.LogLevel.Debug, LogSubject.JavaCrtGeneral, "CrtTestFixture tearDown begin");
242         CrtPlatform platform = CRT.getPlatformImpl();
243         if (platform != null) {
244             platform.testTearDown(context);
245         }
246 
247         context = null;
248 
249         CrtResource.waitForNoResources();
250 
251         if (CRT.getOSIdentifier() != "android") {
252             try {
253                 Runtime.getRuntime().gc();
254                 CrtMemoryLeakDetector.nativeMemoryLeakCheck();
255             } catch (Exception e) {
256                 throw new RuntimeException("Memory leak from native resource detected!");
257             }
258         }
259         Log.log(Log.LogLevel.Debug, LogSubject.JavaCrtGeneral, "CrtTestFixture tearDown end");
260     }
261 
createTlsContextOptions(byte[] trustStore)262     protected TlsContext createTlsContextOptions(byte[] trustStore) {
263         try (TlsContextOptions tlsOpts = configureTlsContextOptions(TlsContextOptions.createDefaultClient(),
264                 trustStore)) {
265             return new TlsContext(tlsOpts);
266         }
267     }
268 
configureTlsContextOptions(TlsContextOptions tlsOpts, byte[] trustStore)269     protected TlsContextOptions configureTlsContextOptions(TlsContextOptions tlsOpts, byte[] trustStore) {
270         if (trustStore != null) {
271             tlsOpts.withCertificateAuthority(new String(trustStore));
272         }
273         return tlsOpts;
274     }
275 
276     private Optional<Credentials> credentials = null;
277 
hasAwsCredentials()278     protected boolean hasAwsCredentials() {
279         if (credentials == null) {
280             try {
281                 try (EventLoopGroup elg = new EventLoopGroup(1);
282                         HostResolver hostResolver = new HostResolver(elg);
283                         ClientBootstrap clientBootstrap = new ClientBootstrap(elg, hostResolver)) {
284 
285                     try (DefaultChainCredentialsProvider provider = ((new DefaultChainCredentialsProviderBuilder())
286                             .withClientBootstrap(clientBootstrap)).build()) {
287                         credentials = Optional.of(provider.getCredentials().get());
288                     }
289                 }
290             } catch (Exception ex) {
291                 credentials = Optional.empty();
292             }
293         }
294         return credentials.isPresent();
295     }
296 
skipIfNetworkUnavailable()297     protected void skipIfNetworkUnavailable() {
298         Assume.assumeTrue(System.getProperty("NETWORK_TESTS_DISABLED") == null);
299     }
300 
skipIfLocalhostUnavailable()301     protected void skipIfLocalhostUnavailable() {
302         Assume.assumeTrue(System.getProperty("aws.crt.localhost") != null);
303     }
304 
skipIfAndroid()305     protected void skipIfAndroid() {
306         CrtPlatform platform = CRT.getPlatformImpl();
307         if (platform != null) {
308             Assume.assumeFalse(platform.getOSIdentifier().contains("android"));
309         }
310     }
311 }
312