Example #1
0
    def test_iterable_eviction(self):
        clock = MockClock()
        cache = ExpiringCache("test", clock, max_len=5, iterable=True)

        cache["key"] = [1]
        cache["key2"] = [2, 3]
        cache["key3"] = [4, 5]

        self.assertEquals(cache.get("key"), [1])
        self.assertEquals(cache.get("key2"), [2, 3])
        self.assertEquals(cache.get("key3"), [4, 5])

        cache["key4"] = [6, 7]
        self.assertEquals(cache.get("key"), None)
        self.assertEquals(cache.get("key2"), None)
        self.assertEquals(cache.get("key3"), [4, 5])
        self.assertEquals(cache.get("key4"), [6, 7])
Example #2
0
    def setUp(self):
        self.mock_http_client = Mock(spec=[])
        self.mock_http_client.put_json = DeferredMockCallable()

        self.mock_federation_resource = MockHttpResource()

        db_pool = SQLiteMemoryDbPool()
        yield db_pool.prepare()

        self.mock_config = NonCallableMock()
        self.mock_config.signing_key = [MockKey()]

        hs = HomeServer(
            "test",
            clock=MockClock(),
            db_pool=db_pool,
            handlers=None,
            resource_for_client=Mock(),
            resource_for_federation=self.mock_federation_resource,
            http_client=self.mock_http_client,
            config=self.mock_config,
            keyring=Mock(),
        )
        hs.handlers = JustPresenceHandlers(hs)

        self.store = hs.get_datastore()

        # Some local users to test with
        self.u_apple = hs.parse_userid("@apple:test")
        self.u_banana = hs.parse_userid("@banana:test")
        yield self.store.create_presence(self.u_apple.localpart)
        yield self.store.create_presence(self.u_banana.localpart)

        # ID of a local user that does not exist
        self.u_durian = hs.parse_userid("@durian:test")

        # A remote user
        self.u_cabbage = hs.parse_userid("@cabbage:elsewhere")

        self.handler = hs.get_handlers().presence_handler

        self.mock_start = Mock()
        self.mock_stop = Mock()

        self.handler.start_polling_presence = self.mock_start
        self.handler.stop_polling_presence = self.mock_stop
Example #3
0
    def test_time_eviction(self):
        clock = MockClock()
        cache = ExpiringCache("test", clock, expiry_ms=1000)

        cache["key"] = 1
        clock.advance_time(0.5)
        cache["key2"] = 2

        self.assertEqual(cache.get("key"), 1)
        self.assertEqual(cache.get("key2"), 2)

        clock.advance_time(0.9)
        self.assertEqual(cache.get("key"), None)
        self.assertEqual(cache.get("key2"), 2)

        clock.advance_time(1)
        self.assertEqual(cache.get("key"), None)
        self.assertEqual(cache.get("key2"), None)
Example #4
0
    def test_from_cache(self):
        clock = MockClock()

        dns_client_mock = Mock(spec_set=["lookupService"])
        dns_client_mock.lookupService = Mock(spec_set=[])

        service_name = b"test_service.example.com"

        entry = Mock(spec_set=["expires"])
        entry.expires = 999999999

        cache = {service_name: [entry]}
        resolver = SrvResolver(dns_client=dns_client_mock,
                               cache=cache,
                               get_time=clock.time)

        servers = yield resolver.resolve_service(service_name)

        self.assertFalse(dns_client_mock.lookupService.called)

        self.assertEquals(len(servers), 1)
        self.assertEquals(servers, cache[service_name])
Example #5
0
    def test_from_cache(self):
        clock = MockClock()

        dns_client_mock = Mock(spec_set=['lookupService'])
        dns_client_mock.lookupService = Mock(spec_set=[])

        service_name = "test_service.examle.com"

        entry = Mock(spec_set=["expires"])
        entry.expires = 999999999

        cache = {
            service_name: [entry]
        }

        servers = yield resolve_service(
            service_name, dns_client=dns_client_mock, cache=cache, clock=clock,
        )

        self.assertFalse(dns_client_mock.lookupService.called)

        self.assertEquals(len(servers), 1)
        self.assertEquals(servers, cache[service_name])
