LogicAppUnit / TestingFramework

Unit testing framework for Azure Logic Apps (Standard)
MIT License
23 stars 11 forks source link

Add support for query parameters, asynchronous response and non-Windows machines #15

Closed atthevergeof closed 1 year ago

atthevergeof commented 1 year ago

This pull request tackles some of the issues we were facing in our team.

There is no support to trigger a workflow with query parameters

We had a workflow with an HTTP trigger, which accepted GET requests with query parameters. Currently there is no support for passing query params during testing.

Resolution

I have added some more overloads of the TriggerWorkflow function with an argument for query parameters. The existing API is not changed and will work as before. Internally the ValueWithRelativePath function is modified to ValueWithQueryAndRelativePath to take the query parameters and generate an appropriate URL.

TriggerWorkflow is returning response before the workflow ends

We had a workflow where after the response action, there were a few more actions to be run. But currently the TriggerWorkflow function returns as soon as it receives the response. This was causing our assertions to fail as the actual status of the workflow was Running.

Resolution

I have modified the PollAndReturnFinalWorkflowResponse function to get the initial response, and then wait till the workflow status is not Running. Then based on the status code of the initial response, it either returns the initial response, or the latest workflow response (in case of non-HTTP trigger).

Unexpected response in case of asynchronous response

Logic app provides support for asynchronous response, which work by returning a 202 Accepted response as soon as they receive the request, along with a callback URL for the caller to poll and get the actual response when it is ready.

Screenshot 2023-05-20 at 2 41 16 PM

The current implementation treats the 202 status code as a response from non-HTTP trigger and sends the workflow run output as the response. This may not be the result expected by the user.

Resolution

The TestRunner class exposes a new method WaitForAsynchronousResponse(TimeSpan maxTimeout) through which the user can opt-in for the runner to wait for and return the actual asynchronous response. If this method is not called, then the default behaviour of the runner will be to simply return the 202 Accepted response. Internally, the WaitForAsynchronousResponse sets a private field to true. Then in the PollAndReturnFinalWorkflowResponse function, it checks if the response is asynchronous (if status code is 202 and Location header is present.) If the user has opted-in to wait, then the function polls the callback URL and returns the response, otherwise simply returns the initial response.

The LogicAppUnit test framework is not working on non-Windows devices

We have a few Mac machines in our team, and none of them were able to run the framework.

Resolution

The first thing I changed was the GetEnvPathForFunctionTools function to conditionally check for either func or func.exe based on the operating system, along with some other supporting changes. The next change is to use localhost instead of the machine's host name in the URL, again based on the operating system. Last change is to add a delay before the getting the trigger callback URL inside GetWorkflowCallbackDefinition function. The reason is unknown but without this delay I was getting a System.Net.Http.HttpRequestException exception.

I have only tested these changes on my Macbook machine with a limited set of cases. It would be better to have these changes tested more robustly before merging.

mark-abrams commented 1 year ago

Hi @atthevergeof , thank you for your contribution. I hope you are finding the testing framework useful. I don't have access to a Mac environment so I have only tested the framework on a Windows operating system, so I appreciate your feedback.

I've also received PR #14 that includes similar changes to resolve the compatibility issues for a Mac, so I will approve both PRs and resolve the conflicts to create a new version 1.5.1 which I'll then push to NuGet.

I don't have a Mac environment but I have created an Ubuntu environment for Logic App development. MacOS is not Ubuntu, but they have enough similarities so that I could easily re-create your compatibility issues with Ubuntu.

mark-abrams commented 1 year ago

Hi @atthevergeof , I'm just looking at your change for the TestRunner class.

I can see that you added a new public method TestRunner.WaitForAsynchronousResponse() but I can't see this method added to the ITestRunner interface. Was there a reason for this? Without adding it to the interface, the test cases won't be able to use the method because the creation of a test runner returns the interface, not the class instance.

atthevergeof commented 1 year ago

Hi @mark-abrams, thank you for pointing out the issue, I must have overlooked adding the method to ITestRunner interface. I have rectified it in the latest commit. Please let me know if you find any other discrepancies.

I've also received PR https://github.com/LogicAppUnit/TestingFramework/pull/14 that includes similar changes to resolve the compatibility issues for a Mac, so I will approve both PRs and resolve the conflicts to create a new version 1.5.1 which I'll then push to NuGet.

Yes this will be helpful. Right now we are maintaining our own version of the framework, but once these changes are merged, we will be able to directly use the official package.

mark-abrams commented 1 year ago

Hi @atthevergeof , I have uploaded version 1.6.0 of LogicAppUnit to NuGet. This includes your changes in PR #15. Thank you for your contribution.