[corlib][Mono.Posix] Remove NunitHelpers.cs reference
[mono.git] / mcs / class / Mono.Posix / Test / Mono.Unix / ReadlinkTest.cs
1 //
2 // readlink() / readlinkat() Test Cases
3 //
4 // Authors:
5 //  Steffen Kiess (s-kiess@web.de)
6 //
7 // Copyright (C) 2013 Steffen Kiess
8 //
9
10 using System;
11 using System.IO;
12 using System.Text;
13
14 using Mono.Unix;
15 using Mono.Unix.Native;
16
17 using NUnit.Framework;
18
19 namespace MonoTests.Mono.Unix
20 {
21         [TestFixture, Category ("NotDotNet"), Category ("NotOnWindows")]
22         public class ReadlinkTest {
23
24                 static string[] Targets = {
25                         // Simple test cases
26                         "a",
27                         "test",
28                         // With non-ASCII characters
29                         "ä",
30                         "test ö test",
31                         // With non-UTF8 bytes
32                         UnixEncoding.Instance.GetString (new byte[] {0xff, 0x80, 0x41, 0x80}),
33                         // Size is roughly initial size of buffer
34                         new string ('a', 255),
35                         new string ('a', 256),
36                         new string ('a', 257),
37                         // With non-ASCII characters, size is roughly initial size of buffer
38                         "ä" + new string ('a', 253), // 254 chars, 255 bytes
39                         "ä" + new string ('a', 254), // 255 chars, 256 bytes
40                         "ä" + new string ('a', 255), // 256 chars, 257 bytes
41                         "ä" + new string ('a', 256), // 257 chars, 258 bytes
42                         new string ('a', 253) + "ä", // 254 chars, 255 bytes
43                         new string ('a', 254) + "ä", // 255 chars, 256 bytes
44                         new string ('a', 255) + "ä", // 256 chars, 257 bytes
45                         new string ('a', 256) + "ä", // 257 chars, 258 bytes
46                         // With non-UTF8 bytes, size is roughly initial size of buffer
47                         "\0\u00ff" + new string ('a', 253), // 255 chars, 254 bytes
48                         "\0\u00ff" + new string ('a', 254), // 256 chars, 255 bytes
49                         "\0\u00ff" + new string ('a', 255), // 257 chars, 256 bytes
50                         "\0\u00ff" + new string ('a', 256), // 258 chars, 257 bytes
51                         new string ('a', 253) + "\0\u00ff", // 255 chars, 254 bytes
52                         new string ('a', 254) + "\0\u00ff", // 256 chars, 255 bytes
53                         new string ('a', 255) + "\0\u00ff", // 257 chars, 256 bytes
54                         new string ('a', 256) + "\0\u00ff", // 258 chars, 257 bytes
55                 };
56
57                 bool HaveReadlinkAt;
58                 string TempFolder;
59                 int TempFD;
60
61                 [SetUp]
62                 public void SetUp ()
63                 {
64                         HaveReadlinkAt = false;
65                         try {
66                                 Syscall.readlinkat (-1, "", new byte[1]);
67                                 HaveReadlinkAt = true;
68                         } catch (EntryPointNotFoundException) {
69                         }
70
71
72                         TempFolder = Path.Combine (Path.GetTempPath (), this.GetType ().FullName);
73
74                         if (Directory.Exists (TempFolder))
75                                 //Directory.Delete (TempFolder, true); // Fails for long link target paths
76                                 new UnixDirectoryInfo (TempFolder).Delete (true);
77
78                         Directory.CreateDirectory (TempFolder);
79
80                         TempFD = Syscall.open (TempFolder, OpenFlags.O_RDONLY | OpenFlags.O_DIRECTORY);
81                         if (TempFD < 0)
82                                 UnixMarshal.ThrowExceptionForLastError ();
83                 }
84
85                 [TearDown]
86                 public void TearDown()
87                 {
88                         if (Syscall.close (TempFD) < 0)
89                                 UnixMarshal.ThrowExceptionForLastError ();
90
91                         if (Directory.Exists (TempFolder))
92                                 //Directory.Delete (TempFolder, true); // Fails for long link target paths
93                                 new UnixDirectoryInfo (TempFolder).Delete (true);
94                 }
95
96                 void CreateLink (string s)
97                 {
98                                 string link = UnixPath.Combine (TempFolder, "link");
99
100                                 //File.Delete (link); // Fails for long link target paths
101                                 if (Syscall.unlink (link) < 0 && Stdlib.GetLastError () != Errno.ENOENT)
102                                         UnixMarshal.ThrowExceptionForLastError ();
103
104                                 if (Syscall.symlink (s, link) < 0)
105                                         UnixMarshal.ThrowExceptionForLastError ();
106                 }
107
108                 [Test]
109                 public void ReadLink ()
110                 {
111                         foreach (string s in Targets) {
112                                 string link = UnixPath.Combine (TempFolder, "link");
113
114                                 CreateLink (s);
115
116                                 var target = UnixPath.ReadLink (link);
117                                 Assert.AreEqual (s, target);
118                         }
119                 }
120
121                 [Test]
122                 public void ReadLinkAt ()
123                 {
124                         if (!HaveReadlinkAt)
125                                 Assert.Ignore ("No ReadlinkAt.");
126
127                         foreach (string s in Targets) {
128                                 CreateLink (s);
129
130                                 var target = UnixPath.ReadLinkAt (TempFD, "link");
131                                 Assert.AreEqual (s, target);
132                         }
133                 }
134
135                 [Test]
136                 public void TryReadLink ()
137                 {
138                         foreach (string s in Targets) {
139                                 string link = UnixPath.Combine (TempFolder, "link");
140
141                                 CreateLink (s);
142
143                                 var target = UnixPath.TryReadLink (link);
144                                 Assert.AreEqual (s, target);
145                         }
146                 }
147
148                 [Test]
149                 public void TryReadLinkAt ()
150                 {
151                         if (!HaveReadlinkAt)
152                                 Assert.Ignore ("No ReadlinkAt.");
153
154                         foreach (string s in Targets) {
155                                 CreateLink (s);
156
157                                 var target = UnixPath.TryReadLinkAt (TempFD, "link");
158                                 Assert.AreEqual (s, target);
159                         }
160                 }
161
162                 [Test]
163                 public void readlink_byte ()
164                 {
165                         foreach (string s in Targets) {
166                                 string link = UnixPath.Combine (TempFolder, "link");
167
168                                 CreateLink (s);
169
170                                 string target = null;
171                                 byte[] buf = new byte[256];
172                                 do {
173                                         long r = Syscall.readlink (link, buf);
174                                         if (r < 0)
175                                                 UnixMarshal.ThrowExceptionForLastError ();
176                                         Assert.That(buf.Length, Is.GreaterThanOrEqualTo(r));
177                                         if (r == buf.Length)
178                                                 buf = new byte[checked (buf.Length * 2)];
179                                         else
180                                                 target = UnixEncoding.Instance.GetString (buf, 0, checked ((int) r));
181                                 } while (target == null);
182
183                                 Assert.AreEqual (s, target);
184                         }
185                 }
186
187                 [Test]
188                 public void readlinkat_byte ()
189                 {
190                         if (!HaveReadlinkAt)
191                                 Assert.Ignore ("No ReadlinkAt.");
192
193                         foreach (string s in Targets) {
194                                 CreateLink (s);
195
196                                 string target = null;
197                                 byte[] buf = new byte[256];
198                                 do {
199                                         long r = Syscall.readlinkat (TempFD, "link", buf);
200                                         if (r < 0)
201                                                 UnixMarshal.ThrowExceptionForLastError ();
202                                         Assert.That(buf.Length, Is.GreaterThanOrEqualTo(r));
203                                         if (r == buf.Length)
204                                                 buf = new byte[checked (buf.Length * 2)];
205                                         else
206                                                 target = UnixEncoding.Instance.GetString (buf, 0, checked ((int) r));
207                                 } while (target == null);
208
209                                 Assert.AreEqual (s, target);
210                         }
211                 }
212
213                 [Test]
214                 public void readlink_char ()
215                 {
216                         foreach (string s in Targets) {
217                                 string link = UnixPath.Combine (TempFolder, "link");
218
219                                 CreateLink (s);
220
221                                 var sb = new StringBuilder (256);
222                                 do {
223                                         int oldCapacity = sb.Capacity;
224                                         int r = Syscall.readlink (link, sb);
225                                         Assert.AreEqual (oldCapacity, sb.Capacity);
226                                         if (r < 0)
227                                                 UnixMarshal.ThrowExceptionForLastError ();
228                                         Assert.AreEqual (r, sb.Length);
229                                         Assert.That(sb.Capacity, Is.GreaterThanOrEqualTo(r));
230                                         if (r == sb.Capacity)
231                                                 checked { sb.Capacity *= 2; }
232                                         else
233                                                 break;
234                                 } while (true);
235                                 var target = sb.ToString ();
236
237                                 Assert.AreEqual (s, target);
238                         }
239                 }
240
241                 [Test]
242                 public void readlinkat_char ()
243                 {
244                         if (!HaveReadlinkAt)
245                                 Assert.Ignore ("No ReadlinkAt.");
246
247                         foreach (string s in Targets) {
248                                 CreateLink (s);
249
250                                 var sb = new StringBuilder (256);
251                                 do {
252                                         int oldCapacity = sb.Capacity;
253                                         int r = Syscall.readlinkat (TempFD, "link", sb);
254                                         Assert.AreEqual (oldCapacity, sb.Capacity);
255                                         if (r < 0)
256                                                 UnixMarshal.ThrowExceptionForLastError ();
257                                         Assert.AreEqual (r, sb.Length);
258                                         Assert.That(sb.Capacity, Is.GreaterThanOrEqualTo(r));
259                                         if (r == sb.Capacity)
260                                                 checked { sb.Capacity *= 2; }
261                                         else
262                                                 break;
263                                 } while (true);
264                                 var target = sb.ToString ();
265
266                                 Assert.AreEqual (s, target);
267                         }
268                 }
269
270                 [Test]
271                 public void ReadlinkMultiByteChar ()
272                 {
273                         string link = UnixPath.Combine (TempFolder, "link");
274
275                         CreateLink ("á");
276
277                         var sb = new StringBuilder (2);
278                         int res = Syscall.readlink (link, sb);
279                         if (res < 0)
280                                 UnixMarshal.ThrowExceptionForLastError ();
281
282                         Assert.AreEqual (res, 2);
283                         Assert.AreEqual (sb.Length, 2);
284                         Assert.AreEqual (sb.Capacity, 2);
285                         Assert.AreEqual (sb.ToString (), "á\u0000");
286                 }
287         }
288 }