Пример #1
0
/**
 * Function to start a node.
 *
 * @param   Node    $n                  Node
 * @param   Int     $id                 Node ID
 * @param   Int     $t                  Tenant ID
 * @param   Array   $nets               Array of networks
 * @return  int                         0 means ok
 */
function start($n, $id, $t, $nets)
{
    if ($n->getStatus() !== 0) {
        // Node is in running or building state
        return 0;
    }
    $rc = prepareNode($n, $id, $t, $nets);
    if ($rc !== 0) {
        // Failed to prepare the node
        return $rc;
    }
    list($bin, $flags) = $n->getCommand();
    if ($bin == False || $flags == False) {
        // Invalid CMD line
        error_log('ERROR: ' . $GLOBALS['messages'][80046]);
        return 80046;
    }
    if (!chdir($n->getRunningPath())) {
        // Failed to change directory
        error_log('ERROR: ' . $GLOBALS['messages'][80047]);
        return 80047;
    }
    // Starting the node
    switch ($n->getNType()) {
        default:
            // Invalid node_type
            error_log('ERROR: ' . $GLOBALS['messages'][80038]);
            return 80028;
        case 'iol':
            $cmd = '/opt/unetlab/wrappers/iol_wrapper -T ' . $t . ' -D ' . $id . ' -t "' . $n->getName() . '" -F /opt/unetlab/addons/iol/bin/' . $n->getImage() . ' -d ' . $n->getDelay() . ' -e ' . $n->getEthernetCount() . ' -s ' . $n->getSerialCount();
            // Adding Serial links
            foreach ($n->getSerials() as $interface_id => $interface) {
                if ($interface->getRemoteId() > 0) {
                    $cmd .= ' -l ' . $interface_id . ':localhost:' . $interface->getRemoteId() . ':' . $interface->getRemoteIf();
                }
            }
            $cmd .= ' -- ' . $flags . ' > ' . $n->getRunningPath() . '/wrapper.txt 2>&1 &';
            break;
        case 'docker':
            $cmd = 'docker start -ai ' . $n->getUuid();
            break;
        case 'dynamips':
            $cmd = '/opt/unetlab/wrappers/dynamips_wrapper -T ' . $t . ' -D ' . $id . ' -t "' . $n->getName() . '" -F /opt/unetlab/addons/dynamips/' . $n->getImage() . ' -d ' . $n->getDelay();
            $cmd .= ' -- ' . $flags . ' > ' . $n->getRunningPath() . '/wrapper.txt 2>&1 &';
            break;
        case 'qemu':
            $cmd = '/opt/unetlab/wrappers/qemu_wrapper -T ' . $t . ' -D ' . $id . ' -t "' . $n->getName() . '" -F ' . $bin . ' -d ' . $n->getDelay();
            if ($n->getConsole() == 'vnc') {
                // Disable telnet (wrapper) console
                $cmd .= ' -x';
            }
            $cmd .= ' -- ' . $flags . ' > ' . $n->getRunningPath() . '/wrapper.txt 2>&1 &';
            break;
    }
    error_log('INFO: CWD is ' . getcwd());
    error_log('INFO: starting ' . $cmd);
    exec($cmd, $o, $rc);
    if ($rc == 0 && $n->getNType() == 'qemu' && is_file($n->getRunningPath() . '/startup-config') && !is_file(is_file($n->getRunningPath() . '/.configured'))) {
        // Start configuration process
        touch($n->getRunningPath() . '/.lock');
        $cmd = 'nohup /opt/unetlab/scripts/config_vios.py -a put -p ' . $n->getPort() . ' -f ' . $n->getRunningPath() . '/startup-config -t ' . ($n->getDelay() + 300) . ' &';
        exec($cmd, $o, $rc);
        error_log('INFO: importing ' . $cmd);
    }
    if ($rc == 0 && $n->getNType() == 'docker') {
        // Need to configure each interface
        foreach ($n->getEthernets() as $interface_id => $interface) {
            // TODO must check each step against errors
            // ip link add docker3_4_5 type veth peer name vnet3_4_5
            $cmd = 'ip link add docker' . $t . '_' . $id . '_' . $interface_id . ' type veth peer name vnet' . $t . '_' . $id . '_' . $interface_id;
            error_log('INFO: starting ' . $cmd);
            exec($cmd, $o, $rc);
            // ip link set dev vnet3_4_5 up
            $cmd = 'ip link set dev vnet' . $t . '_' . $id . '_' . $interface_id . ' up';
            error_log('INFO: starting ' . $cmd);
            exec($cmd, $o, $rc);
            // brctl addif vnet0_1 vnet3_4_5
            $cmd = 'brctl addif vnet' . $t . '_' . $interface->getNetworkId() . '  vnet' . $t . '_' . $id . '_' . $interface_id;
            error_log('INFO: starting ' . $cmd);
            exec($cmd, $o, $rc);
            // PID=$(docker inspect --format '{{ .State.Pid }}' docker3_4) # Must be greater than 0
            $cmd = 'docker inspect --format "{{ .State.Pid }}" ' . $n->getUuid();
            error_log('INFO: starting ' . $cmd);
            exec($cmd, $o, $rc);
            // ip link set netns ${PID} docker3_4_5 name eth0 address 22:ce:e0:99:04:05 up
            $cmd = 'ip link set netns ' . $o[0] . ' docker' . $t . '_' . $id . '_' . $interface_id . ' name eth0 address ' . '50:' . sprintf('%02x', $t) . ':' . sprintf('%02x', $id / 512) . ':' . sprintf('%02x', $id % 512) . ':00:' . sprintf('%02x', $interface_id) . ' up';
            error_log('INFO: starting ' . $cmd);
            exec($cmd, $o, $rc);
            // /opt/unetlab/wrappers/nsenter -t ${PID} -n ip addr add 1.1.1.1/24 dev eth0
            // /opt/unetlab/wrappers/nsenter -t ${PID} -n ip route add default via 1.1.1.254
        }
    }
    return 0;
}
Пример #2
0
/**
 * Function to start a node.
 *
 * @param   Node    $n                  Node
 * @param   Int     $id                 Node ID
 * @param   Int     $t                  Tenant ID
 * @param   Array   $nets               Array of networks
 * @param   int     $scripttimeout      Config Script Timeout
 * @return  int                         0 means ok
 */
function start($n, $id, $t, $nets, $scripttimeout)
{
    if ($n->getStatus() !== 0) {
        // Node is in running or building state
        return 0;
    }
    $rc = prepareNode($n, $id, $t, $nets);
    if ($rc !== 0) {
        // Failed to prepare the node
        return $rc;
    }
    list($bin, $flags) = $n->getCommand();
    if ($bin == False || $flags == False) {
        // Invalid CMD line
        error_log(date('M d H:i:s ') . 'ERROR: ' . $GLOBALS['messages'][80046]);
        return 80046;
    }
    if (!chdir($n->getRunningPath())) {
        // Failed to change directory
        error_log(date('M d H:i:s ') . 'ERROR: ' . $GLOBALS['messages'][80047]);
        return 80047;
    }
    // Starting the node
    switch ($n->getNType()) {
        default:
            // Invalid node_type
            error_log(date('M d H:i:s ') . 'ERROR: ' . $GLOBALS['messages'][80038]);
            return 80028;
        case 'iol':
            $cmd = '/opt/unetlab/wrappers/iol_wrapper -T ' . $t . ' -D ' . $id . ' -t "' . $n->getName() . '" -F /opt/unetlab/addons/iol/bin/' . $n->getImage() . ' -d ' . $n->getDelay() . ' -e ' . $n->getEthernetCount() . ' -s ' . $n->getSerialCount();
            // Adding Serial links
            foreach ($n->getSerials() as $interface_id => $interface) {
                if ($interface->getRemoteId() > 0) {
                    $cmd .= ' -l ' . $interface_id . ':localhost:' . $interface->getRemoteId() . ':' . $interface->getRemoteIf();
                }
            }
            break;
        case 'docker':
            $cmd = 'docker -H=tcp://127.0.0.1:4243 start ' . $n->getUuid();
            break;
        case 'vpcs':
            $cmd = '/opt/vpcsu/bin/vpcs -m ' . $id . ' -N ' . $n->getName();
            break;
        case 'dynamips':
            $cmd = '/opt/unetlab/wrappers/dynamips_wrapper -T ' . $t . ' -D ' . $id . ' -t "' . $n->getName() . '" -F /opt/unetlab/addons/dynamips/' . $n->getImage() . ' -d ' . $n->getDelay();
            break;
        case 'qemu':
            $cmd = '/opt/unetlab/wrappers/qemu_wrapper -T ' . $t . ' -D ' . $id . ' -t "' . $n->getName() . '" -F ' . $bin . ' -d ' . $n->getDelay();
            if ($n->getConsole() == 'vnc') {
                // Disable telnet (wrapper) console
                $cmd .= ' -x';
            }
            break;
    }
    // Special Case for xrv - csr1000v - vIOS - vIOSL - Docker
    if (($n->getTemplate() == 'xrv' || $n->getTemplate() == 'csr1000v' || $n->getTemplate() == 'asav' || $n->getTemplate() == 'titanium') && is_file($n->getRunningPath() . '/config.iso') && !is_file($n->getRunningPath() . '/.configured') && $n->getConfig() != 0) {
        $flags .= ' -cdrom config.iso';
    }
    if (($n->getTemplate() == 'vios' || $n->getTemplate() == 'viosl2') && is_file($n->getRunningPath() . '/minidisk') && !is_file($n->getRunningPath() . '/.configured') && $n->getConfig() != 0) {
        $flags .= ' -drive file=minidisk,if=virtio,bus=0,unit=1,cache=none';
    }
    if (($n->getTemplate() == 'vmx' || $n->getTemplate() == 'vsrx') && is_file($n->getRunningPath() . '/config.iso') && !is_file($n->getRunningPath() . '/.configured') && $n->getConfig() != 0) {
        $flags .= ' -drive file=config.iso,if=virtio,media=cdrom,index=2';
    }
    if ($n->getTemplate() == 'vsrxng' && is_file($n->getRunningPath() . '/config.iso') && !is_file($n->getRunningPath() . '/.configured') && $n->getConfig() != 0) {
        $flags .= ' -drive file=config.iso,if=ide,media=cdrom,index=2';
    }
    if ($n->getTemplate() == 'pfsense' && is_file($n->getRunningPath() . '/config.iso') && !is_file($n->getRunningPath() . '/.configured') && $n->getConfig() != 0) {
        $flags .= ' -cdrom config.iso';
    }
    if ($n->getNType() != 'docker' && $n->getNType() != 'vpcs') {
        $cmd .= ' -- ' . $flags . ' > ' . $n->getRunningPath() . '/wrapper.txt 2>&1 &';
    }
    if ($n->getNType() == 'vpcs') {
        $cmd .= $flags . ' > ' . $n->getRunningPath() . '/wrapper.txt 2>&1 &';
    }
    error_log(date('M d H:i:s ') . 'INFO: CWD is ' . getcwd());
    error_log(date('M d H:i:s ') . 'INFO: starting ' . $cmd);
    exec($cmd, $o, $rc);
    if ($rc == 0 && $n->getNType() == 'qemu' && is_file($n->getRunningPath() . '/startup-config') && !is_file($n->getRunningPath() . '/.configured') && $n->getConfig() != 0) {
        // Start configuration process or check if bootstrap is done
        touch($n->getRunningPath() . '/.lock');
        $cmd = 'nohup /opt/unetlab/scripts/config_' . $n->getTemplate() . '.py -a put -p ' . $n->getPort() . ' -f ' . $n->getRunningPath() . '/startup-config -t ' . ($n->getDelay() + $scripttimeout) . ' > /dev/null 2>&1 &';
        exec($cmd, $o, $rc);
        error_log(date('M d H:i:s ') . 'INFO: importing ' . $cmd);
    }
    if ($rc == 0 && $n->getNType() == 'docker') {
        // Need to configure each interface
        foreach ($n->getEthernets() as $interface_id => $interface) {
            // TODO must check each step against errors
            // ip link add docker3_4_5 type veth peer name vnet3_4_5
            $cmd = 'ip link add docker' . $t . '_' . $id . '_' . $interface_id . ' type veth peer name vnet' . $t . '_' . $id . '_' . $interface_id;
            error_log(date('M d H:i:s ') . 'INFO: starting ' . $cmd);
            exec($cmd, $o, $rc);
            // ip link set dev vnet3_4_5 up
            $cmd = 'ip link set dev vnet' . $t . '_' . $id . '_' . $interface_id . ' up';
            error_log(date('M d H:i:s ') . 'INFO: starting ' . $cmd);
            exec($cmd, $o, $rc);
            // brctl addif vnet0_1 vnet3_4_5
            $cmd = 'brctl addif vnet' . $t . '_' . $interface->getNetworkId() . '  vnet' . $t . '_' . $id . '_' . $interface_id;
            error_log(date('M d H:i:s ') . 'INFO: starting ' . $cmd);
            exec($cmd, $o, $rc);
            // PID=$(docker inspect --format '{{ .State.Pid }}' docker3_4) # Must be greater than 0
            $cmd = 'docker -H=tcp://127.0.0.1:4243 inspect --format "{{ .State.Pid }}" ' . $n->getUuid();
            error_log(date('M d H:i:s ') . 'INFO: starting ' . $cmd);
            exec($cmd, $o, $rc);
            // ip link set netns ${PID} docker3_4_5 name eth0 address 22:ce:e0:99:04:05 up
            $cmd = 'ip link set netns ' . $o[1] . ' docker' . $t . '_' . $id . '_' . $interface_id . ' name eth0 address ' . '50:' . sprintf('%02x', $t) . ':' . sprintf('%02x', $id / 512) . ':' . sprintf('%02x', $id % 512) . ':00:' . sprintf('%02x', $interface_id) . ' up';
            error_log(date('M d H:i:s ') . 'INFO: starting ' . $cmd);
            exec($cmd, $o, $rc);
            // /opt/unetlab/wrappers/nsenter -t ${PID} -n ip addr add 1.1.1.1/24 dev eth0
            // /opt/unetlab/wrappers/nsenter -t ${PID} -n ip route add default via 1.1.1.254
        }
        // Start configuration process
        touch($n->getRunningPath() . '/.lock');
        $cmd = 'nohup /opt/unetlab/scripts/config_' . $n->getTemplate() . '.py -a put -i ' . $n->getUuid() . ' -f ' . $n->getRunningPath() . '/startup-config -t ' . ($n->getDelay() + 300) . ' > /dev/null 2>&1 &';
        exec($cmd, $o, $rc);
        error_log(date('M d H:i:s ') . 'INFO: importing ' . $cmd);
    }
    return 0;
}
Пример #3
0
/**
 * Prepares a Node to be displayed in a navigation tree.
 * This function is used in the construction of:
 *  - Test project specification -> we want ALL test cases defined in test project.
 *  - Test execution             -> we only want the test cases linked to a test plan.
 * 
 * IMPORTANT:
 * when analising a container node (Test Suite) if it is empty and we have requested
 * some sort of filtering NODE WILL BE PRUNED.
 *
 *
 * status: one of the possible execution status of a test case.
 *
 *
 * tplan_tcases: map with testcase versions linked to test plan. 
 *               due to the multiples uses of this function, null has several meanings
 *
 *             When we want to build a Test Project specification tree,
 *             WE SET it to NULL, because we are not interested in a test plan.
 *             
 *             When we want to build a Test execution tree, we dont set it deliverately
 *             to null, but null can be the result of NO tcversion linked => EMPTY TEST PLAN
 *
 *
 * status can be an array with multple values, to do OR search.
 * added version info from test cases in return data structure.
 * ignore_inactive_testcases: useful when building a Test Project Specification tree 
 *                            to be used in the add/link test case to Test Plan.
 * tck_map: Test Case Keyword map:
 *          null            => no filter
 *          empty map       => filter out ALL test case ALWAYS
 *          initialized map => filter out test case ONLY if NOT present in map.
 *
 *
 * added argument:
 *                $map_node_tccount
 *                key => node_id
 *                values => node test case count
 *                          node name (useful only for debug purpouses
 *
 *                IMPORTANT: this new argument is not useful for tree rendering
 *                           but to avoid duplicating logic to get test case count
 *
 *
 * return: map with keys:
 *         'total_count'
 *         'passed'  
 *         'failed'
 *         'blocked'
 *         'not run'
 *
 * @internal revisions
 */
