summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/audio/voip/test/voip_core_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libwebrtc/audio/voip/test/voip_core_unittest.cc')
-rw-r--r--third_party/libwebrtc/audio/voip/test/voip_core_unittest.cc193
1 files changed, 193 insertions, 0 deletions
diff --git a/third_party/libwebrtc/audio/voip/test/voip_core_unittest.cc b/third_party/libwebrtc/audio/voip/test/voip_core_unittest.cc
new file mode 100644
index 0000000000..b432506b12
--- /dev/null
+++ b/third_party/libwebrtc/audio/voip/test/voip_core_unittest.cc
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "audio/voip/voip_core.h"
+
+#include "api/audio_codecs/builtin_audio_decoder_factory.h"
+#include "api/audio_codecs/builtin_audio_encoder_factory.h"
+#include "api/task_queue/default_task_queue_factory.h"
+#include "modules/audio_device/include/mock_audio_device.h"
+#include "modules/audio_processing/include/mock_audio_processing.h"
+#include "test/gtest.h"
+#include "test/mock_transport.h"
+#include "test/run_loop.h"
+
+namespace webrtc {
+namespace {
+
+using ::testing::NiceMock;
+using ::testing::Return;
+
+constexpr int kPcmuPayload = 0;
+constexpr int kPcmuSampleRateHz = 8000;
+constexpr int kDtmfEventDurationMs = 1000;
+constexpr DtmfEvent kDtmfEventCode = DtmfEvent::kDigitZero;
+
+class VoipCoreTest : public ::testing::Test {
+ public:
+ const SdpAudioFormat kPcmuFormat = {"pcmu", 8000, 1};
+
+ VoipCoreTest() { audio_device_ = test::MockAudioDeviceModule::CreateNice(); }
+
+ void SetUp() override {
+ auto encoder_factory = CreateBuiltinAudioEncoderFactory();
+ auto decoder_factory = CreateBuiltinAudioDecoderFactory();
+ rtc::scoped_refptr<AudioProcessing> audio_processing =
+ rtc::make_ref_counted<NiceMock<test::MockAudioProcessing>>();
+
+ voip_core_ = std::make_unique<VoipCore>(
+ std::move(encoder_factory), std::move(decoder_factory),
+ CreateDefaultTaskQueueFactory(), audio_device_,
+ std::move(audio_processing));
+ }
+
+ test::RunLoop run_loop_;
+ std::unique_ptr<VoipCore> voip_core_;
+ NiceMock<MockTransport> transport_;
+ rtc::scoped_refptr<test::MockAudioDeviceModule> audio_device_;
+};
+
+// Validate expected API calls that involves with VoipCore. Some verification is
+// involved with checking mock audio device.
+TEST_F(VoipCoreTest, BasicVoipCoreOperation) {
+ // Program mock as non-operational and ready to start.
+ EXPECT_CALL(*audio_device_, Recording()).WillOnce(Return(false));
+ EXPECT_CALL(*audio_device_, Playing()).WillOnce(Return(false));
+ EXPECT_CALL(*audio_device_, InitRecording()).WillOnce(Return(0));
+ EXPECT_CALL(*audio_device_, InitPlayout()).WillOnce(Return(0));
+ EXPECT_CALL(*audio_device_, StartRecording()).WillOnce(Return(0));
+ EXPECT_CALL(*audio_device_, StartPlayout()).WillOnce(Return(0));
+
+ auto channel = voip_core_->CreateChannel(&transport_, 0xdeadc0de);
+
+ EXPECT_EQ(voip_core_->SetSendCodec(channel, kPcmuPayload, kPcmuFormat),
+ VoipResult::kOk);
+ EXPECT_EQ(
+ voip_core_->SetReceiveCodecs(channel, {{kPcmuPayload, kPcmuFormat}}),
+ VoipResult::kOk);
+
+ EXPECT_EQ(voip_core_->StartSend(channel), VoipResult::kOk);
+ EXPECT_EQ(voip_core_->StartPlayout(channel), VoipResult::kOk);
+
+ EXPECT_EQ(voip_core_->RegisterTelephoneEventType(channel, kPcmuPayload,
+ kPcmuSampleRateHz),
+ VoipResult::kOk);
+
+ EXPECT_EQ(
+ voip_core_->SendDtmfEvent(channel, kDtmfEventCode, kDtmfEventDurationMs),
+ VoipResult::kOk);
+
+ // Program mock as operational that is ready to be stopped.
+ EXPECT_CALL(*audio_device_, Recording()).WillOnce(Return(true));
+ EXPECT_CALL(*audio_device_, Playing()).WillOnce(Return(true));
+ EXPECT_CALL(*audio_device_, StopRecording()).WillOnce(Return(0));
+ EXPECT_CALL(*audio_device_, StopPlayout()).WillOnce(Return(0));
+
+ EXPECT_EQ(voip_core_->StopSend(channel), VoipResult::kOk);
+ EXPECT_EQ(voip_core_->StopPlayout(channel), VoipResult::kOk);
+ EXPECT_EQ(voip_core_->ReleaseChannel(channel), VoipResult::kOk);
+}
+
+TEST_F(VoipCoreTest, ExpectFailToUseReleasedChannelId) {
+ auto channel = voip_core_->CreateChannel(&transport_, 0xdeadc0de);
+
+ // Release right after creation.
+ EXPECT_EQ(voip_core_->ReleaseChannel(channel), VoipResult::kOk);
+
+ // Now use released channel.
+
+ EXPECT_EQ(voip_core_->SetSendCodec(channel, kPcmuPayload, kPcmuFormat),
+ VoipResult::kInvalidArgument);
+ EXPECT_EQ(
+ voip_core_->SetReceiveCodecs(channel, {{kPcmuPayload, kPcmuFormat}}),
+ VoipResult::kInvalidArgument);
+ EXPECT_EQ(voip_core_->RegisterTelephoneEventType(channel, kPcmuPayload,
+ kPcmuSampleRateHz),
+ VoipResult::kInvalidArgument);
+ EXPECT_EQ(voip_core_->StartSend(channel), VoipResult::kInvalidArgument);
+ EXPECT_EQ(voip_core_->StartPlayout(channel), VoipResult::kInvalidArgument);
+ EXPECT_EQ(
+ voip_core_->SendDtmfEvent(channel, kDtmfEventCode, kDtmfEventDurationMs),
+ VoipResult::kInvalidArgument);
+}
+
+TEST_F(VoipCoreTest, SendDtmfEventWithoutRegistering) {
+ // Program mock as non-operational and ready to start send.
+ EXPECT_CALL(*audio_device_, Recording()).WillOnce(Return(false));
+ EXPECT_CALL(*audio_device_, InitRecording()).WillOnce(Return(0));
+ EXPECT_CALL(*audio_device_, StartRecording()).WillOnce(Return(0));
+
+ auto channel = voip_core_->CreateChannel(&transport_, 0xdeadc0de);
+
+ EXPECT_EQ(voip_core_->SetSendCodec(channel, kPcmuPayload, kPcmuFormat),
+ VoipResult::kOk);
+
+ EXPECT_EQ(voip_core_->StartSend(channel), VoipResult::kOk);
+ // Send Dtmf event without registering beforehand, thus payload
+ // type is not set and kFailedPrecondition is expected.
+ EXPECT_EQ(
+ voip_core_->SendDtmfEvent(channel, kDtmfEventCode, kDtmfEventDurationMs),
+ VoipResult::kFailedPrecondition);
+
+ // Program mock as sending and is ready to be stopped.
+ EXPECT_CALL(*audio_device_, Recording()).WillOnce(Return(true));
+ EXPECT_CALL(*audio_device_, StopRecording()).WillOnce(Return(0));
+
+ EXPECT_EQ(voip_core_->StopSend(channel), VoipResult::kOk);
+ EXPECT_EQ(voip_core_->ReleaseChannel(channel), VoipResult::kOk);
+}
+
+TEST_F(VoipCoreTest, SendDtmfEventWithoutStartSend) {
+ auto channel = voip_core_->CreateChannel(&transport_, 0xdeadc0de);
+
+ EXPECT_EQ(voip_core_->RegisterTelephoneEventType(channel, kPcmuPayload,
+ kPcmuSampleRateHz),
+ VoipResult::kOk);
+
+ // Send Dtmf event without calling StartSend beforehand, thus
+ // Dtmf events cannot be sent and kFailedPrecondition is expected.
+ EXPECT_EQ(
+ voip_core_->SendDtmfEvent(channel, kDtmfEventCode, kDtmfEventDurationMs),
+ VoipResult::kFailedPrecondition);
+
+ EXPECT_EQ(voip_core_->ReleaseChannel(channel), VoipResult::kOk);
+}
+
+TEST_F(VoipCoreTest, StartSendAndPlayoutWithoutSettingCodec) {
+ auto channel = voip_core_->CreateChannel(&transport_, 0xdeadc0de);
+
+ // Call StartSend and StartPlayout without setting send/receive
+ // codec. Code should see that codecs aren't set and return false.
+ EXPECT_EQ(voip_core_->StartSend(channel), VoipResult::kFailedPrecondition);
+ EXPECT_EQ(voip_core_->StartPlayout(channel), VoipResult::kFailedPrecondition);
+
+ EXPECT_EQ(voip_core_->ReleaseChannel(channel), VoipResult::kOk);
+}
+
+TEST_F(VoipCoreTest, StopSendAndPlayoutWithoutStarting) {
+ auto channel = voip_core_->CreateChannel(&transport_, 0xdeadc0de);
+
+ EXPECT_EQ(voip_core_->SetSendCodec(channel, kPcmuPayload, kPcmuFormat),
+ VoipResult::kOk);
+ EXPECT_EQ(
+ voip_core_->SetReceiveCodecs(channel, {{kPcmuPayload, kPcmuFormat}}),
+ VoipResult::kOk);
+
+ // Call StopSend and StopPlayout without starting them in
+ // the first place. Should see that it is already in the
+ // stopped state and return true.
+ EXPECT_EQ(voip_core_->StopSend(channel), VoipResult::kOk);
+ EXPECT_EQ(voip_core_->StopPlayout(channel), VoipResult::kOk);
+
+ EXPECT_EQ(voip_core_->ReleaseChannel(channel), VoipResult::kOk);
+}
+
+} // namespace
+} // namespace webrtc