Browse Source

add wscripts for unittests

pull/114/head
nillerusr 2 years ago
parent
commit
9aa0ecab6a
  1. 2
      .github/workflows/build.yml
  2. 37
      unittests/tier0test/tier0test.cpp
  3. 39
      unittests/tier0test/wscript
  4. 6
      unittests/tier1test/commandbuffertest.cpp
  5. 52
      unittests/tier1test/processtest.cpp
  6. 12
      unittests/tier1test/utlstringtest.cpp
  7. 39
      unittests/tier1test/wscript
  8. 39
      unittests/tier2test/wscript
  9. 39
      unittests/tier3test/wscript
  10. 63
      utils/unittest/unittest.cpp
  11. 40
      utils/unittest/wscript
  12. 30
      wscript

2
.github/workflows/build.yml

@ -1,4 +1,4 @@
name: Build tests name: Build
on: on:
push: push:

37
unittests/tier0test/tier0test.cpp

@ -0,0 +1,37 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Unit test program for testing of tier0 libraries
//
// $NoKeywords: $
//=============================================================================//
#include "unitlib/unitlib.h"
#include "appframework/IAppSystem.h"
//-----------------------------------------------------------------------------
// Used to connect/disconnect the DLL
//-----------------------------------------------------------------------------
class CTier0TestAppSystem : public CTier0AppSystem< IAppSystem >
{
typedef CTier0AppSystem< IAppSystem > BaseClass;
public:
virtual bool Connect( CreateInterfaceFn factory )
{
if ( !BaseClass::Connect( factory ) )
return false;
return true;
}
virtual InitReturnVal_t Init()
{
return INIT_OK;
}
virtual void Shutdown()
{
BaseClass::Shutdown();
}
};
USE_UNITTEST_APPSYSTEM( CTier0TestAppSystem )

39
unittests/tier0test/wscript

@ -0,0 +1,39 @@
#! /usr/bin/env python
# encoding: utf-8
from waflib import Utils
import os
top = '.'
PROJECT_NAME = 'tier0test'
def options(opt):
return
def configure(conf):
conf.define('TIER1TEST_EXPORTS', 1)
def build(bld):
source = ['tier0test.cpp']
includes = ['../../public', '../../public/tier0']
defines = []
libs = ['tier0','tier1','unitlib']
if bld.env.DEST_OS != 'win32':
libs += [ 'DL', 'LOG' ]
else:
libs += ['USER32', 'SHELL32']
install_path = bld.env.TESTDIR
bld.shlib(
source = source,
target = PROJECT_NAME,
name = PROJECT_NAME,
features = 'c cxx',
includes = includes,
defines = defines,
use = libs,
install_path = install_path,
subsystem = bld.env.MSVC_SUBSYSTEM,
idx = bld.get_taskgen_count()
)

6
unittests/tier1test/commandbuffertest.cpp