function prepareNode(&$db, &$node, &$decoding_info, &$map_node_tccount, $tck_map = null, &$tplan_tcases = null, $filters = null, $options = null)
{
    static $status_descr_list;
    static $debugMsg;
    static $tables;
    static $my;
    static $enabledFiltersOn;
    static $activeVersionClause;
    static $filterOnTCVersionAttribute;
    static $filtersApplied;
    static $users2filter;
    static $results2filter;
    static $testPlanIsNotEmpty;
    $tpNode = null;
    if (!$tables) {
        $debugMsg = 'Class: ' . __CLASS__ . ' - ' . 'Method: ' . __FUNCTION__ . ' - ';
        $tables = tlObjectWithDB::getDBTables(array('tcversions', 'nodes_hierarchy', 'testplan_tcversions'));
        $status_descr_list = array_keys($decoding_info['status_descr_code']);
        $status_descr_list[] = 'testcase_count';
        $my = array();
        $my['options'] = array('hideTestCases' => 0, 'showTestCaseID' => 1, 'viewType' => 'testSpecTree', 'getExternalTestCaseID' => 1, 'ignoreInactiveTestCases' => 0, 'ignoreActiveTestCases' => 0);
        // added importance here because of "undefined" error in event log
        $my['filters'] = array('status' => null, 'assignedTo' => null, 'importance' => null, 'executionType' => null, 'filter_tc_id' => null);
        $my['options'] = array_merge($my['options'], (array) $options);
        $my['filters'] = array_merge($my['filters'], (array) $filters);
        $enabledFiltersOn['testcase_id'] = isset($my['filters']['filter_tc_id']);
        $enabledFiltersOn['testcase_name'] = isset($my['filters']['filter_testcase_name']);
        $enabledFiltersOn['executionType'] = isset($my['filters']['filter_execution_type']);
        $enabledFiltersOn['importance'] = isset($my['filters']['filter_priority']);
        $enabledFiltersOn['custom_fields'] = isset($my['filters']['filter_custom_fields']);
        $enabledFiltersOn['keywords'] = isset($tck_map);
        $filterOnTCVersionAttribute = $enabledFiltersOn['executionType'] || $enabledFiltersOn['importance'];
        $filtersApplied = false;
        foreach ($enabledFiltersOn as $filterValue) {
            $filtersApplied = $filtersApplied || $filterValue;
        }
        $activeVersionClause = $filterOnTCVersionAttribute ? " AND TCV.active=1 " : '';
        $users2filter = isset($my['filters']['filter_assigned_user']) ? $my['filters']['filter_assigned_user'] : null;
        $results2filter = isset($my['filters']['filter_result_result']) ? $my['filters']['filter_result_result'] : null;
        $testPlanIsNotEmpty = !is_null($tplan_tcases) && count($tplan_tcases) > 0;
    }
    $tcase_counters = array_fill_keys($status_descr_list, 0);
    $node_type = isset($node['node_type_id']) ? $decoding_info['node_id_descr'][$node['node_type_id']] : null;
    if ($node_type == 'testcase') {
        // ABSOLUTELY First implicit filter to be applied when test plan is not empty.
        // is our test case present on Test Spec linked to Test Plan ?
        if ($testPlanIsNotEmpty && !isset($tplan_tcases[$node['id']])) {
            $node = null;
        } else {
            if ($enabledFiltersOn['keywords'] && !isset($tck_map[$node['id']]) || $enabledFiltersOn['testcase_name'] && stripos($node['name'], $my['filters']['filter_testcase_name']) === FALSE || $enabledFiltersOn['testcase_id'] && $node['id'] != $my['filters']['filter_tc_id']) {
                unset($tplan_tcases[$node['id']]);
                $node = null;
            } else {
                if ($my['options']['viewType'] == 'executionTree') {
                    $tpNode = isset($tplan_tcases[$node['id']]) ? $tplan_tcases[$node['id']] : null;
                    if (!($delete_node = is_null($tpNode))) {
                        $delete_node = !is_null($results2filter) && !isset($results2filter[$tpNode['exec_status']]);
                        if (!$delete_node && !is_null($users2filter)) {
                            $somebody_wanted_but_nobody_there = isset($users2filter[TL_USER_SOMEBODY]) && !is_numeric($tpNode['user_id']);
                            $unassigned_wanted_but_someone_assigned = isset($users2filter[TL_USER_NOBODY]) && !is_null($tpNode['user_id']);
                            $wrong_user = !isset($users2filter[TL_USER_NOBODY]) && !isset($users2filter[TL_USER_SOMEBODY]) && !isset($users2filter[$tpNode['user_id']]);
                            $delete_node = $unassigned_wanted_but_someone_assigned || $wrong_user || $somebody_wanted_but_nobody_there;
                        }
                    }
                    if ($delete_node) {
                        unset($tplan_tcases[$node['id']]);
                        $node = null;
                    } else {
                        $externalID = '';
                        $node['tcversion_id'] = $tpNode['tcversion_id'];
                        $node['version'] = $tpNode['version'];
                        if ($my['options']['getExternalTestCaseID']) {
                            if (!isset($tpNode['external_id'])) {
                                $sql = " /* {$debugMsg} - line:" . __LINE__ . " */ " . " SELECT TCV.tc_external_id AS external_id " . " FROM {$tables['tcversions']}  TCV " . " WHERE TCV.id=" . $node['tcversion_id'];
                                $result = $db->exec_query($sql);
                                $myrow = $db->fetch_array($result);
                                $externalID = $myrow['external_id'];
                            } else {
                                $externalID = $tpNode['external_id'];
                            }
                        }
                        $node['external_id'] = $externalID;
                    }
                }
                if ($node && $my['options']['ignoreInactiveTestCases']) {
                    // there are active tcversions for this node ???
                    // I'm doing this instead of creating a test case manager object, because
                    // I think is better for performance.
                    //
                    // =======================================================================================
                    // 20070106 - franciscom
                    // Postgres Problems
                    // =======================================================================================
                    // Problem 1 - SQL Syntax
                    //   While testing with postgres
                    //   SELECT count(TCV.id) NUM_ACTIVE_VERSIONS   -> Error
                    //
                    //   At least for what I remember using AS to create COLUMN ALIAS IS REQUIRED and Standard
                    //   while AS is NOT REQUIRED (and with some DBMS causes errors) when you want to give a
                    //   TABLE ALIAS
                    //
                    // Problem 2 - alias case
                    //   At least in my installation the aliases column name is returned lower case, then
                    //   PHP fails when:
                    //                  if($myrow['NUM_ACTIVE_VERSIONS'] == 0)
                    //
                    //
                    $sql = " /* {$debugMsg} - line:" . __LINE__ . " */ " . " SELECT count(TCV.id) AS num_active_versions " . " FROM {$tables['tcversions']} TCV, {$tables['nodes_hierarchy']} NH " . " WHERE NH.parent_id=" . $node['id'] . " AND NH.id = TCV.id AND TCV.active=1";
                    $result = $db->exec_query($sql);
                    $myrow = $db->fetch_array($result);
                    if ($myrow['num_active_versions'] == 0) {
                        $node = null;
                    }
                }
                // TICKET 4496: added inactive testcase filter
                if ($node && $my['options']['ignoreActiveTestCases']) {
                    $sql = " /* {$debugMsg} - line:" . __LINE__ . " */ " . " SELECT count(TCV.id) AS num_active_versions " . " FROM {$tables['tcversions']} TCV, {$tables['nodes_hierarchy']} NH " . " WHERE NH.parent_id=" . $node['id'] . " AND NH.id = TCV.id AND TCV.active=1";
                    $result = $db->exec_query($sql);
                    $myrow = $db->fetch_array($result);
                    if ($myrow['num_active_versions'] != 0) {
                        $node = null;
                    }
                }
            }
        }
        // -------------------------------------------------------------------
        // -------------------------------------------------------------------
        if ($node && ($my['options']['viewType'] == 'testSpecTree' || $my['options']['viewType'] == 'testSpecTreeForTestPlan')) {
            $sql = " /* {$debugMsg} - line:" . __LINE__ . " */ " . " SELECT COALESCE(MAX(TCV.id),0) AS targetid, TCV.tc_external_id AS external_id" . " FROM {$tables['tcversions']} TCV, {$tables['nodes_hierarchy']} NH " . " WHERE  NH.id = TCV.id {$activeVersionClause} AND NH.parent_id={$node['id']} " . " GROUP BY TCV.tc_external_id ";
            $rs = $db->get_recordset($sql);
            if (is_null($rs)) {
                $node = null;
            } else {
                $node['external_id'] = $rs[0]['external_id'];
                $target_id = $rs[0]['targetid'];
                if ($filterOnTCVersionAttribute) {
                    switch ($my['options']['viewType']) {
                        case 'testSpecTreeForTestPlan':
                            // Try to get info from linked tcversions
                            // Platform is not needed
                            $sql = " /* {$debugMsg} - line:" . __LINE__ . " */ " . " SELECT DISTINCT TPTCV.tcversion_id AS targetid " . " FROM {$tables['tcversions']} TCV " . " JOIN {$tables['nodes_hierarchy']} NH " . " ON NH.id = TCV.id {$activeVersionClause} " . " AND NH.parent_id={$node['id']} " . " JOIN {$tables['testplan_tcversions']} TPTCV " . " ON TPTCV.tcversion_id = TCV.id " . " AND TPTCV.testplan_id = " . " {$my['filters']['setting_testplan']}";
                            $rs = $db->get_recordset($sql);
                            $target_id = !is_null($rs) ? $rs[0]['targetid'] : $target_id;
                            break;
                    }
                    $sql = " /* {$debugMsg} - line:" . __LINE__ . " */ " . " SELECT TCV.execution_type " . " FROM {$tables['tcversions']} TCV " . " WHERE TCV.id = {$target_id} ";
                    if ($enabledFiltersOn['executionType']) {
                        $sql .= " AND TCV.execution_type = " . " {$my['filters']['filter_execution_type']} ";
                    }
                    if ($enabledFiltersOn['importance']) {
                        $sql .= " AND TCV.importance = " . " {$my['filters']['filter_priority']} ";
                    }
                    $rs = $db->fetchRowsIntoMap($sql, 'execution_type');
                    if (is_null($rs)) {
                        $node = null;
                    }
                }
            }
            if (!is_null($node)) {
                // needed to avoid problems when using json_encode with EXTJS
                unset($node['childNodes']);
                $node['leaf'] = true;
            }
        }
        // -------------------------------------------------------------------
        // ========================================================================
        foreach ($tcase_counters as $key => $value) {
            $tcase_counters[$key] = 0;
        }
        if (isset($tpNode['exec_status'])) {
            $tc_status_descr = $decoding_info['status_code_descr'][$tpNode['exec_status']];
        } else {
            $tc_status_descr = "not_run";
        }
        $init_value = $node ? 1 : 0;
        $tcase_counters[$tc_status_descr] = $init_value;
        $tcase_counters['testcase_count'] = $init_value;
        if ($my['options']['hideTestCases']) {
            $node = null;
        }
        // ========================================================================
    }
    // if($node_type == 'testcase')
    // ========================================================================
    if (isset($node['childNodes']) && is_array($node['childNodes'])) {
        // node has to be a Test Suite ?
        $childNodes =& $node['childNodes'];
        $childNodesQty = count($childNodes);
        for ($idx = 0; $idx < $childNodesQty; $idx++) {
            $current =& $childNodes[$idx];
            // I use set an element to null to filter out leaf menu items
            if (is_null($current)) {
                continue;
            }
            $counters_map = prepareNode($db, $current, $decoding_info, $map_node_tccount, $tck_map, $tplan_tcases, $my['filters'], $my['options']);
            foreach ($counters_map as $key => $value) {
                $tcase_counters[$key] += $counters_map[$key];
            }
        }
        foreach ($tcase_counters as $key => $value) {
            $node[$key] = $tcase_counters[$key];
        }
        if (isset($node['id'])) {
            $map_node_tccount[$node['id']] = array('testcount' => $node['testcase_count'], 'name' => $node['name']);
        }
        // node must be destroyed if empty had we have using filtering conditions
        if (($filtersApplied || !is_null($tplan_tcases)) && !$tcase_counters['testcase_count'] && $node_type != 'testproject') {
            $node = null;
        }
    } else {
        if ($node_type == 'testsuite') {
            // does this means is an empty test suite ??? - franciscom 20080328
            $map_node_tccount[$node['id']] = array('testcount' => 0, 'name' => $node['name']);
            // If is an EMPTY Test suite and we have added filtering conditions,
            // We will destroy it.
            if ($filtersApplied || !is_null($tplan_tcases)) {
                $node = null;
            }
        }
    }
    return $tcase_counters;
}
Пример #4
0
/**
 *
 */
