/**
 * Copyright © 2019 IBM Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License 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 "extensions/openpower-pels/data_interface.hpp"
#include "extensions/openpower-pels/host_notifier.hpp"
#include "mocks.hpp"
#include "pel_utils.hpp"

#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>

#include <chrono>

#include <gtest/gtest.h>

using namespace openpower::pels;
using ::testing::_;
using ::testing::Invoke;
using ::testing::NiceMock;
using ::testing::Return;
namespace fs = std::filesystem;
using namespace std::chrono;

const size_t actionFlags0Offset = 66;
const size_t actionFlags1Offset = 67;

class HostNotifierTest : public CleanPELFiles
{
  public:
    HostNotifierTest() : repo(repoPath)
    {
        auto r = sd_event_default(&event);
        EXPECT_TRUE(r >= 0);

        ON_CALL(dataIface, getHostPELEnablement).WillByDefault(Return(true));

        hostIface = std::make_unique<NiceMock<MockHostInterface>>(event,
                                                                  dataIface);

        mockHostIface = reinterpret_cast<MockHostInterface*>(hostIface.get());

        auto send = [this](uint32_t /*id*/, uint32_t /*size*/) {
            return this->mockHostIface->send(0);
        };

        // Unless otherwise specified, sendNewLogCmd should always pass.
        ON_CALL(*mockHostIface, sendNewLogCmd(_, _))
            .WillByDefault(Invoke(send));
    }

    ~HostNotifierTest()
    {
        sd_event_unref(event);
    }

  protected:
    sd_event* event;
    Repository repo;
    NiceMock<MockDataInterface> dataIface;
    std::unique_ptr<HostInterface> hostIface;
    MockHostInterface* mockHostIface;
};

/**
 * @brief Create PEL with the specified action flags
 *
 * @param[in] actionFlagsMask - Optional action flags to use
 *
 * @return std::unique_ptr<PEL>
 */
std::unique_ptr<PEL> makePEL(uint16_t actionFlagsMask = 0)
{
    static uint32_t obmcID = 1;
    auto data = pelDataFactory(TestPELType::pelSimple);

    data[actionFlags0Offset] |= actionFlagsMask >> 8;
    data[actionFlags1Offset] |= actionFlagsMask & 0xFF;

    auto pel = std::make_unique<PEL>(data, obmcID++);
    pel->assignID();
    pel->setCommitTime();
    return pel;
}

/**
 * @brief Run an iteration of the event loop.
 *
 * An event loop is used for:
 *   1) timer expiration callbacks
 *   2) Dispatches
 *   3) host interface receive callbacks
 *
 * @param[in] event - The event object
 * @param[in] numEvents - number of times to call Event::run()
 * @param[in] timeout - timeout value for run()
 */
void runEvents(sdeventplus::Event& event, size_t numEvents,
               milliseconds timeout = milliseconds(1))
{
    for (size_t i = 0; i < numEvents; i++)
    {
        event.run(timeout);
    }
}

// Test that host state change callbacks work
TEST_F(HostNotifierTest, TestHostStateChange)
{
    bool hostState = false;
    bool called = false;
    DataInterfaceBase::HostStateChangeFunc func =
        [&hostState, &called](bool state) {
        hostState = state;
        called = true;
    };

    dataIface.subscribeToHostStateChange("test", func);

    // callback called
    dataIface.changeHostState(true);
    EXPECT_TRUE(called);
    EXPECT_TRUE(hostState);

    // No change, not called
    called = false;
    dataIface.changeHostState(true);
    EXPECT_FALSE(called);

    // Called again
    dataIface.changeHostState(false);
    EXPECT_FALSE(hostState);
    EXPECT_TRUE(called);

    // Shouldn't get called after an unsubscribe
    dataIface.unsubscribeFromHostStateChange("test");

    called = false;

    dataIface.changeHostState(true);
    EXPECT_FALSE(called);
}

