-
Notifications
You must be signed in to change notification settings - Fork 70
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add a helper to capture a free port for tests. (#252)
Summary: Pull Request resolved: #252 We recently have seen a failed unit test caused by an occupied random port. Our system always expects a pre-assigned free port. To meet this requirement, we add a helper function to find this free port. Note: this is a test-only helper, shouldn't be used in production environment. Reviewed By: adshastri Differential Revision: D37505830 fbshipit-source-id: a23afbcadaafe59c5105589e1119f6c9a6b3b0e2
- Loading branch information
1 parent
1d58088
commit 5c11a7b
Showing
3 changed files
with
114 additions
and
63 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
/* | ||
* Copyright (c) Meta Platforms, Inc. and affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include <stdexcept> | ||
#include <string> | ||
|
||
#include <fcntl.h> | ||
|
||
#include <arpa/inet.h> | ||
#include <netinet/in.h> | ||
#include <sys/socket.h> | ||
|
||
namespace fbpcf::engine::communication { | ||
|
||
class SocketInTestHelper { | ||
public: | ||
static int findNextOpenPort(int portNo) { | ||
while (!isPortOpen(portNo)) { | ||
portNo++; | ||
if (portNo > 65535) { | ||
throw std::runtime_error("Can't find a open port!"); | ||
} | ||
} | ||
return portNo; | ||
} | ||
|
||
private: | ||
static bool isPortOpen(int port) { | ||
auto sockfd = socket(AF_INET, SOCK_STREAM, 0); | ||
if (sockfd < 0) { | ||
throw std::runtime_error("error opening socket"); | ||
} | ||
int enable = 1; | ||
|
||
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) < | ||
0) { | ||
throw std::runtime_error("setsockopt(SO_REUSEADDR) failed"); | ||
} | ||
|
||
struct sockaddr_in servAddr; | ||
|
||
memset((char*)&servAddr, 0, sizeof(servAddr)); | ||
servAddr.sin_family = AF_INET; | ||
servAddr.sin_addr.s_addr = INADDR_ANY; | ||
servAddr.sin_port = htons(port); | ||
|
||
// if binding to the original port number fails, try to grab a free port | ||
// instead | ||
if (::bind( | ||
sockfd, (struct sockaddr*)&servAddr, sizeof(struct sockaddr_in)) < | ||
0) { | ||
return false; | ||
} else { | ||
close(sockfd); | ||
return true; | ||
} | ||
} | ||
}; | ||
|
||
} // namespace fbpcf::engine::communication |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters