AdlsDotNetSDKUnitTest/SdkUnitTest.cs (2,683 lines of code) (raw):

using Microsoft.Azure.DataLake.Store.Acl; using Microsoft.VisualStudio.TestTools.UnitTesting; using Azure.Core; using Azure.Identity; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; namespace Microsoft.Azure.DataLake.Store.UnitTest { [TestClass] public class SdkUnitTest { internal static readonly string TestId = Guid.NewGuid().ToString(); private static AdlsClient _adlsClient; private static readonly Random Random = new Random(); /// <summary> /// Full Account domain name /// </summary> private static string _accntName; /// <summary> /// Owner service principal object Id /// </summary> private static string _ownerObjectId; /// <summary> /// Owner App Id /// </summary> private static string _ownerClientId; /// <summary> /// Owner App secret key /// </summary> private static string _ownerClientSecret; /// <summary> /// NonOwner1 service principal object Id /// </summary> internal static string NonOwner1ObjectId; /// <summary> /// NonOwner1 app id /// </summary> private static string _nonOwner1ClientId; /// <summary> /// Nonowner1 app secret key /// </summary> private static string _nonOwner1ClientSecret; /// <summary> /// NonOwner2 service principal object Id /// </summary> internal static string NonOwner2ObjectId; /// <summary> /// NonOwner2 app id /// </summary> private static string _nonOwner2ClientId; /// <summary> /// Nonowner2 app secret key /// </summary> private static string _nonOwner2ClientSecret; /// <summary> /// NonOwner3 service principal object Id /// </summary> internal static string NonOwner3ObjectId; /// <summary> /// NonOwner3 app id /// </summary> private static string _nonOwner3ClientId; /// <summary> /// Nonowner3 app secret key /// </summary> private static string _nonOwner3ClientSecret; /// <summary> /// Group1 Id- Group 1 should include nonowner2 and nonowner3 /// </summary> internal static string Group1Id; /// <summary> /// Tenant Id /// </summary> private static string _domain; private static string _dogFoodAuthEndPoint; private static bool _isAccountTieredStore; private static bool _isFailureExpectedOnColon = false; private static string BasePath; private static string UnitTestDir; public static string RandomString(int length) { const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; return new string(Enumerable.Repeat(chars, length) .Select(s => s[Random.Next(s.Length)]).ToArray()); } /// <summary> /// Sets up the unit test /// </summary> /// <param name="context"></param> [AssemblyInitialize] public static void SetupUnitTest(TestContext context) { BasePath = context.Properties["BasePath"].ToString(); UnitTestDir = "/" + BasePath + "/Test" + TestId; _accntName = context.Properties["Account"].ToString(); _ownerObjectId = (string)context.Properties["AccountOwnerObjectId"]; _ownerClientId = (string)context.Properties["AccountOwnerClientId"]; _ownerClientSecret = (string)context.Properties["AccountOwnerClientSecret"]; NonOwner1ObjectId = (string)context.Properties["NonOwner1ObjectId"]; _nonOwner1ClientId = (string)context.Properties["NonOwner1ClientId"]; _nonOwner1ClientSecret = (string)context.Properties["NonOwner1ClientSecret"]; NonOwner2ObjectId = (string)context.Properties["NonOwner2ObjectId"]; _nonOwner2ClientId = (string)context.Properties["NonOwner2ClientId"]; _nonOwner2ClientSecret = (string)context.Properties["NonOwner2ClientSecret"]; NonOwner3ObjectId = (string)context.Properties["NonOwner3ObjectId"]; _nonOwner3ClientId = (string)context.Properties["NonOwner3ClientId"]; _nonOwner3ClientSecret = (string)context.Properties["NonOwner3ClientSecret"]; Group1Id = (string)context.Properties["Group1Id"]; _domain = (string)context.Properties["Domain"]; _dogFoodAuthEndPoint = (string)context.Properties["DogFoodAuthenticationEndPoint"]; _isAccountTieredStore = bool.Parse((string)context.Properties["IsAccountTieredStore"]); _isFailureExpectedOnColon = bool.Parse((string)context.Properties["FailureExpectedOnColon"]); ServicePointManager.DefaultConnectionLimit = AdlsClient.DefaultNumThreads; string tlsEnabled = (string)context.Properties["TlsEnabled"]; if (!string.IsNullOrEmpty(tlsEnabled) && bool.Parse(tlsEnabled)) { ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; } } /// <summary> /// Setup the client, empties the test directory /// </summary> /// <param name="context"></param> [ClassInitialize] public static void SetupTest(TestContext context) { _adlsClient = SetupSuperClient(); _adlsClient.DeleteRecursive(UnitTestDir); _adlsClient.CreateDirectory(UnitTestDir); _adlsClient.RemoveAllAcls(UnitTestDir); var nonOwnerAclSpec = new List<AclEntry> { new AclEntry(AclType.user, NonOwner1ObjectId, AclScope.Access, AclAction.ExecuteOnly), new AclEntry(AclType.user, NonOwner2ObjectId, AclScope.Access, AclAction.ExecuteOnly), new AclEntry(AclType.user, NonOwner3ObjectId, AclScope.Access, AclAction.ExecuteOnly), new AclEntry(AclType.group, Group1Id, AclScope.Access, AclAction.ExecuteOnly) }; _adlsClient.ModifyAclEntries("/", nonOwnerAclSpec); _adlsClient.ModifyAclEntries(UnitTestDir, nonOwnerAclSpec); } #region Setup /// <summary> /// Setup client from the super owner of the account /// </summary> /// <returns>AdlsClient</returns> internal static AdlsClient SetupSuperClient() { string clientId = _ownerClientId; string clientSecret = _ownerClientSecret; return SetupCommonClient(clientId, clientSecret); } /// <summary> /// Setup client from a app that is not owner of the account /// </summary> /// <returns>ADls Client</returns> private static AdlsClient SetupNonOwnerClient1() { string clientId = _nonOwner1ClientId; string clientSecret = _nonOwner1ClientSecret; return SetupCommonClient(clientId, clientSecret); } /// <summary> /// Setup client from a app that is not owner of the account /// </summary> /// <returns>ADls Client</returns> private static AdlsClient SetupNonOwnerClient2() { string clientId = _nonOwner2ClientId; string clientSecret = _nonOwner2ClientSecret; return SetupCommonClient(clientId, clientSecret); } /// <summary> /// Setup client from a app that is not owner of the account /// </summary> /// <returns>ADls Client</returns> private static AdlsClient SetupNonOwnerClient3() { string clientId = _nonOwner3ClientId; string clientSecret = _nonOwner3ClientSecret; return SetupCommonClient(clientId, clientSecret); } /// <summary> /// Sets up a ADLS client /// </summary> /// <param name="clientId">Client Id of the App</param> /// <param name="clientSecret">Client Secret</param> /// <returns></returns> private static AdlsClient SetupCommonClient(string clientId, string clientSecret) { string clientAccountPath = _accntName; AdlsClient client; if (clientAccountPath.EndsWith("azuredatalakestore.net")) { var clientCreds = new ClientSecretCredential(_domain, clientId, clientSecret); client = AdlsClient.CreateClient(clientAccountPath, clientCreds); } else { var serviceSettings = new TokenCredentialOptions(); serviceSettings.AuthorityHost = new Uri(_dogFoodAuthEndPoint); string[] scopes = new string[] { "https://management.core.windows.net//.default" }; var clientCreds = new ClientSecretCredential(_domain, clientId, clientSecret, serviceSettings); client = AdlsClient.CreateClient(clientAccountPath, clientCreds, scopes); } return client; } private static string GetFileOrFolderName(string type) { var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; Random random = new Random(); string name = ""; for (int i = 0; i < 16; i++) { name += chars[random.Next(chars.Length)]; } if(type.Contains("file")) { name = "file_" + name + ".txt"; } else if(type.Contains("directory")) { name = "dir_" + name; } return name; } private static void SetupTrashFile(string name, string type) { string path = $"{UnitTestDir}/" + name; bool result; if (type.Contains("file")) { _adlsClient.CreateFile(path, IfExists.Overwrite, "732"); } else { result = _adlsClient.CreateDirectory(path, "777" ); Assert.IsTrue(result); } result = _adlsClient.Delete(path); Assert.IsTrue(result); } #endregion [TestMethod] public void TestRequestIdException() { string path = $"{UnitTestDir}/testRequestIdException.txt"; string text1 = "I am the first line"; byte[] textByte1 = Encoding.UTF8.GetBytes(text1); using (var ostream = _adlsClient.CreateFile(path, IfExists.Overwrite, "")) { ostream.Write(textByte1, 0, textByte1.Length); } var response=new OperationResponse(); Core.Append(path,"","",SyncFlag.DATA,0,textByte1,0,textByte1.Length,_adlsClient,new RequestOptions(),response ); Assert.IsTrue(!response.IsSuccessful); Assert.IsTrue(response.RequestId != null); } #region TestCreate [TestMethod] public void TestCreatePathWithColon() { string path = $"{UnitTestDir}/testCreateFile:8080"; try { _adlsClient.CreateDirectory(path); } catch(AdlsException ex) { Assert.IsFalse(ex.Message.Contains('\0')); if (!_isFailureExpectedOnColon) { Assert.Fail(); } } } /// <summary> /// Unit test for creating a directory using ADL SDK /// </summary> [TestMethod] public void TestCreateMakeDir() { string path = $"{UnitTestDir}/testDir"; string permission = "733"; bool result = _adlsClient.CreateDirectory(path, permission); Assert.IsTrue(result); DirectoryEntry diren = _adlsClient.GetDirectoryEntry(path); Assert.IsTrue(!string.IsNullOrEmpty(diren.Name)); Assert.IsTrue(diren.Name == "testDir"); Assert.IsTrue(!string.IsNullOrEmpty(diren.FullName)); Assert.IsTrue(diren.Type == DirectoryEntryType.DIRECTORY); Assert.IsTrue(diren.Permission.Equals(permission)); Assert.IsTrue(diren.Length == 0); } /// <summary> /// Unit test for trying to create a file /// Flag for not creating the parent /// The directories in the path does not exist /// </summary> [TestMethod] [ExpectedException(typeof(AdlsException))] public void TestCreateFileExceptionCreateParent() { string path = $"{UnitTestDir}/dir2/testCreateParentException.txt"; _adlsClient.CreateFile(path, IfExists.Fail, null, false); Assert.Fail("Parent folder does not exist so create should throw an exception"); } /// <summary> /// Unit test for trying to create a file /// Flag for not overwriting if the file exists /// The file exists /// </summary> [TestMethod] [ExpectedException(typeof(AdlsException))] public void TestCreateFileExceptionOverwrite() { string path = $"{UnitTestDir}/testCreateOverwriteException.txt"; using (_adlsClient.CreateFile(path, IfExists.Fail)) { } using (_adlsClient.CreateFile(path, IfExists.Fail)) { } Assert.Fail("File already exists so creating file in non-overwrite mode should throw exception"); } /// <summary> /// Unit test for trying to create a file /// Permission is not valid /// </summary> [TestMethod] [ExpectedException(typeof(AdlsException))] public void TestCreateFileExceptionPermission() { string path = $"{UnitTestDir}/testCreatePermissionException.txt"; using (_adlsClient.CreateFile(path, IfExists.Fail, "3-12")) { } Assert.Fail("Permission is invalid so create file should throw an exception"); } /// <summary> /// Unit test for successfully creating a file /// </summary> [TestMethod] [DataRow(true)] public void TestCreate(bool useConditinalOverwrite) { string path = $"{UnitTestDir}/testCreate.txt"; _adlsClient.SetConditionalCreateWithOverwrite(useConditinalOverwrite); using (_adlsClient.CreateFile(path, IfExists.Overwrite, "732")) { } DirectoryEntry diren = _adlsClient.GetDirectoryEntry(path); Assert.IsTrue(!string.IsNullOrEmpty(diren.Name)); Assert.IsTrue(diren.Name== "testCreate.txt"); Assert.IsTrue(!string.IsNullOrEmpty(diren.FullName)); Assert.IsTrue(diren.FullName.Equals(path)); Assert.IsTrue(diren.Length == 0); Assert.IsTrue(!diren.HasAcl); Assert.IsTrue(diren.Type == DirectoryEntryType.FILE); Assert.IsTrue(diren.Permission.Equals("732")); _adlsClient.SetConditionalCreateWithOverwrite(!useConditinalOverwrite); } /// <summary> /// Unit test for successfully creating a file /// </summary> [TestMethod] [DataRow(true)] public void TestCreateWithOverwrite(bool useConditinalOverwrite) { string path = $"{UnitTestDir}/testCreate.txt"; _adlsClient.SetConditionalCreateWithOverwrite(useConditinalOverwrite); using (_adlsClient.CreateFile(path, IfExists.Overwrite, "732")) { } using (_adlsClient.CreateFile(path, IfExists.Overwrite, "732")) { } DirectoryEntry diren = _adlsClient.GetDirectoryEntry(path); Assert.IsTrue(!string.IsNullOrEmpty(diren.Name)); Assert.IsTrue(diren.Name== "testCreate.txt"); Assert.IsTrue(!string.IsNullOrEmpty(diren.FullName)); Assert.IsTrue(diren.FullName.Equals(path)); Assert.IsTrue(diren.Length == 0); Assert.IsTrue(!diren.HasAcl); Assert.IsTrue(diren.Type == DirectoryEntryType.FILE); Assert.IsTrue(diren.Permission.Equals("732")); _adlsClient.SetConditionalCreateWithOverwrite(!useConditinalOverwrite); } [TestMethod] public void TestCreateFileWithControlCharacter() { string dir = $"{UnitTestDir}/ControlCharacterDir"; // The string below has a delete character in it 7F string unicodeFilename = dir + "/Cnt1-A_€__}_R_€_}_]_‚_ˆ_LA_„_}_L_R_X_‚_Z_]_€I_‚_Y_ƒ_‰_‚_[R_]_€_ƒ_Z_X_ˆ_}_ƒ_‚_LL_X_ˆ_]_‚_Z_."; try { using (_adlsClient.CreateFile(unicodeFilename, IfExists.Overwrite)) { Assert.Fail("This should throw an exception"); } } catch (AdlsException ex) { Assert.IsTrue(ex.HttpStatus == HttpStatusCode.BadRequest); Assert.IsTrue(ex.Ex.GetType().Name.Contains("JsonReaderException")); } } /// <summary> /// Unit test in creating a file with unicode name. Verify by reading the file. /// </summary> [TestMethod] public void TestCreateUnicodeFileName() { string dir = $"{UnitTestDir}/UnicodeDir"; string unicodeFilename = dir + "/ch+ ch.官話.官话.עברית.हिंदी.español.~`!@#$%^&*()_.+=-{}[]|;',.<>?.txt"; string text1 = RandomString(1024); byte[] textByte1 = Encoding.UTF8.GetBytes(text1); using (var ostream = _adlsClient.CreateFile(unicodeFilename, IfExists.Overwrite)) { ostream.Write(textByte1, 0, textByte1.Length); } string output = ""; using (var istream = _adlsClient.GetReadStream(unicodeFilename)) { int noOfBytes; byte[] buffer = new byte[1024 * 1024]; do { noOfBytes = istream.Read(buffer, 0, buffer.Length); output += Encoding.UTF8.GetString(buffer, 0, noOfBytes); } while (noOfBytes > 0); } Assert.IsTrue(output.Equals(text1)); try { _adlsClient.GetDirectoryEntry(unicodeFilename); } catch (IOException) { Assert.Fail("Directory entry list should not throw an exception"); } IEnumerable<DirectoryEntry> diren = _adlsClient.EnumerateDirectory(dir); bool isFound = false; foreach (var entry in diren) { if (entry.FullName.Equals(unicodeFilename)) { isFound = true; break; } } Assert.IsTrue(isFound); } #endregion #region Append /// <summary> /// Unit test for creating and riting in a file. Verifying it by reading the file. /// </summary> [TestMethod] [DataRow(true)] public void TestCreateAppend(bool useConditinalOverwrite) { _adlsClient.SetConditionalCreateWithOverwrite(useConditinalOverwrite); string path = $"{UnitTestDir}/testCreateAppend2.txt"; string text1 = "I am the first line.I am the first line.I am the first line.I am the first line.I am the first line.I am the first line.I am the first line.\n"; string text2 = "I am the second line.I am the second line.I am the second line.I am the second line.I am the second line.I am the second line.I am the second line."; byte[] textByte1 = Encoding.UTF8.GetBytes(text1); byte[] textByte2 = Encoding.UTF8.GetBytes(text2); using (var ostream = _adlsClient.CreateFile(path, IfExists.Overwrite, "")) { ostream.Write(textByte1, 0, textByte1.Length); ostream.Write(textByte2, 0, textByte2.Length); } string output = ""; using (Stream istream = _adlsClient.GetReadStream(path)) { int noOfBytes; byte[] buffer = new byte[25]; do { noOfBytes = istream.Read(buffer, 0, buffer.Length); output += Encoding.UTF8.GetString(buffer, 0, noOfBytes); } while (noOfBytes > 0); } Assert.IsTrue(output.Equals(text1 + text2)); _adlsClient.SetConditionalCreateWithOverwrite(!useConditinalOverwrite); } /// <summary> /// Unit test in trying to append to a non existing file /// </summary> [TestMethod] [ExpectedException(typeof(AdlsException))] public void TestAppendExceptionFile() { string path = $"{UnitTestDir}/testAppendNotExist.txt"; string text1 = RandomString(300); byte[] textByte1 = Encoding.UTF8.GetBytes(text1); using (var ostream = _adlsClient.GetAppendStream(path)) { ostream.Write(textByte1, 0, textByte1.Length); } Assert.Fail("Append for a non-existant file should throw an exception"); } /// <summary> /// Unit test to append multiple times of varying length and perform Flushes /// Verify by reading the file /// </summary> [TestMethod] public void TestAppendDifferentLengthsMultipleTimes() { string path = $"{UnitTestDir}/testAppendDifferentLengthMultipleTimes.txt"; int totLength = 22 * 1024 * 1024; string text1 = RandomString(totLength); byte[] textByte1 = Encoding.UTF8.GetBytes(text1); using (_adlsClient.CreateFile(path, IfExists.Overwrite, "")) { } using (var ostream = _adlsClient.GetAppendStream(path)) { ostream.Write(textByte1, 0, 3 * 1024 * 1024); ostream.Write(textByte1, 3 * 1024 * 1024, 2 * 1024 * 1024); ostream.Write(textByte1, 5 * 1024 * 1024, 5 * 1024 * 1024); ostream.Flush(); ostream.Write(textByte1, 10 * 1024 * 1024, 4 * 1024 * 1024); ostream.Flush(); ostream.Write(textByte1, 14 * 1024 * 1024, 8 * 1024 * 1024); } string output = ""; using (var istream = _adlsClient.GetReadStream(path)) { int noOfBytes; byte[] buffer = new byte[1024 * 1024]; do { noOfBytes = istream.Read(buffer, 0, buffer.Length); output += Encoding.UTF8.GetString(buffer, 0, noOfBytes); } while (noOfBytes > 0); } Assert.IsTrue(output.Equals(text1)); } /// <summary> /// Unit test to append multiple times of varying length /// Verify by reading the file /// </summary> [TestMethod] public void TestAppendDifferentLengthsMultipleTimes1() { string path = $"{UnitTestDir}/testAppendDifferentLengthMultipleTimes1.txt"; int totLength = 16 * 1024 * 1024; string text1 = RandomString(totLength); byte[] textByte1 = Encoding.UTF8.GetBytes(text1); using (_adlsClient.CreateFile(path, IfExists.Overwrite, "")) { } using (var ostream = _adlsClient.GetAppendStream(path)) { ostream.Write(textByte1, 0, 2 * 1024 * 1024); ostream.Write(textByte1, 2 * 1024 * 1024, 1 * 1024 * 1024); ostream.Write(textByte1, 3 * 1024 * 1024, 1 * 1024 * 1024); ostream.Write(textByte1, 4 * 1024 * 1024, 3 * 1024 * 1024); ostream.Write(textByte1, 7 * 1024 * 1024, 2 * 1024 * 1024); ostream.Write(textByte1, 9 * 1024 * 1024, 5 * 1024 * 1024); ostream.Write(textByte1, 14 * 1024 * 1024, 2 * 1024 * 1024); } string output = ""; using (var istream = _adlsClient.GetReadStream(path)) { int noOfBytes; byte[] buffer = new byte[1024 * 1024]; do { noOfBytes = istream.Read(buffer, 0, buffer.Length); output += Encoding.UTF8.GetString(buffer, 0, noOfBytes); } while (noOfBytes > 0); } Assert.IsTrue(output.Equals(text1)); } /// <summary> /// Unit test to create a file and open a appendstream and make one append to empty file. /// Verify by reading. /// </summary> [TestMethod] [DataRow(true)] public void TestAppendEmptyFile(bool useConditinalOverwrite) { _adlsClient.SetConditionalCreateWithOverwrite(useConditinalOverwrite); string path = $"{UnitTestDir}/testAppendEmptyFile.txt"; string text1 = RandomString(9 * 1024 * 1024); byte[] textByte1 = Encoding.UTF8.GetBytes(text1); using (_adlsClient.CreateFile(path, IfExists.Overwrite, "")) { } using (var ostream = _adlsClient.GetAppendStream(path)) { ostream.Write(textByte1, 0, textByte1.Length); } string output = ""; using (var istream = _adlsClient.GetReadStream(path)) { int noOfBytes; byte[] buffer = new byte[1024 * 1024]; do { noOfBytes = istream.Read(buffer, 0, buffer.Length); output += Encoding.UTF8.GetString(buffer, 0, noOfBytes); } while (noOfBytes > 0); } Assert.IsTrue(output.Equals(text1)); _adlsClient.SetConditionalCreateWithOverwrite(!useConditinalOverwrite); } /// <summary> /// Unit test to create a file and open a appendstream and make one append to empty file. /// Verify by reading. This is calling the async API. /// </summary> [TestMethod] public void TestAppendEmptyFileAsync() { string path = $"{UnitTestDir}/testAppendEmptyFileAsync.txt"; string text1 = RandomString(6 * 1024 * 1024); byte[] textByte1 = Encoding.UTF8.GetBytes(text1); using (_adlsClient.CreateFileAsync(path, IfExists.Overwrite, "").GetAwaiter().GetResult()) { } using (var ostream = _adlsClient.GetAppendStream(path)) { ostream.WriteAsync(textByte1, 0, textByte1.Length).GetAwaiter().GetResult(); } string output = ""; using (var istream = _adlsClient.GetReadStream(path)) { int noOfBytes; byte[] buffer = new byte[1024 * 1024]; do { noOfBytes = istream.ReadAsync(buffer, 0, buffer.Length).GetAwaiter().GetResult(); output += Encoding.UTF8.GetString(buffer, 0, noOfBytes); } while (noOfBytes > 0); } Assert.IsTrue(output.Equals(text1)); } /// <summary> /// Unit test to append toa non empty file. Create a file and append. Close and reopen a append stream and then append to a non-empty file. /// Verify by reading /// </summary> [TestMethod] public void TestAppendNotEmptyFile() { string path = $"{UnitTestDir}/testAppend2.txt"; string text1 = RandomString(27 * 1024 * 1024); byte[] textByte1 = Encoding.UTF8.GetBytes(text1); using (var ostream = _adlsClient.CreateFile(path, IfExists.Overwrite, "")) { ostream.Write(textByte1, 0, textByte1.Length); } string text2 = RandomString(1024 * 1024); string text3 = RandomString(100 * 1024); byte[] textByte2 = Encoding.UTF8.GetBytes(text2); byte[] textByte3 = Encoding.UTF8.GetBytes(text3); using (var ostream = _adlsClient.GetAppendStream(path)) { ostream.Write(textByte2, 0, textByte2.Length); ostream.Write(textByte3, 0, textByte3.Length); } string output = ""; using (var istream = _adlsClient.GetReadStream(path)) { istream.Seek(textByte1.Length, SeekOrigin.Begin); int noOfBytes; byte[] buffer = new byte[2 * 1024 * 1024]; do { noOfBytes = istream.Read(buffer, 0, buffer.Length); output += Encoding.UTF8.GetString(buffer, 0, noOfBytes); } while (noOfBytes > 0); } Assert.IsTrue(output.Equals(text2 + text3)); } #endregion #region TestSeek /// <summary> /// Unit test to seek a file from current. /// Read till 1/8th of total size /// Seek from current for 1/8th of total size /// Read 1/8th of current size /// Seek from current for 1/8th of total size /// Read till end /// Verify the expected and actual reads /// </summary> [TestMethod] public void TestSeekCurrent() { string path = $"{UnitTestDir}/testSeekCurrent.txt"; int strLength = 24 * 1024 * 1024; string text1 = RandomString(strLength); int lengthToReadBeforeSeek = strLength / 8; byte[] textByte1 = Encoding.UTF8.GetBytes(text1); using (var ostream = _adlsClient.CreateFile(path, IfExists.Overwrite, "")) { ostream.Write(textByte1, 0, textByte1.Length); } string expectedOp = ""; string actualOp = ""; using (var istream = _adlsClient.GetReadStream(path)) { byte[] buff = new byte[strLength]; int totalBytes = 0, startByte = 0; int noBytes; int totalLengthToRead = lengthToReadBeforeSeek; do { noBytes = istream.Read(buff, 0, totalLengthToRead); actualOp += Encoding.UTF8.GetString(buff, 0, noBytes); totalBytes += noBytes; totalLengthToRead -= noBytes; } while (noBytes > 0 && totalLengthToRead > 0); expectedOp += text1.Substring(startByte, totalBytes); istream.Seek(lengthToReadBeforeSeek, SeekOrigin.Current); totalBytes += lengthToReadBeforeSeek; startByte = totalBytes; totalLengthToRead = lengthToReadBeforeSeek; do { noBytes = istream.Read(buff, 0, totalLengthToRead); actualOp += Encoding.UTF8.GetString(buff, 0, noBytes); totalBytes += noBytes; totalLengthToRead -= noBytes; } while (noBytes > 0 && totalLengthToRead > 0); expectedOp += text1.Substring(startByte, totalBytes - startByte); istream.Seek(lengthToReadBeforeSeek, SeekOrigin.Current); try { istream.Seek(3 * strLength / 4, SeekOrigin.Current); Assert.Fail("Trying to seek beyond the end of file so it should throw an exception"); } catch (IOException) { } totalBytes += lengthToReadBeforeSeek; do { noBytes = istream.Read(buff, 0, buff.Length); actualOp += Encoding.UTF8.GetString(buff, 0, noBytes); } while (noBytes > 0); expectedOp += text1.Substring(totalBytes, text1.Length - totalBytes); } Assert.IsTrue(actualOp.Equals(expectedOp)); } /// <summary> /// Unit test for seek a file from begining /// Read to middle /// Seek to 1/4 from start /// Read to middle /// Seek to 3/4 from start /// Read till end /// Verfiy expected and actual reads /// </summary> [TestMethod] public void TestSeekBegin() { string path = $"{UnitTestDir}/testSeekBegin.txt"; int strLength = 12 * 1024 * 1024; string text1 = RandomString(strLength); int readTill = strLength / 2; byte[] textByte1 = Encoding.UTF8.GetBytes(text1); using (var ostream = _adlsClient.CreateFile(path, IfExists.Overwrite, "")) { ostream.Write(textByte1, 0, textByte1.Length); } string expectedOp = ""; string actualOp = ""; using (var istream = _adlsClient.GetReadStream(path)) { byte[] buff = new byte[strLength]; int totalBytes = 0, startBytes = 0; int noBytes; int totalLengthToRead = readTill - startBytes; do { noBytes = istream.Read(buff, 0, totalLengthToRead); actualOp += Encoding.UTF8.GetString(buff, 0, noBytes); totalBytes += noBytes; totalLengthToRead -= noBytes; } while (noBytes > 0 && totalLengthToRead > 0); expectedOp += text1.Substring(startBytes, totalBytes - startBytes); istream.Seek(strLength / 4, SeekOrigin.Begin); startBytes = totalBytes = strLength / 4; totalLengthToRead = readTill - startBytes; do { noBytes = istream.Read(buff, 0, totalLengthToRead); actualOp += Encoding.UTF8.GetString(buff, 0, noBytes); totalBytes += noBytes; totalLengthToRead -= noBytes; } while (noBytes > 0 && totalLengthToRead > 0); expectedOp += text1.Substring(startBytes, totalBytes - startBytes); istream.Seek(3 * strLength / 4, SeekOrigin.Begin); try { istream.Seek(3 * strLength / 4, SeekOrigin.Current); Assert.Fail("Trying to seek beyond the end of file so it should throw an exception"); } catch (IOException) { } startBytes = totalBytes = 3 * strLength / 4; totalLengthToRead = 2 * readTill - startBytes; do { noBytes = istream.Read(buff, 0, totalLengthToRead); actualOp += Encoding.UTF8.GetString(buff, 0, noBytes); totalBytes += noBytes; totalLengthToRead -= noBytes; } while (noBytes > 0 && totalLengthToRead > 0); expectedOp += text1.Substring(startBytes, totalBytes - startBytes); try { istream.Seek(-1, SeekOrigin.Begin); Assert.Fail("Trying to seek beyond the begining of file so it should throw an exception"); } catch (IOException) { } } Assert.IsTrue(actualOp.Equals(expectedOp)); } /// Unit test for seek a file from current in reverse direction /// Read to middle /// Seek behind to 1/4th of total size from curent /// Read till 3/4th of total size /// Seek behind to middle from current /// Read till end /// Verfiy expected and actual reads [TestMethod] public void TestSeekCurrentBack() { string path = $"{UnitTestDir}/testSeekCurrentBack.txt"; int strLength = 12 * 1024 * 1024; string text1 = RandomString(strLength); int readTill = strLength / 2; byte[] textByte1 = Encoding.UTF8.GetBytes(text1); using (var ostream = _adlsClient.CreateFile(path, IfExists.Overwrite, "")) { ostream.Write(textByte1, 0, textByte1.Length); } string expectedOp = ""; string actualOp = ""; using (var istream = _adlsClient.GetReadStream(path)) { byte[] buff = new byte[strLength]; int totalBytes = 0, startBytes = 0; int noBytes; int totalLengthToRead = readTill - startBytes; do { noBytes = istream.Read(buff, 0, totalLengthToRead); actualOp += Encoding.UTF8.GetString(buff, 0, noBytes); totalBytes += noBytes; totalLengthToRead -= noBytes; } while (noBytes > 0 && totalLengthToRead > 0); expectedOp += text1.Substring(startBytes, totalBytes - startBytes); istream.Seek(-1 * strLength / 4, SeekOrigin.Current); startBytes = totalBytes = strLength / 4; totalLengthToRead = 3 * readTill / 2 - startBytes; do { noBytes = istream.Read(buff, 0, totalLengthToRead); actualOp += Encoding.UTF8.GetString(buff, 0, noBytes); totalBytes += noBytes; totalLengthToRead -= noBytes; } while (noBytes > 0 && totalLengthToRead > 0); expectedOp += text1.Substring(startBytes, totalBytes - startBytes); istream.Seek(-1 * strLength / 4, SeekOrigin.Current); startBytes = totalBytes = strLength / 2; totalLengthToRead = 2 * readTill - startBytes; do { noBytes = istream.Read(buff, 0, totalLengthToRead); actualOp += Encoding.UTF8.GetString(buff, 0, noBytes); totalBytes += noBytes; totalLengthToRead -= noBytes; } while (noBytes > 0 && totalLengthToRead > 0); expectedOp += text1.Substring(startBytes, totalBytes - startBytes); } Assert.IsTrue(actualOp.Equals(expectedOp)); } /// Unit test for seek a file from end of file /// Read to middle /// Seek to 3/4th of total size from end (1/4th from begining) /// Read till middle /// Seek to 1/4th from end (3/4th from begining) /// Read till end /// Verfiy expected and actual reads [TestMethod] public void TestSeekEnd() { string path = $"{UnitTestDir}/testSeekEnd.txt"; int strLength = 12 * 1024 * 1024; string text1 = RandomString(strLength); int readTill = strLength / 2; byte[] textByte1 = Encoding.UTF8.GetBytes(text1); using (var ostream = _adlsClient.CreateFile(path, IfExists.Overwrite, "")) { ostream.Write(textByte1, 0, textByte1.Length); } string expectedOp = ""; string actualOp = ""; using (var istream = _adlsClient.GetReadStream(path)) { byte[] buff = new byte[strLength]; int totalBytes = 0, startBytes = 0; int noBytes; int totalLengthToRead = readTill - startBytes; do { noBytes = istream.Read(buff, 0, totalLengthToRead); actualOp += Encoding.UTF8.GetString(buff, 0, noBytes); totalBytes += noBytes; totalLengthToRead -= noBytes; } while (noBytes > 0 && totalLengthToRead > 0); expectedOp += text1.Substring(startBytes, totalBytes - startBytes); istream.Seek(-3 * strLength / 4, SeekOrigin.End); startBytes = totalBytes = strLength / 4; totalLengthToRead = readTill - startBytes; do { noBytes = istream.Read(buff, 0, totalLengthToRead); actualOp += Encoding.UTF8.GetString(buff, 0, noBytes); totalBytes += noBytes; totalLengthToRead -= noBytes; } while (noBytes > 0 && totalLengthToRead > 0); expectedOp += text1.Substring(startBytes, totalBytes - startBytes); istream.Seek(-strLength / 4, SeekOrigin.End); try { istream.Seek(3 * strLength / 4, SeekOrigin.Current); Assert.Fail("Trying to seek beyond the end of file so it should throw an exception"); } catch (IOException) { } startBytes = totalBytes = 3 * strLength / 4; totalLengthToRead = 2 * readTill - startBytes; do { noBytes = istream.Read(buff, 0, totalLengthToRead); actualOp += Encoding.UTF8.GetString(buff, 0, noBytes); totalBytes += noBytes; totalLengthToRead -= noBytes; } while (noBytes > 0 && totalLengthToRead > 0); expectedOp += text1.Substring(startBytes, totalBytes - startBytes); try { istream.Seek(1, SeekOrigin.End); Assert.Fail("Trying to seek beyond the end of file so it should throw an exception"); } catch (IOException) { } } Assert.IsTrue(actualOp.Equals(expectedOp)); } #endregion #region ConcurrentAppend [TestMethod] [DataRow(15)] [DataRow(4*1024*1024)] [DataRow(6 * 1024 * 1024)] public void TestConcurrentAppendSerial(int size) { string path =$"{UnitTestDir}/testConcurrentAppend_"+size; int count = 5; string line = RandomString(size); byte[] textByte1 = Encoding.UTF8.GetBytes(line); string expectedOutput = ""; for(int i = 0; i < count; i++) { _adlsClient.ConcurrentAppend(path, true, textByte1, 0, textByte1.Length); expectedOutput += line; } string actualOutput; using (var reader = new StreamReader(_adlsClient.GetReadStream(path))) { actualOutput = reader.ReadToEnd(); } Assert.IsTrue(actualOutput.Equals(expectedOutput)); } [TestMethod] [DataRow(15)] [DataRow(1024 * 1024)] public void TestConcurrentAppendParallel(int size) { string path = $"{UnitTestDir}/testConcurrentAppendParallel_" + size; int count = 10; string line = RandomString(size); byte[] textByte1 = Encoding.UTF8.GetBytes(line); string expectedOutput = ""; Parallel.For(0, count, index => { _adlsClient.ConcurrentAppend(path, true, textByte1, 0, textByte1.Length); }); for (int i = 0; i < count; i++) { expectedOutput += line; } string actualOutput; using (var reader = new StreamReader(_adlsClient.GetReadStream(path))) { actualOutput = reader.ReadToEnd(); } Assert.IsTrue(actualOutput.Equals(expectedOutput)); } #endregion #region GetFileStatus [TestMethod] [DataRow(15)] [DataRow(1 * 1024 * 1024)] public void TestConcurrentAppendGetFileStatus(int size) { string path = $"{UnitTestDir}/testConcurrentAppendParallelGetFile_" + size; int count = 10; string line = RandomString(size); byte[] textByte1 = Encoding.UTF8.GetBytes(line); int expectedLength = count * size; Parallel.For(0, count, index => { _adlsClient.ConcurrentAppend(path, true, textByte1, 0, textByte1.Length); }); var resp = new OperationResponse(); var diren = Core.GetFileStatusAsync(path, UserGroupRepresentation.ObjectID, _adlsClient, new RequestOptions(), resp, default(CancellationToken), true).GetAwaiter().GetResult(); Assert.IsTrue(diren.Length == expectedLength); } /// <summary> /// Unit test for verifying whether UserRepresentation correctly retrieves object Id or the user principal name in getfilestatus /// </summary> [TestMethod] public void TestUserRepresentation() { string filename = $"{UnitTestDir}/UserRepresentation.txt"; using (var ostream = new StreamWriter(_adlsClient.CreateFile(filename, IfExists.Overwrite))) { ostream.Write("Hello This is a user representation test"); } var entry = _adlsClient.GetDirectoryEntry(filename); Assert.IsTrue(VerifyGuid(entry.User)); entry = _adlsClient.GetDirectoryEntry(filename, UserGroupRepresentation.UserPrincipalName); Assert.IsFalse(VerifyGuid(entry.User)); } #endregion #region Rename /// <summary> /// Unit test to rename a directory where the source directory exists as a subdirectory in the destination path /// </summary> /// <param name="overwrite">Whether to overwrite the existing destination if it exists</param> [TestMethod] [DataRow(false)] [DataRow(true)] public void TestRenameDirectoryDestinationExistsSubDirec(bool overwrite) { string srcpath = $"{UnitTestDir}/testRenameSource1" + overwrite; string destPath = $"{UnitTestDir}/testRenameDestination1" + overwrite; string subDestpath = destPath + "/testRenameSource1" + overwrite; bool result = _adlsClient.CreateDirectory(srcpath, ""); Assert.IsTrue(result); result = _adlsClient.CreateDirectory(subDestpath, ""); Assert.IsTrue(result); result = _adlsClient.Rename(srcpath, destPath); Assert.IsFalse(result); } /// <summary> /// Unit test to rename a directory where the destination does not exist /// </summary> /// <param name="overwrite">Whether to overwrite the existing destination if it exists</param> [TestMethod] [DataRow(true)] [DataRow(false)] public void TestRenameDirectoryDestinationNotExist(bool overwrite) { string srcDirPath = $"{UnitTestDir}/testRenameSource2" + overwrite; string destDirPath = $"{UnitTestDir}/testRenameDest2" + overwrite; bool result = _adlsClient.CreateDirectory(srcDirPath, ""); Assert.IsTrue(result); result = _adlsClient.Rename(srcDirPath, destDirPath, overwrite); Assert.IsTrue(result); try { _adlsClient.GetDirectoryEntry(srcDirPath); Assert.Fail("Src directory should not exist so GetFileStatus should throw an exception"); } catch (IOException) { } DirectoryEntry diren = _adlsClient.GetDirectoryEntry(destDirPath); Assert.IsNotNull(diren); } /// <summary> /// Unit test to rename a directory where the destination directory is empty /// </summary> /// <param name="overwrite">Whether to overwrite the existing destination if it exists</param> [TestMethod] [DataRow(false)] [DataRow(true)] public void TestRenameDirectoryDestinationExist(bool overwrite) { string srcDirPath = $"{UnitTestDir}/testRenameSource3" + overwrite; string destDirPath = $"{UnitTestDir}/testRenameDest3" + overwrite; string expectedDestPath = destDirPath + "/testRenameSource3" + overwrite; Assert.IsTrue(_adlsClient.CreateDirectory(srcDirPath, "")); Assert.IsTrue(_adlsClient.CreateDirectory(destDirPath, "")); Assert.IsTrue(_adlsClient.Rename(srcDirPath, destDirPath, overwrite)); try { _adlsClient.GetDirectoryEntry(srcDirPath); Assert.Fail("Src directory should not exist so GetFileStatus should throw an exception"); } catch (IOException) { } DirectoryEntry diren = _adlsClient.GetDirectoryEntry(expectedDestPath); Assert.IsNotNull(diren); } /// <summary> /// Unit test to rename a directory where the destination directory has a file /// </summary> /// <param name="overwrite">Whether to overwrite the existing destination if it exists</param> [TestMethod] [DataRow(true)] [DataRow(false)] public void TestRenameDirectoryDestinationExistNonEmpty(bool overwrite) { string srcDirPath = $"{UnitTestDir}/testRenameSource4" + overwrite; string destDirPath = $"{UnitTestDir}/testRenameDest4" + overwrite; string destDirFilePath = destDirPath + "/File.txt"; string expectedDestPath = destDirPath + "/testRenameSource4" + overwrite; Assert.IsTrue(_adlsClient.CreateDirectory(srcDirPath, "")); Assert.IsTrue(_adlsClient.CreateDirectory(destDirPath, "")); using (_adlsClient.CreateFile(destDirFilePath, IfExists.Overwrite, "")) { } Assert.IsTrue(_adlsClient.Rename(srcDirPath, destDirPath, overwrite)); try { _adlsClient.GetDirectoryEntry(srcDirPath); Assert.Fail("Src Directory should not exist so GetFileStatus should throw an exception"); } catch (IOException) { } DirectoryEntry diren = _adlsClient.GetDirectoryEntry(expectedDestPath); Assert.IsNotNull(diren); } /// <summary> /// Unit test to rename a file where the destination does not exist /// </summary> /// <param name="overwrite">Whether to overwrite the existing destination if it exists</param> [TestMethod] [DataRow(false)] [DataRow(true)] public void TestRenameFileDestinationNotExist(bool overwrite) { string srcFilePath = $"{UnitTestDir}/testRenameSource5" + overwrite + ".txt"; string destFilePath = $"{UnitTestDir}/testRenameDest5" + overwrite + ".txt"; int strLength = 300; string srcFileText = RandomString(strLength); byte[] srcByte = Encoding.UTF8.GetBytes(srcFileText); using (var ostream = _adlsClient.CreateFile(srcFilePath, IfExists.Overwrite, "")) { ostream.Write(srcByte, 0, srcByte.Length); } bool result = _adlsClient.Rename(srcFilePath, destFilePath, overwrite); Assert.IsTrue(result); try { _adlsClient.GetDirectoryEntry(srcFilePath); Assert.Fail("Src file shouldnt exist so GetFileStatus should throw an exception"); } catch (IOException) { } string output = ""; try { using (var istream = _adlsClient.GetReadStream(destFilePath)) { int noOfBytes; byte[] buffer = new byte[2 * 1024 * 1024]; do { noOfBytes = istream.Read(buffer, 0, buffer.Length); output += Encoding.UTF8.GetString(buffer, 0, noOfBytes); } while (noOfBytes > 0); } } catch (IOException) { Assert.Fail("The destination file should exist so ReadStream should throw an exception"); } Assert.IsTrue(output.Equals(srcFileText)); } /// <summary> /// Unit test to rename a file where the destination file exists /// </summary> /// <param name="overwrite">Whether to overwrite the existing destination if it exists</param> [TestMethod] [DataRow(false)] [DataRow(true)] public void TestRenameFileDestinationExist(bool overwrite) { string srcFilePath = $"{UnitTestDir}/testRenameSource6" + overwrite + ".txt"; string destFilePath = $"{UnitTestDir}/testRenameDest6" + overwrite + ".txt"; int strLength = 300; string srcFileText = RandomString(strLength); byte[] srcByte = Encoding.UTF8.GetBytes(srcFileText); using (var ostream = _adlsClient.CreateFile(srcFilePath, IfExists.Overwrite, "")) { ostream.Write(srcByte, 0, srcByte.Length); } string destFileText = RandomString(strLength); byte[] destByte = Encoding.UTF8.GetBytes(destFileText); using (var ostream = _adlsClient.CreateFile(destFilePath, IfExists.Overwrite, "")) { ostream.Write(destByte, 0, destByte.Length); } bool result = _adlsClient.Rename(srcFilePath, destFilePath, overwrite); if (overwrite) { Assert.IsTrue(result); } else { Assert.IsFalse(result); } try { _adlsClient.GetDirectoryEntry(srcFilePath); if (overwrite) { Assert.Fail("Src file should not exist so Getfilestatus should throw an exception"); } } catch (IOException) { if (!overwrite) { Assert.Fail("Src file should exist so getfilestatus should not throw an exception"); } } string output = ""; using (var istream = _adlsClient.GetReadStream(destFilePath)) { int noOfBytes; byte[] buffer = new byte[2 * 1024 * 1024]; do { noOfBytes = istream.Read(buffer, 0, buffer.Length); output += Encoding.UTF8.GetString(buffer, 0, noOfBytes); } while (noOfBytes > 0); } Assert.IsTrue(overwrite ? output.Equals(srcFileText) : output.Equals(destFileText)); } [TestMethod] public void TestRenameFileEncoding() { string srcFilePath = $"{UnitTestDir}/testSourceRenameFileEncoding.txt"; string destFilePath = $"{UnitTestDir}/testDestRenameFileEncoding+,#?.txt"; using (_adlsClient.CreateFile(srcFilePath, IfExists.Overwrite, "")) { } bool result = _adlsClient.Rename(srcFilePath, destFilePath); Assert.IsTrue(result); Assert.IsTrue(_adlsClient.CheckExists(destFilePath)); } #endregion #region Delete /// <summary> /// Unit test to try deleting an non empty directory without specifying the flag /// </summary> [TestMethod] [ExpectedException(typeof(AdlsException))] public void TestDeleteException() { string deletePath = $"{UnitTestDir}/testDelete/testDelete1"; _adlsClient.CreateDirectory(deletePath, ""); _adlsClient.Delete($"{UnitTestDir}/testDelete"); Assert.Fail("Trying to delete an non-empty directory so it should throw an exception"); } /// <summary> /// Unit test to delete non empty directory /// </summary> [TestMethod] public void TestDeleteNonRecursive() { string deletePath = $"{UnitTestDir}/testDelete1"; _adlsClient.CreateDirectory(deletePath, ""); bool result = _adlsClient.Delete(deletePath); Assert.IsTrue(result); try { _adlsClient.GetDirectoryEntry(deletePath); Assert.Fail("The directory should have been deleted so GetFileStatus should throw an exception"); } catch (IOException) { } } /// <summary> /// Unit test to delete a directory recursively /// </summary> [TestMethod] public void TestDeleteRecursive() { string deletePath = $"{UnitTestDir}/testDelete2/testDelete3/testDeleteInternal"; _adlsClient.CreateDirectory(deletePath, ""); bool result = _adlsClient.DeleteRecursive($"{UnitTestDir}/testDelete2"); Assert.IsTrue(result); try { _adlsClient.GetDirectoryEntry($"{UnitTestDir}/testDelete2"); Assert.Fail("The directory should have been deleted so GetFileStatus should throw an exception"); } catch (IOException) { } } #endregion #region Concat /// <summary> /// Unit test to try concat same file /// </summary> [TestMethod] [ExpectedException(typeof(AdlsException))] public void TestConcatException1() { string destPath = $"{UnitTestDir}/destPath.txt"; List<string> srcList = new List<string>(); string srcFile1 = $"{UnitTestDir}/Source/srcPathEx1.txt"; srcList.Add(srcFile1); srcList.Add(srcFile1); _adlsClient.ConcatenateFiles(destPath, srcList); Assert.Fail("Trying to concat same file should fail"); } /// <summary> /// Unit test to try concat the destination path also /// </summary> [TestMethod] [ExpectedException(typeof(AdlsException))] public void TestConcatException2() { string destPath = $"{UnitTestDir}/destPath.txt"; List<string> srcList = new List<string>(); string srcFile1 = $"{UnitTestDir}/Source/srcPathEx2.txt"; srcList.Add(destPath); srcList.Add(srcFile1); _adlsClient.ConcatenateFiles(destPath, srcList); Assert.Fail("Concating the destination path should fail"); } /// <summary> /// Unit test to try concat one file /// </summary> [TestMethod] public void TestConcatOneFile() { string destPath = $"{UnitTestDir}/destPathOneFile.txt"; string srcFile1 = $"{UnitTestDir}/Source/srcPathOneFile.txt"; string text1 = RandomString(2 * 1024); byte[] textByte1 = Encoding.UTF8.GetBytes(text1); using (var ostream = _adlsClient.CreateFile(srcFile1, IfExists.Overwrite, "")) { ostream.Write(textByte1, 0, textByte1.Length); } List<string> srcList = new List<string> { srcFile1 }; _adlsClient.ConcatenateFiles(destPath, srcList); string output = ""; using (var istream = _adlsClient.GetReadStream(destPath)) { int noOfBytes; byte[] buffer = new byte[2 * 1024]; do { noOfBytes = istream.Read(buffer, 0, buffer.Length); output += Encoding.UTF8.GetString(buffer, 0, noOfBytes); } while (noOfBytes > 0); } Assert.IsTrue(output.Equals(text1)); } /// <summary> /// Unit test to test failure when the destination is folder /// </summary> [TestMethod] [ExpectedException((typeof(AdlsException)))] public void TestConcatException4() { string destPath = $"{UnitTestDir}/destPath1"; List<string> srcList = new List<string>() { $"{UnitTestDir}/Source4/SrcFileEx4.txt", $"{UnitTestDir}/Source4/SrcFileEx5.txt" }; byte[] textByte1 = Encoding.UTF8.GetBytes("Hello World"); _adlsClient.CreateDirectory(destPath); using (var ostream = _adlsClient.CreateFile(srcList[0], IfExists.Overwrite, "")) { ostream.Write(textByte1, 0, textByte1.Length); } using (var ostream = _adlsClient.CreateFile(srcList[1], IfExists.Overwrite, "")) { ostream.Write(textByte1, 0, textByte1.Length); } _adlsClient.ConcatenateFiles(destPath, srcList); } /// <summary> /// This test is to test stream is sealed after concat. This is valid behavior only in tieredstore. /// </summary> [TestMethod] [ExpectedException(typeof(AdlsException))] public void TestConcatException5() { if (_isAccountTieredStore) { throw new AdlsException("Ignore this test, since stream is not sealed after concat in tiered store"); } string destPath = $"{UnitTestDir}/destPathEx2.txt"; List<string> srcList = new List<string>() { $"{UnitTestDir}/Source4/SrcFileEx1.txt", $"{UnitTestDir}/Source4/SrcFileEx2.txt" }; byte[] textByte1 = Encoding.UTF8.GetBytes("Hello World"); using (var ostream = _adlsClient.CreateFile(srcList[0], IfExists.Overwrite, "")) { ostream.Write(textByte1, 0, textByte1.Length); } using (var ostream = _adlsClient.CreateFile(srcList[1], IfExists.Overwrite, "")) { ostream.Write(textByte1, 0, textByte1.Length); } _adlsClient.ConcatenateFiles(destPath, srcList); using (var ostream = _adlsClient.GetAppendStream(destPath)) { ostream.Write(textByte1, 0, textByte1.Length); } } /// <summary> /// Unit test to concat two file with and without deleting the source directory /// </summary> [TestMethod] public void TestConcatTwoFile() { TestConcatTwoFile(false, UnitTestDir + "/destPath2.txt", UnitTestDir + "/Source"); TestConcatTwoFile(true, UnitTestDir + "/destPath3.txt", UnitTestDir + "/Source1"); TestConcatTwoFile(false, UnitTestDir + "/destPath6.txt", UnitTestDir + "/Source1", "prefix+with,signs"); TestConcatTwoFile(true, UnitTestDir + "/destPath7.txt", UnitTestDir + "/Source1", "prefix+with,signs"); } /// <summary> /// Unit test to concat two file /// </summary> /// <param name="deleteSource">Whether to delete source directory</param> /// <param name="destPath">Destination filename</param> /// <param name="sourcePath">Source directory</param> public void TestConcatTwoFile(bool deleteSource, string destPath, string sourcePath, string sourceFileNamePrefix = "") { List<string> srcList = new List<string>(); string srcFile1 = sourcePath + "/" + sourceFileNamePrefix + "srcPath1.txt"; string text1 = RandomString(2 * 1024 * 1024); byte[] textByte1 = Encoding.UTF8.GetBytes(text1); using (var ostream = _adlsClient.CreateFile(srcFile1, IfExists.Overwrite, "")) { ostream.Write(textByte1, 0, textByte1.Length); } string srcFile2 = sourcePath + "/" + sourceFileNamePrefix + "srcPath2.txt"; string text2 = RandomString(3 * 1024 * 1024); byte[] textByte2 = Encoding.UTF8.GetBytes(text2); using (var ostream = _adlsClient.CreateFile(srcFile2, IfExists.Overwrite, "")) { ostream.Write(textByte2, 0, textByte2.Length); } srcList.Add(srcFile1); srcList.Add(srcFile2); _adlsClient.ConcatenateFiles(destPath, srcList, deleteSource); string output = ""; using (var istream = _adlsClient.GetReadStream(destPath)) { int noOfBytes; byte[] buffer = new byte[5 * 1024 * 1024]; do { noOfBytes = istream.Read(buffer, 0, buffer.Length); output += Encoding.UTF8.GetString(buffer, 0, noOfBytes); } while (noOfBytes > 0); } Assert.IsTrue(output.Equals(text1 + text2)); try { _adlsClient.GetDirectoryEntry(srcFile1); Assert.Fail("The file should have been deleted so Getfilestatus should throw an exception"); } catch (IOException) { } try { _adlsClient.GetDirectoryEntry(srcFile2); Assert.Fail("The file should have been deleted so Getfilestatus should throw an exception"); } catch (IOException) { } if (deleteSource) { try { _adlsClient.GetDirectoryEntry(sourcePath); Assert.Fail("The directory should have been deleted so Getfilestatus should throw an exception"); } catch (IOException) { } } } /// <summary> /// Unit test to concat three files with and without deleting the source directory /// </summary> [TestMethod] public void TestConcatThreeFile() { TestConcatThreeFile(false, UnitTestDir + "/destPath4.txt", UnitTestDir + "/Source2"); TestConcatThreeFile(true, UnitTestDir + "/destPath5.txt", UnitTestDir + "/Source3"); } /// <summary> /// Unit test to concat three files /// </summary> /// <param name="deleteSource">Whether to delete source directory</param> /// <param name="destPath">Destination filename</param> /// <param name="sourcePath">Source directory</param> public void TestConcatThreeFile(bool deleteSource, string destPath, string sourcePath) { List<string> srcList = new List<string>(); string srcFile1 = sourcePath + "/srcPath3.txt"; string text1 = RandomString(1024); byte[] textByte1 = Encoding.UTF8.GetBytes(text1); using (var ostream = _adlsClient.CreateFile(srcFile1, IfExists.Overwrite, "")) { ostream.Write(textByte1, 0, textByte1.Length); } string srcFile2 = sourcePath + "/srcPath4.txt"; string text2 = RandomString(5 * 1024 * 1024); byte[] textByte2 = Encoding.UTF8.GetBytes(text2); using (var ostream = _adlsClient.CreateFile(srcFile2, IfExists.Overwrite, "")) { ostream.Write(textByte2, 0, textByte2.Length); } string srcFile3 = sourcePath + "/srcPath5.txt"; string text3 = RandomString(300 * 1024); byte[] textByte3 = Encoding.UTF8.GetBytes(text3); using (var ostream = _adlsClient.CreateFile(srcFile3, IfExists.Overwrite, "")) { ostream.Write(textByte3, 0, textByte3.Length); } srcList.Add(srcFile1); srcList.Add(srcFile2); srcList.Add(srcFile3); _adlsClient.ConcatenateFiles(destPath, srcList, deleteSource); string output = ""; using (var istream = _adlsClient.GetReadStream(destPath)) { int noOfBytes; byte[] buffer = new byte[8 * 1024 * 1024]; do { noOfBytes = istream.Read(buffer, 0, buffer.Length); output += Encoding.UTF8.GetString(buffer, 0, noOfBytes); } while (noOfBytes > 0); } Assert.IsTrue(output.Equals(text1 + text2 + text3)); try { _adlsClient.GetDirectoryEntry(srcFile1); Assert.Fail("The file should have been deleted so GetFileStatus should throw an exception"); } catch (IOException) { } try { _adlsClient.GetDirectoryEntry(srcFile2); Assert.Fail("The file should have been deleted so GetFileStatus should throw an exception"); } catch (IOException) { } try { _adlsClient.GetDirectoryEntry(srcFile3); Assert.Fail("The file should have been deleted so GetFileStatus should throw an exception"); } catch (IOException) { } if (deleteSource) { try { _adlsClient.GetDirectoryEntry($"{UnitTestDir}/Source"); Assert.Fail("The directory should have been deleted so GetFileStatus should throw an exception"); } catch (IOException) { } } } [TestMethod] public void TestConcatExisting() { string sourcePath = UnitTestDir + "/TestConcatExisting"; List<string> srcList = new List<string>(); string destPath = sourcePath + "/destPath.txt"; string text1 = RandomString(1024); using (var writer = new StreamWriter(_adlsClient.CreateFile(destPath, IfExists.Overwrite, ""))) { writer.Write(text1); } string srcFile1 = sourcePath + "/srcPath1.txt"; string text2 = RandomString( 1024); using (var ostream = new StreamWriter(_adlsClient.CreateFile(srcFile1, IfExists.Overwrite, ""))) { ostream.Write(text2); } string srcFile2 = sourcePath + "/srcPath2.txt"; string text3 = RandomString(1024); using (var ostream = new StreamWriter(_adlsClient.CreateFile(srcFile2, IfExists.Overwrite, ""))) { ostream.Write(text3); } srcList.Add(srcFile1); srcList.Add(srcFile2); _adlsClient.ConcatenateFiles(destPath, srcList); using (var istream = new StreamReader(_adlsClient.GetReadStream(destPath))) { Assert.IsTrue(istream.ReadToEnd().Equals(text1+text2+text3)); } } #endregion #region Expiry /// <summary> /// Unit test to try set expiry time for a directory /// </summary> [TestMethod] [ExpectedException(typeof(AdlsException))] public void TestExpiryFailDirectory() { string path = $"{UnitTestDir}/ExpiryFolder"; _adlsClient.CreateDirectory(path, ""); _adlsClient.SetExpiryTime(path, ExpiryOption.NeverExpire, 0); Assert.Fail("SetExpiry should have raised an exception as expiry cannot be set for folders"); } /// <summary> /// Unit test to set expiry time as never /// </summary> [TestMethod] public void TestExpiryTimeNever() { string path = $"{UnitTestDir}/ExpiryFolder/ExpiryFile1.txt"; string text1 = RandomString(100); byte[] textByte1 = Encoding.UTF8.GetBytes(text1); using (var ostream = _adlsClient.CreateFile(path, IfExists.Overwrite, "")) { ostream.Write(textByte1, 0, textByte1.Length); } _adlsClient.SetExpiryTime(path, ExpiryOption.NeverExpire, 0); DirectoryEntry diren = _adlsClient.GetDirectoryEntry(path); Assert.IsNull(diren.ExpiryTime); } private static bool DateTimeEquals(DateTime d1, DateTime d2) { long diff = Math.Abs(d1.Ticks - d2.Ticks) / 10000; return diff < 100;//Error of 100 milliseconds } /// <summary> /// Unit test to set expiry time as absolute /// </summary> [TestMethod] public void TestExpiryTimeAbsolute() { string path = $"{UnitTestDir}/ExpiryFolder/ExpiryFileAbsolute.txt"; string text1 = RandomString(100); byte[] textByte1 = Encoding.UTF8.GetBytes(text1); using (var ostream = _adlsClient.CreateFile(path, IfExists.Overwrite, "")) { ostream.Write(textByte1, 0, textByte1.Length); } DateTime dt = DateTime.UtcNow.AddDays(1); long milliseconds = (long)(dt - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds; _adlsClient.SetExpiryTime(path, ExpiryOption.Absolute, milliseconds); DirectoryEntry diren = _adlsClient.GetDirectoryEntry(path); Assert.IsNotNull(diren.ExpiryTime); Assert.IsTrue(DateTimeEquals(diren.ExpiryTime.Value, dt)); } /// <summary> /// Unit test to set expiry time as relative to creation time /// </summary> [TestMethod] public void TestExpiryTimeRelativeCreation() { string path = $"{UnitTestDir}/ExpiryFolder/ExpiryFileRelative.txt"; var ostream = _adlsClient.CreateFile(path, IfExists.Overwrite, ""); DirectoryEntry diren = _adlsClient.GetDirectoryEntry(path); Assert.IsNotNull(diren.LastModifiedTime); DateTime create = diren.LastModifiedTime.Value; DateTime endTime = create.Add(new TimeSpan(0, 0, 0, 10)); _adlsClient.SetExpiryTime(path, ExpiryOption.RelativeToCreationDate, 10000); diren = _adlsClient.GetDirectoryEntry(path); Assert.IsNotNull(diren.ExpiryTime); Assert.IsTrue(DateTimeEquals(diren.ExpiryTime.Value, endTime)); ostream.Dispose(); } /// <summary> /// Unit test to set expiry time as relative to current time /// </summary> [TestMethod] public void TestExpiryTimeRelativeNow() { string path = $"{UnitTestDir}/ExpiryFolder/ExpiryFile3.txt"; long time = 5000;//In milliseconds: 5 seconds using (_adlsClient.CreateFile(path, IfExists.Overwrite, "")) { } _adlsClient.SetExpiryTime(path, ExpiryOption.RelativeToNow, time); Thread.Sleep((int)time + 1000); try { using (_adlsClient.GetAppendStream(path)) { } Assert.Fail("File is expired and it cannot be edited so Appendstream should throw an exception"); } catch (IOException) { } } #endregion #region PermissionAndAcls /// <summary> /// Unit test to try setting invalid permission /// </summary> [TestMethod] [ExpectedException(typeof(AdlsException))] public void TestSetPermissionException() { string path = $"{UnitTestDir}/SetPermission"; string permission = "77777"; _adlsClient.CreateDirectory(path, ""); _adlsClient.SetPermission(path, permission); Assert.Fail("SetPermission should have raised an exception because permission is not valid"); } /// <summary> /// Unit test to set permission of a directory /// </summary> [TestMethod] public void TestSetPermissionFolder() { string path = $"{UnitTestDir}/SetPermissionFolder"; string originalPermission = "771"; string permission = "772"; _adlsClient.CreateDirectory(path, originalPermission); string testFile = path + "/testFile.txt"; try { using (_adlsClient.CreateFile(testFile, IfExists.Overwrite, "776")) { } } catch (IOException) { Assert.Fail("Owner should have write permission so CreateFile should not raise an exception"); } AdlsClient nonOwner1 = SetupNonOwnerClient1(); try { using (nonOwner1.GetReadStream(testFile)) { } } catch (IOException) { Assert.Fail("Nonowner1 should have execute permission so ReadStream should not raise an exception"); } _adlsClient.SetPermission(path, permission); DirectoryEntry diren = _adlsClient.GetDirectoryEntry(path); Assert.IsTrue(diren.Permission == permission); try { using (nonOwner1.GetReadStream(testFile)) { } Assert.Fail("Nonowner1 should not have execute permission so ReadStream should raise an exception"); } catch (IOException) { } try { using (nonOwner1.GetAppendStream(testFile)) { } Assert.Fail("Nonowner1 should not have execute permission so AppendStream should raise an exception"); } catch (IOException) { } } /// <summary> /// Unit test to set permission of a file /// </summary> [TestMethod] public void TestSetPermissionFile() { string path = $"{UnitTestDir}/SetPermission.txt"; string originalPermission = "770"; string permission = "772"; using (_adlsClient.CreateFile(path, IfExists.Overwrite, originalPermission)) { } AdlsClient nonOwner1 = SetupNonOwnerClient1(); try { using (nonOwner1.GetAppendStream(path)) { } Assert.Fail("Nonowner1 should not have write permission so AppendStream should raise an exception"); } catch (IOException) { } _adlsClient.SetPermission(path, permission); DirectoryEntry diren = _adlsClient.GetDirectoryEntry(path); Assert.IsTrue(diren.Permission == permission); try { using (nonOwner1.GetAppendStream(path)) { } } catch (IOException) { Assert.Fail("Nonowner1 should have write permission so AppendStream should not raise an exception"); } } /// <summary> /// Unit test to verify check access when user has no access /// </summary> [TestMethod] public void TestCheckNoAccess() { string path = $"{UnitTestDir}/CheckNoAccess"; _adlsClient.CreateDirectory(path, ""); _adlsClient.SetPermission(path, "775"); AdlsClient nonOwner1 = SetupNonOwnerClient1(); Assert.IsFalse(nonOwner1.CheckAccess(path, "-w-")); string testFile = path + "/CheckNoAccessFile.txt"; try { using (nonOwner1.CreateFile(testFile, IfExists.Overwrite, "")) { } Assert.Fail("Nonowner1 should not have write access so CreateFile should raise an exception"); } catch (IOException) { } } /// <summary> /// Unit test to verify check access when user has access /// </summary> [TestMethod] public void TestCheckAccess() { string path = $"{UnitTestDir}/CheckAccess"; string originalPermission = "774"; string changedPermission = "775"; _adlsClient.CreateDirectory(path, ""); _adlsClient.SetPermission(path, originalPermission); string testFile = path + "/CheckAccessFile.txt"; string text1 = RandomString(100); byte[] textByte1 = Encoding.UTF8.GetBytes(text1); using (var ostream = _adlsClient.CreateFile(testFile, IfExists.Overwrite, originalPermission)) { ostream.Write(textByte1, 0, textByte1.Length); } AdlsClient nonOwner1 = SetupNonOwnerClient1(); Assert.IsTrue(nonOwner1.CheckAccess(path, "r--")); try { using (var istream = nonOwner1.GetReadStream(testFile)) { byte[] buff = new byte[25]; istream.Read(buff, 0, buff.Length); } Assert.Fail("nonowner1 should not have access to traverse the directory so ReadStream should not raise an exception"); } catch (IOException) { } _adlsClient.SetPermission(path, changedPermission); Assert.IsTrue(nonOwner1.CheckAccess(path, "r-x")); try { using (nonOwner1.GetReadStream(testFile)) { } } catch (IOException) { Assert.Fail("Nonowner1 should have read permission so ReadStream should not raise an exception"); } } /// <summary> /// Unit test to try set wrong Acl /// </summary> [TestMethod] [ExpectedException(typeof(AdlsException))] public void TestSetAclException() { string path = $"{UnitTestDir}/SetAclEntriesException"; _adlsClient.CreateDirectory(path, ""); List<AclEntry> aclList = new List<AclEntry>() { new AclEntry(AclType.user, NonOwner1ObjectId, AclScope.Access, AclAction.ReadWrite) };//Non owner client 1 _adlsClient.SetAcl(path, aclList); Assert.Fail("Acl List has no default permission acls so SetAcl should raise an exception"); } /// <summary> /// Unit test to set ACL successfully /// </summary> [TestMethod] public void TestSetAcl() { string path = $"{UnitTestDir}/SetAclEntries"; _adlsClient.CreateDirectory(path, ""); _adlsClient.SetPermission(path, "770"); string testFile = path + "/SetAcl.txt"; using (var ostream = _adlsClient.CreateFile(testFile, IfExists.Overwrite, "775")) { byte[] buff = Encoding.UTF8.GetBytes("Hello test i am"); ostream.Write(buff, 0, buff.Length); } AdlsClient nonOwner1 = SetupNonOwnerClient1(); Assert.IsFalse(nonOwner1.CheckAccess(path, "r--")); AdlsClient nonOwner2 = SetupNonOwnerClient2(); Assert.IsFalse(nonOwner2.CheckAccess(path, "r--")); List<AclEntry> aclList = new List<AclEntry>() { new AclEntry(AclType.user, NonOwner1ObjectId, AclScope.Access, AclAction.ReadWrite), //Add the default permission ACLs new AclEntry(AclType.user, "", AclScope.Access, AclAction.All), new AclEntry(AclType.group, "", AclScope.Access, AclAction.All), new AclEntry(AclType.other, "", AclScope.Access, AclAction.None) }; _adlsClient.SetAcl(path, aclList); //Non owner 1 Assert.IsTrue(nonOwner1.CheckAccess(path, "rw-")); Assert.IsFalse(nonOwner1.CheckAccess(path, "--x")); try { byte[] buff = new byte[25]; using (var istream = nonOwner1.GetReadStream(testFile)) { istream.Read(buff, 0, buff.Length); } Assert.Fail("nonowner1 should not have execute permission on the directory so ReadStream should raise an exception"); } catch (IOException) { } //Non owner 2 Assert.IsFalse(nonOwner2.CheckAccess(path, "--x")); Assert.IsFalse(nonOwner2.CheckAccess(path, "rw-")); aclList.Clear(); aclList.Add(new AclEntry(AclType.user, NonOwner2ObjectId, AclScope.Access, AclAction.ExecuteOnly)); //Add the default permission ACLs aclList.Add(new AclEntry(AclType.user, "", AclScope.Access, AclAction.All)); aclList.Add(new AclEntry(AclType.group, "", AclScope.Access, AclAction.All)); aclList.Add(new AclEntry(AclType.other, "", AclScope.Access, AclAction.None)); _adlsClient.SetAcl(path, aclList); Assert.IsFalse(nonOwner1.CheckAccess(path, "rw-")); Assert.IsFalse(nonOwner1.CheckAccess(path, "--x")); Assert.IsTrue(nonOwner2.CheckAccess(path, "--x")); Assert.IsFalse(nonOwner2.CheckAccess(path, "rw-")); try { byte[] buff = new byte[25]; using (var istream = nonOwner2.GetReadStream(testFile)) { istream.Read(buff, 0, buff.Length); } } catch (IOException) { Assert.Fail("The nonowner2 should have execute permission on the directory"); } } /// <summary> /// Unit test to modify ACL entries /// </summary> [TestMethod] public void TestModifyAcl() { TestModifyAcl(UnitTestDir + "/ModifyAclEntries.txt"); } /// <summary> /// Unit test to modify ACL entries /// </summary> /// <param name="path">Destination path</param> public void TestModifyAcl(string path) { using (_adlsClient.CreateFile(path, IfExists.Overwrite, "770")) { } AdlsClient nonOwner1 = SetupNonOwnerClient1(); Assert.IsFalse(nonOwner1.CheckAccess(path, "rw-")); AdlsClient nonOwner2 = SetupNonOwnerClient2(); Assert.IsFalse(nonOwner2.CheckAccess(path, "r-x")); //Setup Acl Entries List<AclEntry> aclList = new List<AclEntry>() { new AclEntry(AclType.user, NonOwner1ObjectId, AclScope.Access, AclAction.ReadWrite), //Non owner client 1 new AclEntry(AclType.user, NonOwner2ObjectId, AclScope.Access, AclAction.ReadExecute) };//NonOwnerClient 2 _adlsClient.ModifyAclEntries(path, aclList); Assert.IsTrue(nonOwner1.CheckAccess(path, "rw-")); try { using (var istream = nonOwner1.GetReadStream(path)) { byte[] buff = new byte[25]; istream.Read(buff, 0, buff.Length); } } catch (IOException) { Assert.Fail("nonowner1 should have read permission so ReadStream should not raise an exception"); } try { using (var istream = nonOwner1.GetReadStream(path)) { byte[] buff = new byte[25]; istream.Read(buff, 0, buff.Length); } } catch (IOException) { Assert.Fail("nonowner1 should have read permission so ReadStream should not raise an exception"); } Assert.IsFalse(nonOwner1.CheckAccess(path, "--x")); Assert.IsTrue(nonOwner2.CheckAccess(path, "--x")); Assert.IsFalse(nonOwner2.CheckAccess(path, "rw-")); } /// <summary> /// Unit test to modify Acl entries for a group /// </summary> [TestMethod] public void TestModifyAclGroup() { string path = $"{UnitTestDir}/ModifyAclEntryGroup.txt"; using (_adlsClient.CreateFile(path, IfExists.Overwrite, "700")) { } AdlsClient nonOwner2 = SetupNonOwnerClient2(); try { using (nonOwner2.GetAppendStream(path)) { } Assert.Fail("Nonowner2 should not have write permission so AppendStream should raise an exception"); } catch (IOException) { } List<AclEntry> aclList = new List<AclEntry>() { new AclEntry(AclType.group, Group1Id, AclScope.Access, AclAction.ReadWrite)};//Non owner client 2 _adlsClient.ModifyAclEntries(path, aclList); try { using (nonOwner2.GetAppendStream(path)) { } } catch (IOException) { Assert.Fail("Nonowner2 should have write permission so AppendStream should not raise an exception"); } try { using (var istream = nonOwner2.GetReadStream(path)) { byte[] buffer = new byte[25]; istream.Read(buffer, 0, buffer.Length); } } catch (IOException) { Assert.Fail("Nonowner2 should not have read permission so ReadStream should not raise an exception"); } } /// <summary> /// Unit test to modify Acl for Other /// </summary> [TestMethod] public void TestModifyAclOther() { string path = $"{UnitTestDir}/ModifyAclEntryOther.txt"; using (_adlsClient.CreateFile(path, IfExists.Overwrite, "700")) { } AdlsClient nonOwner2 = SetupNonOwnerClient2(); try { using (nonOwner2.GetAppendStream(path)) { } Assert.Fail("Nonowner2 should not have write permission so AppendStream should raise an exception"); } catch (IOException) { } List<AclEntry> aclList = new List<AclEntry>() { new AclEntry(AclType.other, "", AclScope.Access, AclAction.ReadWrite)};//Non owner client 1 _adlsClient.ModifyAclEntries(path, aclList); try { using (nonOwner2.GetAppendStream(path)) { } } catch (IOException) { Assert.Fail("Nonowner2 should have write permission so AppendStream should not raise an exception"); } try { using (var istream = nonOwner2.GetReadStream(path)) { byte[] buffer = new byte[25]; istream.Read(buffer, 0, buffer.Length); } } catch (IOException) { Assert.Fail("Nonowner2 should have read permission so ReadStream should not raise an exception"); } } /// <summary> /// Unit test to modify Acl Mask /// </summary> [TestMethod] public void TestModifyAclMask() { string path = $"{UnitTestDir}/ModifyAclEntryMask.txt"; using (var ostream = _adlsClient.CreateFile(path, IfExists.Overwrite, "700")) { byte[] buff = Encoding.UTF8.GetBytes("Hello"); ostream.Write(buff, 0, buff.Length); } AdlsClient nonOwner1 = SetupNonOwnerClient1(); try { using (nonOwner1.GetAppendStream(path)) { } Assert.Fail("Nonowner1 should not have write permission so AppendStream should raise an exception"); } catch (IOException) { } List<AclEntry> aclList = new List<AclEntry>() { new AclEntry(AclType.mask, "", AclScope.Access, AclAction.ReadOnly), new AclEntry(AclType.user, NonOwner1ObjectId, AclScope.Access, AclAction.ReadWrite)};//Non owner client 1 _adlsClient.ModifyAclEntries(path, aclList); try { using (nonOwner1.GetAppendStream(path)) { } Assert.Fail("Nonowner1 still should not have effective write permission so AppendStream should raise an exception"); } catch (IOException) { } try { using (var istream = nonOwner1.GetReadStream(path)) { byte[] buffer = new byte[25]; istream.Read(buffer, 0, buffer.Length); } } catch (IOException) { Assert.Fail("Nonowner1 should have read permission so ReadStream should not raise an exception"); } } /// <summary> /// Unit test to modfy Acl Mask for group /// </summary> [TestMethod] public void TestAclMaskGroup() { string path = $"{UnitTestDir}/TestAclMaskGroup"; _adlsClient.CreateDirectory(path, ""); List<AclEntry> aclList = new List<AclEntry>() { new AclEntry(AclType.user, NonOwner2ObjectId, AclScope.Access, AclAction.All), new AclEntry(AclType.user, NonOwner3ObjectId,AclScope.Access, AclAction.ExecuteOnly) };//Non owner client 2 _adlsClient.ModifyAclEntries(path, aclList); string subDirec = path + "/SubDir"; AdlsClient nonOwner2 = SetupNonOwnerClient2(); nonOwner2.CreateDirectory(subDirec, "770"); aclList = new List<AclEntry>() { new AclEntry(AclType.group, Group1Id, AclScope.Access, AclAction.WriteExecute), //Non owner client 2 and 3 }; nonOwner2.ModifyAclEntries(subDirec, aclList); AdlsClient nonOwner3 = SetupNonOwnerClient3(); Assert.IsTrue(nonOwner3.CheckAccess(subDirec, "-wx")); aclList = new List<AclEntry>() { new AclEntry(AclType.mask, "", AclScope.Access, AclAction.ReadExecute), //Non owner client 2 and 3 }; nonOwner2.ModifyAclEntries(subDirec, aclList); Assert.IsFalse(nonOwner3.CheckAccess(subDirec, "-w-")); } /// <summary> /// Unit test to set owner group and verify the mask changed /// </summary> [TestMethod] public void TestSetOwnerGroupMask() { string path = $"{UnitTestDir}/TestGroupMask"; _adlsClient.CreateDirectory(path, ""); List<AclEntry> aclList = new List<AclEntry>() { new AclEntry(AclType.user, NonOwner2ObjectId, AclScope.Access, AclAction.All), new AclEntry(AclType.user, NonOwner3ObjectId,AclScope.Access, AclAction.ExecuteOnly), new AclEntry(AclType.user, NonOwner1ObjectId,AclScope.Access, AclAction.ExecuteOnly) };//Non owner client 2 _adlsClient.ModifyAclEntries(path, aclList); string subDirec = path + "/SubDir"; AdlsClient nonOwner2 = SetupNonOwnerClient2(); AdlsClient nonOwner3 = SetupNonOwnerClient3(); AdlsClient nonOwner1 = SetupNonOwnerClient1(); nonOwner2.CreateDirectory(subDirec, "770"); _adlsClient.SetOwner(subDirec, "", Group1Id); Assert.IsTrue(nonOwner2.CheckAccess(subDirec, "rwx")); Assert.IsTrue(nonOwner3.CheckAccess(subDirec, "rwx"));//Because group has access aclList = new List<AclEntry>() { new AclEntry(AclType.mask, "", AclScope.Access,AclAction.ReadExecute), new AclEntry(AclType.user,NonOwner1ObjectId, AclScope.Access,AclAction.WriteExecute) }; _adlsClient.ModifyAclEntries(subDirec, aclList); Assert.IsFalse(nonOwner3.CheckAccess(subDirec, "-w-"));//Due to mask the group permission changed Assert.IsTrue(nonOwner3.CheckAccess(subDirec, "r-x")); Assert.IsTrue(nonOwner1.CheckAccess(subDirec, "--x")); Assert.IsFalse(nonOwner1.CheckAccess(subDirec, "-w-")); Assert.IsFalse(nonOwner1.CheckAccess(subDirec, "r--")); Assert.IsTrue(nonOwner2.CheckAccess(subDirec, "rwx")); } /// <summary> /// Unit test to set Owner /// </summary> [TestMethod] public void TestSetOwner() { string path = $"{UnitTestDir}/TestOwner"; _adlsClient.CreateDirectory(path, ""); List<AclEntry> aclList = new List<AclEntry>() { new AclEntry(AclType.user, NonOwner2ObjectId, AclScope.Access, AclAction.All), new AclEntry(AclType.user, NonOwner3ObjectId, AclScope.Access, AclAction.ExecuteOnly), };//Non owner client 2 _adlsClient.ModifyAclEntries(path, aclList); string subDirec = path + "/SubDir"; AdlsClient nonOwner2 = SetupNonOwnerClient2(); nonOwner2.CreateDirectory(subDirec, "770"); Assert.IsTrue(nonOwner2.CheckAccess(subDirec, "rwx")); _adlsClient.SetOwner(subDirec, NonOwner3ObjectId, ""); Assert.IsFalse(nonOwner2.CheckAccess(subDirec, "rwx")); AdlsClient nonOwner3 = SetupNonOwnerClient3(); Assert.IsTrue(nonOwner3.CheckAccess(subDirec, "rwx")); string subSubFile = subDirec + "/subFile.txt"; try { using (nonOwner3.CreateFile(subSubFile, IfExists.Overwrite, "")) { } using (nonOwner3.GetReadStream(subSubFile)) { } } catch (Exception) { Assert.Fail("NonOwner 3 should have read write access to the subdirec so Create file and read stream should not raise an exception"); } DirectoryEntry dir = nonOwner3.GetDirectoryEntry(subDirec); Assert.IsTrue(dir.User.Equals(NonOwner3ObjectId)); } /// <summary> /// Unit test to set group owner /// </summary> [TestMethod] public void TestSetGroup() { string path = $"{UnitTestDir}/TestGroup"; _adlsClient.CreateDirectory(path, ""); List<AclEntry> aclList = new List<AclEntry>() { new AclEntry(AclType.user, NonOwner2ObjectId, AclScope.Access, AclAction.All), new AclEntry(AclType.user, NonOwner3ObjectId, AclScope.Access, AclAction.ExecuteOnly), }; //Non owner client 2 _adlsClient.ModifyAclEntries(path, aclList); string subDirec = path + "/SubDir"; AdlsClient nonOwner2 = SetupNonOwnerClient2(); nonOwner2.CreateDirectory(subDirec, "770"); AdlsClient nonOwner3 = SetupNonOwnerClient3(); //Nonowner3 should not have any access Assert.IsFalse(nonOwner3.CheckAccess(subDirec, "r--")); Assert.IsFalse(nonOwner3.CheckAccess(subDirec, "-w-")); //Nonowner3 is a part of group1 _adlsClient.SetOwner(subDirec, "", Group1Id); Assert.IsTrue(nonOwner3.CheckAccess(subDirec, "rwx")); _adlsClient.SetPermission(subDirec, "750"); //As we changed permission of group the permission of nonowner3 changed Assert.IsTrue(nonOwner3.CheckAccess(subDirec, "r-x")); Assert.IsFalse(nonOwner3.CheckAccess(subDirec, "-w-")); DirectoryEntry dir = nonOwner2.GetDirectoryEntry(subDirec); Assert.IsTrue(dir.Group.Equals(Group1Id)); } /// <summary> /// Unit test for extended Acl /// </summary> [TestMethod] public void TestAclExtended() { string path = $"{UnitTestDir}/TestAclExtended"; _adlsClient.CreateDirectory(path, "750"); List<AclEntry> aclList = new List<AclEntry>() { new AclEntry(AclType.user, NonOwner2ObjectId, AclScope.Access, AclAction.All), //Non owner client 2 }; _adlsClient.ModifyAclEntries(path, aclList); AdlsClient nonOwner2 = SetupNonOwnerClient2(); string subFile1 = path + "/subFile1.txt"; try { using (nonOwner2.CreateFile(subFile1, IfExists.Overwrite, "")) { } } catch (IOException) { Assert.Fail("This should pass because mask is rwx so it still shouldnt have effective write"); } _adlsClient.SetPermission(path, "750"); //When Acl is set and you change the group the mask is changed string subFile2 = path + "/subFile2.txt"; try { using (nonOwner2.CreateFile(subFile2, IfExists.Overwrite, "")) { } Assert.Fail("This shouldnt pass because mask is r-x so it still shouldnt have effective write"); } catch (IOException) { } List<AclEntry> aclList1 = new List<AclEntry>() { new AclEntry(AclType.user, NonOwner1ObjectId, AclScope.Access, AclAction.WriteExecute), //Non owner client 2 }; _adlsClient.ModifyAclEntries(path, aclList1);//Mask is recalculated try { using (nonOwner2.CreateFile(subFile2, IfExists.Overwrite, "")) { } } catch (IOException) { Assert.Fail("Create file should not raise an exception because recalculated mask is rwx and nonowner2 still shouldnt have effective write"); } } /// <summary> /// Unit test to set default Acl /// </summary> [TestMethod] public void TestAclDefault() { TestAclDefault(UnitTestDir + "/DefaultAclEntries"); } /// <summary> /// Unit test to set default Acl /// </summary> /// <param name="path">Path for setting default Acl</param> public void TestAclDefault(string path) { _adlsClient.CreateDirectory(path, "700"); AdlsClient nonOwner1 = SetupNonOwnerClient1(); Assert.IsFalse(nonOwner1.CheckAccess(path, "rwx")); //Setup Acl Entries List<AclEntry> aclList = new List<AclEntry>() { new AclEntry(AclType.user, NonOwner1ObjectId, AclScope.Access, AclAction.WriteExecute),//Non owner client 1 new AclEntry(AclType.user, NonOwner1ObjectId, AclScope.Default, AclAction.WriteExecute)};//Non owner client 1 _adlsClient.ModifyAclEntries(path, aclList); Assert.IsTrue(nonOwner1.CheckAccess(path, "--x")); string subDirec = path + "/subdirec"; string subFile = path + "/subFile"; _adlsClient.CreateDirectory(subDirec, ""); using (_adlsClient.CreateFile(subFile, IfExists.Overwrite, "")) { } Assert.IsTrue(nonOwner1.CheckAccess(subFile, "-wx")); Assert.IsTrue(nonOwner1.CheckAccess(subDirec, "-wx")); string subDirecsubFile = subDirec + "/subSubFile.txt"; try { using (nonOwner1.CreateFile(subDirecsubFile, IfExists.Overwrite, "700")) { } } catch (IOException) { Assert.Fail("Nonowner1 should have write and execute permission on the directory so create file in the directory should not raise an exception "); } } /// <summary> /// Unit test to verify the effective access after setting default Acl for user /// </summary> [TestMethod] public void TestAclDefaultMode() { string path = $"{UnitTestDir}/TestAclDefaultMode"; _adlsClient.CreateDirectory(path, "730"); List<AclEntry> aclList = new List<AclEntry>() { new AclEntry(AclType.user, NonOwner1ObjectId, AclScope.Access, AclAction.WriteExecute), new AclEntry(AclType.user, NonOwner1ObjectId, AclScope.Default, AclAction.WriteExecute)};//Non owner client 2 _adlsClient.ModifyAclEntries(path, aclList); AdlsClient nonOwner1 = SetupNonOwnerClient1(); //Mask is -wx string subFile1 = path + "/subFile1.txt"; string subFile2 = path + "/subFile2.txt"; using (_adlsClient.CreateFile(subFile1, IfExists.Overwrite, "750"))//Mask of subFile1 is r-x { } using (_adlsClient.CreateFile(subFile2, IfExists.Overwrite, "730"))//Mask of subFile1 is -wx { } try { using (nonOwner1.GetAppendStream(subFile1)) { } Assert.Fail("Nonowner1 shouldnt have effective write accecss so AppendStream should raise an exception"); } catch (IOException) { } try { using (nonOwner1.GetAppendStream(subFile2)) { } } catch (IOException) { Assert.Fail("Nonowner1 should have effective write accecss so AppendStream should not raise an exception"); } } /// <summary> /// Unit test to set default Acl for groups /// </summary> [TestMethod] public void TestAclDefaultGroup() { string path = $"{UnitTestDir}/TestAclDefaultGroup"; _adlsClient.CreateDirectory(path, "740"); AdlsClient nonOwner2 = SetupNonOwnerClient2(); string subDirec = path + "/subdirec"; string subFile = path + "/subFile"; List<AclEntry> aclList = new List<AclEntry>() { new AclEntry(AclType.group, Group1Id, AclScope.Access, AclAction.WriteExecute), new AclEntry(AclType.group, Group1Id, AclScope.Default, AclAction.All)};//Non owner client 2 _adlsClient.ModifyAclEntries(path, aclList); //Mask of path is rwx _adlsClient.CreateDirectory(subDirec, "730");//Mask of directory becomes -wx using (_adlsClient.CreateFile(subFile, IfExists.Overwrite, "740"))//Mask of file becomes r-- { } try { using (nonOwner2.GetAppendStream(subFile)) { } Assert.Fail("Nonowner2 should have no effective access so AppendStream should raise an exception"); } catch (IOException) { } Assert.IsTrue(nonOwner2.CheckAccess(subFile, "r--")); Assert.IsTrue(nonOwner2.CheckAccess(subDirec, "-wx")); string subDirecsubFile = subDirec + "/subSubFile.txt"; try { using (nonOwner2.CreateFile(subDirecsubFile, IfExists.Overwrite, "")) { } } catch (IOException) { Assert.Fail("Nonowner2 should have write and default access so CreateFile should not raise an exception"); } } /// <summary> /// Unit test for removing Acl /// </summary> [TestMethod] public void TestRemoveAcl() { string path = $"{UnitTestDir}/TestRemoveAcl.txt"; TestModifyAcl(path); List<AclEntry> aclList = new List<AclEntry>() { new AclEntry(AclType.user, NonOwner1ObjectId, AclScope.Access, AclAction.ReadWrite) };//Non owner client 1 _adlsClient.RemoveAclEntries(path, aclList); AdlsClient nonOwner1 = SetupNonOwnerClient1(); Assert.IsFalse(nonOwner1.CheckAccess(path, "rw-")); Assert.IsFalse(nonOwner1.CheckAccess(path, "--x")); AdlsClient nonOwner2 = SetupNonOwnerClient2(); Assert.IsTrue(nonOwner2.CheckAccess(path, "--x")); Assert.IsFalse(nonOwner2.CheckAccess(path, "rw-")); } /// <summary> /// Unit test for removing Default Acl /// </summary> [TestMethod] public void TestRemoveDefaultAcl() { string path = $"{UnitTestDir}/TestRemoveDefault"; TestAclDefault(path); _adlsClient.RemoveDefaultAcls(path); string subDirec = path + "/subdirecNew"; string subFile = path + "/subFileNew"; _adlsClient.CreateDirectory(subDirec, ""); using (_adlsClient.CreateFile(subFile, IfExists.Overwrite, "")) { } AdlsClient nonOwner1 = SetupNonOwnerClient1(); Assert.IsFalse(nonOwner1.CheckAccess(subDirec, "-wx")); Assert.IsFalse(nonOwner1.CheckAccess(subFile, "-wx")); } /// <summary> /// Unit test for removing all acl /// </summary> [TestMethod] public void TestRemoveAllAcl() { string path = $"{UnitTestDir}/TesRemoveAcl"; TestModifyAcl(path); _adlsClient.RemoveAllAcls(path); AdlsClient nonOwnerCLient1 = SetupNonOwnerClient1(); AdlsClient nonOwnerCLient2 = SetupNonOwnerClient2(); Assert.IsFalse(nonOwnerCLient1.CheckAccess(path, "rw-")); Assert.IsFalse(nonOwnerCLient2.CheckAccess(path, "--x")); } /// <summary> /// Unit test for getting Acl status /// </summary> [TestMethod] public void TestGetAclStatus() { string path = $"{UnitTestDir}/TestGetAclStatus"; TestModifyAcl(path); AclStatus status = _adlsClient.GetAclStatus(path); Assert.IsTrue(status.Owner.Equals(_ownerObjectId)); Assert.IsTrue(status.Permission.Equals("770")); Assert.IsTrue(status.Entries.Contains(new AclEntry(AclType.user, NonOwner1ObjectId, AclScope.Access, AclAction.ReadWrite))); Assert.IsTrue(status.Entries.Contains(new AclEntry(AclType.user, NonOwner2ObjectId, AclScope.Access, AclAction.ReadExecute))); } #endregion #region TrashEnumerateRestore private Tuple<EnumerateDeletedItemsProgress, Progress<EnumerateDeletedItemsProgress>> GetProgressTracker() { var progressTracker = new Progress<EnumerateDeletedItemsProgress>(); EnumerateDeletedItemsProgress progress = new EnumerateDeletedItemsProgress(); progressTracker.ProgressChanged += (s, e) => { lock (progress) { progress.NumSearched = e.NumSearched; progress.NumFound = e.NumFound; progress.NextListAfter = e.NextListAfter; } }; return Tuple.Create<EnumerateDeletedItemsProgress, Progress<EnumerateDeletedItemsProgress>>(progress,progressTracker); } [TestMethod] public void TestRestoreDeletedItemsToOriginalDestination() { // Restore file string streamName = GetFileOrFolderName("file"); SetupTrashFile(streamName, "file"); // Enumerate goes to Alki secondaries, so sleep to let them catch up. Thread.Sleep(3000); IEnumerable<TrashEntry> trashEntries = _adlsClient.EnumerateDeletedItems(streamName, null, 1, null); Assert.IsTrue(trashEntries.Count() == 1); Assert.IsTrue(trashEntries.ElementAt(0).Type == TrashEntryType.FILE); string restoreToken = trashEntries.ElementAt(0).TrashDirPath; string destPath = trashEntries.ElementAt(0).OriginalPath; _adlsClient.RestoreDeletedItems(restoreToken, destPath, "file"); // Get file status on restored entry string path = $"{UnitTestDir}/" + streamName; DirectoryEntry diren = _adlsClient.GetDirectoryEntry(path); // Restore directory string dirName = GetFileOrFolderName("directory"); SetupTrashFile(dirName, "directory"); // Enumerate goes to Alki secondaries, so sleep to let them catch up. Thread.Sleep(3000); trashEntries = _adlsClient.EnumerateDeletedItems(dirName, null, 1, null); Assert.IsTrue(trashEntries.Count() == 1); Assert.IsTrue(trashEntries.ElementAt(0).Type == TrashEntryType.DIRECTORY); restoreToken = trashEntries.ElementAt(0).TrashDirPath; destPath = trashEntries.ElementAt(0).OriginalPath; _adlsClient.RestoreDeletedItems(restoreToken, destPath, "directory"); // Get file status on restored entry path = $"{UnitTestDir}/" + dirName; diren = _adlsClient.GetDirectoryEntry(path); } [TestMethod] public void TestRestoreDeletedItemsToNewDestination() { // Restore file string streamName = GetFileOrFolderName("file"); SetupTrashFile(streamName, "file"); string path = $"{UnitTestDir}/" + streamName; _adlsClient.CreateFile(path, IfExists.Overwrite); Thread.Sleep(3000); IEnumerable<TrashEntry> trashEntries = _adlsClient.EnumerateDeletedItems(streamName, null, 1, null); Assert.IsTrue(trashEntries.Count() == 1); Assert.IsTrue(trashEntries.ElementAt(0).Type == TrashEntryType.FILE); string restoreToken = trashEntries.ElementAt(0).TrashDirPath; string destPath = trashEntries.ElementAt(0).OriginalPath; try { _adlsClient.RestoreDeletedItems(restoreToken, destPath, "file"); Assert.IsTrue(false); } catch (AdlsException ex) { Assert.IsTrue(ex.HttpStatus == HttpStatusCode.Conflict); } destPath.Substring(0, destPath.LastIndexOf('/') + 1); String newName = GetFileOrFolderName("file"); destPath += newName; _adlsClient.RestoreDeletedItems(restoreToken, destPath, "file"); // Get file status on restored entry path.Substring(0, path.LastIndexOf('/') + 1); path += newName; DirectoryEntry diren = _adlsClient.GetDirectoryEntry(path); // Restore Directory string dirName = GetFileOrFolderName("directory"); SetupTrashFile(dirName, "directory"); path = $"{UnitTestDir}/" + dirName; bool result = _adlsClient.CreateDirectory(path); Assert.IsTrue(result); Thread.Sleep(3000); trashEntries = _adlsClient.EnumerateDeletedItems(dirName, null, 1, null); Assert.IsTrue(trashEntries.Count() == 1); Assert.IsTrue(trashEntries.ElementAt(0).Type == TrashEntryType.DIRECTORY); restoreToken = trashEntries.ElementAt(0).TrashDirPath; destPath = trashEntries.ElementAt(0).OriginalPath; try { _adlsClient.RestoreDeletedItems(restoreToken, destPath, "directory"); Assert.IsTrue(false); } catch (AdlsException ex) { Assert.IsTrue(ex.HttpStatus == HttpStatusCode.Conflict); } destPath.Substring(0, destPath.LastIndexOf('/') + 1); newName = GetFileOrFolderName("file"); destPath += newName; _adlsClient.RestoreDeletedItems(restoreToken, destPath, "directory"); // Get file status on restored entry path.Substring(0, path.LastIndexOf('/') + 1); path += newName; diren = _adlsClient.GetDirectoryEntry(path); } [TestMethod] public void TestRestoreDeletedItemsFileWithOverwriteOrCopy() { // Test copy string streamName = GetFileOrFolderName("file"); SetupTrashFile(streamName, "file"); string path = $"{UnitTestDir}/" + streamName; _adlsClient.CreateFile(path, IfExists.Overwrite); Thread.Sleep(3000); IEnumerable<TrashEntry> trashEntries = _adlsClient.EnumerateDeletedItems(streamName, null, 1, null); Assert.IsTrue(trashEntries.Count() == 1); Assert.IsTrue(trashEntries.ElementAt(0).Type == TrashEntryType.FILE); string restoreToken = trashEntries.ElementAt(0).TrashDirPath; string destPath = trashEntries.ElementAt(0).OriginalPath; try { _adlsClient.RestoreDeletedItems(restoreToken, destPath, "file"); Assert.IsTrue(false); } catch (AdlsException ex) { Assert.IsTrue(ex.HttpStatus == HttpStatusCode.Conflict); } _adlsClient.RestoreDeletedItems(restoreToken, destPath, "file", "copy"); // Test overwrite streamName = GetFileOrFolderName("file"); SetupTrashFile(streamName, "file"); path = $"{UnitTestDir}/" + streamName; _adlsClient.CreateFile(path, IfExists.Overwrite, "777"); Thread.Sleep(3000); trashEntries = _adlsClient.EnumerateDeletedItems(streamName, null, 1, null); Assert.IsTrue(trashEntries.Count() == 1); Assert.IsTrue(trashEntries.ElementAt(0).Type == TrashEntryType.FILE); restoreToken = trashEntries.ElementAt(0).TrashDirPath; destPath = trashEntries.ElementAt(0).OriginalPath; try { _adlsClient.RestoreDeletedItems(restoreToken, destPath, "file"); Assert.IsTrue(false); } catch (AdlsException ex) { Assert.IsTrue(ex.HttpStatus == HttpStatusCode.Conflict); } _adlsClient.RestoreDeletedItems(restoreToken, destPath, "file", "overwrite"); } [TestMethod] public void TestRestoreDeletedItemsDirectoryWithCopy() { // Test copy string dirName = GetFileOrFolderName("directory"); SetupTrashFile(dirName, "directory"); string path = $"{UnitTestDir}/" + dirName; bool result = _adlsClient.CreateDirectory(path); Assert.IsTrue(result); Thread.Sleep(3000); IEnumerable<TrashEntry> trashEntries = _adlsClient.EnumerateDeletedItems(dirName, null, 1, null); Assert.IsTrue(trashEntries.Count() == 1); Assert.IsTrue(trashEntries.ElementAt(0).Type == TrashEntryType.DIRECTORY); string restoreToken = trashEntries.ElementAt(0).TrashDirPath; string destPath = trashEntries.ElementAt(0).OriginalPath; try { _adlsClient.RestoreDeletedItems(restoreToken, destPath, "directory"); Assert.IsTrue(false); } catch (AdlsException ex) { Assert.IsTrue(ex.HttpStatus == HttpStatusCode.Conflict); } _adlsClient.RestoreDeletedItems(restoreToken, destPath, "directory", "copy"); // directory restores with overwrites not supported yet } [TestMethod] public void TestTrashEnumerateCancellationToken() { CancellationTokenSource source = new CancellationTokenSource(); CancellationToken token = source.Token; string streamName = GetFileOrFolderName("file"); SetupTrashFile(streamName, "file"); source.Cancel(); var tuple = GetProgressTracker(); IEnumerable<TrashEntry> trashEntries = _adlsClient.EnumerateDeletedItems(streamName, null, 1, tuple.Item2, token); Thread.Sleep(3000); Assert.IsTrue(tuple.Item1.NumSearched == 0); } [TestMethod] public void TestTrashEnumerateForMultipleFileSearch() { string prefix = GetFileOrFolderName("file"); int N = 10; for (int i = 0; i < N; i++) { string streamName = prefix + "_" + GetFileOrFolderName("file"); SetupTrashFile(streamName, "file"); } Thread.Sleep(3000); var progresstuple = GetProgressTracker(); IEnumerable<TrashEntry> trashEntries = _adlsClient.EnumerateDeletedItems(prefix, null, N, progresstuple.Item2); Thread.Sleep(3000); Assert.IsTrue(progresstuple.Item1.NumFound == N); for (int i = 0; i < N; i++) { Assert.IsTrue(trashEntries.ElementAt(i).Type == TrashEntryType.FILE); } } [TestMethod] public void TestTrashEnumerateForZeroFileSearch() { var progresstuple = GetProgressTracker(); IEnumerable<TrashEntry> trashEntries = _adlsClient.EnumerateDeletedItems("zzzzz", null, 1, progresstuple.Item2); Thread.Sleep(3000); Assert.IsTrue(progresstuple.Item1.NumFound == 0); Assert.IsTrue(string.IsNullOrEmpty(progresstuple.Item1.NextListAfter)); } [TestMethod] public void TestTrashEnumerateForEmptyHint() { try { IEnumerable<TrashEntry> trashEntries = _adlsClient.EnumerateDeletedItems("", null, 1, null); Assert.IsTrue(false); } catch(Exception ex) { if(ex is ArgumentException) { Assert.IsTrue(true); } else { Assert.IsTrue(false); } return; } Assert.IsTrue(false); } [TestMethod] public void TestTrashEnumerateForMultipleDirectorySearch() { string prefix = GetFileOrFolderName("directory"); int N = 10; for (int i = 0; i < N; i++) { string dirName = prefix + "_" + GetFileOrFolderName("directory"); SetupTrashFile(dirName, "directory"); } Thread.Sleep(3000); var progresstuple = GetProgressTracker(); IEnumerable<TrashEntry> trashEntries = _adlsClient.EnumerateDeletedItems(prefix, null, N, progresstuple.Item2); Thread.Sleep(3000); Assert.IsTrue(progresstuple.Item1.NumFound == N); for (int i = 0; i < N; i++) { Assert.IsTrue(trashEntries.ElementAt(i).Type == TrashEntryType.DIRECTORY); } } [TestMethod] public void TestTrashEnumerateWithToken() { string prefix = GetFileOrFolderName("file"); int N = 10; for (int i = 0; i < N; i++) { string streamName = prefix + "_" + GetFileOrFolderName("file"); SetupTrashFile(streamName, "file"); } Thread.Sleep(3000); var (trashEntries, nextListAfter) = _adlsClient.EnumerateDeletedItemsWithToken(prefix, null, 10, null); Assert.IsTrue(trashEntries.Count() == 10); Assert.IsTrue(string.IsNullOrEmpty(nextListAfter)); Assert.IsTrue(trashEntries.All(entry => entry.Type == TrashEntryType.FILE)); } #endregion private bool VerifyGuid(string objectId) { return Regex.IsMatch(objectId, @"^[{(]?[0-9A-Fa-f]{8}[-]?([0-9A-Fa-f]{4}[-]?){3}[0-9A-Fa-f]{12}[)}]?$"); } /// <summary> /// Unit test for getting content summary of a directory /// </summary> [TestMethod] public void TestGetContentSummary() { string path = $"{UnitTestDir}/CntSum"; int oneLevelDirecCnt = 3; int oneLevelFileCnt = 2; int recurseLevel = 2; int oneFileSize = 100; int expectedDirCnt = 0; int power = 1; for (int i = 1; i <= recurseLevel; i++) { power *= oneLevelDirecCnt; expectedDirCnt += power; } int expectedFileCnt = (expectedDirCnt + 1) * oneLevelFileCnt; int expectedFileSize = expectedFileCnt * oneFileSize; TestDataCreator.DataCreator.CreateDirRecursiveRemote(_adlsClient, path, recurseLevel, oneLevelDirecCnt, oneLevelFileCnt, oneLevelFileCnt, oneFileSize, oneFileSize); ContentSummary summary = _adlsClient.GetContentSummary(path); Assert.IsTrue(summary.DirectoryCount == expectedDirCnt); Assert.IsTrue(summary.FileCount == expectedFileCnt); Assert.IsTrue(summary.SpaceConsumed == expectedFileSize); } [TestMethod] [ExpectedException(typeof(AdlsException))] public void TestGetFileListStatusNotFoundException() { string path = $"{UnitTestDir}/TestGetFileListStatusException"; foreach (var entry in _adlsClient.EnumerateDirectory(path)) { } } /// <summary> /// Unit test to get filelist status of a directory /// </summary> [TestMethod] public void TestGetFileListStatus() { char prefix = 'F'; string path = $"{UnitTestDir}/{prefix}"; int totFiles = 1; string filePrefix = ""; int setListSize = 120; HashSet<string> hSet = new HashSet<string>(); HashSet<string> hFullNameSet = new HashSet<string>(); // DataCreator creates new folder/file with TestDataCreator.DataCreator.CreateDirRecursiveRemote(_adlsClient, path, 0, 0, 0, 0, 0, 0, false, filePrefix); TestGetFileStatus(path, 0, hSet, hFullNameSet, 0, setListSize); TestGetFileStatus(path, 1, hSet, hFullNameSet, 0, setListSize); TestDataCreator.DataCreator.CreateDirRecursiveRemote(_adlsClient, path, 0, 0, totFiles, totFiles, 0, 0, false, filePrefix); for (int i = 0; i < totFiles; i++) { hSet.Add(prefix + (filePrefix + i + "File.txt")); hFullNameSet.Add(path + "/" + prefix + filePrefix + i + "File.txt"); } TestGetFileStatus(path, 1, hSet, hFullNameSet, 1, setListSize); TestGetFileStatus(path, 2, hSet, hFullNameSet, 1, setListSize); totFiles = 99; filePrefix = "A1"; TestDataCreator.DataCreator.CreateDirRecursiveRemote(_adlsClient, path, 0, 0, totFiles, totFiles, 0, 0, false, filePrefix); for (int i = 0; i < totFiles; i++) { hSet.Add(prefix + (filePrefix + i + "File.txt")); hFullNameSet.Add(path + "/" + prefix + filePrefix + i + "File.txt"); } TestGetFileStatus(path, 50, hSet, hFullNameSet, 50, setListSize); TestGetFileStatus(path, 100, hSet, hFullNameSet, 100, setListSize); TestGetFileStatus(path, setListSize, hSet, hFullNameSet, 100, setListSize); totFiles = 20; filePrefix = "A2"; TestDataCreator.DataCreator.CreateDirRecursiveRemote(_adlsClient, path, 0, 0, totFiles, totFiles, 0, 0, false, filePrefix); for (int i = 0; i < totFiles; i++) { hSet.Add(prefix + (filePrefix + i + "File.txt")); hFullNameSet.Add(path + "/" + prefix + filePrefix + i + "File.txt"); } TestGetFileStatus(path, setListSize - 1, hSet, hFullNameSet, setListSize - 1, setListSize); TestGetFileStatus(path, setListSize, hSet, hFullNameSet, setListSize, setListSize); TestGetFileStatus(path, setListSize + 1, hSet, hFullNameSet, setListSize, setListSize); totFiles = 80; filePrefix = "A3"; TestDataCreator.DataCreator.CreateDirRecursiveRemote(_adlsClient, path, 0, 0, totFiles, totFiles, 0, 0, false, filePrefix); for (int i = 0; i < totFiles; i++) { hSet.Add(prefix + (filePrefix + i + "File.txt")); hFullNameSet.Add(path + "/" + prefix + filePrefix + i + "File.txt"); } TestGetFileStatus(path, 100, hSet, hFullNameSet, 100, setListSize); TestGetFileStatus(path, setListSize, hSet, hFullNameSet, setListSize, setListSize); TestGetFileStatus(path, 200, hSet, hFullNameSet, 200, setListSize); TestGetFileStatus(path, 201, hSet, hFullNameSet, 200, setListSize); totFiles = 100; filePrefix = "A4"; TestDataCreator.DataCreator.CreateDirRecursiveRemote(_adlsClient, path, 0, 0, totFiles, totFiles, 0, 0, false, filePrefix); for (int i = 0; i < totFiles; i++) { hSet.Add(prefix + (filePrefix + i + "File.txt")); hFullNameSet.Add(path + "/" + prefix + filePrefix + i + "File.txt"); } TestGetFileStatus(path, 100, hSet, hFullNameSet, 100, setListSize); TestGetFileStatus(path, setListSize, hSet, hFullNameSet, setListSize, setListSize); TestGetFileStatus(path, 200, hSet, hFullNameSet, 200, setListSize); TestGetFileStatus(path, 2 * setListSize, hSet, hFullNameSet, 2 * setListSize, setListSize); TestGetFileStatus(path, 300, hSet, hFullNameSet, 300, setListSize); TestGetFileStatus(path, 400, hSet, hFullNameSet, 300, setListSize); TestListStatusUsingCore(path, 400, hSet, hFullNameSet, 300); } public static void TestGetFileStatus(string path, int maxEntries, HashSet<string> hSet, HashSet<string> fullNamehSet, int expectedEntries, int setListSize = 100) { TestGetFileStatusStandard(path, maxEntries, hSet, fullNamehSet, expectedEntries, setListSize); TestGetFileStatusMinimal(path, maxEntries, hSet, fullNamehSet, expectedEntries, setListSize); } public static void TestGetFileStatusStandard(string path, int maxEntries, HashSet<string> hSet, HashSet<string> fullNamehSet, int expectedEntries, int setListSize = 100) { int count = 0; var fop = _adlsClient.EnumerateDirectory(path, maxEntries, "", ""); var en = fop.GetEnumerator(); ((FileStatusList<DirectoryEntry>)en).ListSize = setListSize; while (en.MoveNext()) { var dir = en.Current; if (!hSet.Contains(dir.Name)) { Assert.Fail(dir.Name + ": The file should have been in the hashset"); } if (!fullNamehSet.Contains(dir.FullName)) { Assert.Fail(dir.FullName + ": The file fullname should have been in the hashset"); } if (dir.Type != DirectoryEntryType.FILE) { Assert.Fail(dir.Name + " should be file"); } count++; } Assert.IsTrue(count == expectedEntries); } internal static void TestListStatusUsingCore(string path, int maxEntries, HashSet<string> hSet, HashSet<string> fullNamehSet, int expectedEntries) { int count = 0; var resp = new OperationResponse(); var entries = Core.ListStatusAsync(path, "", "", maxEntries, UserGroupRepresentation.ObjectID, _adlsClient, new RequestOptions(), resp).GetAwaiter().GetResult(); foreach(var dir in entries) { if (!hSet.Contains(dir.Name)) { Assert.Fail(dir.Name + ": The file should have been in the hashset"); } if (!fullNamehSet.Contains(dir.FullName)) { Assert.Fail(dir.FullName + ": The file fullname should have been in the hashset"); } if (dir.Type != DirectoryEntryType.FILE) { Assert.Fail(dir.Name + " should be file"); } count++; } Assert.IsTrue(count == expectedEntries); } internal static void TestGetFileStatusMinimal(string path, int maxEntries, HashSet<string> hSet, HashSet<string> fullNamehSet, int expectedEntries, int setListSize = 100) { int count = 0; var fop = _adlsClient.EnumerateDirectory(path, maxEntries, "", "", selection: Selection.Minimal); var en = fop.GetEnumerator(); ((FileStatusList<DirectoryEntry>)en).ListSize = setListSize; while (en.MoveNext()) { var dir = en.Current; if (!hSet.Contains(dir.Name)) { Assert.Fail(dir.Name + ": The file should have been in the hashset"); } if (!fullNamehSet.Contains(dir.FullName)) { Assert.Fail(dir.FullName + ": The file fullname should have been in the hashset"); } if (dir.Type != DirectoryEntryType.FILE) { Assert.Fail(dir.Name + " should be file"); } Assert.AreEqual(dir.ExpiryTime, null); Assert.AreEqual(dir.Group, null); Assert.AreEqual(dir.HasAcl, false); Assert.AreEqual(dir.LastAccessTime, null); Assert.AreEqual(dir.LastModifiedTime, null); Assert.AreEqual(dir.Length, 0); Assert.AreEqual(dir.Permission, null); Assert.AreEqual(dir.User, null); count++; } Assert.IsTrue(count == expectedEntries); } [ClassCleanup] public static void CleanTests() { _adlsClient.DeleteRecursive(UnitTestDir); var nonOwnerAclSpec = new List<AclEntry> { new AclEntry(AclType.user, NonOwner1ObjectId, AclScope.Access, AclAction.ExecuteOnly), new AclEntry(AclType.user, NonOwner2ObjectId, AclScope.Access, AclAction.ExecuteOnly), new AclEntry(AclType.user, NonOwner3ObjectId, AclScope.Access, AclAction.ExecuteOnly), new AclEntry(AclType.group, Group1Id, AclScope.Access, AclAction.ExecuteOnly) }; _adlsClient.RemoveAclEntries("/", nonOwnerAclSpec); } } }