Ejemplo n.º 1
0
 def testTwoRequests(self):
     mngr = SolrConnectionManager(active=True)
     proc = SolrIndexProcessor(mngr)
     output = fakehttp(mngr.getConnection(), getData('schema.xml'),
                       getData('add_response.txt'))
     proc.index(self.foo)
     mngr.closeConnection()
     self.assertEqual(len(output), 2)
     self.failUnless(output.get().startswith(self.schema_request))
     self.assertEqual(sortFields(output.get()), getData('add_request.txt'))
Ejemplo n.º 2
0
    def testLocalConnections(self):
        config = getConfig()
        config.atomic_updates = True
        mngr = SolrConnectionManager(active=True)
        proc = SolrIndexProcessor(mngr)
        mngr.setHost(active=True)
        schema = getData('schema.xml')
        log = []

        def runner():
            # fake schema response on solr connection - caches the schema
            fakehttp(mngr.getConnection(), getData('schema.xml'))
            mngr.getConnection().get_schema()

            fakehttp(mngr.getConnection(), schema)      # fake schema response
            # read and cache the schema
            mngr.getSchema()
            response = getData('add_response.txt')
            # fake add response
            output = fakehttp(mngr.getConnection(), response)
            # indexing sends data
            proc.index(Foo(id='500', name='python test doc'))
            mngr.closeConnection()
            log.append(str(output))
            log.append(proc)
            log.append(mngr.getConnection())
        # after the runner was set up, another thread can be created and
        # started;  its output should contain the proper indexing request,
        # whereas the main thread's connection remain idle;  the latter
        # cannot be checked directly, but the connection object would raise
        # an exception if it was used to send a request without setting up
        # a fake response beforehand...
        thread = Thread(target=runner)
        thread.start()
        thread.join()
        conn = mngr.getConnection()         # get this thread's connection
        fakehttp(conn, schema)              # fake schema response
        mngr.getSchema()                    # read and cache the schema
        mngr.closeConnection()
        mngr.setHost(active=False)
        self.assertEqual(len(log), 3)
        self.assertEqual(sortFields(log[0]), getData(
            'add_request.txt').rstrip('\n'))
        self.failUnless(isinstance(log[1], SolrIndexProcessor))
        self.failUnless(isinstance(log[2], SolrConnection))
        self.failUnless(isinstance(proc, SolrIndexProcessor))
        self.failUnless(isinstance(conn, SolrConnection))
        self.assertEqual(log[1], proc)      # processors should be the same...
        self.assertNotEqual(log[2], conn)   # but not the connections
Ejemplo n.º 3
0
 def testFourRequests(self):
     mngr = SolrConnectionManager(active=True)
     proc = SolrIndexProcessor(mngr)
     output = fakehttp(mngr.getConnection(), getData('schema.xml'),
                       getData('add_response.txt'),
                       getData('delete_response.txt'),
                       getData('commit_response.txt'))
     proc.index(self.foo)
     proc.unindex(self.foo)
     proc.commit()
     mngr.closeConnection()
     self.assertEqual(len(output), 4)
     self.failUnless(output.get().startswith(self.schema_request))
     self.assertEqual(sortFields(output.get()), getData('add_request.txt'))
     self.assertEqual(output.get(), getData('delete_request.txt'))
     self.assertEqual(output.get(), getData('commit_request.txt'))
Ejemplo n.º 4
0
    def test_fallback_search_solr(self):
        """Should work as test_fallback_search, but based on the native solr
           search utility """

        pc = api.portal.get_tool("portal_catalog")
        mock_results = SolrResponse()
        mock_results.response = pc({"path": {"query": "/plone/en-de"}})
        mock_search = MagicMock(return_value=mock_results)
        mock_search.getManager = lambda: SolrConnectionManager(active=True)
        from zope.interface import alsoProvides
        from plone.indexer.interfaces import IIndexableObject
        alsoProvides(mock_search, IIndexableObject)
        sm = self.portal.getSiteManager()
        sm.unregisterUtility(provided=ISearch)
        sm.unregisterUtility(provided=ISolrConnectionConfig)
        sm.registerUtility(component=SolrConnectionConfig(),
                           provided=ISolrConnectionConfig)
        sm.registerUtility(component=mock_search, provided=ISearch)
        lf_search_view = self.portal.restrictedTraverse(
            "@@language-fallback-search")
        results = lf_search_view.search_solr("path_parents:/plone/events")
        self.assertEqual(
            set([x.getPath() for x in results]),
            set([
                '/plone/en-de', '/plone/en-de/en-event',
                '/plone/en/notrans-event'
            ]))
        mock_search.search.assert_called_with(
            "path_parents:/plone/events +Language:en OR all OR de")
Ejemplo n.º 5
0
 def testExtraRequest(self):
     # basically the same as `testThreeRequests`, except it
     # tests adding fake responses consecutively
     mngr = SolrConnectionManager(active=True)
     proc = SolrIndexProcessor(mngr)
     conn = mngr.getConnection()
     output = fakehttp(conn, getData('schema.xml'))
     fakemore(conn, getData('add_response.txt'))
     proc.index(self.foo)
     fakemore(conn, getData('delete_response.txt'))
     proc.unindex(self.foo)
     mngr.closeConnection()
     self.assertEqual(len(output), 3)
     self.failUnless(output.get().startswith(self.schema_request))
     self.assertEqual(sortFields(output.get()), getData('add_request.txt'))
     self.assertEqual(output.get(), getData('delete_request.txt'))
 def testExtraRequest(self):
     # basically the same as `testThreeRequests`, except it
     # tests adding fake responses consecutively
     mngr = SolrConnectionManager(active=True)
     proc = SolrIndexProcessor(mngr)
     conn = mngr.getConnection()
     output = fakehttp(conn, getData('schema.xml'))
     fakemore(conn, getData('add_response.txt'))
     proc.index(self.foo)
     fakemore(conn, getData('delete_response.txt'))
     proc.unindex(self.foo)
     mngr.closeConnection()
     self.assertEqual(len(output), 3)
     self.failUnless(output.get().startswith(self.schema_request))
     self.assertEqual(sortFields(output.get()), getData('add_request.txt'))
     self.assertEqual(output.get(), getData('delete_request.txt'))
Ejemplo n.º 7
0
 def setUp(self):
     provideUtility(SolrConnectionConfig(), ISolrConnectionConfig)
     self.mngr = SolrConnectionManager()
     self.mngr.setHost(active=True)
     self.conn = self.mngr.getConnection()
     self.search = Search()
     self.search.manager = self.mngr
Ejemplo n.º 8
0
 def setUp(self):
     self.mngr = SolrConnectionManager()
     self.mngr.setHost(active=True)
     conn = self.mngr.getConnection()
     fakehttp(conn, getData('schema.xml'))   # fake schema response
     self.mngr.getSchema()                   # read and cache the schema
     self.search = Search()
     self.search.manager = self.mngr
Ejemplo n.º 9
0
 def setUp(self):
     provideUtility(SolrConnectionConfig(), ISolrConnectionConfig)
     self.mngr = SolrConnectionManager()
     self.mngr.setHost(active=True)
     conn = self.mngr.getConnection()
     fakehttp(conn, getData('schema.xml'))       # fake schema response
     self.mngr.getSchema()                       # read and cache the schema
     self.proc = SolrIndexProcessor(self.mngr)
