LCOV - code coverage report
Current view: top level - test/unitTest - common.cpp (source / functions) Hit Total Coverage
Test: jami-coverage-filtered.info Lines: 98 103 95.1 %
Date: 2024-04-15 08:03:09 Functions: 10 10 100.0 %

          Line data    Source code
       1             : /*
       2             :  *  Copyright (C) 2021-2024 Savoir-faire Linux Inc.
       3             :  *
       4             :  *  Author: Olivier Dion <olivier.dion>@savoirfairelinux.com>
       5             :  *
       6             :  *  This program is free software; you can redistribute it and/or modify
       7             :  *  it under the terms of the GNU General Public License as published by
       8             :  *  the Free Software Foundation; either version 3 of the License, or
       9             :  *  (at your option) any later version.
      10             :  *
      11             :  *  This program is distributed in the hope that it will be useful,
      12             :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :  *  GNU General Public License for more details.
      15             :  *
      16             :  *  You should have received a copy of the GNU General Public License
      17             :  *  along with this program; if not, write to the Free Software
      18             :  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
      19             :  */
      20             : 
      21             : #include <cppunit/TestAssert.h>
      22             : #include <cppunit/TestFixture.h>
      23             : #include <cppunit/extensions/HelperMacros.h>
      24             : 
      25             : #include <yaml-cpp/yaml.h>
      26             : 
      27             : #include "common.h"
      28             : 
      29             : /* Jami */
      30             : #include "account_const.h"
      31             : #include "jami.h"
      32             : #include "fileutils.h"
      33             : #include "manager.h"
      34             : 
      35             : /* Make GCC quiet about unused functions */
      36             : #pragma GCC diagnostic push
      37             : #pragma GCC diagnostic ignored "-Wunused-function"
      38             : 
      39             : void
      40         262 : wait_for_announcement_of(const std::vector<std::string> accountIDs,
      41             :                          std::chrono::seconds timeout)
      42             : {
      43         262 :     std::map<std::string, std::shared_ptr<libjami::CallbackWrapperBase>> confHandlers;
      44         262 :     std::mutex mtx;
      45         262 :     std::unique_lock lk {mtx};
      46         262 :     std::condition_variable cv;
      47         262 :     std::vector<std::atomic_bool> accountsReady(accountIDs.size());
      48             : 
      49         262 :     size_t to_be_announced = accountIDs.size();
      50             : 
      51         262 :     confHandlers.insert(
      52         524 :         libjami::exportable_callback<libjami::ConfigurationSignal::VolatileDetailsChanged>(
      53        2522 :             [&,
      54         262 :              accountIDs = std::move(accountIDs)](const std::string& accountID,
      55             :                                                  const std::map<std::string, std::string>& details) {
      56       10969 :                 for (size_t i = 0; i < accountIDs.size(); ++i) {
      57        8447 :                     if (accountIDs[i] != accountID) {
      58        6064 :                         continue;
      59             :                     }
      60             : 
      61        2383 :                     if (jami::Manager::instance().getAccount(accountID)->getAccountType() == "SIP") {
      62           4 :                         auto daemonStatus = details.at(libjami::Account::ConfProperties::Registration::STATUS);
      63           2 :                         if (daemonStatus != "REGISTERED") {
      64           0 :                             continue;
      65             :                         }
      66           2 :                     } else {
      67             :                         try {
      68        4166 :                             if ("true"
      69        2381 :                                 != details.at(libjami::Account::VolatileProperties::DEVICE_ANNOUNCED)) {
      70        1785 :                                 continue;
      71             :                             }
      72           0 :                         } catch (const std::out_of_range&) {
      73           0 :                             continue;
      74           0 :                         }
      75             :                     }
      76             : 
      77         598 :                     accountsReady[i] = true;
      78         598 :                     cv.notify_one();
      79             :                 }
      80        2522 :             }));
      81             : 
      82         262 :     JAMI_DBG("Waiting for %zu account to be announced...", to_be_announced);
      83             : 
      84         262 :     libjami::registerSignalHandlers(confHandlers);
      85             : 
      86        1945 :     CPPUNIT_ASSERT(cv.wait_for(lk, timeout, [&] {
      87             :         for (const auto& rdy : accountsReady) {
      88             :             if (not rdy) {
      89             :                 return false;
      90             :             }
      91             :         }
      92             : 
      93             :         return true;
      94             :     }));
      95             : 
      96         262 :     libjami::unregisterSignalHandlers();
      97             : 
      98         262 :     JAMI_DBG("%zu account announced!", to_be_announced);
      99         262 : }
     100             : 
     101             : void
     102           8 : wait_for_announcement_of(const std::string& accountId,
     103             :                          std::chrono::seconds timeout)
     104             : {
     105          16 :     wait_for_announcement_of(std::vector<std::string> {accountId}, timeout);
     106           8 : }
     107             : 
     108             : void
     109         264 : wait_for_removal_of(const std::vector<std::string> accounts,
     110             :                     std::chrono::seconds timeout)
     111             : {
     112         264 :     JAMI_INFO("Removing %zu accounts...", accounts.size());
     113             : 
     114         264 :     std::map<std::string, std::shared_ptr<libjami::CallbackWrapperBase>> confHandlers;
     115         264 :     std::mutex mtx;
     116         264 :     std::unique_lock lk {mtx};
     117         264 :     std::condition_variable cv;
     118         264 :     std::atomic_bool accountsRemoved {false};
     119             : 
     120         264 :     size_t current = jami::Manager::instance().getAccountList().size();
     121             : 
     122             :     /* Prevent overflow */
     123         264 :     CPPUNIT_ASSERT(current >= accounts.size());
     124             : 
     125         264 :     size_t target = current - accounts.size();
     126             : 
     127         264 :     confHandlers.insert(
     128         528 :         libjami::exportable_callback<libjami::ConfigurationSignal::AccountsChanged>([&]() {
     129         775 :             if (jami::Manager::instance().getAccountList().size() <= target) {
     130         264 :                 accountsRemoved = true;
     131         264 :                 cv.notify_one();
     132             :             }
     133         775 :         }));
     134             : 
     135         264 :     libjami::unregisterSignalHandlers();
     136         264 :     libjami::registerSignalHandlers(confHandlers);
     137             : 
     138        1039 :     for (const auto& account : accounts) {
     139         775 :         jami::Manager::instance().removeAccount(account, true);
     140             :     }
     141             : 
     142         528 :     CPPUNIT_ASSERT(cv.wait_for(lk, timeout, [&] { return accountsRemoved.load(); }));
     143             : 
     144         264 :     libjami::unregisterSignalHandlers();
     145         264 : }
     146             : 
     147             : void
     148          14 : wait_for_removal_of(const std::string& account,
     149             :                     std::chrono::seconds timeout)
     150             : {
     151          28 :     wait_for_removal_of(std::vector<std::string>{account}, timeout);
     152          14 : }
     153             : 
     154             : std::map<std::string, std::string>
     155         255 : load_actors(const std::filesystem::path& from_yaml)
     156             : {
     157         255 :     std::map<std::string, std::string> actors {};
     158             : 
     159         255 :     std::ifstream file(from_yaml);
     160             : 
     161         255 :     CPPUNIT_ASSERT(file.is_open());
     162             : 
     163         255 :     YAML::Node node = YAML::Load(file);
     164             : 
     165         255 :     CPPUNIT_ASSERT(node.IsMap());
     166             : 
     167         255 :     auto default_account = node["default-account"];
     168             : 
     169         510 :     std::map<std::string, std::string> default_details = libjami::getAccountTemplate(default_account["type"].as<std::string>());
     170         255 :     if (default_account.IsMap()) {
     171        1528 :         for (const auto& kv : default_account) {
     172        1273 :             auto key = kv.first.as<std::string>();
     173        1273 :             if (default_details.find(key) != default_details.end()) {
     174           1 :                 default_details[key] = kv.second.as<std::string>();
     175             :             } else {
     176        1272 :                 default_details["Account." + key] = kv.second.as<std::string>();
     177             :             }
     178        1528 :         }
     179             :     }
     180             : 
     181         255 :     auto accounts = node["accounts"];
     182             : 
     183         255 :     CPPUNIT_ASSERT(accounts.IsMap());
     184             : 
     185         986 :     for (const auto& kv : accounts) {
     186         731 :         auto account_name = kv.first.as<std::string>();
     187         731 :         auto account = kv.second.as<YAML::Node>();
     188         731 :         auto details = std::map<std::string, std::string>(default_details);
     189             : 
     190        2209 :         for (const auto& detail : account) {
     191        1478 :             auto key = detail.first.as<std::string>();
     192        1478 :             if (details.find(key) != details.end()) {
     193           0 :                 details[key] = detail.second.as<std::string>();
     194             :             } else {
     195        1478 :                 details["Account." + key] = detail.second.as<std::string>();
     196             :             }
     197        2209 :         }
     198             : 
     199         731 :         actors[account_name] = jami::Manager::instance().addAccount(details);
     200         986 :     }
     201             : 
     202         510 :     return actors;
     203         255 : }
     204             : 
     205             : std::map<std::string, std::string>
     206          96 : load_actors_and_wait_for_announcement(const std::string& from_yaml)
     207             : {
     208          96 :     auto actors = load_actors(from_yaml);
     209             : 
     210          96 :     std::vector<std::string> wait_for;
     211             : 
     212          96 :     wait_for.reserve(actors.size());
     213             : 
     214         346 :     for (auto it = actors.cbegin(); it != actors.cend(); ++it) {
     215         250 :         wait_for.emplace_back(it->second);
     216             :     }
     217             : 
     218          96 :     wait_for_announcement_of(wait_for);
     219             : 
     220         192 :     return actors;
     221          96 : }
     222             : 
     223             : #pragma GCC diagnostic pop

Generated by: LCOV version 1.14