Tarantool development patches archive
 help / color / mirror / Atom feed
From: Sergey Bronnikov via Tarantool-patches <tarantool-patches@dev.tarantool.org>
To: Sergey Kaplun <skaplun@tarantool.org>,
	Sergey Bronnikov <estetus@gmail.com>
Cc: tarantool-patches@dev.tarantool.org, max.kokryashkin@gmail.com
Subject: Re: [Tarantool-patches] [PATCH] cmake: add code coverage support
Date: Thu, 27 Jul 2023 11:42:50 +0300	[thread overview]
Message-ID: <60fc85bf-2ac0-fa2c-9e5c-de9b3b71a726@tarantool.org> (raw)
In-Reply-To: <ZME1dfNPpVDgQfhq@root>

Hello, Sergey! Thanks for review!


On 7/26/23 18:02, Sergey Kaplun wrote:
> Hi, Sergey!
> Thanks for the patch!
> It's very interesting to see coverage statistics of the LuaJIT by our
> tests: have much more work to do! :)
>
> Also, it's interesting to compare test suites with each other (done with
> lcov, sorted alphabetically):
> | lua-Harness-tests:
> |   lines......: 54.2% (13550 of 25023 lines)
> |   functions..: 62.4% (1103 of 1769 functions)
> |   branches...: 37.3% (8293 of 22222 branches)
> | LuaJIT-tests:
> |   lines......: 71.3% (17846 of 25023 lines)
> |   functions..: 74.1% (1310 of 1769 functions)
> |   branches...: 54.7% (12155 of 22222 branches)
> | PUC-Rio-Lua-5.1-tests:
> |   lines......: 51.2% (12800 of 25023 lines)
> |   functions..: 57.9% (1025 of 1769 functions)
> |   branches...: 36.0% (7997 of 22222 branches)
> | tarantool-c-tests:
> |   lines......: 33.3% (8210 of 24676 lines)
> |   functions..: 38.6% (672 of 1740 functions)
> |   branches...: 20.4% (4490 of 22014 branches)
> | tarantool-tests:
> |   lines......: 69.6% (17405 of 25023 lines)
> |   functions..: 76.7% (1357 of 1769 functions)
> |   branches...: 49.9% (11090 of 22222 branches)
>
> | Overall:
> |   lines......: 86.0% (21509 of 25023 lines)
> |   functions..: 90.8% (1606 of 1769 functions)
> |   branches...: 66.7% (14812 of 22222 branches)
>
> Please, consider my comments below.
It is interesting, thanks for measuring it!
>
> On 25.07.23, Sergey Bronnikov wrote:
>> From: Sergey Bronnikov <sergeyb@tarantool.org>
>>
>> The patch adds building code coverage report using gcovr [1] and gcov.
>> gcovr is a better version of lcov, see [2]. CMake target LuaJIT-coverage
> Do we really need any features provided by gcovr that are omitted in
> lcov? It's not a problem for me, but there are many more dependencies
> for gcovr than for lcov. Also, it uses python that isn't such
> available (I mean installed by default) as perl.

gcovr has exactly three dependencies, see [1].

Other dependencies specified for gcovr ebuild are "test" dependencies, 
required for

those who will make patches and run tests for gcovr. I don't get why 
ebuild maintainer

made these dependencies mandatory.

1. 
https://github.com/gcovr/gcovr/blob/27e6b3aaec7c91f54fa8e7531f8d652bf6aeadd4/setup.py#L54


BTW lcov has a bigger number of dependencies than specified

