Skip to content

Commit

Permalink
Update service tests
Browse files Browse the repository at this point in the history
  • Loading branch information
alfred2g committed Nov 29, 2023
1 parent ef241fe commit 6e2f4e4
Show file tree
Hide file tree
Showing 10 changed files with 936 additions and 0 deletions.
17 changes: 17 additions & 0 deletions .builder/actions/build_samples.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ def run(self, env):
'deviceadvisor/tests/shadow_update'
]

servicetests = [
'servicetests/tests/JobsExecution/',
]

for sample_path in samples:
build_path = os.path.join('build', sample_path)
steps.append(['cmake',
Expand All @@ -64,6 +68,19 @@ def run(self, env):
'--build', build_path,
'--config', 'RelWithDebInfo'])

for sample_path in servicetests:
build_path = os.path.join('build', sample_path)
steps.append(['cmake',
f'-B{build_path}',
f'-H{sample_path}',
f'-DCMAKE_PREFIX_PATH={env.install_dir}',
'-DCMAKE_BUILD_TYPE=RelWithDebInfo'])
# append extra cmake configs
steps[-1].extend(cmd_args.cmake_extra)
steps.append(['cmake',
'--build', build_path,
'--config', 'RelWithDebInfo'])

for sample_path in da_samples:
build_path = os.path.join('build', sample_path)
steps.append(['cmake',
Expand Down
9 changes: 9 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ env:
CI_FOLDER: "D:/a/work"
CI_UTILS_FOLDER: "./aws-iot-device-sdk-cpp-v2/utils"
CI_SAMPLES_CFG_FOLDER: "./aws-iot-device-sdk-cpp-v2/.github/workflows"
CI_SERVICE_TESTS_CFG_FOLDER: "./aws-iot-device-sdk-cpp-v2/servicetests/test_cases"
CI_IOT_CONTAINERS: arn:aws:iam::123124136734:role/CRT_IoT_Containers
CI_PUBSUB_ROLE: arn:aws:iam::180635532705:role/CI_PubSub_Role
CI_CYCLEPUBSUB_ROLE: arn:aws:iam::180635532705:role/CI_CyclePubSub_Role
Expand Down Expand Up @@ -570,6 +571,14 @@ jobs:
run: |
python3 ${{ env.CI_UTILS_FOLDER }}/run_sample_ci.py --file ${{ env.CI_SAMPLES_CFG_FOLDER }}/ci_run_greengrass_discovery_cfg.json
- name: run mqtt3 Jobs sericetests
run: |
python3 ${{ env.CI_UTILS_FOLDER }}/run_sample_ci.py --file ${{ env.CI_SERVICE_TESTS_CFG_FOLDER}}/mqtt3_jobs_cfg.json
- name: run mqtt5 Jobs sericetests
run: |
python3 ${{ env.CI_UTILS_FOLDER }}/run_sample_ci.py --file ${{ env.CI_SERVICE_TESTS_CFG_FOLDER}}/mqtt5_jobs_cfg.json
# check that docs can still build
check-docs:
runs-on: ubuntu-20.04 # latest
Expand Down
2 changes: 2 additions & 0 deletions samples/utils/CommandLineUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
namespace Utils
{
// The command names for the samples
static const char *m_cmd_mqtt_version = "mqtt_version";
static const char *m_cmd_endpoint = "endpoint";
static const char *m_cmd_ca_file = "ca_file";
static const char *m_cmd_cert_file = "cert";
Expand Down Expand Up @@ -418,6 +419,7 @@ namespace Utils
cmdData->input_ca = cmdUtils->GetCommand(m_cmd_ca_file);
}
cmdData->input_isCI = cmdUtils->HasCommand(m_cmd_is_ci);
cmdData->input_mqtt_version = atoi(cmdUtils->GetCommandOrDefault(m_cmd_mqtt_version, "3").c_str());
}

static void s_populateTopic(CommandLineUtils *cmdUtils, cmdData *cmdData)
Expand Down
2 changes: 2 additions & 0 deletions samples/utils/CommandLineUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,8 @@ namespace Utils
Aws::Crt::String input_pkcs12Password;
// Greengrass Discovery
bool input_PrintDiscoverRespOnly;
// MQTT protocol version
uint64_t input_mqtt_version;
};

cmdData parseSampleInputDeviceDefender(int argc, char *argv[], Aws::Crt::ApiHandle *api_handle);
Expand Down
32 changes: 32 additions & 0 deletions servicetests/test_cases/mqtt3_jobs_cfg.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"language": "CPP",
"sample_file": "./aws-iot-device-sdk-cpp-v2/build/servicestests/tests/JobsExecution/describe-job-execution",
"sample_region": "us-east-1",
"sample_main_class": "",
"arguments": [
{
"name": "--mqtt_version",
"data": "3"
},
{
"name": "--endpoint",
"secret": "ci/endpoint"
},
{
"name": "--cert",
"data": "certificate.pem.crt"
},
{
"name": "--key",
"data": "private.pem.key"
},
{
"name": "--thing_name",
"data": "ServiceTest_Jobs_$INPUT_UUID"
},
{
"name": "--is_ci",
"data": "true"
}
]
}
32 changes: 32 additions & 0 deletions servicetests/test_cases/mqtt5_jobs_cfg.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"language": "CPP",
"sample_file": "./aws-iot-device-sdk-cpp-v2/build/servicestests/tests/JobsExecution/describe-job-execution",
"sample_region": "us-east-1",
"sample_main_class": "",
"arguments": [
{
"name": "--mqtt_version",
"data": "5"
},
{
"name": "--endpoint",
"secret": "ci/endpoint"
},
{
"name": "--cert",
"data": "certificate.pem.crt"
},
{
"name": "--key",
"data": "private.pem.key"
},
{
"name": "--thing_name",
"data": "ServiceTest_Jobs_$INPUT_UUID"
},
{
"name": "--is_ci",
"data": "true"
}
]
}
103 changes: 103 additions & 0 deletions servicetests/test_cases/test_jobs_execution.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0.

