/// <inheritdoc /> /// <summary> /// Tries to connect. /// </summary> /// <returns>The to connect.</returns> public async Task <bool> TryToConnect() { _logger.Debug("Starting TryToConnect"); try { await _client.GetAsync("api/v1/configuration"); } catch (Exception e) { _logger.Info("Failed to connect to: " + _client.BaseAddress); _logger.Error("Failed to connect.", e); return(false); } _logger.Debug("Finished TryToConnect OK"); return(true); }
/// <inheritdoc /> /// <summary> /// Takes the screenshot android device. /// </summary> /// <returns>The screenshot android device.</returns> /// <param name="device">Device.</param> public FileStreamResult TakeScreenshotAndroidDevice(Device device) { try { var screenshotFolder = Path.Combine(Directory.GetCurrentDirectory(), "Screenshot"); Directory.CreateDirectory(screenshotFolder); var screenshotFilePath = Path.Combine(screenshotFolder, $"{device.Id}.png"); // adb shell screencap -p | perl -pe 's/\x0D\x0A/\x0A/g' > screen.png var screenshotRet = _externalProcesses.RunShellProcess("adb", $" -s {device.Id} exec-out 'screencap -p' > {screenshotFilePath}; exit 0", 10000); _logger.Debug(screenshotRet); if (screenshotRet.Contains("error:")) { return(GetDefaultMobileImage()); } if (new FileInfo(screenshotFilePath).Length == 0) { _logger.Error( $"Failed to get screenshot for device: [{device.Id}]. Screenshot file [{screenshotFilePath}] has 0 size."); return(GetDefaultMobileImage()); } var convertedImagePath = Path.Combine(screenshotFolder, $"{device.Id}.jpg"); ConvertImage(screenshotFilePath, convertedImagePath); FileStream image; if (System.IO.File.Exists(convertedImagePath)) { image = System.IO.File.OpenRead(convertedImagePath); return(File(image, "image/jpeg")); } image = System.IO.File.OpenRead(screenshotFilePath); return(File(image, "image/png")); } catch (Exception e) { _logger.Error($"Failed to get screenshot for device: [{device.Id}].", e); return(GetDefaultMobileImage()); } }
private string EnsureLogFolderIsCreated(string configFolderPath) { var path = configFolderPath.StartsWith("~") ? configFolderPath.Replace("~", Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)) : configFolderPath; try { Directory.CreateDirectory(path); } catch (Exception e) { _logger.Error($"Failed to create AppiumLogFilePath [{configFolderPath}].", e); } return(path); }
public async Task <IActionResult> DeleteAsync(string id) { LogRequestToDebug(); var reservationFromApplied = _reservationsAppliedRepository.Find(id); if (reservationFromApplied == null) { return(NotFoundExtension("Reservation not found in database.")); } foreach (var reservedDevice in reservationFromApplied.ReservedDevices) { try { //todo: change to exception handling when UnlockDevice is developed if (!(await _deviceUtils.UnlockDevice(reservedDevice.DeviceId, _restClient, _appiumService)) .Available) { return(StatusCodeExtension(500, "Failed to unlock device id: " + reservedDevice.DeviceId + " from reservation.")); } } catch (Exception ex) { _logger.Error($"Failed to remove reserved devices due to: {ex.Message}.", ex); return(StatusCodeExtension(500, "Failed to unlock device id: " + reservedDevice.DeviceId + " from reservation.")); } } try { _reservationsAppliedRepository.Remove(id); } catch (Exception ex) { return(StatusCodeExtension(500, "Failed to Remove reservation from database. " + ex.Message)); } return(OkExtension(string.Format("Reservation queued successfully deleted: [{0}]", JsonConvert.SerializeObject(reservationFromApplied)))); }
/// <inheritdoc /> /// <summary> /// Runs the async apply reservation task async. /// </summary> public async Task RunAsyncApplyReservationTaskAsync(CancellationToken cancellationToken) { _logger.Info("RunAsyncApplyReservationTaskAsync Thread Started."); while (!cancellationToken.IsCancellationRequested) { try { var applied = false; if (await RestClient.TryToConnect()) { _logger.Info("ApplyAvailableReservations [START]"); try { applied = await ApplyAvailableReservations(); } catch (Exception e) { _logger.Info("ApplyAvailableReservations: " + e.Message + " [ERROR]"); } _logger.Info("ApplyAvailableReservations: " + applied + " [STOP]"); Thread.Sleep((await RestClient.GetManagerConfiguration()).ReservationServiceRefreshTime); } else { _logger.Error("ApplyAvailableReservations: Failed connecting to " + RestClient.Endpoint + " [STOP]"); var sleep = AppConfigurationProvider.Get <ManagerConfiguration>().GlobalReconnectTimeout; _logger.Info("ApplyAvailableReservations Sleep for [ms]: " + sleep); Thread.Sleep(sleep); _logger.Info("ApplyAvailableReservations Sleep finished"); } } catch (Exception e) { _logger.Error("Exception during RunAsyncApplyReservationTaskAsync.", e); } } _logger.Info($"{nameof(RunAsyncApplyReservationTaskAsync)} STOP."); }
/// <inheritdoc /> /// <summary> /// Locks the device. /// </summary> /// <returns>The device.</returns> /// <param name="deviceId">Device identifier.</param> /// <param name="restClient">Rest client.</param> /// <param name="appiumService">Appium service.</param> public async Task <Device> LockDevice(string deviceId, IRestClient restClient, IAppiumService appiumService) { _logger.Debug($"{nameof(LockDevice)}: device id [{deviceId}]."); var device = await restClient.GetDevice(deviceId); if (device == null) { throw new KeyNotFoundException("Failed to find device with id: " + deviceId); } _logger.Debug( $"{nameof(LockDevice)}: set device id [{deviceId}] available from [{device.Available}] to false."); device.Available = false; _logger.Debug($"{nameof(LockDevice)}: device id [{deviceId}] stop running Appium"); try { device.AppiumEndpoint = Task.Run(() => appiumService.StartAppiumForDeviceId(deviceId)).Result; } catch (Exception e) { _logger.Error($"{nameof(LockDevice)} failed with exception.", e); await UnlockDevice(device.Id, restClient, appiumService); throw; } _logger.Debug($"{nameof(LockDevice)}: device id [{deviceId}] set status from [{device.Status}] to LOCKED"); device.Status = DeviceStatus.Locked; var updatedDevice = await restClient.UpdateDevice(device); _logger.Debug($"{nameof(LockDevice)}: updated device [{JsonConvert.SerializeObject(updatedDevice)}]"); return(updatedDevice); }
/// <summary> /// Configure the specified app, env and loggerFactory. This method gets called by the runtime. Use this method to configure the HTTP request pipeline. /// </summary> /// <returns>The configure.</returns> /// <param name="app">App.</param> /// <param name="env">Env.</param> /// <param name="loggerFactory">Logger factory.</param> /// <param name="applicationLifetime">Handle application lifecycle.</param> /// <param name="logger">Logger.</param> public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IApplicationLifetime applicationLifetime, IManagerLogger logger) { var appconfig = AppConfigurationProvider.Get <AppConfiguration>(); applicationLifetime.ApplicationStopped.Register(OnShutdown); loggerFactory.AddConsole((logText, logLevel) => { if (Debugger.IsAttached) { return(true); } if (logLevel >= appconfig.DefaultLogLevel) { return(true); } return(false); }, appconfig.IncludeScopes); loggerFactory.AddFile("Logs/log-{Date}.txt", LogLevel.Trace); app.UseExceptionHandler( options => { options.Run( async context => { context.Response.StatusCode = (int)HttpStatusCode.InternalServerError; context.Response.ContentType = "text/html"; var ex = context.Features.Get <IExceptionHandlerFeature>(); if (ex != null) { var err = $"<h1>Error: {ex.Error.Message}</h1>{ex.Error.StackTrace}"; await context.Response.WriteAsync(err).ConfigureAwait(false); logger.Error(ex.Error.Message, ex.Error); } }); } ); //app.UseDeveloperExceptionPage(); app.UseStaticFiles(); app.UseMvcWithDefaultRoute(); app.UseCors("AllowAllHeaders"); // Enable middleware to serve generated Swagger as a JSON endpoint. app.UseSwagger(); // Enable middleware to serve swagger-ui (HTML, JS, CSS etc.), specifying the Swagger JSON endpoint. app.UseSwaggerUI(c => { c.RoutePrefix = "doc"; c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1"); }); }
/// <summary> /// Loads the connected IOS Devices async. /// </summary> /// <returns>The connected IOS Devices async.</returns> private async Task LoadConnectedIosDevicesAsync(CancellationToken cancellationToken) { _logger.Info($"{nameof(LoadConnectedIosDevicesAsync)} Thread started."); while (!cancellationToken.IsCancellationRequested) { try { _logger.Debug($"Running {nameof(LoadConnectedIosDevicesAsync)}."); if (await _restClient.TryToConnect()) { var output = _externalProcesses.RunProcessAndReadOutput("idevice_id", "-l"); var listOfIosDeviceIds = output.Split(new[] { Environment.NewLine }, StringSplitOptions.None).ToList(); listOfIosDeviceIds = listOfIosDeviceIds.Where(s => !string.IsNullOrWhiteSpace(s)).Distinct() .ToList(); await _deviceUtils.CheckAllDevicesInDevicePoolAreOnline(listOfIosDeviceIds, DeviceType.IOS, _restClient); foreach (var deviceId in listOfIosDeviceIds) { if (string.IsNullOrEmpty(deviceId)) { continue; } var deviceInDevicePool = await _restClient.GetDevice(deviceId); if (deviceInDevicePool != null) { if (deviceInDevicePool.Status == DeviceStatus.Offline) { SetNewDeviceProperties(deviceInDevicePool); await MountDeveloperDiskAsync(deviceInDevicePool); deviceInDevicePool.Status = DeviceStatus.Online; deviceInDevicePool.Available = true; await _restClient.UpdateDevice(deviceInDevicePool); continue; } _logger.Info( $"{nameof(LoadConnectedIosDevicesAsync)}: Device {deviceId} is already stored in database."); await MountDeveloperDiskAsync(deviceInDevicePool); continue; } var deviceName = _externalProcesses.RunProcessAndReadOutput("idevicename", $"-u {deviceId}"); if (string.IsNullOrEmpty(deviceName) || deviceName.Contains("ERROR")) { _logger.Error( $"{nameof(LoadConnectedIosDevicesAsync)}: Failed get device name for deviceId: [{deviceId}].\n[{deviceName}]"); continue; } var device = new DeviceFactory().NewDevice(deviceId, deviceName.Trim('\n'), true, DeviceType.IOS, DeviceStatus.Online); SetNewDeviceProperties(device); await TryAddNewDeviceToDevicePoolAsync(device); await MountDeveloperDiskAsync(device); } Thread.Sleep((await _restClient.GetManagerConfiguration()).IosDeviceServiceRefreshTime); } else { _logger.Error( $"{nameof(LoadConnectedIosDevicesAsync)}: Failed connecting to {_restClient.Endpoint} [STOP]"); WaitForGlobalReconnectTimeout(); } } catch (Exception e) { _logger.Error($"{nameof(LoadConnectedIosDevicesAsync)} exception.", e); WaitForGlobalReconnectTimeout(); } } }
private async Task LoadConnectedAndroidDevicesAsync(CancellationToken cancellationToken) { _logger.Info($"{nameof(LoadConnectedAndroidDevicesAsync)} Thread started."); try { while (!cancellationToken.IsCancellationRequested) { _logger.Debug($"Running {nameof(LoadConnectedAndroidDevicesAsync)}."); if (await _restClient.TryToConnect()) { var deviceIdAndStatus = GetAndroidDevicesFromAdbDevicesOutput(); await _deviceUtils.CheckAllDevicesInDevicePoolAreOnline(deviceIdAndStatus.Keys.ToList(), DeviceType.Android, _restClient); foreach (var deviceId in deviceIdAndStatus.Keys) { var deviceAlreadyInPool = await IsDeviceAlreadyInDevicePoolAsync(deviceId); if (!deviceAlreadyInPool) { var state = deviceIdAndStatus[deviceId]; if (state != "device") { _logger.Error( $"{nameof(LoadConnectedAndroidDevicesAsync)}: Device with id: [{deviceId}] is in incorrect state: [{state}]. Expected state is [device]"); continue; } } else { continue; } _logger.Debug( $"{nameof(LoadConnectedAndroidDevicesAsync)}: read device [{deviceId}] properties."); var deviceName = GetDeviceName(deviceId); if (string.IsNullOrWhiteSpace(deviceName)) { _logger.Error( $"{nameof(LoadConnectedAndroidDevicesAsync)}: Failed to get deviceName to device with id: '" + deviceId + "'"); continue; } _logger.Debug( $"{nameof(LoadConnectedAndroidDevicesAsync)}: new android device factory [{deviceId}] name [{deviceName.Trim('\n', '\r')}]."); var device = new DeviceFactory().NewDevice(deviceId, deviceName.Trim('\n', '\r'), true, DeviceType.Android, DeviceStatus.Online); var deviceProperties = GetDevicePropertiesById(deviceId); var properties = new List <DeviceProperties>(); foreach (var prop in deviceProperties) { properties.Add(new DeviceProperties(prop.Key, prop.Value)); } device.Properties = properties; await TryAddNewDeviceToDevicePoolAsync(device); _logger.Debug( $"{nameof(LoadConnectedAndroidDevicesAsync)}: TryAddNewDeviceToDevicePoolAsync [{JsonConvert.SerializeObject(device)}]."); await TryAddNewDeviceToDevicePoolAsync(device); } var sleepTime = (await _restClient.GetManagerConfiguration()).AndroidDeviceServiceRefreshTime; _logger.Debug($"{nameof(LoadConnectedAndroidDevicesAsync)}: sleep for [{sleepTime}]."); Thread.Sleep(sleepTime); } else { _logger.Error($"{nameof(LoadConnectedAndroidDevicesAsync)}: Failed connecting to " + _restClient.Endpoint + " [STOP]"); var sleep = AppConfigurationProvider.Get <ManagerConfiguration>().GlobalReconnectTimeout; _logger.Info($"{nameof(LoadConnectedAndroidDevicesAsync)}: Sleep for [ms]: {sleep}"); Thread.Sleep(sleep); _logger.Info($"{nameof(LoadConnectedAndroidDevicesAsync)}: Sleep finished"); } } _logger.Info($"{nameof(LoadConnectedAndroidDevicesAsync)} STOP."); } catch (Exception e) { _logger.Error($"Stopping {nameof(LoadConnectedAndroidDevicesAsync)}.", e); } if (cancellationToken.IsCancellationRequested) { var result = _externalProcesses.RunProcessAndReadOutput("adb", "kill-server"); _logger.Debug( $"{nameof(LoadConnectedAndroidDevicesAsync)}: Stop ADB server to release ports - output:{result}"); } }