// Test dealing with how acked PELs are put on the
// notification queue.
TEST_F(HostNotifierTest, TestPolicyAckedPEL)
{
    HostNotifier notifier{repo, dataIface, std::move(hostIface)};

    auto pel = makePEL();
    repo.add(pel);

    // This is required
    EXPECT_TRUE(notifier.enqueueRequired(pel->id()));
    EXPECT_TRUE(notifier.notifyRequired(pel->id()));

    // Not in the repo
    EXPECT_FALSE(notifier.enqueueRequired(42));
    EXPECT_FALSE(notifier.notifyRequired(42));

    // Now set this PEL to host acked
    repo.setPELHostTransState(pel->id(), TransmissionState::acked);

    // Since it's acked, doesn't need to be enqueued or transmitted
    EXPECT_FALSE(notifier.enqueueRequired(pel->id()));
    EXPECT_FALSE(notifier.notifyRequired(pel->id()));
}

// Test the 'don't report' PEL flag
TEST_F(HostNotifierTest, TestPolicyDontReport)
{
    HostNotifier notifier{repo, dataIface, std::move(hostIface)};

    // dontReportToHostFlagBit
    auto pel = makePEL(0x1000);

    // Double check the action flag is still set
    std::bitset<16> actionFlags = pel->userHeader().actionFlags();
    EXPECT_TRUE(actionFlags.test(dontReportToHostFlagBit));

    repo.add(pel);

    // Don't need to send this to the host
    EXPECT_FALSE(notifier.enqueueRequired(pel->id()));
}

// Test that hidden PELs need notification when there
// is no HMC.
TEST_F(HostNotifierTest, TestPolicyHiddenNoHMC)
{
    HostNotifier notifier{repo, dataIface, std::move(hostIface)};

    // hiddenFlagBit
    auto pel = makePEL(0x4000);

    // Double check the action flag is still set
    std::bitset<16> actionFlags = pel->userHeader().actionFlags();
    EXPECT_TRUE(actionFlags.test(hiddenFlagBit));

    repo.add(pel);

    // Still need to enqueue this
    EXPECT_TRUE(notifier.enqueueRequired(pel->id()));

    // Still need to send it
    EXPECT_TRUE(notifier.notifyRequired(pel->id()));
}

// Don't need to enqueue a hidden log already acked by the HMC
TEST_F(HostNotifierTest, TestPolicyHiddenWithHMCAcked)
{
    HostNotifier notifier{repo, dataIface, std::move(hostIface)};

    // hiddenFlagBit
    auto pel = makePEL(0x4000);

    // Double check the action flag is still set
    std::bitset<16> actionFlags = pel->userHeader().actionFlags();
    EXPECT_TRUE(actionFlags.test(hiddenFlagBit));

    repo.add(pel);

    // No HMC yet, so required
    EXPECT_TRUE(notifier.enqueueRequired(pel->id()));

    repo.setPELHMCTransState(pel->id(), TransmissionState::acked);

    // Not required anymore
    EXPECT_FALSE(notifier.enqueueRequired(pel->id()));
}

// Test that changing the HMC manage status affects
// the policy with hidden log notification.
TEST_F(HostNotifierTest, TestPolicyHiddenWithHMCManaged)
{
    HostNotifier notifier{repo, dataIface, std::move(hostIface)};

    // hiddenFlagBit
    auto pel = makePEL(0x4000);

    repo.add(pel);

    // The first time, the HMC managed is false
    EXPECT_TRUE(notifier.notifyRequired(pel->id()));

    dataIface.setHMCManaged(true);

    // This time, HMC managed is true so no need to notify
    EXPECT_FALSE(notifier.notifyRequired(pel->id()));
}

// Test that PELs are enqueued on startup
TEST_F(HostNotifierTest, TestStartup)
{
    // Give the repo 10 PELs to start with
    for (int i = 0; i < 10; i++)
    {
        auto pel = makePEL();
        repo.add(pel);
    }

    HostNotifier notifier{repo, dataIface, std::move(hostIface)};

    ASSERT_EQ(notifier.queueSize(), 10);

    // Now add 10 more after the notifier is watching
    for (int i = 0; i < 10; i++)
    {
        auto pel = makePEL();
        repo.add(pel);
    }

    ASSERT_EQ(notifier.queueSize(), 20);
}

