示例#1
0
    def test_create_table_no_range(self):
        self.storage_mocker.StubOutWithMock(storage, 'create_table')
        storage.create_table(IgnoreArg(), IgnoreArg(), IgnoreArg()).AndReturn(
            models.TableMeta(
                models.TableSchema(
                    {
                        'hash': models.ATTRIBUTE_TYPE_NUMBER,
                        'indexed_field': models.ATTRIBUTE_TYPE_STRING
                    }, ['hash'],
                    {"index_name": models.IndexDefinition('indexed_field')}),
                models.TableMeta.TABLE_STATUS_ACTIVE))
        self.storage_mocker.ReplayAll()

        Table.create("test",
                     schema=[
                         fields.HashKey('hash', data_type=schema_types.NUMBER),
                     ],
                     throughput={
                         'read': 20,
                         'write': 10,
                     },
                     indexes=[
                         fields.KeysOnlyIndex(
                             'index_name',
                             parts=[
                                 fields.RangeKey('indexed_field',
                                                 data_type=schema_types.STRING)
                             ])
                     ],
                     connection=self.DYNAMODB_CON)

        self.storage_mocker.VerifyAll()
示例#2
0
    def test_describe_table(self):

        self.storage_mocker.StubOutWithMock(storage, 'describe_table')

        storage.describe_table(IgnoreArg(), 'test_table').AndReturn(
            models.TableMeta(
                models.TableSchema(
                    {
                        'city1': models.ATTRIBUTE_TYPE_STRING,
                        'id': models.ATTRIBUTE_TYPE_STRING,
                        'name': models.ATTRIBUTE_TYPE_STRING
                    }, ['id', 'name'],
                    {'index_name': models.IndexDefinition('city1')}),
                models.TableMeta.TABLE_STATUS_ACTIVE))

        self.storage_mocker.ReplayAll()

        table = Table('test_table', connection=self.DYNAMODB_CON)

        table_description = table.describe()

        self.storage_mocker.VerifyAll()

        self.assertEquals('test_table',
                          table_description['Table']['TableName'])
        self.assertItemsEqual([{
            "AttributeName": "city1",
            "AttributeType": "S"
        }, {
            "AttributeName": "id",
            "AttributeType": "S"
        }, {
            "AttributeName": "name",
            "AttributeType": "S"
        }], table_description['Table']['AttributeDefinitions'])
示例#3
0
    def parse_local_secondary_index(cls, local_secondary_index_json):
        key_attrs_for_projection = cls.parse_key_schema(
            local_secondary_index_json.get(Props.KEY_SCHEMA, {})
        )
        hash_key = key_attrs_for_projection[0]

        try:
            range_key = key_attrs_for_projection[1]
        except IndexError:
            raise exception.AWSValidationException(
                "Range key in index wasn't specified"
            )

        index_name = local_secondary_index_json[Props.INDEX_NAME]

        projection_type = local_secondary_index_json.get(
            Props.PROJECTION_TYPE, Values.PROJECTION_TYPE_INCLUDE
        )

        if projection_type == Values.PROJECTION_TYPE_ALL:
            projected_attrs = None
        elif projection_type == Values.PROJECTION_TYPE_KEYS_ONLY:
            projected_attrs = frozenset()
        else:
            projected_attrs = local_secondary_index_json.get(
                Props.NON_KEY_ATTRIBUTES, None
            )

        return index_name, models.IndexDefinition(hash_key,
                                                  range_key,
                                                  projected_attrs)
