public void TestConstructor()
 {
     var target = new RetryHelper();
     Expect(target.DefaultMaxTryCount, EqualTo(RetryHelper.Instance.DefaultMaxTryCount));
     Expect(target.DefaultMaxTryTime, EqualTo(RetryHelper.Instance.DefaultMaxTryTime));
     Expect(target.DefaultTryInterval, EqualTo(RetryHelper.Instance.DefaultTryInterval));
 }
Example #2
0
        static void Main(string[] args)
        {
            // Example 1: I want to retry until I get a return value < 0.1 from the method TryGetSomething.

            // Basic usage
            RetryHelper.Instance.Try(() => TryGetSomething()).Until(result => result < 0.1);

            // Get the result from the retried method
            var resultSmallEnough = RetryHelper.Instance.Try(() => TryGetSomething()).Until(result => result < 0.1);

            // Specify interval
            RetryHelper.Instance.Try(() => TryGetSomething()).WithTryInterval(100).Until(result => result < 0.1);

            // Specify max try count, will throw TimeoutException if exceeded
            RetryHelper.Instance.Try(() => TryGetSomething()).WithMaxTryCount(20).Until(result => result < 0.1);

            // Can also constrain the total try time
            RetryHelper.Instance.Try(() => TryGetSomething()).WithTimeLimit(TimeSpan.FromSeconds(10)).Until(result => result < 0.1);

            // Specify the extra success/fail/timeout action
            RetryHelper.Instance.Try(() => TryGetSomething())
                .WithMaxTryCount(20)
                .OnSuccess(result => Trace.TraceInformation(string.Format("Get result {0}.", result)))
                .OnFailure(result => Trace.TraceWarning(string.Format("Try failed. Got {0}", result)))
                .OnTimeout(lastResult => Trace.TraceError("Did not get result under 0.1 in 20 times."))
                .Until(result => result < 0.1);

            // Example 2: I want to retry method TryDoSomething until there's no exception thrown.
            // Retry on any (non-fatal) exception
            RetryHelper.Instance.Try(() => TryDoSomething()).UntilNoException();

            // Retry on specific exception
            RetryHelper.Instance.Try(() => TryDoSomething()).UntilNoException<ApplicationException>();

            // Lambda can be simplified in this case
            RetryHelper.Instance.Try(TryDoSomething).UntilNoException();

            // Change the global default settings
            RetryHelper.Instance.DefaultMaxTryCount = 3;
            RetryHelper.Instance.DefaultMaxTryTime = TimeSpan.FromSeconds(10);
            RetryHelper.Instance.DefaultTryInterval = TimeSpan.FromMilliseconds(100);

            // Get another RetryHelper instance with custom TraceSource and seperate configration
            var retryHelper = new RetryHelper(new TraceSource("MyTraceSource"))
            {
                DefaultMaxTryCount = 10,
                DefaultMaxTryTime = TimeSpan.FromSeconds(30),
                DefaultTryInterval = TimeSpan.FromMilliseconds(500)
            };
        }
Example #3
0
 public void SetUp()
 {
     _target = new RetryHelper();
     _target.DefaultTryInterval = TimeSpan.FromMilliseconds(RetryHelperTest.Interval);
 }
Example #4
0
        public async Task DeployTestAndAddToSpec(ServerType server, bool ssl, string environment, CancellationToken cancellationToken, Action <AutobahnExpectations> expectationConfig = null)
        {
            var sslNamePart = ssl ? "SSL" : "NoSSL";
            var name        = $"{server}|{sslNamePart}|{environment}";
            var logger      = _loggerFactory.CreateLogger($"AutobahnTestApp:{server}:{sslNamePart}:{environment}");

            var appPath         = Helpers.GetApplicationPath("AutobahnTestApp");
            var configPath      = Path.Combine(Directory.GetCurrentDirectory(), "..", "..", "..", "Http.config");
            var targetFramework =
#if NETCOREAPP2_1
                "netcoreapp2.1";
#elif NETCOREAPP2_0
                "netcoreapp2.0";
#else
#error Target frameworks need to be updated
#endif
            var parameters = new DeploymentParameters(appPath, server, RuntimeFlavor.CoreClr, RuntimeArchitecture.x64)
            {
                Scheme                      = (ssl ? Uri.UriSchemeHttps : Uri.UriSchemeHttp),
                ApplicationType             = ApplicationType.Portable,
                TargetFramework             = targetFramework,
                EnvironmentName             = environment,
                SiteName                    = "HttpTestSite", // This is configured in the Http.config
                ServerConfigTemplateContent = (server == ServerType.IISExpress) ? File.ReadAllText(configPath) : null,
            };

            var deployer = ApplicationDeployerFactory.Create(parameters, _loggerFactory);
            var result   = await deployer.DeployAsync();

            _deployers.Add(deployer);
            _deployments.Add(result);
            cancellationToken.ThrowIfCancellationRequested();

            var handler = new HttpClientHandler();
            // Win7 HttpClient on NetCoreApp2.1 defaults to TLS 1.0 and won't connect to Kestrel. https://github.com/dotnet/corefx/issues/28733
            // Mac HttpClient on NetCoreApp2.0 doesn't alow you to set some combinations.
            // https://github.com/dotnet/corefx/blob/586cffcdfdf23ad6c193a4bf37fce88a1bf69508/src/System.Net.Http/src/System/Net/Http/CurlHandler/CurlHandler.SslProvider.OSX.cs#L104-L106
            handler.SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls;
            handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
            var client = result.CreateHttpClient(handler);

            // Make sure the server works
            var resp = await RetryHelper.RetryRequest(() =>
            {
                cancellationToken.ThrowIfCancellationRequested();
                return(client.GetAsync(result.ApplicationBaseUri));
            }, logger, CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, result.HostShutdownToken).Token);

            resp.EnsureSuccessStatusCode();

            cancellationToken.ThrowIfCancellationRequested();

            // Add to the current spec
            var wsUrl = result.ApplicationBaseUri.Replace("https://", "wss://").Replace("http://", "ws://");
            Spec.WithServer(name, wsUrl);

            var expectations = new AutobahnExpectations(server, ssl, environment);
            expectationConfig?.Invoke(expectations);
            _expectations.Add(expectations);

            cancellationToken.ThrowIfCancellationRequested();
        }
Example #5
0
 public bool WaitForRoleToRespond(string url, int timeoutInMilliSeconds = 900000)
 {
     return(RetryHelper.RetryUntil(() => _webRequestor.PingUrl(url), timeoutInMilliSeconds / 1000, TimeSpan.FromSeconds(1)));
 }
        private async Task RunSite(ServerType server, RuntimeFlavor runtimeFlavor, RuntimeArchitecture architecture, string applicationBaseUrl)
        {
            // calltwo and callthree in the expression below
            // increment on every call.
            // The test verifies that everything else stays the same
            // and that the two values that change are increasing in value
            string responseMatcher =
                @"---------- MyMiddleware ctor\r\n" +
                @"CallOne\[1\]\r\n" +
                @"CallTwo\[2\]\r\n" +
                @"CallThree\[3\]\r\n" +
                @"---------- context\.RequestServices\r\n" +
                @"CallOne\[1\]\r\n" +
                @"CallTwo\[(?<calltwo>\d+)\]\r\n" +
                @"CallThree\[(?<callthree>\d+)\]\r\n" +
                @"---------- Done\r\n";

            var responseRegex = new Regex(responseMatcher, RegexOptions.Compiled | RegexOptions.Multiline);

            await TestServices.RunSiteTest(
                SiteName,
                server,
                runtimeFlavor,
                architecture,
                applicationBaseUrl,
                async (httpClient, logger, token) =>
            {
                // ===== First call =====
                var response = await RetryHelper.RetryRequest(async() =>
                {
                    return(await httpClient.GetAsync(string.Empty));
                }, logger, token, retryCount: 30);

                var responseText = await response.Content.ReadAsStringAsync();

                var match = responseRegex.Match(responseText);
                Assert.True(match.Success);

                var callTwo1   = int.Parse(match.Groups["calltwo"].Value);
                var callThree1 = int.Parse(match.Groups["callthree"].Value);

                // ===== Second call =====
                response = await RetryHelper.RetryRequest(async() =>
                {
                    return(await httpClient.GetAsync(string.Empty));
                }, logger, token, retryCount: 30);

                responseText = await response.Content.ReadAsStringAsync();
                logger.LogResponseOnFailedAssert(response, responseText, () =>
                {
                    match = responseRegex.Match(responseText);
                    Assert.True(match.Success);

                    var callTwo2   = int.Parse(match.Groups["calltwo"].Value);
                    var callThree2 = int.Parse(match.Groups["callthree"].Value);

                    Assert.True(callTwo1 < callTwo2);
                    Assert.True(callThree1 < callThree2);
                });
            });
        }
