예제 #1
0
def test_tar_resource_storage():
    module = Engine(INSTANCE_TEST_SCHEMA).render_python_module()
    valid_data = {
        "Archive.archive":
        ARCHIVE_SIGNATURE_PAYLOAD,
        "Archive.archive.schema":
        module.backward_compatibility_Archive.schema().encode(),
        "resource":
        RESOURCE_PAYLOAD,
        "resource.schema":
        module.backward_compatibility_Archive.resource_schema(
            'resource').encode()
    }

    with tempfile.TemporaryDirectory() as tmpdir:
        archive_path = os.path.join(tmpdir, "archive.tar")
        cwd = os.getcwd()
        os.chdir(tmpdir)
        tar = tarfile.open(archive_path, "w")
        for key, value in valid_data.items():
            with open(os.path.join(tmpdir, key), "wb") as file:
                file.write(value)
            tar.add(key)
        tar.close()
        os.chdir(cwd)

        archive = module.backward_compatibility_Archive(
            TarArchiveResourceStorage.create(archive_path))
        check_signed_struct(archive.resource)
예제 #2
0
def test_create_vector_archive():
    module = Engine(VECTOR_TEST_SCHEMA).render_python_module()
    memwrite = DummyResourceWriter()

    builder = module.backward_compatibility_ArchiveBuilder(memwrite)
    builder.set("resource", [{
        "a": -0x1,
        "b": 0x01234567,
        "c": -0x28,
        "d": 0
    }] * 2)
    builder.finish()

    valid_data = {
        "Archive.archive":
        ARCHIVE_SIGNATURE_PAYLOAD,
        "Archive.archive.schema":
        module.backward_compatibility_Archive.schema().encode(),
        "resource":
        RESOURCE_VECTOR_PAYLOAD,
        "resource.schema":
        module.backward_compatibility_Archive.resource_schema(
            'resource').encode()
    }

    for (vkey, vdata) in valid_data.items():
        assert memwrite.data[vkey].get_data(
        ) == vdata, f'"{vkey}" is "{memwrite.data[vkey]}", should be "{vdata}"'
예제 #3
0
def test_raw_data_reading():
    raw_data_test_schema = """
namespace backward_compatibility {
    archive Archive {
        resource: raw_data;
    }
}
"""

    raw_data_resource_data = (
        b"\x05\x00\x00\x00\x00\x00\x00\x00"  # Payload size in bytes
        b"\xff\xef\xbe\xad\xde"  # Payload
        b"\x00\x00\x00\x00\x00\x00\x00\x00"  # Padding
    )

    module = Engine(raw_data_test_schema).render_python_module()
    valid_data = {
        "Archive.archive":
        ARCHIVE_SIGNATURE_PAYLOAD,
        "Archive.archive.schema":
        module.backward_compatibility_Archive.schema().encode(),
        "resource":
        raw_data_resource_data,
        "resource.schema":
        module.backward_compatibility_Archive.resource_schema(
            'resource').encode(),
    }

    archive = module.backward_compatibility_Archive(
        DictResourceStorage(valid_data))
    eq_(5, len(archive.resource))
    eq_(b"\xff", archive.resource[0])
    eq_(b"\xde", archive.resource[4])
    eq_(b"\xff\xef\xbe\xad\xde", archive.resource[0:5])
예제 #4
0
파일: app.py 프로젝트: stiar/flatdata
def _run(args):
    _setup_logging(args)
    _check_args(args)

    with open(args.schema, 'r') as input_file:
        schema = input_file.read()
        try:
            engine = Engine(schema)
            logging.debug("Tree: %s", engine.tree)
        except FlatdataSyntaxError as ex:
            logging.fatal("Error reading schema: %s ", ex)
            sys.exit(1)

    try:
        logging.info("Generating %s...", args.gen)
        output_content = engine.render(args.gen)
    except ValueError as ex:
        logging.fatal("%s", ex)
        sys.exit(1)

    dirname = os.path.dirname(os.path.abspath(args.output_file))
    if not os.path.exists(dirname):
        os.makedirs(dirname)
    with open(args.output_file, "w") as output:
        output.write(output_content)
        logging.info("Code for %s is written to %s", args.gen,
                     args.output_file)
