public async Task create_template_function_dotnet_space_name()
 {
     await CliTester.Run(new RunConfiguration
     {
         Commands = new[]
         {
             "init . --worker-runtime dotnet",
             "new --template \"http trigger\" --name testfunc2"
         },
         OutputContains = new[]
         {
             "The function \"testfunc2\" was created successfully from the \"http trigger\" template."
         }
     }, _output);
 }
 public async Task create_template_function_using_alias()
 {
     await CliTester.Run(new RunConfiguration
     {
         Commands = new[]
         {
             "init . --worker-runtime node",
             "new --language js --template \"http trigger\" --name testfunc"
         },
         OutputContains = new[]
         {
             "The function \"testfunc\" was created successfully from the \"http trigger\" template."
         }
     }, _output);
 }
 public async Task create_function_custom()
 {
     await CliTester.Run(new RunConfiguration
     {
         Commands = new[]
         {
             "init . --worker-runtime custom --no-bundle",
             "new --template \"Http Trigger\" --name testfunc"
         },
         OutputContains = new[]
         {
             "The function \"testfunc\" was created successfully from the \"Http Trigger\" template."
         }
     }, _output);
 }
 public Task init_docker_only_no_project()
 {
     return(CliTester.Run(new RunConfiguration
     {
         Commands = new[]
         {
             $"init . --docker-only"
         },
         HasStandardError = true,
         ErrorContains = new[]
         {
             $"Unable to find project root"
         }
     }, _output));
 }
示例#5
0
 public Task init_managed_dependencies_is_only_supported_in_powershell()
 {
     return(CliTester.Run(new RunConfiguration
     {
         Commands = new[]
         {
             $"init . --worker-runtime python --managed-dependencies "
         },
         HasStandardError = true,
         ErrorContains = new[]
         {
             $"Managed dependencies is only supported for PowerShell"
         }
     }, _output));
 }
示例#6
0
 public async Task create_httpTrigger_with_authConfigured_dotnet()
 {
     await CliTester.Run(new RunConfiguration
     {
         Commands = new[]
         {
             "init . --worker-runtime dotnet",
             "new --template HttpTrigger --name testfunc --authlevel function"
         },
         OutputContains = new[]
         {
             "The function \"testfunc\" was created successfully from the \"HttpTrigger\" template."
         }
     }, _output);
 }
示例#7
0
 public async Task create_httpTrigger_Invalid_AuthConfig_returns_error()
 {
     await CliTester.Run(new RunConfiguration
     {
         Commands = new[]
         {
             "init . --worker-runtime node",
             "new --template httpTrigger --name testfunc --authlevel invalid"
         },
         OutputContains = new[]
         {
             "Authorization level is applicable to templates that use Http trigger, Allowed values: [function, anonymous, admin]. Authorization level is not enforced when running functions from core tools"
         }
     }, _output);
 }
        public async Task ListFunctionsWorks()
        {
            TestConditions.SkipIfAzureServicePrincipalNotDefined();

            Environment.SetEnvironmentVariable("CLI_DEBUG", "0");
            try
            {
                await CliTester.Run(new[] {
                    new RunConfiguration
                    {
                        Commands = new[]
                        {
                            "azure functionapp list-functions core-tools-list-functions",
                        },
                        OutputContains = new string[]
                        {
                            "api/httpwithkey",
                            "api/httpwithoutkey"
                        },
                        OutputDoesntContain = new string[]
                        {
                            "api/httpwithkey?code=",
                            "api/httpwithoutkey?code="
                        }
                    },
                    new RunConfiguration
                    {
                        Commands = new []
                        {
                            "azure functionapp list-functions core-tools-list-functions --show-keys"
                        },
                        OutputContains = new string []
                        {
                            "api/httpwithkey?code=",
                            "api/httpwithoutkey"
                        },
                        OutputDoesntContain = new string[]
                        {
                            "api/httpwithoutkey?code="
                        }
                    }
                });
            }
            finally
            {
                Environment.SetEnvironmentVariable("CLI_DEBUG", "1");
            }
        }
 public async Task create_timerTrigger_authConfigured_returns_error()
 {
     await CliTester.Run(new RunConfiguration
     {
         Commands = new[]
         {
             "init . --worker-runtime node",
             "new --template TimerTrigger --name testfunc --authlevel function"
         },
         HasStandardError = true,
         ErrorContains    = new[]
         {
             Constants.AuthLevelErrorMessage
         }
     }, _output);
 }
