/// <inheritdoc /> public async Task <BoolResult> StartupAsync(Context context) { StartupStarted = true; BoolResult result = BoolResult.Success; context.Debug("Starting service process"); await Task.Run(() => { AbsolutePath appExeDirPath = new AbsolutePath(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)); var appExePath = appExeDirPath / (OperatingSystemHelper.IsUnixOS ? "ContentStoreApp" : "ContentStoreApp.exe"); _args = _configuration.GetCommandLineArgs(scenario: _scenario); context.Debug($"Running cmd=[{appExePath} {_args}]"); const bool CreateNoWindow = true; _process = new ProcessUtility(appExePath.Path, _args, CreateNoWindow); _process.Start(); string processOutput; if (_process == null) { processOutput = "[Process could not start]"; result = new BoolResult(processOutput); } else if (CreateNoWindow) { if (_process.HasExited) { if (_process.WaitForExit(5000)) { throw new InvalidOperationException(_process.GetLogs()); } else { throw new InvalidOperationException("Process or either wait handle timed out. " + _process.GetLogs()); } } else { processOutput = $"[Process {_process.Id} is still running]"; } } context.Debug("Process output: " + processOutput); }); if (result.Succeeded && !LocalContentServer.EnsureRunning(context, _scenario, _waitForServerReadyTimeoutMs)) { result = new BoolResult($"Failed to detect server ready in separate process for scenario {_scenario}. Process has {(_process.HasExited ? string.Empty : "not")} exited."); } StartupCompleted = true; return(result); }
private void StartRedisServerIfNeeded() { // Can reuse an existing process only when this instance successfully created a connection to it. // Otherwise the test will fail with NRE. if (_process != null && _connectionMultiplexer != null) { _logger.Debug("Redis process is already running. Reusing an existing instance."); return; } _logger.Debug("Starting a redis server."); var redisName = OperatingSystemHelper.IsWindowsOS ? "redis-server.exe" : "redis-server"; string redisServerPath = Path.GetFullPath(Path.Combine("redisServer", redisName)); if (!File.Exists(redisServerPath)) { throw new InvalidOperationException($"Could not find {redisName} at {redisServerPath}"); } int portNumber = 0; const int maxRetries = 10; for (int i = 0; i < maxRetries; i++) { var fileName = _tempDirectory.CreateRandomFileName(); var redisServerLogsPath = _tempDirectory.CreateRandomFileName(); _fileSystem.CreateDirectory(redisServerLogsPath); portNumber = PortExtensions.GetNextAvailablePort(); string newConfig = $@" timeout 0 tcp-keepalive 0 dir {redisServerLogsPath} port {portNumber}"; File.WriteAllText(fileName.Path, newConfig); var args = $" {fileName}"; _logger.Debug($"Running cmd=[{redisServerPath} {args}]"); const bool createNoWindow = true; _process = new ProcessUtility(redisServerPath, args, createNoWindow, workingDirectory: Path.GetDirectoryName(redisServerPath)); _process.Start(); string processOutput; if (_process == null) { processOutput = "[Process could not start]"; throw new InvalidOperationException(processOutput); } if (createNoWindow) { if (_process.HasExited) { if (_process.WaitForExit(5000)) { throw new InvalidOperationException(_process.GetLogs()); } throw new InvalidOperationException("Process or either wait handle timed out. " + _process.GetLogs()); } processOutput = $"[Process {_process.Id} is still running]"; } _logger.Debug("Process output: " + processOutput); ConnectionString = $"localhost:{portNumber}"; ConfigurationOptions options = ConfigurationOptions.Parse(ConnectionString); options.ConnectTimeout = 2000; options.SyncTimeout = 2000; try { _connectionMultiplexer = ConnectionMultiplexer.Connect(options); break; } catch (RedisConnectionException ex) { SafeKillProcess(); _logger.Debug($"Retrying for exception connecting to redis process {_process.Id} with port {portNumber}: {ex.ToString()}. Has process exited {_process.HasExited} with output {_process.GetLogs()}"); if (i != maxRetries - 1) { Thread.Sleep(300); } else { throw; } } catch (Exception ex) { SafeKillProcess(); _logger.Error( $"Exception connecting to redis process {_process.Id} with port {portNumber}: {ex.ToString()}. Has process exited {_process.HasExited} with output {_process.GetLogs()}"); throw; } } _logger.Debug($"Redis server {_process.Id} is up and running at port {portNumber}."); }
private void Start() { // Can reuse an existing process only when this instance successfully created a connection to it. // Otherwise the test will fail with NRE. if (_process != null) { _logger.Debug("Storage process is already running. Reusing an existing instance."); return; } _logger.Debug("Starting a storage server."); var storageName = (OperatingSystemHelper.IsWindowsOS ? "tools/win-x64/blob.exe" : (OperatingSystemHelper.IsLinuxOS ? "tools/linux-x64/blob" : "tools/osx-x64/blob")); string storageServerPath = Path.GetFullPath(Path.Combine("azurite", storageName)); if (!File.Exists(storageServerPath)) { throw new InvalidOperationException($"Could not find {storageName} at {storageServerPath}"); } _portNumber = 0; const int maxRetries = 10; for (int i = 0; i < maxRetries; i++) { var storageServerWorkspacePath = _tempDirectory.CreateRandomFileName(); _fileSystem.CreateDirectory(storageServerWorkspacePath); _portNumber = PortExtensions.GetNextAvailablePort(); var args = $"--blobPort {_portNumber} --location {storageServerWorkspacePath}"; _logger.Debug($"Running cmd=[{storageServerPath} {args}]"); _process = new ProcessUtility(storageServerPath, args, createNoWindow: true, workingDirectory: Path.GetDirectoryName(storageServerPath)); _process.Start(); string processOutput; if (_process == null) { processOutput = "[Process could not start]"; throw new InvalidOperationException(processOutput); } if (_process.HasExited) { if (_process.WaitForExit(5000)) { throw new InvalidOperationException(_process.GetLogs()); } throw new InvalidOperationException("Process or either wait handle timed out. " + _process.GetLogs()); } processOutput = $"[Process {_process.Id} is still running]"; _logger.Debug("Process output: " + processOutput); ConnectionString = $"DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://127.0.0.1:{_portNumber}/devstoreaccount1;"; AzureBlobStorageCredentials creds = new AzureBlobStorageCredentials(ConnectionString); var client = creds.CreateCloudBlobClient(); try { bool exists = client.GetContainerReference("test").ExistsAsync(DefaultBlobStorageRequestOptions, null).GetAwaiter().GetResult(); break; } catch (StorageException ex) { SafeKillProcess(); _logger.Debug($"Retrying for exception connecting to storage process {_process.Id} with port {_portNumber}: {ex.ToString()}. Has process exited {_process.HasExited} with output {_process.GetLogs()}"); if (i != maxRetries - 1) { Thread.Sleep(300); } else { throw; } } catch (Exception ex) { SafeKillProcess(); _logger.Error( $"Exception connecting to storage process {_process.Id} with port {_portNumber}: {ex.ToString()}. Has process exited {_process.HasExited} with output {_process.GetLogs()}"); throw; } } _logger.Debug($"Storage server {_process.Id} is up and running at port {_portNumber}."); }