예제 #5
0
파일: app.py 프로젝트: stiar/flatdata
def _parse_command_line():
    parser = argparse.ArgumentParser(
        description="Generates code for a given flatdata schema file.")
    parser.add_argument("-s",
                        "--schema",
                        type=str,
                        required=True,
                        help="Path to the flatdata schema file")
    parser.add_argument(
        "-g",
        "--gen",
        type=str,
        required=True,
        help="Language to generate bindings for. Supported values: %s" %
        (', '.join(Engine.available_generators())))
    parser.add_argument(
        "-O",
        "--output-file",
        type=str,
        required=True,
        default=None,
        help="Destination file. Forces all output to be stored in one file")
    parser.add_argument("-v",
                        "--verbose",
                        action="store_true",
                        help="Enable verbose mode")
    parser.add_argument("--debug",
                        action="store_true",
                        help="Enable debug output")
    return parser.parse_args()
예제 #6
0
def test_instance_reading():
    module = Engine(INSTANCE_TEST_SCHEMA).render_python_module()
    valid_data = {
        "Archive.archive":
        ARCHIVE_SIGNATURE_PAYLOAD,
        "Archive.archive.schema":
        module.backward_compatibility_Archive.schema().encode(),
        "resource":
        RESOURCE_PAYLOAD,
        "resource.schema":
        module.backward_compatibility_Archive.resource_schema(
            'resource').encode()
    }
    archive = module.backward_compatibility_Archive(
        DictResourceStorage(valid_data))
    check_signed_struct(archive.resource)
def test_multivector_reading():
    module = Engine(MULTIVECTOR_TEST_SCHEMA).render_python_module()
    valid_data = {
        "Archive.archive":
        ARCHIVE_SIGNATURE_PAYLOAD,
        "Archive.archive.schema":
        module.backward_compatibility_Archive.schema().encode(),
        "resource":
        MULTIVECTOR_RESOURCE_DATA,
        "resource.schema":
        module.backward_compatibility_Archive.resource_schema(
            'resource').encode(),
        "resource_index":
        MULTIVECTOR_RESOURCE_INDEX,
        "resource_index.schema":
        module.backward_compatibility_Archive.resource_schema(
            'resource').encode()
    }

    archive = module.backward_compatibility_Archive(
        DictResourceStorage(valid_data))
    eq_(5, len(archive.resource))

    eq_(2, len(archive.resource[0]))
    assert_is_instance(archive.resource[0][0],
                       module.backward_compatibility_SignedStruct)
    check_signed_struct(archive.resource[0][0])
    assert_is_instance(archive.resource[0][1],
                       module.backward_compatibility_SimpleStruct)
    check_simple_struct(archive.resource[0][1])

    eq_(0, len(archive.resource[1]))

    eq_(2, len(archive.resource[2]))
    assert_is_instance(archive.resource[2][0],
                       module.backward_compatibility_SimpleStruct)
    check_simple_struct(archive.resource[2][0])
    assert_is_instance(archive.resource[2][1],
                       module.backward_compatibility_SignedStruct)
    check_signed_struct(archive.resource[2][1])

    eq_(1, len(archive.resource[3]))
    assert_is_instance(archive.resource[3][0],
                       module.backward_compatibility_SimpleStruct)
    check_simple_struct(archive.resource[3][0])
