=== added file 'linaro-hwpack-convert'
--- linaro-hwpack-convert	1970-01-01 00:00:00 +0000
+++ linaro-hwpack-convert	2012-07-19 15:21:06 +0000
@@ -0,0 +1,73 @@
+#!/usr/bin/python
+# Copyright (C) 2010, 2011, 2012 Linaro
+#
+# Author: Milo Casagrande <milo.casagrande@linaro.org>
+#
+# This file is part of Linaro Image Tools.
+#
+# Linaro Image Tools is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# Linaro Image Tools is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Linaro Image Tools; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
+# USA.
+
+
+import argparse
+import logging
+import sys
+import os
+
+from linaro_image_tools.hwpack.hwpack_convert import (
+    HwpackConverter,
+    HwpackConverterException,
+    check_and_validate_args,
+    )
+from linaro_image_tools.__version__ import __version__
+
+
+def get_logger(debug=False):
+    ch = logging.StreamHandler()
+    logger = logging.getLogger("linaro_hwpack_converter")
+
+    if debug:
+        ch.setLevel(logging.DEBUG)
+        formatter = logging.Formatter(
+            "%(asctime)s - %(name)s - %(levelname)s - %(message)s")
+        ch.setFormatter(formatter)
+        logger.setLevel(logging.DEBUG)
+    else:
+        ch.setLevel(logging.INFO)
+        formatter = logging.Formatter("%(message)s")
+        ch.setFormatter(formatter)
+        logger.setLevel(logging.INFO)
+        logger.addHandler(ch)
+
+if __name__ == '__main__':
+    parser = argparse.ArgumentParser(version='%(prog)s ' + __version__)
+    parser.add_argument("CONFIG_FILE",
+                        help="The configuration file to convert.")
+    parser.add_argument("--out",
+                        help="The output file name to write. If none is "
+                            "given, the input file name (and path) will be "
+                            "used with the '.yaml' suffix.")
+    parser.add_argument("--debug", action="store_true")
+    args = parser.parse_args()
+    logger = get_logger(debug=args.debug)
+    try:
+        input_file, output_file = check_and_validate_args(args)
+        print "Converting '%s' into new YAML format..." % (input_file)
+        converter = HwpackConverter(input_file, output_file)
+    except HwpackConverterException, e:
+        sys.stderr.write(str(e) + "\n")
+        sys.exit(1)
+    converter.convert()
+    print "File '%s' converted in '%s'." % (input_file, output_file)

