[libcamera-devel,v2,17/18] test: object: Extend object test to verify parent-child relationships

Message ID 20190817152104.10834-18-laurent.pinchart@ideasonboard.com
State Accepted
Headers show
Series
  • Object & Thread enhancements
Related show

Commit Message

Laurent Pinchart Aug. 17, 2019, 3:21 p.m. UTC
The test verifies correct behaviour of parent-child relationships in
relation to thread affinity.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
---
 test/object.cpp | 82 +++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 76 insertions(+), 6 deletions(-)

Patch

diff --git a/test/object.cpp b/test/object.cpp
index 3f1f700d1b39..16118971c755 100644
--- a/test/object.cpp
+++ b/test/object.cpp
@@ -25,8 +25,8 @@  public:
 		MessageReceived,
 	};
 
-	InstrumentedObject()
-		: status_(NoMessage)
+	InstrumentedObject(Object *parent = nullptr)
+		: Object(parent), status_(NoMessage)
 	{
 	}
 
@@ -51,22 +51,82 @@  class ObjectTest : public Test
 protected:
 	int init()
 	{
+		/*
+		 * Create a hierarchy of objects:
+		 * A -> B -> C
+		 *   \->D
+		 * E
+		 */
 		a_ = new InstrumentedObject();
+		b_ = new InstrumentedObject(a_);
+		c_ = new InstrumentedObject(b_);
+		d_ = new InstrumentedObject(a_);
+		e_ = new InstrumentedObject();
+		f_ = nullptr;
+
 		return TestPass;
 	}
 
 	int run()
 	{
-		/* Verify that moving an object to a different thread succeeds. */
-		a_->moveToThread(&thread_);
+		/* Verify the parent-child relationships. */
+		if (a_->parent() != nullptr || b_->parent() != a_ ||
+		    c_->parent() != b_ || d_->parent() != a_ ||
+		    e_->parent() != nullptr) {
+			cout << "Incorrect parent-child relationships" << endl;
+			return TestFail;
+		}
 
-		if (a_->thread() != &thread_ || a_->thread() == Thread::current()) {
+		/*
+		 * Verify that moving an object with no parent to a different
+		 * thread succeeds.
+		 */
+		e_->moveToThread(&thread_);
+
+		if (e_->thread() != &thread_ || e_->thread() == Thread::current()) {
 			cout << "Failed to move object to thread" << endl;
 			return TestFail;
 		}
 
+		/*
+		 * Verify that moving an object with a parent to a different
+		 * thread fails. This results in an undefined behaviour, the
+		 * test thus depends on the internal implementation returning
+		 * without performing any change.
+		 */
+		b_->moveToThread(&thread_);
+
+		if (b_->thread() != Thread::current()) {
+			cout << "Moving object with parent to thread shouldn't succeed" << endl;
+			return TestFail;
+		}
+
+		/*
+		 * Verify that moving an object with children to a different
+		 * thread moves all the children.
+		 */
+		a_->moveToThread(&thread_);
+
+		if (a_->thread() != &thread_ || b_->thread() != &thread_ ||
+		    c_->thread() != &thread_ || d_->thread() != &thread_) {
+			cout << "Failed to move children to thread" << endl;
+			return TestFail;
+		}
+
+		/* Verify that objects are bound to the thread of their parent. */
+		f_ = new InstrumentedObject(d_);
+
+		if (f_->thread() != &thread_) {
+			cout << "Failed to bind child to parent thread" << endl;
+			return TestFail;
+		}
+
 		/* Verify that objects receive a ThreadMoveMessage when moved. */
-		if (a_->status() != InstrumentedObject::MessageReceived) {
+		if (a_->status() != InstrumentedObject::MessageReceived ||
+		    b_->status() != InstrumentedObject::MessageReceived ||
+		    c_->status() != InstrumentedObject::MessageReceived ||
+		    d_->status() != InstrumentedObject::MessageReceived ||
+		    e_->status() != InstrumentedObject::MessageReceived) {
 			cout << "Moving object didn't deliver ThreadMoveMessage" << endl;
 			return TestFail;
 		}
@@ -77,10 +137,20 @@  protected:
 	void cleanup()
 	{
 		delete a_;
+		delete b_;
+		delete c_;
+		delete d_;
+		delete e_;
+		delete f_;
 	}
 
 private:
 	InstrumentedObject *a_;
+	InstrumentedObject *b_;
+	InstrumentedObject *c_;
+	InstrumentedObject *d_;
+	InstrumentedObject *e_;
+	InstrumentedObject *f_;
 
 	Thread thread_;
 };