2017-05-18 05:02:48 +00:00
|
|
|
/*
|
2019-05-22 23:06:18 +00:00
|
|
|
* Copyright 2017-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
2017-05-18 05:02:48 +00:00
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License").
|
|
|
|
* You may not use this file except in compliance with the License.
|
|
|
|
* A copy of the License is located at
|
|
|
|
*
|
|
|
|
* http://aws.amazon.com/apache2.0/
|
|
|
|
*
|
|
|
|
* or in the "license" file accompanying this file. This file is distributed
|
|
|
|
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
|
|
|
* express or implied. See the License for the specific language governing
|
|
|
|
* permissions and limitations under the License.
|
|
|
|
*/
|
2018-02-12 23:31:53 +00:00
|
|
|
|
2017-05-18 05:02:48 +00:00
|
|
|
#include <string>
|
|
|
|
#include <future>
|
|
|
|
#include <vector>
|
|
|
|
#include <unordered_set>
|
|
|
|
#include <cctype>
|
2017-07-18 22:25:37 +00:00
|
|
|
#include <random>
|
2017-05-18 05:02:48 +00:00
|
|
|
|
|
|
|
#include <gmock/gmock.h>
|
|
|
|
#include <gtest/gtest.h>
|
|
|
|
|
|
|
|
#include "AVSCommon/Utils/UUIDGeneration/UUIDGeneration.h"
|
|
|
|
|
|
|
|
namespace alexaClientSDK {
|
|
|
|
namespace avsCommon {
|
2017-06-23 23:26:34 +00:00
|
|
|
namespace test {
|
2017-05-18 05:02:48 +00:00
|
|
|
|
|
|
|
using namespace testing;
|
|
|
|
using namespace avsCommon::utils::uuidGeneration;
|
|
|
|
|
|
|
|
/// The version of the UUID generated.
|
|
|
|
static const std::string UUID_VERSION("4");
|
|
|
|
|
|
|
|
/// The variant of the UUID generated.
|
|
|
|
static const unsigned int UUID_VARIANT(8);
|
|
|
|
|
|
|
|
/// The offset of the UUID version in the string.
|
|
|
|
static const unsigned int UUID_VERSION_OFFSET(14);
|
|
|
|
|
|
|
|
/// The offset of the UUID variant in the string.
|
|
|
|
static const unsigned int UUID_VARIANT_OFFSET(19);
|
|
|
|
|
|
|
|
/// Hyphen.
|
|
|
|
static const std::string HYPHEN("-");
|
|
|
|
|
|
|
|
/// Position of first hyphen.
|
|
|
|
static const unsigned int HYPHEN1_POSITION(8);
|
|
|
|
|
|
|
|
/// Position of second hyphen.
|
|
|
|
static const unsigned int HYPHEN2_POSITION(13);
|
|
|
|
|
|
|
|
/// Position of third hyphen.
|
|
|
|
static const unsigned int HYPHEN3_POSITION(18);
|
|
|
|
|
|
|
|
/// Position of fourth hyphen.
|
|
|
|
static const unsigned int HYPHEN4_POSITION(23);
|
|
|
|
|
|
|
|
/// The length of the UUID string - 32 hexadecimal digits and 4 hyphens.
|
|
|
|
static const unsigned int UUID_LENGTH(36);
|
|
|
|
|
|
|
|
/// The maximum UUIDs to generate to test for uniqueness.
|
|
|
|
static const unsigned int MAX_UUIDS_TO_GENERATE(100);
|
|
|
|
|
|
|
|
/// The maximum threads to test with.
|
|
|
|
static const unsigned int MAX_TEST_THREADS(10);
|
|
|
|
|
2017-07-18 22:25:37 +00:00
|
|
|
/// The maximum number of retries.
|
|
|
|
static const unsigned int MAX_RETRIES(20);
|
|
|
|
|
2017-10-02 22:59:05 +00:00
|
|
|
class UUIDGenerationTest : public ::testing::Test {};
|
2017-05-18 05:02:48 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Call @c generateUUID and expect a string of length @c UUID_LENGTH.
|
|
|
|
*/
|
2019-05-22 23:06:18 +00:00
|
|
|
TEST_F(UUIDGenerationTest, test_uUIDStringLength) {
|
2017-05-18 05:02:48 +00:00
|
|
|
ASSERT_EQ(UUID_LENGTH, generateUUID().length());
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2017-06-23 23:26:34 +00:00
|
|
|
* Call @c generateUUID and expect a string of length @c UUID_LENGTH. Check that each character in the string
|
|
|
|
* is a hexedecimal number except for the hyphens.
|
|
|
|
*/
|
2019-05-22 23:06:18 +00:00
|
|
|
TEST_F(UUIDGenerationTest, test_uUIDContainsOnlyHexCharacters) {
|
2017-05-18 05:02:48 +00:00
|
|
|
auto uuid = generateUUID();
|
|
|
|
ASSERT_EQ(UUID_LENGTH, uuid.length());
|
|
|
|
for (unsigned int i = 0; i < uuid.length(); i++) {
|
2017-06-23 23:26:34 +00:00
|
|
|
if (i == HYPHEN1_POSITION || i == HYPHEN2_POSITION || i == HYPHEN3_POSITION || i == HYPHEN4_POSITION) {
|
2017-10-02 22:59:05 +00:00
|
|
|
ASSERT_EQ(HYPHEN, uuid.substr(i, 1));
|
2017-05-18 05:02:48 +00:00
|
|
|
} else {
|
|
|
|
ASSERT_TRUE(isxdigit(uuid[i]));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Call @c generateUUID and check that the version is set correctly.
|
|
|
|
*/
|
2019-05-22 23:06:18 +00:00
|
|
|
TEST_F(UUIDGenerationTest, test_uUIDVersion) {
|
2017-10-02 22:59:05 +00:00
|
|
|
ASSERT_EQ(UUID_VERSION, generateUUID().substr(UUID_VERSION_OFFSET, 1));
|
2017-05-18 05:02:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Call @c generateUUID and check the variant is set correctly.
|
|
|
|
*/
|
2019-05-22 23:06:18 +00:00
|
|
|
TEST_F(UUIDGenerationTest, test_uUIDVariant) {
|
2017-10-02 22:59:05 +00:00
|
|
|
ASSERT_EQ(UUID_VARIANT, strtoul(generateUUID().substr(UUID_VARIANT_OFFSET, 1).c_str(), nullptr, 16) & UUID_VARIANT);
|
2017-05-18 05:02:48 +00:00
|
|
|
}
|
|
|
|
|
Version 1.16 alexa-client-sdk
Changes in this update:
**Enhancements**
- Added support for SpeechSynthesizer v.1.2 which includes the new `playBehaviour` directive. For more information, see [SpeechSynthesizer v1.2](https://github.com/alexa/avs-device-sdk/wiki/SpeechSynthesizer-Interface-v1.2).
- Added support for pre-buffering in [AudioPlayer](https://alexa.github.io/avs-device-sdk/classalexa_client_s_d_k_1_1capability_agents_1_1audio_player_1_1_audio_player.html). You can optionally choose the number of instances MediaPlayer uses in the [AlexaClientSDKconfig.json](https://github.com/alexa/avs-device-sdk/blob/master/Integration/AlexaClientSDKConfig.json). Important: the contract for [MediaPlayerInterface](https://alexa.github.io/avs-device-sdk/classalexa_client_s_d_k_1_1avs_common_1_1utils_1_1media_player_1_1_media_player_interface.html) has changed. You must now make sure that the `SourceId` value returned by `setSource()` is unique across all instances.
- AudioPlayer is now licensed under the Amazon Software License instead of the Apache Software License.
**Bug Fixes**
- Fixed Android issue that caused the build script to ignore PKG_CONFIG_PATH. This sometimes caused the build to use a preinstalled dependency instead of the specific version downloaded by the Android script (e.g - openssl).
- Fixed Android issue that prevented the Sample app from running at the same time as other applications using the microphone. Android doesn't inherently allow two applications to use the microphone. Pressing the mute button now temporarily stops Alexa from accessing the microphone.
- Added 'quit' (– q) to the settings sub menu.
- Fixed outdated dependencies issue in the Windows install script.
- Fixed reminders issue that caused Notification LEDs to stay on, even after dismissing the alert.
**Known Issues**
* Music playback history isn't displayed in the Alexa app for certain account and device types.
* When using Gnu Compiler Collection 8+ (GCC 8+), `-Wclass-memaccess` triggers warnings. You can ignore these, they don't cause the build to fail.
* Android error `libDefaultClient.so not found` might occur. Resolve this by upgrading to ADB version 1.0.40.
* If a device loses a network connection, the lost connection status isn't returned via local TTS.
* ACL encounters issues if it receives audio attachments but doesn't consume them.
* `SpeechSynthesizerState` uses `GAINING_FOCUS` and `LOSING_FOCUS` as a workaround for handling intermediate states.
* Media steamed through Bluetooth might abruptly stop. To restart playback, resume the media in the source application or toggle next/previous.
* If a connected Bluetooth device is inactive, the Alexa app might indicates that audio is playing.
* The Bluetooth agent assumes that the Bluetooth adapter is always connected to a power source. Disconnecting from a power source during operation isn't yet supported.
* When using some products, interrupted Bluetooth playback might not resume if other content is locally streamed.
* `make integration` isn't available for Android. To run Android integration tests, manually upload the test binary and input file and run ADB.
* Alexa might truncate the beginning of speech when responding to text-to-speech (TTS) user events. This only impacts Raspberry Pi devices running Android Things with HDMI output audio.
* A reminder TTS message doesn't play if the sample app restarts and loses a network connection. Instead, the default alarm tone plays twice.
* `ServerDisconnectIntegratonTest` tests are disabled until they are updated to reflect new service behavior.
* Bluetooth initialization must complete before connecting devices, otherwise devices are ignored.
* The `DirectiveSequencerTest.test_handleBlockingThenImmediatelyThenNonBockingOnSameDialogId` test fails intermittently.
* On some devices, Alexa gets stuck in a permanent listening state. Pressing `t` and `h` in the Sample App doesn't exit the listening state.
* Exiting the `settings` menu doesn't provide a message to indicate that you are back in the main menu.
2019-10-25 20:19:44 +00:00
|
|
|
/**
|
|
|
|
* Call @c setSalt without error, with various inputs
|
|
|
|
*/
|
|
|
|
TEST_F(UUIDGenerationTest, setSaltTest) {
|
|
|
|
setSalt("");
|
|
|
|
auto uuid = generateUUID();
|
|
|
|
ASSERT_EQ(UUID_VERSION, uuid.substr(UUID_VERSION_OFFSET, 1));
|
|
|
|
ASSERT_EQ(UUID_LENGTH, uuid.length());
|
|
|
|
setSalt("G2A14Q02920602PT");
|
|
|
|
uuid = generateUUID();
|
|
|
|
ASSERT_EQ(UUID_VERSION, uuid.substr(UUID_VERSION_OFFSET, 1));
|
|
|
|
ASSERT_EQ(UUID_LENGTH, uuid.length());
|
|
|
|
setSalt("123456789");
|
|
|
|
uuid = generateUUID();
|
|
|
|
ASSERT_EQ(UUID_VERSION, uuid.substr(UUID_VERSION_OFFSET, 1));
|
|
|
|
ASSERT_EQ(UUID_LENGTH, uuid.length());
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Call @c generateUUID and setSalt from multiple threads and check that all are able to complete
|
|
|
|
* successfully Check for uniqueness of the UUIDs generated.
|
|
|
|
*/
|
|
|
|
TEST_F(UUIDGenerationTest, test_multipleConcurrentSaltSettings) {
|
|
|
|
int no_of_threads = MAX_TEST_THREADS;
|
|
|
|
std::vector<std::future<std::string>> uuidRequesters;
|
|
|
|
std::unordered_set<std::string> uuidsGenerated;
|
|
|
|
|
|
|
|
for (int i = 0; i < no_of_threads; ++i) {
|
|
|
|
int operationSelection = rand() % 10;
|
|
|
|
|
|
|
|
if (operationSelection > 5) {
|
|
|
|
auto future_generate = std::async(std::launch::async, []() { return generateUUID(); });
|
|
|
|
uuidRequesters.push_back(std::move(future_generate));
|
|
|
|
} else {
|
|
|
|
auto future_seed = std::async(
|
|
|
|
std::launch::async,
|
|
|
|
[](int i) {
|
|
|
|
setSalt(std::to_string(i));
|
|
|
|
return generateUUID();
|
|
|
|
},
|
|
|
|
i);
|
|
|
|
uuidRequesters.push_back(std::move(future_seed));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (auto& future : uuidRequesters) {
|
|
|
|
unsigned int prevSizeOfSet = uuidsGenerated.size();
|
|
|
|
auto uuid = future.get();
|
|
|
|
uuidsGenerated.insert(uuid);
|
|
|
|
ASSERT_EQ(UUID_LENGTH, uuid.length());
|
|
|
|
ASSERT_EQ(UUID_VERSION, uuid.substr(UUID_VERSION_OFFSET, 1));
|
|
|
|
ASSERT_EQ(UUID_VARIANT, strtoul(uuid.substr(UUID_VARIANT_OFFSET, 1).c_str(), nullptr, 16) & UUID_VARIANT);
|
|
|
|
ASSERT_EQ(prevSizeOfSet + 1, uuidsGenerated.size());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-18 05:02:48 +00:00
|
|
|
/**
|
|
|
|
* Call @c generateUUID and check that the hyphens are in the right positions.
|
|
|
|
*/
|
2019-05-22 23:06:18 +00:00
|
|
|
TEST_F(UUIDGenerationTest, test_uUIDHyphens) {
|
2017-05-18 05:02:48 +00:00
|
|
|
std::string uuid = generateUUID();
|
2017-10-02 22:59:05 +00:00
|
|
|
ASSERT_EQ(HYPHEN, uuid.substr(HYPHEN1_POSITION, 1));
|
|
|
|
ASSERT_EQ(HYPHEN, uuid.substr(HYPHEN2_POSITION, 1));
|
|
|
|
ASSERT_EQ(HYPHEN, uuid.substr(HYPHEN3_POSITION, 1));
|
|
|
|
ASSERT_EQ(HYPHEN, uuid.substr(HYPHEN4_POSITION, 1));
|
2017-05-18 05:02:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Call @c generateUUID multiple times and check the version and variant are set correctly.
|
|
|
|
* Check for uniqueness of the UUIDs generated.
|
|
|
|
*/
|
2019-05-22 23:06:18 +00:00
|
|
|
TEST_F(UUIDGenerationTest, test_multipleRequests) {
|
2017-05-18 05:02:48 +00:00
|
|
|
std::unordered_set<std::string> uuidsGenerated;
|
|
|
|
|
2017-06-23 23:26:34 +00:00
|
|
|
for (unsigned int i = 0; i < MAX_UUIDS_TO_GENERATE; ++i) {
|
2017-05-18 05:02:48 +00:00
|
|
|
unsigned int prevSizeOfSet = uuidsGenerated.size();
|
|
|
|
auto uuid = generateUUID();
|
|
|
|
uuidsGenerated.insert(uuid);
|
|
|
|
ASSERT_EQ(UUID_LENGTH, uuid.length());
|
2017-10-02 22:59:05 +00:00
|
|
|
ASSERT_EQ(UUID_VERSION, uuid.substr(UUID_VERSION_OFFSET, 1));
|
|
|
|
ASSERT_EQ(UUID_VARIANT, strtoul(uuid.substr(UUID_VARIANT_OFFSET, 1).c_str(), nullptr, 16) & UUID_VARIANT);
|
|
|
|
ASSERT_EQ(prevSizeOfSet + 1, uuidsGenerated.size());
|
2017-05-18 05:02:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Call @c generateUUID from multiple threads and check the version and variant are set correctly.
|
|
|
|
* Check for uniqueness of the UUIDs generated.
|
|
|
|
*/
|
2019-05-22 23:06:18 +00:00
|
|
|
TEST_F(UUIDGenerationTest, test_multipleConcurrentRequests) {
|
2017-05-18 05:02:48 +00:00
|
|
|
int no_of_threads = MAX_TEST_THREADS;
|
|
|
|
std::vector<std::future<std::string>> uuidRequesters;
|
|
|
|
std::unordered_set<std::string> uuidsGenerated;
|
|
|
|
|
2017-06-23 23:26:34 +00:00
|
|
|
for (int i = 0; i < no_of_threads; ++i) {
|
2017-12-09 00:07:37 +00:00
|
|
|
auto future = std::async(std::launch::async, []() { return generateUUID(); });
|
2017-05-18 05:02:48 +00:00
|
|
|
uuidRequesters.push_back(std::move(future));
|
|
|
|
}
|
|
|
|
|
|
|
|
for (auto& future : uuidRequesters) {
|
|
|
|
unsigned int prevSizeOfSet = uuidsGenerated.size();
|
|
|
|
auto uuid = future.get();
|
|
|
|
uuidsGenerated.insert(uuid);
|
|
|
|
ASSERT_EQ(UUID_LENGTH, uuid.length());
|
2017-10-02 22:59:05 +00:00
|
|
|
ASSERT_EQ(UUID_VERSION, uuid.substr(UUID_VERSION_OFFSET, 1));
|
|
|
|
ASSERT_EQ(UUID_VARIANT, strtoul(uuid.substr(UUID_VARIANT_OFFSET, 1).c_str(), nullptr, 16) & UUID_VARIANT);
|
|
|
|
ASSERT_EQ(prevSizeOfSet + 1, uuidsGenerated.size());
|
2017-05-18 05:02:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-18 22:25:37 +00:00
|
|
|
/**
|
|
|
|
* Call @c generateUUID and ensure all hex values are generated. Will retry @c MAX_RETRIES times.
|
|
|
|
*/
|
2019-05-22 23:06:18 +00:00
|
|
|
TEST_F(UUIDGenerationTest, test_allHexValuesGenerated) {
|
2017-07-18 22:25:37 +00:00
|
|
|
std::unordered_set<char> hexCharacters = {
|
2017-10-02 22:59:05 +00:00
|
|
|
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
|
2017-07-18 22:25:37 +00:00
|
|
|
for (unsigned int retry = 0; retry < MAX_RETRIES && !hexCharacters.empty(); retry++) {
|
|
|
|
std::string uuid = generateUUID();
|
2017-10-02 22:59:05 +00:00
|
|
|
for (const char& digit : uuid) {
|
2017-07-18 22:25:37 +00:00
|
|
|
hexCharacters.erase(digit);
|
|
|
|
if (hexCharacters.empty()) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ASSERT_TRUE(hexCharacters.empty());
|
|
|
|
}
|
|
|
|
|
2017-10-02 22:59:05 +00:00
|
|
|
} // namespace test
|
|
|
|
} // namespace avsCommon
|
|
|
|
} // namespace alexaClientSDK
|