File: PrintCTestRunTimes.cmake

package info (click to toggle)
cccl 2.3.2-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 89,900 kB
  • sloc: cpp: 697,664; ansic: 26,964; python: 11,928; sh: 3,284; asm: 2,154; perl: 460; makefile: 112; xml: 13
file content (109 lines) | stat: -rw-r--r-- 3,149 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
## This CMake script parses the output of ctest and prints a formatted list
## of individual test runtimes, sorted longest first.
##
## ctest > ctest_log
## cmake -DLOGFILE=ctest_log \
##       -P PrintCTestRunTimes.cmake
##
################################################################################

cmake_minimum_required(VERSION 3.15)

# Prepend the string with "0" until the string length equals the specified width
function(pad_string_with_zeros string_var width)
  set(local_string "${${string_var}}")
  string(LENGTH "${local_string}" size)
  while(size LESS width)
    string(PREPEND local_string "0")
    string(LENGTH "${local_string}" size)
  endwhile()
  set(${string_var} "${local_string}" PARENT_SCOPE)
endfunction()

################################################################################

if (NOT LOGFILE)
  message(FATAL_ERROR "Missing -DLOGFILE=<ctest output> argument.")
endif()

# Check if logfile exists
if (NOT EXISTS "${LOGFILE}")
  message(FATAL_ERROR "LOGFILE does not exist ('${LOGFILE}').")
endif()

string(JOIN "" regex
  "^[ ]*[0-9]+/[0-9]+[ ]+Test[ ]+#"
  "([0-9]+)"                          # Test ID
  ":[ ]+"
  "(.+)"                              # Test Name
  "[ ]+\\.+[ ]+"
  "(.+[^ ])"                              # Result
  "[ ]+"
  "([0-9]+)"                          # Seconds
  "\\.[0-9]+[ ]+sec[ ]*$"
)

message(DEBUG "Regex: ${regex}")

# Read the logfile and generate a map / keylist
set(keys)
file(STRINGS "${LOGFILE}" lines)
foreach(line ${lines})

  # Parse each build time
  string(REGEX MATCH "${regex}" _DUMMY "${line}")

  if (CMAKE_MATCH_COUNT EQUAL 4)
    set(test_id      "${CMAKE_MATCH_1}")
    set(test_name    "${CMAKE_MATCH_2}")
    set(test_result  "${CMAKE_MATCH_3}")
    set(tmp          "${CMAKE_MATCH_4}") # floor(runtime_seconds)

    # Compute human readable time
    math(EXPR days         "${tmp} / (60 * 60 * 24)")
    math(EXPR tmp          "${tmp} - (${days} * 60 * 60 * 24)")
    math(EXPR hours        "${tmp} / (60 * 60)")
    math(EXPR tmp          "${tmp} - (${hours} * 60 * 60)")
    math(EXPR minutes      "${tmp} / (60)")
    math(EXPR tmp          "${tmp} - (${minutes} * 60)")
    math(EXPR seconds      "${tmp}")

    # Format time components
    pad_string_with_zeros(days 3)
    pad_string_with_zeros(hours 2)
    pad_string_with_zeros(minutes 2)
    pad_string_with_zeros(seconds 2)

    # Construct table entry
    # Later values in the file for the same command overwrite earlier entries
    string(MAKE_C_IDENTIFIER "${test_id}" key)
    string(JOIN " | " ENTRY_${key}
      "${days}d ${hours}h ${minutes}m ${seconds}s"
      "${test_result}"
      "${test_id}: ${test_name}"
    )

    # Record the key:
    list(APPEND keys "${key}")
  endif()
endforeach()

list(REMOVE_DUPLICATES keys)

# Build the entry list:
set(entries)
foreach(key ${keys})
  list(APPEND entries "${ENTRY_${key}}")
endforeach()

if (NOT entries)
  message(FATAL_ERROR "LOGFILE contained no test times ('${LOGFILE}').")
endif()

# Sort in descending order:
list(SORT entries ORDER DESCENDING)

# Dump table:
foreach(entry ${entries})
  message(STATUS ${entry})
endforeach()