System.Data.SQLite
Check-in [04c8756a93]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Adjustments to the test case for ticket [996d13cd87]. However, this still does not reproduce the issue reported.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | tkt-996d13cd87
Files: files | file ages | folders
SHA1: 04c8756a9397ce4ae681363230e341ab7667a1f9
User & Date: mistachkin 2012-05-02 16:52:15
Context
2012-05-02
18:28
Update test case for ticket [996d13cd87]. The test case can now reproduce the issue reported. Closed-Leaf check-in: 0fb2e3848f user: mistachkin tags: tkt-996d13cd87
16:52
Adjustments to the test case for ticket [996d13cd87]. However, this still does not reproduce the issue reported. check-in: 04c8756a93 user: mistachkin tags: tkt-996d13cd87
2012-04-30
20:43
Add DLL file test constraints to tests that execute the test.exe or testlinq.exe files. Also, remove the associated test constraints when deleting build files from the Eagle binary directory. check-in: f8c324fa13 user: mistachkin tags: tkt-996d13cd87
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to Tests/common.eagle.

901
902
903
904
905
906
907







908
909
910
911
912
913
914
915







916
917
918
919
920
921
922
        reportSQLiteResources $::test_channel

        #
        # NOTE: Show the active test constraints.
        #
        tputs $::test_channel [appendArgs "---- constraints: " \
            [formatList [lsort [getConstraints]]] \n]







      }
    }
 
    proc runSQLiteTestEpilogue {} {
      #
      # NOTE: Skip running our custom epilogue if the main one has been skipped.
      #
      if {![info exists ::no(epilogue.eagle)]} then {







        #
        # NOTE: Also report the resource usage after running the tests.
        #
        reportSQLiteResources $::test_channel
      }
    }
 







>
>
>
>
>
>
>








>
>
>
>
>
>
>







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
        reportSQLiteResources $::test_channel

        #
        # NOTE: Show the active test constraints.
        #
        tputs $::test_channel [appendArgs "---- constraints: " \
            [formatList [lsort [getConstraints]]] \n]

        #
        # NOTE: Show when our tests actually began (now).
        #
        tputs $::test_channel [appendArgs \
            "---- System.Data.SQLite tests began at " \
            [clock format [clock seconds]] \n]
      }
    }
 
    proc runSQLiteTestEpilogue {} {
      #
      # NOTE: Skip running our custom epilogue if the main one has been skipped.
      #
      if {![info exists ::no(epilogue.eagle)]} then {
        #
        # NOTE: Show when our tests actually ended (now).
        #
        tputs $::test_channel [appendArgs \
            "---- System.Data.SQLite tests ended at " \
            [clock format [clock seconds]] \n]

        #
        # NOTE: Also report the resource usage after running the tests.
        #
        reportSQLiteResources $::test_channel
      }
    }
 

Changes to Tests/tkt-996d13cd87.eagle.

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
..
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
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
...
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128

129
130
131
132
133
134

135
136
137
138
139
140
141
142
...
146
147
148
149
150
151
152











153
154
155
156
157
158
159
160
161
...
176
177
178
179
180
181
182






183
184
185
186
187
188
189
...
195
196
197
198
199
200
201
202
203
204
205
206
207
###############################################################################

package require System.Data.SQLite.Test
runSQLiteTestPrologue

###############################################################################

