git-remote-mediawiki: test environment of git-remote-mediawiki

In order to test git-remote-mediawiki, a set of functions is needed to
manage a MediaWiki: edit a page, remove a page, fetch a page, fetch all
pages on a given wiki.

A few helper function are also provided to check the content of
directories.

In addition, this patch provides Makefiles to execute tests.
See the README file for more details.

Signed-off-by: Simon CATHEBRAS <Simon.Cathebras@ensimag.imag.fr>
Signed-off-by: Julien KHAYAT <Julien.Khayat@ensimag.imag.fr>
Signed-off-by: Simon Perrat <simon.perrat@ensimag.imag.fr>
Signed-off-by: Charles ROUSSEL <Charles.Roussel@ensimag.imag.fr>
Signed-off-by: Guillaume SASDY <Guillaume.Sasdy@ensimag.imag.fr>
Signed-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Guillaume Sasdy 2012-07-06 12:03:05 +02:00 committed by Junio C Hamano
parent 5ef6ad1785
commit 8435b28989
6 changed files with 556 additions and 0 deletions

View file

@ -0,0 +1,47 @@
#
# Copyright (C) 2012
# Charles Roussel <charles.roussel@ensimag.imag.fr>
# Simon Cathebras <simon.cathebras@ensimag.imag.fr>
# Julien Khayat <julien.khayat@ensimag.imag.fr>
# Guillaume Sasdy <guillaume.sasdy@ensimag.imag.fr>
# Simon Perrat <simon.perrat@ensimag.imag.fr>
#
## Build git-remote-mediawiki
-include ../../config.mak.autogen
-include ../../config.mak
ifndef PERL_PATH
PERL_PATH = /usr/bin/perl
endif
ifndef gitexecdir
gitexecdir = $(shell git --exec-path)
endif
PERL_PATH_SQ = $(subst ','\'',$(PERL_PATH))
gitexecdir_SQ = $(subst ','\'',$(gitexecdir))
SCRIPT = git-remote-mediawiki
.PHONY: install help doc test clean
help:
@echo 'This is the help target of the Makefile. Current configuration:'
@echo ' gitexecdir = $(gitexecdir_SQ)'
@echo ' PERL_PATH = $(PERL_PATH_SQ)'
@echo 'Run "$(MAKE) install" to install $(SCRIPT) in gitexecdir'
@echo 'Run "$(MAKE) test" to run the testsuite'
install:
sed -e '1s|#!.*/perl|#!$(PERL_PATH_SQ)|' $(SCRIPT) \
> '$(gitexecdir_SQ)/$(SCRIPT)'
chmod +x '$(gitexecdir)/$(SCRIPT)'
doc:
@echo 'Sorry, "make doc" is not implemented yet for $(SCRIPT)'
test:
$(MAKE) -C t/ test
clean:
$(RM) '$(gitexecdir)/$(SCRIPT)'
$(MAKE) -C t/ clean

View file

@ -1,2 +1,4 @@
WEB/
wiki/
trash directory.t*/
test-results/

View file

@ -0,0 +1,31 @@
#
# Copyright (C) 2012
# Charles Roussel <charles.roussel@ensimag.imag.fr>
# Simon Cathebras <simon.cathebras@ensimag.imag.fr>
# Julien Khayat <julien.khayat@ensimag.imag.fr>
# Guillaume Sasdy <guillaume.sasdy@ensimag.imag.fr>
# Simon Perrat <simon.perrat@ensimag.imag.fr>
#
## Test git-remote-mediawiki
all: test
-include ../../../config.mak.autogen
-include ../../../config.mak
T = $(wildcard t[0-9][0-9][0-9][0-9]-*.sh)
.PHONY: help test clean all
help:
@echo 'Run "$(MAKE) test" to launch test scripts'
@echo 'Run "$(MAKE) clean" to remove trash folders'
test:
@for t in $(T); do \
echo "$$t"; \
"./$$t" || exit 1; \
done
clean:
$(RM) -r 'trash directory'.*

124
contrib/mw-to-git/t/README Normal file
View file

