--- /dev/null
+//Copyright (c) 2010-2011 Glyn Astill <glyn@8kb.co.uk>\r
+//Copyright Notice: GPL\r
+\r
+using System;\r
+using System.Collections.Generic;\r
+using System.Xml;\r
+using System.Text;\r
+using System.IO;\r
+using System.Threading;\r
+using System.Data;\r
+using Npgsql;\r
+using System.Configuration;\r
+using System.Diagnostics;\r
+\r
+namespace dblt\r
+{\r
+ class dblt\r
+ {\r
+ public static string sServerDescription = (string)ConfigurationManager.AppSettings["ServerDescription"];\r
+ public static int iClients = Convert.ToInt32(ConfigurationManager.AppSettings["Clients"]);\r
+ public static int iClientsScale = Convert.ToInt32(ConfigurationManager.AppSettings["ClientsScale"]);\r
+ public static int iClientsMax = Convert.ToInt32(ConfigurationManager.AppSettings["ClientsMax"]);\r
+ public static int iIterations = Convert.ToInt32(ConfigurationManager.AppSettings["Iterations"]);\r
+ public static string sLogFile = (string)ConfigurationManager.AppSettings["LogFile"];\r
+ public static string sCsvLogFile = (string)ConfigurationManager.AppSettings["CsvLogFile"];\r
+ public static int iLogLevel = Convert.ToInt32(ConfigurationManager.AppSettings["LogLevel"]);\r
+ public static bool bVerboseScreen = Convert.ToBoolean(ConfigurationManager.AppSettings["VerboseScreen"]);\r
+ public static bool bOnFailureRetry = Convert.ToBoolean(ConfigurationManager.AppSettings["ConnectionRetry"]);\r
+ public static bool bConnPerIteration = Convert.ToBoolean(ConfigurationManager.AppSettings["ConnectionPerIteration"]);\r
+ public static string sConn = (string)ConfigurationManager.AppSettings["PgConnectionString"];\r
+ public static string sTransactionsFile = (string)ConfigurationManager.AppSettings["TransactionsFile"];\r
+ public static int iSleepTime = Convert.ToInt32(ConfigurationManager.AppSettings["SleepTime"]);\r
+ \r
+ public static Object oTransCounterLock = new Object();\r
+ public static Object oIterationCounterLock = new Object();\r
+ public static Object oTransDurationLock = new Object();\r
+ public static Object oLogLock = new Object();\r
+\r
+ //public static DataSet dsTransactions = readTransactionsFile(sTransactionsFile);\r
+ public static XmlDocument xmlTransactions = readTransactionsFile(sTransactionsFile);\r
+ \r
+\r
+ private static PerformanceCounter oCpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total");\r
+ private static PerformanceCounter oSysCpuCounter = new PerformanceCounter("Processor", "% Privileged Time", "_Total");\r
+ private static PerformanceCounter oUseCpuCounter = new PerformanceCounter("Processor", "% User Time", "_Total");\r
+\r
+ public static string timeStamp = "dd/MM/yyyy HH:mm";\r
+ public static string[] aLogArray = new string[10000000];\r
+ //public static double[] aTransactionTimeArray = new double[iClientsMax * iIterations * dsTransactions.Tables[0].Columns.Count];\r
+ public static double[] aTransactionTimeArray = new double[iClientsMax * iIterations * xmlTransactions.SelectNodes("//transaction").Count]; \r
+ \r
+ public static int iLogIndex, iRunningAtMax, iRunningAtMin, iMaxRunning, iCompletedIterations, iCompletedTransactions;\r
+ public static int iCompletedQueries, iRunningClients, iRunningTransactions, iConnectionTimeouts;\r
+ public static int iConnectionCeilingHit, iConnectionFailure, iConnectionRetries, iFailure, iTransactionTimeIndex;\r
+ public static double iMaxTransDuration, iMinTransDuration;\r
+ public static bool bRunning = false;\r
+ \r
+ static void Main(string[] args)\r
+ {\r
+ if (iClients != 0)\r
+ {\r
+ MainWorker(iClients);\r
+ }\r
+ else if (iClientsScale != 0) \r
+ {\r
+ if (iClientsMax == 0)\r
+ {\r
+ iClientsMax = iClientsScale;\r
+ }\r
+ for (int i = iClientsScale; i <= iClientsMax; i= i+iClientsScale)\r
+ {\r
+ MainWorker(i);\r
+ }\r
+ }\r
+ }\r
+\r
+ public static void MainWorker(int iClientsRun)\r
+ {\r
+ iClients = iClientsRun;\r
+\r
+ Array.Clear(aLogArray, 0, iLogIndex);\r
+ iLogIndex = 0;\r
+ Array.Clear(aTransactionTimeArray, 0, iTransactionTimeIndex);\r
+ iTransactionTimeIndex = 0;\r
+ iMaxTransDuration = 0;\r
+ iMinTransDuration = 100000000000000000;\r
+ iRunningAtMax = 0;\r
+ iRunningAtMin = 0;\r
+ iMaxRunning = 0;\r
+ iCompletedIterations = 0;\r
+ iCompletedTransactions = 0;\r
+ iCompletedQueries = 0;\r
+ iRunningClients = 0;\r
+ iRunningTransactions = 0;\r
+ iConnectionTimeouts = 0;\r
+ iConnectionCeilingHit = 0;\r
+ iConnectionFailure = 0;\r
+ iConnectionRetries = 0;\r
+ iFailure = 0;\r
+ bRunning = false;\r
+\r
+ Console.Clear();\r
+\r
+ Info("-------------------- Test Start --------------------", iLogLevel, false);\r
+ Info("Server Description: " + sServerDescription, iLogLevel, false);\r
+ Info("Database load tester.", iLogLevel, true);\r
+ Info("Iterations per client = " + iIterations, iLogLevel, true);\r
+ Info("launching " + iClients + " clients...", iLogLevel, true);\r
+\r
+ Thread[] workerThreads = new Thread[iClients];\r
+ \r
+ bRunning = true;\r
+ Thread infoThread = new Thread(new ThreadStart(InfoScreen));\r
+ infoThread.Start();\r
+\r
+ for (int i = 0; i < workerThreads.Length; i++)\r
+ {\r
+ workerThreads[i] = new Thread(new ParameterizedThreadStart(ClientWorker));\r
+ workerThreads[i].Start(i);\r
+ iRunningClients++;\r
+ }\r
+\r
+ for (int i = 0; i < workerThreads.Length; i++)\r
+ {\r
+ workerThreads[i].Join();\r
+ iRunningClients--;\r
+ }\r
+\r
+ bRunning = false;\r
+ infoThread.Join();\r
+\r
+ Info("-------------------- Test Complete --------------------", iLogLevel, false);\r
+ LogWriter();\r
+ }\r
+\r
+ public static void InfoScreen()\r
+ {\r
+ DateTime startTime = DateTime.Now;\r
+ DateTime currTime = DateTime.Now;\r
+ TimeSpan duration = currTime - startTime;\r
+\r
+ double iMeanTransactionDuration = 0;\r
+ double iStandatdDeviation = 0;\r
+\r
+ float fCpuAll = 0;\r
+ float fCpuSys = 0;\r
+ float fCpuUse = 0;\r
+ int iSamples = 0;\r
+\r
+ if (!bVerboseScreen)\r
+ {\r
+ while (bRunning)\r
+ {\r
+ fCpuAll = fCpuAll + oCpuCounter.NextValue();\r
+ fCpuSys = fCpuSys + oSysCpuCounter.NextValue();\r
+ fCpuUse = fCpuUse + oUseCpuCounter.NextValue();\r
+ iSamples++;\r
+\r
+ currTime = DateTime.Now;\r
+ duration = currTime - startTime;\r
+\r
+ Console.SetCursorPosition(0, 4);\r
+ Console.WriteLine("Running Clients {0} ", iRunningClients);\r
+ Console.SetCursorPosition(0, 5);\r
+ Console.WriteLine("Running Transactions {0} : {1} max ", iRunningTransactions, iMaxRunning);\r
+\r
+ Console.SetCursorPosition(0, 7);\r
+ Console.WriteLine("Completed Queries {0} : {1} qps ", iCompletedQueries, (iCompletedQueries / (Convert.ToInt32(duration.TotalSeconds) + 1)));\r
+ Console.SetCursorPosition(0, 8);\r
+ Console.WriteLine("Completed Transactions {0} : {1} tps ", iCompletedTransactions, (iCompletedTransactions / (Convert.ToInt32(duration.TotalSeconds) + 1)));\r
+ Console.SetCursorPosition(0, 9);\r
+ Console.WriteLine("Completed Iterations {0} / {1} ", iCompletedIterations, (iIterations * iClients));\r
+ \r
+ Console.SetCursorPosition(0, 11);\r
+ Console.WriteLine("Maximum Transaction+Read Time {0} ms : {1} Running ", iMaxTransDuration, iRunningAtMax);\r
+ Console.SetCursorPosition(0, 12);\r
+ Console.WriteLine("Minimum Transaction+Read Time {0} ms : {1} Running ", iMinTransDuration, iRunningAtMin);\r
+\r
+ Console.SetCursorPosition(0, 14);\r
+ Console.WriteLine("Connection Timeout/Ceiling Hit/Failure {0} / {1} / {2} ", iConnectionTimeouts, iConnectionCeilingHit, iConnectionFailure);\r
+ Console.SetCursorPosition(0, 15);\r
+ Console.WriteLine("Other Failure {0} ", iFailure);\r
+ Console.SetCursorPosition(0, 16);\r
+ Console.WriteLine("Connection Retries {0} ", iConnectionRetries);\r
+ Console.SetCursorPosition(0, 17);\r
+ Console.WriteLine("Average Client CPU All/User/Sys {0}% / {1}% / {2}% ", Math.Round((fCpuAll / iSamples), 2), Math.Round((fCpuUse / iSamples), 2), Math.Round((fCpuSys / iSamples), 2));\r
+\r
+ Console.SetCursorPosition(0, 23);\r
+ Console.WriteLine("{0} s ", (Convert.ToInt32(duration.TotalSeconds) + 1));\r
+ Thread.Sleep(500);\r
+ }\r
+ }\r
+\r
+ if (!bRunning)\r
+ {\r
+ Thread.Sleep(500);\r
+\r
+ Console.SetCursorPosition(0, 4);\r
+ Console.WriteLine("Running Clients {0} ", iRunningClients);\r
+ Console.SetCursorPosition(0, 5);\r
+ Console.WriteLine("Running Transactions {0} : {1} max ", iRunningTransactions, iMaxRunning);\r
+\r
+ Console.SetCursorPosition(0, 7);\r
+ Console.WriteLine("Completed Queries {0} : {1} qps ", iCompletedQueries, (iCompletedQueries / (Convert.ToInt32(duration.TotalSeconds) + 1)));\r
+ Console.SetCursorPosition(0, 8);\r
+ Console.WriteLine("Completed Transactions {0} : {1} tps ", iCompletedTransactions, (iCompletedTransactions / (Convert.ToInt32(duration.TotalSeconds) + 1)));\r
+ Console.SetCursorPosition(0, 9);\r
+ Console.WriteLine("Completed Iterations {0} / {1} ", iCompletedIterations, (iIterations * iClients));\r
+\r
+ Console.SetCursorPosition(0, 11);\r
+ Console.WriteLine("Maximum Transaction+Read Time {0} ms : {1} Running ", iMaxTransDuration, iRunningAtMax);\r
+ Console.SetCursorPosition(0, 12);\r
+ Console.WriteLine("Minimum Transaction+Read Time {0} ms : {1} Running ", iMinTransDuration, iRunningAtMin);\r
+\r
+ Console.SetCursorPosition(0, 14);\r
+ Console.WriteLine("Connection Timeout/Ceiling Hit/Failure {0} / {1} / {2} ", iConnectionTimeouts, iConnectionCeilingHit, iConnectionFailure);\r
+ Console.SetCursorPosition(0, 15);\r
+ Console.WriteLine("Other Failure {0} ", iFailure);\r
+ Console.SetCursorPosition(0, 16);\r
+ Console.WriteLine("Connection Retries {0} ", iConnectionRetries);\r
+ Console.SetCursorPosition(0, 17);\r
+ Console.WriteLine("Average Client CPU All/User/Sys {0}% / {1}% / {2}% ", Math.Round((fCpuAll / iSamples),2), Math.Round((fCpuUse / iSamples),2), Math.Round((fCpuSys / iSamples),2));\r
+\r
+ Console.SetCursorPosition(0, 23);\r
+ Console.WriteLine("{0} s ", (Convert.ToInt32(duration.TotalSeconds) + 1));\r
+\r
+ Info("==========================================================", iLogLevel, bVerboseScreen);\r
+ Info(" Running Clients " + iRunningClients, iLogLevel, bVerboseScreen);\r
+ Info(" Running Transactions " + iRunningTransactions, iLogLevel, bVerboseScreen);\r
+ Info(" Completed Queries " + iCompletedQueries + " : " + (iCompletedQueries / (Convert.ToInt32(duration.TotalSeconds) + 1)) + " qps", iLogLevel, bVerboseScreen);\r
+ Info(" Completed Transactions " + iCompletedTransactions + " : " + (iCompletedTransactions / (Convert.ToInt32(duration.TotalSeconds) + 1)) + " tps", iLogLevel, bVerboseScreen);\r
+ Info(" Completed Iterations " + iCompletedIterations + " / " + (iIterations * iClients), iLogLevel, bVerboseScreen);\r
+ Info(" Maximum Transaction+Read Time " + iMaxTransDuration + " ms", iLogLevel, bVerboseScreen);\r
+ Info(" Minimum Transaction+Read Time " + iMinTransDuration + " ms", iLogLevel, bVerboseScreen);\r
+ Info(" Connection Timeout/Ceiling Hit/Failure " + iConnectionTimeouts + " / " + iConnectionCeilingHit + " / " + iConnectionFailure, iLogLevel, bVerboseScreen);\r
+ Info(" Other Failure " + iFailure, iLogLevel, bVerboseScreen);\r
+ Info(" Connection Retries " + iConnectionRetries, iLogLevel, bVerboseScreen);\r
+ Info(" Total Time " + Convert.ToInt32(duration.TotalSeconds) + 1, iLogLevel, bVerboseScreen);\r
+ Info(" Max Concurrent Transactions " + iMaxRunning, iLogLevel, bVerboseScreen);\r
+ Info(" Average Client CPU All/User/Sys " + Math.Round((fCpuAll / iSamples), 2) + "% " + Math.Round((fCpuUse / iSamples), 2) + "% " + Math.Round((fCpuSys / iSamples), 2) + "%", iLogLevel, bVerboseScreen);\r
+ Info("==========================================================", iLogLevel, bVerboseScreen);\r
+\r
+ iMeanTransactionDuration = 0;\r
+ iStandatdDeviation = 0;\r
+\r
+ for (int i = 0; i < iTransactionTimeIndex; i++)\r
+ {\r
+ iMeanTransactionDuration = (aTransactionTimeArray[i] + iMeanTransactionDuration);\r
+ }\r
+ iMeanTransactionDuration = (iMeanTransactionDuration / iTransactionTimeIndex);\r
+\r
+ for (int i = 0; i < iTransactionTimeIndex; i++)\r
+ {\r
+\r
+ iStandatdDeviation = (Math.Pow((aTransactionTimeArray[i] - iMeanTransactionDuration), 2) + iStandatdDeviation);\r
+ }\r
+ iStandatdDeviation = Math.Sqrt(iStandatdDeviation / iTransactionTimeIndex);\r
+\r
+ CsvLogWriter("\"" + sServerDescription + "\"," + iClients + "," + iIterations + "," + iMaxTransDuration + "," + iMinTransDuration + "," + iRunningAtMax + "," + iRunningAtMin + "," + iMeanTransactionDuration + "," + iStandatdDeviation + "," + (iCompletedTransactions / (Convert.ToInt32(duration.TotalSeconds) + 1)) + "," + (iCompletedQueries / (Convert.ToInt32(duration.TotalSeconds) + 1)) + "," + iMaxRunning + "," + (Convert.ToInt32(duration.TotalSeconds) + 1) + "," + (fCpuAll / iSamples));\r
+ }\r
+ }\r
+\r
+ public static void ClientWorker(object iThread)\r
+ {\r
+ \r
+ Info("Starting client thread " + iThread.ToString(), iLogLevel, bVerboseScreen);\r
+\r
+ Random random = new Random();\r
+ int iTransOn = 0;\r
+ int iSqlOn = 0;\r
+ string sSql = "";\r
+ int iRandomStmt = 0;\r
+ int iRandomTran = 0;\r
+ NpgsqlConnection conn = null;\r
+ if (!bConnPerIteration)\r
+ {\r
+ conn = new NpgsqlConnection(sConn);\r
+ conn.Open();\r
+ }\r
+\r
+ for (int i = 0; i < iIterations; i++)\r
+ {\r
+ try\r
+ {\r
+ DateTime startTime = DateTime.Now;\r
+ if (bConnPerIteration)\r
+ {\r
+ conn = new NpgsqlConnection(sConn);\r
+ conn.Open();\r
+ }\r
+\r
+ //foreach (DataRow transaction in dsTransactions.Tables[0].Rows)\r
+ iTransOn = 0;\r
+ foreach (XmlNode node in xmlTransactions.SelectNodes("//transaction"))\r
+ {\r
+ iTransOn++;\r
+ XmlNode randomtransaction = node.Attributes["random"];\r
+ if (randomtransaction != null && node.Attributes["random"].Value.Trim().ToLower() == "true")\r
+ {\r
+ iRandomTran = random.Next(0, 2);\r
+ }\r
+\r
+ if (iRandomTran == 0)\r
+ {\r
+ NpgsqlTransaction tran = conn.BeginTransaction();\r
+ DateTime beginTime = DateTime.Now;\r
+\r
+ lock (oTransCounterLock)\r
+ {\r
+ iRunningTransactions++;\r
+ }\r
+\r
+ //foreach (DataColumn column in dsTransactions.Tables[0].Columns)\r
+ iSqlOn = 0;\r
+ foreach (XmlNode subnode in node.SelectNodes("//sql"))\r
+ {\r
+ iSqlOn++;\r
+ XmlNode randomsql = subnode.Attributes["random"];\r
+ if (randomsql != null && subnode.Attributes["random"].Value.Trim().ToLower() == "true")\r
+ {\r
+ iRandomStmt = random.Next(0, 2);\r
+ }\r
+\r
+ if (iRandomStmt == 0)\r
+ {\r
+ sSql = subnode.InnerText;\r
+ //NpgsqlCommand command = new NpgsqlCommand(transaction[column].ToString().Replace("#client_id#", iThread.ToString()), conn, tran);\r
+ NpgsqlCommand command = new NpgsqlCommand(sSql.Replace("#client_id#", iThread.ToString()), conn, tran);\r
+ NpgsqlDataReader dr = command.ExecuteReader();\r
+\r
+ iCompletedQueries++;\r
+ while (dr.Read())\r
+ {\r
+ //Just pull the data back into our dataset (but we don't care about it)\r
+ }\r
+\r
+ if (iLogLevel > 1)\r
+ {\r
+ Info("Client " + iThread.ToString() + " Transaction = " + iTransOn + " Statement = " + iSqlOn + " SQL = \"" + sSql + "\" Running", iLogLevel, bVerboseScreen);\r
+ }\r
+ }\r
+ else\r
+ {\r
+ if (iLogLevel > 1)\r
+ {\r
+ Info("Client " + iThread.ToString() + " Transaction = " + iTransOn + " Statement = " + iSqlOn + " Skipping as random statement = true", iLogLevel, bVerboseScreen);\r
+ }\r
+ }\r
+ }\r
+\r
+ tran.Commit();\r
+ DateTime commitTime = DateTime.Now;\r
+ TimeSpan transactionDuration = commitTime - beginTime;\r
+\r
+ if (iRunningClients == iClients)\r
+ {\r
+\r
+ if (transactionDuration.TotalMilliseconds > iMaxTransDuration)\r
+ {\r
+ lock (oTransDurationLock)\r
+ {\r
+ iMaxTransDuration = transactionDuration.TotalMilliseconds;\r
+ iRunningAtMax = iRunningTransactions;\r
+ }\r
+ }\r
+ if (transactionDuration.TotalMilliseconds < iMinTransDuration)\r
+ {\r
+ lock (oTransDurationLock)\r
+ {\r
+ iMinTransDuration = transactionDuration.TotalMilliseconds;\r
+ iRunningAtMin = iRunningTransactions;\r
+ }\r
+ }\r
+ }\r
+ lock (oTransCounterLock)\r
+ {\r
+ if (iRunningTransactions > iMaxRunning)\r
+ {\r
+ iMaxRunning = iRunningTransactions;\r
+ }\r
+ iCompletedTransactions++;\r
+ aTransactionTimeArray[iTransactionTimeIndex] = transactionDuration.TotalMilliseconds;\r
+ iTransactionTimeIndex++;\r
+ iRunningTransactions--;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ if (iLogLevel > 1)\r
+ {\r
+ Info("Client " + iThread.ToString() + " Transaction = " + iTransOn + " Skipping as random transaction = true", iLogLevel, bVerboseScreen);\r
+ }\r
+ }\r
+ }\r
+\r
+ lock (oIterationCounterLock)\r
+ {\r
+ iCompletedIterations++;\r
+ }\r
+\r
+ if (bConnPerIteration)\r
+ {\r
+ conn.Close();\r
+ }\r
+ \r
+ DateTime stopTime = DateTime.Now;\r
+ TimeSpan duration = stopTime - startTime;\r
+ Info("Client " + iThread.ToString() + " Iteration " + i.ToString() + " Iteration Time " + duration.TotalMilliseconds + " ms (including application read)", iLogLevel, bVerboseScreen);\r
+\r
+ }\r
+ catch (Exception e)\r
+ {\r
+ if (String.Compare(e.Message, 0, "A timeout has occured", 0, 21) == 0)\r
+ {\r
+ iConnectionTimeouts++;\r
+ }\r
+ else if (String.Compare(e.Message, 0, "Failed to establish a connection", 0, 32) == 0)\r
+ {\r
+ iConnectionFailure++;\r
+ }\r
+ else if ((e.Message == "ERROR: 08P01: no more connections allowed") || (e.Message == "FATAL: 53300: connection limit exceeded for non-superusers") || (e.Message == "FATAL: 53300: sorry, too many clients already"))\r
+ {\r
+ iConnectionCeilingHit++;\r
+ }\r
+ else\r
+ {\r
+ iFailure++;\r
+ }\r
+ Info("Client " + iThread.ToString() + " Iteration " + i.ToString() + " FAILURE " + e.Message + " TARGET " + e.TargetSite + " INFO = " + e.ToString(), iLogLevel, bVerboseScreen);\r
+ if (bOnFailureRetry)\r
+ {\r
+ i--;\r
+ iConnectionRetries++;\r
+ continue;\r
+ }\r
+\r
+ }\r
+ if (iSleepTime > 0)\r
+ {\r
+ Thread.Sleep(iSleepTime);\r
+ }\r
+ }\r
+ if (!bConnPerIteration)\r
+ {\r
+ conn.Close();\r
+ }\r
+ }\r
+\r
+ public static void Info(string sInfoText, int iInfoLevel, bool bScreen)\r
+ {\r
+ if (iInfoLevel >= 1)\r
+ {\r
+ AddLog(sInfoText); \r
+ }\r
+ if (bScreen)\r
+ {\r
+ Console.WriteLine(sInfoText);\r
+ }\r
+ }\r
+\r
+ public static void AddLog(string sLogText)\r
+ {\r
+ DateTime currTime = DateTime.Now;\r
+\r
+ if (sLogText.Length != 0)\r
+ {\r
+ lock (oLogLock)\r
+ {\r
+ aLogArray[iLogIndex] = currTime.ToString(timeStamp) + " : " + sLogText;\r
+ iLogIndex++;\r
+ }\r
+ }\r
+ }\r
+\r
+ public static void LogWriter()\r
+ {\r
+ if ((sLogFile != "") && (iLogLevel >=1))\r
+ {\r
+ FileStream fs = new FileStream(sLogFile, FileMode.OpenOrCreate, FileAccess.Write);\r
+ StreamWriter m_streamWriter = new StreamWriter(fs);\r
+ m_streamWriter.BaseStream.Seek(0, SeekOrigin.End);\r
+\r
+ for (int i = 0; i < iLogIndex; i++)\r
+ {\r
+ m_streamWriter.WriteLine(aLogArray[i]);\r
+ }\r
+\r
+ m_streamWriter.Flush();\r
+ m_streamWriter.Close();\r
+ }\r
+ }\r
+\r
+ public static void CsvLogWriter(string sLogText)\r
+ {\r
+ bool bWriteHeader = false;\r
+\r
+ if (sCsvLogFile != "")\r
+ {\r
+ if (!File.Exists(sCsvLogFile))\r
+ {\r
+ bWriteHeader = true;\r
+ }\r
+\r
+ FileStream fs = new FileStream(sCsvLogFile, FileMode.OpenOrCreate, FileAccess.Write);\r
+ StreamWriter m_streamWriter = new StreamWriter(fs);\r
+ m_streamWriter.BaseStream.Seek(0, SeekOrigin.End);\r
+\r
+ if (bWriteHeader)\r
+ {\r
+ m_streamWriter.WriteLine("Server name, Clients, Iterations/client, Max transaction duration (ms), Min transaction duration (ms), Concurrent transactions at max duration, Concurrent transactions at min duration, Mean transaction duration (ms), Transaction duration standard deviation (ms), tps, qps, Max concurrent transactions, Total time (s), Avg CPU Time %");\r
+ }\r
+ m_streamWriter.WriteLine(sLogText);\r
+\r
+ m_streamWriter.Flush();\r
+ m_streamWriter.Close();\r
+ }\r
+ }\r
+\r
+ //public static DataSet readTransactionsFile(string sTransactionsFile)\r
+ public static XmlDocument readTransactionsFile(string sTransactionsFile)\r
+ {\r
+ DataSet ds = new DataSet();\r
+ XmlDocument transfile = new XmlDocument();\r
+ try\r
+ {\r
+ //GA ds.ReadXml(sTransactionsFile, XmlReadMode.InferSchema);\r
+ transfile.Load(sTransactionsFile);\r
+ }\r
+ catch (Exception e)\r
+ {\r
+ Info("Error reading transaction file " + e.ToString(), iLogLevel, bVerboseScreen);\r
+ }\r
+ //return ds;\r
+ return transfile;\r
+ }\r
+ }\r
+ \r
+}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">\r
+ <PropertyGroup>\r
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>\r
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>\r
+ <ProductVersion>9.0.30729</ProductVersion>\r
+ <SchemaVersion>2.0</SchemaVersion>\r
+ <ProjectGuid>{A22A20C7-E58D-48CD-8CA4-A38117BFAE8E}</ProjectGuid>\r
+ <OutputType>Exe</OutputType>\r
+ <AppDesignerFolder>Properties</AppDesignerFolder>\r
+ <RootNamespace>dblt</RootNamespace>\r
+ <AssemblyName>dblt</AssemblyName>\r
+ <StartupObject>dblt.dblt</StartupObject>\r
+ <IsWebBootstrapper>true</IsWebBootstrapper>\r
+ <ApplicationIcon>Blue cube.ico</ApplicationIcon>\r
+ <FileUpgradeFlags>\r
+ </FileUpgradeFlags>\r
+ <UpgradeBackupLocation>\r
+ </UpgradeBackupLocation>\r
+ <OldToolsVersion>3.5</OldToolsVersion>\r
+ <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>\r
+ <TargetFrameworkProfile />\r
+ <PublishUrl>http://localhost/dblt/</PublishUrl>\r
+ <Install>true</Install>\r
+ <InstallFrom>Web</InstallFrom>\r
+ <UpdateEnabled>true</UpdateEnabled>\r
+ <UpdateMode>Foreground</UpdateMode>\r
+ <UpdateInterval>7</UpdateInterval>\r
+ <UpdateIntervalUnits>Days</UpdateIntervalUnits>\r
+ <UpdatePeriodically>false</UpdatePeriodically>\r
+ <UpdateRequired>false</UpdateRequired>\r
+ <MapFileExtensions>true</MapFileExtensions>\r
+ <SupportUrl>http://www.8kb.co.uk</SupportUrl>\r
+ <TargetCulture>en</TargetCulture>\r
+ <ProductName>.NET Database Load Tester</ProductName>\r
+ <PublisherName>Glyn Astill</PublisherName>\r
+ <ApplicationRevision>0</ApplicationRevision>\r
+ <ApplicationVersion>1.0.0.%2a</ApplicationVersion>\r
+ <UseApplicationTrust>false</UseApplicationTrust>\r
+ <BootstrapperEnabled>true</BootstrapperEnabled>\r
+ </PropertyGroup>\r
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">\r
+ <DebugSymbols>true</DebugSymbols>\r
+ <DebugType>full</DebugType>\r
+ <Optimize>false</Optimize>\r
+ <OutputPath>bin\Debug\</OutputPath>\r
+ <DefineConstants>DEBUG;TRACE</DefineConstants>\r
+ <ErrorReport>prompt</ErrorReport>\r
+ <WarningLevel>4</WarningLevel>\r
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>\r
+ </PropertyGroup>\r
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">\r
+ <DebugType>pdbonly</DebugType>\r
+ <Optimize>true</Optimize>\r
+ <OutputPath>bin\Release\</OutputPath>\r
+ <DefineConstants>TRACE</DefineConstants>\r
+ <ErrorReport>prompt</ErrorReport>\r
+ <WarningLevel>4</WarningLevel>\r
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>\r
+ </PropertyGroup>\r
+ <ItemGroup>\r
+ <Reference Include="Npgsql, Version=2.0.11.91, Culture=neutral, PublicKeyToken=5d8b90d52f46fda7, processorArchitecture=MSIL">\r
+ <SpecificVersion>False</SpecificVersion>\r
+ <HintPath>C:\Program Files (x86)\Microsoft Visual Studio 10.0\Npgsql2.0.11.91-bin-ms.net3.5sp1\Npgsql.dll</HintPath>\r
+ </Reference>\r
+ <Reference Include="System" />\r
+ <Reference Include="System.configuration" />\r
+ <Reference Include="System.Data" />\r
+ <Reference Include="System.Web.Extensions" />\r
+ <Reference Include="System.Xml" />\r
+ </ItemGroup>\r
+ <ItemGroup>\r
+ <Compile Include="Program.cs" />\r
+ <Compile Include="Properties\AssemblyInfo.cs" />\r
+ </ItemGroup>\r
+ <ItemGroup>\r
+ <None Include="App.config">\r
+ <SubType>Designer</SubType>\r
+ </None>\r
+ </ItemGroup>\r
+ <ItemGroup>\r
+ <Content Include="Blue cube.ico" />\r
+ <Content Include="Transactions.xml">\r
+ <SubType>Designer</SubType>\r
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\r
+ </Content>\r
+ </ItemGroup>\r
+ <ItemGroup>\r
+ <BootstrapperPackage Include="Microsoft.Net.Client.3.5">\r
+ <Visible>False</Visible>\r
+ <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>\r
+ <Install>false</Install>\r
+ </BootstrapperPackage>\r
+ <BootstrapperPackage Include="Microsoft.Net.Framework.2.0">\r
+ <Visible>False</Visible>\r
+ <ProductName>.NET Framework 2.0 %28x86%29</ProductName>\r
+ <Install>true</Install>\r
+ </BootstrapperPackage>\r
+ <BootstrapperPackage Include="Microsoft.Net.Framework.3.0">\r
+ <Visible>False</Visible>\r
+ <ProductName>.NET Framework 3.0 %28x86%29</ProductName>\r
+ <Install>false</Install>\r
+ </BootstrapperPackage>\r
+ <BootstrapperPackage Include="Microsoft.Net.Framework.3.5">\r
+ <Visible>False</Visible>\r
+ <ProductName>.NET Framework 3.5</ProductName>\r
+ <Install>false</Install>\r
+ </BootstrapperPackage>\r
+ <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">\r
+ <Visible>False</Visible>\r
+ <ProductName>.NET Framework 3.5 SP1</ProductName>\r
+ <Install>false</Install>\r
+ </BootstrapperPackage>\r
+ </ItemGroup>\r
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />\r
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \r
+ Other similar extension points exist, see Microsoft.Common.targets.\r
+ <Target Name="BeforeBuild">\r
+ </Target>\r
+ <Target Name="AfterBuild">\r
+ </Target>\r
+ -->\r
+</Project>
\ No newline at end of file