コード例 #1
0
    def test_skills_with_unicode_characters_are_set_and_get_correctly(self):
        """Test to make sure that a default skill initialized with unicode
        characters is set to the cache without errors and retrieved from the
        cache without any alterations (in an identical state to when it was
        set to the cache).
        """
        skill_id = 'id'

        self.assertEqual(
            caching_services.get_multi(caching_services.CACHE_NAMESPACE_SKILL,
                                       '0', [skill_id]), {})

        rubrics = [
            skill_domain.Rubric(
                constants.SKILL_DIFFICULTIES[0],
                ['<p>[NOTE: Creator should fill this in]</p> 😍']),
            skill_domain.Rubric(
                constants.SKILL_DIFFICULTIES[1],
                ['<p>[NOTE: Creator should fill this in]</p> 😍']),
            skill_domain.Rubric(
                constants.SKILL_DIFFICULTIES[2],
                ['<p>[NOTE: Creator should fill this in]</p> 😍'])
        ]

        default_skill = (skill_domain.Skill.create_default_skill(
            skill_id, 'Description 😍', rubrics))

        caching_services.set_multi(caching_services.CACHE_NAMESPACE_SKILL, '0',
                                   {skill_id: default_skill})

        skills = caching_services.get_multi(
            caching_services.CACHE_NAMESPACE_SKILL, '0', [skill_id])

        self.assertEqual(default_skill.to_dict(), skills[skill_id].to_dict())
コード例 #2
0
def get_topic_by_id(topic_id, strict=True, version=None):
    """Returns a domain object representing a topic.

    Args:
        topic_id: str. ID of the topic.
        strict: bool. Whether to fail noisily if no topic with the given
            id exists in the datastore.
        version: int or None. The version number of the topic to be
            retrieved. If it is None, the latest version will be retrieved.

    Returns:
        Topic or None. The domain object representing a topic with the
        given id, or None if it does not exist.
    """
    sub_namespace = python_utils.convert_to_bytes(version) if version else None
    cached_topic = caching_services.get_multi(
        caching_services.CACHE_NAMESPACE_TOPIC, sub_namespace,
        [topic_id]).get(topic_id)

    if cached_topic is not None:
        return cached_topic
    else:
        topic_model = topic_models.TopicModel.get(topic_id,
                                                  strict=strict,
                                                  version=version)
        if topic_model:
            topic = get_topic_from_model(topic_model)
            caching_services.set_multi(caching_services.CACHE_NAMESPACE_TOPIC,
                                       sub_namespace, {topic_id: topic})
            return topic
        else:
            return None
コード例 #3
0
    def set_value(self, committer_id, raw_value):
        """Sets the value of the property. In general, this should not be
        called directly -- use config_services.set_property() instead.
        """
        value = self.normalize(raw_value)

        # Set value in datastore.
        model_instance = config_models.ConfigPropertyModel.get(
            self.name, strict=False)
        if model_instance is None:
            model_instance = config_models.ConfigPropertyModel(
                id=self.name)
        model_instance.value = value
        model_instance.commit(
            committer_id, [{
                'cmd': CMD_CHANGE_PROPERTY_VALUE,
                'new_value': value
            }])

        # Set value in memcache.
        caching_services.set_multi(
            caching_services.CACHE_NAMESPACE_CONFIG, None,
            {
                model_instance.id: model_instance.value
            })
コード例 #4
0
def get_skill_by_id(skill_id, strict=True, version=None):
    """Returns a domain object representing a skill.

    Args:
        skill_id: str. ID of the skill.
        strict: bool. Whether to fail noisily if no skill with the given
            id exists in the datastore.
        version: int or None. The version number of the skill to be
            retrieved. If it is None, the latest version will be retrieved.

    Returns:
        Skill or None. The domain object representing a skill with the
        given id, or None if it does not exist.
    """
    sub_namespace = python_utils.UNICODE(version) if version else None
    cached_skill = caching_services.get_multi(
        caching_services.CACHE_NAMESPACE_SKILL, sub_namespace,
        [skill_id]).get(skill_id)

    if cached_skill is not None:
        return cached_skill
    else:
        skill_model = skill_models.SkillModel.get(skill_id,
                                                  strict=strict,
                                                  version=version)
        if skill_model:
            skill = get_skill_from_model(skill_model)
            caching_services.set_multi(caching_services.CACHE_NAMESPACE_SKILL,
                                       sub_namespace, {skill_id: skill})
            return skill
        else:
            return None
