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 System.Diagnostics; 6 using Xunit; 7 8 namespace System.IO.Tests 9 { 10 public abstract partial class FileSystemTest : RemoteExecutorTestBase 11 { 12 public static readonly byte[] TestBuffer = { 0xBA, 0x5E, 0xBA, 0x11, 0xF0, 0x07, 0xBA, 0x11 }; 13 14 protected const TestPlatforms CaseInsensitivePlatforms = TestPlatforms.Windows | TestPlatforms.OSX; 15 protected const TestPlatforms CaseSensitivePlatforms = TestPlatforms.AnyUnix & ~TestPlatforms.OSX; 16 17 public static bool AreAllLongPathsAvailable => PathFeatures.AreAllLongPathsAvailable(); 18 19 public static bool LongPathsAreNotBlocked => !PathFeatures.AreLongPathsBlocked(); 20 21 public static bool UsingNewNormalization => !PathFeatures.IsUsingLegacyPathNormalization(); 22 23 public static TheoryData<string> PathsWithInvalidColons = TestData.PathsWithInvalidColons; 24 public static TheoryData<string> PathsWithInvalidCharacters = TestData.PathsWithInvalidCharacters; 25 public static TheoryData<char> TrailingCharacters = TestData.TrailingCharacters; 26 public static TheoryData ValidPathComponentNames = IOInputs.GetValidPathComponentNames().ToTheoryData(); 27 public static TheoryData SimpleWhiteSpace = IOInputs.GetSimpleWhiteSpace().ToTheoryData(); 28 public static TheoryData WhiteSpace = IOInputs.GetWhiteSpace().ToTheoryData(); 29 public static TheoryData UncPathsWithoutShareName = IOInputs.GetUncPathsWithoutShareName().ToTheoryData(); 30 public static TheoryData PathsWithReservedDeviceNames = IOInputs.GetPathsWithReservedDeviceNames().ToTheoryData(); 31 public static TheoryData PathsWithAlternativeDataStreams = IOInputs.GetPathsWithAlternativeDataStreams().ToTheoryData(); 32 public static TheoryData PathsWithComponentLongerThanMaxComponent = IOInputs.GetPathsWithComponentLongerThanMaxComponent().ToTheoryData(); 33 public static TheoryData ControlWhiteSpace = IOInputs.GetControlWhiteSpace().ToTheoryData(); 34 public static TheoryData NonControlWhiteSpace = IOInputs.GetNonControlWhiteSpace().ToTheoryData(); 35 36 /// <summary> 37 /// In some cases (such as when running without elevated privileges), 38 /// the symbolic link may fail to create. Only run this test if it creates 39 /// links successfully. 40 /// </summary> 41 protected static bool CanCreateSymbolicLinks => s_canCreateSymbolicLinks.Value; 42 43 private static readonly Lazy<bool> s_canCreateSymbolicLinks = new Lazy<bool>(() => 44 { 45 // Verify file symlink creation 46 string path = Path.GetTempFileName(); 47 string linkPath = path + ".link"; 48 bool success = MountHelper.CreateSymbolicLink(linkPath, path, isDirectory: false); 49 try { File.Delete(path); } catch { } 50 try { File.Delete(linkPath); } catch { } 51 52 // Verify directory symlink creation 53 path = Path.GetTempFileName(); 54 linkPath = path + ".link"; 55 success = success && MountHelper.CreateSymbolicLink(linkPath, path, isDirectory: true); 56 try { Directory.Delete(path); } catch { } 57 try { Directory.Delete(linkPath); } catch { } 58 59 return success; 60 }); 61 GetNamedPipeServerStreamName()62 protected string GetNamedPipeServerStreamName() 63 { 64 if (PlatformDetection.IsInAppContainer) 65 { 66 return @"LOCAL\" + Guid.NewGuid().ToString("N"); 67 } 68 return Guid.NewGuid().ToString("N"); 69 } 70 71 /// <summary> 72 /// Do a test action against read only file system (for Unix). 73 /// </summary> 74 /// <param name="testAction">Test action to perform. The string argument will be read only directory.</param> 75 /// <param name="subDirectoryName">Optional subdirectory to create.</param> ReadOnly_FileSystemHelper(Action<string> testAction, string subDirectoryName = null)76 protected void ReadOnly_FileSystemHelper(Action<string> testAction, string subDirectoryName = null) 77 { 78 // Set up read only file system 79 // Set up the source directory 80 string sourceDirectory = GetTestFilePath(); 81 if (subDirectoryName == null) 82 { 83 Directory.CreateDirectory(sourceDirectory); 84 } 85 else 86 { 87 string sourceSubDirectory = Path.Combine(sourceDirectory, subDirectoryName); 88 Directory.CreateDirectory(sourceSubDirectory); 89 } 90 91 // Set up the target directory and mount as a read only 92 string readOnlyDirectory = GetTestFilePath(); 93 Directory.CreateDirectory(readOnlyDirectory); 94 95 Assert.Equal(0, AdminHelpers.RunAsSudo($"mount --bind {sourceDirectory} {readOnlyDirectory}")); 96 97 try 98 { 99 Assert.Equal(0, AdminHelpers.RunAsSudo($"mount -o remount,ro,bind {sourceDirectory} {readOnlyDirectory}")); 100 testAction(readOnlyDirectory); 101 } 102 finally 103 { 104 // Clean up test environment 105 Assert.Equal(0, AdminHelpers.RunAsSudo($"umount {readOnlyDirectory}")); 106 } 107 } 108 } 109 } 110