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