/// <summary>
        /// Extract the results and put it into transactionDetails: cnt, min, max, avg, stdev
        /// </summary>
        /// <param name="line"></param>
        private TransactionValue ExtractTrsDetailsCSV(string line)
        {
            //sampler_label,aggregate_report_count,average,aggregate_report_median,aggregate_report_90%_line,aggregate_report_95%_line,aggregate_report_99%_line,aggregate_report_min,aggregate_report_max,aggregate_report_error%,aggregate_report_rate,aggregate_report_bandwidth,aggregate_report_stddev
            //setUp: bsh.shared.zoekgob,1,1697,1697,1697,1697,1697,1697,1697,"0,00%",",6",",0","0,00"
            string cLine = CorrectJmeterCSVLine(line);

            string[] parts = cLine.Split(',');

            // wat nog mist is toevoegen van een lege regel als alles fout gegaan is
            TransactionValue value    = new TransactionValue();
            string           executed = parts[1];

            value.cnt = parts[1];
            string cntExecuted = parts[1];

            value.avg    = Utils.jmeterTimeToIntermediateSecondsString(parts[2]);
            value.median = Utils.jmeterTimeToIntermediateSecondsString(parts[3]);
            value.p90    = Utils.jmeterTimeToIntermediateSecondsString(parts[4]);
            value.p95    = Utils.jmeterTimeToIntermediateSecondsString(parts[5]);
            //6=99p not present in csv but not really useable as an application perf metric
            value.min = Utils.jmeterTimeToIntermediateSecondsString(parts[7]);
            value.max = Utils.jmeterTimeToIntermediateSecondsString(parts[8]);

            value.fail  = NormalizeFail(Utils.NormalizeFloatString(parts[9].TrimEnd('%')), cntExecuted);
            value.stdev = Utils.jmeterTimeToIntermediateSecondsString(parts[12]);

            return(value);
        }
        /// <summary>
        /// Add measure to existing or new transaction line (count canceled trs)
        /// </summary>
        /// <param name="line"></param>
        /// <param name="trsName"></param>
        private void ExtractAddTrsMeasureCSV(string line, string trsName)
        {
            //C;Measure group;Name;Measure type;N;Sum;Min;Max;StdDev;Avg;MinSum;MaxSum;MinMax;MaxMin;MinAvg;MaxAvg;MinCnt;MaxCnt
            //;Transaction;LoketControle_01_inloggen;Trans.(busy) ok[s];4;6,72400000;1,56000000;1,82500000;0,09698711;1,68100000;1,56000000;1,82500000;1,56000000;1,82500000;1,56000000;1,82500000;1,00000000;1,00000000

            if (!_transactionDetails.items.ContainsKey(trsName))
            {
                _transactionDetails.items.Add(trsName, TransactionValue.CreateEmptyValue());
            }

            TransactionValue value = new TransactionValue(_transactionDetails.items[trsName]);

            string[] parts = line.Split(';');

            // failed
            if (line.Contains(TRSFAILEDSUBSTRING))
            {
                value.fail = parts[4];
            }

            // canceled
            if (line.Contains(TRSCANCELEDSUBSTRING))
            {
                value.cancel = parts[4];
            }

            _transactionDetails.items[trsName] = value.ToString();
            //Log.WriteLine("csv data extracted: "+trsName + "=" + value.ToString());
        }
Пример #3
0
        public Income(Guid userId, string name, string category, DateTime date, TransactionValue value) : this()
        {
            if (string.IsNullOrEmpty(name))
            {
                throw new Error.IncomeMustHaveName();
            }

            this.Name   = name;
            this.Date   = date;
            this.UserId = userId;

            if (value == null)
            {
                throw new Error.IncomeTransactionValueCannotBeNull();
            }

            this.Value = value;

            if (!Enum.TryParse(typeof(IncomeCategory), category, out var categoryEnum))
            {
                categoryEnum = IncomeCategory.Other;
            }

            this.Category = (IncomeCategory)categoryEnum;
        }