Example #6
0
    def test_from_cache(self):
        clock = MockClock()

        dns_client_mock = Mock(spec_set=["lookupService"])
        dns_client_mock.lookupService = Mock(spec_set=[])

        service_name = b"test_service.example.com"

        entry = Mock(spec_set=["expires", "priority", "weight"])
        entry.expires = 999999999
        entry.priority = 0
        entry.weight = 0

        cache = {service_name: [entry]}
        resolver = SrvResolver(
            dns_client=dns_client_mock, cache=cache, get_time=clock.time
        )

        servers = yield defer.ensureDeferred(resolver.resolve_service(service_name))

        self.assertFalse(dns_client_mock.lookupService.called)

        self.assertEqual(len(servers), 1)
        self.assertEqual(servers, cache[service_name])
Example #7
0
 def setUp(self):
     self.clock = MockClock()
Example #8
0
    def setUp(self):
        self.clock = MockClock()
        self.cache = HttpTransactionCache(self.clock)

        self.mock_http_response = (200, "GOOD JOB!")
        self.mock_key = "foo"
Example #9
0
 def make_homeserver(self, reactor: MemoryReactor, clock: Clock) -> HomeServer:
     # We need to be able to test advancing time in the homeserver, so we
     # replace the test homeserver's default clock with a MockClock, which
     # supports advancing time.
     return self.setup_test_homeserver(clock=MockClock())
