Commit c4c9a16d authored by David Kline's avatar David Kline
Browse files

Merge remote-tracking branch 'upstream/master'

parents b9399058 3e783f6a
Loading
Loading
Loading
Loading
+184 −0
Original line number Diff line number Diff line
//----------------------------------------------------------------------------------------------
// <copyright file="FileOperation.cs" company="Microsoft Corporation">
//     Licensed under the MIT License. See LICENSE.TXT in the project root license information.
// </copyright>
//----------------------------------------------------------------------------------------------

using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.Tools.WindowsDevicePortal;
using static Microsoft.Tools.WindowsDevicePortal.DevicePortal;

namespace TestApp
{
    /// <summary>
    /// Helper for file related operations
    /// </summary>
    internal class FileOperation
    {
        /// <summary>
        /// Usage message for this operation
        /// </summary>
        private const string XblFileUsageMessage = "Usage:\n" +
            "  /subop:knownfolders\n" +
            "        Lists all available known folder ids on the console\n" +
            "  /subop:dir /knownfolderid:<knownfolderid> [/subpath:<subpath>] [/packagefullname:<packageFullName>]\n" +
            "        Lists the directory contents at the given knownfoldid and optionally subpath.\n" +
            "  /subop:download /knownfolderid:<knownfolderid> /filename:<name of the file to download> /destination:<filepath for storing the file> [/subpath:<subpath>] [/packagefullname:<packageFullName>]\n" +
            "        Downloads the requested file to the desired destination.\n" +
            "  /subop:upload /knownfolderid:<knownfolderid> /filepath:<filepath of the file to upload> [/subpath:<subpath>] [/packagefullname:<packageFullName>]\n" +
            "        Uploads a file to the requested folder.\n" +
            "  /subop:rename /knownfolderid:<knownfolderid> /filename:<name of the file to rename> /newfilename:<new filename> [/subpath:<subpath>] [/packagefullname:<packageFullName>]\n" +
            "        Renames a given file.\n" +
            "  /subop:delete /knownfolderid:<knownfolderid> /filename:<name of the file to delete> [/subpath:<subpath>] [/packagefullname:<packageFullName>]\n" +
            "        Deletes the given file.\n";

