yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
979e16a34
master
1// test-context.cpp 2#include "test-context.h" 3 4#include "../../source/compiler-core/slang-language-server-protocol.h" 5#include "../../source/core/slang-io.h" 6#include "../../source/core/slang-shared-library.h" 7#include "../../source/core/slang-string-util.h" 8#include "../../source/core/slang-test-tool-util.h" 9 10#include <stdio.h> 11#include <stdlib.h> 12 13using namespace Slang ; 14 15thread_localint slangTestThreadIndex = 0 ; 16 17TestContext ::TestContext () 18{ 19/// if we are testing on arm, debug, we may want to increase the connection timeout 20#if (SLANG_PROCESSOR_ARM || SLANG_PROCESSOR_ARM_64 )&& defined(_DEBUG ) 21// 10 mins(!). This seems to be the order of time needed for timeout on a CI ARM test system on 22// debug 23connectionTimeOutInMs = 1000 * 60 * 10 ; 24#endif 25} 26 27void TestContext ::setThreadIndex (int index ) 28{ 29slangTestThreadIndex = index ; 30} 31 32void TestContext ::setMaxTestRunnerThreadCount (int count ) 33{ 34m_jsonRpcConnections .setCount (count ); 35m_testRequirements .setCount (count ); 36m_reporters .setCount (count ); 37for (auto & reporter :m_reporters ) 38 { 39reporter = nullptr ; 40 } 41} 42 43void TestContext ::setTestRequirements (TestRequirements * req ) 44{ 45m_testRequirements [slangTestThreadIndex ]= req ; 46} 47 48TestRequirements * TestContext ::getTestRequirements ()const 49{ 50return m_testRequirements [slangTestThreadIndex ]; 51} 52 53void TestContext ::setTestReporter (TestReporter * reporter ) 54{ 55m_reporters [slangTestThreadIndex ]= reporter ; 56} 57 58TestReporter * TestContext ::getTestReporter () 59{ 60return m_reporters [slangTestThreadIndex ]; 61} 62 63SlangResult TestContext ::locateFileCheck () 64{ 65DefaultSharedLibraryLoader * loader = DefaultSharedLibraryLoader ::getSingleton (); 66 67SLANG_RETURN_ON_FAIL (loader -> loadSharedLibrary ("slang-llvm" ,m_fileCheckLibrary .writeRef ())); 68 69if (!m_fileCheckLibrary ) 70 { 71return SLANG_FAIL ; 72 } 73 74using CreateFileCheckFunc = SlangResult (* )(const SlangUUID & ,void ** ); 75auto fn = reinterpret_cast < CreateFileCheckFunc > ( 76m_fileCheckLibrary -> findFuncByName ("createLLVMFileCheck_V1" )); 77if (!fn ) 78 { 79return SLANG_FAIL ; 80 } 81return fn (SLANG_IID_PPV_ARGS (m_fileCheck .writeRef ())); 82} 83 84Result TestContext ::init (const char * inExePath ) 85{ 86SlangGlobalSessionDesc desc = {}; 87desc .enableGLSL = true; 88SLANG_RETURN_ON_FAIL (slang::createGlobalSession (& desc ,m_session .writeRef ())); 89exePath = inExePath ; 90SLANG_RETURN_ON_FAIL (TestToolUtil ::getExeDirectoryPath (inExePath ,exeDirectoryPath )); 91SLANG_RETURN_ON_FAIL (TestToolUtil ::getDllDirectoryPath (inExePath ,dllDirectoryPath )); 92 93SLANG_RETURN_ON_FAIL (locateFileCheck ()); 94 95return SLANG_OK ; 96} 97 98TestContext ::~TestContext () 99{ 100if (m_languageServerConnection ) 101 { 102m_languageServerConnection -> sendCall ( 103LanguageServerProtocol ::ExitParams ::methodName , 104JSONValue ::makeInt (0 )); 105 } 106} 107 108TestContext ::InnerMainFunc TestContext ::getInnerMainFunc (const String & dirPath ,const String & name ) 109{ 110 { 111SharedLibraryTool * tool = m_sharedLibTools .tryGetValue (name ); 112if (tool ) 113 { 114return tool -> m_func ; 115 } 116 } 117 118StringBuilder sharedLibToolBuilder ; 119sharedLibToolBuilder .append (name ); 120sharedLibToolBuilder .append ("-tool" ); 121 122StringBuilder path ; 123SharedLibrary ::appendPlatformFileName (sharedLibToolBuilder .getUnownedSlice (),path ); 124 125DefaultSharedLibraryLoader * loader = DefaultSharedLibraryLoader ::getSingleton (); 126 127SharedLibraryTool tool = {}; 128 129if (SLANG_SUCCEEDED ( 130loader -> loadPlatformSharedLibrary (path .begin (),tool .m_sharedLibrary .writeRef ()))) 131 { 132tool .m_func = (InnerMainFunc )tool .m_sharedLibrary -> findFuncByName ("innerMain" ); 133tool .m_cleanDeviceCacheFunc = 134 (CleanDeviceCacheFunc )tool .m_sharedLibrary -> findFuncByName ("cleanDeviceCache" ); 135 } 136 137m_sharedLibTools .add (name ,tool ); 138return tool .m_func ; 139} 140 141void TestContext ::setInnerMainFunc (const String & name ,InnerMainFunc func ) 142{ 143SharedLibraryTool * tool = m_sharedLibTools .tryGetValue (name ); 144if (tool ) 145 { 146tool -> m_sharedLibrary .setNull (); 147tool -> m_func = func ; 148 } 149else 150 { 151SharedLibraryTool tool = {}; 152tool .m_func = func ; 153m_sharedLibTools .add (name ,tool ); 154 } 155} 156 157TestContext ::CleanDeviceCacheFunc TestContext ::getCleanDeviceCacheFunc (const String & name ) 158{ 159SharedLibraryTool * tool = m_sharedLibTools .tryGetValue (name ); 160if (tool ) 161 { 162return tool -> m_cleanDeviceCacheFunc ; 163 } 164 165return nullptr ; 166} 167 168DownstreamCompilerSet * TestContext ::getCompilerSet () 169{ 170 std::lock_guard < std::mutex > lock (mutex ); 171if (!compilerSet ) 172 { 173compilerSet = new DownstreamCompilerSet ; 174 175DownstreamCompilerLocatorFunc locators [int (SLANG_PASS_THROUGH_COUNT_OF )]= {nullptr }; 176 177DownstreamCompilerUtil ::setDefaultLocators (locators ); 178for (Index i = 0 ;i < Index (SLANG_PASS_THROUGH_COUNT_OF );++ i ) 179 { 180auto locator = locators [i ]; 181if (locator ) 182 { 183locator (String (),DefaultSharedLibraryLoader ::getSingleton (),compilerSet ); 184 } 185 } 186 187DownstreamCompilerUtil ::updateDefaults (compilerSet ); 188 } 189return compilerSet ; 190} 191 192SlangResult TestContext ::_createJSONRPCConnection (RefPtr < JSONRPCConnection >& out ) 193{ 194RefPtr < Process > process ; 195 196 { 197CommandLine cmdLine ; 198cmdLine .setExecutableLocation (ExecutableLocation (exeDirectoryPath ,"test-server" )); 199 200if (options .ignoreAbortMsg ) 201 { 202cmdLine .addArg ("-ignore-abort-msg" ); 203 } 204 205SLANG_RETURN_ON_FAIL (Process ::create ( 206cmdLine , 207Process ::Flag ::AttachDebugger |Process ::Flag ::DisableStdErrRedirection , 208process )); 209 } 210 211Stream * writeStream = process -> getStream (StdStreamType ::In ); 212RefPtr < BufferedReadStream > readStream ( 213new BufferedReadStream (process -> getStream (StdStreamType ::Out ))); 214RefPtr < BufferedReadStream > readErrStream ( 215new BufferedReadStream (process -> getStream (StdStreamType ::ErrorOut ))); 216 217RefPtr < HTTPPacketConnection > connection = new HTTPPacketConnection (readStream ,writeStream ); 218RefPtr < JSONRPCConnection > rpcConnection = new JSONRPCConnection ; 219 220SLANG_RETURN_ON_FAIL ( 221rpcConnection -> init (connection ,JSONRPCConnection ::CallStyle ::Default ,process )); 222 223out = rpcConnection ; 224 225return SLANG_OK ; 226} 227 228SlangResult TestContext ::createLanguageServerJSONRPCConnection (RefPtr < JSONRPCConnection >& out ) 229{ 230RefPtr < Process > process ; 231 232 { 233CommandLine cmdLine ; 234cmdLine .setExecutableLocation (ExecutableLocation (exeDirectoryPath ,"slangd" )); 235cmdLine .addArg ("-periodic-diagnostic-update" ); 236cmdLine .addArg ("false" ); 237SLANG_RETURN_ON_FAIL (Process ::create (cmdLine ,Process ::Flag ::AttachDebugger ,process )); 238 } 239 240Stream * writeStream = process -> getStream (StdStreamType ::In ); 241RefPtr < BufferedReadStream > readStream ( 242new BufferedReadStream (process -> getStream (StdStreamType ::Out ))); 243 244RefPtr < HTTPPacketConnection > connection = new HTTPPacketConnection (readStream ,writeStream ); 245RefPtr < JSONRPCConnection > rpcConnection = new JSONRPCConnection ; 246 247SLANG_RETURN_ON_FAIL ( 248rpcConnection -> init (connection ,JSONRPCConnection ::CallStyle ::Object ,process )); 249 250out = rpcConnection ; 251 252return SLANG_OK ; 253} 254 255void TestContext ::destroyRPCConnection () 256{ 257if (m_jsonRpcConnections [slangTestThreadIndex ]) 258 { 259m_jsonRpcConnections [slangTestThreadIndex ]-> disconnect (); 260m_jsonRpcConnections [slangTestThreadIndex ].setNull (); 261 } 262} 263 264Slang ::JSONRPCConnection * TestContext ::getOrCreateJSONRPCConnection () 265{ 266if (!m_jsonRpcConnections [slangTestThreadIndex ]) 267 { 268if (SLANG_FAILED (_createJSONRPCConnection (m_jsonRpcConnections [slangTestThreadIndex ]))) 269 { 270return nullptr ; 271 } 272 } 273 274return m_jsonRpcConnections [slangTestThreadIndex ]; 275} 276 277 278Slang ::IDownstreamCompiler * TestContext ::getDefaultCompiler (SlangSourceLanguage sourceLanguage ) 279{ 280DownstreamCompilerSet * set = getCompilerSet (); 281return set ?set -> getDefaultCompiler (sourceLanguage ) :nullptr ; 282} 283 284bool TestContext ::canRunTestWithRenderApiFlags (Slang ::RenderApiFlags requiredFlags ) 285{ 286// If only allow tests that use API - then the requiredFlags must be 0 287if (options .apiOnly && requiredFlags == 0 ) 288 { 289return false; 290 } 291// Are the required rendering APIs enabled from the -api command line switch 292return (requiredFlags & options .enabledApis )== requiredFlags ; 293} 294 295SpawnType TestContext ::getFinalSpawnType (SpawnType spawnType ) 296{ 297if (spawnType == SpawnType ::Default ) 298 { 299if (options .outputMode == TestOutputMode ::Default ) 300 { 301return SpawnType ::UseSharedLibrary ; 302 } 303else 304 { 305return SpawnType ::UseTestServer ; 306 } 307 } 308 309// Just return whatever spawnType was passed in 310return spawnType ; 311} 312 313SpawnType TestContext ::getFinalSpawnType () 314{ 315return getFinalSpawnType (options .defaultSpawnType ); 316}