2 // MemoryMappedFileTest.cs
5 // Zoltan Varga (vargaz@gmail.com)
7 // (C) 2009 Novell, Inc. (http://www.novell.com)
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 using System
.IO
.MemoryMappedFiles
;
36 using NUnit
.Framework
;
38 namespace MonoTests
.System
.IO
.MemoryMappedFiles
{
41 public class MemoryMappedFileTest
{
43 void AssertThrows
<ExType
> (Action del
) where ExType
: Exception
{
51 Assert
.IsTrue (thrown
);
54 static int named_index
;
55 static String
MkNamedMapping ()
57 return "test-" + named_index
++;
61 static string tempDir
= Path
.Combine (Path
.GetTempPath (), typeof (MemoryMappedFileTest
).FullName
);
66 protected void SetUp () {
67 if (Directory
.Exists (tempDir
))
68 Directory
.Delete (tempDir
, true);
70 Directory
.CreateDirectory (tempDir
);
72 fname
= Path
.Combine (tempDir
, "basic.txt");
74 using (StreamWriter sw
= new StreamWriter (fname
)) {
75 sw
.WriteLine ("Hello!");
76 sw
.WriteLine ("World!");
81 protected void TearDown () {
82 if (Directory
.Exists (tempDir
))
83 Directory
.Delete (tempDir
, true);
87 public void Basic () {
88 var file
= MemoryMappedFile
.CreateFromFile (fname
, FileMode
.Open
);
90 using (var stream
= file
.CreateViewStream ()) {
91 TextReader r
= new StreamReader (stream
);
96 Assert
.AreEqual ("Hello!", s
);
98 Assert
.AreEqual ("World!", s
);
103 public void CreateNew ()
106 MemoryMappedFile
.CreateNew (Path
.Combine (tempDir
, "createNew.test"), 8192);
110 [ExpectedException (typeof (IOException
))]
111 public void CreateNew_OnExistingFile ()
114 MemoryMappedFile
.CreateNew (Path
.Combine (tempDir
, "createNew.test"), 8192);
116 // This should fail, the file exists
117 MemoryMappedFile
.CreateNew (Path
.Combine (tempDir
, "createNew.test"), 8192);
120 // Call this twice, it should always work
122 public void CreateOrOpen_Multiple ()
124 MemoryMappedFile
.CreateOrOpen (Path
.Combine (tempDir
, "createOrOpen.test"), 8192);
125 MemoryMappedFile
.CreateOrOpen (Path
.Combine (tempDir
, "createOrOpen.test"), 8192);
129 [ExpectedException(typeof(ArgumentOutOfRangeException
))]
130 public void CreateFromFileWithSmallerCapacityThanFile ()
132 var f
= Path
.Combine (tempDir
, "8192-file");
133 File
.WriteAllBytes (f
, new byte [8192]);
135 // We are requesting fewer bytes to map.
136 MemoryMappedFile
.CreateFromFile (f
, FileMode
.Open
, "myMap", 4192);
140 public void CreateFromFile_Null () {
141 AssertThrows
<ArgumentNullException
> (delegate () {
142 MemoryMappedFile
.CreateFromFile (null);
147 public void CreateViewStream_Offsets () {
148 var file
= MemoryMappedFile
.CreateFromFile (fname
, FileMode
.Open
);
150 using (var stream
= file
.CreateViewStream (2, 3)) {
151 byte[] arr
= new byte [128];
153 int len
= stream
.Read (arr
, 0, 128);
155 Assert
.AreEqual (3, len
);
157 Assert
.AreEqual ('l', (char)arr
[0]);
158 Assert
.AreEqual ('l', (char)arr
[1]);
159 Assert
.AreEqual ('o', (char)arr
[2]);
164 public void CreateViewStream_Rights () {
165 var file
= MemoryMappedFile
.CreateFromFile (fname
, FileMode
.Open
);
167 using (var stream
= file
.CreateViewStream (0, 0, MemoryMappedFileAccess
.Read
)) {
168 AssertThrows
<NotSupportedException
> (delegate () {
169 stream
.WriteByte (0);
173 using (var stream
= file
.CreateViewStream (0, 0, MemoryMappedFileAccess
.Write
)) {
174 AssertThrows
<NotSupportedException
> (delegate () {
181 public unsafe void CreateViewBasic () {
182 var file
= MemoryMappedFile
.CreateFromFile (fname
, FileMode
.Open
);
184 using (var v
= file
.CreateViewAccessor ()) {
188 var handle
= v
.SafeMemoryMappedViewHandle
;
192 handle
.AcquirePointer (ref b
);
194 for (int i
= 0; i
< 5; ++i
)
197 handle
.ReleasePointer ();
200 Assert
.AreEqual ("Hello", s
);
205 public unsafe void ViewReadArray () {
206 var file
= MemoryMappedFile
.CreateFromFile (fname
, FileMode
.Open
);
208 using (var v
= file
.CreateViewAccessor ()) {
209 var a
= new byte [5];
210 var n
= v
.ReadArray (0, a
, 0, 5);
211 Assert
.AreEqual (5, n
);
212 var s
= new string (Array
.ConvertAll (a
, b
=> (char)b
));
213 Assert
.AreEqual ("Hello", s
);
219 public void NamedMappingToInvalidFile ()
221 var fileName
= Path
.Combine (tempDir
, "temp_file_123");
222 if (File
.Exists (fileName
))
223 File
.Delete (fileName
);
224 var memoryMappedFile90
= MemoryMappedFile
.CreateNew (fileName
, 4194304, MemoryMappedFileAccess
.ReadWrite
);
225 memoryMappedFile90
.CreateViewStream (4186112, 3222, MemoryMappedFileAccess
.Write
);
229 public void CreateTheSameAreaTwiceShouldFail ()
231 var name
= MkNamedMapping ();
232 using (var m0
= MemoryMappedFile
.CreateNew(name
, 4096, MemoryMappedFileAccess
.ReadWrite
)) {
234 using (var m1
= MemoryMappedFile
.CreateNew (name
, 4096, MemoryMappedFileAccess
.ReadWrite
)) {
235 Assert
.Fail ("Must fail");
237 } catch (IOException
) {}
242 public void MapAFileToAMemoryAreaShouldFail ()
244 var name
= MkNamedMapping ();
245 using (var m0
= MemoryMappedFile
.CreateNew(name
, 4096, MemoryMappedFileAccess
.ReadWrite
)) {
247 using (var m1
= MemoryMappedFile
.CreateFromFile (fname
, FileMode
.OpenOrCreate
, name
)) {
248 Assert
.Fail ("Must fail");
250 } catch (IOException
) {}
255 public void NamedMappingsShareMemoryArea ()
257 var name
= MkNamedMapping ();
258 using (var m0
= MemoryMappedFile
.CreateNew(name
, 4096, MemoryMappedFileAccess
.ReadWrite
)) {
259 using (var m1
= MemoryMappedFile
.CreateOrOpen (name
, 4096, MemoryMappedFileAccess
.ReadWrite
)) {
260 using (MemoryMappedViewAccessor v0
= m0
.CreateViewAccessor (), v1
= m1
.CreateViewAccessor ()) {
261 v0
.Write (10, 0x12345);
262 Assert
.AreEqual (0x12345, v1
.ReadInt32 (10));
269 public void NamedFileCanBeOpen ()
271 var name
= MkNamedMapping ();
272 using (var sw
= new FileStream (fname
, FileMode
.Open
)) {
273 byte[] b
= new byte[20];
274 for (int i
= 0; i
< 20; ++i
)
279 using (var m0
= MemoryMappedFile
.CreateFromFile (fname
, FileMode
.Open
, name
)) {
280 using (var m1
= MemoryMappedFile
.CreateOrOpen (name
, 4096)) {
281 using (MemoryMappedViewAccessor v0
= m0
.CreateViewAccessor (), v1
= m1
.CreateViewAccessor ()) {
282 v0
.Write (10, 0x11223344);
283 Assert
.AreEqual (0x11223344, v1
.ReadInt32 (10));
290 public void MapAtEdgeOfPage ()
292 using (var f
= new FileStream (fname
, FileMode
.Open
)) {
293 var b
= new byte [4096];
294 for (int i
= 0; i
< 4096; ++i
)
296 for (int i
= 0; i
< 2; ++i
)
297 f
.Write (b
, 0, 4096);
299 var m0
= MemoryMappedFile
.CreateFromFile (fname
, FileMode
.Open
);
300 var v0
= m0
.CreateViewAccessor (500, 4096);
301 var v1
= m0
.CreateViewAccessor (0, 4096 * 2);
302 for (int i
= 0; i
< 4096; ++i
) {
303 Assert
.AreEqual (0xAA, v1
.ReadByte (i
+ 500));
304 v0
.Write (i
, (byte)0xFF);
305 Assert
.AreEqual (0xFF, v1
.ReadByte (i
+ 500));
310 public void DoubleAccountingInOffsetCalculation ()
312 var memoryMappedFile90
= MemoryMappedFile
.CreateNew (MkNamedMapping (), 4194304, MemoryMappedFileAccess
.ReadWrite
);
313 var stream
= memoryMappedFile90
.CreateViewStream (4186112, 3222, MemoryMappedFileAccess
.Write
);
314 using (var tw
= new StreamWriter(stream
))
316 tw
.WriteLine ("Hello World!");