        /// <summary>
        /// Main entry point for handling a Setting operation
        /// </summary>
        /// <param name="portal">DevicePortal reference for communicating with the device.</param>
        /// <param name="parameters">Parsed command line parameters.</param>
        public static void HandleOperation(DevicePortal portal, ParameterHelper parameters)
        {
            if (parameters.HasFlag(ParameterHelper.HelpFlag))
            {
                Console.WriteLine(XblFileUsageMessage);
                return;
            }

            string operationType = parameters.GetParameterValue("subop");

            if (string.IsNullOrWhiteSpace(operationType))
            {
                Console.WriteLine("Missing subop parameter");
                Console.WriteLine();
                Console.WriteLine(XblFileUsageMessage);
                return;
            }

            operationType = operationType.ToLowerInvariant();

            string knownFolderId = parameters.GetParameterValue("knownfolderid");
            string subPath = parameters.GetParameterValue("subpath");
            string packageFullName = parameters.GetParameterValue("packagefullname");

            try
            {
                if (operationType.Equals("knownfolders"))
                {
                    Task<KnownFolders> getKnownFoldersTask = portal.GetKnownFolders();

                    getKnownFoldersTask.Wait();
                    Console.WriteLine(getKnownFoldersTask.Result);
                }
                else
                {
                    if (string.IsNullOrWhiteSpace(knownFolderId))
                    {
                        Console.WriteLine("Missing knownfolderid parameter");
                        Console.WriteLine();
                        Console.WriteLine(XblFileUsageMessage);
                        return;
                    }

                    if (operationType.Equals("dir"))
                    {
                        Task<FolderContents> getDirectoryContents = portal.GetFolderContents(knownFolderId, subPath, packageFullName);

                        getDirectoryContents.Wait();
                        Console.WriteLine(getDirectoryContents.Result);
                    }
                    else if (operationType.Equals("upload"))
                    {
                        string filepath = parameters.GetParameterValue("filepath");

                        if (string.IsNullOrWhiteSpace(filepath))
                        {
                            Console.WriteLine("Missing filepath parameter");
                            Console.WriteLine();
                            Console.WriteLine(XblFileUsageMessage);
                            return;
                        }

                        Task uploadFileTask = portal.UploadFile(knownFolderId, filepath, subPath, packageFullName);

                        uploadFileTask.Wait();
                        Console.WriteLine(string.Format("{0} uploaded.", filepath));
                    }
                    else
                    {
                        string filename = parameters.GetParameterValue("filename");

                        if (string.IsNullOrWhiteSpace(filename))
                        {
                            Console.WriteLine("Missing filename parameter");
                            Console.WriteLine();
                            Console.WriteLine(XblFileUsageMessage);
                            return;
                        }

                        if (operationType.Equals("download"))
                        {
                            string destination = parameters.GetParameterValue("destination");

                            if (string.IsNullOrWhiteSpace(destination))
                            {
                                Console.WriteLine("Missing destination parameter");
                                Console.WriteLine();
                                Console.WriteLine(XblFileUsageMessage);
                                return;
                            }

                            destination += "/" + filename;

                            Task<Stream> getFile = portal.GetFile(knownFolderId, filename, subPath, packageFullName);

                            getFile.Wait();

                            using (FileStream filestream = new FileStream(destination, FileMode.OpenOrCreate, FileAccess.Write))
                            {
                                getFile.Result.CopyTo(filestream);
                            }

                            Console.WriteLine(string.Format("Downloaded {0}.", destination));
                        }
                        else if (operationType.Equals("rename"))
                        {
                            string newfilename = parameters.GetParameterValue("newfilename");

                            if (string.IsNullOrWhiteSpace(newfilename))
                            {
                                Console.WriteLine("Missing newfilename parameter");
                                Console.WriteLine();
                                Console.WriteLine(XblFileUsageMessage);
                                return;
                            }

                            Task renameFileTask = portal.RenameFile(knownFolderId, filename, newfilename, subPath, packageFullName);

                            renameFileTask.Wait();
                            Console.WriteLine(string.Format("Renamed {0} to {1}.", filename, newfilename));
                        }
                        else if (operationType.Equals("delete"))
                        {
                            Task deleteFileTask = portal.DeleteFile(knownFolderId, filename, subPath, packageFullName);

                            deleteFileTask.Wait();
                            Console.WriteLine(string.Format("Deleted {0}.", filename));
                        }
                    }
                }
            }
            catch (AggregateException e)
            {
                if (e.InnerException != null && e.InnerException is DevicePortalException)
                {
                    DevicePortalException exception = e.InnerException as DevicePortalException;

                    Console.WriteLine(string.Format("HTTP Status: {0}, Hresult: 0x{1:X8}. {2}", exception.StatusCode, exception.HResult, exception.Message));
                }
            }
        }
    }
}
 No newline at end of file
+15 −1
Original line number Diff line number Diff line
@@ -81,6 +81,11 @@ namespace TestApp
            /// Get or set Xbox Settings
            /// </summary>
            XboxSettings,

            /// <summary>
            /// Does remote file operations.
            /// </summary>
            FileOperation,
        }

        /// <summary>
@@ -249,6 +254,10 @@ namespace TestApp
            {
                SettingOperation.HandleOperation(portal, parameters);
            }
            else if (operation == OperationType.FileOperation)
            {
                FileOperation.HandleOperation(portal, parameters);
            }
        }

        /// <summary>
@@ -286,6 +295,10 @@ namespace TestApp
            {
                return OperationType.XboxSettings;
            }
            else if (operation.Equals("file", StringComparison.OrdinalIgnoreCase))
            {
                return OperationType.FileOperation;
            }

            throw new Exception("Unknown Operation Type. Supported operations are the following:\n" +
                "info\n" +
@@ -294,7 +307,8 @@ namespace TestApp
                "reboot\n" +
                "processes\n" +
                "systemPerf\n" +
                "config\n");
                "config\n" +
                "file\n");
        }

        /// <summary>
+1 −0
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@
  <ItemGroup>
    <Compile Include="DevicePortalConnection.cs" />
    <Compile Include="NetworkShare.cs" />
    <Compile Include="Operations\FileOperation.cs" />
    <Compile Include="Operations\SettingOperation.cs" />
    <Compile Include="Operations\InstallOperation.cs" />
    <Compile Include="ParameterHelper.cs" />
