fw update: tests for common code
Tests for the common code introduced in another commit.
These tests should check that the common code behaves as outlined in the
design [1]
References:
[1] https://github.com/openbmc/docs/blob/master/designs/code-update.md
Tested: unit tests pass
Change-Id: I8f12839afd47ef3403a80439af54fedcc00f10be
Signed-off-by: Alexander Hansen <alexander.hansen@9elements.com>
diff --git a/test/common/nopdevice/meson.build b/test/common/nopdevice/meson.build
new file mode 100644
index 0000000..be943f5
--- /dev/null
+++ b/test/common/nopdevice/meson.build
@@ -0,0 +1,15 @@
+libnopdevice = static_library('nopdevice',
+ 'nopdevice.cpp',
+ include_directories: ['.', common_include],
+ dependencies: [
+ pdi_dep,
+ phosphor_logging_dep,
+ sdbusplus_dep,
+ libpldm_dep,
+ ],
+ link_with: [
+ software_common_lib,
+ ],
+ install: false,
+)
+
diff --git a/test/common/nopdevice/nopdevice.cpp b/test/common/nopdevice/nopdevice.cpp
new file mode 100644
index 0000000..ddf6f6e
--- /dev/null
+++ b/test/common/nopdevice/nopdevice.cpp
@@ -0,0 +1,91 @@
+#include "nopdevice.hpp"
+
+#include "common/include/device.hpp"
+#include "common/include/device_config.hpp"
+#include "common/include/software_manager.hpp"
+
+#include <phosphor-logging/lg2.hpp>
+#include <sdbusplus/asio/connection.hpp>
+#include <sdbusplus/asio/object_server.hpp>
+#include <sdbusplus/async.hpp>
+#include <sdbusplus/server.hpp>
+#include <xyz/openbmc_project/Association/Definitions/server.hpp>
+#include <xyz/openbmc_project/Software/Update/server.hpp>
+
+#include <memory>
+
+static long getRandomId()
+{
+ struct timespec ts;
+ clock_gettime(CLOCK_REALTIME, &ts);
+ unsigned int seed = ts.tv_nsec ^ getpid();
+ srandom(seed);
+ return random() % 10000;
+}
+
+// nop code updater needs unique suffix on dbus for parallel unit testing
+NopCodeUpdater::NopCodeUpdater(sdbusplus::async::context& ctx) :
+ NopCodeUpdater(ctx, getRandomId())
+{}
+
+NopCodeUpdater::NopCodeUpdater(sdbusplus::async::context& ctx,
+ long uniqueSuffix) :
+ SoftwareManager(ctx, "Nop" + std::to_string(uniqueSuffix), true)
+{}
+
+// NOLINTBEGIN
+sdbusplus::async::task<> NopCodeUpdater::getInitialConfigurationSingleDevice(
+ const std::string& /*unused*/, const std::string& /*unused*/,
+ DeviceConfig& /*unused*/)
+// NOLINTEND
+{
+ co_return;
+}
+
+NopDevice::NopDevice(sdbusplus::async::context& ctx, const DeviceConfig& config,
+ SoftwareManager* parent) :
+ Device(ctx, true, config, parent)
+{}
+NopDevice::NopDevice(sdbusplus::async::context& ctx, SoftwareManager* parent) :
+ Device(ctx, true,
+ DeviceConfig(exampleVendorIANA, exampleCompatible, "Nop",
+ exampleName),
+ parent)
+{}
+
+// NOLINTBEGIN
+sdbusplus::async::task<bool> NopDevice::updateDevice(
+ const uint8_t* /*unused*/, size_t compImageSize,
+ std::unique_ptr<SoftwareActivationProgress>& activationProgress)
+// NOLINTEND
+{
+ lg2::debug(
+ "[nop device] called device specific update function with image size {SIZE}",
+ "SIZE", compImageSize);
+
+ deviceSpecificUpdateFunctionCalled = true;
+
+ // Setting this property for demonstration purpose.
+ // For a real device, this could represent the
+ // percentage completion of writing the firmware,
+ // and any progress made in the update process within this function.
+ activationProgress->progress(30);
+
+ // There is no hard constraint on the values here,
+ // we do not have to reach any specific percentage.
+ // The percentage should be monotonic and increasing.
+ activationProgress->progress(90);
+
+ co_return true;
+}
+
+// NOLINTBEGIN
+sdbusplus::async::task<std::string> NopDevice::getInventoryItemObjectPath()
+// NOLINTEND
+{
+ // for a real device, it could find its inventory item via associations and
+ // the configuration interface, or go via the mapper to find the
+ // specific inventory item interface and then get the path from there.
+
+ co_return "/xyz/openbmc_project/inventory/item/my_nop_item";
+}
diff --git a/test/common/nopdevice/nopdevice.hpp b/test/common/nopdevice/nopdevice.hpp
new file mode 100644
index 0000000..0f3b24e
--- /dev/null
+++ b/test/common/nopdevice/nopdevice.hpp
@@ -0,0 +1,51 @@
+#pragma once
+
+#include "common/include/device.hpp"
+#include "common/include/software_manager.hpp"
+
+#include <phosphor-logging/lg2.hpp>
+#include <sdbusplus/asio/connection.hpp>
+#include <sdbusplus/asio/object_server.hpp>
+#include <sdbusplus/async.hpp>
+#include <sdbusplus/server.hpp>
+#include <xyz/openbmc_project/Association/Definitions/server.hpp>
+#include <xyz/openbmc_project/Software/Update/server.hpp>
+
+#include <memory>
+
+class NopCodeUpdater : public SoftwareManager
+{
+ public:
+ NopCodeUpdater(sdbusplus::async::context& ctx);
+ NopCodeUpdater(sdbusplus::async::context& ctx, long uniqueSuffix);
+
+ sdbusplus::async::task<> getInitialConfigurationSingleDevice(
+ const std::string& service, const std::string& path,
+ DeviceConfig& config) final;
+};
+
+const std::string exampleConfigObjPath =
+ "/xyz/openbmc_project/inventory/system/board/Tyan_S5549_Baseboard/HostSPIFlash";
+const std::string exampleName = "HostSPIFlash";
+
+const uint32_t exampleVendorIANA = 0x0000a015;
+const std::string exampleCompatible = "com.example.compatible";
+
+class NopDevice : public Device
+{
+ public:
+ NopDevice(sdbusplus::async::context& ctx, const DeviceConfig& config,
+ SoftwareManager* parent);
+ NopDevice(sdbusplus::async::context& ctx, SoftwareManager* parent);
+
+ // NOLINTBEGIN
+ sdbusplus::async::task<bool> updateDevice(
+ const uint8_t* image, size_t image_size,
+ std::unique_ptr<SoftwareActivationProgress>& activationProgress)
+ override;
+ // NOLINTEND
+
+ sdbusplus::async::task<std::string> getInventoryItemObjectPath() override;
+
+ bool deviceSpecificUpdateFunctionCalled = false;
+};