コード例 #5
0
    def test_config_properties_identically_cached_in_dev_and_test_environment(
            self):
        """Test to make sure that caching in the test environment is in sync
        with caching in the main development server. More specifically, when a
        config property is created with fields that contain unicode characters,
        the resulting string that is set to the memory cache on the development
        server should be the same as the string that is set to the testing cache
        on the testing server.
        """
        def mock_memory_cache_services_set_multi(id_value_mapping):
            # This mock asserts that for the same config domain attribute
            # containing unicode characters, the string that is set to the cache
            # in the testing environment is the same as the string set to the
            # cache in the development environment.
            for key, value in id_value_mapping.items():
                self.assertEqual(key, 'config::email_footer')
                self.assertEqual(
                    value,
                    '"You can change your email preferences via the <a href='
                    '\\"https://www.example.com\\">Preferences</a> page. '
                    '\\u00a9\\u00a9\\u00ae\\u00ae"')

        config_id = 'email_footer'

        self.assertEqual(
            caching_services.get_multi(
                caching_services.CACHE_NAMESPACE_CONFIG, None,
                [config_id]),
            {})

        with self.swap(
            memory_cache_services, 'set_multi',
            mock_memory_cache_services_set_multi):
            caching_services.set_multi(
                caching_services.CACHE_NAMESPACE_CONFIG, None,
                {
                    config_id: (
                        'You can change your email preferences via the <a href'
                        '="https://www.example.com">Preferences</a> page. ©©®®')
                })

        cache_strings_response = caching_services.set_multi(
            caching_services.CACHE_NAMESPACE_CONFIG, None,
            {
                config_id: (
                    'You can change your email preferences via the <a href'
                    '="https://www.example.com">Preferences</a> page. ©©®®')
            })

        self.assertTrue(cache_strings_response)

        self.assertEqual(
            caching_services.get_multi(
                caching_services.CACHE_NAMESPACE_CONFIG, None,
                [config_id]),
            {
                config_id: (
                    'You can change your email preferences via the <a href'
                    '="https://www.example.com">Preferences</a> page. ©©®®')
            })
コード例 #6
0
ファイル: story_fetchers.py プロジェクト: ReshuKumari/oppia
def get_story_by_id(story_id, strict=True, version=None):
    """Returns a domain object representing a story.

    Args:
        story_id: str. ID of the story.
        strict: bool. Whether to fail noisily if no story with the given
            id exists in the datastore.
        version: str or None. The version number of the story to be
            retrieved. If it is None, the latest version will be retrieved.

    Returns:
        Story or None. The domain object representing a story with the
        given id, or None if it does not exist.
    """
    sub_namespace = python_utils.convert_to_bytes(version) if version else None
    cached_story = caching_services.get_multi(
        caching_services.CACHE_NAMESPACE_STORY, sub_namespace,
        [story_id]).get(story_id)

    if cached_story is not None:
        return cached_story
    else:
        story_model = story_models.StoryModel.get(story_id,
                                                  strict=strict,
                                                  version=version)
        if story_model:
            story = get_story_from_model(story_model)
            caching_services.set_multi(caching_services.CACHE_NAMESPACE_STORY,
                                       sub_namespace, {story_id: story})
            return story
        else:
            return None
コード例 #7
0
def get_exploration_by_id(exploration_id, strict=True, version=None):
    """Returns an Exploration domain object.

    Args:
        exploration_id: str. The id of the exploration to be returned.
        strict: bool. Whether to fail noisily if no exploration with a given id
            exists.
        version: int or None. The version of the exploration to be returned.
            If None, the latest version of the exploration is returned.

    Returns:
        Exploration. The domain object corresponding to the given exploration.
    """
    sub_namespace = python_utils.convert_to_bytes(version) if version else None
    cached_exploration = caching_services.get_multi(
        caching_services.CACHE_NAMESPACE_EXPLORATION, sub_namespace,
        [exploration_id]).get(exploration_id)

    if cached_exploration is not None:
        return cached_exploration
    else:
        exploration_model = exp_models.ExplorationModel.get(exploration_id,
                                                            strict=strict,
                                                            version=version)
        if exploration_model:
            exploration = get_exploration_from_model(exploration_model)
            caching_services.set_multi(
                caching_services.CACHE_NAMESPACE_EXPLORATION, sub_namespace,
                {exploration_id: exploration})
            return exploration
        else:
            return None