// Test the simple path were PELs get sent to the host
TEST_F(HostNotifierTest, TestSendCmd)
{
    sdeventplus::Event sdEvent{event};

    HostNotifier notifier{repo, dataIface, std::move(hostIface)};

    // Add a PEL with the host off
    auto pel = makePEL();
    repo.add(pel);

    EXPECT_EQ(notifier.queueSize(), 1);

    dataIface.changeHostState(true);

    runEvents(sdEvent, 2);

    // It was sent up
    EXPECT_EQ(mockHostIface->numCmdsProcessed(), 1);
    EXPECT_EQ(notifier.queueSize(), 0);

    // Verify the state was written to the PEL.
    Repository::LogID id{Repository::LogID::Pel{pel->id()}};
    auto data = repo.getPELData(id);
    PEL pelFromRepo{*data};
    EXPECT_EQ(pelFromRepo.hostTransmissionState(), TransmissionState::sent);

    // Add a few more PELs.  They will get sent.
    pel = makePEL();
    repo.add(pel);

    // Dispatch it by hitting the event loop (no commands sent yet)
    // Don't need to test this step discretely in the future
    runEvents(sdEvent, 1);
    EXPECT_EQ(mockHostIface->numCmdsProcessed(), 1);
    EXPECT_EQ(notifier.queueSize(), 0);

    // Send the command
    runEvents(sdEvent, 1);

    EXPECT_EQ(mockHostIface->numCmdsProcessed(), 2);
    EXPECT_EQ(notifier.queueSize(), 0);

    pel = makePEL();
    repo.add(pel);

    // dispatch and process the command
    runEvents(sdEvent, 2);

    EXPECT_EQ(mockHostIface->numCmdsProcessed(), 3);
    EXPECT_EQ(notifier.queueSize(), 0);
}

// Test that if the class is created with the host up,
// it will send PELs
TEST_F(HostNotifierTest, TestStartAfterHostUp)
{
    // Add PELs right away
    auto pel = makePEL();
    repo.add(pel);
    pel = makePEL();
    repo.add(pel);

    sdeventplus::Event sdEvent{event};

    // Create the HostNotifier class with the host already up
    dataIface.changeHostState(true);
    HostNotifier notifier{repo, dataIface, std::move(hostIface)};

    // It should start sending PELs right away
    runEvents(sdEvent, 3);

    EXPECT_EQ(mockHostIface->numCmdsProcessed(), 2);
    EXPECT_EQ(notifier.queueSize(), 0);
}

// Test that a single failure will cause a retry
TEST_F(HostNotifierTest, TestHostRetry)
{
    sdeventplus::Event sdEvent{event};

    HostNotifier notifier{repo, dataIface, std::move(hostIface)};

    auto sendFailure = [this](uint32_t /*id*/, uint32_t /*size*/) {
        return this->mockHostIface->send(1);
    };
    auto sendSuccess = [this](uint32_t /*id*/, uint32_t /*size*/) {
        return this->mockHostIface->send(0);
    };

    EXPECT_CALL(*mockHostIface, sendNewLogCmd(_, _))
        .WillOnce(Invoke(sendFailure))
        .WillOnce(Invoke(sendSuccess))
        .WillOnce(Invoke(sendSuccess));

    dataIface.changeHostState(true);

    auto pel = makePEL();
    repo.add(pel);

    // Dispatch and handle the command
    runEvents(sdEvent, 2);

    // The command failed, so the queue isn't empty
    EXPECT_EQ(mockHostIface->numCmdsProcessed(), 1);
    EXPECT_EQ(notifier.queueSize(), 1);

    // Run the events again to let the timer expire and the
    // command to be retried, which will be successful.
    runEvents(sdEvent, 2, mockHostIface->getReceiveRetryDelay());

    EXPECT_EQ(mockHostIface->numCmdsProcessed(), 2);
    EXPECT_EQ(notifier.queueSize(), 0);

    // This one should pass with no problems
    pel = makePEL();
    repo.add(pel);

    // Dispatch and handle the command
    runEvents(sdEvent, 2);

    EXPECT_EQ(mockHostIface->numCmdsProcessed(), 3);
    EXPECT_EQ(notifier.queueSize(), 0);
}

