اختبار قارورة/mongodb webapp غير متناسق
-
13-12-2019 - |
سؤال
لدي اختبار تكامل Flask مدعومًا بـ mongodb ذو عقدة واحدة والذي يفشل بشكل عشوائي:
pytest/test_webapi.py:59: in test_register_test
> assert res.status_code == 302
E assert <Response streamed [404 NOT FOUND]>.status_code == 302
نسبة الفشل حوالي 50%.
اختبار في test_webapi.py يبحث على النحو التالي:
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()
طرق Flask ذات الصلة من 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("/")
...مدعومة بأساليب العمل:
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
...حيث self.users عبارة عن مجموعة mongodb.
self.new() يستمر الكيان باستخدام Safe=True.
ومن المثير للاهتمام أن العديد من الاختبارات الأخرى التي تقوم بأشياء مماثلة لا يبدو أنها تواجه هذه المشكلة أبدًا.
كنت أعتقد أن هذا سيكون كافيًا للتأكد من أن الكائن الثابت سيكون مرئيًا لسلاسل الرسائل الأخرى في تجمع اتصال pymongo.ما هو الجزء من وثائق mongodb/pymongo الذي يجب أن أقرأه بعناية أكبر؟أم أن هناك بعض التفاعل الغريب مع غير المتزامن؟
المحلول
(منقول من موضوع التعليقات)
وفي سياق الاختبارات، هو data
هل قيمة السلسلة المشفرة base64 لمفتاح التنشيط فقط؟يحتوي base64 على أحرف وأرقام، ولكنه يحتوي أيضًا على "+" و"/"، وكلاهما سيتم تفسيرهما بشكل خاطئ بواسطة محللي URL (خاصة "/").