Example #1
0
        public HttpClient Create(string apiKey, ChaosConfiguration apiConfiguration)
        {
            string cacheKey = "client:" + apiKey;

            if (_memoryCache.Contains(cacheKey))
            {
                return((HttpClient)_memoryCache.Get(cacheKey));
            }

            var client =
                HttpClientFactory.Create(
                    new ChaoticDelegatingHandler(
                        new Chance(),
                        new HandlerSettings(new ConfigurationRotationTimer(apiConfiguration), apiConfiguration),
                        new ChaoticResponseFactory(new ResponseMediaType()),
                        new RandomDelay(),
                        new ChaosIntervalTimer(apiConfiguration), new ResponseFiddler(new ResponseMediaType())));

            client.Timeout = TimeSpan.FromSeconds(apiConfiguration.HttpClientTimeoutInSeconds > 0
                ? apiConfiguration.HttpClientTimeoutInSeconds
                : 15);

            _memoryCache.Add(cacheKey, client, DateTimeOffset.UtcNow.AddSeconds(30));

            return(client);
        }
Example #2
0
        private static void Main()
        {
            Logger = LogManager.GetLogger(nameof(Program));

            //This is for one log file per run (based on start time...)
            NLog.GlobalDiagnosticsContext.Set("StartTime", DateTime.Now.ToString("yyyy-MM-dd-HH:mm:ss"));

            var configPath = Path.Combine(Environment.CurrentDirectory, "Chaos.json");

            if (File.Exists(configPath))
            {
                _chaosConfiguration = GetChaosConfiguration(configPath);
            }

            if (_chaosConfiguration == null)
            {
                // if GetChaosConfiguration fails (which it logs...), then exit...
                Logger?.Info("No configruration supplied... Exiting...");
                Environment.Exit(-1);
            }

            //Repeat setting
            if (_chaosConfiguration.Repeat > 0)
            {
                _repeat = _chaosConfiguration.Repeat;
            }

            //Start delay setting
            if (_chaosConfiguration.RunDelay > 0)
            {
                _runDelay = _chaosConfiguration.RunDelay;
            }

            try
            {
                //Must initialize Bedlam with a ChaosConfiguration...
                _bedlam = new Bedlam(_chaosConfiguration);
            }
            catch (Exception e)
            {
                Logger?.Info("Error initializing Bedlam: " + e.Message + "\n Exiting...");
                Logger?.Error(e);
                Environment.Exit(-1);
            }

            for (int i = 0; i < _repeat + 1; i++)
            {
                if (_runDelay > 0)
                {
                    Thread.Sleep(_runDelay * 1000);
                }

                _bedlam.Run();
            }
        }
Example #3
0
        internal Bedlam(ChaosConfiguration configuration)
        {
            _logger = Program.Logger;

            if (configuration == null)
            {
                _logger?.Error("Can't initialize Bedlam with chaos configuration settings. Check your Chaos.config file.");
                Environment.Exit(-1);
            }

            _config = configuration;

            //Check for null to support the use of one or more chaos operations in the config file... -CT
            if (_config.CpuPressure != null)
            {
                _operations.Add(new CpuPressure(_config.CpuPressure, _config.Duration));
            }
            if (_config.MemoryPressure != null)
            {
                _operations.Add(new MemoryPressure(_config.MemoryPressure, _config.Duration));
            }
            if (_config.NetworkEmulation != null)
            {
                _operations.Add(new Operations.NetworkEmulation(_config.NetworkEmulation, _config.Duration));
            }

            if (_operations.Count == 0)
            {
                _logger?.Error("No operations settings provided. Aborting....");
                throw new Exception(
                          "Cannot execute Bedlam without an operations setting. Check your Chaos.config file...");
            }

            if (_operations.Count == 1)
            {
                _config.Orchestration = Orchestration.Sequential;
            }

            if (_config.Orchestration == Orchestration.Unknown)
            {
                _logger?.Error("No orchestration setting provided. Aborting.");
                throw new Exception("Cannot execute Bedlam without an Orchestration setting. Check your Chaos.config file.");
            }

            _runModes = new Dictionary <Orchestration, Action>
            {
                { Orchestration.Concurrent, RunConcurrent },
                { Orchestration.Random, RunRandom },
                { Orchestration.Sequential, RunSequential }
            };
        }
