-
Notifications
You must be signed in to change notification settings - Fork 84
Use tox to test the python3-flask template #42
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use tox to test the python3-flask template #42
Conversation
**What** - Add a sample tox.ini file to the python3-flask. This configuration will run pytest and flake8 for the function handler. The default flake8 is very resticted, only erroring for undefined names and syntax errors. This allows us to lint and test the function during `faas-cli build`, which should simplify CI flows for users. Using `tox` allows th euser to completely customize the test flow without requiring any changes to the template. - Add same test for the echo handler - Include documentationthat describes how to disable Signed-off-by: Lucas Roesler <[email protected]>
#install function code | ||
USER root | ||
|
||
COPY function function | ||
RUN chown -R app:app ./ | ||
COPY function/ . |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder why we did and do this part as root?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
probably need it for chown, i guess
# tox.ini file, in addition to deleting this file. | ||
|
||
def test_handle(): | ||
assert handle("input") == "input" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if we made this pass
instead? So that if there's an issue with layers or backwards compatibility, it always works?
Signed-off-by: Lucas Roesler <[email protected]>
@viveksyngh please could you take a look and try this out with some of your own tests? |
Hi @LucasRoesler, I've never heard of Tox, thank you for sharing. :) I like the idea: I would use it too, if it were implemented like this. Here is one of my Python functions, I just test it with Pytest - no Tox. However, I just hammered in Tox, and was able to get it to lint and test, too! If you clone the repo, you can run Tox with: Some thoughts:
I am wondering, is there a way to accomplish this workflow, not have it be breaking and be low code like your approach here? Almost like a way for people to "opt into" a workflow such as this one? One idea it to have Talk soon, Kyle |
Hi Kyle, these are all good points. I have thought of many of them as well. It is a difficult balance. I like the thought about having hooks. Although, in some ways this is exactly what tox is doing because it provides an entrypoint in which a user can define any commands and a default sequence of commands to run when we call RE point (3), there are already several templates that do have a similar pattern of running tests during the I think we can handle the backwards compatibility by adding an additional checks prior to running tox, maybe wrap it in a small bash script to help make the check more robust: either tox.ini file exists or the pyproject file contains a tox section. This might also reduce concerns about noise by letting people just delete the tox file. How would you feel if it was easy enough to just disable by deleting the tox file? Ultimately though, the templates are very easy to fork and replace, especially when people use this https://docs.openfaas.com/reference/yaml/#yaml-template-stack-configuration or commit the template folder and modify the template as works best for them. |
@alexellis and @kylos101 what do you think of doing something like this ARG TEST_COMMAND=tox
RUN if [ "x$TEST_COMMAND" = "xoff" ]; then \
echo "skipping tests";\
else \
eval "$TEST_COMMAND"; \
fi This allows you to do faas-cli build -f echo0.yml --build-arg TEST_COMMAND='off' you can also add it as a build arg in the stack.yml via https://docs.openfaas.com/reference/yaml/#function-build-args-build-args This gives the DX that the developer can add the build arg to the stack.yml and then delete the tox.ini file . They can even add their own custom script, if they want, providing maximum flexibility. At the same time, the default experience still includes and encourages testing. A note about the script. I know that this looks funny |
**What** - Add a build arg TEST_COMMAND that allows the developer to set the exact test command that should be executed. When set to `off` the tests will be skipped Signed-off-by: Lucas Roesler <[email protected]>
Hi @LucasRoesler , That is really cool! I'm sorry about the delay. Seriously though, good use of an arg. I'm remote right now, but will poke around later tonight. To see what it's like, and if I can help add any value. |
Hi @LucasRoesler, I went through the test notes, thank you for sharing such detailed steps! As an occasional contributor, that helped me quickly dig in and start providing value right away. Additionally, I appreciate your thoughtful response to my initial comment, letting me know that other templates have built-in test functionality too. For example, that tipped me of that I could look at their respective Thoughts on next steps:
Observations:
Errors received during build:
- [echo0] received non-zero exit code from build, error: The command '/bin/sh -c if [ "x$TEST_COMMAND" = "xoff" ]; then echo "skipping tests"; else eval "$TEST_COMMAND"; fi' returned a non-zero code: 1
I've got to step away now, but will try to test some more later. Take care, bud! |
|
||
# Test your handler here | ||
|
||
# To disable testing, you can set the build_arg `TEST_COMMAND=off` on the CLI or in your stack.yml |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we move this to the tox.ini
, replacing lines 1-6?
Some additional tests I ran:
|
template/python3-flask/Dockerfile
Outdated
RUN chown -R app:app ../ | ||
|
||
ARG TEST_COMMAND=tox | ||
RUN if [ "x$TEST_COMMAND" = "xoff" ]; then \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Silly question...why does this work and disable tox? Shouldn't it be looking for a mach of xoff
?
faas-cli build -f echo0.yml --build-arg TEST_COMMAND='off'
I would of expected it to still run tox, and then we'd need something like this to disable tox:
`faas-cli build -f echo0.yml --build-arg TEST_COMMAND='xoff'
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this works to disable tox because the script is check for "off" and just printing an message, if the command is not exactly off, then it runs the test command, which defaults to tox
if "off":
print "disabled";
else:
eval "test command";
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does xoff work with a value of off?
Given this:
"x$TEST_COMMAND" = "xoff"
The x
in xoff
is being ignored somehow when the string comparison is done...right?
I'm guessing there's a bash thing going on that I don't quite understand.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From Lucas:
"" cannot be use to set the TEST_COMMAND to empty
Also, "off" apparently doesn't work so "xoff" is required instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I would err on the side of caution when overloading the build arg with a mode plus a command, so think about splitting out two variables.
TEST_ON=true/false
TEST_COMMAND=go test -v ./...
TEST_COMMAND=go test -v ./pkg
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
@kylos101 RE
The file needs to exist if we decide testing is on by default and using pytest (via tox), then pytest will fail if it finds no test cases to run, see pytest has chosen that that not finding any tests should be considered a failure because it most likely indicates a configuration error and it is better to error early and loud instead of silently missing that no tests were run. If we do not include at least one test and we run pytest by default, then it will always fail. RE
For (2), yes, the modified file replaced the file from the template, it may not be obvious, but this is exactly the same behavior as what already happens to the For (3), it is also expected that the default template file is copied. In this case, the file/test is completely self-contained no-op. It should never cause a build failure because the function literally does nothing. But the existence also means that RE
The failure for you empty test file is actually a failure due to pytest, again see my response to (1). Additionally, the linter configuration is inspired from https://docs.github.com/en/actions/guides/building-and-testing-python and is not intended to enforce all of the flake8/pep8 rules, rather, the flake8 rules chosen as the default highlight actual syntax errors that we would expect to cause runtime errors. This feels appropriate as a test because the function is broken. It did not feel appropriate to add too much here but it did seem like it would be useful to catch and fail on a syntax error. The goal was to make it easy for users to configure it with more rules if necessary via https://github.com/openfaas/python-flask-template/pull/42/files#diff-cab7f7374a89adeb5b48fe4d2cb45bc59ec7534a4207c4dcd2771fc1712352ebR34-R41 The tooling and linting rules in the python community are not exactly universal yet. But, having it there makes it clear (i hope) for how to integrate your favorite tools and settings into the build flow. Reviewing my comment above, it occurs to me that almost everything seems to tie back to "pytest fails if there are no tests" |
Perfect, your reply handles my thoughts Re: next steps, @LucasRoesler. 👍 For what it's worth, I like the idea of it being on by default. If someone finds this to be breaking, they can update their stack file or CI scripting to use build arg. Also, I didn't realize you could reference multiple lines of code in the diff - super helpful! Thank you. Let me know if there's anything else I can do to help? |
At this point, i think the next step is to get a design approval from @alexellis I think one thing to add is that this pattern could easily be copied to any of the other templates and could be very productive, even in the templates that already have test support, e.g. Go, because the user may want to customize the flags given to the test command, for example so that only unit tests are run and integration tests are skipped |
**What** - add TEST_ENABLED build-arg to control if the tests are run or not. Should be easier to document and debug in the future. - Copy the implementation to all of the python3 templates Signed-off-by: Lucas Roesler <[email protected]>
**What** - Add a section to the README explaining how to use the new build args to control the test step. Signed-off-by: Lucas Roesler <[email protected]>
What
will run pytest and flake8 for the function handler. The default
flake8 is very resticted, only erroring for undefined names and
syntax errors. This allows us to lint and test the function during
faas-cli build
, which should simplify CI flows for users. Usingtox
allows th euser to completely customize the test flow withoutrequiring any changes to the template.
Motivation and Context
design/approved
labelThis is a PoC based on based on the experience in https://lucasroesler.com/posts/2021/test-python-functions/ and motivated by discussions from our weekly community calls.
How Has This Been Tested?
faas-cli new echo0 --lang python3-flask && fass-cli build -f echo0.yml
should work in this branch of the repoassert 1 == 2``, now
fass-cli build -f echo0.yml` will failfaas-cli new echo1 --lang python3-flask
then follow the directions to disable testing in thetox.ini
file, then runfaas-cli build -f echo1.yml
. This should also build successfullyTypes of changes
I think this could be a breaking change if someone already has tests setup. If they are using
tox
then it is fine, but it could be an issue if they have some other workflow or configuration. We need to talk to the community and find out more.Checklist:
git commit -s