@ -0,0 +1,124 @@
Tests for Mediawiki-to-Git
==========================
Introduction
------------
This manual describes how to install the git-remote-mediawiki test
environment on a machine with git installed on it.
Prerequisite
------------
In order to run this test environment correctly, you will need to
install the following packages (Debian/Ubuntu names, may need to be
adapted for another distribution):
* lighttpd
* php5
* php5-cgi
* php5-cli
* php5-curl
* php5-sqlite
Principles and Technical Choices
--------------------------------
The test environment makes it easy to install and manipulate one or
several MediaWiki instances. To allow developers to run the testsuite
easily, the environment does not require root priviledge (except to
install the required packages if needed). It starts a webserver
instance on the user's account (using lighttpd greatly helps for
that), and does not need a separate database daemon (thanks to the use
of sqlite).
Run the test environment
------------------------
Install a new wiki
~~~~~~~~~~~~~~~~~~
Once you have all the prerequisite, you need to install a MediaWiki
instance on your machine. If you already have one, it is still
strongly recommended to install one with the script provided. Here's
how to work it:
a. change directory to contrib/mw-to-git/t/
b. if needed, edit test.config to choose your installation parameters
c. run `./install-wiki.sh install`
d. check on your favourite web browser if your wiki is correctly
installed.
Remove an existing wiki
~~~~~~~~~~~~~~~~~~~~~~~
Edit the file test.config to fit the wiki you want to delete, and then
execute the command `./install-wiki.sh delete` from the
contrib/mw-to-git/t directory.
Run the existing tests
~~~~~~~~~~~~~~~~~~~~~~
The provided tests are currently in the `contrib/mw-to-git/t` directory.
The files are all the t936[0-9]-*.sh shell scripts.
a. Run all tests:
To do so, run "make test" from the contrib/mw-to-git/ directory.
b. Run a specific test:
To run a given test <test_name>, run ./<test_name> from the
contrib/mw-to-git/t directory.
How to create new tests
-----------------------
Available functions
~~~~~~~~~~~~~~~~~~~
The test environment of git-remote-mediawiki provides some functions
useful to test its behaviour. for more details about the functions'
parameters, please refer to the `test-gitmw-lib.sh` and
`test-gitmw.pl` files.
** `test_check_wiki_precond`:
Check if the tests must be skipped or not. Please use this function
at the beggining of each new test file.
** `wiki_getpage`:
Fetch a given page from the wiki and puts its content in the
directory in parameter.
** `wiki_delete_page`:
Delete a given page from the wiki.
** `wiki_edit_page`:
Create or modify a given page in the wiki. You can specify several
parameters like a summary for the page edition, or add the page to a
given category.
See test-gitmw.pl for more details.
** `wiki_getallpage`:
Fetch all pages from the wiki into a given directory. The directory
is created if it does not exists.
** `test_diff_directories`:
Compare the content of two directories. The content must be the same.
Use this function to compare the content of a git directory and a wiki
one created by wiki_getallpage.
** `test_contains_N_files`:
Check if the given directory contains a given number of file.
** `wiki_page_exists`:
Tests if a given page exists on the wiki.
** `wiki_reset`:
Reset the wiki, i.e. flush the database. Use this function at the
begining of each new test, except if the test re-uses the same wiki
(and history) as the previous test.
How to write a new test
~~~~~~~~~~~~~~~~~~~~~~~
Please, follow the standards given by git. See git/t/README.
New file should be named as t936[0-9]-*.sh.
Be sure to reset your wiki regulary with the function `wiki_reset`.

View file

