]> git.8kb.co.uk Git - postgresql/dblt/commitdiff
Initial project check in
authorglyn <glyn@8kb.co.uk>
Fri, 17 Jan 2014 15:56:47 +0000 (15:56 +0000)
committerglyn <glyn@8kb.co.uk>
Fri, 17 Jan 2014 15:56:47 +0000 (15:56 +0000)
.gitignore
README.md
dblt/src/dblt.sln [new file with mode: 0644]
dblt/src/dblt/App.config [new file with mode: 0644]
dblt/src/dblt/Blue cube.ico [new file with mode: 0644]
dblt/src/dblt/Program.cs [new file with mode: 0644]
dblt/src/dblt/Properties/AssemblyInfo.cs [new file with mode: 0644]
dblt/src/dblt/Transactions.xml [new file with mode: 0644]
dblt/src/dblt/dblt.csproj [new file with mode: 0644]

index bdc3535f745bc86966fb24c67d252c3ea68e8e03..decdda89abefc84ad2eddbceee7f992d8f0ecd52 100644 (file)
@@ -1,3 +1,7 @@
+<<<<<<< HEAD
+.DS_Store
+Thumb.db
+=======
 # Build Folders (you can keep bin if you'd like, to store dlls and pdbs)
 [Bb]in/
 [Oo]bj/
@@ -106,3 +110,4 @@ Generated_Code #added for RIA/Silverlight projects
 _UpgradeReport_Files/
 Backup*/
 UpgradeLog*.XML
+>>>>>>> fde9f7ab6009e48ed05936471f4553afa32adf7e
index f22e5610fc8babdc14cfc6601e051f27a71379a5..94ebe1f712fe3900950a2415d6ec0d404d170940 100644 (file)
--- a/README.md
+++ b/README.md
@@ -2,3 +2,85 @@ dblt
 ====
 
 A C# load testing program for PostgreSQL using the npgsql data provider.