runTest {test tkt-996d13cd87-1.1 {SQLiteConnectionPool usage} -setup {
  set fileName tkt-996d13cd87-1.1.db
} -body {
  set id [object invoke Interpreter.GetActive NextId]
  set dataSource [file join [getDatabaseDirectory] $fileName]

  unset -nocomplain results errors

  set code [compileCSharpWith [subst {
    using System;
    using System.Data.SQLite;

    using System.Threading;

    namespace _Dynamic${id}
    {
      public static class Test${id}
      {
        public static void Main()
        {






          //
          // NOTE: This is the total number of test threads to create.
          //
          int count = 10;








          //
          // NOTE: Create the event that will be used to synchronize all the
          //       created threads so that they start doing their actual test
          //       "work" at approximately the same time.
          //
          using (ManualResetEvent goEvent = new ManualResetEvent(false))
................................................................................
          {
            //
            // NOTE: Create a (reusable) delegate that will contain the code
            //       that half the created threads are to execute.  This code
            //       will repeatedly create, open, and close a single database
            //       connection with pool enabled.
            //
            ThreadStart threadStart = delegate()
            {
              try
              {
                //
                // NOTE: Wait forever for the "GO" signal so that all threads
                //       can start working at approximately the same time.
                //
                goEvent.WaitOne();

                //
                // NOTE: Create a random number generator suitable for waiting
                //       a random number of milliseconds between each attempt
                //       to cause the race condition on a given thread.
                //
                Random random = new Random();

                //
                // NOTE: Repeatedly try to create, open, and close a pooled
                //       database connection and then wait a random number of
                //       milliseconds before doing it again.
                //
                for (int index = 0; index < count; index++)
                {


                  using (SQLiteConnection connection = new SQLiteConnection(
                      "Data Source=${dataSource};Pooling=True;"))
                  {
                    connection.Open();
                    connection.Close();
                  }

                  Thread.Sleep(random.Next(0, count));

                }
              }
              catch (Exception e)
              {

                Console.WriteLine(e);
              }
            };

            //
            // NOTE: Create a (reusable) delegate that will contain the code
            //       that half the created threads are to execute.  This code
            //       will repeatedly force a full garbage collection.
................................................................................
                //
                // NOTE: Wait forever for the "GO" signal so that all threads
                //       can start working at approximately the same time.
                //
                goEvent.WaitOne();

                //
                // NOTE: Create a random number generator suitable for waiting
                //       a random number of milliseconds between each attempt
                //       to cause the race condition on a given thread.
                //
                Random random = new Random();

                //
                // NOTE: Repeatedly force a full garbage collection and then
                //       wait a random number of milliseconds before doing it
                //       again.
                //
                for (int index = 0; index < count; index++)
                {

                  GC.GetTotalMemory(true);
                  Thread.Sleep(random.Next(0, count));
                }
              }
              catch (Exception e)
              {

                Console.WriteLine(e);
              }
            };

            //
            // NOTE: Create the array of thread objects.
            //
            Thread\[\] thread = new Thread\[count\];
................................................................................
            //       size.  We must specify a stack size here because the
            //       default one for the process would be the same as the
            //       parent executable (the Eagle shell), which is 16MB,
            //       too large to be useful.
            //
            for (int index = 0; index < count; index++)
            {











              thread\[index\] = new Thread(
                  (index % 2) == 0 ? threadStart : threadStart2, 1048576);

              //
              // NOTE: Name each thread for a better debugging experience.
              //
              thread\[index\].Name = String.Format(
                  "[file rootname ${fileName}] #{0}", index);
            }
................................................................................
            //
            // NOTE: Wait forever for each thread to finish its test "work"
            //       and then die.
            //
            for (int index = 0; index < count; index++)
              thread\[index\].Join();
          }






        }
      }
    }
  }] true true true results errors System.Data.SQLite.dll]

  list $code $results \
      [expr {[info exists errors] ? $errors : ""}] \
................................................................................
  object invoke GC GetTotalMemory true

  cleanupDb $fileName

  unset -nocomplain result results errors code dataSource id db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -match \
regexp -result {^Ok System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 \{\}$}}

###############################################################################

runSQLiteTestEpilogue
runTestEpilogue







|










>






|

>
>
>
>
>
>



|
>
>
>
>
>
>
>







 







|









<
<
<
<
<
<
<







>
>
|
|
|
|
|
|
<
<
>




>
|







 







<
<
<
<
<
<
<
<
|
|

<
<
>
|
<
<



>
|







 







>
>
>
>
>
>
>
>
>
>
>
|
<







 







>
>
>
>
>
>







 







|





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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
..
67
68
69
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
110
111
112
...
118
119
120
121
122
123
124








125
126
127


128
129


130
131
132
133
134
135
136
137
138
139
140
141
...
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163

164
165
166
167
168
169
170
...
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
...
210
211
212
213
214
215
216
217
218
219
220
221
222
###############################################################################

package require System.Data.SQLite.Test
runSQLiteTestPrologue

###############################################################################

