From e9a675d925778ef3ec6c38e235a71b25c1e3b344 Mon Sep 17 00:00:00 2001 From: Folker Bernitt Date: Tue, 17 Mar 2015 11:03:06 +0100 Subject: Lock index on index_mail. - Issue #330 --- service/pixelated/adapter/search/__init__.py | 5 ++- service/test/support/test_helper.py | 8 +++- service/test/unit/adapter/search/test_search.py | 60 +++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 3 deletions(-) create mode 100644 service/test/unit/adapter/search/test_search.py diff --git a/service/pixelated/adapter/search/__init__.py b/service/pixelated/adapter/search/__init__.py index 0b1a1034..f1828780 100644 --- a/service/pixelated/adapter/search/__init__.py +++ b/service/pixelated/adapter/search/__init__.py @@ -116,8 +116,9 @@ class SearchEngine(object): return FileIndex.create(storage, self._mail_schema(), indexname='mails') def index_mail(self, mail): - with self._index.writer() as writer: - self._index_mail(writer, mail) + with self._write_lock: + with self._index.writer() as writer: + self._index_mail(writer, mail) def _index_mail(self, writer, mail): mdict = mail.as_dict() diff --git a/service/test/support/test_helper.py b/service/test/support/test_helper.py index 54685008..0f42e433 100644 --- a/service/test/support/test_helper.py +++ b/service/test/support/test_helper.py @@ -16,7 +16,7 @@ from datetime import datetime import io -from pixelated.adapter.model.mail import InputMail +from pixelated.adapter.model.mail import InputMail, PixelatedMail LEAP_FLAGS = ['\\Seen', @@ -68,6 +68,12 @@ def leap_mail(uid=0, flags=LEAP_FLAGS, headers=None, extra_headers={}, mbox='INB return (fdoc, hdoc, bdoc) +def pixelated_mail(uid=0, flags=LEAP_FLAGS, headers=None, extra_headers={}, mbox='INBOX', body='body', chash='chash'): + fdoc, hdoc, bdoc = leap_mail(uid, flags, headers, extra_headers, mbox, body, chash) + + return PixelatedMail.from_soledad(fdoc, hdoc, bdoc) + + def input_mail(): mail = InputMail() mail.fdoc = TestDoc({}) diff --git a/service/test/unit/adapter/search/test_search.py b/service/test/unit/adapter/search/test_search.py new file mode 100644 index 00000000..9018d7c5 --- /dev/null +++ b/service/test/unit/adapter/search/test_search.py @@ -0,0 +1,60 @@ +# +# Copyright (c) 2014 ThoughtWorks, Inc. +# +# Pixelated is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pixelated is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with Pixelated. If not, see . + + +import unittest +from mockito import * +from pixelated.adapter.search import SearchEngine +from tempdir import TempDir +from test.support import test_helper + +INDEX_KEY = '\xde3?\x87\xff\xd9\xd3\x14\xf0\xa7>\x1f%C{\x16.\\\xae\x8c\x13\xa7\xfb\x04\xd4]+\x8d_\xed\xd1\x8d\x0bI' \ + '\x8a\x0e\xa4tm\xab\xbf\xb4\xa5\x99\x00d\xd5w\x9f\x18\xbc\x1d\xd4_W\xd2\xb6\xe8H\x83\x1b\xd8\x9d\xad' + + +class LockStub(object): + def __init__(self): + self.called = False + + def __enter__(self): + self.called = True + return self + + def __exit__(self, type, value, traceback): + return False + + +class SearchEngineTest(unittest.TestCase): + def setUp(self): + self.tempdir = TempDir() + self.agent_home = self.tempdir.name + + def tearDown(self): + self.tempdir.dissolve() + + def test_index_mail_secured_by_lock(self): + # given + soledad_querier = mock() + lock_stub = LockStub() + when(soledad_querier).get_index_masterkey().thenReturn(INDEX_KEY) + se = SearchEngine(soledad_querier, self.agent_home) + se._write_lock = lock_stub + + # when + se.index_mail(test_helper.pixelated_mail()) + + # then + self.assertTrue(lock_stub.called) -- cgit v1.2.3