/* * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. * A copy of the License is located at * * http://aws.amazon.com/apache2.0/ * * or in the "license" file accompanying this file. This file is distributed * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language governing * permissions and limitations under the License. */ #ifndef ALEXA_CLIENT_SDK_ACL_TEST_TRANSPORT_MOCKHTTP2CONNECTION_H_ #define ALEXA_CLIENT_SDK_ACL_TEST_TRANSPORT_MOCKHTTP2CONNECTION_H_ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "MockHTTP2Request.h" namespace alexaClientSDK { namespace avsCommon { namespace utils { namespace http2 { namespace test { /** * A mock class of @c HTTP2ConnectionInterface. */ class MockHTTP2Connection : public HTTP2ConnectionInterface { public: /** * Constructor * @param dURL The URL for downchannel requests. * @param pingURL The URL for ping requests. * @param delegateToReal Whether the mock should delegate to real methods when possible. If false, all methods * will need expectations set. */ MockHTTP2Connection(std::string dURL, std::string pingURL, bool delegateToReal = true); ~MockHTTP2Connection() = default; /// @name HTTP2ConnectionInterface methods /// @{ MOCK_METHOD1(createAndSendRequest, std::shared_ptr(const HTTP2RequestConfig& config)); MOCK_METHOD0(disconnect, void()); void addObserver(std::shared_ptr observer); void removeObserver(std::shared_ptr observer); /// @} /** * A concrete implementation that performs a createAndSendRequest call. * * @param config The HTTP2RequestConfig. * @return The request that was created with the provided config. */ std::shared_ptr createAndSendRequestConcrete(const HTTP2RequestConfig& config); /** * Check whether there are any HTTP requests sent. * * @return True if there are no HTTP requests sent by @c HTTP2Transport. */ bool isRequestQueueEmpty(); /** * Wait for an HTTP request to be sent. * * @param timeout Wait timeout in milliseconds. * @param requestNum The number of HTTP2 requests to wait for. * @return A pointer to the request if there is one before the timeout occurs, otherwise nullptr */ std::shared_ptr waitForRequest(std::chrono::milliseconds timeout, unsigned requestNum = 1); /** * Pop the latest HTTP2 Request from queue. * * @return The oldest HTTP2 Request in the queue. */ std::shared_ptr dequeRequest(); /** * Set the Header content to be matched by @c waitForRequestWithHeader. * * @param matchString The contents of the header to match. */ void setWaitRequestHeader(const std::string& matchString); /** * Wait for a request with a particular Header content. * * @param timeout The wait timeout in milliseconds * @param matchString The contents of the header that it is waiting for * @return True if a match occurred before timeout */ bool waitForRequestWithHeader(std::chrono::milliseconds timeout); /** * Wait for a POST HTTP2request. * * @param timeout The wait timeout in milliseconds. * @return A pointer to the POST request if there is one before the timeout occurs, otherwise nullptr */ std::shared_ptr waitForPostRequest(const std::chrono::milliseconds timeout); /** * Wait for a Ping HTTP2request. * * @param timeout The wait timeout in milliseconds. * @return A pointer to the Ping request if there is one before the timeout occurs, otherwise nullptr */ std::shared_ptr waitForPingRequest(const std::chrono::milliseconds timeout); /** * Respond to downchannel requests with a response code and notify onResponseFinished() if needed. * * @param responseCode The HTTP response code to reply. * @param sendResponseFinished True if needed to notify onResponseFinished(), otherwise false. * @param timeout Timeout for wating for downchannel HTTP2 requests. * @return True if a response has been sent to the downchannel request before timeout, otherwise false. */ bool respondToDownchannelRequests( long responseCode, bool sendResponseFinished, const std::chrono::milliseconds timeout); /** * Set the response code for POST requests that will be immediately replied when an HTTP POST request is sent. * * @param responseCode The HTTP response code to reply to the request. If set to @c * HTTPResponseCode::HTTP_RESPONSE_CODE_UNDEFINED, a response code will not be sent. */ void setResponseToPOSTRequests(http::HTTPResponseCode responseCode); /** * Retrieve the first HTTP2 request made on the downchannel. * * @return The first downchannel request or nullptr if none found */ std::shared_ptr getDownchannelRequest( std::chrono::milliseconds timeout = std::chrono::milliseconds(0)); /** * Check if a pause is received while sending data. * * @return True if a pause is received, false otherwise */ bool isPauseOnSendReceived(std::chrono::milliseconds timeout = std::chrono::milliseconds(0)); /* * Get the number of POST requests in the queue. * * @return The number of POST requests in the queue. */ std::size_t getPostRequestsNum(); /* * Get the number of HTTP2 requests in the queue. * * @return The number of HTTP2 requests in the queue. */ std::size_t getRequestsNum(); /* * Get the number of downchannel requests in the queue. * * @return The number of downchannel requests in the queue. */ std::size_t getDownchannelRequestsNum(); /* * Pop the oldest HTTP2 POST request from queue if it is not empty, otherwise wait for at most @c timeout for a * request to be enqueued * * @return The oldest HTTP2 POST request in the queue or nullptr if the timeout expires */ std::shared_ptr dequePostRequest(const std::chrono::milliseconds timeout); /* * Pop the oldest HTTP2 POST request from queue. * * @return The oldest HTTP2 POST request in the queue. */ std::shared_ptr dequePostRequest(); /* * Pop the oldest HTTP2 Ping request from queue. * * @return The oldest HTTP2 Ping request in the queue. */ std::shared_ptr dequePingRequest(); /* * Retrieve the maximum number of POST requests in the queue at any given time. * * @return The maximum number of POST requests in the queue at any given time. */ std::size_t getMaxPostRequestsEnqueud(); private: /// Queue of HTTP2 requests from @c HTTP2Transport. Serialized by @c m_requestMutex. std::deque> m_requestQueue; /// Serializes concurrent access to the m_requestQueue and m_isStopping members. std::mutex m_requestMutex; /// Used to wake a thread that processes HTTP2Request in @c m_requestQueue. std::condition_variable m_requestCv; /// A string that identifies the downchannel URL. std::string m_downchannelURL; /// A string that identifies the ping URL. std::string m_pingURL; /// Queue of HTTP2 requests that are only for the downchannel. Serialized by @c m_downchannelRequestMutex. std::deque> m_downchannelRequestQueue; /// Serializes access to receiving downchannel requests. std::mutex m_downchannelRequestMutex; // Used to wake a thread that is waiting for a downchannel request. std::condition_variable m_downchannelRequestCv; /// Queue of HTTP2 POST requests. Serialized by @c m_postRequestMutex. std::deque> m_postRequestQueue; /// Serializes access to receiving POST requests. std::mutex m_postRequestMutex; /// Used to wake a thread that is waiting a POST HTTP2Request. std::condition_variable m_requestPostCv; /// Queue of Ping requests. Serialized by @c m_pingRequestMutex. std::deque> m_pingRequestQueue; /// Mutex for observers. std::mutex m_observersMutex; /// Observers std::unordered_set> m_observers; /// Serializes access to receiving Ping requests. std::mutex m_pingRequestMutex; // Used to wake a thread that is waiting for a Ping request. std::condition_variable m_pingRequestCv; /// A string that contains the header to match in @c waitForRequestWithHeader(). std::string m_headerMatch; /// Used to wake a thread that processes HTTP2Request with a header content matching @c m_headerMatch. std::condition_variable m_requestHeaderCv; /// Indicator that a pause is received while doing @c HTTP2RequestSourceInterface::onSendData() PromiseFuturePair m_receivedPauseOnSend; /// The response code to be replied for every POST request received. http::HTTPResponseCode m_postResponseCode; /// The maximum number of POST requests in the queue at any given time. std::size_t m_maxPostRequestsEnqueued; /// A constant to specify the buffer size to be used in reading HTTP2 data. /// Set to 100 bytes for test purposes static const unsigned READ_DATA_BUF_SIZE = 100; }; } // namespace test } // namespace http2 } // namespace utils } // namespace avsCommon } // namespace alexaClientSDK #endif // ALEXA_CLIENT_SDK_ACL_TEST_TRANSPORT_MOCKHTTP2CONNECTION_H_