Ejemplo n.º 10
0
class SearchTests(TestCase):

    def setUp(self):
        provideUtility(SolrConnectionConfig(), ISolrConnectionConfig)
        self.mngr = SolrConnectionManager()
        self.mngr.setHost(active=True)
        self.conn = self.mngr.getConnection()
        self.search = Search()
        self.search.manager = self.mngr

    def tearDown(self):
        self.mngr.closeConnection()
        self.mngr.setHost(active=False)

    def testSimpleSearch(self):
        schema = getData('schema.xml')
        search = getData('search_response.txt')
        request = getData('search_request.txt')
        output = fakehttp(self.conn, schema, search)    # fake responses
        query = self.search.buildQuery(id='[* TO *]')
        results = self.search(query, rows=10, wt='xml', indent='on').results()
        normalize = lambda x: sorted(x.split('&'))      # sort request params
        self.assertEqual(normalize(output.get(skip=1)), normalize(request))
        self.assertEqual(results.numFound, '1')
        self.assertEqual(len(results), 1)
        match = results[0]
        self.assertEqual(match.id, '500')
        self.assertEqual(match.name, 'python test doc')
        self.assertEqual(match.popularity, 0)
        self.assertEqual(match.sku, '500')
        self.assertEqual(match.timestamp,
            DateTime('2008-02-29 16:11:46.998 GMT'))
Ejemplo n.º 11
0
 def setUp(self):
     self.mngr = SolrConnectionManager()
     self.mngr.setHost(active=True)
     conn = self.mngr.getConnection()
     fakehttp(conn, getData('schema.xml'))       # fake schema response
     self.mngr.getSchema()                       # read and cache the schema
     self.proc = SolrIndexProcessor(self.mngr)
     config = getConfig()
     config.atomic_updates = True
Ejemplo n.º 12
0
 def testThreeRequests(self):
     mngr = SolrConnectionManager(active=True)
     proc = SolrIndexProcessor(mngr)
     output = fakehttp(
         mngr.getConnection(),
         getData("schema.xml"),
         getData("add_response.txt"),
         getData("delete_response.txt"),
     )
     proc.index(self.foo)
     proc.unindex(self.foo)
     mngr.closeConnection()
     self.assertEqual(len(output), 3)
     self.failUnless(output.get().decode("utf-8").startswith(self.schema_request))
     self.assertEqual(
         sortFields(output.get()), getData("add_request.txt").rstrip(b"\n")
     )
     self.assertEqual(output.get(), getData("delete_request.txt").rstrip(b"\n"))
Ejemplo n.º 13
0
 def setUp(self):
     provideUtility(SolrConnectionConfig(), ISolrConnectionConfig)
     self.mngr = SolrConnectionManager()
     self.mngr.setHost(active=True)
     self.conn = self.mngr.getConnection()
     self.proc = SolrIndexProcessor(self.mngr)
     self.log = []                   # catch log messages...
     def logger(*args):
         self.log.extend(args)
     logger_indexer.warning = logger
Ejemplo n.º 14
0
    def setUp(self):
        self.mngr = SolrConnectionManager()
        self.mngr.setHost(active=True)
        self.conn = self.mngr.getConnection()
        self.proc = SolrIndexProcessor(self.mngr)
        self.log = []                   # catch log messages...

        def logger(*args):
            self.log.extend(args)
        logger_indexer.warning = logger
        config = getConfig()
        config.atomic_updates = True
Ejemplo n.º 15
0
    def setUp(self):
        provideUtility(SolrConnectionConfig(), ISolrConnectionConfig)
        self.mngr = SolrConnectionManager()
        self.mngr.setHost(active=True)
        conn = self.mngr.getConnection()
        fakehttp(conn, getData('plone_schema.xml')) # fake schema response
        self.mngr.getSchema()                       # read and cache the schema
        self.search = Search()
        self.search.manager = self.mngr

        # Patch buildQuery method
        self.search.buildQuery = buildQuery.__get__(self.search,
                                                    self.search.__class__)
Ejemplo n.º 16
0
class TestBuildQuery(TestCase):

    def setUp(self):
        provideUtility(SolrConnectionConfig(), ISolrConnectionConfig)
        self.mngr = SolrConnectionManager()
        self.mngr.setHost(active=True)
        conn = self.mngr.getConnection()
        fakehttp(conn, getData('plone_schema.xml'))  # fake schema response
        self.mngr.getSchema()                       # read and cache the schema
        self.search = Search()
        self.search.manager = self.mngr

        # Patch buildQuery method
        self.search.buildQuery = buildQueryAndParameters.__get__(
            self.search,
            self.search.__class__)

    def tearDown(self):
        self.mngr.closeConnection()
        self.mngr.setHost(active=False)

    def build_query(self, *args, **kwargs):
        query = self.search.buildQuery(*args, **kwargs)[0]
        return ' '.join(sorted(query.values()))

    def test_simple_path_query(self):
        self.assertEquals('+path_parents:\\/spam\\/and\\/eggs',
                          self.build_query(path_parents='/spam/and/eggs'))

    def test_path_list_query(self):
        self.assertEquals('+path_parents:("\\/spam" OR "\\/eggs")',
                          self.build_query(path_parents=['/spam', '/eggs']))

    def test_slash_in_searchabletext(self):
        self.assertEquals('+SearchableText:spam\\/eggs',
                          self.build_query(SearchableText='spam/eggs'))

    def test_queries_with_path_and_depth_should_be_escaped(self):
        self.assertEquals(
            '+path_depth:[4 TO 6] AND +path_parents:\\/spam\\/and\\/eggs',
            self.build_query(
                path_parents=set(['+path_depth:[4 TO 6] AND '
                                  '+path_parents:/spam/and/eggs'])))
Ejemplo n.º 17
0
class TestBuildQuery(TestCase):
    def setUp(self):
        provideUtility(SolrConnectionConfig(), ISolrConnectionConfig)
        self.mngr = SolrConnectionManager()
        self.mngr.setHost(active=True)
        conn = self.mngr.getConnection()
        fakehttp(conn, getData('plone_schema.xml'))  # fake schema response
        self.mngr.getSchema()  # read and cache the schema
        self.search = Search()
        self.search.manager = self.mngr

        # Patch buildQuery method
        self.search.buildQuery = buildQuery.__get__(self.search,
                                                    self.search.__class__)

    def tearDown(self):
        self.mngr.closeConnection()
        self.mngr.setHost(active=False)

    def build_query(self, *args, **kwargs):
        query = self.search.buildQuery(*args, **kwargs)
        return ' '.join(sorted(query.values()))

    def test_simple_path_query(self):
        self.assertEquals('+path_parents:\\/spam\\/and\\/eggs',
                          self.build_query(path_parents='/spam/and/eggs'))

    def test_path_list_query(self):
        self.assertEquals('+path_parents:(\\/spam OR \\/eggs)',
                          self.build_query(path_parents=['/spam', '/eggs']))

    def test_slash_in_searchabletext(self):
        self.assertEquals('+SearchableText:spam\\/eggs',
                          self.build_query(SearchableText='spam/eggs'))

    def test_queries_with_path_and_depth_should_be_escaped(self):
        self.assertEquals(
            '+path_depth:[4 TO 6] AND +path_parents:\\/spam\\/and\\/eggs',
            self.build_query(path_parents=set(
                ['+path_depth:[4 TO 6] AND '
                 '+path_parents:/spam/and/eggs'])))