コード例 #8
0
def get_multiple_explorations_by_id(exp_ids, strict=True):
    """Returns a dict of domain objects representing explorations with the
    given ids as keys. If an exp_id is not present, it is not included in the
    return dict.

    Args:
        exp_ids: list(str). List of ids of the exploration to be returned.
        strict: bool. If True, a ValueError is raised when any exploration id
            is invalid.

    Returns:
        dict. Maps exploration ids to the corresponding Exploration domain
        objects. Any invalid exploration ids are omitted.

    Raises:
        ValueError. When strict is True and at least one of the given exp_ids
            is invalid.
    """
    result = {}
    uncached = []
    cache_result = caching_services.get_multi(
        caching_services.CACHE_NAMESPACE_EXPLORATION, None, exp_ids)

    for exp_obj in cache_result.values():
        result[exp_obj.id] = exp_obj

    for _id in exp_ids:
        if _id not in result:
            uncached.append(_id)

    db_exp_models = exp_models.ExplorationModel.get_multi(uncached)
    db_results_dict = {}
    not_found = []
    for i, eid in enumerate(uncached):
        model = db_exp_models[i]
        if model:
            exploration = get_exploration_from_model(model)
            db_results_dict[eid] = exploration
        else:
            logging.info(
                'Tried to fetch exploration with id %s, but no such '
                'exploration exists in the datastore' % eid)
            not_found.append(eid)

    if strict and not_found:
        raise ValueError(
            'Couldn\'t find explorations with the following ids:\n%s'
            % '\n'.join(not_found))

    cache_update = {
        eid: results for eid, results in db_results_dict.items()
        if results is not None
    }

    if cache_update:
        caching_services.set_multi(
            caching_services.CACHE_NAMESPACE_EXPLORATION, None, cache_update)

    result.update(db_results_dict)
    return result
コード例 #9
0
    def test_collections_with_unicode_characters_are_set_and_get_correctly(
            self) -> None:
        """Test to make sure that a default collection initialized with unicode
        characters is set to the cache without errors and retrieved from the
        cache without any alterations (in an identical state to when it was
        set to the cache).
        """
        collection_id = 'id 😍'

        self.assertEqual(
            caching_services.get_multi(
                caching_services.CACHE_NAMESPACE_COLLECTION, '0',
                [collection_id]), {})

        default_collection = (
            collection_domain.Collection.
            create_default_collection(  # type: ignore[no-untyped-call]
                collection_id))

        caching_services.set_multi(caching_services.CACHE_NAMESPACE_COLLECTION,
                                   '0', {collection_id: default_collection})

        collections = caching_services.get_multi(
            caching_services.CACHE_NAMESPACE_COLLECTION, '0', [collection_id])

        self.assertEqual(default_collection.to_dict(),
                         collections[collection_id].to_dict(
                         ))  # type: ignore[no-untyped-call]
コード例 #10
0
    def get_platform_parameter(cls, name):
        """Returns the instance of the specified name of the platform
        parameter.

        Args:
            name: str. The name of the platform parameter.

        Returns:
            PlatformParameter. The instance of the specified platform
            parameter.
        """
        parameter_from_cache = cls.load_platform_parameter_from_memcache(name)
        if parameter_from_cache is not None:
            return parameter_from_cache

        parameter = None

        parameter_from_storage = cls.load_platform_parameter_from_storage(name)
        if parameter_from_storage is not None:
            parameter = parameter_from_storage
        elif name in cls.parameter_registry:
            parameter = cls.parameter_registry[name]
        else:
            raise Exception('Platform parameter not found: %s.' % name)

        caching_services.set_multi(
            caching_services.CACHE_NAMESPACE_PLATFORM_PARAMETER, None, {
                name: parameter,
            })
        return parameter
コード例 #11
0
    def test_topics_with_unicode_characters_are_set_and_get_correctly(
            self) -> None:
        """Test to make sure that a default topic initialized with unicode
        characters is set to the cache without errors and retrieved from the
        cache without any alterations (in an identical state to when it was
        set to the cache).
        """
        topic_id = 'id'

        self.assertEqual(
            caching_services.get_multi(caching_services.CACHE_NAMESPACE_TOPIC,
                                       '0', [topic_id]), {})

        default_topic = (
            topic_domain.Topic.
            create_default_topic(  # type: ignore[no-untyped-call]
                topic_id, 'Name 😍', 'abbrev 😍', 'description 😍'))

        caching_services.set_multi(caching_services.CACHE_NAMESPACE_TOPIC, '0',
                                   {topic_id: default_topic})

        topics = caching_services.get_multi(
            caching_services.CACHE_NAMESPACE_TOPIC, '0', [topic_id])

        self.assertEqual(
            default_topic.to_dict(),
            topics[topic_id].to_dict())  # type: ignore[no-untyped-call]