+202 −0
Original line number Diff line number Diff line
//----------------------------------------------------------------------------------------------
// <copyright file="AppFileExplorerTests.cs" company="Microsoft Corporation">
//     Licensed under the MIT License. See LICENSE.TXT in the project root license information.
// </copyright>
//----------------------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using static Microsoft.Tools.WindowsDevicePortal.DevicePortal;

namespace Microsoft.Tools.WindowsDevicePortal.Tests
{
    /// <summary>
    /// Test class for AppFileExplorer APIs
    /// </summary>
    [TestClass]
    public class AppFileExplorerTests : BaseTests
    {
        /// <summary>
        /// Simple test which gets a response with a couple of known folders
        /// and verifies they are returned correctly.
        /// </summary>
        [TestMethod]
        public void AppFileExplorerGetKnownFolderTest()
        {
            HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
            HttpContent content = new StringContent(
                "{\"KnownFolders\" : [\"KnownFolderOne\",\"KnownFolderTwo\",\"KnownFolderThree\"]}",
                System.Text.Encoding.UTF8,
                "application/json");

            response.Content = content;

            TestHelpers.MockHttpResponder.AddMockResponse(DevicePortal.KnownFoldersApi, response);

            Task<KnownFolders> getKnownFoldersTask = TestHelpers.Portal.GetKnownFolders();
            getKnownFoldersTask.Wait();

            Assert.AreEqual(TaskStatus.RanToCompletion, getKnownFoldersTask.Status);

            List<string> knownFolders = getKnownFoldersTask.Result.Folders;

            // Check some known things about this response.
            Assert.AreEqual(3, knownFolders.Count);
            Assert.AreEqual("KnownFolderOne", knownFolders[0]);
            Assert.AreEqual("KnownFolderTwo", knownFolders[1]);
            Assert.AreEqual("KnownFolderThree", knownFolders[2]);
        }

        /// <summary>
        /// Tests getting the contents of a folder that is not for
        /// an application (eg developer folder, documents folder).
        /// </summary>
        [TestMethod]
        public void AppFileExplorerGetFolderContentsTest()
        {
            HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
            HttpContent content = new StringContent(
                "{ \"Items\" : [{\"CurrentDir\" : \"\", \"DateCreated\" : 131117780894053204, \"Id\" : \"FolderOne\", \"Name\" : \"FolderOne\", \"SubPath\" : \"\\\\FolderOne\", \"Type\" : 16}," +
                "{\"CurrentDir\" : \"\", \"DateCreated\" : 131098833024438070, \"Id\" : \"FolderTwo\", \"Name\" : \"FolderTwo\", \"SubPath\" : \"\\\\FolderTwo\", \"Type\" : 16}," +
                "{\"CurrentDir\" : \"\", \"DateCreated\" : 131117780895076062, \"FileSize\" : 2985, \"Id\" : \"fakefile.xml\", \"Name\" : \"fakefile.xml\", \"SubPath\" : \"\", \"Type\" : 32}]}",
                System.Text.Encoding.UTF8,
                "application/json");

            response.Content = content;

            TestHelpers.MockHttpResponder.AddMockResponse(DevicePortal.GetFilesApi, response);

            Task<FolderContents> getFolderContentsTask = TestHelpers.Portal.GetFolderContents("KnownFolderOne");
            getFolderContentsTask.Wait();

            Assert.AreEqual(TaskStatus.RanToCompletion, getFolderContentsTask.Status);

            List<FileOrFolderInformation> directoryContents = getFolderContentsTask.Result.Contents;

            // Check some known things about this response.
            Assert.AreEqual(3, directoryContents.Count);

            Assert.AreEqual(string.Empty, directoryContents[0].CurrentDir);
            Assert.AreEqual(131117780894053204, directoryContents[0].DateCreated);
            Assert.AreEqual("FolderOne", directoryContents[0].Id);
            Assert.AreEqual("FolderOne", directoryContents[0].Name);
            Assert.AreEqual("\\FolderOne", directoryContents[0].SubPath);
            Assert.AreEqual(16, directoryContents[0].Type);

            Assert.AreEqual(string.Empty, directoryContents[1].CurrentDir);
            Assert.AreEqual(131098833024438070, directoryContents[1].DateCreated);
            Assert.AreEqual("FolderTwo", directoryContents[1].Id);
            Assert.AreEqual("FolderTwo", directoryContents[1].Name);
            Assert.AreEqual("\\FolderTwo", directoryContents[1].SubPath);
            Assert.AreEqual(16, directoryContents[1].Type);

            Assert.AreEqual(string.Empty, directoryContents[2].CurrentDir);
            Assert.AreEqual(131117780895076062, directoryContents[2].DateCreated);
            Assert.AreEqual("fakefile.xml", directoryContents[2].Id);
            Assert.AreEqual("fakefile.xml", directoryContents[2].Name);
            Assert.AreEqual(string.Empty, directoryContents[2].SubPath);
            Assert.AreEqual(32, directoryContents[2].Type);
            Assert.AreEqual(2985, directoryContents[2].SizeInBytes);
        }

