static public WebHostTestSetup Setup(
            WebAppConfiguration webAppConfig,
            Func <IWebHostBuilder, IWebHostBuilder> webHostBuilderMap)
        {
            var testDirectory = Filesystem.CreateRandomDirectoryInTempDirectory();

            var setup = new WebHostTestSetup(testDirectory, webHostBuilderMap);

            var webAppConfigFilePath = setup.WebAppConfigFilePath;

            Directory.CreateDirectory(Path.GetDirectoryName(webAppConfigFilePath));

            File.WriteAllBytes(webAppConfigFilePath, ZipArchive.ZipArchiveFromEntries(webAppConfig.AsFiles()));

            return(setup);
        }
        static public WebHostAdminInterfaceTestSetup Setup(
            Func <IWebHostBuilder, IWebHostBuilder> webHostBuilderMap,
            string adminRootPassword = null,
            Composition.Component deployAppConfigAndInitElmState = null,
            string adminWebHostUrlOverride  = null,
            string publicWebHostUrlOverride = null)
        {
            var testDirectory = Filesystem.CreateRandomDirectoryInTempDirectory();

            var setup = new WebHostAdminInterfaceTestSetup(
                testDirectory,
                adminRootPassword: adminRootPassword,
                deployAppConfigAndInitElmState: deployAppConfigAndInitElmState,
                webHostBuilderMap: webHostBuilderMap,
                adminWebHostUrlOverride: adminWebHostUrlOverride,
                publicWebHostUrlOverride: publicWebHostUrlOverride);

            return(setup);
        }
Example #3
0
    static public WebHostAdminInterfaceTestSetup Setup(
        Func <IWebHostBuilder, IWebHostBuilder>?webHostBuilderMap,
        string?adminPassword = null,
        IFileStore?fileStore = null,
        Composition.Component?deployAppConfigAndInitElmState = null,
        string?adminWebHostUrlOverride  = null,
        string?publicWebHostUrlOverride = null,
        Func <DateTimeOffset>?persistentProcessHostDateTime = null)
    {
        var testDirectory = Filesystem.CreateRandomDirectoryInTempDirectory();

        var setup = new WebHostAdminInterfaceTestSetup(
            testDirectory,
            adminPassword: adminPassword,
            fileStore: fileStore,
            deployAppConfigAndInitElmState: deployAppConfigAndInitElmState,
            webHostBuilderMap: webHostBuilderMap,
            adminWebHostUrlOverride: adminWebHostUrlOverride,
            publicWebHostUrlOverride: publicWebHostUrlOverride,
            persistentProcessHostDateTime: persistentProcessHostDateTime);

        return(setup);
    }