コード例 #12
0
    def test_invalid_namespace_raises_error(self):
        invalid_namespace = 'invalid'
        key_value_mapping = {'a': '1', 'b': '2', 'c': '3'}

        with self.assertRaisesRegexp(
                ValueError, 'Invalid namespace: %s.' % invalid_namespace):
            caching_services.set_multi(invalid_namespace, None,
                                       key_value_mapping)

        with self.assertRaisesRegexp(
                ValueError, 'Invalid namespace: %s.' % invalid_namespace):
            caching_services.get_multi(invalid_namespace, None,
                                       ['a', 'b', 'c'])

        with self.assertRaisesRegexp(
                ValueError, 'Invalid namespace: %s.' % invalid_namespace):
            caching_services.delete_multi(invalid_namespace, None,
                                          ['a', 'b', 'c'])

        invalid_sub_namespace = 'sub:namespace'
        with self.assertRaisesRegexp(
                ValueError, 'Sub-namespace %s cannot contain \':\'.' %
                invalid_sub_namespace):
            caching_services.get_multi(
                caching_services.CACHE_NAMESPACE_DEFAULT,
                invalid_sub_namespace, ['a', 'b', 'c'])
コード例 #13
0
    def test_stories_with_unicode_characters_are_set_and_get_correctly(
            self) -> None:
        """Test to make sure that a default story initialized with unicode
        characters is set to the cache without errors and retrieved from the
        cache without any alterations (in an identical state to when it was
        set to the cache).
        """
        story_id = 'id'
        topic_id = 'topic_id'

        self.assertEqual(
            caching_services.get_multi(caching_services.CACHE_NAMESPACE_STORY,
                                       '0', [story_id]), {})

        default_story = (
            story_domain.Story.
            create_default_story(  # type: ignore[no-untyped-call]
                story_id, 'Title 😍', 'Description 😍', topic_id, 'title 😍'))

        caching_services.set_multi(caching_services.CACHE_NAMESPACE_STORY, '0',
                                   {story_id: default_story})

        stories = caching_services.get_multi(
            caching_services.CACHE_NAMESPACE_STORY, '0', [story_id])

        self.assertEqual(
            default_story.to_dict(),
            stories[story_id].to_dict())  # type: ignore[no-untyped-call]
コード例 #14
0
    def test_flush_cache_wipes_cache_clean(self):
        """Tests whether flushing the cache removes the elements in the
        cache.
        """
        key_value_mapping = {'a': '1', 'b': '2', 'c': '3'}
        caching_services.set_multi(caching_services.CACHE_NAMESPACE_DEFAULT,
                                   None, key_value_mapping)
        exploration_id = 'id'
        default_exploration = (
            exp_domain.Exploration.create_default_exploration(
                'exp_id_1', title='A title', category='A category'))
        caching_services.set_multi(
            caching_services.CACHE_NAMESPACE_EXPLORATION, '0',
            {exploration_id: default_exploration})

        self.assertEqual(
            caching_services.get_multi(
                caching_services.CACHE_NAMESPACE_DEFAULT, None,
                ['a', 'b', 'c']), key_value_mapping)

        self.assertIsNotNone(
            caching_services.get_multi(
                caching_services.CACHE_NAMESPACE_EXPLORATION, '0',
                [exploration_id]).get(exploration_id))

        caching_services.flush_memory_cache()

        self.assertEqual(
            caching_services.get_multi(
                caching_services.CACHE_NAMESPACE_DEFAULT, None,
                ['a', 'b', 'c']), {})
        self.assertEqual(
            caching_services.get_multi(
                caching_services.CACHE_NAMESPACE_EXPLORATION, '0',
                [exploration_id]), {})
コード例 #15
0
def get_collection_by_id(collection_id, strict=True, version=None):
    """Returns a domain object representing a collection.

    Args:
        collection_id: str. ID of the collection.
        strict: bool. Whether to fail noisily if no collection with the given
            id exists in the datastore.
        version: int or None. The version number of the collection to be
            retrieved. If it is None, the latest version will be retrieved.

    Returns:
        Collection or None. The domain object representing a collection with the
        given id, or None if it does not exist.
    """
    sub_namespace = python_utils.convert_to_bytes(version) if version else None
    cached_collection = caching_services.get_multi(
        caching_services.CACHE_NAMESPACE_COLLECTION, sub_namespace,
        [collection_id]).get(collection_id)

    if cached_collection is not None:
        return cached_collection
    else:
        collection_model = collection_models.CollectionModel.get(
            collection_id, strict=strict, version=version)
        if collection_model:
            collection = get_collection_from_model(collection_model)
            caching_services.set_multi(
                caching_services.CACHE_NAMESPACE_COLLECTION, sub_namespace,
                {collection_id: collection})
            return collection
        else:
            return None