in ebuild (or these dependencies are included in a Perl distribution, 
see [2]:


   - Capture::Tiny
   - DateTime
   - Devel::Cover
   - Digest::MD5
   - File::Spec
   - at least one flavor of JSON module.
     In order of performance/preference:
        - JSON::XS
        - Cpanel::JSON::XS
        - JSON::PP
        - JSON
  - Memory::Process
  - Time::HiRes


2. https://github.com/linux-test-project/lcov


>
> | $ equery depgraph dev-util/gcovr
> | ...
> |  * dependency graph for dev-util/gcovr-6.0
> |  `--  dev-util/gcovr-6.0  [~amd64 keyword]
> |    `--  dev-python/jinja-3.1.2  (dev-python/jinja) amd64
> |    `--  dev-python/lxml-4.9.2  (dev-python/lxml) amd64
> |    `--  dev-python/pygments-2.15.1  (dev-python/pygments) amd64
> |    `--  dev-python/yaxmldiff-0.1.0  (dev-python/yaxmldiff) amd64
> |    `--  dev-lang/python-3.11.4  (dev-lang/python) amd64
> |    `--  dev-python/pytest-timeout-2.1.0  (dev-python/pytest-timeout) amd64
> |    `--  dev-python/pytest-7.3.2  (>=dev-python/pytest-7.3.1) amd64
> |    `--  dev-python/gpep517-13  (>=dev-python/gpep517-13) amd64
> |    `--  dev-python/setuptools-67.8.0-r1  (>=dev-python/setuptools-67.8.0-r1) amd64
> | [ dev-util/gcovr-6.0 stats: packages (10), max depth (1) ]
> | $ equery depgraph dev-util/lcov
> | ...
> |  * dependency graph for dev-util/lcov-1.15
> |  `--  dev-util/lcov-1.15  ~amd64
> |    `--  dev-lang/perl-5.38.0-r1  (dev-lang/perl) ~amd64
> |    `--  dev-perl/JSON-4.100.0  (dev-perl/JSON) ~amd64
> |    `--  dev-perl/PerlIO-gzip-0.200.0-r1  (dev-perl/PerlIO-gzip) amd64
> | [ dev-util/lcov-1.15 stats: packages (4), max depth (1) ]
>
> If we don't really need "decisions" metrics that are provided by default
> by gcovr I suggest to consider to use lcov instead, since I don't see
> any other advantages.
>
>> executes regression tests, proccess *.gcno and *.gcda files with gcov,
>> builds detailed HTML report and prints summary about code coverage.
>>
>> ```
>> $ cmake -S . -B build -DENABLE_COVERAGE=ON
> I suggest to use -DLUAJIT_ENABLE_COVERAGE=ON to be consistent with other
> options.
I don't mind, renamed to LUAJIT_ENABLE_COVERAGE.
>
>> $ cmake --build build --parallel
>> $ cmake --build build --target LuaJIT-coverage
>>
>> <snipped>
>>
>> lines: 84.1% (26056 out of 30997)
>> functions: 88.8% (2055 out of 2314)
>> branches: 71.5% (14801 out of 20703)
>> ```
>>
>> 1. https://gcovr.com/
>> 2. https://gcovr.com/en/stable/faq.html#what-is-the-difference-between-lcov-and-gcovr
>> ---
>>   CMakeLists.txt                        |  9 ++++++
>>   test/CMakeLists.txt                   | 40 +++++++++++++++++++++++++++
>>   test/tarantool-c-tests/CMakeLists.txt |  2 +-
>>   3 files changed, 50 insertions(+), 1 deletion(-)
>>
>> diff --git a/CMakeLists.txt b/CMakeLists.txt
>> index 6ef24bba..8bc63b90 100644
>> --- a/CMakeLists.txt
>> +++ b/CMakeLists.txt
>> @@ -116,6 +116,15 @@ if(LUAJIT_ENABLE_WARNINGS)
>>     )
>>   endif()
>>   
>> +set(ENABLE_COVERAGE_DEFAULT OFF)
>> +option(ENABLE_COVERAGE "Enable integration with gcovr, a code coverage program" ${ENABLE_COVERAGE_DEFAULT})
> Minor: Please split the line to the several, to avoid too long lines.

Fixed.


