mirror of
https://github.com/Combodo/iTop.git
synced 2026-04-25 19:48:49 +02:00
CI migration/automation + new test to ease iTop release management
- new Jenkinsfile and .jenkins removal to launch phpunit/behat tests triggered on both iTop build and push. - N°3053 - Check XML conversion methods - N°3057 - New build recipe - N°3059 - Automatically set the documentation URLs - N°3052 - Check community modules XML version against latest version - N°3054 - Check community modules version against major version - N°3062 - setup.css file integrity test - N°3060 - Check consistency between the list of modules and installation.xml - Add exclusion group for CI - N°3061 - Automatically check the installation.xml consistency
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -140,3 +140,4 @@ local.properties
|
||||
.scala_dependencies
|
||||
.worksheet
|
||||
|
||||
/css/setup.css
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -x
|
||||
|
||||
# create target dirs
|
||||
mkdir -p var
|
||||
mkdir -p toolkit
|
||||
|
||||
# cleanup target dirs
|
||||
rm -rf toolkit/*
|
||||
|
||||
# fill target dirs
|
||||
curl https://www.combodo.com/documentation/iTopDataModelToolkit-2.3.zip > toolkit.zip
|
||||
unzip toolkit.zip
|
||||
rm toolkit.zip
|
||||
cp -r .jenkins/configuration/default-environment/unattended_install/* toolkit
|
||||
@@ -1,11 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -x
|
||||
|
||||
# on the root dir
|
||||
# composer install -a # => Not needed anymore (libs were added to git with N°2435)
|
||||
|
||||
|
||||
# under the test dir
|
||||
cd test
|
||||
composer install
|
||||
@@ -1,15 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -x
|
||||
|
||||
|
||||
|
||||
whoami
|
||||
pwd
|
||||
ls
|
||||
|
||||
echo "$BRANCH_NAME:${BRANCH_NAME}"
|
||||
|
||||
echo "printenv :"
|
||||
printenv
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -x
|
||||
|
||||
cd test
|
||||
|
||||
export DEBUG_UNIT_TEST=0
|
||||
RUN_NONREG_TESTS=0
|
||||
|
||||
if [ $# -ge 1 -a "x$1" == "xtrue" ]
|
||||
then
|
||||
export DEBUG_UNIT_TEST=1
|
||||
else
|
||||
export DEBUG_UNIT_TEST=0
|
||||
fi
|
||||
|
||||
if [ $# -ge 2 -a "x$2" == "xtrue" ]
|
||||
then
|
||||
php vendor/bin/phpunit --log-junit ../var/test/phpunit-log.junit.xml --teamcity
|
||||
else
|
||||
#echo php vendor/bin/phpunit --log-junit ../var/test/phpunit-log.junit.xml --teamcity
|
||||
php vendor/bin/phpunit --log-junit ../var/test/phpunit-log.junit.xml --exclude-group OQL --teamcity
|
||||
fi
|
||||
@@ -1,8 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -x
|
||||
|
||||
chmod 666 conf/production/config-itop.php
|
||||
|
||||
cd toolkit
|
||||
php unattended_install.php --response_file=default-params.xml --clean=true
|
||||
@@ -1,284 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Configuration file, generated by the iTop configuration wizard
|
||||
*
|
||||
* The file is used in MetaModel::LoadConfig() which does all the necessary initialization job
|
||||
*
|
||||
*/
|
||||
$MySettings = array(
|
||||
|
||||
// access_message: Message displayed to the users when there is any access restriction
|
||||
// default: 'iTop is temporarily frozen, please wait... (the admin team)'
|
||||
'access_message' => 'iTop is temporarily frozen, please wait... (the admin team)',
|
||||
|
||||
// access_mode: Access mode: ACCESS_READONLY = 0, ACCESS_ADMIN_WRITE = 2, ACCESS_FULL = 3
|
||||
// default: 3
|
||||
'access_mode' => 3,
|
||||
|
||||
'allowed_login_types' => 'form|basic|external',
|
||||
|
||||
// apc_cache.enabled: If set, the APC cache is allowed (the PHP extension must also be active)
|
||||
// default: true
|
||||
'apc_cache.enabled' => true,
|
||||
|
||||
// apc_cache.query_ttl: Time to live set in APC for the prepared queries (seconds - 0 means no timeout)
|
||||
// default: 3600
|
||||
'apc_cache.query_ttl' => 3600,
|
||||
|
||||
// app_root_url: Root URL used for navigating within the application, or from an email to the application (you can put $SERVER_NAME$ as a placeholder for the server's name)
|
||||
// default: ''
|
||||
'app_root_url' => 'http://127.0.0.1/itop/svn/trunk/',
|
||||
|
||||
// buttons_position: Position of the forms buttons: bottom | top | both
|
||||
// default: 'both'
|
||||
'buttons_position' => 'both',
|
||||
|
||||
// cas_include_path: The path where to find the phpCAS library
|
||||
// default: '/usr/share/php'
|
||||
'cas_include_path' => '/usr/share/php',
|
||||
|
||||
// cron_max_execution_time: Duration (seconds) of the page cron.php, must be shorter than php setting max_execution_time and shorter than the web server response timeout
|
||||
// default: 600
|
||||
'cron_max_execution_time' => 600,
|
||||
|
||||
// csv_file_default_charset: Character set used by default for downloading and uploading data as a CSV file. Warning: it is case sensitive (uppercase is preferable).
|
||||
// default: 'ISO-8859-1'
|
||||
'csv_file_default_charset' => 'ISO-8859-1',
|
||||
|
||||
'csv_import_charsets' => array (
|
||||
),
|
||||
|
||||
// csv_import_history_display: Display the history tab in the import wizard
|
||||
// default: false
|
||||
'csv_import_history_display' => false,
|
||||
|
||||
// date_and_time_format: Format for date and time display (per language)
|
||||
// default: array (
|
||||
// 'default' =>
|
||||
// array (
|
||||
// 'date' => 'Y-m-d',
|
||||
// 'time' => 'H:i:s',
|
||||
// 'date_time' => '$date $time',
|
||||
// ),
|
||||
// )
|
||||
'date_and_time_format' => array (
|
||||
'default' =>
|
||||
array (
|
||||
'date' => 'Y-m-d',
|
||||
'time' => 'H:i:s',
|
||||
'date_time' => '$date $time',
|
||||
),
|
||||
'FR FR' =>
|
||||
array (
|
||||
'date' => 'd/m/Y',
|
||||
'time' => 'H:i:s',
|
||||
'date_time' => '$date $time',
|
||||
),
|
||||
),
|
||||
|
||||
'db_host' => '',
|
||||
|
||||
'db_name' => 'itop_ci',
|
||||
|
||||
'db_pwd' => 'IKnowYouSeeMeInJenkinsConf',
|
||||
|
||||
'db_subname' => '',
|
||||
|
||||
'db_user' => 'jenkins_itop',
|
||||
|
||||
// deadline_format: The format used for displaying "deadline" attributes: any string with the following placeholders: $date$, $difference$
|
||||
// default: '$difference$'
|
||||
'deadline_format' => '$difference$',
|
||||
|
||||
'default_language' => 'EN US',
|
||||
|
||||
// draft_attachments_lifetime: Lifetime (in seconds) of drafts' attachments and inline images: after this duration, the garbage collector will delete them.
|
||||
// default: 3600
|
||||
'draft_attachments_lifetime' => 3600,
|
||||
|
||||
// email_asynchronous: If set, the emails are sent off line, which requires cron.php to be activated. Exception: some features like the email test utility will force the serialized mode
|
||||
// default: false
|
||||
'email_asynchronous' => false,
|
||||
|
||||
// email_default_sender_address: Default address provided in the email from header field.
|
||||
// default: ''
|
||||
'email_default_sender_address' => '',
|
||||
|
||||
// email_default_sender_label: Default label provided in the email from header field.
|
||||
// default: ''
|
||||
'email_default_sender_label' => '',
|
||||
|
||||
// email_transport: Mean to send emails: PHPMail (uses the function mail()) or SMTP (implements the client protocole)
|
||||
// default: 'PHPMail'
|
||||
'email_transport' => 'SMTP',
|
||||
|
||||
// email_transport_smtp.host: host name or IP address (optional)
|
||||
// default: 'localhost'
|
||||
'email_transport_smtp.host' => 'smtp.combodo.com',
|
||||
|
||||
// email_transport_smtp.password: Authentication password (optional)
|
||||
// default: ''
|
||||
'email_transport_smtp.password' => 'IDoNotWork',
|
||||
|
||||
// email_transport_smtp.port: port number (optional)
|
||||
// default: 25
|
||||
'email_transport_smtp.port' => 25,
|
||||
|
||||
// email_transport_smtp.username: Authentication user (optional)
|
||||
// default: ''
|
||||
'email_transport_smtp.username' => 'test2@combodo.com',
|
||||
|
||||
// email_validation_pattern: Regular expression to validate/detect the format of an eMail address
|
||||
// default: '[a-zA-Z0-9._&\'-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z0-9-]{2,}'
|
||||
'email_validation_pattern' => '[a-zA-Z0-9._&\'-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z0-9-]{2,}',
|
||||
|
||||
'encryption_key' => '@iT0pEncr1pti0n!',
|
||||
|
||||
'ext_auth_variable' => '$_SERVER[\'REMOTE_USER\']',
|
||||
|
||||
'fast_reload_interval' => '60',
|
||||
|
||||
// graphviz_path: Path to the Graphviz "dot" executable for graphing objects lifecycle
|
||||
// default: '/usr/bin/dot'
|
||||
'graphviz_path' => '/usr/bin/dot',
|
||||
|
||||
// inline_image_max_display_width: The maximum width (in pixels) when displaying images inside an HTML formatted attribute. Images will be displayed using this this maximum width.
|
||||
// default: '250'
|
||||
'inline_image_max_display_width' => 250,
|
||||
|
||||
// inline_image_max_storage_width: The maximum width (in pixels) when uploading images to be used inside an HTML formatted attribute. Images larger than the given size will be downsampled before storing them in the database.
|
||||
// default: '1600'
|
||||
'inline_image_max_storage_width' => 1600,
|
||||
|
||||
// link_set_attribute_qualifier: Link set from string: attribute qualifier (encloses both the attcode and the value)
|
||||
// default: '\''
|
||||
'link_set_attribute_qualifier' => '\'',
|
||||
|
||||
// link_set_attribute_separator: Link set from string: attribute separator
|
||||
// default: ';'
|
||||
'link_set_attribute_separator' => ';',
|
||||
|
||||
// link_set_item_separator: Link set from string: line separator
|
||||
// default: '|'
|
||||
'link_set_item_separator' => '|',
|
||||
|
||||
// link_set_value_separator: Link set from string: value separator (between the attcode and the value itself
|
||||
// default: ':'
|
||||
'link_set_value_separator' => ':',
|
||||
|
||||
'log_global' => true,
|
||||
|
||||
'log_issue' => true,
|
||||
|
||||
'log_notification' => true,
|
||||
|
||||
'log_web_service' => true,
|
||||
|
||||
// max_combo_length: The maximum number of elements in a drop-down list. If more then an autocomplete will be used
|
||||
// default: 50
|
||||
'max_combo_length' => 50,
|
||||
|
||||
'max_display_limit' => '15',
|
||||
|
||||
// max_linkset_output: Maximum number of items shown when getting a list of related items in an email, using the form $this->some_list$. 0 means no limit.
|
||||
// default: 100
|
||||
'max_linkset_output' => 100,
|
||||
|
||||
'min_display_limit' => '10',
|
||||
|
||||
// online_help: Hyperlink to the online-help web page
|
||||
// default: 'http://www.combodo.com/itop-help'
|
||||
'online_help' => 'http://www.combodo.com/itop-help',
|
||||
|
||||
// php_path: Path to the php executable in CLI mode
|
||||
// default: 'php'
|
||||
'php_path' => 'php',
|
||||
|
||||
// portal_tickets: CSV list of classes supported in the portal
|
||||
// default: 'UserRequest'
|
||||
'portal_tickets' => 'UserRequest',
|
||||
|
||||
'query_cache_enabled' => true,
|
||||
|
||||
// search_manual_submit: Force manual submit of search requests (class => true)
|
||||
// default: false
|
||||
'search_manual_submit' => array (
|
||||
'Person' => true,
|
||||
),
|
||||
|
||||
'secure_connection_required' => false,
|
||||
|
||||
// session_name: The name of the cookie used to store the PHP session id
|
||||
// default: 'iTop'
|
||||
'session_name' => 'iTop',
|
||||
|
||||
// shortcut_actions: Actions that are available as direct buttons next to the "Actions" menu
|
||||
// default: 'UI:Menu:Modify,UI:Menu:New'
|
||||
'shortcut_actions' => 'UI:Menu:Modify,UI:Menu:New',
|
||||
|
||||
// source_dir: Source directory for the datamodel files. (which gets compiled to env-production).
|
||||
// default: ''
|
||||
'source_dir' => 'datamodels/2.x/',
|
||||
|
||||
'standard_reload_interval' => '300',
|
||||
|
||||
// synchro_trace: Synchronization details: none, display, save (includes 'display')
|
||||
// default: 'none'
|
||||
'synchro_trace' => 'none',
|
||||
|
||||
// timezone: Timezone (reference: http://php.net/manual/en/timezones.php). If empty, it will be left unchanged and MUST be explicitely configured in PHP
|
||||
// default: 'Europe/Paris'
|
||||
'timezone' => 'Europe/Paris',
|
||||
|
||||
// tracking_level_linked_set_default: Default tracking level if not explicitely set at the attribute level, for AttributeLinkedSet (defaults to NONE in case of a fresh install, LIST otherwise - this to preserve backward compatibility while upgrading from a version older than 2.0.3 - see TRAC #936)
|
||||
// default: 1
|
||||
'tracking_level_linked_set_default' => 0,
|
||||
|
||||
// url_validation_pattern: Regular expression to validate/detect the format of an URL (URL attributes and Wiki formatting for Text attributes)
|
||||
// default: '(https?|ftp)\\://([a-zA-Z0-9+!*(),;?&=\\$_.-]+(\\:[a-zA-Z0-9+!*(),;?&=\\$_.-]+)?@)?([a-zA-Z0-9-.]{3,})(\\:[0-9]{2,5})?(/([a-zA-Z0-9%+\\$_-]\\.?)+)*/?(\\?[a-zA-Z+&\\$_.-][a-zA-Z0-9;:[\\]@&%=+/\\$_.-]*)?(#[a-zA-Z_.-][a-zA-Z0-9+\\$_.-]*)?'
|
||||
'url_validation_pattern' => '(https?|ftp)\\://([a-zA-Z0-9+!*(),;?&=\\$_.-]+(\\:[a-zA-Z0-9+!*(),;?&=\\$_.-]+)?@)?([a-zA-Z0-9-.]{3,})(\\:[0-9]{2,5})?(/([a-zA-Z0-9%+\\$_-]\\.?)+)*/?(\\?[a-zA-Z+&\\$_.-][a-zA-Z0-9;:[\\]@&%=+/\\$_.-]*)?(#[a-zA-Z_.-][a-zA-Z0-9+\\$_.-]*)?',
|
||||
);
|
||||
|
||||
/**
|
||||
*
|
||||
* Modules specific settings
|
||||
*
|
||||
*/
|
||||
$MyModuleSettings = array(
|
||||
'authent-local' => array (
|
||||
'password_validation.pattern' => '',
|
||||
),
|
||||
'itop-attachments' => array (
|
||||
'allowed_classes' => array (
|
||||
0 => 'Ticket',
|
||||
),
|
||||
'position' => 'relations',
|
||||
'preview_max_width' => 290,
|
||||
),
|
||||
'itop-backup' => array (
|
||||
'mysql_bindir' => '',
|
||||
'week_days' => 'monday, tuesday, wednesday, thursday, friday',
|
||||
'time' => '23:30',
|
||||
'retention_count' => 5,
|
||||
'enabled' => true,
|
||||
'debug' => false,
|
||||
),
|
||||
'molkobain-console-tooltips' => array (
|
||||
'decoration_class' => 'fas fa-question',
|
||||
'enabled' => true,
|
||||
),
|
||||
);
|
||||
|
||||
/**
|
||||
*
|
||||
* Data model modules to be loaded. Names are specified as relative paths
|
||||
*
|
||||
*/
|
||||
$MyModules = array(
|
||||
'addons' => array (
|
||||
'user rights' => 'addons/userrights/userrightsprofile.class.inc.php',
|
||||
),
|
||||
);
|
||||
?>
|
||||
@@ -1,208 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2019 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
//this scrit will be run under the ./toolkit directory, relatively to the document root
|
||||
|
||||
require_once('../approot.inc.php');
|
||||
require_once(APPROOT.'/application/utils.inc.php');
|
||||
require_once(APPROOT.'/application/clipage.class.inc.php');
|
||||
require_once(APPROOT.'/core/config.class.inc.php');
|
||||
require_once(APPROOT.'/core/log.class.inc.php');
|
||||
require_once(APPROOT.'/core/kpi.class.inc.php');
|
||||
require_once(APPROOT.'/core/cmdbsource.class.inc.php');
|
||||
require_once(APPROOT.'/setup/setuppage.class.inc.php');
|
||||
require_once(APPROOT.'/setup/wizardcontroller.class.inc.php');
|
||||
require_once(APPROOT.'/setup/wizardsteps.class.inc.php');
|
||||
require_once(APPROOT.'/setup/applicationinstaller.class.inc.php');
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
$sParamFile = utils::ReadParam('response_file', 'default-params.xml', true /* CLI allowed */, 'raw_data');
|
||||
$bCheckConsistency = (utils::ReadParam('check_consistency', '0', true /* CLI allowed */) == '1');
|
||||
|
||||
$oParams = new XMLParameters($sParamFile);
|
||||
$sMode = $oParams->Get('mode');
|
||||
|
||||
if ($sMode == 'install')
|
||||
{
|
||||
echo "Installation mode detected.\n";
|
||||
$bClean = utils::ReadParam('clean', false, true /* CLI allowed */);
|
||||
if ($bClean)
|
||||
{
|
||||
echo "Cleanup mode detected.\n";
|
||||
$sTargetEnvironment = $oParams->Get('target_env', '');
|
||||
if ($sTargetEnvironment == '')
|
||||
{
|
||||
$sTargetEnvironment = 'production';
|
||||
}
|
||||
$sTargetDir = APPROOT.'env-'.$sTargetEnvironment;
|
||||
|
||||
// Configuration file
|
||||
$sConfigFile = APPCONF.$sTargetEnvironment.'/'.ITOP_CONFIG_FILE;
|
||||
if (file_exists($sConfigFile))
|
||||
{
|
||||
echo "Trying to delete the configuration file: '$sConfigFile'.\n";
|
||||
@chmod($sConfigFile, 0770); // RWX for owner and group, nothing for others
|
||||
unlink($sConfigFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
echo "No config file to delete ($sConfigFile does not exist).\n";
|
||||
}
|
||||
|
||||
// env-xxx directory
|
||||
if (file_exists($sTargetDir))
|
||||
{
|
||||
if (is_dir($sTargetDir))
|
||||
{
|
||||
echo "Emptying the target directory '$sTargetDir'.\n";
|
||||
SetupUtils::tidydir($sTargetDir);
|
||||
}
|
||||
else
|
||||
{
|
||||
die("ERROR the target dir '$sTargetDir' exists, but is NOT a directory !!!\nExiting.\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
echo "No target directory to delete ($sTargetDir does not exist).\n";
|
||||
}
|
||||
|
||||
// Database
|
||||
$aDBSettings = $oParams->Get('database', array());
|
||||
$sDBServer = $aDBSettings['server'];
|
||||
$sDBUser = $aDBSettings['user'];
|
||||
$sDBPwd = $aDBSettings['pwd'];
|
||||
$sDBName = $aDBSettings['name'];
|
||||
$sDBPrefix = $aDBSettings['prefix'];
|
||||
|
||||
if ($sDBPrefix != '')
|
||||
{
|
||||
die("Cleanup not implemented for a partial database (prefix= '$sDBPrefix')\nExiting.");
|
||||
}
|
||||
|
||||
$oMysqli = new mysqli($sDBServer, $sDBUser, $sDBPwd);
|
||||
if ($oMysqli->connect_errno)
|
||||
{
|
||||
die("Cannot connect to the MySQL server (".$oMysqli->connect_errno . ") ".$oMysqli->connect_error."\nExiting");
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($oMysqli->select_db($sDBName))
|
||||
{
|
||||
echo "Deleting database '$sDBName'\n";
|
||||
$oMysqli->query("DROP DATABASE `$sDBName`");
|
||||
}
|
||||
else
|
||||
{
|
||||
echo "The database '$sDBName' does not seem to exist. Nothing to cleanup.\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$bHasErrors = false;
|
||||
$aChecks = SetupUtils::CheckBackupPrerequisites(APPROOT.'data'); // mmm should be the backup destination dir
|
||||
|
||||
$aSelectedModules = $oParams->Get('selected_modules');
|
||||
$sSourceDir = $oParams->Get('source_dir', 'datamodels/latest');
|
||||
$sExtensionDir = $oParams->Get('extensions_dir', 'extensions');
|
||||
$aChecks = array_merge($aChecks, SetupUtils::CheckSelectedModules($sSourceDir, $sExtensionDir, $aSelectedModules));
|
||||
|
||||
|
||||
foreach($aChecks as $oCheckResult)
|
||||
{
|
||||
switch($oCheckResult->iSeverity)
|
||||
{
|
||||
case CheckResult::ERROR:
|
||||
$bHasErrors = true;
|
||||
$sHeader = "Error";
|
||||
break;
|
||||
|
||||
case CheckResult::WARNING:
|
||||
$sHeader = "Warning";
|
||||
break;
|
||||
|
||||
case CheckResult::INFO:
|
||||
default:
|
||||
$sHeader = "Info";
|
||||
break;
|
||||
}
|
||||
echo $sHeader.": ".$oCheckResult->sLabel;
|
||||
if (strlen($oCheckResult->sDescription))
|
||||
{
|
||||
echo ' - '.$oCheckResult->sDescription;
|
||||
}
|
||||
echo "\n";
|
||||
}
|
||||
|
||||
if ($bHasErrors)
|
||||
{
|
||||
echo "Encountered stopper issues. Aborting...\n";
|
||||
die;
|
||||
}
|
||||
|
||||
$bFoundIssues = false;
|
||||
|
||||
$bInstall = utils::ReadParam('install', true, true /* CLI allowed */);
|
||||
if ($bInstall)
|
||||
{
|
||||
echo "Starting the unattended installation...\n";
|
||||
$oWizard = new ApplicationInstaller($oParams);
|
||||
$bRes = $oWizard->ExecuteAllSteps();
|
||||
if (!$bRes)
|
||||
{
|
||||
echo "\nencountered installation issues!";
|
||||
$bFoundIssues = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
echo "No installation requested.\n";
|
||||
}
|
||||
if (!$bFoundIssues && $bCheckConsistency)
|
||||
{
|
||||
echo "Checking data model consistency.\n";
|
||||
ob_start();
|
||||
$sCheckRes = '';
|
||||
try
|
||||
{
|
||||
MetaModel::CheckDefinitions(false);
|
||||
$sCheckRes = ob_get_clean();
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
$sCheckRes = ob_get_clean()."\nException: ".$e->getMessage();
|
||||
}
|
||||
if (strlen($sCheckRes) > 0)
|
||||
{
|
||||
echo $sCheckRes;
|
||||
echo "\nfound consistency issues!";
|
||||
$bFoundIssues = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$bFoundIssues)
|
||||
{
|
||||
// last line: used to check the install
|
||||
// the only way to track issues in case of Fatal error or even parsing error!
|
||||
echo "\ninstalled!";
|
||||
exit;
|
||||
}
|
||||
90
.make/build/afterBuild.php
Normal file
90
.make/build/afterBuild.php
Normal file
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
$iBeginTime = time();
|
||||
|
||||
chdir(__DIR__);
|
||||
|
||||
$aCommands = [
|
||||
'php composer/rmDeniedTestDir.php',
|
||||
'php build/commands/setupCssCompiler.php',
|
||||
// 'bash /tmp/gabuzomeu.sh',
|
||||
];
|
||||
|
||||
$aFailedCommands=[];
|
||||
foreach ($aCommands as $sCommand)
|
||||
{
|
||||
if (!ExecCommand($sCommand))
|
||||
{
|
||||
$aFailedCommands[] = $sCommand;
|
||||
}
|
||||
}
|
||||
|
||||
$iElapsed = time() - $iBeginTime;
|
||||
|
||||
if (count($aFailedCommands))
|
||||
{
|
||||
fwrite(STDERR, "\nafterBuild execution failed! (in ${iElapsed}s)\n");
|
||||
fwrite(STDERR, "List of failling commands:\n - " . implode("\n - ", $aFailedCommands) . "\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
echo "\nDone (${iElapsed}s)\n";
|
||||
exit(0);
|
||||
|
||||
/**
|
||||
* Executes a command and returns an array with exit code, stdout and stderr content
|
||||
*
|
||||
* @param string $cmd - Command to execute
|
||||
*
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
function ExecCommand($cmd) {
|
||||
$iBeginTime = time();
|
||||
|
||||
|
||||
echo sprintf("command: %s", str_pad("$cmd ", 50));
|
||||
|
||||
$descriptorspec = array(
|
||||
0 => array("pipe", "r"), // stdin
|
||||
1 => array("pipe", "w"), // stdout
|
||||
2 => array("pipe", "w"), // stderr
|
||||
);
|
||||
$process = proc_open($cmd, $descriptorspec, $pipes, __DIR__ . '/..', null);
|
||||
|
||||
$stdout = stream_get_contents($pipes[1]);
|
||||
fclose($pipes[1]);
|
||||
|
||||
$stderr = stream_get_contents($pipes[2]);
|
||||
fclose($pipes[2]);
|
||||
|
||||
$iCode = proc_close($process);
|
||||
$bSuccess = (0 === $iCode);
|
||||
|
||||
$iElapsed = time() - $iBeginTime;
|
||||
if (!$bSuccess) {
|
||||
fwrite(STDERR, sprintf(
|
||||
"\nCOMMAND FAILED! (%s) \n - status:%s \n - stderr:%s \n - stdout: %s\n - elapsed:%ss\n\n",
|
||||
$cmd,
|
||||
$iCode,
|
||||
rtrim($stderr),
|
||||
rtrim($stdout),
|
||||
$iElapsed
|
||||
));
|
||||
}
|
||||
else
|
||||
{
|
||||
echo "| elapsed:${iElapsed}s \n";
|
||||
}
|
||||
|
||||
if (!empty($stderr))
|
||||
{
|
||||
fwrite(STDERR, "$stderr\n");
|
||||
}
|
||||
if (!empty($stdout))
|
||||
{
|
||||
echo "stdout :$stdout\n\n";
|
||||
}
|
||||
|
||||
return $bSuccess;
|
||||
}
|
||||
51
.make/build/commands/setupCssCompiler.php
Normal file
51
.make/build/commands/setupCssCompiler.php
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2010-2020 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with iTop. If not, see <http: *www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
|
||||
use Combodo\iTop\Composer\iTopComposer;
|
||||
|
||||
$iTopFolder = __DIR__."/../../../";
|
||||
|
||||
require_once("$iTopFolder/approot.inc.php");
|
||||
require_once(APPROOT."/application/utils.inc.php");
|
||||
|
||||
if (php_sapi_name() !== 'cli')
|
||||
{
|
||||
throw new \Exception('This script can only run from CLI');
|
||||
}
|
||||
|
||||
$sCssFile = APPROOT.'/css/setup.css';
|
||||
if (file_exists($sCssFile))
|
||||
{
|
||||
fwrite(STDERR, "$sCssFile already exists (it should not), removing it.");
|
||||
if (!unlink($sCssFile))
|
||||
{
|
||||
fwrite(STDERR, "Failed to remove $sCssFile, exiting.");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
$sCssRelPath = utils::GetCSSFromSASS('css/setup.scss');
|
||||
|
||||
if (!file_exists($sCssFile))
|
||||
{
|
||||
fwrite(STDERR, "Failed to compile $sCssFile, exiting.");
|
||||
exit(1);
|
||||
}
|
||||
71
Jenkinsfile
vendored
71
Jenkinsfile
vendored
@@ -1,70 +1,11 @@
|
||||
pipeline {
|
||||
agent any
|
||||
parameters {
|
||||
booleanParam(name: 'debugMode', defaultValue: 'false', description: 'Debug mode?')
|
||||
booleanParam(name: 'runNonRegOQLTests', defaultValue: 'false', description: 'Do You want to run legacy OQL regression tests?')
|
||||
}
|
||||
stages {
|
||||
def infra
|
||||
|
||||
stage('init') {
|
||||
parallel {
|
||||
stage('debug') {
|
||||
steps {
|
||||
sh './.jenkins/bin/init/debug.sh'
|
||||
}
|
||||
}
|
||||
stage('append files to project') {
|
||||
steps {
|
||||
sh './.jenkins/bin/init/append_files.sh'
|
||||
}
|
||||
}
|
||||
stage('composer install') {
|
||||
steps {
|
||||
sh './.jenkins/bin/init/composer_install.sh'
|
||||
}
|
||||
}
|
||||
}
|
||||
node(){
|
||||
checkout scm
|
||||
|
||||
infra = load '/var/lib/jenkins/workspace/itop-test-infra_master/src/Infra.groovy'
|
||||
}
|
||||
|
||||
stage('unattended_install') {
|
||||
parallel {
|
||||
stage('unattended_install default env') {
|
||||
steps {
|
||||
sh './.jenkins/bin/unattended_install/default_env.sh'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('test') {
|
||||
parallel {
|
||||
stage('phpunit') {
|
||||
steps {
|
||||
sh './.jenkins/bin/tests/phpunit.sh ${debugMode} ${runNonRegOQLTests}'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
infra.call()
|
||||
|
||||
}
|
||||
|
||||
post {
|
||||
always {
|
||||
junit 'var/test/phpunit-log.junit.xml'
|
||||
}
|
||||
failure {
|
||||
slackSend(channel: "#jenkins-itop", color: '#FF0000', message: "Ho no! Build failed! (${currentBuild.result}), Job '${env.JOB_NAME_UNESCAPED} [${env.BUILD_NUMBER}]' (${env.BUILD_URL})")
|
||||
}
|
||||
fixed {
|
||||
slackSend(channel: "#jenkins-itop", color: '#FFa500', message: "Yes! Build repaired! (${currentBuild.result}), Job '${env.JOB_NAME_UNESCAPED} [${env.BUILD_NUMBER}]' (${env.BUILD_URL})")
|
||||
}
|
||||
}
|
||||
|
||||
environment {
|
||||
DEBUG_UNIT_TEST = '0'
|
||||
JOB_NAME_UNESCAPED = env.JOB_NAME.replaceAll("%2F", "/")
|
||||
}
|
||||
options {
|
||||
timeout(time: 20, unit: 'MINUTES')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2088,6 +2088,41 @@ class utils
|
||||
return COMPILATION_TIMESTAMP;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string eg : '2_7_0' ITOP_VERSION is '2.7.1-dev'
|
||||
*/
|
||||
public static function GetItopVersionWikiSyntax()
|
||||
{
|
||||
$sMinorVersion = self::GetItopMinorVersion();
|
||||
return str_replace('.', '_', $sMinorVersion).'_0';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string eg 2.7 if ITOP_VERSION is '2.7.0-dev'
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function GetItopMinorVersion()
|
||||
{
|
||||
$sPatchVersion = self::GetItopPatchVersion();
|
||||
$aExplodedVersion = explode('.', $sPatchVersion);
|
||||
|
||||
if (empty($aExplodedVersion[0]) || empty($aExplodedVersion[1]))
|
||||
{
|
||||
throw new Exception('iTop version is wrongfully configured!');
|
||||
}
|
||||
|
||||
return sprintf('%d.%d', $aExplodedVersion[0], $aExplodedVersion[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string eg '2.7.0' if ITOP_VERSION is '2.7.0-dev'
|
||||
*/
|
||||
public static function GetItopPatchVersion()
|
||||
{
|
||||
$aExplodedVersion = explode('-', ITOP_VERSION);
|
||||
return $aExplodedVersion[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given class if configured as a high cardinality class.
|
||||
*
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
define('ITOP_APPLICATION', 'iTop');
|
||||
define('ITOP_APPLICATION_SHORT', 'iTop');
|
||||
define('ITOP_VERSION', '2.7.0-dev');
|
||||
define('ITOP_VERSION', '2.7.0-dev'); // @see utils::GetItopVersionShort() and utils::GetItopVersionWikiSyntax()
|
||||
define('ITOP_REVISION', 'svn');
|
||||
define('ITOP_BUILD_DATE', '$WCNOW$');
|
||||
define('ITOP_VERSION_FULL', ITOP_VERSION.'-'.ITOP_REVISION);
|
||||
|
||||
267
css/setup.css
267
css/setup.css
@@ -1,267 +0,0 @@
|
||||
/*!
|
||||
* Copyright (C) 2013-2020 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
/* Helpers classes */
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
/* Animations */
|
||||
@keyframes progress_bar_color_ongoing {
|
||||
from {
|
||||
background-color: #FBD38D;
|
||||
}
|
||||
to {
|
||||
background-color: #FEEBC8;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes bg-pan-left {
|
||||
0% {
|
||||
background-position: 100% 50%;
|
||||
}
|
||||
100% {
|
||||
background-position: 0 50%;
|
||||
}
|
||||
}
|
||||
@keyframes bg-pan-left {
|
||||
0% {
|
||||
background-position: 100% 50%;
|
||||
}
|
||||
100% {
|
||||
background-position: 0 50%;
|
||||
}
|
||||
}
|
||||
/* Theme */
|
||||
body {
|
||||
background-color: #eee;
|
||||
color: #1A202C;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 10pt;
|
||||
font-family: Tahoma, Verdana, Arial, Helvetica, serif;
|
||||
overflow-y: auto;
|
||||
}
|
||||
h1 {
|
||||
color: #555555;
|
||||
font-size: 16pt;
|
||||
}
|
||||
h2 {
|
||||
color: #1A202C;
|
||||
font-size: 14pt;
|
||||
font-weight: normal;
|
||||
}
|
||||
h3 {
|
||||
color: #1C94C4;
|
||||
font-size: 12pt;
|
||||
font-weight: bold;
|
||||
}
|
||||
a {
|
||||
color: #1c94c4;
|
||||
text-decoration: none;
|
||||
}
|
||||
a:hover {
|
||||
color: #EA7D1E;
|
||||
}
|
||||
#header {
|
||||
width: 600px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
margin-top: 50px;
|
||||
padding: 20px;
|
||||
background-color: #fff;
|
||||
height: 54px;
|
||||
border: 3px solid #CBD2D9;
|
||||
border-bottom: none;
|
||||
}
|
||||
#header img {
|
||||
border: 0;
|
||||
vertical-align: middle;
|
||||
margin-right: 20px;
|
||||
}
|
||||
#header h1 {
|
||||
height: 54px;
|
||||
margin: 0;
|
||||
}
|
||||
#setup {
|
||||
width: 600px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
padding: 20px;
|
||||
background-color: #fff;
|
||||
border: 3px solid #CBD2D9;
|
||||
border-top: none;
|
||||
}
|
||||
.next {
|
||||
width: 100%;
|
||||
text-align: right;
|
||||
}
|
||||
.v-spacer {
|
||||
padding-top: 1em;
|
||||
}
|
||||
button {
|
||||
margin-top: 1em;
|
||||
padding-left: 1em;
|
||||
padding-right: 1em;
|
||||
}
|
||||
p.info {
|
||||
padding-left: 50px;
|
||||
background: url(../images/info-mid.png) no-repeat left -5px;
|
||||
min-height: 48px;
|
||||
}
|
||||
p.ok {
|
||||
padding-left: 50px;
|
||||
background: url(../images/clean-mid.png) no-repeat left -8px;
|
||||
min-height: 48px;
|
||||
}
|
||||
p.warning {
|
||||
padding-left: 50px;
|
||||
background: url(../images/messagebox_warning-mid.png) no-repeat left -5px;
|
||||
min-height: 48px;
|
||||
}
|
||||
p.error {
|
||||
padding-left: 50px;
|
||||
background: url(../images/stop-mid.png) no-repeat left -5px;
|
||||
min-height: 48px;
|
||||
}
|
||||
label {
|
||||
cursor: pointer;
|
||||
}
|
||||
td.label {
|
||||
text-align: left;
|
||||
}
|
||||
label.read-only {
|
||||
color: #666;
|
||||
cursor: text;
|
||||
}
|
||||
td.input {
|
||||
text-align: left;
|
||||
}
|
||||
table.formTable {
|
||||
border: 0;
|
||||
}
|
||||
.wizlabel, .wizinput {
|
||||
color: #000;
|
||||
font-size: 10pt;
|
||||
}
|
||||
.wizhelp {
|
||||
color: #333;
|
||||
font-size: 8pt;
|
||||
}
|
||||
#progress {
|
||||
border: none;
|
||||
width: 210px;
|
||||
height: 26px;
|
||||
line-height: 26px;
|
||||
text-align: center;
|
||||
margin: 5px;
|
||||
box-shadow: inset 0 2px 4px 0 rgba(0, 0, 0, 0.06) !important;
|
||||
border-radius: 2px;
|
||||
background-color: #EDF2F7 !important;
|
||||
}
|
||||
#progress .progress {
|
||||
color: #000000 !important;
|
||||
/* !important to overload jQuery UI style */
|
||||
background-image: linear-gradient(270deg, #FBD38D 50%, #FEEBC8 55%, #FBD38D 80%) !important;
|
||||
/* !important to overload jQuery UI style */
|
||||
animation: bg-pan-left 3s infinite both;
|
||||
background-size: 600% 100%;
|
||||
border-radius: inherit;
|
||||
}
|
||||
#progress .progress.progress-error {
|
||||
background-image: none !important;
|
||||
background-color: #F56565 !important;
|
||||
/* !important to overload jQuery UI style */
|
||||
animation: none;
|
||||
}
|
||||
h3.clickable {
|
||||
background: url(../images/plus.gif) no-repeat left;
|
||||
padding-left: 16px;
|
||||
cursor: hand;
|
||||
}
|
||||
h3.clickable.open {
|
||||
background: url(../images/minus.gif) no-repeat left;
|
||||
padding-left: 16px;
|
||||
cursor: hand;
|
||||
}
|
||||
.message {
|
||||
color: #1A202C;
|
||||
background-color: #F7FAFC;
|
||||
border-left: 4px solid #4A5568;
|
||||
padding: 10px;
|
||||
}
|
||||
.message > .message-title {
|
||||
font-weight: bold;
|
||||
margin-right: 5px;
|
||||
}
|
||||
.message ~ .message {
|
||||
margin-top: 6px;
|
||||
}
|
||||
.message.message-valid {
|
||||
color: #276749;
|
||||
background-color: #F0FFF4;
|
||||
border-color: #48BB78;
|
||||
}
|
||||
.message.message-warning {
|
||||
color: #C05621;
|
||||
background-color: #FFFAF0;
|
||||
border-color: #ED8936;
|
||||
}
|
||||
.message.message-error {
|
||||
color: #C53030;
|
||||
background-color: #FFF5F5;
|
||||
border-color: #E53E3E;
|
||||
}
|
||||
.text-valid {
|
||||
color: #276749;
|
||||
}
|
||||
.text-warning {
|
||||
color: #C05621;
|
||||
}
|
||||
.text-error {
|
||||
color: #C53030;
|
||||
}
|
||||
fieldset {
|
||||
border: none;
|
||||
padding: 0;
|
||||
margin: 30px 0 0 0;
|
||||
}
|
||||
fieldset > legend {
|
||||
margin-top: 25px;
|
||||
margin-bottom: 7px;
|
||||
padding-bottom: 7px;
|
||||
width: 100%;
|
||||
color: #3C3C3C;
|
||||
font-size: 11pt;
|
||||
font-weight: bold;
|
||||
border-bottom: 1px solid #D2D2D2;
|
||||
}
|
||||
.module-selection-banner img {
|
||||
max-height: 48px;
|
||||
}
|
||||
.module-selection-body {
|
||||
height: 28em;
|
||||
overflow: auto;
|
||||
box-shadow: inset 0 2px 4px 0 rgba(0, 0, 0, 0.06) !important;
|
||||
background-color: #F7FAFC;
|
||||
padding: 10px;
|
||||
}
|
||||
.module-selection-body .wiz-choice:checked ~ .description #itop-ticket-mgmt-simple-ticket-enhanced-portal:not(:checked) ~ .description::after, .module-selection-body .wiz-choice:checked ~ .description #itop-ticket-mgmt-itil-enhanced-portal:not(:checked) ~ .description::after {
|
||||
content: "Legacy portal is no longer part of iTop, by leaving this option unchecked your portal users won't be able to access iTop anymore.";
|
||||
display: block;
|
||||
margin-top: 0.5em;
|
||||
font-weight: bold;
|
||||
color: #e60000b8;
|
||||
}
|
||||
@@ -16,6 +16,8 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
/* integrityCheck: begin (do not remove/edit) */
|
||||
|
||||
/////////
|
||||
// Colors
|
||||
$content-border-color: #CBD2D9 !default;
|
||||
@@ -314,3 +316,4 @@ fieldset{
|
||||
}
|
||||
}
|
||||
|
||||
/* integrityCheck: end (do not remove/edit) */
|
||||
@@ -41,7 +41,7 @@ define('ITOP_DESIGN_LATEST_VERSION', '1.7'); // iTop >= 2.7.0
|
||||
*/
|
||||
class iTopDesignFormat
|
||||
{
|
||||
protected static $aVersions = array(
|
||||
public static $aVersions = array(
|
||||
'1.0' => array(
|
||||
'previous' => null,
|
||||
'go_to_previous' => null,
|
||||
@@ -89,7 +89,7 @@ class iTopDesignFormat
|
||||
'go_to_previous' => 'From17To16',
|
||||
'next' => null,
|
||||
'go_to_next' => null,
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
/**
|
||||
|
||||
@@ -916,7 +916,7 @@ class SetupUtils
|
||||
$oPage, $bIsItopInstall, $sDBServer, $sDBUser, $sDBPwd, $sDBName, $sDBPrefix, $bTlsEnabled, $sTlsCA,
|
||||
$sNewDBName = ''
|
||||
) {
|
||||
$sWikiVersion = '2_7_0';
|
||||
$sWikiVersion = utils::GetItopVersionWikiSyntax(); //eg : '2_7_0';
|
||||
$sMysqlTlsWikiPageUrl = 'https://wiki.openitop.org/doku.php?id='.$sWikiVersion.':install:php_and_mysql_tls';
|
||||
|
||||
$oPage->add('<tr><td colspan="2">');
|
||||
|
||||
@@ -68,7 +68,7 @@ class UtilsTest extends \Combodo\iTop\Test\UnitTest\ItopTestCase
|
||||
*/
|
||||
public function testRealPath($sPath, $sBasePath, $expected)
|
||||
{
|
||||
$this->assertSame($expected, utils::RealPath($sPath, $sBasePath));
|
||||
$this->assertSame($expected, utils::RealPath($sPath, $sBasePath), "utils::RealPath($sPath, $sBasePath) does not match $expected");
|
||||
}
|
||||
|
||||
public function realPathDataProvider()
|
||||
@@ -77,14 +77,19 @@ class UtilsTest extends \Combodo\iTop\Test\UnitTest\ItopTestCase
|
||||
|
||||
$sSep = DIRECTORY_SEPARATOR;
|
||||
$sItopRootRealPath = realpath(APPROOT).$sSep;
|
||||
$sLicenseFileName = 'license.txt';
|
||||
if (!is_file(APPROOT.$sLicenseFileName))
|
||||
{
|
||||
$sLicenseFileName = 'LICENSE';
|
||||
}
|
||||
|
||||
return [
|
||||
'licence.txt' => [APPROOT.'license.txt', APPROOT, $sItopRootRealPath.'license.txt'],
|
||||
$sLicenseFileName => [APPROOT.$sLicenseFileName, APPROOT, $sItopRootRealPath.$sLicenseFileName],
|
||||
'unexisting file' => [APPROOT.'license_DOES_NOT_EXIST.txt', APPROOT, false],
|
||||
'/license.txt' => [APPROOT.$sSep.'license.txt', APPROOT, $sItopRootRealPath.'license.txt'],
|
||||
'%2flicense.txt' => [APPROOT.'%2flicense.txt', APPROOT, false],
|
||||
'../license.txt' => [APPROOT.'..'.$sSep.'license.txt', APPROOT, false],
|
||||
'%2e%2e%2flicense.txt' => [APPROOT.'%2e%2e%2flicense.txt', APPROOT, false],
|
||||
'/'.$sLicenseFileName => [APPROOT.$sSep.$sLicenseFileName, APPROOT, $sItopRootRealPath.$sLicenseFileName],
|
||||
'%2f'.$sLicenseFileName => [APPROOT.'%2f'. $sLicenseFileName, APPROOT, false],
|
||||
'../'.$sLicenseFileName => [APPROOT.'..'.$sSep.$sLicenseFileName, APPROOT, false],
|
||||
'%2e%2e%2f'.$sLicenseFileName => [APPROOT.'%2e%2e%2f'.$sLicenseFileName, APPROOT, false],
|
||||
'application/utils.inc.php with basepath=APPROOT' => [
|
||||
APPROOT.'application/utils.inc.php',
|
||||
APPROOT,
|
||||
|
||||
BIN
test/backups/backup-itop.tar.gz
Normal file
BIN
test/backups/backup-itop.tar.gz
Normal file
Binary file not shown.
8
test/ci_description.ini
Normal file
8
test/ci_description.ini
Normal file
@@ -0,0 +1,8 @@
|
||||
[itop]
|
||||
itop_setup=test/setup_params/default-params.xml
|
||||
itop_backup=test/backups/backup-itop.tar.gz
|
||||
|
||||
[phpunit]
|
||||
; when empty phpunit_xml => no phpunit test performed
|
||||
; phpunit xml file description. required for phpunit testing
|
||||
phpunit_xml=test/phpunit.xml.dist
|
||||
@@ -36,6 +36,18 @@ use UserRights;
|
||||
*/
|
||||
class UserRightsTest extends ItopDataTestCase
|
||||
{
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp(); // TODO: Change the autogenerated stub
|
||||
|
||||
try{
|
||||
\utils::GetConfig()->SetModuleSetting('authent-local', 'password_validation.pattern', '' );
|
||||
self::CreateUser('admin', 1);
|
||||
}
|
||||
catch(\CoreCannotSaveObjectException $e)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public static $aClasses = array(
|
||||
'FunctionalCI' => array('class' => 'FunctionalCI', 'attcode' => 'name'),
|
||||
|
||||
@@ -9,13 +9,35 @@ use Combodo\iTop\Test\UnitTest\ItopTestCase;
|
||||
|
||||
class iTopConfigParserTest extends ItopTestCase
|
||||
{
|
||||
private $conf_exists;
|
||||
private $tmpSavePath;
|
||||
private $sConfigPath;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
require_once APPROOT.'/core/iTopConfigParser.php';
|
||||
|
||||
clearstatcache();
|
||||
$this->sConfigPath = utils::GetConfigFilePath();
|
||||
$this->tmpSavePath = tempnam( '/tmp/', 'config-itop');
|
||||
|
||||
$this->conf_exists = is_file($this->sConfigPath);
|
||||
if ($this->conf_exists)
|
||||
{
|
||||
copy($this->sConfigPath, $this->tmpSavePath);
|
||||
}
|
||||
clearstatcache();
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
parent::tearDown(); // TODO: Change the autogenerated stub
|
||||
if ($this->conf_exists)
|
||||
{
|
||||
rename($this->tmpSavePath, $this->sConfigPath);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider ParserProvider
|
||||
@@ -185,30 +207,13 @@ CONF;
|
||||
public function testConfigWriteToFile_FromScratchInstallation()
|
||||
{
|
||||
$sConfigPath = utils::GetConfigFilePath();
|
||||
$tmpSavePath = tempnam( '/tmp/', 'config-itop');
|
||||
|
||||
$conf_exists = is_file($sConfigPath);
|
||||
if ($conf_exists)
|
||||
{
|
||||
rename($sConfigPath, $tmpSavePath);
|
||||
}
|
||||
|
||||
$oConfig = new Config($sConfigPath, false);
|
||||
try{
|
||||
clearstatcache();
|
||||
$oConfig->WriteToFile();
|
||||
if ($conf_exists)
|
||||
{
|
||||
rename($tmpSavePath, $sConfigPath);
|
||||
}
|
||||
}catch(\Exception $e)
|
||||
{
|
||||
if ($conf_exists)
|
||||
{
|
||||
rename($tmpSavePath, $sConfigPath);
|
||||
}
|
||||
|
||||
$this->assertTrue(false, "failed writetofile with no initial file");
|
||||
}
|
||||
|
||||
$this->assertTrue(false, "failed writetofile with no initial file: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
100
test/integration/iTopModulesPhpVersionChecklistTest.php
Normal file
100
test/integration/iTopModulesPhpVersionChecklistTest.php
Normal file
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2020 Combodo SARL
|
||||
* This file is part of iTop.
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Test\UnitTest\Integration;
|
||||
|
||||
use Combodo\iTop\Test\UnitTest\ItopTestCase;
|
||||
use DOMDocument;
|
||||
use iTopDesignFormat;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @runTestsInSeparateProcesses
|
||||
* @preserveGlobalState disabled
|
||||
* @backupGlobals disabled
|
||||
*
|
||||
* @covers iTopDesignFormat
|
||||
*
|
||||
* @package Combodo\iTop\Test\UnitTest\Setup
|
||||
*/
|
||||
class iTopModulesPhpVersionIntegrationTest extends ItopTestCase
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* Verify if the datamodel.*.xml files refer to the current itop version
|
||||
* This is an integration test
|
||||
*
|
||||
* @group skipPostBuild
|
||||
*
|
||||
* @dataProvider iTopModulesPhpVersionProvider
|
||||
*/
|
||||
public function testiTopModulesPhpVersion($sExpectedVersion, $sPhpFile)
|
||||
{
|
||||
|
||||
$sModulePath = realpath($sPhpFile);
|
||||
$sModuleFileName = basename($sModulePath);
|
||||
$sModuleName = preg_replace('/[^.]+\.([^.]+)\.php/', '$1', $sModuleFileName);
|
||||
|
||||
$sFileContent = file_get_contents($sPhpFile);
|
||||
|
||||
preg_match(
|
||||
"#'$sModuleName/([^']+)'#",
|
||||
$sFileContent,
|
||||
$matches
|
||||
);
|
||||
|
||||
$this->assertSame($sExpectedVersion, $matches[1], "$sPhpFile file refer does not refer to current itop version ($matches[1] instead of expected $sExpectedVersion)");
|
||||
}
|
||||
|
||||
public function iTopModulesPhpVersionProvider()
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
require_once APPROOT.'core/config.class.inc.php';
|
||||
require_once APPROOT.'application/utils.inc.php';
|
||||
|
||||
if (is_dir(APPROOT.'datamodels/2.x'))
|
||||
{
|
||||
$DatamodelsPath = APPROOT.'datamodels/2.x';
|
||||
}
|
||||
elseif (is_dir(APPROOT.'datamodels/1.x'))
|
||||
{
|
||||
$DatamodelsPath = APPROOT.'datamodels/1.x';
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new \Exception('Cannot local the datamodels directory');
|
||||
}
|
||||
|
||||
$sPath = $DatamodelsPath.'/*/module.*.php';
|
||||
$aPhpFiles = glob($sPath);
|
||||
|
||||
$sExpectedVersion = \utils::GetItopPatchVersion();
|
||||
|
||||
$aTestCases = array();
|
||||
foreach ($aPhpFiles as $sPhpFile)
|
||||
{
|
||||
$aTestCases[$sPhpFile] = array(
|
||||
'sExpectedVersion' => $sExpectedVersion,
|
||||
'sPhpFile' => $sPhpFile,
|
||||
);
|
||||
}
|
||||
|
||||
return $aTestCases;
|
||||
}
|
||||
|
||||
}
|
||||
84
test/integration/iTopModulesXmlVersionChecklistTest.php
Normal file
84
test/integration/iTopModulesXmlVersionChecklistTest.php
Normal file
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2020 Combodo SARL
|
||||
* This file is part of iTop.
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Test\UnitTest\Integration;
|
||||
|
||||
use Combodo\iTop\Test\UnitTest\ItopTestCase;
|
||||
use DOMDocument;
|
||||
use iTopDesignFormat;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @runTestsInSeparateProcesses
|
||||
* @preserveGlobalState disabled
|
||||
* @backupGlobals disabled
|
||||
*
|
||||
* @covers iTopDesignFormat
|
||||
*
|
||||
* @package Combodo\iTop\Test\UnitTest\Setup
|
||||
*/
|
||||
class iTopModulesXmlVersionIntegrationTest extends ItopTestCase
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* Verify if the datamodel.*.xml files refer to the current itop version
|
||||
* This is an integration test
|
||||
*
|
||||
* @group skipPostBuild
|
||||
*
|
||||
* @dataProvider DatamodelItopXmlVersionProvider
|
||||
*/
|
||||
public function testDatamodelItopXmlVersion($sExpectedXmlVersion, $sXmlFile)
|
||||
{
|
||||
$sFileContent = file_get_contents($sXmlFile);
|
||||
|
||||
preg_match(
|
||||
'/<itop_design .* version="([^"]+)">/',
|
||||
$sFileContent,
|
||||
$matches
|
||||
);
|
||||
|
||||
$this->assertSame($sExpectedXmlVersion, $matches[1], "$sXmlFile file refer does not refer to current itop version ($matches[1] instead of expected $sExpectedXmlVersion)");
|
||||
}
|
||||
|
||||
public function DatamodelItopXmlVersionProvider()
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
require_once APPROOT.'core/config.class.inc.php';
|
||||
require_once APPROOT.'application/utils.inc.php';
|
||||
|
||||
$sPath = APPROOT.'datamodels/2.x/*/datamodel.*.xml';
|
||||
$aXmlFiles = glob($sPath);
|
||||
|
||||
$sItopVersionShort = \utils::GetItopPatchVersion();
|
||||
$aItopVersion = explode('.', $sItopVersionShort);
|
||||
$sExpectedXmlVersion = ($aItopVersion[0] - 1).'.'.($aItopVersion[1]); // eg: 2.7.0-dev become 1.7
|
||||
|
||||
$aTestCases = array();
|
||||
foreach ($aXmlFiles as $sXmlFile)
|
||||
{
|
||||
$aTestCases[$sXmlFile] = array(
|
||||
'sExpectedXmlVersion' => $sExpectedXmlVersion,
|
||||
'sXmlFile' => $sXmlFile,
|
||||
);
|
||||
}
|
||||
|
||||
return $aTestCases;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -59,6 +59,9 @@
|
||||
<testsuite name="Status">
|
||||
<directory>status</directory>
|
||||
</testsuite>
|
||||
<testsuite name="Integration">
|
||||
<directory>integration</directory>
|
||||
</testsuite>
|
||||
<testsuite name="CoreExtensions">
|
||||
<directory>coreExtensions</directory>
|
||||
</testsuite>
|
||||
|
||||
58
test/releaseChecklist.xml.dist
Normal file
58
test/releaseChecklist.xml.dist
Normal file
@@ -0,0 +1,58 @@
|
||||
<!-- Copyright (c) 2010-2017 Combodo SARL -->
|
||||
<!-- -->
|
||||
<!-- This file is part of iTop. -->
|
||||
<!-- -->
|
||||
<!-- iTop is free software; you can redistribute it and/or modify -->
|
||||
<!-- it under the terms of the GNU Affero General Public License as published by -->
|
||||
<!-- the Free Software Foundation, either version 3 of the License, or -->
|
||||
<!-- (at your option) any later version. -->
|
||||
<!-- -->
|
||||
<!-- iTop is distributed in the hope that it will be useful, -->
|
||||
<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->
|
||||
<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->
|
||||
<!-- GNU Affero General Public License for more details. -->
|
||||
<!-- -->
|
||||
<!-- You should have received a copy of the GNU Affero General Public License -->
|
||||
<!-- along with iTop. If not, see <http://www.gnu.org/licenses/> -->
|
||||
<!-- -->
|
||||
|
||||
<phpunit bootstrap="unittestautoload.php"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/6.3/phpunit.xsd"
|
||||
backupGlobals="false"
|
||||
backupStaticAttributes="false"
|
||||
cacheTokens="false"
|
||||
colors="true"
|
||||
convertErrorsToExceptions="true"
|
||||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true"
|
||||
forceCoversAnnotation="false"
|
||||
mapTestClassNameToCoveredClassName="false"
|
||||
printerClass="\PHPUnit\TextUI\ResultPrinter"
|
||||
processIsolation="true"
|
||||
stopOnError="false"
|
||||
stopOnFailure="false"
|
||||
stopOnIncomplete="false"
|
||||
stopOnSkipped="false"
|
||||
stopOnRisky="false"
|
||||
timeoutForSmallTests="1"
|
||||
timeoutForMediumTests="10"
|
||||
timeoutForLargeTests="60"
|
||||
verbose="false">
|
||||
|
||||
<testsuites>
|
||||
<testsuite name="ReleaseChecklist">
|
||||
<directory>releaseChecklist</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
<!-- Code coverage white list -->
|
||||
<filter>
|
||||
<whitelist>
|
||||
<file>../core/apc-emulation.php</file>
|
||||
<file>../core/ormlinkset.class.inc.php</file>
|
||||
<file>../datamodels/2.x/itop-tickets/main.itop-tickets.php</file>
|
||||
</whitelist>
|
||||
</filter>
|
||||
|
||||
</phpunit>
|
||||
59
test/releaseChecklist/SetupCssIntegrityChecklistTest.php
Normal file
59
test/releaseChecklist/SetupCssIntegrityChecklistTest.php
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2010-2020 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with iTop. If not, see <http: *www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Test\UnitTest\ReleaseChecklist;
|
||||
|
||||
use Combodo\iTop\Test\UnitTest\ItopTestCase;
|
||||
use DOMDocument;
|
||||
use iTopDesignFormat;
|
||||
|
||||
|
||||
/**
|
||||
* Class iTopDesignFormatChecklistTest
|
||||
*
|
||||
* @runTestsInSeparateProcesses
|
||||
* @preserveGlobalState disabled
|
||||
* @backupGlobals disabled
|
||||
*
|
||||
* @covers iTopDesignFormat
|
||||
*
|
||||
* @package Combodo\iTop\Test\UnitTest\Setup
|
||||
*/
|
||||
class SetupCssIntegrityChecklistTest extends ItopTestCase
|
||||
{
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function testSetupCssIntegrity()
|
||||
{
|
||||
$sSetupCssPath = APPROOT.'css/setup.css';
|
||||
$sSetupCssContent = file_get_contents($sSetupCssPath);
|
||||
$this->assertContains('/* integrityCheck: begin (do not remove/edit) */', $sSetupCssContent);
|
||||
$this->assertContains('/* integrityCheck: end (do not remove/edit) */', $sSetupCssContent);
|
||||
$this->assertGreaterThan(4000, strlen($sSetupCssContent), "Test if the resulting file $sSetupCssPath is long enough, the value is totally arbitrary (at the time of the writing the file is 5660o long");
|
||||
}
|
||||
|
||||
}
|
||||
101
test/releaseChecklist/iTopDesignFormatChecklistTest.php
Normal file
101
test/releaseChecklist/iTopDesignFormatChecklistTest.php
Normal file
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
namespace Combodo\iTop\Test\UnitTest\ReleaseChecklist;
|
||||
|
||||
use Combodo\iTop\Test\UnitTest\ItopTestCase;
|
||||
use iTopDesignFormat;
|
||||
|
||||
|
||||
/**
|
||||
* Class iTopDesignFormatChecklistTest
|
||||
* Ticket 3053 - Check XML conversion methods
|
||||
* @runTestsInSeparateProcesses
|
||||
* @preserveGlobalState disabled
|
||||
* @backupGlobals disabled
|
||||
*
|
||||
* @covers iTopDesignFormat
|
||||
*
|
||||
* @package Combodo\iTop\Test\UnitTest\Setup
|
||||
*/
|
||||
class TestForITopDesignFormatClass extends ItopTestCase
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
require_once APPROOT.'setup/modelfactory.class.inc.php';
|
||||
require_once APPROOT.'setup/itopdesignformat.class.inc.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* release checklist step: make sure we have datamodel conversion functions for new iTop version
|
||||
*/
|
||||
public function testCurrentVersion_DataModelConversionFunctions()
|
||||
{
|
||||
$aDatamodelCurrentVersions = array();
|
||||
$aDataModelFiles = $this->GetDataModelFiles(APPROOT.'/datamodels');
|
||||
|
||||
//retrieve current XML version in datamoldels files
|
||||
foreach ($aDataModelFiles as $sDataModelFile)
|
||||
{
|
||||
if (preg_match('/itop_design .* version="([\d\.]*)"/', file_get_contents($sDataModelFile), $aMatches))
|
||||
{
|
||||
$sVersion = $aMatches[1];
|
||||
if (!array_key_exists($sVersion, $aDatamodelCurrentVersions))
|
||||
{
|
||||
$aDatamodelCurrentVersions[$sVersion] = $sVersion;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//make sure there is only one found
|
||||
$this->assertTrue(is_array($aDatamodelCurrentVersions));
|
||||
$this->assertEquals(1, count($aDatamodelCurrentVersions), "Found too much XML versions: " . json_encode($aDatamodelCurrentVersions));
|
||||
|
||||
//check we have migration function from new version to previous one
|
||||
$sCurrentVersion = array_values($aDatamodelCurrentVersions)[0];
|
||||
$this->assertTrue(array_key_exists($sCurrentVersion, iTopDesignFormat::$aVersions), "Release checklist: missing $sCurrentVersion config in iTopDesignFormat ");
|
||||
$aCurrentVersionInfo = iTopDesignFormat::$aVersions[$sCurrentVersion];
|
||||
$this->assertTrue(is_array($aCurrentVersionInfo), "Release checklist: wrong $sCurrentVersion config in iTopDesignFormat ");
|
||||
$this->assertTrue(array_key_exists('previous', $aCurrentVersionInfo), "Release checklist: missing previous for $sCurrentVersion config in iTopDesignFormat ");
|
||||
$this->TestDefinedFunction($aCurrentVersionInfo, 'go_to_previous', $sCurrentVersion);
|
||||
|
||||
//check we have migration function from N-1 version to new one
|
||||
$sPreviousVersion = $aCurrentVersionInfo['previous'];
|
||||
$this->assertTrue(array_key_exists($sPreviousVersion, iTopDesignFormat::$aVersions), "Release checklist: missing $sPreviousVersion config in iTopDesignFormat ");
|
||||
$aPreviousVersionInfo = iTopDesignFormat::$aVersions[$sPreviousVersion];
|
||||
$this->assertTrue(is_array($aPreviousVersionInfo), "Release checklist: wrong $sPreviousVersion config in iTopDesignFormat ");
|
||||
$this->assertTrue(array_key_exists('previous', $aPreviousVersionInfo), "Release checklist: missing previous for $sPreviousVersion config in iTopDesignFormat ");
|
||||
$this->TestDefinedFunction($aPreviousVersionInfo, 'go_to_previous', $sPreviousVersion);
|
||||
$this->TestDefinedFunction($aPreviousVersionInfo, 'go_to_next', $sPreviousVersion);
|
||||
}
|
||||
|
||||
private function TestDefinedFunction($aCurrentVersionInfo, $sFunctionKey, $sVersion)
|
||||
{
|
||||
$sInfo = json_encode($aCurrentVersionInfo, true);
|
||||
$this->assertTrue(array_key_exists($sFunctionKey, $aCurrentVersionInfo), "Release checklist: missing $sFunctionKey in $sVersion config in iTopDesignFormat: " . $sInfo);
|
||||
echo $aCurrentVersionInfo[$sFunctionKey].'\n';
|
||||
$oReflectionClass = new \ReflectionClass(iTopDesignFormat::class);
|
||||
$this->assertTrue($oReflectionClass->hasMethod($aCurrentVersionInfo[$sFunctionKey]), "Release checklist: wrong go_to_previous function '".$aCurrentVersionInfo[$sFunctionKey]."'' for $sVersion config in iTopDesignFormat " . $sInfo);
|
||||
}
|
||||
|
||||
public function GetDataModelFiles($sFolder)
|
||||
{
|
||||
$aDataModelFiles = array();
|
||||
if (is_dir($sFolder))
|
||||
{
|
||||
foreach (glob($sFolder."/*") as $sPath)
|
||||
{
|
||||
if (is_dir($sPath))
|
||||
{
|
||||
$aDataModelFiles = array_merge($aDataModelFiles, $this->GetDataModelFiles($sPath));
|
||||
}
|
||||
else if (preg_match("/datamodel\..*\.xml/", basename($sPath)))
|
||||
{
|
||||
$aDataModelFiles[] = $sPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $aDataModelFiles;
|
||||
}
|
||||
}
|
||||
142
test/releaseChecklist/iTopModuleXmlInstallationChecklistTest.php
Normal file
142
test/releaseChecklist/iTopModuleXmlInstallationChecklistTest.php
Normal file
@@ -0,0 +1,142 @@
|
||||
<?php
|
||||
|
||||
namespace Combodo\iTop\Test\UnitTest\ReleaseChecklist;
|
||||
|
||||
use Combodo\iTop\Test\UnitTest\ItopTestCase;
|
||||
use DOMDocument;
|
||||
use iTopDesignFormat;
|
||||
|
||||
|
||||
/**
|
||||
* Class iTopDesignFormatChecklistTest
|
||||
* Ticket 3061 - Automatically check the installation.xml consistency
|
||||
* @runTestsInSeparateProcesses
|
||||
* @preserveGlobalState disabled
|
||||
* @backupGlobals disabled
|
||||
*
|
||||
* @covers iTopDesignFormat
|
||||
*
|
||||
* @package Combodo\iTop\Test\UnitTest\Setup
|
||||
*/
|
||||
class iTopModuleXmlInstallationChecklistTest extends ItopTestCase
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* make sure installation.xml is provided and respects XML format
|
||||
*/
|
||||
public function testInstallationXmlFormat()
|
||||
{
|
||||
$sInstallationXmlPath = APPROOT . 'datamodels/2.x/installation.xml';
|
||||
$this->assertTrue(is_file($sInstallationXmlPath), "$sInstallationXmlPath does not exist");
|
||||
|
||||
$doc = new \DOMDocument();
|
||||
try{
|
||||
$doc->loadxml(file_get_contents($sInstallationXmlPath));
|
||||
}
|
||||
catch(\Exception $e)
|
||||
{
|
||||
$this->assertFalse(true, "$sInstallationXmlPath is not a valid XML content: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* make sure installation.xml includes all packaged modules
|
||||
*/
|
||||
public function testAllModuleAreIncludedInInstallationXml()
|
||||
{
|
||||
$sInstallationXmlPath = APPROOT.'datamodels/2.x/installation.xml';
|
||||
if (!is_file($sInstallationXmlPath))
|
||||
{
|
||||
$sInstallationXmlPath = APPROOT.'datamodels/1.x/installation.xml';
|
||||
}
|
||||
$this->assertTrue(is_file($sInstallationXmlPath), "$sInstallationXmlPath does not exist");
|
||||
|
||||
$sInstallationXmlContent = file_get_contents($sInstallationXmlPath);
|
||||
preg_match_all("|<module>(.*)</module>|", $sInstallationXmlContent, $aMatches);
|
||||
$aDeclaredModules = [] ;
|
||||
if (!empty($aMatches))
|
||||
{
|
||||
foreach ($aMatches[1] as $sModule)
|
||||
{
|
||||
if (!array_key_exists($sModule, $aDeclaredModules))
|
||||
{
|
||||
$aDeclaredModules[$sModule] = $sModule;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->assertArraySubset($this->GetFilteredModulesFromDatamodels(APPROOT.'/datamodels'), $aDeclaredModules, false, "$sInstallationXmlPath does not refer to all provided modules. Refered modules:\n " . var_export($aDeclaredModules, true));
|
||||
|
||||
$aModulesFromDatamodels = $this->GetAllModules(APPROOT.'/datamodels');
|
||||
$this->assertArraySubset($aDeclaredModules, $aModulesFromDatamodels, false, "Not all modules are contained in $sInstallationXmlPath. Refered modules:\n " . var_export($aModulesFromDatamodels, true));
|
||||
}
|
||||
|
||||
public function GetFilteredModulesFromDatamodels($sFolder)
|
||||
{
|
||||
$aExcludedModules = ['authent-external', 'authent-ldap'];
|
||||
$aModules = array();
|
||||
if (is_dir($sFolder))
|
||||
{
|
||||
foreach (glob($sFolder."/*") as $sPath)
|
||||
{
|
||||
if (is_dir($sPath))
|
||||
{
|
||||
$aModules = array_merge($aModules, $this->GetFilteredModulesFromDatamodels($sPath));
|
||||
}
|
||||
else if (preg_match("/module\..*\.php/", basename($sPath)))
|
||||
{
|
||||
$sModulePhpContent = file_get_contents($sPath);
|
||||
if (strpos($sModulePhpContent, "SetupWebPage::AddModule")!==false
|
||||
&& strpos($sModulePhpContent, "'mandatory' => true")===false)
|
||||
{
|
||||
//filter modules autoselected due to below condition
|
||||
if (strpos($sModulePhpContent, "'mandatory' => false")!==false
|
||||
&& strpos($sModulePhpContent, "'visible' => false")!==false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$sModule = basename(dirname($sPath));
|
||||
if (in_array($sModule, $aExcludedModules))// || $sModule === 'authent-ldap')
|
||||
{
|
||||
//hardcode this condition to make sure test is OK (CI context) + added a ticket to work/investigate why it is failed for these 2 cases (itop dev context)
|
||||
continue;
|
||||
}
|
||||
|
||||
$aModules[$sModule] = $sModule;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $aModules;
|
||||
}
|
||||
|
||||
public function GetAllModules($sFolder)
|
||||
{
|
||||
$aModules = array();
|
||||
if (is_dir($sFolder))
|
||||
{
|
||||
foreach (glob($sFolder."/*") as $sPath)
|
||||
{
|
||||
if (is_dir($sPath))
|
||||
{
|
||||
$aModules = array_merge($aModules, $this->GetAllModules($sPath));
|
||||
}
|
||||
else if (preg_match("/module\..*\.php/", basename($sPath)))
|
||||
{
|
||||
$sModulePhpContent = file_get_contents($sPath);
|
||||
if (strpos($sModulePhpContent, "SetupWebPage::AddModule")!==false)
|
||||
{
|
||||
$sModule = basename(dirname($sPath));
|
||||
$aModules[$sModule] = $sModule;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $aModules;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<installation>
|
||||
<!-- On manual installs, this file is generated in setup/install-*.xml -->
|
||||
<mode>upgrade</mode>
|
||||
<mode>install</mode>
|
||||
<preinstall>
|
||||
<copies type="array"/>
|
||||
</preinstall>
|
||||
@@ -20,7 +20,7 @@
|
||||
<db_tls_ca></db_tls_ca>
|
||||
<prefix></prefix>
|
||||
</database>
|
||||
<url>http://127.0.0.1/itop/svn/trunk/</url>
|
||||
<url>http://localhost/iTop/</url>
|
||||
<graphviz_path>/usr/bin/dot</graphviz_path>
|
||||
<admin_account>
|
||||
<user>admin</user>
|
||||
79
test/setup_params/setup.xml
Normal file
79
test/setup_params/setup.xml
Normal file
@@ -0,0 +1,79 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<installation>
|
||||
<mode>install</mode>
|
||||
<preinstall>
|
||||
<copies type="array"/>
|
||||
<backup>
|
||||
<destination>/var/www/html/iTop/data/backups/manual/setup-2020-07-15_15_52</destination>
|
||||
<configuration_file>/var/www/html/iTop//conf/production/config-itop.php</configuration_file>
|
||||
</backup>
|
||||
</preinstall>
|
||||
<source_dir>datamodels/2.x/</source_dir>
|
||||
<datamodel_version>2.7.1</datamodel_version>
|
||||
<previous_configuration_file></previous_configuration_file>
|
||||
<extensions_dir>extensions</extensions_dir>
|
||||
<target_env>production</target_env>
|
||||
<workspace_dir></workspace_dir>
|
||||
<database>
|
||||
<server>localhost</server>
|
||||
<user>iTop</user>
|
||||
<pwd>**removed**</pwd>
|
||||
<name>toto</name>
|
||||
<db_tls_enabled></db_tls_enabled>
|
||||
<db_tls_ca></db_tls_ca>
|
||||
<prefix></prefix>
|
||||
</database>
|
||||
<url>http://localhost/iTop/</url>
|
||||
<graphviz_path>/usr/bin/dot</graphviz_path>
|
||||
<admin_account>
|
||||
<user>admin</user>
|
||||
<pwd>**removed**</pwd>
|
||||
<language>EN US</language>
|
||||
</admin_account>
|
||||
<language>EN US</language>
|
||||
<selected_modules type="array">
|
||||
<item>authent-cas</item>
|
||||
<item>authent-external</item>
|
||||
<item>authent-ldap</item>
|
||||
<item>authent-local</item>
|
||||
<item>itop-backup</item>
|
||||
<item>itop-config</item>
|
||||
<item>itop-files-information</item>
|
||||
<item>itop-portal-base</item>
|
||||
<item>itop-profiles-itil</item>
|
||||
<item>itop-sla-computation</item>
|
||||
<item>itop-tickets</item>
|
||||
<item>itop-welcome-itil</item>
|
||||
<item>itop-config-mgmt</item>
|
||||
<item>itop-attachments</item>
|
||||
<item>combodo-db-tools</item>
|
||||
<item>itop-core-update</item>
|
||||
<item>itop-hub-connector</item>
|
||||
<item>itop-datacenter-mgmt</item>
|
||||
<item>itop-endusers-devices</item>
|
||||
<item>itop-storage-mgmt</item>
|
||||
<item>itop-virtualization-mgmt</item>
|
||||
<item>itop-bridge-virtualization-storage</item>
|
||||
<item>itop-service-mgmt</item>
|
||||
<item>itop-request-mgmt</item>
|
||||
<item>itop-portal</item>
|
||||
<item>itop-change-mgmt</item>
|
||||
<item>itop-knownerror-mgmt</item>
|
||||
</selected_modules>
|
||||
<selected_extensions type="array">
|
||||
<item>itop-config-mgmt-core</item>
|
||||
<item>itop-config-mgmt-datacenter</item>
|
||||
<item>itop-config-mgmt-end-user</item>
|
||||
<item>itop-config-mgmt-storage</item>
|
||||
<item>itop-config-mgmt-virtualization</item>
|
||||
<item>itop-service-mgmt-enterprise</item>
|
||||
<item>itop-ticket-mgmt-simple-ticket</item>
|
||||
<item>itop-ticket-mgmt-simple-ticket-enhanced-portal</item>
|
||||
<item>itop-change-mgmt-simple</item>
|
||||
<item>itop-kown-error-mgmt</item>
|
||||
</selected_extensions>
|
||||
<sample_data>1</sample_data>
|
||||
<old_addon></old_addon>
|
||||
<options type="array"/>
|
||||
<mysql_bindir></mysql_bindir>
|
||||
</installation>
|
||||
@@ -20,47 +20,47 @@ class StatusTest extends ItopTestCase {
|
||||
*
|
||||
*/
|
||||
public function testStatusWrongUrl() {
|
||||
$sPath = APPROOT . 'status_wrong.php';
|
||||
$sPath = __DIR__ . '/status_wrong.php';
|
||||
|
||||
exec("php $sPath", $aOutput, $iRet);
|
||||
$this->assertNotEquals(0, $iRet, "Problem executing status page: $sPath, $iRet, aOutput:\n" . var_export($aOutput, true));
|
||||
|
||||
$this->assertNotEquals(0, $iRet, "Problem executing status page: $sPath, $iRet");
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function testStatusGood() {
|
||||
$sPath = APPROOT . 'status.php';
|
||||
$sPath = __DIR__ . '/status.php';
|
||||
|
||||
exec("php $sPath", $aOutput, $iRet);
|
||||
|
||||
$this->assertEquals(0, $iRet, "Problem executing status page: $sPath, $iRet");
|
||||
$this->assertEquals(0, $iRet, "Problem executing status page: $sPath, $iRet, aOutput:\n" . var_export($aOutput, true));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function testStatusGoodWithJson() {
|
||||
$sPath = APPROOT . 'status.php';
|
||||
$sPath = __DIR__ . '/status.php';
|
||||
|
||||
exec("php $sPath", $aOutput, $iRet);
|
||||
$sAdditionnalInfo = "aOutput:\n" . var_export($aOutput, true);
|
||||
|
||||
//Check response
|
||||
$this->assertNotEmpty($aOutput[0], 'Empty response');
|
||||
$this->assertJson($aOutput[0], 'Not a JSON');
|
||||
$this->assertNotEmpty($aOutput[0], 'Empty response. ' . $sAdditionnalInfo);
|
||||
$this->assertJson($aOutput[0], 'Not a JSON. ' . $sAdditionnalInfo);
|
||||
|
||||
$aResponseDecoded = json_decode($aOutput[0], true);
|
||||
|
||||
//Check status
|
||||
$this->assertArrayHasKey('status', $aResponseDecoded, 'JSON does not have a status\' field');
|
||||
$this->assertEquals('RUNNING', $aResponseDecoded['status'], 'Status is not \'RUNNING\'');
|
||||
$this->assertArrayHasKey('status', $aResponseDecoded, 'JSON does not have a status\' field. ' . $sAdditionnalInfo);
|
||||
$this->assertEquals('RUNNING', $aResponseDecoded['status'], 'Status is not \'RUNNING\'. ' . $sAdditionnalInfo);
|
||||
//Check code
|
||||
$this->assertArrayHasKey('code', $aResponseDecoded, 'JSON does not have a code\' field');
|
||||
$this->assertEquals(0, $aResponseDecoded['code'], 'Code is not 0');
|
||||
$this->assertArrayHasKey('code', $aResponseDecoded, 'JSON does not have a code\' field. ' . $sAdditionnalInfo);
|
||||
$this->assertEquals(0, $aResponseDecoded['code'], 'Code is not 0. ' . $sAdditionnalInfo);
|
||||
//Check message
|
||||
$this->assertArrayHasKey('message', $aResponseDecoded, 'JSON does not have a message\' field');
|
||||
$this->assertEmpty($aResponseDecoded['message'], 'Message is not empty');
|
||||
$this->assertArrayHasKey('message', $aResponseDecoded, 'JSON does not have a message\' field. ' . $sAdditionnalInfo);
|
||||
$this->assertEmpty($aResponseDecoded['message'], 'Message is not empty. ' . $sAdditionnalInfo);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
<?php
|
||||
|
||||
//Include status functions
|
||||
require_once(__DIR__ . '/sources/application/status/status.inc.php');
|
||||
|
||||
require_once(__DIR__.'/../../sources/application/status/status.inc.php');
|
||||
//Do check Status
|
||||
try
|
||||
{
|
||||
Reference in New Issue
Block a user