コード例 #16
0
def get_multiple_collections_by_id(collection_ids, strict=True):
    """Returns a dict of domain objects representing collections with the
    given ids as keys.

    Args:
        collection_ids: list(str). A list of collection ids of collections to
            be retrieved.
        strict: bool. Whether to fail noisily if no collection with a given id
            exists in the datastore.

    Returns:
        dict. A dict of domain objects representing collections with
        the given ids as keys.

    Raises:
        ValueError. The 'strict' is True, and one or more of the given
            collection ids are invalid.
    """
    result = {}
    uncached = []
    cache_result = caching_services.get_multi(
        caching_services.CACHE_NAMESPACE_COLLECTION, None, collection_ids)

    for collection_obj in cache_result.values():
        result[collection_obj.id] = collection_obj

    for _id in collection_ids:
        if _id not in result:
            uncached.append(_id)

    db_collection_models = collection_models.CollectionModel.get_multi(
        uncached)
    db_results_dict = {}
    not_found = []
    for index, cid in enumerate(uncached):
        model = db_collection_models[index]
        if model:
            collection = get_collection_from_model(model)
            db_results_dict[cid] = collection
        else:
            logging.info('Tried to fetch collection with id %s, but no such '
                         'collection exists in the datastore' % cid)
            not_found.append(cid)

    if strict and not_found:
        raise ValueError(
            'Couldn\'t find collections with the following ids:\n%s' %
            '\n'.join(not_found))

    cache_update = {
        cid: db_results_dict[cid]
        for cid in db_results_dict if db_results_dict[cid] is not None
    }

    if cache_update:
        caching_services.set_multi(caching_services.CACHE_NAMESPACE_COLLECTION,
                                   None, cache_update)

    result.update(db_results_dict)
    return result
コード例 #17
0
    def test_explorations_with_unicode_characters_are_set_and_get_correctly(
            self) -> None:
        """Test to make sure that a default explorations initialized with
        unicode characters is set to the cache without errors and retrieved from
        the cache without any alterations (in an identical state to when it was
        set to the cache).
        """
        exploration_id = 'h51Bu72rDIqO'

        self.assertEqual(
            caching_services.get_multi(
                caching_services.CACHE_NAMESPACE_EXPLORATION, '0',
                [exploration_id]), {})

        default_exploration = exp_domain.Exploration.from_dict(  # type: ignore[no-untyped-call]
            self.exploration_dict_with_unicode_characters)

        caching_services.set_multi(
            caching_services.CACHE_NAMESPACE_EXPLORATION, '0',
            {exploration_id: default_exploration})

        exp_ids_to_explorations = caching_services.get_multi(
            caching_services.CACHE_NAMESPACE_EXPLORATION, '0',
            [exploration_id])

        self.assertEqual(default_exploration.to_dict(),
                         exp_ids_to_explorations[exploration_id].to_dict(
                         ))  # type: ignore[no-untyped-call]
コード例 #18
0
    def test_queries_to_wrong_sub_namespace_returns_none(self) -> None:
        exploration_id = 'id'
        default_exploration = (
            exp_domain.Exploration.
            create_default_exploration(  # type: ignore[no-untyped-call]
                'exp_id_1',
                title='A title',
                category='A category'))

        self.assertEqual(
            caching_services.get_multi(
                caching_services.CACHE_NAMESPACE_EXPLORATION, '1',
                [exploration_id]), {})

        caching_services.set_multi(
            caching_services.CACHE_NAMESPACE_EXPLORATION, '1',
            {exploration_id: default_exploration})

        existent_result = caching_services.get_multi(
            caching_services.CACHE_NAMESPACE_EXPLORATION, '1',
            [exploration_id])

        self.assertEqual(
            existent_result[exploration_id].to_dict(
            ),  # type: ignore[no-untyped-call]
            default_exploration.to_dict())
