• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

C++ベースのLightweightなHTTPサーバー


Commit MetaInfo

Revision5201a3954ea0f6a36ff5f8828af6f211ce3ffff3 (tree)
Time2013-01-12 23:52:06
AuthorMichio Hirai <smg_ykz@user...>
CommiterMichio Hirai

Log Message

[Refactor] Refine unit testing for cm::SocketServer and cm::SocketClient (further refinement needed)

cm::SocketServer requires setsockopt(,SO_REUSEADDR,) to properly handle restart.

Change Summary

Incremental Difference

--- a/cm/cm_socket_client.cpp
+++ b/cm/cm_socket_client.cpp
@@ -49,7 +49,7 @@ SocketIf* SocketClient::doConnect(const char* server_name, unsigned short port)
4949 assert(false);
5050 }
5151
52- return new Socket(retval);
52+ return new Socket(fd_);
5353 }
5454
5555 } // namespace cm
--- a/cm/test/cm_socket_server_test.cpp
+++ b/cm/test/cm_socket_server_test.cpp
@@ -1,33 +1,138 @@
11
2+#include <vector>
3+#include <iostream>
4+
25 #include "gtest/gtest.h"
36
4-#include "cm_socket.h"
7+#include "cm_thread.h"
8+#include "mt_auto_ptr.h"
9+#include "cm_socket_if.h"
510 #include "cm_socket_server.h"
11+#include "cm_socket_client.h"
612 #include "cm_event.h"
13+#include "mt_range.h"
14+
15+namespace {
716
8-class CmSocketServerTest : public ::testing::Test
17+struct FindSocket
918 {
10-protected:
11- CmSocketServerTest()
12- : server_(cm::SOCKET_TYPE_INET_STREAM, "0.0.0.0", 8888), event_(cm::Event::tsdInstance()),
13- socket_()
19+ FindSocket(cm::SocketIf& socket_if)
20+ : socket_if_(socket_if)
21+ {}
22+
23+ template <typename InputIterator>
24+ InputIterator operator()(InputIterator begin, const InputIterator& end)
1425 {
15- event_.addHandlerRead(*this, &CmSocketServerTest::accept, server_);
26+ for (; begin != end; ++begin) {
27+ if (*begin == &socket_if_) {
28+ return begin;
29+ }
30+ }
31+ return end;
32+ }
33+
34+ const cm::SocketIf& socket_if_;
35+};
36+
37+class CmSocketServerThread
38+{
39+public:
40+ CmSocketServerThread()
41+ : server_(cm::SOCKET_TYPE_INET_STREAM, "0.0.0.0", 8888),
42+ event_(cm::Event::tsdInstance()),
43+ accepted_sockets_()
44+ {
45+ event_.addHandlerRead(*this, &CmSocketServerThread::accept, server_);
1646 }
1747
1848 bool accept(cm::SocketServer& server)
1949 {
20- EXPECT_EQ(&server, &server_);
21- socket_ = server.accept();
22- return true;
50+ std::cout << __FUNCTION__ << " entry" << std::endl;
51+ mt::AutoPtr<cm::SocketIf> sock = server.accept();
52+ cm::SocketIf* socket_ptr = sock.get();
53+ event_.addHandlerRead(*this, &CmSocketServerThread::readSocket, *socket_ptr);
54+ accepted_sockets_.push_back(socket_ptr);
55+ sock.release();
56+ return false;
57+ }
58+
59+ bool readSocket(cm::SocketIf& socket)
60+ {
61+ std::cout << __FUNCTION__ << " entry" << std::endl;
62+
63+ char buffer[20];
64+ size_t bytes_read = 0u;
65+ if (socket.read(bytes_read, buffer, sizeof(buffer))) {
66+ std::cout << "received " << buffer << std::endl;
67+ }
68+ else {
69+ std::cout << "closing socket " << socket.getFD() << std::endl;
70+
71+ FindSocket socket_finder(socket);
72+ std::vector<cm::SocketIf*>::iterator it = socket_finder(mt::begin(accepted_sockets_),
73+ mt::end(accepted_sockets_));
74+ delete *it;
75+ accepted_sockets_.erase(it);
76+ }
77+ return false;
78+ }
79+
80+ void run()
81+ {
82+ unsigned int count = 0u;
83+ while (count < 4) {
84+ std::cout << "Count " << count << std::endl;
85+ event_.pend();
86+ ++count;
87+ }
2388 }
2489
90+private:
2591 cm::SocketServer server_;
2692 cm::Event& event_;
93+ std::vector<cm::SocketIf*> accepted_sockets_;
94+};
95+
96+class CmSocketClientThread
97+{
98+public:
99+ CmSocketClientThread()
100+ : client_(cm::SOCKET_TYPE_INET_STREAM), event_(cm::Event::tsdInstance()),
101+ socket_()
102+ {
103+ socket_ = client_.connect("127.0.0.1", 8888);
104+ }
105+
106+ void run()
107+ {
108+ char buffer[20];
109+ memset(buffer, 0, sizeof(buffer));
110+ strcpy(buffer, "hello world!¥n");
111+ size_t bytes_written = 0u;
112+ socket_->write(bytes_written, buffer, sizeof(buffer));
113+ memset(buffer, 0, sizeof(buffer));
114+ strcpy(buffer, "good bye world!¥n");
115+ socket_->write(bytes_written, buffer, sizeof(buffer));
116+ socket_.reset();
117+ }
118+
119+private:
120+ cm::SocketClient client_;
121+ cm::Event& event_;
27122 mt::AutoPtr<cm::SocketIf> socket_;
28123 };
29124
30-TEST_F(CmSocketServerTest, inet_anyaddr)
125+
126+TEST(CmSocketServerTest, inet_anyaddr)
31127 {
32- event_.pend();
128+ cm::Thread<CmSocketServerThread> server_thread("server_thread");
129+ server_thread.create();
130+
131+ CmSocketClientThread client;
132+
133+ client.run();
134+
135+ server_thread.join();
33136 }
137+
138+} // namespace
--- a/inc/cm_socket_client.h
+++ b/inc/cm_socket_client.h
@@ -12,6 +12,7 @@ class SocketIf;
1212
1313 class SocketClient
1414 {
15+public:
1516 SocketClient(SocketType type, bool is_nonblock = false);
1617
1718 virtual ~SocketClient();
--- a/inc/cm_thread.h
+++ b/inc/cm_thread.h
@@ -63,8 +63,10 @@ private:
6363 if (SETNAME(thread_arg->tid, thread_arg->name.c_str())) {
6464 assert(false);
6565 }
66- T obj(thread_arg->arg);
67- obj.run();
66+ {
67+ T obj(thread_arg->arg);
68+ obj.run();
69+ }
6870 pthread_exit(0);
6971 }
7072
@@ -74,8 +76,10 @@ private:
7476 if (SETNAME(thread_arg->tid, thread_arg->name.c_str())) {
7577 assert(false);
7678 }
77- T obj;
78- obj.run();
79+ {
80+ T obj;
81+ obj.run();
82+ }
7983 pthread_exit(0);
8084 }
8185