Example #7
0
        public async Task PublishAndRun_Test(TestVariant variant)
        {
            var testName = $"PublishAndRunTests_{variant}";

            using (StartLog(out var loggerFactory, testName))
            {
                var logger           = loggerFactory.CreateLogger("Publish_And_Run_Tests");
                var musicStoreDbName = DbUtils.GetUniqueName();

                var deploymentParameters = new DeploymentParameters(variant)
                {
                    ApplicationPath = Helpers.GetApplicationPath(),
                    PublishApplicationBeforeDeployment       = true,
                    PreservePublishedApplicationForDebugging = Helpers.PreservePublishedApplicationForDebugging,
                    UserAdditionalCleanup = parameters =>
                    {
                        DbUtils.DropDatabase(musicStoreDbName, logger);
                    }
                };

                // Override the connection strings using environment based configuration
                deploymentParameters.EnvironmentVariables
                .Add(new KeyValuePair <string, string>(
                         MusicStoreConfig.ConnectionStringKey,
                         DbUtils.CreateConnectionString(musicStoreDbName)));

                using (var deployer = IISApplicationDeployerFactory.Create(deploymentParameters, loggerFactory))
                {
                    var deploymentResult = await deployer.DeployAsync();

                    var httpClientHandler = new HttpClientHandler {
                        UseDefaultCredentials = true
                    };
                    var httpClient = deploymentResult.CreateHttpClient(httpClientHandler);

                    // Request to base address and check if various parts of the body are rendered &
                    // measure the cold startup time.
                    // Add retry logic since tests are flaky on mono due to connection issues
                    var response = await RetryHelper.RetryRequest(() => httpClient.GetAsync(string.Empty), logger, cancellationToken : deploymentResult.HostShutdownToken);

                    Assert.False(response == null, "Response object is null because the client could not " +
                                 "connect to the server after multiple retries");

                    var validator = new Validator(httpClient, httpClientHandler, logger, deploymentResult);

                    logger.LogInformation("Verifying home page");
                    await validator.VerifyHomePage(response);

                    logger.LogInformation("Verifying architecture");
                    validator.VerifyArchitecture(response, deploymentResult.DeploymentParameters.RuntimeArchitecture);

                    logger.LogInformation("Verifying static files are served from static file middleware");
                    await validator.VerifyStaticContentServed();

                    if (variant.Server != ServerType.IISExpress)
                    {
                        if (Directory.GetFiles(
                                deploymentParameters.ApplicationPath, "*.cmd", SearchOption.TopDirectoryOnly).Length > 0)
                        {
                            throw new Exception("publishExclude parameter values are not honored.");
                        }
                    }

                    logger.LogInformation("Variation completed successfully.");
                }
            }
        }
        public static async Task <List <UpdateTask> > GetUpdates(CancellationToken cancellationToken, UpdateSourceBase[] updateSources, string[] filterByGuids = null)
        {
            Console.WriteLine("Starting update search...");
            var results = new ConcurrentBag <UpdateTask>();

            var ignoreListPath = "ignorelist.txt";
            var ignoreList     = File.Exists(ignoreListPath) ? File.ReadAllLines(ignoreListPath) : new string[0];

            var anySuccessful = false;

            Exception criticalException = null;

            // First start all of the sources, then wait until they all finish
            var concurrentTasks = updateSources.Select(source => new
            {
                task = RetryHelper.RetryOnExceptionAsync(
                    async() =>
                {
                    try
                    {
                        foreach (var task in await source.GetUpdateItems(cancellationToken))
                        {
                            anySuccessful = true;

                            if (cancellationToken.IsCancellationRequested || criticalException != null)
                            {
                                break;
                            }

                            // todo move further inside or decouple getting update tasks and actually processing them
                            if (filterByGuids != null && filterByGuids.Length > 0 &&
                                !filterByGuids.Contains(task.Info.GUID))
                            {
                                continue;
                            }

                            task.Items.RemoveAll(x =>
                                                 x.UpToDate || (x.RemoteFile != null && ignoreList.Any(x.RemoteFile.Name.Contains)));
                            results.Add(task);
                        }
                    }
                    catch (OutdatedVersionException ex)
                    {
                        criticalException = ex;
                    }
                },
                    3, TimeSpan.FromSeconds(3), cancellationToken),
                source
            }).ToList();

            foreach (var task in concurrentTasks)
            {
                try
                {
                    await task.task;
                }
                catch (OperationCanceledException)
                {
                }
                catch (Exception e)
                {
                    Console.WriteLine($"[ERROR] Unexpected error while collecting updates from source {task.source.Origin} - skipping the source. Error: {e.ToStringDemystified()}");
                }
            }

            cancellationToken.ThrowIfCancellationRequested();

            if (criticalException != null)
            {
                throw criticalException;
            }

            if (!anySuccessful)
            {
                throw new InvalidDataException("No valid update sources were found. Either the online update source list could not be accessed, your UpdateSources file is corrupted or in an old format, or KK Manager is outdated. Make sure that you are connected to the internet and not behind a firewall (try using a VPN) and check for KK Manager updates.");
            }

            var filteredTasks = new List <UpdateTask>();

            foreach (var modGroup in results.GroupBy(x => x.Info.GUID))
            {
                var ordered = modGroup.OrderByDescending(x => x.ModifiedTime ?? DateTime.MinValue).ThenByDescending(x => x.Info.Source.DiscoveryPriority).ToList();
                if (ordered.Count > 1)
                {
                    ordered[0].AlternativeSources.AddRange(ordered.Skip(1));
                    Console.WriteLine($"Found {ordered.Count} sources for mod GUID {modGroup.Key} - choosing {ordered[0].Info.Source.Origin} as latest");
                }
                filteredTasks.Add(ordered[0]);
            }

            Console.WriteLine($"Update search finished. Found {filteredTasks.Count} update tasks.");
            return(filteredTasks);
        }
Example #9
0
        public static async Task <List <ServerSideEvent> > GetEvents(string eventLogPath)
        {
            var events = new List <ServerSideEvent>();

            if (!File.Exists(eventLogPath))
            {
                return(events);
            }

            InitializeKnownResourceTypes();

            string fileText = string.Empty;
            await RetryHelper.RetryOnExceptionAsync <IOException>(10, TimeSpan.FromSeconds(1), async() =>
            {
                fileText = await FileSystemHelpers.ReadAllTextFromFileAsync(eventLogPath);
            });

            if (string.IsNullOrWhiteSpace(fileText))
            {
                return(events);
            }

            XmlDocument dom = new XmlDocument();

            dom.LoadXml(fileText);

            XmlNodeList xmlList = dom.SelectNodes("/Events/Event");

            for (int i = (xmlList.Count - 1); i >= 0; i--)
            {
                var     serverSideEvent = new ServerSideEvent();
                XmlNode eventNode       = xmlList[i];
                var     systemNode      = eventNode.SelectSingleNode("System");
                var     eventDataNode   = eventNode.SelectSingleNode("EventData");

                string strProvider = systemNode["Provider"].GetAttribute("Name");
                serverSideEvent.Source = strProvider;
                string dateTimeString = systemNode["TimeCreated"].GetAttribute("SystemTime");

                bool booValidDateFound = false;

                if (dateTimeString.Contains("T") && dateTimeString.Contains("Z"))
                {
                    if (DateTime.TryParse(dateTimeString, out DateTime resultDateTime))
                    {
                        serverSideEvent.DateAndTime = resultDateTime;
                        booValidDateFound           = true;
                    }
                    else
                    {
                        if (DateTime.TryParse(systemNode["TimeCreated"].GetAttribute("SystemTime"), out resultDateTime))
                        {
                            serverSideEvent.DateAndTime = resultDateTime;
                            booValidDateFound           = true;
                        }
                    }
                }
                else
                {
                    if (DateTime.TryParse(systemNode["TimeCreated"].GetAttribute("SystemTime"), out DateTime resultDateTime))
                    {
                        serverSideEvent.DateAndTime = resultDateTime;
                        booValidDateFound           = true;
                    }
                }

                serverSideEvent.EventID       = systemNode["EventID"].InnerText;
                serverSideEvent.TaskCategory  = systemNode["Task"].InnerText;
                serverSideEvent.EventRecordID = systemNode["EventRecordID"].InnerText;
                serverSideEvent.Computer      = systemNode["Computer"].InnerText;

                List <string> arrayOfdata = new List <string>();

                foreach (XmlNode datanode in eventDataNode.ChildNodes)
                {
                    arrayOfdata.Add(datanode.InnerText);
                }

                string[] args    = arrayOfdata.ToArray();
                int      eventId = Convert.ToInt32(systemNode["EventID"].InnerText);

                string strLevel = systemNode["Level"].InnerText;

                int intLevel = -1;
                int.TryParse(strLevel, out intLevel);


                if (strProvider.StartsWith("ASP.NET"))
                {
                    int level = MapEventTypeToWebEngineEventType(intLevel);
                    var aspnetResourceType = ResourceTypes.Values.Where(x => x.SourceStartsWith.StartsWith("ASP.NET"));
                    if (aspnetResourceType != null)
                    {
                        serverSideEvent.Description = GetDescriptionForEvent(aspnetResourceType.FirstOrDefault().PtrHandle, eventId, intLevel, eventDataNode, args);
                    }
                    if (!booValidDateFound)
                    {
                        if (ExtractDateTimeFromFormattedEvent(serverSideEvent.Description, out DateTime parsedDateTime))
                        {
                            serverSideEvent.DateAndTime = parsedDateTime;
                        }
                        else
                        {
                            if (DateTime.TryParse(systemNode["TimeCreated"].GetAttribute("SystemTime"), out DateTime resultDateTime))
                            {
                                serverSideEvent.DateAndTime = resultDateTime;
                            }
                        }
                    }
                }
                else
                {
                    foreach (var item in ResourceTypes)
                    {
                        if (strProvider.StartsWith(item.Value.SourceStartsWith))
                        {
                            serverSideEvent.Description  = GetDescriptionForEvent(item.Value.PtrHandle, eventId, intLevel, eventDataNode, args);
                            serverSideEvent.Description += Environment.NewLine + string.Join(Environment.NewLine, args);
                            break;
                        }
                    }
                }

                if (string.IsNullOrWhiteSpace(serverSideEvent.Description))
                {
                    serverSideEvent.Description = string.Join(Environment.NewLine, args);
                }

                serverSideEvent.Level = systemNode["Level"].InnerText;
                events.Add(serverSideEvent);
            }



            return(events);
        }
 public async Task <IEnumerable <BitFinexPairDetails> > GetPairsDetails(CancellationToken token = default(CancellationToken))
 {
     return(await RetryHelper.DoAsync(async() => await Query <List <BitFinexPairDetails> >(_baseUri.AbsoluteUri +
                                                                                           $"v{Version}/symbols_details", token),
                                      TimeSpan.FromMilliseconds(Constant.DefaultRetryInterval)));
 }
 public async Task <IEnumerable <Pair> > GetSupportedPairs(CancellationToken token = default(CancellationToken))
 {
     return(await RetryHelper.DoAsync(async() => await GetPairs(token), TimeSpan.FromMilliseconds(Constant.DefaultRetryInterval)));
 }
