Add optional output file for qrenderdoc unit tests

This commit is contained in:
baldurk
2020-06-11 17:09:16 +01:00
parent d1f4a47cd5
commit 36d74b32b9
6 changed files with 47 additions and 31 deletions
@@ -69,8 +69,8 @@ PyTypeObject **SbkPySide2_QtWidgetsTypes = NULL;
#include "version.h"
// exported by generated files, used to check interface compliance
bool CheckCoreInterface();
bool CheckQtInterface();
bool CheckCoreInterface(rdcstr &log);
bool CheckQtInterface(rdcstr &log);
// defined in SWIG-generated renderdoc_python.cpp
extern "C" PyObject *PyInit_renderdoc(void);
@@ -457,13 +457,13 @@ PythonContext::~PythonContext()
outputTick();
}
bool PythonContext::CheckInterfaces()
bool PythonContext::CheckInterfaces(rdcstr &log)
{
bool errors = false;
PyGILState_STATE gil = PyGILState_Ensure();
errors |= CheckCoreInterface();
errors |= CheckQtInterface();
errors |= CheckCoreInterface(log);
errors |= CheckQtInterface(log);
PyGILState_Release(gil);
return errors;
+1 -1
View File
@@ -61,7 +61,7 @@ public:
rdcarray<rdcpair<rdcstr, PyObject *>> &args);
static void FreePyArgs(rdcarray<rdcpair<rdcstr, PyObject *>> &args);
bool CheckInterfaces();
bool CheckInterfaces(rdcstr &log);
QString versionString();
+16 -15
View File
@@ -43,7 +43,7 @@ enum class NameType
Member,
};
inline bool checkname(const char *baseType, rdcstr name, NameType nameType)
inline bool checkname(rdcstr &log, const char *baseType, rdcstr name, NameType nameType)
{
// skip __ prefixed names
if(name.beginsWith("__"))
@@ -106,9 +106,9 @@ inline bool checkname(const char *baseType, rdcstr name, NameType nameType)
snprintf(convert_error, sizeof(convert_error) - 1,
"Name of %s '%s.%s' does not match naming scheme.\n"
"Should start with %s letter and not contain underscores",
"Should start with %s letter and not contain underscores\n",
nameTypeStr, baseType, name.c_str(), member ? "lowercase" : "uppercase");
RENDERDOC_LogMessage(LogType::Error, "QTRD", __FILE__, __LINE__, convert_error);
log += convert_error;
return true;
}
@@ -116,7 +116,7 @@ inline bool checkname(const char *baseType, rdcstr name, NameType nameType)
return false;
}
inline bool check_interface(swig_type_info **swig_types, size_t numTypes)
inline bool check_interface(rdcstr &log, swig_type_info **swig_types, size_t numTypes)
{
// track all errors and fatal error at the end, so we see all of the problems at once instead of
// requiring rebuilds over and over.
@@ -142,13 +142,13 @@ inline bool check_interface(swig_type_info **swig_types, size_t numTypes)
if(!result.second)
{
snprintf(convert_error, sizeof(convert_error) - 1,
"Duplicate docstring '%s' found on struct '%s' - are you missing a DOCUMENT()?",
"Duplicate docstring '%s' found on struct '%s' - are you missing a DOCUMENT()?\n",
typedoc.c_str(), typeobj->tp_name);
RENDERDOC_LogMessage(LogType::Error, "QTRD", __FILE__, __LINE__, convert_error);
log += convert_error;
errors_found = true;
}
errors_found |= checkname("renderdoc", typeobj->tp_name, NameType::Type);
errors_found |= checkname(log, "renderdoc", typeobj->tp_name, NameType::Type);
PyObject *dict = typeobj->tp_dict;
@@ -179,8 +179,9 @@ inline bool check_interface(swig_type_info **swig_types, size_t numTypes)
if(str == NULL || len == 0)
{
snprintf(convert_error, sizeof(convert_error) - 1,
"Couldn't get member name for %i'th member of '%s'", (int)i, typeobj->tp_name);
RENDERDOC_LogMessage(LogType::Error, "QTRD", __FILE__, __LINE__, convert_error);
"Couldn't get member name for %i'th member of '%s'\n", (int)i,
typeobj->tp_name);
log += convert_error;
errors_found = true;
}
else
@@ -198,7 +199,7 @@ inline bool check_interface(swig_type_info **swig_types, size_t numTypes)
// if it's a callable it's a method, ignore it
if(!PyCallable_Check(value) && !PyType_IsSubtype(value->ob_type, &PyStaticMethod_Type))
errors_found |= checkname(typeobj->tp_name, name, nameType);
errors_found |= checkname(log, typeobj->tp_name, name, nameType);
}
Py_DecRef(bytes);
@@ -241,9 +242,9 @@ inline bool check_interface(swig_type_info **swig_types, size_t numTypes)
if(documented.find(*it) == documented.end())
{
snprintf(convert_error, sizeof(convert_error) - 1,
"'%s::%s' is not documented in class docstring", typeobj->tp_name,
"'%s::%s' is not documented in class docstring\n", typeobj->tp_name,
it->c_str());
RENDERDOC_LogMessage(LogType::Error, "QTRD", __FILE__, __LINE__, convert_error);
log += convert_error;
errors_found = true;
}
}
@@ -257,7 +258,7 @@ inline bool check_interface(swig_type_info **swig_types, size_t numTypes)
{
rdcstr method_doc = method->ml_doc;
errors_found |= checkname(typeobj->tp_name, method->ml_name, NameType::Method);
errors_found |= checkname(log, typeobj->tp_name, method->ml_name, NameType::Method);
int32_t i = 0;
while(method_doc[i] == '\n')
@@ -278,9 +279,9 @@ inline bool check_interface(swig_type_info **swig_types, size_t numTypes)
{
snprintf(
convert_error, sizeof(convert_error) - 1,
"Duplicate docstring '%s' found on method '%s.%s' - are you missing a DOCUMENT()?",
"Duplicate docstring '%s' found on method '%s.%s' - are you missing a DOCUMENT()?\n",
method_doc.c_str(), typeobj->tp_name, method->ml_name);
RENDERDOC_LogMessage(LogType::Error, "QTRD", __FILE__, __LINE__, convert_error);
log += convert_error;
errors_found = true;
}
}
+2 -2
View File
@@ -120,7 +120,7 @@ TEMPLATE_ARRAY_INSTANTIATE_PTR(rdcarray, ICaptureViewer)
static swig_type_info **interfaceCheckTypes;
static size_t interfaceCheckNumTypes = 0;
bool CheckQtInterface()
bool CheckQtInterface(rdcstr &log)
{
#if defined(RELEASE)
return false;
@@ -128,7 +128,7 @@ TEMPLATE_ARRAY_INSTANTIATE_PTR(rdcarray, ICaptureViewer)
if(interfaceCheckNumTypes == 0)
return false;
return check_interface(interfaceCheckTypes, interfaceCheckNumTypes);
return check_interface(log, interfaceCheckTypes, interfaceCheckNumTypes);
#endif
}
%}
+2 -2
View File
@@ -489,7 +489,7 @@ extern "C" PyObject *RENDERDOC_DumpObject(PyObject *obj)
static swig_type_info **interfaceCheckTypes;
static size_t interfaceCheckNumTypes = 0;
bool CheckCoreInterface()
bool CheckCoreInterface(rdcstr &log)
{
#if defined(RELEASE)
return false;
@@ -497,7 +497,7 @@ extern "C" PyObject *RENDERDOC_DumpObject(PyObject *obj)
if(interfaceCheckNumTypes == 0)
return false;
return check_interface(interfaceCheckTypes, interfaceCheckNumTypes);
return check_interface(log, interfaceCheckTypes, interfaceCheckNumTypes);
#endif
}
%}
+21 -6
View File
@@ -22,6 +22,7 @@
* THE SOFTWARE.
******************************************************************************/
#include <stdio.h>
#include <QApplication>
#include <QCommandLineParser>
#include <QDir>
@@ -104,21 +105,35 @@ int main(int argc, char *argv[])
bool errors = false;
qInfo() << "Checking python binding consistency.";
FILE *logOut = NULL;
if(argc >= 3)
logOut = fopen(argv[2], "w");
if(logOut == NULL)
logOut = stdout;
fputs("Checking python binding consistency.\n", logOut);
rdcstr errorLog;
{
PythonContextHandle py;
errors = py.ctx().CheckInterfaces();
errors = py.ctx().CheckInterfaces(errorLog);
}
if(errors)
{
qCritical() << "Found errors in python bindings. Please fix!";
RENDERDOC_LogMessage(LogType::Error, "EXTN", __FILE__, __LINE__, errorLog.c_str());
fputs("Found errors in python bindings. Please fix!\n", logOut);
fputs(errorLog.c_str(), logOut);
return 1;
}
qInfo() << "Python bindings are consistent.";
return 0;
else
{
fputs("Python bindings are consistent.\n", logOut);
return 0;
}
}
#endif