Pregunta

Tengo una prueba de integración de matraz respaldada por un MongoDB de 1 nodo que falla al azar:

pytest/test_webapi.py:59: in test_register_test
>           assert res.status_code == 302
E           assert <Response streamed [404 NOT FOUND]>.status_code == 302

La tasa de falla es aproximadamente un 50%.

Prueba en test_webapi.py mirando así:

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()

Los métodos de matraz relevantes de 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("/")

... están respaldados por métodos de acción:

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

... donde self.users es una colección mongodb.

Self.New () Persiste la entidad usando Safe= True.

Curiosamente, varias otras pruebas que realizan cosas similares nunca parecen encontrar este problema.

Había pensado que esto sería suficiente para asegurarse de que el objeto persistido fuera visible para otros hilos en el grupo de conexión Pymongo.¿Qué parte de la documentación de Mongodb / Pymongo debería haber leído más detenidamente?¿O hay alguna interacción extraña con Asyncore?

¿Fue útil?

Solución

(portado del hilo de los comentarios)

En el contexto de las pruebas, ¿es el valor de data solo la cadena codificada de base de la clave de activación?Base64 contiene letras y dígitos, pero también "+" y "/", ambos serán mal interpretados por los analizadores de URL (particularmente "/").

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top