// Test that all commands fail and notifier will give up
TEST_F(HostNotifierTest, TestHardFailure)
{
    sdeventplus::Event sdEvent{event};

    HostNotifier notifier{repo, dataIface, std::move(hostIface)};

    // Every call will fail
    auto sendFailure = [this](uint32_t /*id*/, uint32_t /*size*/) {
        return this->mockHostIface->send(1);
    };

    EXPECT_CALL(*mockHostIface, sendNewLogCmd(_, _))
        .WillRepeatedly(Invoke(sendFailure));

    dataIface.changeHostState(true);

    auto pel = makePEL();
    repo.add(pel);

    // Clock more retries than necessary
    runEvents(sdEvent, 40, mockHostIface->getReceiveRetryDelay());

    // Should have stopped after the 15 Tries
    EXPECT_EQ(mockHostIface->numCmdsProcessed(), 15);
    EXPECT_EQ(notifier.queueSize(), 1);

    // Now add another PEL, and it should start trying again
    // though it will also eventually give up
    pel = makePEL();
    repo.add(pel);

    runEvents(sdEvent, 40, mockHostIface->getReceiveRetryDelay());

    // Tried an additional 15 times
    EXPECT_EQ(mockHostIface->numCmdsProcessed(), 30);
    EXPECT_EQ(notifier.queueSize(), 2);
}

// Test that if the command cannot be started it will give
// up but still try again later
TEST_F(HostNotifierTest, TestCannotStartCmd)
{
    sdeventplus::Event sdEvent{event};

    HostNotifier notifier{repo, dataIface, std::move(hostIface)};

    // Make it behave like startCommand() fails.
    auto sendFailure = [this](uint32_t /*id*/, uint32_t /*size*/) {
        this->mockHostIface->cancelCmd();
        return CmdStatus::failure;
    };

    auto sendSuccess = [this](uint32_t /*id*/, uint32_t /*size*/) {
        return this->mockHostIface->send(0);
    };

    // Fails 16 times (1 fail + 15  retries) and
    // then start working.
    EXPECT_CALL(*mockHostIface, sendNewLogCmd(_, _))
        .WillOnce(Invoke(sendFailure))
        .WillOnce(Invoke(sendFailure))
        .WillOnce(Invoke(sendFailure))
        .WillOnce(Invoke(sendFailure))
        .WillOnce(Invoke(sendFailure))
        .WillOnce(Invoke(sendFailure))
        .WillOnce(Invoke(sendFailure))
        .WillOnce(Invoke(sendFailure))
        .WillOnce(Invoke(sendFailure))
        .WillOnce(Invoke(sendFailure))
        .WillOnce(Invoke(sendFailure))
        .WillOnce(Invoke(sendFailure))
        .WillOnce(Invoke(sendFailure))
        .WillOnce(Invoke(sendFailure))
        .WillOnce(Invoke(sendFailure))
        .WillOnce(Invoke(sendFailure))
        .WillRepeatedly(Invoke(sendSuccess));

    dataIface.changeHostState(true);

    auto pel = makePEL();
    repo.add(pel);

    // Clock more retries than necessary
    runEvents(sdEvent, 40, mockHostIface->getReceiveRetryDelay());

    // Didn't get far enough for a cmd to be processed
    EXPECT_EQ(mockHostIface->numCmdsProcessed(), 0);
    EXPECT_EQ(notifier.queueSize(), 1);

    // At this point, commands will work again.

    pel = makePEL();
    repo.add(pel);

    // Run the events to send the PELs
    runEvents(sdEvent, 5, mockHostIface->getReceiveRetryDelay());

    // All PELs sent
    EXPECT_EQ(mockHostIface->numCmdsProcessed(), 2);
    EXPECT_EQ(notifier.queueSize(), 0);
}

// Cancel an in progress command
TEST_F(HostNotifierTest, TestCancelCmd)
{
    sdeventplus::Event sdEvent{event};
    HostNotifier notifier{repo, dataIface, std::move(hostIface)};

    dataIface.changeHostState(true);

    // Add and send one PEL, but don't enter the event loop
    // so the receive function can't run.
    auto pel = makePEL();
    repo.add(pel);

    // Not dispatched yet
    EXPECT_EQ(notifier.queueSize(), 1);

    // Dispatch it
    runEvents(sdEvent, 2);

    // It was sent and off the queue
    EXPECT_EQ(notifier.queueSize(), 0);

    // This will cancel the receive
    dataIface.changeHostState(false);

    // Back on the queue
    EXPECT_EQ(notifier.queueSize(), 1);

    // Turn the host back on and make sure
    // commands will work again
    dataIface.changeHostState(true);

    runEvents(sdEvent, 1);

    EXPECT_EQ(mockHostIface->numCmdsProcessed(), 1);
    EXPECT_EQ(notifier.queueSize(), 0);
}