runTest {test tkt-996d13cd87-1.1 {SQLiteConnectionPool stress} -setup {
  set fileName tkt-996d13cd87-1.1.db
} -body {
  set id [object invoke Interpreter.GetActive NextId]
  set dataSource [file join [getDatabaseDirectory] $fileName]

  unset -nocomplain results errors

  set code [compileCSharpWith [subst {
    using System;
    using System.Data.SQLite;
    using System.Diagnostics;
    using System.Threading;

    namespace _Dynamic${id}
    {
      public static class Test${id}
      {
        public static int Main()
        {
          //
          // NOTE: This is the total number of exceptions caught by all the
          //       test threads.
          //
          int errors = 0;

          //
          // NOTE: This is the total number of test threads to create.
          //
          int count = 200;

          //
          // NOTE: Create a random number generator suitable for waiting a
          //       random number of milliseconds between each attempt to
          //       cause the race condition on a given thread.
          //
          Random random = new Random();

          //
          // NOTE: Create the event that will be used to synchronize all the
          //       created threads so that they start doing their actual test
          //       "work" at approximately the same time.
          //
          using (ManualResetEvent goEvent = new ManualResetEvent(false))
................................................................................
          {
            //
            // NOTE: Create a (reusable) delegate that will contain the code
            //       that half the created threads are to execute.  This code
            //       will repeatedly create, open, and close a single database
            //       connection with pool enabled.
            //
            ThreadStart threadStart1 = delegate()
            {
              try
              {
                //
                // NOTE: Wait forever for the "GO" signal so that all threads
                //       can start working at approximately the same time.
                //
                goEvent.WaitOne();








                //
                // NOTE: Repeatedly try to create, open, and close a pooled
                //       database connection and then wait a random number of
                //       milliseconds before doing it again.
                //
                for (int index = 0; index < count; index++)
                {
                  Thread.Sleep(random.Next(0, 250));

                  SQLiteConnection connection = new SQLiteConnection(
                      "Data Source=${dataSource};Pooling=True;");

                  connection.Open();
                  connection.Close();



                  connection = null;
                }
              }
              catch (Exception e)
              {
                Interlocked.Increment(ref errors);
                Trace.WriteLine(e);
              }
            };

            //
            // NOTE: Create a (reusable) delegate that will contain the code
            //       that half the created threads are to execute.  This code
            //       will repeatedly force a full garbage collection.
................................................................................
                //
                // NOTE: Wait forever for the "GO" signal so that all threads
                //       can start working at approximately the same time.
                //
                goEvent.WaitOne();

                //








                // NOTE: Wait a random number of milliseconds before forcing a
                //       full garbage collection.
                //


                Thread.Sleep(random.Next(0, count * 100));
                GC.GetTotalMemory(true);


              }
              catch (Exception e)
              {
                Interlocked.Increment(ref errors);
                Trace.WriteLine(e);
              }
            };

            //
            // NOTE: Create the array of thread objects.
            //
            Thread\[\] thread = new Thread\[count\];
................................................................................
            //       size.  We must specify a stack size here because the
            //       default one for the process would be the same as the
            //       parent executable (the Eagle shell), which is 16MB,
            //       too large to be useful.
            //
            for (int index = 0; index < count; index++)
            {
              //
              // NOTE: Figure out what kind of thread to create (i.e. one
              //       that uses a connection or one that calls the GC).
              //
              ThreadStart threadStart;

              if (index == 0)
                threadStart = threadStart2;
              else
                threadStart = threadStart1;

              thread\[index\] = new Thread(threadStart, 1048576);


              //
              // NOTE: Name each thread for a better debugging experience.
              //
              thread\[index\].Name = String.Format(
                  "[file rootname ${fileName}] #{0}", index);
            }
................................................................................
            //
            // NOTE: Wait forever for each thread to finish its test "work"
            //       and then die.
            //
            for (int index = 0; index < count; index++)
              thread\[index\].Join();
          }

          //
          // NOTE: Return the total number of exceptions caught by the test
          //       threads.  For this test to pass, this number must be zero.
          //
          return errors;
        }
      }
    }
  }] true true true results errors System.Data.SQLite.dll]

  list $code $results \
      [expr {[info exists errors] ? $errors : ""}] \
................................................................................
  object invoke GC GetTotalMemory true

  cleanupDb $fileName

  unset -nocomplain result results errors code dataSource id db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -match \
regexp -result {^Ok System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 0$}}

###############################################################################

runSQLiteTestEpilogue
runTestEpilogue