LCOV - code coverage report
Current view: top level - test/unitTest/call - recorder.cpp (source / functions) Hit Total Coverage
Test: jami-coverage-filtered.info Lines: 238 239 99.6 %
Date: 2024-05-04 07:58:46 Functions: 47 47 100.0 %

          Line data    Source code
       1             : /*
       2             :  *  Copyright (C) 2022-2024 Savoir-faire Linux Inc.
       3             :  *  Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
       4             :  *
       5             :  *  This program is free software; you can redistribute it and/or modify
       6             :  *  it under the terms of the GNU General Public License as published by
       7             :  *  the Free Software Foundation; either version 3 of the License, or
       8             :  *  (at your option) any later version.
       9             :  *
      10             :  *  This program is distributed in the hope that it will be useful,
      11             :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      12             :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13             :  *  GNU General Public License for more details.
      14             :  *
      15             :  *  You should have received a copy of the GNU General Public License
      16             :  *  along with this program. If not, see <https://www.gnu.org/licenses/>.
      17             :  */
      18             : 
      19             : #include <cppunit/TestAssert.h>
      20             : #include <cppunit/TestFixture.h>
      21             : #include <cppunit/extensions/HelperMacros.h>
      22             : 
      23             : #include <condition_variable>
      24             : #include <filesystem>
      25             : #include <string>
      26             : 
      27             : #include "../../test_runner.h"
      28             : #include "account_const.h"
      29             : #include "fileutils.h"
      30             : #include "jami.h"
      31             : #include "jamidht/jamiaccount.h"
      32             : #include "manager.h"
      33             : #include "media_const.h"
      34             : #include "client/videomanager.h"
      35             : 
      36             : #include "common.h"
      37             : 
      38             : using namespace libjami::Account;
      39             : using namespace std::literals::chrono_literals;
      40             : 
      41             : namespace jami {
      42             : namespace test {
      43             : 
      44             : struct CallData
      45             : {
      46             :     std::string callId {};
      47             :     std::string state {};
      48             :     std::string mediaStatus {};
      49             :     std::string device {};
      50             :     std::string hostState {};
      51             :     bool changeRequested = false;
      52             : 
      53           5 :     void reset()
      54             :     {
      55           5 :         callId = "";
      56           5 :         state = "";
      57           5 :         mediaStatus = "";
      58           5 :         device = "";
      59           5 :         hostState = "";
      60           5 :     }
      61             : };
      62             : 
      63             : class RecorderTest : public CppUnit::TestFixture
      64             : {
      65             : public:
      66           5 :     RecorderTest()
      67           5 :     {
      68             :         // Init daemon
      69           5 :         libjami::init(libjami::InitFlag(libjami::LIBJAMI_FLAG_DEBUG | libjami::LIBJAMI_FLAG_CONSOLE_LOG));
      70           5 :         if (not Manager::instance().initialized)
      71           1 :             CPPUNIT_ASSERT(libjami::start("jami-sample.yml"));
      72           5 :     }
      73          10 :     ~RecorderTest() { libjami::fini(); }
      74           2 :     static std::string name() { return "Recorder"; }
      75             :     void setUp();
      76             :     void tearDown();
      77             : 
      78             :     std::string aliceId {};
      79             :     std::string bobId {};
      80             :     std::string recordDir {};
      81             :     std::string recordedFile {};
      82             :     std::string playerId {};
      83             :     std::shared_ptr<MediaPlayer> player {};
      84             :     CallData bobCall {};
      85             : 
      86             :     std::mutex mtx;
      87             :     std::unique_lock<std::mutex> lk {mtx};
      88             :     std::condition_variable cv;
      89             : 
      90             :     std::string videoPath = "file://" + std::filesystem::absolute("media/test_video_file.mp4").string();
      91             : 
      92             : private:
      93             :     void registerSignalHandlers();
      94             :     void testRecordCall();
      95             :     void testRecordAudioOnlyCall();
      96             :     void testRecordCallOnePersonRdv();
      97             :     void testStopCallWhileRecording();
      98             :     void testDaemonPreference();
      99             : 
     100           2 :     CPPUNIT_TEST_SUITE(RecorderTest);
     101           1 :     CPPUNIT_TEST(testRecordCall);
     102           1 :     CPPUNIT_TEST(testRecordAudioOnlyCall);
     103           1 :     CPPUNIT_TEST(testRecordCallOnePersonRdv);
     104           1 :     CPPUNIT_TEST(testStopCallWhileRecording);
     105           1 :     CPPUNIT_TEST(testDaemonPreference);
     106           4 :     CPPUNIT_TEST_SUITE_END();
     107             : };
     108             : 
     109             : CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(RecorderTest, RecorderTest::name());
     110             : 
     111             : void
     112           5 : RecorderTest::setUp()
     113             : {
     114             :     // Generate a temporary directory with a file inside
     115           5 :     recordDir = "records";
     116           5 :     dhtnet::fileutils::recursive_mkdir(recordDir.c_str());
     117           5 :     CPPUNIT_ASSERT(std::filesystem::is_directory(recordDir));
     118             : 
     119          10 :     auto actors = load_actors_and_wait_for_announcement("actors/alice-bob.yml");
     120           5 :     aliceId = actors["alice"];
     121           5 :     bobId = actors["bob"];
     122           5 :     bobCall.reset();
     123           5 :     playerId = jami::createMediaPlayer(videoPath);
     124           5 :     player = jami::getMediaPlayer(playerId);
     125           5 :     player->setAutoRestart(true);
     126           5 :     player->pause(false);
     127             : 
     128           5 :     libjami::setRecordPath(recordDir);
     129           5 : }
     130             : 
     131             : void
     132           5 : RecorderTest::tearDown()
     133             : {
     134           5 :     player.reset();
     135           5 :     jami::closeMediaPlayer(playerId);
     136           5 :     libjami::setIsAlwaysRecording(false);
     137           5 :     dhtnet::fileutils::removeAll(recordDir);
     138             : 
     139          15 :     wait_for_removal_of({aliceId, bobId});
     140           5 : }
     141             : 
     142             : void
     143           5 : RecorderTest::registerSignalHandlers()
     144             : {
     145           5 :     auto aliceAccount = Manager::instance().getAccount<JamiAccount>(aliceId);
     146           5 :     auto bobAccount = Manager::instance().getAccount<JamiAccount>(bobId);
     147           5 :     auto bobUri = bobAccount->getUsername();
     148             : 
     149           5 :     std::map<std::string, std::shared_ptr<libjami::CallbackWrapperBase>> confHandlers;
     150             :     // Watch signals
     151           5 :     confHandlers.insert(libjami::exportable_callback<libjami::CallSignal::IncomingCallWithMedia>(
     152           5 :         [=](const std::string& accountId,
     153             :             const std::string& callId,
     154             :             const std::string&,
     155             :             const std::vector<std::map<std::string, std::string>>&) {
     156           5 :             if (accountId == bobId) {
     157           5 :                 bobCall.callId = callId;
     158             :             }
     159           5 :             cv.notify_one();
     160           5 :         }));
     161           5 :     confHandlers.insert(libjami::exportable_callback<libjami::CallSignal::MediaChangeRequested>(
     162           1 :         [=](const std::string& accountId,
     163             :             const std::string& callId,
     164             :             const std::vector<std::map<std::string, std::string>>&) {
     165           1 :             if (accountId == bobId && bobCall.callId == callId) {
     166           1 :                 bobCall.changeRequested = true;
     167             :             }
     168           1 :         }));
     169           5 :     confHandlers.insert(
     170          10 :         libjami::exportable_callback<libjami::CallSignal::StateChange>([=](const std::string& accountId,
     171             :                                                                        const std::string& callId,
     172             :                                                                        const std::string& state,
     173             :                                                                        signed) {
     174          55 :             if (accountId == aliceId) {
     175          25 :                 auto details = libjami::getCallDetails(aliceId, callId);
     176          25 :                 if (details["PEER_NUMBER"].find(bobUri) != std::string::npos)
     177          25 :                     bobCall.hostState = state;
     178          55 :             } else if (bobCall.callId == callId)
     179          15 :                 bobCall.state = state;
     180          55 :             cv.notify_one();
     181          55 :         }));
     182             : 
     183           5 :     confHandlers.insert(libjami::exportable_callback<libjami::CallSignal::MediaNegotiationStatus>(
     184          19 :         [&](const std::string& callId,
     185             :             const std::string& event,
     186             :             const std::vector<std::map<std::string, std::string>>&) {
     187          19 :             if (callId == bobCall.callId)
     188           9 :                 bobCall.mediaStatus = event;
     189          19 :             cv.notify_one();
     190          19 :         }));
     191           5 :     confHandlers.insert(libjami::exportable_callback<libjami::CallSignal::RecordPlaybackStopped>(
     192           9 :         [&](const std::string& path) {
     193           9 :             recordedFile = path;
     194           9 :             cv.notify_one();
     195           9 :         }));
     196           5 :     libjami::registerSignalHandlers(confHandlers);
     197           5 : }
     198             : 
     199             : void
     200           1 : RecorderTest::testRecordCall()
     201             : {
     202           1 :     JAMI_INFO("Start testRecordCall");
     203           1 :     registerSignalHandlers();
     204           1 :     auto aliceAccount = Manager::instance().getAccount<JamiAccount>(aliceId);
     205           1 :     auto bobAccount = Manager::instance().getAccount<JamiAccount>(bobId);
     206           1 :     auto bobUri = bobAccount->getUsername();
     207             : 
     208           1 :     JAMI_INFO("Start call between Alice and Bob");
     209           1 :     std::vector<std::map<std::string, std::string>> mediaList;
     210             :     std::map<std::string, std::string> mediaAttributeA
     211             :         = {{libjami::Media::MediaAttributeKey::MEDIA_TYPE, libjami::Media::MediaAttributeValue::AUDIO},
     212             :         {libjami::Media::MediaAttributeKey::ENABLED, TRUE_STR},
     213             :         {libjami::Media::MediaAttributeKey::MUTED, FALSE_STR},
     214             :         {libjami::Media::MediaAttributeKey::LABEL, "audio_0"},
     215           7 :         {libjami::Media::MediaAttributeKey::SOURCE, ""}};
     216             :     std::map<std::string, std::string> mediaAttributeV
     217             :         = {{libjami::Media::MediaAttributeKey::MEDIA_TYPE, libjami::Media::MediaAttributeValue::VIDEO},
     218             :         {libjami::Media::MediaAttributeKey::ENABLED, TRUE_STR},
     219             :         {libjami::Media::MediaAttributeKey::MUTED, FALSE_STR},
     220             :         {libjami::Media::MediaAttributeKey::LABEL, "video_0"},
     221           7 :         {libjami::Media::MediaAttributeKey::SOURCE, videoPath}};
     222           1 :     mediaList.emplace_back(mediaAttributeA);
     223           1 :     auto callId = libjami::placeCallWithMedia(aliceId, bobUri, mediaList);
     224           7 :     CPPUNIT_ASSERT(cv.wait_for(lk, 20s, [&] { return !bobCall.callId.empty(); }));
     225           1 :     libjami::acceptWithMedia(bobId, bobCall.callId, mediaList);
     226           5 :     CPPUNIT_ASSERT(cv.wait_for(lk, 20s, [&] {
     227             :         return bobCall.mediaStatus
     228             :                == libjami::Media::MediaNegotiationStatusEvents::NEGOTIATION_SUCCESS;
     229             :     }));
     230             : 
     231           1 :     std::this_thread::sleep_for(5s);
     232             : 
     233             :     // Start recorder
     234           1 :     recordedFile.clear();
     235           1 :     CPPUNIT_ASSERT(!libjami::getIsRecording(aliceId, callId));
     236           1 :     libjami::toggleRecording(aliceId, callId);
     237           1 :     std::this_thread::sleep_for(5s);
     238           1 :     CPPUNIT_ASSERT(libjami::getIsRecording(aliceId, callId));
     239             : 
     240           2 :     CPPUNIT_ASSERT(cv.wait_for(lk, 20s, [&] { return recordedFile.empty(); }));
     241             : 
     242             :     // add local video
     243             :     {
     244           1 :         auto newMediaList = mediaList;
     245           1 :         newMediaList.emplace_back(mediaAttributeV);
     246             : 
     247             :         // Request Media Change
     248           1 :         libjami::requestMediaChange(aliceId, callId, newMediaList);
     249             : 
     250           3 :         CPPUNIT_ASSERT(cv.wait_for(lk, 10s, [&] { return bobCall.changeRequested; }));
     251             : 
     252             :         // Answer the change request
     253           1 :         bobCall.mediaStatus = "";
     254           1 :         libjami::answerMediaChangeRequest(bobId, bobCall.callId, newMediaList);
     255           1 :         bobCall.changeRequested = false;
     256           3 :         CPPUNIT_ASSERT(cv.wait_for(lk, 20s, [&] {
     257             :             return bobCall.mediaStatus
     258             :                 == libjami::Media::MediaNegotiationStatusEvents::NEGOTIATION_SUCCESS;
     259             :         }));
     260             : 
     261           4 :         CPPUNIT_ASSERT(cv.wait_for(lk, 20s, [&] { return !recordedFile.empty() && recordedFile.find(".ogg") != std::string::npos; }));
     262           1 :         recordedFile = "";
     263             :         // give time to start camera
     264           1 :         std::this_thread::sleep_for(10s);
     265             : 
     266           2 :         CPPUNIT_ASSERT(cv.wait_for(lk, 20s, [&] { return recordedFile.empty(); }));
     267           1 :     }
     268             : 
     269             :     // mute local video
     270             :     {
     271           1 :         mediaAttributeV[libjami::Media::MediaAttributeKey::MUTED] = TRUE_STR;
     272           1 :         auto newMediaList = mediaList;
     273           1 :         newMediaList.emplace_back(mediaAttributeV);
     274             : 
     275             :         // Mute Bob video
     276           1 :         libjami::requestMediaChange(aliceId, callId, newMediaList);
     277           1 :         std::this_thread::sleep_for(5s);
     278           1 :         libjami::requestMediaChange(bobId, bobCall.callId, newMediaList);
     279             : 
     280           4 :         CPPUNIT_ASSERT(cv.wait_for(lk, 20s, [&] { return !recordedFile.empty() && recordedFile.find(".webm") != std::string::npos; }));
     281           1 :         recordedFile = "";
     282           1 :         std::this_thread::sleep_for(10s);
     283           1 :     }
     284             : 
     285             :     // Stop recorder after a few seconds
     286           1 :     libjami::toggleRecording(aliceId, callId);
     287           1 :     CPPUNIT_ASSERT(!libjami::getIsRecording(aliceId, callId));
     288             : 
     289           2 :     CPPUNIT_ASSERT(cv.wait_for(lk, 20s, [&] { return !recordedFile.empty() && recordedFile.find(".ogg") != std::string::npos; }));
     290             : 
     291           1 :     Manager::instance().hangupCall(aliceId, callId);
     292           5 :     CPPUNIT_ASSERT(cv.wait_for(lk, 20s, [&] { return bobCall.state == "OVER"; }));
     293           1 :     JAMI_INFO("End testRecordCall");
     294           1 : }
     295             : 
     296             : void
     297           1 : RecorderTest::testRecordAudioOnlyCall()
     298             : {
     299           1 :     JAMI_INFO("Start testRecordAudioOnlyCall");
     300           1 :     registerSignalHandlers();
     301           1 :     auto aliceAccount = Manager::instance().getAccount<JamiAccount>(aliceId);
     302           1 :     auto bobAccount = Manager::instance().getAccount<JamiAccount>(bobId);
     303           1 :     auto bobUri = bobAccount->getUsername();
     304             : 
     305           1 :     JAMI_INFO("Start call between Alice and Bob");
     306             :     // Audio only call
     307           1 :     std::vector<std::map<std::string, std::string>> mediaList;
     308             :     std::map<std::string, std::string> mediaAttribute
     309             :         = {{libjami::Media::MediaAttributeKey::MEDIA_TYPE, libjami::Media::MediaAttributeValue::AUDIO},
     310             :            {libjami::Media::MediaAttributeKey::ENABLED, TRUE_STR},
     311             :            {libjami::Media::MediaAttributeKey::MUTED, FALSE_STR},
     312             :            {libjami::Media::MediaAttributeKey::LABEL, "audio_0"},
     313           7 :            {libjami::Media::MediaAttributeKey::SOURCE, ""}};
     314           1 :     mediaList.emplace_back(mediaAttribute);
     315           1 :     auto callId = libjami::placeCallWithMedia(aliceId, bobUri, mediaList);
     316           7 :     CPPUNIT_ASSERT(cv.wait_for(lk, 20s, [&] { return !bobCall.callId.empty(); }));
     317           1 :     libjami::acceptWithMedia(bobId, bobCall.callId, mediaList);
     318           4 :     CPPUNIT_ASSERT(cv.wait_for(lk, 20s, [&] {
     319             :         return bobCall.mediaStatus
     320             :                == libjami::Media::MediaNegotiationStatusEvents::NEGOTIATION_SUCCESS;
     321             :     }));
     322             : 
     323             :     // Start recorder
     324           1 :     recordedFile.clear();
     325           1 :     libjami::toggleRecording(aliceId, callId);
     326           1 :     std::this_thread::sleep_for(5s);
     327           1 :     CPPUNIT_ASSERT(libjami::getIsRecording(aliceId, callId));
     328             : 
     329             :     // Toggle recording
     330           1 :     libjami::toggleRecording(aliceId, callId);
     331           1 :     CPPUNIT_ASSERT(!libjami::getIsRecording(aliceId, callId));
     332             : 
     333           2 :     CPPUNIT_ASSERT(cv.wait_for(lk, 20s, [&] {
     334             :         return !recordedFile.empty() && recordedFile.find(".ogg") != std::string::npos;
     335             :     }));
     336             : 
     337           1 :     Manager::instance().hangupCall(aliceId, callId);
     338           2 :     CPPUNIT_ASSERT(cv.wait_for(lk, 20s, [&] { return bobCall.state == "OVER"; }));
     339           1 :     JAMI_INFO("End testRecordAudioOnlyCall");
     340           1 : }
     341             : 
     342             : void
     343           1 : RecorderTest::testRecordCallOnePersonRdv()
     344             : {
     345           1 :     JAMI_INFO("Start testRecordCallOnePersonRdv");
     346           1 :     registerSignalHandlers();
     347           1 :     auto aliceAccount = Manager::instance().getAccount<JamiAccount>(aliceId);
     348           1 :     auto bobAccount = Manager::instance().getAccount<JamiAccount>(bobId);
     349           1 :     auto bobUri = bobAccount->getUsername();
     350             : 
     351             :     try {
     352           1 :         bobAccount->editConfig(
     353           1 :             [&](AccountConfig& config) { config.isRendezVous = true; });
     354           0 :     } catch (...) {}
     355             : 
     356           1 :     CPPUNIT_ASSERT(bobAccount->config().isRendezVous);
     357             : 
     358           1 :     recordedFile.clear();
     359             : 
     360           1 :     JAMI_INFO("Start call between Alice and Bob");
     361             :     // Audio only call
     362           1 :     std::vector<std::map<std::string, std::string>> mediaList;
     363             :     std::map<std::string, std::string> mediaAttributeA
     364             :         = {{libjami::Media::MediaAttributeKey::MEDIA_TYPE, libjami::Media::MediaAttributeValue::AUDIO},
     365             :            {libjami::Media::MediaAttributeKey::ENABLED, TRUE_STR},
     366             :            {libjami::Media::MediaAttributeKey::MUTED, FALSE_STR},
     367             :            {libjami::Media::MediaAttributeKey::LABEL, "audio_0"},
     368           7 :            {libjami::Media::MediaAttributeKey::SOURCE, ""}};
     369           1 :     mediaList.emplace_back(mediaAttributeA);
     370           1 :     auto callId = libjami::placeCallWithMedia(aliceId, bobUri, mediaList);
     371           7 :     CPPUNIT_ASSERT(cv.wait_for(lk, 20s, [&] { return !bobCall.callId.empty(); }));
     372           7 :     CPPUNIT_ASSERT(cv.wait_for(lk, 20s, [&] {
     373             :         return bobCall.mediaStatus
     374             :                == libjami::Media::MediaNegotiationStatusEvents::NEGOTIATION_SUCCESS;
     375             :     }));
     376             : 
     377           1 :     CPPUNIT_ASSERT(!libjami::getIsRecording(aliceId, callId));
     378           1 :     libjami::toggleRecording(aliceId, callId);
     379           1 :     std::this_thread::sleep_for(5s);
     380             : 
     381           1 :     CPPUNIT_ASSERT(libjami::getIsRecording(aliceId, callId));
     382             : 
     383             :     // Stop recorder
     384           1 :     libjami::toggleRecording(aliceId, callId);
     385           1 :     CPPUNIT_ASSERT(!libjami::getIsRecording(aliceId, callId));
     386             : 
     387           2 :     CPPUNIT_ASSERT(cv.wait_for(lk, 20s, [&] { return !recordedFile.empty() && recordedFile.find(".ogg") != std::string::npos; }));
     388             : 
     389           1 :     Manager::instance().hangupCall(aliceId, callId);
     390           4 :     CPPUNIT_ASSERT(
     391             :         cv.wait_for(lk, 20s, [&] { return bobCall.state == "OVER"; }));
     392           1 :     JAMI_INFO("End testRecordCallOnePersonRdv");
     393           1 : }
     394             : 
     395             : void
     396           1 : RecorderTest::testStopCallWhileRecording()
     397             : {
     398           1 :     JAMI_INFO("Start testStopCallWhileRecording");
     399           1 :     registerSignalHandlers();
     400           1 :     auto aliceAccount = Manager::instance().getAccount<JamiAccount>(aliceId);
     401           1 :     auto bobAccount = Manager::instance().getAccount<JamiAccount>(bobId);
     402           1 :     auto bobUri = bobAccount->getUsername();
     403             : 
     404           1 :     JAMI_INFO("Start call between Alice and Bob");
     405           1 :     std::vector<std::map<std::string, std::string>> mediaList;
     406             :     std::map<std::string, std::string> mediaAttributeA
     407             :         = {{libjami::Media::MediaAttributeKey::MEDIA_TYPE, libjami::Media::MediaAttributeValue::AUDIO},
     408             :         {libjami::Media::MediaAttributeKey::ENABLED, TRUE_STR},
     409             :         {libjami::Media::MediaAttributeKey::MUTED, FALSE_STR},
     410             :         {libjami::Media::MediaAttributeKey::LABEL, "audio_0"},
     411           7 :         {libjami::Media::MediaAttributeKey::SOURCE, ""}};
     412             :     std::map<std::string, std::string> mediaAttributeV
     413             :         = {{libjami::Media::MediaAttributeKey::MEDIA_TYPE, libjami::Media::MediaAttributeValue::VIDEO},
     414             :         {libjami::Media::MediaAttributeKey::ENABLED, TRUE_STR},
     415             :         {libjami::Media::MediaAttributeKey::MUTED, FALSE_STR},
     416             :         {libjami::Media::MediaAttributeKey::LABEL, "video_0"},
     417           7 :         {libjami::Media::MediaAttributeKey::SOURCE, videoPath}};
     418           1 :     mediaList.emplace_back(mediaAttributeA);
     419           1 :     mediaList.emplace_back(mediaAttributeV);
     420           1 :     auto callId = libjami::placeCallWithMedia(aliceId, bobUri, mediaList);
     421           7 :     CPPUNIT_ASSERT(cv.wait_for(lk, 20s, [&] { return !bobCall.callId.empty(); }));
     422           1 :     libjami::acceptWithMedia(bobId, bobCall.callId, mediaList);
     423           5 :     CPPUNIT_ASSERT(cv.wait_for(lk, 20s, [&] {
     424             :         return bobCall.mediaStatus
     425             :                == libjami::Media::MediaNegotiationStatusEvents::NEGOTIATION_SUCCESS;
     426             :     }));
     427             : 
     428             :     // give time to start camera
     429           1 :     std::this_thread::sleep_for(5s);
     430             : 
     431             :     // Start recorder
     432           1 :     recordedFile.clear();
     433           1 :     libjami::toggleRecording(aliceId, callId);
     434           1 :     std::this_thread::sleep_for(10s);
     435           1 :     CPPUNIT_ASSERT(libjami::getIsRecording(aliceId, callId));
     436             : 
     437             :     // Hangup call
     438           1 :     Manager::instance().hangupCall(aliceId, callId);
     439           6 :     CPPUNIT_ASSERT(
     440             :         cv.wait_for(lk, 20s, [&] { return bobCall.state == "OVER" && !recordedFile.empty() && recordedFile.find(".webm") != std::string::npos; }));
     441           1 :     JAMI_INFO("End testStopCallWhileRecording");
     442           1 : }
     443             : 
     444             : void
     445           1 : RecorderTest::testDaemonPreference()
     446             : {
     447           1 :     JAMI_INFO("Start testDaemonPreference");
     448           1 :     registerSignalHandlers();
     449           1 :     auto aliceAccount = Manager::instance().getAccount<JamiAccount>(aliceId);
     450           1 :     auto bobAccount = Manager::instance().getAccount<JamiAccount>(bobId);
     451           1 :     auto bobUri = bobAccount->getUsername();
     452             : 
     453           1 :     libjami::setIsAlwaysRecording(true);
     454           1 :     recordedFile.clear();
     455             : 
     456           1 :     JAMI_INFO("Start call between Alice and Bob");
     457           1 :     std::vector<std::map<std::string, std::string>> mediaList;
     458             :     std::map<std::string, std::string> mediaAttributeA
     459             :         = {{libjami::Media::MediaAttributeKey::MEDIA_TYPE, libjami::Media::MediaAttributeValue::AUDIO},
     460             :         {libjami::Media::MediaAttributeKey::ENABLED, TRUE_STR},
     461             :         {libjami::Media::MediaAttributeKey::MUTED, FALSE_STR},
     462             :         {libjami::Media::MediaAttributeKey::LABEL, "audio_0"},
     463           7 :         {libjami::Media::MediaAttributeKey::SOURCE, ""}};
     464             :     std::map<std::string, std::string> mediaAttributeV
     465             :         = {{libjami::Media::MediaAttributeKey::MEDIA_TYPE, libjami::Media::MediaAttributeValue::VIDEO},
     466             :         {libjami::Media::MediaAttributeKey::ENABLED, TRUE_STR},
     467             :         {libjami::Media::MediaAttributeKey::MUTED, FALSE_STR},
     468             :         {libjami::Media::MediaAttributeKey::LABEL, "video_0"},
     469           7 :         {libjami::Media::MediaAttributeKey::SOURCE, videoPath}};
     470           1 :     mediaList.emplace_back(mediaAttributeA);
     471           1 :     mediaList.emplace_back(mediaAttributeV);
     472           1 :     auto callId = libjami::placeCallWithMedia(aliceId, bobUri, mediaList);
     473           7 :     CPPUNIT_ASSERT(cv.wait_for(lk, 20s, [&] { return !bobCall.callId.empty(); }));
     474           1 :     libjami::acceptWithMedia(bobId, bobCall.callId, mediaList);
     475           4 :     CPPUNIT_ASSERT(cv.wait_for(lk, 20s, [&] {
     476             :         return bobCall.mediaStatus
     477             :                == libjami::Media::MediaNegotiationStatusEvents::NEGOTIATION_SUCCESS;
     478             :     }));
     479             : 
     480             :     // Let record some seconds
     481           1 :     std::this_thread::sleep_for(5s);
     482           1 :     CPPUNIT_ASSERT(libjami::getIsRecording(aliceId, callId));
     483           1 :     std::this_thread::sleep_for(10s);
     484             : 
     485           1 :     Manager::instance().hangupCall(aliceId, callId);
     486           2 :     CPPUNIT_ASSERT(
     487             :         cv.wait_for(lk, 20s, [&] { return bobCall.state == "OVER" && !recordedFile.empty() && recordedFile.find(".webm") != std::string::npos; }));
     488           1 :     JAMI_INFO("End testDaemonPreference");
     489           1 : }
     490             : 
     491             : } // namespace test
     492             : } // namespace jami
     493             : 
     494           1 : RING_TEST_RUNNER(jami::test::RecorderTest::name())

Generated by: LCOV version 1.14