2012-05-22 10 views
0

У меня есть тест интеграции колбы при поддержке 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 следует прочитать более внимательно? Или есть какое-то странное взаимодействие с асинкором?

+0

Я предполагаю, что в контексте этих тестов «данные», полученные «SMTPServer», являются просто хешем в качестве строки base64? Возможно ли, что у него есть лишние пробелы или что-то, что вызывает здесь проблему? Если вы используете 'safe = True', то запись должна быть полностью завершена к моменту, когда вызов' insert() ',' update() 'и т. Д. Вернет управление вашей программе - другими словами, я не буду Думаю, что вы неправильно поняли или пропустили что-либо в документах Pymongo. – dcrosta

+0

@ dcrosta: вы абсолютно правы. Данные base64 могут содержать слэши, которые провоцируют соответствие app.route. Преобразуйте свой комментарий в ответ. – Bittrance

ответ

1

(портированы из комментариев нить)

В контексте испытаний, является значение data только в кодировке base64 строка ключа активации? base64 содержит буквы и цифры, но также «+» и «/», оба из которых будут неверно истолковываться парсерами URL (особенно «/»).

 Смежные вопросы

  • Нет связанных вопросов^_^