public void Start(string[] settings, TimeSpan startTimeout) { if (!this._config.RunIntegrationTests || this.Started) { return; } lock (_lock) { if (!this._config.RunIntegrationTests || this.Started) { return; } this.FreeResources(); if (UseAlreadyRunningInstance()) { this.Started = true; return; } var handle = new XplatManualResetEvent(false); var booted = false; var process = new ObservableProcess(this.FileSystem.Binary, settings); this._composite = new CompositeDisposable(process); Console.WriteLine($"Starting: {process.Binary} {process.Arguments}"); try { var subscription = Observable.Using(() => process, p => p.Start()) .Select(c => new ElasticsearchConsoleOut(this._config.ElasticsearchVersion, c.Error, c.Data)) .Subscribe(s => this.HandleConsoleMessage(s, handle), e => throw e, () => handle.Set()); this._composite.Add(subscription); if (!handle.WaitOne(startTimeout, true)) { throw new Exception($"Could not start elasticsearch within {startTimeout}"); } booted = true; } finally { if (!booted) { this.FreeResources(); } } } }
private void HandleConsoleMessage(ElasticsearchConsoleOut consoleOut, XplatManualResetEvent handle) { //no need to snoop for metadata if we already started if (!this._config.RunIntegrationTests || this.Started) { return; } //if we are running on CI and not started dump elasticsearch stdout/err //before the started notification to help debug failures to start if (this.RunningOnCI && !this.Started) { if (consoleOut.Error) { Console.Error.WriteLine(consoleOut.Data); } else { Console.WriteLine(consoleOut.Data); } } if (consoleOut.Error && !this.Started && !string.IsNullOrWhiteSpace(consoleOut.Data)) { throw new Exception(consoleOut.Data); } string version; int? pid; int port; if (this.ProcessId == null && consoleOut.TryParseNodeInfo(out version, out pid)) { var startedVersion = ElasticsearchVersion.Create(version); this.ProcessId = pid; if (this.Version != startedVersion) { throw new Exception($"Booted elasticsearch is version {startedVersion} but the test config dictates {this.Version}"); } } else if (consoleOut.TryGetPortNumber(out port)) { this.Port = port; } else if (consoleOut.TryGetStartedConfirmation()) { this.Started = true; handle.Set(); } }
protected void ExecuteBinary(string binary, string description, params string[] arguments) { Console.WriteLine($"Preparing to execute: {description} ..."); var timeout = TimeSpan.FromSeconds(420); var handle = new XplatManualResetEvent(false); var task = Task.Run(() => { using (var p = new ObservableProcess(binary, arguments)) { var o = p.Start(); Console.WriteLine($"Executing: {binary} {string.Join(" ", arguments)}"); o.Subscribe(c => Console.WriteLine(c.Data), (e) => { Console.WriteLine($"Failed executing: {description} {e.Message} {e.StackTrace}"); handle.Set(); throw e; }, () => { Console.WriteLine($"Finished executing {description} exit code: {p.ExitCode}"); handle.Set(); }); if (!handle.WaitOne(timeout, true)) { throw new Exception($"Timeout while executing {description} exceeded {timeout}"); } } }); if (!handle.WaitOne(timeout, true)) { throw new Exception($"Timeout while executing {description} exceeded {timeout}"); } if (task.Exception != null) { throw task.Exception; } }