removed visualtest

main
Ozkan Sezer 2022-11-22 18:47:03 +03:00
parent ea21628045
commit d8864ea11d
59 changed files with 0 additions and 12223 deletions

9
.gitignore vendored
View File

@ -88,15 +88,6 @@ VisualC/tests/testscale/icon.bmp
VisualC/tests/testscale/sample.bmp
VisualC/tests/testsprite2/icon.bmp
VisualC/tests/testyuv/testyuv.bmp
VisualC/visualtest/icon.bmp
VisualC/visualtest/testquit.actions
VisualC/visualtest/testquit.config
VisualC/visualtest/testquit.exe
VisualC/visualtest/testquit.parameters
VisualC/visualtest/testsprite2.exe
VisualC/visualtest/testsprite2_sample.actions
VisualC/visualtest/testsprite2_sample.config
VisualC/visualtest/testsprite2_sample.parameters
VisualC-GDK/**/Layout
# for Android

View File

@ -1,217 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectName>testquit</ProjectName>
<RootNamespace>testquit</RootNamespace>
<ProjectGuid>{1D12C737-7C71-45CE-AE2C-AAB47B690BC8}</ProjectGuid>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<PlatformToolset Condition="'$(VisualStudioVersion)' != '10.0'">$(DefaultPlatformToolset)</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset Condition="'$(VisualStudioVersion)' != '10.0'">$(DefaultPlatformToolset)</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<PlatformToolset Condition="'$(VisualStudioVersion)' != '10.0'">$(DefaultPlatformToolset)</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<PlatformToolset Condition="'$(VisualStudioVersion)' != '10.0'">$(DefaultPlatformToolset)</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC70.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC70.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC70.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC70.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\$(Configuration)\</IntDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\$(Configuration)\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\$(Configuration)\</IntDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\$(Configuration)\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Midl>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>true</MkTypLibCompatible>
<SuppressStartupBanner>true</SuppressStartupBanner>
<TargetEnvironment>Win32</TargetEnvironment>
</Midl>
<ClCompile>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<AdditionalIncludeDirectories>..\..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<CompileAs>Default</CompileAs>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<SuppressStartupBanner>true</SuppressStartupBanner>
<SubSystem>Windows</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Midl>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>true</MkTypLibCompatible>
<SuppressStartupBanner>true</SuppressStartupBanner>
</Midl>
<ClCompile>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<AdditionalIncludeDirectories>..\..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<CompileAs>Default</CompileAs>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<SuppressStartupBanner>true</SuppressStartupBanner>
<SubSystem>Windows</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Midl>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>true</MkTypLibCompatible>
<SuppressStartupBanner>true</SuppressStartupBanner>
<TargetEnvironment>Win32</TargetEnvironment>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<CompileAs>Default</CompileAs>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<SuppressStartupBanner>true</SuppressStartupBanner>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Midl>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>true</MkTypLibCompatible>
<SuppressStartupBanner>true</SuppressStartupBanner>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<SuppressStartupBanner>true</SuppressStartupBanner>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\..\..\visualtest\unittest\testquit.c" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\SDLmain\SDLmain.vcxproj">
<Project>{da956fd3-e142-46f2-9dd5-c78bebb56b7a}</Project>
</ProjectReference>
<ProjectReference Include="..\..\..\SDLtest\SDLtest.vcxproj">
<Project>{da956fd3-e143-46f2-9fe5-c77bebc56b1a}</Project>
</ProjectReference>
<ProjectReference Include="..\..\..\SDL\SDL.vcxproj">
<Project>{81ce8daf-ebb2-4761-8e45-b71abcca8c68}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -1,308 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectName>visualtest</ProjectName>
<RootNamespace>visualtest</RootNamespace>
<ProjectGuid>{13DDF23A-4A8F-4AF9-9734-CC09D9157924}</ProjectGuid>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<PlatformToolset Condition="'$(VisualStudioVersion)' != '10.0'">$(DefaultPlatformToolset)</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset Condition="'$(VisualStudioVersion)' != '10.0'">$(DefaultPlatformToolset)</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<PlatformToolset Condition="'$(VisualStudioVersion)' != '10.0'">$(DefaultPlatformToolset)</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<PlatformToolset Condition="'$(VisualStudioVersion)' != '10.0'">$(DefaultPlatformToolset)</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC70.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC70.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC70.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC70.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\$(Configuration)\</IntDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\$(Configuration)\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\$(Configuration)\</IntDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\$(Configuration)\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<TargetName>testharness</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Midl>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>true</MkTypLibCompatible>
<SuppressStartupBanner>true</SuppressStartupBanner>
<TargetEnvironment>Win32</TargetEnvironment>
</Midl>
<ClCompile>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<AdditionalIncludeDirectories>..\..\include;..\..\visualtest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<CompileAs>Default</CompileAs>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<SuppressStartupBanner>true</SuppressStartupBanner>
<SubSystem>Windows</SubSystem>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PostBuildEvent>
<Command>copy "$(SolutionDir)..\test\icon.bmp" "$(ProjectDir)icon.bmp"
copy "$(SolutionDir)\$(Platform)\$(Configuration)\testsprite2.exe" "$(ProjectDir)"
copy "$(SolutionDir)\$(Platform)\$(Configuration)\testquit.exe" "$(ProjectDir)"
copy /y "$(SolutionDir)..\visualtest\*.config" "$(ProjectDir)"
copy /y "$(SolutionDir)..\visualtest\*.parameters" "$(ProjectDir)"
copy /y "$(SolutionDir)..\visualtest\*.actions" "$(ProjectDir)"
copy /y "$(SolutionDir)..\visualtest\unittest\*.config" "$(ProjectDir)"
copy /y "$(SolutionDir)..\visualtest\unittest\*.parameters" "$(ProjectDir)"
copy /y "$(SolutionDir)..\visualtest\unittest\*.actions" "$(ProjectDir)"</Command>
</PostBuildEvent>
<PostBuildEvent>
<Message>Copy data files</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Midl>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>true</MkTypLibCompatible>
<SuppressStartupBanner>true</SuppressStartupBanner>
</Midl>
<ClCompile>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<AdditionalIncludeDirectories>..\..\include;..\..\visualtest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<CompileAs>Default</CompileAs>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<SuppressStartupBanner>true</SuppressStartupBanner>
<SubSystem>Windows</SubSystem>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PostBuildEvent>
<Command>copy "$(SolutionDir)..\test\icon.bmp" "$(ProjectDir)icon.bmp"
copy "$(SolutionDir)\$(Platform)\$(Configuration)\testsprite2.exe" "$(ProjectDir)"
copy "$(SolutionDir)\$(Platform)\$(Configuration)\testquit.exe" "$(ProjectDir)"
copy /y "$(SolutionDir)..\visualtest\*.config" "$(ProjectDir)"
copy /y "$(SolutionDir)..\visualtest\*.parameters" "$(ProjectDir)"
copy /y "$(SolutionDir)..\visualtest\*.actions" "$(ProjectDir)"
copy /y "$(SolutionDir)..\visualtest\unittest\*.config" "$(ProjectDir)"
copy /y "$(SolutionDir)..\visualtest\unittest\*.parameters" "$(ProjectDir)"
copy /y "$(SolutionDir)..\visualtest\unittest\*.actions" "$(ProjectDir)"</Command>
</PostBuildEvent>
<PostBuildEvent>
<Message>Copy data files</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Midl>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>true</MkTypLibCompatible>
<SuppressStartupBanner>true</SuppressStartupBanner>
<TargetEnvironment>Win32</TargetEnvironment>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\include;..\..\visualtest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<DisableLanguageExtensions>false</DisableLanguageExtensions>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<SuppressStartupBanner>true</SuppressStartupBanner>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
</Link>
<PostBuildEvent>
<Command>copy "$(SolutionDir)..\test\icon.bmp" "$(ProjectDir)icon.bmp"
copy "$(SolutionDir)\$(Platform)\$(Configuration)\testsprite2.exe" "$(ProjectDir)"
copy "$(SolutionDir)\$(Platform)\$(Configuration)\testquit.exe" "$(ProjectDir)"
copy /y "$(SolutionDir)..\visualtest\*.config" "$(ProjectDir)"
copy /y "$(SolutionDir)..\visualtest\*.parameters" "$(ProjectDir)"
copy /y "$(SolutionDir)..\visualtest\*.actions" "$(ProjectDir)"
copy /y "$(SolutionDir)..\visualtest\unittest\*.config" "$(ProjectDir)"
copy /y "$(SolutionDir)..\visualtest\unittest\*.parameters" "$(ProjectDir)"
copy /y "$(SolutionDir)..\visualtest\unittest\*.actions" "$(ProjectDir)"</Command>
</PostBuildEvent>
<PostBuildEvent>
<Message>Copy data files</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Midl>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>true</MkTypLibCompatible>
<SuppressStartupBanner>true</SuppressStartupBanner>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\include;..\..\visualtest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<SuppressStartupBanner>true</SuppressStartupBanner>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PostBuildEvent>
<Command>copy "$(SolutionDir)..\test\icon.bmp" "$(ProjectDir)icon.bmp"
copy "$(SolutionDir)\$(Platform)\$(Configuration)\testsprite2.exe" "$(ProjectDir)"
copy "$(SolutionDir)\$(Platform)\$(Configuration)\testquit.exe" "$(ProjectDir)"
copy /y "$(SolutionDir)..\visualtest\*.config" "$(ProjectDir)"
copy /y "$(SolutionDir)..\visualtest\*.parameters" "$(ProjectDir)"
copy /y "$(SolutionDir)..\visualtest\*.actions" "$(ProjectDir)"
copy /y "$(SolutionDir)..\visualtest\unittest\*.config" "$(ProjectDir)"
copy /y "$(SolutionDir)..\visualtest\unittest\*.parameters" "$(ProjectDir)"
copy /y "$(SolutionDir)..\visualtest\unittest\*.actions" "$(ProjectDir)"</Command>
</PostBuildEvent>
<PostBuildEvent>
<Message>Copy data files</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\..\visualtest\include\SDL_visualtest_action_configparser.h" />
<ClInclude Include="..\..\visualtest\include\SDL_visualtest_exhaustive_variator.h" />
<ClInclude Include="..\..\visualtest\include\SDL_visualtest_harness_argparser.h" />
<ClInclude Include="..\..\visualtest\include\SDL_visualtest_mischelper.h" />
<ClInclude Include="..\..\visualtest\include\SDL_visualtest_parsehelper.h" />
<ClInclude Include="..\..\visualtest\include\SDL_visualtest_process.h" />
<ClInclude Include="..\..\visualtest\include\SDL_visualtest_random_variator.h" />
<ClInclude Include="..\..\visualtest\include\SDL_visualtest_rwhelper.h" />
<ClInclude Include="..\..\visualtest\include\SDL_visualtest_screenshot.h" />
<ClInclude Include="..\..\visualtest\include\SDL_visualtest_sut_configparser.h" />
<ClInclude Include="..\..\visualtest\include\SDL_visualtest_variators.h" />
<ClInclude Include="..\..\visualtest\include\SDL_visualtest_variator_common.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\visualtest\src\action_configparser.c" />
<ClCompile Include="..\..\visualtest\src\harness_argparser.c" />
<ClCompile Include="..\..\visualtest\src\mischelper.c" />
<ClCompile Include="..\..\visualtest\src\parsehelper.c" />
<ClCompile Include="..\..\visualtest\src\rwhelper.c" />
<ClCompile Include="..\..\visualtest\src\screenshot.c" />
<ClCompile Include="..\..\visualtest\src\sut_configparser.c" />
<ClCompile Include="..\..\visualtest\src\testharness.c" />
<ClCompile Include="..\..\visualtest\src\variators.c" />
<ClCompile Include="..\..\visualtest\src\variator_exhaustive.c" />
<ClCompile Include="..\..\visualtest\src\variator_common.c" />
<ClCompile Include="..\..\visualtest\src\variator_random.c" />
<ClCompile Include="..\..\visualtest\src\windows\windows_process.c" />
<ClCompile Include="..\..\visualtest\src\windows\windows_screenshot.c" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SDLmain\SDLmain.vcxproj">
<Project>{da956fd3-e142-46f2-9dd5-c78bebb56b7a}</Project>
</ProjectReference>
<ProjectReference Include="..\SDLtest\SDLtest.vcxproj">
<Project>{da956fd3-e143-46f2-9fe5-c77bebc56b1a}</Project>
</ProjectReference>
<ProjectReference Include="..\SDL\SDL.vcxproj">
<Project>{81ce8daf-ebb2-4761-8e45-b71abcca8c68}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -1,18 +0,0 @@
Visual and Interactive Test Automation for SDL 3.0
Copyright (C) 2013 Apoorv Upreti <apoorvupreti@gmail.com>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.

View File

@ -1,44 +0,0 @@
# Makefile to build the SDL tests
srcdir = @srcdir@
CC = @CC@
EXE = @EXE@
CFLAGS = @CFLAGS@ -I../include -I./include
LIBS = @LIBS@
TARGETS = \
testharness$(EXE) \
testquit$(EXE)
all: Makefile $(TARGETS)
Makefile: $(srcdir)/Makefile.in
$(SHELL) config.status $@
testharness$(EXE): $(srcdir)/src/action_configparser.c \
$(srcdir)/src/harness_argparser.c \
$(srcdir)/src/rwhelper.c \
$(srcdir)/src/testharness.c \
$(srcdir)/src/variator_exhaustive.c \
$(srcdir)/src/variators.c \
$(srcdir)/src/screenshot.c \
$(srcdir)/src/harness_argparser.c \
$(srcdir)/src/sut_configparser.c \
$(srcdir)/src/variator_common.c \
$(srcdir)/src/variator_random.c \
$(srcdir)/src/parsehelper.c \
$(srcdir)/src/mischelper.c \
$(srcdir)/src/linux/linux_process.c \
$(srcdir)/src/windows/windows_process.c \
$(srcdir)/src/windows/windows_screenshot.c
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
testquit$(EXE): $(srcdir)/unittest/testquit.c
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
clean:
rm -f $(TARGETS)
distclean: clean
rm -f Makefile
rm -f config.status config.cache config.log
rm -rf $(srcdir)/autom4te*

View File

@ -1,214 +0,0 @@
/*!
\mainpage Visual and Interactive Test Automation for SDL 2.0
\section license_sec License
Check the file \c LICENSE.txt for licensing information.
\section intro_sec Introduction
The goal of this GSoC project is to automate the testing of testsprite2.
testsprite2 takes 26 parameters which have thousands of valid combinations and is
used to validate SDL's window, mouse and rendering behaviour. By having a test
harness that runs testsprite2 with various command line argument strings and
validates the output for each run, we can make testing an easier task for
maintainers, contributors and testers. The test harness can be used by a continuous
integration system (like buildbot or jenkins) to validate SDL after checkins.
SDL Homepage: http://libsdl.org/
\section build_sec Building
\subsection build_linux Building on Linux/Cygwin
<tt>./autogen.sh; ./configure; make;</tt>
\subsection build_windows Building on Windows
Use the Visual Studio solution under \c SDL/VisualC/visualtest.
\section docs_sec Documentation
Documentation is available via Doxygen. To build the documentation, cd to the
SDL/visualtest/docs directory and run \c doxygen. A good starting point for
exploring the documentation is \c SDL/visualtest/docs/html/index.html
\section usage_sec Usage
To see all the options supported by the test harness, just run \c testharness
with no arguments.
At the moment the following options are supported:
\li \c sutapp - Path to the system under test (SUT) application
\li \c sutargs - Launch the SUT with the specified arguments string
\li \c timeout - The maximum time after which the SUT process will be killed;
passed as hh:mm:ss; default 00:01:00
\li \c variator - Which variator to use; see \ref variators_sec
\li \c num-variations - The number of variations to run for; taken to be
1 for the random variator and ALL for the exhaustive variator by default
\li \c no-launch - Just print the arguments string for each variation without
launching the SUT or performing any actions
\li \c parameter-config - A config file that describes the command line parameters
supported by the SUT; see \ref paramconfig_sec or the sample *.parameters files
for more details
\li \c action-config - A config file with a list of actions to be performed while
the SUT is running; see \ref actionconfig_sec or the sample *.actions files
\li \c output-dir - Path to the directory where screenshots should be saved; is
created if it doesn't exist; taken to be "./output" by default
\li \c verify-dir - Path to the directory with the verification images; taken to
be "./verify" by default
Paths can be relative or absolute.
Alternatively, the options can be passed as a config file for convenience:
<tt>testharness \-\-config testsprite2_sample.config</tt>
For a sample, take a look at the *.config files in this repository.
We can also pass a config file and override certain options as necessary:
<tt>testharness \-\-config testsprite2_sample.config \-\-num-variations 10</tt>
Note: You may find it convenient to copy the SUT executable along with any
resources to the test harness directory. Also note that testsprite2 and its
resources (icon.bmp) are automatically copied when using the Visual Studio
solution.
\subsection usageexamples_subsec Usage examples:
Passing a custom arguments string:
<tt>testharness \-\-sutapp testsprite2 \-\-sutargs "\-\-cyclecolor \-\-blend mod
\-\-iterations 2" \-\-action-config xyz.actions</tt>
Using the random variator:
<tt>testharness \-\-sutapp testsprite2 \-\-variator random \-\-num-variations 5
\-\-parameter-config xyz.parameters \-\-action-config xyz.actions</tt>
\subsection config_subsec Config Files
Config files are an alternate way to pass parameters to the test harness. We
describe the paramters in a config file and pass that to the test harness using
the \-\-config option. The config file consists of lines of the form "x=y" where
x is an option and y is it's value. For boolean options, we simply give the name
of the option to indicate that it is to be passed to the testharness.
The hash '#' character can be used to start a comment from that point to the end
of the line.
\section paramconfig_sec The SUT Parameters File
To generate variations we need to describe the parameters the will be passed to
the SUT. This description is given in a parameters file. Each line of the parameters
file (except the blank lines) represents one command line option with five
comma separated fields:
<tt>name, type, values, required, categories</tt>
\li \c name is the name of the option, e.g., \c \-\-cyclecolor.
\li \c type can have one of three values - integer, boolean and enum.
\li \c values - for integer options this is the valid range of values the option
can take, i.e., [min max]. For enum options this is a list of strings that
the option can take, e.g., [val1 val2 val3]. For boolean options this field
is ignored.
\li \c required - true if the option is required, false otherwise.
\li \c categories - a list of categories that the option belongs to. For example,
[video mouse audio]
Just like with config files, hash characters can be used to start comments.
\subsection additionalnotes_subsec Additional Notes
\li If you want to have an option that always takes a certain value, use an enum
with only one value.
\li Currently there isn't any way to turn an option off, i.e., all options will
be included in the command line options string that is generated using the
config. If you don't want an option to be passed to the SUT, remove it from
the config file or comment it out.
\section variators_sec Variators
Variators are the mechanism by which we generate strings of command line arguments
to test the SUT with. A variator is quite simply an iterator that iterates through
different variations of command line options. There are two variators supported at
the moment:
\li \b Exhaustive - Generate all possible combinations of command line arguments
that are valid.
\li \b Random - Generate a random variation each time the variator is called.
As an example, let's try a simple .parameters file:\n
<tt>
\-\-blend, enum, [add mod], false, [] \n
\-\-fullscreen, boolean, [], false, []
</tt>
The exhaustive variator would generate the following four variations:\n
<tt>
\-\-blend add \n
\-\-blend mod \n
\-\-blend add \-\-fullscreen \n
\-\-blend mod \-\-fullscreen \n
</tt>
The random variator would simply generate a random variation like the following:\n
<tt>\-\-blend mod</tt>
\section actionconfig_sec The Actions File
Once the SUT process has been launched, automated testing happens using a mechanism
called actions. A list of actions is read from a file and each action is performed
on the SUT process sequentially. Each line in the actions file describes an action.
The format for an action is <tt>hh:mm:ss ACTION_NAME additional parameters</tt>.
There are five actions supported at the moment:
\li \b SCREENSHOT - Takes a screenshot of each window owned by the SUT process. The
images are saved as \c [hash]_[i].bmp where \c [hash] is the 32 character long
hexadecimal MD5 hash of the arguments string that was passed to the SUT while
launching it and \c i is the window number. i = 1 is an exceptional case
where the \c _[i] is dropped and the filename is simply \c [hash].bmp\n
Note: The screenshots are only of the window's client area.
\li \b VERIFY - Verifies the screenshots taken by the last SCREENSHOT action by
comparing them against a verification image. Each \c [hash]_i.bmp image output
by the SCREENSHOT action is compared against a \c [hash].bmp image in the
verify-dir.
\li \b QUIT - Gracefully quits the SUT process. On Windows this means sending a
WM_CLOSE message to each window owned by the SUT process. On Linux it means
sending a SIGQUIT signal to the SUT process.
\li \b KILL - Forcefully kills the SUT process. This is useful when the SUT process
doesn't respond to the QUIT action.
\li <b>LAUNCH [/path/to/executable] [args]</b> - Runs an executable with \c [args]
as the arguments string.
Just like with config files, hash characters can be used to start comments.
\section contint_sec Continuous Integration (CI)
One of the goals of the project was to create a test harness that integrates
with CI systems to provide automated visual and interactive testing to SDL.
At the moment the test harness can be run in two modes that are useful for CI:
\li Crash testing mode - launch the SUT with every variation and all parameters,
report to the CI if there's a crash
\li Visual testing mode - launch and visually verify the SUT for a smaller subset
of the parameters
Look at the launch_harness.sh/launch_harness.cmd for an example scripts that run the
test harness for all variations with all parameters and report an error on a crash.
The script uses the testsprite2_crashtest config, so remember to copy those files
over to the test harness executable directory along with the script.
\section todo_sec TODOs
\li Allow specifying a clipping box along with the VERIFY action, i.e., hh:mm:ss
VERIFY x, y, w, h
\li Add support for spaces between the equals sign in test harness config files
\li Implement the SCREENSHOT action on Linux
\li Add a pairwise variator
\li Add actions to inject keyboard/mouse events
\li Add actions to manipulate the SUT window, e.g., minimize, restore, resize
\li Add support to load and save screenshots as .pngs instead of .bmps
\section issues_sec Known Issues
\li The QUIT action does not work on a testsprite2 process with multiple windows.
This appears to be an issue with testsprite2.
\li The SCREENSHOT action doesn't capture the testsprite2 window correctly if the
--fullscreen option is supplied. It works with --fullscreen-desktop, however.
\section moreinfo_sec More Information
Author Contact Info:\n
Apoorv Upreti \c \<apoorvupreti@gmail.com\>
Other useful links:
- Project Repository: https://bitbucket.org/nerdap/sdlvisualtest
- Project Wiki: https://github.com/nerdap/autotestsprite2/wiki
- Project Blog: http://nerdap.github.io
- Verification images for testsprite2_blendmodes: https://www.dropbox.com/s/nm02aem76m812ng/testsprite2_blendmodes.zip
- Verification images for testsprite2_geometry: https://www.dropbox.com/s/csypwryopaslpaf/testsprite2_geometry.zip
*/

