Notice: This project has been migrated to AtomGit

通知: 本项目已经正式迁移至 AtomGit 平台

mugen

About mugen

mugen is a testing framework provided by openEuler community. This repo contains mugen along with testcases and testsuits for openEuler risc-v port.

Update log

  • New mugen entry function
  • Added support for setting testsuit directory and testing envrionment
  • Added python util functions for testing

How to use

Installation

Simply run bash dep_install.sh.

Set testing envrionment

  • run bash mugen.sh -c --ip $ip --password $passwd --user $user --port $port
  • Parameters
    • ip: ip address of target machine
    • user: username of target machine, default is root
    • password
    • port: ssh port of target machine, default is22
  • Configuration file is located at ./conf/env.json
{
    "NODE": [
        {
            "ID": 1,
            "LOCALTION": "local",
            "MACHINE": "physical",
            "FRAME": "aarch64",
            "NIC": "eth0",
            "MAC": "55:54:00:c8:a9:21",
            "IPV4": "192.168.0.10",
            "USER": "root",
            "PASSWORD": "openEuler12#$",
            "SSH_PORT": 22,
            "BMC_IP": "",
            "BMC_USER": "",
            "BMC_PASSWORD": ""
        },
        {
            "ID": 2,
            "LOCALTION": "remote",
            "MACHINE": "kvm",
            "FRAME": "aarch64",
            "NIC": "eth0",
            "MAC": "55:54:00:c8:a9:22",
            "IPV4": "192.168.0.11",
            "USER": "root",
            "PASSWORD": "openEuler12#$",
            "SSH_PORT": 22,
            "HOST_IP": "",
            "HOST_USER": "",
            "HOST_PASSWORD": ""
            "HOST_SSH_PORT": ""
        }
    ]
}
  • In the testcases, use NODE${id}_${LOCALTION} to use the configured environment.

Run the test

  • Run all test cases bash mugen.sh -a
  • Run a test suite bash mugen.sh -f testsuite
  • Run a test case bash mugen.sh -f testsuite -r testcase
  • Save the testing log
bash mugen.sh -a -x 
bash mugen.sh -f testsuite -x
bash mugen.sh -f testsuite -r testcase -x

Run the suite for reboot cases

  • Configure: Since the suite must be restarted automatically after a reboot, a .service file needs to be configured.
cat > /etc/systemd/system/mugen.service <<'EOF'
[Unit]
Description=Mugen restart suite
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
# Change this path to match your directory
WorkingDirectory=/path/to/mugen
ExecStartPre=/bin/sleep 10
# Change this path to match your directory
ExecStart=/bin/bash -x /path/to/mugen/mugen.sh
Restart=on-failure
RestartSec=10

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable mugen.service
systemctl list-unit-files | grep mugen # make sure the service is enabled
  • Run the suite by bash mugen.sh -f testsuite
  • During execution, the run_test_suite generates case_order.txt and last_order.txt to record the execution sequence and current case. These files can be removed automatically once finish. To restart the suite from the beginning, please ensure these files do not exist.

Write your test case

We provide two templates: one for common cases and another for cases that may cause a reboot
  • Template for common cases:
source ${OET_PATH}/libs/locallibs/common_lib.sh

# Load the data and config 
function config_params() {
    LOG_INFO "Start to config params of the case."

    LOG_INFO "No params need to config."

    LOG_INFO "End to config params of the case."
}

# Prepare the testing environment, eg. Install required packages
function pre_test() {
    LOG_INFO "Start to prepare the test environment."

    LOG_INFO "No pkgs need to install."

    LOG_INFO "End to prepare the test environment."
}

# Run the test
function run_test() {
    LOG_INFO "Start to run test."

    # to test ls
    ls -CZl -all
    CHECK_RESULT 0

    # To check the result
    CHECK_RESULT "$(ls / | grep -cE 'proc|usr|roor|var|sys|etc|boot|dev')" 7

    LOG_INFO "End to run test."
}

# Cleaning the testing environment
function post_test() {
    LOG_INFO "Start to restore the test environment."

    LOG_INFO "Nothing to do."

    LOG_INFO "End to restore the test environment."
}

main "$@"
  • Template for reboot cases
source "${OET_PATH}/testcases/cli-test/common/common_lib.sh"
BOOT_ID_FILE="/root/mugen_boot_id"
# BOOT_ID can be stored in any directory you like, not necessarily /root

function pre_test() {
    LOG_INFO "Start environmental preparation."
    # Save the current BOOT_ID
    cat /proc/sys/kernel/random/boot_id > $BOOT_ID_FILE
    # flush BOOT_ID to disk immediately
    sync
    LOG_INFO "Saved current boot id: $(cat $BOOT_ID_FILE)"
    LOG_INFO "End of environmental preparation!"
}

function run_test() {
    LOG_INFO "Start testing..."
    LOG_INFO "System will reboot now..."
    # reboot trigger
    echo b > /proc/sysrq-trigger
}

function post_test() {
    LOG_INFO "Check if the system has rebooted"
    if [ -f $BOOT_ID_FILE ]; then
        OLD_BOOT_ID=$(cat $BOOT_ID_FILE)
        NEW_BOOT_ID=$(cat /proc/sys/kernel/random/boot_id)
        # compare the BOOT_ID to confirm if the system has rebooted
        if [ "$OLD_BOOT_ID" != "$NEW_BOOT_ID" ]; then
            LOG_INFO "System reboot confirmed (boot_id changed)."
        else
            LOG_ERROR "System did not reboot (boot_id unchanged)."
        fi
        rm -f $BOOT_ID_FILE
    else
        LOG_WARN "No boot_id record found."
    fi
  
    LOG_INFO "Start to restore the test environment."

    LOG_INFO "Nothing to do."

    LOG_INFO "End to restore the test environment."
}