// Test that acking a PEL persist across power cycles
TEST_F(HostNotifierTest, TestPowerCycleAndAcks)
{
    sdeventplus::Event sdEvent{event};

    HostNotifier notifier{repo, dataIface, std::move(hostIface)};

    // Add 2 PELs with host off
    auto pel = makePEL();
    repo.add(pel);
    auto id1 = pel->id();

    pel = makePEL();
    repo.add(pel);
    auto id2 = pel->id();

    dataIface.changeHostState(true);

    runEvents(sdEvent, 3);

    // The were both sent.
    EXPECT_EQ(mockHostIface->numCmdsProcessed(), 2);
    EXPECT_EQ(notifier.queueSize(), 0);

    dataIface.changeHostState(false);

    // Those PELs weren't acked, so they will get sent again
    EXPECT_EQ(notifier.queueSize(), 2);

    // Power back on and send them again
    dataIface.changeHostState(true);
    runEvents(sdEvent, 3);

    EXPECT_EQ(mockHostIface->numCmdsProcessed(), 4);
    EXPECT_EQ(notifier.queueSize(), 0);

    // Ack them and verify the state in the PEL.
    notifier.ackPEL(id1);
    notifier.ackPEL(id2);

    Repository::LogID id{Repository::LogID::Pel{id1}};
    auto data = repo.getPELData(id);
    PEL pelFromRepo1{*data};
    EXPECT_EQ(pelFromRepo1.hostTransmissionState(), TransmissionState::acked);

    id.pelID.id = id2;
    data = repo.getPELData(id);
    PEL pelFromRepo2{*data};
    EXPECT_EQ(pelFromRepo2.hostTransmissionState(), TransmissionState::acked);

    // Power back off, and they should't get re-added
    dataIface.changeHostState(false);

    EXPECT_EQ(notifier.queueSize(), 0);
}

// Test the host full condition
TEST_F(HostNotifierTest, TestHostFull)
{
    // The full interaction with the host is:
    // BMC:  new PEL available
    // Host: ReadPELFile  (not modeled here)
    // Host: Ack(id) (if not full), or HostFull(id)
    // BMC: if full and any new PELs come in, don't sent them
    // Start a timer and try again
    // Host responds with either Ack or full
    // and repeat

    sdeventplus::Event sdEvent{event};
    HostNotifier notifier{repo, dataIface, std::move(hostIface)};

    dataIface.changeHostState(true);

    // Add and dispatch/send one PEL
    auto pel = makePEL();
    auto id = pel->id();
    repo.add(pel);
    runEvents(sdEvent, 2);

    EXPECT_EQ(mockHostIface->numCmdsProcessed(), 1);
    EXPECT_EQ(notifier.queueSize(), 0);

    // Host is full
    notifier.setHostFull(id);

    // It goes back on the queue
    EXPECT_EQ(notifier.queueSize(), 1);

    // The transmission state goes back to new
    Repository::LogID i{Repository::LogID::Pel{id}};
    auto data = repo.getPELData(i);
    PEL pelFromRepo{*data};
    EXPECT_EQ(pelFromRepo.hostTransmissionState(), TransmissionState::newPEL);

    // Clock it, nothing should be sent still.
    runEvents(sdEvent, 1);

    EXPECT_EQ(mockHostIface->numCmdsProcessed(), 1);
    EXPECT_EQ(notifier.queueSize(), 1);

    // Add another PEL and clock it, still nothing sent
    pel = makePEL();
    repo.add(pel);
    runEvents(sdEvent, 2);
    EXPECT_EQ(mockHostIface->numCmdsProcessed(), 1);
    EXPECT_EQ(notifier.queueSize(), 2);

    // Let the host full timer expire to trigger a retry.
    // Add some extra event passes just to be sure nothing new is sent.
    runEvents(sdEvent, 5, mockHostIface->getHostFullRetryDelay());

    // The timer expiration will send just the 1, not both
    EXPECT_EQ(mockHostIface->numCmdsProcessed(), 2);
    EXPECT_EQ(notifier.queueSize(), 1);

    // Host still full
    notifier.setHostFull(id);

    // Let the host full timer attempt again
    runEvents(sdEvent, 2, mockHostIface->getHostFullRetryDelay());
    EXPECT_EQ(mockHostIface->numCmdsProcessed(), 3);

    // Add yet another PEL with the retry timer expired.
    // It shouldn't get sent out.
    pel = makePEL();
    repo.add(pel);
    runEvents(sdEvent, 2);
    EXPECT_EQ(mockHostIface->numCmdsProcessed(), 3);

    // The last 2 PELs still on the queue
    EXPECT_EQ(notifier.queueSize(), 2);

    // Host no longer full, it finally acks the first PEL
    notifier.ackPEL(id);

    // Now the remaining 2 PELs will be dispatched
    runEvents(sdEvent, 3);

    EXPECT_EQ(mockHostIface->numCmdsProcessed(), 5);
    EXPECT_EQ(notifier.queueSize(), 0);
}

