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
Этот коммит содержится в:
Aryan Salmanpour
2025-04-18 13:02:12 -04:00
коммит произвёл GitHub
родитель 37efebb5a7
Коммит 232a9c6906
8 изменённых файлов: 584 добавлений и 1 удалений
+1
Просмотреть файл
@@ -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}")
+2
Просмотреть файл
@@ -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;
}
+12 -1
Просмотреть файл
@@ -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"
)
+93
Просмотреть файл
@@ -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()
+22
Просмотреть файл
@@ -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
```
+365
Просмотреть файл
@@ -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;
}
}
+56
Просмотреть файл
@@ -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
+33
Просмотреть файл
@@ -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;
}