سؤال

لدي اختبار تكامل 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 (خاصة "/").

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top