• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# test-compress.cmake -- Runs a test against an input file to make sure that the specified
2#   targets are able to to compress and then decompress it successfully. Optionally verify
3#   the results with gzip. Output files are generated with unique names to prevent parallel
4#   tests from corrupting one another. Default target arguments are compatible with minigzip.
5
6# Copyright (C) 2021 Nathan Moinvaziri
7# Licensed under the Zlib license, see LICENSE.md for details
8
9# that test a specific input file for compression or decompression.
10
11# Required Variables
12#   INPUT                   - Input file to test
13#   TARGET or               - Command to run for both compress and decompress
14#     COMPRESS_TARGET and   - Command to run to compress input file
15#     DECOMPRESS_TARGET     - Command to run to decompress output file
16
17# Optional Variables
18#   TEST_NAME               - Name of test to use when constructing output file paths
19#   COMPRESS_ARGS           - Arguments to pass for compress command (default: -c -k)
20#   DECOMPRESS_ARGS         - Arguments to pass to decompress command (default: -d -c)
21
22#   GZIP_VERIFY             - Verify that gzip can decompress the COMPRESS_TARGET output and
23#                             verify that DECOMPRESS_TARGET can decompress gzip output of INPUT
24#   COMPARE                 - Verify decompressed output is the same as input
25#   SUCCESS_EXIT            - List of successful exit codes (default: 0, ie: 0;1)
26
27if(TARGET)
28    set(COMPRESS_TARGET ${TARGET})
29    set(DECOMPRESS_TARGET ${TARGET})
30endif()
31
32if(NOT DEFINED INPUT OR NOT DEFINED COMPRESS_TARGET OR NOT DEFINED DECOMPRESS_TARGET)
33    message(FATAL_ERROR "Compress test arguments missing")
34endif()
35
36# Set default values
37if(NOT DEFINED COMPARE)
38    set(COMPARE ON)
39endif()
40if(NOT DEFINED COMPRESS_ARGS)
41    set(COMPRESS_ARGS -c -k)
42endif()
43if(NOT DEFINED DECOMPRESS_ARGS)
44    set(DECOMPRESS_ARGS -d -c)
45endif()
46if(NOT DEFINED GZIP_VERIFY)
47    set(GZIP_VERIFY ON)
48endif()
49if(NOT DEFINED SUCCESS_EXIT)
50    set(SUCCESS_EXIT 0)
51endif()
52
53# Use test name from input file name
54if(NOT DEFINED TEST_NAME)
55    get_filename_component(TEST_NAME "${INPUT}" NAME)
56endif()
57
58# Generate unique output path so multiple tests can be executed at the same time
59string(RANDOM LENGTH 6 UNIQUE_ID)
60string(REPLACE "." "-" TEST_NAME "${TEST_NAME}")
61set(OUTPUT_BASE "${CMAKE_CURRENT_BINARY_DIR}/test/${TEST_NAME}-${UNIQUE_ID}")
62
63# Ensure directory exists for output files
64get_filename_component(OUTPUT_DIR "${OUTPUT_BASE}" DIRECTORY)
65file(MAKE_DIRECTORY "${OUTPUT_DIR}")
66
67macro(cleanup)
68    # Cleanup temporary mingizip files
69    file(REMOVE ${OUTPUT_BASE}.gz ${OUTPUT_BASE}.out)
70    # Cleanup temporary gzip files
71    file(REMOVE ${OUTPUT_BASE}.gzip.gz ${OUTPUT_BASE}.gzip.out)
72endmacro()
73
74# Compress input file
75if(NOT EXISTS ${INPUT})
76    message(FATAL_ERROR "Cannot find compress input: ${INPUT}")
77endif()
78
79set(COMPRESS_COMMAND ${COMPRESS_TARGET} ${COMPRESS_ARGS})
80
81execute_process(COMMAND ${CMAKE_COMMAND}
82    "-DCOMMAND=${COMPRESS_COMMAND}"
83    -DINPUT=${INPUT}
84    -DOUTPUT=${OUTPUT_BASE}.gz
85    "-DSUCCESS_EXIT=${SUCCESS_EXIT}"
86    -P ${CMAKE_CURRENT_LIST_DIR}/run-and-redirect.cmake
87    RESULT_VARIABLE CMD_RESULT)
88
89if(CMD_RESULT)
90    cleanup()
91    message(FATAL_ERROR "Compress failed: ${CMD_RESULT}")
92endif()
93
94# Decompress output
95if(NOT EXISTS ${OUTPUT_BASE}.gz)
96    cleanup()
97    message(FATAL_ERROR "Cannot find decompress input: ${OUTPUT_BASE}.gz")
98endif()
99
100set(DECOMPRESS_COMMAND ${DECOMPRESS_TARGET} ${DECOMPRESS_ARGS})
101
102execute_process(COMMAND ${CMAKE_COMMAND}
103    "-DCOMMAND=${DECOMPRESS_COMMAND}"
104    -DINPUT=${OUTPUT_BASE}.gz
105    -DOUTPUT=${OUTPUT_BASE}.out
106    "-DSUCCESS_EXIT=${SUCCESS_EXIT}"
107    -P ${CMAKE_CURRENT_LIST_DIR}/run-and-redirect.cmake
108    RESULT_VARIABLE CMD_RESULT)
109
110if(CMD_RESULT)
111    cleanup()
112    message(FATAL_ERROR "Decompress failed: ${CMD_RESULT}")
113endif()
114
115if(COMPARE)
116    # Compare decompressed output with original input file
117    execute_process(COMMAND ${CMAKE_COMMAND}
118        -E compare_files ${INPUT} ${OUTPUT_BASE}.out
119        RESULT_VARIABLE CMD_RESULT)
120
121    if(CMD_RESULT)
122        cleanup()
123        message(FATAL_ERROR "Compare minigzip decompress failed: ${CMD_RESULT}")
124    endif()
125endif()
126
127if(GZIP_VERIFY AND NOT "${COMPRESS_ARGS}" MATCHES "-T")
128    # Transparent writing does not use gzip format
129    find_program(GZIP gzip)
130    if(GZIP)
131        if(NOT EXISTS ${OUTPUT_BASE}.gz)
132            cleanup()
133            message(FATAL_ERROR "Cannot find gzip decompress input: ${OUTPUT_BASE}.gz")
134        endif()
135
136        # Check gzip can decompress our compressed output
137        set(GZ_DECOMPRESS_COMMAND ${GZIP} --decompress)
138
139        execute_process(COMMAND ${CMAKE_COMMAND}
140            "-DCOMMAND=${GZ_DECOMPRESS_COMMAND}"
141            -DINPUT=${OUTPUT_BASE}.gz
142            -DOUTPUT=${OUTPUT_BASE}.gzip.out
143            "-DSUCCESS_EXIT=${SUCCESS_EXIT}"
144            -P ${CMAKE_CURRENT_LIST_DIR}/run-and-redirect.cmake
145            RESULT_VARIABLE CMD_RESULT)
146
147        if(CMD_RESULT)
148            cleanup()
149            message(FATAL_ERROR "Gzip decompress failed: ${CMD_RESULT}")
150        endif()
151
152        # Compare gzip output with original input file
153        execute_process(COMMAND ${CMAKE_COMMAND}
154            -E compare_files ${INPUT} ${OUTPUT_BASE}.gzip.out
155            RESULT_VARIABLE CMD_RESULT)
156
157        if(CMD_RESULT)
158            cleanup()
159            message(FATAL_ERROR "Compare gzip decompress failed: ${CMD_RESULT}")
160        endif()
161
162        if(NOT EXISTS ${OUTPUT_BASE}.gz)
163            cleanup()
164            message(FATAL_ERROR "Cannot find gzip compress input: ${INPUT}")
165        endif()
166
167        # Compress input file with gzip
168        set(GZ_COMPRESS_COMMAND ${GZIP} --stdout)
169
170        execute_process(COMMAND ${CMAKE_COMMAND}
171            "-DCOMMAND=${GZ_COMPRESS_COMMAND}"
172            -DINPUT=${INPUT}
173            -DOUTPUT=${OUTPUT_BASE}.gzip.gz
174            "-DSUCCESS_EXIT=${SUCCESS_EXIT}"
175            -P ${CMAKE_CURRENT_LIST_DIR}/run-and-redirect.cmake
176            RESULT_VARIABLE CMD_RESULT)
177
178        if(CMD_RESULT)
179            cleanup()
180            message(FATAL_ERROR "Gzip compress failed: ${CMD_RESULT}")
181        endif()
182
183        if(NOT EXISTS ${OUTPUT_BASE}.gz)
184            cleanup()
185            message(FATAL_ERROR "Cannot find minigzip decompress input: ${OUTPUT_BASE}.gzip.gz")
186        endif()
187
188        # Check decompress target can handle gzip compressed output
189        execute_process(COMMAND ${CMAKE_COMMAND}
190            "-DCOMMAND=${DECOMPRESS_COMMAND}"
191            -DINPUT=${OUTPUT_BASE}.gzip.gz
192            -DOUTPUT=${OUTPUT_BASE}.gzip.out
193            "-DSUCCESS_EXIT=${SUCCESS_EXIT}"
194            -P ${CMAKE_CURRENT_LIST_DIR}/run-and-redirect.cmake
195            RESULT_VARIABLE CMD_RESULT)
196
197        if(CMD_RESULT)
198            cleanup()
199            message(FATAL_ERROR "Minigzip decompress gzip failed: ${CMD_RESULT}")
200        endif()
201
202        if(COMPARE)
203            # Compare original input file with gzip decompressed output
204            execute_process(COMMAND ${CMAKE_COMMAND}
205                -E compare_files ${INPUT} ${OUTPUT_BASE}.gzip.out
206                RESULT_VARIABLE CMD_RESULT)
207
208            if(CMD_RESULT)
209                cleanup()
210                message(FATAL_ERROR "Compare minigzip decompress gzip failed: ${CMD_RESULT}")
211            endif()
212        endif()
213    endif()
214endif()
215
216cleanup()