From 1986b77d78e30684b1ca5ac9d9b1c75736f258d6 Mon Sep 17 00:00:00 2001 From: "Bobby R. Bruce" Date: Fri, 3 Jan 2020 17:47:35 -0800 Subject: tests,base: Added GTest for base/socket.cc It should be noted that some features of this class have not been fully tested due to interaction with system-calls. Change-Id: I8315188327e022ac4c98aa9ce4bd38243266ab17 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/23984 Reviewed-by: Daniel Carvalho Maintainer: Jason Lowe-Power Tested-by: kokoro --- src/base/SConscript | 1 + src/base/socket.cc | 12 ++++ src/base/socket.hh | 6 ++ src/base/socket.test.cc | 170 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 189 insertions(+) create mode 100644 src/base/socket.test.cc diff --git a/src/base/SConscript b/src/base/SConscript index 818428ee5..3bd4dbb45 100644 --- a/src/base/SConscript +++ b/src/base/SConscript @@ -70,6 +70,7 @@ Source('random.cc') if env['TARGET_ISA'] != 'null': Source('remote_gdb.cc') Source('socket.cc') +GTest('socket.test', 'socket.test.cc', 'socket.cc') Source('statistics.cc') Source('str.cc') GTest('str.test', 'str.test.cc', 'str.cc') diff --git a/src/base/socket.cc b/src/base/socket.cc index ece4a6ac4..b188ac1f9 100644 --- a/src/base/socket.cc +++ b/src/base/socket.cc @@ -1,4 +1,7 @@ /* + * Copyright (c) 2020 The Regents of the University of California + * All rights reserved + * * Copyright (c) 2002-2005 The Regents of The University of Michigan * All rights reserved. * @@ -26,6 +29,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Authors: Nathan Binkert + * Bobby R. Bruce */ #include "base/socket.hh" @@ -49,6 +53,14 @@ bool ListenSocket::anyListening = false; bool ListenSocket::bindToLoopback = false; +void +ListenSocket::cleanup() +{ + listeningDisabled = false; + anyListening = false; + bindToLoopback = false; +} + void ListenSocket::disableAll() { diff --git a/src/base/socket.hh b/src/base/socket.hh index fab7f7576..c23a1d3d7 100644 --- a/src/base/socket.hh +++ b/src/base/socket.hh @@ -49,6 +49,12 @@ class ListenSocket bool listening; int fd; + /* + * cleanup resets the static variables back to their default values. + */ + static void cleanup(); + + public: ListenSocket(); virtual ~ListenSocket(); diff --git a/src/base/socket.test.cc b/src/base/socket.test.cc new file mode 100644 index 000000000..c1930757d --- /dev/null +++ b/src/base/socket.test.cc @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2020 The Regents of the University of California + * All rights reserved + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Bobby R. Bruce + */ + +#include + +#include "base/socket.hh" + +#define TEST_PORT_1 7893 +#define TEST_PORT_2 7894 + +/* + * Socket.test tests socket.cc. It should be noted that some features of + * socket.cc have not been fully tested due to interaction with system-calls. + */ + +class MockListenSocket : public ListenSocket +{ + public: + /* + * This mock Listen Socket is used to ensure the static variables are reset + * back to their default values after deconstruction (i.e., after a test + * has completed). + */ + ~MockListenSocket() + { + cleanup(); + } +}; + +TEST(SocketTest, DefaultBehavior) +{ + /* + * Tests the default behavior where listenSocket is constructed, and is + * not listening to a port. + */ + MockListenSocket listen_socket; + EXPECT_EQ(-1, listen_socket.getfd()); + EXPECT_FALSE(listen_socket.islistening()); + EXPECT_FALSE(listen_socket.allDisabled()); +} + +TEST(SocketTest, DisableAll) +{ + MockListenSocket listen_socket; + listen_socket.disableAll(); + EXPECT_EQ(-1, listen_socket.getfd()); + EXPECT_FALSE(listen_socket.islistening()); + EXPECT_TRUE(listen_socket.allDisabled()); +} + +TEST(SocketTest, ListenToPort) +{ + MockListenSocket listen_socket; + EXPECT_TRUE(listen_socket.listen(TEST_PORT_1)); + EXPECT_NE(-1, listen_socket.getfd()); + EXPECT_TRUE(listen_socket.islistening()); + EXPECT_FALSE(listen_socket.allDisabled()); +} + +TEST(SocketTest, ListenToPortReuseFalse) +{ + MockListenSocket listen_socket; + /* + * The ListenSocket object should have the same state regardless as to + * whether reuse is true or false (it is true by default). + */ + EXPECT_TRUE(listen_socket.listen(TEST_PORT_1, false)); + EXPECT_NE(-1, listen_socket.getfd()); + EXPECT_TRUE(listen_socket.islistening()); + EXPECT_FALSE(listen_socket.allDisabled()); +} + +TEST(SocketTest, RelistenWithSameInstanceSamePort) +{ + MockListenSocket listen_socket; + EXPECT_TRUE(listen_socket.listen(TEST_PORT_1)); + + /* + * You cannot listen to another port if you are already listening to one. + */ + testing::internal::CaptureStderr(); + EXPECT_ANY_THROW(listen_socket.listen(TEST_PORT_1)); + std::string expected = "panic: Socket already listening!\n"; + std::string actual = testing::internal::GetCapturedStderr().substr(); + + /* + * The GoogleExitLogger will output using the following: + * `std::cerr << loc.file << ":" << loc.line << ": " << s;` + * As we do not care about the file and line where the error originated + * (this may change, and it shouldn't break the test when this happens), + * we strip out the leading `:: ` (we simply remove everything + * prior to two characters after the second colon in the string). + */ + actual = actual.substr(actual.find(":", actual.find(":") + 1) + 2); + EXPECT_EQ(expected, actual); +} + +TEST(SocketTest, RelistenWithSameInstanceDifferentPort) +{ + MockListenSocket listen_socket; + EXPECT_TRUE(listen_socket.listen(TEST_PORT_1)); + + /* + * You cannot listen to another port if you are already listening to one. + */ + testing::internal::CaptureStderr(); + EXPECT_ANY_THROW(listen_socket.listen(TEST_PORT_2)); + + std::string expected = "panic: Socket already listening!\n"; + std::string actual = testing::internal::GetCapturedStderr().substr(); + actual = actual.substr(actual.find(":", actual.find(":") + 1) + 2); + EXPECT_EQ(expected, actual); +} + +TEST(SocketTest, RelistenWithDifferentInstanceOnDifferentPort) +{ + MockListenSocket listen_socket; + EXPECT_TRUE(listen_socket.listen(TEST_PORT_1)); + + /* + * You can listen to another port with a different instance. + */ + MockListenSocket listen_socket_2; + EXPECT_TRUE(listen_socket_2.listen(TEST_PORT_2)); +} + +TEST(SocketTest, RelistenWithDifferentInstanceOnSamePort) +{ + MockListenSocket listen_socket; + EXPECT_TRUE(listen_socket.listen(TEST_PORT_1)); + + /* + * You cannot listen to a port that's already being listened to. + */ + MockListenSocket listen_socket_2; + EXPECT_FALSE(listen_socket_2.listen(TEST_PORT_1)); +} + +TEST(SocketTest, AcceptError) +{ + MockListenSocket listen_socket; + EXPECT_EQ(-1, listen_socket.accept()); +} -- cgit v1.2.3