On Wed Sep 23, 2026 at 3:04 PM EDT, Trevor Gamblin wrote:
> This series is motivated by the need to compare durations for various test
> results (originally, ptest) as reported by the Autobuilder. In particular, 
> I've
> been looking at the intermittent ptest issues seen on the AB for the
> qemuriscv64-ptest builders, but we needed a good way to compare per-package
> durations before and after commit 6d6aaf4204be ("qemu: backport RISC-V TLB 
> page
> flushing patches"). I tested this change locally with coreutils (which showed
> roughly 38% improvement on my workstation) and other tests (e.g. libpng, which
> showed no meaningful change), and review on the upstream QEMU list confirmed 
> it
> helped with boot and runtime performance for qemuriscv64.
>
> This resulttool durations feature provides a means to quantify changes in
> duration across more packages at a scale beyond what my machines can handle, 
> and
> might be useful to compare before and after other changes (e.g. toolchain 
> tests)
> over time. I've also added a variety of test cases for oeqa selftests, 
> covering
> everything from basic results parsing to making sure the tool respects
> thresholds. Each of those tests is added as a separate commit to make review
> easier.
>
> I used Claude Code to help build this out. Design took some refinement,
> especially with:
>
> - Comparing delta results for very short tests (i.e. those running for 5-10
>   seconds or less) were mostly noise, especially when fractional runtimes were
>   calculated under the hood and ended up reporting "0" for both runtimes but
>   large (68%, 350%, etc.) deltas. I don't think we have much use for tracking
>   differences in such short tests, but I did provide a '-m/--min-duration' to
>   tweak this (defaulting to 10) if we want to be able to look at those.
> - Durations can vary small amounts (5-10 seconds) across consecutive tests 
> even
>   under little or no load, and higher when the host system is under heavy load
>   (like the AB workers), so a '-t/--threshold' option is available to filter 
> out
>   any tests whose deltas are under a certain percentage. I didn't set a 
> default
>   here, but 10% is probably a reasonable one for people to use.
> - A sort option '-s/--sort-by-delta' was an obvious add so that it can be used
>   to check what the biggest changes are from run to run.
> - Importantly, resulttool durations can compare more than two sources. This 
> will
>   be critical for tracking how results trend over time, but reporting deltas 
> in
>   this case seemed more debatable. For now I've left it at only reporting 
> deltas
>   between consecutive runs (so RUN1->RUN2 and RUN2->RUN3, but not RUN1->RUN3).
>   If we need the overall delta then that should be an easy follow-up.
>
> This has already been useful/promising for inspecting the AB experience with
> qemuriscv64-ptest since the aforementioned QEMU patch backport. For example, I
> ran the following yesterday to get the top 25 largest deltas for
> qemuriscv64-ptest: 
>
> 1. resulttool report 
> https://valkyrie.yocto.io/pub/non-release/20260922-113/testresults/qemuriscv64-ptest/testresults.json
>  > 113.log
> 2. resulttool report 
> https://valkyrie.yocto.io/pub/non-release/20260922-114/testresults/qemuriscv64-ptest/testresults.json
>  > 114.log
> 3. resulttool durations -s -l 25 114.log 113.log
>
> And here's what it showed:
>
> |diffstat              96          34           -62      -65
> |xz                    14           5            -9      -64
> |diffutils             44          16           -28      -64
> |quilt                836         307          -529      -63
> |busybox               94          35           -59      -63
> |coreutils           2997        1166         -1831      -61
> |dpkg                 647         256          -391      -60
> |gettext             1910         762         -1148      -60
> |findutils            110          44           -66      -60
> |m4                   680         281          -399      -59
> |util-linux          1522         643          -879      -58
> |gawk                 171          74           -97      -57
> |elfutils             459         213          -246      -54
> |bluez5               115          54           -61      -53
> |libssh2               94          48           -46      -49
> |logrotate            186          95           -91      -49
> |sed                  142          73           -69      -49
> |opkg                 199         113           -86      -43
> |openssh             2846        1662         -1184      -42
> |gdbm                  27          17           -10      -37
> |bzip2                300         409           109       36
> |parted               473         311          -162      -34
> |wayland               12           8            -4      -33
>
> Interestingly, bzip2's runtime actually increased (a lot!). A proper analysis
> would require averaging the results over several runs, but there seems to be a
> trend with some compression and encryption packages that I'll be looking into.
> In the meantime, hopefully this feature for resulttools will prove useful to
> others too, even if they'd like to see further improvements. Note that I've
> tested it for non-ptest cases, and it works there too. 
>
> Using the following command and results:
>
> - resulttool durations -s -t 10
> - 
> https://valkyrie.yocto.io/pub/non-release/20260923-8/testresults/qemux86-64/testresults.json
> - 
> https://valkyrie.yocto.io/pub/non-release/20260923-50/testresults/qemux86-64/testresults.json
>
> I see:
>
> |=== runtime/poky/qemux86-64/core-image-sato-sdk ===
> |TESTCASE                                                  RUN1        RUN2   
>  RUN1->RUN2        %
> |stap.StapTest.test_stap                                      7          13   
>           5       73
> |kernelmodule.KernelModuleTest.test_kernel_module            22          30   
>           8       36
> |buildcpio.BuildCpioTest.test_cpio                           28          31   
>           3       10
> |
> |=== sdk/qemux86-64/i686/core-image-sato ===
> |TESTCASE                             RUN1        RUN2    RUN1->RUN2        %
> |cmake.CMakeTest.test_assimp            71          83            12       17
> |
> |=== sdk/qemux86-64/x86_64/core-image-sato ===
> |TESTCASE                                           RUN1        RUN2    
> RUN1->RUN2        %
> |rust.RustHostCompileTest.test_cargo_build            13          18          
>    4       33
> |cmake.CMakeTest.test_assimp                          71          92          
>   22       31
> |autotools.AutotoolsTest.test_cpio                    24          27          
>    3       11
> |
> |=== sdkext/qemux86-64/x86_64/core-image-minimal ===
> |TESTCASE                                                           RUN1      
>   RUN2    RUN1->RUN2        %
> |maturin.MaturinTest.test_maturin_list_python                          4      
>     21            18      459
> |devtool.DevtoolTest.test_devtool_build_esdk_package                  28      
>    132           104      372
> |python.Python3Test.test_python3                                       5      
>     22            17      335
> |devtool.DevtoolTest.test_extend_autotools_recipe_creation            82      
>    319           238      291
> |devtool.DevtoolTest.test_recipes_for_nodejs                          15      
>     25             9       61
> |devtool.DevtoolTest.test_devtool_kernelmodule                       433      
>    580           147       34
> |cmake.CMakeTest.test_assimp                                          75      
>     95            21       27
> |devtool.DevtoolTest.test_devtool_add_reset                           12      
>     15             3       26
> |devtool.DevtoolTest.test_devtool_build_cmake                         29      
>     36             7       23
> |
> |=== sdkext/qemux86-64/x86_64/core-image-sato ===
> |TESTCASE                                                           RUN1      
>   RUN2    RUN1->RUN2        %
> |devtool.DevtoolTest.test_devtool_build_cmake                         30      
>    236           206      686
> |maturin.MaturinTest.test_maturin_list_python                          4      
>     22            18      469
> |python.Python3Test.test_python3                                       5      
>     22            17      377
> |devtool.DevtoolTest.test_devtool_kernelmodule                       429      
>   1394           965      225
> |devtool.DevtoolTest.test_devtool_add_reset                           13      
>     18             5       39
> |maturin.MaturinDevelopTest.test_maturin_develop                      24      
>     32             9       36
> |cmake.CMakeTest.test_assimp                                          73      
>     97            24       33
> |devtool.DevtoolTest.test_extend_autotools_recipe_creation            81      
>    105            24       30
> |devtool.DevtoolTest.test_recipes_for_nodejs                          15      
>     19             4       24
> |devtool.DevtoolTest.test_devtool_build_make                          33      
>     39             6       17
> |autotools.AutotoolsTest.test_cpio                                    24      
>     27             3       11
>
> Some other examples of use:
>
> First five results when comparing two reports from 'resulttool report':
>
> |tgamblin@megalith ~/workspace/ypbuilds/poky-qemuriscv64/build $ resulttool 
> durations -l 5 tlb_before.log tlb_tweak.log
> |
> |=== qemuriscv64 PTest Result Summary (Libc: glibc) ===
> |TESTCASE             RUN1        RUN2    RUN1->RUN2        %
> |apr                    50          48            -2       -4
> |apr-util               13          11            -2      -15
> |babeltrace2          1302        1042          -260      -20
> |bc                     82          82             0        0
> |bluez5                115          71           -44      -38
>
> First five results from the same reports when sorted by highest change:
>
> |tgamblin@megalith ~/workspace/ypbuilds/poky-qemuriscv64/build $ resulttool 
> durations -l 5 -s tlb_before.log tlb_tweak.log
> |
> |=== qemuriscv64 PTest Result Summary (Libc: glibc) ===
> |TESTCASE            RUN1        RUN2    RUN1->RUN2        %
> |libseccomp          3833        1686         -2147      -56
> |quilt                836         438          -398      -48
> |findutils            110          58           -52      -47
> |diffstat              96          52           -44      -46
> |diffutils             44          24           -20      -45
>
> Raw (and truncated) testresults.json comparison for two sources from the
> Autobuilder:
>
> |tgamblin@megalith 
> ~/workspace/ypbuilds/poky-qemuriscv64/layers/openembedded-core ((no branch, 
> rebasing master))$ resulttool durations 
> https://valkyrie.yocto.io/pub/non-release/20260923-79/testresults/qemuriscv64-ptest/testresults.json
>  
> https://valkyrie.yocto.io/pub/non-release/20260923-78/testresults/qemuriscv64-ptest/testresults.json
> |
> |=== runtime/poky/qemuriscv64/core-image-ptest-apr ===
> |TESTCASE                                                   RUN1        RUN2  
>   RUN1->RUN2        %
> |ptest.PtestRunnerTest.test_ptestrunner_expectfail            48          48  
>            0        1
> |ptestresult.sections.apr                                     46          47  
>            1        2
> |
> |=== runtime/poky/qemuriscv64/core-image-ptest-apr-util ===
> |TESTCASE                                                   RUN1        RUN2  
>   RUN1->RUN2        %
> |ptest.PtestRunnerTest.test_ptestrunner_expectfail            12          13  
>            1        9
> |ptestresult.sections.apr-util                                11          11  
>            0        0
> |
> |=== runtime/poky/qemuriscv64/core-image-ptest-babeltrace2 ===
> |TESTCASE                                                   RUN1        RUN2  
>   RUN1->RUN2        %
> |ptest.PtestRunnerTest.test_ptestrunner_expectfail           981        1066  
>           85        9
> |ptestresult.sections.babeltrace2                            973        1058  
>           85        9
>
> The same results with '-l 1' (one line max):
>
> |tgamblin@megalith 
> ~/workspace/ypbuilds/poky-qemuriscv64/layers/openembedded-core ((no branch, 
> rebasing master))$ resulttool durations -l 1 
> https://valkyrie.yocto.io/pub/non-release/20260923-79/testresults/qemuriscv64-ptest/testresults.json
>  
> https://valkyrie.yocto.io/pub/non-release/20260923-78/testresults/qemuriscv64-ptest/testresults.json
> |
> |=== runtime/poky/qemuriscv64/core-image-ptest-apr ===
> |TESTCASE                                                   RUN1        RUN2  
>   RUN1->RUN2        %
> |ptest.PtestRunnerTest.test_ptestrunner_expectfail            48          48  
>            0        1
> |
> |=== runtime/poky/qemuriscv64/core-image-ptest-apr-util ===
> |TESTCASE                                                   RUN1        RUN2  
>   RUN1->RUN2        %
> |ptest.PtestRunnerTest.test_ptestrunner_expectfail            12          13  
>            1        9
> |
> |=== runtime/poky/qemuriscv64/core-image-ptest-babeltrace2 ===
> |TESTCASE                                                   RUN1        RUN2  
>   RUN1->RUN2        %
> |ptest.PtestRunnerTest.test_ptestrunner_expectfail           981        1066  
>           85        9

