LCOV - code coverage report
Current view: top level - servus/test - servus.h (source / functions) Hit Total Coverage
Test: Servus Lines: 55 60 91.7 %
Date: 2018-10-03 03:09:57 Functions: 12 14 85.7 %

          Line data    Source code
       1             : /* Copyright (c) 2017, Stefan.Eilemann@epfl.ch
       2             :  *
       3             :  * This file is part of Servus <https://github.com/HBPVIS/Servus>
       4             :  *
       5             :  * This library is free software; you can redistribute it and/or modify it under
       6             :  * the terms of the GNU Lesser General Public License version 3.0 as published
       7             :  * by the Free Software Foundation.
       8             :  *
       9             :  * This library is distributed in the hope that it will be useful, but WITHOUT
      10             :  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
      11             :  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
      12             :  * details.
      13             :  *
      14             :  * You should have received a copy of the GNU Lesser General Public License
      15             :  * along with this library; if not, write to the Free Software Foundation, Inc.,
      16             :  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      17             :  */
      18             : 
      19             : #include <algorithm>
      20             : #include <mutex>
      21             : #include <set>
      22             : #include <iterator>
      23             : 
      24             : namespace servus
      25             : {
      26             : namespace test
      27             : {
      28             : class Servus;
      29             : 
      30             : namespace
      31             : {
      32             : struct
      33          10 : {
      34             :     std::mutex mutex;
      35             :     std::set<Servus*> instances;
      36           5 : } _directory;
      37             : }
      38             : 
      39             : class Servus : public servus::Servus::Impl
      40             : {
      41             : public:
      42           3 :     Servus()
      43           3 :         : servus::Servus::Impl(servus::TEST_DRIVER)
      44             :     {
      45           3 :     }
      46             : 
      47           6 :     virtual ~Servus()
      48           6 :     {
      49           3 :         withdraw();
      50           3 :         endBrowsing();
      51           6 :     }
      52             : 
      53           0 :     std::string getClassName() const { return "test"; }
      54           3 :     servus::Servus::Result announce(const unsigned short port,
      55             :                                     const std::string& instance) final
      56             :     {
      57           6 :         std::lock_guard<std::mutex> lock(_directory.mutex);
      58             : 
      59           3 :         _port = port;
      60           3 :         if (instance.empty())
      61           0 :             _instance = getHostname();
      62             :         else
      63           3 :             _instance = instance;
      64           3 :         _directory.instances.insert(this);
      65           3 :         _announced = true;
      66           6 :         return servus::Servus::Result(servus::Result::SUCCESS);
      67             :     }
      68             : 
      69           4 :     void withdraw() final
      70             :     {
      71           8 :         std::lock_guard<std::mutex> lock(_directory.mutex);
      72             : 
      73           4 :         _announced = false;
      74           4 :         _directory.instances.erase(this);
      75           4 :         _port = 0;
      76           4 :         _instance.clear();
      77           4 :     }
      78             : 
      79           0 :     bool isAnnounced() const final { return _announced; }
      80           4 :     servus::Servus::Result beginBrowsing(
      81             :         const ::servus::Servus::Interface) final
      82             :     {
      83           4 :         if (_browsing)
      84           1 :             return servus::Servus::Result(servus::Servus::Result::PENDING);
      85             : 
      86           3 :         _instances.clear();
      87           3 :         _browsing = true;
      88           3 :         return servus::Servus::Result(servus::Servus::Result::SUCCESS);
      89             :     }
      90             : 
      91           6 :     servus::Servus::Result browse(const int32_t) final
      92             :     {
      93          12 :         std::lock_guard<std::mutex> lock(_directory.mutex);
      94             : 
      95          12 :         std::vector<Servus*> diff;
      96             :         std::set_symmetric_difference(_directory.instances.begin(),
      97             :                                       _directory.instances.end(),
      98             :                                       _instances.begin(), _instances.end(),
      99           6 :                                       back_inserter(diff));
     100             : 
     101           6 :         _instanceMap.clear();
     102          13 :         for (auto i : _directory.instances)
     103             :         {
     104           7 :             ValueMap& values = _instanceMap[i->_instance];
     105           7 :             values.clear();
     106           7 :             values["servus_host"] = "localhost";
     107             : 
     108          18 :             for (const auto& j : i->_data)
     109          11 :                 values[j.first] = j.second;
     110             :         }
     111             : 
     112          11 :         for (auto i : diff)
     113             :         {
     114           5 :             if (_instances.count(i) == 0)
     115             :             {
     116           4 :                 _instances.insert(i);
     117           4 :                 for (Listener* listener : _listeners)
     118           0 :                     listener->instanceAdded(i->_instance);
     119             :             }
     120             :             else
     121             :             {
     122           1 :                 for (Listener* listener : _listeners)
     123           0 :                     listener->instanceRemoved(i->_instance);
     124           1 :                 _instances.erase(i);
     125             :             }
     126             :         }
     127          12 :         return servus::Servus::Result(servus::Servus::Result::SUCCESS);
     128             :     }
     129             : 
     130           6 :     void endBrowsing() final
     131             :     {
     132           6 :         _browsing = false;
     133           6 :         _instances.clear();
     134           6 :     }
     135             : 
     136           5 :     bool isBrowsing() const final { return _browsing; }
     137             : private:
     138             :     std::string _instance;
     139             :     unsigned short _port{0};
     140             :     bool _announced{false};
     141             :     bool _browsing{false};
     142             : 
     143             :     std::set<Servus*> _instances;
     144             : 
     145           2 :     void _updateRecord() final { /*nop*/}
     146             : };
     147             : }
     148             : }

Generated by: LCOV version 1.11