コード例 #1
0
        /// <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);
        }
コード例 #2
0
        /// <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());
            }
        }
コード例 #3
0
        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);
        }
コード例 #4
0
        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))));
        }
コード例 #5
0
        /// <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.");
        }
コード例 #6
0
        /// <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);
        }
コード例 #7
0
        /// <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");
            });
        }
コード例 #8
0
        /// <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();
                }
            }
        }
コード例 #9
0
        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}");
            }
        }