Example #12
0
        public virtual async Task <List <UpdateTask> > GetUpdateItems(CancellationToken cancellationToken)
        {
            var updateInfos = new List <UpdateInfo>();

            var filenamesToTry = new[] { UpdateInfo.UpdateFileName, "Updates1.xml", "Updates2.xml" };

            foreach (var fn in filenamesToTry)
            {
                Stream str = null;
                try
                {
                    var downloadFileAsync = DownloadFileAsync(fn, cancellationToken);
                    if (!await downloadFileAsync.WithTimeout(TimeSpan.FromSeconds(20), cancellationToken))
                    {
                        throw new TimeoutException("Timeout when trying to download " + fn);
                    }
                    str = downloadFileAsync.Result;
                }
                catch (TimeoutException ex)
                {
                    throw RetryHelper.DoNotAttemptToRetry(ex);
                }
                catch (FileNotFoundException)
                {
                }
                catch (OperationCanceledException)
                {
                    throw;
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Failed to download Updates file {fn} from {Origin} - {ex.Message}");
                }

                if (str != null)
                {
                    try
                    {
                        updateInfos.AddRange(UpdateInfo.ParseUpdateManifest(str, this));
                    }
                    catch (OutdatedVersionException ex)
                    {
                        Console.WriteLine($"Failed to parse update manifest file {fn} from {Origin} - {ex.Message}");
                        throw;
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"Failed to parse update manifest file {fn} from {Origin} - {ex.ToStringDemystified()}");
                    }
                    finally
                    {
                        str.Dispose();
                    }
                }
            }

            if (updateInfos.Count == 0)
            {
                throw new FileNotFoundException($"Failed to get update list from host {Origin} - check log for details.");
            }

            updateInfos.RemoveAll(
                info =>
            {
                if (!info.CheckConditions())
                {
                    Console.WriteLine($"Skipping {info.GUID} because of conditions");
                    return(true);
                }
                return(false);
            });

            var allResults = new List <UpdateTask>();

            if (updateInfos.Any())
            {
                foreach (var updateInfo in updateInfos)
                {
                    _latestModifiedDate = DateTime.MinValue;
                    var remoteItem = GetRemoteRootItem(updateInfo.ServerPath);
                    if (remoteItem == null)
                    {
                        throw new DirectoryNotFoundException($"Could not find ServerPath: {updateInfo.ServerPath} in host: {Origin}");
                    }

                    var versionEqualsComparer = GetVersionEqualsComparer(updateInfo);

                    await Task.Run(
                        () =>
                    {
                        var results = ProcessDirectory(
                            remoteItem, updateInfo.ClientPathInfo,
                            updateInfo.Recursive, updateInfo.RemoveExtraClientFiles, versionEqualsComparer,
                            cancellationToken);

                        allResults.Add(new UpdateTask(updateInfo.Name ?? remoteItem.Name, results, updateInfo, _latestModifiedDate));
                    }, cancellationToken);
                }

                // If a task is expanded by other tasks, remove the items that other tasks expand from it
                foreach (var resultTask in allResults)
                {
                    if (!string.IsNullOrEmpty(resultTask.Info.ExpandsGUID))
                    {
                        Console.WriteLine($"Expanding task {resultTask.Info.ExpandsGUID} with task {resultTask.Info.GUID}");
                        ApplyExtendedItems(resultTask.Info.ExpandsGUID, resultTask.Items, allResults);
                    }
                }
            }
            return(allResults);
        }
        public async Task NtlmAuthentication(ServerType serverType, RuntimeFlavor runtimeFlavor, RuntimeArchitecture architecture, string applicationBaseUrl, ApplicationType applicationType)
        {
            var logger = new LoggerFactory()
                         .AddConsole()
                         .CreateLogger($"HttpsHelloWorld:{serverType}:{runtimeFlavor}:{architecture}");

            using (logger.BeginScope("NtlmAuthenticationTest"))
            {
                var deploymentParameters = new DeploymentParameters(Helpers.GetTestSitesPath(applicationType), serverType, runtimeFlavor, architecture)
                {
                    ApplicationBaseUriHint      = applicationBaseUrl,
                    EnvironmentName             = "NtlmAuthentication", // Will pick the Start class named 'StartupNtlmAuthentication'
                    ServerConfigTemplateContent = (serverType == ServerType.IISExpress) ? File.ReadAllText("NtlmAuthentation.config") : null,
                    SiteName        = "NtlmAuthenticationTestSite",     // This is configured in the NtlmAuthentication.config
                    TargetFramework = runtimeFlavor == RuntimeFlavor.Clr ? "net451" : "netcoreapp1.0",
                    ApplicationType = applicationType
                };

                using (var deployer = ApplicationDeployerFactory.Create(deploymentParameters, logger))
                {
                    var deploymentResult  = deployer.Deploy();
                    var httpClientHandler = new HttpClientHandler();
                    var httpClient        = new HttpClient(httpClientHandler)
                    {
                        BaseAddress = new Uri(deploymentResult.ApplicationBaseUri),
                        Timeout     = TimeSpan.FromSeconds(5),
                    };

                    // Request to base address and check if various parts of the body are rendered & measure the cold startup time.
                    var response = await RetryHelper.RetryRequest(() =>
                    {
                        return(httpClient.GetAsync(string.Empty));
                    }, logger, deploymentResult.HostShutdownToken, retryCount : 30);

                    var responseText = await response.Content.ReadAsStringAsync();

                    try
                    {
                        Assert.Equal(HttpStatusCode.OK, response.StatusCode);
                        Assert.Equal("Hello World", responseText);

                        response = await httpClient.GetAsync("/Anonymous");

                        responseText = await response.Content.ReadAsStringAsync();

                        Assert.Equal(HttpStatusCode.OK, response.StatusCode);
                        Assert.Equal("Anonymous?True", responseText);

                        response = await httpClient.GetAsync("/Restricted");

                        responseText = await response.Content.ReadAsStringAsync();

                        Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
                        Assert.Contains("NTLM", response.Headers.WwwAuthenticate.ToString());
                        Assert.Contains("Negotiate", response.Headers.WwwAuthenticate.ToString());

                        response = await httpClient.GetAsync("/RestrictedNTLM");

                        responseText = await response.Content.ReadAsStringAsync();

                        Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
                        Assert.Contains("NTLM", response.Headers.WwwAuthenticate.ToString());
                        // Note we can't restrict a challenge to a specific auth type, the native auth modules always add themselves.
                        Assert.Contains("Negotiate", response.Headers.WwwAuthenticate.ToString());

                        response = await httpClient.GetAsync("/Forbidden");

                        responseText = await response.Content.ReadAsStringAsync();

                        Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode);

                        httpClientHandler = new HttpClientHandler()
                        {
                            UseDefaultCredentials = true
                        };
                        httpClient = new HttpClient(httpClientHandler)
                        {
                            BaseAddress = new Uri(deploymentResult.ApplicationBaseUri)
                        };

                        response = await httpClient.GetAsync("/Anonymous");

                        responseText = await response.Content.ReadAsStringAsync();

                        Assert.Equal(HttpStatusCode.OK, response.StatusCode);
                        Assert.Equal("Anonymous?True", responseText);

                        response = await httpClient.GetAsync("/AutoForbid");

                        responseText = await response.Content.ReadAsStringAsync();

                        Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode);

                        response = await httpClient.GetAsync("/Restricted");

                        responseText = await response.Content.ReadAsStringAsync();

                        Assert.Equal("Kerberos", responseText);

                        response = await httpClient.GetAsync("/RestrictedNegotiate");

                        responseText = await response.Content.ReadAsStringAsync();

                        // This is Forbidden because we authenticate with Kerberos and challenge for Negotiate.
                        // Note we can't restrict a challenge to a specific auth type, the native auth modules always add themselves,
                        // so both Negotiate and NTLM get sent again.
                        Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode);

                        response = await httpClient.GetAsync("/RestrictedNTLM");

                        responseText = await response.Content.ReadAsStringAsync();

                        // This is Forbidden because we authenticate with Kerberos and challenge for NTLM.
                        // Note we can't restrict a challenge to a specific auth type, the native auth modules always add themselves,
                        // so both Negotiate and NTLM get sent again.
                        Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode);
                    }
                    catch (XunitException)
                    {
                        logger.LogWarning(response.ToString());
                        logger.LogWarning(responseText);
                        throw;
                    }
                }
            }
        }