>
>> +if (ENABLE_COVERAGE)
>> +  AppendFlags(CMAKE_C_FLAGS
>> +    -fprofile-arcs
>> +    -ftest-coverage
> Should we use just --coverage?
Sure, updated.
>
> | --coverage
> |            This option is used to compile and link code instrumented
> |            for coverage analysis.  The option is a synonym for
> |            -fprofile-arcs -ftest-coverage (when compiling) and -lgcov
> |            (when linking).
>
> See man gcc(1) for details.
>
>> +  )
>> +endif()
>> +
>>   # Auxiliary flags for main targets (libraries, binaries).
>>   AppendFlags(TARGET_C_FLAGS
>>     -D_FILE_OFFSET_BITS=64
>> diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
>> index 47296a22..9b0f11d8 100644
>> --- a/test/CMakeLists.txt
>> +++ b/test/CMakeLists.txt
>> @@ -59,6 +59,44 @@ add_custom_target(${PROJECT_NAME}-test DEPENDS
>>     tarantool-tests
>>   )
>>   
>> +find_program(GCOVR gcovr)
>> +find_program(GCOV gcov)
>> +set(COVERAGE_HTML_REPORT "luajit-coverage.html")
>> +set(COVERAGE_JSON_REPORT "luajit-coverage.json")
> Should we add ${PROJECT_BUILD_DIR} prefix to be more graceful for
> out-of-source build?
> Also, I see tons of html helper files in the working directory. Is there
> any way to use some <coverage/> directory for all this stuff instead?

Updated:


--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -61,9 +61,10 @@ add_custom_target(${PROJECT_NAME}-test DEPENDS

  find_program(GCOVR gcovr)
  find_program(GCOV gcov)
-set(COVERAGE_HTML_REPORT "luajit-coverage.html")
-set(COVERAGE_JSON_REPORT "luajit-coverage.json")
-if(ENABLE_COVERAGE)
+set(COVERAGE_DIR "${PROJECT_BINARY_DIR}/coverage")
+set(COVERAGE_HTML_REPORT "${COVERAGE_DIR}/luajit.html")
+set(COVERAGE_JSON_REPORT "${COVERAGE_DIR}/luajit.json")


>
>> +if(ENABLE_COVERAGE)
>> +  if(NOT GCOVR OR NOT GCOV)
>> +    add_custom_target(${PROJECT_NAME}-coverage)
>> +    add_custom_command(TARGET ${PROJECT_NAME}-coverage
>> +      COMMENT "Either `gcovr' or `gcov` not found, so ${PROJECT_NAME}-coverage target is dummy"
> Minor: Please split the line to the several, to avoid too long lines.


Done.

>
>> +    )
>> +    return()
> I suppose, we should create dummy target instead.
> | cmake . -DCMAKE_BUILD_TYPE=Debug -DLUA_USE_APICHECK=ON -DLUA_USE_ASSERT=ON -DLUAJIT_ENABLE_GC64=OFF -DENABLE_COVERAGE=OFF && make -j
> | -- [SetVersion] Reading version from VCS: v2.1.0-beta3-331-g4a26e6a1
> | -- [SetBuildParallelLevel] CMAKE_BUILD_PARALLEL_LEVEL is 4
> | CMake Error at test/CMakeLists.txt:118 (add_dependencies):
> |   Cannot add target-level dependencies to non-existent target
> |   "LuaJIT-coverage".
>
>> +  endif()
>> +
>> +  add_custom_target(${PROJECT_NAME}-coverage)
>> +  add_custom_command(TARGET ${PROJECT_NAME}-coverage
>> +    COMMENT "Building coverage report"
>> +    COMMAND
>> +      ${GCOVR}
>> +        # See https://gcovr.com/en/stable/guide/configuration.html
>> +        --root ${PROJECT_SOURCE_DIR}
>> +        --filter ${PROJECT_SOURCE_DIR}/src
> I suppose some files like *.dasc files or buildvm sources should be
> excluded too, since they are not informative.

Done.


>> +        --print-summary
>> +        --output ${COVERAGE_HTML_REPORT}
>> +        --coveralls ${COVERAGE_JSON_REPORT}
> I see also output
>
>> +        --html
>> +        --html-title "LuaJIT Code Coverage Report"
>> +        --html-details
>> +        --sort-percentage
> I can't see an option for decreasing percentage of uncovered lines?
> Is its default value? If it is, then it should be used (as far as we want
> to see uncovered cases first).


Seems it can sort in that order only.

>
>> +        --branches
>> +        --decisions
> Do we need this option? AFAICS, this is mostly about Functional Safety
> applications (road vehicles, etc.).

I would leave it.


>
>> +        --verbose
> I suppose that we should use --verbose option only when VERBOSE=1 env
> var is set.
>
> Also, I'm suprised by lines like this:
> | (DEBUG) Parsing coverage data for file /home/burii/reviews/luajit/gcov/src/lj_tab.h
> | (DEBUG) Starting the decision analysis
> | (DEBUG) Decision Analysis finished!
> | (DEBUG) Finding source file corresponding to a gcov data file
> Is it the part of the --verbose options?

Right, it is enabled only when --verbose is passed. Removed option 
--verbose at all,

I believe we don't need it in normal use.


>
>> +        -j ${CMAKE_BUILD_PARALLEL_LEVEL}
>> +    WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
>> +  )
>> +  message(STATUS "Code coverage HTML report: ${COVERAGE_HTML_REPORT}")
>> +  message(STATUS "Code coverage JSON report: ${COVERAGE_JSON_REPORT}")
>> +endif(ENABLE_COVERAGE)
>> +
>>   if(LUAJIT_USE_TEST)
>>     if(POLICY CMP0037)
>>       if(CMAKE_VERSION VERSION_LESS 3.11)
>> @@ -76,4 +114,6 @@ if(LUAJIT_USE_TEST)
>>       ${PROJECT_NAME}-test
>>       ${PROJECT_NAME}-luacheck
>>     )
>> +
>> +  add_dependencies(${PROJECT_NAME}-coverage ${PROJECT_NAME}-test)
> Is it necessary to rerun all tests to generate this analisys every
> time?

What could be a reasons to regenerate  coverage report without rerunning 
tests?

I can make a target LuaJIT-coverage that will generate report and add 
target coverage that will

run tests and then call LuaJIT-coverage. What do you think?


>
>>   endif()
>> diff --git a/test/tarantool-c-tests/CMakeLists.txt b/test/tarantool-c-tests/CMakeLists.txt
>> index 17255345..8cd76b44 100644
>> --- a/test/tarantool-c-tests/CMakeLists.txt
>> +++ b/test/tarantool-c-tests/CMakeLists.txt
>> @@ -45,7 +45,7 @@ foreach(test_source ${tests})
>>       OUTPUT_NAME "${exe}${C_TEST_SUFFIX}"
>>       RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
>>     )
>> -  target_link_libraries(${exe} libtest ${LUAJIT_LIBRARY})
>> +  target_link_libraries(${exe} libtest ${LUAJIT_LIBRARY} --coverage)
> Why is it done unconditionally?

