diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 44c53b53..11c6cc7b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -52,6 +52,7 @@ jobs: - name: Run tests run: | cd build + source ../scripts/get-iot-certs.sh ci ./tst/producer_test mac-os-build-clang: @@ -81,6 +82,37 @@ jobs: - name: Run tests run: | cd build + source ../scripts/get-iot-certs.sh ci + ./tst/producer_test + + mac-os-m1-build-clang: + runs-on: macos-13-xlarge + env: + AWS_KVS_LOG_LEVEL: 2 + permissions: + id-token: write + contents: read + steps: + - name: Clone repository + uses: actions/checkout@v3 + - name: Build repository + run: | + brew install pkgconfig + brew unlink openssl # it seems the libcurl is trying to access this openssl despite explicitly setting it to our build + mkdir build && cd build + sh -c 'cmake .. -DBUILD_TEST=TRUE -DCOMPILER_WARNINGS=TRUE -DCMAKE_C_COMPILER=$(brew --prefix llvm@15)/bin/clang -DCMAKE_CXX_COMPILER=$(brew --prefix llvm@15)/bin/clang++;cmake .. -DBUILD_TEST=TRUE -DCOMPILER_WARNINGS=TRUE -DCMAKE_C_COMPILER=$(brew --prefix llvm@15)/bin/clang -DCMAKE_CXX_COMPILER=$(brew --prefix llvm@15)/bin/clang++' + make + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v1-node16 + with: + role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }} + role-session-name: ${{ secrets.AWS_ROLE_SESSION_NAME }} + aws-region: ${{ secrets.AWS_REGION }} + role-duration-seconds: 10800 + - name: Run tests + run: | + cd build + source ../scripts/get-iot-certs.sh ci ./tst/producer_test mac-os-m1-build-clang: @@ -178,6 +210,7 @@ jobs: - name: Run tests run: | cd build + source ../scripts/get-iot-certs.sh ci ./tst/producer_test mac-os-build-clang-local-openssl: @@ -209,40 +242,30 @@ jobs: - name: Run tests run: | cd build + source ../scripts/get-iot-certs.sh ci ./tst/producer_test - linux-gcc-code-coverage: + ubuntu-os-gcc-build-lws-mbedtls: runs-on: ubuntu-20.04 env: AWS_KVS_LOG_LEVEL: 2 + CC: gcc + CXX: g++ permissions: id-token: write contents: read steps: - name: Clone repository uses: actions/checkout@v3 + - name: Install dependencies + run: | + sudo apt clean && sudo apt update + sudo sh -c 'echo 0 > /proc/sys/net/ipv6/conf/all/disable_ipv6' - name: Build repository run: | mkdir build && cd build - cmake .. -DCODE_COVERAGE=TRUE -DBUILD_TEST=TRUE -DBUILD_COMMON_LWS=TRUE + cmake .. -DBUILD_COMMON_LWS=ON -DBUILD_COMMON_CURL=OFF -DUSE_OPENSSL=OFF -DUSE_MBEDTLS=ON make - - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v1-node16 - with: - role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }} - role-session-name: ${{ secrets.AWS_ROLE_SESSION_NAME }} - aws-region: ${{ secrets.AWS_REGION }} - role-duration-seconds: 10800 - - name: Run tests - run: | - cd build - ulimit -c unlimited -S - timeout --signal=SIGABRT 150m ./tst/producer_test --gtest_break_on_failure - - name: Code coverage - run: | - cd build - for test_file in $(find cproducer.dir kvsCommonCurl.dir kvsCommonLws.dir -name '*.gcno'); do gcov $test_file; done - bash <(curl -s https://codecov.io/bash) address-sanitizer: runs-on: ubuntu-20.04 @@ -253,6 +276,10 @@ jobs: CC: clang CXX: clang++ AWS_KVS_LOG_LEVEL: 2 + # The unit tests will have both LWS and CURL enabled, both linking to globalMemCalloc. Our PIC is + # has quite a few global definitions that get linked twice. TODO: see if we can list common dependency + # to remove this option + ASAN_OPTIONS: detect_odr_violation=0 steps: - name: Clone repository uses: actions/checkout@v3 @@ -272,6 +299,7 @@ jobs: run: | cd build ulimit -c unlimited -S + source ../scripts/get-iot-certs.sh ci timeout --signal=SIGABRT 150m ./tst/producer_test --gtest_break_on_failure undefined-behavior-sanitizer: @@ -302,8 +330,10 @@ jobs: run: | cd build ulimit -c unlimited -S + source ../scripts/get-iot-certs.sh ci timeout --signal=SIGABRT 150m ./tst/producer_test --gtest_break_on_failure + # memory-sanitizer: # runs-on: ubuntu-20.04 # permissions: @@ -378,7 +408,7 @@ jobs: - name: Build repository run: | mkdir build && cd build - cmake .. -DBUILD_TEST=TRUE + cmake .. -DBUILD_TEST=TRUE -DBUILD_COMMON_LWS=ON make - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@v1-node16 @@ -391,6 +421,7 @@ jobs: run: | cd build ulimit -c unlimited -S + source ../scripts/get-iot-certs.sh ci timeout --signal=SIGABRT 150m ./tst/producer_test --gtest_break_on_failure windows-msvc: @@ -405,7 +436,7 @@ jobs: uses: actions/checkout@v3 - name: Install dependencies run: | - choco install nasm strawberryperl + choco install nasm strawberryperl pkgconfiglite - name: Build repository run: | $env:Path += ';C:\Strawberry\perl\site\bin;C:\Strawberry\perl\bin;C:\Strawberry\c\bin;C:\Program Files\NASM;D:\a\amazon-kinesis-video-streams-producer-c\amazon-kinesis-video-streams-producer-c\open-source\lib;D:\a\amazon-kinesis-video-streams-producer-c\amazon-kinesis-video-streams-producer-c\open-source\bin' @@ -421,7 +452,7 @@ jobs: - name: Run tests run: | $env:Path += ';C:\Strawberry\perl\site\bin;C:\Strawberry\perl\bin;C:\Strawberry\c\bin;C:\Program Files\NASM;D:\a\amazon-kinesis-video-streams-producer-c\amazon-kinesis-video-streams-producer-c\open-source\lib;D:\a\amazon-kinesis-video-streams-producer-c\amazon-kinesis-video-streams-producer-c\open-source\bin' - & "D:\a\amazon-kinesis-video-streams-producer-c\amazon-kinesis-video-streams-producer-c\build\tst\producer_test.exe" --gtest_filter="-ProducerFunctionalityTest.pressure_on_buffer_duration_fail_new_connection_at_token_rotation" + & "D:\a\amazon-kinesis-video-streams-producer-c\amazon-kinesis-video-streams-producer-c\build\tst\producer_test.exe" --gtest_filter="-IoTCredentialTest.*:ProducerFunctionalityTest.pressure_on_buffer_duration_fail_new_connection_at_token_rotation" arm64-cross-compilation: runs-on: ubuntu-20.04 diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml new file mode 100644 index 00000000..7a620c0a --- /dev/null +++ b/.github/workflows/codecov.yml @@ -0,0 +1,51 @@ +name: Producer C SDK Codecov + +on: + push: + branches: + - develop + - master + pull_request: + branches: + - develop + - master + +jobs: + linux-gcc-code-coverage: + runs-on: ubuntu-20.04 + env: + AWS_KVS_LOG_LEVEL: 2 + permissions: + id-token: write + contents: read + steps: + - name: Clone repository + uses: actions/checkout@v3 + - name: Build repository + run: | + sudo apt install lcov + mkdir build && cd build + cmake .. -DCODE_COVERAGE=TRUE -DBUILD_TEST=TRUE -DBUILD_COMMON_LWS=TRUE + make + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v1-node16 + with: + role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }} + role-session-name: ${{ secrets.AWS_ROLE_SESSION_NAME }} + aws-region: ${{ secrets.AWS_REGION }} + role-duration-seconds: 10800 + - name: Run tests + run: | + cd build + ulimit -c unlimited -S + source ../scripts/get-iot-certs.sh ci + timeout --signal=SIGABRT 150m ./tst/producer_test --gtest_break_on_failure + - name: Generate and process coverage data with lcov + run: | + cd build + lcov --capture --directory CMakeFiles/cproducer.dir --directory CMakeFiles/kvsCommonCurl.dir --directory CMakeFiles/kvsCommonLws.dir --output-file coverage.info + lcov --list coverage.info + lcov --remove coverage.info '*jsmn*' -o coverage_filtered.info + lcov --list coverage_filtered.info + rm coverage.info + bash <(curl -s https://codecov.io/bash) -f ./coverage_filtered.info -t ${{ secrets.CODECOV_TOKEN }} -Z diff --git a/.github/workflows/version-check.yml b/.github/workflows/version-check.yml new file mode 100644 index 00000000..24ebef72 --- /dev/null +++ b/.github/workflows/version-check.yml @@ -0,0 +1,42 @@ +name: Check Version Mismatch between PR branch and master. + +on: + pull_request: + branches: + - master + +jobs: + check-version: + runs-on: ubuntu-latest + steps: + - name: Checkout PR branch + uses: actions/checkout@v4 + + - name: Get version from PR + id: pr_version + run: | + PR_VERSION=$(grep -Po 'KinesisVideoProducerC VERSION \K[0-9]+\.[0-9]+\.[0-9]+' CMakeLists.txt) + echo "PR_VERSION=$PR_VERSION" >> "$GITHUB_ENV" + echo "PR Version: $PR_VERSION" + + - name: Checkout master branch + uses: actions/checkout@v4 + with: + ref: master + + - name: Get version from master + id: master_version + run: | + MASTER_VERSION=$(grep -Po 'KinesisVideoProducerC VERSION \K[0-9]+\.[0-9]+\.[0-9]+' CMakeLists.txt) + echo "MASTER_VERSION=$MASTER_VERSION" >> "$GITHUB_ENV" + echo "Master version: $MASTER_VERSION" + + - name: Compare versions + run: | + echo "Comparing PR Version: $PR_VERSION with Master Version: $MASTER_VERSION" + if [ "$MASTER_VERSION" == "$PR_VERSION" ]; then + echo "Please update the version in CMakeLists.txt file (project(KinesisVideoProducerC VERSION LANGUAGES C). Any PR getting merged to master requires a version update" + exit 1 + else + echo "Version update detected." + fi \ No newline at end of file diff --git a/CMake/Dependencies/libkvspic-CMakeLists.txt b/CMake/Dependencies/libkvspic-CMakeLists.txt index 87a0fb72..a4eb70d9 100644 --- a/CMake/Dependencies/libkvspic-CMakeLists.txt +++ b/CMake/Dependencies/libkvspic-CMakeLists.txt @@ -8,10 +8,12 @@ include(ExternalProject) ExternalProject_Add(libkvspic-download GIT_REPOSITORY https://github.com/awslabs/amazon-kinesis-video-streams-pic.git GIT_TAG v1.1.0 + SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/kvspic-src" BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/kvspic-build" CMAKE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + -DKVS_DEFAULT_STACK_SIZE=${KVS_DEFAULT_STACK_SIZE} CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" diff --git a/CMake/Dependencies/libwebsockets-CMakeLists.txt b/CMake/Dependencies/libwebsockets-CMakeLists.txt index 3ada49e4..fbf9f36d 100644 --- a/CMake/Dependencies/libwebsockets-CMakeLists.txt +++ b/CMake/Dependencies/libwebsockets-CMakeLists.txt @@ -20,7 +20,7 @@ endif() ExternalProject_Add(project_libwebsockets GIT_REPOSITORY https://github.com/warmcat/libwebsockets.git - GIT_TAG v3.2.3 + GIT_TAG v4.3.3 PREFIX ${CMAKE_CURRENT_BINARY_DIR}/build CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${OPEN_SRC_INSTALL_PREFIX} diff --git a/CMakeLists.txt b/CMakeLists.txt index 3131b847..ec725ca6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,6 +8,11 @@ set(KINESIS_VIDEO_PRODUCER_C_MINOR_VERSION 5) set(KINESIS_VIDEO_PRODUCER_C_PATCH_VERSION 2) set(KINESIS_VIDEO_PRODUCER_C_VERSION ${KINESIS_VIDEO_PRODUCER_C_MAJOR_VERSION}.${KINESIS_VIDEO_PRODUCER_C_MINOR_VERSION}.${KINESIS_VIDEO_PRODUCER_C_PATCH_VERSION}) +set(KINESIS_VIDEO_PRODUCER_C_MAJOR_VERSION 1) +set(KINESIS_VIDEO_PRODUCER_C_MINOR_VERSION 5) +set(KINESIS_VIDEO_PRODUCER_C_PATCH_VERSION 1) +set(KINESIS_VIDEO_PRODUCER_C_VERSION ${KINESIS_VIDEO_PRODUCER_C_MAJOR_VERSION}.${KINESIS_VIDEO_PRODUCER_C_MINOR_VERSION}.${KINESIS_VIDEO_PRODUCER_C_PATCH_VERSION}) + include(GNUInstallDirs) @@ -289,8 +294,7 @@ if(BUILD_COMMON_LWS) set_target_properties(kvsCommonLws PROPERTIES VERSION ${KINESIS_VIDEO_PRODUCER_C_VERSION} SOVERSION ${KINESIS_VIDEO_PRODUCER_C_MAJOR_VERSION}) endif() target_link_libraries(kvsCommonLws - ${OPENSSL_CRYPTO_LIBRARY} - ${OPENSSL_SSL_LIBRARY} + ${PRODUCER_CRYPTO_LIBRARY} ${LIBWEBSOCKETS_LIBRARIES} kvspicUtils) diff --git a/README.md b/README.md index ff2bd346..cc64a1b6 100644 --- a/README.md +++ b/README.md @@ -142,6 +142,7 @@ To run the samples with IoT credential provider: 3. Build the changes: `make` 4. Run the sample using the instructions in previous section. + ### Fragment metadata `./kvsVideoOnlyRealtimeStreamingSample` is the only sample that has the [fragment metadata](https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/how-meta.html) implemented out of the box. diff --git a/scripts/generate-iot-credential.sh b/scripts/generate-iot-credential.sh index 29801cb0..b13c096b 100755 --- a/scripts/generate-iot-credential.sh +++ b/scripts/generate-iot-credential.sh @@ -112,4 +112,4 @@ export AWS_IOT_CORE_CREDENTIAL_ENDPOINT=$(cat iot-credential-provider.txt) export AWS_IOT_CORE_CERT=$(pwd)"/"$iotCert export AWS_IOT_CORE_PRIVATE_KEY=$(pwd)"/"$iotPrivateKey export AWS_IOT_CORE_ROLE_ALIAS=$iotRoleAlias -export AWS_IOT_CORE_THING_NAME=$thingName \ No newline at end of file +export AWS_IOT_CORE_THING_NAME=$thingName diff --git a/scripts/get-iot-certs.sh b/scripts/get-iot-certs.sh new file mode 100644 index 00000000..0dbcbe7d --- /dev/null +++ b/scripts/get-iot-certs.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +prefix=$1 +thingName="${prefix}_thing" +thingTypeName="${prefix}_thing_type" +iotPolicyName="${prefix}_policy" +iotRoleName="${prefix}_role" +iotRoleAlias="${prefix}_role_alias" +iotCert="${prefix}_certificate.pem" +iotPublicKey="${prefix}_public.key" +iotPrivateKey="${prefix}_private.key" + +# Create the certificate to which you must attach the policy for IoT that you created above. +aws iot create-keys-and-certificate --set-as-active --certificate-pem-outfile $iotCert --public-key-outfile $iotPublicKey --private-key-outfile $iotPrivateKey > certificate +# Attach the policy for IoT (KvsCameraIoTPolicy created above) to this certificate. +aws iot attach-policy --policy-name $iotPolicyName --target $(jq --raw-output '.certificateArn' certificate) +# Attach your IoT thing (kvs_example_camera_stream) to the certificate you just created: +aws iot attach-thing-principal --thing-name $thingName --principal $(jq --raw-output '.certificateArn' certificate) +# In order to authorize requests through the IoT credentials provider, you need the IoT credentials endpoint which is unique to your AWS account ID. You can use the following command to get the IoT credentials endpoint. +aws iot describe-endpoint --endpoint-type iot:CredentialProvider --output text > iot-credential-provider.txt +# In addition to the X.509 cerficiate created above, you must also have a CA certificate to establish trust with the back-end service through TLS. You can get the CA certificate using the following command: +curl 'https://www.amazontrust.com/repository/SFSRootCAG2.pem' --output cacert.pem + +export AWS_IOT_CORE_CREDENTIAL_ENDPOINT=$(cat iot-credential-provider.txt) +export AWS_IOT_CORE_CERT=$(pwd)"/"$iotCert +export AWS_IOT_CORE_PRIVATE_KEY=$(pwd)"/"$iotPrivateKey +export AWS_IOT_CORE_ROLE_ALIAS=$iotRoleAlias +export AWS_IOT_CORE_THING_NAME=$thingName \ No newline at end of file diff --git a/src/source/CallbacksProvider.c b/src/source/CallbacksProvider.c index 28572c5d..54ba90f5 100644 --- a/src/source/CallbacksProvider.c +++ b/src/source/CallbacksProvider.c @@ -230,7 +230,7 @@ STATUS createDefaultCallbacksProviderWithFileAuth(PCHAR credentialsFilePath, PCH } if (pAuthCallbacks != NULL) { - freeIotAuthCallbacks(&pAuthCallbacks); + freeFileAuthCallbacks(&pAuthCallbacks); } if (pStreamCallbacks != NULL) { diff --git a/src/source/Common/AwsV4Signer.c b/src/source/Common/AwsV4Signer.c index 19b5831a..f0257d2f 100644 --- a/src/source/Common/AwsV4Signer.c +++ b/src/source/Common/AwsV4Signer.c @@ -916,14 +916,14 @@ STATUS uriDecodeString(PCHAR pSrc, UINT32 srcLen, PCHAR pDst, PUINT32 pDstLen) PCHAR pCurPtr = pSrc, pDec = pDst; CHAR ch; + CHK(pSrc != NULL && pDstLen != NULL, STATUS_NULL_ARG); + // Set the source length to max if not specified strLen = (srcLen == 0) ? MAX_UINT32 : srcLen; // Set the remaining length remaining = (pDst == NULL) ? MAX_UINT32 : *pDstLen; - CHK(pSrc != NULL && pDstLen != NULL, STATUS_NULL_ARG); - while (((UINT32) (pCurPtr - pSrc) < strLen) && ((ch = *pCurPtr) != '\0')) { if (ch == '%') { CHK((UINT32) (pCurPtr - pSrc) + decLen <= strLen && *(pCurPtr + 1) != '\0' && *(pCurPtr + 2) != '\0', STATUS_INVALID_ARG); diff --git a/src/source/Common/IotCredentialProvider.c b/src/source/Common/IotCredentialProvider.c index ba23b185..3deedd7c 100644 --- a/src/source/Common/IotCredentialProvider.c +++ b/src/source/Common/IotCredentialProvider.c @@ -25,7 +25,7 @@ STATUS createIotCredentialProviderWithTime(PCHAR iotGetCredentialEndpoint, PCHAR pIotCredentialProvider->getCurrentTimeFn = (getCurrentTimeFn == NULL) ? commonDefaultGetCurrentTimeFunc : getCurrentTimeFn; pIotCredentialProvider->customData = customData; - CHK(STRNLEN(iotGetCredentialEndpoint, MAX_URI_CHAR_LEN + 1) <= MAX_URI_CHAR_LEN, MAX_URI_CHAR_LEN); + CHK(STRNLEN(iotGetCredentialEndpoint, MAX_URI_CHAR_LEN + 1) <= MAX_URI_CHAR_LEN, STATUS_INVALID_ARG); STRNCPY(pIotCredentialProvider->iotGetCredentialEndpoint, iotGetCredentialEndpoint, MAX_URI_CHAR_LEN); CHK(STRNLEN(roleAlias, MAX_ROLE_ALIAS_LEN + 1) <= MAX_ROLE_ALIAS_LEN, STATUS_MAX_ROLE_ALIAS_LEN_EXCEEDED); diff --git a/src/source/Common/RequestInfo.c b/src/source/Common/RequestInfo.c index 86e7d936..2a9acc28 100644 --- a/src/source/Common/RequestInfo.c +++ b/src/source/Common/RequestInfo.c @@ -245,7 +245,8 @@ STATUS removeRequestHeader(PRequestInfo pRequestInfo, PCHAR headerName) if (STRCMPI(pCurrentHeader->pName, headerName) == 0) { CHK_STATUS(singleListDeleteNode(pRequestInfo->pRequestHeaders, pCurNode)); - + // Free only if found + SAFE_MEMFREE(pCurrentHeader); // Early return CHK(FALSE, retStatus); } @@ -255,8 +256,6 @@ STATUS removeRequestHeader(PRequestInfo pRequestInfo, PCHAR headerName) CleanUp: - SAFE_MEMFREE(pCurrentHeader); - return retStatus; } diff --git a/src/source/Response.c b/src/source/Response.c index b96c0510..6d979664 100644 --- a/src/source/Response.c +++ b/src/source/Response.c @@ -282,6 +282,7 @@ VOID terminateCurlSession(PCurlResponse pCurlResponse, UINT64 timeout) } } +/* UNCOMMENT if required to use for CURL debugging. Not used at the moment. VOID dumpResponseCurlEasyInfo(PCurlResponse pCurlResponse) { DOUBLE time; @@ -353,6 +354,7 @@ VOID dumpResponseCurlEasyInfo(PCurlResponse pCurlResponse) } } } + */ SERVICE_CALL_RESULT getServiceCallResultFromCurlStatus(CURLcode curlStatus) { diff --git a/src/source/Response.h b/src/source/Response.h index 5f625f4a..60fe1b24 100644 --- a/src/source/Response.h +++ b/src/source/Response.h @@ -109,20 +109,18 @@ STATUS freeCurlResponse(PCurlResponse*); STATUS closeCurlHandles(PCurlResponse); /** - * Debug prints statistics of the request/response + * Terminates the ongoing curl session * * @param - PCurlResponse - IN - Response object + * @param - UINT64 - IN - Timeout value to use in 100ns * */ -VOID dumpResponseCurlEasyInfo(PCurlResponse); -/** - * Terminates the ongoing curl session - * - * @param - PCurlResponse - IN - Response object - * @param - UINT64 - IN - Timeout value to use in 100ns +/* @param - PCurlResponse - IN - Response object * + * VOID dumpResponseCurlEasyInfo(PCurlResponse); */ + VOID terminateCurlSession(PCurlResponse, UINT64); /** diff --git a/src/source/StreamInfoProvider.c b/src/source/StreamInfoProvider.c index 5bbdb023..47e40c6f 100644 --- a/src/source/StreamInfoProvider.c +++ b/src/source/StreamInfoProvider.c @@ -112,7 +112,7 @@ STATUS createVideoTrackInfo(VIDEO_CODEC_ID videoCodecId, PCHAR contentType, PTra break; default: STRCPY(pTrackInfo->codecId, MKV_H264_AVC_CODEC_ID); - STRCAT(contentType, MKV_H265_CONTENT_TYPE); + STRCAT(contentType, MKV_H264_CONTENT_TYPE); } STRCPY(pTrackInfo->trackName, DEFAULT_VIDEO_TRACK_NAME); pTrackInfo->trackType = MKV_TRACK_INFO_TYPE_VIDEO; diff --git a/tst/AuthCallbackTest.cpp b/tst/AuthCallbackTest.cpp index 270129bb..0eb09723 100644 --- a/tst/AuthCallbackTest.cpp +++ b/tst/AuthCallbackTest.cpp @@ -19,13 +19,16 @@ TEST_F(AuthCallbackTest, ioTExpirationParsing_Returns_Success) CHAR validFormatIotExpirationTimeStamp[] = "2019-01-31T23:00:59Z"; // expiration is current time + 1 hour UINT64 expirationTimestampInEpoch = 0; - convertTimestampToEpoch(validFormatIotExpirationTimeStamp, iotTimeInEpoch, &expirationTimestampInEpoch); + EXPECT_EQ(STATUS_NULL_ARG, convertTimestampToEpoch(NULL, iotTimeInEpoch, &expirationTimestampInEpoch)); + EXPECT_EQ(STATUS_NULL_ARG, convertTimestampToEpoch(NULL, iotTimeInEpoch, NULL)); + EXPECT_EQ(STATUS_NULL_ARG, convertTimestampToEpoch(validFormatIotExpirationTimeStamp, iotTimeInEpoch, NULL)); + EXPECT_EQ(STATUS_SUCCESS, convertTimestampToEpoch(validFormatIotExpirationTimeStamp, iotTimeInEpoch, &expirationTimestampInEpoch)); EXPECT_TRUE(iotTimeInEpoch == expirationTimestampInEpoch / HUNDREDS_OF_NANOS_IN_A_SECOND - 3600); iotTimeInEpoch = 1548975659; // iot expiration same as current time - convertTimestampToEpoch(validFormatIotExpirationTimeStamp, iotTimeInEpoch, &expirationTimestampInEpoch); + EXPECT_EQ(STATUS_SUCCESS,convertTimestampToEpoch(validFormatIotExpirationTimeStamp, iotTimeInEpoch, &expirationTimestampInEpoch)); EXPECT_TRUE(iotTimeInEpoch == expirationTimestampInEpoch / HUNDREDS_OF_NANOS_IN_A_SECOND); @@ -71,11 +74,7 @@ TEST_F(AuthCallbackTest, verify_fileAuthCallback_provider_works) PCHAR authFilePath = NULL; PAuthCallbacks pAuthCallbacks = NULL; - authFilePath = getenv(TEST_AUTH_FILE_PATH); - if (authFilePath == NULL) { - DLOGI("Auth file not provided, passing test"); - return; - } + authFilePath = SAMPLE_AUTH_FILE_PATH; STRNCPY(streamName, (PCHAR) TEST_STREAM_NAME, MAX_STREAM_NAME_LEN); streamName[MAX_STREAM_NAME_LEN] = '\0'; @@ -96,12 +95,6 @@ TEST_F(AuthCallbackTest, verify_fileAuthCallback_provider_works) authFilePath, &pAuthCallbacks)); - EXPECT_EQ(STATUS_SUCCESS, createKinesisVideoClientSync(pDeviceInfo, pClientCallbacks, &clientHandle)); - EXPECT_EQ(STATUS_SUCCESS, createKinesisVideoStreamSync(clientHandle, pStreamInfo, &streamHandle)); - - EXPECT_EQ(STATUS_SUCCESS, stopKinesisVideoStreamSync(streamHandle)); - EXPECT_EQ(STATUS_SUCCESS, freeKinesisVideoStream(&streamHandle)); - EXPECT_EQ(STATUS_SUCCESS, freeKinesisVideoClient(&clientHandle)); EXPECT_EQ(STATUS_SUCCESS, freeDeviceInfo(&pDeviceInfo)); EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); EXPECT_EQ(STATUS_SUCCESS, freeCallbacksProvider(&pClientCallbacks)); @@ -136,6 +129,8 @@ TEST_F(AuthCallbackTest, credential_provider_auth_callbacks_test) NULL, &pClientCallbacks)); + EXPECT_EQ(STATUS_NULL_ARG, createStaticCredentialProvider(mAccessKey, 0, mSecretKey, 0, mSessionToken, 0, + MAX_UINT64, NULL)); // Create the credential provider based on static credentials which will be used with auth callbacks EXPECT_EQ(STATUS_SUCCESS, createStaticCredentialProvider(mAccessKey, 0, mSecretKey, 0, mSessionToken, 0, MAX_UINT64, &pAwsCredentialProvider)); @@ -159,6 +154,7 @@ TEST_F(AuthCallbackTest, credential_provider_auth_callbacks_test) EXPECT_EQ(STATUS_SUCCESS, freeDeviceInfo(&pDeviceInfo)); EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); EXPECT_EQ(STATUS_SUCCESS, freeCallbacksProvider(&pClientCallbacks)); + EXPECT_EQ(STATUS_NULL_ARG, freeStaticCredentialProvider(NULL)); EXPECT_EQ(STATUS_SUCCESS, freeStaticCredentialProvider(&pAwsCredentialProvider)); } } // namespace video diff --git a/tst/AwsCredentialsTest.cpp b/tst/AwsCredentialsTest.cpp index 4d7f8243..108776ac 100644 --- a/tst/AwsCredentialsTest.cpp +++ b/tst/AwsCredentialsTest.cpp @@ -237,6 +237,8 @@ TEST_F(AwsCredentialsTest, TestFileCredentialsWriteWithoutSession) { CHAR fileContent[10000]; UINT32 length = ARRAY_SIZE(fileContent); + EXPECT_EQ(STATUS_NULL_ARG, createFileCredentialProvider(TEST_FILE_CREDENTIALS_FILE_PATH, NULL)); + EXPECT_EQ(STATUS_INVALID_ARG, createFileCredentialProvider(EMPTY_STRING, &pAwsCredentialProvider)); // Store the credentials in a file under the current dir length = SNPRINTF(fileContent, length, "CREDENTIALS %s %s", mAccessKey, mSecretKey); ASSERT_GT(ARRAY_SIZE(fileContent), length); @@ -244,6 +246,7 @@ TEST_F(AwsCredentialsTest, TestFileCredentialsWriteWithoutSession) { // Create file creds provider from the file EXPECT_EQ(STATUS_SUCCESS, createFileCredentialProvider(TEST_FILE_CREDENTIALS_FILE_PATH, &pAwsCredentialProvider)); + EXPECT_EQ(STATUS_NULL_ARG, freeFileCredentialProvider(NULL)); EXPECT_EQ(STATUS_SUCCESS, freeFileCredentialProvider(&pAwsCredentialProvider)); } diff --git a/tst/AwsV4SignerTest.cpp b/tst/AwsV4SignerTest.cpp new file mode 100644 index 00000000..1969609e --- /dev/null +++ b/tst/AwsV4SignerTest.cpp @@ -0,0 +1,117 @@ +#include "ProducerTestFixture.h" +#include "src/source/Common/AwsV4Signer.h" + +namespace com { namespace amazonaws { namespace kinesis { namespace video { + +class AwsV4SignerTest : public ProducerClientTestBase { +}; + +TEST_F(AwsV4SignerTest, generateAwsSigV4SignatureApiInvalidTest) +{ + RequestInfo requestInfo; + PCHAR pSigningInfo; + UINT32 length; + EXPECT_EQ(STATUS_NULL_ARG, generateAwsSigV4Signature(NULL, NULL, TRUE, NULL, NULL)); + EXPECT_EQ(STATUS_NULL_ARG, generateAwsSigV4Signature(&requestInfo, NULL, TRUE, &pSigningInfo, NULL)); +} + +TEST_F(AwsV4SignerTest, signAwsRequestInfoQueryParamApiTest) +{ + RequestInfo requestInfo; + AwsCredentials awsCredentials; + // Initialize requestInfo and awsCredentials with default values + MEMSET(&requestInfo, 0, SIZEOF(requestInfo)); + MEMSET(&awsCredentials, 0, SIZEOF(awsCredentials)); + + // Set up default awsCredentials + awsCredentials.expiration = GETTIME() + 3600 * HUNDREDS_OF_NANOS_IN_A_SECOND; // 1 hour from now + + // Default setup for requestInfo + STRCPY(requestInfo.url, "https://kinesisvideo.us-west-2.amazonaws.com/describeStream?query=param"); + requestInfo.currentTime = GETTIME(); + requestInfo.pAwsCredentials = &awsCredentials; + EXPECT_EQ(STATUS_NULL_ARG, signAwsRequestInfoQueryParam(NULL)); + EXPECT_EQ(STATUS_SUCCESS, singleListCreate(&requestInfo.pRequestHeaders)); + EXPECT_EQ(STATUS_SUCCESS, signAwsRequestInfoQueryParam(&requestInfo)); + EXPECT_EQ(STATUS_SUCCESS, removeRequestHeaders(&requestInfo)); + EXPECT_EQ(STATUS_SUCCESS, singleListFree(requestInfo.pRequestHeaders)); +} + +TEST_F(AwsV4SignerTest, getCanonicalQueryParamsApiTest) +{ + PCHAR pQuery; + RequestInfo requestInfo; + EXPECT_EQ(STATUS_NULL_ARG, getCanonicalQueryParams(NULL, 0, TRUE, NULL, NULL)); + EXPECT_EQ(STATUS_NULL_ARG, getCanonicalQueryParams(requestInfo.url, STRLEN(requestInfo.url), TRUE, NULL, NULL)); + EXPECT_EQ(STATUS_NULL_ARG, getCanonicalQueryParams(requestInfo.url, STRLEN(requestInfo.url), TRUE, &pQuery, NULL)); +} + +TEST_F(AwsV4SignerTest, signAwsRequestInfoApiTest) +{ + RequestInfo requestInfo; + AwsCredentials awsCredentials; + UINT32 len; + // Initialize requestInfo and awsCredentials with default values + MEMSET(&requestInfo, 0, SIZEOF(requestInfo)); + MEMSET(&awsCredentials, 0, SIZEOF(awsCredentials)); + + // Set up default awsCredentials + awsCredentials.expiration = GETTIME() + 3600 * HUNDREDS_OF_NANOS_IN_A_SECOND; // 1 hour from now + // Default setup for requestInfo + STRCPY(requestInfo.url, "https://kinesisvideo.us-west-2.amazonaws.com/describeStream"); + requestInfo.currentTime = GETTIME(); + requestInfo.pAwsCredentials = &awsCredentials; + + EXPECT_EQ(STATUS_NULL_ARG, signAwsRequestInfo(NULL)); + EXPECT_EQ(STATUS_SUCCESS, singleListCreate(&requestInfo.pRequestHeaders)); + EXPECT_EQ(STATUS_SUCCESS, signAwsRequestInfo(&requestInfo)); + EXPECT_EQ(STATUS_SUCCESS, removeRequestHeaders(&requestInfo)); + EXPECT_EQ(STATUS_SUCCESS, singleListFree(requestInfo.pRequestHeaders)); +} + +TEST_F(AwsV4SignerTest, generateSignatureDateTimeApiTest) +{ + EXPECT_EQ(STATUS_NULL_ARG, generateSignatureDateTime(GETTIME(), NULL)); +} + +TEST_F(AwsV4SignerTest, uriDecodeStringApiTest) +{ + CHAR source[] = "Hello%20World%21"; + CHAR invalidSource[] = "Hello%2"; + CHAR destination[50]; + CHAR invalidSrcDest[50]; + CHAR smallDestination[5]; + UINT32 destLen = SIZEOF(destination); + UINT32 smallDestLen = SIZEOF(smallDestination); + UINT32 invalidSrcDestLen = SIZEOF(invalidSrcDest); + EXPECT_EQ(STATUS_SUCCESS, uriDecodeString(source, 0, destination, &destLen)); + EXPECT_STREQ("Hello World!", destination); + EXPECT_EQ(13U, destLen); // Includes null terminator + EXPECT_EQ(STATUS_NULL_ARG, uriDecodeString(NULL, 0, destination, &destLen)); + EXPECT_EQ(STATUS_NULL_ARG, uriDecodeString(source, STRLEN(source), destination, NULL)); + EXPECT_EQ(STATUS_BUFFER_TOO_SMALL, uriDecodeString(source, STRLEN(source), smallDestination, &smallDestLen)); + EXPECT_EQ(STATUS_INVALID_ARG, uriDecodeString(invalidSource, STRLEN(invalidSource), invalidSrcDest, &invalidSrcDestLen)); +} + +TEST_F(AwsV4SignerTest, uriEncodeStringApiTest) +{ + CHAR input[] = "$"; + CHAR outputInvalid[2] = {'\0'}; // Space required for 3 characters + '\0' . But reserved only for 2 + CHAR outputValid[4] = {'\0'}; + UINT32 outputInvalidLength = SIZEOF(outputInvalid); + UINT32 outputValidLength = SIZEOF(outputValid); + EXPECT_EQ(STATUS_NOT_ENOUGH_MEMORY, uriEncodeString(input, STRLEN(input), outputInvalid, &outputInvalidLength)); + EXPECT_EQ(STATUS_SUCCESS, uriEncodeString(input, STRLEN(input), outputValid, &outputValidLength)); +} +TEST_F(AwsV4SignerTest, getRequestVerbStringApiTest) +{ + EXPECT_STREQ(HTTP_REQUEST_VERB_PUT_STRING, getRequestVerbString(HTTP_REQUEST_VERB_PUT)); + EXPECT_STREQ(HTTP_REQUEST_VERB_GET_STRING, getRequestVerbString(HTTP_REQUEST_VERB_GET)); + EXPECT_STREQ(HTTP_REQUEST_VERB_POST_STRING, getRequestVerbString(HTTP_REQUEST_VERB_POST)); + EXPECT_EQ(NULL, getRequestVerbString((HTTP_REQUEST_VERB) 0xffff)); +} + +} // namespace video +} // namespace kinesis +} // namespace amazonaws +} // namespace com \ No newline at end of file diff --git a/tst/CMakeLists.txt b/tst/CMakeLists.txt index 50e3c738..ace3dde0 100644 --- a/tst/CMakeLists.txt +++ b/tst/CMakeLists.txt @@ -19,6 +19,14 @@ endif() include_directories(${KINESIS_VIDEO_PRODUCER_C_SRC}) file(GLOB PRODUCER_TEST_SOURCE_FILES "*.cpp") +file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/sample_file_creds.txt" DESTINATION .) add_executable(producer_test ${PRODUCER_TEST_SOURCE_FILES}) target_link_libraries(producer_test cproducer ${GTEST_LIBNAME}) + +if(BUILD_COMMON_LWS) + add_definitions(-DKVS_CA_CERT_PATH="${CMAKE_CURRENT_SOURCE_DIR}/cert.pem") + add_definitions(-DCMAKE_DETECTED_CACERT_PATH) + target_compile_definitions(producer_test PRIVATE KVS_BUILD_WITH_LWS) + target_link_libraries(producer_test kvsCommonLws ${GTEST_LIBNAME}) +endif() \ No newline at end of file diff --git a/tst/CallbacksProviderPublicApiTest.cpp b/tst/CallbacksProviderPublicApiTest.cpp index 7e214d24..22c2dd8b 100644 --- a/tst/CallbacksProviderPublicApiTest.cpp +++ b/tst/CallbacksProviderPublicApiTest.cpp @@ -639,6 +639,16 @@ TEST_F(CallbacksProviderPublicApiTest, createDefaultCallbacksProviderWithFileAut TEST_USER_AGENT, &pClientCallbacks)); EXPECT_EQ(NULL, pClientCallbacks); + + EXPECT_EQ(STATUS_SUCCESS, createDefaultCallbacksProviderWithFileAuth( + SAMPLE_AUTH_FILE_PATH, + (PCHAR) DEFAULT_AWS_REGION, + TEST_CA_CERT_PATH, + TEST_USER_AGENT_POSTFIX, + TEST_USER_AGENT, + &pClientCallbacks)); + + EXPECT_EQ(STATUS_SUCCESS, freeCallbacksProvider(&pClientCallbacks)); } TEST_F(CallbacksProviderPublicApiTest, createDefaultCallbacksProviderWithAuthCallbacks) diff --git a/tst/CurlApiTest.cpp b/tst/CurlApiTest.cpp new file mode 100644 index 00000000..3c06bd5a --- /dev/null +++ b/tst/CurlApiTest.cpp @@ -0,0 +1,39 @@ +#include "ProducerTestFixture.h" +#include "src/source/Response.h" + +namespace com { namespace amazonaws { namespace kinesis { namespace video { + +class CurlApiTest : public ProducerClientTestBase { +}; + + +TEST_F(CurlApiTest, createCurlRequestApiNullTest) +{ + CHAR url[MAX_URI_CHAR_LEN]; + CurlApiCallbacks curlApiCallbacks; + EXPECT_EQ(STATUS_NULL_ARG, createCurlRequest(HTTP_REQUEST_VERB_POST, NULL, NULL, INVALID_STREAM_HANDLE_VALUE, (PCHAR) DEFAULT_AWS_REGION, GETTIME(), + 3 * HUNDREDS_OF_NANOS_IN_A_SECOND, 5 * HUNDREDS_OF_NANOS_IN_A_SECOND, 5, NULL, NULL, + NULL, NULL)); + EXPECT_EQ(STATUS_NULL_ARG, createCurlRequest(HTTP_REQUEST_VERB_POST, url, NULL, INVALID_STREAM_HANDLE_VALUE, (PCHAR) DEFAULT_AWS_REGION, GETTIME(), + 3 * HUNDREDS_OF_NANOS_IN_A_SECOND, 5 * HUNDREDS_OF_NANOS_IN_A_SECOND, 5, NULL, NULL, + NULL, NULL)); + EXPECT_EQ(STATUS_NULL_ARG, createCurlRequest(HTTP_REQUEST_VERB_POST, url, NULL, INVALID_STREAM_HANDLE_VALUE, (PCHAR) DEFAULT_AWS_REGION, GETTIME(), + 3 * HUNDREDS_OF_NANOS_IN_A_SECOND, 5 * HUNDREDS_OF_NANOS_IN_A_SECOND, 5, NULL, NULL, + &curlApiCallbacks, NULL)); +} + +TEST_F(CurlApiTest, getServiceCallResultFromCurlStatusApiTest) +{ + EXPECT_EQ(SERVICE_CALL_RESULT_OK, getServiceCallResultFromCurlStatus(CURLE_OK)); + EXPECT_EQ(SERVICE_CALL_INVALID_ARG, getServiceCallResultFromCurlStatus(CURLE_UNSUPPORTED_PROTOCOL)); + EXPECT_EQ(SERVICE_CALL_NETWORK_CONNECTION_TIMEOUT, getServiceCallResultFromCurlStatus(CURLE_OPERATION_TIMEDOUT)); + EXPECT_EQ(SERVICE_CALL_NOT_AUTHORIZED, getServiceCallResultFromCurlStatus(CURLE_SSL_CERTPROBLEM)); + EXPECT_EQ(SERVICE_CALL_NOT_AUTHORIZED, getServiceCallResultFromCurlStatus(CURLE_SSL_CACERT)); + EXPECT_EQ(SERVICE_CALL_UNKNOWN, getServiceCallResultFromCurlStatus((CURLcode) 0xffff)); +} + + +} // namespace video +} // namespace kinesis +} // namespace amazonaws +} // namespace com; \ No newline at end of file diff --git a/tst/InfoProviderApiTest.cpp b/tst/InfoProviderApiTest.cpp index 262aa904..3c0facca 100644 --- a/tst/InfoProviderApiTest.cpp +++ b/tst/InfoProviderApiTest.cpp @@ -2,325 +2,452 @@ namespace com { namespace amazonaws { namespace kinesis { namespace video { - class InfoProviderApiTest : public ProducerClientTestBase { - }; +class InfoProviderApiTest : public ProducerClientTestBase { +}; - TEST_F(InfoProviderApiTest, CreateDefaultDeviceInfo_Returns_Success) - { - PDeviceInfo pDeviceInfo; - - EXPECT_EQ(STATUS_SUCCESS, createDefaultDeviceInfo(&pDeviceInfo)); - - EXPECT_EQ(STATUS_SUCCESS, setDeviceInfoStorageSize(pDeviceInfo, MAX_STORAGE_ALLOCATION_SIZE)); - - EXPECT_EQ(STATUS_INVALID_STORAGE_SIZE, setDeviceInfoStorageSize(pDeviceInfo, MAX_STORAGE_ALLOCATION_SIZE + 1)); - - EXPECT_TRUE(pDeviceInfo->clientInfo.loggerLogLevel == this->loggerLogLevel); - - // 500 Kbps with 2 sec duration - EXPECT_EQ(STATUS_SUCCESS, - setDeviceInfoStorageSizeBasedOnBitrateAndBufferDuration(pDeviceInfo, - 500 * 1000 * 8, - 2 * HUNDREDS_OF_NANOS_IN_A_SECOND)); - // 500 Kbps with 10 sec duration - EXPECT_EQ(STATUS_SUCCESS, - setDeviceInfoStorageSizeBasedOnBitrateAndBufferDuration(pDeviceInfo, - 500 * 1000 * 8, - 10 * HUNDREDS_OF_NANOS_IN_A_SECOND)); - // 1000 Kbps with 10 sec duration - EXPECT_EQ(STATUS_SUCCESS, - setDeviceInfoStorageSizeBasedOnBitrateAndBufferDuration(pDeviceInfo, - 1000 * 1000 * 8, - 10 * HUNDREDS_OF_NANOS_IN_A_SECOND)); - - EXPECT_EQ(STATUS_INVALID_ARG, - setDeviceInfoStorageSizeBasedOnBitrateAndBufferDuration(pDeviceInfo, - 0, - 0 * HUNDREDS_OF_NANOS_IN_A_SECOND)); - - EXPECT_EQ(STATUS_NULL_ARG, - setDeviceInfoStorageSizeBasedOnBitrateAndBufferDuration(NULL, - 0, - 0 * HUNDREDS_OF_NANOS_IN_A_SECOND)); - - EXPECT_EQ(STATUS_NULL_ARG, createDefaultDeviceInfo(NULL)); - - EXPECT_EQ(STATUS_NULL_ARG, setDeviceInfoStorageSize(NULL, MAX_STORAGE_ALLOCATION_SIZE)); - - EXPECT_EQ(STATUS_SUCCESS, freeDeviceInfo(&pDeviceInfo)); +TEST_F(InfoProviderApiTest, CreateDefaultDeviceInfo_Returns_Success) +{ + PDeviceInfo pDeviceInfo; + EXPECT_EQ(STATUS_SUCCESS, createDefaultDeviceInfo(&pDeviceInfo)); + EXPECT_EQ(STATUS_SUCCESS, setDeviceInfoStorageSize(pDeviceInfo, MAX_STORAGE_ALLOCATION_SIZE)); + EXPECT_EQ(STATUS_INVALID_STORAGE_SIZE, setDeviceInfoStorageSize(pDeviceInfo, MAX_STORAGE_ALLOCATION_SIZE + 1)); + EXPECT_TRUE(pDeviceInfo->clientInfo.loggerLogLevel == this->loggerLogLevel); + // 500 Kbps with 2 sec duration + EXPECT_EQ(STATUS_SUCCESS,setDeviceInfoStorageSizeBasedOnBitrateAndBufferDuration(pDeviceInfo, 500 * 1000 * 8, 2 * HUNDREDS_OF_NANOS_IN_A_SECOND)); + // 500 Kbps with 10 sec duration + EXPECT_EQ(STATUS_SUCCESS, setDeviceInfoStorageSizeBasedOnBitrateAndBufferDuration(pDeviceInfo, 500 * 1000 * 8, 10 * HUNDREDS_OF_NANOS_IN_A_SECOND)); + // 1000 Kbps with 10 sec duration + EXPECT_EQ(STATUS_SUCCESS, setDeviceInfoStorageSizeBasedOnBitrateAndBufferDuration(pDeviceInfo, 1000 * 1000 * 8, 10 * HUNDREDS_OF_NANOS_IN_A_SECOND)); + EXPECT_EQ(STATUS_INVALID_ARG, setDeviceInfoStorageSizeBasedOnBitrateAndBufferDuration(pDeviceInfo, 0, 0 * HUNDREDS_OF_NANOS_IN_A_SECOND)); + EXPECT_EQ(STATUS_NULL_ARG, setDeviceInfoStorageSizeBasedOnBitrateAndBufferDuration(NULL, 0, 0 * HUNDREDS_OF_NANOS_IN_A_SECOND)); + EXPECT_EQ(STATUS_NULL_ARG, createDefaultDeviceInfo(NULL)); + EXPECT_EQ(STATUS_NULL_ARG, setDeviceInfoStorageSize(NULL, MAX_STORAGE_ALLOCATION_SIZE)); + EXPECT_EQ(STATUS_SUCCESS, freeDeviceInfo(&pDeviceInfo)); + EXPECT_EQ(NULL, pDeviceInfo); + EXPECT_EQ(STATUS_SUCCESS, freeDeviceInfo(&pDeviceInfo)); + EXPECT_EQ(STATUS_NULL_ARG, freeDeviceInfo(NULL)); +} - EXPECT_EQ(NULL, pDeviceInfo); +TEST_F(InfoProviderApiTest, CreateOfflineVideoStreamInfoProvider_Returns_ValidVideoStreamInfo) +{ + PStreamInfo pStreamInfo; + EXPECT_EQ(STATUS_SUCCESS, createOfflineVideoStreamInfoProvider(TEST_STREAM_NAME, TEST_RETENTION_PERIOD, TEST_STREAM_BUFFER_DURATION, &pStreamInfo)); - EXPECT_EQ(STATUS_SUCCESS, freeDeviceInfo(&pDeviceInfo)); + EXPECT_EQ(FRAME_ORDER_MODE_PASS_THROUGH, pStreamInfo->streamCaps.frameOrderingMode); + EXPECT_EQ(MKV_TRACK_INFO_TYPE_VIDEO, pStreamInfo->streamCaps.trackInfoList->trackType); + EXPECT_EQ(STREAMING_TYPE_OFFLINE, pStreamInfo->streamCaps.streamingType); + EXPECT_NE(0, pStreamInfo->retention); + EXPECT_EQ(1, pStreamInfo->streamCaps.trackInfoCount); + EXPECT_EQ(TRUE, pStreamInfo->streamCaps.absoluteFragmentTimes); + EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); + EXPECT_EQ(STATUS_NULL_ARG, createOfflineVideoStreamInfoProvider(NULL, TEST_RETENTION_PERIOD, TEST_STREAM_BUFFER_DURATION, &pStreamInfo)); + EXPECT_EQ(STATUS_SUCCESS, createOfflineVideoStreamInfoProvider(EMPTY_STRING, TEST_RETENTION_PERIOD, TEST_STREAM_BUFFER_DURATION, &pStreamInfo)); + EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); - EXPECT_EQ(STATUS_NULL_ARG, freeDeviceInfo(NULL)); + EXPECT_EQ(STATUS_INVALID_ARG, createOfflineVideoStreamInfoProvider(TEST_STREAM_NAME, 0, TEST_STREAM_BUFFER_DURATION, &pStreamInfo)); - } + EXPECT_EQ(STATUS_INVALID_ARG, createOfflineVideoStreamInfoProvider(TEST_STREAM_NAME, TEST_RETENTION_PERIOD, 0, &pStreamInfo)); + EXPECT_EQ(STATUS_NULL_ARG, createOfflineVideoStreamInfoProvider(TEST_STREAM_NAME, TEST_RETENTION_PERIOD, TEST_STREAM_BUFFER_DURATION, NULL)); - TEST_F(InfoProviderApiTest, CreateOfflineVideoStreamInfoProvider_Returns_ValidVideoStreamInfo) - { - PStreamInfo pStreamInfo; + EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); - EXPECT_EQ(STATUS_SUCCESS, - createOfflineVideoStreamInfoProvider(TEST_STREAM_NAME, - TEST_RETENTION_PERIOD, - TEST_STREAM_BUFFER_DURATION, - &pStreamInfo)); + EXPECT_EQ(NULL, pStreamInfo); + EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); - EXPECT_EQ(FRAME_ORDER_MODE_PASS_THROUGH, pStreamInfo->streamCaps.frameOrderingMode); - EXPECT_EQ(MKV_TRACK_INFO_TYPE_VIDEO, pStreamInfo->streamCaps.trackInfoList->trackType); - EXPECT_EQ(STREAMING_TYPE_OFFLINE, pStreamInfo->streamCaps.streamingType); - EXPECT_NE(0, pStreamInfo->retention); - EXPECT_EQ(1, pStreamInfo->streamCaps.trackInfoCount); - EXPECT_EQ(TRUE, pStreamInfo->streamCaps.absoluteFragmentTimes); + EXPECT_EQ(STATUS_NULL_ARG, freeStreamInfoProvider(NULL)); +} - EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); +TEST_F(InfoProviderApiTest, CreateRealTimeVideoStreamInfoProvider_Returns_ValidVideoStreamInfo) +{ + PStreamInfo pStreamInfo; - EXPECT_EQ(STATUS_NULL_ARG, - createOfflineVideoStreamInfoProvider(NULL, - TEST_RETENTION_PERIOD, - TEST_STREAM_BUFFER_DURATION, - &pStreamInfo)); + EXPECT_EQ(STATUS_SUCCESS, createRealtimeVideoStreamInfoProvider(TEST_STREAM_NAME, TEST_RETENTION_PERIOD, TEST_STREAM_BUFFER_DURATION, &pStreamInfo)); - EXPECT_EQ(STATUS_SUCCESS, - createOfflineVideoStreamInfoProvider(EMPTY_STRING, - TEST_RETENTION_PERIOD, - TEST_STREAM_BUFFER_DURATION, - &pStreamInfo)); + EXPECT_EQ(FRAME_ORDER_MODE_PASS_THROUGH, pStreamInfo->streamCaps.frameOrderingMode); + EXPECT_EQ(1, pStreamInfo->streamCaps.trackInfoCount); + EXPECT_EQ(STREAMING_TYPE_REALTIME, pStreamInfo->streamCaps.streamingType); + EXPECT_EQ(MKV_TRACK_INFO_TYPE_VIDEO, pStreamInfo->streamCaps.trackInfoList[0].trackType); - EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); + EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); + EXPECT_EQ(STATUS_NULL_ARG, createRealtimeVideoStreamInfoProvider(NULL, TEST_RETENTION_PERIOD,TEST_STREAM_BUFFER_DURATION, &pStreamInfo)); - EXPECT_EQ(STATUS_INVALID_ARG, - createOfflineVideoStreamInfoProvider(TEST_STREAM_NAME, - 0, - TEST_STREAM_BUFFER_DURATION, - &pStreamInfo)); + EXPECT_EQ(STATUS_SUCCESS, createRealtimeVideoStreamInfoProvider(EMPTY_STRING, TEST_RETENTION_PERIOD, TEST_STREAM_BUFFER_DURATION, &pStreamInfo)); - EXPECT_EQ(STATUS_INVALID_ARG, - createOfflineVideoStreamInfoProvider(TEST_STREAM_NAME, - TEST_RETENTION_PERIOD, - 0, - &pStreamInfo)); + EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); + EXPECT_EQ(STATUS_SUCCESS, createRealtimeVideoStreamInfoProvider(TEST_STREAM_NAME, 0, TEST_STREAM_BUFFER_DURATION, &pStreamInfo)); - EXPECT_EQ(STATUS_NULL_ARG, - createOfflineVideoStreamInfoProvider(TEST_STREAM_NAME, - TEST_RETENTION_PERIOD, - TEST_STREAM_BUFFER_DURATION, - NULL)); + EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); + EXPECT_EQ(STATUS_NULL_ARG, createRealtimeVideoStreamInfoProvider(TEST_STREAM_NAME, TEST_RETENTION_PERIOD, TEST_STREAM_BUFFER_DURATION, NULL)); - EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); + EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); - EXPECT_EQ(NULL, pStreamInfo); + EXPECT_EQ(NULL, pStreamInfo); - EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); + EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); - EXPECT_EQ(STATUS_NULL_ARG, freeStreamInfoProvider(NULL)); + EXPECT_EQ(STATUS_NULL_ARG, freeStreamInfoProvider(NULL)); - } +} - TEST_F(InfoProviderApiTest, CreateRealTimeVideoStreamInfoProvider_Returns_ValidVideoStreamInfo) - { - PStreamInfo pStreamInfo; +TEST_F(InfoProviderApiTest, CreateRealTimeAudioVideoStreamInfoProvider_Returns_ValidVideoStreamInfo) +{ + PStreamInfo pStreamInfo; - EXPECT_EQ(STATUS_SUCCESS, - createRealtimeVideoStreamInfoProvider(TEST_STREAM_NAME, - TEST_RETENTION_PERIOD, - TEST_STREAM_BUFFER_DURATION, - &pStreamInfo)); + EXPECT_EQ(STATUS_SUCCESS, createRealtimeAudioVideoStreamInfoProvider(TEST_STREAM_NAME, TEST_RETENTION_PERIOD, TEST_STREAM_BUFFER_DURATION, &pStreamInfo)); - EXPECT_EQ(FRAME_ORDER_MODE_PASS_THROUGH, pStreamInfo->streamCaps.frameOrderingMode); - EXPECT_EQ(1, pStreamInfo->streamCaps.trackInfoCount); - EXPECT_EQ(STREAMING_TYPE_REALTIME, pStreamInfo->streamCaps.streamingType); - EXPECT_EQ(MKV_TRACK_INFO_TYPE_VIDEO, pStreamInfo->streamCaps.trackInfoList[0].trackType); + EXPECT_EQ(FRAME_ORDERING_MODE_MULTI_TRACK_AV_COMPARE_PTS_ONE_MS_COMPENSATE_EOFR, pStreamInfo->streamCaps.frameOrderingMode); + EXPECT_EQ(2, pStreamInfo->streamCaps.trackInfoCount); + EXPECT_EQ(STREAMING_TYPE_REALTIME, pStreamInfo->streamCaps.streamingType); + EXPECT_EQ(MKV_TRACK_INFO_TYPE_VIDEO, pStreamInfo->streamCaps.trackInfoList[0].trackType); + EXPECT_EQ(MKV_TRACK_INFO_TYPE_AUDIO, pStreamInfo->streamCaps.trackInfoList[1].trackType); - EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); + EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); + EXPECT_EQ(STATUS_NULL_ARG, freeStreamInfoProvider(NULL)); + EXPECT_EQ(STATUS_NULL_ARG, createRealtimeAudioVideoStreamInfoProvider(NULL, TEST_RETENTION_PERIOD, TEST_STREAM_BUFFER_DURATION, &pStreamInfo)); - EXPECT_EQ(STATUS_NULL_ARG, - createRealtimeVideoStreamInfoProvider(NULL, - TEST_RETENTION_PERIOD, - TEST_STREAM_BUFFER_DURATION, - &pStreamInfo)); + EXPECT_EQ(STATUS_SUCCESS, createRealtimeAudioVideoStreamInfoProvider(EMPTY_STRING, TEST_RETENTION_PERIOD, TEST_STREAM_BUFFER_DURATION, &pStreamInfo)); - EXPECT_EQ(STATUS_SUCCESS, - createRealtimeVideoStreamInfoProvider(EMPTY_STRING, - TEST_RETENTION_PERIOD, - TEST_STREAM_BUFFER_DURATION, - &pStreamInfo)); + EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); + EXPECT_EQ(STATUS_SUCCESS, createRealtimeAudioVideoStreamInfoProvider(TEST_STREAM_NAME, 0, TEST_STREAM_BUFFER_DURATION, &pStreamInfo)); - EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); + EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); - EXPECT_EQ(STATUS_SUCCESS, - createRealtimeVideoStreamInfoProvider(TEST_STREAM_NAME, - 0, - TEST_STREAM_BUFFER_DURATION, - &pStreamInfo)); + EXPECT_EQ(STATUS_NULL_ARG, createRealtimeAudioVideoStreamInfoProvider(TEST_STREAM_NAME, TEST_RETENTION_PERIOD, TEST_STREAM_BUFFER_DURATION, NULL)); - EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); + EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); + EXPECT_EQ(NULL, pStreamInfo); - EXPECT_EQ(STATUS_NULL_ARG, - createRealtimeVideoStreamInfoProvider(TEST_STREAM_NAME, - TEST_RETENTION_PERIOD, - TEST_STREAM_BUFFER_DURATION, - NULL)); + EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); - EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); + EXPECT_EQ(STATUS_NULL_ARG, freeStreamInfoProvider(NULL)); +} - EXPECT_EQ(NULL, pStreamInfo); +TEST_F(InfoProviderApiTest, setStreamInfoBasedOnStorageSizeApiTest) +{ + PStreamInfo pStreamInfo; - EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); + EXPECT_EQ(STATUS_SUCCESS, createRealtimeVideoStreamInfoProvider(TEST_STREAM_NAME, TEST_RETENTION_PERIOD, TEST_STREAM_BUFFER_DURATION, &pStreamInfo)); - EXPECT_EQ(STATUS_NULL_ARG, freeStreamInfoProvider(NULL)); + EXPECT_EQ(STATUS_INVALID_ARG, setStreamInfoBasedOnStorageSize(0, 1000000, 1, pStreamInfo)); + EXPECT_EQ(STATUS_INVALID_ARG, setStreamInfoBasedOnStorageSize(2 * 1024 * 1024, 0, 1, pStreamInfo)); + EXPECT_EQ(STATUS_INVALID_ARG, setStreamInfoBasedOnStorageSize(2 * 1024 * 1024, 1000000, 0, pStreamInfo)); + EXPECT_EQ(STATUS_NULL_ARG, setStreamInfoBasedOnStorageSize(2 * 1024 * 1024, 1000000, 1, NULL)); - } + EXPECT_EQ(STATUS_SUCCESS, setStreamInfoBasedOnStorageSize(2 * 1024 * 1024, 1000000, 1, pStreamInfo)); + EXPECT_TRUE(pStreamInfo->streamCaps.bufferDuration != TEST_STREAM_BUFFER_DURATION); - TEST_F(InfoProviderApiTest, CreateRealTimeAudioVideoStreamInfoProvider_Returns_ValidVideoStreamInfo) - { - PStreamInfo pStreamInfo; + EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); +} - EXPECT_EQ(STATUS_SUCCESS, - createRealtimeAudioVideoStreamInfoProvider(TEST_STREAM_NAME, - TEST_RETENTION_PERIOD, - TEST_STREAM_BUFFER_DURATION, - &pStreamInfo)); +TEST_F(InfoProviderApiTest, CreateOfflineAudioVideoStreamInfoProvider_Returns_ValidVideoStreamInfo) +{ + PStreamInfo pStreamInfo; - EXPECT_EQ(FRAME_ORDERING_MODE_MULTI_TRACK_AV_COMPARE_PTS_ONE_MS_COMPENSATE_EOFR, pStreamInfo->streamCaps.frameOrderingMode); - EXPECT_EQ(2, pStreamInfo->streamCaps.trackInfoCount); - EXPECT_EQ(STREAMING_TYPE_REALTIME, pStreamInfo->streamCaps.streamingType); - EXPECT_EQ(MKV_TRACK_INFO_TYPE_VIDEO, pStreamInfo->streamCaps.trackInfoList[0].trackType); - EXPECT_EQ(MKV_TRACK_INFO_TYPE_AUDIO, pStreamInfo->streamCaps.trackInfoList[1].trackType); + EXPECT_EQ(STATUS_SUCCESS, createOfflineAudioVideoStreamInfoProvider(TEST_STREAM_NAME, TEST_RETENTION_PERIOD,TEST_STREAM_BUFFER_DURATION, &pStreamInfo)); - EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); - EXPECT_EQ(STATUS_NULL_ARG, freeStreamInfoProvider(NULL)); + EXPECT_EQ(FRAME_ORDERING_MODE_MULTI_TRACK_AV_COMPARE_PTS_ONE_MS_COMPENSATE_EOFR, pStreamInfo->streamCaps.frameOrderingMode); + EXPECT_EQ(2, pStreamInfo->streamCaps.trackInfoCount); + EXPECT_EQ(STREAMING_TYPE_OFFLINE, pStreamInfo->streamCaps.streamingType); + EXPECT_EQ(MKV_TRACK_INFO_TYPE_VIDEO, pStreamInfo->streamCaps.trackInfoList[0].trackType); + EXPECT_EQ(MKV_TRACK_INFO_TYPE_AUDIO, pStreamInfo->streamCaps.trackInfoList[1].trackType); - EXPECT_EQ(STATUS_NULL_ARG, - createRealtimeAudioVideoStreamInfoProvider(NULL, - TEST_RETENTION_PERIOD, - TEST_STREAM_BUFFER_DURATION, - &pStreamInfo)); + EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); - EXPECT_EQ(STATUS_SUCCESS, - createRealtimeAudioVideoStreamInfoProvider(EMPTY_STRING, - TEST_RETENTION_PERIOD, - TEST_STREAM_BUFFER_DURATION, - &pStreamInfo)); + EXPECT_EQ(STATUS_NULL_ARG, createOfflineAudioVideoStreamInfoProvider(NULL, TEST_RETENTION_PERIOD, TEST_STREAM_BUFFER_DURATION, &pStreamInfo)); - EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); + EXPECT_EQ(STATUS_SUCCESS, createOfflineAudioVideoStreamInfoProvider(EMPTY_STRING, TEST_RETENTION_PERIOD, TEST_STREAM_BUFFER_DURATION, &pStreamInfo)); + EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); - EXPECT_EQ(STATUS_SUCCESS, - createRealtimeAudioVideoStreamInfoProvider(TEST_STREAM_NAME, - 0, - TEST_STREAM_BUFFER_DURATION, - &pStreamInfo)); + EXPECT_EQ(STATUS_INVALID_ARG, createOfflineAudioVideoStreamInfoProvider(TEST_STREAM_NAME, 0, TEST_STREAM_BUFFER_DURATION, &pStreamInfo)); - EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); + EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); - EXPECT_EQ(STATUS_NULL_ARG, - createRealtimeAudioVideoStreamInfoProvider(TEST_STREAM_NAME, - TEST_RETENTION_PERIOD, - TEST_STREAM_BUFFER_DURATION, - NULL)); + EXPECT_EQ(STATUS_NULL_ARG, createOfflineAudioVideoStreamInfoProvider(TEST_STREAM_NAME, TEST_RETENTION_PERIOD, TEST_STREAM_BUFFER_DURATION, NULL)); - EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); + EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); - EXPECT_EQ(NULL, pStreamInfo); + EXPECT_EQ(NULL, pStreamInfo); - EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); - - EXPECT_EQ(STATUS_NULL_ARG, freeStreamInfoProvider(NULL)); + EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); + EXPECT_EQ(STATUS_NULL_ARG, freeStreamInfoProvider(NULL)); +} +TEST_F(InfoProviderApiTest, CreateStream_Returns_Success) +{ + PStreamCallbacks pStreamCallbacks; + EXPECT_EQ(STATUS_SUCCESS, createStreamCallbacks(&pStreamCallbacks)); + EXPECT_EQ(STATUS_SUCCESS, freeStreamCallbacks(&pStreamCallbacks)); + EXPECT_EQ(NULL, pStreamCallbacks); + EXPECT_EQ(STATUS_SUCCESS, freeStreamCallbacks(&pStreamCallbacks)); + EXPECT_EQ(STATUS_NULL_ARG, createStreamCallbacks(NULL)); } - TEST_F(InfoProviderApiTest, setStreamInfoBasedOnStorageSizeApiTest) { - PStreamInfo pStreamInfo; - - EXPECT_EQ(STATUS_SUCCESS, - createRealtimeVideoStreamInfoProvider(TEST_STREAM_NAME, - TEST_RETENTION_PERIOD, - TEST_STREAM_BUFFER_DURATION, - &pStreamInfo)); - - EXPECT_EQ(STATUS_INVALID_ARG, setStreamInfoBasedOnStorageSize(0, 1000000, 1, pStreamInfo)); - EXPECT_EQ(STATUS_INVALID_ARG, setStreamInfoBasedOnStorageSize(2 * 1024 * 1024, 0, 1, pStreamInfo)); - EXPECT_EQ(STATUS_INVALID_ARG, setStreamInfoBasedOnStorageSize(2 * 1024 * 1024, 1000000, 0, pStreamInfo)); - EXPECT_EQ(STATUS_NULL_ARG, setStreamInfoBasedOnStorageSize(2 * 1024 * 1024, 1000000, 1, NULL)); - - EXPECT_EQ(STATUS_SUCCESS, setStreamInfoBasedOnStorageSize(2 * 1024 * 1024, 1000000, 1, pStreamInfo)); - EXPECT_TRUE(pStreamInfo->streamCaps.bufferDuration != TEST_STREAM_BUFFER_DURATION); - - EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); - } - - TEST_F(InfoProviderApiTest, CreateOfflineAudioVideoStreamInfoProvider_Returns_ValidVideoStreamInfo) + TEST_F(InfoProviderApiTest, createRealtimeVideoStreamInfoProviderWithCodecsApiTest) { - PStreamInfo pStreamInfo; - - EXPECT_EQ(STATUS_SUCCESS, - createOfflineAudioVideoStreamInfoProvider(TEST_STREAM_NAME, - TEST_RETENTION_PERIOD, - TEST_STREAM_BUFFER_DURATION, - &pStreamInfo)); - - EXPECT_EQ(FRAME_ORDERING_MODE_MULTI_TRACK_AV_COMPARE_PTS_ONE_MS_COMPENSATE_EOFR, pStreamInfo->streamCaps.frameOrderingMode); - EXPECT_EQ(2, pStreamInfo->streamCaps.trackInfoCount); - EXPECT_EQ(STREAMING_TYPE_OFFLINE, pStreamInfo->streamCaps.streamingType); - EXPECT_EQ(MKV_TRACK_INFO_TYPE_VIDEO, pStreamInfo->streamCaps.trackInfoList[0].trackType); - EXPECT_EQ(MKV_TRACK_INFO_TYPE_AUDIO, pStreamInfo->streamCaps.trackInfoList[1].trackType); - - EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); - - EXPECT_EQ(STATUS_NULL_ARG, - createOfflineAudioVideoStreamInfoProvider(NULL, - TEST_RETENTION_PERIOD, - TEST_STREAM_BUFFER_DURATION, - &pStreamInfo)); - - EXPECT_EQ(STATUS_SUCCESS, - createOfflineAudioVideoStreamInfoProvider(EMPTY_STRING, - TEST_RETENTION_PERIOD, - TEST_STREAM_BUFFER_DURATION, - &pStreamInfo)); - - EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); - - EXPECT_EQ(STATUS_INVALID_ARG, - createOfflineAudioVideoStreamInfoProvider(TEST_STREAM_NAME, - 0, - TEST_STREAM_BUFFER_DURATION, - &pStreamInfo)); - - EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); - - EXPECT_EQ(STATUS_NULL_ARG, - createOfflineAudioVideoStreamInfoProvider(TEST_STREAM_NAME, - TEST_RETENTION_PERIOD, - TEST_STREAM_BUFFER_DURATION, - NULL)); - - EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); - - EXPECT_EQ(NULL, pStreamInfo); - - EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); - - EXPECT_EQ(STATUS_NULL_ARG, freeStreamInfoProvider(NULL)); + PStreamInfo pStreamInfo; + EXPECT_EQ(STATUS_NULL_ARG, createRealtimeVideoStreamInfoProviderWithCodecs(TEST_STREAM_NAME, TEST_RETENTION_PERIOD,TEST_STREAM_BUFFER_DURATION, VIDEO_CODEC_ID_H264, NULL)); + EXPECT_EQ(STATUS_NULL_ARG, createRealtimeVideoStreamInfoProviderWithCodecs(NULL, TEST_RETENTION_PERIOD,TEST_STREAM_BUFFER_DURATION, VIDEO_CODEC_ID_H264, NULL)); + + // H264 + EXPECT_EQ(STATUS_SUCCESS, createRealtimeVideoStreamInfoProviderWithCodecs(TEST_STREAM_NAME, TEST_RETENTION_PERIOD,TEST_STREAM_BUFFER_DURATION, VIDEO_CODEC_ID_H264, &pStreamInfo)); + EXPECT_EQ(STREAMING_TYPE_REALTIME, pStreamInfo->streamCaps.streamingType); + EXPECT_STREQ(MKV_H264_CONTENT_TYPE, pStreamInfo->streamCaps.contentType); + EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); + EXPECT_EQ(NULL, pStreamInfo); + + // H265 + EXPECT_EQ(STATUS_SUCCESS, createRealtimeVideoStreamInfoProviderWithCodecs(TEST_STREAM_NAME, TEST_RETENTION_PERIOD,TEST_STREAM_BUFFER_DURATION, VIDEO_CODEC_ID_H265, &pStreamInfo)); + EXPECT_EQ(STREAMING_TYPE_REALTIME, pStreamInfo->streamCaps.streamingType); + EXPECT_STREQ(MKV_H265_CONTENT_TYPE, pStreamInfo->streamCaps.contentType); + EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); + EXPECT_EQ(NULL, pStreamInfo); + + // default + EXPECT_EQ(STATUS_SUCCESS, createRealtimeVideoStreamInfoProviderWithCodecs(TEST_STREAM_NAME, TEST_RETENTION_PERIOD,TEST_STREAM_BUFFER_DURATION, (VIDEO_CODEC_ID) 0xffff, &pStreamInfo)); + EXPECT_EQ(STREAMING_TYPE_REALTIME, pStreamInfo->streamCaps.streamingType); + EXPECT_STREQ(MKV_H264_CONTENT_TYPE, pStreamInfo->streamCaps.contentType); + EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); + EXPECT_EQ(NULL, pStreamInfo); } - TEST_F(InfoProviderApiTest, CreateStream_Returns_Success) + TEST_F(InfoProviderApiTest, createOfflineVideoStreamInfoProviderWithCodecsApiTest) { - PStreamCallbacks pStreamCallbacks; - - EXPECT_EQ(STATUS_SUCCESS, createStreamCallbacks(&pStreamCallbacks)); + PStreamInfo pStreamInfo; + EXPECT_EQ(STATUS_NULL_ARG, createOfflineVideoStreamInfoProviderWithCodecs(TEST_STREAM_NAME, TEST_RETENTION_PERIOD,TEST_STREAM_BUFFER_DURATION, VIDEO_CODEC_ID_H264, NULL)); + EXPECT_EQ(STATUS_NULL_ARG, createOfflineVideoStreamInfoProviderWithCodecs(NULL, TEST_RETENTION_PERIOD,TEST_STREAM_BUFFER_DURATION, VIDEO_CODEC_ID_H264, NULL)); + + // H264 + EXPECT_EQ(STATUS_SUCCESS, createOfflineVideoStreamInfoProviderWithCodecs(TEST_STREAM_NAME, TEST_RETENTION_PERIOD,TEST_STREAM_BUFFER_DURATION, VIDEO_CODEC_ID_H264, &pStreamInfo)); + EXPECT_EQ(STREAMING_TYPE_OFFLINE, pStreamInfo->streamCaps.streamingType); + EXPECT_STREQ(MKV_H264_CONTENT_TYPE, pStreamInfo->streamCaps.contentType); + EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); + EXPECT_EQ(NULL, pStreamInfo); + + // H265 + EXPECT_EQ(STATUS_SUCCESS, createOfflineVideoStreamInfoProviderWithCodecs(TEST_STREAM_NAME, TEST_RETENTION_PERIOD,TEST_STREAM_BUFFER_DURATION, VIDEO_CODEC_ID_H265, &pStreamInfo)); + EXPECT_EQ(STREAMING_TYPE_OFFLINE, pStreamInfo->streamCaps.streamingType); + EXPECT_STREQ(MKV_H265_CONTENT_TYPE, pStreamInfo->streamCaps.contentType); + EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); + EXPECT_EQ(NULL, pStreamInfo); + + // default + EXPECT_EQ(STATUS_SUCCESS, createOfflineVideoStreamInfoProviderWithCodecs(TEST_STREAM_NAME, TEST_RETENTION_PERIOD,TEST_STREAM_BUFFER_DURATION, (VIDEO_CODEC_ID) 0xffff, &pStreamInfo)); + EXPECT_EQ(STREAMING_TYPE_OFFLINE, pStreamInfo->streamCaps.streamingType); + EXPECT_STREQ(MKV_H264_CONTENT_TYPE, pStreamInfo->streamCaps.contentType); + EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); + EXPECT_EQ(NULL, pStreamInfo); +} + +TEST_F(InfoProviderApiTest, createRealtimeAudioVideoStreamInfoProviderWithCodecsApiTest) +{ + PStreamInfo pStreamInfo; + CHAR expectedContentType[MAX_CONTENT_TYPE_LEN + 1] = {"\0"}; + EXPECT_EQ(STATUS_NULL_ARG, createRealtimeAudioVideoStreamInfoProviderWithCodecs(TEST_STREAM_NAME, TEST_RETENTION_PERIOD,TEST_STREAM_BUFFER_DURATION, VIDEO_CODEC_ID_H264, AUDIO_CODEC_ID_AAC, NULL)); + EXPECT_EQ(STATUS_NULL_ARG, createRealtimeAudioVideoStreamInfoProviderWithCodecs(NULL, TEST_RETENTION_PERIOD,TEST_STREAM_BUFFER_DURATION, VIDEO_CODEC_ID_H264, AUDIO_CODEC_ID_AAC, NULL)); + + // H264, AAC + EXPECT_EQ(STATUS_SUCCESS, createRealtimeAudioVideoStreamInfoProviderWithCodecs(TEST_STREAM_NAME, TEST_RETENTION_PERIOD,TEST_STREAM_BUFFER_DURATION, VIDEO_CODEC_ID_H264, AUDIO_CODEC_ID_AAC, &pStreamInfo)); + EXPECT_EQ(STREAMING_TYPE_REALTIME, pStreamInfo->streamCaps.streamingType); + SNPRINTF(expectedContentType, SIZEOF(expectedContentType), "%s,%s", MKV_H264_CONTENT_TYPE, MKV_AAC_CONTENT_TYPE); + EXPECT_STREQ(expectedContentType, pStreamInfo->streamCaps.contentType); + EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); + EXPECT_EQ(NULL, pStreamInfo); + MEMSET(expectedContentType, '\0', SIZEOF(expectedContentType)); + + // H264, PCM ALAW + EXPECT_EQ(STATUS_SUCCESS, createRealtimeAudioVideoStreamInfoProviderWithCodecs(TEST_STREAM_NAME, TEST_RETENTION_PERIOD,TEST_STREAM_BUFFER_DURATION, VIDEO_CODEC_ID_H264, AUDIO_CODEC_ID_PCM_ALAW, &pStreamInfo)); + EXPECT_EQ(STREAMING_TYPE_REALTIME, pStreamInfo->streamCaps.streamingType); + SNPRINTF(expectedContentType, SIZEOF(expectedContentType), "%s,%s", MKV_H264_CONTENT_TYPE, MKV_ALAW_CONTENT_TYPE); + EXPECT_STREQ(expectedContentType, pStreamInfo->streamCaps.contentType); + EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); + EXPECT_EQ(NULL, pStreamInfo); + MEMSET(expectedContentType, '\0', SIZEOF(expectedContentType)); + + // H264, MULAW + EXPECT_EQ(STATUS_SUCCESS, createRealtimeAudioVideoStreamInfoProviderWithCodecs(TEST_STREAM_NAME, TEST_RETENTION_PERIOD,TEST_STREAM_BUFFER_DURATION, VIDEO_CODEC_ID_H264, AUDIO_CODEC_ID_PCM_MULAW, &pStreamInfo)); + EXPECT_EQ(STREAMING_TYPE_REALTIME, pStreamInfo->streamCaps.streamingType); + SNPRINTF(expectedContentType, SIZEOF(expectedContentType), "%s,%s", MKV_H264_CONTENT_TYPE, MKV_MULAW_CONTENT_TYPE); + EXPECT_STREQ(expectedContentType, pStreamInfo->streamCaps.contentType); + EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); + EXPECT_EQ(NULL, pStreamInfo); + + + // H265, AAC + EXPECT_EQ(STATUS_SUCCESS, createRealtimeAudioVideoStreamInfoProviderWithCodecs(TEST_STREAM_NAME, TEST_RETENTION_PERIOD,TEST_STREAM_BUFFER_DURATION, VIDEO_CODEC_ID_H265, AUDIO_CODEC_ID_AAC, &pStreamInfo)); + EXPECT_EQ(STREAMING_TYPE_REALTIME, pStreamInfo->streamCaps.streamingType); + SNPRINTF(expectedContentType, SIZEOF(expectedContentType), "%s,%s", MKV_H265_CONTENT_TYPE, MKV_AAC_CONTENT_TYPE); + EXPECT_STREQ(expectedContentType, pStreamInfo->streamCaps.contentType); + EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); + EXPECT_EQ(NULL, pStreamInfo); + MEMSET(expectedContentType, '\0', SIZEOF(expectedContentType)); + + // H265, PCM ALAW + EXPECT_EQ(STATUS_SUCCESS, createRealtimeAudioVideoStreamInfoProviderWithCodecs(TEST_STREAM_NAME, TEST_RETENTION_PERIOD,TEST_STREAM_BUFFER_DURATION, VIDEO_CODEC_ID_H265, AUDIO_CODEC_ID_PCM_ALAW, &pStreamInfo)); + EXPECT_EQ(STREAMING_TYPE_REALTIME, pStreamInfo->streamCaps.streamingType); + SNPRINTF(expectedContentType, SIZEOF(expectedContentType), "%s,%s", MKV_H265_CONTENT_TYPE, MKV_ALAW_CONTENT_TYPE); + EXPECT_STREQ(expectedContentType, pStreamInfo->streamCaps.contentType); + EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); + EXPECT_EQ(NULL, pStreamInfo); + MEMSET(expectedContentType, '\0', SIZEOF(expectedContentType)); + + // H265, MULAW + EXPECT_EQ(STATUS_SUCCESS, createRealtimeAudioVideoStreamInfoProviderWithCodecs(TEST_STREAM_NAME, TEST_RETENTION_PERIOD,TEST_STREAM_BUFFER_DURATION, VIDEO_CODEC_ID_H265, AUDIO_CODEC_ID_PCM_MULAW, &pStreamInfo)); + EXPECT_EQ(STREAMING_TYPE_REALTIME, pStreamInfo->streamCaps.streamingType); + SNPRINTF(expectedContentType, SIZEOF(expectedContentType), "%s,%s", MKV_H265_CONTENT_TYPE, MKV_MULAW_CONTENT_TYPE); + EXPECT_STREQ(expectedContentType, pStreamInfo->streamCaps.contentType); + EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); + EXPECT_EQ(NULL, pStreamInfo); + + // Default + EXPECT_EQ(STATUS_SUCCESS, createRealtimeAudioVideoStreamInfoProviderWithCodecs(TEST_STREAM_NAME, TEST_RETENTION_PERIOD,TEST_STREAM_BUFFER_DURATION, (VIDEO_CODEC_ID) 0xffff, (AUDIO_CODEC_ID) 0xffff, &pStreamInfo)); + EXPECT_EQ(STREAMING_TYPE_REALTIME, pStreamInfo->streamCaps.streamingType); + SNPRINTF(expectedContentType, SIZEOF(expectedContentType), "%s,%s", MKV_H264_CONTENT_TYPE, MKV_AAC_CONTENT_TYPE); + EXPECT_STREQ(expectedContentType, pStreamInfo->streamCaps.contentType); + EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); + EXPECT_EQ(NULL, pStreamInfo); + +} + +TEST_F(InfoProviderApiTest, createOfflineAudioVideoStreamInfoProviderWithCodecsApiTest) +{ + PStreamInfo pStreamInfo; + CHAR expectedContentType[MAX_CONTENT_TYPE_LEN + 1] = {"\0"}; + EXPECT_EQ(STATUS_NULL_ARG, createOfflineAudioVideoStreamInfoProviderWithCodecs(TEST_STREAM_NAME, TEST_RETENTION_PERIOD,TEST_STREAM_BUFFER_DURATION, VIDEO_CODEC_ID_H264, AUDIO_CODEC_ID_AAC, NULL)); + EXPECT_EQ(STATUS_NULL_ARG, createOfflineAudioVideoStreamInfoProviderWithCodecs(NULL, TEST_RETENTION_PERIOD,TEST_STREAM_BUFFER_DURATION, VIDEO_CODEC_ID_H264, AUDIO_CODEC_ID_AAC, NULL)); + + // H264, AAC + EXPECT_EQ(STATUS_SUCCESS, createOfflineAudioVideoStreamInfoProviderWithCodecs(TEST_STREAM_NAME, TEST_RETENTION_PERIOD,TEST_STREAM_BUFFER_DURATION, VIDEO_CODEC_ID_H264, AUDIO_CODEC_ID_AAC, &pStreamInfo)); + EXPECT_EQ(STREAMING_TYPE_OFFLINE, pStreamInfo->streamCaps.streamingType); + SNPRINTF(expectedContentType, SIZEOF(expectedContentType), "%s,%s", MKV_H264_CONTENT_TYPE, MKV_AAC_CONTENT_TYPE); + EXPECT_STREQ(expectedContentType, pStreamInfo->streamCaps.contentType); + EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); + EXPECT_EQ(NULL, pStreamInfo); + MEMSET(expectedContentType, '\0', SIZEOF(expectedContentType)); + + // H264, PCM ALAW + EXPECT_EQ(STATUS_SUCCESS, createOfflineAudioVideoStreamInfoProviderWithCodecs(TEST_STREAM_NAME, TEST_RETENTION_PERIOD,TEST_STREAM_BUFFER_DURATION, VIDEO_CODEC_ID_H264, AUDIO_CODEC_ID_PCM_ALAW, &pStreamInfo)); + EXPECT_EQ(STREAMING_TYPE_OFFLINE, pStreamInfo->streamCaps.streamingType); + SNPRINTF(expectedContentType, SIZEOF(expectedContentType), "%s,%s", MKV_H264_CONTENT_TYPE, MKV_ALAW_CONTENT_TYPE); + EXPECT_STREQ(expectedContentType, pStreamInfo->streamCaps.contentType); + EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); + EXPECT_EQ(NULL, pStreamInfo); + MEMSET(expectedContentType, '\0', SIZEOF(expectedContentType)); + + // H264, MULAW + EXPECT_EQ(STATUS_SUCCESS, createOfflineAudioVideoStreamInfoProviderWithCodecs(TEST_STREAM_NAME, TEST_RETENTION_PERIOD,TEST_STREAM_BUFFER_DURATION, VIDEO_CODEC_ID_H264, AUDIO_CODEC_ID_PCM_MULAW, &pStreamInfo)); + EXPECT_EQ(STREAMING_TYPE_OFFLINE, pStreamInfo->streamCaps.streamingType); + SNPRINTF(expectedContentType, SIZEOF(expectedContentType), "%s,%s", MKV_H264_CONTENT_TYPE, MKV_MULAW_CONTENT_TYPE); + EXPECT_STREQ(expectedContentType, pStreamInfo->streamCaps.contentType); + EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); + EXPECT_EQ(NULL, pStreamInfo); + + + // H265, AAC + EXPECT_EQ(STATUS_SUCCESS, createOfflineAudioVideoStreamInfoProviderWithCodecs(TEST_STREAM_NAME, TEST_RETENTION_PERIOD,TEST_STREAM_BUFFER_DURATION, VIDEO_CODEC_ID_H265, AUDIO_CODEC_ID_AAC, &pStreamInfo)); + EXPECT_EQ(STREAMING_TYPE_OFFLINE, pStreamInfo->streamCaps.streamingType); + SNPRINTF(expectedContentType, SIZEOF(expectedContentType), "%s,%s", MKV_H265_CONTENT_TYPE, MKV_AAC_CONTENT_TYPE); + EXPECT_STREQ(expectedContentType, pStreamInfo->streamCaps.contentType); + EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); + EXPECT_EQ(NULL, pStreamInfo); + MEMSET(expectedContentType, '\0', SIZEOF(expectedContentType)); + + // H265, PCM ALAW + EXPECT_EQ(STATUS_SUCCESS, createOfflineAudioVideoStreamInfoProviderWithCodecs(TEST_STREAM_NAME, TEST_RETENTION_PERIOD,TEST_STREAM_BUFFER_DURATION, VIDEO_CODEC_ID_H265, AUDIO_CODEC_ID_PCM_ALAW, &pStreamInfo)); + EXPECT_EQ(STREAMING_TYPE_OFFLINE, pStreamInfo->streamCaps.streamingType); + SNPRINTF(expectedContentType, SIZEOF(expectedContentType), "%s,%s", MKV_H265_CONTENT_TYPE, MKV_ALAW_CONTENT_TYPE); + EXPECT_STREQ(expectedContentType, pStreamInfo->streamCaps.contentType); + EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); + EXPECT_EQ(NULL, pStreamInfo); + MEMSET(expectedContentType, '\0', SIZEOF(expectedContentType)); + + // H265, MULAW + EXPECT_EQ(STATUS_SUCCESS, createOfflineAudioVideoStreamInfoProviderWithCodecs(TEST_STREAM_NAME, TEST_RETENTION_PERIOD,TEST_STREAM_BUFFER_DURATION, VIDEO_CODEC_ID_H265, AUDIO_CODEC_ID_PCM_MULAW, &pStreamInfo)); + EXPECT_EQ(STREAMING_TYPE_OFFLINE, pStreamInfo->streamCaps.streamingType); + SNPRINTF(expectedContentType, SIZEOF(expectedContentType), "%s,%s", MKV_H265_CONTENT_TYPE, MKV_MULAW_CONTENT_TYPE); + EXPECT_STREQ(expectedContentType, pStreamInfo->streamCaps.contentType); + EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); + EXPECT_EQ(NULL, pStreamInfo); + + // Default + EXPECT_EQ(STATUS_SUCCESS, createOfflineAudioVideoStreamInfoProviderWithCodecs(TEST_STREAM_NAME, TEST_RETENTION_PERIOD,TEST_STREAM_BUFFER_DURATION, (VIDEO_CODEC_ID) 0xffff, (AUDIO_CODEC_ID) 0xffff, &pStreamInfo)); + EXPECT_EQ(STREAMING_TYPE_OFFLINE, pStreamInfo->streamCaps.streamingType); + SNPRINTF(expectedContentType, SIZEOF(expectedContentType), "%s,%s", MKV_H264_CONTENT_TYPE, MKV_AAC_CONTENT_TYPE); + EXPECT_STREQ(expectedContentType, pStreamInfo->streamCaps.contentType); + EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); + EXPECT_EQ(NULL, pStreamInfo); +} + +TEST_F(InfoProviderApiTest, createRealtimeAudioStreamInfoProviderWithCodecsApiTest) +{ + PStreamInfo pStreamInfo; + EXPECT_EQ(STATUS_NULL_ARG, createRealtimeAudioStreamInfoProviderWithCodecs(TEST_STREAM_NAME, TEST_RETENTION_PERIOD,TEST_STREAM_BUFFER_DURATION, AUDIO_CODEC_ID_PCM_ALAW, NULL)); + EXPECT_EQ(STATUS_NULL_ARG, createRealtimeAudioStreamInfoProviderWithCodecs(NULL, TEST_RETENTION_PERIOD,TEST_STREAM_BUFFER_DURATION, AUDIO_CODEC_ID_PCM_ALAW, NULL)); + + // AAC + EXPECT_EQ(STATUS_SUCCESS, createRealtimeAudioStreamInfoProviderWithCodecs(TEST_STREAM_NAME, TEST_RETENTION_PERIOD,TEST_STREAM_BUFFER_DURATION, AUDIO_CODEC_ID_AAC, &pStreamInfo)); + EXPECT_EQ(STREAMING_TYPE_REALTIME, pStreamInfo->streamCaps.streamingType); + EXPECT_STREQ(MKV_AAC_CONTENT_TYPE, pStreamInfo->streamCaps.contentType); + EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); + EXPECT_EQ(NULL, pStreamInfo); + + // PCM A LAW + EXPECT_EQ(STATUS_SUCCESS, createRealtimeAudioStreamInfoProviderWithCodecs(TEST_STREAM_NAME, TEST_RETENTION_PERIOD,TEST_STREAM_BUFFER_DURATION, AUDIO_CODEC_ID_PCM_ALAW, &pStreamInfo)); + EXPECT_EQ(STREAMING_TYPE_REALTIME, pStreamInfo->streamCaps.streamingType); + EXPECT_STREQ(MKV_ALAW_CONTENT_TYPE, pStreamInfo->streamCaps.contentType); + EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); + EXPECT_EQ(NULL, pStreamInfo); + + // PCM MULAW + EXPECT_EQ(STATUS_SUCCESS, createRealtimeAudioStreamInfoProviderWithCodecs(TEST_STREAM_NAME, TEST_RETENTION_PERIOD,TEST_STREAM_BUFFER_DURATION, AUDIO_CODEC_ID_PCM_MULAW, &pStreamInfo)); + EXPECT_EQ(STREAMING_TYPE_REALTIME, pStreamInfo->streamCaps.streamingType); + EXPECT_STREQ(MKV_MULAW_CONTENT_TYPE, pStreamInfo->streamCaps.contentType); + EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); + EXPECT_EQ(NULL, pStreamInfo); + + // default + EXPECT_EQ(STATUS_SUCCESS, createRealtimeAudioStreamInfoProviderWithCodecs(TEST_STREAM_NAME, TEST_RETENTION_PERIOD,TEST_STREAM_BUFFER_DURATION, (AUDIO_CODEC_ID) 0xffff, &pStreamInfo)); + EXPECT_EQ(STREAMING_TYPE_REALTIME, pStreamInfo->streamCaps.streamingType); + EXPECT_STREQ(MKV_AAC_CONTENT_TYPE, pStreamInfo->streamCaps.contentType); + EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); + EXPECT_EQ(NULL, pStreamInfo); +} + +TEST_F(InfoProviderApiTest, createOfflineAudioStreamInfoProviderWithCodecsApiTest) +{ + PStreamInfo pStreamInfo; + EXPECT_EQ(STATUS_NULL_ARG, createOfflineAudioStreamInfoProviderWithCodecs(TEST_STREAM_NAME, TEST_RETENTION_PERIOD,TEST_STREAM_BUFFER_DURATION, AUDIO_CODEC_ID_PCM_ALAW, NULL)); + EXPECT_EQ(STATUS_NULL_ARG, createOfflineAudioStreamInfoProviderWithCodecs(NULL, TEST_RETENTION_PERIOD,TEST_STREAM_BUFFER_DURATION, AUDIO_CODEC_ID_PCM_ALAW, NULL)); + + // AAC + EXPECT_EQ(STATUS_SUCCESS, createOfflineAudioStreamInfoProviderWithCodecs(TEST_STREAM_NAME, TEST_RETENTION_PERIOD,TEST_STREAM_BUFFER_DURATION, AUDIO_CODEC_ID_AAC, &pStreamInfo)); + EXPECT_EQ(STREAMING_TYPE_OFFLINE, pStreamInfo->streamCaps.streamingType); + EXPECT_STREQ(MKV_AAC_CONTENT_TYPE, pStreamInfo->streamCaps.contentType); + EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); + EXPECT_EQ(NULL, pStreamInfo); + + // PCM A LAW + EXPECT_EQ(STATUS_SUCCESS, createOfflineAudioStreamInfoProviderWithCodecs(TEST_STREAM_NAME, TEST_RETENTION_PERIOD,TEST_STREAM_BUFFER_DURATION, AUDIO_CODEC_ID_PCM_ALAW, &pStreamInfo)); + EXPECT_EQ(STREAMING_TYPE_OFFLINE, pStreamInfo->streamCaps.streamingType); + EXPECT_STREQ(MKV_ALAW_CONTENT_TYPE, pStreamInfo->streamCaps.contentType); + EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); + EXPECT_EQ(NULL, pStreamInfo); + + // PCM MULAW + EXPECT_EQ(STATUS_SUCCESS, createOfflineAudioStreamInfoProviderWithCodecs(TEST_STREAM_NAME, TEST_RETENTION_PERIOD,TEST_STREAM_BUFFER_DURATION, AUDIO_CODEC_ID_PCM_MULAW, &pStreamInfo)); + EXPECT_EQ(STREAMING_TYPE_OFFLINE, pStreamInfo->streamCaps.streamingType); + EXPECT_STREQ(MKV_MULAW_CONTENT_TYPE, pStreamInfo->streamCaps.contentType); + EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); + EXPECT_EQ(NULL, pStreamInfo); + + // default + EXPECT_EQ(STATUS_SUCCESS, createOfflineAudioStreamInfoProviderWithCodecs(TEST_STREAM_NAME, TEST_RETENTION_PERIOD,TEST_STREAM_BUFFER_DURATION, (AUDIO_CODEC_ID) 0xffff, &pStreamInfo)); + EXPECT_EQ(STREAMING_TYPE_OFFLINE, pStreamInfo->streamCaps.streamingType); + EXPECT_STREQ(MKV_AAC_CONTENT_TYPE, pStreamInfo->streamCaps.contentType); + EXPECT_EQ(STATUS_SUCCESS, freeStreamInfoProvider(&pStreamInfo)); + EXPECT_EQ(NULL, pStreamInfo); +} - EXPECT_EQ(STATUS_SUCCESS, freeStreamCallbacks(&pStreamCallbacks)); - - EXPECT_EQ(NULL, pStreamCallbacks); - - EXPECT_EQ(STATUS_SUCCESS, freeStreamCallbacks(&pStreamCallbacks)); - - EXPECT_EQ(STATUS_NULL_ARG, createStreamCallbacks(NULL)); - } } // namespace video } // namespace kinesis } // namespace amazonaws } // namespace com; - diff --git a/tst/IoTCredentialTest.cpp b/tst/IoTCredentialTest.cpp new file mode 100644 index 00000000..dc52608f --- /dev/null +++ b/tst/IoTCredentialTest.cpp @@ -0,0 +1,311 @@ +#include "ProducerTestFixture.h" +#include "src/source/Common/IotCredentialProvider.h" + +namespace com { namespace amazonaws { namespace kinesis { namespace video { + +class IoTCredentialTest : public ProducerClientTestBase { +}; + +TEST_F(IoTCredentialTest, createDefaultCallbacksProviderWithIotCertificateValidEndpoint) +{ + PClientCallbacks pClientCallbacks; + PCHAR iotCoreCredentialEndPoint = NULL; + PCHAR iotCoreCert = NULL; + PCHAR iotCorePrivateKey = NULL; + PCHAR iotCoreRoleAlias = NULL; + PCHAR iotThingName = NULL; + EXPECT_TRUE((iotCoreCredentialEndPoint = GETENV(AWS_IOT_CORE_CREDENTIAL_ENDPOINT_ENV_VAR)) != NULL); + EXPECT_TRUE((iotCoreCert = GETENV(AWS_IOT_CORE_CERT_ENV_VAR)) != NULL); + EXPECT_TRUE((iotCorePrivateKey = GETENV(AWS_IOT_CORE_PRIVATE_KEY_ENV_VAR)) != NULL); + EXPECT_TRUE((iotCoreRoleAlias = GETENV(AWS_IOT_CORE_ROLE_ALIAS_ENV_VAR)) != NULL); + EXPECT_TRUE((iotThingName = GETENV(AWS_IOT_CORE_THING_NAME_ENV_VAR)) != NULL); + + EXPECT_EQ(STATUS_SUCCESS, createDefaultCallbacksProviderWithIotCertificate( + iotCoreCredentialEndPoint, + iotCoreCert, + iotCorePrivateKey, + NULL, + iotCoreRoleAlias, + iotThingName, + (PCHAR) DEFAULT_AWS_REGION, + NULL, + NULL, + &pClientCallbacks)); + EXPECT_EQ(STATUS_SUCCESS, freeCallbacksProvider(&pClientCallbacks)); +} + +TEST_F(IoTCredentialTest, createDefaultCallbacksProviderWithIotCertificateAndTimeoutsValidEndpoint) +{ + PClientCallbacks pClientCallbacks; + PCHAR iotCoreCredentialEndPoint = NULL; + PCHAR iotCoreCert = NULL; + PCHAR iotCorePrivateKey = NULL; + PCHAR iotCoreRoleAlias = NULL; + PCHAR iotThingName = NULL; + EXPECT_TRUE((iotCoreCredentialEndPoint = GETENV(AWS_IOT_CORE_CREDENTIAL_ENDPOINT_ENV_VAR)) != NULL); + EXPECT_TRUE((iotCoreCert = GETENV(AWS_IOT_CORE_CERT_ENV_VAR)) != NULL); + EXPECT_TRUE((iotCorePrivateKey = GETENV(AWS_IOT_CORE_PRIVATE_KEY_ENV_VAR)) != NULL); + EXPECT_TRUE((iotCoreRoleAlias = GETENV(AWS_IOT_CORE_ROLE_ALIAS_ENV_VAR)) != NULL); + EXPECT_TRUE((iotThingName = GETENV(AWS_IOT_CORE_THING_NAME_ENV_VAR)) != NULL); + + EXPECT_EQ(STATUS_SUCCESS, createDefaultCallbacksProviderWithIotCertificateAndTimeouts( + iotCoreCredentialEndPoint, + iotCoreCert, + iotCorePrivateKey, + NULL, + iotCoreRoleAlias, + iotThingName, + (PCHAR) DEFAULT_AWS_REGION, + NULL, + NULL, + 5 * HUNDREDS_OF_NANOS_IN_A_SECOND, + 10 * HUNDREDS_OF_NANOS_IN_A_SECOND, + &pClientCallbacks)); + EXPECT_EQ(STATUS_SUCCESS, freeCallbacksProvider(&pClientCallbacks)); +} + +TEST_F(IoTCredentialTest, createCurlIotCredentialProviderApiTest) +{ + PAwsCredentialProvider pCredentialProvider = NULL; + PCHAR iotCoreCredentialEndPoint; + PCHAR iotCoreCert; + PCHAR iotCorePrivateKey; + PCHAR iotCoreRoleAlias; + PCHAR iotThingName; + + EXPECT_EQ(STATUS_NULL_ARG, createCurlIotCredentialProvider(NULL, + iotCoreCert, + iotCorePrivateKey, + NULL, + iotCoreRoleAlias, + iotThingName, + &pCredentialProvider)); + EXPECT_EQ(STATUS_NULL_ARG, createCurlIotCredentialProvider(NULL, + NULL, + iotCorePrivateKey, + NULL, + iotCoreRoleAlias, + iotThingName, + &pCredentialProvider)); + EXPECT_EQ(STATUS_NULL_ARG, createCurlIotCredentialProvider(NULL, + NULL, + NULL, + NULL, + iotCoreRoleAlias, + iotThingName, + &pCredentialProvider)); + EXPECT_EQ(STATUS_NULL_ARG, createCurlIotCredentialProvider(NULL, + NULL, + NULL, + NULL, + NULL, + iotThingName, + &pCredentialProvider)); + EXPECT_EQ(STATUS_NULL_ARG, createCurlIotCredentialProvider(NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + &pCredentialProvider)); + EXPECT_EQ(STATUS_NULL_ARG, createCurlIotCredentialProvider(NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL)); + EXPECT_EQ(STATUS_NULL_ARG, createCurlIotCredentialProvider(NULL, + iotCoreCert, + iotCorePrivateKey, + NULL, + iotCoreRoleAlias, + iotThingName, + &pCredentialProvider)); + +} + + +TEST_F(IoTCredentialTest, createCurlIotCredentialProviderWithTimeAndTimeoutApiTest) { + PAwsCredentialProvider pCredentialProvider = NULL; + PCHAR iotCoreCredentialEndPoint = NULL; + PCHAR iotCoreCert = NULL; + PCHAR iotCorePrivateKey = NULL; + PCHAR iotCoreRoleAlias = NULL; + PCHAR iotThingName = NULL; + + EXPECT_TRUE((iotCoreCredentialEndPoint = GETENV(AWS_IOT_CORE_CREDENTIAL_ENDPOINT_ENV_VAR)) != NULL); + EXPECT_TRUE((iotCoreCert = GETENV(AWS_IOT_CORE_CERT_ENV_VAR)) != NULL); + EXPECT_TRUE((iotCorePrivateKey = GETENV(AWS_IOT_CORE_PRIVATE_KEY_ENV_VAR)) != NULL); + EXPECT_TRUE((iotCoreRoleAlias = GETENV(AWS_IOT_CORE_ROLE_ALIAS_ENV_VAR)) != NULL); + EXPECT_TRUE((iotThingName = GETENV(AWS_IOT_CORE_THING_NAME_ENV_VAR)) != NULL); + + EXPECT_EQ(STATUS_SUCCESS, createCurlIotCredentialProviderWithTimeAndTimeout(iotCoreCredentialEndPoint, iotCoreCert, + iotCorePrivateKey, NULL, + iotCoreRoleAlias, + iotThingName, + 10 * HUNDREDS_OF_NANOS_IN_A_SECOND, + 5 * HUNDREDS_OF_NANOS_IN_A_SECOND, NULL, + 0, + &pCredentialProvider) + ); + EXPECT_EQ(IOT_REQUEST_CONNECTION_TIMEOUT, reinterpret_cast(pCredentialProvider)->connectionTimeout); + EXPECT_EQ(IOT_REQUEST_COMPLETION_TIMEOUT, reinterpret_cast(pCredentialProvider)->completionTimeout); + EXPECT_EQ(STATUS_SUCCESS, freeIotCredentialProvider(&pCredentialProvider)); +} + +#ifdef KVS_BUILD_WITH_LWS +TEST_F(IoTCredentialTest, createLwsIotCredentialProviderApiTest) { + PAwsCredentialProvider pCredentialProvider; + PCHAR iotCoreCredentialEndPoint; + PCHAR iotCoreCert; + PCHAR iotCorePrivateKey; + PCHAR iotCoreRoleAlias; + PCHAR iotThingName; + CHAR invalidCredentialEndpointLength[MAX_URI_CHAR_LEN + 2]; + CHAR invalidRoleAliasLength[MAX_ROLE_ALIAS_LEN + 2]; + CHAR invalidPrivateKeyPathLength[MAX_PATH_LEN + 2]; + CHAR invalidCaCertPathLength[MAX_PATH_LEN + 2]; + CHAR invalidCoreCertPathLength[MAX_PATH_LEN + 2]; + CHAR invalidThingNameLength[MAX_IOT_THING_NAME_LEN + 2]; + + EXPECT_EQ(STATUS_NULL_ARG, createLwsIotCredentialProvider(NULL, + iotCoreCert, + iotCorePrivateKey, + (PCHAR) DEFAULT_KVS_CACERT_PATH, + iotCoreRoleAlias, + iotThingName, + &pCredentialProvider)); + + EXPECT_EQ(STATUS_NULL_ARG, createLwsIotCredentialProvider(NULL, + NULL, + iotCorePrivateKey, + (PCHAR) DEFAULT_KVS_CACERT_PATH, + iotCoreRoleAlias, + iotThingName, + &pCredentialProvider)); + + EXPECT_EQ(STATUS_NULL_ARG, createLwsIotCredentialProvider(NULL, + NULL, + iotCorePrivateKey, + (PCHAR) DEFAULT_KVS_CACERT_PATH, + iotCoreRoleAlias, + iotThingName, + &pCredentialProvider)); + + EXPECT_EQ(STATUS_NULL_ARG, createLwsIotCredentialProvider(NULL, + NULL, + NULL, + (PCHAR) DEFAULT_KVS_CACERT_PATH, + iotCoreRoleAlias, + iotThingName, + &pCredentialProvider)); + + EXPECT_EQ(STATUS_NULL_ARG, createLwsIotCredentialProvider(NULL, + NULL, + NULL, + NULL, + iotCoreRoleAlias, + iotThingName, + &pCredentialProvider)); + + EXPECT_EQ(STATUS_NULL_ARG, createLwsIotCredentialProvider(NULL, + NULL, + NULL, + NULL, + NULL, + iotThingName, + &pCredentialProvider)); + + EXPECT_EQ(STATUS_NULL_ARG, createLwsIotCredentialProvider(NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + &pCredentialProvider)); + + EXPECT_EQ(STATUS_NULL_ARG, createLwsIotCredentialProvider(NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL)); + + EXPECT_TRUE((iotCoreCredentialEndPoint = GETENV(AWS_IOT_CORE_CREDENTIAL_ENDPOINT_ENV_VAR)) != NULL); + EXPECT_TRUE((iotCoreCert = GETENV(AWS_IOT_CORE_CERT_ENV_VAR)) != NULL); + EXPECT_TRUE((iotCorePrivateKey = GETENV(AWS_IOT_CORE_PRIVATE_KEY_ENV_VAR)) != NULL); + EXPECT_TRUE((iotCoreRoleAlias = GETENV(AWS_IOT_CORE_ROLE_ALIAS_ENV_VAR)) != NULL); + EXPECT_TRUE((iotThingName = GETENV(AWS_IOT_CORE_THING_NAME_ENV_VAR)) != NULL); + MEMSET(invalidCredentialEndpointLength, 'a', SIZEOF(invalidCredentialEndpointLength)); + MEMSET(invalidRoleAliasLength, 'b', SIZEOF(invalidRoleAliasLength)); + MEMSET(invalidPrivateKeyPathLength, 'c', SIZEOF(invalidPrivateKeyPathLength)); + MEMSET(invalidCaCertPathLength, 'd', SIZEOF(invalidCaCertPathLength)); + MEMSET(invalidCoreCertPathLength, 'e', SIZEOF(invalidCoreCertPathLength)); + MEMSET(invalidThingNameLength, 'f', SIZEOF(invalidThingNameLength)); + + EXPECT_EQ(STATUS_INVALID_ARG, createLwsIotCredentialProvider(invalidCredentialEndpointLength, + iotCoreCert, + iotCorePrivateKey, + (PCHAR) DEFAULT_KVS_CACERT_PATH, + iotCoreRoleAlias, + iotThingName, + &pCredentialProvider)); + EXPECT_EQ(STATUS_MAX_ROLE_ALIAS_LEN_EXCEEDED, createLwsIotCredentialProvider(iotCoreCredentialEndPoint, + iotCoreCert, + iotCorePrivateKey, + (PCHAR) DEFAULT_KVS_CACERT_PATH, + invalidRoleAliasLength, + iotThingName, + &pCredentialProvider)); + EXPECT_EQ(STATUS_PATH_TOO_LONG, createLwsIotCredentialProvider(iotCoreCredentialEndPoint, + iotCoreCert, + invalidPrivateKeyPathLength, + (PCHAR) DEFAULT_KVS_CACERT_PATH, + iotCoreRoleAlias, + iotThingName, + &pCredentialProvider)); + EXPECT_EQ(STATUS_PATH_TOO_LONG, createLwsIotCredentialProvider(iotCoreCredentialEndPoint, + iotCoreCert, + invalidPrivateKeyPathLength, + (PCHAR) DEFAULT_KVS_CACERT_PATH, + iotCoreRoleAlias, + iotThingName, + &pCredentialProvider)); + EXPECT_EQ(STATUS_PATH_TOO_LONG, createLwsIotCredentialProvider(iotCoreCredentialEndPoint, + iotCoreCert, + iotCorePrivateKey, + invalidCaCertPathLength, + iotCoreRoleAlias, + iotThingName, + &pCredentialProvider)); + EXPECT_EQ(STATUS_PATH_TOO_LONG, createLwsIotCredentialProvider(iotCoreCredentialEndPoint, + invalidCoreCertPathLength, + iotCorePrivateKey, + (PCHAR) DEFAULT_KVS_CACERT_PATH, + iotCoreRoleAlias, + iotThingName, + &pCredentialProvider)); + EXPECT_EQ(STATUS_MAX_IOT_THING_NAME_LENGTH, createLwsIotCredentialProvider(iotCoreCredentialEndPoint, + iotCoreCert, + iotCorePrivateKey, + (PCHAR) DEFAULT_KVS_CACERT_PATH, + iotCoreRoleAlias, + invalidThingNameLength, + &pCredentialProvider)); + EXPECT_EQ(STATUS_SUCCESS, createLwsIotCredentialProvider(iotCoreCredentialEndPoint, + iotCoreCert, + iotCorePrivateKey, + (PCHAR) DEFAULT_KVS_CACERT_PATH, + iotCoreRoleAlias, + iotThingName, + &pCredentialProvider)); + EXPECT_EQ(STATUS_SUCCESS, freeIotCredentialProvider(&pCredentialProvider)); +} +#endif + +} // namespace video +} // namespace kinesis +} // namespace amazonaws +} // namespace com \ No newline at end of file diff --git a/tst/PlatformCallbackProviderApiTest.cpp b/tst/PlatformCallbackProviderApiTest.cpp index 68c6dfa8..519ad13b 100644 --- a/tst/PlatformCallbackProviderApiTest.cpp +++ b/tst/PlatformCallbackProviderApiTest.cpp @@ -45,7 +45,7 @@ namespace com { namespace amazonaws { namespace kinesis { namespace video { TRUE, &pClientCallbacks)); - setPlatformCallbacks(pClientCallbacks, &platformCallbacks); + EXPECT_EQ(STATUS_SUCCESS, setPlatformCallbacks(pClientCallbacks, &platformCallbacks)); EXPECT_TRUE(broadcastConditionVariableAggregate != pClientCallbacks->broadcastConditionVariableFn); @@ -56,15 +56,67 @@ namespace com { namespace amazonaws { namespace kinesis { namespace video { EXPECT_TRUE(getCurrentTimeAggregate != pClientCallbacks->getCurrentTimeFn); EXPECT_TRUE(getRandomNumberAggregate != pClientCallbacks->getRandomNumberFn); EXPECT_TRUE(lockMutexAggregate != pClientCallbacks->lockMutexFn); + EXPECT_TRUE(tryLockMutexAggregate != pClientCallbacks->tryLockMutexFn); EXPECT_TRUE(signalConditionVariableAggregate != pClientCallbacks->signalConditionVariableFn); EXPECT_TRUE(unlockMutexAggregate != pClientCallbacks->unlockMutexFn); - EXPECT_TRUE(unlockMutexAggregate != pClientCallbacks->unlockMutexFn); + EXPECT_TRUE(broadcastConditionVariableAggregate != pClientCallbacks->broadcastConditionVariableFn); EXPECT_TRUE(waitConditionVariableAggregate != pClientCallbacks->waitConditionVariableFn); //non-null callback definition should return aggregated platform callback - platformCallbacks.getCurrentTimeFn = (UINT64 (*)(UINT64)) 2; - setPlatformCallbacks(pClientCallbacks, &platformCallbacks); + platformCallbacks.getCurrentTimeFn = [](UINT64 customParam) -> UINT64 { + return 1234567890ULL; // Return a dummy timestamp + }; + platformCallbacks.getRandomNumberFn = [](UINT64 seed) -> UINT32 { + return 1; + }; + platformCallbacks.createMutexFn = [](UINT64 customData, BOOL isRecursive) -> MUTEX { + return (MUTEX) 0xff; + }; + platformCallbacks.lockMutexFn = [](UINT64 customData, MUTEX mutex) { + return; + }; + platformCallbacks.unlockMutexFn = [] (UINT64 customData, MUTEX mutex) { + return; + }; + platformCallbacks.tryLockMutexFn = [] (UINT64 customData, MUTEX mutex) -> BOOL { + return TRUE; + }; + + platformCallbacks.freeMutexFn = [] (UINT64 customData, MUTEX mutex) { + MUTEX_FREE(mutex); + }; + + platformCallbacks.createConditionVariableFn = [] (UINT64 customData) -> CVAR { + return (CVAR) 1; + }; + platformCallbacks.signalConditionVariableFn = [] (UINT64 customData, CVAR a) -> STATUS { + return STATUS_SUCCESS; + }; + platformCallbacks.broadcastConditionVariableFn = [] (UINT64 customData, CVAR a) -> STATUS { + return STATUS_SUCCESS; + }; + platformCallbacks.waitConditionVariableFn = [] (UINT64 customData, CVAR cvar, MUTEX mutex, UINT64 timeout) -> STATUS { + return STATUS_SUCCESS; + }; + platformCallbacks.freeConditionVariableFn = [] (UINT64 customData, CVAR a) { + return; + }; + + EXPECT_EQ(STATUS_SUCCESS, setPlatformCallbacks(pClientCallbacks, &platformCallbacks)); + + EXPECT_TRUE(getCurrentTimeAggregate == pClientCallbacks->getCurrentTimeFn); + EXPECT_TRUE(getRandomNumberAggregate == pClientCallbacks->getRandomNumberFn); + EXPECT_TRUE(createMutexAggregate == pClientCallbacks->createMutexFn); + EXPECT_TRUE(lockMutexAggregate == pClientCallbacks->lockMutexFn); + EXPECT_TRUE(unlockMutexAggregate == pClientCallbacks->unlockMutexFn); + EXPECT_TRUE(tryLockMutexAggregate == pClientCallbacks->tryLockMutexFn); + EXPECT_TRUE(freeMutexAggregate == pClientCallbacks->freeMutexFn); + EXPECT_TRUE(createConditionVariableAggregate == pClientCallbacks->createConditionVariableFn); + EXPECT_TRUE(waitConditionVariableAggregate == pClientCallbacks->waitConditionVariableFn); + EXPECT_TRUE(signalConditionVariableAggregate == pClientCallbacks->signalConditionVariableFn); + EXPECT_TRUE(broadcastConditionVariableAggregate == pClientCallbacks->broadcastConditionVariableFn); + EXPECT_TRUE(freeConditionVariableAggregate == pClientCallbacks->freeConditionVariableFn); EXPECT_EQ(STATUS_SUCCESS, freeCallbacksProvider(&pClientCallbacks)); diff --git a/tst/ProducerTestFixture.h b/tst/ProducerTestFixture.h index ce6910d2..360c23cf 100644 --- a/tst/ProducerTestFixture.h +++ b/tst/ProducerTestFixture.h @@ -4,6 +4,7 @@ #include "RotatingStaticAuthCallbacks.h" #define TEST_AUTH_FILE_PATH (PCHAR) "TEST_KVS_AUTH_FILE_PATH" +#define SAMPLE_AUTH_FILE_PATH (PCHAR) "./tst/sample_file_creds.txt" #define TEST_STREAM_NAME (PCHAR) "ScaryTestStream_0" #define TEST_DEVICE_INFO_NAME (PCHAR) "TestDeviceName" #define TEST_USER_AGENT (PCHAR) "Test User Agent" @@ -60,6 +61,13 @@ #define TEST_IOT_THING_NAME (PCHAR) "TestThingName" #define TEST_USER_AGENT_POSTFIX (PCHAR) "Postfix" +// IoT related envs +#define AWS_IOT_CORE_CREDENTIAL_ENDPOINT_ENV_VAR ((PCHAR) "AWS_IOT_CORE_CREDENTIAL_ENDPOINT") +#define AWS_IOT_CORE_CERT_ENV_VAR ((PCHAR) "AWS_IOT_CORE_CERT") +#define AWS_IOT_CORE_PRIVATE_KEY_ENV_VAR ((PCHAR) "AWS_IOT_CORE_PRIVATE_KEY") +#define AWS_IOT_CORE_ROLE_ALIAS_ENV_VAR ((PCHAR) "AWS_IOT_CORE_ROLE_ALIAS") +#define AWS_IOT_CORE_THING_NAME_ENV_VAR ((PCHAR) "AWS_IOT_CORE_THING_NAME") + #ifdef _WIN32 #define TEST_TEMP_DIR_PATH (PCHAR) "C:\\Windows\\Temp\\" #define TEST_TEMP_DIR_PATH_NO_ENDING_SEPARTOR (PCHAR) "C:\\Windows\\Temp" diff --git a/tst/RequestInfoTest.cpp b/tst/RequestInfoTest.cpp new file mode 100644 index 00000000..9f87f5cc --- /dev/null +++ b/tst/RequestInfoTest.cpp @@ -0,0 +1,85 @@ +#include "ProducerTestFixture.h" + +namespace com { namespace amazonaws { namespace kinesis { namespace video { + +class RequestInfoTest : public ProducerClientTestBase { +}; + +TEST_F(RequestInfoTest, createRequestInfoArgsTest) +{ + PRequestInfo pRequestInfo = NULL; + CHAR body[11] = "HelloThere"; + EXPECT_EQ(STATUS_NULL_ARG, createRequestInfo((PCHAR) "http://test.com", NULL, (PCHAR) DEFAULT_AWS_REGION, NULL, NULL, + NULL, SSL_CERTIFICATE_TYPE_PEM, (PCHAR) DEFAULT_USER_AGENT_NAME, + 3 * HUNDREDS_OF_NANOS_IN_A_SECOND, 5 * HUNDREDS_OF_NANOS_IN_A_SECOND, DEFAULT_LOW_SPEED_LIMIT, + DEFAULT_LOW_SPEED_TIME_LIMIT, NULL, NULL)); + EXPECT_EQ(STATUS_NULL_ARG, createRequestInfo(NULL, NULL, (PCHAR) DEFAULT_AWS_REGION, NULL, NULL, + NULL, SSL_CERTIFICATE_TYPE_PEM, (PCHAR) DEFAULT_USER_AGENT_NAME, + 3 * HUNDREDS_OF_NANOS_IN_A_SECOND, 5 * HUNDREDS_OF_NANOS_IN_A_SECOND, DEFAULT_LOW_SPEED_LIMIT, + DEFAULT_LOW_SPEED_TIME_LIMIT, NULL, NULL)); + EXPECT_EQ(STATUS_NULL_ARG, createRequestInfo(NULL, NULL, NULL, NULL, NULL, + NULL, SSL_CERTIFICATE_TYPE_PEM, (PCHAR) DEFAULT_USER_AGENT_NAME, + 3 * HUNDREDS_OF_NANOS_IN_A_SECOND, 5 * HUNDREDS_OF_NANOS_IN_A_SECOND, DEFAULT_LOW_SPEED_LIMIT, + DEFAULT_LOW_SPEED_TIME_LIMIT, NULL, &pRequestInfo)); + EXPECT_EQ(STATUS_SUCCESS, freeRequestInfo(&pRequestInfo)); // Test for idempotency + EXPECT_EQ(STATUS_SUCCESS, createRequestInfo((PCHAR) "http://test.com", NULL, (PCHAR) DEFAULT_AWS_REGION, NULL, NULL, + NULL, SSL_CERTIFICATE_TYPE_PEM, (PCHAR) DEFAULT_USER_AGENT_NAME, + 3 * HUNDREDS_OF_NANOS_IN_A_SECOND, 5 * HUNDREDS_OF_NANOS_IN_A_SECOND, DEFAULT_LOW_SPEED_LIMIT, + DEFAULT_LOW_SPEED_TIME_LIMIT, NULL, &pRequestInfo)); + EXPECT_EQ(STATUS_NULL_ARG, freeRequestInfo(NULL)); + EXPECT_EQ(STATUS_SUCCESS, freeRequestInfo(&pRequestInfo)); + EXPECT_EQ(STATUS_SUCCESS, createRequestInfo((PCHAR) "http://test.com", body, (PCHAR) DEFAULT_AWS_REGION, NULL, NULL, + NULL, SSL_CERTIFICATE_TYPE_PEM, (PCHAR) DEFAULT_USER_AGENT_NAME, + 3 * HUNDREDS_OF_NANOS_IN_A_SECOND, 5 * HUNDREDS_OF_NANOS_IN_A_SECOND, DEFAULT_LOW_SPEED_LIMIT, + DEFAULT_LOW_SPEED_TIME_LIMIT, NULL, &pRequestInfo)); + EXPECT_EQ(0, STRNCMP(body, pRequestInfo->body, STRLEN(body))); + EXPECT_EQ(STRLEN(body), pRequestInfo->bodySize); + EXPECT_EQ(STATUS_SUCCESS, freeRequestInfo(&pRequestInfo)); +} + +TEST_F(RequestInfoTest, removeRequestHeaderApiTest) +{ + RequestInfo requestInfo; + AwsCredentials awsCredentials; + CHAR headerName[5]; + PCHAR pHostStart, pHostEnd; + UINT32 len; + EXPECT_EQ(STATUS_NULL_ARG, removeRequestHeader(NULL, NULL)); + EXPECT_EQ(STATUS_NULL_ARG, removeRequestHeader(&requestInfo, NULL)); + EXPECT_EQ(STATUS_NULL_ARG, removeRequestHeader(NULL, headerName)); + EXPECT_EQ(STATUS_SUCCESS, singleListCreate(&requestInfo.pRequestHeaders)); + + STRCPY(requestInfo.url, "https://kinesisvideo.us-west-2.amazonaws.com/describeStream"); + requestInfo.currentTime = GETTIME(); + requestInfo.pAwsCredentials = &awsCredentials; + + // Get the host header + EXPECT_EQ(STATUS_SUCCESS, getRequestHost(requestInfo.url, &pHostStart, &pHostEnd)); + len = (UINT32) (pHostEnd - pHostStart); + EXPECT_EQ(STATUS_SUCCESS, setRequestHeader(&requestInfo, (PCHAR) "host", 0, pHostStart, len)); + EXPECT_EQ(STATUS_SUCCESS, removeRequestHeader(&requestInfo, (PCHAR) "test")); + EXPECT_EQ(STATUS_SUCCESS, removeRequestHeader(&requestInfo, (PCHAR) "host")); + EXPECT_EQ(STATUS_SUCCESS, singleListFree(requestInfo.pRequestHeaders)); +} + +TEST_F(RequestInfoTest, getServiceCallResultFromHttpStatusApiTest) +{ + EXPECT_EQ((SERVICE_CALL_RESULT) SERVICE_CALL_RESULT_OK, getServiceCallResultFromHttpStatus(SERVICE_CALL_RESULT_OK)); + EXPECT_EQ((SERVICE_CALL_RESULT) SERVICE_CALL_INVALID_ARG, getServiceCallResultFromHttpStatus(SERVICE_CALL_INVALID_ARG)); + EXPECT_EQ((SERVICE_CALL_RESULT) SERVICE_CALL_RESOURCE_NOT_FOUND, getServiceCallResultFromHttpStatus(SERVICE_CALL_RESOURCE_NOT_FOUND)); + EXPECT_EQ((SERVICE_CALL_RESULT) SERVICE_CALL_FORBIDDEN, getServiceCallResultFromHttpStatus(SERVICE_CALL_FORBIDDEN)); + EXPECT_EQ((SERVICE_CALL_RESULT) SERVICE_CALL_RESOURCE_DELETED, getServiceCallResultFromHttpStatus(SERVICE_CALL_RESOURCE_DELETED)); + EXPECT_EQ((SERVICE_CALL_RESULT) SERVICE_CALL_NOT_AUTHORIZED, getServiceCallResultFromHttpStatus(SERVICE_CALL_NOT_AUTHORIZED)); + EXPECT_EQ((SERVICE_CALL_RESULT) SERVICE_CALL_NOT_IMPLEMENTED, getServiceCallResultFromHttpStatus(SERVICE_CALL_NOT_IMPLEMENTED)); + EXPECT_EQ((SERVICE_CALL_RESULT) SERVICE_CALL_INTERNAL_ERROR, getServiceCallResultFromHttpStatus(SERVICE_CALL_INTERNAL_ERROR)); + EXPECT_EQ((SERVICE_CALL_RESULT) SERVICE_CALL_REQUEST_TIMEOUT, getServiceCallResultFromHttpStatus(SERVICE_CALL_REQUEST_TIMEOUT)); + EXPECT_EQ((SERVICE_CALL_RESULT) SERVICE_CALL_GATEWAY_TIMEOUT, getServiceCallResultFromHttpStatus(SERVICE_CALL_GATEWAY_TIMEOUT)); + EXPECT_EQ((SERVICE_CALL_RESULT) SERVICE_CALL_NETWORK_READ_TIMEOUT, getServiceCallResultFromHttpStatus(SERVICE_CALL_NETWORK_READ_TIMEOUT)); + EXPECT_EQ((SERVICE_CALL_RESULT) SERVICE_CALL_NETWORK_CONNECTION_TIMEOUT, getServiceCallResultFromHttpStatus(SERVICE_CALL_NETWORK_CONNECTION_TIMEOUT)); + EXPECT_EQ((SERVICE_CALL_RESULT) SERVICE_CALL_UNKNOWN, getServiceCallResultFromHttpStatus(MAX_UINT32)); +} + +} // namespace video +} // namespace kinesis +} // namespace amazonaws +} // namespace com \ No newline at end of file diff --git a/tst/UtilsApiTest.cpp b/tst/UtilsApiTest.cpp new file mode 100644 index 00000000..044ca081 --- /dev/null +++ b/tst/UtilsApiTest.cpp @@ -0,0 +1,42 @@ +#include "ProducerTestFixture.h" +#include + +namespace com { namespace amazonaws { namespace kinesis { namespace video { + +class UtilsApiTest : public ProducerClientTestBase { +}; + + +TEST_F(UtilsApiTest, ioTExpirationParsingNullArgs) +{ + UINT64 iotTimeInEpoch = 1548972059; + CHAR validFormatIotExpirationTimeStamp[] = "2019-01-31T23:00:59Z"; // expiration is current time + 1 hour + UINT64 expirationTimestampInEpoch = 0; + + EXPECT_EQ(STATUS_NULL_ARG, convertTimestampToEpoch(NULL, iotTimeInEpoch, &expirationTimestampInEpoch)); + EXPECT_EQ(STATUS_NULL_ARG, convertTimestampToEpoch(NULL, iotTimeInEpoch, NULL)); + EXPECT_EQ(STATUS_NULL_ARG, convertTimestampToEpoch(validFormatIotExpirationTimeStamp, iotTimeInEpoch, NULL)); +} + +TEST_F(UtilsApiTest, ioTExpirationParsingValidArgs) +{ + UINT64 iotTimeInEpoch = 1548972059; + CHAR validFormatIotExpirationTimeStamp[] = "2019-01-31T23:00:59Z"; // expiration is current time + 1 hour + UINT64 expirationTimestampInEpoch = 0; + + EXPECT_EQ(STATUS_SUCCESS, convertTimestampToEpoch(validFormatIotExpirationTimeStamp, iotTimeInEpoch, &expirationTimestampInEpoch)); +} + +TEST_F(UtilsApiTest, getSslCertNameFromTypeApiTest) +{ + EXPECT_STREQ(SSL_CERTIFICATE_TYPE_PEM_STR, getSslCertNameFromType(SSL_CERTIFICATE_TYPE_PEM)); + EXPECT_STREQ(SSL_CERTIFICATE_TYPE_DER_STR, getSslCertNameFromType(SSL_CERTIFICATE_TYPE_DER)); + EXPECT_STREQ(SSL_CERTIFICATE_TYPE_ENG_STR, getSslCertNameFromType(SSL_CERTIFICATE_TYPE_ENG)); + EXPECT_STREQ(SSL_CERTIFICATE_TYPE_UNKNOWN_STR, getSslCertNameFromType((SSL_CERTIFICATE_TYPE) 0xffff)); +} + + +} // namespace video +} // namespace kinesis +} // namespace amazonaws +} // namespace com; \ No newline at end of file diff --git a/tst/cert.pem b/tst/cert.pem new file mode 100644 index 00000000..959eacf2 --- /dev/null +++ b/tst/cert.pem @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT +HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs +ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5 +MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD +VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy +ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy +dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p +OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2 +8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K +Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe +hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk +6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw +DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q +AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI +bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB +ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z +qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd +iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn +0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN +sSi6 +-----END CERTIFICATE----- \ No newline at end of file diff --git a/tst/sample_file_creds.txt b/tst/sample_file_creds.txt new file mode 100644 index 00000000..44f78a40 --- /dev/null +++ b/tst/sample_file_creds.txt @@ -0,0 +1 @@ +CREDENTIALS AAAAAAAAAAAAAAAA AAAAAAA \ No newline at end of file