@ -6,7 +6,7 @@
//=============================================================================// //=============================================================================//
#include "unitlib/unitlib.h" #include "unitlib/unitlib.h"
#include "tier1/commandbuffer.h" #include "tier1/CommandBuffer.h"
#include "tier1/strtools.h" #include "tier1/strtools.h"
@ -139,20 +139,24 @@ DEFINE_TESTCASE( CommandBufferTestTiming, CommandBufferTestSuite )
buffer.BeginProcessingCommands( 1 ); buffer.BeginProcessingCommands( 1 );
argc = buffer.DequeueNextCommand( argv ); argc = buffer.DequeueNextCommand( argv );
Shipping_Assert( argc == 3 ); Shipping_Assert( argc == 3 );
Shipping_Assert( !Q_stricmp( argv[0], "test_command" ) ); Shipping_Assert( !Q_stricmp( argv[0], "test_command" ) );
Shipping_Assert( !Q_stricmp( argv[1], "test_arg1" ) ); Shipping_Assert( !Q_stricmp( argv[1], "test_arg1" ) );
Shipping_Assert( !Q_stricmp( argv[2], "test_arg2" ) ); Shipping_Assert( !Q_stricmp( argv[2], "test_arg2" ) );
argc = buffer.DequeueNextCommand( argv ); argc = buffer.DequeueNextCommand( argv );
Shipping_Assert( argc == 1 ); Shipping_Assert( argc == 1 );
Shipping_Assert( !Q_stricmp( argv[0], "test_command3" ) ); Shipping_Assert( !Q_stricmp( argv[0], "test_command3" ) );
argc = buffer.DequeueNextCommand( argv ); argc = buffer.DequeueNextCommand( argv );
Shipping_Assert( argc == 0 ); Shipping_Assert( argc == 0 );
buffer.EndProcessingCommands( ); buffer.EndProcessingCommands( );
} }
{ {
buffer.BeginProcessingCommands( 1 ); buffer.BeginProcessingCommands( 1 );

52
unittests/tier1test/processtest.cpp

@ -1,52 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Unit test program for processes
//
// $NoKeywords: $
//=============================================================================//
#include "unitlib/unitlib.h"
#include "vstdlib/iprocessutils.h"
#include "tier1/strtools.h"
#include "tier1/tier1.h"
#include "tier0/dbg.h"
DEFINE_TESTSUITE( ProcessTestSuite )
DEFINE_TESTCASE( ProcessTestSimple, ProcessTestSuite )
{
Msg( "Simple process test...\n" );
ProcessHandle_t hProcess = g_pProcessUtils->StartProcess( "unittests\\testprocess.exe -delay 1.0", true );
g_pProcessUtils->WaitUntilProcessCompletes( hProcess );
int nLen = g_pProcessUtils->GetProcessOutputSize( hProcess );
char *pBuf = (char*)_alloca( nLen );
g_pProcessUtils->GetProcessOutput( hProcess, pBuf, nLen );
g_pProcessUtils->CloseProcess( hProcess );
Shipping_Assert( !Q_stricmp( pBuf, "Test Finished!\n" ) );
}
DEFINE_TESTCASE( ProcessTestBufferOverflow, ProcessTestSuite )
{
Msg( "Buffer overflow process test...\n" );
ProcessHandle_t hProcess = g_pProcessUtils->StartProcess( "unittests\\testprocess.exe -delay 1.0 -extrabytes 32768", true );
g_pProcessUtils->WaitUntilProcessCompletes( hProcess );
int nLen = g_pProcessUtils->GetProcessOutputSize( hProcess );
Shipping_Assert( nLen == 32768 + 16 );
char *pBuf = (char*)_alloca( nLen );
g_pProcessUtils->GetProcessOutput( hProcess, pBuf, nLen );
g_pProcessUtils->CloseProcess( hProcess );
Shipping_Assert( !Q_strnicmp( pBuf, "Test Finished!\n", 15 ) );
int nEndExtraBytes = 32768;
char *pTest = pBuf + 15;
while( --nEndExtraBytes >= 0 )
{
Shipping_Assert( *pTest == (( nEndExtraBytes % 10 ) + '0') );
++pTest;
}
}

12
unittests/tier1test/utlstringtest.cpp

@ -180,20 +180,20 @@ static void FormatTests()
static void FileNameAPITests() static void FileNameAPITests()
{ {
CUtlString path( "c:\\source2\\game\\source2\\somefile.ext" ); CUtlString path( "/source2/game/source2/somefile.ext" );
CUtlString absPath = path.AbsPath(); CUtlString absPath = path.AbsPath();
Shipping_Assert( absPath == path ); Shipping_Assert( absPath == path );
CUtlString file = path.UnqualifiedFilename(); CUtlString file = path.UnqualifiedFilename();
Shipping_Assert( !V_stricmp( file.Get(), "somefile.ext" ) ); Shipping_Assert( !V_stricmp( file.Get(), "somefile.ext" ) );
CUtlString dir = path.DirName(); CUtlString dir = path.DirName();
Shipping_Assert( !V_stricmp( dir.Get(), "c:\\source2\\game\\source2" ) ); Shipping_Assert( !V_stricmp( dir.Get(), "/source2/game/source2" ) );
dir = dir.DirName(); dir = dir.DirName();
Shipping_Assert( !V_stricmp( dir.Get(), "c:\\source2\\game" ) ); Shipping_Assert( !V_stricmp( dir.Get(), "/source2/game" ) );
CUtlString baseName = path.StripExtension(); CUtlString baseName = path.StripExtension();
Shipping_Assert( !V_stricmp( baseName.Get(), "c:\\source2\\game\\source2\\somefile" ) ); Shipping_Assert( !V_stricmp( baseName.Get(), "/source2/game/source2/somefile" ) );
dir = path.StripFilename(); dir = path.StripFilename();
Shipping_Assert( !V_stricmp( dir.Get(), "c:\\source2\\game\\source2" ) ); Shipping_Assert( !V_stricmp( dir.Get(), "/source2/game/source2" ) );
file = path.GetBaseFilename(); file = path.GetBaseFilename();
Shipping_Assert( !V_stricmp( file.Get(), "somefile" ) ); Shipping_Assert( !V_stricmp( file.Get(), "somefile" ) );
@ -201,7 +201,7 @@ static void FileNameAPITests()
Shipping_Assert( !V_stricmp( ext.Get(), "ext" ) ); Shipping_Assert( !V_stricmp( ext.Get(), "ext" ) );
absPath = path.PathJoin( dir.Get(), file.Get() ); absPath = path.PathJoin( dir.Get(), file.Get() );
Shipping_Assert( !V_stricmp( absPath.Get(), "c:\\source2\\game\\source2\\somefile" ) ); Shipping_Assert( !V_stricmp( absPath.Get(), "/source2/game/source2/somefile" ) );
} }
DEFINE_TESTCASE( UtlStringTest, UtlStringTestSuite ) DEFINE_TESTCASE( UtlStringTest, UtlStringTestSuite )

39
unittests/tier1test/wscript

@ -0,0 +1,39 @@
#! /usr/bin/env python
# encoding: utf-8
from waflib import Utils
import os
top = '.'
PROJECT_NAME = 'tier1test'
def options(opt):
return
def configure(conf):
conf.define('TIER1TEST_EXPORTS', 1)
def build(bld):
source = ['commandbuffertest.cpp', 'utlstringtest.cpp', 'tier1test.cpp']
includes = ['../../public', '../../public/tier0']
defines = []
libs = ['tier0', 'tier1', 'mathlib', 'unitlib']
if bld.env.DEST_OS != 'win32':
libs += [ 'DL', 'LOG' ]
else:
libs += ['USER32', 'SHELL32']
install_path = bld.env.TESTDIR
bld.shlib(
source = source,
target = PROJECT_NAME,
name = PROJECT_NAME,
features = 'c cxx',
includes = includes,
defines = defines,
use = libs,
install_path = install_path,
subsystem = bld.env.MSVC_SUBSYSTEM,
idx = bld.get_taskgen_count()
)

39
unittests/tier2test/wscript

@ -0,0 +1,39 @@
#! /usr/bin/env python
# encoding: utf-8
from waflib import Utils
import os
top = '.'
PROJECT_NAME = 'tier2test'
def options(opt):
return
def configure(conf):
conf.define('TIER2TEST_EXPORTS', 1)
def build(bld):
source = ['tier2test.cpp']
includes = ['../../public', '../../public/tier0']
defines = []
libs = ['tier0', 'tier1','tier2', 'mathlib', 'unitlib']
if bld.env.DEST_OS != 'win32':
libs += [ 'DL', 'LOG' ]
else:
libs += ['USER32', 'SHELL32']
install_path = bld.env.TESTDIR
bld.shlib(
source = source,
target = PROJECT_NAME,
name = PROJECT_NAME,
features = 'c cxx',
includes = includes,
defines = defines,
use = libs,
install_path = install_path,
subsystem = bld.env.MSVC_SUBSYSTEM,
idx = bld.get_taskgen_count()
)

39
unittests/tier3test/wscript

@ -0,0 +1,39 @@
#! /usr/bin/env python
# encoding: utf-8
from waflib import Utils
import os
top = '.'
PROJECT_NAME = 'tier3test'
def options(opt):
return
def configure(conf):
conf.define('TIER3TEST_EXPORTS', 1)
def build(bld):
source = ['tier3test.cpp']
includes = ['../../public', '../../public/tier0']
defines = []
libs = ['tier0', 'tier1','tier2', 'tier3', 'mathlib', 'unitlib']
if bld.env.DEST_OS != 'win32':
libs += [ 'DL', 'LOG' ]
else:
libs += ['USER32', 'SHELL32']
install_path = bld.env.TESTDIR
bld.shlib(
source = source,
target = PROJECT_NAME,
name = PROJECT_NAME,
features = 'c cxx',
includes = includes,
defines = defines,
use = libs,
install_path = install_path,
subsystem = bld.env.MSVC_SUBSYSTEM,
idx = bld.get_taskgen_count()
)

63
utils/unittest/unittest.cpp

@ -6,16 +6,22 @@
//=============================================================================// //=============================================================================//
#include "unitlib/unitlib.h" #include "unitlib/unitlib.h"
#include "appframework/iappsystemgroup.h" #include "appframework/IAppSystemGroup.h"
#include "appframework/appframework.h" #include "appframework/AppFramework.h"
#include "tier0/dbg.h" #include "tier0/dbg.h"
#include <stdio.h> #include <stdio.h>
#include <windows.h>
#include "vstdlib/iprocessutils.h" #include "vstdlib/iprocessutils.h"
#include "tier1/interface.h" #include "tier1/interface.h"
#include "vstdlib/cvar.h" #include "vstdlib/cvar.h"
#if defined(POSIX)
#include <dirent.h>
#elif defined(WIN32)
#pragma warning (disable:4100) #pragma warning (disable:4100)
#include <windows.h>
#endif
static int g_TestResult = 0;
SpewRetval_t UnitTestSpew( SpewType_t type, char const *pMsg ) SpewRetval_t UnitTestSpew( SpewType_t type, char const *pMsg )
{ {
@ -26,13 +32,14 @@ SpewRetval_t UnitTestSpew( SpewType_t type, char const *pMsg )
break; break;
case SPEW_ASSERT: case SPEW_ASSERT:
printf( "UnitTest Assert:\n" ); printf( "UnitTest Assert:\n" );
g_TestResult = 1;
break; break;
case SPEW_ERROR: case SPEW_ERROR:
printf( "UnitTest Error:\n" ); printf( "UnitTest Error:\n" );
g_TestResult = 1;
break; break;
} }
printf( "%s", pMsg ); printf( "%s", pMsg );
OutputDebugString( pMsg );
if ( Sys_IsDebuggerPresent() ) if ( Sys_IsDebuggerPresent() )
return ( type == SPEW_ASSERT || type == SPEW_ERROR ) ? SPEW_DEBUGGER : SPEW_CONTINUE; return ( type == SPEW_ASSERT || type == SPEW_ERROR ) ? SPEW_DEBUGGER : SPEW_CONTINUE;
@ -69,7 +76,7 @@ bool CUnitTestApp::Create()
// FIXME: This list of dlls should come from the unittests themselves // FIXME: This list of dlls should come from the unittests themselves
AppSystemInfo_t appSystems[] = AppSystemInfo_t appSystems[] =
{ {
{ "vstdlib.dll", PROCESS_UTILS_INTERFACE_VERSION }, // { "vstdlib.so", PROCESS_UTILS_INTERFACE_VERSION },
{ "", "" } // Required to terminate the list { "", "" } // Required to terminate the list
}; };
@ -84,12 +91,16 @@ bool CUnitTestApp::Create()
// or giving test DLLs special extensions, or statically linking the test DLLs // or giving test DLLs special extensions, or statically linking the test DLLs
// to this program. // to this program.
#ifdef WIN32
WIN32_FIND_DATA findFileData; WIN32_FIND_DATA findFileData;
HANDLE hFind= FindFirstFile("*.dll", &findFileData); HANDLE hFind= FindFirstFile("tests/*.dll", &findFileData);
while (hFind != INVALID_HANDLE_VALUE) while (hFind != INVALID_HANDLE_VALUE)
{ {
CSysModule* hLib = Sys_LoadModule(findFileData.cFileName); static char path[2048];
snprintf(path, sizeof(path), "tests/%s", findFileData.cFileName);
CSysModule* hLib = Sys_LoadModule(path);
if ( hLib ) if ( hLib )
{ {
CreateInterfaceFn factory = Sys_GetFactory( hLib ); CreateInterfaceFn factory = Sys_GetFactory( hLib );
@ -107,6 +118,40 @@ bool CUnitTestApp::Create()
if (!FindNextFile( hFind, &findFileData )) if (!FindNextFile( hFind, &findFileData ))
break; break;
} }
#elif POSIX
DIR *d;
struct dirent *dir;
d = opendir("tests");
if (d)
{
while ((dir = readdir(d)) != NULL)
{
int len = strlen(dir->d_name);
if( len > 2 && strcmp(dir->d_name+len-3, ".so") == 0)
{
static char path[2048];
snprintf(path, sizeof(path), "tests/%s", dir->d_name);
CSysModule* hLib = Sys_LoadModule(path);
if ( hLib )
{
CreateInterfaceFn factory = Sys_GetFactory( hLib );
if ( factory && factory( UNITTEST_INTERFACE_VERSION, NULL ) )
{
AppModule_t module = LoadModule( factory );
AddSystem( module, UNITTEST_INTERFACE_VERSION );
}
else
{
Sys_UnloadModule( hLib );
}
}
}
}
closedir(d);
}
#else
#error "Implement me!"
#endif
return true; return true;
} }
@ -121,7 +166,7 @@ void CUnitTestApp::Destroy()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
int CUnitTestApp::Main() int CUnitTestApp::Main()
{ {
printf( "Valve Software - unittest.exe (%s)\n", __DATE__ ); printf( "Valve Software - unittest (%s)\n", __DATE__ );
int nTestCount = UnitTestCount(); int nTestCount = UnitTestCount();
for ( int i = 0; i < nTestCount; ++i ) for ( int i = 0; i < nTestCount; ++i )
@ -131,5 +176,5 @@ int CUnitTestApp::Main()
pTestCase->RunTest(); pTestCase->RunTest();
} }
return 0; return g_TestResult;
} }

