d6bcd45c585bb6ecf1e3e8f88e45f0ca956244be
[platform/core/dotnet/launcher.git] / tests / TCs / 6_TOOL / TOOL.py
1 #!/usr/bin/env python3
2 import os, subprocess, sys, argparse
3 sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
4
5 from time import sleep
6 from pathlib import Path
7 from Utils import *
8
9
10 module_name = "TOOL"
11
12
13 # The `dotnettool` works normally.
14 def TC_01():
15     if not exist("/usr/bin/dotnettool"):
16         return "FAIL : The dotnettool works normally"
17
18     raw = cmd(f"shell dotnettool")
19     if "Dotnet Tool Version: 1.0" not in raw:
20         return "FAIL : The dotnettool works normally"
21
22     return "PASS"
23
24 # The `native image` is generated normally.
25 def TC_02():
26     cmd(f"shell dotnettool --ni-system")
27
28     if not exist(f"{RUNTIME_DIR}{SPC_DLL}.Backup"):
29         return "FAIL : Create the platform native image"
30
31     raw = cmd(f"shell find {RUNTIME_DIR} -name *.ni.dll")
32     lines1 = [l for l in raw.splitlines()]
33     len1 = len(lines1) + 1 # System.Private.CoreLib.dll
34     raw = cmd(f"shell find {RUNTIME_DIR} -maxdepth 1 -name *.dll -not -name *.ni.dll")
35     lines2 = [l for l in raw.splitlines()]
36     len2 = len(lines2)
37     if len1 != len2:
38         return f"FAIL : The number of .dll({len2}) and .ni.dll({len1}) must match in the {RUNTIME_DIR}"
39
40     raw = cmd(f"shell find {FRAMEWORK_DIR} -name *.ni.dll")
41     lines1 = [l for l in raw.splitlines()]
42     len1 = len(lines1)
43     raw = cmd(f"shell find {FRAMEWORK_DIR} -name *.dll -not -name *.ni.dll")
44     lines2 = [l for l in raw.splitlines() if "/ref/" not in l]
45     len2 = len(lines2)
46     if len1 != len2:
47         return f"FAIL : The number of .dll({len2}) and .ni.dll({len1}) must match in the {FRAMEWORK_DIR}"
48
49     for ni in lines1:
50         is_same = False
51         for dll in lines2:
52             if Path(ni).name.replace(".ni.dll", "") == Path(dll).name.replace(".dll", ""):
53                 is_same = True
54                 break
55         if not is_same:
56             return "FAIL : The file name of .dll and .ni.dll must match in the platform"
57
58     return "PASS"
59
60 # Remove the `platform` native image.
61 def TC_03():
62     cmd(f"shell dotnettool --ni-reset-system")
63
64     if exist(f"{RUNTIME_DIR}{SPC_DLL}.Backup"):
65         return "FAIL : Remove the platform native image"
66
67     return "PASS"
68
69 # Create native image for `System.Private.CoreLib.dll`.
70 def TC_04():
71     if exist(f"{RUNTIME_DIR}{SPC_DLL}.Backup"):
72         cmd(f"shell rm {RUNTIME_DIR}{SPC_DLL}")
73         cmd(f"shell mv {RUNTIME_DIR}{SPC_DLL}.Backup {RUNTIME_DIR}{SPC_DLL}")
74
75     raw = cmd(f"shell dotnettool --ni-dll {RUNTIME_DIR}{SPC_DLL}")
76     if (f"{SPC_DLL}" not in raw) or \
77        ("System.Private.CoreLib.ni.dll generated successfully." not in raw):
78         return f"FAIL : Create native image for {SPC_DLL}"
79
80     if not exist(f"{RUNTIME_DIR}{SPC_DLL}.Backup"):
81         return f"FAIL : Create native image for {SPC_DLL}"
82
83     return "PASS"
84
85 # The file name of `.dll` and `.ni.dll` must match in the framework.
86 def TC_05():
87     cmd(f"shell dotnettool --ni-dir {FRAMEWORK_DIR}")
88     raw = cmd(f"shell find {FRAMEWORK_DIR} -name *.ni.dll")
89     lines1 = [l for l in raw.splitlines()]
90     raw = cmd(f"shell find {FRAMEWORK_DIR} -name *.dll -not -name *.ni.dll")
91     lines2 = [l for l in raw.splitlines() if "/ref/" not in l]
92     if len(lines1) != len(lines2):
93         return "FAIL : The number of .dll and .ni.dll must match"
94
95     for ni in lines1:
96         is_same = False
97         for dll in lines2:
98             if Path(ni).name.replace(".ni.dll", "") == Path(dll).name.replace(".dll", ""):
99                 is_same = True
100                 break
101         if not is_same:
102             return "FAIL : The file name of .dll and .ni.dll must match in the {FRAMEWORK_DIR}"
103
104     return "PASS"
105
106 # The `.ni.dll` files should not exist in the framework.
107 def TC_06():
108     cmd(f"shell dotnettool --ni-reset-dir {FRAMEWORK_DIR}")
109     raw = cmd(f"shell find {FRAMEWORK_DIR} -name *.ni.dll")
110     lines = [l for l in raw.splitlines()]
111     if len(lines) != 0:
112         return "FAIL : The .ni.dll files should not exist"
113
114     return "PASS"
115
116 # Create native image for Tizen.dll in `R2R` mode.
117 def TC_07():
118     raw = cmd(f"shell dotnettool --r2r --ni-dll {FRAMEWORK_DIR}Tizen.dll")
119     if ("Tizen.dll" not in raw) or \
120        ("Tizen.ni.dll generated successfully." not in raw):
121         return "FAIL : Create native image for Tizen.dll in R2R mode"
122
123     return "PASS"
124
125 # Displays detailed information while creating native image for Tizen.Log.dll.
126 def TC_08():
127     raw = cmd(f"shell dotnettool --verbose --ni-dll {FRAMEWORK_DIR}Tizen.Log.dll")
128     if ("Tizen.Log.ni.dll generated successfully." not in raw) or \
129        ("Processing " not in raw) or \
130        (" dependencies" not in raw) or \
131        ("Moved to phase " not in raw):
132         return "FAIL : Displays detailed information while creating native image for Tizen.Log.dll"
133
134     return "PASS"
135
136 # Create a native image for netstandard.dll by specifying the directory containing the IBC files.
137 def TC_09():
138     packaging_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "../../../packaging"))
139     ibcdata_zip = ""
140
141     raw = cmd("capability")
142     line = [l for l in raw.splitlines() if "cpu_arch" in l]
143     target_arch = line[0].split(":")[1]
144     if ("armv7" == target_arch) or \
145        ("x86" == target_arch):
146         ibcdata_zip = "ibcdata_arm.zip"
147     else:
148         ibcdata_zip = "ibcdata_aarch64.zip"
149
150     cmd(f"push {packaging_path}/{ibcdata_zip} /tmp")
151     cmd(f"shell unzip /tmp/{ibcdata_zip} -d {IBCDATA_DIR}")
152     cmd(f"shell chsmack -a _ {IBCDATA_DIR} -r")
153
154     if not exist(f"{IBCDATA_DIR}netstandard.ibc"):
155         return "FAIL : The netstandard.ibc file should exist"
156
157     raw = cmd(f"shell dotnettool --ibc-dir /usr/share/dotnet.tizen/ibcdata/ --ni-dll {RUNTIME_DIR}netstandard.dll")
158     if ("netstandard.dll" not in raw) or \
159        ("netstandard.ni.dll generated successfully." not in raw):
160         return "FAIL : Create native image for netstandard.dll"
161
162     return "PASS"
163
164 # The `Launcher_TC_TOOL_01` application does not have native image.
165 def TC_10():
166     sln_name = "Launcher_TC_TOOL_01.Tizen"
167
168     tpk_path = get_tpk_path(tpk_list, f"{sln_name}")
169     if tpk_path == None:
170         return f"FAIL : Get the tpk path for {sln_name}"
171
172     if "OK" not in app_install(f"{tpk_path}"):
173         return f"FAIL : Install the application for {tpk_path}"
174
175     pkg_id = f"org.tizen.example.Launcher_TC_TOOL_01.Tizen"
176
177     root_path = get_root_path(f"{pkg_id}")
178     if root_path == "None":
179         return f"FAIL : Get the root path for {pkg_id}"
180
181     if not exist(f"{root_path}/bin/.native_image"):
182         return "FAIL : The .native_image folder should exist"
183
184     cmd(f"shell dotnettool --ni-reset-pkg {pkg_id}")
185
186     if exist(f"{root_path}/bin/.native_image"):
187         return "FAIL : The .native_image folder should not exist"
188
189     raw = cmd(f"shell find {root_path}/bin/ -name *.ni.dll")
190     lines = [l for l in raw.splitlines()]
191     if len(lines) != 0:
192         return "FAIL : The .ni.dll files should not exist"
193
194     return "PASS"
195
196 # The `Launcher_TC_TOOL_02` application generates native image.
197 def TC_11():
198     sln_name = "Launcher_TC_TOOL_02.Tizen"
199
200     tpk_path = get_tpk_path(tpk_list, f"{sln_name}")
201     if tpk_path == None:
202         return f"FAIL : Get the tpk path for {sln_name}"
203
204     if "OK" not in app_install(f"{tpk_path}"):
205         return f"FAIL : Install the application for {tpk_path}"
206
207     pkg_id = f"org.tizen.example.Launcher_TC_TOOL_02.Tizen"
208
209     root_path = get_root_path(f"{pkg_id}")
210     if root_path == "None":
211         return f"FAIL : Get the root path for {pkg_id}"
212
213     if exist(f"{root_path}/bin/.native_image"):
214         return "FAIL : The .native_image folder not should exist"
215
216     cmd(f"shell dotnettool --ni-pkg {pkg_id}")
217
218     if not exist(f"{root_path}/bin/.native_image"):
219         return "FAIL : The .native_image folder should exist"
220
221     raw = cmd(f"shell find {root_path}/bin/.native_image/ -name *.ni.dll")
222     lines1 = [l for l in raw.splitlines()]
223     raw = cmd(f"shell find {root_path}/bin/ -maxdepth 1 -name *.dll -not -name *.ni.dll")
224     lines2 = [l for l in raw.splitlines()]
225     if len(lines1) != len(lines2):
226         return "FAIL : The number of .dll and .ni.dll must match in the application"
227
228     for ni in lines1:
229         is_same = False
230         for dll in lines2:
231             if Path(ni).name.replace(".ni.dll", "") == Path(dll).name.replace(".dll", ""):
232                 is_same = True
233                 break
234         if not is_same:
235             return "FAIL : The file name of .dll and .ni.dll must match in the application"
236
237     return "PASS"
238
239 # The `prefer_dotnet_aot` metadata value of `true` will regenerates the native image in all .NET applications.
240 def TC_12():
241     sln_name = "Launcher_TC_TOOL_03.Tizen"
242
243     tpk_path = get_tpk_path(tpk_list, f"{sln_name}")
244     if tpk_path == None:
245         return f"FAIL : Get the tpk path for {sln_name}"
246
247     if "OK" not in app_install(f"{tpk_path}"):
248         return f"FAIL : Install the application for {tpk_path}"
249
250     cmd(f"shell dotnettool --ni-regen-all-app")
251
252     raw = subprocess.run((f"sdb -s {serial} shell pkginfo --metadata-flt").split(), stdout=subprocess.PIPE, input=f"http://tizen.org/metadata/prefer_dotnet_aot\ntrue\n", encoding="utf-8").stdout
253     lines = [l for l in raw.splitlines() if "appid" in l]
254     for app in lines:
255         pkg_id = app.split(": ")[1]
256         raw = subprocess.run((f"sdb -s {serial} shell pkginfo --pkg {pkg_id}").split(), stdout=subprocess.PIPE, encoding="utf-8").stdout
257         readonly = [l for l in raw.splitlines() if "Readonly" in l]
258         if "0" == readonly[0].split(": ")[1]:
259             path = [l for l in raw.splitlines() if "root_path" in l]
260             root_path = path[0].split(": ")[1]
261             raw = cmd(f"shell find {root_path}/bin/.native_image/ -name *.ni.dll")
262             lines1 = [l for l in raw.splitlines()]
263             raw = cmd(f"shell find {root_path}/bin/ -maxdepth 1 -name *.dll -not -name *.ni.dll")
264             lines2 = [l for l in raw.splitlines()]
265             if len(lines1) != len(lines2):
266                 return "FAIL : The number of .dll and .ni.dll must match in the application"
267
268             for ni in lines1:
269                 is_same = False
270                 for dll in lines2:
271                     if Path(ni).name.replace(".ni.dll", "") == Path(dll).name.replace(".dll", ""):
272                         is_same = True
273                         break
274                 if not is_same:
275                     return "FAIL : The file name of .dll and .ni.dll must match in the application"
276
277     return "PASS"
278
279 # The `prefer_nuget_cache` metadata value of `true` will regenerates the native image in the `TAC`.
280 def TC_13():
281     sln_name = "Launcher_TC_TOOL_04.Tizen"
282
283     tpk_path = get_tpk_path(tpk_list, f"{sln_name}")
284     if tpk_path == None:
285         return f"FAIL : Get the tpk path for {sln_name}"
286
287     if "OK" not in app_install(f"{tpk_path}"):
288         return f"FAIL : Install the application for {tpk_path}"
289
290     raw = cmd(f"shell dotnettool --tac-regen-all")
291     if (".dll" not in raw) or \
292        (".ni.dll generated successfully." not in raw):
293         return "FAIL : Create native image for TAC"
294
295     return "PASS"
296
297 # The `Launcher_TC_TOOL_05` application must not have `TAC` applied.
298 def TC_14():
299     sln_name = "Launcher_TC_TOOL_05.Tizen"
300
301     tpk_path = get_tpk_path(tpk_list, f"{sln_name}")
302     if tpk_path == None:
303         return f"FAIL : Get the tpk path for {sln_name}"
304
305     if "OK" not in app_install(f"{tpk_path}"):
306         return f"FAIL : Install the application for {tpk_path}"
307
308     pkg_id = f"org.tizen.example.Launcher_TC_TOOL_05.Tizen"
309
310     root_path = get_root_path(f"{pkg_id}")
311     if root_path == "None":
312         return f"FAIL : Get the root path for {pkg_id}"
313
314     if not exist(f"{root_path}/bin/.tac_symlink"):
315         return "FAIL : The .tac_symlink folder should exist"
316
317     raw = cmd(f"shell find {root_path}/bin/.tac_symlink/ -name *.dll -not -name *.ni.dll")
318     lines1 = [l for l in raw.splitlines()]
319     raw = cmd(f"shell find {DOTNET_DIR}Xamarin.Forms/4.6.0.967/ -name *.dll -not -name *.ni.dll")
320     lines2 = [l for l in raw.splitlines()]
321     if len(lines1) != len(lines2):
322         return "FAIL : The number of .dll in the .tac_symlink and .dll in the TAC must match"
323
324     raw = cmd(f"shell ls -alZ {root_path}/bin/.tac_symlink/*.dll")
325     lines = [l for l in raw.splitlines() if ".ni.dll" not in l]
326     for dll in lines:
327         origin_path = dll.split("->")[1].strip()
328         if not exist(f"{origin_path}"):
329             return "FAIL : The original file of the symbolic link must exist"
330
331     cmd(f"shell dotnettool --tac-disable-pkg {pkg_id}")
332
333     if exist(f"{root_path}/bin/.tac_symlink"):
334         return "FAIL : The .tac_symlink folder should not exist"
335
336     raw = cmd(f"shell find {root_path}/bin/ -maxdepth 1 -name *.dll -not -name *.ni.dll")
337     lines = [l for l in raw.splitlines()]
338     if len(lines) != 6:
339         return "FAIL : The number of .dll must exist correctly in the bin folder"
340
341     return "PASS"
342
343 # The `Launcher_TC_TOOL_06` application must have `TAC` applied.
344 def TC_15():
345     sln_name = "Launcher_TC_TOOL_06.Tizen"
346
347     tpk_path = get_tpk_path(tpk_list, f"{sln_name}")
348     if tpk_path == None:
349         return f"FAIL : Get the tpk path for {sln_name}"
350
351     if "OK" not in app_install(f"{tpk_path}"):
352         return f"FAIL : Install the application for {tpk_path}"
353
354     pkg_id = f"org.tizen.example.Launcher_TC_TOOL_06.Tizen"
355
356     root_path = get_root_path(f"{pkg_id}")
357     if root_path == "None":
358         return f"FAIL : Get the root path for {pkg_id}"
359
360     cmd(f"shell dotnettool --tac-disable-pkg {pkg_id}")
361
362     if exist(f"{root_path}/bin/.tac_symlink"):
363         return "FAIL : The .tac_symlink folder should not exist"
364
365     raw = cmd(f"shell find {root_path}/bin/ -maxdepth 1 -name *.dll -not -name *.ni.dll")
366     lines = [l for l in raw.splitlines()]
367     if len(lines) != 6:
368         return "FAIL : The number of .dll must exist correctly in the bin folder"
369
370     cmd(f"shell dotnettool --tac-enable-pkg {pkg_id}")
371
372     if not exist(f"{root_path}/bin/.tac_symlink"):
373         return "FAIL : The .tac_symlink folder should exist"
374
375     raw = cmd(f"shell find {root_path}/bin/.tac_symlink/ -name *.dll -not -name *.ni.dll")
376     lines1 = [l for l in raw.splitlines()]
377     raw = cmd(f"shell find {DOTNET_DIR}Xamarin.Forms/4.6.0.967/ -name *.dll -not -name *.ni.dll")
378     lines2 = [l for l in raw.splitlines()]
379     if len(lines1) != len(lines2):
380         return "FAIL : The number of .dll in the .tac_symlink and .dll in the TAC must match"
381
382     raw = cmd(f"shell ls -alZ {root_path}/bin/.tac_symlink/*.dll")
383     lines = [l for l in raw.splitlines() if ".ni.dll" not in l]
384     for dll in lines:
385         origin_path = dll.split("->")[1].strip()
386         if not exist(f"{origin_path}"):
387             return "FAIL : The original file of the symbolic link must exist"
388
389     return "PASS"
390
391 # The `DB` of the restored `TAC` and `TLC` must be a valid value.
392 def TC_16():
393     sln_name = "Launcher_TC_TOOL_07.Tizen"
394
395     tpk_path = get_tpk_path(tpk_list, f"{sln_name}")
396     if tpk_path == None:
397         return f"FAIL : Get the tpk path for {sln_name}"
398
399     if "OK" not in app_install(f"{tpk_path}"):
400         return f"FAIL : Install the application for {tpk_path}"
401
402     cmd(f"shell rm {DOTNET_DIR}.TAC.App.list.db*")
403     cmd(f"shell rm {DOTNET_DIR}.TLC.App.list.db*")
404
405     cmd(f"shell dotnettool --tac-restore-db")
406
407     pkg_id = f"org.tizen.example.Launcher_TC_TOOL_07.Tizen"
408
409     raw = subprocess.run((f"sdb -s {serial} shell sqlite3 {DOTNET_DIR}.TAC.App.list.db").split(), stdout=subprocess.PIPE, input=f"select * from TAC;\n.q\n", encoding="utf-8").stdout
410     lines = [l for l in raw.splitlines() if f"{pkg_id}" in l]
411     for rcd in lines:
412         is_exist = False
413         if ("SkiaSharp/2.80.2" in rcd) or \
414            ("Xamarin.Forms/4.6.0.967" in rcd):
415             is_exist = True
416             continue
417         if not is_exist:
418             return "FAIL : TAC database must have a valid value"
419
420     raw = subprocess.run((f"sdb -s {serial} shell sqlite3 {DOTNET_DIR}.TLC.App.list.db").split(), stdout=subprocess.PIPE, input=f"select * from TLC;\n.q\n", encoding="utf-8").stdout
421     lines = [l for l in raw.splitlines() if f"{pkg_id}" in l]
422     for rcd in lines:
423         if "libSkiaSharp.so..8e2fcc43f9c49b2de7b6212ff5ed914b319bc92f125715b9fe1f35786df82f98" not in rcd:
424             return "FAIL : TLC database must have a valid value"
425
426     return "PASS"
427
428 # The prefer_dotnet_aot metadata value of true will regenerates the native image in all .NET applications of read-only type.
429 def TC_17():
430     sln_name = "Launcher_TC_TOOL_08.Tizen"
431
432     tpk_path = get_tpk_path(tpk_list, f"{sln_name}")
433     if tpk_path == None:
434         return f"FAIL : Get the tpk path for {sln_name}"
435
436     cmd(f"shell mount -o remount,rw /")
437
438     raw = cmd(f"push {tpk_path} /usr/apps/.preload-tpk/")
439     if "1 file(s) pushed. 0 file(s) skipped." in raw:
440         cmd(f"shell install_preload_pkg")
441
442     cmd(f"shell mount -o remount,ro /")
443
444     cmd(f"shell dotnettool --ni-regen-all-app")
445
446     raw = subprocess.run((f"sdb -s {serial} shell pkginfo --metadata-flt").split(), stdout=subprocess.PIPE, input=f"http://tizen.org/metadata/prefer_dotnet_aot\ntrue\n", encoding="utf-8").stdout
447     lines = [l for l in raw.splitlines() if "appid" in l]
448     for app in lines:
449         pkg_id = app.split(": ")[1]
450         raw = subprocess.run((f"sdb -s {serial} shell pkginfo --pkg {pkg_id}").split(), stdout=subprocess.PIPE, encoding="utf-8").stdout
451         readonly = [l for l in raw.splitlines() if "Readonly" in l]
452         if "1" == readonly[0].split(": ")[1]:
453             path = [l for l in raw.splitlines() if "root_path" in l]
454             root_path = path[0].split(": ")[1]
455             raw = cmd(f"shell find {DOTNET_DIR}apps/{pkg_id}/bin/.native_image/ -name *.ni.dll")
456             lines1 = [l for l in raw.splitlines()]
457             raw = cmd(f"shell find {root_path}/bin/ -maxdepth 1 -name *.dll -not -name *.ni.dll")
458             lines2 = [l for l in raw.splitlines()]
459             if len(lines1) != len(lines2):
460                 return "FAIL : The number of .dll and .ni.dll must match in the application"
461
462             for ni in lines1:
463                 is_same = False
464                 for dll in lines2:
465                     if Path(ni).name.replace(".ni.dll", "") == Path(dll).name.replace(".dll", ""):
466                         is_same = True
467                         break
468                 if not is_same:
469                     return "FAIL : The file name of .dll and .ni.dll must match in the application"
470
471     return "PASS"
472
473 # The `Launcher_TC_TOOL_08` application should load the newly generated native image.
474 def TC_18():
475     pkg_id = f"org.tizen.example.Launcher_TC_TOOL_08.Tizen"
476
477     pid = launch_and_get_pid(f"-e", f"{pkg_id}")
478     if 0 == pid:
479         return f"FAIL : Get the pid for {pkg_id}"
480
481     raw = cmd(f"shell cat /proc/{pid}/smaps | grep Xamarin.Forms.*.dll")
482     if (f"{DOTNET_DIR}apps/{pkg_id}/bin/.native_image/Xamarin.Forms.Platform.Tizen.ni.dll" not in raw) or \
483        (f"{DOTNET_DIR}apps/{pkg_id}/bin/.native_image/Xamarin.Forms.Core.ni.dll" not in raw) or \
484        (f"{DOTNET_DIR}apps/{pkg_id}/bin/.native_image/Xamarin.Forms.Platform.ni.dll" not in raw):
485         return "FAIL : The Xamarin.Forms in the application should be loaded when running the application"
486
487     cmd(f"shell app_launcher -t {pkg_id}")
488
489     return "PASS"
490
491 # It should be done together for update test.
492 def TC_17_18():
493     ret = TC_17()
494     if "PASS" != ret:
495         return f"{ret}"
496
497     ret = TC_18()
498     if  "PASS" != ret:
499         return f"{ret}"
500
501     return "PASS"
502
503 # The `Launcher_TC_TOOL_09` application of read-only type generates native image.
504 def TC_19():
505     sln_name = "Launcher_TC_TOOL_09.Tizen"
506
507     tpk_path = get_tpk_path(tpk_list, f"{sln_name}")
508     if tpk_path == None:
509         return f"FAIL : Get the tpk path for {sln_name}"
510
511     cmd(f"shell mount -o remount,rw /")
512     raw = cmd(f"push {tpk_path} /usr/apps/.preload-tpk/")
513     if "1 file(s) pushed. 0 file(s) skipped." in raw:
514         cmd(f"shell install_preload_pkg")
515     cmd(f"shell mount -o remount,ro /")
516
517     pkg_id = f"org.tizen.example.Launcher_TC_TOOL_09.Tizen"
518
519     root_path = get_root_path(f"{pkg_id}")
520     if root_path == "None":
521         return f"FAIL : Get the root path for {pkg_id}"
522
523     if exist(f"{root_path}/bin/.native_image"):
524         return "FAIL : The .native_image folder not should exist"
525
526     cmd(f"shell dotnettool --ni-pkg {pkg_id}")
527
528     if not exist(f"{DOTNET_DIR}apps/{pkg_id}/bin/.native_image"):
529         return "FAIL : The .native_image folder should exist"
530
531     raw = cmd(f"shell find {DOTNET_DIR}apps/{pkg_id}/bin/.native_image/ -name *.ni.dll")
532     lines1 = [l for l in raw.splitlines()]
533     raw = cmd(f"shell find {root_path}/bin/ -maxdepth 1 -name *.dll -not -name *.ni.dll")
534     lines2 = [l for l in raw.splitlines()]
535     if len(lines1) != len(lines2):
536         return "FAIL : The number of .dll and .ni.dll must match in the application"
537
538     for ni in lines1:
539         is_same = False
540         for dll in lines2:
541             if Path(ni).name.replace(".ni.dll", "") == Path(dll).name.replace(".dll", ""):
542                 is_same = True
543                 break
544         if not is_same:
545             return "FAIL : The file name of .dll and .ni.dll must match in the application"
546
547     return "PASS"
548
549 # Print command and option while creating native image for Tizen.dll.
550 def TC_20():
551     cmd(f"shell mount -o remount,rw /")
552     raw = cmd(f"shell dotnettool --print-cmd --ni-dll {FRAMEWORK_DIR}Tizen.dll")
553     if ("Tizen.ni.dll generated successfully." not in raw) or \
554        ("==================== NI Commands =========================" not in raw) or \
555        ("+ /usr/share/dotnet.tizen/netcoreapp/corerun" not in raw) or \
556        ("+ /usr/share/dotnet.tizen/netcoreapp/crossgen2/crossgen2.dll" not in raw) or \
557        ("+ --jitpath" not in raw) or \
558        ("+ /usr/share/dotnet.tizen/netcoreapp/libclrjit.so" not in raw) or \
559        ("+ --targetarch" not in raw) or \
560        ("+ --out-near-input" not in raw) or \
561        ("+ --single-file-compilation" not in raw) or \
562        ("+ --resilient" not in raw) or \
563        ("+ --Ot" not in raw) or \
564        (f"+ {FRAMEWORK_DIR}Tizen.dll" not in raw) or \
565        ("+ (null)" not in raw):
566         return "FAIL : Print command and option while creating native image for Tizen.dll"
567
568     return "PASS"
569
570 # Create native image for netstandard.dll by adding options --inputbubble and --compilebubblegenerics.
571 def TC_21():
572     cmd(f"shell mount -o remount,rw /")
573     raw = cmd(f"shell dotnettool --inputbubble --inputbubbleref \'{RUNTIME_DIR}*.dll\' --print-cmd --ni-dll {RUNTIME_DIR}netstandard.dll")
574     if ("netstandard.ni.dll generated successfully." not in raw) or \
575        ("+ --inputbubble" not in raw) or \
576        ("+ --compilebubblegenerics" not in raw):
577         return "FAIL : Create native image for netstandard.dll by adding options --inputbubble and --compilebubblegenereics"
578
579     return "PASS"
580
581 # Create native image for System.dll by adding options --inputbubble and --inputbubbleref.
582 def TC_22():
583     cmd(f"shell mount -o remount,rw /")
584     raw = cmd(f"shell dotnettool --inputbubble --inputbubbleref \'{RUNTIME_DIR}crossgen2/*.dll\' --print-cmd --ni-dll {RUNTIME_DIR}System.dll")
585     if ("System.ni.dll generated successfully." not in raw) or \
586        ("+ --inputbubble" not in raw) or \
587        ("+ --inputbubbleref:/usr/share/dotnet.tizen/netcoreapp/crossgen2/*.dll" not in raw):
588         return "FAIL : Create native image for System.dll by adding options --inputbubble and --inputbubbleref"
589
590     return "PASS"
591
592 # Create native image for System.Console.dll by adding option --ref.
593 def TC_23():
594     cmd(f"shell mount -o remount,rw /")
595     raw = cmd(f"shell dotnettool --ref \'{RUNTIME_DIR}*.dll:{RUNTIME_DIR}crossgen2/*.dll\' --print-cmd --ni-dll {RUNTIME_DIR}System.Console.dll")
596     if ("System.Console.ni.dll generated successfully." not in raw) or \
597        (f"+ -r:/usr/share/dotnet.tizen/netcoreapp/*.dll" not in raw) or \
598        (f"+ -r:/usr/share/dotnet.tizen/netcoreapp/crossgen2/*.dll" not in raw):
599         return "FAIL : Create native image for System.Console.dll by adding option --ref"
600
601     return "PASS"
602
603 # Create native image for mscorlib.dll by adding option --no-pipeline
604 def TC_24():
605     cmd(f"shell mount -o remount,rw /")
606     raw = cmd(f"shell dotnettool --ni-dll --no-pipeline --print-cmd {RUNTIME_DIR}mscorlib.dll")
607     if ("mscorlib.ni.dll generated successfully." not in raw) or \
608        ("+ -o" not in raw) or \
609        ("/mscorlib.ni.dll" not in raw):
610         return "FAIL : Create native image for mscorlib.dll by adding option --no-pipeline"
611
612     return "PASS"
613
614 #def TC_25():
615 #dotnettool --rm-app-profile
616 #dotnettool --rm-all-app-profile
617
618 # Run the test
619 def run():
620     cmd(f"root on")
621     cmd(f"shell mount -o remount,rw /")
622
623     global tpk_list
624     tpk_list = search_tpk(f"{module_name}")
625
626     pn = run_tc_array(module_name, tc_array)
627     n = int(pn.split(":")[0])
628     f = int(pn.split(":")[1])
629     p = int(pn.split(":")[2])
630     r = 0.0
631     if (len(tc_array) - n) != 0:
632         r = round(((p / (len(tc_array) - n)) * 100), 2)
633     print(f"--- {module_name} TCT Result ---\nNONE : [{n}] / FAIL : [{f}] / PASS : [{p}] - [{r}%]\n")
634
635 # Uninstall the application and restore to original state
636 def clean():
637     cmd(f"uninstall org.tizen.example.Launcher_TC_TOOL_01.Tizen")
638     cmd(f"uninstall org.tizen.example.Launcher_TC_TOOL_02.Tizen")
639     cmd(f"uninstall org.tizen.example.Launcher_TC_TOOL_03.Tizen")
640     cmd(f"uninstall org.tizen.example.Launcher_TC_TOOL_04.Tizen")
641     cmd(f"uninstall org.tizen.example.Launcher_TC_TOOL_05.Tizen")
642     cmd(f"uninstall org.tizen.example.Launcher_TC_TOOL_06.Tizen")
643     cmd(f"uninstall org.tizen.example.Launcher_TC_TOOL_07.Tizen")
644
645     cmd(f"shell rm {FRAMEWORK_DIR}Tizen.ni.dll")
646     cmd(f"shell rm {FRAMEWORK_DIR}Tizen.Log.ni.dll")
647     cmd(f"shell rm {RUNTIME_DIR}netstandard.ni.dll")
648     cmd(f"shell rm {RUNTIME_DIR}System.ni.dll")
649     cmd(f"shell rm {RUNTIME_DIR}System.Console.ni.dll")
650     cmd(f"shell rm {RUNTIME_DIR}mscorlib.ni.dll")
651
652 #    cmd(f"shell rm -rf {IBCDATA_DIR}")
653
654     cmd(f"shell rm -rf {DOTNET_DIR}apps/org.tizen.example.Launcher_TC_TOOL_08.Tizen")
655     cmd(f"shell rm -rf {DOTNET_DIR}apps/org.tizen.example.Launcher_TC_TOOL_09.Tizen")
656
657 # Main entry point
658 def main():
659     parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter)
660     parser.add_argument("TC_NUMBER", type=str, nargs="*", help="Individual excution")
661     args = parser.parse_args()
662
663     global tc_array
664     if args.TC_NUMBER and "TC_" in args.TC_NUMBER[0]:
665         tc_array = []
666         for tc_num in args.TC_NUMBER:
667             if tc_num not in funcMap:
668                 print(f"There is no {tc_num} test.")
669                 exit(1)
670             else:
671                 tc_array.append(funcMap[tc_num])
672     else:
673         # skip TC_07 (--r2r), TC_09 (--ibc-dir)
674         tc_array = [TC_01, TC_02, TC_03, TC_04, TC_05, TC_06, TC_08, TC_10, TC_11, TC_12, TC_13, TC_14, TC_15, TC_16, TC_17, TC_18, TC_19, TC_20, TC_21, TC_22, TC_23, TC_24]
675
676     global serial
677     if len(sys.argv) >= 2 and "TC_" not in sys.argv[1]:
678         serial = read_serial(sys.argv[1])
679     else:
680         serial = read_serial(None)
681
682     if serial is None:
683         print("No connected device(s).")
684         exit(1)
685
686     device = get_device_type()
687     print(f"=== Dotnet-Launcher [{device}] Test Case - ({module_name}) ===")
688
689     run()
690     clean()
691
692
693 funcMap = {
694 'TC_01': TC_01, 'TC_02': TC_02, 'TC_03': TC_03, 'TC_04': TC_04, 'TC_05': TC_05, 'TC_06': TC_06,
695 'TC_07': TC_07, 'TC_08': TC_08, 'TC_09': TC_09, 'TC_10': TC_10, 'TC_11': TC_11, 'TC_12': TC_12,
696 'TC_13': TC_13, 'TC_14': TC_14, 'TC_15': TC_15, 'TC_16': TC_16, 'TC_17': TC_17, 'TC_18': TC_17_18,
697 'TC_19': TC_19, 'TC_20': TC_20, 'TC_21': TC_21, 'TC_22' : TC_22, 'TC_23' : TC_23, 'TC_24' : TC_24,
698 'TOOL_TC_01': TC_01, 'TOOL_TC_02': TC_02, 'TOOL_TC_03': TC_03, 'TOOL_TC_04': TC_04, 'TOOL_TC_05': TC_05, 'TOOL_TC_06': TC_06,
699 'TOOL_TC_07': TC_07, 'TOOL_TC_08': TC_08, 'TOOL_TC_09': TC_09, 'TOOL_TC_10': TC_10, 'TOOL_TC_11': TC_11, 'TOOL_TC_12': TC_12,
700 'TOOL_TC_13': TC_13, 'TOOL_TC_14': TC_14, 'TOOL_TC_15': TC_15, 'TOOL_TC_16': TC_16, 'TOOL_TC_17': TC_17, 'TOOL_TC_18': TC_17_18, 'TOOL_TC_19': TC_19, 'TOOL_TC_20': TC_20, 'TOOL_TC_21': TC_21, 'TOOL_TC_22' : TC_22, 'TOOL_TC_23' : TC_23, 'TOOL_TC_24' : TC_24
701 }
702
703
704 if __name__ == "__main__":
705     try:
706         main()
707     except KeyboardInterrupt:
708         print("\nExit (Pressed Ctrl+C)")
709         exit(1)