Example #14
0
        public async Task DeployTestAndAddToSpec(ServerType server, bool ssl, string environment, CancellationToken cancellationToken, Action <AutobahnExpectations> expectationConfig = null)
        {
            var baseUrl     = ssl ? "https://localhost:0" : "http://localhost:0";
            var sslNamePart = ssl ? "SSL" : "NoSSL";
            var name        = $"{server}|{sslNamePart}|{environment}";
            var logger      = _loggerFactory.CreateLogger($"AutobahnTestApp:{server}:{sslNamePart}:{environment}");

            var appPath         = Helpers.GetApplicationPath("AutobahnTestApp");
            var configPath      = Path.Combine(Directory.GetCurrentDirectory(), "..", "..", "..", "Http.config");
            var targetFramework =
#if NETCOREAPP2_1
                "netcoreapp2.1";
#elif NETCOREAPP2_0
                "netcoreapp2.0";
#else
#error Target frameworks need to be updated
#endif
            var parameters = new DeploymentParameters(appPath, server, RuntimeFlavor.CoreClr, RuntimeArchitecture.x64)
            {
                ApplicationBaseUriHint = baseUrl,
                ApplicationType        = ApplicationType.Portable,
                TargetFramework        = targetFramework,
                EnvironmentName        = environment,
                SiteName = "HttpTestSite", // This is configured in the Http.config
                ServerConfigTemplateContent = (server == ServerType.IISExpress) ? File.ReadAllText(configPath) : null,
            };

            var deployer = ApplicationDeployerFactory.Create(parameters, _loggerFactory);
            var result   = await deployer.DeployAsync();

            _deployers.Add(deployer);
            _deployments.Add(result);
            cancellationToken.ThrowIfCancellationRequested();

            var handler = new HttpClientHandler();
            if (ssl)
            {
                // Don't take this out of the "if(ssl)". If we set it on some platforms, it crashes
                // So we avoid running SSL tests on those platforms (for now).
                // See https://github.com/dotnet/corefx/issues/9728
                handler.ServerCertificateCustomValidationCallback = (_, __, ___, ____) => true;
            }
            var client = result.CreateHttpClient(handler);

            // Make sure the server works
            var resp = await RetryHelper.RetryRequest(() =>
            {
                cancellationToken.ThrowIfCancellationRequested();
                return(client.GetAsync(result.ApplicationBaseUri));
            }, logger, CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, result.HostShutdownToken).Token);

            resp.EnsureSuccessStatusCode();

            cancellationToken.ThrowIfCancellationRequested();

            // Add to the current spec
            var wsUrl = result.ApplicationBaseUri.Replace("https://", "wss://").Replace("http://", "ws://");
            Spec.WithServer(name, wsUrl);

            var expectations = new AutobahnExpectations(server, ssl, environment);
            expectationConfig?.Invoke(expectations);
            _expectations.Add(expectations);

            cancellationToken.ThrowIfCancellationRequested();
        }
        private async Task <UploadResult> UploadAsync(IAsyncCommandContext context, int uploaderId, bool uploadToBlob, CancellationToken token)
        {
            List <string> failedFiles  = new List <string>();
            long          uploadedSize = 0;
            string        fileToUpload;
            Stopwatch     uploadTimer = new Stopwatch();

            while (_fileUploadQueue.TryDequeue(out fileToUpload))
            {
                token.ThrowIfCancellationRequested();
                try
                {
                    string itemPath = (_containerPath.TrimEnd('/') + "/" + fileToUpload.Remove(0, _sourceParentDirectory.Length + 1)).Replace('\\', '/');
                    uploadTimer.Restart();
                    bool catchExceptionDuringUpload = false;
                    HttpResponseMessage response    = null;
                    long uploadLength = 0;
                    try
                    {
                        if (uploadToBlob)
                        {
                            var result = await UploadToBlobStore(context, fileToUpload, token);

                            var retryHelper = new RetryHelper(context);

                            response = await retryHelper.Retry(async() => await _fileContainerHttpClient.CreateItemForArtifactUpload(_containerId, itemPath, _projectId,
                                                                                                                                     result.dedupId.ValueString, (long)result.length, token),
                                                               (retryCounter) => (int)Math.Pow(retryCounter, 2) * 5,
                                                               (exception) => true);

                            uploadLength = (long)result.length;
                        }
                        else
                        {
                            using (FileStream fs = File.Open(fileToUpload, FileMode.Open, FileAccess.Read, FileShare.Read))
                            {
                                response = await _fileContainerHttpClient.UploadFileAsync(_containerId, itemPath, fs, _projectId, cancellationToken : token, chunkSize : 4 * 1024 * 1024);

                                uploadLength = fs.Length;
                            }
                        }
                    }
                    catch (OperationCanceledException) when(token.IsCancellationRequested)
                    {
                        context.Output(StringUtil.Loc("FileUploadCancelled", fileToUpload));
                        if (response != null)
                        {
                            response.Dispose();
                            response = null;
                        }

                        throw;
                    }
                    catch (Exception ex)
                    {
                        catchExceptionDuringUpload = true;
                        context.Output(StringUtil.Loc("FileUploadFailed", fileToUpload, ex.Message));
                        context.Output(ex.ToString());
                    }

                    uploadTimer.Stop();
                    if (catchExceptionDuringUpload || (response != null && response.StatusCode != HttpStatusCode.Created))
                    {
                        if (response != null)
                        {
                            context.Output(StringUtil.Loc("FileContainerUploadFailed", response.StatusCode, response.ReasonPhrase, fileToUpload, itemPath));
                        }

                        // output detail upload trace for the file.
                        ConcurrentQueue <string> logQueue;
                        if (_fileUploadTraceLog.TryGetValue(itemPath, out logQueue))
                        {
                            context.Output(StringUtil.Loc("FileUploadDetailTrace", itemPath));
                            string message;
                            while (logQueue.TryDequeue(out message))
                            {
                                context.Output(message);
                            }
                        }

                        // tracking file that failed to upload.
                        failedFiles.Add(fileToUpload);
                    }
                    else
                    {
                        context.Debug(StringUtil.Loc("FileUploadFinish", fileToUpload, uploadTimer.ElapsedMilliseconds));
                        uploadedSize += uploadLength;
                        // debug detail upload trace for the file.
                        ConcurrentQueue <string> logQueue;
                        if (_fileUploadTraceLog.TryGetValue(itemPath, out logQueue))
                        {
                            context.Debug($"Detail upload trace for file: {itemPath}");
                            string message;
                            while (logQueue.TryDequeue(out message))
                            {
                                context.Debug(message);
                            }
                        }
                    }

                    if (response != null)
                    {
                        response.Dispose();
                        response = null;
                    }

                    Interlocked.Increment(ref _filesProcessed);
                }
                catch (Exception ex)
                {
                    context.Output(StringUtil.Loc("FileUploadFileOpenFailed", ex.Message, fileToUpload));
                    throw;
                }
            }

            return(new UploadResult(failedFiles, uploadedSize));
        }
Example #16
0
 private async Task Connect(bool askToLogin)
 {
     await RetryHelper.RetryOnExceptionAsync(async() => await ConnectImpl(askToLogin), 2, TimeSpan.FromSeconds(2), CancellationToken.None);
 }
 private async Task <BitFinexOrderBook> GetBitFinexOrderBook(Pair pair, CancellationToken token = default(CancellationToken))
 {
     return(await RetryHelper.DoAsync(async() => await Query <BitFinexOrderBook>(_baseUri.AbsoluteUri +
                                                                                 $"v{Version}/book/{PairToString(pair)}", token),
                                      TimeSpan.FromMilliseconds(Constant.DefaultRetryInterval)));
 }