40
utils/unittest/wscript

@ -0,0 +1,40 @@
#! /usr/bin/env python
# encoding: utf-8
from waflib import Utils
import os
top = '.'
PROJECT_NAME = 'unittest'
def options(opt):
# stub
return
def configure(conf):
conf.define('PROTECTED_THINGS_DISABLE',1)
def build(bld):
source = ['unittest.cpp']
includes = ['../../public']
defines = []
libs = ['tier0', 'appframework', 'tier1', 'tier2','tier3', 'vstdlib', 'unitlib']
if bld.env.DEST_OS != 'win32':
libs += [ 'DL', 'LOG' ]
else:
libs += ['USER32', 'SHELL32']
install_path = bld.env.BINDIR
bld(
source = source,
target = PROJECT_NAME,
name = PROJECT_NAME,
features = 'c cxx cxxprogram',
includes = includes,
defines = defines,
use = libs,
install_path = install_path,
subsystem = bld.env.MSVC_SUBSYSTEM,
idx = bld.get_taskgen_count()
)

30
wscript

@ -77,6 +77,23 @@ projects={
'vtf', 'vtf',
'unicode' 'unicode'
], ],
'tests': [
'appframework',
'tier0',
'tier1',
'tier2',
'tier3',
'unitlib',
'mathlib',
'vstdlib',
'filesystem',
'vpklib',
'unittests/tier0test',
'unittests/tier1test',
'unittests/tier2test',
'unittests/tier3test',
'utils/unittest'
],
'dedicated': [ 'dedicated': [
'appframework', 'appframework',
'bitmap', 'bitmap',
@ -136,6 +153,7 @@ def get_taskgen_count(self):
def define_platform(conf): def define_platform(conf):
conf.env.DEDICATED = conf.options.DEDICATED conf.env.DEDICATED = conf.options.DEDICATED
conf.env.TESTS = conf.options.TESTS
conf.env.TOGLES = conf.options.TOGLES conf.env.TOGLES = conf.options.TOGLES
conf.env.GL = conf.options.GL conf.env.GL = conf.options.GL
conf.env.OPUS = conf.options.OPUS conf.env.OPUS = conf.options.OPUS
@ -211,6 +229,9 @@ def options(opt):
grp.add_option('-d', '--dedicated', action = 'store_true', dest = 'DEDICATED', default = False, grp.add_option('-d', '--dedicated', action = 'store_true', dest = 'DEDICATED', default = False,
help = 'build dedicated server [default: %default]') help = 'build dedicated server [default: %default]')
grp.add_option('--tests', action = 'store_true', dest = 'TESTS', default = False,
help = 'build unit tests [default: %default]')
grp.add_option('-D', '--debug-engine', action = 'store_true', dest = 'DEBUG_ENGINE', default = False, grp.add_option('-D', '--debug-engine', action = 'store_true', dest = 'DEBUG_ENGINE', default = False,
help = 'build with -DDEBUG [default: %default]') help = 'build with -DDEBUG [default: %default]')
@ -494,6 +515,7 @@ def configure(conf):
# indicate if we are packaging for Linux/BSD # indicate if we are packaging for Linux/BSD
if conf.env.DEST_OS != 'android': if conf.env.DEST_OS != 'android':
conf.env.LIBDIR = conf.env.PREFIX+'/bin/' conf.env.LIBDIR = conf.env.PREFIX+'/bin/'
conf.env.TESTDIR = conf.env.PREFIX+'/tests/'
conf.env.BINDIR = conf.env.PREFIX conf.env.BINDIR = conf.env.PREFIX
else: else:
conf.env.LIBDIR = conf.env.BINDIR = conf.env.PREFIX conf.env.LIBDIR = conf.env.BINDIR = conf.env.PREFIX
@ -502,7 +524,9 @@ def configure(conf):
conf.env.CC.insert(0, 'ccache') conf.env.CC.insert(0, 'ccache')
conf.env.CXX.insert(0, 'ccache') conf.env.CXX.insert(0, 'ccache')
if conf.options.DEDICATED: if conf.options.TESTS:
conf.add_subproject(projects['tests'])
elif conf.options.DEDICATED:
conf.add_subproject(projects['dedicated']) conf.add_subproject(projects['dedicated'])
else: else:
conf.add_subproject(projects['game']) conf.add_subproject(projects['game'])
@ -517,7 +541,9 @@ def build(bld):
if bld.env.OPUS or bld.env.DEST_OS == 'android': if bld.env.OPUS or bld.env.DEST_OS == 'android':
projects['game'] += ['engine/voice_codecs/opus'] projects['game'] += ['engine/voice_codecs/opus']
if bld.env.DEDICATED: if bld.env.TESTS:
bld.add_subproject(projects['tests'])
elif bld.env.DEDICATED:
bld.add_subproject(projects['dedicated']) bld.add_subproject(projects['dedicated'])
else: else:
if bld.env.TOGLES: if bld.env.TOGLES:

Loading…
Cancel
Save