+
+Usage
+-----
+
+Run parameters are specified in the *App.config* file and the sql transactions
+to run are read from a separate xml file specified in the *TransactionsFile*
+parameter.
+
+App.config parameters
+---------------------
+
+**ServerDescription** (text)            - A description about the test run
+
+**PgConnectionString** (test)           - The npgsql connection string
+
+**ConnectionRetry** (boolean)           - boolean - Whether or not clients that
+                                          fail to connect should retry (true), 
+                                          or give up (false)
+                                          
+**ConnectionPerTransaction** (boolean)  - boolean - Whether clients should 
+                                          connect and disconnect for each 
+                                          attempted transaction (true), or keep
+                                          their connection open (false)
+                                          
+**LogFile** (text)                      - Path to file where verbose details 
+                                          of the test run are logged
+                                          
+**CsvLogFile** (text)                   - Path to file where statistical results
+                                          of test run are logged
+                                          
+**LogLevel** (integer)                  - Verbosity level of log data logged into
+                                          the log file specified in the "LogFile" 
+                                          parameter 
+                                          (0 = minimal, 1 = standard, 2 = verbose)
+                                          
+**VerboseScreen** (boolean)             - Display verbose details of the test 
+                                          to the screen rather than show a summary
+                                          
+**Clients** (integer)                   - Quantity of clients to use for a single
+                                          test, set to 0 if doing multiple tests.
+                                          
+**ClientsScale** (integer)              - Set along with "ClientsMax" parameter 
+                                          to run a set of tests with incrementing
+                                          clients
+                                          E.g. ClientsScale = 4 ClientsMax = 16
+                                          will run 4 tests with 4,8,12 and 16 clients
+                                          
+**ClientsMax** (integer)               - Maximum quantiy of clients to run the test 
+                                         with as detailed above
+                                         
+**Iterations** (integer)               - Number of iterations for each client 
+                                         to run
+                                         
+**SleepTime** (integer)                        - Time for each client to sleep between 
+                                         iterations (milliseconds)
+                                         
+**TransactionsFile** (text)            - Xml file containing the SQL for each  
+                                         iteration of the client - this can contain
+                                         multiple transactions.
+
+The transactions xml file contains a set of transactions and sql statements to 
+be executed against the database.  There's nothing overly intelligent about this
+file, it is simply a <transactions> root node containing *\<transaction>* and *\<sql>* 
+sub nodes, for which any can have a random attribute assigned to make them be 
+either run or skipped on a random basis. 
+
+The text *#client_id#* will also be replaced with the integer id of each client 
+thread in the testing program; this can be usefull for identifying individual
+clients against queries.
+    <transactions>
+       <transaction random="true">
+         <sql>SELECT 'I am client #client_id#';</sql>
+         <sql>SELECT 2;</sql>
+       </transaction>
+       <transaction>
+         <sql random="true">SELECT 'something';</sql>
+         <sql>SELECT 20;</sql>
+       </transaction>
+    </transactions>
+
+
diff --git a/dblt/src/dblt.sln b/dblt/src/dblt.sln
new file mode 100644 (file)
index 0000000..eb906c4
--- /dev/null
@@ -0,0 +1,20 @@
+\r
+Microsoft Visual Studio Solution File, Format Version 11.00\r
+# Visual Studio 2010\r
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dblt", "dblt\dblt.csproj", "{A22A20C7-E58D-48CD-8CA4-A38117BFAE8E}"\r
+EndProject\r
+Global\r
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution\r
+               Debug|Any CPU = Debug|Any CPU\r
+               Release|Any CPU = Release|Any CPU\r
+       EndGlobalSection\r
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution\r
+               {A22A20C7-E58D-48CD-8CA4-A38117BFAE8E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r
+               {A22A20C7-E58D-48CD-8CA4-A38117BFAE8E}.Debug|Any CPU.Build.0 = Debug|Any CPU\r
+               {A22A20C7-E58D-48CD-8CA4-A38117BFAE8E}.Release|Any CPU.ActiveCfg = Release|Any CPU\r
+               {A22A20C7-E58D-48CD-8CA4-A38117BFAE8E}.Release|Any CPU.Build.0 = Release|Any CPU\r
+       EndGlobalSection\r
+       GlobalSection(SolutionProperties) = preSolution\r
+               HideSolutionNode = FALSE\r
+       EndGlobalSection\r
+EndGlobal\r
diff --git a/dblt/src/dblt/App.config b/dblt/src/dblt/App.config
new file mode 100644 (file)
index 0000000..6535a8a
--- /dev/null
@@ -0,0 +1,35 @@
+<?xml version="1.0"?>\r
+<configuration>\r
+  <appSettings>\r
+    <add key="ServerDescription" value="Way5a - test" />\r
+    <add key="PgConnectionString" value="Server=10.10.10.103;Port=5432;User Id=myuser;Password=mypassword;Database=mydatabase;Timeout=600;Pooling=false" />\r
+    <add key="ConnectionRetry" value="false" />\r
+    <add key="ConnectionPerIteration" value="true" />\r
+    <add key="LogFile" value="C:\9.0_environment\tests\9.0_server_benchmarks\dblt\src\dblt\dblt\dblt.log" />\r
+    <add key="CsvLogFile" value="C:\9.0_environment\tests\9.0_server_benchmarks\dblt\src\dblt\dblt\dblt.csv" />\r
+    <add key="LogLevel" value="2" />\r
+    <add key="VerboseScreen" value="false" />\r
+    <add key="Clients" value="0" />\r
+    <add key="ClientsScale" value="1" />\r
+    <add key="ClientsMax" value="10" />\r
+    <add key="Iterations" value="50" />\r
+    <add key="SleepTime" value="0" />\r
+    <add key="TransactionsFile" value="C:\9.0_environment\tests\9.0_server_benchmarks\dblt\src\dblt\dblt\Transactions.xml" />\r
+    <add key="ClientSettingsProvider.ServiceUri" value="" />\r
+  </appSettings>\r
+  <startup>\r
+    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" />\r
+  </startup>\r
+  <system.web>\r
+    <membership defaultProvider="ClientAuthenticationMembershipProvider">\r
+      <providers>\r
+        <add name="ClientAuthenticationMembershipProvider" type="System.Web.ClientServices.Providers.ClientFormsAuthenticationMembershipProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" />\r
+      </providers>\r
+    </membership>\r
+    <roleManager defaultProvider="ClientRoleProvider" enabled="true">\r
+      <providers>\r
+        <add name="ClientRoleProvider" type="System.Web.ClientServices.Providers.ClientRoleProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" cacheTimeout="86400" />\r
+      </providers>\r
+    </roleManager>\r
+  </system.web>\r
+</configuration>
diff --git a/dblt/src/dblt/Blue cube.ico b/dblt/src/dblt/Blue cube.ico
new file mode 100644 (file)
index 0000000..5de1cb9
Binary files /dev/null and b/dblt/src/dblt/Blue cube.ico differ
diff --git a/dblt/src/dblt/Program.cs b/dblt/src/dblt/Program.cs
new file mode 100644 (file)
index 0000000..6158ec7
--- /dev/null
@@ -0,0 +1,538 @@
+//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
diff --git a/dblt/src/dblt/Properties/AssemblyInfo.cs b/dblt/src/dblt/Properties/AssemblyInfo.cs
new file mode 100644 (file)
index 0000000..9c43649
--- /dev/null
@@ -0,0 +1,33 @@
+using System.Reflection;\r
+using System.Runtime.CompilerServices;\r
+using System.Runtime.InteropServices;\r
+\r
+// General Information about an assembly is controlled through the following \r
+// set of attributes. Change these attribute values to modify the information\r
+// associated with an assembly.\r
+[assembly: AssemblyTitle("dblt")]\r
+[assembly: AssemblyDescription("Database Load Test")]\r
+[assembly: AssemblyConfiguration("")]\r
+[assembly: AssemblyCompany("8kb.co.uk")]\r
+[assembly: AssemblyProduct("dblt")]\r
+[assembly: AssemblyCopyright("Copyright © 8kb.co.uk 2011")]\r
+[assembly: AssemblyTrademark("")]\r
+[assembly: AssemblyCulture("")]\r
+\r
+// Setting ComVisible to false makes the types in this assembly not visible \r
+// to COM components.  If you need to access a type in this assembly from \r
+// COM, set the ComVisible attribute to true on that type.\r
+[assembly: ComVisible(false)]\r
+\r
+// The following GUID is for the ID of the typelib if this project is exposed to COM\r
+[assembly: Guid("feeaf39f-1945-434c-9611-57fc670a2048")]\r
+\r
+// Version information for an assembly consists of the following four values:\r
+//\r
+//      Major Version\r
+//      Minor Version \r
+//      Build Number\r
+//      Revision\r
+//\r
+[assembly: AssemblyVersion("1.0.0.0")]\r
+[assembly: AssemblyFileVersion("1.0.0.0")]\r
diff --git a/dblt/src/dblt/Transactions.xml b/dblt/src/dblt/Transactions.xml
new file mode 100644 (file)
index 0000000..a4f62ec
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" ?>\r
+\r
+<transactions>\r
+  <transaction random="true">\r
+    <sql>SELECT 'I am client #client_id#';</sql>\r
+    <sql>SELECT 2;</sql>\r
+  </transaction>\r
+  <transaction>\r
+    <sql random="true">SELECT 'something';</sql>\r
+    <sql>SELECT 20;</sql>\r
+  </transaction>\r
+</transactions>\r
diff --git a/dblt/src/dblt/dblt.csproj b/dblt/src/dblt/dblt.csproj
new file mode 100644 (file)
index 0000000..6737e8b
--- /dev/null
@@ -0,0 +1,123 @@
+<?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