PageRenderTime 71ms CodeModel.GetById 40ms RepoModel.GetById 1ms app.codeStats 0ms

/source/MongoDB.GridFS.Tests/GridFileStreamTest.cs

https://github.com/nikunjdhawan/mongodb-csharp
C# | 379 lines | 319 code | 59 blank | 1 comment | 23 complexity | 21f4cae2c086adae67584dafc4f9abbf MD5 | raw file
  1. using System;
  2. using System.IO;
  3. using NUnit.Framework;
  4. using MongoDB;
  5. namespace MongoDB.GridFS
  6. {
  7. [TestFixture]
  8. public class GridFileStreamTest : GridTestBase
  9. {
  10. GridFile fs;
  11. String filesystem = "gfstream";
  12. public override string TestFileSystems {
  13. get {
  14. return filesystem;
  15. }
  16. }
  17. public override void OnInit (){
  18. fs = new GridFile(DB, filesystem);
  19. }
  20. [Test]
  21. public void TestWrite(){
  22. GridFileStream gfs = fs.Create("test.txt");
  23. Object id = gfs.GridFileInfo.Id;
  24. for(byte b = (byte)0; b < 128; b++){
  25. gfs.WriteByte(b);
  26. }
  27. gfs.Close();
  28. Assert.AreEqual(1, CountChunks(filesystem,id));
  29. Document chunk = GrabChunk(id, 0);
  30. Binary bin = (Binary)chunk["data"];
  31. Assert.AreEqual(127, bin.Bytes[127]);
  32. Assert.AreEqual(0, bin.Bytes[0]);
  33. }
  34. [Test]
  35. public void TestWriteMultipleBytes(){
  36. GridFileStream gfs = fs.Create("multiplebytes.txt");
  37. Object id = gfs.GridFileInfo.Id;
  38. for(int x = 0; x < 256; x++){
  39. gfs.Write(BitConverter.GetBytes(x),0,4);
  40. }
  41. gfs.Close();
  42. Assert.AreEqual(1, CountChunks(filesystem,id));
  43. }
  44. [Test]
  45. public void TestWriteTo3Chunks(){
  46. GridFileStream gfs = fs.Create("largewrite.txt");
  47. Object id = gfs.GridFileInfo.Id;
  48. int chunks = 3;
  49. int buffsize = 256 * 1024 * chunks;
  50. Byte[] buff = CreateBuffer(buffsize, (byte)6);
  51. gfs.Write(buff,0,buff.Length);
  52. Assert.AreEqual(buff.Length, gfs.Position);
  53. gfs.Close();
  54. Assert.AreEqual(chunks, CountChunks(filesystem,id));
  55. }
  56. [Test]
  57. public void TestWriteWithMultipleFlushes(){
  58. string filename = "multiflush.txt";
  59. GridFileStream gfs = fs.Create(filename);
  60. Object id = gfs.GridFileInfo.Id;
  61. int size = gfs.GridFileInfo.ChunkSize * 2;
  62. byte[] buff;
  63. int x = 0;
  64. for(int i = 0; i < size; i+=4){
  65. buff = BitConverter.GetBytes(x);
  66. gfs.Write(buff,0,buff.Length);
  67. x++;
  68. if(i % size/4 == 0){
  69. gfs.Flush();
  70. }
  71. }
  72. gfs.Close();
  73. gfs = fs.OpenRead(filename);
  74. int read;
  75. int val;
  76. buff = new byte[4];
  77. for(int i = 0; i < size/4; i++){
  78. read = gfs.Read(buff,0,4);
  79. val = BitConverter.ToInt32(buff, 0);
  80. Assert.AreEqual(4, read, "Not enough bytes were read. Pos: " + gfs.Position);
  81. Assert.AreEqual(i,val, "value read back was not the same as written. Pos: " + gfs.Position);
  82. }
  83. }
  84. [Test]
  85. public void TestWriteMultipleBytesWithOffset(){
  86. String filename = "multioffset.txt";
  87. int offset = 4;
  88. int chunks = 2;
  89. int chunksize = 100;
  90. int size = chunks * chunksize;
  91. Object id = CreateDummyFile(filename, size, chunksize, offset);
  92. Assert.AreEqual(2, CountChunks(filesystem,id));
  93. GridFileStream gfs = fs.OpenRead(filename);
  94. byte[] buff = new Byte[4];
  95. int read;
  96. int val;
  97. for(int i = 1; i <= size/4 - offset; i++){
  98. read = gfs.Read(buff,0,4);
  99. val = BitConverter.ToInt32(buff, 0);
  100. Assert.AreEqual(4, read, "Not enough bytes were read. Pos: " + gfs.Position);
  101. Assert.AreEqual(i,val, "value read back was not the same as written. Pos: " + gfs.Position);
  102. }
  103. }
  104. [Test]
  105. public void TestNonSequentialWriteToOneChunk(){
  106. string filename = "nonsequential1.txt";
  107. GridFileStream gfs = fs.Create(filename);
  108. Object id = gfs.GridFileInfo.Id;
  109. int chunksize = gfs.GridFileInfo.ChunkSize;
  110. gfs.Seek(chunksize/2, SeekOrigin.Begin);
  111. byte[] two = new byte[]{2};
  112. for(int i = chunksize; i > chunksize/2; i--){
  113. gfs.Write(two, 0, 1);
  114. }
  115. gfs.Seek(0, SeekOrigin.Begin);
  116. byte[] one = new byte[]{1};
  117. for(int i = 0; i < chunksize/2; i++){
  118. gfs.Write(one, 0, 1);
  119. }
  120. gfs.Close();
  121. Assert.AreEqual(1, CountChunks(filesystem,id));
  122. Document chunk = GrabChunk(id, 0);
  123. Binary b = (Binary)chunk["data"];
  124. Assert.AreEqual(2, b.Bytes[chunksize-1]);
  125. Assert.AreEqual(2, b.Bytes[chunksize/2]);
  126. Assert.AreEqual(1, b.Bytes[chunksize/2 -1]);
  127. Assert.AreEqual(1, b.Bytes[0]);
  128. }
  129. [Test]
  130. public void TestNonSequentialWriteToPartialChunk(){
  131. string filename = "nonsequentialpartial.txt";
  132. GridFileStream gfs = fs.Create(filename);
  133. Object id = gfs.GridFileInfo.Id;
  134. int chunksize = gfs.GridFileInfo.ChunkSize;
  135. gfs.Write(BitConverter.GetBytes(0),0,4);
  136. Assert.AreEqual(4, gfs.Position);
  137. gfs.Write(BitConverter.GetBytes(7),0,4);
  138. Assert.AreEqual(8, gfs.Position);
  139. gfs.Seek(0, SeekOrigin.Begin);
  140. gfs.Write(BitConverter.GetBytes(15),0,4);
  141. gfs.Close();
  142. Document chunk = GrabChunk(id, 0);
  143. Binary b = (Binary)chunk["data"];
  144. Assert.AreEqual(8,b.Bytes.Length);
  145. }
  146. [Test]
  147. public void TestNonSequentialWriteToTwoChunks(){
  148. GridFileStream gfs = fs.Create("nonsequential2.txt");
  149. Object id = gfs.GridFileInfo.Id;
  150. int chunks = 3;
  151. int buffsize = 256 * 1024;
  152. for(int c = 0; c < chunks; c++){
  153. Byte[] buff = CreateBuffer(buffsize, (byte)c);
  154. if(c == 2){
  155. gfs.Seek(0, SeekOrigin.Begin); //On last chunk seek to start.
  156. }
  157. gfs.Write(buff,0,buff.Length);
  158. }
  159. Assert.AreEqual(buffsize, gfs.Position, "Position is incorrect");
  160. gfs.Close();
  161. Assert.AreEqual(chunks - 1, CountChunks(filesystem,id));
  162. Document chunk = GrabChunk(id, 0);
  163. Binary b = (Binary)chunk["data"];
  164. Assert.AreEqual(2, b.Bytes[buffsize-1]);
  165. Assert.AreEqual(2, b.Bytes[0]);
  166. chunk = GrabChunk(id, 1);
  167. b = (Binary)chunk["data"];
  168. Assert.AreEqual(1, b.Bytes[buffsize-1]);
  169. }
  170. [Test]
  171. public void TestRead(){
  172. string filename = "readme.txt";
  173. GridFileStream gfs = fs.Create(filename);
  174. for(int i = 1; i <= 50; i++){
  175. gfs.Write(BitConverter.GetBytes(i), 0, 4);
  176. }
  177. gfs.Close();
  178. gfs = fs.OpenRead(filename);
  179. Byte[] buff = new Byte[4];
  180. int read;
  181. for(int i = 1; i <= 50; i++){
  182. read = gfs.Read(buff,0,4);
  183. Assert.AreEqual(4, read, "Not enough bytes were read");
  184. Assert.AreEqual(i,BitConverter.ToInt32(buff, 0), "value read back was not the same as written");
  185. }
  186. }
  187. [Test]
  188. public void TestReadIntoBufferBiggerThanChunk(){
  189. string filename = "largereadbuffer.txt";
  190. int size = 100;
  191. Object id = CreateDummyFile(filename,size,50,0);
  192. GridFileStream gfs = fs.OpenRead(filename);
  193. byte[] buff = new byte[size];
  194. int read = gfs.Read(buff,0,size);
  195. Assert.AreEqual(size, read, "Not all bytes read back from file.");
  196. int expected = 0;
  197. for(int i = 0; i < size; i+=4){
  198. int val = BitConverter.ToInt32(buff,i);
  199. Assert.AreEqual(expected, val, "Val was not same as expected. Pos: " + i);
  200. expected++;
  201. }
  202. }
  203. [Test]
  204. public void TestReadFrom3Chunks(){
  205. string filename = "read3chunks.txt";
  206. int chunks = 3;
  207. int chunkSize = 256 * 1024;
  208. int size = (256 * 1024 * chunks) - 5000;
  209. Object id = CreateDummyFile(filename,size,chunkSize,0);
  210. using(GridFileStream gfs = fs.OpenRead(filename)){
  211. int buffsize = 10240;
  212. Byte[] buff = new Byte[buffsize];
  213. int read = 0;
  214. int totalRead = 0;
  215. while((read = gfs.Read(buff,0,buffsize)) != 0){
  216. totalRead += read;
  217. }
  218. Assert.AreEqual(size,totalRead,"Not all bytes read back");
  219. }
  220. }
  221. [Test]
  222. public void TestSetLengthBigger(){
  223. string filename = "setlengthbigger.txt";
  224. GridFileStream gfs = fs.Create(filename);
  225. Object id = gfs.GridFileInfo.Id;
  226. long length = 256 * 1024 * 5;
  227. gfs.WriteByte(1);
  228. gfs.SetLength(length);
  229. gfs.WriteByte(2);
  230. gfs.Close();
  231. GridFileInfo gfi = new GridFileInfo(DB,filesystem,filename);
  232. Assert.AreEqual(length + 1, gfi.Length);
  233. Assert.AreEqual(6, CountChunks(filesystem,id));
  234. }
  235. [Test]
  236. public void TestSetLengthSmaller(){
  237. string filename = "setlengthsmaller.txt";
  238. int chunksize = 256 * 1024;
  239. int chunks = 4;
  240. int size = chunks * chunksize;
  241. int newsize = (size / 2) - (chunksize/2);
  242. Object id = this.CreateDummyFile(filename, size,chunksize,0);
  243. GridFileStream gfs = fs.Open(filename,FileMode.Open,FileAccess.ReadWrite);
  244. gfs.SetLength(newsize);
  245. gfs.Close();
  246. Assert.AreEqual(newsize, gfs.GridFileInfo.Length);
  247. }
  248. [Test]
  249. public void TestReadLengthIsSameAsWriteLength(){
  250. string filename = "readwritelength.txt";
  251. GridFileStream gfs = fs.Create(filename);
  252. int length = 0;
  253. for(int i = 1; i <= 50; i++){
  254. gfs.Write(BitConverter.GetBytes(i), 0, 4);
  255. length += 4;
  256. }
  257. gfs.Close();
  258. Assert.AreEqual(length, gfs.GridFileInfo.Length, "File length written is not the same as in gridfileinfo");
  259. gfs = fs.OpenRead(filename);
  260. byte[] buffer = new byte[16];
  261. int read = 0;
  262. int readLength = read;
  263. while((read = gfs.Read(buffer,0,buffer.Length)) > 0){
  264. readLength += read;
  265. }
  266. Assert.AreEqual(length, readLength, "Too much read back.");
  267. }
  268. #region File API compatibility
  269. [Test]
  270. public void TestSeekingBeyondEOF(){
  271. int buffsize = 256;
  272. string filename = "seektest.txt";
  273. FileStream gfs = File.Create(filename,buffsize);//,FileOptions.DeleteOnClose);
  274. int chunks = 3;
  275. //int buffsize = 256 * 1024;
  276. for(int c = 0; c < chunks; c++){
  277. Byte[] buff = new byte[buffsize];
  278. for(int i = 0; i < buff.Length; i++){
  279. buff[i] = (byte)(c);
  280. }
  281. if(c == 2) gfs.Seek(0, SeekOrigin.Begin); //On last chunk seek to start.
  282. gfs.Write(buff,0,buff.Length);
  283. gfs.Seek(5,SeekOrigin.Current);
  284. }
  285. gfs.Seek(50,SeekOrigin.End);
  286. gfs.Write(new byte[]{5},0,1);
  287. gfs.Close();
  288. File.Delete(filename);
  289. }
  290. #endregion
  291. protected Document GrabChunk(Object fileid, int chunk){
  292. return DB[filesystem + ".chunks"].FindOne(new Document().Add("files_id", fileid).Add("n", chunk));
  293. }
  294. protected Object CreateDummyFile(string filename, int size, int chunksize, int initialOffset){
  295. GridFileInfo gfi = new GridFileInfo(DB, "gfstream", filename);
  296. gfi.ChunkSize = chunksize;
  297. GridFileStream gfs = gfi.Create();
  298. Object id = gfs.GridFileInfo.Id;
  299. byte[] buff = CreateIntBuffer(size);
  300. gfs.Write(buff,initialOffset,buff.Length - initialOffset);
  301. gfs.Close();
  302. return id;
  303. }
  304. protected byte[] CreateBuffer(int size, byte fill){
  305. Byte[] buff = new byte[size];
  306. for(int i = 0; i < buff.Length; i++){
  307. buff[i] = fill;
  308. }
  309. return buff;
  310. }
  311. protected byte[] CreateIntBuffer(int size){
  312. byte[] buff = new byte[size];
  313. int x = 1;
  314. for(int i = 4; i < buff.Length; i+=4){
  315. Array.Copy(BitConverter.GetBytes(x++),0,buff,i,4);
  316. }
  317. return buff;
  318. }
  319. }
  320. }