| // Copyright 2023 The Pigweed 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 |
| // |
| // https://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_trace_tokenized/trace_service_pwpb.h" |
| |
| #include "pw_chrono/system_clock.h" |
| #include "pw_rpc/pwpb/test_method_context.h" |
| #include "pw_stream/memory_stream.h" |
| #include "pw_trace/trace.h" |
| #include "pw_trace_tokenized/trace_tokenized.h" |
| #include "pw_unit_test/framework.h" |
| |
| namespace pw::trace { |
| namespace { |
| |
| class TraceServiceTest : public ::testing::Test { |
| public: |
| TraceServiceTest() {} |
| |
| static constexpr uint32_t kTraceTransferHandlerId = 7; |
| }; |
| |
| TEST_F(TraceServiceTest, Start) { |
| auto& tracer = trace::GetTokenizedTracer(); |
| |
| std::array<std::byte, PW_TRACE_BUFFER_SIZE_BYTES> dest_buffer; |
| stream::MemoryWriter writer(dest_buffer); |
| PW_PWPB_TEST_METHOD_CONTEXT(TraceService, Start) |
| context(tracer, writer); |
| |
| ASSERT_FALSE(tracer.IsEnabled()); |
| ASSERT_EQ(context.call({}), OkStatus()); |
| ASSERT_TRUE(tracer.IsEnabled()); |
| |
| // multiple calls to start are disallowed |
| ASSERT_EQ(context.call({}), Status::FailedPrecondition()); |
| } |
| |
| TEST_F(TraceServiceTest, Stop) { |
| auto& tracer = trace::GetTokenizedTracer(); |
| |
| std::array<std::byte, PW_TRACE_BUFFER_SIZE_BYTES> dest_buffer; |
| stream::MemoryWriter writer(dest_buffer); |
| PW_PWPB_TEST_METHOD_CONTEXT(TraceService, Stop) |
| context(tracer, writer); |
| context.service().SetTransferId(kTraceTransferHandlerId); |
| |
| tracer.Enable(true); |
| PW_TRACE_INSTANT("TestTrace"); |
| |
| ASSERT_EQ(context.call({}), OkStatus()); |
| ASSERT_FALSE(tracer.IsEnabled()); |
| EXPECT_EQ(kTraceTransferHandlerId, context.response().file_id); |
| EXPECT_LT(0u, writer.bytes_written()); |
| } |
| |
| TEST_F(TraceServiceTest, StopNoTransferHandlerId) { |
| auto& tracer = trace::GetTokenizedTracer(); |
| |
| std::array<std::byte, PW_TRACE_BUFFER_SIZE_BYTES> dest_buffer; |
| stream::MemoryWriter writer(dest_buffer); |
| PW_PWPB_TEST_METHOD_CONTEXT(TraceService, Stop) |
| context(tracer, writer); |
| |
| tracer.Enable(true); |
| PW_TRACE_INSTANT("TestTrace"); |
| |
| ASSERT_EQ(context.call({}), OkStatus()); |
| ASSERT_FALSE(tracer.IsEnabled()); |
| EXPECT_FALSE(context.response().file_id.has_value()); |
| EXPECT_LT(0u, writer.bytes_written()); |
| } |
| |
| TEST_F(TraceServiceTest, StopNotStarted) { |
| auto& tracer = trace::GetTokenizedTracer(); |
| |
| std::array<std::byte, PW_TRACE_BUFFER_SIZE_BYTES> dest_buffer; |
| stream::MemoryWriter writer(dest_buffer); |
| PW_PWPB_TEST_METHOD_CONTEXT(TraceService, Stop) |
| context(tracer, writer); |
| |
| // stopping while tracing is disabled results in FailedPrecondition |
| ASSERT_EQ(context.call({}), Status::FailedPrecondition()); |
| } |
| |
| TEST_F(TraceServiceTest, StopNoData) { |
| auto& tracer = trace::GetTokenizedTracer(); |
| |
| std::array<std::byte, PW_TRACE_BUFFER_SIZE_BYTES> dest_buffer; |
| stream::MemoryWriter writer(dest_buffer); |
| PW_PWPB_TEST_METHOD_CONTEXT(TraceService, Stop) |
| context(tracer, writer); |
| |
| tracer.Enable(true); |
| |
| // stopping with no trace data results in Unavailable |
| ASSERT_EQ(context.call({}), Status::Unavailable()); |
| } |
| |
| TEST_F(TraceServiceTest, GetClockParameters) { |
| auto& tracer = trace::GetTokenizedTracer(); |
| |
| std::array<std::byte, PW_TRACE_BUFFER_SIZE_BYTES> dest_buffer; |
| stream::MemoryWriter writer(dest_buffer); |
| |
| PW_PWPB_TEST_METHOD_CONTEXT(TraceService, GetClockParameters) |
| context(tracer, writer); |
| |
| ASSERT_EQ(context.call({}), OkStatus()); |
| EXPECT_EQ( |
| static_cast<int32_t>(PW_CHRONO_SYSTEM_CLOCK_PERIOD_SECONDS_NUMERATOR), |
| context.response().clock_parameters.tick_period_seconds_numerator); |
| EXPECT_EQ( |
| static_cast<int32_t>(PW_CHRONO_SYSTEM_CLOCK_PERIOD_SECONDS_DENOMINATOR), |
| context.response().clock_parameters.tick_period_seconds_denominator); |
| EXPECT_EQ( |
| static_cast<int32_t>(chrono::SystemClock::epoch), |
| static_cast<int32_t>(*context.response().clock_parameters.epoch_type)); |
| } |
| |
| } // namespace |
| } // namespace pw::trace |