| 181 | }; |
| 182 | |
| 183 | class tester : public tester_base, public waiter { |
| 184 | public: |
| 185 | tester() : waiter(3), container_(*this, "reconnect_client") {} |
| 186 | |
| 187 | void on_container_start(proton::container &c) override { |
| 188 | // Server that fails upon connection |
| 189 | s1.reset(new server_connection_handler(c, 0, *this)); |
| 190 | // Server that fails on first message |
| 191 | s2.reset(new server_connection_handler(c, 1, *this)); |
| 192 | // server that doesn't fail in this test |
| 193 | s3.reset(new server_connection_handler(c, 100, *this)); |
| 194 | } |
| 195 | |
| 196 | // waiter::ready is called when all 3 listeners are ready. |
| 197 | void ready() override { |
| 198 | container_.connect(s1->url(), proton::connection_options().failover_urls({s2->url(), s3->url()})); |
| 199 | } |
| 200 | |
| 201 | void run() { |
| 202 | container_.run(); |
| 203 | ASSERT_EQUAL(1, start_count); |
| 204 | ASSERT_EQUAL(3, open_count); |
| 205 | // Could be > 3, unpredictable number reconnects while listener comes up. |
| 206 | ASSERT(2 < transport_error_count); |
| 207 | // Last reconnect fails before opening links |
| 208 | ASSERT(1 < link_open_count); |
| 209 | // One final transport close, not an error |
| 210 | ASSERT_EQUAL(1, transport_close_count); |
| 211 | ASSERT_EQUAL(0, connection_error_count); |
| 212 | } |
| 213 | |
| 214 | private: |
| 215 | std::unique_ptr<server_connection_handler> s1; |
| 216 | std::unique_ptr<server_connection_handler> s2; |
| 217 | std::unique_ptr<server_connection_handler> s3; |
| 218 | proton::container container_; |
| 219 | }; |
| 220 | |
| 221 | int test_failover_simple() { |
| 222 | tester().run(); |
no outgoing calls