示例#4
0
    def test_delete_table(self):
        self.storage_mocker.StubOutWithMock(storage, 'delete_table')
        self.storage_mocker.StubOutWithMock(storage, 'describe_table')
        storage.delete_table(mox.IgnoreArg(), 'test_table')

        storage.describe_table(mox.IgnoreArg(), 'test_table').AndReturn(
            models.TableMeta(
                '00000000-0000-0000-0000-000000000000',
                models.TableSchema(
                    {
                        'city1': models.AttributeType('S'),
                        'id': models.AttributeType('S'),
                        'name': models.AttributeType('S')
                    },
                    ['id', 'name'],
                    {'index_name': models.IndexDefinition('id', 'city1')}
                ),
                models.TableMeta.TABLE_STATUS_ACTIVE,
                None
            )
        )

        self.storage_mocker.ReplayAll()

        table = ddb_table.Table(
            'test_table',
            connection=self.DYNAMODB_CON
        )

        self.assertTrue(table.delete())

        self.storage_mocker.VerifyAll()
示例#5
0
    def test_create_table(self):
        self.storage_mocker.StubOutWithMock(storage, 'create_table')
        storage.create_table(
            mox.IgnoreArg(), mox.IgnoreArg(), mox.IgnoreArg()
        ).AndReturn(
            models.TableMeta(
                '00000000-0000-0000-0000-000000000000',
                models.TableSchema(
                    {
                        'hash': models.AttributeType('N'),
                        'range': models.AttributeType('S'),
                        'indexed_field': models.AttributeType('S')
                    },
                    ['hash', 'range'],
                    {
                        "index_name": models.IndexDefinition('hash',
                                                             'indexed_field')
                    }
                ),
                models.TableMeta.TABLE_STATUS_ACTIVE,
                None
            )
        )
        self.storage_mocker.ReplayAll()

        ddb_table.Table.create(
            "test",
            schema=[
                fields.HashKey('hash', data_type=schema_types.NUMBER),
                fields.RangeKey('range', data_type=schema_types.STRING)
            ],
            throughput={
                'read': 20,
                'write': 10,
            },
            indexes=[
                fields.KeysOnlyIndex(
                    'index_name',
                    parts=[
                        fields.HashKey('hash', data_type=schema_types.NUMBER),
                        fields.RangeKey('indexed_field',
                                        data_type=schema_types.STRING)
                    ]
                )
            ],
            connection=self.DYNAMODB_CON
        )

        self.storage_mocker.VerifyAll()
示例#6
0
    def parse_local_secondary_index(cls, local_secondary_index_json):
        key_attrs_json = local_secondary_index_json.pop(Props.KEY_SCHEMA, None)
        validation.validate_list(key_attrs_json, Props.KEY_SCHEMA)
        key_attrs_for_projection = cls.parse_key_schema(key_attrs_json)
        hash_key = key_attrs_for_projection[0]

        try:
            range_key = key_attrs_for_projection[1]
        except IndexError:
            raise exception.ValidationError(
                _("Range key in index wasn't specified"))

        index_name = local_secondary_index_json.pop(Props.INDEX_NAME, None)
        validation.validate_index_name(index_name)

        projection_json = local_secondary_index_json.pop(
            Props.PROJECTION, None)
        validation.validate_object(projection_json, Props.PROJECTION)

        validation.validate_unexpected_props(local_secondary_index_json,
                                             "local_secondary_index")

        projection_type = projection_json.pop(Props.PROJECTION_TYPE,
                                              Values.PROJECTION_TYPE_INCLUDE)

        if projection_type == Values.PROJECTION_TYPE_ALL:
            projected_attrs = None
        elif projection_type == Values.PROJECTION_TYPE_KEYS_ONLY:
            projected_attrs = tuple()
        elif projection_type == Values.PROJECTION_TYPE_INCLUDE:
            projected_attrs = projection_json.pop(Props.NON_KEY_ATTRIBUTES,
                                                  None)
        else:
            raise exception.ValidationError(
                _("Only '%(pt_all)', '%(pt_ko)' of '%(pt_incl)' projection "
                  "types are allowed, but '%(projection_type)s' is found"),
                pt_all=Values.PROJECTION_TYPE_ALL,
                pt_ko=Values.PROJECTION_TYPE_KEYS_ONLY,
                pt_incl=Values.PROJECTION_TYPE_INCLUDE,
                projection_type=projection_type)
        validation.validate_unexpected_props(projection_json, Props.PROJECTION)

        return index_name, models.IndexDefinition(hash_key, range_key,
                                                  projected_attrs)
