From 9d705911391c456813ce54a52f70aa2ccbc5b553 Mon Sep 17 00:00:00 2001 From: Milian Wolff Date: Mon, 5 Jan 2015 18:06:43 +0100 Subject: Make the tests less flaky and don't send empty property updates. The tests have been flaky on the CI. And indeed, running the tests locally under valgrind, which heavily influences the timings, I could reproduce failures on my local machine as well. The failure was due to multiple things, but most notably boils down to intermittend property update noficiations. To reduce that, the myFactory.lastObj property is propagated up. This way, any change to that property won't be propagated to the clients and influence the test. Furthermore, the failing tests are hardened by also checking the server messages, which is crucial to correct the flow of messages. Finally, a bug was found, where an empty property change could be broadcasted to all clients, when only a specific client's object got its properties changed. This is also fixed by this patch now. Change-Id: I2c7ba53253e2841db1a290872dacb097a7b984cf Reviewed-by: Bernd Lamecker Reviewed-by: Risto Avila Reviewed-by: Simon Hausmann Reviewed-by: Milian Wolff --- tests/auto/qml/Client.qml | 26 ++++++++++------ tests/auto/qml/tst_webchannel.qml | 63 +++++++++++++++++++++++++++------------ 2 files changed, 61 insertions(+), 28 deletions(-) (limited to 'tests') diff --git a/tests/auto/qml/Client.qml b/tests/auto/qml/Client.qml index c18644f..ff2824b 100644 --- a/tests/auto/qml/Client.qml +++ b/tests/auto/qml/Client.qml @@ -91,17 +91,21 @@ Item { function awaitRawMessage(from) { - if (!from || typeof from !== "string") - from = "clientMessages"; - else - from += "Messages"; + var messages; + if (!from || typeof from !== "string" || from == "client") { + from = "client"; + messages = clientMessages; + } else { + from = "server"; + messages = serverMessages; + } - for (var i = 0; i < 10 && !root[from].length; ++i) + for (var i = 0; i < 10 && !messages.length; ++i) wait(10); - var msg = root[from].shift(); + var msg = messages.shift(); if (debug) { - console.log((root.objectName ? "(" + root.objectName + ")" : ""), "Shifting Message " + from + ":" + JSON.stringify(msg)); + console.log((root.objectName ? "(" + root.objectName + ")" : ""), "shifting message " + from + "[" + messages.length + "]" + ":" + JSON.stringify(msg)); } return msg; } @@ -120,11 +124,15 @@ Item { var msg; do { msg = awaitMessage(from); - verify(msg); + if (!msg) { + console.trace(); + verify(msg); + } } while (skip && (msg.type === JSClient.QWebChannelMessageTypes.idle)); if (type !== null) { + if (!msg || msg.type != type) + console.trace(); verify(msg); - verify(msg.type); compare(msg.type, type); } return msg; diff --git a/tests/auto/qml/tst_webchannel.qml b/tests/auto/qml/tst_webchannel.qml index 8f40cf5..f41c4fa 100644 --- a/tests/auto/qml/tst_webchannel.qml +++ b/tests/auto/qml/tst_webchannel.qml @@ -66,13 +66,13 @@ TestCase { property var bar: 1 WebChannel.id: "myOtherObj" } + property var lastFactoryObj QtObject { id: myFactory - property var lastObj function create(id) { - lastObj = component.createObject(myFactory, {objectName: id}); - return lastObj; + lastFactoryObj = component.createObject(myFactory, {objectName: id}); + return lastFactoryObj; } WebChannel.id: "myFactory" } @@ -235,12 +235,15 @@ TestCase { }); }); client.awaitInit(); + client.awaitResponse(); + // create testObj var msg = client.awaitMessage(); compare(msg.type, JSClient.QWebChannelMessageTypes.invokeMethod); compare(msg.object, "myFactory"); - verify(myFactory.lastObj); - compare(myFactory.lastObj.objectName, "testObj"); + client.awaitResponse(); + verify(lastFactoryObj); + compare(lastFactoryObj.objectName, "testObj"); compare(channel.objects[testObjId].objectName, "testObj"); // mySignal connection @@ -248,29 +251,42 @@ TestCase { compare(msg.type, JSClient.QWebChannelMessageTypes.connectToSignal); compare(msg.object, testObjId); + // set myProperty msg = client.awaitMessage(); compare(msg.type, JSClient.QWebChannelMessageTypes.setProperty); compare(msg.object, testObjId); - compare(myFactory.lastObj.myProperty, 42); + compare(lastFactoryObj.myProperty, 42); + // call myMethod msg = client.awaitMessage(); compare(msg.type, JSClient.QWebChannelMessageTypes.invokeMethod); compare(msg.object, testObjId); compare(msg.args, ["foobar"]); + client.awaitResponse(); compare(lastMethodArg, "foobar"); client.awaitIdle(); - myFactory.lastObj.mySignal("foobar", 42); + // the server should eventually notify the client about the property update + client.awaitPropertyUpdate(); + + client.awaitIdle(); + + // trigger a signal and ensure it gets transmitted + lastFactoryObj.mySignal("foobar", 42); + client.awaitSignal(); // deleteLater call msg = client.awaitMessage(); compare(msg.type, JSClient.QWebChannelMessageTypes.invokeMethod); compare(msg.object, testObjId); + client.awaitResponse(); + // now the signalArgs should also be set compare(signalArgs, {"0": "foobar", "1": 42}); - client.awaitIdle(); // destroyed signal + // and also a destroyed signal + client.awaitSignal(); compare(JSON.stringify(testObjBeforeDeletion), JSON.stringify({})); compare(JSON.stringify(testObjAfterDeletion), JSON.stringify({})); @@ -288,52 +304,61 @@ TestCase { }); }); client.awaitInit(); + client.awaitResponse(); + + // call to myFactory.create() + var msg = client.awaitMessage(); + compare(msg.type, JSClient.QWebChannelMessageTypes.invokeMethod); + client.awaitResponse(); - // ignore first message (call to myFactory.create()) - client.awaitMessage(); client.awaitIdle(); verify(testObj); var testObjId = testObj.__id__; testObj.deleteLater(); - var msg = client.awaitMessage(); + msg = client.awaitMessage(); compare(msg.type, JSClient.QWebChannelMessageTypes.invokeMethod); compare(msg.object, testObjId); + client.awaitResponse(); + // destroyed signal + client.awaitSignal(); - // after receiving the destroyed signal the client deletes - // local objects and sends back a idle message - client.awaitIdle(); - - compare(myFactory.lastObj, null); + compare(lastFactoryObj, null); compare(typeof channel.objects[testObjId], "undefined"); } - function test_wrapper_propertyUpdateOfWrappedObjects() { + function test_wrapper_propertyUpdateOfWrappedObjects() + { var testObj; var testObjId; var channel = client.createChannel(function(channel) { channel.objects.myFactory.create("testObj", function(obj) { - testObj = myFactory.lastObj; + testObj = lastFactoryObj; testObjId = obj.__id__; }); }); client.awaitInit(); + client.awaitResponse(); // call to myFactory.create() var msg = client.awaitMessage(); compare(msg.type, JSClient.QWebChannelMessageTypes.invokeMethod); + client.awaitResponse(); client.awaitIdle(); testObj.myProperty = 42; + client.awaitPropertyUpdate(); client.awaitIdle(); compare(channel.objects[testObjId].myProperty, 42); channel.objects[testObjId].deleteLater(); - client.awaitIdle(); msg = client.awaitMessage(); compare(msg.type, JSClient.QWebChannelMessageTypes.invokeMethod); + client.awaitResponse(); + // destroyed signal + client.awaitSignal(); } function test_disconnect() -- cgit v1.2.1