Qml test with large int values unstable in debug



  • Hello,

    I am using qmltestrunner for some test application and came across a difference in behavior between release and debug build when dealing with large int values.

    The test is the following:
    tst_large-int.qml

    import QtQuick 2.5
    import QtTest 1.0
    
    TestCase
    {
        name: "large-int"
    
        function test_large_int(data)
        {
            var act = 0xA5000000;
            var exp = '2768240640';
            compare(act.toString(), exp);
        }
    }
    

    And the application used
    main.cpp -> ut-qml-large-int.exe

    #include <QQmlApplicationEngine>
    #include <QtQuickTest>
    
    int main(int argc, char *argv[])
    {
        return quick_test_main(argc, argv, "ut_qml", 0);
    }
    

    The command used to run the test is:

    ut-qml-large-int.exe -input tst_large-int.qml
    

    When the application is built in release and run with the command above, the test executes correctly every time.
    execution 1:

    ********* Start testing of ut_qml_large_int *********
    Config: Using QtTest library 5.8.0, Qt 5.8.0 (i386-little_endian-ilp32 shared (dynamic) release build; by GCC 5.3.0)
    PASS   : ut_qml_large_int::large-int::initTestCase()
    PASS   : ut_qml_large_int::large-int::test_large_int()
    PASS   : ut_qml_large_int::large-int::cleanupTestCase()
    Totals: 3 passed, 0 failed, 0 skipped, 0 blacklisted, 11ms
    ********* Finished testing of ut_qml_large_int *********
    

    execution 2:

    ********* Start testing of ut_qml_large_int *********
    Config: Using QtTest library 5.8.0, Qt 5.8.0 (i386-little_endian-ilp32 shared (dynamic) release build; by GCC 5.3.0)
    PASS   : ut_qml_large_int::large-int::initTestCase()
    PASS   : ut_qml_large_int::large-int::test_large_int()
    PASS   : ut_qml_large_int::large-int::cleanupTestCase()
    Totals: 3 passed, 0 failed, 0 skipped, 0 blacklisted, 11ms
    ********* Finished testing of ut_qml_large_int *********
    

    But when the same application is built in debug and run with the same command, the first execution is a success but all the following are failed.
    execution 1:

    ********* Start testing of ut_qml_large_int *********
    Config: Using QtTest library 5.8.0, Qt 5.8.0 (i386-little_endian-ilp32 shared (dynamic) debug build; by GCC 5.3.0)
    PASS   : ut_qml_large_int::large-int::initTestCase()
    PASS   : ut_qml_large_int::large-int::test_large_int()
    PASS   : ut_qml_large_int::large-int::cleanupTestCase()
    Totals: 3 passed, 0 failed, 0 skipped, 0 blacklisted, 13ms
    ********* Finished testing of ut_qml_large_int *********
    

    execution 2:

    ********* Start testing of ut_qml_large_int *********
    Config: Using QtTest library 5.8.0, Qt 5.8.0 (i386-little_endian-ilp32 shared (dynamic) debug build; by GCC 5.3.0)
    PASS   : ut_qml_large_int::large-int::initTestCase()
    FAIL!  : ut_qml_large_int::large-int::test_large_int() Compared values are not the same
       Actual   (): -5.386372713960645e+214
       Expected (): 2768240640
    ...\qtc_Desktop__f4d5050c-debug\install-root\ut-qml-large-int\bin\tst_large-int.qml(12) : failure location
    PASS   : ut_qml_large_int::large-int::cleanupTestCase()
    Totals: 2 passed, 1 failed, 0 skipped, 0 blacklisted, 14ms
    ********* Finished testing of ut_qml_large_int *********
    

    Is it something explicable?
    How to get everytime success in debug?



  • I'm slightly suspicious of the fact that 0xA5000000 = 2768240640 overflows a regular 32 bit signed integer. Whether that's taking you into "undefined behaviour" territory I have no idea. Possibly your issue is related to JS "numbers" sometimes being 32-bit ints and sometimes 64-bit floats though.



  • @timday
    What make JS "numbers" using sometimes 32-bit ints or 64-bit floats?
    Is there a way to know which one will be used?

    Thanks.



  • Sorry don't know nearly enough about gnarly details of JS to comment further. You might find https://stackoverflow.com/questions/3885817/how-do-i-check-that-a-number-is-float-or-integer interesting though.

    One thing I have come across (in webdev world) is people writing things like var y=x|0 to force something to integer (the output of the bitwise | operator is guaranteed to be an int). Apparently tricks like that you can get big performance improvements in JS systems using JIT compilation by helping the compiler "know" what the types the code generated will be dealing with.



  • @vivi
    mmh, have you seen this stackoverflow thread?
    compare seems like it would use bitwise operations. Could be the reason for the behavior.



  • the following test function pass at every execution in release and debug:

    function test_54bits_int(data)
    {
        var act = 9007199254740992;
        var exp = '9007199254740992';
        compare(act.toString(), exp);
    }
    

    makes me puzzling...



  • Seems I got a solution but no explication.

    This test is passing everytime in release and debug...

    function test_large_int_add0(data)
    {
        var act = 0xA5000000 + 0;
        var exp = '2768240640';
        compare(act.toString(), exp);
    }
    

Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.