Realizing I didn't provide an example of the three-sources case. This is what
the raw output looks like:

|TESTCASE                                                   RUN1        RUN2    
    RUN3    RUN1->RUN2        %    RUN2->RUN3        %
|ptestresult.sections.util-linux                            1522         643    
     935          -879      -58           292       45
|ptest.PtestRunnerTest.test_ptestrunner_expectfail          1525         645    
     937          -880      -58           292       45
|
|=== runtime/poky/qemuriscv64/core-image-ptest-wayland ===
|TESTCASE                                                   RUN1        RUN2    
    RUN3    RUN1->RUN2        %    RUN2->RUN3        %
|ptestresult.sections.wayland                                 12           8    
      10            -4      -33             2       25
|ptest.PtestRunnerTest.test_ptestrunner_expectfail            14          10    
      11            -5      -33             2       19
|
|=== runtime/poky/qemuriscv64/core-image-ptest-xz ===
|TESTCASE                                                   RUN1        RUN2    
    RUN3    RUN1->RUN2        %    RUN2->RUN3        %
|ptestresult.sections.xz                                      14           5    
       9            -9      -64             4       80
|ptest.PtestRunnerTest.test_ptestrunner_expectfail            16           7    
      10            -9      -57             3       41

And using reports:

|tgamblin@megalith 
~/workspace/ypbuilds/poky-qemuriscv64/layers/openembedded-core 
(tgamblin/resulttool-durations)$ resulttool durations -s -t 10 114.log 113.log 
64.log
|
|=== qemuriscv64 PTest Result Summary (Libc: glibc) ===
|TESTCASE                            RUN1        RUN2        RUN3    RUN1->RUN2 
       %    RUN2->RUN3        %