Ejemplo n.º 18
0
class SearchTests(TestCase):

    layer = COLLECTIVE_SOLR_MOCK_REGISTRY_FIXTURE

    def setUp(self):
        self.mngr = SolrConnectionManager()
        self.mngr.setHost(active=True)
        self.conn = self.mngr.getConnection()
        self.search = Search()
        self.search.manager = self.mngr

    def tearDown(self):
        self.mngr.closeConnection()
        self.mngr.setHost(active=False)

    def testSimpleSearch(self):
        schema = getData("schema.xml")
        search = getData("search_response.txt")
        request = getData("search_request.txt").rstrip(b"\n")
        request_py2 = getData("search_request_py2.txt").rstrip(b"\n")
        output = fakehttp(self.conn, schema, search)  # fake responses
        query, ignore = self.search.buildQueryAndParameters(id="[* TO *]")
        results = self.search(query, rows="10", wt="xml",
                              indent="on").results()
        normalize = lambda x: sorted(x.split(b"&"))  # sort request params
        self.assertIn(
            normalize(output.get(skip=1)),
            [normalize(request), normalize(request_py2)])
        self.assertEqual(results.numFound, "1")
        self.assertEqual(len(results), 1)
        match = results[0]
        self.assertEqual(match.id, "500")
        self.assertEqual(match.name, "python test doc")
        self.assertEqual(match.popularity, 0)
        self.assertEqual(match.sku, "500")
        self.assertEqual(match.timestamp.ISO8601(),
                         DateTime("2008-02-29 16:11:46.998 GMT").ISO8601())
Ejemplo n.º 19
0
class RobustnessTests(TestCase):

    layer = COLLECTIVE_SOLR_MOCK_REGISTRY_FIXTURE

    def setUp(self):
        self.mngr = SolrConnectionManager()
        self.mngr.setHost(active=True)
        self.conn = self.mngr.getConnection()
        self.proc = SolrIndexProcessor(self.mngr)
        self.log = []  # catch log messages...

        def logger(*args):
            self.log.extend(args)

        logger_indexer.warning = logger
        config = getConfig()
        config.atomic_updates = True

    def tearDown(self):
        self.mngr.closeConnection()
        self.mngr.setHost(active=False)

    def testIndexingWithUniqueKeyMissing(self):
        # fake schema response
        fakehttp(self.conn, getData("simple_schema.xml"))
        # read and cache the schema
        self.mngr.getSchema()
        response = getData("add_response.txt")
        output = fakehttp(self.conn, response)  # fake add response
        foo = Foo(id="500", name="foo")
        # indexing sends data
        self.proc.index(foo)
        # nothing happened...
        self.assertEqual(len(output), 0)
        self.assertEqual(
            self.log, ["schema is missing unique key, skipping indexing of %r", foo]
        )

    def testUnindexingWithUniqueKeyMissing(self):
        # fake schema response
        fakehttp(self.conn, getData("simple_schema.xml"))
        # read and cache the schema
        self.mngr.getSchema()
        response = getData("delete_response.txt")
        # fake delete response
        output = fakehttp(self.conn, response)
        foo = Foo(id="500", name="foo")
        # unindexing sends data
        self.proc.unindex(foo)
        # nothing happened...
        self.assertEqual(len(output), 0)
        self.assertEqual(
            self.log, ["schema is missing unique key, skipping unindexing of %r", foo]
        )
Ejemplo n.º 20
0
class QueueIndexerTests(TestCase):

    def setUp(self):
        provideUtility(SolrConnectionConfig(), ISolrConnectionConfig)
        self.mngr = SolrConnectionManager()
        self.mngr.setHost(active=True)
        conn = self.mngr.getConnection()
        fakehttp(conn, getData('schema.xml'))       # fake schema response
        self.mngr.getSchema()                       # read and cache the schema
        self.proc = SolrIndexProcessor(self.mngr)

    def tearDown(self):
        self.mngr.closeConnection()
        self.mngr.setHost(active=False)

    def testPrepareData(self):
        data = {'allowedRolesAndUsers': [
            'user:test_user_1_', 'user:portal_owner']}
        prepareData(data)
        self.assertEqual(
            data,
            {
                'allowedRolesAndUsers': [
                    'user$test_user_1_',
                    'user$portal_owner'
                ]
            }
        )

    def testLanguageParameterHandling(self):
        # empty strings are replaced...
        data = {'Language': ['en', '']}
        prepareData(data)
        self.assertEqual(data, {'Language': ['en', 'any']})
        data = {'Language': ''}
        prepareData(data)
        self.assertEqual(data, {'Language': 'any'})
        # for other indices this shouldn't happen...
        data = {'Foo': ['en', '']}
        prepareData(data)
        self.assertEqual(data, {'Foo': ['en', '']})

    def testIndexObject(self):
        response = getData('add_response.txt')
        # fake add response
        output = fakehttp(self.mngr.getConnection(), response)
        # indexing sends data
        self.proc.index(Foo(id='500', name='python test doc'))
        self.assertEqual(sortFields(str(output)), getData('add_request.txt'))

    def testIndexAccessorRaises(self):
        response = getData('add_response.txt')
        # fake add response
        output = fakehttp(self.mngr.getConnection(), response)

        def brokenfunc():
            raise ValueError
        self.proc.index(Foo(id='500', name='python test doc',
                            text=brokenfunc))   # indexing sends data
        self.assertEqual(sortFields(str(output)), getData('add_request.txt'))

    def testPartialIndexObject(self):
        foo = Foo(id='500', name='foo', price=42.0)
        # first index all attributes...
        response = getData('add_response.txt')
        output = fakehttp(self.mngr.getConnection(), response)
        self.proc.index(foo)
        self.assert_(str(output).find(
            '<field name="price">42.0</field>') > 0, '"price" data not found')
        # then only a subset...
        response = getData('add_response.txt')
        output = fakehttp(self.mngr.getConnection(), response)
        self.proc.index(foo, attributes=['id', 'name'])
        output = str(output)
        self.assert_(
            output.find('<field name="name">foo</field>') > 0,
            '"name" data not found'
        )
        # at this point we'd normally check for a partial update:
        #   self.assertEqual(output.find('price'), -1, '"price" data found?')
        #   self.assertEqual(output.find('42'), -1, '"price" data found?')
        # however, until SOLR-139 has been implemented (re)index operations
        # always need to provide data for all attributes in the schema...
        self.assert_(
            output.find('<field name="price">42.0</field>') > 0,
            '"price" data not found'
        )

    def testDateIndexing(self):
        foo = Foo(id='zeidler', name='andi', cat='nerd',
                  timestamp=DateTime('May 11 1972 03:45 GMT'))
        response = getData('add_response.txt')
        # fake add response
        output = fakehttp(self.mngr.getConnection(), response)
        self.proc.index(foo)
        required = '<field name="timestamp">1972-05-11T03:45:00.000Z</field>'
        self.assert_(str(output).find(required) > 0, '"date" data not found')

    def testDateIndexingWithPythonDateTime(self):
        foo = Foo(id='gerken', name='patrick', cat='nerd',
                  timestamp=datetime(1980, 9, 29, 14, 02))
        response = getData('add_response.txt')
        # fake add response
        output = fakehttp(self.mngr.getConnection(), response)
        self.proc.index(foo)
        required = '<field name="timestamp">1980-09-29T14:02:00.000Z</field>'
        self.assert_(str(output).find(required) > 0, '"date" data not found')

    def testDateIndexingWithPythonDate(self):
        foo = Foo(id='brand', name='jan-carel',
                  cat='nerd', timestamp=date(1982, 8, 05))
        response = getData('add_response.txt')
        # fake add response
        output = fakehttp(self.mngr.getConnection(), response)
        self.proc.index(foo)
        required = '<field name="timestamp">1982-08-05T00:00:00.000Z</field>'
        self.assert_(str(output).find(required) > 0, '"date" data not found')

    def testReindexObject(self):
        response = getData('add_response.txt')
        # fake add response
        output = fakehttp(self.mngr.getConnection(), response)
        # reindexing sends data
        self.proc.reindex(Foo(id='500', name='python test doc'))
        self.assertEqual(sortFields(str(output)), getData('add_request.txt'))

    def testUnindexObject(self):
        response = getData('delete_response.txt')
        # fake response
        output = fakehttp(self.mngr.getConnection(), response)
        # unindexing sends data
        self.proc.unindex(Foo(id='500', name='python test doc'))
        self.assertEqual(str(output), getData('delete_request.txt'))

    def testCommit(self):
        response = getData('commit_response.txt')
        # fake response
        output = fakehttp(self.mngr.getConnection(), response)
        # committing sends data
        self.proc.commit()
        self.assertEqual(str(output), getData('commit_request.txt'))

    def testNoIndexingWithoutAllRequiredFields(self):
        response = getData('dummy_response.txt')
        # fake add response
        output = fakehttp(self.mngr.getConnection(), response)
        # indexing sends data
        self.proc.index(Foo(id='500'))
        self.assertEqual(str(output), '')

    def testIndexerMethods(self):
        class Bar(Foo):

            def cat(self):
                return 'nerd'

            def price(self):
                raise AttributeError('price')
        foo = Bar(id='500', name='foo')
        # raising the exception should keep the attribute from being indexed
        response = getData('add_response.txt')
        output = fakehttp(self.mngr.getConnection(), response)
        self.proc.index(foo)
        output = str(output)
        self.assertTrue(
            output.find('<field name="cat">nerd</field>') > 0,
            '"cat" data not found'
        )
        self.assertEqual(output.find('price'), -1, '"price" data found?')
