Skip to content

Dive communication protocol: Unit tests for client and unix domain server#357

Open
elviscapiaq wants to merge 12 commits intogoogle:mainfrom
elviscapiaq:unit_tests
Open

Dive communication protocol: Unit tests for client and unix domain server#357
elviscapiaq wants to merge 12 commits intogoogle:mainfrom
elviscapiaq:unit_tests

Conversation

@elviscapiaq
Copy link
Collaborator

No description provided.

@elviscapiaq
Copy link
Collaborator Author

Please take a look of this CL. I want your opinion to decide if we add unit tests in this way or maybe using something else like Google Mock?

@elviscapiaq elviscapiaq force-pushed the unit_tests branch 3 times, most recently from 6df7e26 to 010ed76 Compare September 10, 2025 19:24
@elviscapiaq
Copy link
Collaborator Author

@wangra-google , @footballhead, I fixed the issue for Linux, now you can take a look of this commit.

@footballhead
Copy link
Collaborator

At a high-level, I think this is a good approach since we should strive to write tests using the real implementation. (Google SWE Handbook, chapter 18.e.i) The main arguments against mocking from that chapter are:

  • Using the real implementation provides us with more confidence that the code we are shipping to users is reliable.
  • When the real implementation changes, so too can the mocks. This means mocks add additional maintenance overhead. This can also make refactoring harder.

Chapter 18: Test Doubles goes into options that you can consider if testing the real implementation is not feasible. In general, they encourage looking at other options first instead of mocks, e.g. fakes. TestTcpServer is a good example of a fake.

I'd encourage reading Chapters 16-19 of the SWE handbook

@elviscapiaq
Copy link
Collaborator Author

At a high-level, I think this is a good approach since we should strive to write tests using the real implementation. (Google SWE Handbook, chapter 18.e.i) The main arguments against mocking from that chapter are:

  • Using the real implementation provides us with more confidence that the code we are shipping to users is reliable.
  • When the real implementation changes, so too can the mocks. This means mocks add additional maintenance overhead. This can also make refactoring harder.

Chapter 18: Test Doubles goes into options that you can consider if testing the real implementation is not feasible. In general, they encourage looking at other options first instead of mocks, e.g. fakes. TestTcpServer is a good example of a fake.

I'd encourage reading Chapters 16-19 of the SWE handbook

Thanks for poiting it out. I have read all these good practices and made a commit based on that.
Now we are faking the TestTcpServer as this is the recommended approach for this case.

@elviscapiaq
Copy link
Collaborator Author

I am restarting this commit applying all the recommendations and after reading the tips about how to use a fake test. I found it very interesting and useful

@elviscapiaq elviscapiaq marked this pull request as ready for review November 11, 2025 16:10
@elviscapiaq
Copy link
Collaborator Author

I fixed the issue as the server and client tests are only for Linux OS.
Also, move the PR from draft to for review.

@footballhead footballhead self-requested a review November 18, 2025 17:37
@elviscapiaq
Copy link
Collaborator Author

I addressed the feedback, ready for review.

@elviscapiaq elviscapiaq force-pushed the unit_tests branch 3 times, most recently from 72e8e1b to 8e433ae Compare December 10, 2025 17:40
@elviscapiaq
Copy link
Collaborator Author

Ready for review!

wangra-google
wangra-google previously approved these changes Dec 12, 2025
wangra-google
wangra-google previously approved these changes Dec 12, 2025
wangra-google
wangra-google previously approved these changes Dec 12, 2025
/// Connects to an Unix (Local) Domain with abstract namespace.
sockaddr_un addr = {};
addr.sun_family = AF_UNIX;
// first char is '\0'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let the code speak for itself. Comments should focus on the why, not the what. The what should be obvious from reading the code. If it's not then that's a good sign that it should be refactored

Suggested change
// first char is '\0'

addr.sun_path[0] = '\0';
strncpy(addr.sun_path + 1, kTestServerAddress, std::size(kTestServerAddress));
if (connect(client_socket,
(sockaddr*)&addr,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer C++ casts since they are more explicit https://google.github.io/styleguide/cppguide.html#Casting

ASSERT_TRUE(server->Start(kTestServerAddress).ok());

absl::StatusOr<std::unique_ptr<SocketConnection>> client_conn = ConnectClient();
ASSERT_TRUE(client_conn.ok());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer using the absl_testing::IsOk() matcher since it will print more information if something fails

Suggested change
ASSERT_TRUE(client_conn.ok());
#include "absl/status/status_matchers.h"
using ::absl_testing::IsOk;
// ...
ASSERT_THAT(client_conn.ok(), IsOk());

TEST(UnixDomainServerTest, HandShakeSuccess)
{
auto server = std::make_unique<UnixDomainServer>();
ASSERT_TRUE(server->Start(kTestServerAddress).ok());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer using the absl_testing::IsOk() matcher since it will print more information if something fails

ASSERT_TRUE(server->Start(kTestServerAddress).ok());

absl::StatusOr<std::unique_ptr<SocketConnection>> client_conn = ConnectClient();
ASSERT_TRUE(client_conn.ok());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer using the absl_testing::IsOk() matcher since it will print more information if something fails

HandshakeRequest request;
request.SetMajorVersion(5);
request.SetMinorVersion(2);
ASSERT_TRUE(SendSocketMessage((*client_conn).get(), request).ok());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer using the absl_testing::IsOk() matcher since it will print more information if something fails

// Client receives response.
absl::StatusOr<std::unique_ptr<ISerializable>> response_msg = ReceiveSocketMessage(
(*client_conn).get());
ASSERT_TRUE(response_msg.ok());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer using the absl_testing::IsOk() matcher since it will print more information if something fails

ASSERT_EQ((*response_msg)->GetMessageType(), MessageType::HANDSHAKE_RESPONSE);
auto* response = dynamic_cast<HandshakeResponse*>((*response_msg).get());
ASSERT_NE(response, nullptr);
EXPECT_EQ(response->GetMajorVersion(), request.GetMajorVersion());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer a custom matcher here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants