2 import os, subprocess, sys, argparse
3 sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
6 from pathlib import Path
12 # The `dotnettool` works normally.
14 if not exist("/usr/bin/dotnettool")
15 return "FAIL : The dotnettool works normally"
17 raw = cmd(f"shell dotnettool")
18 if "Dotnet Tool Version: 1.0" not in raw:
19 return "FAIL : The dotnettool works normally"
23 # The `native image` is generated normally.
25 cmd(f"shell dotnettool --ni-system")
27 if not exist(f"{RUNTIME_DIR}{SPC_DLL}.Backup"):
28 return "FAIL : Create the platform native image"
30 raw = cmd(f"shell find {RUNTIME_DIR} -name *.ni.dll")
31 lines1 = [l for l in raw.splitlines()]
32 raw = cmd(f"shell find {RUNTIME_DIR} -name *.dll -not -name *.ni.dll")
33 lines2 = [l for l in raw.splitlines()]
34 if (len(lines1) + 2) != len(lines2):
35 return "FAIL : The number of .dll and .ni.dll must match"
37 raw = cmd(f"shell find {FRAMEWORK_DIR} -name *.ni.dll")
38 lines1 = [l for l in raw.splitlines()]
39 raw = cmd(f"shell find {FRAMEWORK_DIR} -name *.dll -not -name *.ni.dll")
40 lines2 = [l for l in raw.splitlines() if "/ref/" not in l]
41 if len(lines1) != len(lines2):
42 return "FAIL : The number of .dll and .ni.dll must match"
47 if Path(ni).name.replace(".ni.dll", "") == Path(dll).name.replace(".dll", ""):
51 return "FAIL : The file name of .dll and .ni.dll must match in the platform"
55 # Remove the `platform` native image.
57 cmd(f"shell dotnettool --ni-reset-system")
59 if exist(f"{RUNTIME_DIR}{SPC_DLL}.Backup"):
60 return "FAIL : Remove the platform native image"
64 # Create native image for `System.Private.CoreLib.dll`.
66 if exist(f"{RUNTIME_DIR}{SPC_DLL}.Backup"):
67 cmd(f"shell rm {RUNTIME_DIR}{SPC_DLL}")
68 cmd(f"shell mv {RUNTIME_DIR}{SPC_DLL}.Backup {RUNTIME_DIR}{SPC_DLL}")
70 raw = cmd(f"shell dotnettool --ni-dll {RUNTIME_DIR}{SPC_DLL}")
71 if f"{SPC_DLL} (FNV)" not in raw and \
72 "System.Private.CoreLib.ni.dll generated successfully." not in raw:
73 return f"FAIL : Create native image for {SPC_DLL}"
75 if not exist(f"{RUNTIME_DIR}{SPC_DLL}.Backup"):
76 return f"FAIL : Create native image for {SPC_DLL}"
80 # The file name of `.dll` and `.ni.dll` must match in the framework.
82 cmd(f"shell dotnettool --ni-dir {FRAMEWORK_DIR}")
83 raw = cmd(f"shell find {FRAMEWORK_DIR} -name *.ni.dll")
84 lines1 = [l for l in raw.splitlines()]
85 raw = cmd(f"shell find {FRAMEWORK_DIR} -name *.dll -not -name *.ni.dll")
86 lines2 = [l for l in raw.splitlines() if "/ref/" not in l]
87 if len(lines1) != len(lines2):
88 return "FAIL : The number of .dll and .ni.dll must match"
93 if Path(ni).name.replace(".ni.dll", "") == Path(dll).name.replace(".dll", ""):
97 return "FAIL : The file name of .dll and .ni.dll must match in the {FRAMEWORK_DIR}"
101 # The `.ni.dll` files should not exist in the framework.
103 cmd(f"shell dotnettool --ni-reset-dir {FRAMEWORK_DIR}")
104 raw = cmd(f"shell find {FRAMEWORK_DIR} -name *.ni.dll")
105 lines = [l for l in raw.splitlines()]
107 return "FAIL : The .ni.dll files should not exist"
111 # Create native image for Tizen.dll in `R2R` mode.
113 raw = cmd(f"shell dotnettool --r2r --ni-dll {FRAMEWORK_DIR}Tizen.dll")
114 if "Tizen.dll (R2R)" not in raw and \
115 "Tizen.ni.dll generated successfully." not in raw:
116 return "FAIL : Create native image for Tizen.dll in R2R mode"
120 # Displays detailed information while creating native image for Tizen.Log.dll.
122 raw = cmd(f"shell dotnettool --verbose --ni-dll {FRAMEWORK_DIR}Tizen.Log.dll")
123 if ("Opening input file" not in raw) or \
124 ("Breakdown of Indirections" not in raw) or \
125 ("Tizen.Log.ni.dll generated successfully." not in raw):
126 return "FAIL : Displays detailed information while creating native image for Tizen.Log.dll"
130 # Create a native image for netstandard.dll by specifying the directory containing the IBC files.
132 current_path = os.path.abspath(__file__)
133 packaging_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "../../../packaging"))
136 raw = cmd("capability")
137 line = [l for l in raw.splitlines() if "cpu_arch" in l]
138 target_arch = line[0].split(":")[1]
139 if ("armv7" == target_arch) or \
140 ("x86" == target_arch):
141 ibcdata_zip = "ibcdata_arm.zip"
143 ibcdata_zip = "ibcdata_aarch64.zip"
145 cmd(f"push {packaging_path}/{ibcdata_zip} /tmp")
146 cmd(f"shell unzip /tmp/{ibcdata_zip} -d {IBCDATA_DIR}")
147 cmd(f"shell chsmack -a _ {IBCDATA_DIR} -r")
149 if not exist(f"{IBCDATA_DIR}netstandard.ibc"):
150 return "FAIL : The netstandard.ibc file should exist"
152 raw = cmd(f"shell dotnettool --ibc-dir /usr/share/dotnet.tizen/ibcdata/ --ni-dll {RUNTIME_DIR}netstandard.dll")
153 if ("netstandard.dll (FNV)" not in raw) or \
154 ("netstandard.ni.dll generated successfully." not in raw):
155 return "FAIL : Create native image for netstandard.dll"
159 # The `Launcher_TC_TOOL_01` application does not have native image.
161 sln_name = "Launcher_TC_TOOL_01.Tizen"
163 tpk_path = get_tpk_path(tpk_list, f"{sln_name}")
165 return f"FAIL : Get the tpk path for {sln_name}"
167 if "OK" not in app_install(f"{tpk_path}"):
168 return f"FAIL : Install the application for {tpk_path}"
170 pkg_id = f"org.tizen.example.Launcher_TC_TOOL_01.Tizen"
172 root_path = get_root_path(f"{pkg_id}")
173 if root_path == "None":
174 return f"FAIL : Get the root path for {pkg_id}"
176 if not exist(f"{root_path}/bin/.native_image"):
177 return "FAIL : The .native_image folder should exist"
179 cmd(f"shell dotnettool --ni-reset-pkg {pkg_id}")
181 if exist(f"{root_path}/bin/.native_image"):
182 return "FAIL : The .native_image folder should not exist"
184 raw = cmd(f"shell find {root_path}/bin/ -name *.ni.dll")
185 lines = [l for l in raw.splitlines()]
187 return "FAIL : The .ni.dll files should not exist"
191 # The `Launcher_TC_TOOL_02` application generates native image.
193 sln_name = "Launcher_TC_TOOL_02.Tizen"
195 tpk_path = get_tpk_path(tpk_list, f"{sln_name}")
197 return f"FAIL : Get the tpk path for {sln_name}"
199 if "OK" not in app_install(f"{tpk_path}"):
200 return f"FAIL : Install the application for {tpk_path}"
202 pkg_id = f"org.tizen.example.Launcher_TC_TOOL_02.Tizen"
204 root_path = get_root_path(f"{pkg_id}")
205 if root_path == "None":
206 return f"FAIL : Get the root path for {pkg_id}"
208 if exist(f"{root_path}/bin/.native_image"):
209 return "FAIL : The .native_image folder not should exist"
211 cmd(f"shell dotnettool --ni-pkg {pkg_id}")
213 if not exist(f"{root_path}/bin/.native_image"):
214 return "FAIL : The .native_image folder should exist"
216 raw = cmd(f"shell find {root_path}/bin/.native_image/ -name *.ni.dll")
217 lines1 = [l for l in raw.splitlines()]
218 raw = cmd(f"shell find {root_path}/bin/ -maxdepth 1 -name *.dll -not -name *.ni.dll")
219 lines2 = [l for l in raw.splitlines()]
220 if len(lines1) != len(lines2):
221 return "FAIL : The number of .dll and .ni.dll must match in the application"
226 if Path(ni).name.replace(".ni.dll", "") == Path(dll).name.replace(".dll", ""):
230 return "FAIL : The file name of .dll and .ni.dll must match in the application"
234 # The `prefer_dotnet_aot` metadata value of `true` will regenerates the native image in all .NET applications.
236 sln_name = "Launcher_TC_TOOL_03.Tizen"
238 tpk_path = get_tpk_path(tpk_list, f"{sln_name}")
240 return f"FAIL : Get the tpk path for {sln_name}"
242 if "OK" not in app_install(f"{tpk_path}"):
243 return f"FAIL : Install the application for {tpk_path}"
245 cmd(f"shell dotnettool --ni-regen-all-app")
247 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
248 lines = [l for l in raw.splitlines() if "appid" in l]
250 pkg_id = app.split(": ")[1]
251 raw = subprocess.run((f"sdb -s {serial} shell pkginfo --pkg {pkg_id}").split(), stdout=subprocess.PIPE, encoding="utf-8").stdout
252 readonly = [l for l in raw.splitlines() if "Readonly" in l]
253 if "0" == readonly[0].split(": ")[1]:
254 path = [l for l in raw.splitlines() if "root_path" in l]
255 root_path = path[0].split(": ")[1]
256 raw = cmd(f"shell find {root_path}/bin/.native_image/ -name *.ni.dll")
257 lines1 = [l for l in raw.splitlines()]
258 raw = cmd(f"shell find {root_path}/bin/ -maxdepth 1 -name *.dll -not -name *.ni.dll")
259 lines2 = [l for l in raw.splitlines()]
260 if len(lines1) != len(lines2):
261 return "FAIL : The number of .dll and .ni.dll must match in the application"
266 if Path(ni).name.replace(".ni.dll", "") == Path(dll).name.replace(".dll", ""):
270 return "FAIL : The file name of .dll and .ni.dll must match in the application"
274 # The `prefer_nuget_cache` metadata value of `true` will regenerates the native image in the `TAC`.
276 sln_name = "Launcher_TC_TOOL_04.Tizen"
278 tpk_path = get_tpk_path(tpk_list, f"{sln_name}")
280 return f"FAIL : Get the tpk path for {sln_name}"
282 if "OK" not in app_install(f"{tpk_path}"):
283 return f"FAIL : Install the application for {tpk_path}"
285 raw = cmd(f"shell dotnettool --tac-regen-all")
286 if ".dll (FNV)" not in raw and \
287 ".ni.dll generated successfully." not in raw:
288 return "FAIL : Create native image for TAC"
292 # The `Launcher_TC_TOOL_05` application must not have `TAC` applied.
294 sln_name = "Launcher_TC_TOOL_05.Tizen"
296 tpk_path = get_tpk_path(tpk_list, f"{sln_name}")
298 return f"FAIL : Get the tpk path for {sln_name}"
300 if "OK" not in app_install(f"{tpk_path}"):
301 return f"FAIL : Install the application for {tpk_path}"
303 pkg_id = f"org.tizen.example.Launcher_TC_TOOL_05.Tizen"
305 root_path = get_root_path(f"{pkg_id}")
306 if root_path == "None":
307 return f"FAIL : Get the root path for {pkg_id}"
309 if not exist(f"{root_path}/bin/.tac_symlink"):
310 return "FAIL : The .tac_symlink folder should exist"
312 raw = cmd(f"shell find {root_path}/bin/.tac_symlink/ -name *.dll -not -name *.ni.dll")
313 lines1 = [l for l in raw.splitlines()]
314 raw = cmd(f"shell find {DOTNET_DIR}Xamarin.Forms/4.6.0.967/ -name *.dll -not -name *.ni.dll")
315 lines2 = [l for l in raw.splitlines()]
316 if len(lines1) != len(lines2):
317 return "FAIL : The number of .dll in the .tac_symlink and .dll in the TAC must match"
319 raw = cmd(f"shell ls -alZ {root_path}/bin/.tac_symlink/*.dll")
320 lines = [l for l in raw.splitlines() if ".ni.dll" not in l]
322 origin_path = dll.split("->")[1].strip()
323 if not exist(f"{origin_path}"):
324 return "FAIL : The original file of the symbolic link must exist"
326 cmd(f"shell dotnettool --tac-disable-pkg {pkg_id}")
328 if exist(f"{root_path}/bin/.tac_symlink"):
329 return "FAIL : The .tac_symlink folder should not exist"
331 raw = cmd(f"shell find {root_path}/bin/ -maxdepth 1 -name *.dll -not -name *.ni.dll")
332 lines = [l for l in raw.splitlines()]
334 return "FAIL : The number of .dll must exist correctly in the bin folder"
338 # The `Launcher_TC_TOOL_06` application must have `TAC` applied.
340 sln_name = "Launcher_TC_TOOL_06.Tizen"
342 tpk_path = get_tpk_path(tpk_list, f"{sln_name}")
344 return f"FAIL : Get the tpk path for {sln_name}"
346 if "OK" not in app_install(f"{tpk_path}"):
347 return f"FAIL : Install the application for {tpk_path}"
349 pkg_id = f"org.tizen.example.Launcher_TC_TOOL_06.Tizen"
351 root_path = get_root_path(f"{pkg_id}")
352 if root_path == "None":
353 return f"FAIL : Get the root path for {pkg_id}"
355 cmd(f"shell dotnettool --tac-disable-pkg {pkg_id}")
357 if exist(f"{root_path}/bin/.tac_symlink"):
358 return "FAIL : The .tac_symlink folder should not exist"
360 raw = cmd(f"shell find {root_path}/bin/ -maxdepth 1 -name *.dll -not -name *.ni.dll")
361 lines = [l for l in raw.splitlines()]
363 return "FAIL : The number of .dll must exist correctly in the bin folder"
365 cmd(f"shell dotnettool --tac-enable-pkg {pkg_id}")
367 if not exist(f"{root_path}/bin/.tac_symlink"):
368 return "FAIL : The .tac_symlink folder should exist"
370 raw = cmd(f"shell find {root_path}/bin/.tac_symlink/ -name *.dll -not -name *.ni.dll")
371 lines1 = [l for l in raw.splitlines()]
372 raw = cmd(f"shell find {DOTNET_DIR}Xamarin.Forms/4.6.0.967/ -name *.dll -not -name *.ni.dll")
373 lines2 = [l for l in raw.splitlines()]
374 if len(lines1) != len(lines2):
375 return "FAIL : The number of .dll in the .tac_symlink and .dll in the TAC must match"
377 raw = cmd(f"shell ls -alZ {root_path}/bin/.tac_symlink/*.dll")
378 lines = [l for l in raw.splitlines() if ".ni.dll" not in l]
380 origin_path = dll.split("->")[1].strip()
381 if not exist(f"{origin_path}"):
382 return "FAIL : The original file of the symbolic link must exist"
386 # The `DB` of the restored `TAC` and `TLC` must be a valid value.
388 sln_name = "Launcher_TC_TOOL_07.Tizen"
390 tpk_path = get_tpk_path(tpk_list, f"{sln_name}")
392 return f"FAIL : Get the tpk path for {sln_name}"
394 if "OK" not in app_install(f"{tpk_path}"):
395 return f"FAIL : Install the application for {tpk_path}"
397 cmd(f"shell rm {DOTNET_DIR}.TAC.App.list.db*")
398 cmd(f"shell rm {DOTNET_DIR}.TLC.App.list.db*")
400 cmd(f"shell dotnettool --tac-restore-db")
402 pkg_id = f"org.tizen.example.Launcher_TC_TOOL_07.Tizen"
404 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
405 lines = [l for l in raw.splitlines() if f"{pkg_id}" in l]
407 if ("SkiaSharp/2.80.2" not in rcd) and \
408 ("Xamarin.Forms/4.6.0.967" not in rcd):
409 return "FAIL : TAC database must have a valid value"
411 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
412 lines = [l for l in raw.splitlines() if f"{pkg_id}" in l]
414 if "libSkiaSharp.so..8e2fcc43f9c49b2de7b6212ff5ed914b319bc92f125715b9fe1f35786df82f98" not in rcd:
415 return "FAIL : TLC database must have a valid value"
419 # The prefer_dotnet_aot metadata value of true will regenerates the native image in all .NET applications of read-only type.
421 sln_name = "Launcher_TC_TOOL_08.Tizen"
423 tpk_path = get_tpk_path(tpk_list, f"{sln_name}")
425 return f"FAIL : Get the tpk path for {sln_name}"
427 raw = cmd(f"push {tpk_path} /usr/apps/.preload-tpk/")
428 if "1 file(s) pushed. 0 file(s) skipped." in raw:
429 cmd(f"shell install_preload_pkg")
431 cmd(f"shell dotnettool --ni-regen-all-ro-app")
433 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
434 lines = [l for l in raw.splitlines() if "appid" in l]
436 pkg_id = app.split(": ")[1]
437 raw = subprocess.run((f"sdb -s {serial} shell pkginfo --pkg {pkg_id}").split(), stdout=subprocess.PIPE, encoding="utf-8").stdout
438 readonly = [l for l in raw.splitlines() if "Readonly" in l]
439 if "1" == readonly[0].split(": ")[1]:
440 path = [l for l in raw.splitlines() if "root_path" in l]
441 root_path = path[0].split(": ")[1]
442 raw = cmd(f"shell find {DOTNET_DIR}apps/{pkg_id}/bin/.native_image/ -name *.ni.dll")
443 lines1 = [l for l in raw.splitlines()]
444 raw = cmd(f"shell find {root_path}/bin/ -maxdepth 1 -name *.dll -not -name *.ni.dll")
445 lines2 = [l for l in raw.splitlines()]
446 if len(lines1) != len(lines2):
447 return "FAIL : The number of .dll and .ni.dll must match in the application"
452 if Path(ni).name.replace(".ni.dll", "") == Path(dll).name.replace(".dll", ""):
456 return "FAIL : The file name of .dll and .ni.dll must match in the application"
460 # The `Launcher_TC_TOOL_08` application should load the newly generated native image.
462 pkg_id = f"org.tizen.example.Launcher_TC_TOOL_08.Tizen"
464 pid = launch_and_get_pid(f"-e", f"{pkg_id}")
466 return f"FAIL : Get the pid for {pkg_id}"
468 raw = cmd(f"shell cat /proc/{pid}/smaps | grep Xamarin.Forms.*.dll")
469 if (f"{DOTNET_DIR}apps/{pkg_id}/bin/.native_image/Xamarin.Forms.Platform.Tizen.ni.dll" not in raw) or \
470 (f"{DOTNET_DIR}apps/{pkg_id}/bin/.native_image/Xamarin.Forms.Core.ni.dll" not in raw) or \
471 (f"{DOTNET_DIR}apps/{pkg_id}/bin/.native_image/Xamarin.Forms.Platform.ni.dll" not in raw):
472 return "FAIL : The Xamarin.Forms in the application should be loaded when running the application"
474 cmd(f"shell app_launcher -t {pkg_id}")
478 # It should be done together for update test.
491 #dotnettool --resolve-all-app
497 cmd(f"shell mount -o remount,rw /")
500 tpk_list = search_tpk(f"{module_name}")
502 p = run_tc_array(module_name, tc_array)
503 f = len(tc_array) - p
504 r = round(((p / len(tc_array)) * 100), 2)
505 print(f"--- {module_name} TCT Result ---\nFAIL : [{f}] / PASS : [{p}] - [{r}%]\n")
507 # Uninstall the application and restore to original state
509 cmd(f"uninstall org.tizen.example.Launcher_TC_TOOL_01.Tizen")
510 cmd(f"uninstall org.tizen.example.Launcher_TC_TOOL_02.Tizen")
511 cmd(f"uninstall org.tizen.example.Launcher_TC_TOOL_03.Tizen")
512 cmd(f"uninstall org.tizen.example.Launcher_TC_TOOL_04.Tizen")
513 cmd(f"uninstall org.tizen.example.Launcher_TC_TOOL_05.Tizen")
514 cmd(f"uninstall org.tizen.example.Launcher_TC_TOOL_06.Tizen")
515 cmd(f"uninstall org.tizen.example.Launcher_TC_TOOL_07.Tizen")
517 cmd(f"shell rm {FRAMEWORK_DIR}Tizen.ni.dll")
518 cmd(f"shell rm {FRAMEWORK_DIR}Tizen.Log.ni.dll")
519 cmd(f"shell rm {RUNTIME_DIR}netstandard.ni.dll")
521 cmd(f"shell rm -rf {IBCDATA_DIR}")
523 cmd(f"shell rm -rf {DOTNET_DIR}apps/org.tizen.example.Launcher_TC_TOOL_08.Tizen")
527 parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter)
528 parser.add_argument("TC_NUMBER", type=str, nargs="*", help="Individual excution")
529 args = parser.parse_args()
532 if args.TC_NUMBER and "TC_" in args.TC_NUMBER[0]:
534 for tc_num in args.TC_NUMBER:
535 if tc_num not in funcMap:
536 print(f"There is no {tc_num} test.")
539 tc_array.append(funcMap[tc_num])
541 tc_array = [TC_01, TC_02, TC_03, TC_04, TC_05, TC_06, TC_07, TC_08, TC_09, TC_10, TC_11, TC_12, TC_13, TC_14, TC_15, TC_16, TC_17, TC_18]
544 if len(sys.argv) >= 2 and "TC_" not in sys.argv[1]:
545 serial = read_serial(sys.argv[1])
547 serial = read_serial(None)
550 print("No connected device(s).")
553 device = get_device_type()
554 print(f"=== Dotnet-Launcher [{device}] Test Case - ({module_name}) ===")
561 'TC_01': TC_01, 'TC_02': TC_02, 'TC_03': TC_03, 'TC_04': TC_04, 'TC_05': TC_05, 'TC_06': TC_06,
562 'TC_07': TC_07, 'TC_08': TC_08, 'TC_09': TC_09, 'TC_10': TC_10, 'TC_11': TC_11, 'TC_12': TC_12,
563 '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,
564 '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,
565 '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,
566 '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
570 if __name__ == "__main__":
573 except KeyboardInterrupt:
574 print("\nExit (Pressed Ctrl+C)")