示例#10
0
 public Task bundlesconfiguredbydefault_no_action()
 {
     return(CliTester.Run(new RunConfiguration
     {
         Commands = new[] {
             "init . --worker-runtime node",
             "new --template SendGrid --name testfunc",
             "extensions install"
         },
         OutputContains = new[]
         {
             "No action performed"
         },
         CommandTimeout = TimeSpan.FromMinutes(1)
     }, _output));
 }
示例#11
0
 public Task init_with_Dockerfile(string workerRuntime)
 {
     return(CliTester.Run(new RunConfiguration
     {
         Commands = new[] { $"init . --worker-runtime {workerRuntime} --docker" },
         CheckFiles = new[]
         {
             new FileResult
             {
                 Name = "Dockerfile",
                 ContentContains = new[] { $"FROM mcr.microsoft.com/azure-functions/{workerRuntime}:2.0" }
             }
         },
         OutputContains = new[] { "Dockerfile" }
     }, _output));
 }
 public Task init_with_Dockerfile_for_csx()
 {
     return(CliTester.Run(new RunConfiguration
     {
         Commands = new[] { $"init . --worker-runtime dotnet --docker --csx" },
         CheckFiles = new[]
         {
             new FileResult
             {
                 Name = "Dockerfile",
                 ContentNotContains = new[] { "dotnet publish" },
                 ContentContains = new[] { $"FROM mcr.microsoft.com/azure-functions/dotnet:2.0" }
             }
         },
         OutputContains = new[] { "Dockerfile" }
     }, _output));
 }
示例#13
0
        public async Task start_loglevel_overrriden_in_host_json_category_filter()
        {
            var functionName = "HttpTriggerCSharp";

            await CliTester.Run(new RunConfiguration[]
            {
                new RunConfiguration
                {
                    Commands = new[]
                    {
                        "init . --worker-runtime dotnet",
                        $"new --template Httptrigger --name {functionName}",
                    },
                    Test = async(workingDir, p) =>
                    {
                        var filePath           = Path.Combine(workingDir, "host.json");
                        string hostJsonContent = "{\"version\": \"2.0\",\"logging\": {\"logLevel\": {\"Default\": \"None\", \"Host.Startup\": \"Information\"}}}";
                        await File.WriteAllTextAsync(filePath, hostJsonContent);
                    },
                },
                new RunConfiguration
                {
                    Commands = new[]
                    {
                        "start"
                    },
                    ExpectExit     = false,
                    OutputContains = new []
                    {
                        "Found the following functions:"
                    },
                    OutputDoesntContain = new string[]
                    {
                        "Reading host configuration file"
                    },
                    Test = async(_, p) =>
                    {
                        // give the host time to load functions and print any errors
                        await Task.Delay(TimeSpan.FromSeconds(10));
                        p.Kill();
                    }
                },
            }, _output, startHost : true);
        }
        public async Task DurableRaiseEventTest_FileInput()
        {
            Skip.If(string.IsNullOrEmpty(StorageConnectionString),
                    reason: _storageReason);

            string taskHubName = "raiseEventFileInputTest";

            DurableHelper.SetTaskHubName(WorkingDirPath, taskHubName);
            Environment.SetEnvironmentVariable(DurableManager.DefaultConnectionStringKey, StorageConnectionString);

            string filename   = Path.Combine(WorkingDirPath, "raiseEvent.json");
            var    testObject = new
            {
                Name  = "RaiseEvent",
                Hello = "World"
            };

            File.WriteAllText(filename, JsonConvert.SerializeObject(testObject));

            string instanceId = $"{Guid.NewGuid():N}";

            await CliTester.Run(new RunConfiguration
            {
                Commands = new[]
                {
                    $"durable start-new --function-name JsonInput --id {instanceId} --task-hub-name {taskHubName}",
                    $"durable raise-event --id {instanceId} --event-name operation --event-data @raiseEvent.json --task-hub-name {taskHubName}",
                    $"durable get-runtime-status --id {instanceId}"
                },
                OutputContains = new string[]
                {
                    $"Raised event 'operation' to instance '{instanceId}'",
                    "\"OrchestrationStatus\": 0",
                }
            },
                                _output,
                                workingDir : WorkingDirPath,
                                startHost : true);

            Environment.SetEnvironmentVariable(DurableManager.DefaultConnectionStringKey, null);

            File.Delete(filename);
        }
        public async Task DurableStartNewTest_FileInput()
        {
            Skip.If(true, reason: "This test fails intermittently, needs to be fixed");
            Skip.If(string.IsNullOrEmpty(StorageConnectionString),
                    reason: _storageReason);

            string taskHubName = "startNewFileInputTest";

            DurableHelper.SetTaskHubName(WorkingDirPath, taskHubName);
            Environment.SetEnvironmentVariable(DurableManager.DefaultConnectionStringKey, StorageConnectionString);

            string filename   = Path.Combine(WorkingDirPath, "startnew.json");
            var    testObject = new
            {
                Name  = "StartNew",
                Hello = "World"
            };

            File.WriteAllText(filename, JsonConvert.SerializeObject(testObject));

            string instanceId = $"{Guid.NewGuid():N}";

            await CliTester.Run(new RunConfiguration
            {
                Commands = new[]
                {
                    $"durable start-new --function-name JsonInput --input @startnew.json --task-hub-name {taskHubName} --id {instanceId}",
                    $"durable get-runtime-status --id {instanceId}"
                },
                OutputContains = new string[]
                {
                    "Started 'JsonInput'",
                    "\"OrchestrationStatus\": 0",
                }
            },
                                _output,
                                workingDir : WorkingDirPath,
                                startHost : true);

            Environment.SetEnvironmentVariable(DurableManager.DefaultConnectionStringKey, null);

            File.Delete(filename);
        }
