Directory: | ./ |
---|---|
File: | tmp_project/PhoenixSocket/src/PGenericSocket.h |
Date: | 2025-06-03 16:44:11 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 34 | 49 | 69.4% |
Branches: | 26 | 58 | 44.8% |
Line | Branch | Exec | Source |
---|---|---|---|
1 | /*************************************** | ||
2 | Auteur : Pierre Aubert | ||
3 | Mail : pierre.aubert@lapp.in2p3.fr | ||
4 | Licence : CeCILL-C | ||
5 | ****************************************/ | ||
6 | |||
7 | #ifndef __PGENERIC_SOCKET_H__ | ||
8 | #define __PGENERIC_SOCKET_H__ | ||
9 | |||
10 | #include "PSocketMode.h" | ||
11 | #include "PSocketFlag.h" | ||
12 | #include "phoenix_mock_socket.h" | ||
13 | |||
14 | ///@brief Abstract socket which has a mock mode to avoid heavy socket backend for unit tests | ||
15 | template<typename _TBackend, typename _TMockBackend> | ||
16 | class PGenericSocket{ | ||
17 | public: | ||
18 | PGenericSocket(PSocketMode::PSocketMode mode); | ||
19 | virtual ~PGenericSocket(); | ||
20 | |||
21 | bool createClientSocket(const typename _TBackend::Param & param, const typename _TMockBackend::Param & mockParam); | ||
22 | bool createServerSocket(const typename _TBackend::Param & param, const typename _TMockBackend::Param & mockParam); | ||
23 | |||
24 | ///Send message on the given socket | ||
25 | /** @param data : data to be sent | ||
26 | * @param flag : flag to be used to send the message (BLOCK, NON_BLOCK, etc) | ||
27 | * @return true on success, false otherwise | ||
28 | */ | ||
29 | template<typename U> | ||
30 | 30 | bool sendData(const U & data, PSendFlag::PSendFlag flag){ | |
31 | 30 | size_t dataSize(data_size<U>(data)); | |
32 | 30 | bool b(true); | |
33 | |||
34 |
2/2✓ Branch 0 taken 20 times.
✓ Branch 1 taken 10 times.
|
30 | if(p_mode != PSocketMode::NO_MOCK){ |
35 | 20 | typename _TMockBackend::Message msg; | |
36 |
1/1✓ Branch 1 taken 20 times.
|
20 | _TMockBackend::msgResize(msg, dataSize); |
37 |
1/1✓ Branch 1 taken 20 times.
|
20 | DataStreamIter iter = _TMockBackend::msgData(msg); |
38 |
2/3✓ Branch 1 taken 20 times.
✓ Branch 3 taken 20 times.
✗ Branch 4 not taken.
|
20 | if(data_message_save<U>(iter, data)){ //Save the message |
39 |
1/1✓ Branch 1 taken 20 times.
|
20 | b &= _TMockBackend::send(p_mockSocket, msg, flag); |
40 | }else{ | ||
41 | ✗ | b = false; | |
42 | } | ||
43 | 20 | } | |
44 | |||
45 | // If we dont test if b is true, we will always send the message even if the mock backend is not connected | ||
46 | // I don't know if it is a good idea to do so | ||
47 | // If we do that, we might have somme issues if the user tries to end a message. The mock may give an error that will not be catch | ||
48 | // Because the boolean value is not checked. So the real backend could have sent corretly the message and the mock not.... | ||
49 | |||
50 |
3/4✓ Branch 0 taken 10 times.
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
|
30 | if(p_mode != PSocketMode::MOCK && b){ |
51 | 10 | typename _TBackend::Message msg; | |
52 |
1/2✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
|
10 | _TBackend::msgResize(msg, dataSize); |
53 |
1/2✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
|
10 | DataStreamIter iter = _TBackend::msgData(msg); |
54 |
2/4✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
✗ Branch 4 not taken.
|
10 | if(data_message_save<U>(iter, data)){ //Save the message |
55 |
1/2✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
|
10 | b &= _TBackend::send(p_socket, msg, flag); |
56 | }else{ | ||
57 | ✗ | b = false; | |
58 | } | ||
59 | 10 | } | |
60 | 30 | return b; | |
61 | } | ||
62 | |||
63 | bool sendMsg(typename _TBackend::Message & msg, PSendFlag::PSendFlag flag); | ||
64 | |||
65 | ///Recieve message from the given socket | ||
66 | /** @param data : data to be recieved | ||
67 | * @param flag : flag to be used to send the message (BLOCK, NON_BLOCK, etc) | ||
68 | * @return true on success, false otherwise | ||
69 | */ | ||
70 | template<typename U> | ||
71 | 30 | bool recvData(U & data, PRecvFlag::PRecvFlag flag){ | |
72 | 30 | bool b(true); | |
73 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 20 times.
|
30 | if(p_mode == PSocketMode::NO_MOCK){ //Normal mode |
74 | 10 | typename _TBackend::Message msg; | |
75 |
1/2✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
|
10 | b &= _TBackend::recv(p_socket, msg, flag); |
76 | //If the message is empty we cannot initialise the given data, so, this is an error | ||
77 |
1/2✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
|
10 | b &= _TBackend::msgSize(msg) != 0lu; |
78 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
|
10 | if(b){ |
79 | ✗ | DataStreamIter iter = _TBackend::msgData(msg); | |
80 | ✗ | b &= data_message_load<U>(iter, data); | |
81 | } | ||
82 |
1/2✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
|
30 | }else if(p_mode == PSocketMode::MOCK){ //Mock mode |
83 | 20 | typename _TMockBackend::Message msg; | |
84 |
1/1✓ Branch 1 taken 20 times.
|
20 | b &= _TMockBackend::recv(p_mockSocket, msg, flag); |
85 | //If the message is empty we cannot initialise the given data, so, this is an error | ||
86 |
1/1✓ Branch 1 taken 20 times.
|
20 | b &= _TMockBackend::msgSize(msg) != 0lu; |
87 |
1/2✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
|
20 | if(b){ |
88 |
1/1✓ Branch 1 taken 20 times.
|
20 | DataStreamIter iter = _TMockBackend::msgData(msg); |
89 |
1/1✓ Branch 1 taken 20 times.
|
20 | b &= data_message_load<U>(iter, data); |
90 | } | ||
91 | 20 | }else{ //Mock record mode | |
92 | ✗ | typename _TBackend::Message msg; | |
93 | ✗ | b &= _TBackend::recv(p_socket, msg, flag); | |
94 | //If the message is empty we cannot initialise the given data, so, this is an error | ||
95 | ✗ | b &= _TBackend::msgSize(msg) != 0lu; | |
96 | ✗ | if(b){ | |
97 | ✗ | DataStreamIter iter = _TBackend::msgData(msg); | |
98 | ✗ | b &= data_message_load<U>(iter, data); | |
99 | //Let's convert the message into the mock backend | ||
100 | ✗ | typename _TMockBackend::Message msgMock; | |
101 | ✗ | _TBackend::msgToMock(msgMock, msg); | |
102 | ✗ | b &= _TMockBackend::recv(p_mockSocket, msgMock, flag); | |
103 | } | ||
104 | else { | ||
105 | ✗ | typename _TMockBackend::Message empty_msg; | |
106 | ✗ | b &= _TMockBackend::recv(p_mockSocket, empty_msg, flag); | |
107 | } | ||
108 | } | ||
109 | 30 | return b; | |
110 | } | ||
111 | |||
112 | bool recvMsg(typename _TBackend::Message & msg, PRecvFlag::PRecvFlag flag); | ||
113 | |||
114 | void close(); | ||
115 | bool isConnected() const; | ||
116 | |||
117 | private: | ||
118 | void initialisationPGenericSocket(PSocketMode::PSocketMode mode); | ||
119 | |||
120 | ///Mode of the Socket (no mock, mock, mock_record) | ||
121 | PSocketMode::PSocketMode p_mode; | ||
122 | |||
123 | ///Socket to be used with the classical backend | ||
124 | typename _TBackend::Socket p_socket; | ||
125 | ///Socket to be used with the mock backend | ||
126 | typename _TMockBackend::Socket p_mockSocket; | ||
127 | }; | ||
128 | |||
129 | #include "PGenericSocket_impl.h" | ||
130 | |||
131 | |||
132 | #endif | ||
133 | |||
134 |