1 // Copyright 2023 The Pigweed Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not 4 // use this file except in compliance with the License. You may obtain a copy of 5 // the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 // License for the specific language governing permissions and limitations under 13 // the License. 14 #pragma once 15 16 #include "pw_thread_backend/test_thread_context_native.h" 17 18 namespace pw::thread::test { 19 20 /// `TestThreadContext` is a facade class for creating threads for unit tests in 21 /// a platform independent way. To use it, set 22 /// `pw_thread_TEST_THREAD_CONTEXT_BACKEND` to a backend that implements the 23 /// `pw::thread::test::backend::TestThreadContextNative` class. 24 /// 25 /// To create a thread for unit testing, instantiate a `TestThreadContext`, then 26 /// call `options()` to obtain a `pw::thread::Options`. Use that `Options` to 27 /// start a `Thread`. Users must ensure the context's lifespan outlives the 28 /// thread it creates. Recycling or destroying the context is only allowed if 29 /// `join()` is called on the thread first. 30 /// 31 /// @code{.cpp} 32 /// pw::thread::test::TestThreadContext context; 33 /// pw::thread::Thread test_thread(context.options(), 34 /// ExampleThreadFunction); 35 /// @endcode 36 /// 37 /// Threads created with `TestThreadContext` cannot be configured in any way. 38 /// Backends should create threads with sufficient resources to execute typical 39 /// unit tests. Tests for complex scenarios or interactions where e.g. priority 40 /// matters are not portable, and `TestThreadContext` may not work for them. 41 /// Non-portable tests may include backend-specific headers and instantiate 42 /// thread options for their platforms as required. 43 /// 44 /// @note Developers should structure their logic so it can be tested without 45 /// spawning a thread. Unit tests should avoid spawning threads unless 46 /// absolutely necessary. 47 /// 48 /// @warning Threads using the `TestThreadContext` may only be detached if the 49 /// context has a static lifetime, meaning the context is both never re-used and 50 /// not destroyed before the end of the lifetime of the application. 51 class TestThreadContext { 52 public: 53 TestThreadContext() = default; 54 55 TestThreadContext(const TestThreadContext&) = delete; 56 TestThreadContext& operator=(const TestThreadContext&) = delete; 57 58 /// `pw::thread::test::TestThreadContext` returns a `pw::thread::Options` 59 /// associated with the this object, which can be used to contruct a thread. 60 /// 61 /// @return The default options for testing thread. options()62 const Options& options() const { return context_.options(); } 63 64 private: 65 backend::TestThreadContextNative context_; 66 }; 67 68 } // namespace pw::thread::test 69