function buildContentForTestPlanBranch(&$dbHandler, $itemsTree, $branchRoot, $tplanID, $platformIDSet, &$docInfo, $decode, &$tplanMgr, $options = null)
{
    $linkedBy = array();
    $branch_tsuites = null;
    $contentByPlatform = array();
    $pnOptions = array('hideTestCases' => 0);
    $pnOptions = array_merge($pnOptions, (array) $options);
    $tsuite = new testsuite($dbHandler);
    $tInfo = $tsuite->get_by_id($branchRoot);
    $tInfo['node_type_id'] = $decode['node_descr_id']['testsuite'];
    $docInfo->title = htmlspecialchars(isset($tInfo['name']) ? $tInfo['name'] : $docInfo->testplan_name);
    $children_tsuites = $tsuite->tree_manager->get_subtree_list($branchRoot, $decode['node_descr_id']['testsuite']);
    if (!is_null($children_tsuites) and trim($children_tsuites) != "") {
        $branch_tsuites = explode(',', $children_tsuites);
    }
    $branch_tsuites[] = $branchRoot;
    $metrics = (object) array('estimatedExecTime' => null, 'realExecTime' => null);
    $filters = array('tsuites_id' => $branch_tsuites);
    foreach ($platformIDSet as $platform_id) {
        // IMPORTANTE NOTICE:
        // This need to be initialized on each iteration because prepareNode() make changes on it.
        $tInfo['childNodes'] = isset($itemsTree['childNodes']) ? $itemsTree['childNodes'] : null;
        $filters['platform_id'] = $platform_id;
        $metrics->estimatedExecTime[$platform_id] = null;
        $metrics->realExecTime[$platform_id] = null;
        $avalon = $tplanMgr->getLTCVNewGeneration($tplanID, $filters, array('addExecInfo' => true));
        $k2l = array_keys($avalon);
        foreach ($k2l as $key) {
            $linkedBy[$platform_id][$key] = $avalon[$key][$platform_id];
        }
        // After architecture changes on how CF design values for Test Cases are
        // managed, we need the test case version ID and not test case ID
        // In addition if we loop over Platforms we need to save this set each time!!!
        $items2loop = !is_null($linkedBy[$platform_id]) ? array_keys($linkedBy[$platform_id]) : null;
        if (!is_null($items2loop)) {
            foreach ($items2loop as $rdx) {
                $metrics->estimatedExecTime[$platform_id][] = $linkedBy[$platform_id][$rdx]['tcversion_id'];
            }
        }
        // Prepare Node -> pn
        $pnFilters = null;
        $dummy4reference = null;
        $contentByPlatform[$platform_id]['childNodes'] = array();
        if (!is_null($linkedBy[$platform_id])) {
            prepareNode($dbHandler, $tInfo, $decode, $dummy4reference, $dummy4reference, $linkedBy[$platform_id], $pnFilters, $pnOptions);
            $contentByPlatform[$platform_id]['childNodes'] = array($tInfo);
        }
    }
    $metrics->realExecTime = $linkedBy;
    return array($contentByPlatform, $metrics);
}
Пример #5
0
                 $branch_tsuites = explode(',', $children_tsuites);
             }
             $branch_tsuites[] = $args->itemID;
             $filters = array('tsuites_id' => $branch_tsuites, 'platform_id' => $platform_id);
             $tp_tcs = $tplan_mgr->get_linked_tcversions($args->tplan_id, $filters);
             $tcase_filter = !is_null($tp_tcs) ? array_keys((array) $tp_tcs) : null;
             $tInfo['node_type_id'] = $hash_descr_id['testsuite'];
             $tInfo['childNodes'] = isset($subtree['childNodes']) ? $subtree['childNodes'] : null;
             //@TODO: schlundus, can we speed up with NO_EXTERNAL?
             $dummy = null;
             $pnFilters = null;
             $pnOptions = array('hideTestCases' => 0);
             // 3624
             $pnOptions = array_merge($pnOptions, $pnOptionsAdd);
             // prepareNode($db,$tInfo,$decoding_hash,$dummy,$dummy,$tp_tcs,SHOW_TESTCASES);
             prepareNode($db, $tInfo, $decoding_hash, $dummy, $dummy, $tp_tcs, $pnFilters, $pnOptions);
             $doc_info->title = htmlspecialchars(isset($tInfo['name']) ? $tInfo['name'] : $doc_info->testplan_name);
             $tree['childNodes'] = array($tInfo);
             $treeForPlatform[$platform_id] = $tree;
         }
         break;
 }
 // switch($doc_info->content_range)
 // Create list of execution id, that will be used to compute execution time if
 // CF_EXEC_TIME custom field exists and is linked to current testproject
 $doc_data->statistics = null;
 if ($printingOptions['metrics']) {
     $executed_qty = 0;
     if ($tp_tcs) {
         foreach ($tp_tcs as $tcase_id => $info) {
             if ($info['exec_status'] != $status_descr_code['not_run']) {
Пример #6
0
/**
 * @return array a map:
 *         key    => node_id
 *         values => node test case count considering test cases presents
 *                   in the nodes of the subtree that starts on node_id
 *                   Means test case can not be sons/daughters of node_id.
 * 
 *                   node name (useful only for debug purpouses).
 */
function get_testplan_nodes_testcount(&$db, $tproject_id, $tproject_name, $tplan_id, $tplan_name, $keywordsFilter = null)
{
    $tplan_mgr = new testplan($db);
    $tproject_mgr = new testproject($db);
    $tree_manager = $tplan_mgr->tree_manager;
    $tcase_node_type = $tree_manager->node_descr_id['testcase'];
    $hash_descr_id = $tree_manager->get_available_node_types();
    $hash_id_descr = array_flip($hash_descr_id);
    $resultsCfg = config_get('results');
    $decoding_hash = array('node_id_descr' => $hash_id_descr, 'status_descr_code' => $resultsCfg['status_code'], 'status_code_descr' => $resultsCfg['code_status']);
    $test_spec = $tproject_mgr->get_subtree($tproject_id, RECURSIVE_MODE);
    $linkedFilters = array('keyword_id' => $keywordsFilter->items);
    $tplan_tcases = $tplan_mgr->get_linked_tcversions($tplan_id, $linkedFilters);
    if (is_null($tplan_tcases)) {
        $tplan_tcases = array();
    }
    $test_spec['name'] = $tproject_name;
    $test_spec['id'] = $tproject_id;
    $test_spec['node_type_id'] = $hash_descr_id['testproject'];
    $map_node_tccount = array();
    if ($test_spec) {
        $tck_map = null;
        if (!is_null($keywordsFilter)) {
            $tck_map = $tproject_mgr->get_keywords_tcases($tproject_id, $keywordsFilter->items, $keywordsFilter->type);
        }
        //@TODO: schlundus, can we speed up with NO_EXTERNAL?
        $filters = null;
        $options = array('hideTestCases' => 0, 'viewType' => 'executionTree');
        $testcase_counters = prepareNode($db, $test_spec, $decoding_hash, $map_node_tccount, $tck_map, $tplan_tcases, $filters, $options);
        $test_spec['testcase_count'] = $testcase_counters['testcase_count'];
    }
    return $map_node_tccount;
}
Пример #7
0
/**
 * Function to start a node.
 *
 * @param   Node    $n                  Node
 * @param   Int     $id                 Node ID
 * @param   Int     $t                  Tenant ID
 * @param   Array   $nets               Array of networks
 * @return  int                         0 means ok
 */
function start($n, $id, $t, $nets)
{
    if ($n->getStatus() !== 0) {
        // Node is in running or building state
        return 0;
    }
    $rc = prepareNode($n, $id, $t, $nets);
    if ($rc !== 0) {
        // Failed to prepare the node
        return $rc;
    }
    list($bin, $flags) = $n->getCommand();
    if ($bin == False || $flags == False) {
        // Invalid CMD line
        error_log('ERROR: ' . $GLOBALS['messages'][80046]);
        return 80046;
    }
    if (!chdir($n->getRunningPath())) {
        // Failed to change directory
        error_log('ERROR: ' . $GLOBALS['messages'][80047]);
        return 80047;
    }
    // Starting the node
    switch ($n->getNType()) {
        default:
            // Invalid node_type
            error_log('ERROR: ' . $GLOBALS['messages'][80038]);
            return 80028;
        case 'iol':
            $cmd = '/opt/unetlab/wrappers/iol_wrapper -T ' . $t . ' -D ' . $id . ' -t "' . $n->getName() . '" -F /opt/unetlab/addons/iol/bin/' . $n->getImage() . ' -d ' . $n->getDelay() . ' -e ' . $n->getEthernetCount() . ' -s ' . $n->getSerialCount();
            // Adding Serial links
            foreach ($n->getSerials() as $interface_id => $interface) {
                if ($interface->getRemoteId() > 0) {
                    $cmd .= ' -l ' . $interface_id . ':localhost:' . $interface->getRemoteId() . ':' . $interface->getRemoteIf();
                }
            }
            break;
        case 'dynamips':
            $cmd = '/opt/unetlab/wrappers/dynamips_wrapper -T ' . $t . ' -D ' . $id . ' -t "' . $n->getName() . '" -F /opt/unetlab/addons/dynamips/' . $n->getImage() . ' -d ' . $n->getDelay();
            break;
        case 'qemu':
            $cmd = '/opt/unetlab/wrappers/qemu_wrapper -T ' . $t . ' -D ' . $id . ' -t "' . $n->getName() . '" -F ' . $bin . ' -d ' . $n->getDelay();
            if ($n->getConsole() == 'vnc') {
                // Disable telnet (wrapper) console
                $cmd .= ' -x';
            }
            break;
    }
    $cmd .= ' -- ' . $flags . ' > ' . $n->getRunningPath() . '/wrapper.txt 2>&1 &';
    exec($cmd, $o, $rc);
    error_log('INFO: CWD is ' . getcwd());
    error_log('INFO: starting ' . $cmd);
    return 0;
}
Пример #8
0
/** 
 * Creates data for tree menu used on :
 * - Execution of Test Cases
 * - Remove Test cases from test plan
 * 
 * @internal Revisions:
 *
 * 20111031 - franciscom - TICKET
 */
function generateExecTree(&$db, &$menuUrl, $env, $filters, $options)
{
    $tplan_tcases = null;
    $tck_map = null;
    $idx = 0;
    $apply_other_filters = true;
    $map_node_tccount = array();
    $renderOpt = array();
    $renderAux = array();
    $resultsCfg = config_get('results');
    $tplan_mgr = new testplan($db);
    $tcase_mgr = new testcase($db);
    $tproject_mgr = new testproject($db);
    // ---------------------------------------------------------------------------------------------
    // initialize configuration and options
    // ---------------------------------------------------------------------------------------------
    $tproject_id = $env['tproject_id'];
    $tplan_id = $env['tplan_id'];
    $my['filters'] = normalizeFilters($filters);
    $node_types = $tproject_mgr->tree_manager->get_available_node_types();
    $renderAux['hash_id_descr'] = array_flip($node_types);
    $renderAux['testCasePrefix'] = $tproject_mgr->getTestCasePrefix($tproject_id) . config_get('testcase_cfg')->glue_character;
    $decoding_hash = array('node_id_descr' => $renderAux['hash_id_descr'], 'status_descr_code' => $resultsCfg['status_code'], 'status_code_descr' => $resultsCfg['code_status']);
    $renderOpt['showTestCaseID'] = config_get('treemenu_show_testcase_id');
    $renderOpt['hideTCs'] = isset($filters->hide_testcases) ? $filters->hide_testcases : false;
    $renderOpt['showTestSuiteContents'] = isset($filters->show_testsuite_contents) ? $filters->show_testsuite_contents : true;
    $renderOpt['useCounters'] = isset($options->useCounters) ? $options->useCounters : false;
    $renderOpt['colorOptions'] = isset($options->colorOptions) ? $options->colorOptions : null;
    $renderOpt['tc_action_enabled'] = isset($options->tc_action_enabled) ? $options->tc_action_enabled : false;
    $colorBySelectedBuild = isset($options->testcases_colouring_by_selected_build) ? $options->testcases_colouring_by_selected_build : false;
    // ---------------------------------------------------------------------------------------------
    // echo __LINE__;
    $test_spec = getTestSpec4ExecTree($tplan_mgr->tree_manager, $env, $my['filters']);
    // new dBug($my['filters']);
    // new dBug($test_spec);
    if ($doIt = !is_null($test_spec)) {
        if (is_null($my['filters']->filter_tc_id) || $my['filters']->filter_tc_id >= 0) {
            list($tplan_tcases, $tck_map) = getTPlanTCases4ExecTree($db, $tproject_mgr, $tplan_mgr, $env, $my['filters']);
        }
        // new dBug($tplan_tcases);
        // new dBug($tck_map);
        if (is_null($tplan_tcases)) {
            $tplan_tcases = array();
            $apply_other_filters = false;
        } else {
            $tplan_tcases = applyFilters4ExeTree($tplan_mgr, $tplan_tcases, $env['tplan_id'], $resultsCfg, $filters);
            // new dBug($tplan_tcases);
        }
        $apply_other_filters = !is_null($tplan_tcases) && count($tplan_tcases) > 0;
        // BUGID 3450 - Change colors/counters in exec tree.
        // Means: replace exec status in filtered array $tplan_tcases  by the one of last execution of selected build.
        // Since this changes exec status, replacing is done after filtering by status.
        // It has to be done before call to prepareNode() though, because that one sets the counters according to status.
        if ($apply_other_filters && (!is_null($renderOpt['colorOptions']) && $colorBySelectedBuild)) {
            $tplan_tcases = updateStatus4ExecTree($db, $tplan_tcases, $env['tplan_id'], $filters->selected_build, $resultsCfg);
        }
        // 20080224 - franciscom -
        // After reviewing code, seems that assignedTo has no sense because tp_tcs
        // has been filtered.
        // Then to avoid changes to prepareNode() due to include_unassigned,
        // seems enough to set assignedTo to 0, if include_unassigned==true
        $pnFilters['assignedTo'] = $my['filters']->filter_assigned_user_include_unassigned ? null : $my['filters']->filter_assigned_user;
        $keys2init = array('filter_testcase_name', 'filter_execution_type', 'filter_priority');
        foreach ($keys2init as $keyname) {
            $pnFilters[$keyname] = isset($filters->{$keyname}) ? $filters->{$keyname} : null;
        }
        $pnOptions = array('hideTestCases' => $renderOpt['hideTCs'], 'viewType' => 'executionTree');
        // new dBug($tplan_tcases);
        // new dBug($tck_map);
        $testcase_counters = prepareNode($db, $test_spec, $decoding_hash, $map_node_tccount, $tck_map, $tplan_tcases, $pnFilters, $pnOptions);
        foreach ($testcase_counters as $key => $value) {
            $test_spec[$key] = $testcase_counters[$key];
        }
        $keys = array_keys($tplan_tcases);
        // IMPORTANT NOTICE: process makes changes on $test_spec
        renderExecTreeNode($env, 1, $test_spec, $tplan_tcases, $menuUrl, $renderOpt, $renderAux);
    }
    // if($test_spec)
    $treeMenu = new stdClass();
    $treeMenu->menustring = '';
    $treeMenu->rootnode = new stdClass();
    $treeMenu->rootnode->name = $test_spec['text'];
    $treeMenu->rootnode->id = $test_spec['id'];
    $treeMenu->rootnode->leaf = $test_spec['leaf'];
    $treeMenu->rootnode->text = $test_spec['text'];
    $treeMenu->rootnode->position = $test_spec['position'];
    $treeMenu->rootnode->href = $test_spec['href'];
    $menustring = '';
    // new dBug($test_spec['childNodes']);
    if ($doIt) {
        // Change key ('childNodes')  to the one required by Ext JS tree.
        $menustring = str_ireplace('childNodes', 'children', json_encode($test_spec['childNodes']));
        // Remove null elements (Ext JS tree do not like it ).
        // :null happens on -> "children":null,"text" that must become "children":[],"text"
        // $menustring = str_ireplace(array(':null',',null','null,'),array(':[]','',''), $menustring);
        $menustring = str_ireplace(array(':null', ',null', 'null,', 'null'), array(':[]', '', '', ''), $menustring);
    }
    // new dBug($treeMenu->rootnode->href);
    // $menustring = '[{"id":"12","name":"GABA","children":[{"id":"19","name":"API","children":[{"id":"20","name":"set execution result","children":[{"id":"21","name":"set exec result - test plan WITHOUT PLATFORMS","children":[],"leaf":true,"testlink_node_type":"testcase","testlink_node_name":"set exec result - test plan WITHOUT PLATFORMS","text":"PTW-1<\/b>:set exec result - test plan WITHOUT PLATFORMS<\/span>","position":"1000","href":"javascript:ST(21,22)"},{"id":"23","name":"set exec result - test plan WITH WRONG PLATFORM NAME","children":[],"leaf":true,"testlink_node_type":"testcase","testlink_node_name":"set exec result - test plan WITH WRONG PLATFORM NAME","text":"PTW-2<\/b>:set exec result - test plan WITH WRONG PLATFORM NAME<\/span>","position":"1010","href":"javascript:ST(23,24)"},{"id":"25","name":"set exec result - test plan WITH WRONG PLATFORM ID","children":[],"leaf":true,"testlink_node_type":"testcase","testlink_node_name":"set exec result - test plan WITH WRONG PLATFORM ID","text":"PTW-3<\/b>:set exec result - test plan WITH WRONG PLATFORM ID<\/span>","position":"1020","href":"javascript:ST(25,26)"}],"leaf":false,"testlink_node_type":"testsuite","testlink_node_name":"set execution result","text":"set execution result (3)","position":"1","href":"javascript:STS(20,0)"}],"leaf":false,"testlink_node_type":"testsuite","testlink_node_name":"API","text":"API (3)","position":"0","href":"javascript:STS(19,0)"},{"id":"32","name":"Custom Fields Management","children":[{"id":"33","name":"EXPORT - Go back management","children":[],"leaf":true,"testlink_node_type":"testcase","testlink_node_name":"EXPORT - Go back management","text":"PTW-6<\/b>:EXPORT - Go back management<\/span>","position":"1000","href":"javascript:ST(33,34)"},{"id":"35","name":"IMPORT - Go back management","children":[],"leaf":true,"testlink_node_type":"testcase","testlink_node_name":"IMPORT - Go back management","text":"PTW-7<\/b>:IMPORT - Go back management<\/span>","position":"1010","href":"javascript:ST(35,36)"}],"leaf":false,"testlink_node_type":"testsuite","testlink_node_name":"Custom Fields Management","text":"Custom Fields Management (2)","position":"2","href":"javascript:STS(32,0)"}],"leaf":false,"testlink_node_type":"testsuite","testlink_node_name":"GABA","text":"GABA (5)","position":"1","href":"javascript:STS(12,0)"}]';
    $treeMenu->menustring = $menustring;
    // new dBug($menustring);
    return array($treeMenu, $keys);
}