示例#7
0
    def test_delete_table(self):
        self.storage_mocker.StubOutWithMock(storage, 'delete_table')
        self.storage_mocker.StubOutWithMock(storage, 'describe_table')
        storage.delete_table(IgnoreArg(), 'test_table')

        storage.describe_table(IgnoreArg(), 'test_table').AndReturn(
            models.TableMeta(
                models.TableSchema(
                    {
                        'city1': models.ATTRIBUTE_TYPE_STRING,
                        'id': models.ATTRIBUTE_TYPE_STRING,
                        'name': models.ATTRIBUTE_TYPE_STRING
                    }, ['id', 'name'],
                    {'index_name': models.IndexDefinition('city1')}),
                models.TableMeta.TABLE_STATUS_ACTIVE))

        self.storage_mocker.ReplayAll()

        table = Table('test_table', connection=self.DYNAMODB_CON)

        self.assertTrue(table.delete())

        self.storage_mocker.VerifyAll()
示例#8
0
    def test_describe_table(self, mock_describe_table):

        attr_map = {
            'ForumName': models.AttributeType('S'),
            'Subject': models.AttributeType('S'),
            'LastPostDateTime': models.AttributeType('S')
        }

        key_attrs = ['ForumName', 'Subject']

        index_map = {
            'LastPostIndex':
            models.IndexDefinition('ForumName', 'LastPostDateTime')
        }

        table_meta = models.TableMeta(
            '00000000-0000-0000-0000-000000000000',
            models.TableSchema(attr_map, key_attrs, index_map),
            models.TableMeta.TABLE_STATUS_ACTIVE, 123)

        mock_describe_table.return_value = table_meta

        headers = {
            'Content-Type': 'application/json',
            'Accept': 'application/json'
        }

        conn = httplib.HTTPConnection('localhost:8080')
        url = '/v1/data/default_tenant/tables/Thread'

        table_url = ('http://localhost:8080/v1/data/default_tenant'
                     '/tables/Thread')
        expected_response = {
            'table': {
                'attribute_definitions': [{
                    'attribute_name': 'Subject',
                    'attribute_type': 'S'
                }, {
                    'attribute_name': 'LastPostDateTime',
                    'attribute_type': 'S'
                }, {
                    'attribute_name': 'ForumName',
                    'attribute_type': 'S'
                }],
                'creation_date_time':
                123,
                'item_count':
                0,
                'key_schema': [{
                    'attribute_name': 'ForumName',
                    'key_type': 'HASH'
                }, {
                    'attribute_name': 'Subject',
                    'key_type': 'RANGE'
                }],
                'local_secondary_indexes': [{
                    'index_name':
                    'LastPostIndex',
                    'index_size_bytes':
                    0,
                    'item_count':
                    0,
                    'key_schema': [{
                        'attribute_name': 'ForumName',
                        'key_type': 'HASH'
                    }, {
                        'attribute_name': 'LastPostDateTime',
                        'key_type': 'RANGE'
                    }],
                    'projection': {
                        'projection_type': 'ALL'
                    }
                }],
                'table_id':
                '00000000-0000-0000-0000-000000000000',
                'table_name':
                'Thread',
                'table_size_bytes':
                0,
                'table_status':
                'ACTIVE',
                'links': [{
                    'href': table_url,
                    'rel': 'self'
                }, {
                    'href': table_url,
                    'rel': 'bookmark'
                }]
            }
        }

        conn.request("GET", url, headers=headers)

        response = conn.getresponse()

        self.assertTrue(mock_describe_table.called)

        json_response = response.read()
        response_payload = json.loads(json_response)

        self.assertEqual(expected_response, response_payload)
