moved unit test website code to branches/resources/ from trunk/utils/
[[Split portion of a mixed commit.]]
This commit is contained in:
parent
fffd8f131d
commit
4327e0e843
28 changed files with 2103 additions and 0 deletions
64
resources/tests.wesnoth.org/INSTALL
Normal file
64
resources/tests.wesnoth.org/INSTALL
Normal file
|
@ -0,0 +1,64 @@
|
|||
Contents:
|
||||
1. Requirements
|
||||
2. Setting up directories
|
||||
3. Configuring database
|
||||
4. Configuring apache
|
||||
5. Configuring website and autotester
|
||||
|
||||
1. Requirements
|
||||
|
||||
You will need libs required to build wesnoth client.
|
||||
|
||||
php >= 5.0 (both apache mod and cli)
|
||||
mysql >= 5.0
|
||||
scons
|
||||
smarty (http://www.smarty.net)
|
||||
adodb lite (http://adodblite.sourceforge.net/)
|
||||
|
||||
2. Setting up directories
|
||||
|
||||
Go to directory where you want to settup auto unit testing.
|
||||
|
||||
Do a svn checkout from wesnoth trunk.
|
||||
svn co svn://svn.gna.org/svn/wesnoth/trunk/ trunk
|
||||
|
||||
Export website from svn work directory
|
||||
svn export trunk/utils/tests tests
|
||||
|
||||
3. Configuring database
|
||||
|
||||
You need to create new database and user for auto unit tester.User will need right for SELECT, UPDATE, DELETE, ALTER TABLE, DROP TABLE in the created database.
|
||||
|
||||
4. Configuring apache
|
||||
|
||||
Make sure that php is loaded for apache
|
||||
Add to apache site configuration:
|
||||
Alias /wesnoth_test/ "/path/to/export/tests/htdocs/"
|
||||
<Directory "/path/to/export/tests/htdocs/">
|
||||
AllowOverride None
|
||||
Order allow,deny
|
||||
Allow from all
|
||||
</directory>
|
||||
|
||||
restart apache
|
||||
|
||||
5. Configuring website and autotester
|
||||
|
||||
Extract Smarty to tests/smarty_workdir/
|
||||
Extract Adodb to tests/adodb_lite/
|
||||
|
||||
Settup smarty cache directories so that apache can write to them:
|
||||
sudo chown www-data:www-data tests/smarty_workdir/tempalte_c tests/smarty_workdir/cache
|
||||
|
||||
copy tests/autotester/path_settup.sh.template to tests/autoster/path_settup.sh
|
||||
Edit variables in path_settup.sh to have correct path to directories.
|
||||
|
||||
copy tests/include/settup.php.template to tests/include/settup.php
|
||||
Edit database login information in settup.php.
|
||||
|
||||
execute tests/autotester/run_unit_test.sh
|
||||
|
||||
Check that website is visible.
|
||||
|
||||
Make
|
||||
add tests/autotester/run_unit_tests.sh to crontab so it is executed regulary.
|
|
@ -0,0 +1,19 @@
|
|||
# This file is loaded by all unit test scripts to settup correct worknig paths
|
||||
#/*
|
||||
# Copyright (C) 2008 by Pauli Nieminen <paniemin@cc.hut.fi>
|
||||
# Part of the Battle for Wesnoth Project http://www.wesnoth.org/
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License version 2
|
||||
# or at your option any later version.
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY.
|
||||
#
|
||||
# See the COPYING file for more details.
|
||||
#*/
|
||||
|
||||
|
||||
SVNDIR="/path/to/wesnoth/trunk"
|
||||
WEBDIR="/path/to/tests/htdocs"
|
||||
AUTOTESTDIR="/path/to/tests/autotester"
|
||||
|
54
resources/tests.wesnoth.org/autotester/run_unit_tests.php
Normal file
54
resources/tests.wesnoth.org/autotester/run_unit_tests.php
Normal file
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
/*
|
||||
Copyright (C) 2008 by Pauli Nieminen <paniemin@cc.hut.fi>
|
||||
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
or at your option any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
if ($argc != 2)
|
||||
{
|
||||
echo "Wrong number of parameters given";
|
||||
die;
|
||||
}
|
||||
$root_dir = $argv[1];
|
||||
|
||||
require_once $root_dir . '/../include/settup.php';
|
||||
|
||||
// used to show all queries to db when debuging;
|
||||
//$db->debug = true;
|
||||
// Upgrade the database format to the newest
|
||||
$creator = new DBCreator();
|
||||
$creator->checkDB();
|
||||
|
||||
// do svn up
|
||||
$svn = new SVNUpdater();
|
||||
|
||||
if ($svn->getRevision() === false)
|
||||
{
|
||||
trigger_error("SVN is down", E_USER_ERROR);
|
||||
}
|
||||
|
||||
$build = new Build($svn->getRevision());
|
||||
|
||||
if (!$build->Exists()
|
||||
|| $build->getStatus() != Build::S_GOOD)
|
||||
{
|
||||
// Only run tests if build doesn't exists
|
||||
if ($build->compile($svn->getRevision()))
|
||||
{
|
||||
$test_runner = new TestRunner();
|
||||
$test_runner->run($build);
|
||||
}
|
||||
$db->CompleteTrans();
|
||||
}
|
||||
|
||||
$config = new Config('last_autotest_run_time');
|
||||
$config->set(time());
|
||||
?>
|
23
resources/tests.wesnoth.org/autotester/run_unit_tests.sh
Executable file
23
resources/tests.wesnoth.org/autotester/run_unit_tests.sh
Executable file
|
@ -0,0 +1,23 @@
|
|||
#!/bin/bash
|
||||
#/*
|
||||
# Copyright (C) 2008 by Pauli Nieminen <paniemin@cc.hut.fi>
|
||||
# Part of the Battle for Wesnoth Project http://www.wesnoth.org/
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License version 2
|
||||
# or at your option any later version.
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY.
|
||||
#
|
||||
# See the COPYING file for more details.
|
||||
#*/
|
||||
|
||||
FULL_PATH=`dirname $(readlink -f $0)`
|
||||
source $FULL_PATH/path_settup.sh
|
||||
|
||||
export SSH_AUTH_SOCK=`find /tmp/keyring* -name ssh`
|
||||
export DISPLAY=:0.0
|
||||
|
||||
cd $SVNDIR
|
||||
nice php -f ${AUTOTESTDIR}/run_unit_tests.php $WEBDIR
|
||||
# > $FULL_PATH/err.log
|
31
resources/tests.wesnoth.org/htdocs/build_history.php
Normal file
31
resources/tests.wesnoth.org/htdocs/build_history.php
Normal file
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
/*
|
||||
Copyright (C) 2008 by Pauli Nieminen <paniemin@cc.hut.fi>
|
||||
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
or at your option any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
$root_dir = './';
|
||||
|
||||
require_once($root_dir . '../include/settup.php');
|
||||
|
||||
$header = new Header('build_history');
|
||||
|
||||
$footer = new Footer('build_history');
|
||||
|
||||
$header->show();
|
||||
|
||||
$user_params = new ParameterValidator($_GET);
|
||||
|
||||
$smarty->assign(Build::GetVisibleBuilds($user_params));
|
||||
|
||||
$smarty->display('build_history.tpl');
|
||||
|
||||
$footer->show();
|
||||
?>
|
35
resources/tests.wesnoth.org/htdocs/index.php
Normal file
35
resources/tests.wesnoth.org/htdocs/index.php
Normal file
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
/*
|
||||
Copyright (C) 2008 by Pauli Nieminen <paniemin@cc.hut.fi>
|
||||
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
or at your option any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
$root_dir = './';
|
||||
|
||||
require_once($root_dir . '../include/settup.php');
|
||||
|
||||
$header = new Header('index');
|
||||
|
||||
$footer = new Footer('index');
|
||||
|
||||
$header->show();
|
||||
|
||||
$build = new Build();
|
||||
$build->fetchLast();
|
||||
|
||||
$smarty->assign($build->getStatistics());
|
||||
|
||||
$smarty->display('index.tpl');
|
||||
|
||||
|
||||
$footer->show();
|
||||
|
||||
?>
|
195
resources/tests.wesnoth.org/htdocs/js/autohide.js
Normal file
195
resources/tests.wesnoth.org/htdocs/js/autohide.js
Normal file
|
@ -0,0 +1,195 @@
|
|||
/**
|
||||
* Use to make long text to have short description and then on mouse over
|
||||
* show whole text over the page
|
||||
**/
|
||||
|
||||
var autohide_next_id = 0;
|
||||
var autohide_store = new Array();
|
||||
|
||||
var onload_registered = false;
|
||||
|
||||
function addOnloadFunction(func)
|
||||
{
|
||||
var oldonload = window.onload;
|
||||
if (typeof window.onload != 'function') {
|
||||
window.onload = func;
|
||||
} else {
|
||||
window.onload = function() {
|
||||
if (oldonload) {
|
||||
oldonload();
|
||||
}
|
||||
func();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onload_autohide()
|
||||
{
|
||||
for (var hide in autohide_store)
|
||||
{
|
||||
autohide_store[hide].make_hide_text();
|
||||
}
|
||||
}
|
||||
|
||||
function Autohide(text, length, split_from_space, take_end)
|
||||
{
|
||||
this.id = autohide_store.length;
|
||||
this.text = text;
|
||||
this.length = length;
|
||||
this.split_from_space = split_from_space;
|
||||
this.take_end = take_end;
|
||||
document.write('<div id="autohide' + this.id + '"></div>');
|
||||
if (!onload_registered)
|
||||
{
|
||||
addOnloadFunction(onload_autohide);
|
||||
onload_registered = true;
|
||||
}
|
||||
}
|
||||
|
||||
Autohide.prototype.make_hide_text = function()
|
||||
{
|
||||
var short_text;
|
||||
var split_text;
|
||||
if (this.split_from_space)
|
||||
{
|
||||
split_text = this.text.split(' ');
|
||||
short_text = "";
|
||||
|
||||
var i = 0;
|
||||
|
||||
while(i < split_text.length && short_text.length + split_text[i].length < this.length)
|
||||
{
|
||||
if (i>0)
|
||||
short_text += ' ';
|
||||
short_text += split_text[i];
|
||||
++i;
|
||||
}
|
||||
short_text = document.createTextNode(short_text);
|
||||
} else {
|
||||
var start=0;
|
||||
if (this.take_end)
|
||||
{
|
||||
start = this.text.length - this.length;
|
||||
if (start < 0)
|
||||
start =0;
|
||||
}
|
||||
short_text = document.createTextNode(this.text.substr(start,this.length));
|
||||
}
|
||||
this.text = this.text.split("\n");
|
||||
split_text = new Array();
|
||||
for(var index in this.text)
|
||||
{
|
||||
if (this.text[index].length)
|
||||
{
|
||||
split_text.push(document.createTextNode(this.text[index]));
|
||||
split_text.push(document.createElement('BR'));
|
||||
}
|
||||
}
|
||||
if (split_text.length)
|
||||
split_text.pop();
|
||||
// Create short text element
|
||||
var new_elem = document.createElement('DIV');
|
||||
new_elem.id='autohide_' + this.id;
|
||||
new_elem.className="autohide";
|
||||
|
||||
// create full text element
|
||||
var elem_over = new_elem.cloneNode(false);
|
||||
elem_over.id='autohide_over_' + this.id;
|
||||
elem_over.onmouseout=autohide_mouseout;
|
||||
elem_over.style.visibility = 'hidden';
|
||||
for(var i in split_text)
|
||||
{
|
||||
elem_over.appendChild(split_text[i]);
|
||||
}
|
||||
var target = document.getElementById('autohide'+this.id);
|
||||
|
||||
// Fill short text element
|
||||
new_elem.appendChild(short_text);
|
||||
new_elem.onmouseover=autohide_mouseover;
|
||||
elem_over.className="autohide_over";
|
||||
|
||||
// add elements to document
|
||||
target.parentNode.replaceChild(new_elem, target);
|
||||
new_elem.parentNode.appendChild(elem_over);
|
||||
// Make over element apear in same place
|
||||
var max_iter = 3;
|
||||
do {
|
||||
var is_hitting_side = (elem_over.offsetLeft + elem_over.offsetWidth >= document.width)
|
||||
|| (elem_over.offsetTop + elem_over.offsetHeight > document.height);
|
||||
var y_pos = getYpos(new_elem);
|
||||
var x_pos = getXpos(new_elem);
|
||||
var y_pos2 = y_pos + new_elem.scrollHeight;
|
||||
var x_pos2 = x_pos + new_elem.scrollWidth;
|
||||
y_pos = (y_pos+y_pos2)/2;
|
||||
x_pos = (x_pos+x_pos2)/2;
|
||||
|
||||
y_pos = y_pos - elem_over.scrollHeight/2;
|
||||
x_pos = x_pos - elem_over.scrollWidth/2;
|
||||
|
||||
// console.log(this.id + ' x:' + x_pos + ' y:' + y_pos + ' ny:' + new_elem.scrollWidth + ' gy:' + getYpos(new_elem));
|
||||
|
||||
elem_over.style.top = y_pos + 'px';
|
||||
elem_over.style.left = x_pos + 'px';
|
||||
} while(is_hitting_side && --max_iter);
|
||||
}
|
||||
|
||||
function getYpos(element)
|
||||
{
|
||||
if (!element.offsetParent)
|
||||
return element.offsetTop;
|
||||
else
|
||||
return element.offsetTop + getYpos(element.offsetParent);
|
||||
}
|
||||
|
||||
function getXpos(element)
|
||||
{
|
||||
if (!element.offsetParent)
|
||||
return element.offsetLeft;
|
||||
else
|
||||
return element.offsetLeft + getXpos(element.offsetParent);
|
||||
}
|
||||
|
||||
function autohide_mouseover(e)
|
||||
{
|
||||
var new_elem;
|
||||
if(!e) e = window.event;
|
||||
if (e.target) new_elem = e.target;
|
||||
else if (e.srcElement) new_elem = e.srcElement;
|
||||
if (new_elem.nodeType == 3) // defeat Safari bug
|
||||
new_elem = new_elem.parentNode;
|
||||
|
||||
|
||||
var over_id = new String(new_elem.id).replace('hide','hide_over');
|
||||
var elem_over = document.getElementById(over_id);
|
||||
var y_pos = getYpos(new_elem);
|
||||
var x_pos = getXpos(new_elem);
|
||||
var y_pos2 = y_pos + new_elem.scrollHeight;
|
||||
var x_pos2 = x_pos + new_elem.scrollWidth;
|
||||
y_pos = (y_pos+y_pos2)/2;
|
||||
x_pos = (x_pos+x_pos2)/2;
|
||||
|
||||
y_pos = y_pos - elem_over.scrollHeight/2;
|
||||
x_pos = x_pos - elem_over.scrollWidth/2;
|
||||
|
||||
// console.log(this.id + ' x:' + x_pos + ' y:' + y_pos + ' ny:' + new_elem.scrollWidth + ' gy:' + getYpos(new_elem));
|
||||
|
||||
elem_over.style.top = y_pos + 'px';
|
||||
elem_over.style.left = x_pos + 'px';
|
||||
elem_over.style.visibility='visible';
|
||||
new_elem.style.visibility='hidden';
|
||||
}
|
||||
|
||||
function autohide_mouseout(e)
|
||||
{
|
||||
var elem_over;
|
||||
if(!e) e = window.event;
|
||||
if (e.target) elem_over = e.target;
|
||||
else if (e.srcElement) elem_over = e.srcElement;
|
||||
if (elem_over.nodeType == 3) // defeat Safari bug
|
||||
elem_over = elem_over.parentNode;
|
||||
|
||||
elem_over.style.visibility='hidden';
|
||||
var new_elem_id = new String(elem_over.id).replace('_over','');
|
||||
var new_elem = document.getElementById(new_elem_id);
|
||||
new_elem.style.visibility='visible';
|
||||
}
|
113
resources/tests.wesnoth.org/htdocs/styles/unit_test.css
Normal file
113
resources/tests.wesnoth.org/htdocs/styles/unit_test.css
Normal file
|
@ -0,0 +1,113 @@
|
|||
div.menu {
|
||||
position:absolute;
|
||||
margin-left: 3em;
|
||||
width: 7em;
|
||||
border: 1px solid #AAAAAA;
|
||||
}
|
||||
|
||||
.unit_test h3 {
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
table.build {
|
||||
margin: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.build td {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
td.time {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.build .passed {
|
||||
color: #00FF00;
|
||||
}
|
||||
|
||||
.build .failed, .aborted {
|
||||
color: #FF0000;
|
||||
}
|
||||
|
||||
div.autohide {
|
||||
border: 1px solid #225599;
|
||||
padding-left: 0.3em;
|
||||
padding-right: 0.3em;
|
||||
}
|
||||
|
||||
div.autohide_over {
|
||||
position: absolute;
|
||||
background:#FFFBF0 none repeat scroll 0 0;
|
||||
border: 1px solid #225599;
|
||||
padding: 0.5em;
|
||||
padding-left: 1.5em;
|
||||
padding-right: 1.5em;
|
||||
/* max-width: 60em;*/
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
table.test_error {
|
||||
margin-left:auto;
|
||||
margin-right:auto;
|
||||
}
|
||||
|
||||
.test_error .Error {
|
||||
color: #FF0000;
|
||||
}
|
||||
|
||||
.test_error .Warning {
|
||||
color: #FF4000;
|
||||
}
|
||||
|
||||
.test_error .Exception {
|
||||
color: #A00000;
|
||||
}
|
||||
|
||||
.test_error .Message {
|
||||
color: #00FF00;
|
||||
}
|
||||
|
||||
.test_error td {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
table.build_history {
|
||||
width: auto;
|
||||
max-width:60em;
|
||||
min-width:10em;
|
||||
margin: auto auto auto auto;
|
||||
}
|
||||
|
||||
div.paginate {
|
||||
color: #225599;
|
||||
font-weight: bold;
|
||||
text-align: right;
|
||||
margin-left: auto;
|
||||
margin-right: 0;
|
||||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
.paginate a {
|
||||
color: #225599;
|
||||
font-weight: bold;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.paginate a:hoover {
|
||||
text-decoration: underline;
|
||||
font-weight: bold;
|
||||
color: #225599;
|
||||
}
|
||||
|
||||
.paginate .active {
|
||||
color: #104060;
|
||||
}
|
||||
|
||||
.paginate a.hidden {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
/*.paginate span {
|
||||
color: #225599;
|
||||
}*/
|
341
resources/tests.wesnoth.org/include/Build.php
Normal file
341
resources/tests.wesnoth.org/include/Build.php
Normal file
|
@ -0,0 +1,341 @@
|
|||
<?php
|
||||
/*
|
||||
Copyright (C) 2008 by Pauli Nieminen <paniemin@cc.hut.fi>
|
||||
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
or at your option any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (C) 2008 by Pauli Nieminen <paniemin@cc.hut.fi>
|
||||
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
or at your option any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
|
||||
class Build {
|
||||
private $db;
|
||||
private $id;
|
||||
private $svn_version;
|
||||
private $time;
|
||||
private $status;
|
||||
private $error_msg;
|
||||
|
||||
private $binary_name;
|
||||
private $previous_id;
|
||||
private $result;
|
||||
private $errors;
|
||||
|
||||
const S_GOOD = 0;
|
||||
const S_ERROR = 1;
|
||||
|
||||
function __construct($revision = -1)
|
||||
{
|
||||
global $db;
|
||||
$this->db = $db;
|
||||
$this->binary_name = false;
|
||||
$this->previous_id = -1;
|
||||
$this->result = null;
|
||||
$this->errors = null;
|
||||
if ($revision >= 0)
|
||||
$this->fetch("WHERE svn_version=?", array($revision));
|
||||
}
|
||||
|
||||
private function fetch($where, $params = array())
|
||||
{
|
||||
$result = $this->db->Execute('SELECT * FROM builds ' . $where . ' LIMIT 1',$params);
|
||||
if ($result !== false && !$result->EOF())
|
||||
{
|
||||
$this->init($result->fields);
|
||||
} else {
|
||||
$this->reset();
|
||||
}
|
||||
}
|
||||
|
||||
private static function multiFetch($where, $params = array())
|
||||
{
|
||||
global $db;
|
||||
$res = array();
|
||||
$id_list = array();
|
||||
$result = $db->Execute('SELECT * FROM builds ' . $where ,$params);
|
||||
if ($result === false)
|
||||
return $res;
|
||||
while (!$result->EOF())
|
||||
{
|
||||
$build = new Build();
|
||||
$build->init($result->fields);
|
||||
$id_list[] = $build->getId();
|
||||
$res[] = $build;
|
||||
$result->moveNext();
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
public function fetchLast()
|
||||
{
|
||||
$this->fetch('ORDER BY id DESC');
|
||||
}
|
||||
|
||||
private static function fetchVisibleBuilds($page, $builds_per_page)
|
||||
{
|
||||
return self::multiFetch('ORDER BY id DESC LIMIT ?,?',
|
||||
array(($page-1)*$builds_per_page, $builds_per_page));
|
||||
}
|
||||
|
||||
private static function getNumberOfVisiblePages($builds_per_page)
|
||||
{
|
||||
global $db;
|
||||
$result = $db->Execute('SELECT COUNT(*) as number FROM builds');
|
||||
return ceil($result->fields['number']/$builds_per_page);
|
||||
}
|
||||
|
||||
public function init($values)
|
||||
{
|
||||
foreach($values as $key => $value)
|
||||
{
|
||||
$this->$key = $value;
|
||||
}
|
||||
$this->time = $this->db->UnixTimeStamp($this->time);
|
||||
$this->result = null;
|
||||
$this->errors = null;
|
||||
}
|
||||
|
||||
public function reset()
|
||||
{
|
||||
$this->init(array('id' => -1,
|
||||
'svn_version' => -1,
|
||||
'time' => $this->db->DBTimeStamp(0),
|
||||
'status' => -1,
|
||||
'error_msg' => ""));
|
||||
$this->previous_id = -1;
|
||||
}
|
||||
|
||||
public function exists()
|
||||
{
|
||||
return $this->id > -1;
|
||||
}
|
||||
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getStatus()
|
||||
{
|
||||
return $this->status;
|
||||
}
|
||||
|
||||
public function getPreviousId()
|
||||
{
|
||||
if ($this->previous_id == -1)
|
||||
{
|
||||
$result = $this->db->Execute('SELECT MAX(id) as previous_id
|
||||
FROM builds
|
||||
WHERE id<?
|
||||
AND status=?',
|
||||
array($this->id,
|
||||
self::S_GOOD));
|
||||
$this->previous_id = $result->fields['previous_id'];
|
||||
}
|
||||
return $this->previous_id;
|
||||
}
|
||||
public function getLastWorkingId()
|
||||
{
|
||||
if ($this->status == self::S_GOOD)
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
return $this->getPreviousId();
|
||||
}
|
||||
|
||||
public function compile($revision)
|
||||
{
|
||||
$compiler_log = shell_exec('scons test 2>&1');
|
||||
$m =array();
|
||||
$this->error_msg = '';
|
||||
$this->status = self::S_GOOD;
|
||||
if (strpos($compiler_log, "`test' is up to date.") !== false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// build/debug/editor2/
|
||||
$compiler_log = FilenameConverter::stripBuildDirs($compiler_log);
|
||||
if (preg_match_all('/^.*(error:|warning:|note:|undefined reference|ld returned \d exit status).*$/mi',$compiler_log, $m,PREG_SET_ORDER))
|
||||
{
|
||||
|
||||
foreach($m as $match)
|
||||
{
|
||||
$this->error_msg .= $match[0] . "\n";
|
||||
}
|
||||
if (strpos($this->error_msg,'error') !== false
|
||||
|| strpos($this->error_msg,'ld returned'))
|
||||
$this->status = self::S_ERROR;
|
||||
}
|
||||
|
||||
if(preg_match('/test to \.\/([a-zA-Z0-9_-]*)/',$compiler_log, $m))
|
||||
{
|
||||
$this->binary_name = $m[1];
|
||||
}
|
||||
|
||||
$this->time = time();
|
||||
$this->svn_revision = $revision;
|
||||
|
||||
$this->db->StartTrans();
|
||||
|
||||
$this->insert();
|
||||
return $this->status == self::S_GOOD;
|
||||
}
|
||||
|
||||
public function getTestName()
|
||||
{
|
||||
return $this->binary_name;
|
||||
}
|
||||
|
||||
private function insert()
|
||||
{
|
||||
$result = $this->db->Execute('INSERT INTO builds
|
||||
(svn_version, status, error_msg)
|
||||
VALUES (?, ?, ?)',
|
||||
array($this->svn_revision,
|
||||
$this->status,
|
||||
$this->error_msg));
|
||||
|
||||
$this->id = $this->db->Insert_ID();
|
||||
}
|
||||
|
||||
public function insertNull()
|
||||
{
|
||||
if ($result = $this->db->Execute('SELECT id FROM builds WHERE id=?', array(0)))
|
||||
{
|
||||
if ($result->EOF())
|
||||
{
|
||||
$result = $this->db->Execute('INSERT INTO builds
|
||||
(svn_version, status, error_msg)
|
||||
VALUES (?, ?, ?)',
|
||||
array(0,
|
||||
self::S_GOOD,
|
||||
''));
|
||||
$this->id = $this->db->Insert_ID();
|
||||
|
||||
$this->db->Execute('UPDATE builds SET id=? WHERE id=?', array(0, $this->id));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function checkResult()
|
||||
{
|
||||
if (is_null($this->result))
|
||||
{
|
||||
$this->result = new TestResult($this->getLastWorkingId());
|
||||
}
|
||||
}
|
||||
|
||||
private function getErrorStatistics()
|
||||
{
|
||||
$ret = array();
|
||||
foreach($this->errors as $err)
|
||||
{
|
||||
$ret[] = $err->getStatistics();
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public static function getVisibleBuilds(ParameterValidator $user_params)
|
||||
{
|
||||
$ret = array();
|
||||
$builds_per_page = 6; // TODO: get from config
|
||||
$ret['paginate']['number_of_pages'] = self::getNumberOfVisiblePages($builds_per_page);
|
||||
|
||||
$page = $user_params->getInt('page', 1);
|
||||
if ($page < 0)
|
||||
$page = 1;
|
||||
if ($page > $ret['paginate']['number_of_pages'])
|
||||
$page = $ret['paginate']['number_of_pages'];
|
||||
|
||||
$ret['paginate']['page'] = $page;
|
||||
|
||||
$ret['paginate']['link'] = 'build_history.php?page=';
|
||||
$visible = 5;
|
||||
$visible_minus = 0;
|
||||
$start = $page - floor(($visible-1)/2);
|
||||
if ($start <= 1)
|
||||
{
|
||||
$start = 1;
|
||||
$visible_minus = 1;
|
||||
}
|
||||
$last = $start + $visible + $visible_minus;
|
||||
if ($last >= $ret['paginate']['number_of_pages'] + 1)
|
||||
{
|
||||
$last = $ret['paginate']['number_of_pages'] + 1;
|
||||
$start = $last - $visible - 1;
|
||||
if ($start < 1)
|
||||
$start = 1;
|
||||
}
|
||||
$ret['paginate']['first_page'] = $start;
|
||||
$ret['paginate']['last_page'] = $last;
|
||||
$ret['paginate']['visible'] = $last - $start;
|
||||
|
||||
|
||||
$ret['builds'] = array();
|
||||
$builds = self::fetchVisibleBuilds($page, $builds_per_page);
|
||||
foreach($builds as $build)
|
||||
{
|
||||
$ret['builds'][] = $build->getBuildStats();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
private function getBuildStats()
|
||||
{
|
||||
$this->checkResult();
|
||||
|
||||
$build_result = '';
|
||||
if ($this->status == self::S_GOOD)
|
||||
{
|
||||
$build_result = "Build successed." //. " Kaak Test Test"
|
||||
;
|
||||
} else {
|
||||
$build_result = "Build failed:\n" . $this->error_msg;
|
||||
}
|
||||
$build_result = str_replace("\n"," \\n",$build_result);
|
||||
|
||||
|
||||
return array('result' => $build_result,
|
||||
'time' => $this->time,
|
||||
'style' => ($this->status == self::S_GOOD?"passed":"failed"),
|
||||
'id' => $this->id,
|
||||
'result_style' => $this->result->getResult(),
|
||||
'error_msg' => $this->error_msg,
|
||||
'svn_rev' => $this->svn_version,
|
||||
'result_passed' => $this->result->getAssertionsPassed(),
|
||||
'result_failed' => $this->result->getAssertionsFailed());
|
||||
}
|
||||
|
||||
public function getStatistics()
|
||||
{
|
||||
if (is_null($this->errors))
|
||||
$this->errors = TestError::getErrorsForBuild($this->getLastWorkingId());
|
||||
|
||||
return array('builds' => array($this->getBuildStats()),
|
||||
'errors' => $this->getErrorStatistics());
|
||||
}
|
||||
}
|
||||
?>
|
36
resources/tests.wesnoth.org/include/Config.php
Normal file
36
resources/tests.wesnoth.org/include/Config.php
Normal file
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
/*
|
||||
Copyright (C) 2008 by Pauli Nieminen <paniemin@cc.hut.fi>
|
||||
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
or at your option any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
|
||||
class Config {
|
||||
private $name;
|
||||
function __construct($name = null)
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
public function insertDefaults()
|
||||
{
|
||||
}
|
||||
|
||||
public function set()
|
||||
{
|
||||
}
|
||||
|
||||
public function get()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
373
resources/tests.wesnoth.org/include/DBCreator.php
Normal file
373
resources/tests.wesnoth.org/include/DBCreator.php
Normal file
|
@ -0,0 +1,373 @@
|
|||
<?php
|
||||
/*
|
||||
Copyright (C) 2008 by Pauli Nieminen <paniemin@cc.hut.fi>
|
||||
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
or at your option any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
|
||||
class DBForeignKey {
|
||||
private $name;
|
||||
private $field_name;
|
||||
private $reference;
|
||||
|
||||
function __construct($name, $field_name, $reference)
|
||||
{
|
||||
$this->field_name = $field_name;
|
||||
$this->name = $name;
|
||||
$this->reference = $reference;
|
||||
}
|
||||
public function getCreateSQL()
|
||||
{
|
||||
return "CONSTRAINT $this->name FOREIGN KEY ($this->field_name) REFERENCES $this->reference";
|
||||
}
|
||||
|
||||
public function match_and_alter($db, &$create_sql, $table_name)
|
||||
{
|
||||
$m = array();
|
||||
$needle = preg_replace("/[()]/","\\\\$0","/^.*CONSTRAINT `$this->name` FOREIGN KEY ($this->field_name) REFERENCES $this->reference.*$/im");
|
||||
if (!preg_match($needle,$create_sql))
|
||||
{
|
||||
// echo "$needle\n$create_sql\n";
|
||||
// echo "Creating foreign key $this->field_name in $table_name!\n";
|
||||
if (!$db->Execute("ALTER TABLE $table_name
|
||||
ADD CONSTRAINT $this->name
|
||||
FOREIGN KEY ($this->field_name)
|
||||
REFERENCES $this->reference"))
|
||||
{
|
||||
// echo "Failed to create foreign key!";
|
||||
}
|
||||
} else {
|
||||
$create_sql = preg_replace($needle,'',$create_sql);
|
||||
$create_sql = preg_replace("/^.*KEY (`$this->name`)? \\($this->field_name\\).*$/im",'',$create_sql);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class DBIndex {
|
||||
private $field_name;
|
||||
private $type;
|
||||
private $key_name;
|
||||
|
||||
function __construct($field_name, $type, $key_name = '')
|
||||
{
|
||||
$this->field_name = $field_name;
|
||||
$this->type = $type;
|
||||
if (empty($key_name))
|
||||
$key_name = $field_name;
|
||||
$this->key_name = $key_name;
|
||||
}
|
||||
public function getCreateSQL()
|
||||
{
|
||||
return "$this->type $this->key_name ($this->field_name)";
|
||||
}
|
||||
|
||||
public function match_and_alter($db, &$create_sql, $table_name)
|
||||
{
|
||||
$m = array();
|
||||
$needle = "/^.*$this->type (`$this->key_name`)? \\(`$this->field_name`\\).*$/im";
|
||||
if (!preg_match($needle,$create_sql))
|
||||
{
|
||||
// echo "$needle\n$create_sql\n";
|
||||
// echo "Creating index $this->field_name in $table_name!\n";
|
||||
if (!$db->Execute("ALTER TABLE $table_name
|
||||
ADD $this->type $this->key_name ($this->field_name)"))
|
||||
{
|
||||
// echo "Failed to create key!\n";
|
||||
}
|
||||
} else {
|
||||
$create_sql = preg_replace($needle,'',$create_sql);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class DBField {
|
||||
private $name;
|
||||
private $type;
|
||||
private $default;
|
||||
|
||||
function __construct($name, $type, $default = '')
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->type = $type;
|
||||
$this->default = $default;
|
||||
}
|
||||
|
||||
public function getCreateSQL()
|
||||
{
|
||||
$default = '';
|
||||
if (!empty($this->default))
|
||||
{
|
||||
$default = 'DEFAULT ' . $this->default;
|
||||
}
|
||||
return "$this->name $this->type $default";
|
||||
}
|
||||
|
||||
public function match_and_alter($db, &$create_sql, $table_name)
|
||||
{
|
||||
$m = array();
|
||||
|
||||
$default = '';
|
||||
if (!empty($this->default))
|
||||
{
|
||||
$default = ' DEFAULT ' . $this->default;
|
||||
}
|
||||
$needle = "/^\\s*`$this->name`(.*),?$/im";
|
||||
if (preg_match($needle,$create_sql, $m))
|
||||
{
|
||||
// Found the field checking for correct type
|
||||
$type = preg_replace(array("/[()]/","/^([a-zA-Z1-9_]*) /"),array("\\\\$0","$1(\\(\\d*\\))? "), $this->type);
|
||||
if (!preg_match("/$type$default/i",$m[1]))
|
||||
{
|
||||
// echo $m[1] . "\n" . $type . "\n";
|
||||
// echo "Updateing column $this->name in $table_name!\n";
|
||||
if (!$db->Execute("ALTER TABLE $table_name
|
||||
MODIFY COLUMN $this->name $this->type $default"))
|
||||
{
|
||||
// echo "Failed to create column!\n";
|
||||
}
|
||||
}
|
||||
$create_sql = preg_replace($needle,'',$create_sql);
|
||||
} else {
|
||||
// Add new field
|
||||
// echo "Creating column $this->name in $table_name!\n";
|
||||
|
||||
if (!$db->Execute("ALTER TABLE $table_name
|
||||
ADD COLUMN $this->name $this->type $default"))
|
||||
{
|
||||
// echo "Failed to modify column!\n";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class DBTable {
|
||||
private $fields;
|
||||
|
||||
private $name;
|
||||
private $engine;
|
||||
|
||||
function __construct($name, $engine = 'MYISAM')
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->engine = $engine;
|
||||
$this->fields = array();
|
||||
}
|
||||
|
||||
public function addChild($child)
|
||||
{
|
||||
$this->fields[] = $child;
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function check($db)
|
||||
{
|
||||
$result = $db->Execute("SHOW CREATE TABLE $this->name");
|
||||
|
||||
if ($result === false)
|
||||
{
|
||||
echo "Error reading create info for $this->name table\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
$create_sql = $result->fields['Create Table'];
|
||||
|
||||
foreach($this->fields as $id => $field)
|
||||
{
|
||||
$field->match_and_alter($db,$create_sql, $this->name);
|
||||
}
|
||||
$m = array();
|
||||
if (preg_match_all('/^\s*`(.*)` .*(int|varchar|text|blob|char|NULL|NOT NULL|timestamp|date).*$/m',$create_sql,$m,PREG_SET_ORDER))
|
||||
{
|
||||
foreach($m as $col)
|
||||
{
|
||||
try {
|
||||
$colname = $col[1];
|
||||
$db->Execute("ALTER TABLE $this->name
|
||||
DROP COLUMN $colname");
|
||||
} catch(exception $e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (preg_match_all('/^\s*(CONSTRAINT|KEY|PRIMARY KEY|UNIQUE KEY) (`(.*)`)? .*$/m',$create_sql,$m,PREG_SET_ORDER))
|
||||
{
|
||||
foreach($m as $index)
|
||||
{
|
||||
try {
|
||||
$indexname = '';
|
||||
if (isset($index[3]))
|
||||
$indexname = $index[3];
|
||||
$type = $index[1];
|
||||
switch($type)
|
||||
{
|
||||
case "CONSTRAINT":
|
||||
$db->Execute("ALTER TABLE $this->name
|
||||
DREP FOREIGN KEY $indexname");
|
||||
break;
|
||||
case "PRIMARY KEY":
|
||||
$db->Execute("ALTER TABLE $this->name
|
||||
DROP PRIMARY KEY");
|
||||
break;
|
||||
case "UNIQUE KEY":
|
||||
case "KEY":
|
||||
$db->Execute("ALTER TABLE $this->name
|
||||
DROP KEY $indexname");
|
||||
break;
|
||||
}
|
||||
} catch(exception $e)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function createTable($db)
|
||||
{
|
||||
// echo "Creating table '$this->name'\n";
|
||||
$sql = "CREATE TABLE $this->name (";
|
||||
foreach($this->fields as $field)
|
||||
{
|
||||
$sql .= $field->getCreateSQL() . ',';
|
||||
}
|
||||
$sql = rtrim($sql, ',') . ") ENGINE=$this->engine";
|
||||
|
||||
if($db->Execute($sql) === false)
|
||||
{
|
||||
echo "Error creating table $this->name!\n";
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class DBFormat {
|
||||
private $tables;
|
||||
|
||||
function __construct()
|
||||
{
|
||||
$this->tables = array();
|
||||
}
|
||||
|
||||
public function addChild($table)
|
||||
{
|
||||
$this->tables[] = $table;
|
||||
}
|
||||
|
||||
public function checkDB($db)
|
||||
{
|
||||
$result = $db->Execute('show tables');
|
||||
$dbtables = array();
|
||||
if ($result !== false)
|
||||
{
|
||||
while(!$result->EOF())
|
||||
{
|
||||
$dbtables[$result->fields['Tables_in_wesnoth_unit_test']] = true;
|
||||
$result->MoveNext();
|
||||
}
|
||||
} else {
|
||||
echo 'show tables failed';
|
||||
exit;
|
||||
}
|
||||
|
||||
// check for missing and old tables
|
||||
foreach($this->tables as $table)
|
||||
{
|
||||
if (!isset($dbtables[$table->getName()]))
|
||||
{
|
||||
// create missing table
|
||||
$table->createTable($db);
|
||||
} else {
|
||||
// check if this table needs updateing
|
||||
$table->check($db);
|
||||
unset($dbtables[$table->getname()]);
|
||||
}
|
||||
}
|
||||
|
||||
foreach($dbtables as $name => $bool)
|
||||
{
|
||||
$db->Execute('DROP TABLE ' . $name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class DBCreator {
|
||||
private $db;
|
||||
private $format;
|
||||
function __construct()
|
||||
{
|
||||
global $db;
|
||||
$this->format = new DBFormat();
|
||||
|
||||
$configtable = new DBTable('configs', 'InnoDB');
|
||||
$configtable->addChild(new DBField('name', 'VARCHAR(255) NOT NULL'));
|
||||
$configtable->addChild(new DBField('value', 'VARCHAR(255) NOT NULL'));
|
||||
$configtable->addChild(new DBIndex('name', 'PRIMARY KEY'));
|
||||
$this->format->addChild($configtable);
|
||||
|
||||
$buildstable = new DBTable('builds', 'InnoDB');
|
||||
$buildstable->addChild(new DBField('id', 'INT NOT NULL AUTO_INCREMENT'));
|
||||
$buildstable->addChild(new DBField('svn_version', 'INT NOT NULL'));
|
||||
$buildstable->addChild(new DBField('time', 'TIMESTAMP NOT NULL', 'CURRENT_TIMESTAMP'));
|
||||
$buildstable->addChild(new DBField('status', 'INT NOT NULL'));
|
||||
$buildstable->addChild(new DBField('error_msg', 'BLOB NOT NULL'));
|
||||
$buildstable->addChild(new DBIndex('id', 'PRIMARY KEY'));
|
||||
$buildstable->addChild(new DBIndex('time', 'KEY'));
|
||||
$this->format->addChild($buildstable);
|
||||
|
||||
$errortable = new DBTable('test_errors', 'InnoDB');
|
||||
$errortable->addChild(new DBField('id', 'INT NOT NULL AUTO_INCREMENT'));
|
||||
$errortable->addChild(new DBField('before_id', 'INT NOT NULL'));
|
||||
$errortable->addChild(new DBField('last_id', 'INT NOT NULL'));
|
||||
$errortable->addChild(new DBField('error_type', 'VARCHAR(10) NOT NULL'));
|
||||
$errortable->addChild(new DBField('file', 'VARCHAR(255) NOT NULL'));
|
||||
$errortable->addChild(new DBField('line', 'INT NOT NULL'));
|
||||
$errortable->addChild(new DBField('error_msg', 'BLOB NOT NULL'));
|
||||
$errortable->addChild(new DBIndex('id', 'PRIMARY KEY'));
|
||||
$errortable->addChild(new DBForeignKey('test_errors_before_id_key','`before_id`', '`builds` (`id`)'));
|
||||
$errortable->addChild(new DBForeignKey('test_errors_last_id_key','`last_id`', '`builds` (`id`)'));
|
||||
$this->format->addChild($errortable);
|
||||
|
||||
$resulttable = new DBTable('test_results', 'InnoDB');
|
||||
$resulttable->addChild(new DBField('id', 'INT NOT NULL AUTO_INCREMENT'));
|
||||
$resulttable->addChild(new DBField('build_id', 'INT NOT NULL'));
|
||||
$resulttable->addChild(new DBField('result', 'VARCHAR(10) NOT NULL'));
|
||||
$resulttable->addChild(new DBField('assertions_passed', 'INT NOT NULL'));
|
||||
$resulttable->addChild(new DBField('assertions_failed', 'INT NOT NULL'));
|
||||
$resulttable->addChild(new DBField('test_cases_passed', 'INT NOT NULL'));
|
||||
$resulttable->addChild(new DBField('test_cases_failed', 'INT NOT NULL'));
|
||||
$resulttable->addChild(new DBField('test_cases_skipped', 'INT NOT NULL'));
|
||||
$resulttable->addChild(new DBField('test_cases_aborted', 'INT NOT NULL'));
|
||||
$resulttable->addChild(new DBIndex('id', 'PRIMARY KEY'));
|
||||
$resulttable->addChild(new DBForeignKey('test_results_build_id_key', '`build_id`', '`builds` (`id`)'));
|
||||
$this->format->addChild($resulttable);
|
||||
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
public function checkDB()
|
||||
{
|
||||
$this->format->checkDB($this->db);
|
||||
|
||||
$build = new Build();
|
||||
$build->insertNull();
|
||||
|
||||
$config = new Config();
|
||||
$config->insertDefaults();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
22
resources/tests.wesnoth.org/include/FilenameConverter.php
Normal file
22
resources/tests.wesnoth.org/include/FilenameConverter.php
Normal file
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
/*
|
||||
Copyright (C) 2008 by Pauli Nieminen <paniemin@cc.hut.fi>
|
||||
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
or at your option any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
|
||||
class FilenameConverter {
|
||||
public static function stripBuildDirs($text)
|
||||
{
|
||||
return preg_replace('/^(build\/[^\/]*\/)?(.*[^\/]+:[0-9]+:.*)$/m','$2',$text);
|
||||
}
|
||||
}
|
||||
?>
|
32
resources/tests.wesnoth.org/include/Footer.php
Normal file
32
resources/tests.wesnoth.org/include/Footer.php
Normal file
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
/*
|
||||
Copyright (C) 2008 by Pauli Nieminen <paniemin@cc.hut.fi>
|
||||
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
or at your option any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
|
||||
class Footer
|
||||
{
|
||||
private $file;
|
||||
private $smarty;
|
||||
function __construct($file)
|
||||
{
|
||||
global $smarty;
|
||||
$this->file = $file;
|
||||
$this->smarty = $smarty;
|
||||
}
|
||||
|
||||
public function show()
|
||||
{
|
||||
$this->smarty->display('footer.tpl');
|
||||
}
|
||||
}
|
||||
?>
|
33
resources/tests.wesnoth.org/include/Header.php
Normal file
33
resources/tests.wesnoth.org/include/Header.php
Normal file
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
/*
|
||||
Copyright (C) 2008 by Pauli Nieminen <paniemin@cc.hut.fi>
|
||||
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
or at your option any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
|
||||
class Header
|
||||
{
|
||||
private $file;
|
||||
private $smarty;
|
||||
function __construct($file)
|
||||
{
|
||||
global $smarty;
|
||||
$this->file = $file;
|
||||
$this->smarty = $smarty;
|
||||
}
|
||||
|
||||
public function show()
|
||||
{
|
||||
$this->smarty->assign('extra_title', "| The report site for automated unit tests");
|
||||
$this->smarty->display('header.tpl');
|
||||
}
|
||||
}
|
||||
?>
|
37
resources/tests.wesnoth.org/include/ParameterValidator.php
Normal file
37
resources/tests.wesnoth.org/include/ParameterValidator.php
Normal file
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
/*
|
||||
Copyright (C) 2008 by Pauli Nieminen <paniemin@cc.hut.fi>
|
||||
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
or at your option any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
// posible class to set default values
|
||||
//class ParameterLimit {
|
||||
//}
|
||||
|
||||
class ParameterValidator {
|
||||
private $user_params;
|
||||
function __construct(array $user_params)
|
||||
{
|
||||
$this->user_params = $user_params;
|
||||
}
|
||||
|
||||
function getInt($name, $default)
|
||||
{
|
||||
if (isset($this->user_params[$name])
|
||||
&& is_numeric($this->user_params[$name]))
|
||||
{
|
||||
return (int)$this->user_params[$name];
|
||||
} else {
|
||||
return $default;
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
50
resources/tests.wesnoth.org/include/SVNUpdater.php
Normal file
50
resources/tests.wesnoth.org/include/SVNUpdater.php
Normal file
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
/*
|
||||
Copyright (C) 2008 by Pauli Nieminen <paniemin@cc.hut.fi>
|
||||
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
or at your option any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
|
||||
class SVNUpdater {
|
||||
private $revision;
|
||||
function __construct()
|
||||
{
|
||||
$this->updateSVN();
|
||||
}
|
||||
|
||||
public function getRevision()
|
||||
{
|
||||
return $this->revision;
|
||||
}
|
||||
|
||||
private function updateSVN()
|
||||
{
|
||||
$success = false;
|
||||
$m = array();
|
||||
$tries = 3;
|
||||
while(!$success && $tries--)
|
||||
{
|
||||
$svnlog = shell_exec('svn up 2>&1');
|
||||
global $db;
|
||||
if ($db->debug)
|
||||
echo $svnlog;
|
||||
$success = preg_match('/At revision ([0-9]*)\./m', $svnlog, $m);
|
||||
if (!$success)
|
||||
sleep(5);
|
||||
}
|
||||
if ($success)
|
||||
$this->revision = (int)$m[1];
|
||||
else
|
||||
$this->revision = false;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
150
resources/tests.wesnoth.org/include/TestError.php
Normal file
150
resources/tests.wesnoth.org/include/TestError.php
Normal file
|
@ -0,0 +1,150 @@
|
|||
<?php
|
||||
/*
|
||||
Copyright (C) 2008 by Pauli Nieminen <paniemin@cc.hut.fi>
|
||||
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
or at your option any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
class TestError {
|
||||
private $db;
|
||||
private $id;
|
||||
private $before_id;
|
||||
private $last_id;
|
||||
private $error_type;
|
||||
private $file;
|
||||
private $line;
|
||||
private $error_msg;
|
||||
|
||||
private $start_version;
|
||||
private $end_version;
|
||||
|
||||
function __construct($name = null, $data = null, Build $build = null)
|
||||
{
|
||||
global $db;
|
||||
$this->db = $db;
|
||||
$this->start_version = -1;
|
||||
$this->end_version = -1;
|
||||
if (!is_null($name))
|
||||
{
|
||||
$this->error_type = $name;
|
||||
$this->file = FilenameConverter::stripBuildDirs((string)$data->attributes()->file);
|
||||
$this->line = (string)$data->attributes()->line;
|
||||
$this->error_msg = (string)$data[0];
|
||||
$result = $this->db->Execute('SELECT t.id as id, before_id, last_id FROM test_errors t, builds b
|
||||
WHERE t.error_type=?
|
||||
AND t.file=?
|
||||
AND t.error_msg=?
|
||||
AND t.last_id=b.id
|
||||
AND b.time > ?
|
||||
LIMIT 1',
|
||||
array($this->error_type,
|
||||
$this->file,
|
||||
$this->error_msg,
|
||||
$this->db->DBTimeStamp(time() - 24*60*60)
|
||||
));
|
||||
if (!$result->EOF())
|
||||
{
|
||||
$this->id = $result->fields['id'];
|
||||
$this->before_id = $result->fields['before_id'];
|
||||
$this->last_id = $result->fields['last_id'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function fetch($where, $params =array(), $fields = '*')
|
||||
{
|
||||
$result = $this->db->Execute("SELECT $fields FROM test_errors $where LIMIT 1",$params);
|
||||
if (!$result->EOF())
|
||||
{
|
||||
$this->init($result->fields);
|
||||
}
|
||||
}
|
||||
|
||||
private function init($values)
|
||||
{
|
||||
$this->start_version = -1;
|
||||
$this->end_version = -1;
|
||||
foreach($values as $key => $value)
|
||||
{
|
||||
$this->$key = $value;
|
||||
}
|
||||
}
|
||||
|
||||
public static function getErrorsForBuild($id)
|
||||
{
|
||||
global $db;
|
||||
$ret = array();
|
||||
$result = $db->Execute('SELECT * FROM test_errors
|
||||
WHERE before_id<? AND last_id >=?',
|
||||
array($id,$id));
|
||||
while(!$result->EOF())
|
||||
{
|
||||
$error = new TestError();
|
||||
$error->init($result->fields);
|
||||
$ret[] = $error;
|
||||
$result->moveNext();
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function updateDB(Build $build)
|
||||
{
|
||||
if (is_null($this->id))
|
||||
{
|
||||
$this->before_id = $build->getPreviousId();
|
||||
$this->last_id = $build->getId();
|
||||
$this->insert();
|
||||
} else {
|
||||
$this->db->Execute('UPDATE test_errors SET last_id=?, line=? WHERE id=?', array($build->getid(), $this->line, $this->id));
|
||||
}
|
||||
}
|
||||
|
||||
private function insert()
|
||||
{
|
||||
$this->db->Execute('INSERT INTO test_errors (before_id, last_id, error_type, file, line, error_msg)
|
||||
VALUES (?, ?, ?, ?, ?, ?)',
|
||||
array($this->before_id,$this->last_id,$this->error_type,$this->file,$this->line,$this->error_msg));
|
||||
$this->id = $this->db->Insert_ID();
|
||||
}
|
||||
|
||||
public function getStatistics()
|
||||
{
|
||||
return array('error_type' => $this->error_type,
|
||||
'start_version' => $this->getStartVersion(),
|
||||
'end_version' => $this->getEndVersion(),
|
||||
'file' => $this->file,
|
||||
'line' => $this->line,
|
||||
'error_msg' => $this->error_msg);
|
||||
}
|
||||
|
||||
public function getStartVersion()
|
||||
{
|
||||
if ($this->start_version == -1)
|
||||
{
|
||||
$result = $this->db->Execute('SELECT svn_version as start_version FROM builds WHERE id=?',array($this->before_id));
|
||||
$this->start_version = $result->fields['start_version'];
|
||||
}
|
||||
return $this->start_version;
|
||||
}
|
||||
|
||||
public function getEndVersion()
|
||||
{
|
||||
if ($this->end_version == -1)
|
||||
{
|
||||
$result = $this->db->Execute('SELECT MIN(svn_version) as end_version FROM builds WHERE id>? AND status=?',array($this->before_id, Build::S_GOOD));
|
||||
$this->end_version = $result->fields['end_version'];
|
||||
}
|
||||
return $this->end_version;
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
123
resources/tests.wesnoth.org/include/TestResult.php
Normal file
123
resources/tests.wesnoth.org/include/TestResult.php
Normal file
|
@ -0,0 +1,123 @@
|
|||
<?php
|
||||
/*
|
||||
Copyright (C) 2008 by Pauli Nieminen <paniemin@cc.hut.fi>
|
||||
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
or at your option any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
class TestResult {
|
||||
private $db;
|
||||
private $id;
|
||||
private $build_id;
|
||||
private $name;
|
||||
private $result;
|
||||
private $assertions_passed;
|
||||
private $assertions_failed;
|
||||
private $test_cases_passed;
|
||||
private $test_cases_failed;
|
||||
private $test_cases_skipped;
|
||||
private $test_cases_aborted;
|
||||
|
||||
function __construct($data = null, Build $build = null)
|
||||
{
|
||||
global $db;
|
||||
$this->db = $db;
|
||||
if (!is_null($data))
|
||||
{
|
||||
if ($data instanceof SimpleXMLElement)
|
||||
{
|
||||
$this->build_id = $build->getId();
|
||||
$attr = $data->attributes();
|
||||
foreach($attr as $name => $value)
|
||||
{
|
||||
$this->$name = (string)$value;
|
||||
if (is_numeric($this->name))
|
||||
$this->$name = (int)$this->$name;
|
||||
}
|
||||
} else {
|
||||
$this->fetch('WHERE build_id = ?', array($data));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function fetch($where, $params = array())
|
||||
{
|
||||
$result = $this->db->Execute('SELECT * FROM test_results '
|
||||
. $where . ' LIMIT 1', $params);
|
||||
if (!$result->EOF())
|
||||
{
|
||||
$this->init($result->fields);
|
||||
} else {
|
||||
$this->reset();
|
||||
}
|
||||
}
|
||||
|
||||
private function init($values)
|
||||
{
|
||||
foreach($values as $key => $value)
|
||||
{
|
||||
$this->$key = $value;
|
||||
}
|
||||
}
|
||||
|
||||
private function reset()
|
||||
{
|
||||
$this->id = -1;
|
||||
$this->build_id = -1;
|
||||
$this->name = '';
|
||||
$this->result = '';
|
||||
$this->assertions_passed = -1;
|
||||
$this->assertions_failed = -1;
|
||||
$this->test_cases_passed = -1;
|
||||
$this->test_cases_failed = -1;
|
||||
$this->test_cases_skipped = -1;
|
||||
$this->test_cases_aborted = -1;
|
||||
|
||||
}
|
||||
|
||||
public function updateDB()
|
||||
{
|
||||
if (!empty($this->result))
|
||||
$this->insert();
|
||||
}
|
||||
|
||||
private function insert()
|
||||
{
|
||||
$this->db->Execute('INSERT INTO test_results
|
||||
(build_id, result, assertions_passed,
|
||||
assertions_failed, test_cases_passed,
|
||||
test_cases_failed, test_cases_skipped,
|
||||
test_cases_aborted)
|
||||
VALUES(?,?,?,
|
||||
?,?,
|
||||
?,?,
|
||||
?)',
|
||||
array($this->build_id, $this->result, $this->assertions_passed,
|
||||
$this->assertions_failed, $this->test_cases_passed,
|
||||
$this->test_cases_failed, $this->test_cases_skipped,
|
||||
$this->test_cases_aborted));
|
||||
}
|
||||
|
||||
public function getResult()
|
||||
{
|
||||
return $this->result;
|
||||
}
|
||||
|
||||
public function getAssertionsPassed()
|
||||
{
|
||||
return $this->assertions_passed;
|
||||
}
|
||||
|
||||
public function getAssertionsFailed()
|
||||
{
|
||||
return $this->assertions_failed;
|
||||
}
|
||||
}
|
||||
?>
|
66
resources/tests.wesnoth.org/include/TestRunner.php
Normal file
66
resources/tests.wesnoth.org/include/TestRunner.php
Normal file
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
/*
|
||||
Copyright (C) 2008 by Pauli Nieminen <paniemin@cc.hut.fi>
|
||||
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
or at your option any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
|
||||
class TestRunner {
|
||||
function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public function run(Build $build)
|
||||
{
|
||||
$binary_name = $build->getTestName();
|
||||
if ($binary_name === false)
|
||||
{
|
||||
trigger_error("No executeable name for tests");
|
||||
return;
|
||||
}
|
||||
$test_output = '<UnitTest>'.shell_exec("./$binary_name --log_format=XML --report_format=XML 2>&1").'</UnitTest>';
|
||||
|
||||
//$test_output = '<UnitTest><TestLog><Message file="./boost/test/impl/results_collector.ipp" line="220">Test case test_user_team_name doesn't include any assertions</Message><Error file="build/debug/tests/test_config_cache.cpp" line="84">check defines_map.size() == cache.get_preproc_map().size() failed [2 != 0]</Error></TestLog>
|
||||
//<TestResult><TestSuite name="wesnoth unit tests master suite"
|
||||
//result="failed"
|
||||
//assertions_passed="112"
|
||||
//assertions_failed="1"
|
||||
//expected_failures="0"
|
||||
//test_cases_passed="17"
|
||||
//test_cases_failed="1"
|
||||
//test_cases_skipped="0"
|
||||
//test_cases_aborted="0"></TestSuite>
|
||||
//</TestResult></UnitTest>';
|
||||
$xml = simplexml_load_string($test_output);
|
||||
if (!($xml instanceof SimpleXMLElement)
|
||||
|| !isset($xml->TestLog[0]) )
|
||||
{
|
||||
global $db;
|
||||
if ($db->debug)
|
||||
echo $test_output;
|
||||
$db->FailTrans();
|
||||
return;
|
||||
}
|
||||
foreach($xml->TestLog[0] as $name => $data)
|
||||
{
|
||||
$test_error = new TestError($name, $data, $build);
|
||||
$test_error->updateDB($build);
|
||||
}
|
||||
|
||||
foreach($xml->TestResult[0] as $name => $data)
|
||||
{
|
||||
$test_report = new TestResult($data, $build);
|
||||
$test_report->updateDB();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
30
resources/tests.wesnoth.org/include/WesnothSmarty.php
Normal file
30
resources/tests.wesnoth.org/include/WesnothSmarty.php
Normal file
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
/*
|
||||
Copyright (C) 2008 by Pauli Nieminen <paniemin@cc.hut.fi>
|
||||
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
or at your option any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
|
||||
global $smarty_dir;
|
||||
require($smarty_dir . 'libs/Smarty.class.php');
|
||||
|
||||
class WesnothSmarty extends Smarty {
|
||||
function __construct($work_dir)
|
||||
{
|
||||
parent::__construct();
|
||||
$this->template_dir = $work_dir . '/templates';
|
||||
$this->compile_dir = $work_dir . '/templates_c';
|
||||
$this->cache_dir = $work_dir . '/cache';
|
||||
$this->config_dir = $work_dir . '/configs';
|
||||
$this->plugins_dir[] = $work_dir . '/plugins';
|
||||
}
|
||||
}
|
||||
?>
|
50
resources/tests.wesnoth.org/include/settup.php.template
Normal file
50
resources/tests.wesnoth.org/include/settup.php.template
Normal file
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
// debug
|
||||
error_reporting(E_ALL | E_STRICT);
|
||||
|
||||
// production error_loging to system log
|
||||
//ini_set('syslog');
|
||||
|
||||
// settup auto class loader
|
||||
function __autoload($class)
|
||||
{
|
||||
global $root_dir;
|
||||
require_once($root_dir . '/../include/'.$class .'.php');
|
||||
}
|
||||
|
||||
// initialize database connection
|
||||
|
||||
$adodb_dir = $root_dir . '/../adodb_lite/';
|
||||
|
||||
|
||||
include($adodb_dir . "adodb-exceptions.inc.php");
|
||||
require_once($adodb_dir . 'adodb.inc.php');
|
||||
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
|
||||
$driver = 'mysqli';
|
||||
$username = 'username';
|
||||
$password = 'password';
|
||||
$hostname = 'localhost';
|
||||
$database = 'wesnoth_unit_test';
|
||||
$flags = MYSQL_CLIENT_COMPRESS;
|
||||
|
||||
$extra_options = '';
|
||||
//$debug = 'debug&persit&'
|
||||
$modules = '#date:transaction';
|
||||
try {
|
||||
$db = ADONewConnection("$driver://$username:$password@$hostname/$database?${extra_options}${modules}");
|
||||
}
|
||||
catch(exception $e)
|
||||
{
|
||||
echo "Connection to database failed!";
|
||||
exit;
|
||||
}
|
||||
|
||||
// initialize tempalte parser
|
||||
|
||||
$smarty_dir = $root_dir . '/../smarty_workdir/';
|
||||
|
||||
$smarty = new WesnothSmarty($smarty_dir);
|
||||
|
||||
?>
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
/*
|
||||
Copyright (C) 2008 by Pauli Nieminen <paniemin@cc.hut.fi>
|
||||
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
or at your option any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
|
||||
function smarty_modifier_autohide($text, $min_length_to_hide, $split_from_space, $take_end = false)
|
||||
{
|
||||
if (mb_strlen($text) > $min_length_to_hide)
|
||||
{
|
||||
$split_from_space = $split_from_space?"true":"false";
|
||||
$take_end = $take_end?"true":"false";
|
||||
return "<script type='text/javascript'>
|
||||
/*<![CDATA[*/
|
||||
autohide_store.push(new Autohide('$text', $min_length_to_hide, $split_from_space, $take_end));
|
||||
/*]]>*/
|
||||
</script>";
|
||||
} else {
|
||||
return $text;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,8 @@
|
|||
<h3>Build history</h3>
|
||||
<table class="build_history">
|
||||
<tr><td>
|
||||
{include file='paginate.tpl'}
|
||||
{include file='build_list.tpl'}
|
||||
{include file='paginate.tpl'}
|
||||
</td></tr>
|
||||
</table>
|
|
@ -0,0 +1,17 @@
|
|||
<table class="build" border="1">
|
||||
<tr>
|
||||
<th>Time</th>
|
||||
<th>Revision</th>
|
||||
<th>Error message</th>
|
||||
<th>Passed/Total</th>
|
||||
</tr>
|
||||
{foreach from=$builds item=build}
|
||||
<tr>
|
||||
<td class="time">{$build.time|date_format:"%H:%M %b %e, %Y"}</td>
|
||||
<td class="revision {$build.style}">r{$build.svn_rev}</td>
|
||||
<td class="message {$build.style}">{$build.result|autohide:20:true}</td>
|
||||
<td class="testresult {$build.result_style}">{$build.result_passed}/{$build.result_passed+$build.result_failed}</td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
</table>
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
<div id="content">
|
||||
</div> <!-- content -->
|
||||
|
||||
<div class="visualClear"></div>
|
||||
|
||||
<div id="footer">
|
||||
<div id="note">
|
||||
<p><a href="http://www.wesnoth.org/wiki/Site_Map">Site map</a></p>
|
||||
<p><a href="http://www.wesnoth.org/wiki/Wesnoth:Copyrights">Copyright</a> © 2003-2008 The Battle for Wesnoth</p>
|
||||
<p>Supported by <a href="http://www.jexiste.fr/">Jexiste</a>.</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div> <!-- main -->
|
||||
|
||||
</div> <!-- global -->
|
||||
|
||||
<script type="text/javascript">
|
||||
_uacct = "UA-1872754-3";
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
urchinTracker();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "xhtml11.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
|
||||
|
||||
<!--
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
|
||||
-->
|
||||
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/xhtml; charset=utf-8" />
|
||||
<link rel="shortcut icon" type="image/png" href="http://www.wesnoth.org/mw/skins/glamdrol/ico.png" />
|
||||
<style type="text/css">@import url('http://www.wesnoth.org/mw/skins/glamdrol/main.css');</style>
|
||||
<style type="text/css">@import url('http://www.wesnoth.org/mw/skins/glamdrol/home.css');</style>
|
||||
|
||||
<style type="text/css">@import url('styles/unit_test.css');</style>
|
||||
<script src="js/autohide.js" type="text/javascript"></script>
|
||||
|
||||
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
|
||||
</script>
|
||||
|
||||
<link rel="alternate" type="application/rss+xml" title="news" href="http://feed43.com/wesnoth.xml" />
|
||||
<title>Battle for Wesnoth {$extra_title}</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="global">
|
||||
|
||||
<div id="header">
|
||||
<div id="logo">
|
||||
<a href="home"><img alt="Wesnoth logo" src="http://www.wesnoth.org/mw/skins/glamdrol/wesnoth-logo.jpg" /></a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="nav">
|
||||
<ul>
|
||||
<li><a href="http://www.wesnoth.org/">Home</a></li>
|
||||
<li><a href="http://www.wesnoth.org/wiki/Play">Play</a></li>
|
||||
<li><a href="http://www.wesnoth.org/wiki/Create">Create</a></li>
|
||||
<li><a href="http://www.wesnoth.org/forum/">Forums</a></li>
|
||||
|
||||
<li><a href="http://www.wesnoth.org/wiki/Support">Support</a></li>
|
||||
<li><a href="http://www.wesnoth.org/wiki/Project">Project</a></li>
|
||||
<li><a href="http://www.wesnoth.org/wiki/Credits">Credits</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div id="menu" class="menu">
|
||||
<table class="menu">
|
||||
<tr><td><a href="index.php">Status</a></td></tr>
|
||||
<tr><td><a href="build_history.php">Build history</a></td></tr>
|
||||
<tr><td><a href="index.php">Test Graphs</a></td></tr>
|
||||
</table>
|
||||
</div>
|
||||
<div id="main" class="unit_test">
|
|
@ -0,0 +1,26 @@
|
|||
<h3>The status from the latest build</h3>
|
||||
{include file='build_list.tpl'}
|
||||
<br/>
|
||||
{if count($errors) eq 0}
|
||||
<h3>All unit test passed! Congratulations!</h3>
|
||||
{else}
|
||||
<h3>Current list of errors in unit tests</h3>
|
||||
<table class="test_error" border="1">
|
||||
<tr>
|
||||
<th>Type</th>
|
||||
<th>First broken</th>
|
||||
<th>File</th>
|
||||
<th>Line</th>
|
||||
<th>Message</th>
|
||||
</tr>
|
||||
{foreach from=$errors item=err}
|
||||
<tr>
|
||||
<td class="{$err.error_type}">{$err.error_type}</td>
|
||||
<td class="{$err.error_type}">r{$err.start_version} - r{$err.end_version}</td>
|
||||
<td class="{$err.error_type}">{$err.file|autohide:25:false:true}</td>
|
||||
<td class="{$err.error_type}">{$err.line}</td>
|
||||
<td class="{$err.error_type}">{$err.error_msg|autohide:40:true}</td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
{/if}
|
||||
</table>
|
|
@ -0,0 +1,58 @@
|
|||
{strip}
|
||||
<div class="paginate">
|
||||
{if $paginate.visible > 1}
|
||||
{if $paginate.page > 1}
|
||||
<a href="{$paginate.link}{$paginate.page-1}">
|
||||
{else}
|
||||
<span class="active">
|
||||
{/if}
|
||||
Previous
|
||||
{if $paginate.page > 1}
|
||||
</a>
|
||||
{else}
|
||||
</span>
|
||||
{/if}
|
||||
|
||||
{if $paginate.first_page > 1}
|
||||
<a href="{$paginate.link}1">1</a>
|
||||
{if $paginate.first_page > 2}
|
||||
...
|
||||
{else}
|
||||
,
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
{section name=pager loop=$paginate.last_page start=$paginate.first_page max=$paginate.visible}
|
||||
<a href="{$paginate.link}{$smarty.section.pager.index}"
|
||||
{if $paginate.page == $smarty.section.pager.index}
|
||||
class="active"
|
||||
{/if}
|
||||
>{$smarty.section.pager.index}</a>
|
||||
{if $smarty.section.pager.last == false}
|
||||
,
|
||||
{/if}
|
||||
{/section}
|
||||
|
||||
{if $paginate.last_page <= $paginate.number_of_pages}
|
||||
{if $paginate.last_page <= $paginate.number_of_pages - 1}
|
||||
...
|
||||
{else}
|
||||
,
|
||||
{/if}
|
||||
<a href="{$paginate.link}{$paginate.number_of_pages}">{$paginate.number_of_pages}</a>
|
||||
{/if}
|
||||
|
||||
{if $paginate.page < $paginate.number_of_pages}
|
||||
<a href="{$paginate.link}{$paginate.page+1}">
|
||||
{else}
|
||||
<span class="active">
|
||||
{/if}
|
||||
next
|
||||
{if $paginate.page < $paginate.number_of_pages}
|
||||
</a>
|
||||
{else}
|
||||
</span>
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
{/strip}
|
Loading…
Add table
Reference in a new issue