• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/router/db-4.8.30/test/scr037/
1/*-
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 2009 Oracle.  All rights reserved.
5 *
6 */
7using System;
8using System.Collections;
9using System.Collections.Generic;
10using System.Diagnostics;
11using System.IO;
12using System.Text;
13using System.Threading;
14using System.Xml;
15using NUnit.Framework;
16using BerkeleyDB;
17
18namespace CsharpAPITest
19{
20	[TestFixture]
21	public class DatabaseEnvironmentTest
22	{
23		private string testFixtureHome;
24		private string testFixtureName;
25		private string testName;
26		private string testHome;
27
28		private DatabaseEnvironment testBeginTransactionEnv;
29		private BTreeDatabase testBeginTransactionDB;
30
31		private DatabaseEnvironment testCheckpointEnv;
32		private BTreeDatabase testCheckpointDB;
33
34		private DatabaseEnvironment testDetectDeadlocksEnv;
35		private BTreeDatabase testDetectDeadlocksDB;
36
37		private DatabaseEnvironment testFailCheckEnv;
38
39		private EventWaitHandle signal;
40
41		[TestFixtureSetUp]
42		public void SetUp()
43		{
44			testFixtureName = "DatabaseEnvironmentTest";
45			testFixtureHome = "./TestOut/" + testFixtureName;
46			try
47			{
48				Configuration.ClearDir(testFixtureHome);
49			}
50			catch (Exception)
51			{
52				throw new TestException(
53				    "Please clean the directory");
54			}
55		}
56
57		[Test]
58		public void TestArchivableDatabaseFiles()
59		{
60			testName = "TestArchivableDatabaseFiles";
61			testHome = testFixtureHome + "/" + testName;
62			string dbFileName1 = testName + "1.db";
63			string dbFileName2 = testName + "2.db";
64
65			Configuration.ClearDir(testHome);
66
67			// Open an environment.
68			DatabaseEnvironmentConfig envConfig =
69			    new DatabaseEnvironmentConfig();
70			envConfig.AutoCommit = true;
71			envConfig.Create = true;
72			envConfig.UseMPool = true;
73			envConfig.UseLogging = true;
74			envConfig.UseTxns = true;
75			DatabaseEnvironment env = DatabaseEnvironment.Open(
76			    testHome, envConfig);
77
78			// Open two databases.
79			BTreeDatabaseConfig dbConfig =
80			    new BTreeDatabaseConfig();
81			dbConfig.Creation = CreatePolicy.IF_NEEDED;
82			dbConfig.Env = env;
83			BTreeDatabase db1 = BTreeDatabase.Open(dbFileName1, dbConfig);
84			db1.Close();
85			BTreeDatabase db2 = BTreeDatabase.Open(dbFileName2, dbConfig);
86			db2.Close();
87
88			/*
89			 * Get all database files name in the environment.
90			 * Two database file name should be returned and
91			 * the same as the ones when opening the databases.
92			 */
93			List<string> dbFiles = env.ArchivableDatabaseFiles(false);
94			Assert.AreEqual(2, dbFiles.Count);
95			Assert.IsTrue(dbFiles.Contains(dbFileName1));
96			Assert.IsTrue(dbFiles.Contains(dbFileName2));
97
98			/*
99			 * Get all database file's abosolute path in the
100			 * environment. Confirm those files exist.
101			 */
102			List<string> dbFilesPath = env.ArchivableDatabaseFiles(true);
103			Assert.IsTrue(File.Exists(dbFilesPath[0]));
104			Assert.IsTrue(File.Exists(dbFilesPath[1]));
105
106			env.Close();
107		}
108
109		[Test]
110		public void TestArchivableLogFiles()
111		{
112			testName = "TestArchivableLogFiles";
113			testHome = testFixtureHome + "/" + testName;
114			string dbFileName = testName + ".db";
115
116			Configuration.ClearDir(testHome);
117
118			// Open an environment.
119			DatabaseEnvironmentConfig envConfig =
120			    new DatabaseEnvironmentConfig();
121			envConfig.AutoCommit = true;
122			envConfig.Create = true;
123			envConfig.UseMPool = true;
124			envConfig.UseLogging = true;
125			envConfig.UseTxns = true;
126			DatabaseEnvironment env = DatabaseEnvironment.Open(
127			    testHome, envConfig);
128
129			// Open a databases.
130			BTreeDatabaseConfig dbConfig =
131			    new BTreeDatabaseConfig();
132			dbConfig.Creation = CreatePolicy.IF_NEEDED;
133			dbConfig.Env = env;
134			BTreeDatabase db = BTreeDatabase.Open(
135			    dbFileName, dbConfig);
136
137			/*
138			 * Put 1000 records into the database to generate
139			 * more than one log files.
140			 */
141			byte[] byteArr = new byte[1024];
142			for (int i = 0; i < 1000; i++)
143				db.Put(new DatabaseEntry(
144				    BitConverter.GetBytes(i)),
145				    new DatabaseEntry(byteArr));
146
147			db.Close();
148
149			List<string> logFiles = env.ArchivableLogFiles(false);
150
151			List<string> logFilesPath =
152			    env.ArchivableLogFiles(true);
153			for (int i = 0; i < logFilesPath.Count; i++)
154				Assert.IsTrue(File.Exists(logFilesPath[i]));
155
156			env.Close();
157		}
158
159		[Test]
160		public void TestBeginCDSGroup()
161		{
162			testName = "TestBeginCDSGroup";
163			testHome = testFixtureHome + "/" + testName;
164
165			Configuration.ClearDir(testHome);
166
167			DatabaseEnvironmentConfig cfg =
168			    new DatabaseEnvironmentConfig();
169			cfg.Create = true;
170			cfg.UseCDB = true;
171			cfg.UseMPool = true;
172			DatabaseEnvironment env = DatabaseEnvironment.Open(testHome, cfg);
173			Transaction txn = env.BeginCDSGroup();
174			BTreeDatabaseConfig dbConfig = new BTreeDatabaseConfig();
175			dbConfig.Creation = CreatePolicy.IF_NEEDED;
176			dbConfig.Env = env;
177			BTreeDatabase db = BTreeDatabase.Open(
178			    testName + ".db", dbConfig, txn);
179			db.Put(new DatabaseEntry(
180			    ASCIIEncoding.ASCII.GetBytes("key")),
181			    new DatabaseEntry(
182			    ASCIIEncoding.ASCII.GetBytes("data")), txn);
183			db.Close();
184			txn.Commit();
185			env.Close();
186		}
187
188		[Test]
189		public void TestBeginTransaction()
190		{
191			testName = "TestBeginTransaction";
192			testHome = testFixtureHome + "/" + testName;
193
194			Configuration.ClearDir(testHome);
195
196			// Open an environment.
197			DatabaseEnvironmentConfig cfg =
198			    new DatabaseEnvironmentConfig();
199			cfg.Create = true;
200			cfg.UseTxns = true;
201			cfg.UseMPool = true;
202			cfg.UseLogging = true;
203			cfg.UseLocking = true;
204			cfg.NoLocking = false;
205			cfg.FreeThreaded = true;
206			testBeginTransactionEnv = DatabaseEnvironment.Open(testHome, cfg);
207			testBeginTransactionEnv.DeadlockResolution = DeadlockPolicy.OLDEST;
208
209			// Open btree database.
210			BTreeDatabaseConfig dbConfig = new BTreeDatabaseConfig();
211			dbConfig.AutoCommit = true;
212			dbConfig.Creation = CreatePolicy.IF_NEEDED;
213			dbConfig.Env = testBeginTransactionEnv;
214			dbConfig.Duplicates = DuplicatesPolicy.NONE;
215			dbConfig.FreeThreaded = true;
216			testBeginTransactionDB = BTreeDatabase.Open(
217			    testName + ".db", dbConfig);
218
219			testBeginTransactionDB.Put(
220			    new DatabaseEntry(ASCIIEncoding.ASCII.GetBytes("key")),
221			    new DatabaseEntry(ASCIIEncoding.ASCII.GetBytes("data")));
222
223			// Begin two threads to run dead lock detection.
224			Thread thread1 = new Thread(new ThreadStart(
225			    DeadLockThreadWithLockTimeOut));
226			Thread thread2 = new Thread(new ThreadStart(
227			    DeadLockThreadWithTxnTimeout));
228			signal = new EventWaitHandle(false, EventResetMode.ManualReset);
229			thread1.Start();
230			thread2.Start();
231			Thread.Sleep(1000);
232			signal.Set();
233			thread1.Join();
234			thread2.Join();
235
236			// Close all.
237			testBeginTransactionDB.Close();
238			testBeginTransactionEnv.Close();
239		}
240
241		public void DeadLockThreadWithLockTimeOut()
242		{
243			// Configure and begin a transaction.
244			TransactionConfig txnConfig = new TransactionConfig();
245			txnConfig.LockTimeout = 5000;
246			txnConfig.Name = "DeadLockThreadWithLockTimeOut";
247			Transaction txn =
248			    testBeginTransactionEnv.BeginTransaction(txnConfig, null);
249			try
250			{
251				testBeginTransactionDB.Put(
252				    new DatabaseEntry(ASCIIEncoding.ASCII.GetBytes("key")),
253				    new DatabaseEntry(ASCIIEncoding.ASCII.GetBytes("data")));
254				signal.WaitOne();
255				testBeginTransactionDB.Put(
256				    new DatabaseEntry(ASCIIEncoding.ASCII.GetBytes("newkey")),
257				    new DatabaseEntry(ASCIIEncoding.ASCII.GetBytes("newdata")),
258				    txn);
259				txn.Commit();
260			}
261			catch (DeadlockException)
262			{
263				try
264				{
265					txn.Abort();
266				}
267				catch (DatabaseException)
268				{
269					throw new TestException();
270				}
271			}
272			catch (DatabaseException)
273			{
274				try
275				{
276					txn.Abort();
277				}
278				catch (DatabaseException)
279				{
280					throw new TestException();
281				}
282			}
283		}
284
285		public void DeadLockThreadWithTxnTimeout()
286		{
287			// Configure and begin a transaction.
288			TransactionConfig txnConfig = new TransactionConfig();
289			txnConfig.TxnTimeout = 5000;
290			txnConfig.Name = "DeadLockThreadWithTxnTimeout";
291			Transaction txn =
292			    testBeginTransactionEnv.BeginTransaction(txnConfig, null);
293			try
294			{
295				testBeginTransactionDB.Put(
296				    new DatabaseEntry(ASCIIEncoding.ASCII.GetBytes("key")),
297				    new DatabaseEntry(ASCIIEncoding.ASCII.GetBytes("data")));
298				signal.WaitOne();
299				testBeginTransactionDB.Put(
300				    new DatabaseEntry(ASCIIEncoding.ASCII.GetBytes("newkey")),
301				    new DatabaseEntry(ASCIIEncoding.ASCII.GetBytes("newdata")),
302				    txn);
303				txn.Commit();
304			}
305			catch (DeadlockException)
306			{
307				try
308				{
309					txn.Abort();
310				}
311				catch (DatabaseException)
312				{
313					throw new TestException();
314				}
315			}
316			catch (DatabaseException)
317			{
318				try
319				{
320					txn.Abort();
321				}
322				catch (DatabaseException)
323				{
324					throw new TestException();
325				}
326			}
327		}
328
329		[Test]
330		public void TestCheckpoint()
331		{
332			testName = "TestCheckpoint";
333			testHome = testFixtureHome + "/" + testName;
334
335			Configuration.ClearDir(testHome);
336
337			// Open an environment.
338			DatabaseEnvironmentConfig cfg =
339			    new DatabaseEnvironmentConfig();
340			cfg.Create = true;
341			cfg.UseTxns = true;
342			cfg.UseMPool = true;
343			cfg.UseLogging = true;
344			cfg.UseLocking = true;
345			cfg.NoLocking = false;
346			cfg.FreeThreaded = true;
347			testCheckpointEnv = DatabaseEnvironment.Open(testHome, cfg);
348
349			// Open btree database.
350			BTreeDatabaseConfig dbConfig = new BTreeDatabaseConfig();
351			dbConfig.AutoCommit = true;
352			dbConfig.Creation = CreatePolicy.IF_NEEDED;
353			dbConfig.Env = testCheckpointEnv;
354			dbConfig.FreeThreaded = true;
355			testCheckpointDB = BTreeDatabase.Open(testName + ".db", dbConfig);
356
357
358			// Run a thread to put records into database.
359			Thread thread1 = new Thread(new ThreadStart(PutRecordsThread));
360
361			/*
362			 * Run a thread to do checkpoint periodically and
363			 * finally do a checkpoint to flush all in memory pool
364			 * to log files.
365			 */
366			Thread thread2 = new Thread(new ThreadStart(CheckpointThread));
367
368			thread1.Start();
369			thread2.Start();
370			thread1.Join();
371			thread2.Join();
372
373			// Close all.
374			testCheckpointDB.Close();
375			testCheckpointEnv.Close();
376		}
377
378		public void PutRecordsThread()
379		{
380			Transaction txn = testCheckpointEnv.BeginTransaction();
381			byte[] byteArr = new byte[1024];
382			for (int i = 0; i < 1000; i++)
383				testCheckpointDB.Put(
384				    new DatabaseEntry(BitConverter.GetBytes(i)),
385				    new DatabaseEntry(byteArr), txn);
386			txn.Commit();
387		}
388
389		public void CheckpointThread()
390		{
391			uint bytes = 64;
392			uint minutes = 1;
393			uint count = 1;
394			while (count < 3)
395			{
396				testCheckpointEnv.Checkpoint(bytes, minutes);
397				count++;
398			}
399			Thread.Sleep(500);
400			testCheckpointEnv.Checkpoint();
401		}
402
403		[Test]
404		public void TestClose()
405		{
406			testName = "TestClose";
407			testHome = testFixtureHome + "/" + testName;
408
409			Configuration.ClearDir(testHome);
410
411			DatabaseEnvironmentConfig cfg =
412			    new DatabaseEnvironmentConfig();
413			cfg.Create = true;
414			DatabaseEnvironment env = DatabaseEnvironment.Open(
415			    testHome, cfg);
416			env.Close();
417		}
418
419		[Test]
420		public void TestConfigAll()
421		{
422			testName = "TestConfigAll";
423			testHome = testFixtureHome + "/" + testName;
424
425			Configuration.ClearDir(testHome);
426
427			XmlElement xmlElem = Configuration.TestSetUp(
428			    testFixtureName, testName);
429
430			/*
431			 * Open a new environment with all properties,
432			 * fields and subsystems configured.
433			 */
434			DatabaseEnvironmentConfig envConig =
435			    new DatabaseEnvironmentConfig();
436			Config(xmlElem, ref envConig, true, true, true,
437			    true, true, true);
438
439			// Configure with methods.
440			ReplicationHostAddress address =
441			    new ReplicationHostAddress("127.0.0.0", 11111);
442			envConig.RepSystemCfg.Clockskew(102, 100);
443			envConig.RepSystemCfg.RetransmissionRequest(10, 100);
444			envConig.RepSystemCfg.TransmitLimit(1, 1024);
445
446			// Open the environment.
447			DatabaseEnvironment env = DatabaseEnvironment.Open(
448			    testHome, envConig);
449
450			// Confirm environment status with its configuration.
451			Confirm(xmlElem, env, true, true, true, true, true, true);
452
453			// Print statistics of the current environment.
454			env.PrintStats(true, true);
455
456			// Print statistics of all subsytems.
457			env.PrintSubsystemStats(true, true);
458
459			env.Close();
460		}
461
462		[Test]
463		public void TestDeadlockPolicy()
464		{
465			testName = "TestDeadlockPolicy";
466			testHome = testFixtureHome + "/" + testName;
467
468			DetectDeadlockPolicy(testHome + "_DEFAULT",
469			    DeadlockPolicy.DEFAULT);
470
471			DetectDeadlockPolicy(testHome + "_EXPIRE",
472			    DeadlockPolicy.EXPIRE);
473			DetectDeadlockPolicy(testHome + "_MAX_LOCKS",
474			    DeadlockPolicy.MAX_LOCKS);
475			DetectDeadlockPolicy(testHome + "_MAX_WRITE",
476			    DeadlockPolicy.MAX_WRITE);
477			DetectDeadlockPolicy(testHome + "_MIN_LOCKS",
478			    DeadlockPolicy.MIN_LOCKS);
479			DetectDeadlockPolicy(testHome + "_MIN_WRITE",
480			    DeadlockPolicy.MIN_WRITE);
481			DetectDeadlockPolicy(testHome + "_OLDEST",
482			    DeadlockPolicy.OLDEST);
483			DetectDeadlockPolicy(testHome + "_RANDOM",
484			    DeadlockPolicy.RANDOM);
485			DetectDeadlockPolicy(testHome + "_YOUNGEST",
486			    DeadlockPolicy.YOUNGEST);
487		}
488
489		public void DetectDeadlockPolicy(
490		    string home, DeadlockPolicy deadlock)
491		{
492			Configuration.ClearDir(home);
493			DatabaseEnvironmentConfig envConfig =
494			    new DatabaseEnvironmentConfig();
495			envConfig.Create = true;
496			envConfig.UseLocking = true;
497			envConfig.UseLogging = true;
498			envConfig.UseMPool = true;
499			envConfig.UseTxns = true;
500			DatabaseEnvironment env = DatabaseEnvironment.Open(
501			    home, envConfig);
502			env.DeadlockResolution = deadlock;
503			Assert.AreEqual(deadlock, env.DeadlockResolution);
504			env.DetectDeadlocks(deadlock);
505			env.Close();
506		}
507
508		[Test]
509		public void TestDetectDeadlocks()
510		{
511			testName = "TestDetectDeadlocks";
512			testHome = testFixtureHome + "/" + testName;
513
514			Configuration.ClearDir(testHome);
515
516			// Open an environment.
517			DatabaseEnvironmentConfig cfg =
518			    new DatabaseEnvironmentConfig();
519			cfg.Create = true;
520			cfg.UseTxns = true;
521			cfg.UseMPool = true;
522			cfg.UseLogging = true;
523			cfg.UseLocking = true;
524			cfg.FreeThreaded = true;
525			testDetectDeadlocksEnv = DatabaseEnvironment.Open(
526			    testHome, cfg);
527
528			// Open btree database.
529			BTreeDatabaseConfig dbConfig = new BTreeDatabaseConfig();
530			dbConfig.AutoCommit = true;
531			dbConfig.Creation = CreatePolicy.IF_NEEDED;
532			dbConfig.Env = testDetectDeadlocksEnv;
533			dbConfig.Duplicates = DuplicatesPolicy.NONE;
534			dbConfig.FreeThreaded = true;
535			testDetectDeadlocksDB = BTreeDatabase.Open(
536			    testName + ".db", dbConfig);
537
538			// Put one record("key", "data") into database.
539			testDetectDeadlocksDB.Put(
540			    new DatabaseEntry(ASCIIEncoding.ASCII.GetBytes("key")),
541			    new DatabaseEntry(ASCIIEncoding.ASCII.GetBytes("data")));
542
543			// Begin two threads to read and write record.
544			Thread thread1 = new Thread(new ThreadStart(ReadAndPutRecordThread));
545			Thread thread2 = new Thread(new ThreadStart(ReadAndPutRecordThread));
546			signal = new EventWaitHandle(false, EventResetMode.ManualReset);
547			thread1.Start();
548			thread2.Start();
549
550			// Give enough time for threads to read record.
551			Thread.Sleep(1000);
552
553			/*
554			 * Let the two threads apply for write lock
555			 * synchronously.
556			 */
557			signal.Set();
558
559			// Confirm that there is deadlock in the environment.
560			Thread.Sleep(1000);
561			uint deadlockNum = testDetectDeadlocksEnv.DetectDeadlocks(
562			    DeadlockPolicy.DEFAULT);
563			Assert.Less(0, deadlockNum);
564
565			thread1.Join();
566			thread2.Join();
567
568			// Close all.
569			testDetectDeadlocksDB.Close(false);
570			testDetectDeadlocksEnv.Close();
571		}
572
573		public void ReadAndPutRecordThread()
574		{
575			Transaction txn =
576			    testDetectDeadlocksEnv.BeginTransaction();
577			try
578			{
579				testDetectDeadlocksDB.GetBoth(
580				    new DatabaseEntry(ASCIIEncoding.ASCII.GetBytes("key")),
581				    new DatabaseEntry(ASCIIEncoding.ASCII.GetBytes("data")), txn);
582				signal.WaitOne();
583				testDetectDeadlocksDB.Put(
584				    new DatabaseEntry(ASCIIEncoding.ASCII.GetBytes("newKey")),
585				    new DatabaseEntry(ASCIIEncoding.ASCII.GetBytes("newData")),
586				    txn);
587				txn.Commit();
588			}
589			catch (DeadlockException)
590			{
591				txn.Abort();
592			}
593		}
594
595		[Test]
596		public void TestFailCheck()
597		{
598			testName = "TestFailCheck";
599			testHome = testFixtureHome + "/" + testName;
600
601			Configuration.ClearDir(testHome);
602
603			DatabaseEnvironmentConfig cfg =
604			    new DatabaseEnvironmentConfig();
605			cfg.Create = true;
606			cfg.UseTxns = true;
607			cfg.UseMPool = true;
608			cfg.UseLogging = true;
609			cfg.UseLocking = true;
610			cfg.FreeThreaded = true;
611			cfg.ThreadIsAlive = new ThreadIsAliveDelegate(ThrdAlive);
612			cfg.SetThreadID = new SetThreadIDDelegate(SetThrdID);
613			cfg.ThreadCount = 10;
614			testFailCheckEnv = DatabaseEnvironment.Open(testHome, cfg);
615
616			Thread thread = new Thread(new ThreadStart(WriteThreadWithoutTxnCommit));
617			thread.Start();
618			thread.Join();
619			testFailCheckEnv.FailCheck();
620			testFailCheckEnv.Close();
621		}
622
623		public void WriteThreadWithoutTxnCommit()
624		{
625			Transaction txn = testFailCheckEnv.BeginTransaction();
626			BTreeDatabaseConfig dbConfig = new BTreeDatabaseConfig();
627			dbConfig.Creation = CreatePolicy.IF_NEEDED;
628			dbConfig.Env = testFailCheckEnv;
629			BTreeDatabase db = BTreeDatabase.Open("TestFailCheck.db", dbConfig, txn);
630			db.Close();
631			txn.Commit();
632		}
633
634		public bool ThrdAlive(DbThreadID info, bool procOnly)
635		{
636			Process pcs = Process.GetProcessById(info.processID);
637			if (pcs.HasExited == true)
638				return false;
639			else if (procOnly)
640				return true;
641			ProcessThreadCollection thrds = pcs.Threads;
642			foreach (ProcessThread pcsThrd in thrds)
643			{
644				if (pcsThrd.Id == info.threadID)
645				{
646					/*
647					 * We have to use the fully qualified name, ThreadState
648					 * defaults to System.Threading.ThreadState.
649					 */
650					return (pcsThrd.ThreadState !=
651						System.Diagnostics.ThreadState.Terminated);
652				}
653			}
654			// If we can't find the thread, we say it's not alive
655			return false;
656		}
657
658		public DbThreadID SetThrdID()
659		{
660			DbThreadID threadID;
661
662			int pid = Process.GetCurrentProcess().Id;
663			uint tid = (uint)AppDomain.GetCurrentThreadId();
664			threadID = new DbThreadID(pid, tid);
665			return threadID;
666		}
667
668		[Test]
669		public void TestFeedback()
670		{
671			testName = "TestFeedback";
672			testHome = testFixtureHome + "/" + testName;
673
674			Configuration.ClearDir(testHome);
675
676			// Open the environment.
677			DatabaseEnvironmentConfig cfg =
678			    new DatabaseEnvironmentConfig();
679			cfg.AutoCommit = true;
680			cfg.UseLocking = true;
681			cfg.UseLogging = true;
682			cfg.UseMPool = true;
683			cfg.UseTxns = true;
684			cfg.Create = true;
685			DatabaseEnvironment env = DatabaseEnvironment.Open(testHome, cfg);
686
687			env.Feedback = new EnvironmentFeedbackDelegate(
688			    EnvRecovery10PercentFeedback);
689			env.Feedback(EnvironmentFeedbackEvent.RECOVERY, 10);
690
691			env.Close();
692		}
693
694		public void EnvRecovery10PercentFeedback(
695		    EnvironmentFeedbackEvent opcode, int percent)
696		{
697			Assert.AreEqual(opcode, EnvironmentFeedbackEvent.RECOVERY);
698			Assert.AreEqual(10, percent);
699		}
700
701		[Test]
702		public void TestMutexSystemStats()
703		{
704			testName = "TestMutexSystemStats";
705			testHome = testFixtureHome + "/" + testName;
706
707			Configuration.ClearDir(testHome);
708
709			DatabaseEnvironmentConfig cfg =
710			    new DatabaseEnvironmentConfig();
711			cfg.Create = true;
712			cfg.UseLogging = true;
713			cfg.UseLocking = true;
714			cfg.UseMPool = true;
715			cfg.UseTxns = true;
716			cfg.MutexSystemCfg = new MutexConfig();
717			cfg.MutexSystemCfg.Alignment = 512;
718			cfg.MutexSystemCfg.Increment = 128;
719			cfg.MutexSystemCfg.MaxMutexes = 150;
720			cfg.MutexSystemCfg.NumTestAndSetSpins = 10;
721			DatabaseEnvironment env = DatabaseEnvironment.Open(testHome, cfg);
722
723			MutexStats stats = env.MutexSystemStats();
724			env.PrintMutexSystemStats(true, true);
725			Assert.AreEqual(512, stats.Alignment);
726			Assert.AreEqual(stats.Count, stats.Available + stats.InUse);
727			Assert.LessOrEqual(stats.InUse, stats.MaxInUse);
728			Assert.AreNotEqual(0, stats.RegionSize);
729			Assert.AreEqual(0, stats.RegionWait);
730			Assert.AreEqual(10, stats.TASSpins);
731			ulong regionNoWait = stats.RegionNoWait;
732
733			BTreeDatabaseConfig dbCfg = new BTreeDatabaseConfig();
734			dbCfg.Creation = CreatePolicy.IF_NEEDED;
735			dbCfg.Env = env;
736			BTreeDatabase db = BTreeDatabase.Open(testName + ".db", dbCfg);
737			for (int i = 0; i < 1000; i++)
738			{
739				db.Put(new DatabaseEntry(BitConverter.GetBytes(i)),
740				    new DatabaseEntry(BitConverter.GetBytes(i)));
741				stats = env.MutexSystemStats();
742			}
743			Assert.LessOrEqual(regionNoWait, stats.RegionNoWait);
744			regionNoWait = stats.RegionNoWait;
745
746			stats = env.MutexSystemStats(true);
747			env.PrintMutexSystemStats();
748			stats = env.MutexSystemStats();
749			Assert.GreaterOrEqual(regionNoWait, stats.RegionNoWait);
750
751			db.Close();
752			env.Close();
753		}
754
755		[Test]
756		public void TestLogFile()
757		{
758			testName = "TestLogFile";
759			testHome = testFixtureHome + "/" + testName;
760
761			Configuration.ClearDir(testHome);
762
763			// Open environment and configure logging subsystem.
764			DatabaseEnvironmentConfig cfg =
765			    new DatabaseEnvironmentConfig();
766			cfg.Create = true;
767			cfg.UseTxns = true;
768			cfg.AutoCommit = true;
769			cfg.UseLocking = true;
770			cfg.UseMPool = true;
771			cfg.UseLogging = true;
772			cfg.MPoolSystemCfg = new MPoolConfig();
773			cfg.MPoolSystemCfg.CacheSize =
774			    new CacheInfo(0, 1048576, 1);
775			cfg.LogSystemCfg = new LogConfig();
776			cfg.LogSystemCfg.AutoRemove = false;
777			cfg.LogSystemCfg.BufferSize = 10240;
778			cfg.LogSystemCfg.Dir = "./";
779			cfg.LogSystemCfg.FileMode = 755;
780			cfg.LogSystemCfg.ForceSync = true;
781			cfg.LogSystemCfg.InMemory = false;
782			cfg.LogSystemCfg.MaxFileSize = 1048576;
783			cfg.LogSystemCfg.NoBuffer = false;
784			cfg.LogSystemCfg.RegionSize = 204800;
785			cfg.LogSystemCfg.ZeroOnCreate = true;
786			DatabaseEnvironment env = DatabaseEnvironment.Open(testHome, cfg);
787
788			// Open database.
789			Transaction allTxn = env.BeginTransaction();
790			TransactionConfig txnConfig = new TransactionConfig();
791			txnConfig.Name = "OpenTransaction";
792			Transaction openTxn = env.BeginTransaction(txnConfig, allTxn);
793			BTreeDatabaseConfig dbConfig = new BTreeDatabaseConfig();
794			dbConfig.Creation = CreatePolicy.IF_NEEDED;
795			dbConfig.Env = env;
796			BTreeDatabase db = BTreeDatabase.Open(
797			    testName + ".db", dbConfig, openTxn);
798
799			List<ActiveTransaction> activeTxns =
800			    env.TransactionSystemStats().Transactions;
801			for (int i = 0; i < activeTxns.Count; i++)
802				if (activeTxns[i].Name == "OpenTransaction")
803				{
804					LSN lsn = new LSN(
805					    activeTxns[i].Begun.LogFileNumber,
806					    activeTxns[i].Begun.Offset);
807					env.LogFlush(lsn);
808					string fileName = env.LogFile(lsn);
809				}
810
811			openTxn.Commit();
812
813			// Write "##" to log before putting data into database.
814			env.WriteToLog("##");
815
816			// Write 1000 records into database.
817			TransactionConfig writeTxnConfig = new TransactionConfig();
818			writeTxnConfig.Name = "WriteTxn";
819			Transaction writeTxn = env.BeginTransaction(writeTxnConfig);
820			byte[] byteArr = new byte[1024];
821			for (int i = 0; i < 1000; i++)
822			{
823				db.Put(new DatabaseEntry(BitConverter.GetBytes(i)),
824				    new DatabaseEntry(byteArr), writeTxn);
825				env.LogFlush();
826				env.WriteToLog("#" + i.ToString(), writeTxn);
827			}
828
829			activeTxns = env.TransactionSystemStats().Transactions;
830			for (int i = 0; i < activeTxns.Count; i++)
831				if (activeTxns[i].Name == "WriteTxn")
832				{
833					LSN lsn = new LSN(
834					    activeTxns[i].Begun.LogFileNumber,
835					    activeTxns[i].Begun.Offset);
836					env.LogFlush(lsn);
837					string fileName = env.LogFile(lsn);
838				}
839
840
841			writeTxn.Commit();
842			db.Close();
843
844			// Write "##" after data has been put.
845			env.WriteToLog("##");
846
847			List<string> logFiles = env.LogFiles(true);
848
849			env.LogWrite(new DatabaseEntry(), true);
850
851			env.RemoveUnusedLogFiles();
852
853			allTxn.Commit();
854			env.Close();
855		}
856
857		[Test]
858		public void TestOpen()
859		{
860			testName = "TestOpen";
861			testHome = testFixtureHome + "/" + testName;
862
863			Configuration.ClearDir(testHome);
864
865			DatabaseEnvironmentConfig cfg =
866			    new DatabaseEnvironmentConfig();
867			cfg.Create = true;
868			DatabaseEnvironment env = DatabaseEnvironment.Open(testHome, cfg);
869
870			// Confirm that the environment is initialized.
871			Assert.IsNotNull(env);
872
873			// Confirm the environment home directory.
874			Assert.AreEqual(testHome, env.Home);
875
876			// Print statistics of the current environment.
877			env.PrintStats();
878
879			// Print statistics of all subsytems.
880			env.PrintSubsystemStats();
881
882			env.Close();
883		}
884
885		[Test]
886		public void TestMPoolSystemStats()
887		{
888			testName = "TestMPoolSystemStats";
889			testHome = testFixtureHome + "/" + testName;
890
891			Configuration.ClearDir(testHome);
892
893			DatabaseEnvironmentConfig envConfig =
894			    new DatabaseEnvironmentConfig();
895			envConfig.AutoCommit = true;
896			envConfig.MPoolSystemCfg = new MPoolConfig();
897			envConfig.MPoolSystemCfg.CacheSize =
898			    new CacheInfo(0, 1048576, 3);
899			envConfig.Create = true;
900			envConfig.UseLocking = true;
901			envConfig.UseLogging = true;
902			envConfig.UseMPool = true;
903			envConfig.UseTxns = true;
904			envConfig.UseLogging = true;
905			DatabaseEnvironment env = DatabaseEnvironment.Open(
906			    testHome, envConfig);
907
908			MPoolStats stats = env.MPoolSystemStats();
909			env.PrintMPoolSystemStats();
910
911			Assert.AreEqual(0, stats.BlockedOperations);
912			Assert.AreEqual(0, stats.BucketsCheckedDuringAlloc);
913			Assert.AreEqual(3, stats.CacheRegions);
914			Assert.LessOrEqual(1048576, stats.CacheSettings.Bytes);
915			Assert.AreEqual(0, stats.CacheSettings.Gigabytes);
916			Assert.AreEqual(3, stats.CacheSettings.NCaches);
917			Assert.AreEqual(0, stats.CleanPages);
918			Assert.AreEqual(0, stats.CleanPagesEvicted);
919			Assert.AreEqual(0, stats.DirtyPages);
920			Assert.AreEqual(0, stats.DirtyPagesEvicted);
921			Assert.IsNotNull(stats.Files);
922			Assert.AreEqual(0, stats.FrozenBuffers);
923			Assert.AreEqual(0, stats.FrozenBuffersFreed);
924			Assert.LessOrEqual(37, stats.HashBuckets);
925			Assert.LessOrEqual(0, stats.HashChainSearches);
926			Assert.AreEqual(0, stats.HashEntriesSearched);
927			Assert.AreEqual(0, stats.HashLockNoWait);
928			Assert.AreEqual(0, stats.HashLockWait);
929			Assert.AreEqual(0, stats.LongestHashChainSearch);
930			Assert.AreEqual(0, stats.MappedPages);
931			Assert.AreEqual(0, stats.MaxBucketsCheckedDuringAlloc);
932			Assert.AreEqual(0, stats.MaxBufferWrites);
933			Assert.AreEqual(0, stats.MaxBufferWritesSleep);
934			Assert.AreEqual(0, stats.MaxHashLockNoWait);
935			Assert.AreEqual(0, stats.MaxHashLockWait);
936			Assert.AreEqual(0, stats.MaxMMapSize);
937			Assert.AreEqual(0, stats.MaxOpenFileDescriptors);
938			Assert.AreEqual(0, stats.MaxPagesCheckedDuringAlloc);
939			Assert.AreEqual(0, stats.PageAllocations);
940			Assert.AreEqual(0, stats.Pages);
941			Assert.AreEqual(0, stats.PagesCheckedDuringAlloc);
942			Assert.LessOrEqual(0, stats.PagesCreatedInCache);
943			Assert.AreEqual(0, stats.PagesInCache);
944			Assert.AreEqual(0, stats.PagesNotInCache);
945			Assert.AreEqual(0, stats.PagesRead);
946			Assert.AreEqual(0, stats.PagesTrickled);
947			Assert.AreEqual(0, stats.PagesWritten);
948			Assert.AreNotEqual(0, stats.RegionLockNoWait);
949			Assert.AreEqual(0, stats.RegionLockWait);
950			Assert.LessOrEqual(0, stats.RegionSize);
951			Assert.AreEqual(0, stats.ThawedBuffers);
952
953			BTreeDatabaseConfig dbConfig = new BTreeDatabaseConfig();
954			dbConfig.Creation = CreatePolicy.IF_NEEDED;
955			dbConfig.Env = env;
956			dbConfig.PageSize = 4096;
957			BTreeDatabase db = BTreeDatabase.Open(
958			    testName + ".db", dbConfig);
959
960			byte[] largeByte = new byte[1088576];
961			for (int i = 0; i < 10; i++)
962				db.Put(new DatabaseEntry(BitConverter.GetBytes(i)),
963				    new DatabaseEntry(largeByte));
964			db.Put(new DatabaseEntry(largeByte), new DatabaseEntry(largeByte));
965
966			db.Close();
967
968			// Clean the stats after printing.
969			stats = env.MPoolSystemStats(true);
970			env.PrintMPoolSystemStats(true, true);
971			stats = env.MPoolSystemStats();
972			env.PrintMPoolSystemStats(true, true, true);
973
974			env.Close();
975		}
976
977		[Test]
978		public void TestRemove()
979		{
980			testName = "TestRemove";
981			testHome = testFixtureHome + "/" + testName;
982
983			Configuration.ClearDir(testHome);
984
985			// Open new environment.
986			DatabaseEnvironmentConfig envConig =
987			    new DatabaseEnvironmentConfig();
988			envConig.Create = true;
989			envConig.ErrorPrefix = testFixtureName + ":" + testName;
990			DatabaseEnvironment env = DatabaseEnvironment.Open(
991			    testHome, envConig);
992			env.Close();
993
994			// Remove the existing environment.
995			DatabaseEnvironment.Remove(testHome);
996
997			// Confirm that the __db.001 is removed.
998			Assert.IsFalse(File.Exists(testHome + "__db.001"));
999		}
1000
1001		[Test]
1002		public void TestRemoveCorruptedEnv()
1003		{
1004			testName = "TestRemoveCorruptedEnv";
1005			testHome = testFixtureHome + "/" + testName;
1006
1007			Configuration.ClearDir(testHome);
1008
1009			// Open new environment.
1010			DatabaseEnvironmentConfig envConig =
1011			    new DatabaseEnvironmentConfig();
1012			envConig.Create = true;
1013			envConig.ErrorPrefix = testFixtureName + ":" + testName;
1014			DatabaseEnvironment env = DatabaseEnvironment.Open(testHome, envConig);
1015
1016			// Panic the environment.
1017			env.Panic();
1018
1019			// Remove the corrupted environment.
1020			DatabaseEnvironment.Remove(testHome, true);
1021
1022			// Confirm that the __db.001 is removed.
1023			Assert.IsFalse(File.Exists(testHome + "__db.001"));
1024		}
1025
1026		[Test, ExpectedException(typeof(ExpectedTestException))]
1027		public void TestRenameDB()
1028		{
1029			testName = "TestRenameDB";
1030			testHome = testFixtureHome + "/" + testName;
1031
1032			RenameDB(testHome, testName, false);
1033		}
1034
1035		[Test, ExpectedException(typeof(ExpectedTestException))]
1036		public void TestRenameDBWithTxn()
1037		{
1038			testName = "TestRenameDBWithTxn";
1039			testHome = testFixtureHome + "/" + testName;
1040
1041			RenameDB(testHome, testName, true);
1042		}
1043
1044		public void RenameDB(string home, string name, bool ifTxn)
1045		{
1046			string dbFileName = name + ".db";
1047			string dbName = "db1";
1048			string dbNewName = "db2";
1049
1050			Configuration.ClearDir(home);
1051
1052			DatabaseEnvironmentConfig envConig =
1053			    new DatabaseEnvironmentConfig();
1054			envConig.Create = true;
1055			envConig.UseTxns = true;
1056			envConig.UseLogging = true;
1057			envConig.UseMPool = true;
1058			DatabaseEnvironment env = DatabaseEnvironment.Open(
1059			    home, envConig);
1060
1061			Transaction openTxn = env.BeginTransaction();
1062			BTreeDatabaseConfig dbConfig =
1063			    new BTreeDatabaseConfig();
1064			dbConfig.Creation = CreatePolicy.IF_NEEDED;
1065			dbConfig.Env = env;
1066			BTreeDatabase db = BTreeDatabase.Open(
1067			    dbFileName, dbName, dbConfig, openTxn);
1068			db.Close();
1069			openTxn.Commit();
1070
1071			// Open the database.
1072			if (ifTxn == false)
1073				env.RenameDB(dbFileName, dbName, dbNewName, true);
1074			else
1075			{
1076				Transaction renameTxn = env.BeginTransaction();
1077				env.RenameDB(dbFileName, dbName, dbNewName, false, renameTxn);
1078				renameTxn.Commit();
1079			}
1080
1081			// Confirm that the database are renamed.
1082			Transaction reopenTxn = env.BeginTransaction();
1083			try
1084			{
1085				Database db1 = Database.Open(
1086				    dbFileName, new DatabaseConfig());
1087				db1.Close();
1088			}
1089			catch (DatabaseException)
1090			{
1091				throw new ExpectedTestException();
1092			}
1093			finally
1094			{
1095				reopenTxn.Commit();
1096				env.Close();
1097			}
1098		}
1099
1100		[Test]
1101		public void TestResetFileID()
1102		{
1103			testName = "TestResetFileID";
1104			testHome = testFixtureHome + "/" + testName;
1105			string dbFileName = testName + ".db";
1106			string dbNewFileName = testName + "_new.db";
1107
1108			Configuration.ClearDir(testHome);
1109
1110			DatabaseEnvironmentConfig envConfig =
1111			    new DatabaseEnvironmentConfig();
1112			envConfig.Create = true;
1113			envConfig.UseMPool = true;
1114			DatabaseEnvironment env = DatabaseEnvironment.Open(
1115			    testHome, envConfig);
1116
1117			// Opening a new database.
1118			BTreeDatabaseConfig dbConfig =
1119			    new BTreeDatabaseConfig();
1120			dbConfig.Creation = CreatePolicy.IF_NEEDED;
1121			dbConfig.Env = env;
1122			BTreeDatabase db = BTreeDatabase.Open(
1123			    dbFileName, dbConfig);
1124			db.Close();
1125
1126			// Copy the physical database file.
1127			File.Copy(testHome + "/" + dbFileName,
1128			    testHome + "/" + dbNewFileName);
1129
1130			// Reset the file ID.
1131			env.ResetFileID(dbNewFileName, false);
1132
1133			// Open the exisiting database in copied database file.
1134			BTreeDatabaseConfig cfg = new BTreeDatabaseConfig();
1135			cfg.Creation = CreatePolicy.NEVER;
1136			cfg.Env = env;
1137			BTreeDatabase newDB = BTreeDatabase.Open(
1138			    dbNewFileName, cfg);
1139			newDB.Close();
1140			env.Close();
1141		}
1142
1143		[Test, ExpectedException(typeof(ExpectedTestException))]
1144		public void TestRemoveDB()
1145		{
1146			testName = "TestRemoveDB";
1147			testHome = testFixtureHome + "/" + testName;
1148
1149			Configuration.ClearDir(testHome);
1150
1151			RmDBWithoutTxn(testHome, testName, false);
1152		}
1153
1154		[Test, ExpectedException(typeof(ExpectedTestException))]
1155		public void TestRemoveDBWithAutoCommit()
1156		{
1157			testName = "TestRemoveDBWithAutoCommit";
1158			testHome = testFixtureHome + "/" + testName;
1159
1160			Configuration.ClearDir(testHome);
1161
1162			RmDBWithoutTxn(testHome, testName, true);
1163		}
1164
1165		[Test, ExpectedException(typeof(ExpectedTestException))]
1166		public void TestRemoveDBWithinTxn()
1167		{
1168			testName = "TestRemoveDBWithinTxn";
1169			testHome = testFixtureHome + "/" + testName;
1170			string dbFileName = testName + ".db";
1171			string dbName1 = testName + "1";
1172			string dbName2 = testName + "2";
1173
1174			Configuration.ClearDir(testHome);
1175
1176			// Open environment.
1177			DatabaseEnvironmentConfig envConfig =
1178			    new DatabaseEnvironmentConfig();
1179			envConfig.Create = true;
1180			envConfig.UseMPool = true;
1181			envConfig.UseTxns = true;
1182			envConfig.UseLogging = true;
1183			DatabaseEnvironment env = DatabaseEnvironment.Open(
1184			    testHome, envConfig);
1185			Transaction txn = env.BeginTransaction();
1186
1187			// Create two databases in the environment.
1188			BTreeDatabaseConfig dbConfig =
1189			    new BTreeDatabaseConfig();
1190			dbConfig.Creation = CreatePolicy.IF_NEEDED;
1191			dbConfig.Env = env;
1192			BTreeDatabase btreeDB1 = BTreeDatabase.Open(
1193			    dbFileName, dbName1, dbConfig, txn);
1194			btreeDB1.Close();
1195			BTreeDatabase btreeDB2 = BTreeDatabase.Open(
1196			    dbFileName, dbName2, dbConfig, txn);
1197			btreeDB2.Close();
1198
1199			// Remove one database from the environment.
1200			env.RemoveDB(dbFileName, dbName2, false, txn);
1201
1202			// Try to open the existing database.
1203			DatabaseConfig cfg = new DatabaseConfig();
1204			cfg.Env = env;
1205			Database db1 = Database.Open(dbFileName, dbName1, cfg, txn);
1206			db1.Close();
1207
1208			/*
1209			 * Attempting to open the removed database should
1210			 * cause error.
1211			 */
1212			try
1213			{
1214				Database db2 = Database.Open(
1215				    dbFileName, dbName2, cfg, txn);
1216				db2.Close();
1217			}
1218			catch (DatabaseException)
1219			{
1220				throw new ExpectedTestException();
1221			}
1222			finally
1223			{
1224				txn.Commit();
1225				env.Close();
1226			}
1227		}
1228
1229		public void RmDBWithoutTxn(string home, string dbName,
1230		    bool ifAutoCommit)
1231		{
1232			string dbFileName = dbName + ".db";
1233			string dbName1 = dbName + "1";
1234			string dbName2 = dbName + "2";
1235
1236			// Open environment.
1237			DatabaseEnvironmentConfig envConfig =
1238			    new DatabaseEnvironmentConfig();
1239			envConfig.Create = true;
1240			envConfig.UseMPool = true;
1241			if (ifAutoCommit == true)
1242			{
1243				envConfig.AutoCommit = true;
1244				envConfig.UseTxns = true;
1245			}
1246
1247			DatabaseEnvironment env = DatabaseEnvironment.Open(
1248			    home, envConfig);
1249
1250			// Create two databases in the environment.
1251			BTreeDatabaseConfig dbConfig =
1252			    new BTreeDatabaseConfig();
1253			dbConfig.Creation = CreatePolicy.IF_NEEDED;
1254			dbConfig.Env = env;
1255			BTreeDatabase btreeDB1 = BTreeDatabase.Open(
1256			    dbFileName, dbName1, dbConfig);
1257			btreeDB1.Close();
1258			BTreeDatabase btreeDB2 = BTreeDatabase.Open(
1259			    dbFileName, dbName2, dbConfig);
1260			btreeDB2.Close();
1261
1262			// Remove one database from the environment.
1263			env.RemoveDB(dbFileName, dbName2, false);
1264
1265			// Try to open the existing database.
1266			DatabaseConfig cfg = new DatabaseConfig();
1267			cfg.Env = env;
1268			Database db1 = Database.Open(dbFileName, dbName1, cfg);
1269			db1.Close();
1270
1271			/*
1272			 * Attempting to open the removed database should
1273			 * cause error.
1274			 */
1275			try
1276			{
1277				Database db2 = Database.Open(
1278				    dbFileName, dbName2, cfg);
1279				db2.Close();
1280			}
1281			catch (DatabaseException)
1282			{
1283				throw new ExpectedTestException();
1284			}
1285			finally
1286			{
1287				env.Close();
1288			}
1289		}
1290
1291
1292		[Test]
1293		public void TestTransactionSystemStats()
1294		{
1295			testName = "TestTransactionSystemStats";
1296			testHome = testFixtureHome + "/" + testName;
1297
1298			Configuration.ClearDir(testHome);
1299
1300			TransactionStats stats;
1301			BTreeDatabase db;
1302			Transaction openTxn = null;
1303
1304			// Open an environment.
1305			long dateTime;
1306			DatabaseEnvironmentConfig envConfig =
1307			    new DatabaseEnvironmentConfig();
1308			envConfig.Create = true;
1309			envConfig.MaxTransactions = 50;
1310			envConfig.UseLogging = true;
1311			envConfig.UseMPool = true;
1312			envConfig.UseTxns = true;
1313			envConfig.TxnNoSync = false;
1314			envConfig.TxnNoWait = true;
1315			envConfig.TxnSnapshot = true;
1316			envConfig.TxnTimestamp = DateTime.Now;
1317			envConfig.TxnWriteNoSync = false;
1318			DatabaseEnvironment env = DatabaseEnvironment.Open(
1319			    testHome, envConfig);
1320
1321			try
1322			{
1323				try
1324				{
1325					// Confirm initial transaction subsystem statistics.
1326					stats = env.TransactionSystemStats();
1327					env.PrintTransactionSystemStats(true, true);
1328					Assert.AreEqual(0, stats.Aborted);
1329					Assert.AreEqual(0, stats.Active);
1330					Assert.AreEqual(0, stats.Begun);
1331					Assert.AreEqual(0, stats.Committed);
1332					Assert.AreEqual(0, stats.LastCheckpoint.LogFileNumber);
1333					Assert.AreEqual(0, stats.LastCheckpoint.Offset);
1334					Assert.AreEqual(50, stats.MaxTransactions);
1335					Assert.AreNotEqual(0, stats.RegionSize);
1336					Assert.AreEqual(0, stats.Transactions.Count);
1337				}
1338				catch (AssertionException e)
1339				{
1340					throw e;
1341				}
1342
1343				try
1344				{
1345					//Begin a transaction called openTxn and open a database.
1346					TransactionConfig openTxnCfg = new TransactionConfig();
1347					openTxnCfg.Name = "openTxn";
1348					openTxn = env.BeginTransaction(openTxnCfg);
1349					BTreeDatabaseConfig dbConfig = new BTreeDatabaseConfig();
1350					dbConfig.Creation = CreatePolicy.IF_NEEDED;
1351					dbConfig.Env = env;
1352					db = BTreeDatabase.Open(testName + ".db", dbConfig, openTxn);
1353				}
1354				catch (DatabaseException e)
1355				{
1356					if (openTxn != null)
1357						openTxn.Abort();
1358					throw e;
1359				}
1360
1361				try
1362				{
1363					// At least there is one transaction that is alive.
1364					env.Checkpoint();
1365					stats = env.TransactionSystemStats();
1366					env.PrintTransactionSystemStats();
1367					Assert.AreNotEqual(0, stats.Active);
1368					Assert.AreNotEqual(0, stats.Transactions.Count);
1369					Assert.AreNotEqual(0, stats.Transactions.Capacity);
1370					Assert.AreNotEqual(0, stats.RegionLockNoWait);
1371					dateTime = stats.LastCheckpointTime;
1372
1373					// Begin an embedded transaction called putTxn.
1374					TransactionConfig putTxnCfg =
1375					    new TransactionConfig();
1376					putTxnCfg.Name = "putTxn";
1377					putTxnCfg.NoWait = false;
1378					Transaction putTxn = env.BeginTransaction(
1379					    putTxnCfg, openTxn);
1380
1381					try
1382					{
1383						// Put some records into database within putTxn.
1384						for (int i = 0; i < 50; i++)
1385							db.Put(new DatabaseEntry(BitConverter.GetBytes(i)),
1386							    new DatabaseEntry(BitConverter.GetBytes(i)), putTxn);
1387							stats = env.TransactionSystemStats();
1388							Assert.AreNotEqual(0, stats.MaxActive);
1389							Assert.AreNotEqual(0, stats.MaxTransactions);
1390							Assert.AreEqual(0, stats.MaxSnapshot);
1391							Assert.AreEqual(0, stats.Snapshot);
1392							Assert.AreEqual(stats.Begun,
1393							    stats.Aborted + stats.Active + stats.Committed);
1394							Assert.AreEqual(2, stats.Transactions.Count);
1395
1396						/*
1397						 * Both of LogFileNumber and Offset in active transaction
1398						 * couldn't be 0.
1399						 */
1400						uint logFileNumbers = 0;
1401						uint offSets = 0;
1402						for (int i = 0; i < stats.Transactions.Count;i++)
1403						{
1404							logFileNumbers += stats.Transactions[i].Begun.LogFileNumber;
1405							offSets += stats.Transactions[i].Begun.Offset;
1406						}
1407						Assert.AreNotEqual(0, logFileNumbers);
1408						Assert.AreNotEqual(0, offSets);
1409
1410						// All active transactions are run by the same process and thread.
1411
1412						Assert.AreEqual(stats.Transactions[0].ThreadID,
1413						    stats.Transactions[1].ThreadID);
1414						Assert.AreEqual(stats.Transactions[0].ProcessID,
1415						    stats.Transactions[1].ProcessID);
1416
1417						// All transactions are alive.
1418						Assert.AreEqual(ActiveTransaction.TransactionStatus.RUNNING,
1419						    stats.Transactions[0].Status);
1420						Assert.AreEqual(ActiveTransaction.TransactionStatus.RUNNING,
1421						    stats.Transactions[1].Status);
1422
1423						/*
1424						 * Find the openTxn in active transactions, which is the
1425						 * parent transaction of putTxn.
1426						 */
1427						int parentPos = 0;
1428						if (stats.Transactions[0].Name == "putTxn")
1429							parentPos = 1;
1430
1431						// putTxn's parent id should be the openTxn.
1432						Assert.AreEqual(stats.Transactions[parentPos].ID,
1433						    stats.Transactions[1 - parentPos].ParentID);
1434
1435						// Other stats should be an positive integer.
1436						for (int i = 0; i < stats.Transactions.Count - 1; i++)
1437						{
1438							Assert.LessOrEqual(0,
1439							    stats.Transactions[i].BufferCopiesInCache);
1440							Assert.LessOrEqual(0,
1441							    stats.Transactions[i].SnapshotReads.LogFileNumber);
1442							Assert.LessOrEqual(0,
1443							    stats.Transactions[i].SnapshotReads.Offset);
1444							Assert.IsNotNull(stats.Transactions[i].GlobalID);
1445						}
1446
1447						// Commit putTxn.
1448						putTxn.Commit();
1449					}
1450					catch (DatabaseException e)
1451					{
1452						putTxn.Abort();
1453						throw e;
1454					}
1455
1456					stats = env.TransactionSystemStats();
1457					Assert.AreNotEqual(0, stats.LastCheckpoint.LogFileNumber);
1458					Assert.AreNotEqual(0, stats.LastCheckpoint.Offset);
1459					Assert.AreEqual(dateTime, stats.LastCheckpointTime);
1460
1461					openTxn.Commit();
1462				}
1463				catch (DatabaseException e)
1464				{
1465					openTxn.Abort();
1466					throw e;
1467				}
1468				finally
1469				{
1470					db.Close();
1471				}
1472			}
1473			finally
1474			{
1475				env.Close();
1476			}
1477		}
1478
1479		/*
1480		 * Configure an environment. Here only configure those that could be
1481		 * set before environment open.
1482		 */
1483		public void Config(XmlElement xmlElem,
1484		    ref DatabaseEnvironmentConfig envConfig, bool compulsory,
1485		    bool logging, bool locking, bool mutex, bool mpool, bool replication)
1486		{
1487			XmlNode childNode;
1488
1489			// Configure environment without any subsystems.
1490			DatabaseEnvironmentConfigTest.Config(xmlElem, ref envConfig, compulsory);
1491
1492			// Configure environment with logging subsystem.
1493			if (logging == true)
1494			{
1495				childNode = XMLReader.GetNode(xmlElem, "LogConfig");
1496				envConfig.LogSystemCfg = new LogConfig();
1497				LogConfigTest.Config((XmlElement)childNode,
1498				    ref envConfig.LogSystemCfg, compulsory);
1499			}
1500
1501			// Configure environment with locking subsystem.
1502			if (locking == true)
1503			{
1504				childNode = XMLReader.GetNode(xmlElem, "LockingConfig");
1505				envConfig.LockSystemCfg = new LockingConfig();
1506				LockingConfigTest.Config((XmlElement)childNode,
1507				    ref envConfig.LockSystemCfg, compulsory);
1508			}
1509
1510			// Configure environment with mutex subsystem.
1511			if (mutex == true)
1512			{
1513				childNode = XMLReader.GetNode(xmlElem, "MutexConfig");
1514				envConfig.MutexSystemCfg = new MutexConfig();
1515				MutexConfigTest.Config((XmlElement)childNode,
1516				    ref envConfig.MutexSystemCfg, compulsory);
1517			}
1518
1519			if (mpool == true)
1520			{
1521				childNode = XMLReader.GetNode(xmlElem, "MPoolConfig");
1522				envConfig.MPoolSystemCfg = new MPoolConfig();
1523				MPoolConfigTest.Config((XmlElement)childNode,
1524				    ref envConfig.MPoolSystemCfg, compulsory);
1525			}
1526
1527			// Configure environment with replication.
1528			if (replication == true)
1529			{
1530				childNode = XMLReader.GetNode(xmlElem, "ReplicationConfig");
1531				envConfig.RepSystemCfg = new ReplicationConfig();
1532				ReplicationConfigTest.Config((XmlElement)childNode,
1533				    ref envConfig.RepSystemCfg, compulsory);
1534			}
1535		}
1536
1537		/*
1538		 * Confirm the fields/properties in the environment.
1539		 * Those set by setting functions are not checked here.
1540		 */
1541		public static void Confirm(XmlElement xmlElement,
1542		    DatabaseEnvironment env, bool compulsory,
1543		    bool logging, bool locking, bool mutex, bool mpool,
1544		    bool replication)
1545		{
1546			XmlElement childElem;
1547			CacheInfo cacheInfo = new CacheInfo(0, 0, 0);
1548
1549			// Confirm environment configuration.
1550			Configuration.ConfirmBool(xmlElement, "AutoCommit",
1551			    env.AutoCommit, compulsory);
1552			Configuration.ConfirmBool(xmlElement, "CDB_ALLDB",
1553			    env.CDB_ALLDB, compulsory);
1554			Configuration.ConfirmBool(xmlElement, "Create",
1555			    env.Create, compulsory);
1556			Configuration.ConfirmStringList(xmlElement, "DataDirs",
1557			    env.DataDirs, compulsory);
1558			Configuration.ConfirmString(xmlElement, "ErrorPrefix",
1559			    env.ErrorPrefix, compulsory);
1560			Configuration.ConfirmBool(xmlElement, "ForceFlush",
1561			    env.ForceFlush, compulsory);
1562			Configuration.ConfirmBool(xmlElement, "FreeThreaded",
1563			    env.FreeThreaded, compulsory);
1564			Configuration.ConfirmBool(xmlElement, "InitRegions",
1565			    env.InitRegions, compulsory);
1566			Configuration.ConfirmString(xmlElement, "IntermediateDirMode",
1567			    env.IntermediateDirMode, compulsory);
1568			Configuration.ConfirmBool(xmlElement, "Lockdown",
1569			    env.Lockdown, compulsory);
1570			Configuration.ConfirmUint(xmlElement, "LockTimeout",
1571			    env.LockTimeout, compulsory);
1572			Configuration.ConfirmUint(xmlElement, "MaxTransactions",
1573			    env.MaxTransactions, compulsory);
1574			Configuration.ConfirmBool(xmlElement, "NoBuffer",
1575			    env.NoBuffer, compulsory);
1576			Configuration.ConfirmBool(xmlElement, "NoLocking",
1577			    env.NoLocking, compulsory);
1578			Configuration.ConfirmBool(xmlElement, "NoMMap",
1579			    env.NoMMap, compulsory);
1580			Configuration.ConfirmBool(xmlElement, "NoPanic",
1581			    env.NoPanic, compulsory);
1582			Configuration.ConfirmBool(xmlElement, "Overwrite",
1583			    env.Overwrite, compulsory);
1584			Configuration.ConfirmBool(xmlElement, "Private",
1585			    env.Private, compulsory);
1586			Configuration.ConfirmBool(xmlElement, "Register",
1587			    env.Register, compulsory);
1588			Configuration.ConfirmBool(xmlElement, "RunFatalRecovery",
1589			    env.RunFatalRecovery, compulsory);
1590			Configuration.ConfirmBool(xmlElement, "RunRecovery",
1591			    env.RunRecovery, compulsory);
1592			Configuration.ConfirmBool(xmlElement, "SystemMemory",
1593			    env.SystemMemory, compulsory);
1594			Configuration.ConfirmString(xmlElement, "TempDir",
1595			    env.TempDir, compulsory);
1596			Configuration.ConfirmBool(xmlElement, "TimeNotGranted",
1597			    env.TimeNotGranted, compulsory);
1598			Configuration.ConfirmBool(xmlElement, "TxnNoSync",
1599			    env.TxnNoSync, compulsory);
1600			Configuration.ConfirmBool(xmlElement, "TxnNoWait",
1601			    env.TxnNoWait, compulsory);
1602			Configuration.ConfirmBool(xmlElement, "TxnSnapshot",
1603			    env.TxnSnapshot, compulsory);
1604			Configuration.ConfirmDateTime(xmlElement, "TxnTimestamp",
1605			    env.TxnTimestamp, compulsory);
1606			Configuration.ConfirmBool(xmlElement, "TxnWriteNoSync",
1607			    env.TxnWriteNoSync, compulsory);
1608			Configuration.ConfirmBool(xmlElement, "UseMVCC",
1609			    env.UseMVCC, compulsory);
1610			Configuration.ConfirmBool(xmlElement, "UseCDB",
1611			    env.UsingCDB, compulsory);
1612			Configuration.ConfirmBool(xmlElement, "UseLocking",
1613			    env.UsingLocking, compulsory);
1614			Configuration.ConfirmBool(xmlElement, "UseLogging",
1615			    env.UsingLogging, compulsory);
1616			Configuration.ConfirmBool(xmlElement, "UseMPool",
1617			    env.UsingMPool, compulsory);
1618			Configuration.ConfirmBool(xmlElement, "UseReplication",
1619			    env.UsingReplication, compulsory);
1620			Configuration.ConfirmBool(xmlElement, "UseTxns",
1621			    env.UsingTxns, compulsory);
1622			env.Verbosity = new VerboseMessages();
1623			Configuration.ConfirmVerboseMessages(xmlElement,
1624			    "Verbosity", env.Verbosity, compulsory);
1625			Configuration.ConfirmBool(xmlElement, "YieldCPU",
1626			    env.YieldCPU, compulsory);
1627
1628			/*
1629			 * If the locking subsystem is set, check the
1630			 * field/properties set in LockingConfig.
1631			 */
1632			if (locking == true)
1633			{
1634				childElem = (XmlElement)XMLReader.GetNode(
1635				    xmlElement, "LockingConfig");
1636				Configuration.ConfirmByteMatrix(childElem,
1637				    "Conflicts", env.LockConflictMatrix,
1638				    compulsory);
1639				Configuration.ConfirmDeadlockPolicy(
1640				    childElem, "DeadlockResolution",
1641				    env.DeadlockResolution, compulsory);
1642				Configuration.ConfirmUint(childElem,
1643				    "Partitions", env.LockPartitions,
1644				    compulsory);
1645				Configuration.ConfirmUint(childElem,
1646				    "MaxLockers", env.MaxLockers, compulsory);
1647				Configuration.ConfirmUint(childElem,
1648				    "MaxLocks", env.MaxLocks, compulsory);
1649				Configuration.ConfirmUint(childElem,
1650				    "MaxObjects", env.MaxObjects, compulsory);
1651			}
1652
1653			/*
1654			 * If the locking subsystem is set, check the
1655			 * field/properties set in LogConfig.
1656			 */
1657			if (logging == true)
1658			{
1659				childElem = (XmlElement)XMLReader.GetNode(
1660				    xmlElement, "LogConfig");
1661				Configuration.ConfirmBool(childElem,
1662				    "AutoRemove", env.LogAutoRemove,
1663				    compulsory);
1664				Configuration.ConfirmUint(childElem,
1665				    "BufferSize", env.LogBufferSize,
1666				    compulsory);
1667				Configuration.ConfirmString(childElem,
1668				    "Dir", env.LogDir, compulsory);
1669				Configuration.ConfirmInt(childElem,
1670				    "FileMode", env.LogFileMode, compulsory);
1671				Configuration.ConfirmBool(childElem,
1672				    "ForceSync", env.LogForceSync, compulsory);
1673				Configuration.ConfirmBool(childElem,
1674				    "InMemory", env.LogInMemory, compulsory);
1675				Configuration.ConfirmBool(childElem,
1676				    "NoBuffer", env.LogNoBuffer, compulsory);
1677				Configuration.ConfirmUint(childElem,
1678				    "RegionSize", env.LogRegionSize,
1679				    compulsory);
1680				Configuration.ConfirmBool(childElem,
1681				    "ZeroOnCreate", env.LogZeroOnCreate,
1682				    compulsory);
1683				Configuration.ConfirmUint(childElem,
1684				    "MaxFileSize", env.MaxLogFileSize,
1685				    compulsory);
1686			}
1687
1688			/*
1689			 * If the locking subsystem is set, check the
1690			 * field/properties set in MutexConfig.
1691			 */
1692			if (mutex == true)
1693			{
1694				childElem = (XmlElement)XMLReader.GetNode(
1695				    xmlElement, "MutexConfig");
1696				Configuration.ConfirmUint(childElem,
1697				    "Alignment", env.MutexAlignment,
1698				    compulsory);
1699				Configuration.ConfirmUint(childElem,
1700				    "MaxMutexes", env.MaxMutexes, compulsory);
1701				try
1702				{
1703					Configuration.ConfirmUint(childElem,
1704					    "Increment", env.MutexIncrement,
1705					    compulsory);
1706				}
1707				catch (AssertionException)
1708				{
1709					Assert.AreEqual(0, env.MutexIncrement);
1710				}
1711
1712				Configuration.ConfirmUint(childElem,
1713				    "NumTestAndSetSpins",
1714				    env.NumTestAndSetSpins, compulsory);
1715			}
1716
1717			if (mpool == true)
1718			{
1719				childElem = (XmlElement)XMLReader.GetNode(
1720				    xmlElement, "MPoolConfig");
1721				Configuration.ConfirmCacheSize(childElem,
1722				    "CacheSize", env.CacheSize, compulsory);
1723				if (env.UsingMPool == false)
1724					Configuration.ConfirmCacheSize(childElem,
1725					    "MaxCacheSize", env.MaxCacheSize, compulsory);
1726				Configuration.ConfirmInt(childElem,
1727				    "MaxOpenFiles", env.MaxOpenFiles, compulsory);
1728				Configuration.ConfirmMaxSequentialWrites(childElem,
1729				    "MaxSequentialWrites", env.SequentialWritePause,
1730				    env.MaxSequentialWrites, compulsory);
1731				Configuration.ConfirmUint(childElem,
1732				    "MMapSize", env.MMapSize, compulsory);
1733			}
1734
1735			if (replication == true)
1736			{
1737				childElem = (XmlElement)XMLReader.GetNode(
1738				    xmlElement, "ReplicationConfig");
1739				Configuration.ConfirmUint(childElem,
1740				    "AckTimeout", env.RepAckTimeout, compulsory);
1741				Configuration.ConfirmBool(childElem,
1742				    "BulkTransfer", env.RepBulkTransfer, compulsory);
1743				Configuration.ConfirmUint(childElem,
1744				    "CheckpointDelay", env.RepCheckpointDelay, compulsory);
1745				Configuration.ConfirmUint(childElem,
1746				    "ConnectionRetry", env.RepConnectionRetry, compulsory);
1747				Configuration.ConfirmBool(childElem,
1748				    "DelayClientSync", env.RepDelayClientSync, compulsory);
1749				Configuration.ConfirmUint(childElem,
1750				    "ElectionRetry", env.RepElectionRetry, compulsory);
1751				Configuration.ConfirmUint(childElem,
1752				    "ElectionTimeout", env.RepElectionTimeout, compulsory);
1753				Configuration.ConfirmUint(childElem,
1754				    "FullElectionTimeout", env.RepFullElectionTimeout,compulsory);
1755				Configuration.ConfirmUint(childElem,
1756				    "HeartbeatMonitor", env.RepHeartbeatMonitor, compulsory);
1757				Configuration.ConfirmUint(childElem,
1758				    "HeartbeatSend", env.RepHeartbeatSend, compulsory);
1759				Configuration.ConfirmUint(childElem,
1760				    "LeaseTimeout", env.RepLeaseTimeout, compulsory);
1761				Configuration.ConfirmBool(childElem,
1762				    "NoAutoInit", env.RepNoAutoInit, compulsory);
1763				Configuration.ConfirmBool(childElem,
1764				    "NoBlocking", env.RepNoBlocking, compulsory);
1765				Configuration.ConfirmUint(childElem,
1766				    "NSites", env.RepNSites, compulsory);
1767				Configuration.ConfirmUint(childElem,
1768				    "Priority", env.RepPriority, compulsory);
1769				Configuration.ConfirmAckPolicy(childElem,
1770				    "RepMgrAckPolicy", env.RepMgrAckPolicy, compulsory);
1771				Configuration.ConfirmBool(childElem,
1772				    "Strict2Site", env.RepStrict2Site, compulsory);
1773				Configuration.ConfirmBool(childElem,
1774				    "UseMasterLeases", env.RepUseMasterLeases, compulsory);
1775			}
1776		}
1777	}
1778}
1779