예제 #8
0
def test_archive_does_not_open_on_signature_resource_or_schemas_missing():
    module = Engine(INSTANCE_TEST_SCHEMA).render_python_module()
    valid_data = {
        "Archive.archive":
        ARCHIVE_SIGNATURE_PAYLOAD,
        "Archive.archive.schema":
        module.backward_compatibility_Archive.schema().encode(),
        "resource":
        RESOURCE_PAYLOAD,
        "resource.schema":
        module.backward_compatibility_Archive.resource_schema(
            'resource').encode()
    }

    missing_signature = valid_data.copy()
    del missing_signature["Archive.archive"]

    corrupt_signature = valid_data.copy()
    corrupt_signature["Archive.archive"] = b'\xde\xad\xbe\xef'

    corrupt_signature_more_than_8_bytes = valid_data.copy()
    corrupt_signature_more_than_8_bytes[
        "Archive.archive"] = b'\xde\xad\xbe\xef\0\0\0\0\0\0\0\0'

    missing_schema = valid_data.copy()
    del missing_schema["Archive.archive.schema"]

    corrupt_schema = valid_data.copy()
    corrupt_schema["Archive.archive.schema"] = b"foo"

    missing_resource = valid_data.copy()
    del missing_resource["resource"]

    missing_resource_schema = valid_data.copy()
    del missing_resource_schema["resource.schema"]

    corrupt_resource_schema = valid_data.copy()
    corrupt_resource_schema["resource.schema"] = b"foo"

    datasets = [
        (missing_signature, CorruptArchiveError),
        (corrupt_signature, CorruptArchiveError),
        (missing_schema, CorruptArchiveError),
        (corrupt_schema, SchemaMismatchError),
        (missing_resource, CorruptArchiveError),
        (missing_resource_schema, CorruptArchiveError),
        (corrupt_resource_schema, SchemaMismatchError),
    ]

    def _test(index, data, error_type):
        with assert_raises(error_type):
            module.backward_compatibility_Archive(DictResourceStorage(data))

    for index, payload in enumerate(datasets):
        data, error_type = payload
        yield _test, index, data, error_type
def test_raw_data_reading():
    module = Engine(RAW_DATA_TEST_SCHEMA).render_python_module()
    valid_data = {
        "Archive.archive":
        ARCHIVE_SIGNATURE_PAYLOAD,
        "Archive.archive.schema":
        module.backward_compatibility_Archive.schema().encode(),
        "resource":
        RAW_DATA_RESOURCE_DATA,
        "resource.schema":
        module.backward_compatibility_Archive.resource_schema(
            'resource').encode(),
    }

    archive = module.backward_compatibility_Archive(
        DictResourceStorage(valid_data))
    eq_(5, len(archive.resource))
    eq_(b"\xff", archive.resource[0])
    eq_(b"\xde", archive.resource[4])
    eq_(b"\xff\xef\xbe\xad\xde", archive.resource[0:5])
예제 #10
0
def test_vector_reading():
    vector_test_schema = """
namespace backward_compatibility {
    struct SignedStruct {
        a : i16 : 5;
        b : u32 : 32;
        c : i32 : 7;
        d : u32 : 32;
    }
    archive Archive {
        resource: vector< SignedStruct >;
    }
}
"""

    RESOURCE_PAYLOAD = (
        b"\x14\x00\x00\x00\x00\x00\x00\x00"  # Payload size in bytes
        b"\xff\xac\x68\x24\x00\x0b\x00\x00"  # Payload
        b"\x00\x00\xff\xac\x68\x24\x00\x0b"  # Payload
        b"\x00\x00\x00\x00"  # Payload
        b"\x00\x00\x00\x00\x00\x00\x00\x00"  # Padding
    )

    module = Engine(vector_test_schema).render_python_module()
    valid_data = {
        "Archive.archive":
        ARCHIVE_SIGNATURE_PAYLOAD,
        "Archive.archive.schema":
        module.backward_compatibility_Archive.schema().encode(),
        "resource":
        RESOURCE_PAYLOAD,
        "resource.schema":
        module.backward_compatibility_Archive.resource_schema(
            'resource').encode()
    }

    archive = module.backward_compatibility_Archive(
        DictResourceStorage(valid_data))
    eq_(2, len(archive.resource))
    check_signed_struct(archive.resource[0])
    check_signed_struct(archive.resource[1])
예제 #11
0
def test_create_raw_data():
    module = Engine(RAW_DATA_TEST_SCHEMA).render_python_module()
    memwrite = DummyResourceWriter()

    builder = module.backward_compatibility_ArchiveBuilder(memwrite)
    builder.set("resource", b"\xff\xef\xbe\xad\xde")
    builder.finish()

    valid_data = {
        "Archive.archive":
        ARCHIVE_SIGNATURE_PAYLOAD,
        "Archive.archive.schema":
        module.backward_compatibility_Archive.schema().encode(),
        "resource":
        RAW_DATA_RESOURCE_DATA,
        "resource.schema":
        module.backward_compatibility_Archive.resource_schema(
            'resource').encode(),
    }

    for (vkey, vdata) in valid_data.items():
        assert memwrite.data[vkey].get_data(
        ) == vdata, f'"{vkey}" is "{memwrite.data[vkey]}", should be "{vdata}"'