示例#16
0
 public async void RemoteBuildPythonFunctionApp()
 {
     TestConditions.SkipIfEnableDeploymentTestsNotDefined();
     await CliTester.Run(new[] {
         new RunConfiguration
         {
             Commands = new[]
             {
                 "init . --worker-runtime python",
                 "new -l python -t HttpTrigger -n httptrigger",
                 $"azure functionapp publish {linuxConsumptionPythonFunctionApp} --build remote"
             },
             OutputContains = new string[]
             {
                 "Remote build succeeded!"
             },
             CommandTimeout = TimeSpan.FromMinutes(5)
         },
     }, _output);
 }
        public async Task init_with_python_Dockerfile()
        {
            WorkerLanguageVersionInfo worker = await PythonHelpers.GetEnvironmentPythonVersion();

            Skip.If(worker == null);

            await CliTester.Run(new RunConfiguration
            {
                Commands   = new[] { $"init . --worker-runtime python --docker" },
                CheckFiles = new[]
                {
                    new FileResult
                    {
                        Name            = "Dockerfile",
                        ContentContains = new[] { $"FROM mcr.microsoft.com/azure-functions/python:2.0-python{worker.Major}.{worker.Minor}" }
                    }
                },
                OutputContains = new[] { "Dockerfile" }
            }, _output);
        }
        public async Task start_displays_error_on_invalid_function_json()
        {
            var functionName = "HttpTriggerJS";

            await CliTester.Run(new RunConfiguration[]
            {
                new RunConfiguration
                {
                    Commands = new[]
                    {
                        "init . --worker-runtime node",
                        $"new --template \"Http Trigger\" --name {functionName}",
                    },
                    Test = async(workingDir, _) =>
                    {
                        var filePath     = Path.Combine(workingDir, functionName, "function.json");
                        var functionJson = await File.ReadAllTextAsync(filePath);
                        functionJson     = functionJson.Replace("\"type\": \"http\"", "\"type\": \"http2\"");
                        await File.WriteAllTextAsync(filePath, functionJson);
                    }
                },
                new RunConfiguration
                {
                    Commands = new[]
                    {
                        "start"
                    },
                    ExpectExit     = false,
                    OutputContains = new []
                    {
                        "The binding type(s) 'http2' are not registered. Please ensure the type is correct and the binding extension is installed."
                    },
                    Test = async(_, p) =>
                    {
                        // give the host time to load functions and print any errors
                        await Task.Delay(TimeSpan.FromSeconds(10));
                        p.Kill();
                    }
                }
            }, _output);
        }
 public async Task start_nodejs_with_inspect()
 {
     await CliTester.Run(new RunConfiguration
     {
         Commands = new[]
         {
             "init . --worker-runtime node",
             "new --template \"Http trigger\" --name HttpTrigger",
             "start --language-worker -- \"--inspect=5050\""
         },
         ExpectExit     = false,
         OutputContains = new[]
         {
             "Debugger listening on ws://127.0.0.1:5050"
         },
         Test = async(_, p) =>
         {
             await Task.Delay(TimeSpan.FromSeconds(15));
             p.Kill();
         },
     }, _output);
 }
