1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 
5 using Xunit;
6 
7 namespace System.IO.Tests
8 {
9     public class File_Create_str : FileSystemTest
10     {
11         #region Utilities
12 
Create(string path)13         public virtual FileStream Create(string path)
14         {
15             return File.Create(path);
16         }
17 
18         #endregion
19 
20         #region UniversalTests
21 
22         [Fact]
NullPath()23         public void NullPath()
24         {
25             Assert.Throws<ArgumentNullException>(() => Create(null));
26         }
27 
28         [Fact]
EmptyPath()29         public void EmptyPath()
30         {
31             Assert.Throws<ArgumentException>(() => Create(string.Empty));
32         }
33 
34         [Fact]
NonExistentPath()35         public void NonExistentPath()
36         {
37             Assert.Throws<DirectoryNotFoundException>(() => Create(Path.Combine(TestDirectory, GetTestFileName(), GetTestFileName())));
38         }
39 
40         [Fact]
CreateCurrentDirectory()41         public void CreateCurrentDirectory()
42         {
43             Assert.Throws<UnauthorizedAccessException>(() => Create("."));
44         }
45 
46         [Fact]
ValidCreation()47         public void ValidCreation()
48         {
49             DirectoryInfo testDir = Directory.CreateDirectory(GetTestFilePath());
50             string testFile = Path.Combine(testDir.FullName, GetTestFileName());
51             using (FileStream stream = Create(testFile))
52             {
53                 Assert.True(File.Exists(testFile));
54                 Assert.Equal(0, stream.Length);
55                 Assert.Equal(0, stream.Position);
56             }
57         }
58 
59         [ConditionalFact(nameof(UsingNewNormalization))]
60         [PlatformSpecific(TestPlatforms.Windows)]  // Valid Windows path extended prefix
ValidCreation_ExtendedSyntax()61         public void ValidCreation_ExtendedSyntax()
62         {
63             DirectoryInfo testDir = Directory.CreateDirectory(IOInputs.ExtendedPrefix + GetTestFilePath());
64             Assert.StartsWith(IOInputs.ExtendedPrefix, testDir.FullName);
65             string testFile = Path.Combine(testDir.FullName, GetTestFileName());
66             using (FileStream stream = Create(testFile))
67             {
68                 Assert.True(File.Exists(testFile));
69                 Assert.Equal(0, stream.Length);
70                 Assert.Equal(0, stream.Position);
71             }
72         }
73 
74         [ConditionalFact(nameof(AreAllLongPathsAvailable))]
75         [PlatformSpecific(TestPlatforms.Windows)]  // Valid Windows path extended prefix, long path
ValidCreation_LongPathExtendedSyntax()76         public void ValidCreation_LongPathExtendedSyntax()
77         {
78             DirectoryInfo testDir = Directory.CreateDirectory(IOServices.GetPath(IOInputs.ExtendedPrefix + TestDirectory, characterCount: 500));
79             Assert.StartsWith(IOInputs.ExtendedPrefix, testDir.FullName);
80             string testFile = Path.Combine(testDir.FullName, GetTestFileName());
81             using (FileStream stream = Create(testFile))
82             {
83                 Assert.True(File.Exists(testFile));
84                 Assert.Equal(0, stream.Length);
85                 Assert.Equal(0, stream.Position);
86             }
87         }
88 
89         [Fact]
CreateInParentDirectory()90         public void CreateInParentDirectory()
91         {
92             string testFile = GetTestFileName();
93             using (FileStream stream = Create(Path.Combine(TestDirectory, "DoesntExists", "..", testFile)))
94             {
95                 Assert.True(File.Exists(Path.Combine(TestDirectory, testFile)));
96             }
97         }
98 
99         [Fact]
LegalSymbols()100         public void LegalSymbols()
101         {
102             DirectoryInfo testDir = Directory.CreateDirectory(GetTestFilePath());
103             string testFile = Path.Combine(testDir.FullName, GetTestFileName() + "!@#$%^&");
104             using (FileStream stream = Create(testFile))
105             {
106                 Assert.True(File.Exists(testFile));
107             }
108         }
109 
110         [Fact]
InvalidDirectory()111         public void InvalidDirectory()
112         {
113             DirectoryInfo testDir = Directory.CreateDirectory(GetTestFilePath());
114             string testFile = Path.Combine(testDir.FullName, GetTestFileName(), GetTestFileName());
115             Assert.Throws<DirectoryNotFoundException>(() => Create(testFile));
116         }
117 
118         [Fact]
FileInUse()119         public void FileInUse()
120         {
121             DirectoryInfo testDir = Directory.CreateDirectory(GetTestFilePath());
122             string testFile = Path.Combine(testDir.FullName, GetTestFileName());
123             using (FileStream stream = Create(testFile))
124             {
125                 Assert.True(File.Exists(testFile));
126                 Assert.Throws<IOException>(() => Create(testFile));
127             }
128         }
129 
130         [Fact]
FileAlreadyExists()131         public void FileAlreadyExists()
132         {
133             DirectoryInfo testDir = Directory.CreateDirectory(GetTestFilePath());
134             string testFile = Path.Combine(testDir.FullName, GetTestFileName());
135             Create(testFile).Dispose();
136             Assert.True(File.Exists(testFile));
137             Create(testFile).Dispose();
138             Assert.True(File.Exists(testFile));
139         }
140 
141         [Fact]
OverwriteReadOnly()142         public void OverwriteReadOnly()
143         {
144             DirectoryInfo testDir = Directory.CreateDirectory(GetTestFilePath());
145             string testFile = Path.Combine(testDir.FullName, GetTestFileName());
146             Create(testFile).Dispose();
147             Assert.True(File.Exists(testFile));
148             Create(testFile).Dispose();
149             Assert.True(File.Exists(testFile));
150         }
151 
152         [Fact]
LongPathSegment()153         public void LongPathSegment()
154         {
155             DirectoryInfo testDir = Directory.CreateDirectory(GetTestFilePath());
156 
157             // Long path should throw PathTooLongException on Desktop and IOException
158             // elsewhere.
159             if (PlatformDetection.IsFullFramework)
160             {
161                 Assert.Throws<PathTooLongException>(
162                     () => Create(Path.Combine(testDir.FullName, new string('a', 300))));
163             }
164             else
165             {
166                 AssertExtensions.ThrowsAny<IOException, DirectoryNotFoundException, PathTooLongException>(
167                     () => Create(Path.Combine(testDir.FullName, new string('a', 300))));
168             }
169         }
170 
171         #endregion
172 
173         #region PlatformSpecific
174 
175         [Fact]
176         [PlatformSpecific(CaseSensitivePlatforms)]
CaseSensitive()177         public void CaseSensitive()
178         {
179             DirectoryInfo testDir = Directory.CreateDirectory(GetTestFilePath());
180             string testFile = Path.Combine(testDir.FullName, GetTestFileName());
181             using (File.Create(testFile + "AAAA"))
182             using (File.Create(testFile + "aAAa"))
183             {
184                 Assert.False(File.Exists(testFile + "AaAa"));
185                 Assert.True(File.Exists(testFile + "AAAA"));
186                 Assert.True(File.Exists(testFile + "aAAa"));
187                 Assert.Equal(2, Directory.GetFiles(testDir.FullName).Length);
188             }
189             Assert.Throws<DirectoryNotFoundException>(() => File.Create(testFile.ToLowerInvariant()));
190         }
191 
192         [Fact]
193         [PlatformSpecific(CaseInsensitivePlatforms)]
CaseInsensitive()194         public void CaseInsensitive()
195         {
196             DirectoryInfo testDir = Directory.CreateDirectory(GetTestFilePath());
197             string testFile = Path.Combine(testDir.FullName, GetTestFileName());
198             File.Create(testFile + "AAAA").Dispose();
199             File.Create(testFile.ToLowerInvariant() + "aAAa").Dispose();
200             Assert.Equal(1, Directory.GetFiles(testDir.FullName).Length);
201         }
202 
203         [Fact]
204         [PlatformSpecific(TestPlatforms.Windows)] // Invalid file name with wildcard characters on Windows
WindowsWildCharacterPath()205         public void WindowsWildCharacterPath()
206         {
207             DirectoryInfo testDir = Directory.CreateDirectory(GetTestFilePath());
208             Assert.Throws<ArgumentException>(() => Create(Path.Combine(testDir.FullName, "dls;d", "442349-0", "v443094(*)(+*$#$*", new string(Path.DirectorySeparatorChar, 3))));
209             Assert.Throws<ArgumentException>(() => Create(Path.Combine(testDir.FullName, "*")));
210             Assert.Throws<ArgumentException>(() => Create(Path.Combine(testDir.FullName, "Test*t")));
211             Assert.Throws<ArgumentException>(() => Create(Path.Combine(testDir.FullName, "*Tes*t")));
212         }
213 
214         [Theory,
215             InlineData("         "),
216             InlineData(" "),
217             InlineData("\n"),
218             InlineData(">"),
219             InlineData("<"),
220             InlineData("\0"),
221             InlineData("\t")]
222         [PlatformSpecific(TestPlatforms.Windows)]  // Invalid file name with whitespace on Windows
WindowsWhitespacePath(string path)223         public void WindowsWhitespacePath(string path)
224         {
225             Assert.Throws<ArgumentException>(() => Create(path));
226         }
227 
228         [Fact]
229         [PlatformSpecific(TestPlatforms.AnyUnix)]
CreateNullThrows_Unix()230         public void CreateNullThrows_Unix()
231         {
232             Assert.Throws<ArgumentException>(() => Create("\0"));
233         }
234 
235         [Theory,
236             InlineData("         "),
237             InlineData(" "),
238             InlineData("\n"),
239             InlineData(">"),
240             InlineData("<"),
241             InlineData("\t")]
242         [PlatformSpecific(TestPlatforms.AnyUnix)]  // Valid file name with Whitespace on Unix
UnixWhitespacePath(string path)243         public void UnixWhitespacePath(string path)
244         {
245             DirectoryInfo testDir = Directory.CreateDirectory(GetTestFilePath());
246             using (Create(Path.Combine(testDir.FullName, path)))
247             {
248                 Assert.True(File.Exists(Path.Combine(testDir.FullName, path)));
249             }
250         }
251 
252         #endregion
253     }
254 
255     public class File_Create_str_i : File_Create_str
256     {
Create(string path)257         public override FileStream Create(string path)
258         {
259             return File.Create(path, 4096); // Default buffer size
260         }
261 
Create(string path, int bufferSize)262         public virtual FileStream Create(string path, int bufferSize)
263         {
264             return File.Create(path, bufferSize);
265         }
266 
267         [Fact]
NegativeBuffer()268         public void NegativeBuffer()
269         {
270             Assert.Throws<ArgumentOutOfRangeException>(() => Create(GetTestFilePath(), -1));
271             Assert.Throws<ArgumentOutOfRangeException>(() => Create(GetTestFilePath(), -100));
272         }
273     }
274 
275     public class File_Create_str_i_fo : File_Create_str_i
276     {
Create(string path)277         public override FileStream Create(string path)
278         {
279             return File.Create(path, 4096, FileOptions.Asynchronous);
280         }
281 
Create(string path, int bufferSize)282         public override FileStream Create(string path, int bufferSize)
283         {
284             return File.Create(path, bufferSize, FileOptions.Asynchronous);
285         }
286     }
287 }
288