예제 #12
0
def open_archive(path, archive=None, module_name=None):
    """
    Opens archive at a given path.
    Archive schema is read and python bindings are generated on the fly.

    :param path: Path to archive
    :param archive: Archive name to open (in case multiple archives reside in one directory)
                    if None, will be implied. If cannot be implied, RuntimeError is raised.
    :param module_name: Module name to create. If None, will match the highest-level namespace.
    :return: tuple archive, module
    """
    if not os.path.exists(path):
        raise RuntimeError("Specified non-existent path %s" % path)

    is_tar = path.endswith(".tar") and not os.path.isdir(path)
    archive_path = path if is_tar or os.path.isdir(path) else os.path.dirname(path)
    if is_tar:
        storage = TarArchiveResourceStorage.create(archive_path)
    else:
        storage = FileResourceStorage(archive_path)

    signatures = [p for p in storage.ls() if fnmatch.fnmatch(p, "*.archive")]

    if not signatures:
        raise RuntimeError("No archives located at path %s" % path)

    if len(signatures) > 1 and archive is None:
        raise RuntimeError(
            "Multiple archives found at given path %s\nPlease specify archive name. Found: %s" %
            (path, signatures))

    matching = 0
    if archive is not None:
        try:
            matching = signatures.index(archive + ".archive")
        except ValueError:
            raise RuntimeError("Specified archive not found at path.")

    archive_name, _ = signatures[matching].rsplit('.', 1)
    schema = storage.get(signatures[matching] + ".schema")

    try:
        module, archive_type = \
            Engine(schema.read().decode()).render_python_module(module_name=module_name,
                                                                archive_name=archive_name)
    except FlatdataSyntaxError as err:
        raise RuntimeError("Error reading schema: %s " % err)

    archive = archive_type(storage)
    return archive, module
예제 #13
0
    def __init__(self, archive_schema, path, archive_name=""):
        '''
        Creates instance or Writer class. Archive module is rendered by engine
        using provided schema.

        :param archive_schema(str): flatdata schema
        :param path(str): file path where flatdata files are created
        '''
        try:
            if not archive_name:
                archive_name = Writer._get_archive_name(archive_schema)
            _, archive_type = Engine(archive_schema).render_python_module(
                archive_name=archive_name + "Builder")
        except FlatdataSyntaxError as err:
            raise RuntimeError(
                "Error in generating modules from provided schema: %s " % err)

        self.builder = archive_type(ResourceStorage(FileResourceWriter(),
                                                    path))
예제 #14
0
def test_create_multivector_archive():
    multivector_data = [[{
        "name": "backward_compatibility_SignedStruct",
        "attributes": {
            "a": -1,
            "b": 19088743,
            "c": -40,
            "d": 0
        }
    }, {
        "name": "backward_compatibility_SimpleStruct",
        "attributes": {
            "a": 4294967295,
            "b": 3735928559
        }
    }], [],
                        [{
                            "name": "backward_compatibility_SimpleStruct",
                            "attributes": {
                                "a": 4294967295,
                                "b": 3735928559
                            }
                        }, {
                            "name": "backward_compatibility_SignedStruct",
                            "attributes": {
                                "a": -1,
                                "b": 19088743,
                                "c": -40,
                                "d": 0
                            }
                        }],
                        [{
                            "name": "backward_compatibility_SimpleStruct",
                            "attributes": {
                                "a": 4294967295,
                                "b": 3735928559
                            }
                        }]]

    module = Engine(MULTIVECTOR_TEST_SCHEMA).render_python_module()
    memwrite = DummyResourceWriter()

    builder = module.backward_compatibility_ArchiveBuilder(memwrite)
    builder.set("resource", multivector_data)
    builder.finish()

    valid_data = {
        "Archive.archive":
        ARCHIVE_SIGNATURE_PAYLOAD,
        "Archive.archive.schema":
        module.backward_compatibility_Archive.schema().encode(),
        "resource":
        MULTIVECTOR_RESOURCE_DATA,
        "resource.schema":
        module.backward_compatibility_Archive.resource_schema(
            'resource').encode(),
        "resource_index":
        MULTIVECTOR_RESOURCE_INDEX,
        "resource_index.schema":
        bytearray(
            f'index({module.backward_compatibility_Archive.resource_schema("resource")})'
            .encode())
    }

    for (vkey, vdata) in valid_data.items():
        assert memwrite.data[vkey].get_data(
        ) == vdata, f'"{vkey}" is "{memwrite.data[vkey]}", should be "{vdata}"'
