|
| 1 | +import csv |
| 2 | +import os |
| 3 | +from time import sleep |
| 4 | + |
| 5 | +from nose_parameterized import parameterized |
| 6 | + |
| 7 | +from core.base_class.BaseClass import BaseClass |
| 8 | +from core.device.emulator import Emulator |
| 9 | +from core.device.simulator import Simulator |
| 10 | +from core.git.git import Git |
| 11 | +from core.npm.npm import Npm |
| 12 | +from core.osutils.command import run |
| 13 | +from core.osutils.file import File |
| 14 | +from core.osutils.folder import Folder |
| 15 | +from core.settings.settings import ANDROID_PACKAGE, TYPESCRIPT_PACKAGE, WEBPACK_PACKAGE, ANDROID_KEYSTORE_PATH, \ |
| 16 | + ANDROID_KEYSTORE_PASS, ANDROID_KEYSTORE_ALIAS_PASS, ANDROID_KEYSTORE_ALIAS, TEST_RUN_HOME, PROVISIONING, IOS_PACKAGE |
| 17 | +from core.tns.tns import Tns |
| 18 | +from core.tns.tns_platform_type import Platform |
| 19 | +from core.tns.tns_verifications import TnsAsserts |
| 20 | +import re |
| 21 | + |
| 22 | + |
| 23 | +def read_data(platform, app_name=None): |
| 24 | + csv_file_path = os.path.join(TEST_RUN_HOME, 'tests', 'perf', 'cli_operations_time_values.csv') |
| 25 | + csv_list = tuple(csv.reader(open(csv_file_path, 'rb'), delimiter=',')) |
| 26 | + if app_name is None: |
| 27 | + return [tuple(l) for l in csv_list if l[2].startswith(platform)] |
| 28 | + else: |
| 29 | + return [tuple(l) for l in csv_list if (l[2].startswith(platform) and l[0] == app_name)] |
| 30 | + |
| 31 | + |
| 32 | +class PerfBuildTests(BaseClass): |
| 33 | + platform = os.getenv('PLATFORM', None) |
| 34 | + APP_NAME = os.getenv('APP_NAME', None) |
| 35 | + DATA = read_data(platform, APP_NAME) |
| 36 | + |
| 37 | + @staticmethod |
| 38 | + def get_time(log): |
| 39 | + m = re.search('\d+\.\d+ real', log) |
| 40 | + time = m.group(0).split(".")[0] |
| 41 | + return float(time) |
| 42 | + |
| 43 | + @staticmethod |
| 44 | + def assert_time(expected, actual, tolerance=20, error_message="Startup time is not expected.", |
| 45 | + verification_errors=[]): |
| 46 | + print "Actual startup: " + str(actual) |
| 47 | + print "Expected startup: " + str(expected) |
| 48 | + x = int(expected) |
| 49 | + y = int(actual) |
| 50 | + if actual >= 0: |
| 51 | + diff = abs(x - y) * 1.00 |
| 52 | + try: |
| 53 | + assert diff <= x * tolerance * 0.01, error_message |
| 54 | + except AssertionError, e: |
| 55 | + verification_errors.append(str(e)) |
| 56 | + return verification_errors |
| 57 | + |
| 58 | + @staticmethod |
| 59 | + def report_add_column_titles(): |
| 60 | + |
| 61 | + with open('perfResults.csv', 'a+') as csvfile: |
| 62 | + fieldnames = ['app_name', 'configuration', 'platform', 'action', 'expected_first_start', |
| 63 | + 'actual_first_start', |
| 64 | + 'expected_second_start', 'actual_second_start'] |
| 65 | + |
| 66 | + writer = csv.DictWriter(csvfile, fieldnames=fieldnames) |
| 67 | + |
| 68 | + writer.writeheader() |
| 69 | + |
| 70 | + @staticmethod |
| 71 | + def report_add_data(demo, config, platform, expected_tns_create_time, actual_tns_create_time, |
| 72 | + expected_tns_platform_add_time, |
| 73 | + actual_tns_platform_add_time, expected_tns_build_time, actual_tns_build_time): |
| 74 | + with open('perfResults.csv', 'a+') as csvfile: |
| 75 | + fieldnames = ['app_name', 'configuration', 'platform', 'expected_tns_create_time', |
| 76 | + 'actual_tns_create_time', |
| 77 | + 'expected_tns_platform_add_time', 'actual_tns_platform_add_time', |
| 78 | + 'expected_tns_build_time', 'actual_tns_build_time'] |
| 79 | + |
| 80 | + writer = csv.DictWriter(csvfile, fieldnames=fieldnames) |
| 81 | + |
| 82 | + writer.writerow({'app_name': demo.split('/')[-1], 'configuration': config, 'platform': platform, |
| 83 | + 'expected_tns_create_time': str(expected_tns_create_time), |
| 84 | + 'actual_tns_create_time': str(actual_tns_create_time), |
| 85 | + 'expected_tns_platform_add_time': str(expected_tns_platform_add_time), |
| 86 | + 'actual_tns_platform_add_time': str(actual_tns_platform_add_time), |
| 87 | + 'expected_tns_build_time': str(expected_tns_build_time), |
| 88 | + 'actual_tns_build_time': str(actual_tns_build_time) |
| 89 | + }) |
| 90 | + |
| 91 | + @classmethod |
| 92 | + def setUpClass(cls): |
| 93 | + BaseClass.setUpClass(cls.__name__) |
| 94 | + Npm.cache_clean() |
| 95 | + Emulator.stop() |
| 96 | + Simulator.stop() |
| 97 | + PerfBuildTests.report_add_column_titles() |
| 98 | + |
| 99 | + def setUp(self): |
| 100 | + Tns.kill() |
| 101 | + BaseClass.setUp(self) |
| 102 | + |
| 103 | + def tearDown(self): |
| 104 | + BaseClass.tearDown(self) |
| 105 | + Tns.kill() |
| 106 | + |
| 107 | + @classmethod |
| 108 | + def tearDownClass(cls): |
| 109 | + BaseClass.tearDownClass() |
| 110 | + |
| 111 | + @parameterized.expand(DATA) |
| 112 | + def test_tns_commands_time(self, demo, config, platform, expected_tns_create_time, |
| 113 | + expected_tns_platform_add_time, expected_tns_build_time): |
| 114 | + |
| 115 | + perf_loop = int(os.getenv('RUN_TIMES', '3')) |
| 116 | + tns_create_log = '' |
| 117 | + tns_platform_add_log = '' |
| 118 | + tns_build_log = '' |
| 119 | + actual_tns_create_time = 0.0 |
| 120 | + actual_tns_platform_add_time = 0.0 |
| 121 | + actual_tns_build_time = 0.0 |
| 122 | + for x in range(0, perf_loop): |
| 123 | + print "Number of run " + str((x + 1)) |
| 124 | + if x > 0: |
| 125 | + sleep(60) |
| 126 | + if "ios" in platform: |
| 127 | + attributes = {"--path": self.app_name, |
| 128 | + "--provision": PROVISIONING, |
| 129 | + "--release": ""} |
| 130 | + else: |
| 131 | + attributes = {"--path": self.app_name, |
| 132 | + "--keyStorePath": ANDROID_KEYSTORE_PATH, |
| 133 | + "--keyStorePassword": ANDROID_KEYSTORE_PASS, |
| 134 | + "--keyStoreAlias": ANDROID_KEYSTORE_ALIAS, |
| 135 | + "--keyStoreAliasPassword": ANDROID_KEYSTORE_ALIAS_PASS, |
| 136 | + "--release": ""} |
| 137 | + |
| 138 | + if "webpack" in config: |
| 139 | + attr = {"--bundle": "", "--env.uglify": "", "--env.aot": ""} |
| 140 | + attributes.update(attr) |
| 141 | + |
| 142 | + if "snapshot" in config: |
| 143 | + attr = {"--env.snapshot": ""} |
| 144 | + attributes.update(attr) |
| 145 | + |
| 146 | + if "template" in demo: |
| 147 | + Npm.cache_clean() |
| 148 | + sleep(10) |
| 149 | + tns_create_log = Tns.create_app(self.app_name, attributes={"--template": "https://github.com/" + demo}, |
| 150 | + measureTime=True) |
| 151 | + Npm.cache_clean() |
| 152 | + sleep(20) |
| 153 | + if "android" in platform: |
| 154 | + tns_platform_add_log = Tns.platform_add_android( |
| 155 | + attributes={"--path": self.app_name, "--frameworkPath": ANDROID_PACKAGE}, |
| 156 | + measureTime=True) |
| 157 | + else: |
| 158 | + tns_platform_add_log = Tns.platform_add_ios( |
| 159 | + attributes={"--path": self.app_name, "--frameworkPath": IOS_PACKAGE}, |
| 160 | + measureTime=True) |
| 161 | + sleep(10) |
| 162 | + if "-ng" in demo: |
| 163 | + Tns.update_angular(self.app_name) |
| 164 | + if "-ng" in demo or "-ts" in demo: |
| 165 | + Npm.uninstall(package="nativescript-dev-typescript", option='--save-dev', folder=self.app_name) |
| 166 | + Npm.install(package=TYPESCRIPT_PACKAGE, option='--save-dev', folder=self.app_name) |
| 167 | + if "vue" not in demo: |
| 168 | + Tns.install_npm(package=WEBPACK_PACKAGE, option='--save-dev', folder=self.app_name) |
| 169 | + sleep(10) |
| 170 | + else: |
| 171 | + Npm.cache_clean() |
| 172 | + sleep(10) |
| 173 | + Folder.cleanup(self.app_name) |
| 174 | + Git.clone_repo(repo_url="https://github.com/" + demo, local_folder=self.app_name) |
| 175 | + if "android" in platform: |
| 176 | + Tns.platform_remove(platform=Platform.ANDROID, attributes={"--path": self.app_name}, |
| 177 | + assert_success=False) |
| 178 | + sleep(5) |
| 179 | + Npm.cache_clean() |
| 180 | + sleep(10) |
| 181 | + tns_platform_add_log = Tns.platform_add_android( |
| 182 | + attributes={"--path": self.app_name, "--frameworkPath": ANDROID_PACKAGE}, |
| 183 | + measureTime=True) |
| 184 | + sleep(20) |
| 185 | + else: |
| 186 | + Tns.platform_remove(platform=Platform.IOS, attributes={"--path": self.app_name}, |
| 187 | + assert_success=False) |
| 188 | + sleep(5) |
| 189 | + Npm.cache_clean() |
| 190 | + sleep(10) |
| 191 | + tns_platform_add_log = Tns.platform_add_ios( |
| 192 | + attributes={"--path": self.app_name, "--frameworkPath": IOS_PACKAGE}, |
| 193 | + measureTime=True) |
| 194 | + sleep(20) |
| 195 | + Tns.update_modules(self.app_name) |
| 196 | + Npm.uninstall(package="nativescript-dev-webpack", option='--save-dev', folder=self.app_name) |
| 197 | + Tns.install_npm(package=WEBPACK_PACKAGE, option='--save-dev', folder=self.app_name) |
| 198 | + |
| 199 | + json = str(TnsAsserts.get_package_json(self.app_name)) |
| 200 | + if "angular" in json: |
| 201 | + Tns.update_angular(self.app_name) |
| 202 | + if "typescript" in json: |
| 203 | + Npm.uninstall(package="nativescript-dev-typescript", option='--save-dev', folder=self.app_name) |
| 204 | + Npm.install(package=TYPESCRIPT_PACKAGE, option='--save-dev', folder=self.app_name) |
| 205 | + sleep(10) |
| 206 | + if "timeline" in config: |
| 207 | + package_json = os.path.join(self.app_name, 'app', 'package.json') |
| 208 | + File.replace(package_json, "\"main\": \"main.js\"", "\"main\": \"main.js\",\"profiling\": \"timeline\"") |
| 209 | + |
| 210 | + if "android" in platform: |
| 211 | + tns_build_log = Tns.build_android(attributes=attributes, measureTime=True) |
| 212 | + else: |
| 213 | + tns_build_log = Tns.build_ios(attributes=attributes, measureTime=True) |
| 214 | + |
| 215 | + actual_tns_create_time += PerfBuildTests.get_time(tns_create_log) |
| 216 | + actual_tns_platform_add_time += PerfBuildTests.get_time(tns_platform_add_log) |
| 217 | + actual_tns_build_time += PerfBuildTests.get_time(tns_build_log) |
| 218 | + run('rm -rf {0}'.format(self.app_name)) |
| 219 | + |
| 220 | + actual_tns_create_time = actual_tns_create_time / perf_loop |
| 221 | + actual_tns_platform_add_time = actual_tns_platform_add_time / perf_loop |
| 222 | + actual_tns_build_time = actual_tns_build_time / perf_loop |
| 223 | + verification_errors = [] |
| 224 | + PerfBuildTests.report_add_data(demo, config, platform, expected_tns_create_time, actual_tns_create_time, |
| 225 | + expected_tns_platform_add_time, |
| 226 | + actual_tns_platform_add_time, expected_tns_build_time, actual_tns_build_time) |
| 227 | + |
| 228 | + message = "Tns create project command for platform {1} for {0} with {4} configuration is {3} s. " \ |
| 229 | + "The expected time is {2} s.".format(demo, |
| 230 | + platform, expected_tns_create_time, |
| 231 | + actual_tns_create_time, config) |
| 232 | + |
| 233 | + verification_errors = PerfBuildTests.assert_time(expected=expected_tns_create_time, |
| 234 | + actual=actual_tns_create_time, |
| 235 | + tolerance=20, |
| 236 | + error_message=message, verification_errors=verification_errors) |
| 237 | + |
| 238 | + message = "Tns platform add command for platform {1} for {0} with {4} configuration is {3} s. " \ |
| 239 | + "The expected time is {2} s.".format(demo, platform, expected_tns_platform_add_time, |
| 240 | + actual_tns_platform_add_time, config) |
| 241 | + |
| 242 | + verification_errors = PerfBuildTests.assert_time(expected=expected_tns_platform_add_time, |
| 243 | + actual=actual_tns_platform_add_time, |
| 244 | + tolerance=20, |
| 245 | + error_message=message, verification_errors=verification_errors) |
| 246 | + message = "Tns build command for platform {1} for {0} with {4} configuration is {3} s. " \ |
| 247 | + "The expected time is {2} s.".format(demo, platform, expected_tns_build_time, |
| 248 | + actual_tns_build_time, config) |
| 249 | + |
| 250 | + verification_errors = PerfBuildTests.assert_time(expected=expected_tns_build_time, actual=actual_tns_build_time, |
| 251 | + tolerance=20, |
| 252 | + error_message=message, verification_errors=verification_errors) |
| 253 | + |
| 254 | + self.assertEqual([], verification_errors) |
0 commit comments