summaryrefslogtreecommitdiffstats
path: root/meta/lib/oeqa
diff options
context:
space:
mode:
authorAdrian Freihofer <adrian.freihofer@gmail.com>2024-01-22 14:58:22 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2024-02-18 07:34:42 +0000
commit946cac328aa57acabc0456a188118a5dc24dd1fe (patch)
tree25424efc3addd199f4a61249ab12cbfdff5cd81e /meta/lib/oeqa
parent3ccb4d8ab1d7f4103f245f754086ec19f0195cc1 (diff)
downloadpoky-946cac328aa57acabc0456a188118a5dc24dd1fe.tar.gz
oe-selftest devtool: ide-sdk tests
Add some oe-selftests for the new devtool ide-sdk plugin. Most of the workflows are covered. Many thanks to Enguerrand de Ribaucourt for testing and bug fixing. (From OE-Core rev: 458fa66b117ccad690720931f912de09655691dc) Signed-off-by: Adrian Freihofer <adrian.freihofer@siemens.com> Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/lib/oeqa')
-rw-r--r--meta/lib/oeqa/selftest/cases/devtool.py492
1 files changed, 492 insertions, 0 deletions
diff --git a/meta/lib/oeqa/selftest/cases/devtool.py b/meta/lib/oeqa/selftest/cases/devtool.py
index dd3a5e9b5c..d76b974fbb 100644
--- a/meta/lib/oeqa/selftest/cases/devtool.py
+++ b/meta/lib/oeqa/selftest/cases/devtool.py
@@ -12,6 +12,7 @@ import tempfile
12import glob 12import glob
13import fnmatch 13import fnmatch
14import unittest 14import unittest
15import json
15 16
16from oeqa.selftest.case import OESelftestTestCase 17from oeqa.selftest.case import OESelftestTestCase
17from oeqa.utils.commands import runCmd, bitbake, get_bb_var, create_temp_layer 18from oeqa.utils.commands import runCmd, bitbake, get_bb_var, create_temp_layer
@@ -2362,3 +2363,494 @@ class DevtoolUpgradeTests(DevtoolBase):
2362 2363
2363 #Step 4.5 2364 #Step 4.5
2364 runCmd("grep %s %s" % (modconfopt, codeconfigfile)) 2365 runCmd("grep %s %s" % (modconfopt, codeconfigfile))
2366
2367
2368class DevtoolIdeSdkTests(DevtoolBase):
2369 def _write_bb_config(self, recipe_names):
2370 """Helper to write the bitbake local.conf file"""
2371 conf_lines = [
2372 'IMAGE_CLASSES += "image-combined-dbg"',
2373 'IMAGE_GEN_DEBUGFS = "1"',
2374 'IMAGE_INSTALL:append = " gdbserver %s"' % ' '.join(
2375 [r + '-ptest' for r in recipe_names])
2376 ]
2377 self.write_config("\n".join(conf_lines))
2378
2379 def _check_workspace(self):
2380 """Check if a workspace directory is available and setup the cleanup"""
2381 self.assertTrue(not os.path.exists(self.workspacedir),
2382 'This test cannot be run with a workspace directory under the build directory')
2383 self.track_for_cleanup(self.workspacedir)
2384 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
2385
2386 def _workspace_scripts_dir(self, recipe_name):
2387 return os.path.realpath(os.path.join(self.builddir, 'workspace', 'ide-sdk', recipe_name, 'scripts'))
2388
2389 def _sources_scripts_dir(self, src_dir):
2390 return os.path.realpath(os.path.join(src_dir, 'oe-scripts'))
2391
2392 def _workspace_gdbinit_dir(self, recipe_name):
2393 return os.path.realpath(os.path.join(self.builddir, 'workspace', 'ide-sdk', recipe_name, 'scripts', 'gdbinit'))
2394
2395 def _sources_gdbinit_dir(self, src_dir):
2396 return os.path.realpath(os.path.join(src_dir, 'oe-gdbinit'))
2397
2398 def _devtool_ide_sdk_recipe(self, recipe_name, build_file, testimage):
2399 """Setup a recipe for working with devtool ide-sdk
2400
2401 Basically devtool modify -x followed by some tests
2402 """
2403 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
2404 self.track_for_cleanup(tempdir)
2405 self.add_command_to_tearDown('bitbake -c clean %s' % recipe_name)
2406
2407 result = runCmd('devtool modify %s -x %s' % (recipe_name, tempdir))
2408 self.assertExists(os.path.join(tempdir, build_file),
2409 'Extracted source could not be found')
2410 self.assertExists(os.path.join(self.workspacedir, 'conf',
2411 'layer.conf'), 'Workspace directory not created')
2412 matches = glob.glob(os.path.join(self.workspacedir,
2413 'appends', recipe_name + '.bbappend'))
2414 self.assertTrue(matches, 'bbappend not created %s' % result.output)
2415
2416 # Test devtool status
2417 result = runCmd('devtool status')
2418 self.assertIn(recipe_name, result.output)
2419 self.assertIn(tempdir, result.output)
2420 self._check_src_repo(tempdir)
2421
2422 # Usually devtool ide-sdk would initiate the build of the SDK.
2423 # But there is a circular dependency with starting Qemu and passing the IP of runqemu to devtool ide-sdk.
2424 if testimage:
2425 bitbake("%s qemu-native qemu-helper-native" % testimage)
2426 deploy_dir_image = get_bb_var('DEPLOY_DIR_IMAGE')
2427 self.add_command_to_tearDown('bitbake -c clean %s' % testimage)
2428 self.add_command_to_tearDown(
2429 'rm -f %s/%s*' % (deploy_dir_image, testimage))
2430
2431 return tempdir
2432
2433 def _get_recipe_ids(self, recipe_name):
2434 """IDs needed to write recipe specific config entries into IDE config files"""
2435 package_arch = get_bb_var('PACKAGE_ARCH', recipe_name)
2436 recipe_id = recipe_name + "-" + package_arch
2437 recipe_id_pretty = recipe_name + ": " + package_arch
2438 return (recipe_id, recipe_id_pretty)
2439
2440 def _verify_install_script_code(self, tempdir, recipe_name):
2441 """Verify the scripts referred by the tasks.json file are fine.
2442
2443 This function does not depend on Qemu. Therefore it verifies the scripts
2444 exists and the delete step works as expected. But it does not try to
2445 deploy to Qemu.
2446 """
2447 recipe_id, recipe_id_pretty = self._get_recipe_ids(recipe_name)
2448 with open(os.path.join(tempdir, '.vscode', 'tasks.json')) as tasks_j:
2449 tasks_d = json.load(tasks_j)
2450 tasks = tasks_d["tasks"]
2451 task_install = next(
2452 (task for task in tasks if task["label"] == "install && deploy-target %s" % recipe_id_pretty), None)
2453 self.assertIsNot(task_install, None)
2454 # execute only the bb_run_do_install script since the deploy would require e.g. Qemu running.
2455 i_and_d_script = "install_and_deploy_" + recipe_id
2456 i_and_d_script_path = os.path.join(
2457 self._workspace_scripts_dir(recipe_name), i_and_d_script)
2458 self.assertExists(i_and_d_script_path)
2459 del_script = "delete_package_dirs_" + recipe_id
2460 del_script_path = os.path.join(
2461 self._workspace_scripts_dir(recipe_name), del_script)
2462 self.assertExists(del_script_path)
2463 runCmd(del_script_path, cwd=tempdir)
2464
2465 def _devtool_ide_sdk_qemu(self, tempdir, qemu, recipe_name, example_exe):
2466 """Verify deployment and execution in Qemu system work for one recipe.
2467
2468 This function checks the entire SDK workflow: changing the code, recompiling
2469 it and deploying it back to Qemu, and checking that the changes have been
2470 incorporated into the provided binaries. It also runs the tests of the recipe.
2471 """
2472 recipe_id, _ = self._get_recipe_ids(recipe_name)
2473 i_and_d_script = "install_and_deploy_" + recipe_id
2474 install_deploy_cmd = os.path.join(
2475 self._workspace_scripts_dir(recipe_name), i_and_d_script)
2476 self.assertExists(install_deploy_cmd,
2477 '%s script not found' % install_deploy_cmd)
2478 runCmd(install_deploy_cmd)
2479
2480 MAGIC_STRING_ORIG = "Magic: 123456789"
2481 MAGIC_STRING_NEW = "Magic: 987654321"
2482 ptest_cmd = "ptest-runner " + recipe_name
2483
2484 # validate that SSH is working
2485 status, _ = qemu.run("uname")
2486 self.assertEqual(
2487 status, 0, msg="Failed to connect to the SSH server on Qemu")
2488
2489 # Verify the unmodified example prints the magic string
2490 status, output = qemu.run(example_exe)
2491 self.assertEqual(status, 0, msg="%s failed: %s" %
2492 (example_exe, output))
2493 self.assertIn(MAGIC_STRING_ORIG, output)
2494
2495 # Verify the unmodified ptests work
2496 status, output = qemu.run(ptest_cmd)
2497 self.assertEqual(status, 0, msg="%s failed: %s" % (ptest_cmd, output))
2498 self.assertIn("PASS: cpp-example-lib", output)
2499
2500 # Replace the Magic String in the code, compile and deploy to Qemu
2501 cpp_example_lib_hpp = os.path.join(tempdir, 'cpp-example-lib.hpp')
2502 with open(cpp_example_lib_hpp, 'r') as file:
2503 cpp_code = file.read()
2504 cpp_code = cpp_code.replace(MAGIC_STRING_ORIG, MAGIC_STRING_NEW)
2505 with open(cpp_example_lib_hpp, 'w') as file:
2506 file.write(cpp_code)
2507 runCmd(install_deploy_cmd, cwd=tempdir)
2508
2509 # Verify the modified example prints the modified magic string
2510 status, output = qemu.run(example_exe)
2511 self.assertEqual(status, 0, msg="%s failed: %s" %
2512 (example_exe, output))
2513 self.assertNotIn(MAGIC_STRING_ORIG, output)
2514 self.assertIn(MAGIC_STRING_NEW, output)
2515
2516 # Verify the modified example ptests work
2517 status, output = qemu.run(ptest_cmd)
2518 self.assertEqual(status, 0, msg="%s failed: %s" % (ptest_cmd, output))
2519 self.assertIn("PASS: cpp-example-lib", output)
2520
2521 def _gdb_cross(self):
2522 """Verify gdb-cross is provided by devtool ide-sdk"""
2523 target_arch = self.td["TARGET_ARCH"]
2524 target_sys = self.td["TARGET_SYS"]
2525 gdb_recipe = "gdb-cross-" + target_arch
2526 gdb_binary = target_sys + "-gdb"
2527
2528 native_sysroot = get_bb_var("RECIPE_SYSROOT_NATIVE", gdb_recipe)
2529 r = runCmd("%s --version" % gdb_binary,
2530 native_sysroot=native_sysroot, target_sys=target_sys)
2531 self.assertEqual(r.status, 0)
2532 self.assertIn("GNU gdb", r.output)
2533
2534 def _gdb_cross_debugging(self, qemu, recipe_name, example_exe):
2535 """Verify gdb-cross is working
2536
2537 Test remote debugging:
2538 break main
2539 run
2540 continue
2541 """
2542 sshargs = '-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no'
2543 gdbserver_script = os.path.join(self._workspace_scripts_dir(
2544 recipe_name), 'gdbserver_1234_usr-bin-' + example_exe + '_m')
2545 gdb_script = os.path.join(self._workspace_scripts_dir(
2546 recipe_name), 'gdb_1234_usr-bin-' + example_exe)
2547
2548 # Start a gdbserver
2549 r = runCmd(gdbserver_script)
2550 self.assertEqual(r.status, 0)
2551
2552 # Check there is a gdbserver running
2553 r = runCmd('ssh %s root@%s %s' % (sshargs, qemu.ip, 'ps'))
2554 self.assertEqual(r.status, 0)
2555 self.assertIn("gdbserver ", r.output)
2556
2557 # Check the pid file is correct
2558 test_cmd = "cat /proc/$(cat /tmp/gdbserver_1234_usr-bin-" + \
2559 example_exe + "/pid)/cmdline"
2560 r = runCmd('ssh %s root@%s %s' % (sshargs, qemu.ip, test_cmd))
2561 self.assertEqual(r.status, 0)
2562 self.assertIn("gdbserver", r.output)
2563
2564 # Test remote debugging works
2565 r = runCmd(
2566 gdb_script + " --batch -ex 'break main' --ex 'run' -ex 'continue'")
2567 self.assertEqual(r.status, 0)
2568 self.assertIn("Breakpoint 1, main", r.output)
2569 self.assertIn("exited normally", r.output)
2570
2571 # Stop the gdbserver
2572 r = runCmd(gdbserver_script + ' stop')
2573 self.assertEqual(r.status, 0)
2574
2575 # Check there is no gdbserver running
2576 r = runCmd('ssh %s root@%s %s' % (sshargs, qemu.ip, 'ps'))
2577 self.assertEqual(r.status, 0)
2578 self.assertNotIn("gdbserver ", r.output)
2579
2580 def _verify_cmake_preset(self, tempdir):
2581 """Verify the generated cmake preset works as expected
2582
2583 Check if compiling works
2584 Check if unit tests can be executed in qemu (not qemu-system)
2585 """
2586 with open(os.path.join(tempdir, 'CMakeUserPresets.json')) as cmake_preset_j:
2587 cmake_preset_d = json.load(cmake_preset_j)
2588 config_presets = cmake_preset_d["configurePresets"]
2589 self.assertEqual(len(config_presets), 1)
2590 cmake_exe = config_presets[0]["cmakeExecutable"]
2591 preset_name = config_presets[0]["name"]
2592
2593 # Verify the wrapper for cmake native is available
2594 self.assertExists(cmake_exe)
2595
2596 # Verify the cmake preset generated by devtool ide-sdk is available
2597 result = runCmd('%s --list-presets' % cmake_exe, cwd=tempdir)
2598 self.assertIn(preset_name, result.output)
2599
2600 # Verify cmake re-uses the o files compiled by bitbake
2601 result = runCmd('%s --build --preset %s' %
2602 (cmake_exe, preset_name), cwd=tempdir)
2603 self.assertIn("ninja: no work to do.", result.output)
2604
2605 # Verify the unit tests work (in Qemu user mode)
2606 result = runCmd('%s --build --preset %s --target test' %
2607 (cmake_exe, preset_name), cwd=tempdir)
2608 self.assertIn("100% tests passed", result.output)
2609
2610 # Verify re-building and testing works again
2611 result = runCmd('%s --build --preset %s --target clean' %
2612 (cmake_exe, preset_name), cwd=tempdir)
2613 self.assertIn("Cleaning", result.output)
2614 result = runCmd('%s --build --preset %s' %
2615 (cmake_exe, preset_name), cwd=tempdir)
2616 self.assertIn("Building", result.output)
2617 self.assertIn("Linking", result.output)
2618 result = runCmd('%s --build --preset %s --target test' %
2619 (cmake_exe, preset_name), cwd=tempdir)
2620 self.assertIn("Running tests...", result.output)
2621 self.assertIn("100% tests passed", result.output)
2622
2623 @OETestTag("runqemu")
2624 def test_devtool_ide_sdk_none_qemu(self):
2625 """Start qemu-system and run tests for multiple recipes. ide=none is used."""
2626 recipe_names = ["cmake-example", "meson-example"]
2627 testimage = "oe-selftest-image"
2628
2629 self._check_workspace()
2630 self._write_bb_config(recipe_names)
2631 self._check_runqemu_prerequisites()
2632
2633 # Verify deployment to Qemu (system mode) works
2634 bitbake(testimage)
2635 with runqemu(testimage, runqemuparams="nographic") as qemu:
2636 # cmake-example recipe
2637 recipe_name = "cmake-example"
2638 example_exe = "cmake-example"
2639 build_file = "CMakeLists.txt"
2640 tempdir = self._devtool_ide_sdk_recipe(
2641 recipe_name, build_file, testimage)
2642 bitbake_sdk_cmd = 'devtool ide-sdk %s %s -t root@%s -c --ide=none' % (
2643 recipe_name, testimage, qemu.ip)
2644 runCmd(bitbake_sdk_cmd)
2645 self._verify_cmake_preset(tempdir)
2646 self._devtool_ide_sdk_qemu(tempdir, qemu, recipe_name, example_exe)
2647 # Verify the oe-scripts sym-link is valid
2648 self.assertEqual(self._workspace_scripts_dir(
2649 recipe_name), self._sources_scripts_dir(tempdir))
2650 # Verify GDB is working after devtool ide-sdk
2651 self._gdb_cross()
2652 self._gdb_cross_debugging(qemu, recipe_name, example_exe)
2653
2654 # meson-example recipe
2655 recipe_name = "meson-example"
2656 example_exe = "mesonex"
2657 build_file = "meson.build"
2658 tempdir = self._devtool_ide_sdk_recipe(
2659 recipe_name, build_file, testimage)
2660 bitbake_sdk_cmd = 'devtool ide-sdk %s %s -t root@%s -c --ide=none' % (
2661 recipe_name, testimage, qemu.ip)
2662 runCmd(bitbake_sdk_cmd)
2663 self._devtool_ide_sdk_qemu(tempdir, qemu, recipe_name, example_exe)
2664 # Verify the oe-scripts sym-link is valid
2665 self.assertEqual(self._workspace_scripts_dir(
2666 recipe_name), self._sources_scripts_dir(tempdir))
2667 # Verify GDB is working after devtool ide-sdk
2668 self._gdb_cross()
2669 self._gdb_cross_debugging(qemu, recipe_name, example_exe)
2670
2671 def test_devtool_ide_sdk_code_cmake(self):
2672 """Verify a cmake recipe works with ide=code mode"""
2673 recipe_name = "cmake-example"
2674 build_file = "CMakeLists.txt"
2675 testimage = "oe-selftest-image"
2676
2677 self._check_workspace()
2678 self._write_bb_config([recipe_name])
2679 tempdir = self._devtool_ide_sdk_recipe(
2680 recipe_name, build_file, testimage)
2681 bitbake_sdk_cmd = 'devtool ide-sdk %s %s -t root@192.168.17.17 -c --ide=code' % (
2682 recipe_name, testimage)
2683 runCmd(bitbake_sdk_cmd)
2684 self._verify_cmake_preset(tempdir)
2685 self._verify_install_script_code(tempdir, recipe_name)
2686 self._gdb_cross()
2687
2688 def test_devtool_ide_sdk_code_meson(self):
2689 """Verify a meson recipe works with ide=code mode"""
2690 recipe_name = "meson-example"
2691 build_file = "meson.build"
2692 testimage = "oe-selftest-image"
2693
2694 self._check_workspace()
2695 self._write_bb_config([recipe_name])
2696 tempdir = self._devtool_ide_sdk_recipe(
2697 recipe_name, build_file, testimage)
2698 bitbake_sdk_cmd = 'devtool ide-sdk %s %s -t root@192.168.17.17 -c --ide=code' % (
2699 recipe_name, testimage)
2700 runCmd(bitbake_sdk_cmd)
2701
2702 with open(os.path.join(tempdir, '.vscode', 'settings.json')) as settings_j:
2703 settings_d = json.load(settings_j)
2704 meson_exe = settings_d["mesonbuild.mesonPath"]
2705 meson_build_folder = settings_d["mesonbuild.buildFolder"]
2706
2707 # Verify the wrapper for meson native is available
2708 self.assertExists(meson_exe)
2709
2710 # Verify meson re-uses the o files compiled by bitbake
2711 result = runCmd('%s compile -C %s' %
2712 (meson_exe, meson_build_folder), cwd=tempdir)
2713 self.assertIn("ninja: no work to do.", result.output)
2714
2715 # Verify the unit tests work (in Qemu)
2716 runCmd('%s test -C %s' % (meson_exe, meson_build_folder), cwd=tempdir)
2717
2718 # Verify re-building and testing works again
2719 result = runCmd('%s compile -C %s --clean' %
2720 (meson_exe, meson_build_folder), cwd=tempdir)
2721 self.assertIn("Cleaning...", result.output)
2722 result = runCmd('%s compile -C %s' %
2723 (meson_exe, meson_build_folder), cwd=tempdir)
2724 self.assertIn("Linking target", result.output)
2725 runCmd('%s test -C %s' % (meson_exe, meson_build_folder), cwd=tempdir)
2726
2727 self._verify_install_script_code(tempdir, recipe_name)
2728 self._gdb_cross()
2729
2730 def test_devtool_ide_sdk_shared_sysroots(self):
2731 """Verify the shared sysroot SDK"""
2732
2733 # Handle the workspace (which is not needed by this test case)
2734 self._check_workspace()
2735
2736 result_init = runCmd(
2737 'devtool ide-sdk -m shared oe-selftest-image cmake-example meson-example --ide=code')
2738 bb_vars = get_bb_vars(
2739 ['REAL_MULTIMACH_TARGET_SYS', 'DEPLOY_DIR_IMAGE', 'COREBASE'], "meta-ide-support")
2740 environment_script = 'environment-setup-%s' % bb_vars['REAL_MULTIMACH_TARGET_SYS']
2741 deploydir = bb_vars['DEPLOY_DIR_IMAGE']
2742 environment_script_path = os.path.join(deploydir, environment_script)
2743 cpp_example_src = os.path.join(
2744 bb_vars['COREBASE'], 'meta-selftest', 'recipes-test', 'cpp', 'files')
2745
2746 # Verify the cross environment script is available
2747 self.assertExists(environment_script_path)
2748
2749 def runCmdEnv(cmd, cwd):
2750 cmd = '/bin/sh -c ". %s > /dev/null && %s"' % (
2751 environment_script_path, cmd)
2752 return runCmd(cmd, cwd)
2753
2754 # Verify building the C++ example works with CMake
2755 tempdir_cmake = tempfile.mkdtemp(prefix='devtoolqa')
2756 self.track_for_cleanup(tempdir_cmake)
2757
2758 result_cmake = runCmdEnv("which cmake", cwd=tempdir_cmake)
2759 cmake_native = os.path.normpath(result_cmake.output.strip())
2760 self.assertExists(cmake_native)
2761
2762 runCmdEnv('cmake %s' % cpp_example_src, cwd=tempdir_cmake)
2763 runCmdEnv('cmake --build %s' % tempdir_cmake, cwd=tempdir_cmake)
2764
2765 # Verify the printed note really referres to a cmake executable
2766 cmake_native_code = ""
2767 for line in result_init.output.splitlines():
2768 m = re.search(r'"cmake.cmakePath": "(.*)"', line)
2769 if m:
2770 cmake_native_code = m.group(1)
2771 break
2772 self.assertExists(cmake_native_code)
2773 self.assertEqual(cmake_native, cmake_native_code)
2774
2775 # Verify building the C++ example works with Meson
2776 tempdir_meson = tempfile.mkdtemp(prefix='devtoolqa')
2777 self.track_for_cleanup(tempdir_meson)
2778
2779 result_cmake = runCmdEnv("which meson", cwd=tempdir_meson)
2780 meson_native = os.path.normpath(result_cmake.output.strip())
2781 self.assertExists(meson_native)
2782
2783 runCmdEnv('meson setup %s' % tempdir_meson, cwd=cpp_example_src)
2784 runCmdEnv('meson compile', cwd=tempdir_meson)
2785
2786 def test_devtool_ide_sdk_plugins(self):
2787 """Test that devtool ide-sdk can use plugins from other layers."""
2788
2789 # We need a workspace layer and a modified recipe (but no image)
2790 modified_recipe_name = "meson-example"
2791 modified_build_file = "meson.build"
2792 testimage = "oe-selftest-image"
2793 shared_recipe_name = "cmake-example"
2794
2795 self._check_workspace()
2796 self._write_bb_config([modified_recipe_name])
2797 tempdir = self._devtool_ide_sdk_recipe(
2798 modified_recipe_name, modified_build_file, None)
2799
2800 IDE_RE = re.compile(r'.*--ide \{(.*)\}.*')
2801
2802 def get_ides_from_help(help_str):
2803 m = IDE_RE.search(help_str)
2804 return m.group(1).split(',')
2805
2806 # verify the default plugins are available but the foo plugin is not
2807 result = runCmd('devtool ide-sdk -h')
2808 found_ides = get_ides_from_help(result.output)
2809 self.assertIn('code', found_ides)
2810 self.assertIn('none', found_ides)
2811 self.assertNotIn('foo', found_ides)
2812
2813 shared_config_file = os.path.join(tempdir, 'shared-config.txt')
2814 shared_config_str = 'Dummy shared IDE config'
2815 modified_config_file = os.path.join(tempdir, 'modified-config.txt')
2816 modified_config_str = 'Dummy modified IDE config'
2817
2818 # Generate a foo plugin in the workspace layer
2819 plugin_dir = os.path.join(
2820 self.workspacedir, 'lib', 'devtool', 'ide_plugins')
2821 os.makedirs(plugin_dir)
2822 plugin_code = 'from devtool.ide_plugins import IdeBase\n\n'
2823 plugin_code += 'class IdeFoo(IdeBase):\n'
2824 plugin_code += ' def setup_shared_sysroots(self, shared_env):\n'
2825 plugin_code += ' with open("%s", "w") as config_file:\n' % shared_config_file
2826 plugin_code += ' config_file.write("%s")\n\n' % shared_config_str
2827 plugin_code += ' def setup_modified_recipe(self, args, image_recipe, modified_recipe):\n'
2828 plugin_code += ' with open("%s", "w") as config_file:\n' % modified_config_file
2829 plugin_code += ' config_file.write("%s")\n\n' % modified_config_str
2830 plugin_code += 'def register_ide_plugin(ide_plugins):\n'
2831 plugin_code += ' ide_plugins["foo"] = IdeFoo\n'
2832
2833 plugin_py = os.path.join(plugin_dir, 'ide_foo.py')
2834 with open(plugin_py, 'w') as plugin_file:
2835 plugin_file.write(plugin_code)
2836
2837 # Verify the foo plugin is available as well
2838 result = runCmd('devtool ide-sdk -h')
2839 found_ides = get_ides_from_help(result.output)
2840 self.assertIn('code', found_ides)
2841 self.assertIn('none', found_ides)
2842 self.assertIn('foo', found_ides)
2843
2844 # Verify the foo plugin generates a shared config
2845 result = runCmd(
2846 'devtool ide-sdk -m shared --skip-bitbake --ide foo %s' % shared_recipe_name)
2847 with open(shared_config_file) as shared_config:
2848 shared_config_new = shared_config.read()
2849 self.assertEqual(shared_config_str, shared_config_new)
2850
2851 # Verify the foo plugin generates a modified config
2852 result = runCmd('devtool ide-sdk --skip-bitbake --ide foo %s %s' %
2853 (modified_recipe_name, testimage))
2854 with open(modified_config_file) as modified_config:
2855 modified_config_new = modified_config.read()
2856 self.assertEqual(modified_config_str, modified_config_new)