| // 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. | |
| // | |
| #ifndef THIRD_PARTY_CREDENTIO_TRACING_TEST_TRACING_H_ | |
| #define THIRD_PARTY_CREDENTIO_TRACING_TEST_TRACING_H_ | |
| #include <memory> | |
| #include <optional> | |
| #include <string> | |
| #include <utility> | |
| #include <variant> | |
| #include <vector> | |
| #include "absl/base/thread_annotations.h" | |
| #include "absl/container/flat_hash_map.h" | |
| #include "absl/status/status.h" | |
| #include "absl/strings/string_view.h" | |
| #include "absl/synchronization/mutex.h" | |
| #include "absl/time/clock.h" | |
| #include "absl/time/time.h" | |
| #include "tracing/span.h" | |
| #include "tracing/tracer.h" | |
| #include "tracing/tracer_factory.h" | |
| namespace credentio_tracing { | |
| // Simple struct representing a recorded point-in-time event within a span. | |
| struct TestRecordedEvent { | |
| std::string name; | |
| absl::Time time = absl::Now(); | |
| bool operator==(const TestRecordedEvent& other) const { | |
| return name == other.name; | |
| } | |
| }; | |
| // Simple struct holding recorded span data for verification in tests. | |
| class TestRecordedSpan { | |
| public: | |
| TestRecordedSpan() = default; | |
| std::string name_; | |
| std::string trace_id_; | |
| std::string span_id_; | |
| std::string parent_span_id_; | |
| const Span* parent_ = nullptr; | |
| absl::Time start_time_ = absl::Now(); | |
| // Set or update an attribute key-value pair. | |
| void SetAttribute(absl::string_view key, AttributeValue value); | |
| // Record an event. | |
| void AddEvent(absl::string_view name); | |
| // Set status. | |
| void SetStatus(const absl::Status& status); | |
| // Mark span as ended. | |
| void End(); | |
| // Returns true if the span has ended. | |
| bool ended() const; | |
| // Returns the recorded status. | |
| absl::Status status() const; | |
| // Returns the recorded end time. | |
| absl::Time end_time() const; | |
| // Returns a copy of recorded attributes. | |
| std::vector<std::pair<std::string, AttributeValue>> attributes() const; | |
| // Returns a copy of recorded events. | |
| std::vector<TestRecordedEvent> events() const; | |
| // Returns optional copy of attribute value for specified key. | |
| std::optional<AttributeValue> GetAttribute(absl::string_view key) const; | |
| // Returns the attribute value converted to type T if found and matching, or | |
| // std::nullopt. | |
| template <typename T> | |
| std::optional<T> GetAttributeAs(absl::string_view key) const { | |
| std::optional<AttributeValue> val = GetAttribute(key); | |
| if (val && std::holds_alternative<T>(*val)) { | |
| return std::get<T>(*val); | |
| } | |
| return std::nullopt; | |
| } | |
| private: | |
| mutable absl::Mutex mutex_; | |
| std::vector<std::pair<std::string, AttributeValue>> attributes_ | |
| ABSL_GUARDED_BY(mutex_); | |
| std::vector<TestRecordedEvent> events_ ABSL_GUARDED_BY(mutex_); | |
| absl::Status status_ ABSL_GUARDED_BY(mutex_) = absl::OkStatus(); | |
| bool ended_ ABSL_GUARDED_BY(mutex_) = false; | |
| absl::Time end_time_ ABSL_GUARDED_BY(mutex_) = absl::InfinitePast(); | |
| }; | |
| // Test implementation of Span that records operations to a TestRecordedSpan | |
| // struct. | |
| class TestSpan : public Span { | |
| public: | |
| explicit TestSpan(std::shared_ptr<TestRecordedSpan> recorded_span); | |
| void SetAttribute(absl::string_view key, AttributeValue value) override; | |
| void AddEvent(absl::string_view name) override; | |
| void SetStatus(const absl::Status& status) override; | |
| void End() override; | |
| // Returns the underlying TestRecordedSpan struct pointer. | |
| std::shared_ptr<TestRecordedSpan> recorded_span() const; | |
| private: | |
| const std::shared_ptr<TestRecordedSpan> recorded_span_; | |
| }; | |
| // Test implementation of Tracer that records created spans. | |
| class TestTracer : public Tracer { | |
| public: | |
| using Tracer::StartSpan; | |
| TestTracer() = default; | |
| std::unique_ptr<Span> StartSpanImpl( | |
| absl::string_view span_name, | |
| const StartSpanOptions& options) const override; | |
| // Returns all recorded spans. | |
| std::vector<std::shared_ptr<TestRecordedSpan>> GetSpans() const; | |
| // Returns the first span matching the given name, or nullptr if not found. | |
| std::shared_ptr<TestRecordedSpan> GetSpan(absl::string_view name) const; | |
| // Returns all spans matching the given name. | |
| std::vector<std::shared_ptr<TestRecordedSpan>> GetSpansByName( | |
| absl::string_view name) const; | |
| // Clears all recorded spans. | |
| void Clear(); | |
| private: | |
| mutable absl::Mutex mutex_; | |
| mutable std::vector<std::shared_ptr<TestRecordedSpan>> spans_ | |
| ABSL_GUARDED_BY(mutex_); | |
| }; | |
| // Test implementation of TracerFactory that manages TestTracer instances. | |
| class TestTracerFactory | |
| : public TracerFactory, | |
| public std::enable_shared_from_this<TestTracerFactory> { | |
| public: | |
| TestTracerFactory() = default; | |
| // Creates a new TestTracerFactory instance, registers it as the global | |
| // factory, and returns it. | |
| static std::shared_ptr<TestTracerFactory> Register(); | |
| // Registers the specified factory instance as the global factory. | |
| static void Register(std::shared_ptr<TestTracerFactory> factory); | |
| // Registers this TestTracerFactory instance as the global factory. | |
| void RegisterThis(); | |
| // Unregisters the global TracerFactory instance, resetting to default. | |
| static void Unregister(); | |
| std::shared_ptr<Tracer> GetTracer( | |
| absl::string_view tracer_name) const override; | |
| // Returns the TestTracer associated with tracer_name, or nullptr if not | |
| // found. | |
| std::shared_ptr<TestTracer> GetTestTracer( | |
| absl::string_view tracer_name) const; | |
| // Returns all recorded spans across all managed tracers. | |
| std::vector<std::shared_ptr<TestRecordedSpan>> GetAllSpans() const; | |
| // Clears all registered tracers and their recorded spans. | |
| void Clear(); | |
| private: | |
| mutable absl::Mutex mutex_; | |
| mutable absl::flat_hash_map<std::string, std::shared_ptr<TestTracer>> tracers_ | |
| ABSL_GUARDED_BY(mutex_); | |
| }; | |
| } // namespace credentio_tracing | |
| #endif // THIRD_PARTY_CREDENTIO_TRACING_TEST_TRACING_H_ |