test: object: Extend object test to verify parent-child relationships

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>
This commit is contained in:
Laurent Pinchart 2019-08-12 14:26:24 +03:00
parent 1554d0b6e6
commit d7aded92d3

View file

@ -25,8 +25,8 @@ public:
MessageReceived, MessageReceived,
}; };
InstrumentedObject() InstrumentedObject(Object *parent = nullptr)
: status_(NoMessage) : Object(parent), status_(NoMessage)
{ {
} }
@ -51,22 +51,82 @@ class ObjectTest : public Test
protected: protected:
int init() int init()
{ {
/*
* Create a hierarchy of objects:
* A -> B -> C
* \->D
* E
*/
a_ = new InstrumentedObject(); a_ = new InstrumentedObject();
b_ = new InstrumentedObject(a_);
c_ = new InstrumentedObject(b_);
d_ = new InstrumentedObject(a_);
e_ = new InstrumentedObject();
f_ = nullptr;
return TestPass; return TestPass;
} }
int run() int run()
{ {
/* Verify that moving an object to a different thread succeeds. */ /* Verify the parent-child relationships. */
a_->moveToThread(&thread_); 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; cout << "Failed to move object to thread" << endl;
return TestFail; 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. */ /* 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; cout << "Moving object didn't deliver ThreadMoveMessage" << endl;
return TestFail; return TestFail;
} }
@ -77,10 +137,20 @@ protected:
void cleanup() void cleanup()
{ {
delete a_; delete a_;
delete b_;
delete c_;
delete d_;
delete e_;
delete f_;
} }
private: private:
InstrumentedObject *a_; InstrumentedObject *a_;
InstrumentedObject *b_;
InstrumentedObject *c_;
InstrumentedObject *d_;
InstrumentedObject *e_;
InstrumentedObject *f_;
Thread thread_; Thread thread_;
}; };