diff --git a/Builds/VisualStudio2015/RippleD.vcxproj b/Builds/VisualStudio2015/RippleD.vcxproj
index 48c2106444..2b8fe0fb23 100644
--- a/Builds/VisualStudio2015/RippleD.vcxproj
+++ b/Builds/VisualStudio2015/RippleD.vcxproj
@@ -4921,6 +4921,10 @@
True
True
+
+ True
+ True
+
True
True
diff --git a/Builds/VisualStudio2015/RippleD.vcxproj.filters b/Builds/VisualStudio2015/RippleD.vcxproj.filters
index 1a2f988380..9bf79914ac 100644
--- a/Builds/VisualStudio2015/RippleD.vcxproj.filters
+++ b/Builds/VisualStudio2015/RippleD.vcxproj.filters
@@ -5610,6 +5610,9 @@
test\rpc
+
+ test\rpc
+
test\rpc
diff --git a/src/test/rpc/Peers_test.cpp b/src/test/rpc/Peers_test.cpp
new file mode 100644
index 0000000000..1a48729a8a
--- /dev/null
+++ b/src/test/rpc/Peers_test.cpp
@@ -0,0 +1,96 @@
+//------------------------------------------------------------------------------
+/*
+ This file is part of rippled: https://github.com/ripple/rippled
+ Copyright (c) 2012-2017 Ripple Labs Inc.
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+//==============================================================================
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace ripple {
+
+class Peers_test : public beast::unit_test::suite
+{
+ void testRequest()
+ {
+ testcase("Basic request");
+ using namespace test::jtx;
+ Env env {*this};
+
+ // without modification of the cluster, expect an empty set
+ // from this request
+ auto peers = env.rpc("peers")[jss::result];
+ BEAST_EXPECT(peers.isMember(jss::cluster) &&
+ peers[jss::cluster].size() == 0 );
+ BEAST_EXPECT(peers.isMember(jss::peers) &&
+ peers[jss::peers].isNull());
+
+ // insert some nodes in to the cluster
+ std::unordered_map nodes;
+ for(auto i =0; i < 3; ++i)
+ {
+
+ auto kp = generateKeyPair (KeyType::secp256k1,
+ generateSeed("seed" + std::to_string(i)));
+
+ std::string name = "Node " + std::to_string(i);
+
+ env.app().cluster().update(
+ kp.first,
+ name,
+ 200,
+ env.timeKeeper().now() - 10s);
+ nodes.insert( std::make_pair(
+ toBase58(TokenType::TOKEN_NODE_PUBLIC, kp.first), name));
+ }
+
+ // make request, verify nodes we created match
+ // what is reported
+ peers = env.rpc("peers")[jss::result];
+ if(! BEAST_EXPECT(peers.isMember(jss::cluster)))
+ return;
+ if(! BEAST_EXPECT(peers[jss::cluster].size() == nodes.size()))
+ return;
+ for(auto it = peers[jss::cluster].begin();
+ it != peers[jss::cluster].end();
+ ++it)
+ {
+ auto key = it.key().asString();
+ auto search = nodes.find(key);
+ if(! BEAST_EXPECTS(search != nodes.end(), key))
+ continue;
+ if(! BEAST_EXPECT((*it).isMember(jss::tag)))
+ continue;
+ auto tag = (*it)[jss::tag].asString();
+ BEAST_EXPECTS((*it)[jss::tag].asString() == nodes[key], key);
+ }
+ BEAST_EXPECT(peers.isMember(jss::peers) && peers[jss::peers].isNull());
+ }
+
+public:
+ void run ()
+ {
+ testRequest();
+ }
+};
+
+BEAST_DEFINE_TESTSUITE (Peers, rpc, ripple);
+
+} // ripple
diff --git a/src/test/unity/rpc_test_unity.cpp b/src/test/unity/rpc_test_unity.cpp
index 3c89559ad9..e4a14365da 100644
--- a/src/test/unity/rpc_test_unity.cpp
+++ b/src/test/unity/rpc_test_unity.cpp
@@ -35,6 +35,7 @@
#include
#include
#include
+#include
#include
#include
#include