예제 #15
0
def test_multivector_reading():
    multivector_test_schema = """
namespace backward_compatibility {
    struct SimpleStruct {
        a : u32 : 32;
        b : u32 : 32;
    }
    struct SignedStruct {
        a : i16 : 5;
        b : u32 : 32;
        c : i32 : 7;
        d : u32 : 32;
    }
    archive Archive {
        resource: multivector< 33, SimpleStruct, SignedStruct >;
    }
}
"""

    multivector_resource_data = (
        b"\x31\x00\x00\x00\x00\x00\x00\x00"  # Payload size in bytes
        b"\x01\xff\xac\x68\x24\x00\x0b\x00\x00\x00\x00"  # Payload
        b"\x00\xff\xff\xff\xff\xef\xbe\xad\xde"  # Payload
        b"\x00\xff\xff\xff\xff\xef\xbe\xad\xde"  # Payload
        b"\x01\xff\xac\x68\x24\x00\x0b\x00\x00\x00\x00"  # Payload
        b"\x00\xff\xff\xff\xff\xef\xbe\xad\xde"  # Payload
        b"\x00\x00\x00\x00\x00\x00\x00\x00"  # Padding
    )

    multivector_resource_index = (
        b"\x19\x00\x00\x00\x00\x00\x00\x00"  # Index size in bytes
        b"\x00\x00\x00\x00\x00"  # Data pointer 1
        b"\x14\x00\x00\x00\x00"  # Data pointer 2
        b"\x14\x00\x00\x00\x00"  # Data pointer 3
        b"\x28\x00\x00\x00\x00"  # Data pointer 4
        b"\x31\x00\x00\x00\x00"  # Sentinel (end of data 4)
        b"\x00\x00\x00\x00\x00\x00\x00\x00"  # Padding
    )

    module = Engine(multivector_test_schema).render_python_module()
    valid_data = {
        "Archive.archive":
        ARCHIVE_SIGNATURE_PAYLOAD,
        "Archive.archive.schema":
        module.backward_compatibility_Archive.schema().encode(),
        "resource":
        multivector_resource_data,
        "resource.schema":
        module.backward_compatibility_Archive.resource_schema(
            'resource').encode(),
        "resource_index":
        multivector_resource_index,
        "resource_index.schema":
        module.backward_compatibility_Archive.resource_schema(
            'resource').encode()
    }

    archive = module.backward_compatibility_Archive(
        DictResourceStorage(valid_data))
    eq_(5, len(archive.resource))

    eq_(2, len(archive.resource[0]))
    assert_is_instance(archive.resource[0][0],
                       module.backward_compatibility_SignedStruct)
    check_signed_struct(archive.resource[0][0])
    assert_is_instance(archive.resource[0][1],
                       module.backward_compatibility_SimpleStruct)
    check_simple_struct(archive.resource[0][1])

    eq_(0, len(archive.resource[1]))

    eq_(2, len(archive.resource[2]))
    assert_is_instance(archive.resource[2][0],
                       module.backward_compatibility_SimpleStruct)
    check_simple_struct(archive.resource[2][0])
    assert_is_instance(archive.resource[2][1],
                       module.backward_compatibility_SignedStruct)
    check_signed_struct(archive.resource[2][1])

    eq_(1, len(archive.resource[3]))
    assert_is_instance(archive.resource[3][0],
                       module.backward_compatibility_SimpleStruct)
    check_simple_struct(archive.resource[3][0])