=== added file 'linaro_image_tools/hwpack/hwpack_convert.py'
--- linaro_image_tools/hwpack/hwpack_convert.py	1970-01-01 00:00:00 +0000
+++ linaro_image_tools/hwpack/hwpack_convert.py	2012-07-19 15:10:43 +0000
@@ -0,0 +1,297 @@
+# Copyright (C) 2010, 2011, 2012 Linaro
+#
+# Author: Milo Casagrande <milo.casagrande@linaro.org>
+#
+# This file is part of Linaro Image Tools.
+#
+# Linaro Image Tools is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# Linaro Image Tools is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Linaro Image Tools; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
+# USA.
+
+import ConfigParser
+import logging
+import os
+import os.path
+import re
+import yaml
+
+from hwpack_fields import (
+    ARCHITECTURES_FIELD,
+    ASSUME_INSTALLED_FIELD,
+    BOOTLOADERS_FIELD,
+    EXTRA_BOOT_OPTIONS_FIELD,
+    EXTRA_SERIAL_OPTIONS_FIELD,
+    SOURCES_FIELD,
+    FORMAT_FIELD,
+    PACKAGES_FIELD,
+    PACKAGE_FIELD,
+    FILE_FIELD,
+    IN_BOOT_PART_FIELD,
+    DD_FIELD,
+    ENV_DD_FIELD,
+    SPL_IN_BOOT_PART_FIELD,
+    SPL_DD_FIELD,
+    SPL_PACKAGE_FIELD,
+    SPL_FILE_FIELD,
+    WIRED_INTERFACES_FIELD,
+    WIRELESS_INTERFACES_FIELD,
+)
+
+# This is the main section of an INI-style hwpack config file.
+MAIN_SECTION = 'hwpack'
+# The suffix for the new file
+NEW_FILE_SUFFIX = '.yaml'
+# How many spaces should be used for indentation.
+INDENT_STEP = 1
+# Regular expression to convert from Yes/No values into Boolean.
+YES_REGEX = '[Yy]es'
+NO_REGEX = '[Nn]o'
+# The default format number.
+DEFAULT_FORMAT = '3.0'
+# Old INI style u_boot keys name.
+UBOOT_PACKAGE_KEY = "u_boot_package"
+UBOOT_FILE_KEY = "u_boot_file"
+UBOOT_IN_BOOT_PART_KEY = 'u_boot_in_boot_part'
+UBOOT_DD_KEY = 'u_boot_dd'
+# All the u_boot defined keys in a list.
+UBOOT_KEYS = [UBOOT_PACKAGE_KEY, UBOOT_FILE_KEY, UBOOT_IN_BOOT_PART_KEY,
+                UBOOT_DD_KEY]
+
+# Old field, the only one with a dash: since the format is new, convert it.
+ASSUME_INSTALLED_OLD = 'assume-installed'
+
+# The default bootloader for the bootloaders section.
+DEFAULT_BOOTLOADER = 'u_boot'
+
+# All the SPL keys
+SPL_KEYS = [SPL_IN_BOOT_PART_FIELD, SPL_DD_FIELD, SPL_PACKAGE_FIELD,
+            SPL_FILE_FIELD, ENV_DD_FIELD]
+
+logger = logging.getLogger("linaro_hwpack_converter")
+
+
+class HwpackConverterException(Exception):
+    """General exception class for the converter."""
+
+
+class HwpackConverter(object):
+    """Simple and basic class that converts an INI-style format file into the
+    new YAML format.
+
+    The old format number is maintained.
+
+    :param input_file: the input file to parse, has to be an INI-style file.
+    :param output_file: where to write the new file, if not given, the name
+                        of the input file will be used adding the 'yaml'
+                        suffix.
+    """
+    def __init__(self, input_file=None, output_file=None):
+        """Initializie the class."""
+        self.input_file = input_file
+        self.output_file = output_file
+
+        # Where we store the list of sources.
+        self.sources = {}
+        # Where we store all the information of the hwpack config file
+        # In this case we have one board per hwpack config file.
+        self.hwpack = {}
+        # List of supported architectures.
+        self.architectures = []
+        # Where we hold bootloaders info
+        self.bootloaders = {}
+        # List to store extra boot options.
+        self.extra_boot_options = []
+        # The list of packages.
+        self.packages = []
+        # List of the extra_serial_options.
+        self.extra_serial_options = []
+        # Lists for network interfaces.
+        self.wired_interfaces = []
+        self.wireless_interfaces = []
+        # SPL entries
+        self.spl = {}
+
+    def _parse(self):
+        """Parses the config file and stores its values."""
+        if self.input_file is not None:
+            parser = ConfigParser.RawConfigParser()
+            with open(self.input_file, 'r') as fp:
+                parser.readfp(fp)
+
+            # Iterate through all the file sections.
+            for section in parser.sections():
+                if section == MAIN_SECTION:
+                    for key, value in parser.items(section):
+                        if value is not None:
+                            if re.match("[Yy]es", value):
+                                value = True
+                            elif re.match("[Nn]o", value):
+                                value = False
+                            if key == ARCHITECTURES_FIELD:
+                                self.parse_list_string(self.architectures,
+                                                        value)
+                                continue
+                            elif key == EXTRA_BOOT_OPTIONS_FIELD:
+                                self.parse_list_string(self.extra_boot_options,
+                                                        value)
+                                continue
+                            elif key == EXTRA_SERIAL_OPTIONS_FIELD:
+                                self.parse_list_string(
+                                                    self.extra_serial_options,
+                                                    value)
+                                continue
+                            elif key == WIRED_INTERFACES_FIELD:
+                                self.parse_list_string(self.wired_interfaces,
+                                                        value)
+                                continue
+                            elif key == WIRELESS_INTERFACES_FIELD:
+                                self.parse_list_string(
+                                                    self.wireless_interfaces,
+                                                    value)
+                                continue
+                            elif key in SPL_KEYS:
+                                self.spl[key] = value
+                                continue
+                            elif key == FORMAT_FIELD:
+                                value = DEFAULT_FORMAT
+                            elif key == PACKAGES_FIELD:
+                                self.parse_list_string(self.packages, value)
+                                continue
+                            elif key in UBOOT_KEYS:
+                                self._set_bootloaders(key, value)
+                                continue
+                            # Convert an old key into the new one.
+                            elif key == ASSUME_INSTALLED_OLD:
+                                key = ASSUME_INSTALLED_FIELD
+                            self.hwpack[key] = value
+                else:
+                    # Here we have only sources sections.
+                    for _, value in parser.items(section):
+                        if value is not None:
+                            self.sources[section] = value
+
+    def _set_bootloaders(self, key, value):
+        """Sets the bootloaders dictionary of a new YAML file. Converts from
+        the old INI keys name into the new ones.
+
+        :param key: The key of the bootloader.
+        :param value: The key value."""
+        if key == UBOOT_PACKAGE_KEY:
+            self.bootloaders[PACKAGE_FIELD] = value
+        elif key == UBOOT_FILE_KEY:
+            self.bootloaders[FILE_FIELD] = value
+        elif key == UBOOT_IN_BOOT_PART_KEY:
+            self.bootloaders[IN_BOOT_PART_FIELD] = value
+        elif key == UBOOT_DD_KEY:
+            self.bootloaders[DD_FIELD] = value
+
+    def parse_list_string(self, store, string, split=" "):
+        """Parses a string of listed values, and stores the single splitted
+        value in the provided list.
+
+        :param store: The list where to store the values.
+        :param string: The string that should be splitted.
+        :param split: The separator to use, defaults to empty space.
+        """
+        if not isinstance(store, list):
+            raise HwpackConverterException("Can use this method only with "
+                                            "list.")
+        store.extend(string.split(" "))
+
+    def _to_file(self):
+        """Writes the converted hwpack to file."""
+        with open(self.output_file, 'w') as fp:
+            fp.write(str(self))
+
+    def convert(self):
+        """Converts the input file into the output file with the new format.
+        """
+        self._parse()
+        self._to_file()
+
+    def __str__(self):
+        """Readable representation of the converted hwpack.
+
+        :return A YAML-string representation of the hwpack configuration.
+        """
+        converted = ''
+        if self.hwpack:
+            converted += dump(self.hwpack)
+        if self.architectures:
+            archs = {ARCHITECTURES_FIELD: self.architectures}
+            converted += dump(archs)
+        if self.extra_serial_options:
+            serial_options = {EXTRA_SERIAL_OPTIONS_FIELD:
+                                self.extra_serial_options}
+            converted += dump(serial_options)
+        if self.packages:
+            packages = {PACKAGES_FIELD: self.packages}
+            converted += dump(packages)
+        if self.wired_interfaces:
+            wired = {WIRED_INTERFACES_FIELD: self.wired_interfaces}
+            converted += dump(wired)
+        if self.wireless_interfaces:
+            converted += dump(self.wireless_interfaces)
+        if self.sources:
+            sources = {SOURCES_FIELD: self.sources}
+            converted += dump(sources)
+        if self.bootloaders or self.extra_boot_options or self.spl:
+            # The bootloaders section in the new YAML file is a dictionary
+            # containing a dictionary which can contains also other
+            # dictionaries. In this case we only have list and normal values.
+            nested_value = {}
+            if self.bootloaders:
+                for key, value in self.bootloaders.iteritems():
+                    nested_value[key] = value
+            if self.extra_boot_options:
+                nested_value[EXTRA_BOOT_OPTIONS_FIELD] = \
+                                                    self.extra_boot_options
+            if self.spl:
+                for key, value in self.spl.iteritems():
+                    nested_value[key] = value
+            default_bootloader = {DEFAULT_BOOTLOADER: nested_value}
+            bootloaders = {BOOTLOADERS_FIELD: default_bootloader}
+            converted += dump(bootloaders)
+        return converted
+
+
+def dump(python_object):
+    """Serialize a Python object in a YAML string format.
+
+    :param python_object: The object to serialize.
+    """
+    return yaml.dump(python_object, default_flow_style=False, indent=True)
+
+
+def check_and_validate_args(args):
+    """Assures that the args passed are valid.
+
+    :param args: the args as defined in linaro-hwpack-convert.
+    """
+    input_file = args.CONFIG_FILE
+    output_file = args.out
+    if not os.path.exists(input_file) or not os.path.isfile(input_file):
+        raise HwpackConverterException("The configuration file '%s' is not a "
+                                        "regular file." % input_file)
+    if output_file is not None:
+        if os.path.exists(output_file) or os.path.isdir(output_file):
+            raise HwpackConverterException("The output file name provided "
+                                            "'%s' already exists, or is a "
+                                            "directory." % output_file)
+        elif not os.path.isabs(output_file):
+            # If we output file is just a name, write it in the current dir.
+            output_file = os.path.join(os.getcwd(), output_file)
+    else:
+        output_file = input_file + NEW_FILE_SUFFIX
+    return (input_file, output_file)

