Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(915)

Unified Diff: components/tracing/core/proto_zero_message_unittest.cc

Issue 2158323005: tracing v2: Introduce handles for safe usage of ProtoZeroMessage (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: final nits Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « components/tracing/core/proto_zero_message_handle.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: components/tracing/core/proto_zero_message_unittest.cc
diff --git a/components/tracing/core/proto_zero_message_unittest.cc b/components/tracing/core/proto_zero_message_unittest.cc
index e95db77319254ab9537b93b011557f0ea212ac72..93b5ca343cb42963e59ac7e72510e5c5729625a1 100644
--- a/components/tracing/core/proto_zero_message_unittest.cc
+++ b/components/tracing/core/proto_zero_message_unittest.cc
@@ -10,6 +10,7 @@
#include "base/hash.h"
#include "components/tracing/core/proto_utils.h"
+#include "components/tracing/core/proto_zero_message_handle.h"
#include "components/tracing/test/fake_scattered_buffer.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -21,9 +22,8 @@ const uint8_t kTestBytes[] = {0, 0, 0, 0, 0x42, 1, 0x42, 0xff, 0x42, 0};
const char kStartWatermark[] = {'a', 'b', 'c', 'd', '1', '2', '3', '\0'};
const char kEndWatermark[] = {'9', '8', '7', '6', 'z', 'w', 'y', '\0'};
-class FakeMessage : public ProtoZeroMessage {
- public:
-};
+class FakeRootMessage : public ProtoZeroMessage {};
+class FakeChildMessage : public ProtoZeroMessage {};
class ProtoZeroMessageTest : public ::testing::Test {
public:
@@ -48,17 +48,17 @@ class ProtoZeroMessageTest : public ::testing::Test {
buffer_.reset();
}
- ProtoZeroMessage* NewMessage() {
+ FakeRootMessage* NewMessage() {
std::unique_ptr<uint8_t[]> mem(
- new uint8_t[sizeof(kStartWatermark) + sizeof(ProtoZeroMessage) +
+ new uint8_t[sizeof(kStartWatermark) + sizeof(FakeRootMessage) +
sizeof(kEndWatermark)]);
uint8_t* msg_start = mem.get() + sizeof(kStartWatermark);
memcpy(mem.get(), kStartWatermark, sizeof(kStartWatermark));
- memset(msg_start, 0, sizeof(ProtoZeroMessage));
- memcpy(msg_start + sizeof(ProtoZeroMessage), kEndWatermark,
+ memset(msg_start, 0, sizeof(FakeRootMessage));
+ memcpy(msg_start + sizeof(FakeRootMessage), kEndWatermark,
sizeof(kEndWatermark));
messages_.push_back(std::move(mem));
- ProtoZeroMessage* msg = reinterpret_cast<ProtoZeroMessage*>(msg_start);
+ FakeRootMessage* msg = reinterpret_cast<FakeRootMessage*>(msg_start);
msg->Reset(stream_writer_.get());
return msg;
}
@@ -81,8 +81,9 @@ class ProtoZeroMessageTest : public ::testing::Test {
msg->AppendBytes(i, kTestBytes, sizeof(kTestBytes));
if (depth < ProtoZeroMessage::kMaxNestingDepth) {
- auto* child_msg = msg->BeginNestedMessage<FakeMessage>(1 + depth * 10);
- BuildNestedMessages(depth + 1, child_msg);
+ auto* nested_msg =
+ msg->BeginNestedMessage<FakeChildMessage>(1 + depth * 10);
+ BuildNestedMessages(depth + 1, nested_msg);
}
for (uint32_t i = 129; i <= 256; ++i)
@@ -131,12 +132,13 @@ TEST_F(ProtoZeroMessageTest, NestedMessagesSimple) {
ProtoZeroMessage* root_msg = NewMessage();
root_msg->AppendVarIntU32(1 /* field_id */, 1);
- FakeMessage* nested_msg =
- root_msg->BeginNestedMessage<FakeMessage>(128 /* field_id */);
+ FakeChildMessage* nested_msg =
+ root_msg->BeginNestedMessage<FakeChildMessage>(128 /* field_id */);
ASSERT_EQ(0u, reinterpret_cast<uintptr_t>(nested_msg) % sizeof(void*));
nested_msg->AppendVarIntU32(2 /* field_id */, 2);
- nested_msg = root_msg->BeginNestedMessage<FakeMessage>(129 /* field_id */);
+ nested_msg =
+ root_msg->BeginNestedMessage<FakeChildMessage>(129 /* field_id */);
nested_msg->AppendVarIntU32(4 /* field_id */, 2);
root_msg->AppendVarIntU32(5 /* field_id */, 3);
@@ -170,15 +172,17 @@ TEST_F(ProtoZeroMessageTest, NestedMessagesSimple) {
// on finalization.
TEST_F(ProtoZeroMessageTest, BackfillSizeOnFinalization) {
ProtoZeroMessage* root_msg = NewMessage();
- uint8_t root_msg_size[proto::kMessageLengthFieldSize];
+ uint8_t root_msg_size[proto::kMessageLengthFieldSize] = {};
root_msg->set_size_field(
{&root_msg_size[0], &root_msg_size[proto::kMessageLengthFieldSize]});
root_msg->AppendVarIntU32(1, 0x42);
- FakeMessage* nested_msg_1 = root_msg->BeginNestedMessage<FakeMessage>(2);
+ FakeChildMessage* nested_msg_1 =
+ root_msg->BeginNestedMessage<FakeChildMessage>(2);
nested_msg_1->AppendVarIntU32(3, 0x43);
- FakeMessage* nested_msg_2 = nested_msg_1->BeginNestedMessage<FakeMessage>(4);
+ FakeChildMessage* nested_msg_2 =
+ nested_msg_1->BeginNestedMessage<FakeChildMessage>(4);
uint8_t buf200[200];
memset(buf200, 0x42, sizeof(buf200));
nested_msg_2->AppendBytes(5, buf200, sizeof(buf200));
@@ -226,5 +230,96 @@ TEST_F(ProtoZeroMessageTest, StressTest) {
EXPECT_EQ(0x14BC1BA3u, buf_hash);
}
+TEST_F(ProtoZeroMessageTest, MessageHandle) {
+ FakeRootMessage* msg1 = NewMessage();
+ FakeRootMessage* msg2 = NewMessage();
+ FakeRootMessage* msg3 = NewMessage();
+ FakeRootMessage* ignored_msg = NewMessage();
+ uint8_t msg1_size[proto::kMessageLengthFieldSize] = {};
+ uint8_t msg2_size[proto::kMessageLengthFieldSize] = {};
+ uint8_t msg3_size[proto::kMessageLengthFieldSize] = {};
+ msg1->set_size_field(
+ {&msg1_size[0], &msg1_size[proto::kMessageLengthFieldSize]});
+ msg2->set_size_field(
+ {&msg2_size[0], &msg2_size[proto::kMessageLengthFieldSize]});
+ msg3->set_size_field(
+ {&msg3_size[0], &msg3_size[proto::kMessageLengthFieldSize]});
+
+ // Test that the handle going out of scope causes the finalization of the
+ // target message.
+ {
+ ProtoZeroMessageHandle<FakeRootMessage> handle1(msg1);
+ handle1->AppendBytes(1 /* field_id */, kTestBytes, 1 /* size */);
+ ASSERT_EQ(0u, msg1_size[0]);
+ }
+ ASSERT_EQ(0x83u, msg1_size[0]);
+
+ // Test that the handle can be late initialized.
+ ProtoZeroMessageHandle<FakeRootMessage> handle2(ignored_msg);
+ handle2 = ProtoZeroMessageHandle<FakeRootMessage>(msg2);
+ handle2->AppendBytes(1 /* field_id */, kTestBytes, 2 /* size */);
+ ASSERT_EQ(0u, msg2_size[0]); // |msg2| should not be finalized yet.
+
+ // Test that std::move works and does NOT cause finalization of the moved
+ // message.
+ ProtoZeroMessageHandle<FakeRootMessage> handle_swp(ignored_msg);
+ handle_swp = std::move(handle2);
+ ASSERT_EQ(0u, msg2_size[0]); // msg2 should be NOT finalized yet.
+ handle_swp->AppendBytes(2 /* field_id */, kTestBytes, 3 /* size */);
+
+ ProtoZeroMessageHandle<FakeRootMessage> handle3(msg3);
+ handle3->AppendBytes(1 /* field_id */, kTestBytes, 4 /* size */);
+ ASSERT_EQ(0u, msg3_size[0]); // msg2 should be NOT finalized yet.
+
+ // Both |handle3| and |handle_swp| point to a valid message (respectively,
+ // |msg3| and |msg2|). Now move |handle3| into |handle_swp|.
+ handle_swp = std::move(handle3);
+ ASSERT_EQ(0x89u, msg2_size[0]); // |msg2| should be finalized at this point.
+
+ // At this point writing into handle_swp should actually write into |msg3|.
+ ASSERT_EQ(msg3, &*handle_swp);
+ handle_swp->AppendBytes(2 /* field_id */, kTestBytes, 8 /* size */);
+ ProtoZeroMessageHandle<FakeRootMessage> another_handle(ignored_msg);
+ handle_swp = std::move(another_handle);
+ ASSERT_EQ(0x90u, msg3_size[0]); // |msg3| should be finalized at this point.
+
+#if DCHECK_IS_ON()
+ // In developer builds w/ DCHECK on a finalized message should invalidate the
+ // handle, in order to early catch bugs in the client code.
+ FakeRootMessage* msg4 = NewMessage();
+ ProtoZeroMessageHandle<FakeRootMessage> handle4(msg4);
+ ASSERT_EQ(msg4, &*handle4);
+ msg4->Finalize();
+ ASSERT_EQ(nullptr, &*handle4);
+#endif
+
+ // Test also the behavior of handle with non-root (nested) messages.
+
+ ContiguousMemoryRange size_msg_2;
+ {
+ auto* nested_msg_1 = NewMessage()->BeginNestedMessage<FakeChildMessage>(3);
+ ProtoZeroMessageHandle<FakeChildMessage> child_handle_1(nested_msg_1);
+ ContiguousMemoryRange size_msg_1 = nested_msg_1->size_field();
+ memset(size_msg_1.begin, 0, size_msg_1.size());
+ child_handle_1->AppendVarIntU32(1, 0x11);
+
+ auto* nested_msg_2 = NewMessage()->BeginNestedMessage<FakeChildMessage>(2);
+ size_msg_2 = nested_msg_2->size_field();
+ memset(size_msg_2.begin, 0, size_msg_2.size());
+ ProtoZeroMessageHandle<FakeChildMessage> child_handle_2(nested_msg_2);
+ child_handle_2->AppendVarIntU32(2, 0xFF);
+
+ // |nested_msg_1| should not be finalized yet.
+ ASSERT_EQ(0u, size_msg_1.begin[0]);
+
+ // This move should cause |nested_msg_1| to be finalized, but not
+ // |nested_msg_2|, which will be finalized only after the current scope.
+ child_handle_1 = std::move(child_handle_2);
+ ASSERT_EQ(0x82u, size_msg_1.begin[0]);
+ ASSERT_EQ(0u, size_msg_2.begin[0]);
+ }
+ ASSERT_EQ(0x83u, size_msg_2.begin[0]);
+}
+
} // namespace v2
} // namespace tracing
« no previous file with comments | « components/tracing/core/proto_zero_message_handle.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698