У меня есть тест интеграции колбы при поддержке MongoDB 1-узла, который случайным образом терпит неудачу:Колба/MongoDB WebApp несовместимым тест
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()
Соответствующие методы Колба из 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 следует прочитать более внимательно? Или есть какое-то странное взаимодействие с асинкором?
Я предполагаю, что в контексте этих тестов «данные», полученные «SMTPServer», являются просто хешем в качестве строки base64? Возможно ли, что у него есть лишние пробелы или что-то, что вызывает здесь проблему? Если вы используете 'safe = True', то запись должна быть полностью завершена к моменту, когда вызов' insert() ',' update() 'и т. Д. Вернет управление вашей программе - другими словами, я не буду Думаю, что вы неправильно поняли или пропустили что-либо в документах Pymongo. – dcrosta
@ dcrosta: вы абсолютно правы. Данные base64 могут содержать слэши, которые провоцируют соответствие app.route. Преобразуйте свой комментарий в ответ. – Bittrance