@ -13,6 +13,7 @@
. ./test.config
WIKI_URL=http://"$SERVER_ADDR:$PORT/$WIKI_DIR_NAME"
CURR_DIR=$(pwd)
TEST_OUTPUT_DIRECTORY=$(pwd)
TEST_DIRECTORY="$CURR_DIR"/../../../t
@ -25,6 +26,148 @@ else
WIKI_DIR_INST="$CURR_DIR/$WEB_WWW"
fi
wiki_getpage () {
"$CURR_DIR"/test-gitmw.pl get_page "$@"
}
wiki_delete_page () {
"$CURR_DIR"/test-gitmw.pl delete_page "$@"
}
wiki_editpage () {
"$CURR_DIR"/test-gitmw.pl edit_page "$@"
}
die () {
die_with_status 1 "$@"
}
die_with_status () {
status=$1
shift
echo >&2 "$*"
exit "$status"
}
# Check the preconditions to run git-remote-mediawiki's tests
test_check_precond () {
if ! test_have_prereq PERL
then
skip_all='skipping gateway git-mw tests, perl not available'
test_done
fi
if [ ! -f "$GIT_BUILD_DIR"/git-remote-mediawiki ];
then
echo "No remote mediawiki for git found. Copying it in git"
echo "cp $GIT_BUILD_DIR/contrib/mw-to-git/git-remote-mediawiki $GIT_BUILD_DIR/"
ln -s "$GIT_BUILD_DIR"/contrib/mw-to-git/git-remote-mediawiki "$GIT_BUILD_DIR"
fi
if [ ! -d "$WIKI_DIR_INST/$WIKI_DIR_NAME" ];
then
skip_all='skipping gateway git-mw tests, no mediawiki found'
test_done
fi
}
# test_diff_directories <dir_git> <dir_wiki>
#
# Compare the contents of directories <dir_git> and <dir_wiki> with diff
# and errors if they do not match. The program will
# not look into .git in the process.
# Warning: the first argument MUST be the directory containing the git data
test_diff_directories () {
rm -rf "$1_tmp"
mkdir -p "$1_tmp"
cp "$1"/*.mw "$1_tmp"
diff -r -b "$1_tmp" "$2"
}
# $1=<dir>
# $2=<N>
#
# Check that <dir> contains exactly <N> files
test_contains_N_files () {
if test `ls -- "$1" | wc -l` -ne "$2"; then
echo "directory $1 sould contain $2 files"
echo "it contains these files:"
ls "$1"
false
fi
}
# wiki_check_content <file_name> <page_name>
#
# Compares the contents of the file <file_name> and the wiki page
# <page_name> and exits with error 1 if they do not match.
wiki_check_content () {
mkdir -p wiki_tmp
wiki_getpage "$2" wiki_tmp
# replacement of forbidden character in file name
page_name=$(printf "%s\n" "$2" | sed -e "s/\//%2F/g")
diff -b "$1" wiki_tmp/"$page_name".mw
if test $? -ne 0
then
rm -rf wiki_tmp
error "ERROR: file $2 not found on wiki"
fi
rm -rf wiki_tmp
}
# wiki_page_exist <page_name>
#
# Check the existence of the page <page_name> on the wiki and exits
# with error if it is absent from it.
wiki_page_exist () {
mkdir -p wiki_tmp
wiki_getpage "$1" wiki_tmp
page_name=$(printf "%s\n" "$1" | sed "s/\//%2F/g")
if test -f wiki_tmp/"$page_name".mw ; then
rm -rf wiki_tmp
else
rm -rf wiki_tmp
error "test failed: file $1 not found on wiki"
fi
}
# wiki_getallpagename
#
# Fetch the name of each page on the wiki.
wiki_getallpagename () {
"$CURR_DIR"/test-gitmw.pl getallpagename
}
# wiki_getallpagecategory <category>
#
# Fetch the name of each page belonging to <category> on the wiki.
wiki_getallpagecategory () {
"$CURR_DIR"/test-gitmw.pl getallpagename "$@"
}
# wiki_getallpage <dest_dir> [<category>]
#
# Fetch all the pages from the wiki and place them in the directory
# <dest_dir>.
# If <category> is define, then wiki_getallpage fetch the pages included
# in <category>.
wiki_getallpage () {
if test -z "$2";
then
wiki_getallpagename
else
wiki_getallpagecategory "$2"
fi
mkdir -p "$1"
while read -r line; do
wiki_getpage "$line" $1;
done < all.txt
}
# ================= Install part =================
error () {

209
contrib/mw-to-git/t/test-gitmw.pl Executable file
View file

@ -0,0 +1,209 @@
#!/usr/bin/perl -w -s
# Copyright (C) 2012
# Charles Roussel <charles.roussel@ensimag.imag.fr>
# Simon Cathebras <simon.cathebras@ensimag.imag.fr>
# Julien Khayat <julien.khayat@ensimag.imag.fr>
# Guillaume Sasdy <guillaume.sasdy@ensimag.imag.fr>
# Simon Perrat <simon.perrat@ensimag.imag.fr>
# License: GPL v2 or later
# Usage:
# ./test-gitmw.pl <command> [argument]*
# Execute in terminal using the name of the function to call as first
# parameter, and the function's arguments as following parameters
#
# Example:
# ./test-gitmw.pl "get_page" foo .
# will call <wiki_getpage> with arguments <foo> and <.>
#
# Available functions are:
# "get_page"
# "delete_page"
# "edit_page"
# "getallpagename"
use MediaWiki::API;
use Getopt::Long;
use encoding 'utf8';
use DateTime::Format::ISO8601;
use open ':encoding(utf8)';
use constant SLASH_REPLACEMENT => "%2F";
#Parsing of the config file
my $configfile = "$ENV{'CURR_DIR'}/test.config";
my %config;
open my $CONFIG, "<", $configfile or die "can't open $configfile: $!";
while (<$CONFIG>)
{
chomp;
s/#.*//;
s/^\s+//;
s/\s+$//;
next unless length;
my ($key, $value) = split (/\s*=\s*/,$_, 2);
$config{$key} = $value;
last if ($key eq 'LIGHTTPD' and $value eq 'false');
last if ($key eq 'PORT');
}
close $CONFIG or die "can't close $configfile: $!";
my $wiki_address = "http://$config{'SERVER_ADDR'}".":"."$config{'PORT'}";
my $wiki_url = "$wiki_address/$config{'WIKI_DIR_NAME'}/api.php";
my $wiki_admin = "$config{'WIKI_ADMIN'}";
my $wiki_admin_pass = "$config{'WIKI_PASSW'}";
my $mw = MediaWiki::API->new;
$mw->{config}->{api_url} = $wiki_url;
# wiki_login <name> <password>
#
# Logs the user with <name> and <password> in the global variable
# of the mediawiki $mw
sub wiki_login {
$mw->login( { lgname => "$_[0]",lgpassword => "$_[1]" } )
|| die "getpage: login failed";
}
# wiki_getpage <wiki_page> <dest_path>
#
# fetch a page <wiki_page> from the wiki referenced in the global variable
# $mw and copies its content in directory dest_path
sub wiki_getpage {
my $pagename = $_[0];
my $destdir = $_[1];
my $page = $mw->get_page( { title => $pagename } );
if (!defined($page)) {
die "getpage: wiki does not exist";
}
my $content = $page->{'*'};
if (!defined($content)) {
die "getpage: page does not exist";
}
$pagename=$page->{'title'};
# Replace spaces by underscore in the page name
$pagename =~ s/ /_/g;
$pagename =~ s/\//%2F/g;
open(my $file, ">$destdir/$pagename.mw");
print $file "$content";
close ($file);
}
# wiki_delete_page <page_name>
#
# delete the page with name <page_name> from the wiki referenced
# in the global variable $mw
sub wiki_delete_page {
my $pagename = $_[0];
my $exist=$mw->get_page({title => $pagename});
if (defined($exist->{'*'})){
$mw->edit({ action => 'delete',
title => $pagename})
|| die $mw->{error}->{code} . ": " . $mw->{error}->{details};
} else {
die "no page with such name found: $pagename\n";
}
}
# wiki_editpage <wiki_page> <wiki_content> <wiki_append> [-c=<category>] [-s=<summary>]
#
# Edit a page named <wiki_page> with content <wiki_content> on the wiki
# referenced with the global variable $mw
# If <wiki_append> == true : append <wiki_content> at the end of the actual
# content of the page <wiki_page>
# If <wik_page> doesn't exist, that page is created with the <wiki_content>
sub wiki_editpage {
my $wiki_page = $_[0];
my $wiki_content = $_[1];
my $wiki_append = $_[2];
my $summary = "";
my ($summ, $cat) = ();
GetOptions('s=s' => \$summ, 'c=s' => \$cat);
my $append = 0;
if (defined($wiki_append) && $wiki_append eq 'true') {
$append=1;
}
my $previous_text ="";
if ($append) {
my $ref = $mw->get_page( { title => $wiki_page } );
$previous_text = $ref->{'*'};
}
my $text = $wiki_content;
if (defined($previous_text)) {
$text="$previous_text$text";
}
# Eventually, add this page to a category.
if (defined($cat)) {
my $category_name="[[Category:$cat]]";
$text="$text\n $category_name";
}
if(defined($summ)){
$summary=$summ;
}
$mw->edit( { action => 'edit', title => $wiki_page, summary => $summary, text => "$text"} );
}
# wiki_getallpagename [<category>]
#
# Fetch all pages of the wiki referenced by the global variable $mw
# and print the names of each one in the file all.txt with a new line
# ("\n") between these.
# If the argument <category> is defined, then this function get only the pages
# belonging to <category>.
sub wiki_getallpagename {
# fetch the pages of the wiki
if (defined($_[0])) {
my $mw_pages = $mw->list ( { action => 'query',
list => 'categorymembers',
cmtitle => "Category:$_[0]",
cmnamespace => 0,
cmlimit => 500 },
)
|| die $mw->{error}->{code}.": ".$mw->{error}->{details};
open(my $file, ">all.txt");
foreach my $page (@{$mw_pages}) {
print $file "$page->{title}\n";
}
close ($file);
} else {
my $mw_pages = $mw->list({
action => 'query',
list => 'allpages',
aplimit => 500,
})
|| die $mw->{error}->{code}.": ".$mw->{error}->{details};
open(my $file, ">all.txt");
foreach my $page (@{$mw_pages}) {
print $file "$page->{title}\n";
}
close ($file);
}
}
# Main part of this script: parse the command line arguments
# and select which function to execute
my $fct_to_call = shift;
wiki_login($wiki_admin, $wiki_admin_pass);
my %functions_to_call = qw(
get_page wiki_getpage
delete_page wiki_delete_page
edit_page wiki_editpage
getallpagename wiki_getallpagename
);
die "$0 ERROR: wrong argument" unless exists $functions_to_call{$fct_to_call};
&{$functions_to_call{$fct_to_call}}(@ARGV);