I am testing my scheduled function via this approach:
firebase functions:shell
firebase> RUN_NAME_OF_THE_FUCTION()
In this function, I am verifying if an action should be run, and if it should, I am sending emails. The problem - I can't differentiate between the test and prod environment as I do not know how to:
Pass an argument to the scheduled function
Understand the context of me running a local function.
Is there a way for me to somehow identify that the scheduled function was run manually?
Pass an argument to the scheduled function
Scheduled functions don't accept custom arguments, so it doesn't really make sense to pass one. They receive a context, and that's all it should expect.
Understand the context of me running a local function.
You can simply set an environment variable on your development machine prior to executing the function. Check this variable at the time of execution to determine that it's being tested, as opposed to invoked on a schedule.
You can also use environment variables to effectively "pass" data to the function for the purpose of development, if that helps you.
Related
Let me introduce the scenario:
I need to test an AzureFunction with a queue trigger:
[FunctionName("AFunction")]
public async Task DispatchAction([QueueTrigger("queuename")] string message)
{
await DoMyLogicAsync();
}
The test needs to be run by the "functional-test-container" in my docker-compose testing env, which is made up by:
a) functional-test-container: a .net core container running an nUnit test suite
b) azure-function-container: this container hosts the azure function
c) azurite-container: this container hosts the queue server
d) sql-server-container
e) wiremock-container
The test logic is the following:
Clear the sql database, the queue and wiremock status
Prepare the wiremock stubs
Somehow trigger the function
wait for the function to end
make assertions on what the function produced in sql server, in the queue and on what wiremock's stubs have been called
As far as I know I have 2 ways of triggering the function:
a) pushing a message in the queue
b) using azure function's admin API /admin/functions/afunction
the problem is that both of them don't give any hint on when the function ends its execution.
Here it is my question: is there a way to call the function in a "sync" way (so that I can know when the execution ends)?
I don't think it can be implemented. The queue trigger function runs as an instance in azure server, we can just trigger it to run. It doesn't response any data like HttpTrigger function. So it can't be executed synchronously in your entire process.
To solve your problem, I think you can just add some code to do an operation at the end of your function. The operation is used to let you know the function execution is completed. Or another solution is move the steps after function into your function code.
Does anyone know if there is an easy way to trigger a function everytime i re-deploy some funciont to firebase?
I have an specific firabase functions which i define inside GCP (this way when i do "firebase deploy" it doesnt re-deploy, unnisntal or touch in any form my current function)
but sometimes i might update this function manually on GCP and i would like to trigger a inner function of its code everytime it happens... is it possible?
ex:
exports.decrementAction = (req, res) => {/*do stuff*/res.status(200).send("ok")};
function auxiliary(){
//to be called on re-deploy
}
Unfortunately, there isn't an easy way for you to trigger a function within a code that is being redeployed. Since this code is only being deployed at the moment, this wouldn't be possible to be done automatically.
The alternative would be to have this function separately from the "root" function in the moment of deploying and use triggers to run this other Cloud Function, when the first is redeployed. This way, it would be possible to run it based in the deployment of the other.
You can get more information on the triggers available for Cloud Functions here: Calling Cloud Functions. With them, you should be able to configure the timing for the execution.
Besides that, it might be worth it to raise a Feature Request for Google's to verify the possibility of adding this in future releases.
Let me know if the information clarified!
I think there exists a manner.
With Pub/Sub you can catch logs from Stackdriver (docs). Those services allow you to store only the logs related to the deployment of a Cloud Function.
The store could be, for instance, Cloud Firestore. As you should know, there is available a trigger for Cloud Firestore events.
Finally, every time an event log related to a function's deployment is generated, it will be stored and triggers a function attached to that event. In the function, you can parse or filter the logs.
Is there any way to manually trigger a scheduled function and/or a Firestore trigger function? I have two scenarios I need to solve:
A cloud function that is listening to a Firestore document (onCreate) didn't fire - it failed on 3 of about 1,000 invocations, so I need to manually trigger it for these 3 documents. Is this possible (to manually trigger this function)?
I have a scheduled function that runs hourly, but threw an error b/c of a map in the Firestore document when the code expected an array. Any way I can manually run the scheduled function once rather than waiting an hour before it runs again?
-- firebase console
-- functions
-- "..." at right side of cron job
-- "view in cloud scheduler"
-- "run now" at right side of function
You can run a firestore scheduled function via the FirebaseTools and running it locally. Starting the shell command eg npm run build && firebase functions:shell will allow you to invoke a Scheduled Function eg:
export const parseGarminHealthAPIActivityQueue = functions.region('europe-west2').runWith({
timeoutSeconds: TIMEOUT_IN_SECONDS,
memory: MEMORY
}).pubsub.schedule('every 10 minutes').onRun(async (context) => {
await parseQueueItems(ServiceNames.GarminHealthAPI);
});
It's not possible to manually trigger a function from the Firebase console. Your best bet is to use the methods shown in the Cloud documentation, which involve using gcloud's call command or the Cloud console's Testing tab. Neither of these are very easy, as you will have to construct the JSON payload to the function manually.
If I may make a suggestion - if your functions are failing due to errors, you should consider enabling retry on your functions, and making sure that your functions only generate errors for situations that should be retried. Depending on manual invocation in the event of a failure will not scale very well - errors should be handled by code as much as possible.
Typically when we can define the callback before and/or after the test case. Are there any callback for the test suite using data provider?
(i.e. run before or/and after a group of test cases?)
No, there is no such callback. Also note that all data providers are executed before the first test is executed.
For a Shiny app that I am making, I have to define some variables in the global environment as they need to be available to many functions here and there. Some of these variables don't exist to start with and are created as the user interacts with the app. The app is to check for existence of the variables and if they don't exist, it has to do something. However, after one session of use, the variables come into existence and stay in the global environment. When the user starts the app again, the app sees the variables in the global environment and so it behaves the way it is not supposed to behave. Is there a way I can remove the variables I create just before the user chooses to terminate the app? Any help is highly appreciated.
The valid way to solution that would be using onStop function as in:
onStop(function() cat("Session stopped\n"))
The linked documentation suggests using that within server function.
Create a function to cleanup when exiting using on.exit. on.exit records the expression given as its argument as needing to be executed when the current function exits (either naturally or as the result of an error). This is useful for resetting graphical parameters or performing other cleanup actions.
on.exit(rm(list= list(myListOfThings)))