Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add threading test to the Windows CE test application. Also, some cleanup and refactoring work to make adding new tests easier. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
5e6b70f411677578f5d98ee80ebbd690 |
User & Date: | mistachkin 2012-10-09 11:33:36.615 |
Context
2012-10-09
| ||
13:07 | For Visual Studio 2012 only, run the design-time installer tool twice for both install and uninstall to make sure the settings are present in the per-user and per-machine registry hives. check-in: c1187b14fb user: mistachkin tags: trunk | |
11:33 | Add threading test to the Windows CE test application. Also, some cleanup and refactoring work to make adding new tests easier. check-in: 5e6b70f411 user: mistachkin tags: trunk | |
09:40 | Add wrapper batch file for the Windows CE test automation and update the version history docs. check-in: 305bd4b0ab user: mistachkin tags: trunk | |
Changes
Changes to testce/Program.cs.
︙ | ︙ | |||
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | namespace test { class Program { private static readonly string DefaultConnectionString = "Data Source={DataDirectory}\\test.db;Password=yVXL39etehPX;"; [MTAThread] static int Main(string[] args) { bool autoClose = false; int exitCode = 2; /* INCOMPLETE */ Assembly assembly = Assembly.GetExecutingAssembly(); AssemblyName assemblyName = assembly.GetName(); string directory = Path.GetDirectoryName(assemblyName.CodeBase); if (args.Length > 0) autoClose = bool.Parse(args[0]); try { File.Delete(directory + "\\test.db"); } catch { } SQLiteFunction.RegisterFunction(typeof(TestFunc)); SQLiteFunction.RegisterFunction(typeof(MyCount)); SQLiteFunction.RegisterFunction(typeof(MySequence)); | > > > > > | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | namespace test { class Program { private static readonly string DefaultConnectionString = "Data Source={DataDirectory}\\test.db;Password=yVXL39etehPX;"; internal static DbConnection NewConnection() { return new SQLiteConnection(); } [MTAThread] static int Main(string[] args) { bool autoClose = false; int exitCode = 2; /* INCOMPLETE */ Assembly assembly = Assembly.GetExecutingAssembly(); AssemblyName assemblyName = assembly.GetName(); string directory = Path.GetDirectoryName(assemblyName.CodeBase); if (args.Length > 0) autoClose = bool.Parse(args[0]); try { File.Delete(directory + "\\test.db"); } catch { } SQLiteFunction.RegisterFunction(typeof(TestFunc)); SQLiteFunction.RegisterFunction(typeof(MyCount)); SQLiteFunction.RegisterFunction(typeof(MySequence)); using (DbConnection cnn = NewConnection()) { string connectionString = DefaultConnectionString; try { // // NOTE: Attempt to open the configuration file associated with |
︙ | ︙ | |||
73 74 75 76 77 78 79 | // connectionString = connectionString.Replace( "{DataDirectory}", directory); cnn.ConnectionString = connectionString; cnn.Open(); | | | | 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | // connectionString = connectionString.Replace( "{DataDirectory}", directory); cnn.ConnectionString = connectionString; cnn.Open(); TestCases tests = new TestCases(connectionString, cnn, autoClose); tests.Run(); Application.Run(tests.frm); if (tests.Succeeded()) exitCode = 0; /* SUCCESS */ else exitCode = 1; /* FAILURE */ |
︙ | ︙ |
Changes to testce/TestCases.cs.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | /******************************************************** * ADO.NET 2.0 Data Provider for SQLite Version 3.X * Written by Robert Simpson (robert@blackcastlesoft.com) * * Released to the public domain, use at your own risk! ********************************************************/ using System; using System.Data.Common; using System.Data; using System.Data.SQLite; namespace test { /// <summary> /// Scalar user-defined function. In this example, the same class is declared twice with /// different function names to demonstrate how to use alias names for user-defined functions. | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /******************************************************** * ADO.NET 2.0 Data Provider for SQLite Version 3.X * Written by Robert Simpson (robert@blackcastlesoft.com) * * Released to the public domain, use at your own risk! ********************************************************/ using System; using System.Data.Common; using System.Data; using System.Data.SQLite; using System.Threading; namespace test { /// <summary> /// Scalar user-defined function. In this example, the same class is declared twice with /// different function names to demonstrate how to use alias names for user-defined functions. |
︙ | ︙ | |||
69 70 71 72 73 74 75 76 77 78 79 80 | } } internal class TestCases { internal Form1 frm; private bool autoClose; private int total; private int passed; private int failed; | > > | > > > > > > | < | 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | } } internal class TestCases { internal Form1 frm; private string connectionString; private DbConnection cnn; private bool autoClose; private int total; private int passed; private int failed; internal TestCases( string connectionString, DbConnection cnn, bool autoExit ) { this.connectionString = connectionString; this.cnn = cnn; this.autoClose = autoExit; } internal bool Succeeded() { return (failed == 0) && (passed == total); } internal void Run() { frm = new Form1(); frm.Show(); Type type = cnn.GetType(); frm.WriteLine("\r\nBeginning Test on " + type.ToString()); SQLiteConnection cnn2 = cnn as SQLiteConnection; if (cnn2 != null) |
︙ | ︙ | |||
177 178 179 180 181 182 183 184 185 186 187 188 189 190 | try { UserAggregate(cnn); frm.WriteLine("SUCCESS - UserAggregate"); passed++; } catch (Exception) { frm.WriteLine("FAIL - UserAggregate"); failed++; } total++; try { UserCollation(cnn); frm.WriteLine("SUCCESS - UserCollation"); passed++; } catch (Exception) { frm.WriteLine("FAIL - UserCollation"); failed++; } total++; try { DropTable(cnn); frm.WriteLine("SUCCESS - DropTable"); passed++; } catch (Exception) { frm.WriteLine("FAIL - DropTable"); failed++; } frm.WriteLine("\r\nTests Finished."); frm.WriteLine(String.Format("\r\nCounts: {0} total, {1} passed, {2} failed", total, passed, failed)); frm.WriteLine(String.Format("Result: {0}", Succeeded() ? "SUCCESS" : "FAILURE")); | > > > > | 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 | try { UserAggregate(cnn); frm.WriteLine("SUCCESS - UserAggregate"); passed++; } catch (Exception) { frm.WriteLine("FAIL - UserAggregate"); failed++; } total++; try { UserCollation(cnn); frm.WriteLine("SUCCESS - UserCollation"); passed++; } catch (Exception) { frm.WriteLine("FAIL - UserCollation"); failed++; } total++; try { MultipleThreadStress(cnn); frm.WriteLine("SUCCESS - MultipleThreadStress"); passed++; } catch (Exception) { frm.WriteLine("FAIL - MultipleThreadStress"); failed++; } total++; try { DropTable(cnn); frm.WriteLine("SUCCESS - DropTable"); passed++; } catch (Exception) { frm.WriteLine("FAIL - DropTable"); failed++; } frm.WriteLine("\r\nTests Finished."); frm.WriteLine(String.Format("\r\nCounts: {0} total, {1} passed, {2} failed", total, passed, failed)); frm.WriteLine(String.Format("Result: {0}", Succeeded() ? "SUCCESS" : "FAILURE")); |
︙ | ︙ | |||
404 405 406 407 408 409 410 | //cmd.CommandText = "CREATE TABLE TestCase (ID bigint primary key identity, Field1 Integer, Field2 Float, Field3 VARCHAR(50), Field4 CHAR(10), Field5 DateTime, Field6 Image)"; cmd.ExecuteNonQuery(); } } internal void DropTable(DbConnection cnn) { | > > > > > | | | | > | 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 | //cmd.CommandText = "CREATE TABLE TestCase (ID bigint primary key identity, Field1 Integer, Field2 Float, Field3 VARCHAR(50), Field4 CHAR(10), Field5 DateTime, Field6 Image)"; cmd.ExecuteNonQuery(); } } internal void DropTable(DbConnection cnn) { string[] tables = { "TestCase", "keyinfotest", "datatypetest", "TestThreads" }; foreach (string table in tables) { using (DbCommand cmd = cnn.CreateCommand()) { cmd.CommandText = String.Format("DROP TABLE {0};", table); cmd.ExecuteNonQuery(); } } } internal void InsertTable(DbConnection cnn) { using (DbCommand cmd = cnn.CreateCommand()) { |
︙ | ︙ | |||
876 877 878 879 880 881 882 | // and "Field3" will be next, followed by a NULL. Our user-defined collating sequence will // deliberately place them out of order so Field3 is first. cmd.CommandText = "SELECT Field3 FROM TestCase ORDER BY Field3 COLLATE MYSEQUENCE DESC"; string s = (string)cmd.ExecuteScalar(); if (s != "Field3") throw new ArgumentOutOfRangeException("MySequence didn't sort properly"); } } | | > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 | // and "Field3" will be next, followed by a NULL. Our user-defined collating sequence will // deliberately place them out of order so Field3 is first. cmd.CommandText = "SELECT Field3 FROM TestCase ORDER BY Field3 COLLATE MYSEQUENCE DESC"; string s = (string)cmd.ExecuteScalar(); if (s != "Field3") throw new ArgumentOutOfRangeException("MySequence didn't sort properly"); } } private int nextId = 0; private const int MAX_THREADS = 3; private const int MAX_ITERATIONS = 100; private ManualResetEvent goEvent = new ManualResetEvent(false); private static int GetThreadId() { return Thread.CurrentThread.ManagedThreadId; } // Mutli-threading test. internal void MultipleThreadStress(DbConnection cnn) { string[] commands = { "CREATE TABLE TestThreads(Id INTEGER PRIMARY KEY, Data INTEGER);", "INSERT INTO TestThreads (Id, Data) VALUES (" + Interlocked.Increment(ref nextId).ToString() + ", " + GetThreadId().ToString() + ");" }; foreach (string command in commands) { using (DbCommand cmd = cnn.CreateCommand()) { cmd.CommandText = command; cmd.ExecuteNonQuery(); } } Thread[] threads = new Thread[MAX_THREADS]; for (int index = 0; index < threads.Length; index++) threads[index] = new Thread(TestThreadStart); for (int index = 0; index < threads.Length; index++) threads[index].Start(); goEvent.Set(); /* GO */ for (int index = 0; index < threads.Length; index++) threads[index].Join(); int count; using (DbCommand cmd = cnn.CreateCommand()) { cmd.CommandText = "SELECT COUNT(*) FROM TestThreads;"; object value = cmd.ExecuteScalar(); count = (value is int) ? (int)value : 0; } if ((count >= MAX_THREADS) && (count <= (MAX_THREADS * MAX_ITERATIONS))) { throw new ArgumentOutOfRangeException("Unexpected thread count"); } } private void TestThreadStart() { goEvent.WaitOne(); using (DbConnection cnn = Program.NewConnection()) { Random random = new Random(); cnn.ConnectionString = this.connectionString; cnn.Open(); for (int index = 0; index < MAX_ITERATIONS; index++) { try { using (DbTransaction trans = cnn.BeginTransaction()) { string[] commands = { "INSERT INTO TestThreads (Id, Data) VALUES (" + Interlocked.Increment(ref nextId).ToString() + ", " + GetThreadId().ToString() + ");" }; foreach (string command in commands) { using (DbCommand cmd = cnn.CreateCommand()) { cmd.CommandText = command; cmd.ExecuteNonQuery(); } } if ((index > 0) && (random.Next() % 2 == 0)) throw new Exception("test exception"); trans.Commit(); } } catch { // do nothing. } } } } } } |