1 // Copyright 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <chrono>
6 #include <thread>
7 
8 #include "gmock/gmock.h"
9 #include "gtest/gtest.h"
10 #include "platform/test/trace_logging_helpers.h"
11 #include "util/trace_logging.h"
12 
13 #if defined(ENABLE_TRACE_LOGGING)
14 
15 namespace openscreen {
16 namespace internal {
17 
18 using ::testing::_;
19 using ::testing::DoAll;
20 using ::testing::Invoke;
21 
22 // These tests validate that parameters are passed correctly by using the Trace
23 // Internals.
24 constexpr auto category = TraceCategory::kMdns;
25 constexpr uint32_t line = 10;
26 
TEST(TraceLoggingInternalTest,CreatingNoTraceObjectValid)27 TEST(TraceLoggingInternalTest, CreatingNoTraceObjectValid) {
28   TraceInstanceHelper<SynchronousTraceLogger>::Empty();
29 }
30 
TEST(TraceLoggingInternalTest,TestMacroStyleInitializationTrue)31 TEST(TraceLoggingInternalTest, TestMacroStyleInitializationTrue) {
32   constexpr uint32_t delay_in_ms = 50;
33   MockLoggingPlatform platform;
34   EXPECT_CALL(platform, LogTrace(_, _, _, _, _, _, _))
35       .Times(1)
36       .WillOnce(DoAll(Invoke(ValidateTraceTimestampDiff<delay_in_ms>),
37                       Invoke(ValidateTraceErrorCode<Error::Code::kNone>)));
38 
39   {
40     uint8_t temp[sizeof(SynchronousTraceLogger)];
41     auto ptr = TraceInstanceHelper<SynchronousTraceLogger>::Create(
42         temp, category, "Name", __FILE__, line);
43     std::this_thread::sleep_for(std::chrono::milliseconds(delay_in_ms));
44     auto ids = ScopedTraceOperation::hierarchy();
45     EXPECT_NE(ids.current, kEmptyTraceId);
46   }
47   auto ids2 = ScopedTraceOperation::hierarchy();
48   EXPECT_EQ(ids2.current, kEmptyTraceId);
49   EXPECT_EQ(ids2.parent, kEmptyTraceId);
50   EXPECT_EQ(ids2.root, kEmptyTraceId);
51 }
52 
TEST(TraceLoggingInternalTest,TestMacroStyleInitializationFalse)53 TEST(TraceLoggingInternalTest, TestMacroStyleInitializationFalse) {
54   MockLoggingPlatform platform;
55   EXPECT_CALL(platform, LogTrace(_, _, _, _, _, _, _)).Times(0);
56 
57   {
58     auto ptr = TraceInstanceHelper<SynchronousTraceLogger>::Empty();
59     auto ids = ScopedTraceOperation::hierarchy();
60     EXPECT_EQ(ids.current, kEmptyTraceId);
61     EXPECT_EQ(ids.parent, kEmptyTraceId);
62     EXPECT_EQ(ids.root, kEmptyTraceId);
63   }
64   auto ids2 = ScopedTraceOperation::hierarchy();
65   EXPECT_EQ(ids2.current, kEmptyTraceId);
66   EXPECT_EQ(ids2.parent, kEmptyTraceId);
67   EXPECT_EQ(ids2.root, kEmptyTraceId);
68 }
69 
TEST(TraceLoggingInternalTest,ExpectParametersPassedToResult)70 TEST(TraceLoggingInternalTest, ExpectParametersPassedToResult) {
71   MockLoggingPlatform platform;
72   EXPECT_CALL(platform, LogTrace(testing::StrEq("Name"), line,
73                                  testing::StrEq(__FILE__), _, _, _, _))
74       .WillOnce(Invoke(ValidateTraceErrorCode<Error::Code::kNone>));
75 
76   { SynchronousTraceLogger{category, "Name", __FILE__, line}; }
77 }
78 
TEST(TraceLoggingInternalTest,CheckTraceAsyncStartLogsCorrectly)79 TEST(TraceLoggingInternalTest, CheckTraceAsyncStartLogsCorrectly) {
80   MockLoggingPlatform platform;
81   EXPECT_CALL(platform, LogAsyncStart(testing::StrEq("Name"), line,
82                                       testing::StrEq(__FILE__), _, _))
83       .Times(1);
84 
85   { AsynchronousTraceLogger{category, "Name", __FILE__, line}; }
86 }
87 
TEST(TraceLoggingInternalTest,ValidateGettersValidOnEmptyStack)88 TEST(TraceLoggingInternalTest, ValidateGettersValidOnEmptyStack) {
89   EXPECT_EQ(ScopedTraceOperation::current_id(), kEmptyTraceId);
90   EXPECT_EQ(ScopedTraceOperation::root_id(), kEmptyTraceId);
91 
92   auto ids = ScopedTraceOperation::hierarchy();
93   EXPECT_EQ(ids.current, kEmptyTraceId);
94   EXPECT_EQ(ids.parent, kEmptyTraceId);
95   EXPECT_EQ(ids.root, kEmptyTraceId);
96 }
97 
TEST(TraceLoggingInternalTest,ValidateSetResultDoesntSegfaultOnEmptyStack)98 TEST(TraceLoggingInternalTest, ValidateSetResultDoesntSegfaultOnEmptyStack) {
99   Error error = Error::Code::kNone;
100   ScopedTraceOperation::set_result(error);
101 
102   ScopedTraceOperation::set_result(Error::Code::kNone);
103 }
104 
105 }  // namespace internal
106 }  // namespace openscreen
107 
108 #endif  // defined(ENABLE_TRACE_LOGGING)
109