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 | |||
25 | bool createClientSocket(const std::string & host, size_t port, const typename _TBackend::Param & param, const std::string & mockPrefix, const typename _TMockBackend::Param & mockParam); | ||
26 | bool createServerSocket(const std::string & host, size_t port, const typename _TBackend::Param & param, const std::string & mockPrefix, const typename _TMockBackend::Param & mockParam); | ||
27 | |||
28 | void setMode(PSocketMode::PSocketMode mode); | ||
29 | |||
30 | ///Send message on the given socket | ||
31 | /** @param data : data to be sent | ||
32 | * @param flag : flag to be used to send the message (BLOCK, NON_BLOCK, etc) | ||
33 | * @return true on success, false otherwise | ||
34 | */ | ||
35 | template<typename U> | ||
36 | 10 | bool sendData(const U & data, PSendFlag::PSendFlag flag){ | |
37 | 10 | size_t dataSize(data_size<U>(data)); | |
38 | 10 | bool b(true); | |
39 | |||
40 |
1/2✓ Branch 0 (3→4) taken 10 times.
✗ Branch 1 (3→14) not taken.
|
10 | if(p_mode != PSocketMode::NO_MOCK){ |
41 | 10 | typename _TMockBackend::Message msg; | |
42 |
1/1✓ Branch 0 (5→6) taken 10 times.
|
10 | _TMockBackend::msgResize(msg, dataSize); |
43 |
1/1✓ Branch 0 (6→7) taken 10 times.
|
10 | DataStreamIter iter = _TMockBackend::msgData(msg); |
44 |
2/3✓ Branch 0 (7→8) taken 10 times.
✓ Branch 2 (8→9) taken 10 times.
✗ Branch 3 (8→11) not taken.
|
10 | if(data_message_save<U>(iter, data)){ //Save the message |
45 |
1/1✓ Branch 0 (9→10) taken 10 times.
|
10 | b &= _TMockBackend::send(p_mockSocket, msg, flag); |
46 | }else{ | ||
47 | ✗ | b = false; | |
48 | } | ||
49 | 10 | } | |
50 | |||
51 | // If we dont test if b is true, we will always send the message even if the mock backend is not connected | ||
52 | // I don't know if it is a good idea to do so | ||
53 | // 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 | ||
54 | // Because the boolean value is not checked. So the real backend could have sent corretly the message and the mock not.... | ||
55 | |||
56 |
2/4✓ Branch 0 (14→15) taken 10 times.
✗ Branch 1 (14→26) not taken.
✓ Branch 2 (15→16) taken 10 times.
✗ Branch 3 (15→26) not taken.
|
10 | if(p_mode != PSocketMode::MOCK && b){ |
57 | 10 | typename _TBackend::Message msg; | |
58 |
1/1✓ Branch 0 (17→18) taken 10 times.
|
10 | _TBackend::msgResize(msg, dataSize); |
59 |
1/1✓ Branch 0 (18→19) taken 10 times.
|
10 | DataStreamIter iter = _TBackend::msgData(msg); |
60 |
2/3✓ Branch 0 (19→20) taken 10 times.
✓ Branch 2 (20→21) taken 10 times.
✗ Branch 3 (20→23) not taken.
|
10 | if(data_message_save<U>(iter, data)){ //Save the message |
61 |
1/1✓ Branch 0 (21→22) taken 10 times.
|
10 | b &= _TBackend::send(p_socket, msg, flag); |
62 | }else{ | ||
63 | ✗ | b = false; | |
64 | } | ||
65 | 10 | } | |
66 | 10 | return b; | |
67 | } | ||
68 | |||
69 | bool sendMsg(typename _TBackend::Message & msg, PSendFlag::PSendFlag flag); | ||
70 | |||
71 | ///Recieve message from the given socket | ||
72 | /** @param data : data to be recieved | ||
73 | * @param flag : flag to be used to send the message (BLOCK, NON_BLOCK, etc) | ||
74 | * @return true on success, false otherwise | ||
75 | */ | ||
76 | template<typename U> | ||
77 | 10 | bool recvData(U & data, PRecvFlag::PRecvFlag flag){ | |
78 | 10 | bool b(true); | |
79 |
1/2✗ Branch 0 (2→3) not taken.
✓ Branch 1 (2→12) taken 10 times.
|
10 | if(p_mode == PSocketMode::NO_MOCK){ //Normal mode |
80 | ✗ | typename _TBackend::Message msg; | |
81 | ✗ | b &= _TBackend::recv(p_socket, msg, flag); | |
82 | //If the message is empty we cannot initialise the given data, so, this is an error | ||
83 | ✗ | b &= _TBackend::msgSize(msg) != 0lu; | |
84 | ✗ | if(b){ | |
85 | ✗ | DataStreamIter iter = _TBackend::msgData(msg); | |
86 | ✗ | b &= data_message_load<U>(iter, data); | |
87 | } | ||
88 |
1/2✓ Branch 0 (12→13) taken 10 times.
✗ Branch 1 (12→22) not taken.
|
10 | }else if(p_mode == PSocketMode::MOCK){ //Mock mode |
89 | 10 | typename _TMockBackend::Message msg; | |
90 |
1/1✓ Branch 0 (14→15) taken 10 times.
|
10 | b &= _TMockBackend::recv(p_mockSocket, msg, flag); |
91 | //If the message is empty we cannot initialise the given data, so, this is an error | ||
92 |
1/1✓ Branch 0 (15→16) taken 10 times.
|
10 | b &= _TMockBackend::msgSize(msg) != 0lu; |
93 |
1/2✓ Branch 0 (16→17) taken 10 times.
✗ Branch 1 (16→20) not taken.
|
10 | if(b){ |
94 |
1/1✓ Branch 0 (17→18) taken 10 times.
|
10 | DataStreamIter iter = _TMockBackend::msgData(msg); |
95 |
1/1✓ Branch 0 (18→19) taken 10 times.
|
10 | b &= data_message_load<U>(iter, data); |
96 | } | ||
97 | 10 | }else{ //Mock record mode | |
98 | ✗ | typename _TBackend::Message msg; | |
99 | ✗ | b &= _TBackend::recv(p_socket, msg, flag); | |
100 | //If the message is empty we cannot initialise the given data, so, this is an error | ||
101 | ✗ | b &= _TBackend::msgSize(msg) != 0lu; | |
102 | ✗ | if(b){ | |
103 | ✗ | DataStreamIter iter = _TBackend::msgData(msg); | |
104 | ✗ | b &= data_message_load<U>(iter, data); | |
105 | //Let's convert the message into the mock backend | ||
106 | ✗ | typename _TMockBackend::Message msgMock; | |
107 | ✗ | _TBackend::msgToMock(msgMock, msg); | |
108 | ✗ | b &= _TMockBackend::recv(p_mockSocket, msgMock, flag); | |
109 | ✗ | } | |
110 | else { | ||
111 | ✗ | typename _TMockBackend::Message empty_msg; | |
112 | ✗ | b &= _TMockBackend::recv(p_mockSocket, empty_msg, flag); | |
113 | ✗ | } | |
114 | ✗ | } | |
115 | 10 | return b; | |
116 | } | ||
117 | |||
118 | bool recvMsg(typename _TBackend::Message & msg, PRecvFlag::PRecvFlag flag); | ||
119 | |||
120 | void close(); | ||
121 | bool isConnected() const; | ||
122 | |||
123 | private: | ||
124 | void initialisationPGenericSocket(PSocketMode::PSocketMode mode); | ||
125 | |||
126 | ///Mode of the Socket (no mock, mock, mock_record) | ||
127 | PSocketMode::PSocketMode p_mode; | ||
128 | |||
129 | ///Socket to be used with the classical backend | ||
130 | typename _TBackend::Socket p_socket; | ||
131 | ///Socket to be used with the mock backend | ||
132 | typename _TMockBackend::Socket p_mockSocket; | ||
133 | }; | ||
134 | |||
135 | #include "PGenericSocket_impl.h" | ||
136 | |||
137 | |||
138 | #endif | ||
139 | |||
140 |