Ejemplo n.º 21
0
class QueueIndexerTests(TestCase):

    layer = COLLECTIVE_SOLR_MOCK_REGISTRY_FIXTURE

    def setUp(self):
        self.mngr = SolrConnectionManager()
        self.mngr.setHost(active=True)
        conn = self.mngr.getConnection()
        fakehttp(conn, getData("schema.xml"))  # fake schema response
        self.mngr.getSchema()  # read and cache the schema
        self.proc = SolrIndexProcessor(self.mngr)
        config = getConfig()
        config.atomic_updates = True

    def tearDown(self):
        self.mngr.closeConnection()
        self.mngr.setHost(active=False)

    def testPrepareData(self):
        data = {"allowedRolesAndUsers": ["user:test_user_1_", "user:portal_owner"]}
        prepareData(data)
        self.assertEqual(
            data, {"allowedRolesAndUsers": ["user$test_user_1_", "user$portal_owner"]}
        )

    def testLanguageParameterHandling(self):
        # empty strings are replaced...
        data = {"Language": ["en", ""]}
        prepareData(data)
        self.assertEqual(data, {"Language": ["en", "any"]})
        data = {"Language": ""}
        prepareData(data)
        self.assertEqual(data, {"Language": "any"})
        # for other indices this shouldn't happen...
        data = {"Foo": ["en", ""]}
        prepareData(data)
        self.assertEqual(data, {"Foo": ["en", ""]})

    def testIndexObject(self):
        response = getData("add_response.txt")
        # fake add response
        output = fakehttp(self.mngr.getConnection(), response)
        # indexing sends data
        self.proc.index(Foo(id="500", name="python test doc"))
        self.assertEqual(
            sortFields(str(output).encode("utf-8")),
            getData("add_request.txt").rstrip(b"\n"),
        )

    def testIndexAccessorRaises(self):
        response = getData("add_response.txt")
        # fake add response
        output = fakehttp(self.mngr.getConnection(), response)

        def brokenfunc():
            raise ValueError

        self.proc.index(
            Foo(id="500", name="python test doc", text=brokenfunc)
        )  # indexing sends data
        self.assertEqual(
            sortFields(str(output).encode("utf-8")),
            getData("add_request.txt").rstrip(b"\n"),
        )

    def testPartialIndexObject(self):
        foo = Foo(id="500", name="foo", price=42.0)
        # first index all attributes...
        response = getData("add_response.txt")
        output = fakehttp(self.mngr.getConnection(), response)
        self.proc.index(foo)
        self.assert_(
            str(output).find('<field name="price" update="set">42.0</field>') > 0,
            '"price" data not found',
        )
        # then only a subset...
        response = getData("add_response.txt")
        output = fakehttp(self.mngr.getConnection(), response)
        self.proc.index(foo, attributes=["id", "name"])
        output = str(output)
        self.assert_(
            output.find('<field name="name" update="set">foo</field>') > 0,
            '"name" data not found',
        )
        # at this point we'd normally check for a partial update:
        self.assertEqual(output.find("price"), -1, '"price" data found?')
        self.assertEqual(output.find("42"), -1, '"price" data found?')

    def testDateIndexing(self):
        foo = Foo(
            id="zeidler",
            name="andi",
            cat="nerd",
            timestamp=DateTime("May 11 1972 03:45:59.999730 GMT"),
        )
        response = getData("add_response.txt")
        # fake add response
        output = fakehttp(self.mngr.getConnection(), response)
        self.proc.index(foo)
        required = (
            '<field name="timestamp" update="set">' "1972-05-11T03:45:59.999Z</field>"
        )
        self.assert_(str(output).find(required) > 0, '"date" data not found')

    def testDateIndexingWithPythonDateTime(self):
        foo = Foo(
            id="gerken",
            name="patrick",
            cat="nerd",
            timestamp=datetime(1980, 9, 29, 14, 0o2, 59, 999730),
        )
        response = getData("add_response.txt")
        # fake add response
        output = fakehttp(self.mngr.getConnection(), response)
        self.proc.index(foo)
        required = (
            '<field name="timestamp" update="set">' "1980-09-29T14:02:59.999Z</field>"
        )
        self.assert_(str(output).find(required) > 0, '"date" data not found')

    def testDateIndexingWithPythonDate(self):
        foo = Foo(
            id="brand", name="jan-carel", cat="nerd", timestamp=date(1982, 8, 0o5)
        )
        response = getData("add_response.txt")
        # fake add response
        output = fakehttp(self.mngr.getConnection(), response)
        self.proc.index(foo)
        required = (
            '<field name="timestamp" update="set">' "1982-08-05T00:00:00.000Z</field>"
        )
        self.assert_(str(output).find(required) > 0, '"date" data not found')

    def testReindexObject(self):
        response = getData("add_response.txt")
        # fake add response
        output = fakehttp(self.mngr.getConnection(), response)
        # reindexing sends data
        self.proc.reindex(Foo(id="500", name="python test doc"))
        self.assertEqual(
            sortFields(str(output).encode("utf-8")),
            getData("add_request.txt").rstrip(b"\n"),
        )

    def testUnindexObject(self):
        response = getData("delete_response.txt")
        # fake response
        output = fakehttp(self.mngr.getConnection(), response)
        # unindexing sends data
        self.proc.unindex(Foo(id="500", name="python test doc"))
        self.assertEqual(
            str(output), getData("delete_request.txt").decode("utf-8").rstrip("\n")
        )

    def testCommit(self):
        response = getData("commit_response.txt")
        # fake response
        output = fakehttp(self.mngr.getConnection(), response)
        # committing sends data
        self.proc.commit()
        self.assertEqual(
            str(output), getData("commit_request.txt").decode("utf-8").rstrip("\n")
        )

    def testNoIndexingWithoutAllRequiredFields(self):
        response = getData("dummy_response.txt")
        # fake add response
        output = fakehttp(self.mngr.getConnection(), response)
        # indexing sends data
        self.proc.index(Foo(id="500"))
        self.assertEqual(str(output), "")

    def testIndexerMethods(self):
        class Bar(Foo):
            def cat(self):
                return "nerd"

            def price(self):
                raise AttributeError("price")

        foo = Bar(id="500", name="foo")
        # raising the exception should keep the attribute from being indexed
        response = getData("add_response.txt")
        output = fakehttp(self.mngr.getConnection(), response)
        self.proc.index(foo)
        output = str(output)
        self.assertTrue(
            output.find('<field name="cat" update="set">nerd</field>') > 0,
            '"cat" data not found',
        )
        self.assertEqual(output.find("price"), -1, '"price" data found?')