import argparse
import json
import os
import sys
import uuid

import boto3

import run_in_ci
import ci_iot_thing


def main():
argument_parser = argparse.ArgumentParser(
description="Run Jobs test in CI")
argument_parser.add_argument(
"--config-file", required=True, help="JSON file providing command-line arguments for a test")
argument_parser.add_argument(
"--input-uuid", required=False, help="UUID for thing name. UUID will be generated if this option is omit")
argument_parser.add_argument(
"--region", required=False, default="us-east-1", help="The name of the region to use")
parsed_commands = argument_parser.parse_args()

try:
iot_client = boto3.client('iot', region_name=parsed_commands.region)
secrets_client = boto3.client("secretsmanager", region_name=parsed_commands.region)
except Exception as e:
print(f"ERROR: Could not make Boto3 iot-data client. Credentials likely could not be sourced. Exception: {e}",
file=sys.stderr)
return -1

input_uuid = parsed_commands.input_uuid if parsed_commands.input_uuid else str(uuid.uuid4())

thing_name = "ServiceTest_Jobs_" + input_uuid
policy_name = secrets_client.get_secret_value(
SecretId="ci/JobsServiceClientTest/policy_name")["SecretString"]

# Temporary certificate/key file path.
certificate_path = os.path.join(os.getcwd(), "tests/jobs_execution/certificate.pem.crt")
key_path = os.path.join(os.getcwd(), "tests/jobs_execution/private.pem.key")

try:
ci_iot_thing.create_iot_thing(
thing_name=thing_name,
thing_group="CI_ServiceClient_Thing_Group",
region=parsed_commands.region,
policy_name=policy_name,
certificate_path=certificate_path,
key_path=key_path)
except Exception as e:
print(f"ERROR: Failed to create IoT thing: {e}")
sys.exit(-1)

# Perform Jobs test. If it's successful, the Job execution should be marked as SUCCEEDED for the thing.
try:
test_result = run_in_ci.setup_and_launch(parsed_commands.config_file, input_uuid)
except Exception as e:
print(f"ERROR: Failed to execute Jobs test: {e}")
test_result = -1

# Test reported success, verify that Job was indeed executed by the thing.
if test_result == 0:
print("Verifying that Job was executed")
try:
job_id = secrets_client.get_secret_value(SecretId="ci/JobsServiceClientTest/job_id")["SecretString"]
thing_job = iot_client.describe_job_execution(jobId=job_id, thingName=thing_name)
job_status = thing_job.get('execution', {}).get('status', {})
if job_status != 'SUCCEEDED':
print(f"ERROR: Could not verify Job execution; Job info: {thing_job}")
test_result = -1
except Exception as e:
print(f"ERROR: Could not verify Job execution: {e}")
test_result = -1

if test_result == 0:
print("Test succeeded")

# Delete a thing created for this test run.
# NOTE We want to try to delete thing even if test was unsuccessful.
try:
ci_iot_thing.delete_iot_thing(thing_name, parsed_commands.region)
except Exception as e:
print(f"ERROR: Failed to delete thing: {e}")
# Fail the test if unable to delete thing, so this won't remain unnoticed.
test_result = -1

try:
if os.path.isfile(certificate_path):
os.remove(certificate_path)
if os.path.isfile(key_path):
os.remove(key_path)
except Exception as e:
print(f"WARNING: Failed to delete local files: {e}")

if test_result != 0:
sys.exit(-1)


if __name__ == "__main__":
main()
28 changes: 28 additions & 0 deletions servicetests/tests/JobsExecution/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
cmake_minimum_required(VERSION 3.1)
# note: cxx-17 requires cmake 3.8, cxx-20 requires cmake 3.12
project(describe-job-execution CXX)

file(GLOB SRC_FILES
"*.cpp"
"../../../samples/utils/CommandLineUtils.cpp"
"../../../samples/utils/CommandLineUtils.h"
)

add_executable(${PROJECT_NAME} ${SRC_FILES})

set_target_properties(${PROJECT_NAME} PROPERTIES
CXX_STANDARD 14)

#set warnings
if (MSVC)
target_compile_options(${PROJECT_NAME} PRIVATE /W4 /WX)
else ()
target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Wno-long-long -pedantic -Werror)
endif ()

find_package(aws-crt-cpp REQUIRED)
find_package(IotJobs-cpp REQUIRED)

install(TARGETS ${PROJECT_NAME} DESTINATION bin)

target_link_libraries(${PROJECT_NAME} PRIVATE AWS::aws-crt-cpp AWS::IotJobs-cpp)
Loading

0 comments on commit 6e2f4e4

Please sign in to comment.