Example #4
0
    static public (ProcessOutput processOutput, IReadOnlyCollection <(IImmutableList <string> path, IReadOnlyList <byte> content)> resultingFiles) ExecuteFileWithArguments(
        IReadOnlyDictionary <IImmutableList <string>, IReadOnlyList <byte> > environmentFilesNotExecutable,
        byte[] executableFile,
        string arguments,
        IDictionary <string, string>?environmentStrings,
        IImmutableList <string>?workingDirectory = null,
        IReadOnlyDictionary <IImmutableList <string>, IReadOnlyList <byte> >?environmentFilesExecutable = null,
        IReadOnlyDictionary <string, IReadOnlyList <byte> >?environmentPathExecutableFiles = null)
    {
        var environmentStringsDict =
            environmentStrings?.ToImmutableDictionary() ?? ImmutableDictionary <string, string> .Empty;

        var environmentPathContainerDirectoryName = "environment-path-cont";

        var containerDirectory = Filesystem.CreateRandomDirectoryInTempDirectory();

        string writeEnvironmentFile(KeyValuePair <IImmutableList <string>, IReadOnlyList <byte> > environmentFile)
        {
            var environmentFilePath      = Path.Combine(containerDirectory, Filesystem.MakePlatformSpecificPath(environmentFile.Key));
            var environmentFileDirectory = Path.GetDirectoryName(environmentFilePath) !;

            Directory.CreateDirectory(environmentFileDirectory);

            File.WriteAllBytes(environmentFilePath, (environmentFile.Value as byte[]) ?? environmentFile.Value.ToArray());

            return(environmentFilePath);
        }

        foreach (var environmentFile in environmentFilesNotExecutable)
        {
            writeEnvironmentFile(environmentFile);
        }

        var mainExecutableFileName         = "name-used-to-execute-file.exe";
        var mainExecutableFilePathRelative = ImmutableList.Create(mainExecutableFileName);

        var executableFileNameAppendix =
            RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ".exe" : "";

        var allExecutableFiles =
            (environmentFilesExecutable ?? ImmutableDictionary <IImmutableList <string>, IReadOnlyList <byte> > .Empty)
            .ToImmutableDictionary()
            .SetItems(
                (environmentPathExecutableFiles ?? ImmutableDictionary <string, IReadOnlyList <byte> > .Empty)
                .Select(execFile => new KeyValuePair <IImmutableList <string>, IReadOnlyList <byte> >(
                            ImmutableList.Create(environmentPathContainerDirectoryName, execFile.Key + executableFileNameAppendix), execFile.Value)))
            .SetItem(mainExecutableFilePathRelative, executableFile);

        foreach (var environmentFile in allExecutableFiles)
        {
            var fileAbsolutePath = writeEnvironmentFile(environmentFile);

            if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
            {
                var unixFileInfo = new UnixFileInfo(fileAbsolutePath);

                unixFileInfo.FileAccessPermissions |=
                    FileAccessPermissions.GroupExecute | FileAccessPermissions.UserExecute | FileAccessPermissions.OtherExecute |
                    FileAccessPermissions.GroupRead | FileAccessPermissions.UserRead | FileAccessPermissions.OtherRead;
            }
        }

        var workingDirectoryAbsolute =
            Path.Combine(
                containerDirectory,
                Filesystem.MakePlatformSpecificPath(workingDirectory ?? ImmutableList <string> .Empty));

        var mainExecutableFilePathAbsolute = Path.Combine(containerDirectory, mainExecutableFileName);

        var environmentPathExecutableFilesPathAbsolute = Path.Combine(containerDirectory, environmentPathContainerDirectoryName);

        var pathEnvironmentVarSeparator =
            RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ";" : ":";

        var environmentPathEntryBefore =
            environmentStringsDict.FirstOrDefault(c => c.Key.Equals("PATH", StringComparison.InvariantCultureIgnoreCase));

        var environmentPath = environmentPathExecutableFilesPathAbsolute + pathEnvironmentVarSeparator + environmentPathEntryBefore.Value;

        var environmentStringsWithExecutableFiles =
            environmentStringsDict
            .SetItem(environmentPathEntryBefore.Key ?? "PATH", environmentPath);

        var process = new Process
        {
            StartInfo = new ProcessStartInfo
            {
                WorkingDirectory       = workingDirectoryAbsolute,
                FileName               = mainExecutableFilePathAbsolute,
                Arguments              = arguments,
                UseShellExecute        = false,
                RedirectStandardOutput = true,
                RedirectStandardError  = true,
                CreateNoWindow         = true,
            },
        };

        foreach (var envString in environmentStringsWithExecutableFiles.EmptyIfNull())
        {
            process.StartInfo.Environment[envString.Key] = envString.Value;
        }

        process.Start();
        var standardOutput = process.StandardOutput.ReadToEnd();
        var standardError  = process.StandardError.ReadToEnd();

        process.WaitForExit();
        var exitCode = process.ExitCode;

        process.Close();

        var createdFiles =
            Filesystem.GetFilesFromDirectory(
                directoryPath: containerDirectory,
                filterByRelativeName: path => !path.SequenceEqual(mainExecutableFilePathRelative));

        try
        {
            Directory.Delete(path: containerDirectory, recursive: true);
        }
        // Avoid crash in scenario like https://forum.botlab.org/t/farm-manager-tribal-wars-2-farmbot/3038/170
        catch (UnauthorizedAccessException)
        {
        }

        return(new ProcessOutput
        {
            ExitCode = exitCode,
            StandardError = standardError,
            StandardOutput = standardOutput,
        }, createdFiles);
    }
    static public Result <string, LoadFromUrlSuccess> LoadFromUrl(
        string sourceUrl,
        Func <GetRepositoryFilesPartialForCommitRequest, IImmutableDictionary <IImmutableList <string>, IReadOnlyList <byte> > > getRepositoryFilesPartialForCommit)
    {
        var parsedUrl = ParseUrl(sourceUrl);

        if (parsedUrl == null)
        {
            return(Result <string, LoadFromUrlSuccess> .err(
                       "Failed to parse string '" + sourceUrl + "' as GitHub or GitLab URL."));
        }

        string?branchName         = null;
        bool   refLooksLikeCommit = false;

        if (parsedUrl.inRepository != null)
        {
            refLooksLikeCommit = Regex.IsMatch(parsedUrl.inRepository.@ref, "[A-Fa-f0-9]{40}");

            branchName = refLooksLikeCommit ? null : parsedUrl.inRepository.@ref;
        }

        var cloneUrl = parsedUrl.repository.TrimEnd('/') + ".git";

        if (getRepositoryFilesPartialForCommit == null)
        {
            getRepositoryFilesPartialForCommit =
                req => GetRepositoryFilesPartialForCommitViaLibGitSharpCheckout(
                    cloneUrl: req.cloneUrlCandidates[0],
                    commit: req.commit);
        }

        var repositoryFilesPartial =
            refLooksLikeCommit ?
            getRepositoryFilesPartialForCommit(
                new GetRepositoryFilesPartialForCommitRequest(
                    commit: parsedUrl.inRepository !.@ref,
                    cloneUrlCandidates: ImmutableList.Create(cloneUrl)))
            :
            GetRepositoryFilesPartialForBranchViaLibGitSharpCheckout(cloneUrl, branchName);

        var tempWorkingDirectory        = Filesystem.CreateRandomDirectoryInTempDirectory();
        var gitRepositoryLocalDirectory = Path.Combine(tempWorkingDirectory, "git-repository");

        try
        {
            foreach (var fileWithPath in repositoryFilesPartial)
            {
                var absoluteFilePath      = Path.Combine(new[] { gitRepositoryLocalDirectory }.Concat(fileWithPath.Key).ToArray());
                var absoluteDirectoryPath = Path.GetDirectoryName(absoluteFilePath) !;

                Directory.CreateDirectory(absoluteDirectoryPath);
                File.WriteAllBytes(absoluteFilePath, fileWithPath.Value.ToArray());
            }

            (string hash, CommitContent content)? rootCommit = null;

            using var gitRepository = new Repository(gitRepositoryLocalDirectory);

            Commit?startCommit = null;

            if (parsedUrl.inRepository == null)
            {
                startCommit = gitRepository.Head.Commits.FirstOrDefault();

                if (startCommit == null)
                {
                    return(Result <string, LoadFromUrlSuccess> .err(
                               "Failed to get the first commit from HEAD"));
                }
            }
            else
            {
                startCommit = gitRepository.Lookup(parsedUrl.inRepository.@ref) as Commit;

                if (startCommit == null)
                {
                    return(Result <string, LoadFromUrlSuccess> .err(
                               "I did not find the commit for ref '" + parsedUrl.inRepository.@ref + "'."));
                }
            }

            ParsedUrlInRepository partInRepositoryWithCommit(Commit replacementCommit) =>
            parsedUrl.inRepository == null ?
            new ParsedUrlInRepository(GitObjectType.tree, @ref: replacementCommit.Sha, path: "") :
            parsedUrl.inRepository with
            {
                @ref = replacementCommit.Sha
            };

            var urlInCommit = BackToUrl(parsedUrl with {
                inRepository = partInRepositoryWithCommit(startCommit)
            });

            rootCommit = GetCommitHashAndContent(startCommit);

            var parsedUrlPath =
                parsedUrl.inRepository == null ? "" : parsedUrl.inRepository.path;

            var pathNodesNames = parsedUrlPath.Split('/', StringSplitOptions.RemoveEmptyEntries);

            var findGitObjectResult =
                FindGitObjectAtPath(startCommit.Tree, pathNodesNames);

            var linkedObject = findGitObjectResult?.Ok;

            if (linkedObject == null)
            {
                return(Result <string, LoadFromUrlSuccess> .err(
                           "I did not find an object at path '" + parsedUrlPath + "' in " + startCommit.Sha));
            }

            IEnumerable <Commit> traceBackTreeParents()
            {
                var queue = new Queue <Commit>();

                queue.Enqueue(startCommit);

                while (queue.TryDequeue(out var currentCommit))
                {
                    yield return(currentCommit);

                    foreach (var parent in currentCommit.Parents)
                    {
                        if (FindGitObjectAtPath(parent.Tree, pathNodesNames)?.Ok?.Sha != linkedObject?.Sha)
                        {
                            continue;
                        }

                        queue.Enqueue(parent);
                    }
                }
            }

            var firstParentCommitWithSameTreeRef =
                traceBackTreeParents().OrderBy(commit => commit.Author.When).First();

            var firstParentCommitWithSameTree =
                GetCommitHashAndContent(firstParentCommitWithSameTreeRef);

            var urlInFirstParentCommitWithSameValueAtThisPath =
                BackToUrl(parsedUrl with {
                inRepository = partInRepositoryWithCommit(firstParentCommitWithSameTreeRef)
            });