GCC Code Coverage Report


Directory: ./
File: TESTS/TEST_BACKEND_ERRORS/main_receiver_errors.cpp
Date: 2026-01-23 17:10:06
Exec Total Coverage
Lines: 66 69 95.7%
Functions: 7 7 100.0%
Branches: 119 134 88.8%

Line Branch Exec Source
1 #include <iostream>
2 #include <thread>
3 #include <chrono>
4 #include <zmq.hpp>
5 #include <unistd.h>
6 #include <atomic>
7 #include "data_stream_assert.h"
8 #include "PGenericSocketManager.h"
9 #include "PZmqBackend.h"
10
11 typedef PGenericSocketManager<std::string, PZmqBackend, PMockBackend> SocketManager;
12 typedef SocketManager::Backend Backend;
13 typedef SocketManager::Mock Mock;
14
15 // Test 1: EAGAIN - No messages available in non-blocking mode
16 1 void test_no_message() {
17
2/2
✓ Branch 0 (2→3) taken 1 times.
✓ Branch 2 (3→4) taken 1 times.
1 std::cout << "\n1. Test no message available (non-blocking):" << std::endl;
18
1/1
✓ Branch 0 (4→5) taken 1 times.
1 SocketManager manager(PSocketMode::NO_MOCK);
19
20
11/14
✓ Branch 0 (7→8) taken 1 times.
✓ Branch 2 (10→11) taken 1 times.
✓ Branch 4 (13→14) taken 1 times.
✓ Branch 6 (14→15) taken 1 times.
✓ Branch 8 (17→18) taken 1 times.
✓ Branch 10 (18→19) taken 1 times.
✓ Branch 12 (21→22) taken 1 times.
✓ Branch 14 (24→25) taken 1 times.
✓ Branch 16 (25→26) taken 1 times.
✓ Branch 18 (26→27) taken 1 times.
✗ Branch 20 (30→31) not taken.
✓ Branch 21 (30→32) taken 1 times.
✗ Branch 22 (79→80) not taken.
✗ Branch 23 (79→81) not taken.
11 data_stream_assert(manager.addClientSocket("receiver", PSocketParam{"localhost", 5565}, Backend::client(), "./", Mock::client()));
21
22 1 size_t data = 0;
23
2/2
✓ Branch 0 (43→44) taken 1 times.
✓ Branch 2 (44→45) taken 1 times.
1 PRecvStatus::PRecvStatus status = manager.recvData("receiver", data, PRecvFlag::NON_BLOCK);
24
25
5/5
✓ Branch 0 (47→48) taken 1 times.
✓ Branch 2 (48→49) taken 1 times.
✓ Branch 4 (49→50) taken 1 times.
✓ Branch 6 (50→51) taken 1 times.
✓ Branch 8 (51→52) taken 1 times.
1 std::cout << " Recv status: " << statusToStr(status) << " should be SOCKET_NOT_AVAILABLE" << std::endl;
26
4/4
✓ Branch 0 (55→56) taken 1 times.
✓ Branch 2 (58→59) taken 1 times.
✓ Branch 4 (61→62) taken 1 times.
✓ Branch 6 (62→63) taken 1 times.
5 data_stream_assert(status == PRecvStatus::NO_MESSAGE_RECEIVED);
27 1 }
28
29 // Test 2: Test broken socket
30 1 void test_broken_socket() {
31
2/2
✓ Branch 0 (2→3) taken 1 times.
✓ Branch 2 (3→4) taken 1 times.
1 std::cout << "\n2. Test broken socket:" << std::endl;
32
1/1
✓ Branch 0 (4→5) taken 1 times.
1 SocketManager manager(PSocketMode::NO_MOCK);
33
34 // Add socket then remove it
35
11/14
✓ Branch 0 (7→8) taken 1 times.
✓ Branch 2 (10→11) taken 1 times.
✓ Branch 4 (13→14) taken 1 times.
✓ Branch 6 (14→15) taken 1 times.
✓ Branch 8 (17→18) taken 1 times.
✓ Branch 10 (18→19) taken 1 times.
✓ Branch 12 (21→22) taken 1 times.
✓ Branch 14 (24→25) taken 1 times.
✓ Branch 16 (25→26) taken 1 times.
✓ Branch 18 (26→27) taken 1 times.
✗ Branch 20 (30→31) not taken.
✓ Branch 21 (30→32) taken 1 times.
✗ Branch 22 (85→86) not taken.
✗ Branch 23 (85→87) not taken.
12 data_stream_assert(manager.addClientSocket("receiver", PSocketParam{"localhost", 5566}, Backend::client(), "./", Mock::client()));
36
2/2
✓ Branch 0 (43→44) taken 1 times.
✓ Branch 2 (44→45) taken 1 times.
1 manager.removeSocket("receiver");
37
38 1 size_t data = 0;
39
2/2
✓ Branch 0 (49→50) taken 1 times.
✓ Branch 2 (50→51) taken 1 times.
1 PRecvStatus::PRecvStatus status = manager.recvData("receiver", data, PRecvFlag::NON_BLOCK);
40
41
5/5
✓ Branch 0 (53→54) taken 1 times.
✓ Branch 2 (54→55) taken 1 times.
✓ Branch 4 (55→56) taken 1 times.
✓ Branch 6 (56→57) taken 1 times.
✓ Branch 8 (57→58) taken 1 times.
1 std::cout << " Recv status: " << statusToStr(status) << " should be BROKEN_SOCKET" << std::endl;
42
4/4
✓ Branch 0 (61→62) taken 1 times.
✓ Branch 2 (64→65) taken 1 times.
✓ Branch 4 (67→68) taken 1 times.
✓ Branch 6 (68→69) taken 1 times.
5 data_stream_assert(status == PRecvStatus::BROKEN_SOCKET);
43 1 }
44
45 // Test 3: Test with PUSH socket (wrong type for receiving)
46 1 void test_wrong_socket_type() {
47
2/2
✓ Branch 0 (2→3) taken 1 times.
✓ Branch 2 (3→4) taken 1 times.
1 std::cout << "\n3. Test wrong socket type for receiving:" << std::endl;
48
1/1
✓ Branch 0 (4→5) taken 1 times.
1 SocketManager manager(PSocketMode::NO_MOCK);
49
50 // Create a PUSH server socket (sends only)
51
11/14
✓ Branch 0 (7→8) taken 1 times.
✓ Branch 2 (10→11) taken 1 times.
✓ Branch 4 (13→14) taken 1 times.
✓ Branch 6 (14→15) taken 1 times.
✓ Branch 8 (17→18) taken 1 times.
✓ Branch 10 (18→19) taken 1 times.
✓ Branch 12 (21→22) taken 1 times.
✓ Branch 14 (24→25) taken 1 times.
✓ Branch 16 (25→26) taken 1 times.
✓ Branch 18 (26→27) taken 1 times.
✗ Branch 20 (30→31) not taken.
✓ Branch 21 (30→32) taken 1 times.
✗ Branch 22 (79→80) not taken.
✗ Branch 23 (79→81) not taken.
11 data_stream_assert(manager.addServerSocket("sender", PSocketParam{"localhost", 5567}, Backend::server(), "./", Mock::server()));
52
53 1 size_t data = 0;
54
2/2
✓ Branch 0 (43→44) taken 1 times.
✓ Branch 2 (44→45) taken 1 times.
1 PRecvStatus::PRecvStatus status = manager.recvData("sender", data, PRecvFlag::NON_BLOCK);
55
56
5/5
✓ Branch 0 (47→48) taken 1 times.
✓ Branch 2 (48→49) taken 1 times.
✓ Branch 4 (49→50) taken 1 times.
✓ Branch 6 (50→51) taken 1 times.
✓ Branch 8 (51→52) taken 1 times.
1 std::cout << " Recv status: " << statusToStr(status) << " should be BROKEN_BACKEND" << std::endl;
57
4/4
✓ Branch 0 (55→56) taken 1 times.
✓ Branch 2 (58→59) taken 1 times.
✓ Branch 4 (61→62) taken 1 times.
✓ Branch 6 (62→63) taken 1 times.
5 data_stream_assert(status == PRecvStatus::BROKEN_BACKEND);
58 1 }
59
60 // Test 4: Test socket closure during operation
61 1 void test_socket_closure() {
62
2/2
✓ Branch 0 (2→3) taken 1 times.
✓ Branch 2 (3→4) taken 1 times.
1 std::cout << "\n4. Test socket closure (simulates context termination):" << std::endl;
63
64 1 std::atomic<bool> recv_started{false};
65 1 std::atomic<PRecvStatus::PRecvStatus> recv_status{PRecvStatus::OK};
66 1 std::atomic<bool> recv_done{false};
67
68
1/1
✓ Branch 0 (4→5) taken 1 times.
1 SocketManager manager(PSocketMode::NO_MOCK);
69
11/14
✓ Branch 0 (7→8) taken 1 times.
✓ Branch 2 (10→11) taken 1 times.
✓ Branch 4 (13→14) taken 1 times.
✓ Branch 6 (14→15) taken 1 times.
✓ Branch 8 (17→18) taken 1 times.
✓ Branch 10 (18→19) taken 1 times.
✓ Branch 12 (21→22) taken 1 times.
✓ Branch 14 (24→25) taken 1 times.
✓ Branch 16 (25→26) taken 1 times.
✓ Branch 18 (26→27) taken 1 times.
✗ Branch 20 (30→31) not taken.
✓ Branch 21 (30→32) taken 1 times.
✗ Branch 22 (116→117) not taken.
✗ Branch 23 (116→118) not taken.
11 data_stream_assert(manager.addServerSocket("receiver", PSocketParam{"localhost", 5568}, Backend::server(), "./", Mock::server()));
70
71 std::thread recv_thread([&]() {
72 1 recv_started = true;
73 1 size_t data = 0;
74
75 // Try to recv multiple times with small delays, socket will be closed in other thread to create error
76 1 int attempts = 0;
77 1 const int max_attempts = 50;
78
79
1/2
✓ Branch 0 (17→4) taken 1 times.
✗ Branch 1 (17→18) not taken.
1 while (attempts < max_attempts) {
80
2/2
✓ Branch 0 (6→7) taken 1 times.
✓ Branch 2 (7→8) taken 1 times.
2 recv_status = manager.recvData("receiver", data, PRecvFlag::NON_BLOCK);
81
1/2
✓ Branch 0 (12→13) taken 1 times.
✗ Branch 1 (12→14) not taken.
1 if (recv_status != PRecvStatus::SOCKET_NOT_AVAILABLE) {
82 1 break;
83 }
84 std::this_thread::sleep_for(std::chrono::milliseconds(10));
85 attempts++;
86 }
87
88 1 recv_done = true;
89
1/1
✓ Branch 0 (41→42) taken 1 times.
2 });
90
91 // Wait for recv to start
92
2/2
✓ Branch 0 (47→43) taken 1 times.
✓ Branch 1 (47→48) taken 1 times.
2 while (!recv_started.load()) {
93
1/1
✓ Branch 0 (44→45) taken 1 times.
1 std::this_thread::sleep_for(std::chrono::milliseconds(10));
94 }
95
96 // Close the socket while recv is trying
97
1/1
✓ Branch 0 (49→50) taken 1 times.
1 std::this_thread::sleep_for(std::chrono::milliseconds(200));
98
3/3
✓ Branch 0 (52→53) taken 1 times.
✓ Branch 2 (53→54) taken 1 times.
✓ Branch 4 (54→55) taken 1 times.
2 manager.getSocket("receiver")->close();
99
2/2
✓ Branch 0 (59→60) taken 1 times.
✓ Branch 2 (60→61) taken 1 times.
1 manager.removeSocket("receiver");
100
101
1/1
✓ Branch 0 (63→64) taken 1 times.
1 recv_thread.join();
102
103
4/4
✓ Branch 0 (66→67) taken 1 times.
✓ Branch 2 (69→70) taken 1 times.
✓ Branch 4 (72→73) taken 1 times.
✓ Branch 6 (74→75) taken 1 times.
6 data_stream_assert(recv_done.load());
104 // Should be BROKEN_SOCKET
105
4/4
✓ Branch 0 (83→84) taken 1 times.
✓ Branch 2 (86→87) taken 1 times.
✓ Branch 4 (89→90) taken 1 times.
✓ Branch 6 (91→92) taken 1 times.
5 data_stream_assert(recv_status.load() == PRecvStatus::BROKEN_BACKEND);
106
5/5
✓ Branch 0 (98→99) taken 1 times.
✓ Branch 2 (100→101) taken 1 times.
✓ Branch 4 (101→102) taken 1 times.
✓ Branch 6 (102→103) taken 1 times.
✓ Branch 8 (103→104) taken 1 times.
1 std::cout << " Recv status: " << statusToStr(recv_status.load()) << " should be BROKEN_BACKEND" << std::endl;
107 1 }
108
109 1 void testRecvErrors() {
110 1 std::cout << "=== Test error cases when receiving via Backend Manager ===" << std::endl;
111
112 1 test_no_message();
113 1 test_broken_socket();
114 1 test_wrong_socket_type();
115 1 test_socket_closure();
116
117 1 std::cout << "\n✓ All backend receiver tests passed" << std::endl;
118 1 }
119
120 1 int main() {
121 1 testRecvErrors();
122 1 return 0;
123 }
124