Example #10
0
def setup_test_homeserver(
    cleanup_func,
    name="test",
    config=None,
    reactor=None,
    homeserver_to_use: Type[HomeServer] = TestHomeServer,
    **kwargs,
):
    """
    Setup a homeserver suitable for running tests against.  Keyword arguments
    are passed to the Homeserver constructor.

    If no datastore is supplied, one is created and given to the homeserver.

    Args:
        cleanup_func : The function used to register a cleanup routine for
                       after the test.

    Calling this method directly is deprecated: you should instead derive from
    HomeserverTestCase.
    """
    if reactor is None:
        from twisted.internet import reactor

    if config is None:
        config = default_config(name, parse=True)

    config.ldap_enabled = False

    if "clock" not in kwargs:
        kwargs["clock"] = MockClock()

    if USE_POSTGRES_FOR_TESTS:
        test_db = "synapse_test_%s" % uuid.uuid4().hex

        database_config = {
            "name": "psycopg2",
            "args": {
                "database": test_db,
                "host": POSTGRES_HOST,
                "password": POSTGRES_PASSWORD,
                "user": POSTGRES_USER,
                "cp_min": 1,
                "cp_max": 5,
            },
        }
    else:
        if SQLITE_PERSIST_DB:
            # The current working directory is in _trial_temp, so this gets created within that directory.
            test_db_location = os.path.abspath("test.db")
            logger.debug("Will persist db to %s", test_db_location)
            # Ensure each test gets a clean database.
            try:
                os.remove(test_db_location)
            except FileNotFoundError:
                pass
            else:
                logger.debug("Removed existing DB at %s", test_db_location)
        else:
            test_db_location = ":memory:"

        database_config = {
            "name": "sqlite3",
            "args": {
                "database": test_db_location,
                "cp_min": 1,
                "cp_max": 1
            },
        }

    if "db_txn_limit" in kwargs:
        database_config["txn_limit"] = kwargs["db_txn_limit"]

    database = DatabaseConnectionConfig("master", database_config)
    config.database.databases = [database]

    db_engine = create_engine(database.config)

    # Create the database before we actually try and connect to it, based off
    # the template database we generate in setupdb()
    if isinstance(db_engine, PostgresEngine):
        db_conn = db_engine.module.connect(
            database=POSTGRES_BASE_DB,
            user=POSTGRES_USER,
            host=POSTGRES_HOST,
            password=POSTGRES_PASSWORD,
        )
        db_conn.autocommit = True
        cur = db_conn.cursor()
        cur.execute("DROP DATABASE IF EXISTS %s;" % (test_db, ))
        cur.execute("CREATE DATABASE %s WITH TEMPLATE %s;" %
                    (test_db, POSTGRES_BASE_DB))
        cur.close()
        db_conn.close()

    hs = homeserver_to_use(
        name,
        config=config,
        version_string="Synapse/tests",
        reactor=reactor,
    )

    # Install @cache_in_self attributes
    for key, val in kwargs.items():
        setattr(hs, "_" + key, val)

    # Mock TLS
    hs.tls_server_context_factory = Mock()
    hs.tls_client_options_factory = Mock()

    hs.setup()
    if homeserver_to_use == TestHomeServer:
        hs.setup_background_tasks()

    if isinstance(db_engine, PostgresEngine):
        database = hs.get_datastores().databases[0]

        # We need to do cleanup on PostgreSQL
        def cleanup():
            import psycopg2

            # Close all the db pools
            database._db_pool.close()

            dropped = False

            # Drop the test database
            db_conn = db_engine.module.connect(
                database=POSTGRES_BASE_DB,
                user=POSTGRES_USER,
                host=POSTGRES_HOST,
                password=POSTGRES_PASSWORD,
            )
            db_conn.autocommit = True
            cur = db_conn.cursor()

            # Try a few times to drop the DB. Some things may hold on to the
            # database for a few more seconds due to flakiness, preventing
            # us from dropping it when the test is over. If we can't drop
            # it, warn and move on.
            for _ in range(5):
                try:
                    cur.execute("DROP DATABASE IF EXISTS %s;" % (test_db, ))
                    db_conn.commit()
                    dropped = True
                except psycopg2.OperationalError as e:
                    warnings.warn("Couldn't drop old db: " + str(e),
                                  category=UserWarning)
                    time.sleep(0.5)

            cur.close()
            db_conn.close()

            if not dropped:
                warnings.warn("Failed to drop old DB.", category=UserWarning)

        if not LEAVE_DB:
            # Register the cleanup hook
            cleanup_func(cleanup)

    # bcrypt is far too slow to be doing in unit tests
    # Need to let the HS build an auth handler and then mess with it
    # because AuthHandler's constructor requires the HS, so we can't make one
    # beforehand and pass it in to the HS's constructor (chicken / egg)
    async def hash(p):
        return hashlib.md5(p.encode("utf8")).hexdigest()

    hs.get_auth_handler().hash = hash

    async def validate_hash(p, h):
        return hashlib.md5(p.encode("utf8")).hexdigest() == h

    hs.get_auth_handler().validate_hash = validate_hash

    # Make the threadpool and database transactions synchronous for testing.
    _make_test_homeserver_synchronous(hs)

    return hs
