LCOV - code coverage report
Current view: top level - daphnemodules/test/apps - DaphneMezzModule_test.cxx (source / functions) Coverage Total Hit
Test: code.result Lines: 0.0 % 87 0
Test Date: 2025-12-21 13:07:08 Functions: 0.0 % 4 0

            Line data    Source code
       1              : /**
       2              :  * @file DaphneMezzModule_test.cxx
       3              :  *
       4              :  * Testing configurations sender for the daphne v3 
       5              :  *
       6              :  * This is part of the DUNE DAQ Software Suite, copyright 2020.
       7              :  * Licensing/copyright details are in the COPYING file that you should have
       8              :  * received with this code.
       9              :  *
      10              :  */
      11              : 
      12              : #include "DaphneV3Interface.hpp"
      13              : 
      14              : #include <zmq.hpp>
      15              : #include "daphnemodules/daphne_control_high.pb.h"
      16              : 
      17              : #include <iostream>
      18              : #include <string>
      19              : #include <vector>
      20              : #include <stdexcept>
      21              : #include <cstdlib>
      22              : #include <cstring>
      23              : #include <chrono>
      24              : #include <random>
      25              : 
      26              : 
      27              : 
      28              : using namespace daphne;
      29              : using namespace dunedaq::daphnemodules;
      30              : 
      31              : // ------------- small helpers -------------
      32              : static std::vector<zmq::message_t> recv_multipart(zmq::socket_t& s) {
      33              :   std::vector<zmq::message_t> frames;
      34              :   while (true) {
      35              :     zmq::message_t part;
      36              :     auto ok = s.recv(part, zmq::recv_flags::none);
      37              :     if (!ok || *ok <= 0) throw std::runtime_error("No response from slow controller");
      38              :     frames.emplace_back(std::move(part));
      39              :     if (!s.get(zmq::sockopt::rcvmore)) break;
      40              :   }
      41              :   return frames;
      42              : }
      43              : 
      44            0 : static inline uint64_t now_ns() {
      45            0 :   using namespace std::chrono;
      46            0 :   return duration_cast<nanoseconds>(steady_clock::now().time_since_epoch()).count();
      47              : }
      48              : 
      49            0 : static inline std::pair<uint64_t,uint64_t> next_ids() {
      50            0 :   static std::mt19937_64 rng{std::random_device{}()};
      51            0 :   static uint64_t seq = 1;
      52            0 :   uint64_t t = now_ns();
      53            0 :   uint64_t task = (t << 16) ^ (rng() & 0xFFFF);
      54            0 :   uint64_t msg  = (t << 1) ^ (++seq);
      55            0 :   task &= ((1ull<<63)-1);
      56            0 :   msg  &= ((1ull<<63)-1);
      57            0 :   return {task, msg};
      58              : }
      59              : 
      60            0 : static void usage(const char* prog) {
      61            0 :   std::cerr << "Usage: " << prog << " [--ip <addr>] [--port <num>] [--route <name>]\n"
      62              :             << "       " << prog << " [ip] [port]\n"
      63              :             << "Env:   DAPHNE_IP, DAPHNE_PORT\n"
      64            0 :             << "Default: 10.73.137.161:9000, route=mezz/0\n";
      65            0 : }
      66              : 
      67            0 : int main(int argc, char** argv) {
      68              :   // ---- Defaults
      69            0 :   std::string ip = "10.73.137.161";
      70            0 :   int port = 9000;
      71            0 :   std::string route = "mezz/0";
      72              : 
      73              :   // ---- Env
      74            0 :   if (const char* eip = std::getenv("DAPHNE_IP"); eip && *eip) ip = eip;
      75            0 :   if (const char* ep  = std::getenv("DAPHNE_PORT"); ep  && *ep) { try { port = std::stoi(ep); } catch (...) {} }
      76              : 
      77              :   // ---- CLI flags (priority over env)
      78            0 :   for (int i = 1; i < argc; ++i) {
      79            0 :     if (!std::strcmp(argv[i], "--help") || !std::strcmp(argv[i], "-h")) {
      80            0 :       usage(argv[0]); return 0;
      81              :     }
      82            0 :     if (!std::strcmp(argv[i], "--ip")    && i + 1 < argc) { ip = argv[++i]; continue; }
      83            0 :     if (!std::strcmp(argv[i], "--port")  && i + 1 < argc) { try { port = std::stoi(argv[++i]); } catch (...) {} continue; }
      84            0 :     if (!std::strcmp(argv[i], "--route") && i + 1 < argc) { route = argv[++i]; continue; }
      85              :   }
      86              :   // ---- Positional args (fallback if flags not used)
      87            0 :   if (argc >= 2 && argv[1][0] != '-') ip = argv[1];
      88            0 :   if (argc >= 3 && argv[2][0] != '-') { try { port = std::stoi(argv[2]); } catch (...) {} }
      89              : 
      90            0 :   const std::string address = ip + ":" + std::to_string(port);
      91            0 :   const std::string endpoint = "tcp://" + address;
      92            0 :   std::cerr << "[SMOKE-V2] connecting to " << endpoint << " route=" << route << "\n";
      93              : 
      94              : 
      95              :   
      96            0 :   DaphneV3Interface iface( address, route);
      97              :   
      98            0 :   GOOGLE_PROTOBUF_VERIFY_VERSION;
      99              : 
     100              :   // ---- Build ConfigureRequest (same payload you used before)
     101            0 :   ConfigureRequest cfg;
     102            0 :   cfg.set_daphne_address(ip);
     103            0 :   cfg.set_slot(0);
     104            0 :   cfg.set_timeout_ms(500);
     105            0 :   cfg.set_biasctrl(1300);
     106            0 :   cfg.set_self_trigger_threshold(0x1F40);
     107            0 :   cfg.set_self_trigger_xcorr(0x68);
     108            0 :   cfg.set_tp_conf(0x0010DB35);
     109            0 :   cfg.set_compensator(0xFFFFFFFFFFull);
     110            0 :   cfg.set_inverters(0xFF00000000ull);
     111              : 
     112            0 :   for (uint32_t ch = 0; ch < 40; ++ch) {
     113            0 :     auto* c = cfg.add_channels();
     114            0 :     c->set_id(ch);
     115            0 :     c->set_trim(0);
     116            0 :     c->set_offset(2275);
     117            0 :     c->set_gain(1);
     118              :   }
     119            0 :   for (uint32_t afe = 0; afe < 5; ++afe) {
     120            0 :     auto* a = cfg.add_afes();
     121            0 :     a->set_id(afe);
     122            0 :     a->set_attenuators(1600);
     123            0 :     a->set_v_bias(0);
     124            0 :     a->mutable_adc()->set_resolution(true);
     125            0 :     a->mutable_adc()->set_output_format(true);
     126            0 :     a->mutable_adc()->set_sb_first(false);
     127            0 :     a->mutable_pga()->set_lpf_cut_frequency(4);
     128            0 :     a->mutable_pga()->set_integrator_disable(true);
     129            0 :     a->mutable_pga()->set_gain(0);
     130            0 :     a->mutable_lna()->set_clamp(0);
     131            0 :     a->mutable_lna()->set_gain(2);
     132            0 :     a->mutable_lna()->set_integrator_disable(true);
     133              :   }
     134              : 
     135              :   // ---- Wrap in V2 envelope
     136            0 :   ControlEnvelopeV2 req;
     137            0 :   req.set_version(2);
     138            0 :   req.set_dir(DIR_REQUEST);
     139            0 :   req.set_type(MT2_CONFIGURE_FE_REQ);
     140            0 :   req.set_payload(cfg.SerializeAsString());
     141            0 :   {
     142            0 :     auto [task_id, msg_id] = next_ids();
     143            0 :     req.set_task_id(task_id);
     144            0 :     req.set_msg_id(msg_id);
     145            0 :     req.set_timestamp_ns(now_ns());
     146            0 :     if (!route.empty()) req.set_route(route);
     147              :   }
     148              : 
     149            0 :   try {
     150              :     // zmq::context_t ctx(1);
     151              :     // zmq::socket_t  sock(ctx, zmq::socket_type::dealer);
     152              :     // sock.set(zmq::sockopt::routing_id, "zmq-config-smoke-v2");
     153              :     // sock.set(zmq::sockopt::rcvtimeo, 4000);
     154              :     // sock.set(zmq::sockopt::sndtimeo, 4000);
     155              :     // sock.connect(endpoint);
     156              : 
     157              :     
     158              :     // send
     159              :     // {
     160              :     //   std::string bytes = req.SerializeAsString();
     161              :     //   zmq::message_t msg(bytes.size());
     162              :     //   std::memcpy(msg.data(), bytes.data(), bytes.size());
     163              :     //   if (!sock.send(msg, zmq::send_flags::none)) {
     164              :     //     std::cerr << "send() timed out\n"; return 2;
     165              :     //   }
     166              :     // }
     167              : 
     168              :     // // recv
     169              :     // auto frames = recv_multipart(sock);
     170              :     // const zmq::message_t& payload = frames.back();
     171              : 
     172              :     // ControlEnvelopeV2 rep;
     173              :     // if (!rep.ParseFromArray(payload.data(), static_cast<int>(payload.size()))) {
     174              :     //   std::cerr << "Failed to parse ControlEnvelopeV2 reply\n"; return 3;
     175              :     // }
     176              : 
     177              :     
     178              :     // // validate V2 transport
     179              :     // bool ok_dir  = (rep.dir()  == DIR_RESPONSE);
     180              :     // bool ok_type = (rep.type() == MT2_CONFIGURE_FE_RESP);
     181              :     // bool ok_tid  = (rep.task_id()   == req.task_id());
     182              :     // bool ok_corr = (rep.correl_id() == req.msg_id());
     183              :     // if (!ok_dir || !ok_type || !ok_tid || !ok_corr) {
     184              :     //   std::cerr << "Correlation/type mismatch:"
     185              :     //             << "\n  dir:  got " << rep.dir()  << " expect " << DIR_RESPONSE
     186              :     //             << "\n  type: got " << rep.type() << " expect " << MT2_CONFIGURE_FE_RESP
     187              :     //             << "\n  task: got " << rep.task_id()  << " expect " << req.task_id()
     188              :     //             << "\n  corr: got " << rep.correl_id()<< " expect " << req.msg_id()
     189              :     //             << "\n";
     190              :     //   return 4;
     191              :     // }
     192              : 
     193              :     // // decode payload
     194              :     // ConfigureResponse resp;
     195              :     // if (!resp.ParseFromString(rep.payload())) {
     196              :     //   std::cerr << "Failed to parse ConfigureResponse\n"; return 5;
     197              :     // }
     198              : 
     199            0 :     auto resp = iface.send<ConfigureResponse>( cfg.SerializeAsString(), MT2_CONFIGURE_FE_REQ, MT2_CONFIGURE_FE_RESP);
     200              :     
     201              :     // std::cout << "[V2 meta]\n";
     202              :     // std::cout << "  task_id      : " << rep.task_id() << "\n";
     203              :     // std::cout << "  msg_id       : " << rep.msg_id() << "\n";
     204              :     // std::cout << "  correl_id    : " << rep.correl_id() << "\n";
     205              :     // std::cout << "  timestamp_ns : " << rep.timestamp_ns() << "\n";
     206              :     // if (!rep.route().empty())
     207              :     //   std::cout << "  route        : " << rep.route() << "\n";
     208              :     // std::cout << "\n";
     209            0 :     std::cout << "Success: " << std::boolalpha << resp.success() << "\n";
     210            0 :     std::cout << "Message:\n" << resp.message() << "\n";
     211              : 
     212            0 :     google::protobuf::ShutdownProtobufLibrary();
     213            0 :     return resp.success() ? 0 : 6;
     214              : 
     215            0 :   } catch (const std::exception& e) {
     216            0 :     std::cerr << "Exception: " << e.what() << "\n";
     217            0 :     return 7;
     218            0 :   }
     219            0 : }
        

Generated by: LCOV version 2.0-1