示例#20
0
        public Task init_with_worker_runtime(string workerRuntime)
        {
            var files = new List <FileResult>
            {
                new FileResult
                {
                    Name            = "local.settings.json",
                    ContentContains = new []
                    {
                        "FUNCTIONS_WORKER_RUNTIME",
                        workerRuntime
                    }
                },
            };

            if (workerRuntime == "powershell")
            {
                files.Add(new FileResult
                {
                    Name            = "profile.ps1",
                    ContentContains = new[] { "# Azure Functions profile.ps1" }
                });
            }

            return(CliTester.Run(new RunConfiguration
            {
                Commands = new[] { $"init . --worker-runtime {workerRuntime}" },
                CheckFiles = files.ToArray(),
                OutputContains = new[]
                {
                    "Writing .gitignore",
                    "Writing host.json",
                    "Writing local.settings.json",
                    $".vscode{Path.DirectorySeparatorChar}extensions.json",
                },
                OutputDoesntContain = new[] { "Initialized empty Git repository" }
            }, _output));
        }
示例#21
0
 public Task init_python_app_twice()
 {
     return(CliTester.Run(new RunConfiguration
     {
         Commands = new[]
         {
             "init \"anapp\" --worker-runtime python",
             "init \"anapp\" --worker-runtime python"
         },
         OutputContains = new[]
         {
             "Writing .gitignore",
             "Writing host.json",
             "Writing local.settings.json",
             $".vscode{Path.DirectorySeparatorChar}extensions.json",
             "requirements.txt already exists. Skipped!",
             ".gitignore already exists. Skipped!",
             "host.json already exists. Skipped!",
             "local.settings.json already exists. Skipped!",
             $".vscode{Path.DirectorySeparatorChar}extensions.json already exists. Skipped!"
         }
     }, _output));
 }
示例#22
0
 public async Task start_nodejs_loglevel_overrriden_in_settings()
 {
     await CliTester.Run(new RunConfiguration
     {
         Commands = new[]
         {
             "init . --worker-runtime node",
             "settings add AzureFunctionsJobHost__logging__logLevel__Default Debug",
             "new --template \"Http trigger\" --name HttpTrigger",
             "start"
         },
         ExpectExit     = false,
         OutputContains = new[]
         {
             "Worker path for language worker node"
         },
         Test = async(_, p) =>
         {
             await Task.Delay(TimeSpan.FromSeconds(15));
             p.Kill();
         },
     }, _output);
 }
 public async Task create_template_function_sanitization_dotnet()
 {
     await CliTester.Run(new RunConfiguration
     {
         Commands = new[]
         {
             "init 12n.ew-file$ --worker-runtime dotnet",
             "new --prefix 12n.ew-file$ --template HttpTrigger --name [email protected]$"
         },
         CheckFiles = new[]
         {
             new FileResult
             {
                 Name            = "12n.ew-file$/_12_n_other_file_.cs",
                 ContentContains = new[]
                 {
                     "namespace _12n.ew_file_",
                     "public static class _12_n_other_file_"
                 }
             }
         }
     }, _output);
 }
示例#24
0
 public async Task add_setting_plain_text()
 {
     await CliTester.Run(new RunConfiguration
     {
         Commands = new[]
         {
             "init . --worker-runtime node",
             "settings add testKey valueValue"
         },
         CheckFiles = new[]
         {
             new FileResult
             {
                 Name            = "local.settings.json",
                 ContentContains = new[]
                 {
                     "\"IsEncrypted\": false",
                     "\"testKey\": \"valueValue\""
                 }
             }
         }
     }, _output);
 }
