chore: remove Qt and SDL2 from radio unit tests (#6452)

This commit is contained in:
Raphael Coeffic
2025-07-24 08:05:18 +10:00
committed by GitHub
parent 9e86a3ea84
commit 538721ef6b
17 changed files with 226 additions and 200 deletions
-1
View File
@@ -46,7 +46,6 @@ endif()
# Windows-specific includes and libs shared by sub-projects
if(WIN32)
list(APPEND WIN_INCLUDE_DIRS "${RADIO_SRC_DIR}/thirdparty/windows/dirent")
# TODO: is that still necessary?
set(CMAKE_C_USE_RESPONSE_FILE_FOR_INCLUDES OFF)
set(CMAKE_C_USE_RESPONSE_FILE_FOR_LIBRARIES OFF)
+1 -3
View File
@@ -60,7 +60,6 @@ if(WARNINGS_AS_ERRORS)
endif()
if(WIN32)
include_directories(SYSTEM ${WIN_INCLUDE_DIRS})
if(NOT WIN_USE_CONSOLE)
set(WIN_EXECUTABLE_TYPE WIN32) # GUI (WinMain) app
endif()
@@ -187,8 +186,7 @@ target_link_libraries(common
Qt::Widgets
Qt::SerialPort
${SDL2_LIBRARIES}
${WIN_LINK_LIBRARIES}
)
)
set(CPN_COMMON_LIB common)
-5
View File
@@ -14,11 +14,6 @@ if(Qt6Widgets_FOUND)
include_directories(${CMAKE_CURRENT_BINARY_DIR})
if(WIN32)
target_include_directories(gtests-companion-lib PUBLIC ${WIN_INCLUDE_DIRS})
target_link_libraries(gtests-companion-lib PRIVATE ${WIN_LINK_LIBRARIES})
endif(WIN32)
file(GLOB TEST_SRC_FILES ${TESTS_PATH}/*.cpp)
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0")
-4
View File
@@ -35,10 +35,6 @@
#include "model_audio.h"
#include "hal/audio_driver.h"
#if defined(SIMU) && !defined(SIMU_AUDIO)
void audioConsumeCurrentBuffer() {}
#endif
extern mutex_handle_t audioMutex;
// Only first quadrant values - other quadrants calulated taking advantage of symmetry in sine wave.
+13 -17
View File
@@ -5,13 +5,12 @@ if(NOT SIMU_TARGET)
return()
endif()
target_compile_options(radiolib_native PUBLIC -DSIMU)
set(SIMU_DRIVERS
simpgmspace.cpp
simufatfs.cpp
simudisk.cpp
simulcd.cpp
audio_driver.cpp
switch_driver.cpp
adc_driver.cpp
module_drivers.cpp
@@ -40,7 +39,6 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR})
if(SDL2_FOUND)
include_directories(${SDL2_INCLUDE_DIRS})
target_compile_options(radiolib_native PUBLIC -DSIMU_AUDIO)
list(APPEND SIMU_DRIVERS simuaudio.cpp)
if(TARGET SDL2::SDL2)
set(SDL2_LIBRARIES SDL2::SDL2)
endif()
@@ -97,20 +95,24 @@ if(Qt6Widgets_FOUND)
qt_wrap_cpp(SIMULATOR_SRC
${COMPANION_SRC_DIRECTORY}/simulation/simulatorinterface.h
opentxsimulator.h
)
)
list(APPEND SIMULATOR_SRC ${SIMU_SRC} opentxsimulator.cpp)
add_library(${SIMULATOR_TARGET} SHARED ${SIMULATOR_SRC})
if(SDL2_FOUND)
target_sources(${SIMULATOR_TARGET} PRIVATE simuaudio.cpp)
else()
target_sources(${SIMULATOR_TARGET} PRIVATE no_audio.cpp)
endif()
target_compile_options(${SIMULATOR_TARGET} PRIVATE ${SIMU_SRC_OPTIONS})
target_compile_definitions(${SIMULATOR_TARGET} PUBLIC ${APP_COMMON_DEFINES})
target_link_libraries(${SIMULATOR_TARGET} ${SDL2_LIBRARIES} Qt::Core Qt::SerialPort)
# Remove debug symbols on release builds
if(NOT CLANG)
if("${CMAKE_BUILD_TYPE}" STREQUAL "Release")
add_custom_command(TARGET ${SIMULATOR_TARGET} POST_BUILD
COMMAND ${CMAKE_STRIP} $<TARGET_FILE:${SIMULATOR_TARGET}>)
endif()
if("${CMAKE_BUILD_TYPE}" STREQUAL "Release")
add_custom_command(TARGET ${SIMULATOR_TARGET} POST_BUILD
COMMAND ${CMAKE_STRIP} -x $<TARGET_FILE:${SIMULATOR_TARGET}>)
endif()
add_custom_command(
@@ -118,7 +120,7 @@ if(Qt6Widgets_FOUND)
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/plugins/
COMMAND ${CMAKE_COMMAND} -E copy
$<TARGET_FILE:${SIMULATOR_TARGET}> ${CMAKE_BINARY_DIR}/plugins/
)
)
# Introduced at 2.5 - TODO replace with a code change
# When compiled shared simulators using libopenui and Companion have classes named MainWindow
@@ -152,13 +154,6 @@ if(Qt6Widgets_FOUND)
add_custom_target(all-simu-libs COMMAND ${all_libs_cmd} USES_TERMINAL WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
endif()
if(WIN32)
include_directories(SYSTEM ${WIN_INCLUDE_DIRS})
if(Qt6Widgets_FOUND)
target_link_libraries(${SIMULATOR_TARGET} PRIVATE ${WIN_LINK_LIBRARIES})
endif()
endif(WIN32)
if(MINGW)
# struct packing breaks on MinGW w/out -mno-ms-bitfields: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52991 & http://stackoverflow.com/questions/24015852/struct-packing-and-alignment-with-mingw
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mno-ms-bitfields")
@@ -178,6 +173,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNING_FLAGS}")
add_executable(simu
EXCLUDE_FROM_ALL
${SIMU_SRC}
simuaudio.cpp
display.cpp
widgets.cpp
knobs.cpp
+57
View File
@@ -0,0 +1,57 @@
/*
* Copyright (C) EdgeTX
*
* Based on code named
* opentx - https://github.com/opentx/opentx
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "audio.h"
#include "simuaudio.h"
#if !defined(SOFTWARE_VOLUME)
static int _simu_volume = 0;
void audioSetVolume(uint8_t volume)
{
_simu_volume = volume;
}
#endif
int simuAudioGetVolume()
{
#if !defined(SOFTWARE_VOLUME)
return _simu_volume;
#else
return VOLUME_LEVEL_MAX;
#endif
}
void simuQueueAudio(const uint8_t* data, uint32_t len);
void audioConsumeCurrentBuffer()
{
auto& fifo = audioQueue.buffersFifo;
while(true) {
auto nextBuffer = fifo.getNextFilledBuffer();
if (!nextBuffer) return;
auto data = (const uint8_t*)nextBuffer->data;
uint32_t len = nextBuffer->size * sizeof(audio_data_t);
simuQueueAudio(data, len);
fifo.freeNextFilledBuffer();
}
}
+26
View File
@@ -0,0 +1,26 @@
/*
* Copyright (C) EdgeTX
*
* Based on code named
* opentx - https://github.com/opentx/opentx
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "simuaudio.h"
bool simuAudioInit() { return false; }
void simuAudioDeInit() {}
void simuQueueAudio(const uint8_t*, uint32_t) {}
-4
View File
@@ -22,10 +22,6 @@
#include "board.h"
#define SIMPGMSPC_USE_QT 0
#if defined(SIMU_AUDIO)
#include <SDL.h>
#endif
#include "edgetx.h"
#include "simulcd.h"
-8
View File
@@ -48,14 +48,6 @@ void simuStop();
bool simuIsRunning();
void startEepromThread(const char * filename = "eeprom.bin");
void stopEepromThread();
#if defined(SIMU_AUDIO)
int startAudio(int volumeGain = 10);
void stopAudio();
#else
#define startAudio(dummy) (-1)
#define stopAudio()
#endif
#endif
void simuMain();
+5 -39
View File
@@ -29,48 +29,14 @@
static SDL_AudioDeviceID _sdl_audio_device = 0;
void simuQueueAudio(const uint8_t* data, uint32_t len)
{
#if !defined(SOFTWARE_VOLUME)
static Uint8 _tmp_buf[AUDIO_BUFFER_SIZE * sizeof(audio_data_t)];
static int _simu_volume = 0;
void audioSetVolume(uint8_t volume)
{
_simu_volume = SDL_MIX_MAXVOLUME * volume / VOLUME_LEVEL_MAX;
}
static void _fill_with_silence(Uint8* dst, uint32_t len)
{
auto p = (audio_data_t*)dst;
auto end = p + len / sizeof(audio_data_t);
while (p < end) {
*p++ = AUDIO_DATA_SILENCE;
}
}
int volume = (simuAudioGetVolume() * SDL_MIX_MAXVOLUME ) / VOLUME_LEVEL_MAX;
SDL_MixAudioFormat((uint8_t*)data, data, SIMU_AUDIO_FMT, len, volume);
#endif
void audioConsumeCurrentBuffer()
{
while(true) {
auto nextBuffer = audioQueue.buffersFifo.getNextFilledBuffer();
if (!nextBuffer) return;
auto data = (const Uint8*)nextBuffer->data;
uint32_t len = nextBuffer->size * sizeof(audio_data_t);
#if !defined(SOFTWARE_VOLUME)
assert(len <= sizeof(_tmp_buf));
_fill_with_silence(_tmp_buf, len);
SDL_MixAudioFormat(_tmp_buf, data, SIMU_AUDIO_FMT, len, _simu_volume);
data = _tmp_buf;
#endif
SDL_QueueAudio(_sdl_audio_device, data, len);
audioQueue.buffersFifo.freeNextFilledBuffer();
}
SDL_QueueAudio(_sdl_audio_device, data, len);
}
bool simuAudioInit()
+4 -5
View File
@@ -21,10 +21,9 @@
#pragma once
#if defined(SIMU_AUDIO)
#include <stdint.h>
bool simuAudioInit();
void simuAudioDeInit();
#else
static inline bool simuAudioInit() { return false; }
static inline void simuAudioDeInit() {}
#endif
void simuQueueAudio(const uint8_t* data, uint32_t len);
int simuAudioGetVolume();
+24 -42
View File
@@ -1,49 +1,31 @@
if(Qt6Widgets_FOUND)
add_library(gtests-radio-lib STATIC EXCLUDE_FROM_ALL
${googletest_SOURCE_DIR}/googletest/src/gtest-all.cc
)
target_include_directories(gtests-radio-lib PRIVATE
${googletest_SOURCE_DIR}/googletest
)
add_library(gtests-radio-lib STATIC EXCLUDE_FROM_ALL
${googletest_SOURCE_DIR}/googletest/src/gtest-all.cc
)
target_include_directories(gtests-radio-lib PRIVATE
${googletest_SOURCE_DIR}/googletest
)
set(TESTS_PATH ${RADIO_SRC_DIR}/tests)
set(TESTS_BUILD_PATH ${CMAKE_CURRENT_BINARY_DIR})
configure_file(${RADIO_SRC_DIR}/tests/location.h.in ${CMAKE_CURRENT_BINARY_DIR}/location.h @ONLY)
include_directories(${CMAKE_CURRENT_BINARY_DIR})
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS_DEBUG} -O0 -fsanitize=address")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_DEBUG} -O0 ${WARNING_FLAGS} -fsanitize=address")
set(TESTS_PATH ${RADIO_SRC_DIR}/tests)
set(TESTS_BUILD_PATH ${CMAKE_CURRENT_BINARY_DIR})
configure_file(${RADIO_SRC_DIR}/tests/location.h.in ${CMAKE_CURRENT_BINARY_DIR}/location.h @ONLY)
include_directories(${CMAKE_CURRENT_BINARY_DIR})
if(WIN32)
target_include_directories(gtests-radio-lib PUBLIC ${WIN_INCLUDE_DIRS})
target_link_libraries(gtests-radio-lib PRIVATE ${WIN_LINK_LIBRARIES})
endif(WIN32)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS_DEBUG} -O0 -fsanitize=address")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_DEBUG} -O0 ${WARNING_FLAGS} -fsanitize=address")
if(SDL2_FOUND)
target_include_directories(gtests-radio-lib PUBLIC ${SDL2_INCLUDE_DIR})
target_link_libraries(gtests-radio-lib PRIVATE ${SDL2_LIBRARIES})
endif()
file(GLOB TEST_SRC_FILES ${RADIO_SRC_DIR}/tests/*.cpp
CONFIGURE_DEPENDS "${RADIO_SRC_DIR}/tests/*.cpp")
set(TEST_SRC_FILES ${TEST_SRC_FILES}
${CMAKE_CURRENT_SOURCE_DIR}/location.h
${SIMU_SRC}
)
file(GLOB TEST_SRC_FILES ${RADIO_SRC_DIR}/tests/*.cpp
CONFIGURE_DEPENDS "${RADIO_SRC_DIR}/tests/*.cpp")
add_executable(gtests-radio EXCLUDE_FROM_ALL
${TEST_SRC_FILES}
)
target_compile_options(gtests-radio PRIVATE ${SIMU_SRC_OPTIONS})
set(TEST_SRC_FILES ${TEST_SRC_FILES}
${CMAKE_CURRENT_SOURCE_DIR}/location.h
${SIMU_SRC}
)
if(MINGW)
# struct packing breaks on MinGW w/out -mno-ms-bitfields: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52991 & http://stackoverflow.com/questions/24015852/struct-packing-and-alignment-with-mingw
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mno-ms-bitfields")
endif()
add_executable(gtests-radio EXCLUDE_FROM_ALL
${TEST_SRC_FILES}
)
target_compile_options(gtests-radio PRIVATE ${SIMU_SRC_OPTIONS})
add_dependencies(gtests-radio gtests-radio-lib)
target_link_libraries(gtests-radio gtests-radio-lib Qt::Core Qt::Widgets)
message(STATUS "Added optional gtests target")
endif()
target_link_libraries(gtests-radio gtests-radio-lib)
message(STATUS "Added optional gtests target")
+2 -2
View File
@@ -19,7 +19,6 @@
* GNU General Public License for more details.
*/
#include <QApplication>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@@ -128,6 +127,8 @@ uint16_t simu_get_analog(uint8_t idx)
return 0;
}
void simuQueueAudio(const uint8_t*, uint32_t) {}
static char _stringResult[200];
const char * nchar2string(const char * string, int size)
@@ -144,7 +145,6 @@ extern const etx_hal_adc_driver_t simu_adc_driver;
int main(int argc, char **argv)
{
QCoreApplication app(argc, argv);
simuInit();
adcInit(&simu_adc_driver);
-2
View File
@@ -21,11 +21,9 @@
#pragma once
#include <QtCore/QString>
#include <math.h>
#include <gtest/gtest.h>
#define SWAP_DEFINED
#include "edgetx.h"
#include "model_init.h"
#include "switches.h"
+88 -61
View File
@@ -20,84 +20,111 @@
*/
/* -*- coding: utf-8 -*- */
#include <QtCore/QDir>
#include <QtCore/QDebug>
#include <QApplication>
#include <QPainter>
#include <math.h>
#include <assert.h>
#include <gtest/gtest.h>
#define SWAP_DEFINED
#include "edgetx.h"
#include "location.h"
#include "targets/simu/simulcd.h"
void doPaint(QPainter & p)
#if !defined(COLORLCD)
#define STB_IMAGE_IMPLEMENTATION
#include "stb/stb_image.h"
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb/stb_image_write.h"
#if LCD_W < 212
#define BPP 1
#else
#define BPP 4
#endif
static uint8_t _get_pixel(int x, int y)
{
QRgb rgb = qRgb(161, 161, 161);
assert(x < LCD_W && y < LCD_H);
p.setBackground(QBrush(rgb));
p.eraseRect(0, 0, LCD_W, LCD_H);
if (BPP == 1) {
if (simuLcdBuf[x + (y / 8) * LCD_W] & (1 << (y % 8))) {
return 0; // TODO
}
return 161;
}
if (1) {
#if LCD_W < 212
rgb = qRgb(0, 0, 0);
p.setPen(rgb);
p.setBrush(QBrush(rgb));
#endif
if (BPP == 4) {
pixel_t p = simuLcdBuf[y / 2 * LCD_W + x];
uint8_t z = (y & 1) ? (p >> 4) : (p & 0x0F);
return 161 - ((uint16_t)z * 161) / 15; // TODO
}
}
#if LCD_W >= 212
unsigned int previousDepth = 0xFF;
#endif
static uint8_t _get_ref_pixel(const uint8_t* data, int x, int y, int bpp)
{
return data[(y * LCD_W + x) * bpp];
}
for (int y=0; y<LCD_H; y++) {
#if LCD_W >= 212
unsigned int idx = (y/2) * LCD_W;
#else
unsigned int idx = (y/8) * LCD_W;
unsigned int mask = (1 << (y%8));
#endif
for (int x=0; x<LCD_W; x++, idx++) {
#if LCD_W < 212
if (simuLcdBuf[idx] & mask) {
p.drawPoint(x, y);
}
#else
unsigned int z = (y & 1) ? (simuLcdBuf[idx] >> 4) : (simuLcdBuf[idx] & 0x0F);
if (z) {
if (z != previousDepth) {
previousDepth = z;
rgb = qRgb(161-(z*161)/15, 161-(z*161)/15, 161-(z*161)/15);
p.setPen(rgb);
p.setBrush(QBrush(rgb));
}
p.drawPoint(x, y);
}
#endif
static void dumpImage(const std::string& filename)
{
std::string fullpath = TESTS_PATH "/images/color/failed_" + filename;
TRACE("dumping image '%s'", fullpath.c_str());
// allocate enough for 3 channels
std::vector<uint8_t> img;
auto stride = LCD_W * 3;
auto pixel_bytes = stride * LCD_H;
img.resize(pixel_bytes);
for (int y = 0; y < LCD_H; y++) {
for (int x = 0; x < LCD_W; x++) {
auto p = _get_pixel(x, y);
auto offset = (y * LCD_W + x) * 3;
img[offset + 0] = p;
img[offset + 1] = p;
img[offset + 2] = p;
}
}
stbi_write_png(fullpath.c_str(), LCD_W, LCD_H, 3, img.data(), stride);
}
bool checkScreenshot(const char* test)
{
lcdRefresh();
std::string filename = std::string(test);
filename += '_' + std::to_string(LCD_W);
filename += 'x' + std::to_string(LCD_H);
filename += ".png";
std::string fullpath = TESTS_PATH "/images/bw/" + filename;
// Read data
int32_t w, h, bpp;
std::shared_ptr<uint8_t> ref_data = {
stbi_load(fullpath.c_str(), &w, &h, &bpp, 0), stbi_image_free};
if (!ref_data || w != LCD_W || h != LCD_H) {
dumpImage(filename);
return false;
}
for (int y = 0; y < LCD_H; y++) {
for (int x = 0; x < LCD_W; x++) {
auto p = _get_pixel(x, y);
auto ref_p = _get_ref_pixel(ref_data.get(), x, y, bpp);
if (p != ref_p) {
dumpImage(filename);
return false;
}
}
}
return true;
}
bool checkScreenshot(const QString & test)
{
lcdRefresh();
QImage buffer(LCD_W, LCD_H, QImage::Format_RGB32);
QPainter p(&buffer);
doPaint(p);
QString filename(QString("%1_%2x%3.png").arg(test).arg(LCD_W).arg(LCD_H));
QImage reference(TESTS_PATH "/images/bw/" + filename);
if (buffer == reference) {
return true;
}
else {
buffer.save(TESTS_PATH "/images/bw/failed_" + filename);
return false;
}
}
#if !defined(COLORLCD)
TEST(outdezNAtt, test_unsigned)
{
lcdClear();
+6 -6
View File
@@ -22,7 +22,6 @@
#include <gtest/gtest.h>
#include <math.h>
#define SWAP_DEFINED
#include "location.h"
#include "edgetx.h"
@@ -53,12 +52,13 @@ void dumpImage(const std::string& filename, const BitmapBuffer* dc)
TRACE("dumping image '%s'", fullpath.c_str());
// allocate enough for 3 channels
auto pixels = dc->width() * dc->height();
std::vector<uint8_t> img;
auto stride = dc->width() * 3;
uint8_t* img = (uint8_t*)malloc(pixels * 3);
convert_RGB565_to_RGB888(img, dc, dc->width(), dc->height());
stbi_write_png(fullpath.c_str(), dc->width(), dc->height(), 3, img, stride);
free(img);
auto pixel_bytes = stride * dc->height();
img.resize(pixel_bytes);
convert_RGB565_to_RGB888(img.data(), dc, dc->width(), dc->height());
stbi_write_png(fullpath.c_str(), dc->width(), dc->height(), 3, img.data(), stride);
}
bool checkScreenshot_colorlcd(const BitmapBuffer* dc, const char* test)
-1
View File
@@ -24,7 +24,6 @@
#if defined(LUA)
#define SWAP_DEFINED
#include "edgetx.h"
#include "lua/lua_states.h"