Example #11
0
    def setUp(self):
        self.mock_http_client = Mock(spec=[])
        self.mock_http_client.put_json = DeferredMockCallable()

        self.mock_federation_resource = MockHttpResource()

        hs = HomeServer(
            "test",
            clock=MockClock(),
            db_pool=None,
            datastore=Mock(spec=[
                # Bits that Federation needs
                "prep_send_transaction",
                "delivered_txn",
                "get_received_txn_response",
                "set_received_txn_response",
            ]),
            handlers=None,
            resource_for_client=Mock(),
            resource_for_federation=self.mock_federation_resource,
            http_client=self.mock_http_client,
        )
        hs.handlers = JustPresenceHandlers(hs)

        self.datastore = hs.get_datastore()

        def get_received_txn_response(*args):
            return defer.succeed(None)

        self.datastore.get_received_txn_response = get_received_txn_response

        self.mock_update_client = Mock()

        def update(*args, **kwargs):
            # print "mock_update_client: Args=%s, kwargs=%s" %(args, kwargs,)
            return defer.succeed(None)

        self.mock_update_client.side_effect = update

        self.handler = hs.get_handlers().presence_handler
        self.handler.push_update_to_clients = self.mock_update_client

        hs.handlers.room_member_handler = Mock(spec=[
            "get_rooms_for_user",
        ])

        # For this test no users are ever in rooms
        def get_rooms_for_user(user):
            return defer.succeed([])

        hs.handlers.room_member_handler.get_rooms_for_user = get_rooms_for_user

        # Mocked database state
        # Local users always start offline
        self.current_user_state = {
            "apple": OFFLINE,
            "banana": OFFLINE,
            "clementine": OFFLINE,
            "fig": OFFLINE,
        }

        def get_presence_state(user_localpart):
            return defer.succeed({
                "state":
                self.current_user_state[user_localpart],
                "status_msg":
                None,
                "mtime":
                123456000
            })

        self.datastore.get_presence_state = get_presence_state

        def set_presence_state(user_localpart, new_state):
            was = self.current_user_state[user_localpart]
            self.current_user_state[user_localpart] = new_state["state"]
            return defer.succeed({"state": was})

        self.datastore.set_presence_state = set_presence_state

        def get_presence_list(user_localpart, accepted):
            return defer.succeed([{
                "observed_user_id": u
            } for u in self.PRESENCE_LIST[user_localpart]])

        self.datastore.get_presence_list = get_presence_list

        def is_presence_visible(observed_localpart, observer_userid):
            return True

        self.datastore.is_presence_visible = is_presence_visible

        # Local users
        self.u_apple = hs.parse_userid("@apple:test")
        self.u_banana = hs.parse_userid("@banana:test")
        self.u_clementine = hs.parse_userid("@clementine:test")
        self.u_fig = hs.parse_userid("@fig:test")

        # Remote users
        self.u_potato = hs.parse_userid("@potato:remote")
Example #12
0
    def setUp(self):
        db_pool = SQLiteMemoryDbPool()
        yield db_pool.prepare()

        hs = HomeServer(
            "test",
            clock=MockClock(),
            db_pool=db_pool,
            handlers=None,
            resource_for_federation=Mock(),
            http_client=None,
        )
        hs.handlers = JustPresenceHandlers(hs)

        self.store = hs.get_datastore()

        # Mock the RoomMemberHandler
        room_member_handler = Mock(spec=[])
        hs.handlers.room_member_handler = room_member_handler

        # Some local users to test with
        self.u_apple = hs.parse_userid("@apple:test")
        self.u_banana = hs.parse_userid("@banana:test")
        self.u_clementine = hs.parse_userid("@clementine:test")

        yield self.store.create_presence(self.u_apple.localpart)
        yield self.store.set_presence_state(self.u_apple.localpart, {
            "state": ONLINE,
            "status_msg": "Online"
        })

        self.handler = hs.get_handlers().presence_handler

        self.room_members = []

        def get_rooms_for_user(user):
            if user in self.room_members:
                return defer.succeed(["a-room"])
            else:
                return defer.succeed([])

        room_member_handler.get_rooms_for_user = get_rooms_for_user

        def get_room_members(room_id):
            if room_id == "a-room":
                return defer.succeed(self.room_members)
            else:
                return defer.succeed([])

        room_member_handler.get_room_members = get_room_members

        def user_rooms_intersect(userlist):
            room_member_ids = map(lambda u: u.to_string(), self.room_members)

            shared = all(map(lambda i: i in room_member_ids, userlist))
            return defer.succeed(shared)

        self.store.user_rooms_intersect = user_rooms_intersect

        self.mock_start = Mock()
        self.mock_stop = Mock()

        self.handler.start_polling_presence = self.mock_start
        self.handler.stop_polling_presence = self.mock_stop