|xz                                    14           5           9            -9 
     -64             4       80
|flex                                  33          11          19           -22 
     -67             8       73
|libseccomp                          3833        1098        1766         -2735 
     -71           668       61
|busybox                               94          35          58           -59 
     -63            23       66
|diffstat                              96          34          55           -62 
     -65            21       62

Trevor

>
> Trevor Gamblin (13):
>   scripts: resulttool: add 'durations' option
>   selftest: resulttooltests.py: add basic durations test
>   selftest: resulttooltests.py: add report-log Time(s) column test
>   selftest: resulttooltests.py: add zero-round pct suppression test
>   selftest: resulttooltests.py: add consecutive-pair delta test
>   selftest: resulttooltests.py: add threshold filtering test
>   selftest: resulttooltests.py: add threshold-disabled test
>   selftest: resulttooltests.py: add multi-pair threshold test
>   selftest: resulttooltests.py: add None-pct threshold test
>   selftest: resulttooltests.py: add sort-by-delta test
>   selftest: resulttooltests.py: add limit-after-sort test
>   selftest: resulttooltests.py: add short-tables ordering test
>   selftest: resulttooltests.py: add min-duration default test
>
>  .../oeqa/selftest/cases/resulttooltests.py    | 201 ++++++++++++++++++
>  scripts/lib/resulttool/durations.py           | 187 ++++++++++++++++
>  scripts/resulttool                            |   2 +
>  3 files changed, 390 insertions(+)
>  create mode 100644 scripts/lib/resulttool/durations.py


-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#246559): 
https://lists.openembedded.org/g/openembedded-core/message/246559
Mute This Topic: https://lists.openembedded.org/mt/121399132/21656
Group Owner: [email protected]
Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub 
[[email protected]]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to