Example #18
0
        internal static async Task RunTestsAsync(DeploymentResult deploymentResult, ILogger logger)
        {
            var httpClientHandler = new HttpClientHandler();
            var httpClient        = deploymentResult.CreateHttpClient(httpClientHandler);

            httpClient.Timeout = TimeSpan.FromSeconds(15);

            // Request to base address and check if various parts of the body are rendered
            // & measure the cold startup time.
            var response = await RetryHelper.RetryRequest(async() =>
            {
                return(await httpClient.GetAsync(string.Empty));
            }, logger, cancellationToken : deploymentResult.HostShutdownToken);

            Assert.False(response == null, "Response object is null because the client could not " +
                         "connect to the server after multiple retries");

            var validator = new Validator(httpClient, httpClientHandler, logger, deploymentResult);

            logger.LogInformation("Verifying home page");
            await validator.VerifyHomePage(response);

            logger.LogInformation("Verifying static files are served from static file middleware");
            await validator.VerifyStaticContentServed();

            logger.LogInformation("Verifying access to a protected resource should automatically redirect to login page.");
            await validator.AccessStoreWithoutPermissions();

            logger.LogInformation("Verifying mismatched passwords trigger validaton errors during user registration");
            await validator.RegisterUserWithNonMatchingPasswords();

            logger.LogInformation("Verifying valid user registration");
            var generatedEmail = await validator.RegisterValidUser();

            logger.LogInformation("Verifying duplicate user email registration");
            await validator.RegisterExistingUser(generatedEmail);

            logger.LogInformation("Verifying incorrect password login");
            await validator.SignInWithInvalidPassword(generatedEmail, "InvalidPassword~1");

            logger.LogInformation("Verifying valid user log in");
            await validator.SignInWithUser(generatedEmail, "Password~1");

            logger.LogInformation("Verifying change password");
            await validator.ChangePassword(generatedEmail);

            logger.LogInformation("Verifying old password is not valid anymore");
            await validator.SignOutUser(generatedEmail);

            await validator.SignInWithInvalidPassword(generatedEmail, "Password~1");

            await validator.SignInWithUser(generatedEmail, "Password~2");

            logger.LogInformation("Verifying authenticated user trying to access unauthorized resource");
            await validator.AccessStoreWithoutPermissions(generatedEmail);

            logger.LogInformation("Verifying user log out");
            await validator.SignOutUser(generatedEmail);

            logger.LogInformation("Verifying admin user login");
            await validator.SignInWithUser("*****@*****.**", "YouShouldChangeThisPassword1!");

            logger.LogInformation("Verifying admin user's access to store manager page");
            await validator.AccessStoreWithPermissions();

            logger.LogInformation("Verifying creating a new album");
            var albumName = await validator.CreateAlbum();

            var albumId = await validator.FetchAlbumIdFromName(albumName);

            logger.LogInformation("Verifying retrieved album details");
            await validator.VerifyAlbumDetails(albumId, albumName);

            logger.LogInformation("Verifying status code pages for non-existing items");
            await validator.VerifyStatusCodePages();

            logger.LogInformation("Verifying non-admin view of an album");
            await validator.GetAlbumDetailsFromStore(albumId, albumName);

            logger.LogInformation("Verifying adding album to a cart");
            await validator.AddAlbumToCart(albumId, albumName);

            logger.LogInformation("Verifying cart checkout");
            await validator.CheckOutCartItems();

            logger.LogInformation("Verifying deletion of album from a cart");
            await validator.DeleteAlbum(albumId, albumName);

            logger.LogInformation("Verifying administrator log out");
            await validator.SignOutUser("Administrator");

            logger.LogInformation("Variation completed successfully.");
        }
 public async Task <IEnumerable <BitFinexLend> > GetLends(string currency, CancellationToken token = default(CancellationToken))
 {
     return(await RetryHelper.DoAsync(async() => await Query <List <BitFinexLend> >(_baseUri.AbsoluteUri +
                                                                                    $"v{Version}/lends/{currency}", token), TimeSpan.FromMilliseconds(Constant.DefaultRetryInterval)));
 }
        private async Task NtlmAuthenticationTest(ServerType serverType, RuntimeFlavor runtimeFlavor, ApplicationType applicationType)
        {
            var architecture = RuntimeArchitecture.x64;
            var testName     = $"NtlmAuthentication_{serverType}_{runtimeFlavor}_{applicationType}";

            using (StartLog(out var loggerFactory, testName))
            {
                var logger           = loggerFactory.CreateLogger("NtlmAuthenticationTest");
                var musicStoreDbName = DbUtils.GetUniqueName();

                var deploymentParameters = new DeploymentParameters(Helpers.GetApplicationPath(), serverType, runtimeFlavor, architecture)
                {
                    PublishApplicationBeforeDeployment       = true,
                    PreservePublishedApplicationForDebugging = Helpers.PreservePublishedApplicationForDebugging,
                    TargetFramework             = Helpers.GetTargetFramework(runtimeFlavor),
                    Configuration               = Helpers.GetCurrentBuildConfiguration(),
                    ApplicationType             = applicationType,
                    EnvironmentName             = "NtlmAuthentication", //Will pick the Start class named 'StartupNtlmAuthentication'
                    ServerConfigTemplateContent = (serverType == ServerType.IISExpress) ? File.ReadAllText(Path.Combine(AppContext.BaseDirectory, "NtlmAuthentation.config")) : null,
                    SiteName = "MusicStoreNtlmAuthentication",          //This is configured in the NtlmAuthentication.config
                    UserAdditionalCleanup = parameters =>
                    {
                        DbUtils.DropDatabase(musicStoreDbName, logger);
                    }
                };

                // Override the connection strings using environment based configuration
                deploymentParameters.EnvironmentVariables
                .Add(new KeyValuePair <string, string>(
                         MusicStoreConfig.ConnectionStringKey,
                         DbUtils.CreateConnectionString(musicStoreDbName)));

                using (var deployer = ApplicationDeployerFactory.Create(deploymentParameters, loggerFactory))
                {
                    var deploymentResult = await deployer.DeployAsync();

                    var httpClientHandler = new HttpClientHandler()
                    {
                        UseDefaultCredentials = true
                    };
                    var httpClient = deploymentResult.CreateHttpClient(httpClientHandler);

                    // Request to base address and check if various parts of the body are rendered & measure the cold startup time.
                    var response = await RetryHelper.RetryRequest(async() =>
                    {
                        return(await httpClient.GetAsync(string.Empty));
                    }, logger : logger, cancellationToken : deploymentResult.HostShutdownToken);

                    Assert.False(response == null, "Response object is null because the client could not " +
                                 "connect to the server after multiple retries");

                    var validator = new Validator(httpClient, httpClientHandler, logger, deploymentResult);

                    logger.LogInformation("Verifying home page");
                    await validator.VerifyNtlmHomePage(response);

                    logger.LogInformation("Verifying access to store with permissions");
                    await validator.AccessStoreWithPermissions();

                    logger.LogInformation("Variation completed successfully.");
                }
            }
        }
Example #21
0
        public async Task NtlmAuthentication(TestVariant variant)
        {
            var testName = $"NtlmAuthentication_{variant.Server}_{variant.Tfm}_{variant.Architecture}_{variant.ApplicationType}";

            using (StartLog(out var loggerFactory, testName))
            {
                var logger = loggerFactory.CreateLogger("NtlmAuthenticationTest");

                var deploymentParameters = new DeploymentParameters(variant)
                {
                    ApplicationPath = Helpers.GetApplicationPath(),
                    EnvironmentName = "NtlmAuthentication", // Will pick the Start class named 'StartupNtlmAuthentication'
                };

                using (var deployer = IISApplicationDeployerFactory.Create(deploymentParameters, loggerFactory))
                {
                    var deploymentResult = await deployer.DeployAsync();

                    var httpClient = deploymentResult.HttpClient;

                    // Request to base address and check if various parts of the body are rendered & measure the cold startup time.
                    var response = await RetryHelper.RetryRequest(() =>
                    {
                        return(httpClient.GetAsync(string.Empty));
                    }, logger, deploymentResult.HostShutdownToken);

                    var responseText = await response.Content.ReadAsStringAsync();

                    try
                    {
                        Assert.Equal("Hello World", responseText);

                        logger.LogInformation("Testing /Anonymous");
                        response = await httpClient.GetAsync("/Anonymous");

                        responseText = await response.Content.ReadAsStringAsync();

                        Assert.Equal("Anonymous?True", responseText);

                        logger.LogInformation("Testing /Restricted");
                        response = await httpClient.GetAsync("/Restricted");

                        responseText = await response.Content.ReadAsStringAsync();

                        Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
                        if (variant.Server == ServerType.Kestrel)
                        {
                            Assert.DoesNotContain("NTLM", response.Headers.WwwAuthenticate.ToString());
                        }
                        else
                        {
                            Assert.Contains("NTLM", response.Headers.WwwAuthenticate.ToString());
                        }
                        Assert.Contains("Negotiate", response.Headers.WwwAuthenticate.ToString());

                        logger.LogInformation("Testing /Forbidden");
                        response = await httpClient.GetAsync("/Forbidden");

                        Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode);

                        logger.LogInformation("Enabling Default Credentials");

                        // Change the http client to one that uses default credentials
                        httpClient = deploymentResult.CreateHttpClient(new HttpClientHandler()
                        {
                            UseDefaultCredentials = true
                        });

                        logger.LogInformation("Testing /Restricted");
                        response = await httpClient.GetAsync("/Restricted");

                        responseText = await response.Content.ReadAsStringAsync();

                        Assert.Equal(HttpStatusCode.OK, response.StatusCode);
                        Assert.Equal("Authenticated", responseText);

                        logger.LogInformation("Testing /Forbidden");
                        response = await httpClient.GetAsync("/Forbidden");

                        Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode);
                    }
                    catch (XunitException)
                    {
                        logger.LogWarning(response.ToString());
                        logger.LogWarning(responseText);
                        throw;
                    }
                }
            }
        }