main "$@"
  • A testcase is a shell/python script, and a return value of 0 indicates a successful test.
    • Examples: oe_test_casename_02 and oe_test_casename_03

The json file in suite2cases

  • The json file is a configuration of a test suit.
  • Note that:

Util functions provided by mugen

  • How to load and call these util functions
# bash
source ${OET_PATH}/libs/locallibs/common_lib.sh

# python
import os, sys, subprocess

LIBS_PATH = os.environ.get("OET_PATH") + "/libs/locallibs"
sys.path.append(LIBS_PATH)
import xxx
  • Util functions
    • Logging
    # bash 
    LOG_INFO "$message"
    LOG_WARN "$message"
    LOG_DEBUG "$message"
    LOG_ERROR "$message"
    # python
    import mugen_log
    mugen_log.logging(level, message) # level:INFO,WARN,DEBUG,ERROR;message:日志输出
    
    • Check result
    # bash
    CHECK_RESULT $1 $2 $3 $4
    # $1: Return value of last command
    # $2: Expected value
    # $3: Comp mode, 0: ret == expected -> successful ; 1: ret != expected -> successful
    # $4: Output of 
    
    • Install/Uninstall of rpm packages
    # bash
    ## func 1
    DNF_INSTALL "vim bc" "$node_id"
    DNF_REMOVE "$node_id" "jq" "$mode"
    
    # mode: Default 0, indicates normal removal of the package; when mode is not 0, mugen will only remove the required package.
    # python
    import rpm_manage
    tpmfile = rpm_manage.rpm_install(pkgs, node, tmpfile)
    rpm_manage.rpm_remove(node, pkgs, tmpfile)
    
    • Remote execution
    # bash
    ## func 1
    SSH_CMD "$cmd" $remote_ip $remote_password $remote_user $time_out $remote_port`
    ## func 2
    P_SSH_CMD --cmd $cmd --node $node(PORT)
    P_SSH_CMD --cmd $cmd --ip $remote_ip --password $remote_password --port $remote_port --user $remote_user --timeout $timeout
    # python
    conn = ssh_cmd.pssh_conn(remote_ip, remote_password,remote_port,remote_user,remote_timeout)
    exitcode, output = ssh_cmd.pssh_cmd(conn, cmd)
    
    # port: default is 22
    # user: default is root
    # timeout: default is unlimited
    
    • File transfer
    # bash
    ## func 1
    ### local -> remote  
    `SSH_SCP $local_path/$file $REMOTE_USER@$REMOTE_IP:$remote_path "$REMOTE_PASSWD"`
    ### local <- remote
    `SSH_SCP $REMOTE_USER@$REMOTE_IP:$remote_path/$file $local_path "$REMOTE_PASSWD"`
    ## func 2
    ### Transfer a directory
    SFTP get/put --localdir $localdir --remotedir $remotedir
    ### Transfer a file
    SFTP get/put --localdir $localdir --remotedir $remotedir --localfile/remotefile $localfile/$remotefile
    # python
    ### Transfer a directory
    import ssh_cmd, sftp
    conn = ssh_cmd.pssh_conn(remote_ip, remote_password,remote_port,remote_user,remote_timeout)
    psftp_get(conn,remote_dir, local_dir)
    psftp_put(local_dir=local_dir, remote_dir=remote_dir)
    ### Transfer a directory
    import ssh_cmd, sftp
    psftp_get(remote_dir, remote_file, local_dir)
    psftp_put(local_dir=local_dir, local_file=local_file, remote_dir=remote_dir)
    
    
    # get: get from remote
    # put: put into remote
    # localdir: default is local $(pwd)
    # remotedir: default is remote $(pwd)
    
    • Get a free port
    # bash
    GET_FREE_PORT $ip
    # python
    import free_port
    free_port.find_free_port(ip)
    
    • Check if a port is taken
    # bash 
    IS_FREE_PORT $port $ip
    # python
    import free_port
    free_port.is_free_port(port, ip)
    
    • Get a test NIC
    # bash
    TEST_NIC $node_id
    # python
    import get_test_device
    get_test_nic(node_id)
    
    # node_id: 默认为1号节点
    
    • Get a test Disk
    # bash
    TEST_DISK $node_id
    # python
    import get_test_device
    get_test_disk(node_id)
    
    # node_id: default is 1
    
    • Sleep
    # bash
    SLEEP_WAIT $wait_time $cmd
    # python
    import sleep_wait
    sleep_wait.sleep_wait(wait_time,cmd)
    
    • Reboot remote
    # bash
    REMOTE_REBOOT_WAIT $node_id $wait_time
    

How to debug your testcase

  • use export OET_PATH=$(pwd) to set OET_PATH and just run the script in their correspoding dir

About timeout

  • Default timeout is 30 min
  • If a test case costs more than 30 minset TIMEOUT in the test case script

FAQ

  • Timeout in remote execution
    • Possible cause: ssh will wait for stdout and will not exit unless there is a signal
    • Possible solution: Redirect stdout to /dev/null, like cmd > /dev/nul 2>&1 &

Contribution

  1. Fork the repository
  2. Create Feat_xxx branch
  3. Commit your code
  4. Create Pull Request

Gitee Feature

  1. You can use Readme_XXX.md to support different languages, such as Readme_en.md, Readme_zh.md
  2. Gitee blog blog.gitee.com
  3. Explore open source project https://gitee.com/explore
  4. The most valuable open source project GVP
  5. The manual of Gitee https://gitee.com/help
  6. The most popular members https://gitee.com/gitee-stars/
Description
No description provided
Readme 1.3 GiB
Languages
Shell 85.9%
Python 6.3%
C 5.5%
Logos 0.6%
Makefile 0.5%
Other 0.9%