CTest: Add a test to perform negative testing on all rocJPEG APIs (#143)
* CTest: Add a test to perform negative testing on all rocJPEG APIs * clean up
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
37efebb5a7
Коммит
232a9c6906
@@ -220,6 +220,7 @@ if(HIP_FOUND AND Libva_FOUND)
|
||||
install(FILES ${CPACK_RESOURCE_FILE_LICENSE} DESTINATION ${CMAKE_INSTALL_DOCDIR}-asan COMPONENT asan)
|
||||
# install test cmake
|
||||
install(FILES test/CMakeLists.txt DESTINATION ${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME}/test COMPONENT test)
|
||||
install(FILES test/rocjpeg_negative_api_tests/CMakeLists.txt test/rocjpeg_negative_api_tests/README.md test/rocjpeg_negative_api_tests/rocjpeg_api_negative_tests.cpp test/rocjpeg_negative_api_tests/rocjpeg_api_negative_tests.h test/rocjpeg_negative_api_tests/rocjpegnegativetest.cpp DESTINATION ${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME}/test/rocjpeg_negative_api_tests COMPONENT test)
|
||||
|
||||
message("-- ${White}AMD ROCm rocJPEG -- CMAKE_CXX_FLAGS:${CMAKE_CXX_FLAGS}${ColourReset}")
|
||||
message("-- ${White}AMD ROCm rocJPEG -- Link Libraries: ${LINK_LIBRARY_LIST}${ColourReset}")
|
||||
|
||||
@@ -89,6 +89,8 @@ RocJpegStatus RocJpegDecoder::InitializeDecoder() {
|
||||
}
|
||||
} else if (backend_ == ROCJPEG_BACKEND_HYBRID) {
|
||||
return ROCJPEG_STATUS_NOT_IMPLEMENTED;
|
||||
} else {
|
||||
return ROCJPEG_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
return rocjpeg_status;
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ include(CTest)
|
||||
# add ROCm find Config location
|
||||
list(APPEND CMAKE_PREFIX_PATH ${ROCM_PATH}/lib/cmake)
|
||||
|
||||
# find rocDecode
|
||||
# find rocjpeg
|
||||
find_package(ROCJPEG QUIET)
|
||||
|
||||
if(ROCJPEG_FOUND)
|
||||
@@ -324,4 +324,15 @@ add_test(
|
||||
--build-generator "${CMAKE_GENERATOR}"
|
||||
--test-command "jpegdecodeperf"
|
||||
-i ${ROCM_PATH}/share/rocjpeg/images/
|
||||
)
|
||||
|
||||
add_test(
|
||||
NAME
|
||||
jpeg-negative-api-tests
|
||||
COMMAND
|
||||
"${CMAKE_CTEST_COMMAND}"
|
||||
--build-and-test "${ROCM_PATH}/share/rocjpeg/test/rocjpeg_negative_api_tests"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/rocjpeg_negative_api_tests"
|
||||
--build-generator "${CMAKE_GENERATOR}"
|
||||
--test-command "rocjpegnegativetest"
|
||||
)
|
||||
@@ -0,0 +1,93 @@
|
||||
################################################################################
|
||||
# Copyright (c) 2024 - 2025 Advanced Micro Devices, Inc.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
################################################################################
|
||||
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
# ROCM Path
|
||||
if(DEFINED ENV{ROCM_PATH})
|
||||
set(ROCM_PATH $ENV{ROCM_PATH} CACHE PATH "Default ROCm installation path")
|
||||
elseif(ROCM_PATH)
|
||||
message("-- INFO:ROCM_PATH Set -- ${ROCM_PATH}")
|
||||
else()
|
||||
set(ROCM_PATH /opt/rocm CACHE PATH "Default ROCm installation path")
|
||||
endif()
|
||||
# Set AMD Clang as default compiler
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED On)
|
||||
set(CMAKE_CXX_EXTENSIONS ON)
|
||||
if (NOT DEFINED CMAKE_CXX_COMPILER)
|
||||
set(CMAKE_C_COMPILER ${ROCM_PATH}/bin/amdclang)
|
||||
set(CMAKE_CXX_COMPILER ${ROCM_PATH}/bin/amdclang++)
|
||||
endif()
|
||||
|
||||
project(rocjpegnegativetest)
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/../../cmake)
|
||||
list(APPEND CMAKE_PREFIX_PATH ${ROCM_PATH}/lib/cmake)
|
||||
|
||||
# rocJPEG sample build type
|
||||
set(DEFAULT_BUILD_TYPE "Release")
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE "${DEFAULT_BUILD_TYPE}" CACHE STRING "rocJPEG Default Build Type" FORCE)
|
||||
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release")
|
||||
endif()
|
||||
if(CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
# -O0 -- Don't Optimize output file
|
||||
# -gdwarf-4 -- generate debugging information, dwarf-4 for making valgrind work
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -gdwarf-4")
|
||||
else()
|
||||
# -O3 -- Optimize output file
|
||||
# -DNDEBUG -- turn off asserts
|
||||
# -fPIC -- Generate position-independent code if possible
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -DNDEBUG -fPIC")
|
||||
endif()
|
||||
|
||||
find_package(HIP QUIET)
|
||||
find_package(rocjpeg QUIET)
|
||||
find_package(rocprofiler-register QUIET)
|
||||
|
||||
if(HIP_FOUND AND rocjpeg_FOUND AND rocprofiler-register_FOUND)
|
||||
# HIP
|
||||
set(LINK_LIBRARY_LIST ${LINK_LIBRARY_LIST} hip::host)
|
||||
# rocJPEG and utils
|
||||
include_directories (${rocjpeg_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
set(LINK_LIBRARY_LIST ${LINK_LIBRARY_LIST} ${rocjpeg_LIBRARY})
|
||||
# rocprofiler-register
|
||||
set(LINK_LIBRARY_LIST ${LINK_LIBRARY_LIST} rocprofiler-register::rocprofiler-register)
|
||||
# sample app exe
|
||||
list(APPEND SOURCES ${PROJECT_SOURCE_DIR} rocjpegnegativetest.cpp rocjpeg_api_negative_tests.cpp)
|
||||
# --all-warnings/-Wall Enable most warning messages
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
|
||||
add_executable(${PROJECT_NAME} ${SOURCES})
|
||||
target_link_libraries(${PROJECT_NAME} ${LINK_LIBRARY_LIST})
|
||||
else()
|
||||
message("-- ERROR!: ${PROJECT_NAME} excluded! please install all the dependencies and try again!")
|
||||
if (NOT HIP_FOUND)
|
||||
message(FATAL_ERROR "-- ERROR!: HIP Not Found! - please install ROCm and HIP!")
|
||||
endif()
|
||||
if (NOT rocjpeg_FOUND)
|
||||
message(FATAL_ERROR "-- ERROR!: rocJPEG Not Found! - please install rocJPEG!")
|
||||
endif()
|
||||
if (NOT rocprofiler-register_FOUND)
|
||||
message(FATAL_ERROR "-- ERROR!: rocprofiler-register Not Found! - please install rocprofiler-register!")
|
||||
endif()
|
||||
endif()
|
||||
@@ -0,0 +1,22 @@
|
||||
# rocJPEG API Negative tests
|
||||
|
||||
This test suite is designed to perform negative testing on all rocJPEG APIs. The purpose of these tests is to validate the robustness and error-handling mechanisms of the rocJPEG APIs
|
||||
by providing invalid inputs, unexpected scenarios, or edge cases to ensure the APIs respond with appropriate error messages or behaviors.
|
||||
|
||||
## Prerequisites:
|
||||
|
||||
* Install [rocJPEG](../../README.md#build-and-install-instructions)
|
||||
|
||||
## Build
|
||||
|
||||
```shell
|
||||
mkdir build && cd build
|
||||
cmake ../
|
||||
make -j
|
||||
```
|
||||
|
||||
## Run
|
||||
|
||||
```shell
|
||||
./rocjpegnegativetest
|
||||
```
|
||||
@@ -0,0 +1,365 @@
|
||||
|
||||
/*
|
||||
Copyright (c) 2024 - 2025 Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "rocjpeg_api_negative_tests.h"
|
||||
|
||||
RocJpegApiNegativeTests:: RocJpegApiNegativeTests() {};
|
||||
|
||||
RocJpegApiNegativeTests::~RocJpegApiNegativeTests() {
|
||||
RocJpegStatus rocjpeg_status = rocJpegDestroy(rocjpeg_handle_);
|
||||
if (rocjpeg_status != ROCJPEG_STATUS_SUCCESS) {
|
||||
std::cerr << "Failed to destroy rocjpeg handle: " << rocJpegGetErrorName(rocjpeg_status) << std::endl;
|
||||
}
|
||||
rocjpeg_status = rocJpegStreamDestroy(rocjpeg_stream_handle_);
|
||||
if (rocjpeg_status != ROCJPEG_STATUS_SUCCESS) {
|
||||
std::cerr << "Failed to destroy rocjpeg stream handle " << rocJpegGetErrorName(rocjpeg_status) << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
int RocJpegApiNegativeTests::TestInvalidStreamCreate() {
|
||||
std::cout << "info: Executing negative test cases for the rocJpegStreamCreate API" << std::endl;
|
||||
//Scenario 1: Pass nullptr for jpeg_stream_handle
|
||||
RocJpegStatus rocjpeg_status = rocJpegStreamCreate(nullptr);
|
||||
if (rocjpeg_status != ROCJPEG_STATUS_INVALID_PARAMETER) {
|
||||
std::cerr << "Expected ROCJPEG_STATUS_INVALID_PARAMETER but got " << rocJpegGetErrorName(rocjpeg_status) << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
// Create a valid rocJPEG stream handle - This step ensures a valid rocjpeg_stream_handle_ is available for subsequent negative testing of other rocJPEG parser APIs.
|
||||
rocjpeg_status = rocJpegStreamCreate(&rocjpeg_stream_handle_);
|
||||
if (rocjpeg_status != ROCJPEG_STATUS_SUCCESS) {
|
||||
std::cerr << "Expected ROCJPEG_STATUS_SUCCESS but got " << rocJpegGetErrorName(rocjpeg_status) << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
int RocJpegApiNegativeTests::TestInvalidStreamParse() {
|
||||
std::cout << "info: Executing negative test cases for the rocJpegStreamParse API" << std::endl;
|
||||
|
||||
// Scenario 1: Pass nullptr for data and jpeg_stream_handle
|
||||
RocJpegStatus rocjpeg_status = rocJpegStreamParse(nullptr, 0, nullptr);
|
||||
if (rocjpeg_status != ROCJPEG_STATUS_INVALID_PARAMETER) {
|
||||
std::cerr << "Expected ROCJPEG_STATUS_INVALID_PARAMETER but got " << rocJpegGetErrorName(rocjpeg_status) << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Scenario 2: Pass a valid jpeg_stream_handle but nullptr for data
|
||||
rocjpeg_status = rocJpegStreamParse(nullptr, 0, rocjpeg_stream_handle_);
|
||||
if (rocjpeg_status != ROCJPEG_STATUS_INVALID_PARAMETER) {
|
||||
std::cerr << "Expected ROCJPEG_STATUS_INVALID_PARAMETER but got " << rocJpegGetErrorName(rocjpeg_status) << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Scenario 3: Invalid SOI marker
|
||||
std::vector<uint8_t> invalid_soi_data = {0xFF, 0x00}; // Invalid SOI marker
|
||||
rocjpeg_status = rocJpegStreamParse(invalid_soi_data.data(), invalid_soi_data.size(), rocjpeg_stream_handle_);
|
||||
if (rocjpeg_status != ROCJPEG_STATUS_BAD_JPEG) {
|
||||
std::cerr << "Expected ROCJPEG_STATUS_BAD_JPEG but got " << rocJpegGetErrorName(rocjpeg_status) << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Scenario 4: Invalid DRI marker
|
||||
std::vector<uint8_t> invalid_dri_data = {0xFF, 0xD8, 0xFF, 0xDD, 0x00, 0x03}; // Invalid DRI marker length
|
||||
rocjpeg_status = rocJpegStreamParse(invalid_dri_data.data(), invalid_dri_data.size(), rocjpeg_stream_handle_);
|
||||
if (rocjpeg_status != ROCJPEG_STATUS_BAD_JPEG) {
|
||||
std::cerr << "Expected ROCJPEG_STATUS_BAD_JPEG but got " << rocJpegGetErrorName(rocjpeg_status) << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Scenario 5: Invalid SOS marker - provide an invalid number of components (e.g., the number of components cannot exceed 3, but 4 is provided)
|
||||
std::vector<uint8_t> invalid_sos_data = {0xFF, 0xD8, 0xFF, 0xDA, 0x00, 0x01, 0x04}; // Invalid number of component
|
||||
rocjpeg_status = rocJpegStreamParse(invalid_sos_data.data(), invalid_sos_data.size(), rocjpeg_stream_handle_);
|
||||
if (rocjpeg_status != ROCJPEG_STATUS_BAD_JPEG) {
|
||||
std::cerr << "Expected ROCJPEG_STATUS_BAD_JPEG but got " << rocJpegGetErrorName(rocjpeg_status) << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Scenario 6: Invalid number of quantization tables in the DQT marker
|
||||
std::vector<uint8_t> invalid_quantization_data = {0xFF, 0xD8, 0xFF, 0xDB, 0x00, 0x03, 0x1F}; // Invalid quantization table
|
||||
rocjpeg_status = rocJpegStreamParse(invalid_quantization_data.data(), invalid_quantization_data.size(), rocjpeg_stream_handle_);
|
||||
if (rocjpeg_status != ROCJPEG_STATUS_BAD_JPEG) {
|
||||
std::cerr << "Expected ROCJPEG_STATUS_BAD_JPEG but got " << rocJpegGetErrorName(rocjpeg_status) << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Scenario 7: Invalid number of Huffman tables in the DHT marker
|
||||
std::vector<uint8_t> invalid_huffman_table_data = {0xFF, 0xD8, 0xFF, 0xC4, 0x00, 0x03, 0x02}; // Too many Huffman tables
|
||||
rocjpeg_status = rocJpegStreamParse(invalid_huffman_table_data.data(), invalid_huffman_table_data.size(), rocjpeg_stream_handle_);
|
||||
if (rocjpeg_status != ROCJPEG_STATUS_BAD_JPEG) {
|
||||
std::cerr << "Expected ROCJPEG_STATUS_BAD_JPEG for invalid number of Huffman tables but got " << rocJpegGetErrorName(rocjpeg_status) << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Scenario 8: Invalid AC Huffman table in the DHT marker
|
||||
std::vector<uint8_t> invalid_ac_huffman_table_data = {
|
||||
0xFF, 0xD8, //SOI
|
||||
0xFF, 0xC4, 0x00, 0x03, 0x10, // DHT with AC Hufman table
|
||||
0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0xA3 // Array of the invalid number of AC codes - the count of values cannot exceed 0xA2, but 0xA3 is provided
|
||||
};
|
||||
rocjpeg_status = rocJpegStreamParse(invalid_ac_huffman_table_data.data(), invalid_ac_huffman_table_data.size(), rocjpeg_stream_handle_);
|
||||
if (rocjpeg_status != ROCJPEG_STATUS_BAD_JPEG) {
|
||||
std::cerr << "Expected ROCJPEG_STATUS_BAD_JPEG but got " << rocJpegGetErrorName(rocjpeg_status) << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Scenario 9: Invalid DC Huffman table in the DHT marker
|
||||
std::vector<uint8_t> invalid_dc_huffman_table_data = {
|
||||
0xFF, 0xD8, // SOI
|
||||
0xFF, 0xC4, 0x00, 0x03, 0x01, // DHT with DC Hufman table
|
||||
0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0x0D // Array of the invalid number of DC codes - the count of values cannot exceed 0x0C, but 0x0D is provided
|
||||
}; // Invalid DC Huffman table
|
||||
rocjpeg_status = rocJpegStreamParse(invalid_dc_huffman_table_data.data(), invalid_dc_huffman_table_data.size(), rocjpeg_stream_handle_);
|
||||
if (rocjpeg_status != ROCJPEG_STATUS_BAD_JPEG) {
|
||||
std::cerr << "Expected ROCJPEG_STATUS_BAD_JPEG but got " << rocJpegGetErrorName(rocjpeg_status) << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Scenario 10: invalid number of JPEG component in the SOF marker
|
||||
std::vector<uint8_t> invalid_num_component_data = {
|
||||
0xFF, 0xD8, // SOI
|
||||
0xFF, 0xC0, 0x00, 0x08, // Invalid SOF with the number of component is set to 4
|
||||
0x08, 0x00, 0x10, 0x00, 0x10, 0x04
|
||||
};
|
||||
rocjpeg_status = rocJpegStreamParse(invalid_num_component_data.data(), invalid_num_component_data.size(), rocjpeg_stream_handle_);
|
||||
if (rocjpeg_status != ROCJPEG_STATUS_BAD_JPEG) {
|
||||
std::cerr << "Expected ROCJPEG_STATUS_BAD_JPEG but got " << rocJpegGetErrorName(rocjpeg_status) << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Scenario 11: Invalid quantization table selector specified in the SOF marker
|
||||
std::vector<uint8_t> Invalid_quantization_table_selector_data = {
|
||||
0xFF, 0xD8, // SOI
|
||||
0xFF, 0xC0, 0x00, 0x0B, // SOF with 3 components with invalid quantization table selector is set to 4
|
||||
0x08, 0x00, 0x10, 0x00, 0x10, 0x03, 0x00, 0x00, 0x04
|
||||
};
|
||||
rocjpeg_status = rocJpegStreamParse(Invalid_quantization_table_selector_data.data(), Invalid_quantization_table_selector_data.size(), rocjpeg_stream_handle_);
|
||||
if (rocjpeg_status != ROCJPEG_STATUS_BAD_JPEG) {
|
||||
std::cerr << "Expected ROCJPEG_STATUS_BAD_JPEG but got " << rocJpegGetErrorName(rocjpeg_status) << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Scenario 11: Mismatch in the number of components between the SOS and SOF markers
|
||||
std::vector<uint8_t> component_mismatch_data = {
|
||||
0xFF, 0xD8, // SOI
|
||||
0xFF, 0xC0, 0x00, 0x11, // SOF with 3 components
|
||||
0x08, 0x00, 0x10, 0x00, 0x10, 0x03, 0x01, 0xFF, 0x00, 0x02, 0xFF, 0x01, 0x03, 0xFF, 0x02,
|
||||
0xFF, 0xDA, 0x00, 0x07, // SOS with 2 components (mismatch)
|
||||
0x01, 0x00, 0x02, 0x11, 0x00
|
||||
};
|
||||
rocjpeg_status = rocJpegStreamParse(component_mismatch_data.data(), component_mismatch_data.size(), rocjpeg_stream_handle_);
|
||||
if (rocjpeg_status != ROCJPEG_STATUS_BAD_JPEG) {
|
||||
std::cerr << "Expected ROCJPEG_STATUS_BAD_JPEG but got " << rocJpegGetErrorName(rocjpeg_status) << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Scenario 12: Invalid AC Huffman table selector in the SOS marker
|
||||
std::vector<uint8_t> invalid_ac_huffman_sos_data = {
|
||||
0xFF, 0xD8, // SOI
|
||||
0xFF, 0xDA, 0x00, 0x07, // SOS with invalid number of AC Huffman table
|
||||
0x01, 0x00, 0x04, 0x11, 0x00
|
||||
};
|
||||
rocjpeg_status = rocJpegStreamParse(invalid_ac_huffman_sos_data.data(), invalid_ac_huffman_sos_data.size(), rocjpeg_stream_handle_);
|
||||
if (rocjpeg_status != ROCJPEG_STATUS_BAD_JPEG) {
|
||||
std::cerr << "Expected ROCJPEG_STATUS_BAD_JPEG but got " << rocJpegGetErrorName(rocjpeg_status) << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Scenario 13: Invalid DC Huffman table selector in the SOS marker
|
||||
std::vector<uint8_t> invalid_dc_huffman_sos_data = {
|
||||
0xFF, 0xD8, // SOI
|
||||
0xFF, 0xDA, 0x00, 0x07, // SOS with invalid number of DC Huffman table
|
||||
0x01, 0x00, 0x44, 0x11, 0x00
|
||||
};
|
||||
rocjpeg_status = rocJpegStreamParse(invalid_dc_huffman_sos_data.data(), invalid_dc_huffman_sos_data.size(), rocjpeg_stream_handle_);
|
||||
if (rocjpeg_status != ROCJPEG_STATUS_BAD_JPEG) {
|
||||
std::cerr << "Expected ROCJPEG_STATUS_BAD_JPEG but got " << rocJpegGetErrorName(rocjpeg_status) << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
int RocJpegApiNegativeTests::TestInvalidStreamDestroy() {
|
||||
std::cout << "info: Executing negative test cases for the rocJpegStreamDestroy API" << std::endl;
|
||||
//Scenario 1: Pass nullptr for jpeg_stream_handle
|
||||
RocJpegStatus rocjpeg_status = rocJpegStreamDestroy(nullptr);
|
||||
if (rocjpeg_status != ROCJPEG_STATUS_INVALID_PARAMETER) {
|
||||
std::cerr << "Expected ROCJPEG_STATUS_INVALID_PARAMETER but got " << rocJpegGetErrorName(rocjpeg_status) << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
int RocJpegApiNegativeTests::TestInvalidCreate() {
|
||||
std::cout << "info: Executing negative test cases for the rocJpegCreate API" << std::endl;
|
||||
// Scenario 1: Pass nullptr for decoder_handle and decoder_create_info
|
||||
RocJpegStatus rocjpeg_status = rocJpegCreate(ROCJPEG_BACKEND_HARDWARE, 0, nullptr);
|
||||
if (rocjpeg_status != ROCJPEG_STATUS_INVALID_PARAMETER) {
|
||||
std::cerr << "Expected ROCJPEG_STATUS_INVALID_PARAMETER but got " << rocJpegGetErrorName(rocjpeg_status) << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Scenario 2: Pass valid pointer for handle but invalid negative device_id
|
||||
int device_id = -1; // Invalid device ID
|
||||
rocjpeg_status = rocJpegCreate(ROCJPEG_BACKEND_HARDWARE, device_id, &rocjpeg_handle_);
|
||||
if (rocjpeg_status != ROCJPEG_STATUS_EXECUTION_FAILED) {
|
||||
std::cerr << "Expected ROCJPEG_STATUS_EXECUTION_FAILED but got " << rocJpegGetErrorName(rocjpeg_status) << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Scenario 3: Pass valid pointer for handle but invalid device_id
|
||||
device_id = 255; // Invalid device ID
|
||||
rocjpeg_status = rocJpegCreate(ROCJPEG_BACKEND_HARDWARE, device_id, &rocjpeg_handle_);
|
||||
if (rocjpeg_status != ROCJPEG_STATUS_INVALID_PARAMETER) {
|
||||
std::cerr << "Expected ROCJPEG_STATUS_INVALID_PARAMETER but got " << rocJpegGetErrorName(rocjpeg_status) << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Scenario 4: Pass valid pointer for handle but unsupported backend
|
||||
device_id = 0;
|
||||
rocjpeg_status = rocJpegCreate(ROCJPEG_BACKEND_HYBRID, device_id, &rocjpeg_handle_);
|
||||
if (rocjpeg_status != ROCJPEG_STATUS_NOT_IMPLEMENTED) {
|
||||
std::cerr << "Expected ROCJPEG_STATUS_NOT_IMPLEMENTED but got " << rocJpegGetErrorName(rocjpeg_status) << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Scenario 5: Use an unsupported backend
|
||||
RocJpegBackend backend = static_cast<RocJpegBackend>(-1);
|
||||
rocjpeg_status = rocJpegCreate(backend, device_id, &rocjpeg_handle_);
|
||||
if (rocjpeg_status != ROCJPEG_STATUS_INVALID_PARAMETER) {
|
||||
std::cerr << "Expected ROCJPEG_STATUS_INVALID_PARAMETER but got " << rocJpegGetErrorName(rocjpeg_status) << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Create a valid rocJPEG handle - This step ensures a valid rocjpeg_handle_ is available for subsequent negative testing of other rocJPEG APIs.
|
||||
rocjpeg_status = rocJpegCreate(ROCJPEG_BACKEND_HARDWARE, device_id, &rocjpeg_handle_);
|
||||
if (rocjpeg_status != ROCJPEG_STATUS_SUCCESS) {
|
||||
std::cerr << "Expected ROCJPEG_STATUS_SUCCESS but got " << rocJpegGetErrorName(rocjpeg_status) << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
int RocJpegApiNegativeTests::TestInvalidDestroy() {
|
||||
std::cout << "info: Executing negative test cases for the rocJpegDestroy API" << std::endl;
|
||||
//Scenario 1: Pass nullptr for decoder_handle
|
||||
RocJpegStatus rocjpeg_status = rocJpegDestroy(nullptr);
|
||||
if (rocjpeg_status != ROCJPEG_STATUS_INVALID_PARAMETER) {
|
||||
std::cerr << "Expected ROCJPEG_STATUS_INVALID_PARAMETER but got " << rocJpegGetErrorName(rocjpeg_status) << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
int RocJpegApiNegativeTests::TestInvalidGetImageInfo() {
|
||||
std::cout << "info: Executing negative test cases for the rocJpegGetImageInfo API" << std::endl;
|
||||
// Scenario 1: Pass nullptr for all parameters
|
||||
RocJpegStatus rocjpeg_status = rocJpegGetImageInfo(rocjpeg_handle_, nullptr, nullptr, nullptr, nullptr, nullptr);
|
||||
if (rocjpeg_status != ROCJPEG_STATUS_INVALID_PARAMETER) {
|
||||
std::cerr << "Expected ROCJPEG_STATUS_INVALID_PARAMETER but got " << rocJpegGetErrorName(rocjpeg_status) << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
int RocJpegApiNegativeTests::TestInvalidDecode() {
|
||||
std::cout << "info: Executing negative test cases for the rocJpegDecode API" << std::endl;
|
||||
// Scenario 1: Pass nullptr for all parameters
|
||||
RocJpegStatus rocjpeg_status = rocJpegDecode(nullptr, nullptr, nullptr, nullptr);
|
||||
if (rocjpeg_status != ROCJPEG_STATUS_INVALID_PARAMETER) {
|
||||
std::cerr << "Expected ROCJPEG_STATUS_INVALID_PARAMETER but got " << rocJpegGetErrorName(rocjpeg_status) << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Scenario 2: Pass valid handle but nullptr for other parameters
|
||||
rocjpeg_status = rocJpegDecode(rocjpeg_handle_, nullptr, nullptr, nullptr);
|
||||
if (rocjpeg_status != ROCJPEG_STATUS_INVALID_PARAMETER) {
|
||||
std::cerr << "Expected ROCJPEG_STATUS_INVALID_PARAMETER but got " << rocJpegGetErrorName(rocjpeg_status) << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Scenario 3: Pass valid handle and stream but nullptr for decode_params and destination
|
||||
rocjpeg_status = rocJpegDecode(rocjpeg_handle_, rocjpeg_stream_handle_, nullptr, nullptr);
|
||||
if (rocjpeg_status != ROCJPEG_STATUS_INVALID_PARAMETER) {
|
||||
std::cerr << "Expected ROCJPEG_STATUS_INVALID_PARAMETER but got " << rocJpegGetErrorName(rocjpeg_status) << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Scenario 4: Pass valid handle, stream, and decode_params but nullptr for destination
|
||||
RocJpegDecodeParams decode_params = {}; // Assume this is initialized with valid data
|
||||
rocjpeg_status = rocJpegDecode(rocjpeg_handle_, rocjpeg_stream_handle_, &decode_params, nullptr);
|
||||
if (rocjpeg_status != ROCJPEG_STATUS_INVALID_PARAMETER) {
|
||||
std::cerr << "Expected ROCJPEG_STATUS_INVALID_PARAMETER but got " << rocJpegGetErrorName(rocjpeg_status) << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
int RocJpegApiNegativeTests::TestInvalidDecodeBatched() {
|
||||
std::cout << "info: Executing negative test cases for the rocJpegDecodeBatched API" << std::endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
int RocJpegApiNegativeTests::TestInvalidGetErrorName() {
|
||||
std::cout << "info: Executing negative test cases for the rocJpegGetErrorName API" << std::endl;
|
||||
// Scenario 1: Pass an invalid error code
|
||||
RocJpegStatus invalid_status = static_cast<RocJpegStatus>(-999); // Invalid error code
|
||||
const char *error_name = rocJpegGetErrorName(invalid_status);
|
||||
if (error_name == nullptr) {
|
||||
std::cerr << "Expected a valid error but got nullptr" << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Scenario 2: Pass a valid error code and ensure it returns a non-null name
|
||||
for (int i = 0; i >= -8; i--) {
|
||||
RocJpegStatus valid_status = static_cast<RocJpegStatus>(i);;
|
||||
error_name = rocJpegGetErrorName(valid_status);
|
||||
if (error_name == nullptr) {
|
||||
std::cerr << "Expected a valid error but got nullptr" << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
// Scenario 3: Pass a boundary value (e.g., maximum enum value + 1)
|
||||
RocJpegStatus boundary_status = static_cast<RocJpegStatus>(ROCJPEG_STATUS_SUCCESS + 1);
|
||||
error_name = rocJpegGetErrorName(boundary_status);
|
||||
if (error_name == nullptr) {
|
||||
std::cerr << "Expected a valid error but got nullptr" << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
int RocJpegApiNegativeTests::RunTests() {
|
||||
if (TestInvalidStreamCreate() || TestInvalidStreamParse () || TestInvalidStreamDestroy() || TestInvalidCreate() || TestInvalidDestroy() ||
|
||||
TestInvalidGetImageInfo() || TestInvalidDecode() || TestInvalidDecodeBatched() || TestInvalidGetErrorName()) {
|
||||
std::cerr << "One or more negative tests failed." << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
Copyright (c) 2024 - 2025 Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
#ifndef ROCJPEG_API_NEGATIVE_TESTS_H
|
||||
#define ROCJPEG_API_NEGATIVE_TESTS_H
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <rocjpeg/rocjpeg.h>
|
||||
|
||||
/**
|
||||
* @class RocJpegApiNegativeTests
|
||||
* @brief A class to perform negative API tests for the rocJPEG library.
|
||||
*
|
||||
* This class contains a set of test cases designed to validate the behavior
|
||||
* of the rocJPEG library when invalid or unexpected inputs are provided.
|
||||
* It ensures the robustness and error handling capabilities of the library.
|
||||
*/
|
||||
class RocJpegApiNegativeTests {
|
||||
public:
|
||||
RocJpegApiNegativeTests();
|
||||
~RocJpegApiNegativeTests();
|
||||
int RunTests();
|
||||
private:
|
||||
int TestInvalidStreamCreate();
|
||||
int TestInvalidStreamParse();
|
||||
int TestInvalidStreamDestroy();
|
||||
int TestInvalidCreate();
|
||||
int TestInvalidDestroy();
|
||||
int TestInvalidGetImageInfo();
|
||||
int TestInvalidDecode();
|
||||
int TestInvalidDecodeBatched();
|
||||
int TestInvalidGetErrorName();
|
||||
RocJpegHandle rocjpeg_handle_;
|
||||
RocJpegStreamHandle rocjpeg_stream_handle_;
|
||||
};
|
||||
|
||||
#endif // ROCJPEG_API_NEGATIVE_TESTS_H
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
Copyright (c) 2024 - 2025 Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "rocjpeg_api_negative_tests.h"
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
RocJpegApiNegativeTests rocjpeg_negative_test;
|
||||
if (rocjpeg_negative_test.RunTests()) {
|
||||
std::cout << "Test Failed!" << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
std::cout << "Test Passed!" << std::endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
Ссылка в новой задаче
Block a user