Пример #4
0
        public Income AddIncome(string name, string category, DateTime date, TransactionValue value)
        {
            var newIncome = new Income(this.Id, name, category, date, value);

            this._incomes.Add(newIncome);

            return(newIncome);
        }
Пример #5
0
        internal static Income WithRecurrency(Guid userId, string name, string category, DateTime date,
                                              TransactionValue value, Guid recurrentIncomeId)
        {
            var newIncome = new Income(userId, name, category, date, value);

            newIncome.RecurrentIncomeId = recurrentIncomeId;

            return(newIncome);
        }
Пример #6
0
        public Income EditIncome(Guid id, string name, DateTime date, TransactionValue value)
        {
            var foundIncome = this._incomes.FirstOrDefault(i => i.Id == id);

            if (foundIncome == null)
            {
                throw new Error.IncomeNotFound();
            }

            foundIncome.Update(name, date, value);

            return(foundIncome);
        }
Пример #7
0
        public Expense(Guid userId, string name, string category, DateTime date, TransactionValue value) : this()
        {
            this.Validate(userId, name, date, value);

            this.Date   = date;
            this.Name   = name;
            this.Value  = value;
            this.UserId = userId;

            if (!Enum.TryParse(typeof(ExpenseCategory), category, out var categoryEnum))
            {
                this.Category = ExpenseCategory.Others;
            }

            this.Category = (ExpenseCategory)categoryEnum;
        }
        /// <summary>
        /// Generate aggregate data (total faults, average of percentiles...)
        /// </summary>
        /// <param name="parameters"></param>
        public void GenerateAggregates(ParamInterpreter parameters)
        {
            int cnt = 0;

            Log.WriteLine("generate aggregated data...");
            // scrape and aggregate data from transaction data
            TransactionValueAggregate transactionAggregate = new TransactionValueAggregate();

            // foreach transactionlines (evaluate only successful transactions, leave faulty ones away from aggregation)
            foreach (string transactionName in _transactionNames)
            {
                // only include in agggregation if transactionname matches 'report transacton name pattern'
                if (IsSummarizeTransaction(transactionName) && _transactionDetails.items.ContainsKey(transactionName))
                {
                    TransactionValue trs = new TransactionValue(_transactionDetails.items[transactionName]);
                    transactionAggregate.AddTransaction(trs);
                    cnt++;
                }
            }

            // give up if no summarizable transactions found (try to prevent weird crashes lateron)
            if (0 == cnt)
            {
                string msg = "no transaction names found that meet naming convention (" + REPORTTRANSACTIONNAMEPATTERN + ")";
                Log.WriteLine("SEVERE: " + msg);
                throw new Exception(msg);
            }

            transactionAggregate.Aggregate();

            // write aggregated transaction line
            _transactionDetails.Add(AGGREGATEDTRSNAME, transactionAggregate.ToString());

            // isolate most important values as variable for history graph -> measure format (later to variable category?)
            _variables.Add(AVGOF90PERCENTILES, Utils.ToMeasureFormatString(transactionAggregate.p90));
            _variables.Add(AVGOFMEDIAN, Utils.ToMeasureFormatString(transactionAggregate.median));
            _variables.Add(AVGOF95PERCENTILES, Utils.ToMeasureFormatString(transactionAggregate.p95));
            _variables.Add(AVGOFAVERAGES, Utils.ToMeasureFormatString(transactionAggregate.avg));
            _variables.Add(TRANSACTIONSFAILED, transactionAggregate.fail);

            // old, can be deleted in time (replaced by transactionssuccess)
            // _variables.Add(TRANSACTIONSTOTAL, transactionAggregate.cnt);
            _variables.Add(TRANSACTIONSTOTAL, AddIntStrings(transactionAggregate.cnt, transactionAggregate.fail));
            _variables.Add(TRANSACTIONSSUCCESS, transactionAggregate.cnt); // is new

            Log.WriteLine(string.Format("{0} of {1} transactions aggregated", cnt, _transactionNames.Length));
        }
        /// <summary>
        /// Min, max, avg, cnt transactiondata
        /// </summary>
        /// <param name="lines"></param>
        /// <param name="trsNames"></param>
        private TransactionDetails ReadTransactionDetailsFromCSV(string[] lines, string[] trsNames)
        {
            string             trsName;
            TransactionDetails td = new TransactionDetails();

            foreach (string line in lines)
            {
                trsName = Utils.NormalizeTransactionName(line.Split(',')[0]);

                if (trsNames.Contains(trsName))
                {
                    TransactionValue value = ExtractTrsDetailsCSV(line);
                    td.Add(trsName, value.ToString());
                }
            }
            return(td);
        }
        /// <summary>
        /// Extract percentile data from trs summary in bpr/xml
        /// </summary>
        /// <param name="xml"></param>
        /// <param name="trsName"></param>
        private void ExtractAddTrsDetailsXML(string xml, string trsName)
        {
            //string p90 = Regex.Match(xml, @"nr=""90""><Height>(.*?)</Height").Groups[1].Value;
            if (!_transactionDetails.items.ContainsKey(trsName))
            {
                throw new Exception(string.Format("Transaction [{0}] not found in XML/BRP, cannot add percentile data.", trsName));
            }

            TransactionValue value = new TransactionValue(_transactionDetails.items[trsName]);

            // 50, 90 and 99 percentiles are the most used and easily available, the rest can be calculated by interpolation
            value.median = Regex.Match(xml, @"nr=""50""><Height>(.*?)</Height").Groups[1].Value.TrimEnd('0');
            value.p90    = Regex.Match(xml, @"nr=""90""><Height>(.*?)</Height").Groups[1].Value.TrimEnd('0');
            value.p95    = Regex.Match(xml, @"nr=""95""><Height>(.*?)</Height").Groups[1].Value.TrimEnd('0');

            _transactionDetails.items[trsName] = value.ToString();
            //Log.WriteLine(trsName+" brp data extracted, 90p is : "+value.p90);
        }
        /// <summary>
        /// Extract the results and put it into transactionDetails: cnt, min, max, avg, stdev
        /// </summary>
        /// <param name="line"></param>
        /// <param name="trsName"></param>
        private void ExtractTrsDetailsCSV(string line, string trsName)
        {
            //C;Measure group;Name;Measure type;N;Sum;Min;Max;StdDev;Avg;MinSum;MaxSum;MinMax;MaxMin;MinAvg;MaxAvg;MinCnt;MaxCnt
            //;Transaction;LoketControle_01_inloggen;Trans.(busy) ok[s];4;6,72400000;1,56000000;1,82500000;0,09698711;1,68100000;1,56000000;1,82500000;1,56000000;1,82500000;1,56000000;1,82500000;1,00000000;1,00000000
            //;Timer;DR_01_OpenDonorregister;Response time[s];1;0,80400000;0,80400000;0,80400000;0,00000000;0,80400000;0,80400000;0,80400000;0,80400000;0,80400000;0,80400000;0,80400000;1,00000000;1,00000000

            string[] parts = line.Split(';');

            // wat nog mist is toevoegen van een lege regel als alles fout gegaan is
            TransactionValue value = new TransactionValue();

            value.cnt   = parts[4];
            value.min   = parts[6].TrimEnd('0');
            value.avg   = parts[9].TrimEnd('0');
            value.max   = parts[7].TrimEnd('0');
            value.stdev = parts[8].TrimEnd('0');

            _transactionDetails.Add(trsName, value.ToString());

            Log.WriteLine(trsName + "=" + value.ToString());
        }
