| // Copyright 2026 Google LLC | |
| // | |
| // 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 "tracing/span.h" | |
| #include <cstdint> | |
| #include <memory> | |
| #include <string> | |
| #include "absl/status/status.h" | |
| #include "absl/strings/string_view.h" | |
| #include "gmock/gmock.h" | |
| #include "gtest/gtest.h" | |
| #include "tracing/noop_tracing.h" | |
| #include "tracing/tracer.h" | |
| #include "tracing/tracer_factory.h" | |
| namespace credentio_tracing { | |
| namespace { | |
| class MockSpan : public Span { | |
| public: | |
| MOCK_METHOD(void, SetAttribute, (absl::string_view key, AttributeValue value), | |
| (override)); | |
| MOCK_METHOD(void, AddEvent, (absl::string_view name), (override)); | |
| MOCK_METHOD(void, SetStatus, (const absl::Status& status), (override)); | |
| MOCK_METHOD(void, End, (), (override)); | |
| }; | |
| TEST(AttributeValueTest, SupportsExpectedTypes) { | |
| AttributeValue str_val = std::string("test_string"); | |
| EXPECT_EQ(std::get<std::string>(str_val), "test_string"); | |
| AttributeValue uint_val = uint64_t{42}; | |
| EXPECT_EQ(std::get<uint64_t>(uint_val), 42); | |
| AttributeValue int_val = int64_t{42}; | |
| EXPECT_EQ(std::get<int64_t>(int_val), 42); | |
| AttributeValue double_val = 3.14159; | |
| EXPECT_DOUBLE_EQ(std::get<double>(double_val), 3.14159); | |
| AttributeValue bool_val = true; | |
| EXPECT_TRUE(std::get<bool>(bool_val)); | |
| } | |
| TEST(SpanTest, MockSpanInvocations) { | |
| MockSpan span; | |
| EXPECT_CALL(span, SetAttribute("key", AttributeValue(int64_t{123}))); | |
| EXPECT_CALL(span, AddEvent("event_name")); | |
| EXPECT_CALL(span, SetStatus(absl::OkStatus())); | |
| EXPECT_CALL(span, End()); | |
| span.SetAttribute("key", int64_t{123}); | |
| span.AddEvent("event_name"); | |
| span.SetStatus(absl::OkStatus()); | |
| span.End(); | |
| } | |
| TEST(SpanTest, EndWithStatusInvocations) { | |
| MockSpan span; | |
| absl::Status test_status = absl::InvalidArgumentError("invalid argument"); | |
| EXPECT_CALL(span, SetStatus(test_status)); | |
| EXPECT_CALL(span, End()); | |
| span.EndWithStatus(test_status); | |
| } | |
| TEST(NoopSpanTest, AllMethodsExecuteWithoutError) { | |
| NoopSpan span; | |
| span.SetAttribute("key_str", std::string("value")); | |
| span.SetAttribute("key_int", int64_t{42}); | |
| span.SetAttribute("key_double", 3.14); | |
| span.SetAttribute("key_bool", true); | |
| span.AddEvent("test_event"); | |
| span.SetStatus(absl::OkStatus()); | |
| span.SetStatus(absl::InvalidArgumentError("invalid argument")); | |
| span.End(); | |
| } | |
| TEST(NoopTracerTest, StartSpanReturnsNonNullNoopSpan) { | |
| NoopTracer tracer; | |
| std::unique_ptr<Span> span = tracer.StartSpan("test_span"); | |
| ASSERT_NE(span, nullptr); | |
| span->SetAttribute("key", int64_t{100}); | |
| span->AddEvent("event"); | |
| span->SetStatus(absl::OkStatus()); | |
| span->End(); | |
| } | |
| TEST(TracerFactoryTest, DefaultGlobalFactoryIsNoopTracerFactory) { | |
| auto factory = TracerFactory::GetGlobalFactory(); | |
| ASSERT_NE(factory, nullptr); | |
| auto tracer = factory->GetTracer("test_tracer"); | |
| ASSERT_NE(tracer, nullptr); | |
| auto span = tracer->StartSpan("test_span"); | |
| ASSERT_NE(span, nullptr); | |
| } | |
| class MockCustomTracerFactory : public TracerFactory { | |
| public: | |
| MOCK_METHOD(std::shared_ptr<Tracer>, GetTracer, | |
| (absl::string_view tracer_name), (const, override)); | |
| }; | |
| TEST(TracerFactoryTest, GlobalFactoryRegistration) { | |
| auto initial_factory = TracerFactory::GetGlobalFactory(); | |
| EXPECT_NE(initial_factory, nullptr); | |
| auto custom_factory = std::make_shared<MockCustomTracerFactory>(); | |
| TracerFactory::RegisterGlobalFactory(custom_factory); | |
| EXPECT_EQ(TracerFactory::GetGlobalFactory(), custom_factory); | |
| // Restore original factory state after test | |
| TracerFactory::RegisterGlobalFactory(initial_factory); | |
| } | |
| TEST(TracerFactoryTest, RegisterNullptrResetsToNoopTracerFactory) { | |
| auto initial_factory = TracerFactory::GetGlobalFactory(); | |
| EXPECT_NE(initial_factory, nullptr); | |
| auto custom_factory = std::make_shared<MockCustomTracerFactory>(); | |
| TracerFactory::RegisterGlobalFactory(custom_factory); | |
| EXPECT_EQ(TracerFactory::GetGlobalFactory(), custom_factory); | |
| TracerFactory::RegisterGlobalFactory(nullptr); | |
| auto current_factory = TracerFactory::GetGlobalFactory(); | |
| ASSERT_NE(current_factory, nullptr); | |
| EXPECT_NE(current_factory, custom_factory); | |
| // Restore original factory state after test | |
| TracerFactory::RegisterGlobalFactory(initial_factory); | |
| } | |
| } // namespace | |
| } // namespace credentio_tracing |