        /// <summary>
        /// Tests download method for downloading a file.
        /// </summary>
        [TestMethod]
        public void AppFileExplorerDownloadFileTest()
        {
            Stream stream = new FileStream("MockData\\Defaults\\api_os_devicefamily_Default.dat", FileMode.Open, FileAccess.Read);
            long fileLength = stream.Length;

            HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
            HttpContent content = new StreamContent(stream);
            response.Content = content;

            TestHelpers.MockHttpResponder.AddMockResponse(DevicePortal.GetFileApi, response);

            Task<Stream> getFileTask = TestHelpers.Portal.GetFile("knownfolder", "FileToDownload.txt", "SubFolder\\SubFolder2");
            getFileTask.Wait();

            Assert.AreEqual(TaskStatus.RanToCompletion, getFileTask.Status);

            Assert.AreEqual(fileLength, getFileTask.Result.Length);
        }

        /// <summary>
        /// Tests upload method for uploading a file.
        /// </summary>
        [TestMethod]
        public void AppFileExplorerUploadFileTest()
        {
            HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);

            TestHelpers.MockHttpResponder.AddMockResponse(DevicePortal.GetFileApi, response);

            Task uploadFileTask = TestHelpers.Portal.UploadFile("knownfolder", "MockData\\Defaults\\api_os_devicefamily_Default.dat", "SubFolder\\SubFolder2");
            uploadFileTask.Wait();

            Assert.AreEqual(TaskStatus.RanToCompletion, uploadFileTask.Status);
        }

        /// <summary>
        /// Tests failure of method for uploading a file when the file
        /// doesn't exist.
        /// </summary>
        [TestMethod]
        public void AppFileExplorerUploadFileTest_Failure()
        {
            HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);

            TestHelpers.MockHttpResponder.AddMockResponse(DevicePortal.GetFileApi, response);

            try
            {
                Task uploadFileTask = TestHelpers.Portal.UploadFile("knownfolder", "NonExistentFilePath\\NonExistentFile.txt", "SubFolder\\SubFolder2");
                uploadFileTask.Wait();

                Assert.Fail("Should not have succeeded if uploading a file which doesn't exist.");
            }
            catch (AggregateException e)
            {
                Assert.IsInstanceOfType(e.InnerException, typeof(IOException));
            }
        }

        /// <summary>
        /// Tests delete method for deleting a file.
        /// </summary>
        [TestMethod]
        public void AppFileExplorerDeleteFileTest()
        {
            HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);

            TestHelpers.MockHttpResponder.AddMockResponse(DevicePortal.GetFileApi, response);

            Task deleteFileTask = TestHelpers.Portal.DeleteFile("knownfolder", "FileToDelete.txt", "SubFolder\\SubFolder2");
            deleteFileTask.Wait();

            Assert.AreEqual(TaskStatus.RanToCompletion, deleteFileTask.Status);
        }

        /// <summary>
        /// Tests rename method for renaming a file
        /// </summary>
        [TestMethod]
        public void AppFileExplorerRenameFileTest()
        {
            HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);

            TestHelpers.MockHttpResponder.AddMockResponse(DevicePortal.RenameFileApi, response);

            Task renameFileTask = TestHelpers.Portal.RenameFile("knownfolder", "FileToRename.txt", "NewFileName.txt", "SubFolder\\SubFolder2");
            renameFileTask.Wait();

            Assert.AreEqual(TaskStatus.RanToCompletion, renameFileTask.Status);
        }
    }
}
+125 −0

File changed.

Preview size limit exceeded, changes collapsed.

Loading