View File

@ -1,337 +0,0 @@
# Configure paths for SDL
# Sam Lantinga 9/21/99
# stolen from Manish Singh
# stolen back from Frank Belew
# stolen from Manish Singh
# Shamelessly stolen from Owen Taylor
# serial 2
dnl AM_PATH_SDL3([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
dnl Test for SDL, and define SDL_CFLAGS and SDL_LIBS
dnl
AC_DEFUN([AM_PATH_SDL3],
[dnl
dnl Get the cflags and libraries from the sdl3-config script
dnl
AC_ARG_WITH(sdl-prefix,[ --with-sdl-prefix=PFX Prefix where SDL is installed (optional)],
sdl_prefix="$withval", sdl_prefix="")
AC_ARG_WITH(sdl-exec-prefix,[ --with-sdl-exec-prefix=PFX Exec prefix where SDL is installed (optional)],
sdl_exec_prefix="$withval", sdl_exec_prefix="")
AC_ARG_ENABLE(sdltest, [ --disable-sdltest Do not try to compile and run a test SDL program],
, enable_sdltest=yes)
min_sdl_version=ifelse([$1], ,3.0.0,$1)
if test "x$sdl_prefix$sdl_exec_prefix" = x ; then
PKG_CHECK_MODULES([SDL], [sdl3 >= $min_sdl_version],
[sdl_pc=yes],
[sdl_pc=no])
else
sdl_pc=no
if test x$sdl_exec_prefix != x ; then
sdl_config_args="$sdl_config_args --exec-prefix=$sdl_exec_prefix"
if test x${SDL3_CONFIG+set} != xset ; then
SDL3_CONFIG=$sdl_exec_prefix/bin/sdl3-config
fi
fi
if test x$sdl_prefix != x ; then
sdl_config_args="$sdl_config_args --prefix=$sdl_prefix"
if test x${SDL3_CONFIG+set} != xset ; then
SDL3_CONFIG=$sdl_prefix/bin/sdl3-config
fi
fi
fi
if test "x$sdl_pc" = xyes ; then
no_sdl=""
SDL3_CONFIG="pkg-config sdl3"
else
as_save_PATH="$PATH"
if test "x$prefix" != xNONE && test "$cross_compiling" != yes; then
PATH="$prefix/bin:$prefix/usr/bin:$PATH"
fi
AC_PATH_PROG(SDL3_CONFIG, sdl3-config, no, [$PATH])
PATH="$as_save_PATH"
AC_MSG_CHECKING(for SDL - version >= $min_sdl_version)
no_sdl=""
if test "$SDL3_CONFIG" = "no" ; then
no_sdl=yes
else
SDL_CFLAGS=`$SDL3_CONFIG $sdl_config_args --cflags`
SDL_LIBS=`$SDL3_CONFIG $sdl_config_args --libs`
sdl_major_version=`$SDL3_CONFIG $sdl_config_args --version | \
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
sdl_minor_version=`$SDL3_CONFIG $sdl_config_args --version | \
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
sdl_micro_version=`$SDL3_CONFIG $sdl_config_args --version | \
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
if test "x$enable_sdltest" = "xyes" ; then
ac_save_CFLAGS="$CFLAGS"
ac_save_CXXFLAGS="$CXXFLAGS"
ac_save_LIBS="$LIBS"
CFLAGS="$CFLAGS $SDL_CFLAGS"
CXXFLAGS="$CXXFLAGS $SDL_CFLAGS"
LIBS="$LIBS $SDL_LIBS"
dnl
dnl Now check if the installed SDL is sufficiently new. (Also sanity
dnl checks the results of sdl3-config to some extent
dnl
rm -f conf.sdltest
AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <stdio.h>
#include <stdlib.h>
#include "SDL.h"
int main (int argc, char *argv[])
{
int major, minor, micro;
FILE *fp = fopen("conf.sdltest", "w");
if (fp) fclose(fp);
if (sscanf("$min_sdl_version", "%d.%d.%d", &major, &minor, &micro) != 3) {
printf("%s, bad version string\n", "$min_sdl_version");
exit(1);
}
if (($sdl_major_version > major) ||
(($sdl_major_version == major) && ($sdl_minor_version > minor)) ||
(($sdl_major_version == major) && ($sdl_minor_version == minor) && ($sdl_micro_version >= micro)))
{
return 0;
}
else
{
printf("\n*** 'sdl3-config --version' returned %d.%d.%d, but the minimum version\n", $sdl_major_version, $sdl_minor_version, $sdl_micro_version);
printf("*** of SDL required is %d.%d.%d. If sdl3-config is correct, then it is\n", major, minor, micro);
printf("*** best to upgrade to the required version.\n");
printf("*** If sdl3-config was wrong, set the environment variable SDL3_CONFIG\n");
printf("*** to point to the correct copy of sdl3-config, and remove the file\n");
printf("*** config.cache before re-running configure\n");
return 1;
}
}
]])], [], [no_sdl=yes], [echo $ac_n "cross compiling; assumed OK... $ac_c"])
CFLAGS="$ac_save_CFLAGS"
CXXFLAGS="$ac_save_CXXFLAGS"
LIBS="$ac_save_LIBS"
fi
fi
if test "x$no_sdl" = x ; then
AC_MSG_RESULT(yes)
else
AC_MSG_RESULT(no)
fi
fi
if test "x$no_sdl" = x ; then
ifelse([$2], , :, [$2])
else
if test "$SDL3_CONFIG" = "no" ; then
echo "*** The sdl3-config script installed by SDL could not be found"
echo "*** If SDL was installed in PREFIX, make sure PREFIX/bin is in"
echo "*** your path, or set the SDL3_CONFIG environment variable to the"
echo "*** full path to sdl3-config."
else
if test -f conf.sdltest ; then
:
else
echo "*** Could not run SDL test program, checking why..."
CFLAGS="$CFLAGS $SDL_CFLAGS"
CXXFLAGS="$CXXFLAGS $SDL_CFLAGS"
LIBS="$LIBS $SDL_LIBS"
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#include <stdio.h>
#include "SDL.h"
int main(int argc, char *argv[])
{ return 0; }
#undef main
#define main K_and_R_C_main
]], [[ return 0; ]])],
[ echo "*** The test program compiled, but did not run. This usually means"
echo "*** that the run-time linker is not finding SDL or finding the wrong"
echo "*** version of SDL. If it is not finding SDL, you'll need to set your"
echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
echo "*** to the installed location Also, make sure you have run ldconfig if that"
echo "*** is required on your system"
echo "***"
echo "*** If you have an old version installed, it is best to remove it, although"
echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"],
[ echo "*** The test program failed to compile or link. See the file config.log for the"
echo "*** exact error that occured. This usually means SDL was incorrectly installed"
echo "*** or that you have moved SDL since it was installed. In the latter case, you"
echo "*** may want to edit the sdl3-config script: $SDL3_CONFIG" ])
CFLAGS="$ac_save_CFLAGS"
CXXFLAGS="$ac_save_CXXFLAGS"
LIBS="$ac_save_LIBS"
fi
fi
SDL_CFLAGS=""
SDL_LIBS=""
ifelse([$3], , :, [$3])
fi
AC_SUBST(SDL_CFLAGS)
AC_SUBST(SDL_LIBS)
rm -f conf.sdltest
])
# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
# serial 1 (pkg-config-0.24)
#
# Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# 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.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# PKG_PROG_PKG_CONFIG([MIN-VERSION])
# ----------------------------------
AC_DEFUN([PKG_PROG_PKG_CONFIG],
[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
m4_pattern_allow([^PKG_CONFIG(_PATH|_LIBDIR)?$])
AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])
AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path])
AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path])
if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
fi
if test -n "$PKG_CONFIG"; then
_pkg_min_version=m4_default([$1], [0.9.0])
AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
PKG_CONFIG=""
fi
fi[]dnl
])# PKG_PROG_PKG_CONFIG
# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
#
# Check to see whether a particular set of modules exists. Similar
# to PKG_CHECK_MODULES(), but does not set variables or print errors.
#
# Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
# only at the first occurence in configure.ac, so if the first place
# it's called might be skipped (such as if it is within an "if", you
# have to call PKG_CHECK_EXISTS manually
# --------------------------------------------------------------
AC_DEFUN([PKG_CHECK_EXISTS],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
if test -n "$PKG_CONFIG" && \
AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
m4_default([$2], [:])
m4_ifvaln([$3], [else
$3])dnl
fi])
# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
# ---------------------------------------------
m4_define([_PKG_CONFIG],
[if test -n "$$1"; then
pkg_cv_[]$1="$$1"
elif test -n "$PKG_CONFIG"; then
PKG_CHECK_EXISTS([$3],
[pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`],
[pkg_failed=yes])
else
pkg_failed=untried
fi[]dnl
])# _PKG_CONFIG
# _PKG_SHORT_ERRORS_SUPPORTED
# -----------------------------
AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])
if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
_pkg_short_errors_supported=yes
else
_pkg_short_errors_supported=no
fi[]dnl
])# _PKG_SHORT_ERRORS_SUPPORTED
# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
# [ACTION-IF-NOT-FOUND])
#
#
# Note that if there is a possibility the first call to
# PKG_CHECK_MODULES might not happen, you should be sure to include an
# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
#
#
# --------------------------------------------------------------
AC_DEFUN([PKG_CHECK_MODULES],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
pkg_failed=no
AC_MSG_CHECKING([for $2])
_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
_PKG_CONFIG([$1][_LIBS], [libs], [$2])
m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS
and $1[]_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.])
if test $pkg_failed = yes; then
AC_MSG_RESULT([no])
_PKG_SHORT_ERRORS_SUPPORTED
if test $_pkg_short_errors_supported = yes; then
$1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "$2" 2>&1`
else
$1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors "$2" 2>&1`
fi
# Put the nasty error message in config.log where it belongs
echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
m4_default([$4], [AC_MSG_ERROR(
[Package requirements ($2) were not met:
$$1_PKG_ERRORS
Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.
_PKG_TEXT])[]dnl
])
elif test $pkg_failed = untried; then
AC_MSG_RESULT([no])
m4_default([$4], [AC_MSG_FAILURE(
[The pkg-config script could not be found or is too old. Make sure it
is in your PATH or set the PKG_CONFIG environment variable to the full
path to pkg-config.
_PKG_TEXT
To get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl
])
else
$1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
$1[]_LIBS=$pkg_cv_[]$1[]_LIBS
AC_MSG_RESULT([yes])
$3
fi[]dnl
])# PKG_CHECK_MODULES

View File

@ -1,11 +0,0 @@
#!/bin/sh
cp acinclude.m4 aclocal.m4
if test "$AUTOCONF"x = x; then
AUTOCONF=autoconf
fi
$AUTOCONF || exit 1
rm aclocal.m4
rm -rf autom4te.cache

View File

@ -1,3 +0,0 @@
00:00:03 SCREENSHOT
00:00:06 VERIFY
00:00:09 QUIT

View File

@ -1,5 +0,0 @@
parameter-config=testsprite2_blendmodes.parameters
variator=exhaustive
sutapp=testsprite2
timeout=00:00:15
action-config=testsprite2_blendmodes.actions

View File

@ -1,5 +0,0 @@
# parameter name, type, value range, required, categories
--blend, enum, [none blend add mod], false, []
--cyclecolor, boolean, [], false, []
--cyclealpha, boolean, [], false, []
--iterations, integer, [1000 1000], true, []

View File

@ -1,5 +0,0 @@
parameter-config=testsprite2_crashtest.parameters
variator=exhaustive
sutapp=testsprite2
timeout=00:00:10
action-config=testsprite2_crashtest.actions

View File

@ -1,24 +0,0 @@
# parameter name, type, value range, required, categories
--display, integer, [1 5], false, []
--fullscreen, boolean, [], false, []
--fullscreen-desktop, boolean, [], false, []
--title, enum, [vartest bartest footest], false, []
--icon, enum, [icon.bmp], false, []
--center, boolean, [], false, []
--position, enum, [300,300], false, []
--geometry, enum, [500x500], false, []
--min-geometry, enum, [100x100 200x200], false, []
--max-geometry, enum, [600x600 700x700], false, []
--logical, enum, [500x500 550x450], false, []
--scale, integer, [1 5], false, []
--depth, integer, [1 5], false, []
--refresh, integer, [1 5], false, []
--vsync, boolean, [], false, []
--noframe, boolean, [], false, []
--resize, boolean, [], false, []
--minimize, boolean, [], false, []
--maximize, boolean, [], false, []
--grab, boolean, [], false, [mouse]
--blend, enum, [none blend add mod], false, []
--cyclecolor, boolean, [], false, []
--cyclealpha, boolean, [], false, []

View File

@ -1,3 +0,0 @@
00:00:03 SCREENSHOT
00:00:06 VERIFY
00:00:09 QUIT

View File

@ -1,5 +0,0 @@
parameter-config=testsprite2_fullscreen.parameters
variator=exhaustive
sutapp=testsprite2
timeout=00:00:15
action-config=testsprite2_fullscreen.actions

View File

@ -1,5 +0,0 @@
# parameter name, type, value range, required, categories
--blend, enum, [none blend add mod], false, []
--fullscreen, boolean, [], false, []
--fullscreen-desktop, boolean, [], false, []
--iterations, integer, [1000 1000], true, []

View File

@ -1,3 +0,0 @@
00:00:03 SCREENSHOT
00:00:06 VERIFY
00:00:09 QUIT

View File

@ -1,5 +0,0 @@
parameter-config=testsprite2_geometry.parameters
variator=exhaustive
sutapp=testsprite2
timeout=00:00:15
action-config=testsprite2_geometry.actions

View File

@ -1,5 +0,0 @@
# parameter name, type, value range, required, categories
--geometry, enum, [500x500 600x600], false, []
--logical, enum, [300x500 550x450], false, []
--scale, integer, [1 5], false, []
--iterations, integer, [1000 1000], true, []

4442
visualtest/configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -1,41 +0,0 @@
dnl Process this file with autoconf to produce a configure script.
AC_INIT
AC_CONFIG_SRCDIR([unittest/testquit.c])
dnl Detect the canonical build and host environments
AC_CONFIG_AUX_DIR([../build-scripts])
AC_CANONICAL_HOST
dnl Check for tools
AC_PROG_CC
dnl Figure out which math or extra library to use
case "$host" in
*-*-cygwin* | *-*-mingw*)
EXE=".exe"
EXTRALIB="-lshlwapi"
;;
*)
EXE=""
EXTRALIB=""
;;
esac
AC_SUBST(EXE)
dnl Check for SDL
SDL_VERSION=3.0.0
AM_PATH_SDL3($SDL_VERSION,
:,
AC_MSG_ERROR([*** SDL version $SDL_VERSION not found!])
)
CFLAGS="$CFLAGS $SDL_CFLAGS"
LIBS="$LIBS -lSDL3_test $SDL_LIBS $EXTRALIB"
PKG_CHECK_MODULES(LIBUNWIND, libunwind, have_libunwind=yes, have_libunwind=no)
if test x$have_libunwind = xyes ; then
LIBS="$LIBS $LIBUNWIND_LIBS"
fi
dnl Finally create all the generated files
AC_CONFIG_FILES([Makefile])
AC_OUTPUT

File diff suppressed because it is too large Load Diff

View File

