LcamDev: Add baked in camera profiles; use new test supports

This commit is contained in:
2026-06-13 18:50:31 -04:00
parent f3ca20ac1d
commit 25d7b9c013
8 changed files with 488 additions and 90 deletions
@@ -0,0 +1,193 @@
#include <boostAsioLinkageFix.h>
#include <catalogHelpers.h>
#include <lcameraDev.h>
#include <gtest/gtest.h>
#include <support/bakedDeviceCatalog.h>
#include <support/probeComponentThread.h>
#include <cstdlib>
#include <functional>
#include <memory>
#include <string>
#include <vector>
namespace lcamera_dev {
namespace {
constexpr const char *hilEnvVar = "LCAMERADEV_HIL";
constexpr const char *machineEnvVar = "LCAMERADEV_MACHINE";
constexpr const char *defaultMachineTag = "dell-laptop";
bool hilTestsEnabled()
{
const char *value = std::getenv(hilEnvVar);
return value != nullptr && std::string(value) == "1";
}
std::string machineTagFromEnvironment()
{
const char *value = std::getenv(machineEnvVar);
if (value != nullptr && std::string(value).size() > 0) {
return value;
}
return defaultMachineTag;
}
sscl::co::NonViralNonPostingInvoker enumerateCamerasCInd(
std::exception_ptr& exceptionStorage,
std::function<void()> callerLambda,
std::vector<lcamera_dev::LcameraDevCameraInfo>& enumeratedCameras)
{
(void)exceptionStorage;
(void)callerLambda;
enumeratedCameras = co_await lcameraDev_enumerateCamerasCReq();
co_return;
}
sscl::co::NonViralNonPostingInvoker getOrCreateCInd(
std::exception_ptr& exceptionStorage,
std::function<void()> callerLambda,
const char *deviceSelector,
lcamera_dev::LcameraDevGetOrCreateResult& createResult)
{
(void)exceptionStorage;
(void)callerLambda;
createResult = co_await lcameraDev_getOrCreateDeviceCReq(deviceSelector);
co_return;
}
sscl::co::NonViralNonPostingInvoker releaseCInd(
std::exception_ptr& exceptionStorage,
std::function<void()> callerLambda,
const std::shared_ptr<lcamera_dev::CameraSession>& deviceSession)
{
(void)exceptionStorage;
(void)callerLambda;
co_await lcameraDev_releaseDeviceCReq(deviceSession);
co_return;
}
void runLcameraDevMainAndNurseryTask(
const std::function<void(
const std::shared_ptr<sscl::ComponentThread>&)>& work)
{
sscl::tests::ProbeComponentThreadHarness harness("lcameraDev-hil");
harness.runSync(
[&work](const std::shared_ptr<sscl::ComponentThread>& componentThread)
{
lcameraDev_main(componentThread);
work(componentThread);
lcameraDev_exit();
});
}
class LcameraDevHilTest : public ::testing::Test
{
protected:
void SetUp() override
{
if (!hilTestsEnabled()) {
GTEST_SKIP() << "Set " << hilEnvVar << "=1 to run hardware tests";
}
machineTag = machineTagFromEnvironment();
requiredProfiles =
sscl::tests::requiredProfilesForMachine(machineTag.c_str());
if (requiredProfiles.empty()) {
GTEST_SKIP() << "No baked profiles for machine tag "
<< machineTag;
}
}
std::string machineTag;
std::vector<const test_fixtures::BakedCameraProfile *> requiredProfiles;
};
TEST_F(LcameraDevHilTest, EnumerateMatchesBakedCatalog)
{
std::vector<lcamera_dev::LcameraDevCameraInfo> enumeratedCameras;
runLcameraDevMainAndNurseryTask(
[&enumeratedCameras](
const std::shared_ptr<sscl::ComponentThread>& componentThread)
{
sscl::tests::runNonViralNurseryOnComponentThread(
componentThread,
[&enumeratedCameras](
sscl::co::NonViralTaskNursery::Slot::Lease& lease)
{
return enumerateCamerasCInd(
lease.getExceptionStorage(),
lease.getCallerLambda(),
enumeratedCameras);
});
});
EXPECT_GE(enumeratedCameras.size(), requiredProfiles.size());
for (const test_fixtures::BakedCameraProfile *profile : requiredProfiles)
{
bool found = false;
for (const lcamera_dev::LcameraDevCameraInfo& camera : enumeratedCameras)
{
if (camera.id == profile->libcameraId) {
found = true;
break;
}
}
EXPECT_TRUE(found)
<< "Missing baked profile camera id=" << profile->libcameraId;
}
}
TEST_F(LcameraDevHilTest, GetOrCreateByBakedSelector)
{
runLcameraDevMainAndNurseryTask(
[this](const std::shared_ptr<sscl::ComponentThread>& componentThread)
{
for (const test_fixtures::BakedCameraProfile *profile :
requiredProfiles)
{
lcamera_dev::LcameraDevGetOrCreateResult createResult;
sscl::tests::runNonViralNurseryOnComponentThread(
componentThread,
[profile, &createResult](
sscl::co::NonViralTaskNursery::Slot::Lease& lease)
{
return getOrCreateCInd(
lease.getExceptionStorage(),
lease.getCallerLambda(),
profile->exampleSelector,
createResult);
});
EXPECT_TRUE(createResult.deviceSession != nullptr)
<< profile->profileTag;
EXPECT_EQ(
createResult.resolvedIdentity.id,
profile->libcameraId)
<< profile->profileTag;
sscl::tests::runNonViralNurseryOnComponentThread(
componentThread,
[&createResult](
sscl::co::NonViralTaskNursery::Slot::Lease& lease)
{
return releaseCInd(
lease.getExceptionStorage(),
lease.getCallerLambda(),
createResult.deviceSession);
});
}
});
}
} // namespace
} // namespace lcamera_dev