Пример #12
0
        private void Validate(Guid userId, string name, DateTime date, TransactionValue value)
        {
            if (userId == Guid.Empty)
            {
                throw new Error.ExpenseMustHaveUserId();
            }

            if (string.IsNullOrEmpty(name))
            {
                throw new Error.ExpenseMustHaveName();
            }

            if (date < DateTime.Now.AddYears(-100))
            {
                throw new Error.ExpenseCannotBeOlderThanOneHundredYears();
            }

            if (value == null)
            {
                throw new Error.ExpenseTransactionValueCannotBeNull();
            }
        }
        /// <summary>
        /// Merge fault data from 'all' transaction data into 'success' transaction data
        /// </summary>
        /// <param name="successTransactionDetails"></param>
        /// <param name="allTransactionDetails"></param>
        private void MergeFaultData(TransactionDetails successTransactionDetails, TransactionDetails allTransactionDetails)
        {
            // iterate over list of all transactions (allTransactionDetails)
            foreach (string trsName in allTransactionDetails.items.GetKeys())
            {
                // if found in successTransactionDetails: some exceptions, so: add only num of faults to existing success story
                if (successTransactionDetails.items.ContainsKey(trsName))
                {
                    // create working object for source- and target data
                    TransactionValue allValue     = new TransactionValue(allTransactionDetails.items[trsName]);
                    TransactionValue successValue = new TransactionValue(successTransactionDetails.items[trsName]);
                    // if all fail (success=0): clear stats
                    if (successValue.cnt == "0")
                    {
                        successValue = new TransactionValue();
                    }

                    // if faults have occured -> calculate fault field
                    if (!successValue.cnt.Equals(allValue.cnt, StringComparison.Ordinal))
                    {
                        successValue.fail = SubtractStrInt(allValue.cnt, successValue.cnt);
                        _transactionDetails.items[trsName] = successValue.ToString(); // replace num of failed
                        Log.WriteLine(string.Format("fault data: {0} faults added to {1}", successValue.fail, trsName));
                    }
                }
                // if not found in successTransactionDetails: 100% exception, so: add empty row with only number of faults
                else
                {
                    TransactionValue newSuccessValue = new TransactionValue();
                    TransactionValue allValue        = new TransactionValue(allTransactionDetails.items[trsName]);
                    // only fill failed field from allvalue (=failed)
                    newSuccessValue.fail = allValue.cnt;
                    _transactionDetails.Add(trsName, newSuccessValue.ToString());
                    Log.WriteLine(string.Format("fault data: no-stats result ({0} faults) for {1}", newSuccessValue.fail, trsName));
                }
            }
        }