示例#9
0
    def test_create_table(self, mock_create_table):
        mock_create_table.return_value = models.TableMeta(
            '00000000-0000-0000-0000-000000000000',
            models.TableSchema(attribute_type_map={
                "ForumName": models.AttributeType('S'),
                "Subject": models.AttributeType('S'),
                "LastPostDateTime": models.AttributeType('S')
            },
                               key_attributes=["ForumName", "Subject"],
                               index_def_map={
                                   "LastPostIndex":
                                   models.IndexDefinition(
                                       "ForumName", "LastPostDateTime")
                               }), models.TableMeta.TABLE_STATUS_ACTIVE, 123)

        conn = httplib.HTTPConnection('localhost:8080')
        body = """
            {
                "attribute_definitions": [
                    {
                        "attribute_name": "ForumName",
                        "attribute_type": "S"
                    },
                    {
                        "attribute_name": "Subject",
                        "attribute_type": "S"
                    },
                    {
                        "attribute_name": "LastPostDateTime",
                        "attribute_type": "S"
                    }
                ],
                "table_name": "Thread",
                "key_schema": [
                    {
                        "attribute_name": "ForumName",
                        "key_type": "HASH"
                    },
                    {
                        "attribute_name": "Subject",
                        "key_type": "RANGE"
                    }
                ],
                "local_secondary_indexes": [
                    {
                        "index_name": "LastPostIndex",
                        "key_schema": [
                            {
                                "attribute_name": "ForumName",
                                "key_type": "HASH"
                            },
                            {
                                "attribute_name": "LastPostDateTime",
                                "key_type": "RANGE"
                            }
                        ],
                        "projection": {
                            "projection_type": "KEYS_ONLY"
                        }
                    }
                ]
            }
        """

        expected_response = {
            'table_description': {
                'attribute_definitions': [{
                    'attribute_name': 'Subject',
                    'attribute_type': 'S'
                }, {
                    'attribute_name': 'LastPostDateTime',
                    'attribute_type': 'S'
                }, {
                    'attribute_name': 'ForumName',
                    'attribute_type': 'S'
                }],
                'creation_date_time':
                123,
                'item_count':
                0,
                'key_schema': [{
                    'attribute_name': 'ForumName',
                    'key_type': 'HASH'
                }, {
                    'attribute_name': 'Subject',
                    'key_type': 'RANGE'
                }],
                'local_secondary_indexes': [{
                    'index_name':
                    'LastPostIndex',
                    'index_size_bytes':
                    0,
                    'item_count':
                    0,
                    'key_schema': [{
                        'attribute_name': 'ForumName',
                        'key_type': 'HASH'
                    }, {
                        'attribute_name': 'LastPostDateTime',
                        'key_type': 'RANGE'
                    }],
                    'projection': {
                        'projection_type': 'ALL'
                    }
                }],
                'table_id':
                '00000000-0000-0000-0000-000000000000',
                'table_name':
                'Thread',
                'table_size_bytes':
                0,
                'table_status':
                'ACTIVE',
                'links': [{
                    'href': self.table_url,
                    'rel': 'self'
                }, {
                    'href': self.table_url,
                    'rel': 'bookmark'
                }]
            }
        }

        conn.request("POST", self.url, headers=self.headers, body=body)

        response = conn.getresponse()

        self.assertTrue(mock_create_table.called)

        json_response = response.read()
        response_payload = json.loads(json_response)

        self.assertEqual(expected_response, response_payload)