コード例 #19
0
    def test_get_multi_correctly_retrieves_cache_elements(self) -> None:
        """Testing that querying the cache for elements where either all of the
        ids exist or don't exist in the cache returns reasonable output.
        """
        # Key value mapping tests that strings, numbers, booleans, floats,
        # lists, and Nonetypes are all correctly set and get from the cache.
        key_value_mapping = {
            'a': '1', 'b': 2, 'c': [True, None],
            'd': {
                'd.1': 1.2,
                'd.2': 30
            }}

        exploration_id = 'id'

        self.assertEqual(
            caching_services.get_multi(
                caching_services.CACHE_NAMESPACE_DEFAULT,
                None,
                ['a', 'b', 'c', 'd']),
            {})
        self.assertEqual(
            caching_services.get_multi(
                caching_services.CACHE_NAMESPACE_EXPLORATION,
                '0',
                [exploration_id]),
            {})

        # set_mutli can accept str with literal(default), but here
        # we passing object. Hence, ignore statement is used.
        caching_services.set_multi( # type: ignore[call-overload]
            caching_services.CACHE_NAMESPACE_DEFAULT, None, key_value_mapping)
        default_exploration = (
            exp_domain.Exploration.create_default_exploration( # type: ignore[no-untyped-call]
                'exp_id_1', title='A title', category='A category'))
        caching_services.set_multi(
            caching_services.CACHE_NAMESPACE_EXPLORATION,
            '0',
            {
                exploration_id: default_exploration
            })

        self.assertEqual(
            caching_services.get_multi(
                caching_services.CACHE_NAMESPACE_DEFAULT, None,
                ['a', 'b', 'c', 'd']),
            key_value_mapping)

        self.assertEqual(
            caching_services.get_multi(
                caching_services.CACHE_NAMESPACE_DEFAULT, None, ['e', 'f']),
            {})

        exp_ids_to_explorations = caching_services.get_multi(
            caching_services.CACHE_NAMESPACE_EXPLORATION,
            '0', [exploration_id])
        self.assertEqual(
            default_exploration.to_dict(),
            exp_ids_to_explorations[exploration_id].to_dict()) # type: ignore[no-untyped-call]
コード例 #20
0
    def test_delete_multi_returns_false_when_namespace_incorrect(self) -> None:
        key_value_mapping = {'a': '1', 'b': '2', 'c': '3'}

        caching_services.set_multi(caching_services.CACHE_NAMESPACE_DEFAULT,
                                   None, key_value_mapping)

        self.assertFalse(
            caching_services.delete_multi(
                caching_services.CACHE_NAMESPACE_EXPLORATION, None,
                ['a', 'b', 'c']))
コード例 #21
0
    def test_partial_fetches_returns_correct_elements(self):
        """Testing that querying the cache returns reasonable output for
        elements where only a subsection of the queried ids exist in the cache.
        """
        key_value_mapping = {'a': '1', 'c': '3'}
        exploration_id = 'id'
        nonexistent_exploration_id = 'id2'
        default_exploration = (
            exp_domain.Exploration.create_default_exploration(
                'exp_id_1', title='A title', category='A category'))

        self.assertEqual(
            caching_services.get_multi(
                caching_services.CACHE_NAMESPACE_EXPLORATION,
                '0',
                [exploration_id]),
            {})

        self.assertEqual(
            caching_services.get_multi(
                caching_services.CACHE_NAMESPACE_DEFAULT, None,
                ['a', 'b', 'c']), {})

        self.assertEqual(
            caching_services.get_multi(
                caching_services.CACHE_NAMESPACE_DEFAULT, None, []),
            {})

        caching_services.set_multi(
            caching_services.CACHE_NAMESPACE_EXPLORATION,
            '0',
            {
                exploration_id: default_exploration
            })

        caching_services.set_multi(
            caching_services.CACHE_NAMESPACE_DEFAULT, None, key_value_mapping)

        self.assertEqual(
            caching_services.get_multi(
                caching_services.CACHE_NAMESPACE_DEFAULT, None,
                ['a', 'b', 'c']),
            {'a': '1', 'c': '3'})

        result = caching_services.get_multi(
            caching_services.CACHE_NAMESPACE_EXPLORATION,
            '0',
            [exploration_id, nonexistent_exploration_id])

        self.assertEqual(
            default_exploration.to_dict(),
            result.get(exploration_id).to_dict())

        self.assertFalse(nonexistent_exploration_id in result)
コード例 #22
0
    def test_delete_multi_returns_false_when_not_all_ids_exist(self) -> None:
        """Tests that deleting keys that don't exist returns False."""
        key_value_mapping = {'a': '1', 'b': '2', 'c': '3'}

        caching_services.set_multi(caching_services.CACHE_NAMESPACE_DEFAULT,
                                   None, key_value_mapping)

        self.assertFalse(
            caching_services.delete_multi(
                caching_services.CACHE_NAMESPACE_DEFAULT, None,
                ['a', 'e', 'f']))