Пример #14
0
        public RecurrentExpense(Guid userId, string name, string category, DateTime date, TransactionValue value,
                                DateTime until, int frequency) : this()
        {
            this.Recurrency = new Recurrency(Frequency.FromValue(frequency), until);

            this._expenses.Add(new Expense(userId, name, category, date, value, this.Id));

            foreach (var nextDate in this.Recurrency.DatesUntilRecurrencyEndsByFrequency(date))
            {
                this._expenses.Add(new Expense(userId, name, category, nextDate, value, this.Id));
            }
        }
Пример #15
0
        internal void Update(Guid userId, string name, ExpenseCategory category, DateTime date, TransactionValue value)
        {
            this.Validate(userId, name, date, value);

            this.Name     = name;
            this.Category = category;
            this.Date     = date;
            this.Value    = value;
        }
Пример #16
0
 internal Expense(Guid userId, string name, string category, DateTime date, TransactionValue value, Guid recurrentExpenseId)
     : this(userId, name, category, date, value)
 {
     this.RecurrentExpenseId = recurrentExpenseId;
 }
Пример #17
0
        public Expense EditExpense(Guid id, string name, Expense.ExpenseCategory category, DateTime date, TransactionValue value)
        {
            var foundExpense = this._expenses.FirstOrDefault(e => e.Id == id);

            if (foundExpense == null)
            {
                throw new Error.ExpenseNotFound();
            }

            foundExpense.Update(this.Id, name, category, date, value);

            return(foundExpense);
        }
Пример #18
0
 public void Update(string name, DateTime date, TransactionValue value)
 {
     this.Name  = name;
     this.Date  = date;
     this.Value = value;
 }