Example #4
0
        private static void Main()
        {
            Logger = LogManager.GetLogger(nameof(Program));

            var configPath = Path.Combine(Environment.CurrentDirectory, "Chaos.config");

            if (File.Exists(configPath))
            {
                _chaosConfiguration = GetChaosConfiguration(configPath);
            }

            if (_chaosConfiguration == null)
            {
                // if GetChaosConfiguration fails (which it logs...), then exit...
                Logger?.Info("No configruration supplied... Exiting...");
                Environment.Exit(-1);
            }

            //Repeat setting
            if (_chaosConfiguration.Repeat > 0)
            {
                _repeat = _chaosConfiguration.Repeat;
            }

            //Start delay setting
            if (_chaosConfiguration.RunDelay > 0)
            {
                _runDelay = _chaosConfiguration.RunDelay;
            }

            try
            {
                //Must initialize Bedlam instance with ChaosConfiguration instance...
                _bedlam = new Bedlam(_chaosConfiguration);
            }
            catch (Exception e)
            {
                Logger?.Info("Error initializing Bedlam: " + e.Message + "\n Exiting...");
                Environment.Exit(-1);
            }

            for (int i = 0; i < _repeat + 1; i++)
            {
                if (_runDelay > 0)
                {
                    Thread.Sleep(_runDelay * 1000);
                }
                _bedlam.Run();
            }
        }
Example #5
0
        protected void Run(int port = 0)
        {
            var endpoint = GetServerEndpoint();

            IListener listener = Listener;

            if (ParseUtils.ParseSize(options.Bandwidth) is int bandwidth)
            {
                listener = new ThrottlingListener(listener, bandwidth);
            }

            IConnector connector = new SimpleConnector(endpoint, listener);

            if (options.Chaos)
            {
                var chaosConfiguration = new ChaosConfiguration
                {
                    Reject =
                    {
                        Percentage = 0.5
                    },
                    Abort =
                    {
                        Percentage      =                  1,
                        UpstreamBytes   = new Range <long>(0, 1024 * 1024 * 10),
                        DownstreamBytes = new Range <long>(0, 1024 * 1024 * 10)
                    }
                };
                var chaosConnector = new ChaosConnector(chaosConfiguration, connector);

                //chaosConnector.Rejected += (s, e) => Console.WriteLine("REJECTED");
                //chaosConnector.Aborted += (s, e) => Console.WriteLine($"ABORTED reason {e.Reason}, upstream {e.UpstreamTransferred}, downstream {e.DownstreamTransferred}");

                connector = chaosConnector;
            }

            proxy = new ProxyServer(new IPEndPoint(IPAddress.Loopback, port), connector);
            proxy.ExceptionOccured += (s, e) => Console.WriteLine($"EXCEPTION: {e.Exception.Message} ({e.Exception.GetType().FullName})");
            proxy.Start();

            Running(proxy.EndPoint);
        }
Example #6
0
        /// <summary>
        /// Returns a ChaosConfiguaration object with properties set from supplied config file
        /// throws an Exception if anything goes wrong, so try-catch the call to this and handle it...
        /// </summary>
        /// <param name="configPath">full path to Chaos.config file</param>
        /// <returns>ChaosConfguration</returns>
        private static ChaosConfiguration GetChaosConfiguration(string configPath)
        {
            if (!File.Exists(configPath))
            {
                return(null);
            }

            try
            {
                var config = File.ReadAllText(configPath);
                _chaosConfiguration = JsonConvert.DeserializeObject <ChaosConfiguration>(config);
                return(_chaosConfiguration);
            }
            catch (Exception e)
            {
                Logger?.Error(e);
                //Main will exit, OK not to die here...
                return(null);
            }
        }
