configurationengine/source/scripts/tests/unittest_export.py
changeset 0 2e8eeb919028
child 3 e7e0ae78773e
equal deleted inserted replaced
-1:000000000000 0:2e8eeb919028
       
     1 #
       
     2 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 # All rights reserved.
       
     4 # This component and the accompanying materials are made available
       
     5 # under the terms of "Eclipse Public License v1.0"
       
     6 # which accompanies this distribution, and is available
       
     7 # at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 #
       
     9 # Initial Contributors:
       
    10 # Nokia Corporation - initial contribution.
       
    11 #
       
    12 # Contributors:
       
    13 #
       
    14 # Description: 
       
    15 #
       
    16 
       
    17 """
       
    18 Test the configuration
       
    19 """
       
    20 import unittest
       
    21 import string
       
    22 import sys
       
    23 import os
       
    24 import subprocess
       
    25 import zipfile
       
    26 import shutil
       
    27 import __init__
       
    28 from testautomation.base_testcase import BaseTestCase
       
    29 from testautomation.unzip_file import unzip_file
       
    30 from cone.storage.filestorage import FileStorage
       
    31 from cone.storage.zipstorage import ZipStorage
       
    32 from scripttest_common import get_cmd
       
    33 
       
    34 ROOT_PATH   = os.path.dirname(os.path.abspath(__file__))
       
    35 
       
    36 def abspath(p):
       
    37     return os.path.normpath(os.path.join(ROOT_PATH, p))
       
    38     
       
    39 TEST_PROJECT_CPF    = abspath("test_project.cpf")
       
    40 TEMP_DIR            = abspath("temp/export")
       
    41 EXPORT_TEST_PROJECT = abspath("export_test_project.zip")
       
    42 
       
    43 class TestExport(BaseTestCase):
       
    44 
       
    45     def setUp(self):
       
    46         self.orig_workdir = os.getcwd()
       
    47         os.chdir(ROOT_PATH)
       
    48         
       
    49     def tearDown(self):
       
    50         os.chdir(self.orig_workdir)
       
    51 
       
    52     def test_get_help(self):
       
    53         cmd = '%s -h' % get_cmd('export')
       
    54         out = self.run_command(cmd)
       
    55         lines = out.split('\r\n')
       
    56         self.assertTrue('Options:' in lines)
       
    57         self.assertTrue('  Export options:' in lines)
       
    58 
       
    59     def test_export_project(self):
       
    60         remote = os.path.join(TEMP_DIR, 'test1')
       
    61         self.remove_if_exists(remote)
       
    62         
       
    63         self.set_modification_reference_time(TEST_PROJECT_CPF)
       
    64         cmd = '%s -p "%s" -c "root4.confml" -r "%s' % (get_cmd('export'), TEST_PROJECT_CPF, remote)
       
    65         out = self.run_command(cmd)
       
    66         #print out
       
    67         lines = out.split('\r\n')
       
    68         self.assertTrue('Export root4.confml to %s done!' % remote in lines)
       
    69         
       
    70         self.assertEquals(set(os.listdir(remote)),
       
    71             set(["Layer1", "Layer2", "Layer3", "Layer4", ".metadata", "root4.confml"]))
       
    72         def fp(p): # fp = full_path
       
    73             return os.path.join(remote, p)
       
    74         self.assert_exists_and_contains_something(fp("Layer1"))
       
    75         self.assert_exists_and_contains_something(fp("Layer2"))
       
    76         self.assert_exists_and_contains_something(fp("Layer3"))
       
    77         self.assert_exists_and_contains_something(fp("Layer4"))
       
    78         self.assert_exists_and_contains_something(fp("root4.confml"))
       
    79         
       
    80         self.assert_not_modified(TEST_PROJECT_CPF)
       
    81         
       
    82     def test_export_multiple_configurations(self):
       
    83         remote = os.path.join(TEMP_DIR, 'test2')
       
    84         self.remove_if_exists(remote)
       
    85         
       
    86         self.set_modification_reference_time(TEST_PROJECT_CPF)
       
    87         cmd = '%s -p "%s" -c "root2.confml" -c "root3.confml" -c "root5.confml" -r "%s"' % (get_cmd('export'), TEST_PROJECT_CPF, remote)
       
    88         out = self.run_command(cmd)
       
    89         #print out
       
    90         lines = out.split('\r\n')
       
    91         self.assertTrue('Export root2.confml to %s done!' % remote in lines)
       
    92         self.assertTrue('Export root3.confml to %s done!' % remote in lines)
       
    93         self.assertTrue('Export root5.confml to %s done!' % remote in lines)
       
    94         
       
    95         self.assertEquals(set(os.listdir(remote)),
       
    96             set(["Layer1", "Layer2", "Layer3", "Layer4", "Layer5",
       
    97                  ".metadata", "root2.confml", "root3.confml", "root5.confml"]))
       
    98         def fp(p): # fp = full_path
       
    99             return os.path.join(remote, p)
       
   100         self.assert_exists_and_contains_something(fp("Layer1"))
       
   101         self.assert_exists_and_contains_something(fp("Layer2"))
       
   102         self.assert_exists_and_contains_something(fp("Layer3"))
       
   103         self.assert_exists_and_contains_something(fp("Layer4"))
       
   104         self.assert_exists_and_contains_something(fp("Layer5"))
       
   105         self.assert_exists_and_contains_something(fp("root2.confml"))
       
   106         self.assert_exists_and_contains_something(fp("root3.confml"))
       
   107         self.assert_exists_and_contains_something(fp("root5.confml"))
       
   108         
       
   109         self.assert_not_modified(TEST_PROJECT_CPF)
       
   110     
       
   111     def test_export_multiple_configurations_into_cpf(self):
       
   112         remote = os.path.join(TEMP_DIR, 'test3.cpf')
       
   113         self.remove_if_exists(remote)
       
   114         
       
   115         self.set_modification_reference_time(TEST_PROJECT_CPF)
       
   116         cmd = '%s -p "%s" -c "root2.confml" -c "root3.confml" -c "root5.confml" -r "%s"' % (get_cmd('export'), TEST_PROJECT_CPF, remote)
       
   117         out = self.run_command(cmd)
       
   118         #print out
       
   119         lines = out.split('\r\n')
       
   120         self.assertTrue('Export root2.confml to %s done!' % remote in lines)
       
   121         self.assertTrue('Export root3.confml to %s done!' % remote in lines)
       
   122         self.assertTrue('Export root5.confml to %s done!' % remote in lines)
       
   123         
       
   124         self.assert_zip_entry_exists(remote, "root2.confml")
       
   125         self.assert_zip_entry_exists(remote, "root3.confml")
       
   126         self.assert_zip_entry_exists(remote, "root5.confml")
       
   127         
       
   128         self.assert_not_modified(TEST_PROJECT_CPF)
       
   129     
       
   130     def assert_zip_entry_exists(self, zip_file, path):
       
   131         zf = zipfile.ZipFile(zip_file, "r")
       
   132         try:
       
   133             if path not in zf.namelist():
       
   134                 self.fail("Entry '%s' not in zip file '%s'." % (path, zipfile))
       
   135         finally:
       
   136             zf.close()
       
   137     
       
   138     
       
   139     def _run_test_export_project_to_project(self,
       
   140         source_project, source_storage_type,
       
   141         target_project, target_storage_type,
       
   142         empty_folders):
       
   143         # Set up the source project
       
   144         # -------------------------
       
   145         source_path = os.path.join(TEMP_DIR, source_project)
       
   146         self.remove_if_exists(source_path)
       
   147         if source_storage_type == 'file':
       
   148             unzip_file(EXPORT_TEST_PROJECT, source_path, delete_if_exists=True)
       
   149         elif source_storage_type == 'zip':
       
   150             self.create_dir_for_file_path(source_path)
       
   151             shutil.copy2(EXPORT_TEST_PROJECT, source_path)
       
   152         else:
       
   153             raise RuntimeError('Invalid storage type %r' % source_storage_type)
       
   154         
       
   155         # Set up the target project
       
   156         # -------------------------
       
   157         target_path = os.path.join(TEMP_DIR, target_project)
       
   158         self.remove_if_exists(target_path)
       
   159         if target_storage_type not in ('file', 'zip'):
       
   160             raise RuntimeError('Invalid storage type %r' % target_storage_type)
       
   161         
       
   162         # Run the command
       
   163         # ---------------
       
   164         if empty_folders:   empty_folder_switch = ''
       
   165         else:               empty_folder_switch = '--exclude-folders'
       
   166         cmd = '%s -p "%s" -c "root5.confml" -r "%s" %s' % \
       
   167             (get_cmd('export'), source_path, target_path, empty_folder_switch)
       
   168         out = self.run_command(cmd)
       
   169         
       
   170         # Check the output
       
   171         # ----------------
       
   172         if target_storage_type == 'file':   storage_class = FileStorage
       
   173         elif target_storage_type == 'zip':  storage_class = ZipStorage
       
   174         
       
   175         storage = storage_class(target_path, 'r')
       
   176         res_list = storage.list_resources("/", recurse=True, empty_folders=True)
       
   177         
       
   178         expected = ['.metadata',
       
   179                     'root5.confml',
       
   180                     'Layer1/root.confml',
       
   181                     'Layer2/root.confml',
       
   182                     'Layer3/root.confml',
       
   183                     'Layer4/root.confml',
       
   184                     'Layer5/root.confml',]
       
   185         for res in expected:
       
   186             self.assertTrue(res in res_list, "%r not in %r" % (res, res_list))
       
   187             self.assertFalse(storage.is_folder(res), "%r is a folder")
       
   188         
       
   189         not_expected = ['Layer1/foo/foo.txt',
       
   190                         'Layer2/foo/layer2_foo.txt',
       
   191                         'Layer3/foo/layer3_foo.txt',
       
   192                         'Layer4/foo/layer4_foo.txt',
       
   193                         'Layer5/foo/layer5_foo.txt',]
       
   194         for res in not_expected:
       
   195             self.assertFalse(res in res_list, "%r in %r" % (res, res_list))
       
   196         
       
   197         # Check empty folders
       
   198         expected = ['Layer1/doc/empty',
       
   199                     'Layer1/content/empty',
       
   200                     'Layer1/implml/empty',
       
   201                     'Layer3/doc/empty',
       
   202                     'Layer3/content/empty',
       
   203                     'Layer3/implml/empty',]
       
   204         not_expected = ['Layer1/foo/empty',
       
   205                         'Layer3/foo/empty']
       
   206         if empty_folders:
       
   207             for res in expected:
       
   208                 self.assertTrue(res in res_list, "%r not in %r" % (res, res_list))
       
   209                 self.assertTrue(storage.is_folder(res), "%r is not a folder")
       
   210             
       
   211             for res in not_expected:
       
   212                 self.assertFalse(res in res_list, "%r in %r" % (res, res_list))
       
   213         else:
       
   214             for res in expected + not_expected:
       
   215                 self.assertFalse(res in res_list, "%r in %r" % (res, res_list))
       
   216 
       
   217     
       
   218     def test_export_file_to_file(self):
       
   219         self._run_test_export_project_to_project(
       
   220             source_project      = 'f2f/source',
       
   221             source_storage_type = 'file',
       
   222             target_project      = 'f2f/target',
       
   223             target_storage_type = 'file',
       
   224             empty_folders       = False)
       
   225     
       
   226         self._run_test_export_project_to_project(
       
   227             source_project      = 'f2f/source_ef',
       
   228             source_storage_type = 'file',
       
   229             target_project      = 'f2f/target_ef',
       
   230             target_storage_type = 'file',
       
   231             empty_folders       = True)
       
   232     
       
   233     def test_export_zip_to_zip(self):
       
   234         self._run_test_export_project_to_project(
       
   235             source_project      = 'z2z/source.zip',
       
   236             source_storage_type = 'zip',
       
   237             target_project      = 'z2z/target.zip',
       
   238             target_storage_type = 'zip',
       
   239             empty_folders       = False)
       
   240     
       
   241         self._run_test_export_project_to_project(
       
   242             source_project      = 'z2z/source_ef.zip',
       
   243             source_storage_type = 'zip',
       
   244             target_project      = 'z2z/target_ef.zip',
       
   245             target_storage_type = 'zip',
       
   246             empty_folders       = True)
       
   247     
       
   248     def test_export_file_to_zip(self):
       
   249         self._run_test_export_project_to_project(
       
   250             source_project      = 'f2z/source',
       
   251             source_storage_type = 'file',
       
   252             target_project      = 'f2z/target.zip',
       
   253             target_storage_type = 'zip',
       
   254             empty_folders       = False)
       
   255     
       
   256         self._run_test_export_project_to_project(
       
   257             source_project      = 'f2z/source_ef',
       
   258             source_storage_type = 'file',
       
   259             target_project      = 'f2z/target_ef.zip',
       
   260             target_storage_type = 'zip',
       
   261             empty_folders       = True)
       
   262     
       
   263     def test_export_zip_to_file(self):
       
   264         self._run_test_export_project_to_project(
       
   265             source_project      = 'z2f/source.zip',
       
   266             source_storage_type = 'zip',
       
   267             target_project      = 'z2f/target',
       
   268             target_storage_type = 'file',
       
   269             empty_folders       = False)
       
   270     
       
   271         self._run_test_export_project_to_project(
       
   272             source_project      = 'z2f/source_ef.zip',
       
   273             source_storage_type = 'zip',
       
   274             target_project      = 'z2f/target_ef',
       
   275             target_storage_type = 'file',
       
   276             empty_folders       = True)
       
   277     
       
   278     def _run_test_multi_export(self, export_dir, export_format, config_args,
       
   279                                expected_cpfs=None, expected_dirs=None):
       
   280         self.assertFalse(expected_cpfs is None and expected_dirs is None,
       
   281                          "Only one of expected_cpfs or expected_dirs can be specified!")
       
   282         self.assertFalse(expected_cpfs is None and expected_dirs is None,
       
   283                          "Either expected_cpfs or expected_dirs must be specified!")
       
   284         
       
   285         EXPORT_DIR = os.path.join(TEMP_DIR, export_dir)
       
   286         self.remove_if_exists(EXPORT_DIR)
       
   287         
       
   288         self.set_modification_reference_time(TEST_PROJECT_CPF)
       
   289         cmd = '%(cmd)s -p "%(project)s" %(args)s --export-dir "%(export_dir)s" --export-format %(export_format)s' \
       
   290             % {'cmd'            : get_cmd('export'),
       
   291                'project'        : TEST_PROJECT_CPF,
       
   292                'args'           : config_args,
       
   293                'export_dir'     : EXPORT_DIR,
       
   294                'export_format'  : export_format}
       
   295         out = self.run_command(cmd)
       
   296         self.assert_not_modified(TEST_PROJECT_CPF)
       
   297         
       
   298         if expected_cpfs:
       
   299             for cpf_name, config_root in expected_cpfs:
       
   300                 path = os.path.join(EXPORT_DIR, cpf_name)
       
   301                 self.assert_exists_and_contains_something(path)
       
   302                 self.assert_zip_entry_exists(path, config_root)
       
   303         else:
       
   304             for dir_name, config_root in expected_dirs:
       
   305                 path = os.path.join(EXPORT_DIR, dir_name)
       
   306                 self.assert_exists_and_contains_something(path)
       
   307                 self.assert_exists_and_contains_something(os.path.join(path, config_root))
       
   308     
       
   309     def test_export_multiple_cpfs(self):
       
   310         self._run_test_multi_export(
       
   311             export_dir    = 'multiexport/cpfs',
       
   312             export_format = 'cpf',
       
   313             config_args   = '--configuration root1.confml '\
       
   314                             '--configuration root3.confml',
       
   315             expected_cpfs = [('root1.cpf', 'root1.confml'),
       
   316                              ('root3.cpf', 'root3.confml')])
       
   317     
       
   318     def test_export_multiple_dirs(self):
       
   319         self._run_test_multi_export(
       
   320             export_dir    = 'multiexport/dirs',
       
   321             export_format = 'dir',
       
   322             config_args   = '--configuration root1.confml '\
       
   323                             '--configuration root3.confml',
       
   324             expected_dirs = [('root1/', 'root1.confml'),
       
   325                              ('root3/', 'root3.confml')])
       
   326     
       
   327     def test_export_multiple_dirs_with_added_layers(self):
       
   328         self._run_test_multi_export(
       
   329             export_dir    = 'multiexport/dirs_with_added_layers',
       
   330             export_format = 'dir',
       
   331             config_args   = '--configuration root1.confml '\
       
   332                             '--configuration root3.confml '\
       
   333                             '--add new/layer1/root.confml '\
       
   334                             '--add new/layer2/root.confml ',
       
   335             expected_dirs = [('root1/', 'root1.confml'),
       
   336                              ('root3/', 'root3.confml')])
       
   337         # Check that the added layers have really been added to the exported
       
   338         # projects
       
   339         def check(path):
       
   340             path = os.path.join(TEMP_DIR, 'multiexport/dirs_with_added_layers', path)
       
   341             self.assert_exists_and_contains_something(path)
       
   342         check('root1/new/layer1/root.confml')
       
   343         check('root1/new/layer2/root.confml')
       
   344         check('root3/new/layer1/root.confml')
       
   345         check('root3/new/layer2/root.confml')
       
   346         
       
   347         # Check that the configuration root contains the added layers
       
   348         file_path = os.path.join(TEMP_DIR, 'multiexport/dirs_with_added_layers/root1/root1.confml')
       
   349         data = self.read_data_from_file(file_path)
       
   350         self.assertTrue('href="Layer1/root.confml"' in data)
       
   351         self.assertTrue('href="new/layer1/root.confml"' in data)
       
   352         self.assertTrue('href="new/layer2/root.confml"' in data)
       
   353         
       
   354         file_path = os.path.join(TEMP_DIR, 'multiexport/dirs_with_added_layers/root3/root3.confml')
       
   355         data = self.read_data_from_file(file_path)
       
   356         self.assertTrue('href="Layer1/root.confml"' in data)
       
   357         self.assertTrue('href="Layer2/root.confml"' in data)
       
   358         self.assertTrue('href="Layer3/root.confml"' in data)
       
   359         self.assertTrue('href="new/layer1/root.confml"' in data)
       
   360         self.assertTrue('href="new/layer2/root.confml"' in data)
       
   361     
       
   362     def test_export_multiple_cpfs_with_wildcard(self):
       
   363         self._run_test_multi_export(
       
   364             export_dir    = 'multiexport/cpfs_wildcard',
       
   365             export_format = 'cpf',
       
   366             config_args   = '--config-wildcard root*.confml',
       
   367             expected_cpfs = [('root1.cpf', 'root1.confml'),
       
   368                              ('root2.cpf', 'root2.confml'),
       
   369                              ('root3.cpf', 'root3.confml'),
       
   370                              ('root4.cpf', 'root4.confml'),
       
   371                              ('root5.cpf', 'root5.confml')])
       
   372     
       
   373     def test_export_multiple_cpfs_with_regex(self):
       
   374         self._run_test_multi_export(
       
   375             export_dir    = 'multiexport/cpfs_regex',
       
   376             export_format = 'cpf',
       
   377             config_args   = '--config-regex root[14].confml',
       
   378             expected_cpfs = [('root1.cpf', 'root1.confml'),
       
   379                              ('root4.cpf', 'root4.confml')])
       
   380     
       
   381 
       
   382 class TestExportInvalidArgs(BaseTestCase):
       
   383     
       
   384     def _run_test_invalid_args(self, args, expected_msg):
       
   385         cmd = '%s -p "%s" %s' \
       
   386             % (get_cmd('export'), TEST_PROJECT_CPF, args)
       
   387         # Note: The following run_command() should really expect the
       
   388         #       return code 2, but for some reason when running from the
       
   389         #       standalone test set, the return value is 0
       
   390         out = self.run_command(cmd, expected_return_code = None)
       
   391         self.assertTrue(expected_msg in out,
       
   392                         "Expected message '%s' not in output.\nOutput:\n%s" % (expected_msg, out))
       
   393     
       
   394     def test_export_format_without_export_dir(self):
       
   395         self._run_test_invalid_args(
       
   396             '-c root1.confml --export-format cpf',
       
   397             "error: --export-format can only be used in conjunction with --export-dir")
       
   398     
       
   399     def test_remote_storage_and_export_dir(self):
       
   400         self._run_test_invalid_args(
       
   401             '-c root1.confml --remote jojo.cpf --export-dir test/',
       
   402             "error: --export-dir and --remote cannot be used at the same time")
       
   403     
       
   404     def test_unknown_export_format(self):
       
   405         self._run_test_invalid_args(
       
   406             '-c root1.confml --export-dir test/ --export-format foo',
       
   407             "error: Invalid export format 'foo'")
       
   408     
       
   409     def test_export_dir_but_no_configurations(self):
       
   410         self._run_test_invalid_args(
       
   411             '--export-dir test/',
       
   412             "error: Use of --export-dir requires at least one configuration to be specified")
       
   413     
       
   414 
       
   415 if __name__ == '__main__':
       
   416       unittest.main()