Example #22
0
        private async Task NtlmAuthenticationTest(TestVariant variant)
        {
            var testName = $"NtlmAuthentication_{variant}";

            using (StartLog(out var loggerFactory, testName))
            {
                var logger           = loggerFactory.CreateLogger("NtlmAuthenticationTest");
                var musicStoreDbName = DbUtils.GetUniqueName();

                var deploymentParameters = new DeploymentParameters(variant)
                {
                    ApplicationPath = Helpers.GetApplicationPath(),
                    PreservePublishedApplicationForDebugging = Helpers.PreservePublishedApplicationForDebugging,
                    EnvironmentName       = "NtlmAuthentication", //Will pick the Start class named 'StartupNtlmAuthentication'
                    UserAdditionalCleanup = parameters =>
                    {
                        DbUtils.DropDatabase(musicStoreDbName, logger);
                    }
                };

                // Override the connection strings using environment based configuration
                deploymentParameters.EnvironmentVariables
                .Add(new KeyValuePair <string, string>(
                         MusicStoreConfig.ConnectionStringKey,
                         DbUtils.CreateConnectionString(musicStoreDbName)));

                if (variant.Server == ServerType.IISExpress)
                {
                    var iisDeploymentParameters = new IISDeploymentParameters(deploymentParameters);
                    iisDeploymentParameters.ServerConfigActionList.Add(
                        (element, _) => {
                        var authentication = element
                                             .RequiredElement("system.webServer")
                                             .GetOrAdd("security")
                                             .GetOrAdd("authentication");

                        authentication.GetOrAdd("anonymousAuthentication")
                        .SetAttributeValue("enabled", "false");

                        authentication.GetOrAdd("windowsAuthentication")
                        .SetAttributeValue("enabled", "true");
                    });
                    deploymentParameters = iisDeploymentParameters;
                }

                using (var deployer = IISApplicationDeployerFactory.Create(deploymentParameters, loggerFactory))
                {
                    var deploymentResult = await deployer.DeployAsync();

                    var httpClientHandler = new HttpClientHandler()
                    {
                        UseDefaultCredentials = true
                    };
                    var httpClient = deploymentResult.CreateHttpClient(httpClientHandler);

                    // Request to base address and check if various parts of the body are rendered & measure the cold startup time.
                    var response = await RetryHelper.RetryRequest(async() =>
                    {
                        return(await httpClient.GetAsync(string.Empty));
                    }, logger : logger, cancellationToken : deploymentResult.HostShutdownToken);

                    Assert.False(response == null, "Response object is null because the client could not " +
                                 "connect to the server after multiple retries");

                    var validator = new Validator(httpClient, httpClientHandler, logger, deploymentResult);

                    logger.LogInformation("Verifying home page");
                    await validator.VerifyNtlmHomePage(response);

                    logger.LogInformation("Verifying architecture");
                    validator.VerifyArchitecture(response, deploymentResult.DeploymentParameters.RuntimeArchitecture);

                    logger.LogInformation("Verifying access to store with permissions");
                    await validator.AccessStoreWithPermissions();

                    logger.LogInformation("Variation completed successfully.");
                }
            }
        }
Example #23
0
        public async Task HelloWorld(TestVariant variant)
        {
            var testName = $"HelloWorld_{variant.Server}_{variant.Tfm}_{variant.Architecture}_{variant.ApplicationType}";

            using (StartLog(out var loggerFactory,
                            variant.Server == ServerType.Nginx ? LogLevel.Trace : LogLevel.Debug, // https://github.com/aspnet/ServerTests/issues/144
                            testName))
            {
                var logger = loggerFactory.CreateLogger("HelloWorld");

                var deploymentParameters = new DeploymentParameters(variant)
                {
                    ApplicationPath = Helpers.GetApplicationPath()
                };

                if (variant.Server == ServerType.Nginx)
                {
                    deploymentParameters.ServerConfigTemplateContent = Helpers.GetNginxConfigContent("nginx.conf");
                }

                using (var deployer = IISApplicationDeployerFactory.Create(deploymentParameters, loggerFactory))
                {
                    var deploymentResult = await deployer.DeployAsync();

                    // Request to base address and check if various parts of the body are rendered & measure the cold startup time.
                    var response = await RetryHelper.RetryRequest(() =>
                    {
                        return(deploymentResult.HttpClient.GetAsync(string.Empty));
                    }, logger, deploymentResult.HostShutdownToken);

                    var responseText = await response.Content.ReadAsStringAsync();

                    try
                    {
                        if (variant.Architecture == RuntimeArchitecture.x64)
                        {
                            Assert.Equal("Hello World X64", responseText);
                        }
                        else
                        {
                            Assert.Equal("Hello World X86", responseText);
                        }
                    }
                    catch (XunitException)
                    {
                        logger.LogWarning(response.ToString());
                        logger.LogWarning(responseText);
                        throw;
                    }

                    // Make sure it was the right server.
                    var serverHeader = response.Headers.Server.ToString();
                    switch (variant.Server)
                    {
                    case ServerType.HttpSys:
                        Assert.Equal("Microsoft-HTTPAPI/2.0", serverHeader);
                        break;

                    case ServerType.Nginx:
                        Assert.StartsWith("nginx/", serverHeader);
                        break;

                    case ServerType.Kestrel:
                        Assert.Equal("Kestrel", serverHeader);
                        break;

                    case ServerType.IIS:
                    case ServerType.IISExpress:
                        if (variant.HostingModel == HostingModel.OutOfProcess)
                        {
                            Assert.Equal("Kestrel", serverHeader);
                        }
                        else
                        {
                            Assert.StartsWith("Microsoft-IIS/", serverHeader);
                        }
                        break;

                    default:
                        throw new NotImplementedException(variant.Server.ToString());
                    }
                }
            }
        }
        public async Task Process(IBatchMigrationContext batchContext)
        {
            object           identityObject      = null;
            string           identityValue       = null;
            HashSet <string> identitiesToProcess = new HashSet <string>(StringComparer.OrdinalIgnoreCase);

            foreach (var sourceWorkItem in batchContext.SourceWorkItems)
            {
                foreach (var field in context.IdentityFields)
                {
                    if (sourceWorkItem.Fields.TryGetValueIgnoringCase(field, out identityObject))
                    {
                        identityValue = (string)identityObject;
                        if (!string.IsNullOrEmpty(identityValue) &&
                            identityValue.Contains("<") && identityValue.Contains(">") && (identityValue.Contains("@")))
                        {
                            // parse out email address from the combo string
                            identityValue = identityValue.Substring(identityValue.LastIndexOf("<") + 1, identityValue.LastIndexOf(">") - identityValue.LastIndexOf("<") - 1);

                            if (!identitiesToProcess.Contains(identityValue) &&
                                !this.context.ValidatedIdentities.Contains(identityValue) &&
                                !this.context.InvalidIdentities.Contains(identityValue))
                            {
                                Logger.LogTrace(LogDestination.File, $"Found identity {identityValue} in batch {batchContext.BatchId} which has not yet been validated for the target account");
                                identitiesToProcess.Add(identityValue);
                            }
                        }
                    }
                }
            }

            Logger.LogTrace(LogDestination.File, $"Adding {identitiesToProcess.Count} identities to the account for batch {batchContext.BatchId}");
            foreach (var identity in identitiesToProcess)
            {
                try
                {
                    var createUserResult = await RetryHelper.RetryAsync(async() =>
                    {
                        return(await graphClient.CreateUserAsync(new GraphUserPrincipalNameCreationContext()
                        {
                            PrincipalName = identity
                        }));
                    }, 5);

                    // using identity from createUserResult since the identity could be in a mangled format that ReadIdentities does not support
                    var identities = await RetryHelper.RetryAsync(async() =>
                    {
                        return(await identityHttpClient.ReadIdentitiesAsync(IdentitySearchFilter.MailAddress, createUserResult.MailAddress));
                    }, 5);

                    if (identities.Count == 0)
                    {
                        Logger.LogWarning(LogDestination.File, $"Unable to add identity {identity} to the target account for batch {batchContext.BatchId}");
                        context.InvalidIdentities.Add(identity);
                    }
                    else
                    {
                        var assignResult = await RetryHelper.RetryAsync(async() =>
                        {
                            return(await licensingHttpClient.AssignAvailableEntitlementAsync(identities[0].Id, dontNotifyUser: true));
                        }, 5);

                        context.ValidatedIdentities.Add(identity);
                    }
                }
                catch (Exception ex)
                {
                    Logger.LogWarning(LogDestination.File, ex, $"Unable to add identity {identity} to the target account for batch {batchContext.BatchId}");
                    context.InvalidIdentities.Add(identity);
                }
            }

            Logger.LogTrace(LogDestination.File, $"Completed adding {identitiesToProcess.Count} identities to the account for batch {batchContext.BatchId}");
        }