=== added file 'linaro_image_tools/hwpack/hwpack_fields.py'
--- linaro_image_tools/hwpack/hwpack_fields.py	1970-01-01 00:00:00 +0000
+++ linaro_image_tools/hwpack/hwpack_fields.py	2012-07-19 15:10:43 +0000
@@ -0,0 +1,88 @@
+# Copyright (C) 2010, 2011, 2012 Linaro
+#
+# Author: Milo Casagrande <milo.casagrande@linaro.org>
+#
+# This file is part of Linaro Image Tools.
+#
+# Linaro Image Tools is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# Linaro Image Tools is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Linaro Image Tools; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
+# USA.
+
+# This file contains all the valid fields for an hwpack v3.
+# Reference wiki page: https://wiki.linaro.org/HardwarePacksV3
+#
+# Try to keep it alphabetically sorted per section.
+#
+ARCHITECTURES_FIELD = 'architectures'
+ASSUME_INSTALLED_FIELD = 'assume_installed'
+BOARDS_FIELD = 'boards'
+BOOTLOADERS_FIELD = 'bootloaders'
+BOOT_MIN_SIZE_FIELD = 'boot_min_size'
+BOOT_SCRIPT_FIELD = 'boot_script'
+COPY_FILES_FIELD = 'copy_files'
+DTB_ADDR_FIELD = 'dtb_addr'
+DTB_FILE_FIELD = 'dtb_file'
+DTB_FILES_FIELD = 'dtb_files'
+EXTRA_SERIAL_OPTIONS_FIELD = 'extra_serial_options'
+FORMAT_FIELD = 'format'
+INITRD_ADDR_FIELD = 'initrd_addr'
+INITRD_FILE_FIELD = 'initrd_file'
+KERNEL_ADDR_FIELD = 'kernel_addr'
+KERNEL_FILE_FIELD = 'kernel_file'
+LOAD_ADDR_FIELD = 'load_addr'
+LOADER_MIN_SIZE_FIELD = 'loader_min_size'
+LOADER_START_FIELD = 'loader_start'
+MAINTAINER_FIELD = 'maintainer'
+MMC_ID_FIELD = 'mmc_id'
+NAME_FIELD = 'name'
+ORIGIN_FIELD = 'origin'
+PACKAGES_FIELD = 'packages'
+PARTITION_LAYOUT_FIELD = 'partition_layout'
+ROOT_MIN_SIZE_FIELD = 'root_min_size'
+SERIAL_TTY_FIELD = 'serial_tty'
+SOURCES_FIELD = 'sources'
+SUPPORT_FIELD = 'support'
+WIRED_INTERFACES_FIELD = 'wired_interfaces'
+WIRELESS_INTERFACES_FIELD = 'wireless_interfaces'
+
+# Bootloaders specific fields
+DD_FIELD = 'dd'
+ENV_DD_FIELD = 'env_dd'
+EXTRA_BOOT_OPTIONS_FIELD = 'extra_boot_options'
+FILE_FIELD = 'file'
+IN_BOOT_PART_FIELD = 'in_boot_part'
+PACKAGE_FIELD = 'package'
+SPL_DD_FIELD = 'spl_dd'
+SPL_FILE_FIELD = 'spl_file'
+SPL_IN_BOOT_PART_FIELD = 'spl_in_boot_part'
+SPL_PACKAGE_FIELD = 'spl_package'
+
+# Samsung fields
+SAMSUNG_BL1_LEN_FIELD = 'samsung_bl1_len'
+SAMSUNG_BL1_START_FIELD = 'samsung_bl1_start'
+SAMSUNG_BL2_LEN_FIELD = 'samsung_bl2_len'
+SAMSUNG_ENV_LEN_FIELD = 'samsung_env_len'
+
+# Snowball fields
+SNOWBALL_STARTUP_FILES_CONFIG_FIELD = 'snowball_startup_files_config'
+
+# Fields that might be necessary for the metadata file
+METADATA_ARCH_FIELD = 'architecture'
+METADATA_VERSION_FIELD = 'version'
+
+# The allowed partition layouts.
+DEFINED_PARTITION_LAYOUTS = [
+    'bootfs16_rootfs',
+    'bootfs_rootfs',
+    'reserved_bootfs_rootfs', ]

