示例#1
0
        /// <summary>
        /// The main method of this MSBuild task which calls the asynchronous execution method and
        /// collates logged errors in order to determine the success of HelixWorkItems
        /// </summary>
        /// <returns>A boolean value indicating the success of HelixWorkItem creation</returns>
        public bool ExecuteTask(
            IProvisioningProfileProvider provisioningProfileProvider,
            IZipArchiveManager zipArchiveManager,
            IFileSystem fileSystem)
        {
            var tasks = AppBundles.Select(bundle => PrepareWorkItem(zipArchiveManager, fileSystem, provisioningProfileProvider, bundle));

            WorkItems = Task.WhenAll(tasks).GetAwaiter().GetResult().Where(wi => wi != null).ToArray();

            return(!Log.HasLoggedErrors);
        }
示例#2
0
        /// <summary>
        /// Prepares HelixWorkItem that can run on an iOS device using XHarness
        /// </summary>
        /// <param name="appFolderPath">Path to application package</param>
        /// <returns>An ITaskItem instance representing the prepared HelixWorkItem.</returns>
        private async Task <ITaskItem> PrepareWorkItem(
            IZipArchiveManager zipArchiveManager,
            IFileSystem fileSystem,
            IProvisioningProfileProvider provisioningProfileProvider,
            ITaskItem appBundleItem)
        {
            var(workItemName, appFolderPath) = GetNameAndPath(appBundleItem, MetadataNames.AppBundlePath, fileSystem);

            appFolderPath = appFolderPath.TrimEnd(Path.DirectorySeparatorChar);

            bool isAlreadyArchived = appFolderPath.EndsWith(".zip");

            if (isAlreadyArchived && workItemName.EndsWith(".app"))
            {
                // If someone named the zip something.app.zip, we want both gone
                workItemName = workItemName.Substring(0, workItemName.Length - 4);
            }

            if (!ValidateAppBundlePath(fileSystem, appFolderPath, isAlreadyArchived))
            {
                Log.LogError($"App bundle not found in {appFolderPath}");
                return(null);
            }

            // If we are re-using one .zip for multiple work items, we need to copy it to a new location
            // because we will be changing the contents (we assume we don't mind otherwise)
            if (isAlreadyArchived && appBundleItem.TryGetMetadata(MetadataNames.AppBundlePath, out string metadata) && !string.IsNullOrEmpty(metadata))
            {
                string appFolderDirectory = fileSystem.GetDirectoryName(appFolderPath);
                string fileName           = $"xharness-payload-{workItemName.ToLowerInvariant()}.zip";
                string archiveCopyPath    = fileSystem.PathCombine(appFolderDirectory, fileName);
                fileSystem.CopyFile(appFolderPath, archiveCopyPath, overwrite: true);
                appFolderPath = archiveCopyPath;
            }

            var(testTimeout, workItemTimeout, expectedExitCode, customCommands) = ParseMetadata(appBundleItem);

            // Validation of any metadata specific to iOS stuff goes here
            if (!appBundleItem.TryGetMetadata(MetadataNames.Target, out string target))
            {
                Log.LogError($"'{MetadataNames.Target}' metadata must be specified - " +
                             "expecting list of target device/simulator platforms to execute tests on (e.g. ios-simulator-64)");
                return(null);
            }

            target = target.ToLowerInvariant();

            // Optional timeout for the how long it takes for the app to be installed, booted and tests start executing
            TimeSpan launchTimeout = target.Contains("device") ? s_defaultDeviceLaunchTimeout : s_defaultSimulatorLaunchTimeout;

            if (appBundleItem.TryGetMetadata(MetadataNames.LaunchTimeout, out string launchTimeoutProp))
            {
                if (!TimeSpan.TryParse(launchTimeoutProp, out launchTimeout) || launchTimeout.Ticks < 0)
                {
                    Log.LogError($"Invalid value \"{launchTimeoutProp}\" provided in <{MetadataNames.LaunchTimeout}>");
                    return(null);
                }
            }

            bool includesTestRunner = true;

            if (appBundleItem.TryGetMetadata(MetadataNames.IncludesTestRunner, out string includesTestRunnerProp))
            {
                if (includesTestRunnerProp.ToLowerInvariant() == "false")
                {
                    includesTestRunner = false;
                }
            }

            if (includesTestRunner && expectedExitCode != 0 && customCommands != null)
            {
                Log.LogWarning($"The {MetadataName.ExpectedExitCode} property is ignored in the `apple test` scenario");
            }

            bool resetSimulator = false;

            if (appBundleItem.TryGetMetadata(MetadataNames.ResetSimulator, out string resetSimulatorRunnerProp))
            {
                if (resetSimulatorRunnerProp.ToLowerInvariant() == "true")
                {
                    resetSimulator = true;
                }
            }

            if (customCommands == null)
            {
                // When no user commands are specified, we add the default `apple test ...` command
                customCommands = GetDefaultCommand(includesTestRunner, resetSimulator);
            }

            string appName            = isAlreadyArchived ? $"{fileSystem.GetFileNameWithoutExtension(appFolderPath)}.app" : fileSystem.GetFileName(appFolderPath);
            string helixCommand       = GetHelixCommand(appName, target, workItemTimeout, testTimeout, launchTimeout, includesTestRunner, expectedExitCode, resetSimulator);
            string payloadArchivePath = await CreatePayloadArchive(
                zipArchiveManager,
                fileSystem,
                workItemName,
                isAlreadyArchived,
                isPosix : true,
                appFolderPath,
                customCommands,
                new[] { EntryPointScript, RunnerScript });

            provisioningProfileProvider.AddProfileToPayload(payloadArchivePath, target);

            return(CreateTaskItem(workItemName, payloadArchivePath, helixCommand, workItemTimeout));
        }