Example #25
0
 internal Task <HttpResponseMessage> SendRequest(string path) =>
 RetryHelper.RetryRequest(() => _httpClient.GetAsync(new Uri(ListeningUri, path)), logger: NullLogger.Instance);
Example #26
0
        private async Task ResponseCompression(TestVariant variant,
                                               Func <HttpClient, ILogger, Task> scenario,
                                               bool hostCompression,
                                               [CallerMemberName] string testName = null)
        {
            testName = $"{testName}_{variant.Server}_{variant.Tfm}_{variant.Architecture}_{variant.ApplicationType}";
            using (StartLog(out var loggerFactory, testName))
            {
                var logger = loggerFactory.CreateLogger("ResponseCompression");

                var deploymentParameters = new DeploymentParameters(variant)
                {
                    ApplicationPath = Helpers.GetApplicationPath(),
                    EnvironmentName = "ResponseCompression",
                };

                if (variant.Server == ServerType.Nginx)
                {
                    deploymentParameters.ServerConfigTemplateContent = hostCompression
                        ? Helpers.GetNginxConfigContent("nginx.conf")
                        : Helpers.GetNginxConfigContent("NoCompression.conf");
                }
                else if (variant.Server == ServerType.IISExpress && !hostCompression)
                {
                    var iisDeploymentParameters = new IISDeploymentParameters(deploymentParameters);
                    iisDeploymentParameters.ServerConfigActionList.Add(
                        (element, _) => {
                        var compressionElement = element
                                                 .RequiredElement("system.webServer")
                                                 .RequiredElement("httpCompression");

                        compressionElement
                        .RequiredElement("dynamicTypes")
                        .Elements()
                        .SkipLast(1)
                        .Remove();

                        compressionElement
                        .RequiredElement("staticTypes")
                        .Elements()
                        .SkipLast(1)
                        .Remove();
                        // last element in both dynamicTypes and staticTypes disables compression
                        // <add mimeType="*/*" enabled="false" />
                    });
                    deploymentParameters = iisDeploymentParameters;
                }

                using (var deployer = IISApplicationDeployerFactory.Create(deploymentParameters, loggerFactory))
                {
                    var deploymentResult = await deployer.DeployAsync();

                    var httpClientHandler = new HttpClientHandler()
                    {
                        AutomaticDecompression = DecompressionMethods.None
                    };
                    Assert.True(httpClientHandler.SupportsAutomaticDecompression);
                    var httpClient = deploymentResult.CreateHttpClient(httpClientHandler);

                    // Request to base address and check if various parts of the body are rendered & measure the cold startup time.
                    var response = await RetryHelper.RetryRequest(() =>
                    {
                        return(httpClient.GetAsync(string.Empty));
                    }, logger, deploymentResult.HostShutdownToken);

                    var responseText = await response.Content.ReadAsStringAsync();

                    try
                    {
                        Assert.Equal("Running", responseText);
                    }
                    catch (XunitException)
                    {
                        logger.LogWarning(response.ToString());
                        logger.LogWarning(responseText);
                        throw;
                    }

                    await scenario(httpClient, logger);
                }
            }
        }
Example #27
0
 internal Task <HttpResponseMessage> SendRequest(Func <HttpRequestMessage> requestFactory)
 => RetryHelper.RetryRequest(() => _httpClient.SendAsync(requestFactory()), logger: NullLogger.Instance);
        private async Task <bool> UpdateSingleItem(IGrouping <string, Tuple <UpdateInfo, UpdateItem> > task)
        {
            var firstItem = task.First().Item2;
            var itemSize  = firstItem.GetDownloadSize();

            var lastTimestamp        = DateTime.UtcNow;
            var lastDownloadedKBytes = 0l;

            var progress = new Progress <double>(thisPercent =>
            {
                var timeNow = DateTime.UtcNow;
                var secondsSinceLastUpdate = (timeNow - lastTimestamp).TotalSeconds;

                if (secondsSinceLastUpdate < 1 && thisPercent < 100)
                {
                    return;
                }

                //This item: 70% done (1MB / 20MB)
                //Overall: 50% done (111MB / 1221MB)
                //Speed: 1234KB/s (average 1111KB/s)

                var downloadedKBytes    = (long)(itemSize.GetRawSize() * (thisPercent / 100d));
                var downloadedSize      = FileSize.FromKilobytes(downloadedKBytes);
                var totalDownloadedSize = _completedSize + downloadedSize;
                var totalPercent        = ((double)totalDownloadedSize.GetRawSize() / (double)_overallSize.GetRawSize()) * 100d;

                var speed = (downloadedKBytes - lastDownloadedKBytes) / secondsSinceLastUpdate;
                if (double.IsNaN(speed))
                {
                    speed = 0;
                }
                lastDownloadedKBytes = downloadedKBytes;
                lastTimestamp        = timeNow;

                labelPercent.Text =
                    $@"This item: {thisPercent:F1}% done ({downloadedSize} / {itemSize})
Overall: {totalPercent:F1}% done ({totalDownloadedSize} / {_overallSize})
Speed: {speed:F1}KB/s";

                progressBar1.Value = Math.Min((int)(totalPercent * 10), progressBar1.Maximum);
            });

            SetStatus($"Updating {firstItem.TargetPath.Name}");
            SetStatus($"Updating {InstallDirectoryHelper.GetRelativePath(firstItem.TargetPath)}", false, true);

            var sourcesToAttempt = task.Where(x => !_badUpdateSources.Contains(x.Item1)).OrderBy(x => GetPing(x.Item1)).ToList();

            if (sourcesToAttempt.Count == 0)
            {
                Console.WriteLine("There are no working sources to download from. Check the log for reasons why the sources failed.");

                _failedItems.Add(task);
                return(false);
            }

            Exception ex = null;

            foreach (var source in sourcesToAttempt)
            {
                try
                {
                    // Needed because ZipUpdater doesn't support progress
                    if (source.Item2.RemoteFile is ZipUpdater.ArchiveItem)
                    {
                        labelPercent.Text = $"Extracting... Overall progress: {_completedSize} / {_overallSize}.";
                    }

                    await RetryHelper.RetryOnExceptionAsync(() => source.Item2.Update(progress, _cancelToken.Token), 3,
                                                            TimeSpan.FromSeconds(3), _cancelToken.Token);

                    _completedSize += source.Item2.GetDownloadSize();
                    ex              = null;
                    break;
                }
                catch (OperationCanceledException)
                {
                    throw;
                }
                catch (Exception e)
                {
                    Console.WriteLine($"Marking source {source.Item1.Source.Origin} as broken because of exception: {e.ToStringDemystified()}");

                    ex = e;
                    _badUpdateSources.Add(source.Item1);
                }
            }
            // Check if all sources failed
            if (ex != null)
            {
                Console.WriteLine("There are no working sources to download from. Check the log for reasons why the sources failed.");

                _failedItems.Add(task);
                _failedExceptions.Add(ex);
                return(false);
            }

            return(true);
        }
Example #29
0
        private async Task HelloWorld(RuntimeFlavor runtimeFlavor, ApplicationType applicationType, ANCMVersion ancmVersion)
        {
            var serverType   = ServerType.IISExpress;
            var architecture = RuntimeArchitecture.x64;
            var testName     = $"HelloWorld_{runtimeFlavor}";

            using (StartLog(out var loggerFactory, testName))
            {
                var logger = loggerFactory.CreateLogger("HelloWorldTest");

                var deploymentParameters = new DeploymentParameters(Helpers.GetOutOfProcessTestSitesPath(), serverType, runtimeFlavor, architecture)
                {
                    EnvironmentName             = "HelloWorld", // Will pick the Start class named 'StartupHelloWorld',
                    ServerConfigTemplateContent = (serverType == ServerType.IISExpress) ? File.ReadAllText("AppHostConfig/Http.config") : null,
                    SiteName        = "HttpTestSite",           // This is configured in the Http.config
                    TargetFramework = runtimeFlavor == RuntimeFlavor.Clr ? "net461" : "netcoreapp2.1",
                    ApplicationType = applicationType,
                    ANCMVersion     = ancmVersion
                };

                using (var deployer = ApplicationDeployerFactory.Create(deploymentParameters, loggerFactory))
                {
                    var deploymentResult = await deployer.DeployAsync();

                    // Request to base address and check if various parts of the body are rendered & measure the cold startup time.
                    var response = await RetryHelper.RetryRequest(() =>
                    {
                        return(deploymentResult.HttpClient.GetAsync(string.Empty));
                    }, logger, deploymentResult.HostShutdownToken, retryCount : 30);

                    var responseText = await response.Content.ReadAsStringAsync();

                    try
                    {
                        Assert.Equal("Hello World", responseText);

                        response = await deploymentResult.HttpClient.GetAsync("/Path%3F%3F?query");

                        responseText = await response.Content.ReadAsStringAsync();

                        Assert.Equal("/Path??", responseText);

                        response = await deploymentResult.HttpClient.GetAsync("/Query%3FPath?query?");

                        responseText = await response.Content.ReadAsStringAsync();

                        Assert.Equal("?query?", responseText);

                        response = await deploymentResult.HttpClient.GetAsync("/BodyLimit");

                        responseText = await response.Content.ReadAsStringAsync();

                        Assert.Equal("null", responseText);

                        response = await deploymentResult.HttpClient.GetAsync("/Auth");

                        responseText = await response.Content.ReadAsStringAsync();

                        // We adapted the Http.config file to be used for inprocess too. We specify WindowsAuth is enabled
                        // We now expect that windows auth is enabled rather than disabled.
                        Assert.True("backcompat;Windows".Equals(responseText) || "latest;Windows".Equals(responseText), "Auth");
                    }
                    catch (XunitException)
                    {
                        logger.LogWarning(response.ToString());
                        logger.LogWarning(responseText);
                        throw;
                    }
                }
            }
        }
