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