1c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell/*
2c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell * Copyright (C) 2016 The Android Open Source Project
3c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell * All rights reserved.
4c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell *
5c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell * Redistribution and use in source and binary forms, with or without
6c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell * modification, are permitted provided that the following conditions
7c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell * are met:
8c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell *  * Redistributions of source code must retain the above copyright
9c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell *    notice, this list of conditions and the following disclaimer.
10c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell *  * Redistributions in binary form must reproduce the above copyright
11c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell *    notice, this list of conditions and the following disclaimer in
12c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell *    the documentation and/or other materials provided with the
13c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell *    distribution.
14c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell *
15c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell * SUCH DAMAGE.
27c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell */
28c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell
29c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell#include "socket_mock.h"
30c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell
31c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell#include <gtest/gtest.h>
32c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell
33c3a466960ff19bbf9b28b4d069dd0b872d4165d8David PursellSocketMock::SocketMock() : Socket(INVALID_SOCKET) {}
34c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell
35c3a466960ff19bbf9b28b4d069dd0b872d4165d8David PursellSocketMock::~SocketMock() {
36c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell    if (!events_.empty()) {
37c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell        ADD_FAILURE() << events_.size() << " event(s) were not handled";
38c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell    }
39c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell}
40c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell
41b34e4a06eeaaeaa42e0de6fdb44fb4202839b996David Pursellbool SocketMock::Send(const void* data, size_t length) {
42c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell    if (events_.empty()) {
43c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell        ADD_FAILURE() << "Send() was called when no message was expected";
44b34e4a06eeaaeaa42e0de6fdb44fb4202839b996David Pursell        return false;
45c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell    }
46c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell
47c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell    if (events_.front().type != EventType::kSend) {
48c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell        ADD_FAILURE() << "Send() was called out-of-order";
49b34e4a06eeaaeaa42e0de6fdb44fb4202839b996David Pursell        return false;
50c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell    }
51c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell
52c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell    std::string message(reinterpret_cast<const char*>(data), length);
53c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell    if (events_.front().message != message) {
54c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell        ADD_FAILURE() << "Send() expected " << events_.front().message << ", but got " << message;
55b34e4a06eeaaeaa42e0de6fdb44fb4202839b996David Pursell        return false;
56c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell    }
57c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell
58c742a7f17475e22739c09a5b19862b8d1ec6050aDavid Pursell    bool return_value = events_.front().status;
59c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell    events_.pop();
602c094f79836d7defb6114e59b6412157658c0f90David Pursell    return return_value;
61b34e4a06eeaaeaa42e0de6fdb44fb4202839b996David Pursell}
62b34e4a06eeaaeaa42e0de6fdb44fb4202839b996David Pursell
63b34e4a06eeaaeaa42e0de6fdb44fb4202839b996David Pursell// Mock out multi-buffer send to be one large send, since that's what it should looks like from
64b34e4a06eeaaeaa42e0de6fdb44fb4202839b996David Pursell// the user's perspective.
65b34e4a06eeaaeaa42e0de6fdb44fb4202839b996David Pursellbool SocketMock::Send(std::vector<cutils_socket_buffer_t> buffers) {
66b34e4a06eeaaeaa42e0de6fdb44fb4202839b996David Pursell    std::string data;
67b34e4a06eeaaeaa42e0de6fdb44fb4202839b996David Pursell    for (const auto& buffer : buffers) {
68b34e4a06eeaaeaa42e0de6fdb44fb4202839b996David Pursell        data.append(reinterpret_cast<const char*>(buffer.data), buffer.length);
69b34e4a06eeaaeaa42e0de6fdb44fb4202839b996David Pursell    }
70b34e4a06eeaaeaa42e0de6fdb44fb4202839b996David Pursell    return Send(data.data(), data.size());
71c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell}
72c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell
73c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursellssize_t SocketMock::Receive(void* data, size_t length, int /*timeout_ms*/) {
74c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell    if (events_.empty()) {
75c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell        ADD_FAILURE() << "Receive() was called when no message was ready";
76c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell        return -1;
77c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell    }
78c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell
79c742a7f17475e22739c09a5b19862b8d1ec6050aDavid Pursell    const Event& event = events_.front();
80c742a7f17475e22739c09a5b19862b8d1ec6050aDavid Pursell    if (event.type != EventType::kReceive) {
81c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell        ADD_FAILURE() << "Receive() was called out-of-order";
82c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell        return -1;
83c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell    }
84c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell
85c742a7f17475e22739c09a5b19862b8d1ec6050aDavid Pursell    const std::string& message = event.message;
86c742a7f17475e22739c09a5b19862b8d1ec6050aDavid Pursell    if (message.length() > length) {
87c742a7f17475e22739c09a5b19862b8d1ec6050aDavid Pursell        ADD_FAILURE() << "Receive(): not enough bytes (" << length << ") for " << message;
88c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell        return -1;
89c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell    }
90c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell
91c742a7f17475e22739c09a5b19862b8d1ec6050aDavid Pursell    receive_timed_out_ = event.status;
92c742a7f17475e22739c09a5b19862b8d1ec6050aDavid Pursell    ssize_t return_value = message.length();
93c742a7f17475e22739c09a5b19862b8d1ec6050aDavid Pursell
94c742a7f17475e22739c09a5b19862b8d1ec6050aDavid Pursell    // Empty message indicates failure.
95c742a7f17475e22739c09a5b19862b8d1ec6050aDavid Pursell    if (message.empty()) {
96c742a7f17475e22739c09a5b19862b8d1ec6050aDavid Pursell        return_value = -1;
97c742a7f17475e22739c09a5b19862b8d1ec6050aDavid Pursell    } else {
98c742a7f17475e22739c09a5b19862b8d1ec6050aDavid Pursell        memcpy(data, message.data(), message.length());
99c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell    }
100c742a7f17475e22739c09a5b19862b8d1ec6050aDavid Pursell
101c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell    events_.pop();
102c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell    return return_value;
103c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell}
104c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell
105c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursellint SocketMock::Close() {
106c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell    return 0;
107c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell}
108c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell
109c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursellstd::unique_ptr<Socket> SocketMock::Accept() {
110c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell    if (events_.empty()) {
111c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell        ADD_FAILURE() << "Accept() was called when no socket was ready";
112c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell        return nullptr;
113c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell    }
114c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell
115c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell    if (events_.front().type != EventType::kAccept) {
116c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell        ADD_FAILURE() << "Accept() was called out-of-order";
117c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell        return nullptr;
118c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell    }
119c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell
120c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell    std::unique_ptr<Socket> sock = std::move(events_.front().sock);
121c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell    events_.pop();
122c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell    return sock;
123c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell}
124c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell
125c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursellvoid SocketMock::ExpectSend(std::string message) {
1262c094f79836d7defb6114e59b6412157658c0f90David Pursell    events_.push(Event(EventType::kSend, std::move(message), true, nullptr));
127c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell}
128c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell
1292c094f79836d7defb6114e59b6412157658c0f90David Pursellvoid SocketMock::ExpectSendFailure(std::string message) {
1302c094f79836d7defb6114e59b6412157658c0f90David Pursell    events_.push(Event(EventType::kSend, std::move(message), false, nullptr));
1312c094f79836d7defb6114e59b6412157658c0f90David Pursell}
132c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell
133c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursellvoid SocketMock::AddReceive(std::string message) {
134c742a7f17475e22739c09a5b19862b8d1ec6050aDavid Pursell    events_.push(Event(EventType::kReceive, std::move(message), false, nullptr));
135c742a7f17475e22739c09a5b19862b8d1ec6050aDavid Pursell}
136c742a7f17475e22739c09a5b19862b8d1ec6050aDavid Pursell
137c742a7f17475e22739c09a5b19862b8d1ec6050aDavid Pursellvoid SocketMock::AddReceiveTimeout() {
138c742a7f17475e22739c09a5b19862b8d1ec6050aDavid Pursell    events_.push(Event(EventType::kReceive, "", true, nullptr));
139c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell}
140c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell
141c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursellvoid SocketMock::AddReceiveFailure() {
142c742a7f17475e22739c09a5b19862b8d1ec6050aDavid Pursell    events_.push(Event(EventType::kReceive, "", false, nullptr));
143c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell}
144c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell
145c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursellvoid SocketMock::AddAccept(std::unique_ptr<Socket> sock) {
146c742a7f17475e22739c09a5b19862b8d1ec6050aDavid Pursell    events_.push(Event(EventType::kAccept, "", false, std::move(sock)));
147c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell}
148c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell
149c742a7f17475e22739c09a5b19862b8d1ec6050aDavid PursellSocketMock::Event::Event(EventType _type, std::string _message, ssize_t _status,
150c3a466960ff19bbf9b28b4d069dd0b872d4165d8David Pursell                         std::unique_ptr<Socket> _sock)
151c742a7f17475e22739c09a5b19862b8d1ec6050aDavid Pursell        : type(_type), message(_message), status(_status), sock(std::move(_sock)) {}
152