Ah, missed it. Thanks!


--- a/test/tarantool-c-tests/CMakeLists.txt
+++ b/test/tarantool-c-tests/CMakeLists.txt
@@ -45,7 +45,11 @@ foreach(test_source ${tests})
      OUTPUT_NAME "${exe}${C_TEST_SUFFIX}"
      RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
    )
-  target_link_libraries(${exe} libtest ${LUAJIT_LIBRARY} --coverage)
+  set(libtest-libs libtest ${LUAJIT_LIBRARY})
+  if (LUAJIT_ENABLE_COVERAGE)
+    set(libtest-libs ${libtest-libs} --coverage)
+  endif (LUAJIT_ENABLE_COVERAGE)
+  target_link_libraries(${exe} ${libtest-libs})
    LIST(APPEND TESTS_COMPILED ${exe})
  endforeach()

>
>>     LIST(APPEND TESTS_COMPILED ${exe})
>>   endforeach()
>>   
>> -- 
>> 2.34.1
>>

  reply	other threads:[~2023-07-27  8:42 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-07-25 13:52 Sergey Bronnikov via Tarantool-patches
2023-07-26 15:02 ` Sergey Kaplun via Tarantool-patches
2023-07-27  8:42   ` Sergey Bronnikov via Tarantool-patches [this message]
2023-07-30 12:55     ` Maxim Kokryashkin via Tarantool-patches
2023-07-30 13:34     ` Maxim Kokryashkin via Tarantool-patches
2023-08-01 15:25       ` Sergey Bronnikov via Tarantool-patches
2023-08-08  8:16 ` Sergey Bronnikov via Tarantool-patches
2023-08-08 10:47   ` Sergey Kaplun via Tarantool-patches
2023-08-08 19:25     ` Sergey Bronnikov via Tarantool-patches
2023-08-14  7:46       ` Maxim Kokryashkin via Tarantool-patches

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=60fc85bf-2ac0-fa2c-9e5c-de9b3b71a726@tarantool.org \
    --to=tarantool-patches@dev.tarantool.org \
    --cc=estetus@gmail.com \
    --cc=max.kokryashkin@gmail.com \
    --cc=sergeyb@tarantool.org \
    --cc=skaplun@tarantool.org \
    --subject='Re: [Tarantool-patches] [PATCH] cmake: add code coverage support' \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox