def test_export_with_include_content_filter_project_to_cpf(self):
        # test cpf export
        source = os.path.join(TEMP_DIR, "layers")
        remote = os.path.join(TEMP_DIR, 'layers.cpf')
        self.remove_if_exists(remote)

        unzip_file(EXPORT_TEST_PROJECT, source, delete_if_exists=True)

        cmd = '%s -p "%s" -c "root4.confml" -r "%s" --include-content-filter="%s"' % (
            get_cmd('export'), TEST_PROJECT_CPF, remote, ".*layer1.*")
        out = self.run_command(cmd)

        # layer1 content
        self.assert_zip_entry_exists(remote, "root4.confml")
        self.assert_zip_entry_exists(remote, "Layer1/content/default_file.txt")
        self.assert_zip_entry_exists(remote,
                                     "Layer1/content/seq/def1_file.txt")

        # filtered content
        self.assert_zip_entry_exists_not(remote,
                                         "Layer2/content/layer2_file.txt")
        self.assert_zip_entry_exists_not(remote,
                                         "Layer3/content/seq/layer3_file.txt")
        self.assert_zip_entry_exists_not(remote,
                                         "Layer4/content/seq/layer4_file.txt")
    def test_export_to_zipstorage(self):
        test_project_dir = os.path.join(temp_dir, "test_project_1")
        unzip_file.unzip_file(test_cpf,
                              test_project_dir,
                              delete_if_exists=True)

        export_zip = os.path.join(temp_dir, "configexport.zip")

        fs = FileStorage(test_project_dir)
        p = api.Project(fs)
        conf = p.get_configuration('root5.confml')
        zs = ZipStorage(export_zip, "w")
        zp = api.Project(zs)
        conf_files = conf.list_resources()
        files1 = ['.metadata']
        files1.extend(conf_files)
        p.export_configuration(conf, zs)
        zp.close()
        self.assertTrue(os.path.exists(export_zip))
        zfile = zipfile.ZipFile(export_zip, "r")
        files2 = zfile.namelist()
        zfile.close()
        files1.sort()
        files2.sort()
        for i in range(len(files1)):
            self.assertEquals(files1[i], files2[i])
        os.unlink(export_zip)
Exemple #3
0
    def test_import_to_zipstorage(self):
        test_project_dir = os.path.join(temp_dir, "test_project_1")
        unzip_file.unzip_file(test_cpf,
                              test_project_dir,
                              delete_if_exists=True)

        imported_zip = os.path.join(temp_dir, "imported1.zip")

        fs = FileStorage(test_project_dir)
        p = api.Project(fs)
        zs = ZipStorage(imported_zip, "w")
        zp = api.Project(zs)
        conf = p.get_configuration('root5.confml')
        conf_files = conf.list_resources()
        conf_files.append('.metadata')
        zp.import_configuration(conf)
        zp.close()
        p.close()
        self.assertTrue(os.path.exists(imported_zip))
        zfile = zipfile.ZipFile(imported_zip, "r")
        files = zfile.namelist()
        conf_files.sort()
        files.sort()
        self.assertEquals(conf_files, files)
        zfile.close()
        os.unlink(imported_zip)
    def _get_project_and_config(self, workdir, storage_type):
        # Create the working directory for the test
        self.remove_if_exists(workdir)
        os.makedirs(workdir)

        # Unpack or copy the project into the working directory
        project_source_zip = os.path.join(TESTDATA_DIR,
                                          'emptydircopy/project.zip')
        if storage_type == 'fs':
            project_location = os.path.join(workdir, 'project')
            unzip_file(project_source_zip, project_location)
        elif storage_type == 'zs':
            project_location = os.path.join(workdir, 'project.zip')
            shutil.copy(project_source_zip, project_location)
        else:
            raise ValueError('Invalid storage type %r' % storage_type)

        # Copy the external content directory
        unzip_file(
            os.path.join(TESTDATA_DIR, 'emptydircopy/external_content.zip'),
            os.path.join(workdir, 'external_content'))

        project = api.Project(api.Storage.open(project_location, 'r'))
        config = project.get_configuration('root.confml')
        return project, config
    def test_read_name_id_mapped_values(self):
        PROJ = os.path.join(TEMP_DIR, "test_project_5")
        CONF = 'root3.confml'
        unzip_file.unzip_file(TEST_CPF, PROJ, delete_if_exists=True)

        with open_config_and_get_dview(PROJ, 'r', CONF) as dview:

            def check(setting, expected_value):
                fea = dview.get_feature('NameIdMappingTestTargetSettings.' +
                                        setting)
                self.assertEquals(fea.get_value(), expected_value)

            check('Selection', 'seq1_item2')
            check('Selection2', 12)
            check('MultiSelection',
                  ('seq1_item1', 'seq1_item2', 'seq2_item2', 'seq2_item3'))
            check('MultiSelection2', (11, 12, True, False))
            check('String', 'seq1_item2')
            check('Int', 12)
            check('Real', 1.2)
            check('Boolean', False)

            check('Sequence.Selection', ['seq1_item2'])
            check('Sequence.Selection2', [12])
            check('Sequence.MultiSelection',
                  [('seq1_item1', 'seq1_item2', 'seq2_item2', 'seq2_item3')])
            check('Sequence.MultiSelection2', [(11, 12, True, False)])
            check('Sequence.String', ['seq1_item2'])
            check('Sequence.Int', [12])
            check('Sequence.Real', [1.2])
            check('Sequence.Boolean', [False])
    def test_export_with_include_content_filter(self):
        include_content_filter = ".*layer4.*"
        include_filters = {'content': include_content_filter}
        test_project_dir = os.path.join(temp_dir, "test_project_1")
        unzip_file.unzip_file(test_cpf,
                              test_project_dir,
                              delete_if_exists=True)

        export_zip = os.path.join(temp_dir, "configexport.zip")

        fs = FileStorage(test_project_dir)
        p = api.Project(fs)
        conf = p.get_configuration('root5.confml')
        zs = ZipStorage(export_zip, "w")
        zp = api.Project(zs)
        p.export_configuration(conf, zs, include_filters=include_filters)
        zp.close()

        zs = ZipStorage(export_zip, "r")
        zp = api.Project(zs)
        conf = zp.get_configuration('root5.confml')
        rel = conf.get_layer().list_all_related()

        exp = [
            'Layer1/implml/bitmask_test_12341002.crml',
            'Layer1/implml/feature1_12341000.crml',
            'Layer1/implml/feature1_12341001.crml',
            'Layer1/implml/feature1_sequence.gcfml',
            'Layer1/implml/feature2_ABCD0000.crml',
            'Layer1/implml/time_types_test_12341003.crml',
            'Layer4/content/seq/layer4_file.txt'
        ]
        zs.close()
        self.assertEquals(exp, rel)
        os.unlink(export_zip)
    def test_add_and_remove_meta_in_filesystem_project(self):
        TEST_PROJECT_DIR = os.path.join(ROOT_PATH, 'temp/update/project')
        unzip_file.unzip_file(TEST_PROJECT_CPF,
                              TEST_PROJECT_DIR,
                              delete_if_exists=True)

        rootfile = os.path.join(TEST_PROJECT_DIR, "root5.confml")
        self._run_test_add_and_remove_meta_in_project(
            project=TEST_PROJECT_DIR,
            root_file_reader=lambda: self.read_data_from_file(rootfile))
    def test_edit_complex_sequence_data_on_last_layer_with_dview(self):
        PROJ = os.path.join(TEMP_DIR, "test_project_4")
        CONF = 'root3.confml'
        SETTING = 'SequenceSettingTest.SequenceSetting'
        unzip_file.unzip_file(TEST_CPF, PROJ, delete_if_exists=True)

        # Open the temp project in append mode
        with open_config_and_get_setting(PROJ, 'a', CONF, SETTING) as setting:
            self.assertEquals(
                setting.value,
                [[['seq/layer2_folder2', None], 2.1000000000000001,
                  ['seq/layer2_file2.txt', None], 222, 'L22', True, '1',
                  ('opt 1', 'opt 3'), '\x22\x22'],
                 [['seq/layer2_folder', None], 2.0,
                  ['seq/layer2_file.txt', None], 22, 'L21', True, '2',
                  ('opt 2', ), '\x22\x11'],
                 [['seq/def1_folder', None], 1.25, ['seq/def1_file.txt', None],
                  128, 'def1', False, '1', ('opt 1', ), '\x00\x11'],
                 [['seq/def2_folder', None], 1.5, ['seq/def2_file.txt', None],
                  256, 'def2', False, '1', ('opt 2', ), '\x00\x22'],
                 [['seq/layer3_folder', None], 3.0,
                  ['seq/layer3_file.txt', None], 33, 'L31', False, '0',
                  ('opt 3', 'opt 2'), '\x33\x11'],
                 [['seq/layer3_folder', None],
                  3.3500000000000001, [None, None], 1, 'L32', True, '2',
                  ('opt 1', 'opt 2'), '\x33\x22']])

            # Change the value
            setting.value = [[['seq/foofolder1', None], 5.6,
                              ['seq/foofile1.txt', None], 1010, 'Lfoo', False,
                              '3', ('opt 4', 'opt 0'), '\xaa\xbb'],
                             [['seq/foofolder2', None], 6.5,
                              ['seq/foofile2.txt', None], 2020, 'Lfoo', True,
                              '3', (), ''],
                             [['seq/foofolder1', None], 5.6,
                              ['seq/foofile1.txt', None], 1010, 'Lfoo', False,
                              '3', ('opt 4', 'opt 0'), '\xaa\xbb']]

        with open_config_and_get_setting(PROJ, 'r', CONF, SETTING) as setting:
            self.assertEquals(
                setting.value,
                [[['seq/foofolder1', None], 5.6, ['seq/foofile1.txt', None],
                  1010, 'Lfoo', False, '3', ('opt 4', 'opt 0'), '\xaa\xbb'],
                 [['seq/foofolder2', None], 6.5, ['seq/foofile2.txt', None],
                  2020, 'Lfoo', True, '3', (), ''],
                 [['seq/foofolder1', None], 5.6, ['seq/foofile1.txt', None],
                  1010, 'Lfoo', False, '3', ('opt 4', 'opt 0'), '\xaa\xbb']])
        # Modify the sequence data again by setting it empty
        with open_config_and_get_setting(PROJ, 'a', CONF, SETTING) as setting:
            setting.value = []

        # Reopen and check again
        with open_config_and_get_setting(PROJ, 'r', CONF, SETTING) as setting:
            self.assertEquals(setting.value, [])
Exemple #9
0
 def _prepare_workdir(self, subdir, project_zip, expected_zip):
     WORKDIR = os.path.join(TEMP_DIR, subdir)
     PROJECT_DIR = os.path.join(WORKDIR, 'project')
     EXPECTED_DIR = os.path.join(WORKDIR, 'expected')
     
     self.remove_if_exists(WORKDIR)
     
     unzip_file.unzip_file(
         os.path.join(TESTDATA_DIR, project_zip),
         PROJECT_DIR)
     unzip_file.unzip_file(
        os.path.join(TESTDATA_DIR, expected_zip),
        EXPECTED_DIR)
     
     return PROJECT_DIR, EXPECTED_DIR
Exemple #10
0
 def get_temp_file_storage(self, path, empty=False):
     """
     Get a new file storage located in the temp/ directory.
     
     @param path: Path of the storage directory relative to the temp/ directory.
     @param empty: If False, the DATA_ZIP is extracted to the location specified
         by 'path' and returned as a read-only storage. If True, a new writable
         empty storage is returned.
     """
     full_path = os.path.join(TEMP_DIR, path)
     if not empty:
         unzip_file(DATA_ZIP, full_path, delete_if_exists=True)
         return filestorage.FileStorage(full_path, 'r')
     else:
         self.recreate_dir(full_path)
         return filestorage.FileStorage(full_path, 'w')
Exemple #11
0
    def prepare_workdir(self, workdir):
        """
        Prepare a working directory with all needed test data into
        the given sub-dir under the temporary directory.
        @param workdir: Absolute path to the working directory.
        """
        assert os.path.isabs(workdir)

        # Remove the working directory
        self.remove_if_exists(workdir)

        # Extract asset merge test data into the working dir
        unzip_file.unzip_file(self.TESTDATA_ZIP, workdir)

        # Extract expected data
        unzip_file.unzip_file(self.EXPECTED_ZIP,
                              os.path.join(workdir, 'expected'))

        return workdir
    def test_edit_sequence_data_on_last_layer_with_dview(self):
        PROJ = os.path.join(TEMP_DIR, "test_project_1")
        CONF = 'root3.confml'
        SETTING = 'Feature2.SequenceSetting'
        unzip_file.unzip_file(TEST_CPF, PROJ, delete_if_exists=True)

        # Open the temp project in append mode
        with open_config_and_get_setting(PROJ, 'a', CONF, SETTING) as setting:
            self.assertEquals(setting.value,
                              [[333, 'layer3 (1)'], [1, 'default 1'],
                               [2, 'default 2'], [222, 'layer2 (1)'],
                               [222, 'layer2 (2)'], [222, 'layer2 (3)']])

            # Change the value
            setting.value = [[123, 'foo1'], [456, 'foo2']]

        # Reopen the project in read mode and check that the sequence data
        # was modified correctly
        with open_config_and_get_setting(PROJ, 'r', CONF, SETTING) as setting:
            self.assertEquals(setting.value, [[123, 'foo1'], [456, 'foo2']])
            self.assertEquals(setting.get_original_value(),
                              [['123', 'foo1'], ['456', 'foo2']])

        # Modify the sequence data again by setting it empty
        with open_config_and_get_setting(PROJ, 'a', CONF, SETTING) as setting:
            setting.value = []
            self.assertEquals(setting.value, [])
            self.assertEquals(setting.get_original_value(), [])

        # Reopen and check again
        with open_config_and_get_setting(PROJ, 'r', CONF, SETTING) as setting:
            self.assertEquals(setting.value, [])
            self.assertEquals(setting.get_original_value(), [])

        # Do the same 'set empty' check with a more complex sequence setting
        SETTING = 'SequenceSettingTest.SequenceSetting'
        with open_config_and_get_setting(PROJ, 'a', CONF, SETTING) as setting:
            setting.value = []
            self.assertEquals(setting.value, [])
            self.assertEquals(setting.get_original_value(), [])
        with open_config_and_get_setting(PROJ, 'r', CONF, SETTING) as setting:
            self.assertEquals(setting.value, [])
            self.assertEquals(setting.get_original_value(), [])
    def test_export_from_files_to_zipstorage_add(self):
        test_project_dir = os.path.join(temp_dir, "test_project_1")
        unzip_file.unzip_file(test_cpf,
                              test_project_dir,
                              delete_if_exists=True)

        export_zip = os.path.join(temp_dir, "configexport2.zip")

        fs = FileStorage(test_project_dir)
        p = api.Project(fs)
        exportconf = p.get_configuration('root4.confml')
        compareconf = p.get_configuration('root5.confml')
        zs = ZipStorage(export_zip, "w")
        zp = api.Project(zs)
        conf_files = compareconf.list_resources()
        files1 = ['.metadata']
        files1.extend(conf_files)
        p.export_configuration(exportconf, zs)
        zp.close()
        self.assertTrue(os.path.exists(export_zip))

        #Re-opening in append mode for adding new layers.
        zs = ZipStorage(export_zip, "a")
        zp = api.Project(zs)
        conf = p.get_configuration('Layer5/root.confml')
        p.export_configuration(conf, zs)
        zp.save()
        zp.close()

        zfile = zipfile.ZipFile(export_zip, "r")
        files2 = zfile.namelist()
        #Root file renaming.
        files2[files2.index('root4.confml')] = 'root5.confml'
        zfile.close()
        files1.sort()
        files2.sort()

        for i in range(len(files1)):
            self.assertEquals(files1[i], files2[i])
        os.unlink(export_zip)
