diff options
Diffstat (limited to 'pw_thread/public/pw_thread')
-rw-r--r-- | pw_thread/public/pw_thread/config.h | 2 | ||||
-rw-r--r-- | pw_thread/public/pw_thread/non_portable_test_thread_options.h | 53 | ||||
-rw-r--r-- | pw_thread/public/pw_thread/snapshot.h | 4 | ||||
-rw-r--r-- | pw_thread/public/pw_thread/test_thread_context.h | 68 | ||||
-rw-r--r-- | pw_thread/public/pw_thread/test_threads.h | 36 |
5 files changed, 124 insertions, 39 deletions
diff --git a/pw_thread/public/pw_thread/config.h b/pw_thread/public/pw_thread/config.h index 7b83a7eca..e8dbde11f 100644 --- a/pw_thread/public/pw_thread/config.h +++ b/pw_thread/public/pw_thread/config.h @@ -26,4 +26,4 @@ // The max number of threads to bundle by default for thread snapshot service. #ifndef PW_THREAD_NUM_BUNDLED_THREADS #define PW_THREAD_NUM_BUNDLED_THREADS 3 -#endif // PW_THREAD_MAXIMUM_THREADS
\ No newline at end of file +#endif // PW_THREAD_MAXIMUM_THREADS diff --git a/pw_thread/public/pw_thread/non_portable_test_thread_options.h b/pw_thread/public/pw_thread/non_portable_test_thread_options.h new file mode 100644 index 000000000..48277b543 --- /dev/null +++ b/pw_thread/public/pw_thread/non_portable_test_thread_options.h @@ -0,0 +1,53 @@ +// 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. + +// IMPORTANT: DO NOT USE THIS HEADER FOR UNIT TESTS!!! +// +// Instead, use pw::thread::test::TestThreadContext in +// pw_thread/test_thread_context.h. See +// https://pigweed.dev/pw_thread#unit-testing-with-threads. +// +// pw_thread/non_portable_test_thread_options.h is not a facade. Code written +// against it is not portable. It was created for testing of pw_thread itself, +// so threads with different configurations can be instantiated in tests. +#pragma once + +#include "pw_thread/thread.h" + +namespace pw::thread::test { + +// Two test threads are used to verify the thread facade. +// +// These functions are NOT part of a facade! They are used to allocate thread +// options for testing pw_thread backends only. Multiple variations of these +// functions may be instantiated within a single toolchain for testing purposes. +// Do NOT use unless absolutely necessary. Instead, use the TestThreadContext +// facade for unit tests. +const Options& TestOptionsThread0(); +const Options& TestOptionsThread1(); + +// The proper way to ensure a thread is finished and cleaned up is to call +// join(). However, the pw_thread facade tests must test detached thread +// functionality. This backend-specific cleanup API blocks until all the test +// threads above have finished executing. +// +// Threads may be backed by static contexts or dynamic context heap allocations. +// After this function returns, the threads' static contexts are ready for reuse +// and/or their dynamically allocated memory has been freed. +// +// Precondition: The threads must have started to execute before calling this +// if cleanup is expected. +void WaitUntilDetachedThreadsCleanedUp(); + +} // namespace pw::thread::test diff --git a/pw_thread/public/pw_thread/snapshot.h b/pw_thread/public/pw_thread/snapshot.h index c2502ae2b..4ae30e054 100644 --- a/pw_thread/public/pw_thread/snapshot.h +++ b/pw_thread/public/pw_thread/snapshot.h @@ -28,7 +28,7 @@ namespace pw::thread { // field. This should encode either raw_backtrace or raw_stack to the provided // Thread stream encoder. using ProcessThreadStackCallback = - Function<Status(proto::Thread::StreamEncoder&, ConstByteSpan)>; + Function<Status(proto::pwpb::Thread::StreamEncoder&, ConstByteSpan)>; struct StackContext { std::string_view thread_name; @@ -48,7 +48,7 @@ struct StackContext { // stack_end_pointer // stack_pointer Status SnapshotStack(const StackContext& stack, - proto::Thread::StreamEncoder& encoder, + proto::pwpb::Thread::StreamEncoder& encoder, const ProcessThreadStackCallback& thread_stack_callback); } // namespace pw::thread diff --git a/pw_thread/public/pw_thread/test_thread_context.h b/pw_thread/public/pw_thread/test_thread_context.h new file mode 100644 index 000000000..f4b8039f1 --- /dev/null +++ b/pw_thread/public/pw_thread/test_thread_context.h @@ -0,0 +1,68 @@ +// 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. +#pragma once + +#include "pw_thread_backend/test_thread_context_native.h" + +namespace pw::thread::test { + +/// `TestThreadContext` is a facade class for creating threads for unit tests in +/// a platform independent way. To use it, set +/// `pw_thread_TEST_THREAD_CONTEXT_BACKEND` to a backend that implements the +/// `pw::thread::test::backend::TestThreadContextNative` class. +/// +/// To create a thread for unit testing, instantiate a `TestThreadContext`, then +/// call `options()` to obtain a `pw::thread::Options`. Use that `Options` to +/// start a `Thread`. Users must ensure the context's lifespan outlives the +/// thread it creates. Recycling or destroying the context is only allowed if +/// `join()` is called on the thread first. +/// +/// @code{.cpp} +/// pw::thread::test::TestThreadContext context; +/// pw::thread::Thread test_thread(context.options(), +/// ExampleThreadFunction); +/// @endcode +/// +/// Threads created with `TestThreadContext` cannot be configured in any way. +/// Backends should create threads with sufficient resources to execute typical +/// unit tests. Tests for complex scenarios or interactions where e.g. priority +/// matters are not portable, and `TestThreadContext` may not work for them. +/// Non-portable tests may include backend-specific headers and instantiate +/// thread options for their platforms as required. +/// +/// @note Developers should structure their logic so it can be tested without +/// spawning a thread. Unit tests should avoid spawning threads unless +/// absolutely necessary. +/// +/// @warning Threads using the `TestThreadContext` may only be detached if the +/// context has a static lifetime, meaning the context is both never re-used and +/// not destroyed before the end of the lifetime of the application. +class TestThreadContext { + public: + TestThreadContext() = default; + + TestThreadContext(const TestThreadContext&) = delete; + TestThreadContext& operator=(const TestThreadContext&) = delete; + + /// `pw::thread::test::TestThreadContext` returns a `pw::thread::Options` + /// associated with the this object, which can be used to contruct a thread. + /// + /// @return The default options for testing thread. + const Options& options() const { return context_.options(); } + + private: + backend::TestThreadContextNative context_; +}; + +} // namespace pw::thread::test diff --git a/pw_thread/public/pw_thread/test_threads.h b/pw_thread/public/pw_thread/test_threads.h deleted file mode 100644 index 4d7a45627..000000000 --- a/pw_thread/public/pw_thread/test_threads.h +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2020 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. -#pragma once - -#include "pw_thread/thread.h" - -namespace pw::thread::test { - -// Two test threads are used to verify the thread facade. -const Options& TestOptionsThread0(); -const Options& TestOptionsThread1(); - -// Unfortunately the thread facade test's job is also to test detached threads -// which may be backed by static contexts or dynamic context heap allocations. -// In literally every other case you would use join for this, however that is -// not an option here as detached thread functionality is being tested. -// For this reason a backend specific cleanup API is provided which shall block -// until all the test threads above have finished executions and are ready for -// potential re-use and/or freed any dynamic allocations. -// -// Precondition: The threads must have started to execute before calling this -// if cleanup is expected. -void WaitUntilDetachedThreadsCleanedUp(); - -} // namespace pw::thread::test |