示例#25
0
 public Task init_function_app_powershell_supports_managed_dependencies()
 {
     return(CliTester.Run(new RunConfiguration
     {
         Commands = new[] { "init . --worker-runtime powershell --managed-dependencies" },
         CheckFiles = new FileResult[]
         {
             new FileResult
             {
                 Name = "host.json",
                 ContentContains = new []
                 {
                     "managedDependency",
                     "enabled",
                     "true"
                 }
             },
             new FileResult
             {
                 Name = "requirements.psd1",
                 ContentContains = new []
                 {
                     "Az",
                 }
             }
         },
         OutputContains = new[]
         {
             "Writing profile.ps1",
             "Writing requirements.psd1",
             "Writing .gitignore",
             "Writing host.json",
             "Writing local.settings.json",
             $".vscode{Path.DirectorySeparatorChar}extensions.json",
         }
     }, _output));
 }
示例#26
0
 public async Task start_nodejs()
 {
     await CliTester.Run(new RunConfiguration
     {
         Commands = new[]
         {
             "init . --worker-runtime node",
             "new --template \"Http trigger\" --name HttpTrigger",
             "start"
         },
         ExpectExit     = false,
         OutputContains = new[]
         {
             "Functions:",
             "HttpTrigger: [GET,POST] http://localhost:7071/api/HttpTrigger"
         },
         OutputDoesntContain = new string[]
         {
             "Initializing function HTTP routes",
             "Content root path:"     // ASPNETCORE_SUPPRESSSTATUSMESSAGES is set to true by default
         },
         Test = async(workingDir, p) =>
         {
             using (var client = new HttpClient()
             {
                 BaseAddress = new Uri("http://localhost:7071/")
             })
             {
                 (await WaitUntilReady(client)).Should().BeTrue(because: _serverNotReady);
                 var response = await client.GetAsync("/api/HttpTrigger?name=Test");
                 var result   = await response.Content.ReadAsStringAsync();
                 p.Kill();
                 result.Should().Be("Hello, Test. This HTTP triggered function executed successfully.", because: "response from default function should be 'Hello, {name}. This HTTP triggered function executed successfully.'");
             }
         },
     }, _output);
 }
