/*- * See the file LICENSE for redistribution information. * * Copyright (c) 2010, 2015 Oracle and/or its affiliates. All rights reserved. * */ using System; using System.Collections.Generic; using System.Text; using System.Threading; using NUnit.Framework; using BerkeleyDB; namespace CsharpAPITest { [TestFixture] public class TransactionCommitTokenTest : CSharpTestFixture { private uint masterPort; private uint clientPort; private string ip = "127.0.0.1"; [TestFixtureSetUp] public void SetUpTestFixture() { testFixtureName = "TransactionCommitTokenTest"; base.SetUpTestfixture(); ReplicationTest.AvailablePorts portGen = new ReplicationTest.AvailablePorts(); masterPort = portGen.Current; portGen.MoveNext(); clientPort = portGen.Current; } public DatabaseEnvironment SetUpEnv(String home, uint priority, uint port, bool isMaster) { try { Configuration.ClearDir(home); } catch (Exception e) { Console.WriteLine(e.Message); throw new TestException("Please clean the directory"); } /* Configure and open environment with replication * application. */ DatabaseEnvironmentConfig cfg = new DatabaseEnvironmentConfig(); cfg.UseReplication = true; cfg.MPoolSystemCfg = new MPoolConfig(); cfg.MPoolSystemCfg.CacheSize = new CacheInfo(0, 20485760, 1); cfg.UseLocking = true; cfg.UseTxns = true; cfg.UseMPool = true; cfg.Create = true; cfg.UseLogging = true; cfg.RunRecovery = true; cfg.TxnNoSync = true; cfg.FreeThreaded = true; cfg.RepSystemCfg = new ReplicationConfig(); DbSiteConfig dbSiteConfig = new DbSiteConfig(); dbSiteConfig.Host = ip; dbSiteConfig.Port = port; dbSiteConfig.LocalSite = true; cfg.RepSystemCfg.RepmgrSitesConfig.Add(dbSiteConfig); cfg.RepSystemCfg.Priority = priority; if (!isMaster) { DbSiteConfig dbSiteConfig1 = new DbSiteConfig(); dbSiteConfig1.Host = ip; dbSiteConfig1.Port = masterPort; dbSiteConfig1.Helper = true; cfg.RepSystemCfg.RepmgrSitesConfig.Add(dbSiteConfig1); } cfg.RepSystemCfg.BulkTransfer = false; cfg.RepSystemCfg.AckTimeout = 5000; cfg.RepSystemCfg.RepMgrAckPolicy = AckPolicy.ALL_PEERS; DatabaseEnvironment env = DatabaseEnvironment.Open( home, cfg); return env; } public BTreeDatabase Open(DatabaseEnvironment env, bool isMaster) { string dbName = "rep.db"; // Set up the database. BTreeDatabaseConfig dbCfg = new BTreeDatabaseConfig(); dbCfg.Env = env; if (isMaster) dbCfg.Creation = CreatePolicy.IF_NEEDED; dbCfg.AutoCommit = true; dbCfg.FreeThreaded = true; /* * Open the database. Do not provide a txn handle. This * Open is autocommitted because BTreeDatabaseConfig.AutoCommit * is true. */ return BTreeDatabase.Open(dbName, dbCfg); } [Test] public void TestCommitSuccess() { testName = "TestCommitSuccess"; SetUpTest(true); string[] keys = {"key 1", "key 2", "key 3", "key 4", "key 5", "key 6", "key 7", "key 8", "key 9", "key 10"}; DatabaseEnvironment master = SetUpEnv(testHome + "/master", 100, masterPort, true); DatabaseEnvironment client = SetUpEnv(testHome + "/client", 0, clientPort, false); master.RepMgrStartMaster(2); Thread.Sleep(2000); client.RepMgrStartClient(2); BTreeDatabase db1 = Open(master, true); BTreeDatabase db2 = null; for (; ; ) { if (db2 == null) try { db2 = Open(client, false); break; } catch (DatabaseException) { if (db2 != null) { db2.Close(true); db2 = null; } System.Threading.Thread.Sleep(1000); continue; } } try { for (int i = 0; i < 3; i++) { Transaction txn = master.BeginTransaction(); // Get the key. DatabaseEntry key, data; key = new DatabaseEntry( ASCIIEncoding.ASCII.GetBytes(keys[i])); data = new DatabaseEntry( ASCIIEncoding.ASCII.GetBytes(keys[i])); db1.Put(key, data, txn); txn.Commit(); byte[] token = txn.CommitToken; Assert.AreEqual(master.IsTransactionApplied(token, 5000), TransactionAppliedStatus.APPLIED); Assert.AreEqual(client.IsTransactionApplied(token, 200000), TransactionAppliedStatus.APPLIED); } } finally { db1.Close(); db2.Close(); master.Close(); client.Close(); } } [Test] public void TestNullArgument() { testName = "TestNullArgument"; SetUpTest(true); DatabaseEnvironment master = SetUpEnv(testHome + "/master", 100, 8000, true); Assert.Throws( delegate { master.IsTransactionApplied(null, 0); }); master.Close(); } [Test] public void TestValidArgument() { testName = "TestValidArgument"; SetUpTest(true); DatabaseEnvironment master = SetUpEnv(testHome + "/master", 100, 8000, true); Assert.Throws( delegate { master.IsTransactionApplied(new byte[10], 0); }); master.Close(); } [Test] public void TestEmptyException() { testName = "TestEmptyException"; SetUpTest(true); DatabaseEnvironment master = SetUpEnv(testHome + "/master", 100, 8000, true); Transaction txn = master.BeginTransaction(); txn.Commit(); byte[] token = txn.CommitToken; Assert.AreEqual(TransactionAppliedStatus.EMPTY_TRANSACTION, master.IsTransactionApplied(token, 1000)); master.Close(); } [Test] public void TestInvalidToken() { testName = "TestInvalidToken"; SetUpTest(true); DatabaseEntry key, data; DatabaseEnvironment master = SetUpEnv(testHome + "/master", 100, 8000, true); BTreeDatabase db = Open(master,true); Transaction txn = master.BeginTransaction(); key = new DatabaseEntry( ASCIIEncoding.ASCII.GetBytes("Key")); data = new DatabaseEntry( ASCIIEncoding.ASCII.GetBytes("Data")); db.Put(key, data, txn); txn.Commit(); byte[] token = txn.CommitToken; token[19] += 123; Assert.Throws(delegate { master.IsTransactionApplied(token, 1000); }); db.Close(); master.Close(); } [Test] public void TestOperationOrder() { testName = "TestOperationOrder"; SetUpTest(true); DatabaseEnvironment master = SetUpEnv(testHome + "/master", 100, 8000, true); Transaction txn = master.BeginTransaction(); txn.Abort(); byte[] token; Assert.Throws(delegate { token = txn.CommitToken; }); master.Close(); } [Test] public void TestNestedTXN() { testName = "TestNestedTXN"; SetUpTest(true); DatabaseEntry key, data; DatabaseEnvironment master = SetUpEnv(testHome + "/master", 100, 8000, true); BTreeDatabase db = Open(master, true); TransactionConfig txnconfig = new TransactionConfig(); Transaction txn = master.BeginTransaction(); Transaction txn1 = master.BeginTransaction(txnconfig, txn); key = new DatabaseEntry( ASCIIEncoding.ASCII.GetBytes("Key")); data = new DatabaseEntry( ASCIIEncoding.ASCII.GetBytes("Data")); db.Put(key, data, txn1); txn1.Commit(); txn.Commit(); byte[] token; Assert.Throws(delegate { token = txn1.CommitToken; }); master.Close(); } } }