Ejemplo n.º 22
0
 def setUp(self):
     self.mngr = SolrConnectionManager()
     self.mngr.setHost(active=True)
     self.conn = self.mngr.getConnection()
     self.search = Search()
     self.search.manager = self.mngr
Ejemplo n.º 23
0
class QueryTests(TestCase):

    layer = COLLECTIVE_SOLR_MOCK_REGISTRY_FIXTURE

    def setUp(self):
        self.mngr = SolrConnectionManager()
        self.mngr.setHost(active=True)
        conn = self.mngr.getConnection()
        fakehttp(conn, getData("schema.xml"))  # fake schema response
        self.mngr.getSchema()  # read and cache the schema
        self.search = Search()
        self.search.manager = self.mngr

    def tearDown(self):
        self.mngr.closeConnection()
        self.mngr.setHost(active=False)

    def bq(self, *args, **kw):
        query, ignore = self.search.buildQueryAndParameters(*args, **kw)
        return " ".join(sorted(query.values()))

    def testSimpleQueries(self):
        bq = self.bq
        self.assertEqual(bq("foo"), "+foo")
        self.assertEqual(bq("foo*"), "+foo*")
        self.assertEqual(bq("foo!"), "+foo\\!")
        self.assertEqual(bq("(foo)"), "+foo")
        self.assertEqual(bq("(foo..."), "+foo...")
        self.assertEqual(bq("foo bar"), "+(foo bar)")
        self.assertEqual(bq("*****@*****.**"), "*****@*****.**")
        self.assertEqual(bq(name="foo"), "+name:foo")
        self.assertEqual(bq(name="foo*"), "+name:foo*")
        self.assertEqual(bq(name="foo bar"), "+name:(foo bar)")
        self.assertEqual(bq(name="*****@*****.**"), "+name:[email protected]")
        self.assertEqual(bq(name=" "), "")  # Whitespace is removed
        self.assertEqual(bq(name=""), "")

    def testMultiValueQueries(self):
        bq = self.bq
        self.assertEqual(bq(("foo", "bar")), "+(foo OR bar)")
        self.assertEqual(bq(("foo", "bar*")), "+(foo OR bar*)")
        self.assertEqual(bq(("foo bar", "hmm")), '+("foo bar" OR hmm)')
        self.assertEqual(bq((u"foø bar", "hmm")), u'+("foø bar" OR hmm)')
        self.assertEqual(bq(('"foo bar"', "hmm")), '+("foo bar" OR hmm)')
        self.assertEqual(bq(name=["foo", "bar"]), "+name:(foo OR bar)")
        self.assertEqual(bq(name=["foo", "bar*"]), "+name:(foo OR bar*)")
        self.assertEqual(bq(name=["foo bar", "hmm"]),
                         '+name:("foo bar" OR hmm)')
        self.assertEqual(bq(price=[1.5, 2.5]), "+price:(1.5 OR 2.5)")
        self.assertEqual(bq(popularity=[1.5, 2.5]), "+popularity:(1.5 OR 2.5)")

    def testMultiArgumentQueries(self):
        bq = self.bq
        self.assertEqual(bq("foo", name="bar"), "+foo +name:bar")
        self.assertEqual(bq("foo", name=("bar", "hmm")),
                         "+foo +name:(bar OR hmm)")
        self.assertEqual(bq("foo", name=("foo bar", "hmm")),
                         '+foo +name:("foo bar" OR hmm)')
        self.assertEqual(bq(name="foo", cat="bar"), "+cat:bar +name:foo")
        self.assertEqual(bq(name="foo", cat=["bar", "hmm"]),
                         "+cat:(bar OR hmm) +name:foo")
        self.assertEqual(bq(name="foo", cat=["foo bar", "hmm"]),
                         '+cat:("foo bar" OR hmm) +name:foo')
        self.assertEqual(bq("foo", name=" "), "+foo")

        # empty value for a name should return no results like in ZCatalog, so
        # empty query is returned
        self.assertEqual(bq("foo", name=""), "")

    def testInvalidArguments(self):
        bq = self.bq
        self.assertEqual(bq(title="foo"), "")
        self.assertEqual(bq(title="foo", name="bar"), "+name:bar")
        self.assertEqual(bq("bar", title="foo"), "+bar")

    def testUnicodeArguments(self):
        bq = self.bq
        self.assertEqual(bq(u"foo"), u"+foo")
        self.assertEqual(bq(u"foø"), u"+foø")
        self.assertEqual(bq(u"*****@*****.**"), u"*****@*****.**")
        self.assertEqual(bq(name=[u"foo", u"bar"]), u"+name:(foo OR bar)")
        self.assertEqual(bq(name=[u"foo", u"bär"]), u"+name:(foo OR bär)")
        self.assertEqual(bq(name=u"foo", cat=(u"bar", u"hmm")),
                         u"+cat:(bar OR hmm) +name:foo")
        self.assertEqual(bq(name="foo", cat=(u"bär", u"hmm")),
                         u"+cat:(bär OR hmm) +name:foo")
        self.assertEqual(bq(name=u"*****@*****.**", cat=u"spammer"),
                         "+cat:spammer +name:[email protected]")

    def testQuotedQueries(self):
        bq = self.bq
        self.assertEqual(bq('"foo"'), '+"foo"')
        self.assertEqual(bq("foo"), "+foo")
        self.assertEqual(bq('"foo*"'), '+"foo\\*"')
        self.assertEqual(bq("foo*"), "+foo*")
        self.assertEqual(bq('"+foo"'), '+"\\+foo"')
        self.assertEqual(bq("+foo"), "+foo")
        self.assertEqual(bq('"foo bar"'), '+"foo bar"')
        self.assertEqual(bq("foo bar"), "+(foo bar)")
        self.assertEqual(bq('"foo bar?"'), '+"foo bar\\?"')
        self.assertEqual(bq("foo bar?"), "+(foo bar?)")
        self.assertEqual(bq("-foo +bar"), "+(-foo +bar)")
        self.assertEqual(bq('"-foo +bar"'), '+"\\-foo \\+bar"')
        self.assertEqual(bq("foo-bar"), '+"foo\\-bar"')
        self.assertEqual(bq('"foo-bar"'), '+"foo\\-bar"')
        self.assertEqual(bq(name='"foo"'), '+name:"foo"')
        self.assertEqual(bq(name='"foo bar'), '+name:(\\"foo bar)')
        self.assertEqual(bq(name='"foo bar*'), '+name:(\\"foo bar\\*)')
        self.assertEqual(bq(name="-foo", timestamp="[* TO NOW]"),
                         "+name:-foo +timestamp:[* TO NOW]")
        self.assertEqual(bq(name='"*****@*****.**"'), '+name:"*****@*****.**"')
        self.assertEqual(bq(name='" "'), '+name:" "')
        self.assertEqual(bq(name='""'), '+name:\\"\\"')

    def testComplexQueries(self):
        bq = self.bq
        self.assertEqual(
            bq(u"foo", name=u'"herb*"', cat=(u"bär", u'"-hmm"')),
            u'+cat:(bär OR "\\-hmm") +foo +name:"herb\\*"',
        )
        self.assertEqual(
            bq(u"foo", name=u"herb*", cat=(u"bär", u"-hmm")),
            u"+cat:(bär OR -hmm) +foo +name:herb*",
        )

    def testBooleanQueries(self):
        bq = self.bq
        self.assertEqual(bq(inStock=True), "+inStock:true")
        self.assertEqual(bq(inStock=False), "+inStock:false")

    def testBooleanCriteriaQuoting(self):
        bq = self.bq
        self.assertEqual(bq(inStock=[1, True, "1", "True"]), "+inStock:true")
        self.assertEqual(
            bq(inStock=[0, "", False, "0", "False", None, (), [], {}, MV]),
            "+inStock:false",
        )
        self.assertEqual(bq(inStock=True), "+inStock:true")
        self.assertEqual(bq(inStock=1), "+inStock:true")
        self.assertEqual(bq(inStock="0"), "+inStock:false")
        self.assertEqual(bq(inStock=[True, False]), "")
        self.assertEqual(bq(inStock=[1, MV]), "")

    def testLiterateQueries(self):
        bq = self.bq
        self.assertEqual(bq(name=set(["bar"])), "bar")
        self.assertEqual(bq(name=set(["foo OR bar"])), "foo OR bar")
        self.assertEqual(bq(name=set(["(foo OR bar)"])), "(foo OR bar)")
        self.assertEqual(
            bq(name=set(["(Title:foo^10 OR Description:foo)"])),
            "(Title:foo^10 OR Description:foo)",
        )
        self.assertTrue(
            bq(name=set(["foo", "bar"])) in ["(foo OR bar)", "(bar OR foo)"])
        self.assertTrue(
            bq(name=set(["foo!", "+bar:camp"])) in
            ["(foo! OR +bar:camp)", "(+bar:camp OR foo!)"])

    def testNotQueries(self):
        bq = self.bq
        self.assertEqual(bq(name={"not": "foo"}), "-name:foo")
        self.assertEqual(bq(name={
            "query": "bar",
            "not": "foo"
        }), "+name:bar -name:foo")
        self.assertEqual(bq(cat={"not": ["foo", "bar"]}), "-cat:(foo OR bar)")
        self.assertEqual(
            bq(cat={
                "query": ["FOO", "BAR"],
                "not": ["foo", "bar"]
            }),
            "+cat:(FOO OR BAR) -cat:(foo OR bar)",
        )

    def testIntegerFloatQueries(self):
        bq = self.bq
        self.assertEqual(bq(price=1.5), "+price:1.5")
        self.assertEqual(bq(price={"query": 1.5}), "+price:1.5")
        self.assertEqual(bq(price={
            "query": (1.5, 2.5),
            "range": "min:max"
        }), "+price:[1.5 TO 2.5]")
        self.assertEqual(bq(popularity=2), "+popularity:2")
        self.assertEqual(bq(popularity={"query": 2}), "+popularity:2")
        self.assertEqual(bq(popularity={
            "query": (2, 5),
            "range": "min:max"
        }), "+popularity:[2 TO 5]")
