/* * Copyright 2018-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * 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. */ #include #include #include #include #include #include #include #include #include #include "EqualizerImplementations/EqualizerController.h" #include "EqualizerImplementations/InMemoryEqualizerConfiguration.h" namespace alexaClientSDK { namespace equalizer { namespace test { using namespace ::testing; using namespace avsCommon::sdkInterfaces::audio; using namespace avsCommon::sdkInterfaces::audio::test; using namespace avsCommon::utils::error; using namespace equalizer; /// Band level used as minimum value in tests static constexpr int MIN_LEVEL = -10; /// Band level used as maximum value in tests static constexpr int MAX_LEVEL = 10; /// Band level below the minimum allowed static constexpr int BELOW_MIN_LEVEL = -11; /// Band level above the maximum allowed static constexpr int ABOVE_MAX_LEVEL = 11; /// Band level used as a default static constexpr int DEFAULT_LEVEL = 0; /// Default value to adjust band level static constexpr int DEFAULT_ADJUST_DELTA = 1; /// A sample default band level for MIDRANGE band static constexpr int DEFAULT_MIDRANGE = DEFAULT_LEVEL; /// A sample band level for MIDRANGE band different from default static constexpr int NON_DEFAULT_MIDRANGE = 4; /// A sample default band level for TREBLE band static constexpr int DEFAULT_TREBLE = 5; /// A sample band level for TREBLE band different from default static constexpr int NON_DEFAULT_TREBLE = -5; /// A sample default mode static constexpr EqualizerMode DEFAULT_MODE = EqualizerMode::NONE; /// Number of times to perform an operation to make sure that it provides consistent results. static constexpr int STABILITY_CHECK_ITERATIONS = 100; /** * Test fixture for @c EqualizerController tests */ class EqualizerControllerTest : public ::testing::Test { protected: void SetUp() override; /// Persistent storage mock. std::shared_ptr m_storage; /// Equalizer configuration used in tests. std::shared_ptr m_configuration; /// Equalizer mode controller mock. std::shared_ptr m_modeController; }; void EqualizerControllerTest::SetUp() { auto bands = std::set({EqualizerBand::MIDRANGE, EqualizerBand::TREBLE}); auto defaultState = EqualizerState{ DEFAULT_MODE, EqualizerBandLevelMap({{EqualizerBand::MIDRANGE, DEFAULT_MIDRANGE}, {EqualizerBand::TREBLE, DEFAULT_TREBLE}})}; auto modes = std::set({EqualizerMode::NIGHT, EqualizerMode::TV}); m_configuration = InMemoryEqualizerConfiguration::create(MIN_LEVEL, MAX_LEVEL, DEFAULT_ADJUST_DELTA, bands, modes, defaultState); m_storage = std::make_shared>(); m_modeController = std::make_shared>(); // Make sure storage will never contain a valid state so that we always use the hardcoded defaults. ON_CALL(*(m_storage.get()), loadState()).WillByDefault(Invoke([]() { return SuccessResult::failure(); })); // Make sure setEqualizerMode() will return true (success), rather than mocked default - false. ON_CALL(*(m_modeController.get()), setEqualizerMode(_)).WillByDefault(Return(true)); } // Test internal state right after controller creation TEST_F(EqualizerControllerTest, test_providedEmptyConfig_shouldUseDefaults) { auto controller = EqualizerController::create(m_modeController, m_configuration, m_storage); auto configuration = controller->getConfiguration(); ASSERT_NE(configuration, nullptr); EXPECT_EQ(controller->getBandLevel(EqualizerBand::TREBLE).value(), DEFAULT_TREBLE); EXPECT_EQ(controller->getBandLevel(EqualizerBand::MIDRANGE).value(), DEFAULT_MIDRANGE); auto bandLevelsResult = controller->getBandLevels(std::set({EqualizerBand::TREBLE, EqualizerBand::MIDRANGE})); EXPECT_TRUE(bandLevelsResult.isSucceeded()); // Must return levels only for supported bands auto bandLevels = bandLevelsResult.value(); EXPECT_TRUE(bandLevels.end() != bandLevels.find(EqualizerBand::MIDRANGE)); EXPECT_TRUE(bandLevels.end() != bandLevels.find(EqualizerBand::TREBLE)); EXPECT_FALSE(bandLevels.end() != bandLevels.find(EqualizerBand::BASS)); // Check values EXPECT_EQ(bandLevels[EqualizerBand::TREBLE], DEFAULT_TREBLE); EXPECT_EQ(bandLevels[EqualizerBand::MIDRANGE], DEFAULT_MIDRANGE); // Check if current mode is NONE EXPECT_EQ(controller->getCurrentMode(), DEFAULT_MODE); } // Test simple changes TEST_F(EqualizerControllerTest, test_changeBandLevels_shouldSucceed) { auto controller = EqualizerController::create(m_modeController, m_configuration, m_storage); controller->setBandLevel(EqualizerBand::TREBLE, NON_DEFAULT_TREBLE); EXPECT_EQ(controller->getBandLevel(EqualizerBand::TREBLE).value(), NON_DEFAULT_TREBLE); controller->setBandLevel(EqualizerBand::MIDRANGE, NON_DEFAULT_MIDRANGE); EXPECT_EQ(controller->getBandLevel(EqualizerBand::MIDRANGE).value(), NON_DEFAULT_MIDRANGE); auto bandLevelsResult = controller->getBandLevels(std::set({EqualizerBand::TREBLE, EqualizerBand::MIDRANGE})); EXPECT_TRUE(bandLevelsResult.isSucceeded()); auto bandLevels = bandLevelsResult.value(); EXPECT_EQ(bandLevels[EqualizerBand::TREBLE], NON_DEFAULT_TREBLE); EXPECT_EQ(bandLevels[EqualizerBand::MIDRANGE], NON_DEFAULT_MIDRANGE); controller->setBandLevel(EqualizerBand::MIDRANGE, DEFAULT_LEVEL); controller->adjustBandLevels(EqualizerBandLevelMap({{EqualizerBand::MIDRANGE, -1}})); EXPECT_EQ(controller->getBandLevel(EqualizerBand::MIDRANGE).value(), DEFAULT_LEVEL - 1); } // Test simple changes with invalid levels TEST_F(EqualizerControllerTest, test_setInvalidBandLevels_shouldClampToSupportedRange) { auto controller = EqualizerController::create(m_modeController, m_configuration, m_storage); controller->setBandLevel(EqualizerBand::TREBLE, BELOW_MIN_LEVEL); EXPECT_EQ(controller->getBandLevel(EqualizerBand::TREBLE).value(), MIN_LEVEL); controller->setBandLevel(EqualizerBand::MIDRANGE, ABOVE_MAX_LEVEL); EXPECT_EQ(controller->getBandLevel(EqualizerBand::MIDRANGE).value(), MAX_LEVEL); // Should crop to min controller->adjustBandLevels(EqualizerBandLevelMap({{EqualizerBand::MIDRANGE, -(MAX_LEVEL - MIN_LEVEL + 1)}})); EXPECT_EQ(controller->getBandLevel(EqualizerBand::MIDRANGE).value(), MIN_LEVEL); // Should crop to max controller->adjustBandLevels(EqualizerBandLevelMap({{EqualizerBand::MIDRANGE, (MAX_LEVEL - MIN_LEVEL + 1)}})); EXPECT_EQ(controller->getBandLevel(EqualizerBand::MIDRANGE).value(), MAX_LEVEL); } // Test mode changes TEST_F(EqualizerControllerTest, test_setMode_shouldSucceed) { auto controller = EqualizerController::create(m_modeController, m_configuration, m_storage); controller->setCurrentMode(EqualizerMode::NIGHT); // Check if modifications have been applied ASSERT_EQ(controller->getCurrentMode(), EqualizerMode::NIGHT); } // Test invalid modes TEST_F(EqualizerControllerTest, test_setInvalidMode_shouldNotChangeMode) { auto controller = EqualizerController::create(m_modeController, m_configuration, m_storage); controller->setCurrentMode(EqualizerMode::MOVIE); // Check if state remains the same ASSERT_EQ(controller->getCurrentMode(), DEFAULT_MODE); } // Test single listener reaction on band level changes TEST_F(EqualizerControllerTest, test_providedBandLevelChanges_addRemoveListener_shouldFollowSubscriptionStatus) { auto controller = EqualizerController::create(m_modeController, m_configuration, m_storage); auto listener = std::make_shared>(); controller->addListener(listener); // Variable to hold state reported by onEqualizerStateChanged() EqualizerState reportedState; EXPECT_CALL(*(listener.get()), onEqualizerStateChanged(_)).Times(1).WillOnce(SaveArg<0>(&reportedState)); controller->setBandLevel(EqualizerBand::TREBLE, NON_DEFAULT_TREBLE); EXPECT_EQ(reportedState.bandLevels[EqualizerBand::TREBLE], NON_DEFAULT_TREBLE); // Call again with the same value. Must not report changes EXPECT_CALL(*(listener.get()), onEqualizerStateChanged(_)).Times(0); controller->setBandLevel(EqualizerBand::TREBLE, NON_DEFAULT_TREBLE); // Reset level to default and try to adjust. // NOTE: Putting AtLeast(0) here to handle the case when DEFAULT_MIDRANGE == DEFAULT_LEVEL EXPECT_CALL(*(listener.get()), onEqualizerStateChanged(_)).Times(AtLeast(0)); controller->setBandLevel(EqualizerBand::MIDRANGE, DEFAULT_LEVEL); EXPECT_CALL(*(listener.get()), onEqualizerStateChanged(_)).Times(1).WillOnce(SaveArg<0>(&reportedState)); controller->adjustBandLevels(EqualizerBandLevelMap({{EqualizerBand::MIDRANGE, 1}})); ASSERT_EQ(reportedState.bandLevels[EqualizerBand::MIDRANGE], DEFAULT_LEVEL + 1); // Remove listener and see if it is called again controller->removeListener(listener); EXPECT_CALL(*(listener.get()), onEqualizerStateChanged(_)).Times(0); controller->setBandLevel(EqualizerBand::TREBLE, DEFAULT_TREBLE); } // Test single listener reaction on mode changes TEST_F(EqualizerControllerTest, test_providedModeChanges_addRemoveListener_shouldFollowSubscriptionStatus) { auto controller = EqualizerController::create(m_modeController, m_configuration, m_storage); auto listener = std::make_shared>(); controller->addListener(listener); // Variable to hold state reported by onEqualizerStateChanged() EqualizerState reportedState; EXPECT_CALL(*(listener.get()), onEqualizerStateChanged(_)).Times(1).WillOnce(SaveArg<0>(&reportedState)); controller->setCurrentMode(EqualizerMode::NIGHT); ASSERT_EQ(reportedState.mode, EqualizerMode::NIGHT); // Repeat same mode. Should not notify EXPECT_CALL(*(listener.get()), onEqualizerStateChanged(_)).Times(0); controller->setCurrentMode(EqualizerMode::NIGHT); // Change back to make sure that it works more than once EXPECT_CALL(*(listener.get()), onEqualizerStateChanged(_)).Times(1).WillOnce(SaveArg<0>(&reportedState)); controller->setCurrentMode(EqualizerMode::TV); ASSERT_EQ(reportedState.mode, EqualizerMode::TV); // Try unsupported mode. Should not notify EXPECT_CALL(*(listener.get()), onEqualizerStateChanged(_)).Times(0); controller->setCurrentMode(EqualizerMode::MUSIC); } // Test multiple listeners reaction on changes TEST_F( EqualizerControllerTest, test_providedBandLevelChanges_addRemoveMultipleListeners_shouldFollowSubscriptionStatus) { auto controller = EqualizerController::create(m_modeController, m_configuration, m_storage); // Variables to hold state reported by onEqualizerStateChanged() EqualizerState reportedState1; EqualizerState reportedState2; auto listener1 = std::make_shared>(); EXPECT_CALL(*(listener1.get()), onEqualizerStateChanged(_)).Times(1).WillOnce(SaveArg<0>(&reportedState1)); controller->addListener(listener1); auto listener2 = std::make_shared>(); EXPECT_CALL(*(listener2.get()), onEqualizerStateChanged(_)).Times(1).WillOnce(SaveArg<0>(&reportedState2)); controller->addListener(listener2); // Perform change controller->setBandLevel(EqualizerBand::MIDRANGE, NON_DEFAULT_MIDRANGE); ASSERT_EQ(reportedState1.bandLevels[EqualizerBand::MIDRANGE], NON_DEFAULT_MIDRANGE); ASSERT_EQ(reportedState2.bandLevels[EqualizerBand::MIDRANGE], NON_DEFAULT_MIDRANGE); // Remove one and make sure second still receives updates controller->removeListener(listener1); EXPECT_CALL(*(listener1.get()), onEqualizerStateChanged(_)).Times(0); EXPECT_CALL(*(listener2.get()), onEqualizerStateChanged(_)).Times(1).WillOnce(SaveArg<0>(&reportedState2)); // Perform change controller->setBandLevel(EqualizerBand::MIDRANGE, DEFAULT_MIDRANGE); ASSERT_EQ(reportedState2.bandLevels[EqualizerBand::MIDRANGE], DEFAULT_MIDRANGE); } // Test the synchronous nature of callbacks TEST_F(EqualizerControllerTest, test_triggerChangesMultipleTimes_ExpectListenersNotifiedSameTimes) { auto controller = EqualizerController::create(m_modeController, m_configuration, m_storage); auto listener = std::make_shared>(); controller->addListener(listener); EXPECT_CALL(*(listener.get()), onEqualizerStateChanged(_)).Times(STABILITY_CHECK_ITERATIONS); for (int i = 0; i < STABILITY_CHECK_ITERATIONS; i++) { controller->setBandLevel(EqualizerBand::TREBLE, DEFAULT_TREBLE + 1 + i % 2); } // Set expectation again to force gmock count validation at this point EXPECT_CALL(*(listener.get()), onEqualizerStateChanged(_)).Times(0); } // Test single equalizer registrations TEST_F(EqualizerControllerTest, test_providedBandLevelChanges_addRemoveSingleEqualizer_shouldFollowRegistrationStatus) { auto controller = EqualizerController::create(m_modeController, m_configuration, m_storage); auto equalizer = std::make_shared>(); ON_CALL(*(equalizer.get()), getMinimumBandLevel()).WillByDefault(Return(MIN_LEVEL)); ON_CALL(*(equalizer.get()), getMaximumBandLevel()).WillByDefault(Return(MAX_LEVEL)); controller->registerEqualizer(equalizer); // Variable to hold state reported by onEqualizerStateChanged() EqualizerBandLevelMap reportedBandLevels; EXPECT_CALL(*(equalizer.get()), setEqualizerBandLevels(_)).Times(1).WillOnce(SaveArg<0>(&reportedBandLevels)); controller->setBandLevel(EqualizerBand::TREBLE, NON_DEFAULT_TREBLE); EXPECT_EQ(reportedBandLevels[EqualizerBand::TREBLE], NON_DEFAULT_TREBLE); // Remove equalizer and make sure no updates received EXPECT_CALL(*(equalizer.get()), setEqualizerBandLevels(_)).Times(0); controller->unregisterEqualizer(equalizer); controller->setBandLevel(EqualizerBand::TREBLE, DEFAULT_TREBLE); } // Test multiple equalizer registrations TEST_F( EqualizerControllerTest, test_providedBandLevelChanges_addRemoveMultipleEqualizers_shouldFollowRegistrationStatus) { auto controller = EqualizerController::create(m_modeController, m_configuration, m_storage); auto equalizer1 = std::make_shared>(); ON_CALL(*(equalizer1.get()), getMinimumBandLevel()).WillByDefault(Return(MIN_LEVEL)); ON_CALL(*(equalizer1.get()), getMaximumBandLevel()).WillByDefault(Return(MAX_LEVEL)); controller->registerEqualizer(equalizer1); auto equalizer2 = std::make_shared>(); ON_CALL(*(equalizer2.get()), getMinimumBandLevel()).WillByDefault(Return(MIN_LEVEL)); ON_CALL(*(equalizer2.get()), getMaximumBandLevel()).WillByDefault(Return(MAX_LEVEL)); controller->registerEqualizer(equalizer2); // Variables to hold state reported by onEqualizerStateChanged() EqualizerBandLevelMap reportedBandLevels1; EqualizerBandLevelMap reportedBandLevels2; EXPECT_CALL(*(equalizer1.get()), setEqualizerBandLevels(_)).Times(1).WillOnce(SaveArg<0>(&reportedBandLevels1)); EXPECT_CALL(*(equalizer2.get()), setEqualizerBandLevels(_)).Times(1).WillOnce(SaveArg<0>(&reportedBandLevels2)); controller->setBandLevel(EqualizerBand::TREBLE, NON_DEFAULT_TREBLE); EXPECT_EQ(reportedBandLevels1[EqualizerBand::TREBLE], NON_DEFAULT_TREBLE); EXPECT_EQ(reportedBandLevels2[EqualizerBand::TREBLE], NON_DEFAULT_TREBLE); // Remove one and make sure second still receives updates EXPECT_CALL(*(equalizer1.get()), setEqualizerBandLevels(_)).Times(0); EXPECT_CALL(*(equalizer2.get()), setEqualizerBandLevels(_)).Times(1).WillOnce(SaveArg<0>(&reportedBandLevels2)); controller->unregisterEqualizer(equalizer1); controller->setBandLevel(EqualizerBand::TREBLE, DEFAULT_TREBLE); EXPECT_EQ(reportedBandLevels2[EqualizerBand::TREBLE], DEFAULT_TREBLE); } // Test synchronous nature of equalizer handling TEST_F(EqualizerControllerTest, test_triggerChangesMultipleTimes_ExpectEqualizersCalledSameTimes) { auto controller = EqualizerController::create(m_modeController, m_configuration, m_storage); auto equalizer = std::make_shared>(); controller->registerEqualizer(equalizer); EXPECT_CALL(*(equalizer.get()), setEqualizerBandLevels(_)).Times(STABILITY_CHECK_ITERATIONS); for (int i = 0; i < STABILITY_CHECK_ITERATIONS; i++) { controller->setBandLevel(EqualizerBand::TREBLE, DEFAULT_TREBLE + 1 + i % 2); } // Set expectation again to force gmock count validation at this point EXPECT_CALL(*(equalizer.get()), setEqualizerBandLevels(_)).Times(0); } // Test persistent storage operations TEST_F(EqualizerControllerTest, test_saveLoadStateWithPersistentStorage_shouldSucceed) { EXPECT_CALL(*(m_storage.get()), loadState()).Times(1); auto controller = EqualizerController::create(m_modeController, m_configuration, m_storage); // Perform change and see if state is updated EXPECT_CALL(*(m_storage.get()), saveState(_)).Times(1); controller->setBandLevel(EqualizerBand::TREBLE, DEFAULT_TREBLE + 1); EXPECT_CALL(*(m_storage.get()), saveState(_)).Times(1); controller->setBandLevels(EqualizerBandLevelMap( {{EqualizerBand::TREBLE, DEFAULT_TREBLE + 1}, {EqualizerBand::MIDRANGE, DEFAULT_MIDRANGE + 1}})); EXPECT_CALL(*(m_storage.get()), saveState(_)).Times(1); controller->adjustBandLevels(EqualizerBandLevelMap({{EqualizerBand::TREBLE, -1}})); EXPECT_CALL(*(m_storage.get()), saveState(_)).Times(1); controller->setCurrentMode(EqualizerMode::TV); } TEST_F(EqualizerControllerTest, test_setLevelBelowEqualizerMinimum_shouldClamp) { EXPECT_CALL(*(m_storage.get()), loadState()).Times(1); auto controller = EqualizerController::create(m_modeController, m_configuration, m_storage); auto equalizer = std::make_shared>(); ON_CALL(*(equalizer.get()), getMinimumBandLevel()).WillByDefault(Return(MAX_LEVEL)); ON_CALL(*(equalizer.get()), getMaximumBandLevel()).WillByDefault(Return(MAX_LEVEL)); controller->registerEqualizer(equalizer); EqualizerBandLevelMap bandLevelMap; EXPECT_CALL(*(equalizer.get()), setEqualizerBandLevels(_)).Times(1).WillOnce(SaveArg<0>(&bandLevelMap)); controller->setBandLevel(EqualizerBand::MIDRANGE, MIN_LEVEL); EXPECT_EQ(bandLevelMap[EqualizerBand::MIDRANGE], MAX_LEVEL); } TEST_F(EqualizerControllerTest, test_setLevelAboveEqualizerMaximum_shouldClamp) { EXPECT_CALL(*(m_storage.get()), loadState()).Times(1); auto controller = EqualizerController::create(m_modeController, m_configuration, m_storage); auto equalizer = std::make_shared>(); ON_CALL(*(equalizer.get()), getMinimumBandLevel()).WillByDefault(Return(MIN_LEVEL)); ON_CALL(*(equalizer.get()), getMaximumBandLevel()).WillByDefault(Return(MIN_LEVEL)); controller->registerEqualizer(equalizer); EqualizerBandLevelMap bandLevelMap; EXPECT_CALL(*(equalizer.get()), setEqualizerBandLevels(_)).Times(1).WillOnce(SaveArg<0>(&bandLevelMap)); controller->setBandLevel(EqualizerBand::MIDRANGE, MAX_LEVEL); EXPECT_EQ(bandLevelMap[EqualizerBand::MIDRANGE], MIN_LEVEL); } } // namespace test } // namespace equalizer } // namespace alexaClientSDK