Example #13
0
    def setUp(self):
        self.clock = MockClock()

        self.mock_http_client = Mock(spec=[])
        self.mock_http_client.put_json = DeferredMockCallable()

        self.mock_federation_resource = MockHttpResource()

        hs = HomeServer(
            "test",
            clock=self.clock,
            db_pool=None,
            datastore=Mock(spec=[
                "set_presence_state",
                "get_joined_hosts_for_room",

                # Bits that Federation needs
                "prep_send_transaction",
                "delivered_txn",
                "get_received_txn_response",
                "set_received_txn_response",
            ]),
            handlers=None,
            resource_for_client=Mock(),
            resource_for_federation=self.mock_federation_resource,
            http_client=self.mock_http_client,
        )
        hs.handlers = JustPresenceHandlers(hs)

        self.datastore = hs.get_datastore()

        def get_received_txn_response(*args):
            return defer.succeed(None)

        self.datastore.get_received_txn_response = get_received_txn_response

        self.handler = hs.get_handlers().presence_handler
        self.event_source = hs.get_event_sources().sources["presence"]

        # Mock the RoomMemberHandler
        hs.handlers.room_member_handler = Mock(spec=[
            "get_rooms_for_user",
            "get_room_members",
        ])
        self.room_member_handler = hs.handlers.room_member_handler

        self.room_members = []

        def get_rooms_for_user(user):
            if user in self.room_members:
                return defer.succeed(["a-room"])
            else:
                return defer.succeed([])

        self.room_member_handler.get_rooms_for_user = get_rooms_for_user

        def get_room_members(room_id):
            if room_id == "a-room":
                return defer.succeed(self.room_members)
            else:
                return defer.succeed([])

        self.room_member_handler.get_room_members = get_room_members

        def get_room_hosts(room_id):
            if room_id == "a-room":
                hosts = set([u.domain for u in self.room_members])
                return defer.succeed(hosts)
            else:
                return defer.succeed([])

        self.datastore.get_joined_hosts_for_room = get_room_hosts

        def user_rooms_intersect(userlist):
            room_member_ids = map(lambda u: u.to_string(), self.room_members)

            shared = all(map(lambda i: i in room_member_ids, userlist))
            return defer.succeed(shared)

        self.datastore.user_rooms_intersect = user_rooms_intersect

        @defer.inlineCallbacks
        def fetch_room_distributions_into(room_id,
                                          localusers=None,
                                          remotedomains=None,
                                          ignore_user=None):

            members = yield get_room_members(room_id)
            for member in members:
                if ignore_user is not None and member == ignore_user:
                    continue

                if member.is_mine:
                    if localusers is not None:
                        localusers.add(member)
                else:
                    if remotedomains is not None:
                        remotedomains.add(member.domain)

        self.room_member_handler.fetch_room_distributions_into = (
            fetch_room_distributions_into)

        def get_presence_list(user_localpart, accepted=None):
            if user_localpart == "apple":
                return defer.succeed([
                    {
                        "observed_user_id": "@banana:test"
                    },
                    {
                        "observed_user_id": "@clementine:test"
                    },
                ])
            else:
                return defer.succeed([])

        self.datastore.get_presence_list = get_presence_list

        def is_presence_visible(observer_userid, observed_localpart):
            if (observed_localpart == "clementine"
                    and observer_userid == "@banana:test"):
                return False
            return False

        self.datastore.is_presence_visible = is_presence_visible

        self.distributor = hs.get_distributor()
        self.distributor.declare("user_joined_room")

        # Some local users to test with
        self.u_apple = hs.parse_userid("@apple:test")
        self.u_banana = hs.parse_userid("@banana:test")
        self.u_clementine = hs.parse_userid("@clementine:test")
        self.u_durian = hs.parse_userid("@durian:test")
        self.u_elderberry = hs.parse_userid("@elderberry:test")

        # Remote user
        self.u_onion = hs.parse_userid("@onion:farm")
        self.u_potato = hs.parse_userid("@potato:remote")