Ejemplo n.º 24
0
class QueueIndexerTests(TestCase):

    def setUp(self):
        provideUtility(SolrConnectionConfig(), ISolrConnectionConfig)
        self.mngr = SolrConnectionManager()
        self.mngr.setHost(active=True)
        conn = self.mngr.getConnection()
        fakehttp(conn, getData('schema.xml'))       # fake schema response
        self.mngr.getSchema()                       # read and cache the schema
        self.proc = SolrIndexProcessor(self.mngr)

    def tearDown(self):
        self.mngr.closeConnection()
        self.mngr.setHost(active=False)

    def testPrepareData(self):
        data = {'allowedRolesAndUsers': ['user:test_user_1_', 'user:portal_owner']}
        prepareData(data)
        self.assertEqual(data, {'allowedRolesAndUsers': ['user$test_user_1_', 'user$portal_owner']})

    def testLanguageParameterHandling(self):
        # empty strings are replaced...
        data = {'Language': ['en', '']}
        prepareData(data)
        self.assertEqual(data, {'Language': ['en', 'any']})
        data = {'Language': ''}
        prepareData(data)
        self.assertEqual(data, {'Language': 'any'})
        # for other indices this shouldn't happen...
        data = {'Foo': ['en', '']}
        prepareData(data)
        self.assertEqual(data, {'Foo': ['en', '']})

    def testIndexObject(self):
        response = getData('add_response.txt')
        output = fakehttp(self.mngr.getConnection(), response)   # fake add response
        self.proc.index(Foo(id='500', name='python test doc'))   # indexing sends data
        self.assertEqual(sortFields(str(output)), getData('add_request.txt'))

    def testIndexAccessorRaises(self):
        response = getData('add_response.txt')
        output = fakehttp(self.mngr.getConnection(), response)   # fake add response
        def brokenfunc():
            raise ValueError
        self.proc.index(Foo(id='500', name='python test doc',
                            text=brokenfunc))   # indexing sends data
        self.assertEqual(sortFields(str(output)), getData('add_request.txt'))

    def testPartialIndexObject(self):
        foo = Foo(id='500', name='foo', price=42.0)
        # first index all attributes...
        response = getData('add_response.txt')
        output = fakehttp(self.mngr.getConnection(), response)
        self.proc.index(foo)
        self.assert_(str(output).find('<field name="price">42.0</field>') > 0, '"price" data not found')
        # then only a subset...
        response = getData('add_response.txt')
        output = fakehttp(self.mngr.getConnection(), response)
        self.proc.index(foo, attributes=['id', 'name'])
        output = str(output)
        self.assert_(output.find('<field name="name">foo</field>') > 0, '"name" data not found')
        # at this point we'd normally check for a partial update:
        #   self.assertEqual(output.find('price'), -1, '"price" data found?')
        #   self.assertEqual(output.find('42'), -1, '"price" data found?')
        # however, until SOLR-139 has been implemented (re)index operations
        # always need to provide data for all attributes in the schema...
        self.assert_(output.find('<field name="price">42.0</field>') > 0, '"price" data not found')

    def testDateIndexing(self):
        foo = Foo(id='zeidler', name='andi', cat='nerd', timestamp=DateTime('May 11 1972 03:45 GMT'))
        response = getData('add_response.txt')
        output = fakehttp(self.mngr.getConnection(), response)   # fake add response
        self.proc.index(foo)
        required = '<field name="timestamp">1972-05-11T03:45:00.000Z</field>'
        self.assert_(str(output).find(required) > 0, '"date" data not found')

    def testDateIndexingWithPythonDateTime(self):
        foo = Foo(id='gerken', name='patrick', cat='nerd', timestamp=datetime(1980, 9, 29, 14, 02))
        response = getData('add_response.txt')
        output = fakehttp(self.mngr.getConnection(), response)   # fake add response
        self.proc.index(foo)
        required = '<field name="timestamp">1980-09-29T14:02:00.000Z</field>'
        self.assert_(str(output).find(required) > 0, '"date" data not found')

    def testReindexObject(self):
        response = getData('add_response.txt')
        output = fakehttp(self.mngr.getConnection(), response)   # fake add response
        self.proc.reindex(Foo(id='500', name='python test doc')) # reindexing sends data
        self.assertEqual(sortFields(str(output)), getData('add_request.txt'))

    def testUnindexObject(self):
        response = getData('delete_response.txt')
        output = fakehttp(self.mngr.getConnection(), response)   # fake response
        self.proc.unindex(Foo(id='500', name='python test doc')) # unindexing sends data
        self.assertEqual(str(output), getData('delete_request.txt'))

    def testCommit(self):
        response = getData('commit_response.txt')
        output = fakehttp(self.mngr.getConnection(), response)   # fake response
        self.proc.commit()                                       # committing sends data
        self.assertEqual(str(output), getData('commit_request.txt'))

    def testNoIndexingWithoutAllRequiredFields(self):
        response = getData('dummy_response.txt')
        output = fakehttp(self.mngr.getConnection(), response)   # fake add response
        self.proc.index(Foo(id='500'))                           # indexing sends data
        self.assertEqual(str(output), '')

    def testIndexerMethods(self):
        class Bar(Foo):
            def cat(self):
                return 'nerd'
            def price(self):
                raise AttributeError('price')
        foo = Bar(id='500', name='foo')
        # raising the exception should keep the attribute from being indexed
        response = getData('add_response.txt')
        output = fakehttp(self.mngr.getConnection(), response)
        self.proc.index(foo)
        output = str(output)
        self.assertTrue(output.find('<field name="cat">nerd</field>') > 0, '"cat" data not found')
        self.assertEqual(output.find('price'), -1, '"price" data found?')