// Test when the host says it was send a malformed PEL
TEST_F(HostNotifierTest, TestBadPEL)
{
    sdeventplus::Event sdEvent{event};

    {
        Repository repo1{repoPath};
        HostNotifier notifier{repo1, dataIface, std::move(hostIface)};

        dataIface.changeHostState(true);

        // Add a PEL and dispatch and send it
        auto pel = makePEL();
        auto id = pel->id();
        repo1.add(pel);

        runEvents(sdEvent, 2);
        EXPECT_EQ(mockHostIface->numCmdsProcessed(), 1);
        EXPECT_EQ(notifier.queueSize(), 0);

        // The host rejected it.
        notifier.setBadPEL(id);

        // Doesn't go back on the queue
        EXPECT_EQ(notifier.queueSize(), 0);

        // Check the state was saved in the PEL itself
        Repository::LogID i{Repository::LogID::Pel{id}};
        auto data = repo1.getPELData(i);
        PEL pelFromRepo{*data};
        EXPECT_EQ(pelFromRepo.hostTransmissionState(),
                  TransmissionState::badPEL);

        dataIface.changeHostState(false);

        // Ensure it doesn't go back on the queue on a power cycle
        EXPECT_EQ(notifier.queueSize(), 0);
    }

    // Now restore the repo, and make sure it doesn't come back
    {
        Repository repo1{repoPath};

        std::unique_ptr<HostInterface> hostIface1 =
            std::make_unique<MockHostInterface>(event, dataIface);

        HostNotifier notifier{repo1, dataIface, std::move(hostIface1)};

        EXPECT_EQ(notifier.queueSize(), 0);
    }
}

// Test that sending PELs can be disabled
TEST_F(HostNotifierTest, TestDisable)
{
    // Turn off sending the PELs except for once in the middle
    EXPECT_CALL(dataIface, getHostPELEnablement())
        .WillOnce(Return(false))
        .WillOnce(Return(false))
        .WillOnce(Return(true))
        .WillOnce(Return(false))
        .WillOnce(Return(false))
        .WillOnce(Return(false));

    {
        HostNotifier notifier{repo, dataIface, std::move(hostIface)};

        // Add a PEL with the host off
        auto pel = makePEL();
        repo.add(pel);

        // Not added to the send queue
        EXPECT_EQ(notifier.queueSize(), 0);

        dataIface.changeHostState(true);

        // Try again with the host on
        pel = makePEL();
        repo.add(pel);

        EXPECT_EQ(notifier.queueSize(), 0);

        // Now getHostPELEnablement() will return true for the new PEL
        pel = makePEL();
        repo.add(pel);

        EXPECT_EQ(notifier.queueSize(), 1);
    }

    // getHostPELEnablement is back to returning false.
    // Create a new second instance and make sure the 3 existing PELs
    // aren't put on the queue on startup
    {
        Repository repo1{repoPath};
        std::unique_ptr<HostInterface> hostIface1 =
            std::make_unique<MockHostInterface>(event, dataIface);

        HostNotifier notifier{repo1, dataIface, std::move(hostIface1)};

        EXPECT_EQ(notifier.queueSize(), 0);
    }
}
