FLASK / MONGODB WebApp Test incoerente
-
13-12-2019 - |
Domanda
Ho un test di integrazione del pallone supportato da un mongodb a 1 nodo che non riesce a caso:
pytest/test_webapi.py:59: in test_register_test
> assert res.status_code == 302
E assert <Response streamed [404 NOT FOUND]>.status_code == 302
.
Il tasso di guasto è circa il 50%.
Test in Test_Webapi.py Guardando così:
def test_register_user(self):
res = self.client.get("/logout")
class MySMTPServer(smtpd.SMTPServer):
mails = []
def process_message(self, peer, mailfrom, rcpttos, data):
self.mails.append((rcpttos[0], data))
server = MySMTPServer(('localhost', 12345), None)
t = threading.Thread(target=asyncore.loop, args=(1,))
t.start()
time.sleep(.1)
try:
res = self.client.post("/register", data=self.registration)
assert res.status_code == 200
mail, hash = server.mails[0]
self.conn.fsync()
time.sleep(.1)
res = self.client.get('/activate/' + hash)
assert res.status_code == 302
finally:
server.close()
.
I metodi pertinenti del pallone da webapi.py:
@app.route("/register", methods=["POST"])
def register_user():
mail = flask.request.form['mail']
user = flask.request.form["user"]
pw = flask.request.form["pass"]
hash = users.register(user, pw, mail=mail)
return flask.jsonify({'_id': None}) # XXX
@app.route('/activate/<hash>', methods=['GET'])
def activate_user(hash):
key = users.activate(hash=hash)
if not key:
flask.abort(404)
return flask.redirect("/")
.
... sono supportati dai metodi di azione:
make_key = lambda : base64.encodestring(os.urandom(32)).strip()
def register(self, user, pw, **kw):
hash = self.make_key()
user = self.new(user, pw, activation=hash, **kw)
self._send_mail(**user)
return hash
def activate(self, hash):
user = self.users.find_one({'activation': hash})
if not user:
return None
key = self.make_key()
activation = {
'$unset': {'activation': 1},
'$set': {'status': 'active', 'key': key} }
self.users.update({'_id': user['_id']}, activation)
return user
.
... dove self.users è una collezione mongodb.
Self.New () persiste l'entità usando Safe= True.
Interessante, diversi altri test che fanno cose simili non sembrano mai incontrare questo problema.
Avevo pensato che questo sarebbe stato sufficiente per assicurarmi che l'oggetto persista fosse visibile ad altri fili nel pool di collegamento Pymongo.Quale parte della documentazione mongodb / Pymongo dovrei aver letto più attentamente?O c'è una strana interazione con Asyncore?
Soluzione
(portato da commenti thread)
Nel contesto dei test, è il valore data
solo la stringa codificata di base64 della chiave di attivazione?Base64 contiene lettere e cifre, ma anche "+" e "/", entrambi saranno erroneamente interpretati dai parrsers dell'URL (in particolare "/").