コード例 #23
0
    def test_delete_multi_returns_true_when_all_ids_exist(self) -> None:
        key_value_mapping = {'a': '1', 'b': '2', 'c': '3'}

        self.assertFalse(
            caching_services.delete_multi(
                caching_services.CACHE_NAMESPACE_DEFAULT, None,
                ['a', 'b', 'c']))

        caching_services.set_multi(
            caching_services.CACHE_NAMESPACE_DEFAULT, None, key_value_mapping)

        exploration_id = 'id'
        default_exploration = (
            exp_domain.Exploration.create_default_exploration( # type: ignore[no-untyped-call]
                'exp_id_1', title='A title', category='A category'))
        caching_services.set_multi(
            caching_services.CACHE_NAMESPACE_EXPLORATION,
            '0', {
                exploration_id: default_exploration
            })

        self.assertTrue(
            caching_services.delete_multi(
                caching_services.CACHE_NAMESPACE_DEFAULT, None, []))

        self.assertTrue(
            caching_services.delete_multi(
                caching_services.CACHE_NAMESPACE_DEFAULT, None,
                ['a', 'b', 'c']))

        self.assertGreater(
            len(
                caching_services.get_multi(
                    caching_services.CACHE_NAMESPACE_EXPLORATION,
                    '0',
                    [exploration_id]
                ),
            ),
            0
        )

        self.assertTrue(
            caching_services.delete_multi(
                caching_services.CACHE_NAMESPACE_EXPLORATION,
                '0', [exploration_id]))

        self.assertEqual(
            caching_services.get_multi(
                caching_services.CACHE_NAMESPACE_EXPLORATION,
                '0',
                [exploration_id]),
            {})
コード例 #24
0
    def test_queries_to_wrong_namespace_returns_none(self):
        exploration_id = 'id'
        default_exploration = (
            exp_domain.Exploration.create_default_exploration(
                'exp_id_1', title='A title', category='A category'))

        caching_services.set_multi(
            caching_services.CACHE_NAMESPACE_EXPLORATION, '0',
            {exploration_id: default_exploration})

        self.assertEqual(
            caching_services.get_multi(
                caching_services.CACHE_NAMESPACE_DEFAULT, '0',
                [exploration_id]), {})
コード例 #25
0
    def test_platform_parameters_with_unicode_are_set_and_get_correctly(
        self
    ) -> None:
        """Test to make sure that a default platform parameter initialized with
        unicode characters is set to the cache without errors and retrieved from
        the cache without any alterations (in an identical state to when it was
        set to the cache).
        """
        platform_parameter_id = 'id'

        self.assertEqual(
            caching_services.get_multi(
                caching_services.CACHE_NAMESPACE_PLATFORM_PARAMETER,
                '0',
                [platform_parameter_id]),
            {})

        default_parameter = parameter_domain.PlatformParameter.from_dict({ # type: ignore[no-untyped-call]
            'name': 'parameter_a 😍',
            'description': '😍😍😍😍',
            'data_type': 'bool',
            'rules': [
                {
                    'filters': [
                        {'type': 'server_mode', 'conditions': [['=', 'prod']]}],
                    'value_when_matched': True
                }
            ],
            'rule_schema_version': (
                feconf.CURRENT_PLATFORM_PARAMETER_RULE_SCHEMA_VERSION),
            'default_value': False,
            'is_feature': True,
            'feature_stage': 'test 😍',
        })

        caching_services.set_multi(
            caching_services.CACHE_NAMESPACE_PLATFORM_PARAMETER,
            '0',
            {
                platform_parameter_id: default_parameter
            })

        platform_parameters = caching_services.get_multi(
            caching_services.CACHE_NAMESPACE_PLATFORM_PARAMETER,
            '0', [platform_parameter_id])

        self.assertEqual(
            default_parameter.to_dict(),
            platform_parameters[platform_parameter_id].to_dict()) # type: ignore[no-untyped-call]
コード例 #26
0
    def test_explorations_identically_cached_in_dev_and_test_environment(
        self
    ) -> None:
        """Test to make sure that caching in the test environment is in sync
        with caching in the main development server. More specifically, when an
        exploration is created with fields that contain unicode characters, the
        resulting string that is set to the memory cache on the development
        server should be the same as the string that is set to the testing cache
        on the testing server.
        """
        exploration_id = 'h51Bu72rDIqO'

        self.assertEqual(
            caching_services.get_multi(
                caching_services.CACHE_NAMESPACE_EXPLORATION,
                '0',
                [exploration_id]),
            {})

        default_exploration = exp_domain.Exploration.from_dict( # type: ignore[no-untyped-call]
            self.exploration_dict_with_unicode_characters)

        # id_value_mapping is a Dict whose values can be any of the type from
        # Exploration, Skill, Story, Topic, Collection, str. hence Any type
        # has to be used here for the value type of id_value_mapping dictionary.
        def mock_memory_cache_services_set_multi(
            id_value_mapping: Dict[str, Any]
        ) -> None:
            # The json encoded string is the string that is set to the cache
            # when an exploration is created in the development server. This
            # mock asserts that for the same exploration, the string
            # representing the exploration set to the testing environment cache
            # is the same as the string set to the cache in the development
            # environment.
            for key, value in id_value_mapping.items():
                self.assertEqual(key, 'exploration:0:%s' % exploration_id)
                self.assertEqual(
                    json.loads(value),
                    json.loads(
                        self.json_encoded_string_representing_an_exploration))
        with self.swap(
            memory_cache_services, 'set_multi',
            mock_memory_cache_services_set_multi):
            caching_services.set_multi(
                caching_services.CACHE_NAMESPACE_EXPLORATION,
                '0',
                {
                    exploration_id: default_exploration
                })
