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 LogCursorTest
20	{
21		private string testFixtureHome;
22		private string testFixtureName;
23		private string testName;
24		private string testHome;
25		DatabaseEnvironment env;
26
27		[TestFixtureSetUp]
28		public void RunBeforeTests()
29		{
30			testFixtureName = "LogCursorTest";
31			testFixtureHome = "./TestOut/" + testFixtureName;
32
33			/*
34			 * Delete existing test ouput directory and files specified
35			 * for the current test fixture and then create a new one.
36			 */
37			Configuration.ClearDir(testFixtureHome);
38		}
39
40		[Test]
41		public void TestClose()
42		{
43			testName = "TestClose";
44			testHome = testFixtureHome + "/" + testName;
45			DatabaseEnvironment env;
46			LogCursor logCursor;
47			RecnoDatabase db;
48
49			Logging(testHome, testName, out env, out db);
50
51			// Get log cursor to read/write log.
52			logCursor = env.GetLogCursor();
53
54			// Close the log cursor and env.
55			logCursor.Close();
56			db.Close();
57			env.Close();
58		}
59
60		[Test]
61		public void TesCurrentLSN()
62		{
63			testName = "TesCurrentLSN";
64			testHome = testFixtureHome + "/" + testName;
65			RecnoDatabase db;
66
67			Logging(testHome, testName, out env, out db);
68
69			// Get log cursor to read/write log.
70			LogCursor logCursor = env.GetLogCursor();
71
72			/*
73			 * Move the cursor to the beginning of the #1 log file.
74			 * Get the current LSN and confirm that is the position
75			 * the cursor is moved to.
76			 */
77			LSN lsn = new LSN(1, 0);
78			logCursor.Move(lsn);
79			Assert.AreEqual(lsn.LogFileNumber,
80			    logCursor.CurrentLSN.LogFileNumber);
81			Assert.AreEqual(lsn.Offset, logCursor.CurrentLSN.Offset);
82
83			// Close all.
84			logCursor.Close();
85			db.Close();
86			env.Close();
87		}
88
89		[Test]
90		public void TestCurrentRecord()
91		{
92			testName = "TestCurrentRecord";
93			testHome = testFixtureHome + "/" + testName;
94			DatabaseEnvironment env;
95			RecnoDatabase db;
96
97			Logging(testHome, testName, out env, out db);
98
99			// Get log cursor to read/write log.
100			LogCursor logCursor = env.GetLogCursor();
101
102			/*
103			 * Move the cursor to the beginning of the #1 log file.
104			 * Get the current LSN and confirm that is the position
105			 * the cursor is moved to.
106			 */
107			LSN lsn = new LSN(1, 0);
108			logCursor.Move(lsn);
109			Assert.IsNotNull(logCursor.CurrentRecord.Data);
110
111			// Close all.
112			logCursor.Close();
113			db.Close();
114			env.Close();
115		}
116
117		[Test]
118		public void TestMove()
119		{
120			testName = "TestMove";
121			testHome = testFixtureHome + "/" + testName;
122			DatabaseEnvironment env;
123			RecnoDatabase db;
124
125			Logging(testHome, testName, out env, out db);
126
127			// Get log cursor to read/write log.
128			LogCursor logCursor = env.GetLogCursor();
129
130			// Move the cursor to specified location in log files.
131			LSN lsn = new LSN(1, 0);
132			Assert.IsTrue(logCursor.Move(lsn));
133
134			// Close all.
135			logCursor.Close();
136			db.Close();
137			env.Close();
138		}
139
140		/*
141		[Test]
142		public void TestMoveFirst()
143		{
144			testName = "TestMoveFirst";
145			testHome = testFixtureHome + "/" + testName;
146			DatabaseEnvironment env;
147			RecnoDatabase db;
148
149			Logging(testHome, testName, out env, out db);
150
151			// Get log cursor to read/write log.
152			LogCursor logCursor = env.GetLogCursor();
153
154			// Move to the first LSN in log file.
155			Assert.IsTrue(logCursor.MoveFirst());
156
157			// Confirm offset of the fist LSN should be 0.
158			Assert.AreEqual(0, logCursor.CurrentLSN.Offset);
159
160			// Close all.
161			logCursor.Close();
162			db.Close();
163			env.Close();
164		}
165		*/
166
167		[Test]
168		public void TestMoveLast()
169		{
170			testName = "TestMoveLast";
171			testHome = testFixtureHome + "/" + testName;
172			DatabaseEnvironment env;
173			RecnoDatabase db;
174
175			Logging(testHome, testName, out env, out db);
176
177			// Get log cursor to read/write log.
178			LogCursor logCursor = env.GetLogCursor();
179
180			// Move to the last LSN in log file.
181			Assert.IsTrue(logCursor.MoveLast());
182
183			// The offset of last LSN shouldn't be 0.
184			Assert.AreNotEqual(0, logCursor.CurrentLSN.Offset);
185
186			// Close all.
187			logCursor.Close();
188			db.Close();
189			env.Close();
190		}
191
192		[Test]
193		public void TestMoveNext()
194		{
195			testName = "TestMoveNext";
196			testHome = testFixtureHome + "/" + testName;
197			DatabaseEnvironment env;
198			RecnoDatabase db;
199
200			Logging(testHome, testName, out env, out db);
201
202			// Get log cursor to read/write log.
203			LogCursor logCursor = env.GetLogCursor();
204
205			logCursor.MoveLast();
206			DatabaseEntry curRec = logCursor.CurrentRecord;
207			for (int i = 0; i < 1000; i++)
208				db.Append(new DatabaseEntry(
209				    ASCIIEncoding.ASCII.GetBytes("new data")));
210
211			Assert.IsTrue(logCursor.MoveNext());
212
213			logCursor.MoveNext();
214
215			// Close the log cursor.
216			logCursor.Close();
217			db.Close();
218			env.Close();
219		}
220
221
222		[Test]
223		public void TestMovePrev()
224		{
225			testName = "TestMovePrev";
226			testHome = testFixtureHome + "/" + testName;
227			DatabaseEnvironment env;
228			LSN lsn;
229			RecnoDatabase db;
230
231			Logging(testHome, testName, out env, out db);
232
233			// Get log cursor to read/write log.
234			LogCursor logCursor = env.GetLogCursor();
235
236			// Get the last two LSN in log file.
237			logCursor.MoveLast();
238			Assert.IsTrue(logCursor.MovePrev());
239
240			// Close all.
241			logCursor.Close();
242			db.Close();
243			env.Close();
244		}
245
246		[Test]
247		public void TestRefresh()
248		{
249			testName = "TestRefresh";
250			testHome = testFixtureHome + "/" + testName;
251			DatabaseEnvironment env;
252			LSN lsn;
253			RecnoDatabase db;
254
255			Logging(testHome, testName, out env, out db);
256
257			// Get log cursor to read/write log.
258			LogCursor logCursor = env.GetLogCursor();
259
260			// Move the cursor to the last record.
261			logCursor.MoveLast();
262			DatabaseEntry curRec = logCursor.CurrentRecord;
263
264			// Put some new records into database.
265			for (int i = 0; i < 10; i++)
266				db.Append(new DatabaseEntry(
267				    ASCIIEncoding.ASCII.GetBytes("new data")));
268
269			// Get the current record that cursor points to.
270			logCursor.Refresh();
271
272			// It shouldn't be changed.
273			Assert.AreEqual(curRec.Data,
274			    logCursor.CurrentRecord.Data);
275
276			// Close all.
277			logCursor.Close();
278			db.Close();
279			env.Close();
280		}
281
282		/*
283		 * Open environment, database and write data into database.
284		 * Generated log files are put under testHome.
285		 */
286		public void Logging(string home, string dbName,
287		    out DatabaseEnvironment env, out RecnoDatabase recnoDB)
288		{
289			string dbFileName = dbName + ".db";
290
291			Configuration.ClearDir(home);
292
293			// Open environment with logging subsystem.
294			DatabaseEnvironmentConfig envConfig =
295			    new DatabaseEnvironmentConfig();
296			envConfig.Create = true;
297			envConfig.UseLogging = true;
298			envConfig.LogSystemCfg = new LogConfig();
299			envConfig.LogSystemCfg.FileMode = 755;
300			envConfig.LogSystemCfg.ZeroOnCreate = true;
301			envConfig.UseMPool = true;
302			env = DatabaseEnvironment.Open(home, envConfig);
303
304			/*
305			 * Open recno database, write 100000 records into
306			 * the database and close it.
307			 */
308			RecnoDatabaseConfig recnoConfig =
309			    new RecnoDatabaseConfig();
310			recnoConfig.Creation = CreatePolicy.IF_NEEDED;
311			recnoConfig.Env = env;
312			// The db needs mpool to open.
313			recnoConfig.NoMMap = false;
314			recnoDB = RecnoDatabase.Open(dbFileName,
315			    recnoConfig);
316			for (int i = 0; i < 1000; i++)
317				recnoDB.Append(new DatabaseEntry(
318				    ASCIIEncoding.ASCII.GetBytes("key")));
319		}
320	}
321}
322