Skip to content

Commit

Permalink
Additional unit-tests and unit-test adjustment (#499)
Browse files Browse the repository at this point in the history
Refactors unit-tests to use a common set of environment variables and adds a bunch of missing MQTT311 and MQTT5 connection-related unit-tests.
  • Loading branch information
TwistedTwigleg authored May 25, 2023
1 parent 9f259ec commit 4716c95
Show file tree
Hide file tree
Showing 13 changed files with 3,012 additions and 991 deletions.
28 changes: 28 additions & 0 deletions .builder/actions/build_crt.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,47 @@ class BuildCrt(Builder.Action):
technique of overlaying data from json files.
"""

def _setenv(self, env, var, value):
"""
Set environment variable now,
and ensure the environment variable is set again when tests run
"""
env.shell.setenv(var, value)
env.project.config['test_env'][var] = value

def run(self, env):
project = Builder.Project.find_project('aws-crt-cpp')
return Builder.CMakeBuild(project, args_transformer=self._transform_cmake_args)

def _transform_cmake_args(self, env, project, cmake_args):
new_args = []
is_using_openssl = False

# remove or swap out flags that we don't want for C++
for arg in cmake_args:
# we want to use PERFORM_HEADER_CHECK_CXX instead of PERFORM_HEADER_CHECK
if arg == "-DPERFORM_HEADER_CHECK=ON":
arg = "-DPERFORM_HEADER_CHECK_CXX=ON"
if (arg == "-DUSE_OPENSSL=ON"):
is_using_openssl = True

new_args.append(arg)

# If we are using OpenSSL on Linux, then we want to make sure our CI container has the latest version
# for that platform, therefore we need to update
if (is_using_openssl):
self._setenv(env, "AWS_TEST_PKCS11_USE_OPENSSL_SET", "true")
print(
"Trying to install a SSL development library (either libssl-dev or openssl-devel)")
# Make sure libssl-dev is installed
try:
Builder.InstallPackages(['libssl-dev']).run(env)
print("Installed/Updated libssl-dev")
except:
try:
Builder.InstallPackages(['openssl-devel']).run(env)
print("Installed/Updated openssl-devel")
except:
print(
"ERROR - could not install either libssl-devel or openssl-devel")
return new_args
63 changes: 3 additions & 60 deletions .builder/actions/crt-ci-prep.py
Original file line number Diff line number Diff line change
@@ -1,66 +1,9 @@
import Builder
import json
import os
import re
import subprocess
import sys
import tempfile


class CrtCiPrep(Builder.Action):
def _write_environment_script_secret_to_env(self, env, secret_name):
mqtt5_ci_environment_script = env.shell.get_secret(secret_name)
env_line = re.compile('^export\s+(\w+)=(.+)')

lines = mqtt5_ci_environment_script.splitlines()
for line in lines:
env_pair_match = env_line.match(line)
if env_pair_match.group(1) and env_pair_match.group(2):
env.shell.setenv(env_pair_match.group(1), env_pair_match.group(2), quiet=True)

def _write_secret_to_temp_file(self, env, secret_name):
secret_value = env.shell.get_secret(secret_name)

fd, filename = tempfile.mkstemp()
os.write(fd, str.encode(secret_value))
os.close(fd)

return filename

def _write_s3_to_temp_file(self, env, s3_file):
try:
tmp_file = tempfile.NamedTemporaryFile(delete=False)
tmp_file.flush()
tmp_s3_filepath = tmp_file.name
cmd = ['aws', '--region', 'us-east-1', 's3', 'cp',
s3_file, tmp_s3_filepath]
env.shell.exec(*cmd, check=True, quiet=True)
return tmp_s3_filepath
except:
print (f"ERROR: Could not get S3 file from URL {s3_file}!")
raise RuntimeError("Could not get S3 file from URL")


def run(self, env):
env.shell.setenv("AWS_TESTING_COGNITO_IDENTITY", env.shell.get_secret("aws-c-auth-testing/cognito-identity"))
env.shell.setenv("AWS_TESTING_STS_ROLE_ARN", env.shell.get_secret("aws-c-auth-testing/sts-role-arn"))

# Unfortunately, we can't use NamedTemporaryFile and a with-block because NamedTemporaryFile is not readable
# on Windows.
self._write_environment_script_secret_to_env(env, "mqtt5-testing/github-ci-environment")

cert_file_name = self._write_secret_to_temp_file(env, "unit-test/certificate")
key_file_name = self._write_secret_to_temp_file(env, "unit-test/privatekey")

env.shell.setenv("AWS_TEST_MQTT5_IOT_CORE_CERTIFICATE_PATH", cert_file_name, quiet=True)
env.shell.setenv("AWS_TEST_MQTT5_IOT_CORE_KEY_PATH", key_file_name, quiet=True)

# PKCS12 setup (MacOS only)
if (sys.platform == "darwin"):
pkcs12_file_name = self._write_s3_to_temp_file(env, "s3://aws-crt-test-stuff/unit-test-key-pkcs12.pem")
env.shell.setenv("AWS_TEST_MQTT311_IOT_CORE_PKCS12_KEY", pkcs12_file_name)
env.shell.setenv("AWS_TEST_MQTT311_IOT_CORE_PKCS12_KEY_PASSWORD", "PKCS12_KEY_PASSWORD")

actions = []

actions = [
Builder.SetupCrossCICrtEnvironment()
]
return Builder.Script(actions, name='crt-ci-prep')
34 changes: 25 additions & 9 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ on:
- 'docs'

env:
BUILDER_VERSION: v0.9.21
BUILDER_VERSION: v0.9.44
BUILDER_SOURCE: releases
BUILDER_HOST: https://d19elf31gohf1l.cloudfront.net
PACKAGE_NAME: aws-crt-cpp
Expand All @@ -18,6 +18,25 @@ env:
AWS_REGION: us-east-1

jobs:
linux-compat-use-openssl:
runs-on: ubuntu-20.04 # latest
strategy:
matrix:
image:
- fedora-34-x64
- opensuse-leap
- rhel8-x64
steps:
- name: Install qemu/docker
run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
- name: Build ${{ env.PACKAGE_NAME }}
run: |
aws s3 cp s3://aws-crt-test-stuff/ci/${{ env.BUILDER_VERSION }}/linux-container-ci.sh ./linux-container-ci.sh && chmod a+x ./linux-container-ci.sh
./linux-container-ci.sh ${{ env.BUILDER_VERSION }} aws-crt-${{ matrix.image }} build -p ${{ env.PACKAGE_NAME }} --cmake-extra=-DUSE_OPENSSL=ON
# These linux-compat images need to run without -DUSE_OPENSSL because they do not have OpenSSL packages
# that are up-to-date (AL2) or don't provide OpenSSL development packages that is found in CMake (alpine)
# or are not able to connect on the socket even with the correct setup (manylinux2014)
linux-compat:
runs-on: ubuntu-20.04 # latest
strategy:
Expand All @@ -26,9 +45,6 @@ jobs:
- manylinux2014-x64
- manylinux2014-x86
- al2-x64
- fedora-34-x64
- opensuse-leap
- rhel8-x64
- alpine-3.16-x64
- alpine-3.16-x86
- alpine-3.16-armv6
Expand Down Expand Up @@ -63,7 +79,7 @@ jobs:
- name: Build ${{ env.PACKAGE_NAME }}
run: |
aws s3 cp s3://aws-crt-test-stuff/ci/${{ env.BUILDER_VERSION }}/linux-container-ci.sh ./linux-container-ci.sh && chmod a+x ./linux-container-ci.sh
./linux-container-ci.sh ${{ env.BUILDER_VERSION }} aws-crt-${{ env.LINUX_BASE_IMAGE }} build -p ${{ env.PACKAGE_NAME }} --compiler=${{ matrix.compiler }}
./linux-container-ci.sh ${{ env.BUILDER_VERSION }} aws-crt-${{ env.LINUX_BASE_IMAGE }} build -p ${{ env.PACKAGE_NAME }} --compiler=${{ matrix.compiler }} --cmake-extra=-DUSE_OPENSSL=ON
raspberry:
runs-on: ubuntu-20.04 # latest
Expand Down Expand Up @@ -94,7 +110,7 @@ jobs:
run: |
export CXXFLAGS=-std=${{ matrix.std }}
aws s3 cp s3://aws-crt-test-stuff/ci/${{ env.BUILDER_VERSION }}/linux-container-ci.sh ./linux-container-ci.sh && chmod a+x ./linux-container-ci.sh
./linux-container-ci.sh ${{ env.BUILDER_VERSION }} aws-crt-${{ env.LINUX_BASE_IMAGE }} build -p ${{ env.PACKAGE_NAME }} --compiler=${{ matrix.compiler }}
./linux-container-ci.sh ${{ env.BUILDER_VERSION }} aws-crt-${{ env.LINUX_BASE_IMAGE }} build -p ${{ env.PACKAGE_NAME }} --compiler=${{ matrix.compiler }} --cmake-extra=-DUSE_OPENSSL=ON
byo-crypto:
runs-on: ubuntu-20.04 # latest
Expand All @@ -103,7 +119,7 @@ jobs:
- name: Build ${{ env.PACKAGE_NAME }}
run: |
aws s3 cp s3://aws-crt-test-stuff/ci/${{ env.BUILDER_VERSION }}/linux-container-ci.sh ./linux-container-ci.sh && chmod a+x ./linux-container-ci.sh
./linux-container-ci.sh ${{ env.BUILDER_VERSION }} aws-crt-${{ env.LINUX_BASE_IMAGE }} build -p ${{ env.PACKAGE_NAME }} -cmake-extra=-DBYO_CRYPTO=ON
./linux-container-ci.sh ${{ env.BUILDER_VERSION }} aws-crt-${{ env.LINUX_BASE_IMAGE }} build -p ${{ env.PACKAGE_NAME }} --cmake-extra=-DBYO_CRYPTO=ON --cmake-extra=-DUSE_OPENSSL=ON
linux-shared-libs:
runs-on: ubuntu-20.04 # latest
Expand Down Expand Up @@ -139,7 +155,7 @@ jobs:
- name: Build ${{ env.PACKAGE_NAME }}
run: |
aws s3 cp s3://aws-crt-test-stuff/ci/${{ env.BUILDER_VERSION }}/linux-container-ci.sh ./linux-container-ci.sh && chmod a+x ./linux-container-ci.sh
./linux-container-ci.sh ${{ env.BUILDER_VERSION }} aws-crt-${{ env.LINUX_BASE_IMAGE }} build -p ${{ env.PACKAGE_NAME }} --cmake-extra=-DUSE_CPU_EXTENSIONS=OFF
./linux-container-ci.sh ${{ env.BUILDER_VERSION }} aws-crt-${{ env.LINUX_BASE_IMAGE }} build -p ${{ env.PACKAGE_NAME }} --cmake-extra=-DUSE_CPU_EXTENSIONS=OFF --cmake-extra=-DUSE_OPENSSL=ON
windows:
runs-on: windows-2022 # latest
Expand Down Expand Up @@ -229,7 +245,7 @@ jobs:
run: |
python3 -c "from urllib.request import urlretrieve; urlretrieve('${{ env.BUILDER_HOST }}/${{ env.BUILDER_SOURCE }}/${{ env.BUILDER_VERSION }}/builder.pyz?run=${{ env.RUN }}', 'builder')"
chmod a+x builder
./builder build -p ${{ env.PACKAGE_NAME }} --target=ios-arm64
./builder build -p ${{ env.PACKAGE_NAME }} --target=ios-arm64 --cmake-extra=-DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED=NO
cross_compile:
name: Cross Compile ${{matrix.arch}}
Expand Down
51 changes: 5 additions & 46 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,53 +11,12 @@ option(USE_OPENSSL "Set this if you want to use your system's OpenSSL 1.0.2/1.1.
# Let aws-iot-device-sdk-cpp-v2 report its own version in MQTT connections (instead of reporting aws-crt-cpp's version).
option(AWS_IOT_SDK_VERSION "Set the version reported by Aws::Iot::MqttClientConnectionConfigBuilder")

# Proxy integration test control - In addition to this option, all proxy tests require the following environment variables set appropriately when running tests:
#
# AWS_TEST_HTTP_PROXY_HOST - host address of the proxy to use for tests that make open connections to the proxy
# AWS_TEST_HTTP_PROXY_PORT - port to use for tests that make open connections to the proxy
# AWS_TEST_HTTPS_PROXY_HOST - host address of the proxy to use for tests that make tls-protected connections to the proxy
# AWS_TEST_HTTPS_PROXY_PORT - port to use for tests that make tls-protected connections to the proxy
# AWS_TEST_HTTP_PROXY_BASIC_HOST - host address of the proxy to use for tests that make open connections to the proxy with basic authentication
# AWS_TEST_HTTP_PROXY_BASIC_PORT - port to use for tests that make open connections to the proxy with basic authentication
#
# The x509 proxy tests also require:
#
# AWS_TEST_TLS_CERT_PATH - file path to certificate used to initialize the tls context of the x509 provider connection
# AWS_TEST_TLS_KEY_PATH - file path to the key used to initialize the tls context of the x509 provider connection
# AWS_TEST_TLS_ROOT_CERT_PATH - file path to the root CA used to initialize the tls context of the x509 provider connection
# AWS_TEST_X509_ENDPOINT - AWS account-specific endpoint to source x509 credentials from
# AWS_TEST_X509_THING_NAME - associated name of the x509 thing
# AWS_TEST_X509_ROLE_ALIAS - associated role alias ...
#
# And the mqtt websocket tests require x509 sourced credentials with sufficient permission to
# connect to IoT Core as well as:
#
# AWS_TEST_IOT_SIGNING_REGION - AWS region to make a websocket connection to
# AWS_TEST_IOT_MQTT_ENDPOINT - AWS account-specific endpoint to connect to IoT core by
#
# The MQTT5 tests environment variables:
#
# AWS_TEST_MQTT5_DIRECT_MQTT_HOST - host to connect to in direct mqtt tests
# AWS_TEST_MQTT5_DIRECT_MQTT_PORT - port to connect to in direct mqtt tests
# AWS_TEST_MQTT5_DIRECT_MQTT_BASIC_AUTH_HOST - host to connect to in direct mqtt basic authentication tests
# AWS_TEST_MQTT5_DIRECT_MQTT_BASIC_AUTH_PORT - port to connect to in direct mqtt basic authentication tests
# AWS_TEST_MQTT5_DIRECT_MQTT_TLS_HOST - host to connect to in direct mqtt tls tests
# AWS_TEST_MQTT5_DIRECT_MQTT_TLS_PORT - port to connect to in direct mqtt tls tests
# AWS_TEST_MQTT5_WS_MQTT_HOST - host to connect to in websocket tests
# AWS_TEST_MQTT5_WS_MQTT_PORT - port to connect to in websocket tests
# AWS_TEST_MQTT5_WS_MQTT_BASIC_AUTH_HOST - host to connect to in websocket basic authentication tests
# AWS_TEST_MQTT5_WS_MQTT_BASIC_AUTH_PORT - port to connect to in websocket basic authentication tests
# AWS_TEST_MQTT5_WS_MQTT_TLS_HOST - host to connect to in websocket tls tests
# AWS_TEST_MQTT5_WS_MQTT_TLS_PORT - port to connect to in websocket tls tests
# AWS_TEST_MQTT5_BASIC_AUTH_USERNAME - username to use in basic authentication tests
# AWS_TEST_MQTT5_BASIC_AUTH_PASSWORD - password to use in basic authentication tests
# AWS_TEST_MQTT5_PROXY_HOST - name of http proxy host to use in proxy-based tests
# AWS_TEST_MQTT5_PROXY_PORT - port of http proxy host to use in proxy-based tests
#
# ToDo: Scripts to populate environment variables via the CLI and IoT, SecretsManager calls
#
# Tests require environment variables setup in order to run properly.
# See https://github.com/awslabs/aws-crt-builder/blob/main/builder/actions/setup_cross_ci_crt_environment.py
# for how environment variables are setup.
# NOTE: Some environment variables use Mosquitto or Proxy servers, which are assumed to be installed
# locally if running the testing outside of CI/CD.
option(ENABLE_PROXY_INTEGRATION_TESTS "Whether or not to build and run the proxy integration tests that rely on a proxy server installed and running locally" OFF)
option(ENABLE_MQTT5_TEST "Whether or not to build and run the mqtt5 integration reply on a proxy server running locally" ON)


list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
Expand Down
25 changes: 12 additions & 13 deletions codebuild/linux-integration-tests.yml
Original file line number Diff line number Diff line change
@@ -1,31 +1,30 @@
version: 0.2
env:
shell: bash
#this buildspec assumes the ubuntu 14 image
variables:
BUILDER_VERSION: v0.9.44
BUILDER_SOURCE: releases
BUILDER_HOST: https://d19elf31gohf1l.cloudfront.net
PACKAGE_NAME: aws-crt-cpp
#this buildspec assumes usage of an Ubuntu image
phases:
install:
commands:
- wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
- sudo add-apt-repository ppa:ubuntu-toolchain-r/test
- sudo apt-add-repository "deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-6.0 main"
- sudo apt-get update -y
- sudo apt-get install clang-6.0 cmake3 clang-tidy-6.0 clang-format-6.0 -y -f
- curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "/tmp/awscliv2.zip"
- unzip -q -d /tmp /tmp/awscliv2.zip
- sudo /tmp/aws/install

- sudo apt-get install gcc-7 cmake python3 python3-pip -y -f
pre_build:
commands:
- export CC=clang-6.0
- export CXX=clang++-6.0
- export CC=gcc-7
build:
commands:
- echo Build started on `date`
- aws s3 cp s3://aws-crt-test-stuff/setup_proxy_test_env.sh /tmp/setup_proxy_test_env.sh
- sudo chmod a+xr /tmp/setup_proxy_test_env.sh
# Setup Mqtt5 test environment
- source ./codebuild/mqtt5_test_setup.sh s3://aws-crt-test-stuff/CodeBuildIotProdMQTT5EnvironmentVariables_v2.txt us-east-1
- ./codebuild/common-posix.sh -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DENABLE_FUZZ_TESTS=ON -DENABLE_MQTT5_TEST=ON
- git submodule update --init
# Build using builder, which will also run tests
- python3 -c "from urllib.request import urlretrieve; urlretrieve('$BUILDER_HOST/$BUILDER_SOURCE/$BUILDER_VERSION/builder.pyz?run=$CODEBUILD_BUILD_ID', 'builder.pyz')"
- python3 builder.pyz build --project aws-crt-cpp downstream --cmake-extra=-DUSE_OPENSSL=ON
post_build:
commands:
- echo Build completed on `date`
Expand Down
49 changes: 42 additions & 7 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,34 @@ if(NOT BYO_CRYPTO)
add_net_test_case(TLSContextResourceSafety)
add_net_test_case(TLSContextUninitializedNewConnectionOptions)
add_test_case(Sigv4aSigningTestCredentials)

add_net_test_case(IoTMqtt311ConnectWithNoSigningCustomAuth)
add_net_test_case(IoTMqtt311ConnectWithSigningCustomAuth)
add_net_test_case(IoTMqtt311ConnectWithSigningCustomAuthWebsockets)
add_net_test_case(IoTMqtt311ConnectWithPKCS11)
add_net_test_case(IoTMqtt311ConnectWithPKCS12)
add_net_test_case(IoTMqtt311ConnectWithWindowsCert)
add_net_test_case(IoTMqtt311ConnectWSDefault)
add_net_test_case(IoTMqtt311ConnectWSStatic)
add_net_test_case(IoTMqtt311ConnectWSCognito)
add_net_test_case(IoTMqtt311ConnectWSProfile)
add_net_test_case(IoTMqtt311ConnectWSEnvironment)

add_net_test_case(IoTMqtt5ConnectWithmTLS)
add_net_test_case(IoTMqtt5ConnectWithWebsocket)
add_net_test_case(IoTMqtt5ConnectWithSigningCustomAuth)
add_net_test_case(IoTMqtt5ConnectWithNoSigningCustomAuth)
add_net_test_case(IoTMqtt5ConnectWithNoSigningCustomAuthWebsockets)
add_net_test_case(IoTMqtt5ConnectWithSigningCustomAuthWebsockets)
add_net_test_case(IoTMqtt5ConnectWithPKCS11)
add_net_test_case(IoTMqtt5ConnectWithPKCS12)
add_net_test_case(IoTMqtt5ConnectWithWindowsCert)
add_net_test_case(IoTMqtt5ConnectWSStatic)
add_net_test_case(IoTMqtt5ConnectWSCognito)
add_net_test_case(IoTMqtt5ConnectWSProfile)
add_net_test_case(IoTMqtt5ConnectWSEnvironment)
add_net_test_case(IoTMqtt5ConnectWSX509)

endif()

add_test_case(Base64RoundTrip)
Expand All @@ -42,6 +67,7 @@ if(NOT BYO_CRYPTO)
add_net_test_case(HttpStreamUnActivated)
add_net_test_case(HttpCreateConnectionInvalidTlsConnectionOptions)
add_net_test_case(IotPublishSubscribe)
add_net_test_case(IotWillTest)
add_net_test_case(IoTStatisticsPublishWaitStatisticsDisconnect)
add_net_test_case(IoTStatisticsPublishStatisticsWaitDisconnect)
add_net_test_case(HttpClientConnectionManagerResourceSafety)
Expand Down Expand Up @@ -133,10 +159,25 @@ if(ENABLE_PROXY_INTEGRATION_TESTS AND NOT BYO_CRYPTO)
add_test_case(MqttViaHttpProxyAlpnBasicAuth)
endif()

#MQTT311 related tests
if (NOT BYO_CRYPTO)
# MQTT311 TESTS
add_net_test_case(Mqtt311DirectConnectionMinimal)
add_net_test_case(Mqtt311DirectConnectionWithBasicAuth)
add_net_test_case(Mqtt311DirectConnectionWithTLS)
add_net_test_case(Mqtt311DirectConnectionWithMutualTLS)
add_net_test_case(Mqtt311DirectConnectionWithHttpProxy)
add_net_test_case(Mqtt311WSConnectionMinimal)
add_net_test_case(Mqtt311WSConnectionWithBasicAuth)
add_net_test_case(Mqtt311WSConnectionWithTLS)
add_net_test_case(Mqtt311WSConnectionWithHttpProxy)
endif()

#MQTT5 related tests
add_test_case(Mqtt5NewClientMinimal)
add_test_case(Mqtt5NewClientFull)
if(ENABLE_MQTT5_TEST AND NOT BYO_CRYPTO)
if(NOT BYO_CRYPTO)
# MQTT5 TESTS
add_net_test_case(Mqtt5DirectConnectionMinimal)
add_net_test_case(Mqtt5DirectConnectionWithBasicAuth)
add_net_test_case(Mqtt5DirectConnectionWithTLS)
Expand Down Expand Up @@ -171,12 +212,6 @@ if(ENABLE_MQTT5_TEST AND NOT BYO_CRYPTO)
add_net_test_case(Mqtt5RetainSetAndClear)

# IOT CORE TEST
add_net_test_case(IoTMqtt5ConnectWithmTLS)
add_net_test_case(IoTMqtt5ConnectWithWebsocket)
add_net_test_case(IoTMqtt5ConnectWithSigningCustomAuth)
add_net_test_case(IoTMqtt5ConnectWithNoSigningCustomAuth)
add_net_test_case(IoTMqtt5ConnectWithNoSigningCustomAuthWebsockets)
add_net_test_case(IoTMqtt5ConnectWithSigningCustomAuthWebsockets)
add_net_test_case(Mqtt5InterruptSub)
add_net_test_case(Mqtt5InterruptUnsub)
add_net_test_case(Mqtt5InterruptPublishQoS1)
Expand Down
Loading

0 comments on commit 4716c95

Please sign in to comment.