9#ifndef CAMCOM_TEST_FIXTURE_HPP
10#define CAMCOM_TEST_FIXTURE_HPP
12#include <gtest/gtest.h>
19#include <sys/socket.h>
20#include <netinet/in.h>
28#include <ifw/fnd/defs/base.hpp>
37 static bool done =
false;
39 ifw::fnd::InstallLogger(ifw::fnd::MakeNullLogger());
50 int sock = socket(AF_INET, SOCK_STREAM, 0);
51 struct sockaddr_in addr {};
52 addr.sin_family = AF_INET;
53 addr.sin_addr.s_addr = INADDR_ANY;
55 bind(sock,
reinterpret_cast<struct sockaddr*
>(&addr),
sizeof(addr));
57 socklen_t len =
sizeof(addr);
58 getsockname(sock,
reinterpret_cast<struct sockaddr*
>(&addr), &len);
59 int port = ntohs(addr.sin_port);
65template <
typename Pred>
66bool waitFor(Pred pred,
int timeout_ms = 3000,
int poll_ms = 50) {
68 std::chrono::steady_clock::now() + std::chrono::milliseconds(timeout_ms);
69 while (std::chrono::steady_clock::now() < deadline) {
70 if (pred())
return true;
71 std::this_thread::sleep_for(std::chrono::milliseconds(poll_ms));
78 const std::string& rec_dir) {
81 cfg.
uri =
"sim://localhost";
91 {
"acquisition_mode",
"Continuous"},
92 {
"exposure_time",
"0.01"},
93 {
"frame_rate",
"0.0"},
98 {
"binning_horizontal",
"1"},
99 {
"binning_vertical",
"1"},
101 {
"sim_type",
"Gaussian"},
102 {
"sim_data_type",
"UInt16"},
103 {
"sim_nb_planes",
"11"},
104 {
"sim_amplitude",
"1000.0"},
105 {
"sim_sigma",
"5.0"},
106 {
"sim_noise_level",
"50"},
148 const std::string& rec_dir) {
151 cfg.
uri =
"genicam-emu://localhost";
161 {
"AcquisitionMode",
"Continuous"},
162 {
"ExposureTime",
"1000.0"},
163 {
"AcquisitionFrameRate",
"30.0"},
168 {
"BinningHorizontal",
"1"},
169 {
"BinningVertical",
"1"},
171 {
"TriggerMode",
"Off"},
172 {
"PixelFormat",
"Mono8"},
223 rec_dir_ = std::filesystem::temp_directory_path() /
224 (
"camcom_test_" + std::to_string(port_));
225 std::filesystem::create_directories(rec_dir_);
228 server_ = std::make_unique<server::CameraServer>(config_);
229 ASSERT_TRUE(server_->start()) <<
"Server failed to start on port " << port_;
231 client_ = std::make_unique<httplib::Client>(
"127.0.0.1", port_);
232 client_->set_connection_timeout(3);
233 client_->set_read_timeout(5);
236 bool healthy =
waitFor([
this]() {
237 auto res = client_->Get(
"/health");
238 return res && res->status == 200;
240 ASSERT_TRUE(healthy) <<
"Server did not become healthy within timeout";
249 std::filesystem::remove_all(rec_dir_, ec);
255 int port()
const {
return port_; }
256 const std::filesystem::path&
recDir()
const {
return rec_dir_; }
259 static std::string
jsonStr(
const std::string& body,
const std::string& key) {
260 std::string needle =
"\"" + key +
"\":\"";
261 auto pos = body.find(needle);
262 if (pos == std::string::npos)
return "";
263 pos += needle.size();
264 auto end = body.find(
'"', pos);
265 if (end == std::string::npos)
return "";
266 return body.substr(pos, end - pos);
270 static bool jsonBool(
const std::string& body,
const std::string& key) {
271 std::string needle =
"\"" + key +
"\":";
272 auto pos = body.find(needle);
273 if (pos == std::string::npos)
return false;
274 pos += needle.size();
275 return body.substr(pos, 4) ==
"true";
279 static int jsonInt(
const std::string& body,
const std::string& key) {
280 std::string needle =
"\"" + key +
"\":";
281 auto pos = body.find(needle);
282 if (pos == std::string::npos)
return -1;
283 pos += needle.size();
284 return std::stoi(body.substr(pos));
288 static double jsonDouble(
const std::string& body,
const std::string& key) {
289 std::string needle =
"\"" + key +
"\":";
290 auto pos = body.find(needle);
291 if (pos == std::string::npos)
return 0.0;
292 pos += needle.size();
293 return std::stod(body.substr(pos));
298 std::filesystem::path rec_dir_;
300 std::unique_ptr<server::CameraServer> server_;
301 std::unique_ptr<httplib::Client> client_;
312 ASSERT_TRUE(res) <<
"Failed to send /connect request";
313 ASSERT_EQ(res->status, 200) <<
"Connect failed: " << res->
body;
329 auto res =
client().
Get(
"/acquisition/start");
330 ASSERT_TRUE(res) <<
"Failed to send /acquisition/start";
331 ASSERT_EQ(res->status, 200) <<
"Start acquisition failed: " << res->
body;
334 bool got_frame =
waitFor([
this]() {
336 if (!r || r->status != 200)
return false;
337 return r->
body.find(
"\"frame_id\":0") == std::string::npos &&
338 r->body.find(
"\"changed\":true") != std::string::npos;
340 ASSERT_TRUE(got_frame) <<
"No frame received within timeout";
360 rec_dir_ = std::filesystem::temp_directory_path() /
361 (
"camcom_emu_test_" + std::to_string(port_));
362 std::filesystem::create_directories(rec_dir_);
365 server_ = std::make_unique<server::CameraServer>(config_);
366 ASSERT_TRUE(server_->start()) <<
"Server failed to start on port " << port_;
368 client_ = std::make_unique<httplib::Client>(
"127.0.0.1", port_);
369 client_->set_connection_timeout(3);
370 client_->set_read_timeout(5);
372 bool healthy =
waitFor([
this]() {
373 auto res = client_->Get(
"/health");
374 return res && res->status == 200;
376 ASSERT_TRUE(healthy) <<
"Server did not become healthy within timeout";
384 std::filesystem::remove_all(rec_dir_, ec);
390 int port()
const {
return port_; }
391 const std::filesystem::path&
recDir()
const {
return rec_dir_; }
393 static std::string
jsonStr(
const std::string& body,
const std::string& key) {
394 std::string needle =
"\"" + key +
"\":\"";
395 auto pos = body.find(needle);
396 if (pos == std::string::npos)
return "";
397 pos += needle.size();
398 auto end = body.find(
'"', pos);
399 if (end == std::string::npos)
return "";
400 return body.substr(pos, end - pos);
403 static bool jsonBool(
const std::string& body,
const std::string& key) {
404 std::string needle =
"\"" + key +
"\":";
405 auto pos = body.find(needle);
406 if (pos == std::string::npos)
return false;
407 pos += needle.size();
408 return body.substr(pos, 4) ==
"true";
411 static int jsonInt(
const std::string& body,
const std::string& key) {
412 std::string needle =
"\"" + key +
"\":";
413 auto pos = body.find(needle);
414 if (pos == std::string::npos)
return -1;
415 pos += needle.size();
416 return std::stoi(body.substr(pos));
419 static double jsonDouble(
const std::string& body,
const std::string& key) {
420 std::string needle =
"\"" + key +
"\":";
421 auto pos = body.find(needle);
422 if (pos == std::string::npos)
return 0.0;
423 pos += needle.size();
424 return std::stod(body.substr(pos));
429 std::filesystem::path rec_dir_;
431 std::unique_ptr<server::CameraServer> server_;
432 std::unique_ptr<httplib::Client> client_;
440 ASSERT_TRUE(res) <<
"Failed to send /connect request";
441 ASSERT_EQ(res->status, 200) <<
"Connect failed: " << res->
body;
454 auto res =
client().
Get(
"/acquisition/start");
455 ASSERT_TRUE(res) <<
"Failed to send /acquisition/start";
456 ASSERT_EQ(res->status, 200) <<
"Start acquisition failed: " << res->
body;
458 bool got_frame =
waitFor([
this]() {
460 if (!r || r->status != 200)
return false;
461 return r->
body.find(
"\"frame_id\":0") == std::string::npos &&
462 r->body.find(
"\"changed\":true") != std::string::npos;
464 ASSERT_TRUE(got_frame) <<
"No frame received within timeout";
Main camera server class Orchestrates all components: adapter, HTTP server, frame pipeline.
Definition server.hpp:43
Definition test_fixture.hpp:450
void TearDown() override
Definition test_fixture.hpp:467
void SetUp() override
Definition test_fixture.hpp:452
Definition test_fixture.hpp:325
void TearDown() override
Definition test_fixture.hpp:343
void SetUp() override
Definition test_fixture.hpp:327
Definition test_fixture.hpp:215
static double jsonDouble(const std::string &body, const std::string &key)
Parse JSON double value: {"key":1.5} → 1.5.
Definition test_fixture.hpp:288
int port() const
Definition test_fixture.hpp:255
static int jsonInt(const std::string &body, const std::string &key)
Parse JSON int value: {"key":42} → 42.
Definition test_fixture.hpp:279
void TearDown() override
Definition test_fixture.hpp:243
static bool jsonBool(const std::string &body, const std::string &key)
Parse JSON bool value: {"key":true} → true.
Definition test_fixture.hpp:270
static std::string jsonStr(const std::string &body, const std::string &key)
Parse JSON string value: {"key":"value"} → value.
Definition test_fixture.hpp:259
const server::ServerConfig & config() const
Definition test_fixture.hpp:253
server::CameraServer & server()
Definition test_fixture.hpp:254
const std::filesystem::path & recDir() const
Definition test_fixture.hpp:256
void SetUp() override
Definition test_fixture.hpp:217
httplib::Client & client()
Definition test_fixture.hpp:252
Definition test_fixture.hpp:435
void SetUp() override
Definition test_fixture.hpp:437
void TearDown() override
Definition test_fixture.hpp:444
Definition test_fixture.hpp:307
void SetUp() override
Definition test_fixture.hpp:309
void TearDown() override
Definition test_fixture.hpp:316
Definition test_fixture.hpp:353
static std::string jsonStr(const std::string &body, const std::string &key)
Definition test_fixture.hpp:393
int port() const
Definition test_fixture.hpp:390
server::CameraServer & server()
Definition test_fixture.hpp:389
void TearDown() override
Definition test_fixture.hpp:379
static int jsonInt(const std::string &body, const std::string &key)
Definition test_fixture.hpp:411
const std::filesystem::path & recDir() const
Definition test_fixture.hpp:391
static bool jsonBool(const std::string &body, const std::string &key)
Definition test_fixture.hpp:403
void SetUp() override
Definition test_fixture.hpp:355
httplib::Client & client()
Definition test_fixture.hpp:387
static double jsonDouble(const std::string &body, const std::string &key)
Definition test_fixture.hpp:419
const server::ServerConfig & config() const
Definition test_fixture.hpp:388
Definition httplib.h:2388
Result Get(const std::string &path, DownloadProgress progress=nullptr)
Definition httplib.h:14740
Header file for the CamCom Common Library.
Definition test_fixture.hpp:30
server::ServerConfig buildGenICamEmuTestConfig(int port, const std::string &rec_dir)
Build a minimal ServerConfig for GenICam emulator integration tests.
Definition test_fixture.hpp:147
bool waitFor(Pred pred, int timeout_ms=3000, int poll_ms=50)
Poll a predicate with timeout. Returns true if predicate became true.
Definition test_fixture.hpp:66
void initLogger()
Definition test_fixture.hpp:36
server::ServerConfig buildTestConfig(int port, const std::string &rec_dir)
Build a minimal ServerConfig for integration tests.
Definition test_fixture.hpp:77
int findFreePort()
Find a free TCP port by binding to port 0.
Definition test_fixture.hpp:49
bool skip_silently
Definition config.hpp:136
int frame_queue_size
Definition config.hpp:135
bool auto_connect
Definition config.hpp:24
std::string factory_symbol
Definition config.hpp:23
std::string library
Definition config.hpp:21
int port
Definition config.hpp:40
std::string host
Definition config.hpp:39
std::string level
Definition config.hpp:113
std::string trigger
Definition config.hpp:83
bool cube_timestamp_table
Definition config.hpp:81
std::string compression
Definition config.hpp:70
std::string format
Definition config.hpp:69
bool skip_silently
Definition config.hpp:79
std::string overwrite_policy
Definition config.hpp:80
int nb_of_frames
Definition config.hpp:74
std::string directory
Definition config.hpp:68
int max_frames_buffer
Definition config.hpp:78
Main server configuration.
Definition config.hpp:157
SetValues set_values
Definition config.hpp:168
AcquisitionConfig acquisition
Definition config.hpp:174
std::string camera_name
Definition config.hpp:162
LoggingConfig logging
Definition config.hpp:178
WebInterfaceConfig web_interface
Definition config.hpp:172
HttpServerConfig http_server
Definition config.hpp:171
RecordingConfig recording
Definition config.hpp:175
StreamingConfig streaming
Definition config.hpp:173
TelemetryConfig telemetry
Definition config.hpp:176
AdapterConfig adapter
Definition config.hpp:167
std::string uri
Definition config.hpp:163
int timeout
Definition config.hpp:164
StatisticsConfig statistics
Definition config.hpp:177
bool enabled
Definition config.hpp:105
int window_size
Definition config.hpp:106
bool enabled
Definition config.hpp:60
std::string protocol
Definition config.hpp:61
double sampling_period
Definition config.hpp:93
bool sample_read_only_pars
Definition config.hpp:96
bool enabled
Definition config.hpp:92
bool enabled
Definition config.hpp:48
int max_image_height
Definition config.hpp:50
std::string compression
Definition config.hpp:52
int max_image_width
Definition config.hpp:49
int max_fps
Definition config.hpp:51
std::string body
Definition httplib.h:1294