Exemple #14
0
    def _prepare_workdir_with_project(self, workdir, expected_zip=None):
        """
        Prepare a working directory for running a test.
        @param workdir: Sub-directory of the workdir.
        @param expected_zip: Zip file containing expected data that should
            be extracted under the workdir, can be None. The path should be
            relative to testdata/merge.
        @return: Tuple (test_project_abs, expected_dir_abs). expected_dir_abs
            will be None if expected_zip was None.
        """
        workdir = os.path.join(TEMP_DIR, workdir)
        self.recreate_dir(workdir)

        # Unzip the test project
        test_project_dir = os.path.join(workdir, 'test_project')
        unzip_file.unzip_file(TEST_PROJECT_CPF,
                              test_project_dir,
                              delete_if_exists=True)

        # Check that it was unzipped correctly
        paths = [
            "Layer1/", "Layer2/", "Layer3/", "Layer4/", "Layer5/",
            "root1.confml", "root2.confml", "root3.confml", "root4.confml",
            "root5.confml"
        ]
        for path in paths:
            self.assert_exists_and_contains_something(
                os.path.join(test_project_dir, path))

        expected_dir = None
        # Unzip the expected data
        if expected_zip:
            expected_zip = os.path.join(TESTDATA_DIR, expected_zip)
            expected_dir = os.path.join(workdir, 'expected')
            unzip_file.unzip_file(expected_zip, expected_dir)

        return test_project_dir, expected_dir
    def test_packvariant(self):
        PROJECT_DIR = os.path.join(ROOT_PATH, TESTDATA_DIR, 'project')
        REMOTE_ZIP = os.path.join(ROOT_PATH, TEMP_DIR, 'output/packvariant.zip')
        EXPECTED_ZIP = os.path.join(ROOT_PATH, TESTDATA_DIR, 'expected/packvariant.zip')

        self.remove_if_exists(REMOTE_ZIP)
        cmd = '%s -p "%s" -c "%s" -r "%s"' % (get_cmd('packvariant'),PROJECT_DIR,rootconf,REMOTE_ZIP)
        out = self.run_command(cmd)
        self.assert_exists_and_contains_something(REMOTE_ZIP)
        
        REMOTE_TEMP_DIR = os.path.join(TEMP_DIR, 'output/remote')
        EXPECTED_TEMP_DIR = os.path.join(TEMP_DIR, 'output/expected')

        self.remove_if_exists(REMOTE_TEMP_DIR)    
        self.remove_if_exists(EXPECTED_TEMP_DIR)    

        unzip_file.unzip_file(
            REMOTE_ZIP,
            REMOTE_TEMP_DIR)
        unzip_file.unzip_file(
            EXPECTED_ZIP,
            EXPECTED_TEMP_DIR)
        
        self.assert_dir_contents_equal(REMOTE_TEMP_DIR, EXPECTED_TEMP_DIR, ignore=['.svn'])
    def test_edit_data_on_last_layer_with_dview(self):
        PROJ = os.path.join(TEMP_DIR, "test_project_2")
        CONF = 'root3.confml'
        unzip_file.unzip_file(TEST_CPF, PROJ, delete_if_exists=True)

        # Open the temp project in append mode
        with open_config_and_get_dview(PROJ, 'a', CONF) as dview:
            self.assertEquals(
                dview.get_feature('BasicSettingTypesTest.IntSetting').value,
                333)
            self.assertEquals(
                dview.get_feature(
                    'BasicSettingTypesTest.BooleanSetting').value, False)
            self.assertEquals(
                dview.get_feature('BasicSettingTypesTest.RealSetting').value,
                3.1456)
            self.assertEquals(
                dview.get_feature(
                    'BasicSettingTypesTest.SelectionSetting').value, '3')
            self.assertEquals(
                dview.get_feature('BasicSettingTypesTest.StringSetting').value,
                'layer 3 string')
            self.assertEquals(
                dview.get_feature(
                    'BasicSettingTypesTest.MultiSelectionSetting').value,
                ('opt 1', 'opt 3'))
            self.assertEquals(
                dview.get_feature(
                    'BasicSettingTypesTest.HexBinarySetting').value,
                '\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff'
            )

            dview.get_feature('BasicSettingTypesTest.IntSetting').value = 1500
            dview.get_feature(
                'BasicSettingTypesTest.BooleanSetting').value = True
            dview.get_feature(
                'BasicSettingTypesTest.RealSetting').value = 15.15
            dview.get_feature(
                'BasicSettingTypesTest.SelectionSetting').value = '1'
            dview.get_feature(
                'BasicSettingTypesTest.StringSetting').value = 'edit data test'
            dview.get_feature('BasicSettingTypesTest.MultiSelectionSetting'
                              ).value = ('opt 4', 'opt 0')
            dview.get_feature(
                'BasicSettingTypesTest.HexBinarySetting').value = '\x12\x34'

        # Reopen the project in read mode and check that the sequence data
        # was modified correctly
        with open_config_and_get_dview(PROJ, 'r', CONF) as dview:
            self.assertEquals(
                dview.get_feature('BasicSettingTypesTest.IntSetting').value,
                1500)
            self.assertEquals(
                dview.get_feature(
                    'BasicSettingTypesTest.BooleanSetting').value, True)
            self.assertEquals(
                dview.get_feature('BasicSettingTypesTest.RealSetting').value,
                15.15)
            self.assertEquals(
                dview.get_feature(
                    'BasicSettingTypesTest.SelectionSetting').value, '1')
            self.assertEquals(
                dview.get_feature('BasicSettingTypesTest.StringSetting').value,
                'edit data test')
            self.assertEquals(
                dview.get_feature(
                    'BasicSettingTypesTest.MultiSelectionSetting').value,
                ('opt 4', 'opt 0'))
            self.assertEquals(
                dview.get_feature(
                    'BasicSettingTypesTest.HexBinarySetting').value,
                '\x12\x34')

        # Test that setting the multi-selection setting to empty works
        SETTING = 'BasicSettingTypesTest.MultiSelectionSetting'
        with open_config_and_get_setting(PROJ, 'a', 'root4.confml',
                                         SETTING) as setting:
            self.assertEquals(setting.value, ('opt 0', 'opt 4'))
            setting.value = ()
            self.assertEquals(setting.value, ())
        with open_config_and_get_setting(PROJ, 'r', 'root4.confml',
                                         SETTING) as setting:
            self.assertEquals(setting.value, ())
    def _run_test_export_project_to_project(self, source_project,
                                            source_storage_type,
                                            target_project,
                                            target_storage_type,
                                            empty_folders):
        # Set up the source project
        # -------------------------
        source_path = os.path.join(TEMP_DIR, source_project)
        self.remove_if_exists(source_path)
        if source_storage_type == 'file':
            unzip_file(EXPORT_TEST_PROJECT, source_path, delete_if_exists=True)
        elif source_storage_type == 'zip':
            self.create_dir_for_file_path(source_path)
            shutil.copy2(EXPORT_TEST_PROJECT, source_path)
        else:
            raise RuntimeError('Invalid storage type %r' % source_storage_type)

        # Set up the target project
        # -------------------------
        target_path = os.path.join(TEMP_DIR, target_project)
        self.remove_if_exists(target_path)
        if target_storage_type not in ('file', 'zip'):
            raise RuntimeError('Invalid storage type %r' % target_storage_type)

        # Run the command
        # ---------------
        if empty_folders: empty_folder_switch = ''
        else: empty_folder_switch = '--exclude-folders'
        cmd = '%s -p "%s" -c "root5.confml" -r "%s" %s' % \
            (get_cmd('export'), source_path, target_path, empty_folder_switch)
        out = self.run_command(cmd)

        # Check the output
        # ----------------
        if target_storage_type == 'file': storage_class = FileStorage
        elif target_storage_type == 'zip': storage_class = ZipStorage

        storage = storage_class(target_path, 'r')
        res_list = storage.list_resources("/",
                                          recurse=True,
                                          empty_folders=True)

        expected = [
            '.metadata',
            'root5.confml',
            'Layer1/root.confml',
            'Layer2/root.confml',
            'Layer3/root.confml',
            'Layer4/root.confml',
            'Layer5/root.confml',
        ]
        for res in expected:
            self.assertTrue(res in res_list, "%r not in %r" % (res, res_list))
            self.assertFalse(storage.is_folder(res), "%r is a folder")

        not_expected = [
            'Layer1/foo/foo.txt',
            'Layer2/foo/layer2_foo.txt',
            'Layer3/foo/layer3_foo.txt',
            'Layer4/foo/layer4_foo.txt',
            'Layer5/foo/layer5_foo.txt',
        ]
        for res in not_expected:
            self.assertFalse(res in res_list, "%r in %r" % (res, res_list))

        # Check empty folders
        expected = [
            'Layer1/doc/empty',
            'Layer1/content/empty',
            'Layer1/implml/empty',
            'Layer3/doc/empty',
            'Layer3/content/empty',
            'Layer3/implml/empty',
        ]
        not_expected = ['Layer1/foo/empty', 'Layer3/foo/empty']
        if empty_folders:
            for res in expected:
                self.assertTrue(res in res_list,
                                "%r not in %r" % (res, res_list))
                self.assertTrue(storage.is_folder(res), "%r is not a folder")

            for res in not_expected:
                self.assertFalse(res in res_list, "%r in %r" % (res, res_list))
        else:
            for res in expected + not_expected:
                self.assertFalse(res in res_list, "%r in %r" % (res, res_list))
    def _run_test_add_meta_to_multiple_roots_in_filesystem_project(
            self, project, args, updated_configs):
        TEST_PROJECT_DIR = os.path.join(ROOT_PATH, 'temp/update', project)
        unzip_file.unzip_file(TEST_PROJECT_CPF,
                              TEST_PROJECT_DIR,
                              delete_if_exists=True)
        self.assert_exists_and_contains_something(TEST_PROJECT_DIR)

        self.set_modification_reference_time(TEST_PROJECT_DIR)
        cmd = ('%(cmd)s '\
            '--project "%(project)s" %(args)s '\
            '--add-meta owner="test person" '\
            '--add-meta product="test product" '\
            '--add-cpf-meta product_type="XYZ-123" '\
            '--add-cpf-meta platform="Platform X" '\
            '--add-desc "Testing description"')\
            % {'cmd'    : get_cmd('update'),
               'project': TEST_PROJECT_DIR,
               'args'   : args}
        out = self.run_command(cmd)
        #print out
        self.assert_modified(TEST_PROJECT_DIR)

        # Check that the metadata is correct for all roots
        project = api.Project(api.Storage.open(TEST_PROJECT_DIR, 'r'))
        for config in project.list_configurations():
            config_file_path = os.path.join(TEST_PROJECT_DIR, config)
            root_elem = ElementTree.fromstring(
                self.read_data_from_file(config_file_path))

            if config in updated_configs:
                try:
                    desc_elem = root_elem.find(
                        "{http://www.s60.com/xml/confml/2}desc")
                    self.assertNotEquals(desc_elem, None)
                    self.assertEquals(desc_elem.text, "Testing description")

                    meta_elem = root_elem.find(
                        "{http://www.s60.com/xml/confml/2}meta")
                    self.assertEquals(self._get_meta_entry(meta_elem, 'owner'),
                                      'test person')
                    self.assertEquals(
                        self._get_meta_entry(meta_elem, 'product'),
                        'test product')
                    self.assertEquals(
                        self._get_cpf_meta_entry(meta_elem, 'product_type'),
                        'XYZ-123')
                    self.assertEquals(
                        self._get_cpf_meta_entry(meta_elem, 'platform'),
                        'Platform X')
                except AssertionError:
                    self.fail(
                        "Root '%s' was not updated when it should have been!" %
                        config)
            else:
                try:
                    desc_elem = root_elem.find(
                        "{http://www.s60.com/xml/confml/2}desc")
                    self.assertEquals(desc_elem, None)

                    meta_elem = root_elem.find(
                        "{http://www.s60.com/xml/confml/2}meta")
                    self.assertEquals(meta_elem, None)
                except AssertionError:
                    self.fail(
                        "Root '%s' was updated when it should not have been!" %
                        config)