# -*- coding: utf-8 -*- # Copyright 2015 OpenMarket Ltd # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. from tests import unittest from twisted.internet import defer from synapse.appservice import ApplicationService, ApplicationServiceState from synapse.server import HomeServer from synapse.storage.appservice import ( ApplicationServiceStore, ApplicationServiceTransactionStore ) from mock import Mock from tests.utils import SQLiteMemoryDbPool, MockClock class ApplicationServiceStoreTestCase(unittest.TestCase): @defer.inlineCallbacks def setUp(self): db_pool = SQLiteMemoryDbPool() yield db_pool.prepare() hs = HomeServer( "test", db_pool=db_pool, clock=MockClock(), config=Mock() ) self.as_token = "token1" db_pool.runQuery( "INSERT INTO application_services(token) VALUES(?)", (self.as_token,) ) db_pool.runQuery( "INSERT INTO application_services(token) VALUES(?)", ("token2",) ) db_pool.runQuery( "INSERT INTO application_services(token) VALUES(?)", ("token3",) ) # must be done after inserts self.store = ApplicationServiceStore(hs) @defer.inlineCallbacks def test_update_and_retrieval_of_service(self): url = "https://matrix.org/appservices/foobar" hs_token = "hstok" user_regex = [ {"regex": "@foobar_.*:matrix.org", "exclusive": True} ] alias_regex = [ {"regex": "#foobar_.*:matrix.org", "exclusive": False} ] room_regex = [ ] service = ApplicationService( url=url, hs_token=hs_token, token=self.as_token, namespaces={ ApplicationService.NS_USERS: user_regex, ApplicationService.NS_ALIASES: alias_regex, ApplicationService.NS_ROOMS: room_regex }) yield self.store.update_app_service(service) stored_service = yield self.store.get_app_service_by_token( self.as_token ) self.assertEquals(stored_service.token, self.as_token) self.assertEquals(stored_service.url, url) self.assertEquals( stored_service.namespaces[ApplicationService.NS_ALIASES], alias_regex ) self.assertEquals( stored_service.namespaces[ApplicationService.NS_ROOMS], room_regex ) self.assertEquals( stored_service.namespaces[ApplicationService.NS_USERS], user_regex ) @defer.inlineCallbacks def test_retrieve_unknown_service_token(self): service = yield self.store.get_app_service_by_token("invalid_token") self.assertEquals(service, None) @defer.inlineCallbacks def test_retrieval_of_service(self): stored_service = yield self.store.get_app_service_by_token( self.as_token ) self.assertEquals(stored_service.token, self.as_token) self.assertEquals(stored_service.url, None) self.assertEquals( stored_service.namespaces[ApplicationService.NS_ALIASES], [] ) self.assertEquals( stored_service.namespaces[ApplicationService.NS_ROOMS], [] ) self.assertEquals( stored_service.namespaces[ApplicationService.NS_USERS], [] ) @defer.inlineCallbacks def test_retrieval_of_all_services(self): services = yield self.store.get_app_services() self.assertEquals(len(services), 3) class ApplicationServiceTransactionStoreTestCase(unittest.TestCase): @defer.inlineCallbacks def setUp(self): self.db_pool = SQLiteMemoryDbPool() yield self.db_pool.prepare() hs = HomeServer( "test", db_pool=self.db_pool, clock=MockClock(), config=Mock() ) self.as_list = [ { "token": "token1", "url": "https://matrix-as.org", "id": 3 }, { "token": "alpha_tok", "url": "https://alpha.com", "id": 5 }, { "token": "beta_tok", "url": "https://beta.com", "id": 6 }, { "token": "delta_tok", "url": "https://delta.com", "id": 7 }, ] for s in self.as_list: yield self._add_service(s["id"], s["url"], s["token"]) self.store = TestTransactionStore(hs) def _add_service(self, as_id, url, token): return self.db_pool.runQuery( "INSERT INTO application_services(id, url, token) VALUES(?,?,?)", (as_id, url, token) ) def _set_state(self, id, state, txn=None): return self.db_pool.runQuery( "INSERT INTO application_services_state(as_id, state, last_txn) " "VALUES(?,?,?)", (id, state, txn) ) @defer.inlineCallbacks def test_get_appservice_state_none(self): service = Mock(id=999) state = yield self.store.get_appservice_state(service) self.assertEquals(None, state) @defer.inlineCallbacks def test_get_appservice_state_up(self): yield self._set_state( self.as_list[0]["id"], ApplicationServiceState.UP ) service = Mock(id=self.as_list[0]["id"]) state = yield self.store.get_appservice_state(service) self.assertEquals(ApplicationServiceState.UP, state) @defer.inlineCallbacks def test_get_appservice_state_down(self): yield self._set_state( self.as_list[0]["id"], ApplicationServiceState.UP ) yield self._set_state( self.as_list[1]["id"], ApplicationServiceState.DOWN ) yield self._set_state( self.as_list[2]["id"], ApplicationServiceState.DOWN ) service = Mock(id=self.as_list[1]["id"]) state = yield self.store.get_appservice_state(service) self.assertEquals(ApplicationServiceState.DOWN, state) @defer.inlineCallbacks def test_get_appservices_by_state_none(self): services = yield self.store.get_appservices_by_state( ApplicationServiceState.DOWN ) self.assertEquals(0, len(services)) @defer.inlineCallbacks def test_set_appservices_state_down(self): service = Mock(id=self.as_list[1]["id"]) yield self.store.set_appservice_state( service, ApplicationServiceState.DOWN ) rows = yield self.db_pool.runQuery( "SELECT as_id FROM application_services_state WHERE state=?", (ApplicationServiceState.DOWN,) ) self.assertEquals(service.id, rows[0][0]) @defer.inlineCallbacks def test_set_appservices_state_multiple_up(self): service = Mock(id=self.as_list[1]["id"]) yield self.store.set_appservice_state( service, ApplicationServiceState.UP ) yield self.store.set_appservice_state( service, ApplicationServiceState.DOWN ) yield self.store.set_appservice_state( service, ApplicationServiceState.UP ) rows = yield self.db_pool.runQuery( "SELECT as_id FROM application_services_state WHERE state=?", (ApplicationServiceState.UP,) ) self.assertEquals(service.id, rows[0][0]) @defer.inlineCallbacks def test_get_appservices_by_state_single(self): yield self._set_state( self.as_list[0]["id"], ApplicationServiceState.DOWN ) yield self._set_state( self.as_list[1]["id"], ApplicationServiceState.UP ) services = yield self.store.get_appservices_by_state( ApplicationServiceState.DOWN ) self.assertEquals(1, len(services)) self.assertEquals(self.as_list[0]["id"], services[0].id) @defer.inlineCallbacks def test_get_appservices_by_state_multiple(self): yield self._set_state( self.as_list[0]["id"], ApplicationServiceState.DOWN ) yield self._set_state( self.as_list[1]["id"], ApplicationServiceState.UP ) yield self._set_state( self.as_list[2]["id"], ApplicationServiceState.DOWN ) yield self._set_state( self.as_list[3]["id"], ApplicationServiceState.UP ) services = yield self.store.get_appservices_by_state( ApplicationServiceState.DOWN ) self.assertEquals(2, len(services)) self.assertEquals(self.as_list[2]["id"], services[0].id) self.assertEquals(self.as_list[0]["id"], services[1].id) # required for ApplicationServiceTransactionStoreTestCase tests class TestTransactionStore(ApplicationServiceTransactionStore, ApplicationServiceStore): def __init__(self, hs): super(TestTransactionStore, self).__init__(hs)