示例#27
0
    public async Task Create_TOTP_Record_and_Generate_Code()
    {
        using var cli = new CliTester();
        await cli.InitAsync();

        await cli.InvokeSuccessfullyAsync("reg", "--email", "*****@*****.**", "--password", "foobar", "--raw-session");

        var sessionKey = cli.ReadOut();

        cli.SetEnv("KYPR_SESSION", sessionKey);

        await cli.InvokeSuccessfullyAsync("new", "vault", "--label", "v1");

        _ = cli.ReadOut();

        await cli.InvokeSuccessfullyAsync("new", "rec", "--vault", "v1", "--file", "samples/record-totp1.json");

        var recId = cli.ReadOut().Trim();

        await cli.InvokeSuccessfullyAsync("get", "otp", "--record", recId);

        var otpCode = cli.ReadOut().Trim();

        Assert.NotEmpty(otpCode);
        Assert.Equal(6, otpCode.Length);

        var otpSecret  = "I65VU7K5ZQL7WB4E";
        var otpCodeUrl = $"https://authenticationtest.com/totp/?secret={otpSecret}";

        using var http = new HttpClient();
        var otpJson = await http.GetStringAsync(otpCodeUrl);

        var otpResp = JsonSerializer.Deserialize <AuthTestOtpResponse>(otpJson);

        Assert.Equal(otpResp !.code, otpCode);
    }
 public Task try_install_with_a_version()
 {
     return(CliTester.Run(new RunConfiguration
     {
         Commands = new[] {
             "init . --worker-runtime node --no-bundle",
             "new --template SendGrid --name testfunc",
             "extensions install",
             "extensions install -p Microsoft.Azure.WebJobs.Extensions.Storage -v 3.0.8"
         },
         OutputContains = new[]
         {
             "Restoring packages for",
             "Restore completed"
         },
         OutputDoesntContain = new[]
         {
             "No action performed because no functions in your app require extensions"
         },
         CheckFiles = new[]
         {
             new FileResult
             {
                 Name = "extensions.csproj",
                 Exists = true,
                 ContentContains = new[]
                 {
                     "Microsoft.Azure.WebJobs.Script.ExtensionsMetadataGenerator",
                     "Microsoft.Azure.WebJobs.Extensions.SendGrid",
                     "Include=\"Microsoft.Azure.WebJobs.Extensions.Storage\" Version=\"3.0.8\""
                 }
             }
         },
         CommandTimeout = TimeSpan.FromMinutes(1)
     }, _output));
 }
        public Task pack_python_from_cache()
        {
            var syncDirMessage = "Directory .python_packages already in sync with requirements.txt. Skipping restoring dependencies...";

            return(CliTester.Run(new[] {
                // Create a Python function
                new RunConfiguration
                {
                    Commands = new[]
                    {
                        "init . --worker-runtime python",
                        "new --template \"Httptrigger\" --name httptrigger",
                    },
                    CheckFiles = new FileResult[]
                    {
                        new FileResult
                        {
                            Name = "local.settings.json",
                            ContentContains = new []
                            {
                                "FUNCTIONS_WORKER_RUNTIME",
                                "python"
                            }
                        }
                    },
                    OutputContains = new[]
                    {
                        "Writing .gitignore",
                        "Writing host.json",
                        "Writing local.settings.json"
                    }
                },
                // Make sure pack works
                new RunConfiguration
                {
                    Commands = new[]
                    {
                        "pack",
                    },
                    OutputContains = new[]
                    {
                        "Creating a new package"
                    },
                    CheckFiles = new FileResult[]
                    {
                        new FileResult
                        {
                            Name = Path.Combine(".python_packages", "requirements.txt.md5")
                        }
                    },
                    OutputDoesntContain = new[]
                    {
                        syncDirMessage
                    },
                    CommandTimeout = TimeSpan.FromMinutes(2)
                },
                // Without changing requirements.txt, make sure pack does not restore again
                new RunConfiguration
                {
                    Commands = new[]
                    {
                        "pack",
                    },
                    OutputContains = new[]
                    {
                        "Creating a new package",
                        syncDirMessage
                    },
                    CheckFiles = new FileResult[]
                    {
                        new FileResult
                        {
                            Name = Path.Combine(".python_packages", "requirements.txt.md5")
                        }
                    },
                    CommandTimeout = TimeSpan.FromMinutes(2)
                },
                // Update requirements.txt and make sure pack restores the dependencies
                new RunConfiguration
                {
                    PreTest = (workingDir) =>
                    {
                        var reqTxt = Path.Combine(workingDir, "requirements.txt");
                        _output.WriteLine($"Writing to file {reqTxt}");
                        FileSystemHelpers.WriteAllTextToFile(reqTxt, "requests");
                    },
                    Commands = new[]
                    {
                        "pack",
                    },
                    OutputContains = new[]
                    {
                        "Creating a new package"
                    },
                    CheckFiles = new FileResult[]
                    {
                        new FileResult
                        {
                            Name = Path.Combine(".python_packages", "requirements.txt.md5")
                        }
                    },
                    OutputDoesntContain = new[]
                    {
                        syncDirMessage
                    },
                    CommandTimeout = TimeSpan.FromMinutes(2)
                }
            }, _output));
        }
 public Task init_function_app_powershell_enable_managed_dependencies_and_set_default_version()
 {
     return(CliTester.Run(new RunConfiguration
     {
         Commands = new[] { "init . --worker-runtime powershell --managed-dependencies" },
         CheckFiles = new FileResult[]
         {
             new FileResult
             {
                 Name = "host.json",
                 ContentContains = new []
                 {
                     "logging",
                     "applicationInsights",
                     "extensionBundle",
                     "managedDependency",
                     "enabled",
                     "true"
                 }
             },
             new FileResult
             {
                 Name = "requirements.psd1",
                 ContentContains = new []
                 {
                     "Az",
                 }
             },
             new FileResult
             {
                 Name = "profile.ps1",
                 ContentContains = new []
                 {
                     "env:MSI_SECRET",
                     "Disable-AzContextAutosave",
                     "Connect-AzAccount -Identity"
                 }
             },
             new FileResult
             {
                 Name = "local.settings.json",
                 ContentContains = new []
                 {
                     "FUNCTIONS_WORKER_RUNTIME",
                     "powershell",
                     "FUNCTIONS_WORKER_RUNTIME_VERSION",
                     "~6"
                 }
             }
         },
         OutputContains = new[]
         {
             "Writing profile.ps1",
             "Writing requirements.psd1",
             "Writing .gitignore",
             "Writing host.json",
             "Writing local.settings.json",
             $".vscode{Path.DirectorySeparatorChar}extensions.json",
         }
     }, _output));
 }