Ejemplo n.º 25
0
 def testLocalConnections(self):
     provideUtility(SolrConnectionConfig(), ISolrConnectionConfig)
     mngr = SolrConnectionManager(active=True)
     proc = SolrIndexProcessor(mngr)
     mngr.setHost(active=True)
     schema = getData('schema.xml')
     log = []
     def runner():
         fakehttp(mngr.getConnection(), schema)      # fake schema response
         mngr.getSchema()                            # read and cache the schema
         response = getData('add_response.txt')
         output = fakehttp(mngr.getConnection(), response)   # fake add response
         proc.index(Foo(id='500', name='python test doc'))   # indexing sends data
         mngr.closeConnection()
         log.append(str(output))
         log.append(proc)
         log.append(mngr.getConnection())
     # after the runner was set up, another thread can be created and
     # started;  its output should contain the proper indexing request,
     # whereas the main thread's connection remain idle;  the latter
     # cannot be checked directly, but the connection object would raise
     # an exception if it was used to send a request without setting up
     # a fake response beforehand...
     thread = Thread(target=runner)
     thread.start()
     thread.join()
     conn = mngr.getConnection()         # get this thread's connection
     fakehttp(conn, schema)              # fake schema response
     mngr.getSchema()                    # read and cache the schema
     mngr.closeConnection()
     mngr.setHost(active=False)
     self.assertEqual(len(log), 3)
     self.assertEqual(sortFields(log[0]), getData('add_request.txt'))
     self.failUnless(isinstance(log[1], SolrIndexProcessor))
     self.failUnless(isinstance(log[2], SolrConnection))
     self.failUnless(isinstance(proc, SolrIndexProcessor))
     self.failUnless(isinstance(conn, SolrConnection))
     self.assertEqual(log[1], proc)      # processors should be the same...
     self.assertNotEqual(log[2], conn)   # but not the connections
Ejemplo n.º 26
0
 def testSingleRequest(self):
     mngr = SolrConnectionManager(active=True)
     output = fakehttp(mngr.getConnection(), getData('schema.xml'))
     mngr.getSchema()
     mngr.closeConnection()
     self.failUnless(output.get().startswith(self.schema_request))
Ejemplo n.º 27
0
 def testUnavailableSchema(self):
     search = Search()
     search.manager = SolrConnectionManager()
     self.assertEqual(search.buildQueryAndParameters("foo"), ({}, {}))
     self.assertEqual(search.buildQueryAndParameters(name="foo"), ({}, {}))
Ejemplo n.º 28
0
class RobustnessTests(TestCase):

    def setUp(self):
        provideUtility(SolrConnectionConfig(), ISolrConnectionConfig)
        self.mngr = SolrConnectionManager()
        self.mngr.setHost(active=True)
        self.conn = self.mngr.getConnection()
        self.proc = SolrIndexProcessor(self.mngr)
        self.log = []                   # catch log messages...
        def logger(*args):
            self.log.extend(args)
        logger_indexer.warning = logger

    def tearDown(self):
        self.mngr.closeConnection()
        self.mngr.setHost(active=False)

    def testIndexingWithUniqueKeyMissing(self):
        fakehttp(self.conn, getData('simple_schema.xml'))   # fake schema response
        self.mngr.getSchema()                               # read and cache the schema
        response = getData('add_response.txt')
        output = fakehttp(self.conn, response)              # fake add response
        foo = Foo(id='500', name='foo')
        self.proc.index(foo)                                # indexing sends data
        self.assertEqual(len(output), 0)                    # nothing happened...
        self.assertEqual(self.log, [
            'schema is missing unique key, skipping indexing of %r', foo])

    def testUnindexingWithUniqueKeyMissing(self):
        fakehttp(self.conn, getData('simple_schema.xml'))   # fake schema response
        self.mngr.getSchema()                               # read and cache the schema
        response = getData('delete_response.txt')
        output = fakehttp(self.conn, response)              # fake delete response
        foo = Foo(id='500', name='foo')
        self.proc.unindex(foo)                              # unindexing sends data
        self.assertEqual(len(output), 0)                    # nothing happened...
        self.assertEqual(self.log, [
            'schema is missing unique key, skipping unindexing of %r', foo])
