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.IO;
11using System.Text;
12using System.Xml;
13using NUnit.Framework;
14using BerkeleyDB;
15
16namespace CsharpAPITest
17{
18	[TestFixture]
19	public class LogConfigTest
20	{
21		private string testFixtureHome;
22		private string testFixtureName;
23		private string testName;
24		private string testHome;
25
26		[TestFixtureSetUp]
27		public void RunBeforeTests()
28		{
29			testFixtureName = "LogConfigTest";
30			testFixtureHome = "./TestOut/" + testFixtureName;
31			Configuration.ClearDir(testFixtureHome);
32		}
33
34		[Test]
35		public void TestConfig()
36		{
37			testName = "TestConfig";
38			/*
39			 * Configure the fields/properties and see if
40			 * they are updated successfully.
41			 */
42			LogConfig logConfig = new LogConfig();
43			XmlElement xmlElem = Configuration.TestSetUp(testFixtureName, testName);
44			Config(xmlElem, ref logConfig, true);
45			Confirm(xmlElem, logConfig, true);
46		}
47
48		[Test, ExpectedException(typeof(ExpectedTestException))]
49		public void TestFullLogBufferException()
50		{
51			testName = "TestFullLogBufferException";
52			testHome = testFixtureHome + "/" + testName;
53
54			Configuration.ClearDir(testHome);
55
56			// Open an environment and configured log subsystem.
57			DatabaseEnvironmentConfig cfg =
58			    new DatabaseEnvironmentConfig();
59			cfg.Create = true;
60			cfg.TxnNoSync = true;
61			cfg.UseTxns = true;
62			cfg.UseLocking = true;
63			cfg.UseMPool = true;
64			cfg.UseLogging = true;
65			cfg.LogSystemCfg = new LogConfig();
66			cfg.LogSystemCfg.AutoRemove = false;
67			cfg.LogSystemCfg.BufferSize = 409600;
68			cfg.LogSystemCfg.MaxFileSize = 10480;
69			cfg.LogSystemCfg.NoBuffer = false;
70			cfg.LogSystemCfg.ZeroOnCreate = true;
71			cfg.LogSystemCfg.InMemory = true;
72			DatabaseEnvironment env = DatabaseEnvironment.Open(testHome, cfg);
73
74			BTreeDatabase db;
75			try
76			{
77				Transaction openTxn = env.BeginTransaction();
78				try
79				{
80					BTreeDatabaseConfig dbConfig =
81					    new BTreeDatabaseConfig();
82					dbConfig.Creation = CreatePolicy.IF_NEEDED;
83					dbConfig.Env = env;
84					db = BTreeDatabase.Open(testName + ".db", dbConfig, openTxn);
85					openTxn.Commit();
86				}
87				catch (DatabaseException e)
88				{
89					openTxn.Abort();
90					throw e;
91				}
92
93				Transaction writeTxn = env.BeginTransaction();
94				try
95				{
96					/*
97					 * Writing 10 large records into in-memory logging
98					 * database should throw FullLogBufferException since
99					 * the amount of put data is larger than buffer size.
100					 */
101					byte[] byteArr = new byte[204800];
102					for (int i = 0; i < 10; i++)
103						db.Put(new DatabaseEntry(BitConverter.GetBytes(i)),
104						    new DatabaseEntry(byteArr), writeTxn);
105					writeTxn.Commit();
106				}
107				catch (Exception e)
108				{
109					writeTxn.Abort();
110					throw e;
111				}
112				finally
113				{
114					db.Close(true);
115				}
116			}
117			catch (FullLogBufferException e)
118			{
119				Assert.AreEqual(ErrorCodes.DB_LOG_BUFFER_FULL, e.ErrorCode);
120				throw new ExpectedTestException();
121			}
122			finally
123			{
124				env.Close();
125			}
126		}
127
128		[Test]
129		public void TestLoggingSystemStats()
130		{
131			testName = "TestLoggingSystemStats";
132			testHome = testFixtureHome + "/" + testName;
133			string logDir = "./";
134
135			Configuration.ClearDir(testHome);
136			Directory.CreateDirectory(testHome + "/" + logDir);
137
138			DatabaseEnvironmentConfig cfg =
139			    new DatabaseEnvironmentConfig();
140			cfg.Create = true;
141			cfg.UseTxns = true;
142			cfg.AutoCommit = true;
143			cfg.UseLocking = true;
144			cfg.UseMPool = true;
145			cfg.UseLogging = true;
146			cfg.MPoolSystemCfg = new MPoolConfig();
147			cfg.MPoolSystemCfg.CacheSize = new CacheInfo(0, 1048576, 1);
148
149			cfg.LogSystemCfg = new LogConfig();
150			cfg.LogSystemCfg.AutoRemove = false;
151			cfg.LogSystemCfg.BufferSize = 10240;
152			cfg.LogSystemCfg.Dir = logDir;
153			cfg.LogSystemCfg.FileMode = 755;
154			cfg.LogSystemCfg.ForceSync = true;
155			cfg.LogSystemCfg.InMemory = false;
156			cfg.LogSystemCfg.MaxFileSize = 1048576;
157			cfg.LogSystemCfg.NoBuffer = false;
158			cfg.LogSystemCfg.RegionSize = 204800;
159			cfg.LogSystemCfg.ZeroOnCreate = true;
160
161			DatabaseEnvironment env = DatabaseEnvironment.Open(testHome, cfg);
162
163			LogStats stats = env.LoggingSystemStats();
164			env.PrintLoggingSystemStats();
165			Assert.AreEqual(10240, stats.BufferSize);
166			Assert.AreEqual(1, stats.CurrentFile);
167			Assert.AreNotEqual(0, stats.CurrentOffset);
168			Assert.AreEqual(1048576, stats.FileSize);
169			Assert.AreNotEqual(0, stats.MagicNumber);
170			Assert.AreNotEqual(0, stats.PermissionsMode);
171			Assert.AreEqual(1, stats.Records);
172			Assert.AreNotEqual(0, stats.RegionLockNoWait);
173			Assert.LessOrEqual(204800, stats.RegionSize);
174			Assert.AreNotEqual(0, stats.Version);
175
176			Transaction openTxn = env.BeginTransaction();
177			BTreeDatabaseConfig dbConfig = new BTreeDatabaseConfig();
178			dbConfig.Creation = CreatePolicy.IF_NEEDED;
179			dbConfig.Env = env;
180			BTreeDatabase db = BTreeDatabase.Open(testName + ".db", dbConfig, openTxn);
181			openTxn.Commit();
182
183			Transaction writeTxn = env.BeginTransaction();
184			byte[] byteArr = new byte[1024];
185			for (int i = 0; i < 1000; i++)
186				db.Put(new DatabaseEntry(BitConverter.GetBytes(i)),
187				    new DatabaseEntry(byteArr), writeTxn);
188			writeTxn.Commit();
189
190			stats = env.LoggingSystemStats();
191			Assert.AreNotEqual(0, stats.Bytes);
192			Assert.AreNotEqual(0, stats.BytesSinceCheckpoint);
193			Assert.AreNotEqual(0, stats.DiskFileNumber);
194			Assert.AreNotEqual(0, stats.DiskOffset);
195			Assert.AreNotEqual(0, stats.MaxCommitsPerFlush);
196			Assert.AreNotEqual(0, stats.MBytes);
197			Assert.AreNotEqual(0, stats.MBytesSinceCheckpoint);
198			Assert.AreNotEqual(0, stats.MinCommitsPerFlush);
199			Assert.AreNotEqual(0, stats.OverflowWrites);
200			Assert.AreNotEqual(0, stats.Syncs);
201			Assert.AreNotEqual(0, stats.Writes);
202			Assert.AreEqual(0, stats.Reads);
203			Assert.AreEqual(0, stats.RegionLockWait);
204
205			stats = env.LoggingSystemStats(true);
206			stats = env.LoggingSystemStats();
207			Assert.AreEqual(0, stats.Bytes);
208			Assert.AreEqual(0, stats.BytesSinceCheckpoint);
209			Assert.AreEqual(0, stats.MaxCommitsPerFlush);
210			Assert.AreEqual(0, stats.MBytes);
211			Assert.AreEqual(0, stats.MBytesSinceCheckpoint);
212			Assert.AreEqual(0, stats.MinCommitsPerFlush);
213			Assert.AreEqual(0, stats.OverflowWrites);
214			Assert.AreEqual(0, stats.Syncs);
215			Assert.AreEqual(0, stats.Writes);
216			Assert.AreEqual(0, stats.Reads);
217
218			env.PrintLoggingSystemStats(true, true);
219
220			db.Close();
221			env.Close();
222		}
223
224		[Test]
225		public void TestLsn()
226		{
227			testName = "TestLsn";
228			testHome = testFixtureHome + "/" + testName;
229			Configuration.ClearDir(testHome);
230
231			LSN lsn = new LSN(12, 411);
232			Assert.AreEqual(12, lsn.LogFileNumber);
233			Assert.AreEqual(411, lsn.Offset);
234
235			LSN newLsn = new LSN(15, 410);
236			Assert.AreEqual(0, LSN.Compare(lsn, lsn));
237			Assert.Greater(0, LSN.Compare(lsn, newLsn));
238		}
239
240		public static void Confirm(XmlElement
241		    xmlElement, LogConfig logConfig, bool compulsory)
242		{
243			Configuration.ConfirmBool(xmlElement, "AutoRemove",
244			    logConfig.AutoRemove, compulsory);
245			Configuration.ConfirmUint(xmlElement, "BufferSize",
246			    logConfig.BufferSize, compulsory);
247			Configuration.ConfirmString(xmlElement, "Dir",
248			    logConfig.Dir, compulsory);
249			Configuration.ConfirmInt(xmlElement, "FileMode",
250			    logConfig.FileMode, compulsory);
251			Configuration.ConfirmBool(xmlElement, "ForceSync",
252			    logConfig.ForceSync, compulsory);
253			Configuration.ConfirmBool(xmlElement, "InMemory",
254			    logConfig.InMemory, compulsory);
255			Configuration.ConfirmUint(xmlElement, "MaxFileSize",
256			    logConfig.MaxFileSize, compulsory);
257			Configuration.ConfirmBool(xmlElement, "NoBuffer",
258			    logConfig.NoBuffer, compulsory);
259			Configuration.ConfirmUint(xmlElement, "RegionSize",
260			    logConfig.RegionSize, compulsory);
261			Configuration.ConfirmBool(xmlElement, "ZeroOnCreate",
262			    logConfig.ZeroOnCreate, compulsory);
263		}
264
265		public static void Config(XmlElement
266		    xmlElement, ref LogConfig logConfig, bool compulsory)
267		{
268			uint uintValue = new uint();
269			int intValue = new int();
270
271			Configuration.ConfigBool(xmlElement, "AutoRemove",
272			    ref logConfig.AutoRemove, compulsory);
273			if (Configuration.ConfigUint(xmlElement, "BufferSize",
274			    ref uintValue, compulsory))
275				logConfig.BufferSize = uintValue;
276			Configuration.ConfigString(xmlElement, "Dir",
277			    ref logConfig.Dir, compulsory);
278			if (Configuration.ConfigInt(xmlElement, "FileMode",
279			    ref intValue, compulsory))
280				logConfig.FileMode = intValue;
281			Configuration.ConfigBool(xmlElement, "ForceSync",
282			    ref logConfig.ForceSync, compulsory);
283			Configuration.ConfigBool(xmlElement, "InMemory",
284			    ref logConfig.InMemory, compulsory);
285			if (Configuration.ConfigUint(xmlElement, "MaxFileSize",
286			    ref uintValue, compulsory))
287				logConfig.MaxFileSize = uintValue;
288			Configuration.ConfigBool(xmlElement, "NoBuffer",
289			    ref logConfig.NoBuffer, compulsory);
290			if (Configuration.ConfigUint(xmlElement, "RegionSize",
291			    ref uintValue, compulsory))
292				logConfig.RegionSize = uintValue;
293			Configuration.ConfigBool(xmlElement, "ZeroOnCreate",
294			    ref logConfig.ZeroOnCreate, compulsory);
295		}
296	}
297}
298