0

Ultimate goal is I want to run a Function App locally for automated testing. I don't know how to do so without using func.exe. Here is my attempt:

    /// <summary>
    /// Setup environment for running integration tests on MyApp APIs
    /// </summary>
    /// <param name="testContext"></param>
    [ClassInitialize]
    public static void RunFileHubLocally(TestContext testContext)
    {
        // Do the programmatic equivalent of right-click "Debug -> Start new instance" on API.
        // This uses Azure Functions Core CLI to deploy the Function App locally.
        azureFunctionsCliShell = new Process();

        azureFunctionsCliShell.StartInfo.UseShellExecute = false;
        azureFunctionsCliShell.StartInfo.RedirectStandardOutput = true;
        azureFunctionsCliShell.StartInfo.CreateNoWindow = true;

        azureFunctionsCliShell.StartInfo.FileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"..\..\..\lib\azure-functions-core-tools\func.exe"); ;
        var fileInTargettedWorkingDirectory = new FileInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"..\..\..\..\..\..\src\MyApp.Api\bin\Debug\netcoreapp2.1\host.json"));
        azureFunctionsCliShell.StartInfo.WorkingDirectory = fileInTargettedWorkingDirectory.Directory.FullName;
        int port = FreeTcpPort();
        azureFunctionsCliShell.StartInfo.Arguments = $"host start --port {port}";
        apiUrl = $"http://localhost:{port}/api";
        azureFunctionsCliShell.Start();

        // Wait for "Application started", the line in the output that indicates the
        // application is listening to the port
        const string specialPhrase = "Application started";
        for ( ; ; )
        {
            string line = azureFunctionsCliShell.StandardOutput.ReadLine();

            Console.WriteLine(line);

            if (line.Contains(specialPhrase))
            {
                break;
            }

            if (azureFunctionsCliShell.StandardOutput.EndOfStream)
            {
                throw new Exception($"Output did not contain special phrase '{specialPhrase}'. Last line: '{line}'.");
            }
        }

        // Hold instance of HttpClient to be disposed of during cleanup
        httpClient = new HttpClient();
    }

This fails with output

your worker runtime is not set. As of 2.0.1-beta.26 a worker runtime setting is required. Please run func settings add FUNCTIONS_WORKER_RUNTIME <option> or add FUNCTIONS_WORKER_RUNTIME to your local.settings.json Available options: dotnet, node, python, powershell

              %%%%%%
             %%%%%%
        @   %%%%%%    @
      @@   %%%%%%      @@
   @@@    %%%%%%%%%%%    @@@
 @@      %%%%%%%%%%        @@
   @@         %%%%       @@
     @@      %%%       @@
       @@    %%      @@
            %%
            %

Azure Functions Core Tools (2.6.666 Commit hash: 2ea98edb55cd2fc249765fcf3f5e30829c7c9932) Function Runtime Version: 2.0.12408.0 Application is shutting down...

When I run the same command through the console it succeeds with

your worker runtime is not set. As of 2.0.1-beta.26 a worker runtime setting is required. Please run func settings add FUNCTIONS_WORKER_RUNTIME <option> or add FUNCTIONS_WORKER_RUNTIME to your local.settings.json Available options: dotnet, node, python, powershell

              %%%%%%
             %%%%%%
        @   %%%%%%    @
      @@   %%%%%%      @@
   @@@    %%%%%%%%%%%    @@@
 @@      %%%%%%%%%%        @@
   @@         %%%%       @@
     @@      %%%       @@
       @@    %%      @@
            %%
            %

Azure Functions Core Tools (2.6.666 Commit hash: 2ea98edb55cd2fc249765fcf3f5e30829c7c9932) Function Runtime Version: 2.0.12408.0 [4/26/2019 2:29:18 PM] Starting Rpc Initialization Service. [4/26/2019 2:29:18 PM] Initializing RpcServer … … Now listening on: http://0.0.0.0:63819 Application started. Press Ctrl+C to shut down.

Cœur
  • 37,241
  • 25
  • 195
  • 267
See Sharp
  • 379
  • 1
  • 4
  • 11
  • 1
    _"I want to run a Function App locally for automated testing"_ - can't you use the techniques in [Strategies for testing your code in Azure Functions](https://learn.microsoft.com/en-us/azure/azure-functions/functions-test-a-function)? – stuartd Apr 26 '19 at 15:55
  • @stuartd I know how to unit test my functions. I want proper integration tests, live HTTP endpoint. – See Sharp Apr 26 '19 at 16:32
  • 1
    Sorry, I didn't get that. I'm a bit confused though - you say you don't know how to run the script _"without using func.exe"_ but your sample code **does** use func.exe, as the `process.StartInfo.FileName`. You say _"When I run the same command through the console it succeeds"_ - do you mean that invoking func.exe with exactly the same command works in a command window, but not when calling `Process.Start`? Have you tried calling the code from a console program rather than a test? – stuartd Apr 26 '19 at 17:06

1 Answers1

0

The func CLI is itself a wrapper around the Azure Functions Runtime.

Instead of writing yet another wrapper around func CLI, you could instead go the docker route which would be as close as running it on Azure itself.

With docker, you would greatly simplify your overall CI pipelines since most CI servers natively support running workflows with containers.

Also, if you'd like, you could also deploy these containers to Azure too but note that Linux is not supported for Consumption Plan yet, so you will have to use a Linux App Service Plan instead.

PramodValavala
  • 6,026
  • 1
  • 11
  • 30