Example #7
0
        private static void SimulateNetworkFailureEchoServer()
        {
            using (var echoServer = new EchoServer(new IPEndPoint(IPAddress.Loopback, 0)))
            {
                echoServer.Start();

                var configuration = new ChaosConfiguration
                {
                    Reject =
                    {
                        Percentage = 0.5
                    }
                };
                var connector = new ChaosConnector(
                    configuration,
                    new SimpleConnector(echoServer.EndPoint)
                    );

                using (var proxyServer = new ProxyServer(new IPEndPoint(IPAddress.Loopback, 0), connector))
                {
                    proxyServer.Start();

                    var block = Encoding.UTF8.GetBytes("Hello world!");

                    int errors = 0;

                    for (int i = 0; i < 100; i++)
                    {
                        using (var echoClient = new EchoPingClient(proxyServer.EndPoint, block))
                        {
                            echoClient.ExceptionOccured += (s, e) => Interlocked.Increment(ref errors);
                            echoClient.Start();
                            echoClient.Ping();
                        }
                    }

                    Console.WriteLine(errors);
                }
            }
        }
Example #8
0
        /// <summary>
        /// Returns a ChaosConfiguaration object with properties set from supplied config file
        /// throws an Exception if anything goes wrong, so try-catch the call to this and handle it...
        /// </summary>
        /// <param name="configPath">full path to Chaos.config file</param>
        /// <returns>ChaosConfguration</returns>
        private static ChaosConfiguration GetChaosConfiguration(string configPath)
        {
            if (!File.Exists(configPath))
            {
                return(null);
            }

            try
            {
                var serializer = new XmlSerializer(typeof(ChaosConfiguration));
                using (var reader = new StringReader(File.ReadAllText(configPath)))
                {
                    _chaosConfiguration = (ChaosConfiguration)serializer.Deserialize(reader);
                }

                return(_chaosConfiguration);
            }
            catch (Exception e)
            {
                Logger?.Error(e);
                return(null);
            }
        }
        private HttpClient CreateHttpClientForProxiedRequest(ChaosConfiguration chaosConfiguration, string apiKey)
        {
            var client = _chaosHttpClientFactory.Create(apiKey, chaosConfiguration);

            return(client);
        }
 public void Init()
 {
     _apiConfiguration = new ChaosConfiguration();
 }
Example #11
0
        public static ChaosConfiguration ToChaosConfiguration(UpdateConfigurationRequest updateRequest)
        {
            var config = new ChaosConfiguration
            {
                ChaosInterval = new TimeSpan(0, 0, updateRequest.ChaosInterval),
                ConfigurationRotationInterval = new TimeSpan(0, 0, updateRequest.ConfigurationRotationInterval),
                Enabled = updateRequest.Enabled,
                HttpClientTimeoutInSeconds = updateRequest.HttpClientTimeoutInSeconds
            };

            foreach (var updateChaosSettings in updateRequest.ChaosSettings)
            {
                var chaosConfiguration = new ChaosSettings
                {
                    Name = updateChaosSettings.Name,
                    MaxResponseDelayTime      = updateChaosSettings.MaxResponseDelayTime,
                    MinResponseDelayTime      = updateChaosSettings.MinResponseDelayTime,
                    PercentageOfChaos         = updateChaosSettings.PercentageOfChaos,
                    PercentageOfSlowResponses = updateChaosSettings.PercentageOfSlowResponses,
                    ResponseTypeMediaType     = updateChaosSettings.ResponseTypeMediaType
                };

                if (updateChaosSettings.IgnoreUrls != null)
                {
                    foreach (var url in updateChaosSettings.IgnoreUrls)
                    {
                        chaosConfiguration.IgnoreUrlPattern.Add(url.Pattern);
                    }
                }

                foreach (var updateResponse in updateChaosSettings.HttpResponses)
                {
                    var httpResponse = new ResponseDetails {
                        StatusCode = updateResponse.StatusCode
                    };

                    foreach (var payload in updateResponse.Payloads.Select(chaosResponsePayload =>
                                                                           new ChaosResponsePayload
                    {
                        Code = chaosResponsePayload.Code, Content = chaosResponsePayload.Content
                    }))
                    {
                        httpResponse.Payloads.Add(payload);
                    }

                    chaosConfiguration.HttpResponses.Add(httpResponse);
                }

                foreach (var responseFiddle in updateChaosSettings.ResponseFiddles)
                {
                    var fiddle = new ResponseFiddle
                    {
                        Match = responseFiddle.Match,
                        ReplaceMatchingWith = responseFiddle.ReplaceMatchingWith
                    };

                    chaosConfiguration.ResponseFiddles.Add(fiddle);
                }

                config.ChaosSettings.Add(chaosConfiguration);
            }

            return(config);
        }