template <typename Protocol, typename StreamSocketService = stream_socket_service<Protocol> > class basic_stream_socket : public basic_socket<Protocol, StreamSocketService> { }
template <typename ConnectHandler> void async_connect(const endpoint_type& peer_endpoint, BOOST_ASIO_MOVE_ARG(ConnectHandler) handler) { ..... this->get_service().async_connect(this->get_implementation(), peer_endpoint, BOOST_ASIO_MOVE_CAST(ConnectHandler)(handler)); }
class BoostPrimitives { public: typedef boost::asio::ip::tcp::socket TCPSocket; typedef boost::asio::ip::icmp::socket ICMPSocket; typedef boost::asio::ip::tcp::resolver Resolver; typedef boost::asio::deadline_timer Timer; };
class Primitives { public: typedef ba::basic_stream_socket < ba::ip::tcp, SocketService<ba::ip::tcp> > TCPSocket; typedef ba::basic_raw_socket < ba::ip::icmp, SocketService<ba::ip::icmp> > ICMPSocket; typedef ba::basic_deadline_timer < boost::posix_time::ptime, ba::time_traits<boost::posix_time::ptime>, TimerService < boost::posix_time::ptime, ba::time_traits<boost::posix_time::ptime> > > Timer; typedef ba::ip::basic_resolver < ba::ip::tcp, ResolverService<ba::ip::tcp> > Resolver; };
template<typename Traits> class PingerImpl { ..... //! Socket type typedef typename Traits::TCPSocket TCPSocket; ..... }
class Pinger { //! Implementation type typedef PingerImpl<BoostPrimitives> Impl; .... private: //! Implementation std::auto_ptr<Impl> m_Impl; };
class BaseTest : boost::noncopyable { protected: //! Pinger implementation type typedef Net::PingerImpl<Test::Primitives> TestPinger; .... };
//! Pinger test command interface class ICommand : boost::noncopyable { public: //! Command pointer typedef boost::shared_ptr<ICommand> Ptr; //! Error callback type typedef boost::function<void(const boost::system::error_code&)> ErrorCallback; //! Error and size callback typedef boost::function<void(const boost::system::error_code&, std::size_t)> ErrorAndSizeCallback; //! Resolver callback typedef boost::function<void(const boost::system::error_code&, boost::asio::ip::tcp::resolver::iterator)> ResolverCallback; public: ICommand(const Status::Enum status) : m_Status(status) {} //! Timer wait virtual void AsyncWait(ErrorCallback& callback, boost::asio::io_service& io); //! Async connect virtual void AsyncConnect(ErrorCallback& callback, boost::asio::io_service& io); //! Async receive virtual void AsyncReceive(ErrorAndSizeCallback& callback, const std::vector<char>& sended, const boost::asio::mutable_buffer& buffer, boost::asio::io_service& io); //! Async resolve virtual void AsyncResolve(ResolverCallback& callback, boost::asio::io_service& io); //! Dtor virtual ~ICommand() {} protected: Status::Enum m_Status; };
void Connect::AsyncConnect(ErrorCallback& callback, boost::asio::io_service& io) { if (m_Status != Status::Pending) { io.post(boost::bind(callback, m_Code)); callback = ErrorCallback(); } }
void ICommand::AsyncConnect(ErrorCallback& /*callback*/, boost::asio::io_service& /*io*/) { assert(false); }
//! Test fixture class Fixture { //! Commands list typedef std::list<ICommand::Ptr> Commands; public: Fixture(); ~Fixture(); static void Push(ICommand* cmd); static ICommand::Ptr Pop(); private: static Commands s_Commands; }; Fixture::Commands Fixture::s_Commands; Fixture::Fixture() { assert(s_Commands.empty()); // , - } Fixture::~Fixture() { assert(s_Commands.empty()); // } void Fixture::Push(ICommand* cmd) { s_Commands.push_back(ICommand::Ptr(cmd)); } ICommand::Ptr Fixture::Pop() { assert(!s_Commands.empty()); const ICommand::Ptr result = s_Commands.front(); s_Commands.pop_front(); return result; }
template<typename T> void async_connect(implementation_type& /*impl*/, const endpoint& /*ep*/, const T& callback) { m_ConnectCallback = callback; Fixture::Pop()->AsyncConnect(m_ConnectCallback, m_Service); // }
class BaseTest : boost::noncopyable { protected: //! Pinger implementation type typedef Net::PingerImpl<Test::Primitives> TestPinger; BaseTest() { m_Pinger.reset(new TestPinger(boost::bind(&BaseTest::Callback, this, _1, _2))); } virtual ~BaseTest() { m_Pinger->AddRequest(m_Command); while (m_Pinger->IsActive()) boost::this_thread::interruptible_wait(100); } template<typename T> void Cmd(const Status::Enum status) { m_Fixture.Push(new T(status)); } template<typename T, typename A> void Cmd(const Status::Enum status, const A& arg) { m_Fixture.Push(new T(status, arg)); } void Callback(const Net::PingCommand& /*cmd*/, const Net::PingResult& /*rslt*/) { // , } Fixture m_Fixture; std::auto_ptr<TestPinger> m_Pinger; Net::PingCommand m_Command; }; // // - , . class ICMPTest : public testing::Test, public BaseTest { }; TEST(ICMPTest, ICMPSuccess) { m_Command.m_HostName = "ptsecurity.ru"; Cmd<Resolve>(Status::Success, m_Command.m_HostName); // IP Cmd<Wait>(Status::Pending); // , Status::Pending – , Cmd<Receive>(Status::Success); // m_Command.m_Flags = SCANMGR_PING_ICMP; // BaseTest } TEST(ICMPTest, ICMPFail) { m_Command.m_HostName = "ptsecurity.ru"; Cmd<Resolve>(Status::Success, m_Command.m_HostName); // IP Cmd<Wait>(Status::Success); // , Status::Success – , Cmd<Receive>(Status::Pending); // m_Command.m_Flags = SCANMGR_PING_ICMP; // BaseTest }
class TestLogic : public Net::PingerLogic { public: TestLogic(const Net::PingCommand& cmd, const Net::Pinger::Callback& callback) : Net::PingerLogic(cmd, callback) { } MOCK_METHOD1(InitPorts, void (const std::string& ports)); MOCK_METHOD1(ResolveIP, bool (const std::string& name)); MOCK_METHOD1(StartResolveNameByIp, void (unsigned long ip)); MOCK_METHOD1(StartResolveIpByName, void (const std::string& name)); MOCK_METHOD1(StartTCPPing, void (std::size_t timeout)); MOCK_METHOD1(StartICMPPing, void (std::size_t timeout)); MOCK_METHOD1(StartGetNetBiosName, void (const std::string& name)); MOCK_METHOD0(Cancel, void ()); };
TEST(Logic, Start) { const std::string host = "ptsecurity.ru"; EXPECT_CALL(*m_Logic, InitPorts(g_TargetPorts)).Times(Exactly(1)); EXPECT_CALL(*m_Logic, ResolveIP(host)).Times(Exactly(1)).WillOnce(Return(true)); EXPECT_CALL(*m_Logic, StartResolveIpByName(host)).Times(Exactly(1)); m_Logic->OnStart(); } TEST(Logic, ResolveIp) { static const unsigned long ip = 0x10101010; EXPECT_CALL(*m_Logic, StartResolveNameByIp(ip)).Times(Exactly(1)); EXPECT_CALL(*m_Logic, StartICMPPing(1)).Times(Exactly(1)); EXPECT_CALL(*m_Logic, StartTCPPing(1)).Times(Exactly(1)); m_Logic->OnIpResolved(ip); }
Source: https://habr.com/ru/post/166139/
All Articles