Comments (8)
Happy to help @nykolaslima!
There is a note in the FAQ that multi-threading in general is not supported. I'll see if I can extend that with this use case as an example.
I'll close this then, but let us know if you run into any other issues.
from moto.
Hi @nykolaslima, both UserPools and Users are stored in the global scope. So i don't quite understand what is going wrong in your example.
Are you able to provide a full reproducible test, in a standalone repo for example?
from moto.
Hi @bblommers , thanks for helping.
I found the problem. I am using pytest flask
in order to start the flask app that is going to be tested. So I have two fixtures, one fixture to create the user in the cognito pool and other fixture to create the flask app.
@fixture
def logged_user(self, cognito_client, cognito_util, logged_user_password):
user = UserTableFactory.create().to_domain()
cognito_util.create_confirmed_user(user.email, logged_user_password)
return user
@fixture
def app(self, cognito_client):
os.environ['no_proxy'] = '*'
app = create_app()
app.config['SERVER_NAME'] = 'localhost'
return app
With this code I do not guarantee that the logged_user
will run before the app
fixture. And what was happening is that the app
was created first, and then the logged_user
is created.
Looks like somehow the state that is used by the flask app is "copied" when the app is created, as the moto objects were used by value and not by reference - and in the moment that the app was created there were not users in the cognito pool.
to solve this, add the logged_user
fixture as a dependency of app
fixture we guarantee that the user will be created in the pool before the flask app - and then it works.
working code:
@fixture
def logged_user(self, cognito_client, cognito_util, logged_user_password):
user = UserTableFactory.create().to_domain()
cognito_util.create_confirmed_user(user.email, logged_user_password)
return user
@fixture
def app(self, logged_user):
os.environ['no_proxy'] = '*'
app = create_app()
app.config['SERVER_NAME'] = 'localhost'
return app
Anyways it looks like a strange behavior since we supposed to share the same object, and if we are changing the users
list inside of it, it should reflect in the flask app in the runtime, doesn't it?
from moto.
Looks like somehow the state that is used by the flask app is "copied" when the app is created
Based on that description, I think it is a multi-threading problem actually.
If you start a new thread, Python will copy everything in the global context to the new thread - which includes the UserPool (and now User).
Any future actions in a thread will only impact the state/global context in that thread, and resources created/updated by Flask (in the Flask-thread) will not show up in the main thread. So this setup really only works for read-only tests.
You might want to have a look at the Moto server. If all threads send their boto3-calls to a shared server, they're guaranteed to share state.
https://docs.getmoto.org/en/latest/docs/server_mode.html
from moto.
makes totally sense, thanks very much for the explanation.
actually in my context it would be ok to keep the read-only approach since I am creating the setup and doing some "black box" testing that doesn't really dig into the details of the mutate state.
I believe we can close the issue since it's not a bug but a multi thread behavior.
Do you believe it worth to mention about it somewhere in the docs?
from moto.
may I open a PR with this improvement?
I could create it if you help me to figure out where is the best place to put it.
from moto.
Sounds good to me!
I was planning on extending the second question here:
https://github.com/getmoto/moto/blob/master/docs%2Fdocs%2Ffaq.rst
Which would show up here:
https://docs.getmoto.org/en/latest/docs/faq.html
from moto.
Awesome. will work on some draft here and send you a PR
from moto.
Related Issues (20)
- moto is not compatible with the "certificate_validated" waiter HOT 1
- primary Athena workgroup is missing EnforceWorkGroupConfiguration HOT 1
- When querying with ExclusiveStartKey the page is identical to the previous one HOT 5
- confusing pytest fixture example HOT 1
- ThreadedMotoServer: support automatic port picking HOT 1
- Document how to use ThreadedMotoServer as pytest fixture HOT 2
- EC2 instance with predefined IP and SubnetId: network interface stays around after instance termination HOT 1
- Incorrect behavior of SageMaker Client Search Method HOT 1
- What’s the master branch‘s actual current package version? HOT 1
- Large size on disk when installing for just one service HOT 1
- The security token included in the request is invalid for glue HOT 1
- ec2.describe_security_group_rules bad output response for IPv4, IPv6, Prefix Lists, Security Groups targets and overlapping port/protocols HOT 1
- implementation_coverage.py script misses covered API calls HOT 1
- Cryptographic API Misuse Vulnerability HOT 1
- Directory Service: DescribeDirectories expects LaunchTime to be a JSON Number, got string instead HOT 2
- No ValidationException raised when calling DDB UpdateItem operation with an empty ExpressionAttributeValues HOT 1
- Sagemaker runtime: InvokeEndpointAsync does not provide FailureLocation parameter HOT 2
- Organizations `create_account()` should create an IAM role in the new "account" HOT 2
- API GatewayV2 GetApi with an empty string: not implemented HOT 2
- Support for QLDB
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from moto.