|  | /* | 
|  | *    Copyright (c) 2023 Project CHIP Authors | 
|  | * | 
|  | *    Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | *    you may not use this file except in compliance with the License. | 
|  | *    You may obtain a copy of the License at | 
|  | * | 
|  | *        http://www.apache.org/licenses/LICENSE-2.0 | 
|  | * | 
|  | *    Unless required by applicable law or agreed to in writing, software | 
|  | *    distributed under the License is distributed on an "AS IS" BASIS, | 
|  | *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | *    See the License for the specific language governing permissions and | 
|  | *    limitations under the License. | 
|  | */ | 
|  |  | 
|  | #include <pw_unit_test/framework.h> | 
|  |  | 
|  | #include <lib/core/StringBuilderAdapters.h> | 
|  | #include <tracing/backend.h> | 
|  | #include <tracing/macros.h> | 
|  | #include <tracing/registry.h> | 
|  |  | 
|  | #include <algorithm> | 
|  | #include <string> | 
|  | #include <vector> | 
|  |  | 
|  | using namespace chip; | 
|  | using namespace chip::Tracing; | 
|  |  | 
|  | namespace { | 
|  |  | 
|  | // This keeps a log of all received trace items | 
|  | class LoggingTraceBackend : public Backend | 
|  | { | 
|  | public: | 
|  | LoggingTraceBackend() {} | 
|  | const std::vector<std::string> & traces() const { return mTraces; } | 
|  |  | 
|  | // Implementation | 
|  | void TraceBegin(const char * label, const char * group) override | 
|  | { | 
|  | mTraces.push_back(std::string("BEGIN:") + group + ":" + label); | 
|  | } | 
|  |  | 
|  | void TraceEnd(const char * label, const char * group) override { mTraces.push_back(std::string("END:") + group + ":" + label); } | 
|  |  | 
|  | void TraceInstant(const char * label, const char * group) override | 
|  | { | 
|  | mTraces.push_back(std::string("INSTANT:") + group + ":" + label); | 
|  | } | 
|  |  | 
|  | private: | 
|  | std::vector<std::string> mTraces; | 
|  | }; | 
|  |  | 
|  | TEST(TestTracing, TestBasicTracing) | 
|  | { | 
|  | LoggingTraceBackend backend; | 
|  |  | 
|  | { | 
|  | ScopedRegistration scope(backend); | 
|  |  | 
|  | MATTER_TRACE_SCOPE("A", "Group"); | 
|  | { | 
|  | MATTER_TRACE_SCOPE("B", "Group"); | 
|  |  | 
|  | // direct scope begin/end (not usual, but should work) | 
|  | MATTER_TRACE_BEGIN("C", "Group"); | 
|  | MATTER_TRACE_BEGIN("D", "Group"); | 
|  | MATTER_TRACE_END("D", "Group"); | 
|  | MATTER_TRACE_INSTANT("FOO", "Group"); | 
|  | MATTER_TRACE_END("C", "Group"); | 
|  | } | 
|  | { | 
|  | MATTER_TRACE_SCOPE("E", "Group"); | 
|  | } | 
|  | } | 
|  |  | 
|  | std::vector<std::string> expected = { | 
|  | "BEGIN:Group:A", "BEGIN:Group:B", "BEGIN:Group:C", "BEGIN:Group:D", "END:Group:D", "INSTANT:Group:FOO", | 
|  | "END:Group:C",   "END:Group:B",   "BEGIN:Group:E", "END:Group:E",   "END:Group:A", | 
|  | }; | 
|  |  | 
|  | EXPECT_EQ(backend.traces().size(), expected.size()); | 
|  | EXPECT_TRUE(std::equal(backend.traces().begin(), backend.traces().end(), expected.begin(), expected.end())); | 
|  | } | 
|  |  | 
|  | TEST(TestTracing, TestMultipleBackends) | 
|  | { | 
|  | LoggingTraceBackend b1; | 
|  | LoggingTraceBackend b2; | 
|  | LoggingTraceBackend b3; | 
|  |  | 
|  | { | 
|  | ScopedRegistration register1(b1); | 
|  | MATTER_TRACE_SCOPE("1", "G"); | 
|  |  | 
|  | { | 
|  | ScopedRegistration register2(b2); | 
|  | MATTER_TRACE_SCOPE("2", "G"); | 
|  |  | 
|  | { | 
|  | ScopedRegistration register3(b3); | 
|  | MATTER_TRACE_SCOPE("3", "G"); | 
|  | } | 
|  | { | 
|  | MATTER_TRACE_SCOPE("4", "G"); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | std::vector<std::string> expected1 = { | 
|  | "BEGIN:G:1", "BEGIN:G:2", "BEGIN:G:3", "END:G:3", "BEGIN:G:4", "END:G:4", "END:G:2", "END:G:1", | 
|  | }; | 
|  |  | 
|  | EXPECT_EQ(b1.traces().size(), expected1.size()); | 
|  | EXPECT_TRUE(std::equal(b1.traces().begin(), b1.traces().end(), expected1.begin(), expected1.end())); | 
|  |  | 
|  | std::vector<std::string> expected2 = { | 
|  | "BEGIN:G:2", "BEGIN:G:3", "END:G:3", "BEGIN:G:4", "END:G:4", "END:G:2", | 
|  | }; | 
|  |  | 
|  | EXPECT_EQ(b2.traces().size(), expected2.size()); | 
|  | EXPECT_TRUE(std::equal(b2.traces().begin(), b2.traces().end(), expected2.begin(), expected2.end())); | 
|  |  | 
|  | std::vector<std::string> expected3 = { | 
|  | "BEGIN:G:3", | 
|  | "END:G:3", | 
|  | }; | 
|  |  | 
|  | EXPECT_EQ(b3.traces().size(), expected3.size()); | 
|  | EXPECT_TRUE(std::equal(b3.traces().begin(), b3.traces().end(), expected3.begin(), expected3.end())); | 
|  | } | 
|  |  | 
|  | } // namespace |