=== modified file 'linaro_image_tools/hwpack/tests/__init__.py'
--- linaro_image_tools/hwpack/tests/__init__.py	2012-06-13 14:26:02 +0000
+++ linaro_image_tools/hwpack/tests/__init__.py	2012-07-19 07:49:47 +0000
@@ -28,6 +28,7 @@
         'linaro_image_tools.hwpack.tests.test_builder',
         'linaro_image_tools.hwpack.tests.test_config',
         'linaro_image_tools.hwpack.tests.test_hardwarepack',
+        'linaro_image_tools.hwpack.tests.test_hwpack_converter',
         'linaro_image_tools.hwpack.tests.test_packages',
         'linaro_image_tools.hwpack.tests.test_script',
         'linaro_image_tools.hwpack.tests.test_tarfile_matchers',

=== added file 'linaro_image_tools/hwpack/tests/test_hwpack_converter.py'
--- linaro_image_tools/hwpack/tests/test_hwpack_converter.py	1970-01-01 00:00:00 +0000
+++ linaro_image_tools/hwpack/tests/test_hwpack_converter.py	2012-07-19 15:21:06 +0000
@@ -0,0 +1,132 @@
+# Copyright (C) 2010, 2011, 2012 Linaro
+#
+# Author: Milo Casagrande <milo.casagrande@linaro.org>
+#
+# This file is part of Linaro Image Tools.
+#
+# Linaro Image Tools is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# Linaro Image Tools is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Linaro Image Tools; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
+# USA.
+
+import tempfile
+from linaro_image_tools.testing import TestCaseWithFixtures
+from linaro_image_tools.tests.fixtures import (
+    CreateTempDirFixture,
+    CreateTempFileFixture,
+    )
+
+from linaro_image_tools.hwpack.hwpack_convert import (
+    HwpackConverter,
+    HwpackConverterException,
+    check_and_validate_args,
+    )
+
+
+class Args():
+    """Defines the args for the command line options."""
+    def __init__(self, input_file, output_file=None):
+        self.CONFIG_FILE = input_file
+        self.out = output_file
+
+
+class HwpackConverterTests(TestCaseWithFixtures):
+    """Test class for the hwpack converter."""
+
+    def setUp(self):
+        super(HwpackConverterTests, self).setUp()
+
+    def test_wrong_input_file(self):
+        """Pass a non-existing file."""
+        input_file = '/tmp/foobaz'
+        self.assertRaises(
+            HwpackConverterException, check_and_validate_args,
+            Args(input_file=input_file))
+
+    def test_wrong_input_dir(self):
+        """Pass a directory instead of file."""
+        temp_file = tempfile.NamedTemporaryFile()
+        temp_dir = self.useFixture(CreateTempDirFixture()).get_temp_dir()
+        self.assertRaises(
+            HwpackConverterException, check_and_validate_args,
+            Args(input_file=temp_file.name, output_file=temp_dir))
+
+    def test_same_input_output_file(self):
+        """Pass the same existing file path to the two arguments."""
+        temp_file = self.useFixture(CreateTempFileFixture()).get_file_name()
+        self.assertRaises(
+            HwpackConverterException, check_and_validate_args,
+            Args(input_file=temp_file, output_file=temp_file))
+
+    def test_basic_parse(self):
+        ini_format = '[hwpack]\nformat=2.0\nsupport=supported'
+        output_format = "format: '3.0'\nsupport: supported\n"
+        input_file = self.useFixture(CreateTempFileFixture(ini_format)).\
+                                                                get_file_name()
+        output_file = self.useFixture(CreateTempFileFixture()).get_file_name()
+        converter = HwpackConverter(input_file, output_file)
+        converter._parse()
+        self.assertEqual(output_format, str(converter))
+
+    def test_architectures_section_creation(self):
+        """Tests that we create the correct architectures list in the
+        converted file.
+        """
+        ini_format = '[hwpack]\nformat=2.0\narchitectures=armhf armel'
+        output_format = "format: '3.0'\narchitectures:\n- armhf\n- armel\n"
+        input_file = self.useFixture(CreateTempFileFixture(ini_format)).\
+                                                                get_file_name()
+        output_file = self.useFixture(CreateTempFileFixture()).get_file_name()
+        converter = HwpackConverter(input_file, output_file)
+        converter._parse()
+        self.assertEqual(output_format, str(converter))
+
+    def test_bootloaders(self):
+        """Tests the correct creation of the bootloaders part."""
+        ini_format = ("[hwpack]\nformat=2.0\nu_boot_package=a_package\n"
+                        "u_boot_file=a_file\nu_boot_in_boot_part=Yes\n"
+                        "u_boot_dd=33")
+        out_format = ("format: '3.0'\nbootloaders:\n  u_boot:\n    dd: '33'"
+                        "\n    file: a_file\n    in_boot_part: true\n"
+                        "    package: a_package\n")
+        input_file = self.useFixture(CreateTempFileFixture(ini_format)).\
+                                                                get_file_name()
+        output_file = self.useFixture(CreateTempFileFixture()).get_file_name()
+        converter = HwpackConverter(input_file, output_file)
+        converter._parse()
+        self.assertEqual(out_format, str(converter))
+
+    def test_extra_boot_options(self):
+        """Tests the correct creation of the extra_boot_options part."""
+        ini_format = ("[hwpack]\nformat=2.0\nu_boot_package=a_package\n"
+                        "extra_boot_options=opt1 opt2")
+        out_format = ("format: '3.0'\nbootloaders:\n  u_boot:\n "
+                        "   extra_boot_options:\n    - opt1\n    "
+                        "- opt2\n    package: a_package\n")
+        input_file = self.useFixture(CreateTempFileFixture(ini_format)).\
+                                                                get_file_name()
+        output_file = self.useFixture(CreateTempFileFixture()).get_file_name()
+        converter = HwpackConverter(input_file, output_file)
+        converter._parse()
+        self.assertEqual(out_format, str(converter))
+
+    def test_extra_serial_options(self):
+        """Tests the correct creation of the extra_serial_options part."""
+        ini_format = ("[hwpack]\nformat=2.0\nextra_serial_options=opt1 opt2")
+        out_format = ("format: '3.0'\nextra_serial_options:\n- opt1\n- opt2\n")
+        input_file = self.useFixture(CreateTempFileFixture(ini_format)).\
+                                                                get_file_name()
+        output_file = self.useFixture(CreateTempFileFixture()).get_file_name()
+        converter = HwpackConverter(input_file, output_file)
+        converter._parse()
+        self.assertEqual(out_format, str(converter))

=== modified file 'linaro_image_tools/tests/fixtures.py'
--- linaro_image_tools/tests/fixtures.py	2012-06-13 14:55:34 +0000
+++ linaro_image_tools/tests/fixtures.py	2012-07-19 07:49:47 +0000
@@ -41,6 +41,32 @@
         return self.tempdir
 
 
+class CreateTempFileFixture(object):
+    """Class to create a temporary file to be used in a test."""
+    def __init__(self, string=None):
+        """Initialize the fixture.
+
+        :param string: the string to write in the file.
+        """
+        self.temp_file = None
+        self.string = string
+
+    def setUp(self):
+        self.temp_file = tempfile.NamedTemporaryFile()
+        if self.string is not None:
+            self.temp_file.write(self.string)
+            # Go back to the initial position, we just need to write something
+            # and be able to read from the beginning of the file.
+            self.temp_file.seek(0)
+
+    def tearDown(self):
+        # We don't need to do anything, file is automatically deleted.
+        pass
+
+    def get_file_name(self):
+        return self.temp_file.name
+
+
 class MockSomethingFixture(object):
     """A fixture which mocks something on the given object.
 