示例#10
0
    def test_create_table_duplicate(self):
        self.storage_mocker.StubOutWithMock(storage, 'create_table')
        storage.create_table(IgnoreArg(), IgnoreArg(), IgnoreArg()).AndReturn(
            models.TableMeta(
                models.TableSchema(
                    {
                        'hash': models.ATTRIBUTE_TYPE_NUMBER,
                        'range': models.ATTRIBUTE_TYPE_STRING,
                        'indexed_field': models.ATTRIBUTE_TYPE_STRING
                    }, ['hash', 'range'],
                    {"index_name": models.IndexDefinition('indexed_field')}),
                models.TableMeta.TABLE_STATUS_ACTIVE))
        storage.create_table(IgnoreArg(), IgnoreArg(),
                             IgnoreArg()).AndRaise(TableAlreadyExistsException)
        self.storage_mocker.ReplayAll()

        Table.create("test",
                     schema=[
                         fields.HashKey('hash', data_type=schema_types.NUMBER),
                         fields.RangeKey('range',
                                         data_type=schema_types.STRING)
                     ],
                     throughput={
                         'read': 20,
                         'write': 10,
                     },
                     indexes=[
                         fields.KeysOnlyIndex(
                             'index_name',
                             parts=[
                                 fields.RangeKey('indexed_field',
                                                 data_type=schema_types.STRING)
                             ])
                     ],
                     connection=self.DYNAMODB_CON)

        try:
            Table.create("test",
                         schema=[
                             fields.HashKey('hash',
                                            data_type=schema_types.NUMBER),
                             fields.RangeKey('range',
                                             data_type=schema_types.STRING)
                         ],
                         throughput={
                             'read': 20,
                             'write': 10,
                         },
                         indexes=[
                             fields.KeysOnlyIndex(
                                 'index_name',
                                 parts=[
                                     fields.RangeKey(
                                         'indexed_field',
                                         data_type=schema_types.STRING)
                                 ])
                         ],
                         connection=self.DYNAMODB_CON)

            self.fail()
        except JSONResponseError as e:
            self.assertEqual('ResourceInUseException', e.error_code)
            self.storage_mocker.VerifyAll()
        except Exception as e:
            self.fail()
示例#11
0
    def test_create_table_duplicate(self):
        self.storage_mocker.StubOutWithMock(storage, 'create_table')
        storage.create_table(
            mox.IgnoreArg(), mox.IgnoreArg(), mox.IgnoreArg()
        ).AndReturn(
            models.TableMeta(
                '00000000-0000-0000-0000-000000000000',
                models.TableSchema(
                    {
                        'hash': models.AttributeType('N'),
                        'range': models.AttributeType('S'),
                        'indexed_field': models.AttributeType('S')
                    },
                    ['hash', 'range'],
                    {
                        "index_name": models.IndexDefinition('hash',
                                                             'indexed_field')
                    }
                ),
                models.TableMeta.TABLE_STATUS_ACTIVE,
                None
            )
        )
        storage.create_table(
            mox.IgnoreArg(), mox.IgnoreArg(), mox.IgnoreArg()
        ).AndRaise(exception.TableAlreadyExistsException)
        self.storage_mocker.ReplayAll()

        ddb_table.Table.create(
            "test",
            schema=[
                fields.HashKey('hash', data_type=schema_types.NUMBER),
                fields.RangeKey('range', data_type=schema_types.STRING)
            ],
            throughput={
                'read': 20,
                'write': 10,
            },
            indexes=[
                fields.KeysOnlyIndex(
                    'index_name',
                    parts=[
                        fields.HashKey('hash', data_type=schema_types.NUMBER),
                        fields.RangeKey('indexed_field',
                                        data_type=schema_types.STRING)
                    ]
                )
            ],
            connection=self.DYNAMODB_CON
        )

        try:
            ddb_table.Table.create(
                "test",
                schema=[
                    fields.HashKey('hash', data_type=schema_types.NUMBER),
                    fields.RangeKey('range', data_type=schema_types.STRING)
                ],
                throughput={
                    'read': 20,
                    'write': 10,
                },
                indexes=[
                    fields.KeysOnlyIndex(
                        'index_name',
                        parts=[
                            fields.HashKey('hash',
                                           data_type=schema_types.NUMBER),
                            fields.RangeKey('indexed_field',
                                            data_type=schema_types.STRING)
                        ]
                    )
                ],
                connection=self.DYNAMODB_CON
            )

            self.fail()
        except boto_exc.JSONResponseError as e:
            self.assertEqual('ResourceInUseException', e.error_code)
            self.assertEqual('Table already exists: test', e.body['message'])
            self.storage_mocker.VerifyAll()
        except Exception as e:
            self.fail()