@ -1,149 +0,0 @@
/* See LICENSE.txt for the full license governing this code. */
/**
* \file SDL_visualtest_action_configparser.h
*
* Header file for the parser for action config files.
*/
#ifndef SDL_visualtest_action_configparser_h_
#define SDL_visualtest_action_configparser_h_
/** The maximum length of one line in the actions file */
#define MAX_ACTION_LINE_LENGTH 300
/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
extern "C" {
#endif
/**
* Type of the action.
*/
typedef enum
{
/*! Launch an application with some given arguments */
SDL_ACTION_LAUNCH = 0,
/*! Kill the SUT process */
SDL_ACTION_KILL,
/*! Quit (Gracefully exit) the SUT process */
SDL_ACTION_QUIT,
/*! Take a screenshot of the SUT window */
SDL_ACTION_SCREENSHOT,
/*! Verify a previously taken screenshot */
SDL_ACTION_VERIFY
} SDLVisualTest_ActionType;
/**
* Struct that defines an action that will be performed on the SUT process at
* a specific time.
*/
typedef struct SDLVisualTest_Action
{
/*! The type of action to be performed */
SDLVisualTest_ActionType type;
/*! The time, in milliseconds from the launch of the SUT, when the action
will be performed */
int time;
/*! Any additional information needed to perform the action. */
union
{
/*! The path and arguments to the process to be launched */
struct
{
char* path;
char* args;
} process;
} extra;
} SDLVisualTest_Action;
/**
* Struct for a node in the action queue.
*/
typedef struct SDLVisualTest_ActionNode
{
/*! The action in this node */
SDLVisualTest_Action action;
/*! Pointer to the next element in the queue */
struct SDLVisualTest_ActionNode* next;
} SDLVisualTest_ActionNode;
/**
* Queue structure for actions loaded from the actions config file.
*/
typedef struct SDLVisualTest_ActionQueue
{
/*! Pointer to the front of the queue */
SDLVisualTest_ActionNode* front;
/*! Pointer to the rear of the queue */
SDLVisualTest_ActionNode* rear;
/*! Number of nodes in the queue */
int size;
} SDLVisualTest_ActionQueue;
/**
* Add an action pointed to by \c action to the rear of the action queue pointed
* to by \c queue.
*
* \return 1 on success, 0 on failure.
*/
int SDLVisualTest_EnqueueAction(SDLVisualTest_ActionQueue* queue,
SDLVisualTest_Action action);
/**
* Remove an action from the front of the action queue pointed to by \c queue.
*
* \return 1 on success, 0 on failure.
*/
int SDLVisualTest_DequeueAction(SDLVisualTest_ActionQueue* queue);
/**
* Initialize the action queue pointed to by \c queue.
*/
void SDLVisualTest_InitActionQueue(SDLVisualTest_ActionQueue* queue);
/**
* Get the action at the front of the action queue pointed to by \c queue.
* The returned action pointer may become invalid after subsequent dequeues.
*
* \return pointer to the action on success, NULL on failure.
*/
SDLVisualTest_Action* SDLVisualTest_GetQueueFront(SDLVisualTest_ActionQueue* queue);
/**
* Check if the queue pointed to by \c queue is empty or not.
*
* \return 1 if the queue is empty, 0 otherwise.
*/
int SDLVisualTest_IsActionQueueEmpty(SDLVisualTest_ActionQueue* queue);
/**
* Dequeues all the elements in the queque pointed to by \c queue.
*/
void SDLVisualTest_EmptyActionQueue(SDLVisualTest_ActionQueue* queue);
/**
* Inserts an action \c action into the queue pointed to by \c queue such that
* the times of actions in the queue increase as we move from the front to the
* rear.
*
* \return 1 on success, 0 on failure.
*/
int SDLVisualTest_InsertIntoActionQueue(SDLVisualTest_ActionQueue* queue,
SDLVisualTest_Action action);
/**
* Parses an action config file with path \c file and populates an action queue
* pointed to by \c queue with actions.
*
* \return 1 on success, 0 on failure.
*/
int SDLVisualTest_ParseActionConfig(const char* file, SDLVisualTest_ActionQueue* queue);
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
#endif
#endif /* SDL_visualtest_action_configparser_h_ */
/* vi: set ts=4 sw=4 expandtab: */

View File

@ -1,64 +0,0 @@
/* See LICENSE.txt for the full license governing this code. */
/**
* \file SDL_visualtest_exhaustive_variator.h
*
* Header for the exhaustive variator.
*/
#include "SDL_visualtest_harness_argparser.h"
#include "SDL_visualtest_variator_common.h"
#ifndef SDL_visualtest_exhaustive_variator_h_
#define SDL_visualtest_exhaustive_variator_h_
/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
extern "C" {
#endif
/**
* Struct for the variator that exhaustively iterates through all variations of
* command line arguments to the SUT.
*/
typedef struct SDLVisualTest_ExhaustiveVariator
{
/*! The current variation. */
SDLVisualTest_Variation variation;
/*! Configuration object for the SUT that the variator is running for. */
SDLVisualTest_SUTConfig config;
/*! Buffer to store the arguments string built from the variation */
char buffer[MAX_SUT_ARGS_LEN];
} SDLVisualTest_ExhaustiveVariator;
/**
* Initializes the variator.
*
* \return 1 on success, 0 on failure
*/
int SDLVisualTest_InitExhaustiveVariator(SDLVisualTest_ExhaustiveVariator* variator,
SDLVisualTest_SUTConfig* config);
/**
* Gets the arguments string for the next variation using the variator and updates
* the variator's current variation object to the next variation.
*
* \return The arguments string representing the next variation on success, and
* NULL on failure or if we have iterated through all possible variations.
* In the latter case subsequent calls will start the variations again from
* the very beginning. The pointer returned should not be freed.
*/
char* SDLVisualTest_GetNextExhaustiveVariation(SDLVisualTest_ExhaustiveVariator* variator);
/**
* Frees any resources associated with the variator.
*/
void SDLVisualTest_FreeExhaustiveVariator(SDLVisualTest_ExhaustiveVariator* variator);
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
#endif
#endif /* SDL_visualtest_exhaustive_variator_h_ */
/* vi: set ts=4 sw=4 expandtab: */

View File

@ -1,75 +0,0 @@
/**
* \file SDL_visualtest_harness_argparser.h
*
* Provides functionality to parse command line arguments to the test harness.
*/
#include <SDL.h>
#include "SDL_visualtest_sut_configparser.h"
#include "SDL_visualtest_variator_common.h"
#include "SDL_visualtest_action_configparser.h"
#ifndef SDL_visualtest_harness_argparser_h_
#define SDL_visualtest_harness_argparser_h_
/** Maximum length of a path string */
#define MAX_PATH_LEN 300
/** Maximum length of a string of SUT arguments */
#define MAX_SUT_ARGS_LEN 600
/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
extern "C" {
#endif
/**
* Stores the state of the test harness.
*/
typedef struct SDLVisualTest_HarnessState
{
/*! Path to the System Under Test (SUT) executable */
char sutapp[MAX_PATH_LEN];
/*! Command line arguments to be passed to the SUT */
char sutargs[MAX_SUT_ARGS_LEN];
/*! Time in milliseconds after which to kill the SUT */
int timeout;
/*! Configuration object for the SUT */
SDLVisualTest_SUTConfig sut_config;
/*! What type of variator to use to generate argument strings */
SDLVisualTest_VariatorType variator_type;
/*! The number of variations to generate */
int num_variations;
/*! If true, the test harness will just print the different variations
without launching the SUT for each one */
SDL_bool no_launch;
/*! A queue with actions to be performed while the SUT is running */
SDLVisualTest_ActionQueue action_queue;
/*! Output directory to save the screenshots */
char output_dir[MAX_PATH_LEN];
/*! Path to directory with the verification images */
char verify_dir[MAX_PATH_LEN];
} SDLVisualTest_HarnessState;
/**
* Parse command line paramters to the test harness and populate a state object.
*
* \param argv The array of command line parameters.
* \param state Pointer to the state object to be populated.
*
* \return Non-zero on success, zero on failure.
*/
int SDLVisualTest_ParseHarnessArgs(char** argv, SDLVisualTest_HarnessState* state);
/**
* Frees any resources associated with the state object pointed to by \c state.
*/
void SDLVisualTest_FreeHarnessState(SDLVisualTest_HarnessState* state);
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
#endif
#endif /* SDL_visualtest_harness_argparser_h_ */
/* vi: set ts=4 sw=4 expandtab: */

View File

@ -1,28 +0,0 @@
/**
* \file mischelper.c
*
* Header with miscellaneous helper functions.
*/
#ifndef SDL_visualtest_mischelper_h_
#define SDL_visualtest_mischelper_h_
/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
extern "C" {
#endif
/**
* Stores a 32 digit hexadecimal string representing the MD5 hash of the
* string \c str in \c hash.
*/
void SDLVisualTest_HashString(char* str, char hash[33]);
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
#endif
#endif /* SDL_visualtest_mischelper_h_ */
/* vi: set ts=4 sw=4 expandtab: */

View File

@ -1,46 +0,0 @@
/* See LICENSE.txt for the full license governing this code. */
/**
* \file SDL_visualtest_parsehelper.h
*
* Header with some helper functions for parsing strings.
*/
#ifndef SDL_visualtest_parsehelper_h_
#define SDL_visualtest_parsehelper_h_
/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
extern "C" {
#endif
/**
* Takes an string of command line arguments and breaks them up into an array
* based on whitespace.
*
* \param args The string of arguments.
*
* \return NULL on failure, an array of strings on success. The last element
* of the array is NULL. The first element of the array is NULL and should
* be set to the path of the executable by the caller.
*/
char** SDLVisualTest_ParseArgsToArgv(char* args);
/**
* Takes a string and breaks it into tokens by splitting on whitespace.
*
* \param str The string to be split.
* \param max_token_len Length of each element in the array to be returned.
*
* \return NULL on failure; an array of strings with the tokens on success. The
* last element of the array is NULL.
*/
char** SDLVisualTest_Tokenize(char* str, int max_token_len);
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
#endif
#endif /* SDL_visualtest_parsehelper_h_ */
/* vi: set ts=4 sw=4 expandtab: */

View File

@ -1,112 +0,0 @@
/* See LICENSE.txt for the full license governing this code. */
/**
* \file SDL_visualtest_process.h
*
* Provides cross-platfrom process launching and termination functionality.
*/
#include <SDL_platform.h>
#if defined(__WIN32__)
#include <windows.h>
#include <shlwapi.h>
#elif defined(__LINUX__)
#include <unistd.h>
#else
#error "Unsupported platform."
#endif
#ifndef SDL_visualtest_process_h_
#define SDL_visualtest_process_h_
/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
extern "C" {
#endif
/**
* Struct to store a platform specific handle to a process.
*/
typedef struct SDL_ProcessInfo
{
//#if defined(_WIN32) || defined(__WIN32__)
#if defined(__WIN32__)
PROCESS_INFORMATION pi;
//#elif defined(__linux__)
#elif defined(__LINUX__)
int pid;
#endif
} SDL_ProcessInfo;
/**
* This structure stores the exit status (value returned by main()) and
* whether the process exited sucessfully or not.
*/
typedef struct SDL_ProcessExitStatus
{
int exit_success; /*!< Zero if the process exited successfully */
int exit_status; /*!< The exit status of the process. 8-bit value. */
} SDL_ProcessExitStatus;
/**
* Launches a process with the given commandline arguments.
*
* \param file The path to the executable to be launched.
* \param args The command line arguments to be passed to the process.
* \param pinfo Pointer to an SDL_ProcessInfo object to be populated with
* platform specific information about the launched process.
*
* \return Non-zero on success, zero on failure.
*/
int SDL_LaunchProcess(char* file, char* args, SDL_ProcessInfo* pinfo);
/**
* Checks if a process is running or not.
*
* \param pinfo Pointer to SDL_ProcessInfo object of the process that needs to be
* checked.
*
* \return 1 if the process is still running; zero if it is not and -1 if the
* status could not be retrieved.
*/
int SDL_IsProcessRunning(SDL_ProcessInfo* pinfo);
/**
* Kills a currently running process.
*
* \param pinfo Pointer to a SDL_ProcessInfo object of the process to be terminated.
* \param ps Pointer to a SDL_ProcessExitStatus object which will be populated
* with the exit status.
*
* \return 1 on success, 0 on failure.
*/
int SDL_KillProcess(SDL_ProcessInfo* pinfo, SDL_ProcessExitStatus* ps);
/**
* Cleanly exits the process represented by \c pinfo and stores the exit status
* in the exit status object pointed to by \c ps.
*
* \return 1 on success, 0 on failure.
*/
int SDL_QuitProcess(SDL_ProcessInfo* pinfo, SDL_ProcessExitStatus* ps);
/**
* Gets the exit status of a process. If the exit status is -1, the process is
* still running.
*
* \param pinfo Pointer to a SDL_ProcessInfo object of the process to be checked.
* \param ps Pointer to a SDL_ProcessExitStatus object which will be populated
* with the exit status.
*
* \return 1 on success, 0 on failure.
*/
int SDL_GetProcessExitStatus(SDL_ProcessInfo* pinfo, SDL_ProcessExitStatus* ps);
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
#endif
#endif /* SDL_visualtest_process_h_ */
/* vi: set ts=4 sw=4 expandtab: */

View File

@ -1,61 +0,0 @@
/* See LICENSE.txt for the full license governing this code. */
/**
* \file SDL_visualtest_random_variator.h
*
* Header for the random variator.
*/
#include "SDL_visualtest_harness_argparser.h"
#include "SDL_visualtest_variator_common.h"
#ifndef SDL_visualtest_random_variator_h_
#define SDL_visualtest_random_variator_h_
/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
extern "C" {
#endif
/**
* Struct for the variator that randomly generates variations of command line
* arguments to the SUT.
*/
typedef struct SDLVisualTest_RandomVariator
{
/*! The current variation. */
SDLVisualTest_Variation variation;
/*! Configuration object for the SUT that the variator is running for. */
SDLVisualTest_SUTConfig config;
/*! Buffer to store the arguments string built from the variation */
char buffer[MAX_SUT_ARGS_LEN];
} SDLVisualTest_RandomVariator;
/**
* Initializes the variator.
*
* \return 1 on success, 0 on failure
*/
int SDLVisualTest_InitRandomVariator(SDLVisualTest_RandomVariator* variator,
SDLVisualTest_SUTConfig* config, Uint64 seed);
/**
* Generates a new random variation.
*
* \return The arguments string representing the random variation on success, and
* NULL on failure. The pointer returned should not be freed.
*/
char* SDLVisualTest_GetNextRandomVariation(SDLVisualTest_RandomVariator* variator);
/**
* Frees any resources associated with the variator.
*/
void SDLVisualTest_FreeRandomVariator(SDLVisualTest_RandomVariator* variator);
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
#endif
#endif /* SDL_visualtest_random_variator_h_ */
/* vi: set ts=4 sw=4 expandtab: */

View File

@ -1,87 +0,0 @@
/* See LICENSE.txt for the full license governing this code. */
/**
* \file rwhelper.c
*
* Header file with some helper functions for working with SDL_RWops.
*/
#include <SDL_rwops.h>
#ifndef SDL_visualtest_rwhelper_h_
#define SDL_visualtest_rwhelper_h_
/** Length of the buffer in SDLVisualTest_RWHelperBuffer */
#define RWOPS_BUFFER_LEN 256
/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
extern "C" {
#endif
/**
* Struct that is used as a buffer by the RW helper functions. Should be initialized by calling
* SDLVisualTest_RWHelperResetBuffer() before being used.
*/
typedef struct SDLVisualTest_RWHelperBuffer
{
/*! Character buffer that data is read into */
char buffer[RWOPS_BUFFER_LEN];
/*! buffer[buffer_pos] is the next character to be read from the buffer */
int buffer_pos;
/*! Number of character read into the buffer */
int buffer_width;
} SDLVisualTest_RWHelperBuffer;
/**
* Resets the buffer pointed to by \c buffer used by some of the helper functions.
* This function should be called when you're using one of the helper functions
* with a new SDL_RWops object.
*/
void SDLVisualTest_RWHelperResetBuffer(SDLVisualTest_RWHelperBuffer* buffer);
/**
* Reads a single character using the SDL_RWops object pointed to by \c rw.
* This function reads data in blocks and stores them in the buffer pointed to by
* \c buffer, so other SDL_RWops functions should not be used in conjunction
* with this function.
*
* \return The character that was read.
*/
char SDLVisualTest_RWHelperReadChar(SDL_RWops* rw,
SDLVisualTest_RWHelperBuffer* buffer);
/**
* Reads characters using the SDL_RWops object pointed to by \c rw into the
* character array pointed to by \c str (of size \c size) until either the
* array is full or a new line is encountered. If \c comment_char is encountered,
* all characters from that position till the end of the line are ignored. The new line
* is not included as part of the buffer. Lines with only whitespace and comments
* are ignored. This function reads data in blocks and stores them in the buffer
* pointed to by \c buffer, so other SDL_RWops functions should not be used in
* conjunction with this function.
*
* \return pointer to the string on success, NULL on failure or EOF.
*/
char* SDLVisualTest_RWHelperReadLine(SDL_RWops* rw, char* str, int size,
SDLVisualTest_RWHelperBuffer* buffer,
char comment_char);
/**
* Counts the number of lines that are not all whitespace and comments using the
* SDL_RWops object pointed to by \c rw. \c comment_char indicates the character
* used for comments. Uses the buffer pointed to by \c buffer to read data in blocks.
*
* \return Number of lines on success, -1 on failure.
*/
int SDLVisualTest_RWHelperCountNonEmptyLines(SDL_RWops* rw,
SDLVisualTest_RWHelperBuffer* buffer,
char comment_char);
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
#endif
#endif /* SDL_visualtest_rwhelper_h_ */
/* vi: set ts=4 sw=4 expandtab: */

View File

@ -1,52 +0,0 @@
/* See LICENSE.txt for the full license governing this code. */
/**
* \file SDL_visualtest_screenshot.h
*
* Header for the screenshot API.
*/
#include "SDL_visualtest_process.h"
#ifndef SDL_visualtest_screenshot_h_
#define SDL_visualtest_screenshot_h_
/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
extern "C" {
#endif
/**
* Takes a screenshot of each window owned by the process \c pinfo and saves
* it in a file \c prefix-i.png where \c prefix is the full path to the file
* along with a prefix given to each screenshot.
*
* \return 1 on success, 0 on failure.
*/
int SDLVisualTest_ScreenshotProcess(SDL_ProcessInfo* pinfo, char* prefix);
/**
* Takes a screenshot of the desktop and saves it into the file with path
* \c filename.
*
* \return 1 on success, 0 on failure.
*/
int SDLVisualTest_ScreenshotDesktop(char* filename);
/**
* Compare a screenshot taken previously with SUT arguments \c args that is
* located in \c test_dir with a verification image that is located in
* \c verify_dir.
*
* \return -1 on failure, 0 if the images were not equal, 1 if the images are equal
* and 2 if the verification image is not present.
*/
int SDLVisualTest_VerifyScreenshots(char* args, char* test_dir, char* verify_dir);
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
#endif
#endif /* SDL_visualtest_screenshot_h_ */
/* vi: set ts=4 sw=4 expandtab: */

View File

@ -1,105 +0,0 @@
/* See LICENSE.txt for the full license governing this code. */
/**
* \file SDL_visualtest_sut_configparser.h
*
* Header for the parser for SUT config files.
*/
#ifndef SDL_visualtest_sut_configparser_h_
#define SDL_visualtest_sut_configparser_h_
/** Maximum length of the name of an SUT option */
#define MAX_SUTOPTION_NAME_LEN 100
/** Maximum length of the name of a category of an SUT option */
#define MAX_SUTOPTION_CATEGORY_LEN 40
/** Maximum length of one enum value of an SUT option */
#define MAX_SUTOPTION_ENUMVAL_LEN 40
/** Maximum length of a line in the paramters file */
#define MAX_SUTOPTION_LINE_LENGTH 256
/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
extern "C" {
#endif
/**
* Describes the different kinds of options to the SUT.
*/
typedef enum {
SDL_SUT_OPTIONTYPE_STRING = 0,
SDL_SUT_OPTIONTYPE_INT,
SDL_SUT_OPTIONTYPE_ENUM,
SDL_SUT_OPTIONTYPE_BOOL
} SDLVisualTest_SUTOptionType;
/**
* Represents the range of values an integer option can take.
*/
typedef struct SDLVisualTest_SUTIntRange {
/*! Minimum value of the integer option */
int min;
/*! Maximum value of the integer option */
int max;
} SDLVisualTest_SUTIntRange;
/**
* Struct that defines an option to be passed to the SUT.
*/
typedef struct SDLVisualTest_SUTOption {
/*! The name of the option. This is what you would pass in the command line
along with two leading hyphens. */
char name[MAX_SUTOPTION_NAME_LEN];
/*! An array of categories that the option belongs to. The last element is
NULL. */
char** categories;
/*! Type of the option - integer, boolean, etc. */
SDLVisualTest_SUTOptionType type;
/*! Whether the option is required or not */
SDL_bool required;
/*! extra data that is required for certain types */
union {
/*! This field is valid only for integer type options; it defines the
valid range for such an option */
SDLVisualTest_SUTIntRange range;
/*! This field is valid only for enum type options; it holds the list of values
that the option can take. The last element is NULL */
char** enum_values;
} data;
} SDLVisualTest_SUTOption;
/**
* Struct to hold all the options to an SUT application.
*/
typedef struct SDLVisualTest_SUTConfig
{
/*! Pointer to an array of options */
SDLVisualTest_SUTOption* options;
/*! Number of options in \c options */
int num_options;
} SDLVisualTest_SUTConfig;
/**
* Parses a configuration file that describes the command line options an SUT
* application will take and populates a SUT config object. All lines in the
* config file must be smaller than
*
* \param file Path to the configuration file.
* \param config Pointer to an object that represents an SUT configuration.
*
* \return zero on failure, non-zero on success
*/
int SDLVisualTest_ParseSUTConfig(char* file, SDLVisualTest_SUTConfig* config);
/**
* Free any resources associated with the config object pointed to by \c config.
*/
void SDLVisualTest_FreeSUTConfig(SDLVisualTest_SUTConfig* config);
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
#endif
#endif /* SDL_visualtest_sut_configparser_h_ */
/* vi: set ts=4 sw=4 expandtab: */

View File

@ -1,122 +0,0 @@
/* See LICENSE.txt for the full license governing this code. */
/**
* \file SDL_visualtest_variator_common.h
*
* Header for common functionality used by variators.
*/
#include <SDL_types.h>
#include "SDL_visualtest_sut_configparser.h"
#ifndef SDL_visualtest_variator_common_h_
#define SDL_visualtest_variator_common_h_
/** The number of variations one integer option would generate */
#define SDL_SUT_INTEGER_OPTION_TEST_STEPS 3
/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
extern "C" {
#endif
/** enum for indicating the type of variator being used */
typedef enum SDLVisualTest_VariatorType
{
SDL_VARIATOR_NONE = 0,
SDL_VARIATOR_EXHAUSTIVE,
SDL_VARIATOR_RANDOM
} SDLVisualTest_VariatorType;
/**
* One possible value for a command line option to the SUT.
*/
typedef union SDLVisualTest_SUTOptionValue
{
/*! Value if the option is of type boolean */
SDL_bool bool_value;
/*! Value if the option is of type integer. If on is true then the option
will be passed to the SUT, otherwise it will be ignored. */
struct {
int value;
SDL_bool on;
} integer;
/*! Index of the string in the enum_values field of the corresponding
SDLVisualTest_SUTOption object. If on is true the option will passed
to the SUT, otherwise it will be ignored. */
struct {
int index;
SDL_bool on;
} enumerated;
/*! Value if the option is of type string. If on is true the option will
be passed to the SUT, otherwise it will be ignored. */
struct {
char* value;
SDL_bool on;
} string;
} SDLVisualTest_SUTOptionValue;
/**
* Represents a valid combination of parameters that can be passed to the SUT.
* The ordering of the values here is the same as the ordering of the options in
* the SDLVisualTest_SUTConfig object for this variation.
*/
typedef struct SDLVisualTest_Variation
{
/*! Pointer to array of option values */
SDLVisualTest_SUTOptionValue* vars;
/*! Number of option values in \c vars */
int num_vars;
} SDLVisualTest_Variation;
/**
* "Increments" the value of the option by one and returns the carry. We wrap
* around to the initial value on overflow which makes the carry one.
* For example: "incrementing" an SDL_FALSE option makes it SDL_TRUE with no
* carry, and "incrementing" an SDL_TRUE option makes it SDL_FALSE with carry
* one. For integers, a random value in the valid range for the option is used.
*
* \param var Value of the option
* \param opt Object with metadata about the option
*
* \return 1 if there is a carry for enum and bool type options, 0 otherwise.
* 1 is always returned for integer and string type options. -1 is
* returned on error.
*/
int SDLVisualTest_NextValue(SDLVisualTest_SUTOptionValue* var,
SDLVisualTest_SUTOption* opt);
/**
* Converts a variation object into a string of command line arguments.
*
* \param variation Variation object to be converted.
* \param config Config object for the SUT.
* \param buffer Pointer to the buffer the arguments string will be copied into.
* \param size Size of the buffer.
*
* \return 1 on success, 0 on failure
*/
int SDLVisualTest_MakeStrFromVariation(SDLVisualTest_Variation* variation,
SDLVisualTest_SUTConfig* config,
char* buffer, int size);
/**
* Initializes the variation using the following rules:
* - Boolean options are initialized to SDL_FALSE.
* - Integer options are initialized to the minimum valid value they can hold.
* - Enum options are initialized to the first element in the list of values they
* can take.
* - String options are initialized to the name of the option.
*
* \return 1 on success, 0 on failure.
*/
int SDLVisualTest_InitVariation(SDLVisualTest_Variation* variation,
SDLVisualTest_SUTConfig* config);
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
#endif
#endif /* SDL_visualtest_variator_common_h_ */
/* vi: set ts=4 sw=4 expandtab: */

View File

@ -1,66 +0,0 @@
/* See LICENSE.txt for the full license governing this code. */
/**
* \file SDL_visualtest_variators.h
*
* Header for all the variators that vary input parameters to a SUT application.
*/
#include "SDL_visualtest_exhaustive_variator.h"
#include "SDL_visualtest_random_variator.h"
#ifndef SDL_visualtest_variators_h_
#define SDL_visualtest_variators_h_
/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
extern "C" {
#endif
/**
* Struct that acts like a wrapper around the different types of variators
* available.
*/
typedef struct SDLVisualTest_Variator
{
/*! Type of the variator */
SDLVisualTest_VariatorType type;
/*! union object that stores the variator */
union
{
SDLVisualTest_ExhaustiveVariator exhaustive;
SDLVisualTest_RandomVariator random;
} data;
} SDLVisualTest_Variator;
/**
* Initializes the variator object pointed to by \c variator of type \c type
* with information from the config object pointed to by \c config.
*
* \return 1 on success, 0 on failure
*/
int SDLVisualTest_InitVariator(SDLVisualTest_Variator* variator,
SDLVisualTest_SUTConfig* config,
SDLVisualTest_VariatorType type,
Uint64 seed);
/**
* Gets the next variation using the variator.
*
* \return The arguments string representing the variation on success, and
* NULL on failure. The pointer returned should not be freed.
*/
char* SDLVisualTest_GetNextVariation(SDLVisualTest_Variator* variator);
/**
* Frees any resources associated with the variator.
*/
void SDLVisualTest_FreeVariator(SDLVisualTest_Variator* variator);
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
#endif
#endif /* SDL_visualtest_variators_h_ */
/* vi: set ts=4 sw=4 expandtab: */

View File

@ -1,2 +0,0 @@
start /wait testharness.exe --config testsprite2_crashtest.config > testrun.log 2>&1
if %ERRORLEVEL% NEQ 0 echo TEST RUN FAILED (see testrun.log)

View File

@ -1,6 +0,0 @@
#!/bin/bash
./testharness.exe --config testsprite2_crashtest.config > testrun.log 2>&1
if [ "$?" != "0" ]; then
echo TEST RUN FAILED (see testrun.log)
# report error code to CI
fi

View File

@ -1,399 +0,0 @@
/* See LICENSE.txt for the full license governing this code. */
/**
* \file action_configparser.c
*
* Source file for the parser for action config files.
*/
#include <SDL_stdinc.h>
#include <SDL_test.h>
#include <string.h>
#include "SDL_visualtest_action_configparser.h"
#include "SDL_visualtest_rwhelper.h"
#include "SDL_visualtest_parsehelper.h"
static void
FreeAction(SDLVisualTest_Action* action)
{
if(!action)
return;
switch(action->type)
{
case SDL_ACTION_LAUNCH:
{
char* path;
char* args;
path = action->extra.process.path;
args = action->extra.process.args;
if(path)
SDL_free(path);
if(args)
SDL_free(args);
action->extra.process.path = NULL;
action->extra.process.args = NULL;
}
break;
default:
break;
}
}
int
SDLVisualTest_EnqueueAction(SDLVisualTest_ActionQueue* queue,
SDLVisualTest_Action action)
{
SDLVisualTest_ActionNode* node;
if(!queue)
{
SDLTest_LogError("queue argument cannot be NULL");
return 0;
}
node = (SDLVisualTest_ActionNode*)SDL_malloc(
sizeof(SDLVisualTest_ActionNode));
if(!node)
{
SDLTest_LogError("SDL_malloc() failed");
return 0;
}
node->action = action;
node->next = NULL;
queue->size++;
if(!queue->rear)
queue->rear = queue->front = node;
else
{
queue->rear->next = node;
queue->rear = node;
}
return 1;
}
int
SDLVisualTest_DequeueAction(SDLVisualTest_ActionQueue* queue)
{
SDLVisualTest_ActionNode* node;
if(!queue)
{
SDLTest_LogError("queue argument cannot be NULL");
return 0;
}
if(SDLVisualTest_IsActionQueueEmpty(queue))
{
SDLTest_LogError("cannot dequeue from empty queue");
return 0;
}
if(queue->front == queue->rear)
{
FreeAction(&queue->front->action);
SDL_free(queue->front);
queue->front = queue->rear = NULL;
}
else
{
node = queue->front;
queue->front = queue->front->next;
FreeAction(&node->action);
SDL_free(node);
}
queue->size--;
return 1;
}
void
SDLVisualTest_InitActionQueue(SDLVisualTest_ActionQueue* queue)
{
if(!queue)
{
SDLTest_LogError("queue argument cannot be NULL");
return;
}
queue->front = NULL;
queue->rear = NULL;
queue->size = 0;
}
SDLVisualTest_Action*
SDLVisualTest_GetQueueFront(SDLVisualTest_ActionQueue* queue)
{
if(!queue)
{
SDLTest_LogError("queue argument cannot be NULL");
return NULL;
}
if(!queue->front)
{
SDLTest_LogError("cannot get front of empty queue");
return NULL;
}
return &queue->front->action;
}
int
SDLVisualTest_IsActionQueueEmpty(SDLVisualTest_ActionQueue* queue)
{
if(!queue)
{
SDLTest_LogError("queue argument cannot be NULL");
return 1;
}
if(queue->size > 0)
return 0;
return 1;
}
void
SDLVisualTest_EmptyActionQueue(SDLVisualTest_ActionQueue* queue)
{
if(queue)
{
while(!SDLVisualTest_IsActionQueueEmpty(queue))
SDLVisualTest_DequeueAction(queue);
}
}
/* Since the size of the queue is not likely to be larger than 100 elements
we can get away with using insertion sort. */
static void
SortQueue(SDLVisualTest_ActionQueue* queue)
{
SDLVisualTest_ActionNode* head;
SDLVisualTest_ActionNode* tail;
if(!queue || SDLVisualTest_IsActionQueueEmpty(queue))
return;
head = queue->front;
for(tail = head; tail && tail->next;)
{
SDLVisualTest_ActionNode* pos;
SDLVisualTest_ActionNode* element = tail->next;
if(element->action.time < head->action.time)
{
tail->next = tail->next->next;
element->next = head;
head = element;
}
else if(element->action.time >= tail->action.time)
{
tail = tail->next;
}
else
{
for(pos = head;
(pos->next->action.time < element->action.time);
pos = pos->next);
tail->next = tail->next->next;
element->next = pos->next;
pos->next = element;
}
}
queue->front = head;
queue->rear = tail;
}
int
SDLVisualTest_InsertIntoActionQueue(SDLVisualTest_ActionQueue* queue,
SDLVisualTest_Action action)
{
SDLVisualTest_ActionNode* n;
SDLVisualTest_ActionNode* prev;
SDLVisualTest_ActionNode* newnode;
if(!queue)
{
SDLTest_LogError("queue argument cannot be NULL");
return 0;
}
if(SDLVisualTest_IsActionQueueEmpty(queue))
{
if(!SDLVisualTest_EnqueueAction(queue, action))
{
SDLTest_LogError("SDLVisualTest_EnqueueAction() failed");
return 0;
}
return 1;
}
newnode = (SDLVisualTest_ActionNode*)SDL_malloc(sizeof(SDLVisualTest_ActionNode));
if(!newnode)
{
SDLTest_LogError("SDL_malloc() failed");
return 0;
}
newnode->action = action;
queue->size++;
for(n = queue->front, prev = NULL; n; n = n->next)
{
if(action.time < n->action.time)
{
if(prev)
{
prev->next = newnode;
newnode->next = n;
}
else
{
newnode->next = queue->front;
queue->front = newnode;
}
return 1;
}
prev = n;
}
queue->rear->next = newnode;
newnode->next = NULL;
queue->rear = newnode;
return 1;
}
int
SDLVisualTest_ParseActionConfig(const char* file, SDLVisualTest_ActionQueue* queue)
{
char line[MAX_ACTION_LINE_LENGTH];
SDLVisualTest_RWHelperBuffer buffer;
char* token_ptr;
int linenum;
SDL_RWops* rw;
if(!file)
{
SDLTest_LogError("file argument cannot be NULL");
return 0;
}
if(!queue)
{
SDLTest_LogError("queue argument cannot be NULL");
return 0;
}
rw = SDL_RWFromFile(file, "r");
if(!rw)
{
SDLTest_LogError("SDL_RWFromFile() failed");
return 0;
}
SDLVisualTest_RWHelperResetBuffer(&buffer);
SDLVisualTest_InitActionQueue(queue);
linenum = 0;
while(SDLVisualTest_RWHelperReadLine(rw, line, MAX_ACTION_LINE_LENGTH,
&buffer, '#'))
{
SDLVisualTest_Action action;
int hr, min, sec;
/* parse time */
token_ptr = strtok(line, " ");
if(!token_ptr ||
(SDL_sscanf(token_ptr, "%d:%d:%d", &hr, &min, &sec) != 3))
{
SDLTest_LogError("Could not parse time token at line: %d",
linenum);
SDLVisualTest_EmptyActionQueue(queue);
SDL_RWclose(rw);
return 0;
}
action.time = (((hr * 60 + min) * 60) + sec) * 1000;
/* parse type */
token_ptr = strtok(NULL, " ");
if(SDL_strcasecmp(token_ptr, "launch") == 0)
action.type = SDL_ACTION_LAUNCH;
else if(SDL_strcasecmp(token_ptr, "kill") == 0)
action.type = SDL_ACTION_KILL;
else if(SDL_strcasecmp(token_ptr, "quit") == 0)
action.type = SDL_ACTION_QUIT;
else if(SDL_strcasecmp(token_ptr, "screenshot") == 0)
action.type = SDL_ACTION_SCREENSHOT;
else if(SDL_strcasecmp(token_ptr, "verify") == 0)
action.type = SDL_ACTION_VERIFY;
else
{
SDLTest_LogError("Could not parse type token at line: %d",
linenum);
SDLVisualTest_EmptyActionQueue(queue);
SDL_RWclose(rw);
return 0;
}
/* parse the extra field */
if(action.type == SDL_ACTION_LAUNCH)
{
int len;
char* args;
char* path;
token_ptr = strtok(NULL, " ");
len = token_ptr ? SDL_strlen(token_ptr) : 0;
if(len <= 0)
{
SDLTest_LogError("Please specify the process to launch at line: %d",
linenum);
SDLVisualTest_EmptyActionQueue(queue);
SDL_RWclose(rw);
return 0;
}
path = (char*)SDL_malloc(sizeof(char) * (len + 1));
if(!path)
{
SDLTest_LogError("SDL_malloc() failed");
SDLVisualTest_EmptyActionQueue(queue);
SDL_RWclose(rw);
return 0;
}
SDL_strlcpy(path, token_ptr, len + 1);
token_ptr = strtok(NULL, "");
len = token_ptr ? SDL_strlen(token_ptr) : 0;
if(len > 0)
{
args = (char*)SDL_malloc(sizeof(char) * (len + 1));
if(!args)
{
SDLTest_LogError("SDL_malloc() failed");
SDL_free(path);
SDLVisualTest_EmptyActionQueue(queue);
SDL_RWclose(rw);
return 0;
}
SDL_strlcpy(args, token_ptr, len + 1);
}
else
args = NULL;
action.extra.process.path = path;
action.extra.process.args = args;
}
/* add the action to the queue */
if(!SDLVisualTest_EnqueueAction(queue, action))
{
SDLTest_LogError("SDLVisualTest_EnqueueAction() failed");
if(action.type == SDL_ACTION_LAUNCH)
{
SDL_free(action.extra.process.path);
if(action.extra.process.args)
SDL_free(action.extra.process.args);
}
SDLVisualTest_EmptyActionQueue(queue);
SDL_RWclose(rw);
return 0;
}
}
/* sort the queue of actions */
SortQueue(queue);
SDL_RWclose(rw);
return 1;
}

View File

@ -1,358 +0,0 @@
/* See LICENSE.txt for the full license governing this code. */
/**
* \file harness_argparser.c
*
* Source file for functions to parse arguments to the test harness.
*/
#include <SDL_test.h>
#include <stdio.h>
#include <string.h>
#include "SDL_visualtest_harness_argparser.h"
#include "SDL_visualtest_rwhelper.h"
/** Maximum length of one line in the config file */
#define MAX_CONFIG_LINE_LEN 400
/** Default value for the timeout after which the SUT is forcefully killed */
#define DEFAULT_SUT_TIMEOUT (60 * 1000)
/* String compare s1 and s2 ignoring leading hyphens */
static int
StrCaseCmpIgnoreHyphen(const char* s1, const char* s2)
{
/* treat NULL pointer as empty strings */
if(!s1)
s1 = "";
if(!s2)
s2 = "";
while(*s1 == '-')
s1++;
while(*s2 == '-')
s2++;
return SDL_strcasecmp(s1, s2);
}
/* parser an argument, updates the state object and returns the number of
arguments processed; returns -1 on failure */
static int
ParseArg(char** argv, int index, SDLVisualTest_HarnessState* state)
{
if(!argv || !argv[index] || !state)
return 0;
if(StrCaseCmpIgnoreHyphen("sutapp", argv[index]) == 0)
{
index++;
if(!argv[index])
{
SDLTest_LogError("Arguments parsing error: Invalid argument for sutapp.");
return -1;
}
SDL_strlcpy(state->sutapp, argv[index], MAX_PATH_LEN);
SDLTest_Log("SUT Application: %s", state->sutapp);
return 2;
}
else if(StrCaseCmpIgnoreHyphen("output-dir", argv[index]) == 0)
{
index++;
if(!argv[index])
{
SDLTest_LogError("Arguments parsing error: Invalid argument for output-dir.");
return -1;
}
SDL_strlcpy(state->output_dir, argv[index], MAX_PATH_LEN);
SDLTest_Log("Screenshot Output Directory: %s", state->output_dir);
return 2;
}
else if(StrCaseCmpIgnoreHyphen("verify-dir", argv[index]) == 0)
{
index++;
if(!argv[index])
{
SDLTest_LogError("Arguments parsing error: Invalid argument for verify-dir.");
return -1;
}
SDL_strlcpy(state->verify_dir, argv[index], MAX_PATH_LEN);
SDLTest_Log("Screenshot Verification Directory: %s", state->verify_dir);
return 2;
}
else if(StrCaseCmpIgnoreHyphen("sutargs", argv[index]) == 0)
{
index++;
if(!argv[index])
{
SDLTest_LogError("Arguments parsing error: Invalid argument for sutargs.");
return -1;
}
SDL_strlcpy(state->sutargs, argv[index], MAX_SUT_ARGS_LEN);
SDLTest_Log("SUT Arguments: %s", state->sutargs);
return 2;
}
else if(StrCaseCmpIgnoreHyphen("timeout", argv[index]) == 0)
{
int hr, min, sec;
index++;
if(!argv[index] || SDL_sscanf(argv[index], "%d:%d:%d", &hr, &min, &sec) != 3)
{
SDLTest_LogError("Arguments parsing error: Invalid argument for timeout.");
return -1;
}
state->timeout = (((hr * 60) + min) * 60 + sec) * 1000;
SDLTest_Log("Maximum Timeout for each SUT run: %d milliseconds",
state->timeout);
return 2;
}
else if(StrCaseCmpIgnoreHyphen("parameter-config", argv[index]) == 0)
{
index++;
if(!argv[index])
{
SDLTest_LogError("Arguments parsing error: Invalid argument for parameter-config.");
return -1;
}
SDLTest_Log("SUT Parameters file: %s", argv[index]);
SDLVisualTest_FreeSUTConfig(&state->sut_config);
if(!SDLVisualTest_ParseSUTConfig(argv[index], &state->sut_config))
{
SDLTest_LogError("Failed to parse SUT parameters file");
return -1;
}
return 2;
}
else if(StrCaseCmpIgnoreHyphen("variator", argv[index]) == 0)
{
index++;
if(!argv[index])
{
SDLTest_LogError("Arguments parsing error: Invalid argument for variator.");
return -1;
}
SDLTest_Log("Variator: %s", argv[index]);
if(SDL_strcasecmp("exhaustive", argv[index]) == 0)
state->variator_type = SDL_VARIATOR_EXHAUSTIVE;
else if(SDL_strcasecmp("random", argv[index]) == 0)
state->variator_type = SDL_VARIATOR_RANDOM;
else
{
SDLTest_LogError("Arguments parsing error: Invalid variator name.");
return -1;
}
return 2;
}
else if(StrCaseCmpIgnoreHyphen("num-variations", argv[index]) == 0)
{
index++;
if(!argv[index])
{
SDLTest_LogError("Arguments parsing error: Invalid argument for num-variations.");
return -1;
}
state->num_variations = SDL_atoi(argv[index]);
SDLTest_Log("Number of variations to run: %d", state->num_variations);
if(state->num_variations <= 0)
{
SDLTest_LogError("Arguments parsing error: num-variations must be positive.");
return -1;
}
return 2;
}
else if(StrCaseCmpIgnoreHyphen("no-launch", argv[index]) == 0)
{
state->no_launch = SDL_TRUE;
SDLTest_Log("SUT will not be launched.");
return 1;
}
else if(StrCaseCmpIgnoreHyphen("action-config", argv[index]) == 0)
{
index++;
if(!argv[index])
{
SDLTest_LogError("Arguments parsing error: invalid argument for action-config");
return -1;
}
SDLTest_Log("Action Config file: %s", argv[index]);
SDLVisualTest_EmptyActionQueue(&state->action_queue);
if(!SDLVisualTest_ParseActionConfig(argv[index], &state->action_queue))
{
SDLTest_LogError("SDLVisualTest_ParseActionConfig() failed");
return -1;
}
return 2;
}
else if(StrCaseCmpIgnoreHyphen("config", argv[index]) == 0)
{
index++;
if(!argv[index])
{
SDLTest_LogError("Arguments parsing error: invalid argument for config");
return -1;
}
/* do nothing, this option has already been handled */
return 2;
}
return 0;
}
/* TODO: Trailing/leading spaces and spaces between equals sign not supported. */
static int
ParseConfig(const char* file, SDLVisualTest_HarnessState* state)
{
SDL_RWops* rw;
SDLVisualTest_RWHelperBuffer buffer;
char line[MAX_CONFIG_LINE_LEN];
rw = SDL_RWFromFile(file, "r");
if(!rw)
{
SDLTest_LogError("SDL_RWFromFile() failed");
return 0;
}
SDLVisualTest_RWHelperResetBuffer(&buffer);
while(SDLVisualTest_RWHelperReadLine(rw, line, MAX_CONFIG_LINE_LEN,
&buffer, '#'))
{
char** argv;
int i, num_params;
/* count number of parameters and replace the trailing newline with 0 */
num_params = 1;
for(i = 0; line[i]; i++)
{
if(line[i] == '=')
{
num_params = 2;
break;
}
}
/* populate argv */
argv = (char**)SDL_malloc((num_params + 1) * sizeof(char*));
if(!argv)
{
SDLTest_LogError("SDL_malloc() failed.");
SDL_RWclose(rw);
return 0;
}
argv[num_params] = NULL;
for(i = 0; i < num_params; i++)
{
argv[i] = strtok(i == 0 ? line : NULL, "=");
}
if(ParseArg(argv, 0, state) == -1)
{
SDLTest_LogError("ParseArg() failed");
SDL_free(argv);
SDL_RWclose(rw);
return 0;
}
SDL_free(argv);
}
SDL_RWclose(rw);
if(!state->sutapp[0])
return 0;
return 1;
}
int
SDLVisualTest_ParseHarnessArgs(char** argv, SDLVisualTest_HarnessState* state)
{
int i;
SDLTest_Log("Parsing commandline arguments..");
if(!argv)
{
SDLTest_LogError("argv is NULL");
return 0;
}
if(!state)
{
SDLTest_LogError("state is NULL");
return 0;
}
/* initialize the state object */
state->sutargs[0] = '\0';
state->sutapp[0] = '\0';
state->output_dir[0] = '\0';
state->verify_dir[0] = '\0';
state->timeout = DEFAULT_SUT_TIMEOUT;
SDL_memset(&state->sut_config, 0, sizeof(SDLVisualTest_SUTConfig));
SDL_memset(&state->action_queue, 0, sizeof(SDLVisualTest_ActionQueue));
state->variator_type = SDL_VARIATOR_RANDOM;
state->num_variations = -1;
state->no_launch = SDL_FALSE;
/* parse config file if passed */
for(i = 0; argv[i]; i++)
{
if(StrCaseCmpIgnoreHyphen("config", argv[i]) == 0)
{
if(!argv[i + 1])
{
SDLTest_Log("Arguments parsing error: invalid argument for config.");
return 0;
}
if(!ParseConfig(argv[i + 1], state))
{
SDLTest_LogError("ParseConfig() failed");
return 0;
}
}
}
/* parse the arguments */
for(i = 0; argv[i];)
{
int consumed = ParseArg(argv, i, state);
if(consumed == -1 || consumed == 0)
{
SDLTest_LogError("ParseArg() failed");
return 0;
}
i += consumed;
}
if(state->variator_type == SDL_VARIATOR_RANDOM && state->num_variations == -1)
state->num_variations = 1;
/* check to see if required options have been passed */
if(!state->sutapp[0])
{
SDLTest_LogError("sutapp must be passed.");
return 0;
}
if(!state->sutargs[0] && !state->sut_config.options)
{
SDLTest_LogError("Either sutargs or parameter-config must be passed.");
return 0;
}
if(!state->output_dir[0])
{
SDL_strlcpy(state->output_dir, "./output", MAX_PATH_LEN);
}
if(!state->verify_dir[0])
{
SDL_strlcpy(state->verify_dir, "./verify", MAX_PATH_LEN);
}
return 1;
}
void
SDLVisualTest_FreeHarnessState(SDLVisualTest_HarnessState* state)
{
if(state)
{
SDLVisualTest_EmptyActionQueue(&state->action_queue);
SDLVisualTest_FreeSUTConfig(&state->sut_config);
}
}

View File

@ -1,208 +0,0 @@
/* See LICENSE.txt for the full license governing this code. */
/**
* \file linux_process.c
*
* Source file for the process API on linux.
*/
#include <SDL.h>
#include <SDL_test.h>
#include "SDL_visualtest_process.h"
#include "SDL_visualtest_harness_argparser.h"
#include "SDL_visualtest_parsehelper.h"
#if defined(__LINUX__)
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <errno.h>
static void
LogLastError(const char* str)
{
const char* error = strerror(errno);
if(!str || !error)
return;
SDLTest_LogError("%s: %s", str, error);
}
int
SDL_LaunchProcess(char* file, char* args, SDL_ProcessInfo* pinfo)
{
pid_t pid;
char** argv;
if(!file)
{
SDLTest_LogError("file argument cannot be NULL");
return 0;
}
if(!pinfo)
{
SDLTest_LogError("pinfo cannot be NULL");
return 0;
}
pid = fork();
if(pid == -1)
{
LogLastError("fork() failed");
return 0;
}
else if(pid == 0)
{
/* parse the arguments string */
argv = SDLVisualTest_ParseArgsToArgv(args);
argv[0] = file;
execv(file, argv);
LogLastError("execv() failed");
return 0;
}
else
{
pinfo->pid = pid;
return 1;
}
/* never executed */
return 0;
}
int
SDL_GetProcessExitStatus(SDL_ProcessInfo* pinfo, SDL_ProcessExitStatus* ps)
{
int success, status;
if(!pinfo)
{
SDLTest_LogError("pinfo argument cannot be NULL");
return 0;
}
if(!ps)
{
SDLTest_LogError("ps argument cannot be NULL");
return 0;
}
success = waitpid(pinfo->pid, &status, WNOHANG);
if(success == -1)
{
LogLastError("waitpid() failed");
return 0;
}
else if(success == 0)
{
ps->exit_status = -1;
ps->exit_success = 1;
}
else
{
ps->exit_success = WIFEXITED(status);
ps->exit_status = WEXITSTATUS(status);
}
return 1;
}
int
SDL_IsProcessRunning(SDL_ProcessInfo* pinfo)
{
int success;
if(!pinfo)
{
SDLTest_LogError("pinfo cannot be NULL");
return -1;
}
success = kill(pinfo->pid, 0);
if(success == -1)
{
if(errno == ESRCH) /* process is not running */
return 0;
else
{
LogLastError("kill() failed");
return -1;
}
}
return 1;
}
int
SDL_QuitProcess(SDL_ProcessInfo* pinfo, SDL_ProcessExitStatus* ps)
{
int success, status;
if(!pinfo)
{
SDLTest_LogError("pinfo argument cannot be NULL");
return 0;
}
if(!ps)
{
SDLTest_LogError("ps argument cannot be NULL");
return 0;
}
success = kill(pinfo->pid, SIGQUIT);
if(success == -1)
{
LogLastError("kill() failed");
return 0;
}
success = waitpid(pinfo->pid, &status, 0);
if(success == -1)
{
LogLastError("waitpid() failed");
return 0;
}
ps->exit_success = WIFEXITED(status);
ps->exit_status = WEXITSTATUS(status);
return 1;
}
int
SDL_KillProcess(SDL_ProcessInfo* pinfo, SDL_ProcessExitStatus* ps)
{
int success, status;
if(!pinfo)
{
SDLTest_LogError("pinfo argument cannot be NULL");
return 0;
}
if(!ps)
{
SDLTest_LogError("ps argument cannot be NULL");
return 0;
}
success = kill(pinfo->pid, SIGKILL);
if(success == -1)
{
LogLastError("kill() failed");
return 0;
}
success = waitpid(pinfo->pid, &status, 0);
if(success == -1)
{
LogLastError("waitpid() failed");
return 0;
}
ps->exit_success = WIFEXITED(status);
ps->exit_status = WEXITSTATUS(status);
return 1;
}
/* each window of the process will have a screenshot taken. The file name will be
prefix-i.png for the i'th window. */
int
SDLVisualTest_ScreenshotProcess(SDL_ProcessInfo* pinfo, char* prefix)
{
SDLTest_LogError("Screenshot process not implemented");
return 0;
}
#endif

View File

@ -1,28 +0,0 @@
/**
* \file mischelper.c
*
* Source file with miscellaneous helper functions.
*/
#include <SDL_test.h>
void
SDLVisualTest_HashString(char* str, char hash[33])
{
SDLTest_Md5Context md5c;
int i;
if(!str)
{
SDLTest_LogError("str argument cannot be NULL");
return;
}
SDLTest_Md5Init(&md5c);
SDLTest_Md5Update(&md5c, (unsigned char*)str, SDL_strlen(str));
SDLTest_Md5Final(&md5c);
/* convert the md5 hash to an array of hexadecimal digits */
for(i = 0; i < 16; i++)
SDL_snprintf(hash + 2 * i, 33 - 2 * i, "%02x", (int)md5c.digest[i]);
}

View File

@ -1,231 +0,0 @@
/* See LICENSE.txt for the full license governing this code. */
/**
* \file parsehelper.c
*
* Source file with some helper functions for parsing strings.
*/
#include <SDL_test.h>
#include "SDL_visualtest_harness_argparser.h"
/* this function uses a DFA to count the number of tokens in an agruments string.
state 0 is taken to be the start and end state. State 1 handles a double quoted
argument and state 2 handles unquoted arguments. */
static int
CountTokens(char* args)
{
int index, num_tokens;
int state; /* current state of the DFA */
if(!args)
return -1;
index = 0;
state = 0;
num_tokens = 0;
while(args[index])
{
char ch = args[index];
switch(state)
{
case 0:
if(ch == '\"')
{
state = 1;
num_tokens++;
}
else if(!SDL_isspace(ch))
{
state = 2;
num_tokens++;
}
break;
case 1:
if(ch == '\"')
{
state = 0;
}
break;
case 2:
if(SDL_isspace(ch))
{
state = 0;
}
break;
}
index++;
}
return num_tokens;
}
/* - size of tokens is num_tokens + 1
- uses the same DFA used in CountTokens() to split args into an array of strings */
static int
TokenizeHelper(char* str, char** tokens, int num_tokens, int max_token_len)
{
int index, state, done, st_index, token_index;
if(!str)
{
SDLTest_LogError("str argument cannot be NULL");
return 0;
}
if(!tokens)
{
SDLTest_LogError("tokens argument cannot be NULL");
return 0;
}
if(num_tokens <= 0)
{
SDLTest_LogError("num_tokens argument must be positive");
return 0;
}
if(max_token_len <= 0)
{
SDLTest_LogError("max_token_len argument must be positive");
return 0;
}
/* allocate memory for the tokens */
tokens[num_tokens] = NULL;
for(index = 0; index < num_tokens; index++)
{
tokens[index] = (char*)SDL_malloc(max_token_len);
if(!tokens[index])
{
int i;
SDLTest_LogError("SDL_malloc() failed.");
for(i = 0; i < index; i++)
SDL_free(tokens[i]);
return 0;
}
tokens[index][0] = '\0';
}
/* copy the tokens into the array */
st_index = 0;
index = 0;
token_index = 0;
state = 0;
done = 0;
while(!done)
{
char ch = str[index];
switch(state)
{
case 0:
if(ch == '\"')
{
state = 1;
st_index = index + 1;
}
else if(!ch)
done = 1;
else if(ch && !SDL_isspace(ch))
{
state = 2;
st_index = index;
}
break;
case 1:
if(ch == '\"')
{
int i;
state = 0;
for(i = st_index; i < index; i++)
{
tokens[token_index][i - st_index] = str[i];
}
tokens[token_index][i - st_index] = '\0';
token_index++;
}
else if(!ch)
{
SDLTest_LogError("Parsing Error!");
done = 1;
}
break;
case 2:
if(!ch)
done = 1;
if(SDL_isspace(ch) || !ch)
{
int i;
state = 0;
for(i = st_index; i < index; i++)
{
tokens[token_index][i - st_index] = str[i];
}
tokens[token_index][i - st_index] = '\0';
token_index++;
}
break;
}
index++;
}
return 1;
}
char**
SDLVisualTest_Tokenize(char* str, int max_token_len)
{
int num_tokens;
char** tokens;
if(!str)
{
SDLTest_LogError("str argument cannot be NULL");
return NULL;
}
if(max_token_len <= 0)
{
SDLTest_LogError("max_token_len argument must be positive");
return NULL;
}
num_tokens = CountTokens(str);
if(num_tokens == 0)
return NULL;
tokens = (char**)SDL_malloc(sizeof(char*) * (num_tokens + 1));
if(!TokenizeHelper(str, tokens, num_tokens, max_token_len))
{
SDLTest_LogError("TokenizeHelper() failed");
SDL_free(tokens);
return NULL;
}
return tokens;
}
char**
SDLVisualTest_ParseArgsToArgv(char* args)
{
char** argv;
int num_tokens;
num_tokens = CountTokens(args);
if(num_tokens == 0)
return NULL;
/* allocate space for arguments */
argv = (char**)SDL_malloc((num_tokens + 2) * sizeof(char*));
if(!argv)
{
SDLTest_LogError("SDL_malloc() failed.");
return NULL;
}
/* tokenize */
if(!TokenizeHelper(args, argv + 1, num_tokens, MAX_SUT_ARGS_LEN))
{
SDLTest_LogError("TokenizeHelper() failed");
SDL_free(argv);
return NULL;
}
argv[0] = NULL;
return argv;
}

View File

@ -1,131 +0,0 @@
/* See LICENSE.txt for the full license governing this code. */
/**
* \file rwhelper.c
*
* Source file with some helper functions for working with SDL_RWops.
*/
#include <SDL_test.h>
#include "SDL_visualtest_sut_configparser.h"
#include "SDL_visualtest_rwhelper.h"
void
SDLVisualTest_RWHelperResetBuffer(SDLVisualTest_RWHelperBuffer* buffer)
{
if(!buffer)
{
SDLTest_LogError("buffer argument cannot be NULL");
return;
}
buffer->buffer_pos = 0;
buffer->buffer_width = 0;
}
char
SDLVisualTest_RWHelperReadChar(SDL_RWops* rw, SDLVisualTest_RWHelperBuffer* buffer)
{
if(!rw || !buffer)
return 0;
/* if the buffer has been consumed, we fill it up again */
if(buffer->buffer_pos == buffer->buffer_width)
{
buffer->buffer_width = SDL_RWread(rw, buffer->buffer, 1, RWOPS_BUFFER_LEN);
buffer->buffer_pos = 0;
if(buffer->buffer_width == 0)
return 0;
}
buffer->buffer_pos++;
return buffer->buffer[buffer->buffer_pos - 1];
}
/* does not include new lines in the buffer and adds a trailing null character */
char*
SDLVisualTest_RWHelperReadLine(SDL_RWops* rw, char* str, int size,
SDLVisualTest_RWHelperBuffer* buffer,
char comment_char)
{
char ch;
int current_pos, done;
if(!rw)
{
SDLTest_LogError("rw argument cannot be NULL");
return NULL;
}
if(!str)
{
SDLTest_LogError("str argument cannot be NULL");
return NULL;
}
if(!buffer)
{
SDLTest_LogError("buffer argument cannot be NULL");
return NULL;
}
if(size <= 0)
{
SDLTest_LogError("size argument should be positive");
return NULL;
}
done = 0;
while(!done)
{
/* ignore leading whitespace */
for(ch = SDLVisualTest_RWHelperReadChar(rw, buffer); ch && SDL_isspace(ch);
ch = SDLVisualTest_RWHelperReadChar(rw, buffer));
for(current_pos = 0;
ch && ch != '\n' && ch != '\r' && ch != comment_char;
current_pos++)
{
str[current_pos] = ch;
if(current_pos >= size - 2)
{
current_pos++;
break;
}
ch = SDLVisualTest_RWHelperReadChar(rw, buffer);
}
done = 1;
if(ch == comment_char) /* discard all characters until the next line */
{
do
{
ch = SDLVisualTest_RWHelperReadChar(rw, buffer);
}while(ch && ch != '\n' && ch != '\r');
if(current_pos == 0)
done = 0;
}
}
if(current_pos == 0)
return NULL;
str[current_pos] = '\0';
return str;
}
/* Lines with all whitespace are ignored */
int
SDLVisualTest_RWHelperCountNonEmptyLines(SDL_RWops* rw,
SDLVisualTest_RWHelperBuffer* buffer,
char comment_char)
{
int num_lines = 0;
char str[MAX_SUTOPTION_LINE_LENGTH];
if(!rw)
{
SDLTest_LogError("rw argument cannot be NULL");
return -1;
}
if(!buffer)
{
SDLTest_LogError("buffer argument cannot be NULL");
return -1;
}
while(SDLVisualTest_RWHelperReadLine(rw, str, MAX_SUTOPTION_LINE_LENGTH,
buffer, comment_char))
num_lines++;
return num_lines;
}

View File

@ -1,136 +0,0 @@
/* See LICENSE.txt for the full license governing this code. */
/**
* \file screenshot.c
*
* Source file for the screenshot API.
*/
#include "SDL_visualtest_mischelper.h"
#include <SDL_test.h>
int
SDLVisualTest_VerifyScreenshots(char* args, char* test_dir, char* verify_dir)
{
int i, verify_len, return_code, test_len;
char hash[33];
char* verify_path; /* path to the bmp file used for verification */
char* test_path; /* path to the bmp file to be verified */
SDL_RWops* rw;
SDL_Surface* verifybmp;
return_code = 1;
if(!args)
{
SDLTest_LogError("args argument cannot be NULL");
return_code = -1;
goto verifyscreenshots_cleanup_generic;
}
if(!test_dir)
{
SDLTest_LogError("test_dir argument cannot be NULL");
return_code = -1;
goto verifyscreenshots_cleanup_generic;
}
if(!verify_dir)
{
SDLTest_LogError("verify_dir argument cannot be NULL");
return_code = -1;
goto verifyscreenshots_cleanup_generic;
}
/* generate the MD5 hash */
SDLVisualTest_HashString(args, hash);
/* find the verification image */
/* path_len + hash_len + some number of extra characters */
verify_len = SDL_strlen(verify_dir) + 32 + 10;
verify_path = (char*)SDL_malloc(verify_len * sizeof(char));
if(!verify_path)
{
SDLTest_LogError("SDL_malloc() failed");
return_code = -1;
goto verifyscreenshots_cleanup_generic;
}
SDL_snprintf(verify_path, verify_len - 1,
"%s/%s.bmp", verify_dir, hash);
rw = SDL_RWFromFile(verify_path, "rb");
if(!rw)
{
SDLTest_Log("Verification image does not exist."
" Please manually verify that the SUT is working correctly.");
return_code = 2;
goto verifyscreenshots_cleanup_verifypath;
}
/* load the verification image */
verifybmp = SDL_LoadBMP_RW(rw, 1);
if(!verifybmp)
{
SDLTest_LogError("SDL_LoadBMP_RW() failed");
return_code = -1;
goto verifyscreenshots_cleanup_verifypath;
}
/* load the test images and compare with the verification image */
/* path_len + hash_len + some number of extra characters */
test_len = SDL_strlen(test_dir) + 32 + 10;
test_path = (char*)SDL_malloc(test_len * sizeof(char));
if(!test_path)
{
SDLTest_LogError("SDL_malloc() failed");
return_code = -1;
goto verifyscreenshots_cleanup_verifybmp;
}
for(i = 1; ; i++)
{
SDL_RWops* testrw;
SDL_Surface* testbmp;
if(i == 1)
SDL_snprintf(test_path, test_len - 1, "%s/%s.bmp", test_dir, hash);
else
SDL_snprintf(test_path, test_len - 1, "%s/%s_%d.bmp", test_dir, hash, i);
testrw = SDL_RWFromFile(test_path, "rb");
/* we keep going until we've iterated through the screenshots each
SUT window */
if(!testrw)
break;
/* load the test screenshot */
testbmp = SDL_LoadBMP_RW(testrw, 1);
if(!testbmp)
{
SDLTest_LogError("SDL_LoadBMP_RW() failed");
return_code = -1;
goto verifyscreenshots_cleanup_verifybmp;
}
/* compare with the verification image */
if(SDLTest_CompareSurfaces(testbmp, verifybmp, 0) != 0)
{
return_code = 0;
SDL_FreeSurface(testbmp);
goto verifyscreenshots_cleanup_verifybmp;
}
SDL_FreeSurface(testbmp);
}
if(i == 1)
{
SDLTest_LogError("No verification images found");
return_code = -1;
}
verifyscreenshots_cleanup_verifybmp:
SDL_FreeSurface(verifybmp);
verifyscreenshots_cleanup_verifypath:
SDL_free(verify_path);
verifyscreenshots_cleanup_generic:
return return_code;
}

View File

@ -1,232 +0,0 @@
/* See LICENSE.txt for the full license governing this code. */
/**
* \file sut_configparser.c
*
* Source file for the parser for SUT config files.
*/
#include <limits.h>
#include <string.h>
#include <SDL_test.h>
#include <SDL_rwops.h>
#include "SDL_visualtest_sut_configparser.h"
#include "SDL_visualtest_parsehelper.h"
#include "SDL_visualtest_rwhelper.h"
int
SDLVisualTest_ParseSUTConfig(char* file, SDLVisualTest_SUTConfig* config)
{
char line[MAX_SUTOPTION_LINE_LENGTH];
SDLVisualTest_RWHelperBuffer buffer;
char* token_ptr;
char* token_end;
int num_lines, i, token_len;
SDL_RWops* rw;
if(!file)
{
SDLTest_LogError("file argument cannot be NULL");
return 0;
}
if(!config)
{
SDLTest_LogError("config argument cannot be NULL");
return 0;
}
/* count the number of lines */
rw = SDL_RWFromFile(file, "r");
if(!rw)
{
SDLTest_LogError("SDL_RWFromFile() failed");
return 0;
}
SDLVisualTest_RWHelperResetBuffer(&buffer);
num_lines = SDLVisualTest_RWHelperCountNonEmptyLines(rw, &buffer, '#');
if(num_lines == -1)
return 0;
else if(num_lines == 0)
{
config->options = NULL;
config->num_options = 0;
SDL_RWclose(rw);
return 1;
}
/* allocate memory */
SDL_RWseek(rw, 0, RW_SEEK_SET);
SDLVisualTest_RWHelperResetBuffer(&buffer);
config->num_options = num_lines;
config->options = (SDLVisualTest_SUTOption*)SDL_malloc(num_lines *
sizeof(SDLVisualTest_SUTOption));
if(!config->options)
{
SDLTest_LogError("SDL_malloc() failed");
SDL_RWclose(rw);
return 0;
}
/* actually parse the options */
for(i = 0; i < num_lines; i++)
{
if(!SDLVisualTest_RWHelperReadLine(rw, line, MAX_SUTOPTION_LINE_LENGTH,
&buffer, '#'))
{
SDLTest_LogError("SDLVisualTest_RWHelperReadLine() failed");
SDL_free(config->options);
SDL_RWclose(rw);
return 0;
}
/* parse name */
token_ptr = strtok(line, ", ");
if(!token_ptr)
{
SDLTest_LogError("Could not parse line %d", i + 1);
SDL_free(config->options);
SDL_RWclose(rw);
return 0;
}
token_len = SDL_strlen(token_ptr) + 1;
SDL_strlcpy(config->options[i].name, token_ptr, token_len);
/* parse type */
token_ptr = strtok(NULL, ", ");
if(!token_ptr)
{
SDLTest_LogError("Could not parse line %d", i + 1);
SDL_free(config->options);
SDL_RWclose(rw);
return 0;
}
if(SDL_strcmp(token_ptr, "string") == 0)
config->options[i].type = SDL_SUT_OPTIONTYPE_STRING;
else if(SDL_strcmp(token_ptr, "integer") == 0)
config->options[i].type = SDL_SUT_OPTIONTYPE_INT;
else if(SDL_strcmp(token_ptr, "enum") == 0)
config->options[i].type = SDL_SUT_OPTIONTYPE_ENUM;
else if(SDL_strcmp(token_ptr, "boolean") == 0)
config->options[i].type = SDL_SUT_OPTIONTYPE_BOOL;
else
{
SDLTest_LogError("Could not parse type token at line %d", i + 1);
SDL_free(config->options);
SDL_RWclose(rw);
return 0;
}
/* parse values */
token_ptr = strtok(NULL, "]");
if(!token_ptr)
{
SDLTest_LogError("Could not parse line %d", i + 1);
SDL_free(config->options);
SDL_RWclose(rw);
return 0;
}
token_ptr = SDL_strchr(token_ptr, '[');
if(!token_ptr)
{
SDLTest_LogError("Could not parse enum token at line %d", i + 1);
SDL_free(config->options);
SDL_RWclose(rw);
return 0;
}
token_ptr++;
if(config->options[i].type == SDL_SUT_OPTIONTYPE_INT)
{
if(SDL_sscanf(token_ptr, "%d %d", &config->options[i].data.range.min,
&config->options[i].data.range.max) != 2)
{
config->options[i].data.range.min = INT_MIN;
config->options[i].data.range.max = INT_MAX;
}
}
else if(config->options[i].type == SDL_SUT_OPTIONTYPE_ENUM)
{
config->options[i].data.enum_values = SDLVisualTest_Tokenize(token_ptr,
MAX_SUTOPTION_ENUMVAL_LEN);
if(!config->options[i].data.enum_values)
{
SDLTest_LogError("Could not parse enum token at line %d", i + 1);
SDL_free(config->options);
SDL_RWclose(rw);
return 0;
}
}
/* parse required */
token_ptr = strtok(NULL, ", ");
if(!token_ptr)
{
SDLTest_LogError("Could not parse line %d", i + 1);
SDL_free(config->options);
SDL_RWclose(rw);
return 0;
}
if(SDL_strcmp(token_ptr, "true") == 0)
config->options[i].required = SDL_TRUE;
else if(SDL_strcmp(token_ptr, "false") == 0)
config->options[i].required = SDL_FALSE;
else
{
SDLTest_LogError("Could not parse required token at line %d", i + 1);
SDL_free(config->options);
SDL_RWclose(rw);
return 0;
}
/* parse categories */
token_ptr = strtok(NULL, ",");
if(!token_ptr)
{
SDLTest_LogError("Could not parse line %d", i + 1);
SDL_free(config->options);
SDL_RWclose(rw);
return 0;
}
token_ptr = SDL_strchr(token_ptr, '[');
if(!token_ptr)
{
SDLTest_LogError("Could not parse enum token at line %d", i + 1);
SDL_free(config->options);
SDL_RWclose(rw);
return 0;
}
token_ptr++;
token_end = SDL_strchr(token_ptr, ']');
*token_end = '\0';
if(!token_end)
{
SDLTest_LogError("Could not parse enum token at line %d", i + 1);
SDL_free(config->options);
SDL_RWclose(rw);
return 0;
}
config->options[i].categories = SDLVisualTest_Tokenize(token_ptr,
MAX_SUTOPTION_CATEGORY_LEN);
}
SDL_RWclose(rw);
return 1;
}
void
SDLVisualTest_FreeSUTConfig(SDLVisualTest_SUTConfig* config)
{
if(config && config->options)
{
SDLVisualTest_SUTOption* option;
for(option = config->options;
option != config->options + config->num_options; option++)
{
if(option->categories)
SDL_free(option->categories);
if(option->type == SDL_SUT_OPTIONTYPE_ENUM && option->data.enum_values)
SDL_free(option->data.enum_values);
}
SDL_free(config->options);
config->options = NULL;
config->num_options = 0;
}
}

View File

@ -1,532 +0,0 @@
/* See LICENSE.txt for the full license governing this code. */
/**
* \file testharness.c
*
* Source file for the test harness.
*/
#include <stdlib.h>
#include <SDL_test.h>
#include <SDL.h>
#include <SDL_assert.h>
#include "SDL_visualtest_harness_argparser.h"
#include "SDL_visualtest_process.h"
#include "SDL_visualtest_variators.h"
#include "SDL_visualtest_screenshot.h"
#include "SDL_visualtest_mischelper.h"
#if defined(__WIN32__) && !defined(__CYGWIN__)
#include <direct.h>
#elif defined(__WIN32__) && defined(__CYGWIN__)
#include <signal.h>
#elif defined(__LINUX__)
#include <sys/stat.h>
#include <sys/types.h>
#include <signal.h>
#else
#error "Unsupported platform"
#endif
/** Code for the user event triggered when a new action is to be executed */
#define ACTION_TIMER_EVENT 0
/** Code for the user event triggered when the maximum timeout is reached */
#define KILL_TIMER_EVENT 1
/** FPS value used for delays in the action loop */
#define ACTION_LOOP_FPS 10
/** Value returned by RunSUTAndTest() when the test has passed */
#define TEST_PASSED 1
/** Value returned by RunSUTAndTest() when the test has failed */
#define TEST_FAILED 0
/** Value returned by RunSUTAndTest() on a fatal error */
#define TEST_ERROR -1
static SDL_ProcessInfo pinfo;
static SDL_ProcessExitStatus sut_exitstatus;
static SDLVisualTest_HarnessState state;
static SDLVisualTest_Variator variator;
static SDLVisualTest_ActionNode* current; /* the current action being performed */
static SDL_TimerID action_timer, kill_timer;
/* returns a char* to be passed as the format argument of a printf-style function. */
static const char*
usage(void)
{
return "Usage: \n%s --sutapp xyz"
" [--sutargs abc | --parameter-config xyz.parameters"
" [--variator exhaustive|random]"
" [--num-variations N] [--no-launch]] [--timeout hh:mm:ss]"
" [--action-config xyz.actions]"
" [--output-dir /path/to/output]"
" [--verify-dir /path/to/verify]"
" or --config app.config";
}
/* register Ctrl+C handlers */
#if defined(__LINUX__) || defined(__CYGWIN__)
static void
CtrlCHandlerCallback(int signum)
{
SDL_Event event;
SDLTest_Log("Ctrl+C received");
event.type = SDL_QUIT;
SDL_PushEvent(&event);
}
#endif
static Uint32
ActionTimerCallback(Uint32 interval, void* param)
{
SDL_Event event;
SDL_UserEvent userevent;
Uint32 next_action_time;
/* push an event to handle the action */
SDL_zero(userevent);
userevent.type = SDL_USEREVENT;
userevent.code = ACTION_TIMER_EVENT;
userevent.data1 = &current->action;
event.type = SDL_USEREVENT;
event.user = userevent;
SDL_PushEvent(&event);
/* calculate the new interval and return it */
if(current->next)
next_action_time = current->next->action.time - current->action.time;
else
{
next_action_time = 0;
action_timer = 0;
}
current = current->next;
return next_action_time;
}
static Uint32
KillTimerCallback(Uint32 interval, void* param)
{
SDL_Event event;
SDL_UserEvent userevent;
SDL_zero(userevent);
userevent.type = SDL_USEREVENT;
userevent.code = KILL_TIMER_EVENT;
event.type = SDL_USEREVENT;
event.user = userevent;
SDL_PushEvent(&event);
kill_timer = 0;
return 0;
}
static int
ProcessAction(SDLVisualTest_Action* action, int* sut_running, char* args)
{
if(!action || !sut_running)
return TEST_ERROR;
switch(action->type)
{
case SDL_ACTION_KILL:
SDLTest_Log("Action: Kill SUT");
if(SDL_IsProcessRunning(&pinfo) == 1 &&
!SDL_KillProcess(&pinfo, &sut_exitstatus))
{
SDLTest_LogError("SDL_KillProcess() failed");
return TEST_ERROR;
}
*sut_running = 0;
break;
case SDL_ACTION_QUIT:
SDLTest_Log("Action: Quit SUT");
if(SDL_IsProcessRunning(&pinfo) == 1 &&
!SDL_QuitProcess(&pinfo, &sut_exitstatus))
{
SDLTest_LogError("SDL_QuitProcess() failed");
return TEST_FAILED;
}
*sut_running = 0;
break;
case SDL_ACTION_LAUNCH:
{
char* path;
char* args;
SDL_ProcessInfo action_process;
SDL_ProcessExitStatus ps;
path = action->extra.process.path;
args = action->extra.process.args;
if(args)
{
SDLTest_Log("Action: Launch process: %s with arguments: %s",
path, args);
}
else
SDLTest_Log("Action: Launch process: %s", path);
if(!SDL_LaunchProcess(path, args, &action_process))
{
SDLTest_LogError("SDL_LaunchProcess() failed");
return TEST_ERROR;
}
/* small delay so that the process can do its job */
SDL_Delay(1000);
if(SDL_IsProcessRunning(&action_process) > 0)
{
SDLTest_LogError("Process %s took too long too complete."
" Force killing...", action->extra.process.path);
if(!SDL_KillProcess(&action_process, &ps))
{
SDLTest_LogError("SDL_KillProcess() failed");
return TEST_ERROR;
}
}
}
break;
case SDL_ACTION_SCREENSHOT:
{
char path[MAX_PATH_LEN], hash[33];
SDLTest_Log("Action: Take screenshot");
/* can't take a screenshot if the SUT isn't running */
if(SDL_IsProcessRunning(&pinfo) != 1)
{
SDLTest_LogError("SUT has quit.");
*sut_running = 0;
return TEST_FAILED;
}
/* file name for the screenshot image */
SDLVisualTest_HashString(args, hash);
SDL_snprintf(path, MAX_PATH_LEN, "%s/%s", state.output_dir, hash);
if(!SDLVisualTest_ScreenshotProcess(&pinfo, path))
{
SDLTest_LogError("SDLVisualTest_ScreenshotProcess() failed");
return TEST_ERROR;
}
}
break;
case SDL_ACTION_VERIFY:
{
int ret;
SDLTest_Log("Action: Verify screenshot");
ret = SDLVisualTest_VerifyScreenshots(args, state.output_dir,
state.verify_dir);
if(ret == -1)
{
SDLTest_LogError("SDLVisualTest_VerifyScreenshots() failed");
return TEST_ERROR;
}
else if(ret == 0)
{
SDLTest_Log("Verification failed: Images were not equal.");
return TEST_FAILED;
}
else if(ret == 1)
SDLTest_Log("Verification successful.");
else
{
SDLTest_Log("Verfication skipped.");
return TEST_FAILED;
}
}
break;
default:
SDLTest_LogError("Invalid action type");
return TEST_ERROR;
break;
}
return TEST_PASSED;
}
static int
RunSUTAndTest(char* sutargs, int variation_num)
{
int success, sut_running, return_code;
char hash[33];
SDL_Event event;
return_code = TEST_PASSED;
if(!sutargs)
{
SDLTest_LogError("sutargs argument cannot be NULL");
return_code = TEST_ERROR;
goto runsutandtest_cleanup_generic;
}
SDLVisualTest_HashString(sutargs, hash);
SDLTest_Log("Hash: %s", hash);
success = SDL_LaunchProcess(state.sutapp, sutargs, &pinfo);
if(!success)
{
SDLTest_Log("Could not launch SUT.");
return_code = TEST_ERROR;
goto runsutandtest_cleanup_generic;
}
SDLTest_Log("SUT launch successful.");
SDLTest_Log("Process will be killed in %d milliseconds", state.timeout);
sut_running = 1;
/* launch the timers */
SDLTest_Log("Performing actions..");
current = state.action_queue.front;
action_timer = 0;
kill_timer = 0;
if(current)
{
action_timer = SDL_AddTimer(current->action.time, ActionTimerCallback, NULL);
if(!action_timer)
{
SDLTest_LogError("SDL_AddTimer() failed");
return_code = TEST_ERROR;
goto runsutandtest_cleanup_timer;
}
}
kill_timer = SDL_AddTimer(state.timeout, KillTimerCallback, NULL);
if(!kill_timer)
{
SDLTest_LogError("SDL_AddTimer() failed");
return_code = TEST_ERROR;
goto runsutandtest_cleanup_timer;
}
/* the timer stops running if the actions queue is empty, and the
SUT stops running if it crashes or if we encounter a KILL/QUIT action */
while(sut_running)
{
/* process the actions by using an event queue */
while(SDL_PollEvent(&event))
{
if(event.type == SDL_USEREVENT)
{
if(event.user.code == ACTION_TIMER_EVENT)
{
SDLVisualTest_Action* action;
action = (SDLVisualTest_Action*)event.user.data1;
switch(ProcessAction(action, &sut_running, sutargs))
{
case TEST_PASSED:
break;
case TEST_FAILED:
return_code = TEST_FAILED;
goto runsutandtest_cleanup_timer;
break;
default:
SDLTest_LogError("ProcessAction() failed");
return_code = TEST_ERROR;
goto runsutandtest_cleanup_timer;
}
}
else if(event.user.code == KILL_TIMER_EVENT)
{
SDLTest_LogError("Maximum timeout reached. Force killing..");
return_code = TEST_FAILED;
goto runsutandtest_cleanup_timer;
}
}
else if(event.type == SDL_QUIT)
{
SDLTest_LogError("Received QUIT event. Testharness is quitting..");
return_code = TEST_ERROR;
goto runsutandtest_cleanup_timer;
}
}
SDL_Delay(1000/ACTION_LOOP_FPS);
}
SDLTest_Log("SUT exit code was: %d", sut_exitstatus.exit_status);
if(sut_exitstatus.exit_status == 0)
{
return_code = TEST_PASSED;
goto runsutandtest_cleanup_timer;
}
else
{
return_code = TEST_FAILED;
goto runsutandtest_cleanup_timer;
}
return_code = TEST_ERROR;
goto runsutandtest_cleanup_generic;
runsutandtest_cleanup_timer:
if(action_timer && !SDL_RemoveTimer(action_timer))
{
SDLTest_Log("SDL_RemoveTimer() failed");
return_code = TEST_ERROR;
}
if(kill_timer && !SDL_RemoveTimer(kill_timer))
{
SDLTest_Log("SDL_RemoveTimer() failed");
return_code = TEST_ERROR;
}
/* runsutandtest_cleanup_process: */
if(SDL_IsProcessRunning(&pinfo) && !SDL_KillProcess(&pinfo, &sut_exitstatus))
{
SDLTest_Log("SDL_KillProcess() failed");
return_code = TEST_ERROR;
}
runsutandtest_cleanup_generic:
return return_code;
}
/** Entry point for testharness */
int
main(int argc, char* argv[])
{
int i, passed, return_code, failed;
/* freeing resources, linux style! */
return_code = 0;
if(argc < 2)
{
SDLTest_Log(usage(), argv[0]);
goto cleanup_generic;
}
#if defined(__LINUX__) || defined(__CYGWIN__)
signal(SIGINT, CtrlCHandlerCallback);
#endif
/* parse arguments */
if(!SDLVisualTest_ParseHarnessArgs(argv + 1, &state))
{
SDLTest_Log(usage(), argv[0]);
return_code = 1;
goto cleanup_generic;
}
SDLTest_Log("Parsed harness arguments successfully.");
/* initialize SDL */
if(SDL_Init(SDL_INIT_TIMER) == -1)
{
SDLTest_LogError("SDL_Init() failed.");
SDLVisualTest_FreeHarnessState(&state);
return_code = 1;
goto cleanup_harness_state;
}
/* create an output directory if none exists */
#if defined(__LINUX__) || defined(__CYGWIN__)
mkdir(state.output_dir, 0777);
#elif defined(__WIN32__)
_mkdir(state.output_dir);
#else
#error "Unsupported platform"
#endif
/* test with sutargs */
if(SDL_strlen(state.sutargs))
{
SDLTest_Log("Running: %s %s", state.sutapp, state.sutargs);
if(!state.no_launch)
{
switch(RunSUTAndTest(state.sutargs, 0))
{
case TEST_PASSED:
SDLTest_Log("Status: PASSED");
break;
case TEST_FAILED:
SDLTest_Log("Status: FAILED");
break;
case TEST_ERROR:
SDLTest_LogError("Some error occurred while testing.");
return_code = 1;
goto cleanup_sdl;
break;
}
}
}
if(state.sut_config.num_options > 0)
{
const char* variator_name = (state.variator_type == SDL_VARIATOR_RANDOM) ?
"RANDOM" : "EXHAUSTIVE";
if(state.num_variations > 0)
SDLTest_Log("Testing SUT with variator: %s for %d variations",
variator_name, state.num_variations);
else
SDLTest_Log("Testing SUT with variator: %s and ALL variations",
variator_name);
/* initialize the variator */
if(!SDLVisualTest_InitVariator(&variator, &state.sut_config,
state.variator_type, 0))
{
SDLTest_LogError("Could not initialize variator");
return_code = 1;
goto cleanup_sdl;
}
/* iterate through all the variations */
passed = 0;
failed = 0;
for(i = 0; state.num_variations > 0 ? (i < state.num_variations) : 1; i++)
{
char* args = SDLVisualTest_GetNextVariation(&variator);
if(!args)
break;
SDLTest_Log("\nVariation number: %d\nArguments: %s", i + 1, args);
if(!state.no_launch)
{
switch(RunSUTAndTest(args, i + 1))
{
case TEST_PASSED:
SDLTest_Log("Status: PASSED");
passed++;
break;
case TEST_FAILED:
SDLTest_Log("Status: FAILED");
failed++;
break;
case TEST_ERROR:
SDLTest_LogError("Some error occurred while testing.");
goto cleanup_variator;
break;
}
}
}
if(!state.no_launch)
{
/* report stats */
SDLTest_Log("Testing complete.");
SDLTest_Log("%d/%d tests passed.", passed, passed + failed);
}
goto cleanup_variator;
}
goto cleanup_sdl;
cleanup_variator:
SDLVisualTest_FreeVariator(&variator);
cleanup_sdl:
SDL_Quit();
cleanup_harness_state:
SDLVisualTest_FreeHarnessState(&state);
cleanup_generic:
return return_code;
}

View File

@ -1,225 +0,0 @@
/* See LICENSE.txt for the full license governing this code. */
/**
* \file variator_common.c
*
* Source file for some common functionality used by variators.
*/
#include <SDL_test.h>
#include "SDL_visualtest_variator_common.h"
int
SDLVisualTest_NextValue(SDLVisualTest_SUTOptionValue* var,
SDLVisualTest_SUTOption* opt)
{
if(!var)
{
SDLTest_LogError("var argument cannot be NULL");
return -1;
}
if(!opt)
{
SDLTest_LogError("opt argument cannot be NULL");
return -1;
}
switch(opt->type)
{
case SDL_SUT_OPTIONTYPE_BOOL:
if(var->bool_value)
{
var->bool_value = SDL_FALSE;
return 1;
}
else
{
var->bool_value = SDL_TRUE;
return 0;
}
break;
case SDL_SUT_OPTIONTYPE_ENUM:
var->enumerated.index++;
if(!opt->data.enum_values[var->enumerated.index])
{
var->enumerated.index = 0;
return 1;
}
return 0;
break;
case SDL_SUT_OPTIONTYPE_INT:
{
int increment = (opt->data.range.max - opt->data.range.min) /
SDL_SUT_INTEGER_OPTION_TEST_STEPS;
/* prevents infinite loop when rounding */
if(increment == 0)
increment = 1;
var->integer.value += increment;
if(var->integer.value > opt->data.range.max)
{
var->integer.value = opt->data.range.min;
return 1;
}
return 0;
}
break;
case SDL_SUT_OPTIONTYPE_STRING:
return 1;
break;
}
return -1;
}
int
SDLVisualTest_MakeStrFromVariation(SDLVisualTest_Variation* variation,
SDLVisualTest_SUTConfig* config,
char* buffer, int size)
{
int i, index;
SDLVisualTest_SUTOptionValue* vars;
SDLVisualTest_SUTOption* options;
if(!variation)
{
SDLTest_LogError("variation argument cannot be NULL");
return 0;
}
if(!config)
{
SDLTest_LogError("config argument cannot be NULL");
return 0;
}
if(!buffer)
{
SDLTest_LogError("buffer argument cannot be NULL");
return 0;
}
if(size <= 0)
{
SDLTest_LogError("size argument should be positive");
return 0;
}
index = 0;
buffer[0] = '\0';
options = config->options;
vars = variation->vars;
for(i = 0; i < variation->num_vars; i++)
{
int n, enum_index;
if(index >= size - 1)
{
SDLTest_LogError("String did not fit in buffer size");
return 0;
}
switch(options[i].type)
{
case SDL_SUT_OPTIONTYPE_BOOL:
if(vars[i].bool_value)
{
n = SDL_snprintf(buffer + index, size - index, "%s ",
options[i].name);
if(n <= 0)
{
SDLTest_LogError("SDL_snprintf() failed");
return 0;
}
index += n;
}
break;
case SDL_SUT_OPTIONTYPE_ENUM:
if(vars[i].enumerated.on)
{
enum_index = vars[i].enumerated.index;
n = SDL_snprintf(buffer + index, size - index, "%s %s ",
options[i].name, options[i].data.enum_values[enum_index]);
index += n;
}
break;
case SDL_SUT_OPTIONTYPE_INT:
if(vars[i].integer.on)
{
n = SDL_snprintf(buffer + index, size - index, "%s %d ",
options[i].name, vars[i].integer.value);
index += n;
}
break;
case SDL_SUT_OPTIONTYPE_STRING:
if(vars[i].string.on)
{
n = SDL_snprintf(buffer + index, size - index, "%s %s ",
options[i].name, vars[i].string.value);
index += n;
}
break;
}
}
return 1;
}
int
SDLVisualTest_InitVariation(SDLVisualTest_Variation* variation,
SDLVisualTest_SUTConfig* config)
{
int i;
SDLVisualTest_SUTOptionValue* vars;
SDLVisualTest_SUTOption* options;
if(!variation)
{
SDLTest_LogError("variation argument cannot be NULL");
return 0;
}
if(!config)
{
SDLTest_LogError("config argument cannot be NULL");
return 0;
}
/* initialize the first variation */
if(config->num_options <= 0)
{
SDLTest_LogError("config->num_options must be positive");
return 0;
}
variation->vars = (SDLVisualTest_SUTOptionValue*)SDL_malloc(config->num_options *
sizeof(SDLVisualTest_SUTOptionValue));
if(!variation->vars)
{
SDLTest_LogError("SDL_malloc() failed");
return 0;
}
variation->num_vars = config->num_options;
vars = variation->vars;
options = config->options;
for(i = 0; i < variation->num_vars; i++)
{
switch(options[i].type)
{
case SDL_SUT_OPTIONTYPE_BOOL:
vars[i].bool_value = SDL_FALSE;
break;
case SDL_SUT_OPTIONTYPE_ENUM:
vars[i].enumerated.on = SDL_TRUE;
vars[i].enumerated.index = 0;
break;
case SDL_SUT_OPTIONTYPE_INT:
{
vars[i].integer.on = SDL_TRUE;
vars[i].integer.value = options[i].data.range.min;
}
break;
case SDL_SUT_OPTIONTYPE_STRING:
vars[i].string.on = SDL_TRUE;
vars[i].string.value = options[i].name;
break;
}
}
return 1;
}

View File

@ -1,133 +0,0 @@
/* See LICENSE.txt for the full license governing this code. */
/**
* \file variator_exhaustive.c
*
* Source file for the variator that tests the SUT with all the different
* variations of input parameters that are valid.
*/
#include <time.h>
#include <SDL_test.h>
#include "SDL_visualtest_sut_configparser.h"
#include "SDL_visualtest_exhaustive_variator.h"
static int
NextVariation(SDLVisualTest_Variation* variation,
SDLVisualTest_SUTConfig* config)
{
int i, carry;
if(!variation)
{
SDLTest_LogError("variation argument cannot be NULL");
return -1;
}
if(!config)
{
SDLTest_LogError("config argument cannot be NULL");
return -1;
}
carry = 1;
for(i = 0; i < variation->num_vars; i++)
{
carry = SDLVisualTest_NextValue(&variation->vars[i], &config->options[i]);
if(carry != 1)
break;
}
if(carry == 1) /* we're done, we've tried all possible variations */
return 0;
if(carry == 0)
return 1;
SDLTest_LogError("NextVariation() failed");
return -1;
}
int
SDLVisualTest_InitExhaustiveVariator(SDLVisualTest_ExhaustiveVariator* variator,
SDLVisualTest_SUTConfig* config)
{
if(!variator)
{
SDLTest_LogError("variator argument cannot be NULL");
return 0;
}
if(!config)
{
SDLTest_LogError("config argument cannot be NULL");
return 0;
}
SDLTest_FuzzerInit(time(NULL));
variator->config = *config;
variator->variation.num_vars = 0;
variator->variation.vars = NULL;
return 1;
}
/* TODO: Right now variations where an option is not specified at all are not
tested for. This can be implemented by switching the on attribute for integer,
enum and string options to true and false. */
char*
SDLVisualTest_GetNextExhaustiveVariation(SDLVisualTest_ExhaustiveVariator* variator)
{
int success;
if(!variator)
{
SDLTest_LogError("variator argument cannot be NULL");
return NULL;
}
if(!variator->variation.vars) /* the first time this function is called */
{
success = SDLVisualTest_InitVariation(&variator->variation,
&variator->config);
if(!success)
{
SDLTest_LogError("SDLVisualTest_InitVariation() failed");
return NULL;
}
success = SDLVisualTest_MakeStrFromVariation(&variator->variation,
&variator->config, variator->buffer, MAX_SUT_ARGS_LEN);
if(!success)
{
SDLTest_LogError("SDLVisualTest_MakeStrFromVariation() failed");
return NULL;
}
return variator->buffer;
}
else
{
success = NextVariation(&variator->variation, &variator->config);
if(success == 1)
{
success = SDLVisualTest_MakeStrFromVariation(&variator->variation,
&variator->config, variator->buffer, MAX_SUT_ARGS_LEN);
if(!success)
{
SDLTest_LogError("SDLVisualTest_MakeStrFromVariation() failed");
return NULL;
}
return variator->buffer;
}
else if(success == -1)
SDLTest_LogError("NextVariation() failed.");
return NULL;
}
return NULL;
}
void
SDLVisualTest_FreeExhaustiveVariator(SDLVisualTest_ExhaustiveVariator* variator)
{
if(!variator)
{
SDLTest_LogError("variator argument cannot be NULL");
return;
}
SDL_free(variator->variation.vars);
variator->variation.vars = NULL;
}

View File

@ -1,113 +0,0 @@
/* See LICENSE.txt for the full license governing this code. */
/**
* \file variator_random.c
*
* Source file for the variator that tests the SUT with random variations to the
* input parameters.
*/
#include <time.h>
#include <SDL_test.h>
#include "SDL_visualtest_random_variator.h"
int
SDLVisualTest_InitRandomVariator(SDLVisualTest_RandomVariator* variator,
SDLVisualTest_SUTConfig* config, Uint64 seed)
{
if(!variator)
{
SDLTest_LogError("variator argument cannot be NULL");
return 0;
}
if(!config)
{
SDLTest_LogError("config argument cannot be NULL");
return 0;
}
if(seed)
SDLTest_FuzzerInit(seed);
else
SDLTest_FuzzerInit(time(NULL));
variator->config = *config;
if(!SDLVisualTest_InitVariation(&variator->variation, &variator->config))
{
SDLTest_LogError("SDLVisualTest_InitVariation() failed");
return 0;
}
return 1;
}
char*
SDLVisualTest_GetNextRandomVariation(SDLVisualTest_RandomVariator* variator)
{
SDLVisualTest_SUTOptionValue* vars;
SDLVisualTest_SUTOption* options;
int i;
if(!variator)
{
SDLTest_LogError("variator argument cannot be NULL");
return NULL;
}
/* to save typing */
vars = variator->variation.vars;
options = variator->config.options;
/* generate a random variation */
for(i = 0; i < variator->variation.num_vars; i++)
{
switch(options[i].type)
{
case SDL_SUT_OPTIONTYPE_BOOL:
vars[i].bool_value = SDLTest_RandomIntegerInRange(0, 1) ? SDL_FALSE :
SDL_TRUE;
break;
case SDL_SUT_OPTIONTYPE_ENUM:
{
int emx = 0;
while(options[i].data.enum_values[emx])
emx++;
vars[i].enumerated.index = SDLTest_RandomIntegerInRange(0, emx - 1);
}
break;
case SDL_SUT_OPTIONTYPE_INT:
vars[i].integer.value = SDLTest_RandomIntegerInRange(
options[i].data.range.min,
options[i].data.range.max);
break;
case SDL_SUT_OPTIONTYPE_STRING:
// String values are left unchanged
break;
}
}
/* convert variation to an arguments string */
if(!SDLVisualTest_MakeStrFromVariation(&variator->variation, &variator->config,
variator->buffer, MAX_SUT_ARGS_LEN))
{
SDLTest_LogError("SDLVisualTest_MakeStrFromVariation() failed");
return NULL;
}
return variator->buffer;
}
void SDLVisualTest_FreeRandomVariator(SDLVisualTest_RandomVariator* variator)
{
if(!variator)
{
SDLTest_LogError("variator argument cannot be NULL");
return;
}
SDL_free(variator->variation.vars);
variator->variation.vars = NULL;
}

View File

@ -1,95 +0,0 @@
/* See LICENSE.txt for the full license governing this code. */
/**
* \file variators.c
*
* Source file for the operations that act on variators.
*/
#include <SDL_test.h>
#include "SDL_visualtest_variators.h"
int
SDLVisualTest_InitVariator(SDLVisualTest_Variator* variator,
SDLVisualTest_SUTConfig* config,
SDLVisualTest_VariatorType type,
Uint64 seed)
{
if(!variator)
{
SDLTest_LogError("variator argument cannot be NULL");
return 0;
}
if(!config)
{
SDLTest_LogError("config argument cannot be NULL");
return 0;
}
variator->type = type;
switch(type)
{
case SDL_VARIATOR_EXHAUSTIVE:
return SDLVisualTest_InitExhaustiveVariator(&variator->data.exhaustive,
config);
break;
case SDL_VARIATOR_RANDOM:
return SDLVisualTest_InitRandomVariator(&variator->data.random,
config, seed);
break;
default:
SDLTest_LogError("Invalid value for variator type");
return 0;
}
return 0;
}
char*
SDLVisualTest_GetNextVariation(SDLVisualTest_Variator* variator)
{
if(!variator)
{
SDLTest_LogError("variator argument cannot be NULL");
return NULL;
}
switch(variator->type)
{
case SDL_VARIATOR_EXHAUSTIVE:
return SDLVisualTest_GetNextExhaustiveVariation(&variator->data.exhaustive);
break;
case SDL_VARIATOR_RANDOM:
return SDLVisualTest_GetNextRandomVariation(&variator->data.random);
break;
default:
SDLTest_LogError("Invalid value for variator type");
return NULL;
}
return NULL;
}
void SDLVisualTest_FreeVariator(SDLVisualTest_Variator* variator)
{
if(!variator)
{
SDLTest_LogError("variator argument cannot be NULL");
return;
}
switch(variator->type)
{
case SDL_VARIATOR_EXHAUSTIVE:
SDLVisualTest_FreeExhaustiveVariator(&variator->data.exhaustive);
break;
case SDL_VARIATOR_RANDOM:
SDLVisualTest_FreeRandomVariator(&variator->data.random);
break;
default:
SDLTest_LogError("Invalid value for variator type");
}
}

View File

@ -1,283 +0,0 @@
/* See LICENSE.txt for the full license governing this code. */
/**
* \file windows_process.c
*
* Source file for the process API on windows.
*/
#include <SDL.h>
#include <SDL_test.h>
#include <string.h>
#include <stdlib.h>
#include "SDL_visualtest_process.h"
#if defined(__WIN32__)
void
LogLastError(const char* str)
{
LPVOID buffer;
DWORD dw = GetLastError();
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|
FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&buffer,
0, NULL);
SDLTest_LogError("%s: %s", str, (char*)buffer);
LocalFree(buffer);
}
int
SDL_LaunchProcess(char* file, char* args, SDL_ProcessInfo* pinfo)
{
BOOL success;
char* working_directory;
char* command_line;
int path_length, args_length;
STARTUPINFO sui = {0};
sui.cb = sizeof(sui);
if(!file)
{
SDLTest_LogError("Path to executable to launched cannot be NULL.");
return 0;
}
if(!pinfo)
{
SDLTest_LogError("pinfo cannot be NULL.");
return 0;
}
/* get the working directory of the process being launched, so that
the process can load any resources it has in it's working directory */
path_length = SDL_strlen(file);
if(path_length == 0)
{
SDLTest_LogError("Length of the file parameter is zero.");
return 0;
}
working_directory = (char*)SDL_malloc(path_length + 1);
if(!working_directory)
{
SDLTest_LogError("Could not allocate working_directory - SDL_malloc() failed.");
return 0;
}
SDL_memcpy(working_directory, file, path_length + 1);
PathRemoveFileSpec(working_directory);
if(SDL_strlen(working_directory) == 0)
{
SDL_free(working_directory);
working_directory = NULL;
}
/* join the file path and the args string together */
if(!args)
args = "";
args_length = SDL_strlen(args);
command_line = (char*)SDL_malloc(path_length + args_length + 2);
if(!command_line)
{
SDLTest_LogError("Could not allocate command_line - SDL_malloc() failed.");
return 0;
}
SDL_memcpy(command_line, file, path_length);
command_line[path_length] = ' ';
SDL_memcpy(command_line + path_length + 1, args, args_length + 1);
/* create the process */
success = CreateProcess(NULL, command_line, NULL, NULL, FALSE,
NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW,
NULL, working_directory, &sui, &pinfo->pi);
if(working_directory)
{
SDL_free(working_directory);
working_directory = NULL;
}
SDL_free(command_line);
if(!success)
{
LogLastError("CreateProcess() failed");
return 0;
}
return 1;
}
int
SDL_GetProcessExitStatus(SDL_ProcessInfo* pinfo, SDL_ProcessExitStatus* ps)
{
DWORD exit_status;
BOOL success;
if(!pinfo)
{
SDLTest_LogError("pinfo cannot be NULL");
return 0;
}
if(!ps)
{
SDLTest_LogError("ps cannot be NULL");
return 0;
}
/* get the exit code */
success = GetExitCodeProcess(pinfo->pi.hProcess, &exit_status);
if(!success)
{
LogLastError("GetExitCodeProcess() failed");
return 0;
}
if(exit_status == STILL_ACTIVE)
ps->exit_status = -1;
else
ps->exit_status = exit_status;
ps->exit_success = 1;
return 1;
}
int
SDL_IsProcessRunning(SDL_ProcessInfo* pinfo)
{
DWORD exit_status;
BOOL success;
if(!pinfo)
{
SDLTest_LogError("pinfo cannot be NULL");
return -1;
}
success = GetExitCodeProcess(pinfo->pi.hProcess, &exit_status);
if(!success)
{
LogLastError("GetExitCodeProcess() failed");
return -1;
}
if(exit_status == STILL_ACTIVE)
return 1;
return 0;
}
static BOOL CALLBACK
CloseWindowCallback(HWND hwnd, LPARAM lparam)
{
DWORD pid;
SDL_ProcessInfo* pinfo;
pinfo = (SDL_ProcessInfo*)lparam;
GetWindowThreadProcessId(hwnd, &pid);
if(pid == pinfo->pi.dwProcessId)
{
DWORD_PTR result;
if(!SendMessageTimeout(hwnd, WM_CLOSE, 0, 0, SMTO_BLOCK,
1000, &result))
{
if(GetLastError() != ERROR_TIMEOUT)
{
LogLastError("SendMessageTimeout() failed");
return FALSE;
}
}
}
return TRUE;
}
int
SDL_QuitProcess(SDL_ProcessInfo* pinfo, SDL_ProcessExitStatus* ps)
{
DWORD wait_result;
if(!pinfo)
{
SDLTest_LogError("pinfo argument cannot be NULL");
return 0;
}
if(!ps)
{
SDLTest_LogError("ps argument cannot be NULL");
return 0;
}
/* enumerate through all the windows, trying to close each one */
if(!EnumWindows(CloseWindowCallback, (LPARAM)pinfo))
{
SDLTest_LogError("EnumWindows() failed");
return 0;
}
/* wait until the process terminates */
wait_result = WaitForSingleObject(pinfo->pi.hProcess, 1000);
if(wait_result == WAIT_FAILED)
{
LogLastError("WaitForSingleObject() failed");
return 0;
}
if(wait_result != WAIT_OBJECT_0)
{
SDLTest_LogError("Process did not quit.");
return 0;
}
/* get the exit code */
if(!SDL_GetProcessExitStatus(pinfo, ps))
{
SDLTest_LogError("SDL_GetProcessExitStatus() failed");
return 0;
}
return 1;
}
int
SDL_KillProcess(SDL_ProcessInfo* pinfo, SDL_ProcessExitStatus* ps)
{
BOOL success;
DWORD exit_status, wait_result;
if(!pinfo)
{
SDLTest_LogError("pinfo argument cannot be NULL");
return 0;
}
if(!ps)
{
SDLTest_LogError("ps argument cannot be NULL");
return 0;
}
/* initiate termination of the process */
success = TerminateProcess(pinfo->pi.hProcess, 0);
if(!success)
{
LogLastError("TerminateProcess() failed");
return 0;
}
/* wait until the process terminates */
wait_result = WaitForSingleObject(pinfo->pi.hProcess, INFINITE);
if(wait_result == WAIT_FAILED)
{
LogLastError("WaitForSingleObject() failed");
return 0;
}
/* get the exit code */
success = GetExitCodeProcess(pinfo->pi.hProcess, &exit_status);
if(!success)
{
LogLastError("GetExitCodeProcess() failed");
return 0;
}
ps->exit_status = exit_status;
ps->exit_success = 1;
return 1;
}
#endif

View File

@ -1,349 +0,0 @@
/* See LICENSE.txt for the full license governing this code. */
/**
* \file windows_screenshot.c
*
* Source file for the screenshot API on windows.
*/
#include "SDL_visualtest_process.h"
#include <SDL.h>
#include <SDL_test.h>
#if defined(__CYGWIN__)
#include <sys/stat.h>
#endif
#if defined(__WIN32__)
#include <windows.h>
void LogLastError(const char* str);
static int img_num;
static SDL_ProcessInfo screenshot_pinfo;
/* Saves a bitmap to a file using hdc as a device context */
static int
SaveBitmapToFile(HDC hdc, HBITMAP hbitmap, char* filename)
{
BITMAP bitmap;
BITMAPFILEHEADER bfh;
BITMAPINFOHEADER bih;
DWORD bmpsize, bytes_written;
HANDLE hdib, hfile;
char* bmpdata;
int return_code = 1;
if(!hdc)
{
SDLTest_LogError("hdc argument is NULL");
return 0;
}
if(!hbitmap)
{
SDLTest_LogError("hbitmap argument is NULL");
return 0;
}
if(!filename)
{
SDLTest_LogError("filename argument is NULL");
return 0;
}
if(!GetObject(hbitmap, sizeof(BITMAP), (void*)&bitmap))
{
SDLTest_LogError("GetObject() failed");
return_code = 0;
goto savebitmaptofile_cleanup_generic;
}
bih.biSize = sizeof(BITMAPINFOHEADER);
bih.biWidth = bitmap.bmWidth;
bih.biHeight = bitmap.bmHeight;
bih.biPlanes = 1;
bih.biBitCount = 32;
bih.biCompression = BI_RGB;
bih.biSizeImage = 0;
bih.biXPelsPerMeter = 0;
bih.biYPelsPerMeter = 0;
bih.biClrUsed = 0;
bih.biClrImportant = 0;
bmpsize = ((bitmap.bmWidth * bih.biBitCount + 31) / 32) * 4 * bitmap.bmHeight;
hdib = GlobalAlloc(GHND, bmpsize);
if(!hdib)
{
LogLastError("GlobalAlloc() failed");
return_code = 0;
goto savebitmaptofile_cleanup_generic;
}
bmpdata = (char*)GlobalLock(hdib);
if(!bmpdata)
{
LogLastError("GlobalLock() failed");
return_code = 0;
goto savebitmaptofile_cleanup_hdib;
}
if(!GetDIBits(hdc, hbitmap, 0, (UINT)bitmap.bmHeight, bmpdata,
(LPBITMAPINFO)&bih, DIB_RGB_COLORS))
{
SDLTest_LogError("GetDIBits() failed");
return_code = 0;
goto savebitmaptofile_cleanup_unlockhdib;
}
hfile = CreateFile(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
if(hfile == INVALID_HANDLE_VALUE)
{
LogLastError("CreateFile()");
return_code = 0;
goto savebitmaptofile_cleanup_unlockhdib;
}
bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
bfh.bfSize = bmpsize + bfh.bfOffBits;
bfh.bfType = 0x4D42;
bytes_written = 0;
if(!WriteFile(hfile, (void*)&bfh, sizeof(BITMAPFILEHEADER), &bytes_written, NULL) ||
!WriteFile(hfile, (void*)&bih, sizeof(BITMAPINFOHEADER), &bytes_written, NULL) ||
!WriteFile(hfile, (void*)bmpdata, bmpsize, &bytes_written, NULL))
{
LogLastError("WriteFile() failed");
return_code = 0;
goto savebitmaptofile_cleanup_hfile;
}
savebitmaptofile_cleanup_hfile:
CloseHandle(hfile);
/* make the screenshot file writable on cygwin, since it could be overwritten later */
#if defined(__CYGWIN__)
if(chmod(filename, 0777) == -1)
{
SDLTest_LogError("chmod() failed");
return_code = 0;
}
#endif
savebitmaptofile_cleanup_unlockhdib:
GlobalUnlock(hdib);
savebitmaptofile_cleanup_hdib:
GlobalFree(hdib);
savebitmaptofile_cleanup_generic:
return return_code;
}
/* Takes the screenshot of a window and saves it to a file. If only_client_area
is true, then only the client area of the window is considered */
static int
ScreenshotWindow(HWND hwnd, char* filename, SDL_bool only_client_area)
{
int width, height;
RECT dimensions;
HDC windowdc, capturedc;
HBITMAP capturebitmap;
HGDIOBJ select_success;
BOOL blt_success;
int return_code = 1;
if(!filename)
{
SDLTest_LogError("filename argument cannot be NULL");
return_code = 0;
goto screenshotwindow_cleanup_generic;
}
if(!hwnd)
{
SDLTest_LogError("hwnd argument cannot be NULL");
return_code = 0;
goto screenshotwindow_cleanup_generic;
}
if(!GetWindowRect(hwnd, &dimensions))
{
LogLastError("GetWindowRect() failed");
return_code = 0;
goto screenshotwindow_cleanup_generic;
}
if(only_client_area)
{
RECT crect;
if(!GetClientRect(hwnd, &crect))
{
SDLTest_LogError("GetClientRect() failed");
return_code = 0;
goto screenshotwindow_cleanup_generic;
}
width = crect.right;
height = crect.bottom;
windowdc = GetDC(hwnd);
if(!windowdc)
{
SDLTest_LogError("GetDC() failed");
return_code = 0;
goto screenshotwindow_cleanup_generic;
}
}
else
{
width = dimensions.right - dimensions.left;
height = dimensions.bottom - dimensions.top;
windowdc = GetWindowDC(hwnd);
if(!windowdc)
{
SDLTest_LogError("GetWindowDC() failed");
return_code = 0;
goto screenshotwindow_cleanup_generic;
}
}
capturedc = CreateCompatibleDC(windowdc);
if(!capturedc)
{
SDLTest_LogError("CreateCompatibleDC() failed");
return_code = 0;
goto screenshotwindow_cleanup_windowdc;
}
capturebitmap = CreateCompatibleBitmap(windowdc, width, height);
if(!capturebitmap)
{
SDLTest_LogError("CreateCompatibleBitmap() failed");
return_code = 0;
goto screenshotwindow_cleanup_capturedc;
}
select_success = SelectObject(capturedc, capturebitmap);
if(!select_success || select_success == HGDI_ERROR)
{
SDLTest_LogError("SelectObject() failed");
return_code = 0;
goto screenshotwindow_cleanup_capturebitmap;
}
blt_success = BitBlt(capturedc, 0, 0, width, height, windowdc,
0, 0, SRCCOPY|CAPTUREBLT);
if(!blt_success)
{
LogLastError("BitBlt() failed");
return_code = 0;
goto screenshotwindow_cleanup_capturebitmap;
}
/* save bitmap as file */
if(!SaveBitmapToFile(windowdc, capturebitmap, filename))
{
SDLTest_LogError("SaveBitmapToFile() failed");
return_code = 0;
goto screenshotwindow_cleanup_capturebitmap;
}
/* Free resources */
screenshotwindow_cleanup_capturebitmap:
if(!DeleteObject(capturebitmap))
{
SDLTest_LogError("DeleteObjectFailed");
return_code = 0;
}
screenshotwindow_cleanup_capturedc:
if(!DeleteDC(capturedc))
{
SDLTest_LogError("DeleteDC() failed");
return_code = 0;
}
screenshotwindow_cleanup_windowdc:
if(!ReleaseDC(hwnd, windowdc))
{
SDLTest_LogError("ReleaseDC() failed");
return_code = 0;
}
screenshotwindow_cleanup_generic:
return return_code;
}
/* Takes the screenshot of the entire desktop and saves it to a file */
int SDLVisualTest_ScreenshotDesktop(char* filename)
{
HWND hwnd;
hwnd = GetDesktopWindow();
return ScreenshotWindow(hwnd, filename, SDL_FALSE);
}
/* take screenshot of a window and save it to a file */
static BOOL CALLBACK
ScreenshotHwnd(HWND hwnd, LPARAM lparam)
{
int len;
DWORD pid;
char* prefix;
char* filename;
GetWindowThreadProcessId(hwnd, &pid);
if(pid != screenshot_pinfo.pi.dwProcessId)
return TRUE;
if(!IsWindowVisible(hwnd))
return TRUE;
prefix = (char*)lparam;
len = SDL_strlen(prefix) + 100;
filename = (char*)SDL_malloc(len * sizeof(char));
if(!filename)
{
SDLTest_LogError("SDL_malloc() failed");
return FALSE;
}
/* restore the window and bring it to the top */
ShowWindowAsync(hwnd, SW_RESTORE);
/* restore is not instantaneous */
SDL_Delay(500);
/* take a screenshot of the client area */
if(img_num == 1)
SDL_snprintf(filename, len, "%s.bmp", prefix);
else
SDL_snprintf(filename, len, "%s_%d.bmp", prefix, img_num);
img_num++;
ScreenshotWindow(hwnd, filename, SDL_TRUE);
SDL_free(filename);
return TRUE;
}
/* each window of the process will have a screenshot taken. The file name will be
prefix-i.png for the i'th window. */
int
SDLVisualTest_ScreenshotProcess(SDL_ProcessInfo* pinfo, char* prefix)
{
if(!pinfo)
{
SDLTest_LogError("pinfo argument cannot be NULL");
return 0;
}
if(!prefix)
{
SDLTest_LogError("prefix argument cannot be NULL");
return 0;
}
img_num = 1;
screenshot_pinfo = *pinfo;
if(!EnumWindows(ScreenshotHwnd, (LPARAM)prefix))
{
SDLTest_LogError("EnumWindows() failed");
return 0;
}
return 1;
}
#endif

View File

@ -1,3 +0,0 @@
00:00:02 SCREENSHOT # Take a screenshot of each window owned by the SUT process
00:00:05 VERIFY # Verify each screenshot taken with verification images
00:00:10 QUIT # Gracefully quit the SUT process

View File

@ -1,6 +0,0 @@
parameter-config=testsprite2_sample.parameters
num-variations=10
variator=random
sutapp=testsprite2
timeout=00:00:20
action-config=testsprite2_sample.actions

View File

@ -1,29 +0,0 @@
# parameter name, type, value range, required, categories
--gldebug, boolean, [], false, []
--info, enum, [all video modes render event], false, []
--log, enum, [all error system audio video render input], false, []
--display, integer, [1 5], false, []
--fullscreen, boolean, [], false, []
--fullscreen-desktop, boolean, [], false, []
# --windows, integer, [1 5], false, [] # this option is not supported yet
--title, enum, [vartest bartest footest], false, []
--icon, enum, [icon.bmp], false, []
--center, boolean, [], false, []
--position, enum, [300,300], false, []
--geometry, enum, [500x500], false, []
--min-geometry, enum, [100x100], false, []
--max-geometry, enum, [600x600 700x700], false, []
--logical, enum, [500x500 550x450], false, []
--scale, integer, [1 5], false, []
--depth, integer, [1 5], false, []
--refresh, integer, [1 5], false, []
--vsync, boolean, [], false, []
--noframe, boolean, [], false, []
--resize, boolean, [], false, []
--minimize, boolean, [], false, []
--maximize, boolean, [], false, []
--grab, boolean, [], false, [mouse]
--blend, enum, [none blend add mod], false, []
--cyclecolor, boolean, [], false, []
--cyclealpha, boolean, [], false, []
--iterations, integer, [10 100], false, []

View File

@ -1 +0,0 @@
00:00:05 QUIT

View File

@ -1,102 +0,0 @@
/*
Copyright (C) 2013 Apoorv Upreti <apoorvupreti@gmail.com>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely.
*/
/* Quits, hangs or crashes based on the command line options passed. */
#include <SDL.h>
#include <SDL_test.h>
static SDLTest_CommonState *state;
static int exit_code;
static SDL_bool hang;
static SDL_bool crash;
int
main(int argc, char** argv)
{
int i, done;
SDL_Event event;
state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO);
if(!state)
return 1;
state->window_flags |= SDL_WINDOW_RESIZABLE;
exit_code = 0;
hang = SDL_FALSE;
crash = SDL_FALSE;
for(i = 1; i < argc; )
{
int consumed;
consumed = SDLTest_CommonArg(state, i);
if(consumed == 0)
{
consumed = -1;
if(SDL_strcasecmp(argv[i], "--exit-code") == 0)
{
if(argv[i + 1])
{
exit_code = SDL_atoi(argv[i + 1]);
consumed = 2;
}
}
else if(SDL_strcasecmp(argv[i], "--hang") == 0)
{
hang = SDL_TRUE;
consumed = 1;
}
else if(SDL_strcasecmp(argv[i], "--crash") == 0)
{
crash = SDL_TRUE;
consumed = 1;
}
}
if(consumed < 0)
{
static const char *options[] = { "[--exit-code N]", "[--crash]", "[--hang]", NULL };
SDLTest_CommonLogUsage(state, argv[0], options);
SDLTest_CommonQuit(state);
return 1;
}
i += consumed;
}
if(!SDLTest_CommonInit(state))
{
SDLTest_CommonQuit(state);
return 1;
}
/* infinite loop to hang the process */
while(hang)
SDL_Delay(10);
/* dereference NULL pointer to crash process */
if(crash)
{
int* p = NULL;
*p = 5;
}
/* event loop */
done = 0;
while(!done)
{
while(SDL_PollEvent(&event))
SDLTest_CommonEvent(state, &event, &done);
SDL_Delay(10);
}
return exit_code;
}

View File

@ -1,5 +0,0 @@
sutconfig=testquit.parameters
action-config=testquit.actions
variator=exhaustive
sutapp=testquit
timeout=00:00:10

View File

@ -1,3 +0,0 @@
--exit-code, integer, [-1 1], false, [] # The exit code returned by the executable
--crash, boolean, [], false, [] # Crashes the SUT executable
--hang, boolean, [], false, [] # Runs the SUT in the infinite loop and ignores all events