Ejemplo n.º 29
0
class QueryTests(TestCase):

    def setUp(self):
        provideUtility(SolrConnectionConfig(), ISolrConnectionConfig)
        self.mngr = SolrConnectionManager()
        self.mngr.setHost(active=True)
        conn = self.mngr.getConnection()
        fakehttp(conn, getData('schema.xml'))   # fake schema response
        self.mngr.getSchema()                   # read and cache the schema
        self.search = Search()
        self.search.manager = self.mngr

    def tearDown(self):
        self.mngr.closeConnection()
        self.mngr.setHost(active=False)

    def bq(self, *args, **kw):
        query = self.search.buildQuery(*args, **kw)
        return ' '.join(sorted(query.values()))

    def testSimpleQueries(self):
        bq = self.bq
        self.assertEqual(bq('foo'), '+foo')
        self.assertEqual(bq('foo*'), '+foo*')
        self.assertEqual(bq('foo!'), '+foo\\!')
        self.assertEqual(bq('(foo)'), '+foo')
        self.assertEqual(bq('(foo...'), '+foo...')
        self.assertEqual(bq('foo bar'), '+(foo bar)')
        self.assertEqual(bq('*****@*****.**'), '*****@*****.**')
        self.assertEqual(bq(name='foo'), '+name:foo')
        self.assertEqual(bq(name='foo*'), '+name:foo*')
        self.assertEqual(bq(name='foo bar'), '+name:(foo bar)')
        self.assertEqual(bq(name='*****@*****.**'), '+name:[email protected]')
        self.assertEqual(bq(name=' '), '') # Whitespace is removed
        self.assertEqual(bq(name=''), '')

    def testMultiValueQueries(self):
        bq = self.bq
        self.assertEqual(bq(('foo', 'bar')), '+(foo OR bar)')
        self.assertEqual(bq(('foo', 'bar*')), '+(foo OR bar*)')
        self.assertEqual(bq(('foo bar', 'hmm')), '+("foo bar" OR hmm)')
        self.assertEqual(bq(('foø bar', 'hmm')), '+("fo\xc3\xb8 bar" OR hmm)')
        self.assertEqual(bq(('"foo bar"', 'hmm')), '+("foo bar" OR hmm)')
        self.assertEqual(bq(name=['foo', 'bar']), '+name:(foo OR bar)')
        self.assertEqual(bq(name=['foo', 'bar*']), '+name:(foo OR bar*)')
        self.assertEqual(bq(name=['foo bar', 'hmm']), '+name:("foo bar" OR hmm)')

    def testMultiArgumentQueries(self):
        bq = self.bq
        self.assertEqual(bq('foo', name='bar'), '+foo +name:bar')
        self.assertEqual(bq('foo', name=('bar', 'hmm')),
            '+foo +name:(bar OR hmm)')
        self.assertEqual(bq('foo', name=('foo bar', 'hmm')),
            '+foo +name:("foo bar" OR hmm)')
        self.assertEqual(bq(name='foo', cat='bar'), '+cat:bar +name:foo')
        self.assertEqual(bq(name='foo', cat=['bar', 'hmm']),
            '+cat:(bar OR hmm) +name:foo')
        self.assertEqual(bq(name='foo', cat=['foo bar', 'hmm']),
            '+cat:("foo bar" OR hmm) +name:foo')
        self.assertEqual(bq('foo', name=' '), '+foo')

        # empty value for a name should return no results like in ZCatalog, so
        # empty query is returned
        self.assertEqual(bq('foo', name=''), '')

    def testInvalidArguments(self):
        bq = self.bq
        self.assertEqual(bq(title='foo'), '')
        self.assertEqual(bq(title='foo', name='bar'), '+name:bar')
        self.assertEqual(bq('bar', title='foo'), '+bar')

    def testUnicodeArguments(self):
        bq = self.bq
        self.assertEqual(bq(u'foo'), '+foo')
        self.assertEqual(bq(u'foø'), '+fo\xc3\xb8')
        self.assertEqual(bq(u'*****@*****.**'), '*****@*****.**')
        self.assertEqual(bq(name=['foo', u'bar']), '+name:(foo OR bar)')
        self.assertEqual(bq(name=['foo', u'bär']), '+name:(foo OR b\xc3\xa4r)')
        self.assertEqual(bq(name='foo', cat=(u'bar', 'hmm')), '+cat:(bar OR hmm) +name:foo')
        self.assertEqual(bq(name='foo', cat=(u'bär', 'hmm')), '+cat:(b\xc3\xa4r OR hmm) +name:foo')
        self.assertEqual(bq(name=u'*****@*****.**', cat='spammer'), '+cat:spammer +name:[email protected]')

    def testQuotedQueries(self):
        bq = self.bq
        self.assertEqual(bq('"foo"'), '+"foo"')
        self.assertEqual(bq('foo'), '+foo')
        self.assertEqual(bq('"foo*"'), '+"foo\*"')
        self.assertEqual(bq('foo*'), '+foo*')
        self.assertEqual(bq('"+foo"'), '+"\+foo"')
        self.assertEqual(bq('+foo'), '+foo')
        self.assertEqual(bq('"foo bar"'), '+"foo bar"')
        self.assertEqual(bq('foo bar'), '+(foo bar)')
        self.assertEqual(bq('"foo bar?"'), '+"foo bar\?"')
        self.assertEqual(bq('foo bar?'), '+(foo bar?)')
        self.assertEqual(bq('-foo +bar'), '+(-foo +bar)')
        self.assertEqual(bq('"-foo +bar"'), '+"\-foo \+bar"')
        self.assertEqual(bq('foo-bar'), '+"foo\\-bar"')
        self.assertEqual(bq('"foo-bar"'), '+"foo\-bar"')
        self.assertEqual(bq(name='"foo"'), '+name:"foo"')
        self.assertEqual(bq(name='"foo bar'), '+name:(\\"foo bar)')
        self.assertEqual(bq(name='"foo bar*'), '+name:(\\"foo bar\\*)')
        self.assertEqual(bq(name='-foo', timestamp='[* TO NOW]'),
            '+name:-foo +timestamp:[* TO NOW]')
        self.assertEqual(bq(name='"*****@*****.**"'), '+name:"*****@*****.**"')
        self.assertEqual(bq(name='" "'), '+name:" "')
        self.assertEqual(bq(name='""'), '+name:\\"\\"')

    def testComplexQueries(self):
        bq = self.bq
        self.assertEqual(bq('foo', name='"herb*"', cat=(u'bär', '"-hmm"')),
            '+cat:(b\xc3\xa4r OR "\-hmm") +foo +name:"herb\*"')
        self.assertEqual(bq('foo', name='herb*', cat=(u'bär', '-hmm')),
            '+cat:(b\xc3\xa4r OR -hmm) +foo +name:herb*')

    def testBooleanQueries(self):
        bq = self.bq
        self.assertEqual(bq(inStock=True), '+inStock:true')
        self.assertEqual(bq(inStock=False), '+inStock:false')

    def testBooleanCriteriaQuoting(self):
        bq = self.bq
        self.assertEqual(
            bq(inStock=[1, True, '1', 'True']),
            '+inStock:true')
        self.assertEqual(
            bq(inStock=[0, '', False, '0', 'False', None, (), [], {}, MV]),
            '+inStock:false')
        self.assertEqual(bq(inStock=True), '+inStock:true')
        self.assertEqual(bq(inStock=1), '+inStock:true')
        self.assertEqual(bq(inStock='0'), '+inStock:false')
        self.assertEqual(bq(inStock=[True, False]), '')
        self.assertEqual(bq(inStock=[1, MV]), '')

    def testLiterateQueries(self):
        bq = self.bq
        self.assertEqual(bq(name=set(['bar'])), 'bar')
        self.assertEqual(bq(name=set(['foo OR bar'])), 'foo OR bar')
        self.assertEqual(bq(name=set(['(foo OR bar)'])), '(foo OR bar)')
        self.assertEqual(bq(name=set(['(Title:foo^10 OR Description:foo)'])),
            '(Title:foo^10 OR Description:foo)')
        self.failUnless(bq(name=set(['foo', 'bar'])) in
            ['(foo OR bar)', '(bar OR foo)'])
        self.failUnless(bq(name=set(['foo!', '+bar:camp'])) in
            ['(foo! OR +bar:camp)', '(+bar:camp OR foo!)'])
Ejemplo n.º 30
0
 def testUnavailableSchema(self):
     provideUtility(SolrConnectionConfig(), ISolrConnectionConfig)
     search = Search()
     search.manager = SolrConnectionManager()
     self.assertEqual(search.buildQuery('foo'), {})
     self.assertEqual(search.buildQuery(name='foo'), {})
Ejemplo n.º 31
0
class RobustnessTests(TestCase):

    def setUp(self):
        provideUtility(SolrConnectionConfig(), ISolrConnectionConfig)
        self.mngr = SolrConnectionManager()
        self.mngr.setHost(active=True)
        self.conn = self.mngr.getConnection()
        self.proc = SolrIndexProcessor(self.mngr)
        self.log = []                   # catch log messages...

        def logger(*args):
            self.log.extend(args)
        logger_indexer.warning = logger

    def tearDown(self):
        self.mngr.closeConnection()
        self.mngr.setHost(active=False)

    def testIndexingWithUniqueKeyMissing(self):
        # fake schema response
        fakehttp(self.conn, getData('simple_schema.xml'))
        # read and cache the schema
        self.mngr.getSchema()
        response = getData('add_response.txt')
        output = fakehttp(self.conn, response)              # fake add response
        foo = Foo(id='500', name='foo')
        # indexing sends data
        self.proc.index(foo)
        # nothing happened...
        self.assertEqual(len(output), 0)
        self.assertEqual(self.log, [
            'schema is missing unique key, skipping indexing of %r', foo])

    def testUnindexingWithUniqueKeyMissing(self):
        # fake schema response
        fakehttp(self.conn, getData('simple_schema.xml'))
        # read and cache the schema
        self.mngr.getSchema()
        response = getData('delete_response.txt')
        # fake delete response
        output = fakehttp(self.conn, response)
        foo = Foo(id='500', name='foo')
        # unindexing sends data
        self.proc.unindex(foo)
        # nothing happened...
        self.assertEqual(len(output), 0)
        self.assertEqual(self.log, [
            'schema is missing unique key, skipping unindexing of %r', foo])
Ejemplo n.º 32
0
 def testSingleRequest(self):
     mngr = SolrConnectionManager(active=True)
     output = fakehttp(mngr.getConnection(), getData('schema.xml'))
     mngr.getSchema()
     mngr.closeConnection()
     self.failUnless(output.get().startswith(self.schema_request))
Ejemplo n.º 33
0
 def setUp(self):
     self.mngr = SolrConnectionManager()
     self.mngr.setHost(active=True)
     self.conn = self.mngr.getConnection()
     self.search = Search()
     self.search.manager = self.mngr