コード例 #27
0
    def test_unicode_characters_are_set_and_get_correctly_in_default_namespace(
        self
    ) -> None:
        """Test to make sure that default namespace values (ints, floats,
        strings, boolean, lists, and dicts) can be set to the cache without
        errors and retrieved from the cache without any alterations.
        """
        key_value_mapping = {
            'a': '%#$', 'b': '\t',
            'c': '😃😄'
        }
        self.assertEqual(
            caching_services.get_multi(
                caching_services.CACHE_NAMESPACE_DEFAULT,
                None,
                ['a', 'b', 'c']),
            {})
        cache_strings_response = caching_services.set_multi(
            caching_services.CACHE_NAMESPACE_DEFAULT, None, key_value_mapping)
        self.assertTrue(cache_strings_response)

        self.assertEqual(
            caching_services.get_multi(
                caching_services.CACHE_NAMESPACE_DEFAULT,
                None,
                ['a', 'b', 'c']),
            {
                'a': '%#$', 'b': '\t',
                'c': '😃😄'
            })
コード例 #28
0
ファイル: config_domain.py プロジェクト: xarcode/oppia
    def value(self):
        """Get the latest value from memcache, datastore, or use default."""

        memcached_items = caching_services.get_multi(
            caching_services.CACHE_NAMESPACE_CONFIG, None, [self.name])
        if self.name in memcached_items:
            return memcached_items[self.name]

        datastore_item = config_models.ConfigPropertyModel.get(self.name,
                                                               strict=False)
        if datastore_item is not None:
            caching_services.set_multi(
                caching_services.CACHE_NAMESPACE_CONFIG, None,
                {datastore_item.id: datastore_item.value})
            return datastore_item.value

        return self.default_value
コード例 #29
0
    def test_set_multi_returns_true_for_successful_insert_into_cache(self):
        key_value_mapping = {'a': '1', 'b': '2', 'c': '3'}
        cache_strings_response = caching_services.set_multi(
            caching_services.CACHE_NAMESPACE_DEFAULT, None, key_value_mapping)
        self.assertTrue(cache_strings_response)

        exploration_id = 'id'
        default_exploration = (
            exp_domain.Exploration.create_default_exploration(
                'exp_id_1', title='A title', category='A category'))
        cache_exploration_response = caching_services.set_multi(
            caching_services.CACHE_NAMESPACE_EXPLORATION, '0',
            {exploration_id: default_exploration})
        self.assertTrue(cache_exploration_response)

        cache_empty_list_response = caching_services.set_multi(
            caching_services.CACHE_NAMESPACE_DEFAULT, None, {})
        self.assertTrue(cache_empty_list_response)
コード例 #30
0
    def test_explorations_identically_cached_in_dev_and_test_environment(
            self):
        """Test to make sure that caching in the test environment is in sync
        with caching in the main development server. More specifically, when an
        exploration is created with fields that contain unicode characters, the
        resulting string that is set to the memory cache on the development
        server should be the same as the string that is set to the testing cache
        on the testing server.
        """
        exploration_id = 'h51Bu72rDIqO'

        self.assertEqual(
            caching_services.get_multi(
                caching_services.CACHE_NAMESPACE_EXPLORATION,
                '0',
                [exploration_id]),
            {})

        default_exploration = exp_domain.Exploration.from_dict(
            self.exploration_dict_with_unicode_characters)

        def mock_memory_cache_services_set_multi(id_value_mapping):
            # The json encoded string is the string that is set to the cache
            # when an exploration is created in the development server. This
            # mock asserts that for the same exploration, the string
            # representing the exploration set to the testing environment cache
            # is the same as the string set to the cache in the development
            # environment.
            for key, value in id_value_mapping.items():
                self.assertEqual(key, 'exploration:0:%s' % exploration_id)
                self.assertEqual(
                    json.loads(value),
                    json.loads(
                        self.json_encoded_string_representing_an_exploration))
        with self.swap(
            memory_cache_services, 'set_multi',
            mock_memory_cache_services_set_multi):
            caching_services.set_multi(
                caching_services.CACHE_NAMESPACE_EXPLORATION,
                '0',
                {
                    exploration_id: default_exploration
                })