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