Example #30
0
        /// <exception cref="IOException">Failed to apply the update.</exception>
        public async Task Update(Progress <double> progressCallback, CancellationToken cancellationToken)
        {
            var downloadTarget = await GetTempDownloadFilename();

            // Need to store the filename because MoveTo changes it to the new filename
            var downloadFilename = downloadTarget.FullName;

            if (RemoteFile != null)
            {
                Console.WriteLine($"Attempting download from source {RemoteFile.Source.Origin}");
                await RetryHelper.RetryOnExceptionAsync(async() => await RemoteFile.Download(downloadTarget, progressCallback, cancellationToken), 2, TimeSpan.FromSeconds(10), cancellationToken);

                downloadTarget.Refresh();
                if (!downloadTarget.Exists || downloadTarget.Length != RemoteFile.ItemSize)
                {
                    throw new IOException($"Failed to download the update file {RemoteFile.Name} - the downloaded file doesn't exist or is corrupted");
                }

                Console.WriteLine($"Downloaded {downloadTarget.Length} bytes successfully");
            }

retryDelete:
            try
            {
                Directory.CreateDirectory(Path.GetDirectoryName(TargetPath.FullName));
                if (TargetPath.Exists)
                {
                    Console.WriteLine($"Deleting old file {TargetPath.FullName}");
                    TargetPath.Delete();
                }
                if (RemoteFile != null)
                {
                    downloadTarget.MoveTo(TargetPath.FullName);
                }
            }
            catch (IOException ex)
            {
                if (await ProcessWaiter.CheckForProcessesBlockingKoiDir() != true)
                {
                    throw new IOException($"Failed to apply update {TargetPath.FullName} because of an IO issue - {ex.Message}", ex);
                }

                goto retryDelete;
            }
            catch (SecurityException ex)
            {
                if (MessageBox.Show($"Failed to apply update {TargetPath.FullName} because of a security issue - {ex.Message}\n\nDo you want KK Manager to attempt to fix the issue? Click cancel if you want to abort.",
                                    "Could not apply update", MessageBoxButtons.OKCancel, MessageBoxIcon.Error) != DialogResult.OK)
                {
                    throw;
                }

                var fixPermissions = ProcessTools.FixPermissions(InstallDirectoryHelper.KoikatuDirectory.FullName);
                if (fixPermissions == null)
                {
                    throw new IOException($"Failed to create file in directory {TargetPath.FullName} because of a security issue - {ex.Message}", ex);
                }
                fixPermissions.WaitForExit();
                goto retryDelete;
            }
            finally
            {
                try { File.Delete(downloadFilename); }
                catch (SystemException ex) { Console.WriteLine(ex); }
            }
        }
Example #31
0
        private void DownloadChapter(BackgroundWorker backgroundWorker, DoWorkEventArgs e, IChapterRecord chapter, string outputFolder, IDownloadFormatProvider formatProvider)
        {
            // add task -> export result
            AddTask();

            var directory = Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), "MangaScraper", Guid.NewGuid().ToString()));

            try
            {
                AddTask();
                backgroundWorker.ReportProgress(GetPercentComplete(), "Resolving list of pages.");

                var pages = _pageResolver(chapter);

                AddTask(pages.Count);

                TaskDone();
                backgroundWorker.ReportProgress(GetPercentComplete(), String.Format("List of pages resolved, chapter has {0} pages.", pages.Count));

                int current = 1;

                foreach (var page in pages)
                {
                    if (backgroundWorker.CancellationPending)
                    {
                        e.Cancel = true;
                        return;
                    }

                    backgroundWorker.ReportProgress(GetPercentComplete(), String.Format("Downloading page {0} from {1}", current, pages.Count));

                    string imgUrl   = _imageFinder(page.Value);
                    string filePath = GetUniqueFileName(directory.FullName, page.Key, Path.GetExtension(imgUrl));

                    try
                    {
                        RetryHelper.Retry(() => WebHelper.DownloadImage(imgUrl, filePath));
                    }
                    catch (Exception ex)
                    {
                        _log.Error("Unable to download image from url: '" + imgUrl + "' to '" + filePath + "'", ex);
                    }

                    current++;
                    TaskDone();
                }

                backgroundWorker.ReportProgress(GetPercentComplete(), "All pages downloaded.");
                backgroundWorker.ReportProgress(GetPercentComplete(), "Exporting chapter");

                if (backgroundWorker.CancellationPending)
                {
                    e.Cancel = true;
                    return;
                }

                string path;
                formatProvider.SaveDownloadedChapter(chapter, directory, outputFolder, out path);

                // save result path of the downloaded file
                e.Result = path;

                TaskDone();
                backgroundWorker.ReportProgress(GetPercentComplete(), "Download completed");
            }
            finally
            {
                // remove temp dir
                directory.Delete(true);
            }
        }
 public void SetUp()
 {
     _target = new RetryHelper();
     _target.DefaultTryInterval = TimeSpan.FromMilliseconds(RetryHelperTest.Interval);
 }
Example #33
0
        public async Task Publish_And_Run_Tests(
            ServerType serverType,
            RuntimeFlavor runtimeFlavor,
            RuntimeArchitecture architecture,
            ApplicationType applicationType,
            string applicationBaseUrl,
            bool noSource)
        {
            using (_logger.BeginScope("Publish_And_Run_Tests"))
            {
                var musicStoreDbName = DbUtils.GetUniqueName();

                var deploymentParameters = new DeploymentParameters(
                    Helpers.GetApplicationPath(applicationType), serverType, runtimeFlavor, architecture)
                {
                    ApplicationBaseUriHint                   = applicationBaseUrl,
                    PublishApplicationBeforeDeployment       = true,
                    PreservePublishedApplicationForDebugging = Helpers.PreservePublishedApplicationForDebugging,
                    TargetFramework       = runtimeFlavor == RuntimeFlavor.Clr ? "net451" : "netcoreapp1.1",
                    Configuration         = Helpers.GetCurrentBuildConfiguration(),
                    ApplicationType       = applicationType,
                    UserAdditionalCleanup = parameters =>
                    {
                        DbUtils.DropDatabase(musicStoreDbName, _logger);
                    }
                };

                // Override the connection strings using environment based configuration
                deploymentParameters.EnvironmentVariables
                .Add(new KeyValuePair <string, string>(
                         MusicStoreConfig.ConnectionStringKey,
                         DbUtils.CreateConnectionString(musicStoreDbName)));

                using (var deployer = ApplicationDeployerFactory.Create(deploymentParameters, _logger))
                {
                    var deploymentResult  = deployer.Deploy();
                    var httpClientHandler = new HttpClientHandler()
                    {
                        UseDefaultCredentials = true
                    };
                    var httpClient = new HttpClient(httpClientHandler);
                    httpClient.BaseAddress = new Uri(deploymentResult.ApplicationBaseUri);

                    // Request to base address and check if various parts of the body are rendered &
                    // measure the cold startup time.
                    // Add retry logic since tests are flaky on mono due to connection issues
                    var response = await RetryHelper.RetryRequest(async() => await httpClient.GetAsync(string.Empty), logger : _logger, cancellationToken : deploymentResult.HostShutdownToken);

                    Assert.False(response == null, "Response object is null because the client could not " +
                                 "connect to the server after multiple retries");

                    var validator = new Validator(httpClient, httpClientHandler, _logger, deploymentResult);

                    Console.WriteLine("Verifying home page");
                    await validator.VerifyHomePage(response);

                    Console.WriteLine("Verifying static files are served from static file middleware");
                    await validator.VerifyStaticContentServed();

                    if (serverType != ServerType.IISExpress)
                    {
                        if (Directory.GetFiles(
                                deploymentParameters.ApplicationPath, "*.cmd", SearchOption.TopDirectoryOnly).Length > 0)
                        {
                            throw new Exception("publishExclude parameter values are not honored.");
                        }
                    }

                    _logger.LogInformation("Variation completed successfully.");
                }
            }
        }