diff --git a/INSTALL b/INSTALL index a17d968f8..dfca3ad4a 100644 --- a/INSTALL +++ b/INSTALL @@ -1,886 +1,886 @@ -Invenio INSTALLATION ==================== About ===== This document specifies how to build, customize, and install Invenio v1.2.1 for the first time. See RELEASE-NOTES if you are upgrading from a previous Invenio release. Contents ======== 1. Using kickstart scripts 2. Prerequisites 3. Quick instructions for the impatient Invenio admin 4. Detailed instructions for the patient Invenio admin 1. Using kickstart scripts ========================== You can install Invenio on a Unix-based operating system in an unassisted automated way by using kickstart scripts. Tested on Ubuntu 12.04, CentOS 6. The other operating systems will work similarly. Please run: $ $EDITOR .inveniorc # edit your options $ source .inveniorc $ ./scripts/provision-web.sh $ ./scripts/provision-mysql.sh $ ./scripts/create-instance.sh $ ./scripts/populate-instance.sh $ firefox http://192.168.50.10/record/1 Note that you can use Vagrant to run this in a virtual machine; please see the .inveniorc file for more details. You can also read the detailed installation instructions in the sections below. They basically explain in detail what the kickstart scripts do. 2. Prerequisites ================ Here is the software you need to have around before you start installing Invenio: a) Unix-like operating system. The main development and production platforms for Invenio at CERN are GNU/Linux distributions Debian, Gentoo, Scientific Linux (aka RHEL), Ubuntu, but we also develop on Mac OS X. Basically any Unix system supporting the software listed below should do. If you are using Debian GNU/Linux ``Lenny'' or later, then you can install most of the below-mentioned prerequisites and recommendations by running: $ sudo aptitude install python-dev apache2-mpm-prefork \ mysql-server mysql-client python-mysqldb \ python-4suite-xml python-simplejson python-xml \ gnuplot poppler-utils \ gs-common clisp gettext libapache2-mod-wsgi unzip \ python-dateutil python-rdflib python-pyparsing \ python-gnuplot python-magic pdftk html2text giflib-tools \ pstotext netpbm python-pypdf python-chardet python-lxml \ python-unidecode redis-server python-redis You may also want to install some of the following packages, if you have them available on your concrete architecture: $ sudo aptitude install sbcl cmucl pylint pychecker pyflakes \ python-profiler python-epydoc libapache2-mod-xsendfile \ openoffice.org python-utidylib python-beautifulsoup \ libhdf5-dev (Note that if you use pip to manage your Python dependencies instead of operating system packages, please see the section (d) below on how to use pip instead of aptitude.) Moreover, you should install some Message Transfer Agent (MTA) such as Postfix so that Invenio can email notification alerts or registration information to the end users, contact moderators and reviewers of submitted documents, inform administrators about various runtime system information, etc: $ sudo aptitude install postfix After running the above-quoted aptitude command(s), you can proceed to configuring your MySQL server instance (max_allowed_packet in my.cnf, see item b below) and then to installing the Invenio software package in the section 1 below. If you are using another operating system, then please continue reading the rest of this prerequisites section, and please consult our wiki pages for any concrete hints for your specific operating system. b) MySQL server (may be on a remote machine), and MySQL client (must be available locally too). MySQL versions 4.1 or 5.0 are supported. Please set the variable "max_allowed_packet" in your "my.cnf" init file to at least 4M. (For sites such as INSPIRE, having 1M records with 10M citer-citee pairs in its citation map, you may need to increase max_allowed_packet to 1G.) You may perhaps also want to run your MySQL server natively in UTF-8 mode by setting "default-character-set=utf8" in various parts of your "my.cnf" file, such as in the "[mysql]" part and elsewhere; but this is not really required. Note also that you may encounter problems when MySQL is run in "strict mode"; you may want to configure your "my.cnf" in order to avoid using strict mode (such as `STRICT_ALL_TABLES`). c) Redis server (may be on a remote machine) for user session management and caching purposes. By default, Invenio would use Redis to store sessions, so it is highly recommended to install it. However, if you do not want to use Redis, you can change CFG_WEBSESSION_STORAGE settings in invenio-local.conf and MySQL will be used for session management instead. d) Apache 2 server, with support for loading DSO modules, and optionally with SSL support for HTTPS-secure user authentication, and mod_xsendfile for off-loading file downloads away from Invenio processes to Apache. e) Python v2.6 or above: as well as the following Python modules: - (mandatory) MySQLdb (version >= 1.2.1_p2; see below) - (mandatory) Pyparsing, for document parsing - (mandatory) unidecode, for ASCII representation of Unicode text: - (recommended) Redis connector: - (recommended) Nydus, Redis consistent hashing connector: - (recommended) python-dateutil, for complex date processing: - (recommended) PyRXP, for very fast XML MARC processing: - (recommended) lxml, for XML/XLST processing: - (recommended) Gnuplot.Py, for producing graphs: - (recommended) Snowball Stemmer, for stemming: - (recommended) py-editdist, for record merging: - (recommended) numpy, for citerank methods: - (recommended) magic, for full-text file handling: - (recommended) cerberus, extensible validation for Python dictionaries. - (optional) libxml2-python, for XML/XLST processing: - (optional) chardet, for character encoding detection: - (optional) 4suite, slower alternative to PyRXP and libxml2-python: - (optional) feedparser, for web journal creation: - (optional) RDFLib, to use RDF ontologies and thesauri: - (optional) mechanize, to run regression web test suite: - (optional) python-mock, mocking library for the test suite: - (optional) utidylib, for HTML washing: - (optional) Beautiful Soup, for HTML washing: - (optional) Python Twitter (and its dependencies) if you want to use the Twitter Fetcher bibtasklet: - (optional) Python OpenID if you want to enable OpenID support for authentication: - (optional) Python Rauth if you want to enable OAuth 1.0/2.0 support for authentication (depends on Python-2.6 or later): - (optional) libhdf5-7, libhdf5-dev, python-h5py, in order to run author disambiguation. Note that if you are using pip to install and manage your Python dependencies, then you can run: $ sudo pip install -r requirements.txt $ sudo pip install -r requirements-extras.txt to install all manadatory, recommended, and optional packages mentioned above. f) mod_wsgi Apache module. Versions 3.x and above are recommended. g) If you want to be able to extract references from PDF fulltext files, then you need to install pdftotext version 3 at least. h) If you want to be able to search for words in the fulltext files (i.e. to have fulltext indexing) or to stamp submitted files, then you need as well to install some of the following tools: - for Microsoft Office/OpenOffice.org document conversion: OpenOffice.org - for PDF file stamping: pdftk, pdf2ps - for PDF files: pdftotext or pstotext - for PostScript files: pstotext or ps2ascii - for DjVu creation, elaboration: DjVuLibre - to perform OCR: OCRopus (tested only with release 0.3.1) - to perform different image elaborations: ImageMagick - to generate PDF after OCR: netpbm, ReportLab and pyPdf or pyPdf2 i) If you have chosen to install fast XML MARC Python processors in the step d) above, then you have to install the parsers themselves: - (optional) 4suite: j) (recommended) Gnuplot, the command-line driven interactive plotting program. It is used to display download and citation history graphs on the Detailed record pages on the web interface. Note that Gnuplot must be compiled with PNG output support, that is, with the GD library. Note also that Gnuplot is not required, only recommended. k) (recommended) A Common Lisp implementation, such as CLISP, SBCL or CMUCL. It is used for the web server log analysing tool and the metadata checking program. Note that any of the three implementations CLISP, SBCL, or CMUCL will do. CMUCL produces fastest machine code, but it does not support UTF-8 yet. Pick up CLISP if you don't know what to do. Note that a Common Lisp implementation is not required, only recommended. l) GNU gettext, a set of tools that makes it possible to translate the application in multiple languages. This is available by default on many systems. m) (recommended) xlwt 0.7.2, Library to create spreadsheet files compatible with MS Excel 97/2000/XP/2003 XLS files, on any platform, with Python 2.3 to 2.6 n) (recommended) matplotlib 1.0.0 is a python 2D plotting library which produces publication quality figures in a variety of hardcopy formats and interactive environments across platforms. matplotlib can be used in python scripts, the python and ipython shell (ala MATLAB® or Mathematica®), web application servers, and six graphical user interface toolkits. It is used to generate pie graphs in the custom summary query (WebStat) o) (optional) FFmpeg, an open-source tools an libraries collection to convert video and audio files. It makes use of both internal as well as external libraries to generate videos for the web, such as Theora, WebM and H.264 out of almost any thinkable video input. FFmpeg is needed to run video related modules and submission workflows in Invenio. The minimal configuration of ffmpeg for the Invenio demo site requires a number of external libraries. It is highly recommended to remove all installed versions and packages that are comming with various Linux distributions and install the latest versions from sources. Additionally, you will need the Mediainfo Library for multimedia metadata handling. Minimum libraries for the demo site: - the ffmpeg multimedia encoder tools - a library for jpeg images needed for thumbnail extraction - a library for the ogg container format, needed for Vorbis and Theora - the OGG Vorbis audi codec library - the OGG Theora video codec library - the WebM video codec library - the mediainfo library for multimedia metadata Recommended for H.264 video (!be aware of licensing issues!): - a library for H.264 video encoding - a library for Advanced Audi Coding - a library for MP3 encoding Note that the configure script checks whether you have all the prerequisite software installed and that it won't let you continue unless everything is in order. It also warns you if it cannot find some optional but recommended software. 3. Quick instructions for the impatient Invenio admin ===================================================== 3a. Installation ---------------- $ cd $HOME/src/ $ wget http://invenio-software.org/download/invenio-1.2.1.tar.gz $ wget http://invenio-software.org/download/invenio-1.2.1.tar.gz.md5 $ wget http://invenio-software.org/download/invenio-1.2.1.tar.gz.sig $ md5sum -c invenio-1.2.1.tar.gz.md5 $ gpg --verify invenio-1.2.1.tar.gz.sig invenio-1.2.1.tar.gz $ tar xvfz invenio-1.2.1.tar.gz $ cd invenio-1.2.1 $ ./configure $ make $ make install $ make install-mathjax-plugin ## optional $ make install-jquery-plugins ## optional $ make install-ckeditor-plugin ## optional $ make install-pdfa-helper-files ## optional $ make install-mediaelement ## optional $ make install-solrutils ## optional $ make install-js-test-driver ## optional 3b. Configuration ----------------- $ sudo chown -R www-data.www-data /opt/invenio $ sudo -u www-data $EDITOR /opt/invenio/etc/invenio-local.conf $ sudo -u www-data /opt/invenio/bin/inveniocfg --update-all $ sudo -u www-data /opt/invenio/bin/inveniocfg --create-tables $ sudo -u www-data /opt/invenio/bin/inveniocfg --load-bibfield-conf $ sudo -u www-data /opt/invenio/bin/inveniocfg --load-webstat-conf $ sudo -u www-data /opt/invenio/bin/inveniocfg --create-apache-conf - $ sudo /etc/init.d/apache2 restart + $ sudo /usr/sbin/service apache2 restart $ sudo -u www-data /opt/invenio/bin/inveniocfg --check-openoffice $ sudo -u www-data /opt/invenio/bin/inveniocfg --create-demo-site $ sudo -u www-data /opt/invenio/bin/inveniocfg --load-demo-records $ sudo -u www-data /opt/invenio/bin/inveniocfg --run-unit-tests $ sudo -u www-data /opt/invenio/bin/inveniocfg --run-regression-tests $ sudo -u www-data /opt/invenio/bin/inveniocfg --run-web-tests $ sudo -u www-data /opt/invenio/bin/inveniocfg --remove-demo-records $ sudo -u www-data /opt/invenio/bin/inveniocfg --drop-demo-site $ firefox http://your.site.com/help/admin/howto-run 4. Detailed instructions for the patient Invenio admin ====================================================== 4a. Installation ---------------- The Invenio uses standard GNU autoconf method to build and install its files. This means that you proceed as follows: $ cd $HOME/src/ Change to a directory where we will build the Invenio sources. (The built files will be installed into different "target" directories later.) $ wget http://invenio-software.org/download/invenio-1.2.1.tar.gz $ wget http://invenio-software.org/download/invenio-1.2.1.tar.gz.md5 $ wget http://invenio-software.org/download/invenio-1.2.1.tar.gz.sig Fetch Invenio source tarball from the distribution server, together with MD5 checksum and GnuPG cryptographic signature files useful for verifying the integrity of the tarball. $ md5sum -c invenio-1.2.1.tar.gz.md5 Verify MD5 checksum. $ gpg --verify invenio-1.2.1.tar.gz.sig invenio-1.2.1.tar.gz Verify GnuPG cryptographic signature. Note that you may first have to import my public key into your keyring, if you haven't done that already: $ gpg --keyserver pool.sks-keyservers.net --recv-key 0xBA5A2B67 The output of the gpg --verify command should then read: Good signature from "Tibor Simko " You can safely ignore any trusted signature certification warning that may follow after the signature has been successfully verified. $ tar xvfz invenio-1.2.1.tar.gz Untar the distribution tarball. $ cd invenio-1.2.1 Go to the source directory. $ ./configure Configure Invenio software for building on this specific platform. You can use the following optional parameters: --prefix=/opt/invenio Optionally, specify the Invenio general installation directory (default is /opt/invenio). It will contain command-line binaries and program libraries containing the core Invenio functionality, but also store web pages, runtime log and cache information, document data files, etc. Several subdirs like `bin', `etc', `lib', or `var' will be created inside the prefix directory to this effect. Note that the prefix directory should be chosen outside of the Apache htdocs tree, since only one its subdirectory (prefix/var/www) is to be accessible directly via the Web (see below). Note that Invenio won't install to any other directory but to the prefix mentioned in this configuration line. --with-python=/opt/python/bin/python2.7 Optionally, specify a path to some specific Python binary. This is useful if you have more than one Python installation on your system. If you don't set this option, then the first Python that will be found in your PATH will be chosen for running Invenio. --with-mysql=/opt/mysql/bin/mysql Optionally, specify a path to some specific MySQL client binary. This is useful if you have more than one MySQL installation on your system. If you don't set this option, then the first MySQL client executable that will be found in your PATH will be chosen for running Invenio. --with-clisp=/opt/clisp/bin/clisp Optionally, specify a path to CLISP executable. This is useful if you have more than one CLISP installation on your system. If you don't set this option, then the first executable that will be found in your PATH will be chosen for running Invenio. --with-cmucl=/opt/cmucl/bin/lisp Optionally, specify a path to CMUCL executable. This is useful if you have more than one CMUCL installation on your system. If you don't set this option, then the first executable that will be found in your PATH will be chosen for running Invenio. --with-sbcl=/opt/sbcl/bin/sbcl Optionally, specify a path to SBCL executable. This is useful if you have more than one SBCL installation on your system. If you don't set this option, then the first executable that will be found in your PATH will be chosen for running Invenio. --with-openoffice-python Optionally, specify the path to the Python interpreter embedded with OpenOffice.org. This is normally not contained in the normal path. If you don't specify this it won't be possible to use OpenOffice.org to convert from and to Microsoft Office and OpenOffice.org documents. This configuration step is mandatory. Usually, you do this step only once. (Note that if you are building Invenio not from a released tarball, but from the Git sources, then you have to generate the configure file via autotools: $ sudo aptitude install automake1.9 autoconf $ aclocal-1.9 $ automake-1.9 -a $ autoconf after which you proceed with the usual configure command.) $ make Launch the Invenio build. Since many messages are printed during the build process, you may want to run it in a fast-scrolling terminal such as rxvt or in a detached screen session. During this step all the pages and scripts will be pre-created and customized based on the config you have edited in the previous step. Note that on systems such as FreeBSD or Mac OS X you have to use GNU make ("gmake") instead of "make". $ make install Install the web pages, scripts, utilities and everything needed for Invenio runtime into respective installation directories, as specified earlier by the configure command. Note that if you are installing Invenio for the first time, you will be asked to create symbolic link(s) from Python's site-packages system-wide directory(ies) to the installation location. This is in order to instruct Python where to find Invenio's Python files. You will be hinted as to the exact command to use based on the parameters you have used in the configure command. $ make install-mathjax-plugin ## optional This will automatically download and install in the proper place MathJax, a JavaScript library to render LaTeX formulas in the client browser. Note that in order to enable the rendering you will have to set the variable CFG_WEBSEARCH_USE_MATHJAX_FOR_FORMATS in invenio-local.conf to a suitable list of output format codes. For example: CFG_WEBSEARCH_USE_MATHJAX_FOR_FORMATS = hd,hb $ make install-jquery-plugins ## optional This will automatically download and install in the proper place jQuery and related plugins. They are used for AJAX applications such as the record editor. Note that `unzip' is needed when installing jquery plugins. $ make install-ckeditor-plugin ## optional This will automatically download and install in the proper place CKeditor, a WYSIWYG Javascript-based editor (e.g. for the WebComment module). Note that in order to enable the editor you have to set the CFG_WEBCOMMENT_USE_RICH_EDITOR to True. $ make install-pdfa-helper-files ## optional This will automatically download and install in the proper place the helper files needed to create PDF/A files out of existing PDF files. $ make install-mediaelement ## optional This will automatically download and install the MediaElementJS HTML5 video player that is needed for videos on the DEMO site. $ make install-solrutils ## optional This will automatically download and install a Solr instance which can be used for full-text searching. See CFG_SOLR_URL variable in the invenio.conf. Note that the admin later has to take care of running init.d scripts which would start the Solr instance automatically. $ make install-js-test-driver ## optional This will automatically download and install JsTestDriver which is needed to run JS unit tests. Recommended for developers. 4b. Configuration ----------------- Once the basic software installation is done, we proceed to configuring your Invenio system. $ sudo chown -R www-data.www-data /opt/invenio For the sake of simplicity, let us assume that your Invenio installation will run under the `www-data' user process identity. The above command changes ownership of installed files to www-data, so that we shall run everything under this user identity from now on. For production purposes, you would typically enable Apache server to read all files from the installation place but to write only to the `var' subdirectory of your installation place. You could achieve this by configuring Unix directory group permissions, for example. $ sudo -u www-data $EDITOR /opt/invenio/etc/invenio-local.conf Customize your Invenio installation. Please read the 'invenio.conf' file located in the same directory that contains the vanilla default configuration parameters of your Invenio installation. If you want to customize some of these parameters, you should create a file named 'invenio-local.conf' in the same directory where 'invenio.conf' lives and you should write there only the customizations that you want to be different from the vanilla defaults. Here is a realistic, minimalist, yet production-ready example of what you would typically put there: $ cat /opt/invenio/etc/invenio-local.conf [Invenio] CFG_SITE_NAME = John Doe's Document Server CFG_SITE_NAME_INTL_fr = Serveur des Documents de John Doe CFG_SITE_URL = http://your.site.com CFG_SITE_SECURE_URL = https://your.site.com CFG_SITE_ADMIN_EMAIL = john.doe@your.site.com CFG_SITE_SUPPORT_EMAIL = john.doe@your.site.com CFG_WEBALERT_ALERT_ENGINE_EMAIL = john.doe@your.site.com CFG_WEBCOMMENT_ALERT_ENGINE_EMAIL = john.doe@your.site.com CFG_WEBCOMMENT_DEFAULT_MODERATOR = john.doe@your.site.com CFG_BIBAUTHORID_AUTHOR_TICKET_ADMIN_EMAIL = john.doe@your.site.com CFG_BIBCATALOG_SYSTEM_EMAIL_ADDRESS = john.doe@your.site.com CFG_DATABASE_HOST = localhost CFG_DATABASE_NAME = invenio CFG_DATABASE_USER = invenio CFG_DATABASE_PASS = my123p$ss CFG_BIBDOCFILE_ENABLE_BIBDOCFSINFO_CACHE = 1 You should override at least the parameters mentioned above in order to define some very essential runtime parameters such as the name of your document server (CFG_SITE_NAME and CFG_SITE_NAME_INTL_*), the visible URL of your document server (CFG_SITE_URL and CFG_SITE_SECURE_URL), the email address of the local Invenio administrator, comment moderator, and alert engine (CFG_SITE_SUPPORT_EMAIL, CFG_SITE_ADMIN_EMAIL, etc), and last but not least your database credentials (CFG_DATABASE_*). If this is a first installation of Invenio it is recommended you set the CFG_BIBDOCFILE_ENABLE_BIBDOCFSINFO_CACHE variable to 1. If this is instead an upgrade from an existing installation don't add it until you have run: $ bibdocfile --fix-bibdocfsinfo-cache . The Invenio system will then read both the default invenio.conf file and your customized invenio-local.conf file and it will override any default options with the ones you have specifield in your local file. This cascading of configuration parameters will ease your future upgrades. If you want to have multiple Invenio instances for distributed video encoding, you need to share the same configuration amongs them and make some of the folders of the Invenio installation available for all nodes. Configure the allowed tasks for every node: CFG_BIBSCHED_NODE_TASKS = { "hostname_machine1" : ["bibindex", "bibupload", "bibreformat","webcoll", "bibtaskex", "bibrank", "oaiharvest", "oairepositoryupdater", "inveniogc", "webstatadmin", "bibclassify", "bibexport", "dbdump", "batchuploader", "bibauthorid", "bibtasklet"], "hostname_machine2" : ['bibencode',] } Share the following directories among Invenio instances: /var/tmp-shared hosts video uploads in a temporary form /var/tmp-shared/bibencode/jobs hosts new job files for the video encoding daemon /var/tmp-shared/bibencode/jobs/done hosts job files that have been processed by the daemon /var/data/files hosts fulltext and media files associated to records /var/data/submit hosts files created during submissions $ sudo -u www-data /opt/invenio/bin/inveniocfg --update-all Make the rest of the Invenio system aware of your invenio-local.conf changes. This step is mandatory each time you edit your conf files. $ sudo -u www-data /opt/invenio/bin/inveniocfg --create-tables If you are installing Invenio for the first time, you have to create database tables. Note that this step checks for potential problems such as the database connection rights and may ask you to perform some more administrative steps in case it detects a problem. Notably, it may ask you to set up database access permissions, based on your configure values. If you are installing Invenio for the first time, you have to create a dedicated database on your MySQL server that the Invenio can use for its purposes. Please contact your MySQL administrator and ask him to execute the commands this step proposes you. At this point you should now have successfully completed the "make install" process. We continue by setting up the Apache web server. $ sudo -u www-data /opt/invenio/bin/inveniocfg --load-bibfield-conf Load the configuration file of the BibField module. It will create `bibfield_config.py' file. (FIXME: When BibField becomes essential part of Invenio, this step should be later automatised so that people do not have to run it manually.) $ sudo -u www-data /opt/invenio/bin/inveniocfg --load-webstat-conf Load the configuration file of webstat module. It will create the tables in the database for register customevents, such as basket hits. $ sudo -u www-data /opt/invenio/bin/inveniocfg --create-apache-conf Running this command will generate Apache virtual host configurations matching your installation. You will be instructed to check created files (usually they are located under /opt/invenio/etc/apache/) and edit your httpd.conf to activate Invenio virtual hosts. If you are using Debian GNU/Linux ``Lenny'' or later, then you can do the following to create your SSL certificate and to activate your Invenio vhosts: ## make SSL certificate: $ sudo aptitude install ssl-cert $ sudo mkdir /etc/apache2/ssl $ sudo /usr/sbin/make-ssl-cert /usr/share/ssl-cert/ssleay.cnf \ /etc/apache2/ssl/apache.pem ## add Invenio web sites: $ sudo ln -s /opt/invenio/etc/apache/invenio-apache-vhost.conf \ /etc/apache2/sites-available/invenio $ sudo ln -s /opt/invenio/etc/apache/invenio-apache-vhost-ssl.conf \ /etc/apache2/sites-available/invenio-ssl ## disable Debian's default web site: $ sudo /usr/sbin/a2dissite default ## enable Invenio web sites: $ sudo /usr/sbin/a2ensite invenio $ sudo /usr/sbin/a2ensite invenio-ssl ## enable SSL module: $ sudo /usr/sbin/a2enmod ssl ## if you are using xsendfile module, enable it too: $ sudo /usr/sbin/a2enmod xsendfile If you are using another operating system, you should do the equivalent, for example edit your system-wide httpd.conf and put the following include statements: Include /opt/invenio/etc/apache/invenio-apache-vhost.conf Include /opt/invenio/etc/apache/invenio-apache-vhost-ssl.conf Note that you may need to adapt generated vhost file snippets to match your concrete operating system specifics. For example, the generated configuration snippet will preload Invenio WSGI daemon application upon Apache start up for faster site response. The generated configuration assumes that you are using mod_wsgi version 3 or later. If you are using the old legacy mod_wsgi version 2, then you would need to comment out the WSGIImportScript directive from the generated snippet, or else move the WSGI daemon setup to the top level, outside of the VirtualHost section. Note also that you may want to tweak the generated Apache vhost snippet for performance reasons, especially with respect to WSGIDaemonProcess parameters. For example, you can increase the number of processes from the default value `processes=5' if you have lots of RAM and if many concurrent users may access your site in parallel. However, note that you must use `threads=1' there, because Invenio WSGI daemon processes are not fully thread safe yet. This may change in the future. - $ sudo /etc/init.d/apache2 restart + $ sudo /usr/sbin/service apache2 restart Please ask your webserver administrator to restart the Apache server after the above "httpd.conf" changes. $ sudo -u www-data /opt/invenio/bin/inveniocfg --check-openoffice If you plan to support MS Office or Open Document Format files in your installation, you should check whether LibreOffice or OpenOffice.org is well integrated with Invenio by running the above command. You may be asked to create a temporary directory for converting office files with special ownership (typically as user nobody) and permissions. Note that you can do this step later. $ sudo -u www-data /opt/invenio/bin/inveniocfg --create-demo-site This step is recommended to test your local Invenio installation. It should give you our "Atlantis Institute of Science" demo installation, exactly as you see it at . $ sudo -u www-data /opt/invenio/bin/inveniocfg --load-demo-records Optionally, load some demo records to be able to test indexing and searching of your local Invenio demo installation. $ sudo -u www-data /opt/invenio/bin/inveniocfg --run-unit-tests Optionally, you can run the unit test suite to verify the unit behaviour of your local Invenio installation. Note that this command should be run only after you have installed the whole system via `make install'. $ sudo -u www-data /opt/invenio/bin/inveniocfg --run-regression-tests Optionally, you can run the full regression test suite to verify the functional behaviour of your local Invenio installation. Note that this command requires to have created the demo site and loaded the demo records. Note also that running the regression test suite may alter the database content with junk data, so that rebuilding the demo site is strongly recommended afterwards. $ sudo -u www-data /opt/invenio/bin/inveniocfg --run-web-tests Optionally, you can run additional automated web tests running in a real browser. This requires to have Firefox with the Selenium IDE extension installed. $ sudo -u www-data /opt/invenio/bin/inveniocfg --remove-demo-records Optionally, remove the demo records loaded in the previous step, but keeping otherwise the demo collection, submission, format, and other configurations that you may reuse and modify for your own production purposes. $ sudo -u www-data /opt/invenio/bin/inveniocfg --drop-demo-site Optionally, drop also all the demo configuration so that you'll end up with a completely blank Invenio system. However, you may want to find it more practical not to drop the demo site configuration but to start customizing from there. $ firefox http://your.site.com/help/admin/howto-run In order to start using your Invenio installation, you can start indexing, formatting and other daemons as indicated in the "HOWTO Run" guide on the above URL. You can also use the Admin Area web interfaces to perform further runtime configurations such as the definition of data collections, document types, document formats, word indexes, etc. $ sudo ln -s /opt/invenio/etc/bash_completion.d/inveniocfg \ /etc/bash_completion.d/inveniocfg Optionally, if you are using Bash shell completion, then you may want to create the above symlink in order to configure completion for the inveniocfg command. Happy hacking and thanks for flying Invenio. - Invenio Development Team Email: info@invenio-software.org IRC: #invenio on irc.freenode.net Twitter: http://twitter.com/inveniosoftware Github: http://github.com/inveniosoftware URL: http://invenio-software.org diff --git a/Vagrantfile b/Vagrantfile index 3d5359b0a..049660b10 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -1,68 +1,71 @@ # -*- coding: utf-8 -*- # # This file is part of Invenio. # Copyright (C) 2016 CERN. # # Invenio is free software; you can redistribute it # and/or modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of the # License, or (at your option) any later version. # # Invenio 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Invenio; if not, write to the # Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, # MA 02111-1307, USA. # # In applying this license, CERN does not # waive the privileges and immunities granted to it by virtue of its status # as an Intergovernmental Organization or submit itself to any jurisdiction. # This Vagrant configuration is suitable for Invenio demo site installation as # governed by `.inveniorc`. It uses separate dedicated VMs for various services # in order to better emulate production environment conditions. You can install # an Invenio demo site by running: # # $ vagrant up --no-parallel # $ vagrant ssh web -c 'source .inveniorc && /vagrant/scripts/create-instance.sh' # $ vagrant ssh web -c 'source .inveniorc && /vagrant/scripts/populate-instance.sh' # $ firefox http://192.168.50.10/record/1 # $ vagrant ssh web -c 'source .inveniorc && sudo -u www-data /opt/invenio/bin/inveniocfg --run-unit-tests' # $ vagrant ssh web -c 'source .inveniorc && sudo -u www-data /opt/invenio/bin/inveniocfg --run-regression-tests --yes-i-know' -#OS = 'hfm4/centos6' -OS = 'ubuntu/precise64' +# Tested on: +# +# OS = 'hfm4/centos6' # CentOS 6 +# OS = 'ubuntu/precise64' # Ubuntu 12.04 LTS Precise Pangolin -- used by Travis CI +OS = 'ubuntu/trusty64' # Ubuntu 14.04 LTS Trusty Tahr Vagrant.configure("2") do |config| if Vagrant.has_plugin?("vagrant-cachier") config.cache.scope = :box end config.vm.define "web" do |web| web.vm.box = OS web.vm.hostname = 'web' web.vm.provision "file", source: ".inveniorc", destination: ".inveniorc" web.vm.provision "shell", inline: "source .inveniorc && /vagrant/scripts/provision-web.sh", privileged: false web.vm.network "forwarded_port", guest: 80, host: 80 web.vm.network "forwarded_port", guest: 443, host: 443 web.vm.network "private_network", ip: ENV.fetch('INVENIO_WEB_HOST','192.168.50.10') web.vm.provider :virtualbox do |vb| vb.customize ["modifyvm", :id, "--memory", "4096"] vb.customize ["modifyvm", :id, "--cpus", 2] end end config.vm.define "mysql" do |mysql| mysql.vm.box = OS mysql.vm.hostname = 'mysql' mysql.vm.provision "file", source: ".inveniorc", destination: ".inveniorc" mysql.vm.provision "shell", inline: "source .inveniorc && /vagrant/scripts/provision-mysql.sh", privileged: false mysql.vm.network "private_network", ip: ENV.fetch('INVENIO_MYSQL_HOST','192.168.50.11') end end diff --git a/modules/bibcatalog/lib/bibcatalog_system_email_unit_tests.py b/modules/bibcatalog/lib/bibcatalog_system_email_unit_tests.py index 71951d371..4def2daf4 100644 --- a/modules/bibcatalog/lib/bibcatalog_system_email_unit_tests.py +++ b/modules/bibcatalog/lib/bibcatalog_system_email_unit_tests.py @@ -1,87 +1,92 @@ # -*- coding: utf-8 -*- # # This file is part of Invenio. -# Copyright (C) 2008, 2009, 2010, 2011, 2013 CERN. +# Copyright (C) 2008, 2009, 2010, 2011, 2013, 2016 CERN. # # Invenio is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of the # License, or (at your option) any later version. # # Invenio 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Invenio; if not, write to the Free Software Foundation, Inc., # 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. """Unit tests for bibcatalog_system_email library.""" from invenio.testutils import InvenioTestCase -from invenio.config import CFG_SITE_SUPPORT_EMAIL +from invenio.config import CFG_SITE_SUPPORT_EMAIL, CFG_MISCUTIL_SMTP_PORT from invenio.testutils import make_test_suite, run_test_suite from invenio import bibcatalog_system_email -class BibCatalogSystemEmailTest(InvenioTestCase): - """Testing of BibCatalog.""" +if CFG_MISCUTIL_SMTP_PORT: + class BibCatalogSystemEmailTest(InvenioTestCase): + """Testing of BibCatalog.""" - def setUp(self): - self.email = bibcatalog_system_email.BibCatalogSystemEmail() - bibcatalog_system_email.CFG_BIBCATALOG_SYSTEM_TICKETS_EMAIL = CFG_SITE_SUPPORT_EMAIL - bibcatalog_system_email.CFG_BIBCATALOG_SYSTEM = 'EMAIL' - pass + def setUp(self): + self.email = bibcatalog_system_email.BibCatalogSystemEmail() + bibcatalog_system_email.CFG_BIBCATALOG_SYSTEM_TICKETS_EMAIL = CFG_SITE_SUPPORT_EMAIL + bibcatalog_system_email.CFG_BIBCATALOG_SYSTEM = 'EMAIL' + pass - def tearDown(self): - pass + def tearDown(self): + pass - def test_email_ticket_search_exception_not_implemented(self): - """bibcatalog_system_email - execution raises NotImplementedError exception""" + def test_email_ticket_search_exception_not_implemented(self): + """bibcatalog_system_email - execution raises NotImplementedError exception""" - self.assertRaises(NotImplementedError, self.email.ticket_search, 1) + self.assertRaises(NotImplementedError, self.email.ticket_search, 1) - def test_ticket_submit_via_email(self): - """bibcatalog_system_email - test creating ticket via email""" + def test_ticket_submit_via_email(self): + """bibcatalog_system_email - test creating ticket via email""" - # TODO: our return values are ticket id or none; check both cases - self.assertTrue(self.email.ticket_submit(subject="Issue with RT", text="The RT system is not as good as the email ticketing", owner='eduardo', priority=3, queue='TEST', requestor='Joeb', recordid=100)) + # TODO: our return values are ticket id or none; check both cases + self.assertTrue(self.email.ticket_submit(subject="Issue with RT", text="The RT system is not as good as the email ticketing", owner='eduardo', priority=3, queue='TEST', requestor='Joeb', recordid=100)) - def test_ticket_comment_via_email(self): - """bibcatalog_system_email - test commention on ticket via email""" + def test_ticket_comment_via_email(self): + """bibcatalog_system_email - test commention on ticket via email""" - self.assertTrue(self.email.ticket_comment(uid=1, ticketid='d834bnklca', comment='Eduardo is commenting on ticket blah, blah, blah')) + self.assertTrue(self.email.ticket_comment(uid=1, ticketid='d834bnklca', comment='Eduardo is commenting on ticket blah, blah, blah')) - def test_ticket_assign_via_email(self): - """bibcatalog_system_email - test commention on ticket via email""" + def test_ticket_assign_via_email(self): + """bibcatalog_system_email - test commention on ticket via email""" - self.assertTrue(self.email.ticket_assign(uid=1, ticketid='d834bnklca', to_user='jrbl')) + self.assertTrue(self.email.ticket_assign(uid=1, ticketid='d834bnklca', to_user='jrbl')) - def test_ticket_set_attribute_via_email(self): - """bibcatalog_system_email - test setting attribute on ticket via email""" + def test_ticket_set_attribute_via_email(self): + """bibcatalog_system_email - test setting attribute on ticket via email""" - self.assertTrue(self.email.ticket_set_attribute(uid=1, ticketid='d834bnklca', attribute='priority', new_value='1')) + self.assertTrue(self.email.ticket_set_attribute(uid=1, ticketid='d834bnklca', attribute='priority', new_value='1')) - def test_ckeck_system(self): - """bibcatalog_system_email - check_system returns true if succesfull, a message otherwise""" + def test_ckeck_system(self): + """bibcatalog_system_email - check_system returns true if succesfull, a message otherwise""" - self.assertEqual(self.email.check_system(), '') + self.assertEqual(self.email.check_system(), '') - def test_ticket_get_info(self): - """bibcatalog_system_email - ticket_get_info raises NotImplementedError exception""" + def test_ticket_get_info(self): + """bibcatalog_system_email - ticket_get_info raises NotImplementedError exception""" - self.assertRaises(NotImplementedError, self.email.ticket_get_info, uid=1, ticketid=0) + self.assertRaises(NotImplementedError, self.email.ticket_get_info, uid=1, ticketid=0) +else: + # SMTP server is not available. let's skip this test + class BibCatalogSystemEmailTest(InvenioTestCase): + pass TEST_SUITE = make_test_suite(BibCatalogSystemEmailTest) if __name__ == "__main__": run_test_suite(TEST_SUITE) diff --git a/modules/websearch/lib/websearch_regression_tests.py b/modules/websearch/lib/websearch_regression_tests.py index 4486a612e..d6ffbde7f 100644 --- a/modules/websearch/lib/websearch_regression_tests.py +++ b/modules/websearch/lib/websearch_regression_tests.py @@ -1,5161 +1,5160 @@ # -*- coding: utf-8 -*- # # This file is part of Invenio. -# Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015 CERN. +# Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 CERN. # # Invenio is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of the # License, or (at your option) any later version. # # Invenio 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Invenio; if not, write to the Free Software Foundation, Inc., # 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. # pylint: disable=C0301 # pylint: disable=E1102 """WebSearch module regression tests.""" __revision__ = "$Id$" from invenio.testutils import InvenioTestCase, InvenioXmlTestCase import re import urlparse, cgi import sys import cStringIO if sys.hexversion < 0x2040000: # pylint: disable=W0622 from sets import Set as set # pylint: enable=W0622 from mechanize import Browser, LinkNotFoundError from invenio.config import (CFG_SITE_URL, CFG_SITE_NAME, CFG_SITE_LANG, CFG_SITE_RECORD, CFG_SITE_LANGS, CFG_SITE_SECURE_URL, CFG_WEBSEARCH_SPIRES_SYNTAX, CFG_BASE_URL) from invenio.testutils import (make_test_suite, run_test_suite, nottest, make_url, make_surl, make_rurl, test_web_page_content, merge_error_messages, InvenioXmlTestCase) from invenio.urlutils import same_urls_p from invenio.dbquery import run_sql from invenio.webinterface_handler_wsgi import SimulatedModPythonRequest from invenio.search_engine import perform_request_search, \ guess_primary_collection_of_a_record, guess_collection_of_a_record, \ collection_restricted_p, get_permitted_restricted_collections, \ search_pattern, search_unit, search_unit_in_bibrec, \ wash_colls, record_public_p from invenio import search_engine_summarizer from invenio.search_engine_utils import get_fieldvalues from invenio.intbitset import intbitset from invenio.search_engine import intersect_results_with_collrecs from invenio.bibrank_bridge_utils import get_external_word_similarity_ranker from invenio.search_engine_query_parser_unit_tests import DATEUTIL_AVAILABLE from invenio.bibindex_engine_utils import get_index_tags from invenio.bibindex_engine_config import CFG_BIBINDEX_INDEX_TABLE_TYPE if 'fr' in CFG_SITE_LANGS: lang_french_configured = True else: lang_french_configured = False def parse_url(url): parts = urlparse.urlparse(url) query = cgi.parse_qs(parts[4], True) return parts[2].split('/')[1:], query def string_combinations(str_list): """Returns all the possible combinations of the strings in the list. Example: for the list ['A','B','Cd'], it will return [['Cd', 'B', 'A'], ['B', 'A'], ['Cd', 'A'], ['A'], ['Cd', 'B'], ['B'], ['Cd'], []] It adds "B", "H", "F" and "S" values to the results so different combinations of them are also checked. """ out_list = [] for i in range(len(str_list) + 1): out_list += list(combinations(str_list, i)) for i in range(len(out_list)): out_list[i] = (list(out_list[i]) + { 0: lambda: ["B", "H", "S"], 1: lambda: ["B", "H", "F"], 2: lambda: ["B", "F", "S"], 3: lambda: ["B", "F"], 4: lambda: ["B", "S"], 5: lambda: ["B", "H"], 6: lambda: ["B"] }[i % 7]()) return out_list def combinations(iterable, r): """Return r length subsequences of elements from the input iterable.""" # combinations('ABCD', 2) --> AB AC AD BC BD CD # combinations(range(4), 3) --> 012 013 023 123 pool = tuple(iterable) n = len(pool) if r > n: return indices = range(r) yield tuple(pool[i] for i in indices) while True: for i in reversed(range(r)): if indices[i] != i + n - r: break else: return indices[i] += 1 for j in range(i+1, r): indices[j] = indices[j-1] + 1 yield tuple(pool[i] for i in indices) class WebSearchWebPagesAvailabilityTest(InvenioTestCase): """Check WebSearch web pages whether they are up or not.""" def test_search_interface_pages_availability(self): """websearch - availability of search interface pages""" baseurl = CFG_SITE_URL + '/' _exports = ['', 'collection/Poetry', 'collection/Poetry?as=1'] error_messages = [] for url in [baseurl + page for page in _exports]: error_messages.extend(test_web_page_content(url)) if error_messages: self.fail(merge_error_messages(error_messages)) return def test_search_results_pages_availability(self): """websearch - availability of search results pages""" baseurl = CFG_SITE_URL + '/search' _exports = ['', '?c=Poetry', '?p=ellis', '/cache', '/log'] error_messages = [] for url in [baseurl + page for page in _exports]: error_messages.extend(test_web_page_content(url)) if error_messages: self.fail(merge_error_messages(error_messages)) return def test_search_detailed_record_pages_availability(self): """websearch - availability of search detailed record pages""" baseurl = CFG_SITE_URL + '/'+ CFG_SITE_RECORD +'/' _exports = ['', '1', '1/', '1/files', '1/files/'] error_messages = [] for url in [baseurl + page for page in _exports]: error_messages.extend(test_web_page_content(url)) if error_messages: self.fail(merge_error_messages(error_messages)) return def test_browse_results_pages_availability(self): """websearch - availability of browse results pages""" baseurl = CFG_SITE_URL + '/search' _exports = ['?p=ellis&f=author&action_browse=Browse'] error_messages = [] for url in [baseurl + page for page in _exports]: error_messages.extend(test_web_page_content(url)) if error_messages: self.fail(merge_error_messages(error_messages)) return def test_help_page_availability(self): """websearch - availability of Help Central page""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/help', expected_text="Help Central")) if lang_french_configured: def test_help_page_availability_fr(self): """websearch - availability of Help Central page in french""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/help/?ln=fr', expected_text="Centre d'aide")) def test_search_tips_page_availability(self): """websearch - availability of Search Tips""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/help/search-tips', expected_text="Search Tips")) if lang_french_configured: def test_search_tips_page_availability_fr(self): """websearch - availability of Search Tips in french""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/help/search-tips?ln=fr', expected_text="Conseils de recherche")) def test_search_guide_page_availability(self): """websearch - availability of Search Guide""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/help/search-guide', expected_text="Search Guide")) if lang_french_configured: def test_search_guide_page_availability_fr(self): """websearch - availability of Search Guide in french""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/help/search-guide?ln=fr', expected_text="Guide de recherche")) class WebSearchTestLegacyURLs(InvenioTestCase): """ Check that the application still responds to legacy URLs for navigating, searching and browsing.""" def test_legacy_collections(self): """ websearch - collections handle legacy urls """ browser = Browser() def check(legacy, new, browser=browser): browser.open(legacy) got = browser.geturl() self.failUnless(same_urls_p(got, new), got) # Use the root URL unless we need more check(make_url('/', c=CFG_SITE_NAME), make_url('/', ln=CFG_SITE_LANG)) # Other collections are redirected in the /collection area check(make_url('/', c='Poetry'), make_url('/collection/Poetry', ln=CFG_SITE_LANG)) # Drop unnecessary arguments, like ln and as (when they are # the default value) from invenio.config import CFG_WEBSEARCH_DEFAULT_SEARCH_INTERFACE from invenio.search_engine_config import CFG_WEBSEARCH_ENABLED_SEARCH_INTERFACES args = {'as': CFG_WEBSEARCH_DEFAULT_SEARCH_INTERFACE} check(make_url('/', c='Poetry', **args), make_url('/collection/Poetry', ln=CFG_SITE_LANG)) # Otherwise, keep them as_arg = [as_arg for as_arg in CFG_WEBSEARCH_ENABLED_SEARCH_INTERFACES if as_arg != CFG_WEBSEARCH_DEFAULT_SEARCH_INTERFACE][0] args = {'as': 1, 'ln': CFG_SITE_LANG} check(make_url('/', c='Poetry', **args), make_url('/collection/Poetry', **args)) # Support the /index.py addressing too check(make_url('/index.py', c='Poetry'), make_url('/collection/Poetry', ln=CFG_SITE_LANG)) def test_legacy_search(self): """ websearch - search queries handle legacy urls """ browser = Browser() def check(legacy, new, browser=browser): browser.open(legacy) got = browser.geturl() self.failUnless(same_urls_p(got, new), got) # /search.py is redirected on /search # Note that `as' is a reserved word in Python 2.5 check(make_url('/search.py', p='nuclear', ln='en') + 'as=1', make_url('/search', p='nuclear', ln='en') + 'as=1') if lang_french_configured: def test_legacy_search_fr(self): """ websearch - search queries handle legacy urls """ browser = Browser() def check(legacy, new, browser=browser): browser.open(legacy) got = browser.geturl() self.failUnless(same_urls_p(got, new), got) # direct recid searches are redirected to /CFG_SITE_RECORD check(make_url('/search.py', recid=1, ln='fr'), make_url('/%s/1' % CFG_SITE_RECORD, ln='fr')) def test_legacy_search_help_link(self): """websearch - legacy Search Help page link""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/help/search/index.en.html', expected_text="Help Central")) if lang_french_configured: def test_legacy_search_tips_link(self): """websearch - legacy Search Tips page link""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/help/search/tips.fr.html', expected_text="Conseils de recherche")) def test_legacy_search_guide_link(self): """websearch - legacy Search Guide page link""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/help/search/guide.en.html', expected_text="Search Guide")) class WebSearchTestRecord(InvenioTestCase): """ Check the interface of the /CFG_SITE_RECORD results """ def test_format_links(self): """ websearch - check format links for records """ browser = Browser() # We open the record in all known HTML formats for hformat in ('hd', 'hx', 'hm'): browser.open(make_url('/%s/1' % CFG_SITE_RECORD, of=hformat)) if hformat == 'hd': # hd format should have a link to the following # formats for oformat in ('hx', 'hm', 'xm', 'xd'): target = '%s/%s/1/export/%s?ln=en' % \ (CFG_BASE_URL, CFG_SITE_RECORD, oformat) try: browser.find_link(url=target) except LinkNotFoundError: self.fail('link %r should be in page' % target) else: # non-hd HTML formats should have a link back to # the main detailed record target = '%s/%s/1' % (CFG_BASE_URL, CFG_SITE_RECORD) try: browser.find_link(url=target) except LinkNotFoundError: self.fail('link %r should be in page' % target) return def test_exported_formats(self): """ websearch - check formats exported through /CFG_SITE_RECORD/1/export/ URLs""" self.assertEqual([], test_web_page_content(make_url('/%s/1/export/hm' % CFG_SITE_RECORD), expected_text='245__ $$aALEPH experiment')) self.assertEqual([], test_web_page_content(make_url('/%s/1/export/hd' % CFG_SITE_RECORD), expected_text='ALEPH experiment')) self.assertEqual([], test_web_page_content(make_url('/%s/1/export/xm' % CFG_SITE_RECORD), expected_text='ALEPH experiment')) self.assertEqual([], test_web_page_content(make_url('/%s/1/export/xd' % CFG_SITE_RECORD), expected_text='ALEPH experiment')) self.assertEqual([], test_web_page_content(make_url('/%s/1/export/hs' % CFG_SITE_RECORD), expected_text='ALEPH experiment' % \ (CFG_SITE_RECORD, CFG_SITE_LANG))) self.assertEqual([], test_web_page_content(make_url('/%s/1/export/hx' % CFG_SITE_RECORD), expected_text='title = "{ALEPH experiment')) self.assertEqual([], test_web_page_content(make_url('/%s/1/export/t?ot=245' % CFG_SITE_RECORD), expected_text='245__ $$aALEPH experiment')) self.assertNotEqual([], test_web_page_content(make_url('/%s/1/export/t?ot=245' % CFG_SITE_RECORD), expected_text='001__')) self.assertEqual([], test_web_page_content(make_url('/%s/1/export/h?ot=245' % CFG_SITE_RECORD), expected_text='245__ $$aALEPH experiment')) self.assertNotEqual([], test_web_page_content(make_url('/%s/1/export/h?ot=245' % CFG_SITE_RECORD), expected_text='001__')) return def test_plots_tab(self): """ websearch - test to ensure the plots tab is working """ self.assertEqual([], test_web_page_content(make_url('/%s/8/plots' % CFG_SITE_RECORD), expected_text='div id="clip"', unexpected_text='Abstract')) def test_meta_header(self): """ websearch - test that metadata embedded in header of hd relies on hdm format and Default_HTML_meta bft, but hook is in websearch to display the format """ self.assertEqual([], test_web_page_content(make_url('/record/1'), expected_text='')) return class WebSearchTestCollections(InvenioTestCase): def test_traversal_links(self): """ websearch - traverse all the publications of a collection """ browser = Browser() from invenio.config import CFG_WEBSEARCH_DEFAULT_SEARCH_INTERFACE from invenio.search_engine_config import \ CFG_WEBSEARCH_ENABLED_SEARCH_INTERFACES try: for aas in CFG_WEBSEARCH_ENABLED_SEARCH_INTERFACES: args = {'as': aas} browser.open(make_url('/collection/Preprints', **args)) for jrec in (11, 21, 11, 27): args = {'jrec': jrec, 'cc': 'Preprints'} if aas != CFG_WEBSEARCH_DEFAULT_SEARCH_INTERFACE: args['as'] = aas url = make_rurl('/search', **args) try: browser.follow_link(url=url) except LinkNotFoundError: args['ln'] = CFG_SITE_LANG url = make_rurl('/search', **args) browser.follow_link(url=url) except LinkNotFoundError: self.fail('no link %r in %r' % (url, browser.geturl())) def test_collections_links(self): """ websearch - enter in collections and subcollections """ browser = Browser() def tryfollow(url): cur = browser.geturl() body = browser.response().read() try: browser.follow_link(url=url) except LinkNotFoundError: print body self.fail("in %r: could not find %r" % ( cur, url)) return for aas in (0, 1): if aas: kargs = {'as': 1} else: kargs = {} kargs['ln'] = CFG_SITE_LANG # We navigate from immediate son to immediate son... browser.open(make_url('/', **kargs)) tryfollow(make_rurl('/collection/Articles%20%26%20Preprints', **kargs)) tryfollow(make_rurl('/collection/Articles', **kargs)) # But we can also jump to a grandson immediately browser.back() browser.back() tryfollow(make_rurl('/collection/ALEPH', **kargs)) return def test_records_links(self): """ websearch - check the links toward records in leaf collections """ browser = Browser() browser.open(make_url('/collection/Preprints')) def harvest(): """ Parse all the links in the page, and check that for each link to a detailed record, we also have the corresponding link to the similar records.""" records = set() similar = set() for link in browser.links(): path, q = parse_url(link.url) if not path: continue if path[0] == CFG_SITE_RECORD: records.add(int(path[1])) continue if path[0] == 'search': if not q.get('rm') == ['wrd']: continue recid = q['p'][0].split(':')[1] similar.add(int(recid)) self.failUnlessEqual(records, similar) return records # We must have 10 links to the corresponding /CFG_SITE_RECORD found = harvest() self.failUnlessEqual(len(found), 10) # When clicking on the "Search" button, we must also have # these 10 links on the records. browser.select_form(name="search") browser.submit() found = harvest() self.failUnlessEqual(len(found), 10) return def test_em_parameter(self): """ websearch - check different values of em return different parts of the collection page""" for combi in string_combinations(["L", "P", "Prt"]): url = '/collection/Articles?em=%s' % ','.join(combi) expected_text = ["Development of photon beam diagnostics for VUV radiation from a SASE FEL"] unexpected_text = [] if "H" in combi: expected_text.append(">Atlantis Institute of Fictive Science") else: unexpected_text.append(">Atlantis Institute of Fictive Science") if "F" in combi: expected_text.append("This site is also available in the following languages:") else: unexpected_text.append("This site is also available in the following languages:") if "S" in combi: expected_text.append('value="Search"') else: unexpected_text.append('value="Search"') if "L" in combi: expected_text.append('Search also:') else: unexpected_text.append('Search also:') if "Prt" in combi or "P" in combi: expected_text.append('
ABOUT ARTICLES
') else: unexpected_text.append('
ABOUT ARTICLES
') self.assertEqual([], test_web_page_content(make_url(url), expected_text=expected_text, unexpected_text=unexpected_text)) def test_canonical_and_alternate_urls_quoting(self): """ websearch - check that canonical and alternate URL in collection page header are properly quoted""" url = CFG_SITE_URL + '/collection/Experimental%20Physics%20%28EP%29?ln=en' expected_text = ['', ''] unexpected_text = ['', ''] self.assertEqual([], test_web_page_content(url, expected_text=expected_text, unexpected_text=unexpected_text)) class WebSearchTestBrowse(InvenioTestCase): def test_browse_field(self): """ websearch - check that browsing works """ browser = Browser() args = {'as': 0, 'ln': 'en'} browser.open(make_url('/', **args)) browser.select_form(name='search') browser['f'] = ['title'] browser.submit(name='action_browse') def collect(): # We'll get a few links to search for the actual hits, plus a # link to the following results. res = [] for link in browser.links(): if not link.url.startswith("%s/search" % (CFG_BASE_URL,)): continue if "as=1" in link.url or "action=browse" in link.url: continue for attr in link.attrs: if "class" in attr: break else: dummy, q = parse_url(link.url) res.append((link, q)) return res # Here we should have 4 links to different records batch_1 = collect() self.assertEqual(4, len(batch_1)) # if we follow the next link, we should get another # batch of 4. There is an overlap of one item. next_link = [l for l in browser.links() if l.text == "next"][0] browser.follow_link(link=next_link) batch_2 = collect() self.assertEqual(8, len(batch_2)) # FIXME: we cannot compare the whole query, as the collection # set is not equal # Expecting "A naturalist\'s voyage around the world" # Last link in batch_1 should equal the 4th link in batch_2 self.failUnlessEqual(batch_1[-1][1]['p'], batch_2[3][1]['p']) def test_browse_restricted_record_as_unauthorized_user(self): """websearch - browse for a record that belongs to a restricted collection as an unauthorized user.""" error_messages = test_web_page_content(CFG_SITE_URL + '/search?p=CERN-THESIS-99-074&f=088__a&action_browse=Browse&ln=en', username = 'guest', expected_text = ['Hits', '088__a'], unexpected_text = ['>CERN-THESIS-99-074']) if error_messages: self.fail(merge_error_messages(error_messages)) def test_browse_restricted_record_as_unauthorized_user_in_restricted_collection(self): """websearch - browse for a record that belongs to a restricted collection as an unauthorized user.""" error_messages = test_web_page_content(CFG_SITE_URL + '/search?p=CERN-THESIS-99-074&f=088__a&action_browse=Browse&c=ALEPH+Theses&ln=en', username='guest', expected_text= ['This collection is restricted'], unexpected_text= ['Hits', '>CERN-THESIS-99-074']) if error_messages: self.fail(merge_error_messages(error_messages)) def test_browse_restricted_record_as_authorized_user(self): """websearch - browse for a record that belongs to a restricted collection as an authorized user.""" error_messages = test_web_page_content(CFG_SITE_URL + '/search?p=CERN-THESIS-99-074&f=088__a&action_browse=Browse&ln=en', username='admin', password='', expected_text= ['Hits', '088__a'], unexpected_text = ['>CERN-THESIS-99-074']) if error_messages: self.fail(merge_error_messages(error_messages)) def test_browse_restricted_record_as_authorized_user_in_restricted_collection(self): """websearch - browse for a record that belongs to a restricted collection as an authorized user.""" error_messages = test_web_page_content(CFG_SITE_URL + '/search?p=CERN-THESIS-99-074&f=088__a&action_browse=Browse&c=ALEPH+Theses&ln=en', username='admin', password='', expected_text= ['Hits', '>CERN-THESIS-99-074']) if error_messages: self.fail(merge_error_messages(error_messages)) def test_browse_exact_author_help_link(self): error_messages = test_web_page_content(CFG_SITE_URL + '/search?ln=en&p=Dasse%2C+Michel&f=author&action_browse=Browse', username = 'guest', expected_text = ['Did you mean to browse in', 'index?']) if error_messages: self.fail(merge_error_messages(error_messages)) error_messages = test_web_page_content(CFG_SITE_URL + '/search?ln=en&p=Dasse%2C+Michel&f=firstauthor&action_browse=Browse', username = 'guest', expected_text = ['Did you mean to browse in', 'index?']) if error_messages: self.fail(merge_error_messages(error_messages)) error_messages = test_web_page_content(CFG_SITE_URL + '/search?ln=en&as=1&m1=a&p1=Dasse%2C+Michel&f1=author&op1=a&m2=a&p2=&f2=firstauthor&op2=a&m3=a&p3=&f3=&action_browse=Browse', username = 'guest', expected_text = ['Did you mean to browse in', 'index?']) if error_messages: self.fail(merge_error_messages(error_messages)) class WebSearchTestOpenURL(InvenioTestCase): def test_isbn_01(self): """ websearch - isbn query via OpenURL 0.1""" browser = Browser() # We do a precise search in an isolated collection browser.open(make_url('/openurl', isbn='0387940758')) dummy, current_q = parse_url(browser.geturl()) self.failUnlessEqual(current_q, { 'sc' : ['1'], 'p' : ['isbn:"0387940758"'], 'of' : ['hd'] }) def test_isbn_10_rft_id(self): """ websearch - isbn query via OpenURL 1.0 - rft_id""" browser = Browser() # We do a precise search in an isolated collection browser.open(make_url('/openurl', rft_id='urn:ISBN:0387940758')) dummy, current_q = parse_url(browser.geturl()) self.failUnlessEqual(current_q, { 'sc' : ['1'], 'p' : ['isbn:"0387940758"'], 'of' : ['hd'] }) def test_isbn_10(self): """ websearch - isbn query via OpenURL 1.0""" browser = Browser() # We do a precise search in an isolated collection browser.open(make_url('/openurl?rft.isbn=0387940758')) dummy, current_q = parse_url(browser.geturl()) self.failUnlessEqual(current_q, { 'sc' : ['1'], 'p' : ['isbn:"0387940758"'], 'of' : ['hd'] }) class WebSearchTestSearch(InvenioTestCase): def test_hits_in_other_collection(self): """ websearch - check extension of a query to the home collection """ browser = Browser() args = {'ln':'en', 'as': 0} # We do a precise search in an isolated collection browser.open(make_url('/collection/ISOLDE', **args)) browser.select_form(name='search') browser['f'] = ['author'] browser['p'] = 'matsubara' browser.submit() dummy, current_q = parse_url(browser.geturl()) link = browser.find_link(text_regex=re.compile('.*hit', re.I)) dummy, target_q = parse_url(link.url) # the target query should be the current query without any c # or cc specified. for f in ('cc', 'c', 'action_search'): if f in current_q: del current_q[f] self.failUnlessEqual(current_q, target_q) def test_nearest_terms(self): """ websearch - provide a list of nearest terms """ browser = Browser() args = {'as': 0} browser.open(make_url('', **args)) # Search something weird browser.select_form(name='search') browser['p'] = 'gronf' browser.submit() dummy, original = parse_url(browser.geturl()) for to_drop in ('cc', 'action_search', 'f'): if to_drop in original: del original[to_drop] if 'ln' not in original: original['ln'] = [CFG_SITE_LANG] # we should get a few searches back, which are identical # except for the p field being substituted (and the cc field # being dropped). if 'cc' in original: del original['cc'] for link in browser.links(url_regex=re.compile(CFG_SITE_URL + r'/search\?')): if link.text == 'Advanced Search': continue dummy, target = parse_url(link.url) if 'ln' not in target: target['ln'] = [CFG_SITE_LANG] original['p'] = [link.text] self.failUnlessEqual(original, target) return def test_switch_to_simple_search(self): """ websearch - switch to simple search """ browser = Browser() args = {'as': 1} browser.open(make_url('/collection/ISOLDE', **args)) browser.select_form(name='search') browser['p1'] = 'tandem' browser['f1'] = ['title'] browser.submit() browser.follow_link(text='Simple Search') dummy, q = parse_url(browser.geturl()) self.failUnlessEqual(q, {'cc': ['ISOLDE'], 'p': ['tandem'], 'f': ['title'], 'ln': ['en']}) def test_no_boolean_hits(self): """ websearch - check the 'no boolean hits' proposed links """ browser = Browser() args = {'as': 0} browser.open(make_url('', **args)) browser.select_form(name='search') browser['p'] = 'quasinormal muon' browser.submit() dummy, q = parse_url(browser.geturl()) for to_drop in ('cc', 'action_search', 'f'): if to_drop in q: del q[to_drop] for bsu in ('quasinormal', 'muon'): l = browser.find_link(text=bsu) q['p'] = bsu if not same_urls_p(l.url, make_rurl('/search', **q)): self.fail(repr((l.url, make_rurl('/search', **q)))) def test_similar_authors(self): """ websearch - test similar authors box """ browser = Browser() args = {'as': 0} browser.open(make_url('', **args)) browser.select_form(name='search') browser['p'] = 'Ellis, R K' browser['f'] = ['author'] browser.submit() l = browser.find_link(text="Ellis, R S") urlargs = dict(p="Ellis, R S", f='author', ln='en') self.failUnless(same_urls_p(l.url, make_rurl('/search', **urlargs))) def test_em_parameter(self): """ websearch - check different values of em return different parts of the search page""" for combi in string_combinations(["K", "A", "I", "O"]): url = '/search?ln=en&cc=Articles+%%26+Preprints&sc=1&c=Articles&c=Preprints&em=%s' % ','.join(combi) expected_text = ["Influence of processing parameters on the manufacturing of anode-supported solid oxide fuel cells by different wet chemical routes"] unexpected_text = [] if "H" in combi: expected_text.append(">Atlantis Institute of Fictive Science") else: unexpected_text.append(">Atlantis Institute of Fictive Science") if "F" in combi: expected_text.append("This site is also available in the following languages:") else: unexpected_text.append("This site is also available in the following languages:") if "S" in combi: expected_text.append('value="Search"') else: unexpected_text.append('value="Search"') if "K" in combi: expected_text.append('value="Add to basket"') else: unexpected_text.append('value="Add to basket"') if "A" in combi: expected_text.append('Interested in being notified about new results for this query?') else: unexpected_text.append('Interested in being notified about new results for this query?') if "I" in combi: expected_text.append('jump to record:') else: unexpected_text.append('jump to record:') if "O" in combi: expected_text.append('Results overview: Found ') else: unexpected_text.append('Results overview: Found ') self.assertEqual([], test_web_page_content(make_url(url), expected_text=expected_text, unexpected_text=unexpected_text)) return class WebSearchCJKTokenizedSearchTest(InvenioTestCase): """ Reindexes record 104 (the one with chinese poetry) with use of BibIndexCJKTokenizer. After tests it reindexes record 104 back with BibIndexDefaultTokenizer. Checks if one can find record 104 specifying only one or two CJK characters. """ test_counter = 0 reindexed = False index_name = 'title' @classmethod def setUp(self): if not self.reindexed: from invenio.bibindex_engine import WordTable, AbstractIndexTable query = """SELECT last_updated FROM idxINDEX WHERE name='%s'""" % self.index_name self.last_updated = run_sql(query)[0][0] query = """UPDATE idxINDEX SET tokenizer='BibIndexCJKTokenizer', last_updated='0000-00-00 00:00:00' WHERE name='%s'""" % self.index_name run_sql(query) self.reindexed = True wordTable = WordTable(index_name=self.index_name, table_type = CFG_BIBINDEX_INDEX_TABLE_TYPE["Words"]) wordTable.turn_off_virtual_indexes() wordTable.add_recIDs([[104, 104]], 10000) @classmethod def tearDown(self): self.test_counter += 1 if self.test_counter == 2: from invenio.bibindex_engine import WordTable, AbstractIndexTable query = """UPDATE idxINDEX SET tokenizer='BibIndexDefaultTokenizer', last_updated='%s' WHERE name='%s'""" % (self.last_updated, self.index_name) run_sql(query) wordTable = WordTable(index_name=self.index_name, table_type = CFG_BIBINDEX_INDEX_TABLE_TYPE["Words"]) wordTable.turn_off_virtual_indexes() wordTable.add_recIDs([[104, 104]], 10000) def test_title_cjk_tokenized_two_characters(self): """CJKTokenizer - test for finding chinese poetry with two CJK characters""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?ln=en&sc=1&p=title%3A敬亭&f=&of=id', expected_text='[104]')) def test_title_cjk_tokenized_single_character(self): """CJKTokenizer - test for finding chinese poetry with one CJK character""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?ln=en&sc=1&p=title%3A亭&f=&of=id', expected_text='[104]')) class WebSearchTestWildcardLimit(InvenioTestCase): """Checks if the wildcard limit is correctly passed and that users without autorization can not exploit it""" def test_wildcard_limit_correctly_passed_when_not_set(self): """websearch - wildcard limit is correctly passed when default""" self.assertEqual(search_pattern(p='e*', f='author'), search_pattern(p='e*', f='author', wl=1000)) def test_wildcard_limit_correctly_passed_when_set(self): """websearch - wildcard limit is correctly passed when set""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=e*&f=author&of=id&wl=5&rg=100', expected_text="[96, 88, 81, 74, 72, 67, 54, 53, 52, 51, 50, 48, 46, 17, 11, 10, 9, 92]")) def test_wildcard_limit_correctly_not_active(self): """websearch - wildcard limit is not active when there is no wildcard query""" self.assertEqual(search_pattern(p='ellis', f='author'), search_pattern(p='ellis', f='author', wl=1)) def test_wildcard_limit_increased_by_authorized_users(self): """websearch - wildcard limit increased by authorized user""" browser = Browser() #try a search query, with no wildcard limit set by the user browser.open(make_url('/search?p=a*&of=id')) recid_list_guest_no_limit = browser.response().read() # so the limit is CGF_WEBSEARCH_WILDCARD_LIMIT #try a search query, with a wildcard limit imposed by the user #wl=1000000 - a very high limit,higher then what the CFG_WEBSEARCH_WILDCARD_LIMIT might be browser.open(make_url('/search?p=a*&of=id&wl=1000000')) recid_list_guest_with_limit = browser.response().read() #same results should be returned for a search without the wildcard limit set by the user #and for a search with a large limit set by the user #in this way we know that nomatter how large the limit is, the wildcard query will be #limitted by CFG_WEBSEARCH_WILDCARD_LIMIT (for a guest user) self.failIf(len(recid_list_guest_no_limit.split(',')) != len(recid_list_guest_with_limit.split(','))) ##login as admin browser.open(make_surl('/youraccount/login')) browser.select_form(nr=0) browser['p_un'] = 'admin' browser['p_pw'] = '' browser.submit() #try a search query, with a wildcard limit imposed by an authorized user #wl = 10000 a very high limit, higher then what the CFG_WEBSEARCH_WILDCARD_LIMIT might be browser.open(make_surl('/search?p=a*&of=id&wl=10000')) recid_list_authuser_with_limit = browser.response().read() #the authorized user can set whatever limit he might wish #so, the results returned for the auth. users should exceed the results returned for unauth. users self.failUnless(len(recid_list_guest_no_limit.split(',')) <= len(recid_list_authuser_with_limit.split(','))) #logout browser.open(make_surl('/youraccount/logout')) browser.response().read() browser.close() class WebSearchNearestTermsTest(InvenioTestCase): """Check various alternatives of searches leading to the nearest terms box.""" def test_nearest_terms_box_in_okay_query(self): """ websearch - no nearest terms box for a successful query """ self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=ellis', expected_text="jump to record")) def test_nearest_terms_box_in_unsuccessful_simple_query(self): """ websearch - nearest terms box for unsuccessful simple query """ self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=ellisz', expected_text="Nearest terms in any collection are", expected_link_target=CFG_BASE_URL+"/search?ln=en&p=embed", expected_link_label='embed')) def test_nearest_terms_box_in_unsuccessful_simple_accented_query(self): """ websearch - nearest terms box for unsuccessful accented query """ self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=elliszà', expected_text="Nearest terms in any collection are", expected_link_target=CFG_BASE_URL+"/search?ln=en&p=embed", expected_link_label='embed')) def test_nearest_terms_box_in_unsuccessful_structured_query(self): """ websearch - nearest terms box for unsuccessful structured query """ self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=ellisz&f=author', expected_text="Nearest terms in any collection are", expected_link_target=CFG_BASE_URL+"/search?ln=en&p=eisenhandler&f=author", expected_link_label='eisenhandler')) self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=author%3Aellisz', expected_text="Nearest terms in any collection are", expected_link_target=CFG_BASE_URL+"/search?ln=en&p=author%3Aeisenhandler", expected_link_label='eisenhandler')) def test_nearest_terms_box_in_query_with_invalid_index(self): """ websearch - nearest terms box for queries with invalid indexes specified """ self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=bednarz%3Aellis', expected_text="Nearest terms in any collection are", expected_link_target=CFG_BASE_URL+"/search?ln=en&p=bednarz", expected_link_label='bednarz')) self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=1%3Aellis', expected_text="no index 1.", expected_link_target=CFG_BASE_URL+"/record/47?ln=en", expected_link_label="Detailed record")) def test_nearest_terms_box_in_unsuccessful_phrase_query(self): """ websearch - nearest terms box for unsuccessful phrase query """ self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=author%3A%22Ellis%2C+Z%22', expected_text="Nearest terms in any collection are", expected_link_target=CFG_BASE_URL+"/search?ln=en&p=author%3A%22Enqvist%2C+K%22", expected_link_label='Enqvist, K')) self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=%22ellisz%22&f=author', expected_text="Nearest terms in any collection are", expected_link_target=CFG_BASE_URL+"/search?ln=en&p=%22Enqvist%2C+K%22&f=author", expected_link_label='Enqvist, K')) self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=%22elliszà%22&f=author', expected_text="Nearest terms in any collection are", expected_link_target=CFG_BASE_URL+"/search?ln=en&p=%22Enqvist%2C+K%22&f=author", expected_link_label='Enqvist, K')) def test_nearest_terms_box_in_unsuccessful_partial_phrase_query(self): """ websearch - nearest terms box for unsuccessful partial phrase query """ self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=author%3A%27Ellis%2C+Z%27', expected_text="Nearest terms in any collection are", expected_link_target=CFG_BASE_URL+"/search?ln=en&p=author%3A%27Enqvist%2C+K%27", expected_link_label='Enqvist, K')) self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=%27ellisz%27&f=author', expected_text="Nearest terms in any collection are", expected_link_target=CFG_BASE_URL+"/search?ln=en&p=%27Enqvist%2C+K%27&f=author", expected_link_label='Enqvist, K')) self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=%27elliszà%27&f=author', expected_text="Nearest terms in any collection are", expected_link_target=CFG_BASE_URL+"/search?ln=en&p=%27Enqvist%2C+K%27&f=author", expected_link_label='Enqvist, K')) def test_nearest_terms_box_in_unsuccessful_partial_phrase_advanced_query(self): """ websearch - nearest terms box for unsuccessful partial phrase advanced search query """ self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p1=aaa&f1=title&m1=p&as=1', expected_text="Nearest terms in any collection are", expected_link_target=CFG_BASE_URL+"/search?ln=en&f1=title&as=1&p1=A+simple+functional+form+for+proton-nucleus+total+reaction+cross+sections&m1=p", expected_link_label='A simple functional form for proton-nucleus total reaction cross sections')) def test_nearest_terms_box_in_unsuccessful_exact_phrase_advanced_query(self): """ websearch - nearest terms box for unsuccessful exact phrase advanced search query """ self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p1=aaa&f1=title&m1=e&as=1', expected_text="Nearest terms in any collection are", expected_link_target=CFG_BASE_URL+"/search?ln=en&f1=title&as=1&p1=A+simple+functional+form+for+proton-nucleus+total+reaction+cross+sections&m1=e", expected_link_label='A simple functional form for proton-nucleus total reaction cross sections')) def test_nearest_terms_box_in_unsuccessful_boolean_query(self): """ websearch - nearest terms box for unsuccessful boolean query """ self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=title%3Aellisz+author%3Aellisz', expected_text="Nearest terms in any collection are", expected_link_target=CFG_BASE_URL+"/search?ln=en&p=title%3Aenergi+author%3Aellisz", expected_link_label='energi')) self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=title%3Aenergi+author%3Aenergie', expected_text="Nearest terms in any collection are", expected_link_target=CFG_BASE_URL+"/search?ln=en&p=title%3Aenergi+author%3Aenqvist", expected_link_label='enqvist')) self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?ln=en&p=title%3Aellisz+author%3Aellisz&f=keyword', expected_text="Nearest terms in any collection are", expected_link_target=CFG_BASE_URL+"/search?ln=en&p=title%3Aenergi+author%3Aellisz&f=keyword", expected_link_label='energi')) self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?ln=en&p=title%3Aenergi+author%3Aenergie&f=keyword', expected_text="Nearest terms in any collection are", expected_link_target=CFG_BASE_URL+"/search?ln=en&p=title%3Aenergi+author%3Aenqvist&f=keyword", expected_link_label='enqvist')) def test_nearest_terms_box_in_unsuccessful_uppercase_query(self): """ websearch - nearest terms box for unsuccessful uppercase query """ self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=fOo%3Atest', expected_text="Nearest terms in any collection are", expected_link_target=CFG_BASE_URL+"/search?ln=en&p=food", expected_link_label='food')) self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=arXiv%3A1007.5048', expected_text="Nearest terms in any collection are", expected_link_target=CFG_BASE_URL+"/search?ln=en&p=artist", expected_link_label='artist')) def test_nearest_terms_box_in_unsuccessful_spires_query(self): """ websearch - nearest terms box for unsuccessful spires query """ self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?ln=en&p=find+a+foobar', expected_text="Nearest terms in any collection are", expected_link_target=CFG_BASE_URL+"/search?ln=en&p=find+a+finch", expected_link_label='finch')) class WebSearchBooleanQueryTest(InvenioTestCase): """Check various boolean queries.""" def test_successful_boolean_query(self): """ websearch - successful boolean query """ self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=ellis+muon', expected_text="records found", expected_link_label="Detailed record")) def test_unsuccessful_boolean_query_where_all_individual_terms_match(self): """ websearch - unsuccessful boolean query where all individual terms match """ self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=ellis+muon+letter', expected_text="Boolean query returned no hits. Please combine your search terms differently.")) def test_unsuccessful_boolean_query_in_advanced_search_where_all_individual_terms_match(self): """ websearch - unsuccessful boolean query in advanced search where all individual terms match """ self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?m1=a&p1=ellis&op1=a&m2=a&p2=muon&op2=a&p3=letter', expected_text="Boolean query returned no hits. Please combine your search terms differently.")) class WebSearchAuthorQueryTest(InvenioTestCase): """Check various author-related queries.""" def test_propose_similar_author_names_box(self): """ websearch - propose similar author names box """ self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=Ellis%2C+R&f=author', expected_text="See also: similar author names", expected_link_target=CFG_BASE_URL+"/search?ln=en&p=Ellis%2C+R+K&f=author", expected_link_label="Ellis, R K")) def test_do_not_propose_similar_author_names_box(self): """ websearch - do not propose similar author names box """ errmsgs = test_web_page_content(CFG_SITE_URL + '/search?p=author%3A%22Ellis%2C+R%22', expected_link_target=CFG_BASE_URL+"/search?ln=en&p=Ellis%2C+R+K&f=author", expected_link_label="Ellis, R K") if errmsgs[0].find("does not contain link to") > -1: pass else: self.fail("Should not propose similar author names box.") return class WebSearchSearchEnginePythonAPITest(InvenioXmlTestCase): """Check typical search engine Python API calls on the demo data.""" def test_search_engine_python_api_for_failed_query(self): """websearch - search engine Python API for failed query""" self.assertEqual([], perform_request_search(p='aoeuidhtns')) def test_search_engine_python_api_for_successful_query(self): """websearch - search engine Python API for successful query""" self.assertEqual([8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 47], perform_request_search(p='ellis')) def test_search_engine_python_api_for_successful_query_format_intbitset(self): """websearch - search engine Python API for successful query, output format intbitset""" self.assertEqual(intbitset([8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 47]), perform_request_search(p='ellis', of='intbitset')) def test_search_engine_web_api_jrec_parameter(self): """websearch - search engine Python API for successful query, ignore paging parameters""" self.assertEqual([11, 12, 13, 14, 15, 16, 17, 18, 47], perform_request_search(p='ellis', jrec=3)) def test_search_engine_web_api_paging_parameters(self): """websearch - search engine Python API for successful query, ignore paging parameters""" self.assertEqual([11, 12, 13, 14, 15], perform_request_search(p='ellis', rg=5, jrec=3)) def test_search_engine_python_api_respect_sorting_parameter(self): """websearch - search engine Python API for successful query, respect sorting parameters""" self.assertEqual([77, 84, 85], perform_request_search(p='klebanov')) self.assertEqual([77, 85, 84], perform_request_search(p='klebanov', sf='909C4v')) def test_search_engine_python_api_respect_ranking_parameter(self): """websearch - search engine Python API for successful query, respect ranking parameters""" self.assertEqual([77, 84, 85], perform_request_search(p='klebanov')) self.assertEqual([85, 77, 84], perform_request_search(p='klebanov', rm='citation')) def test_search_engine_python_api_for_existing_record(self): """websearch - search engine Python API for existing record""" self.assertEqual([8], perform_request_search(recid=8)) def test_search_engine_python_api_for_existing_record_format_intbitset(self): """websearch - search engine Python API for existing record, output format intbitset""" self.assertEqual(intbitset([8]), perform_request_search(recid=8, of='intbitset')) def test_search_engine_python_api_for_nonexisting_record(self): """websearch - search engine Python API for non-existing record""" self.assertEqual([], perform_request_search(recid=12345678)) def test_search_engine_python_api_for_nonexisting_record_format_intbitset(self): """websearch - search engine Python API for non-existing record, output format intbitset""" self.assertEqual(intbitset(), perform_request_search(recid=16777215, of='intbitset')) def test_search_engine_python_api_for_nonexisting_collection(self): """websearch - search engine Python API for non-existing collection""" self.assertEqual([], perform_request_search(c='Foo')) def test_search_engine_python_api_for_range_of_records(self): """websearch - search engine Python API for range of records""" self.assertEqual([1, 2, 3, 4, 5, 6, 7, 8, 9], perform_request_search(recid=1, recidb=10)) def test_search_engine_python_api_old_style_ranked_by_citation(self): """websearch - search engine Python API old style citation ranking""" self.assertEqual([86, 77], perform_request_search(p='recid:95', rm='citation')) def test_search_engine_python_api_textmarc_full(self): """websearch - search engine Python API for Text MARC output, full""" req = make_fake_request() perform_request_search(req=req, p='higgs', of='tm', so='d') out = req.test_output_buffer.getvalue() self.assertMultiLineEqual(out, """\ 000000085 001__ 85 000000085 003__ SzGeCERN 000000085 005__ %(rec_85_rev)s 000000085 035__ $$a2356302CERCER 000000085 035__ $$9SLAC$$a5423422 000000085 037__ $$ahep-th/0212181 000000085 041__ $$aeng 000000085 100__ $$aGirardello, L$$uINFN$$uUniversita di Milano-Bicocca 000000085 245__ $$a3-D Interacting CFTs and Generalized Higgs Phenomenon in Higher Spin Theories on AdS 000000085 260__ $$c2003 000000085 269__ $$c16 Dec 2002 000000085 300__ $$a8 p 000000085 520__ $$aWe study a duality, recently conjectured by Klebanov and Polyakov, between higher-spin theories on AdS_4 and O(N) vector models in 3-d. These theories are free in the UV and interacting in the IR. At the UV fixed point, the O(N) model has an infinite number of higher-spin conserved currents. In the IR, these currents are no longer conserved for spin s>2. In this paper, we show that the dual interpretation of this fact is that all fields of spin s>2 in AdS_4 become massive by a Higgs mechanism, that leaves the spin-2 field massless. We identify the Higgs field and show how it relates to the RG flow connecting the two CFTs, which is induced by a double trace deformation. 000000085 65017 $$2SzGeCERN$$aParticle Physics - Theory 000000085 690C_ $$aARTICLE 000000085 695__ $$9LANL EDS$$aHigh Energy Physics - Theory 000000085 700__ $$aPorrati, Massimo 000000085 700__ $$aZaffaroni, A 000000085 8564_ $$s112828$$u%(siteurl)s/record/85/files/0212181.ps.gz 000000085 8564_ $$s151257$$u%(siteurl)s/record/85/files/0212181.pdf 000000085 859__ $$falberto.zaffaroni@mib.infn.it 000000085 909C4 $$c289-293$$pPhys. Lett. B$$v561$$y2003 000000085 916__ $$sn$$w200251 000000085 960__ $$a13 000000085 961__ $$c20060823$$h0007$$lCER01$$x20021217 000000085 963__ $$aPUBLIC 000000085 970__ $$a002356302CER 000000085 980__ $$aARTICLE 000000085 999C5 $$mD. Francia and A. Sagnotti,$$o[1]$$rhep-th/0207002$$sPhys. Lett. B 543 (2002) 303 000000085 999C5 $$mP. Haggi-Mani and B. Sundborg,$$o[1]$$rhep-th/0002189$$sJ. High Energy Phys. 0004 (2000) 031 000000085 999C5 $$mB. Sundborg,$$o[1]$$rhep-th/0103247$$sNucl. Phys. B, Proc. Suppl. 102 (2001) 113 000000085 999C5 $$mE. Sezgin and P. Sundell,$$o[1]$$rhep-th/0105001$$sJ. High Energy Phys. 0109 (2001) 036 000000085 999C5 $$mA. Mikhailov,$$o[1]$$rhep-th/0201019 000000085 999C5 $$mE. Sezgin and P. Sundell,$$o[1]$$rhep-th/0205131$$sNucl. Phys. B 644 (2002) 303 000000085 999C5 $$mE. Sezgin and P. Sundell,$$o[1]$$rhep-th/0205132$$sJ. High Energy Phys. 0207 (2002) 055 000000085 999C5 $$mJ. Engquist, E. Sezgin and P. Sundell,$$o[1]$$rhep-th/0207101$$sClass. Quantum Gravity 19 (2002) 6175 000000085 999C5 $$mM. A. Vasiliev,$$o[1]$$rhep-th/9611024$$sInt. J. Mod. Phys. D 5 (1996) 763 000000085 999C5 $$mD. Anselmi,$$o[1]$$rhep-th/9808004$$sNucl. Phys. B 541 (1999) 323 000000085 999C5 $$mD. Anselmi,$$o[1]$$rhep-th/9906167$$sClass. Quantum Gravity 17 (2000) 1383 000000085 999C5 $$mE. S. Fradkin and M. A. Vasiliev,$$o[2]$$sNucl. Phys. B 291 (1987) 141 000000085 999C5 $$mE. S. Fradkin and M. A. Vasiliev,$$o[2]$$sPhys. Lett. B 189 (1987) 89 000000085 999C5 $$mI. R. Klebanov and A. M. Polyakov,$$o[3]$$rhep-th/0210114$$sPhys. Lett. B 550 (2002) 213 000000085 999C5 $$mM. A. Vasiliev,$$o[4]$$rhep-th/9910096 000000085 999C5 $$mT. Leonhardt, A. Meziane and W. Ruhl,$$o[5]$$rhep-th/0211092 000000085 999C5 $$mO. Aharony, M. Berkooz and E. Silverstein,$$o[6]$$rhep-th/0105309$$sJ. High Energy Phys. 0108 (2001) 006 000000085 999C5 $$mE. Witten,$$o[7]$$rhep-th/0112258 000000085 999C5 $$mM. Berkooz, A. Sever and A. Shomer$$o[8]$$rhep-th/0112264$$sJ. High Energy Phys. 0205 (2002) 034 000000085 999C5 $$mS. S. Gubser and I. Mitra,$$o[9]$$rhep-th/0210093 000000085 999C5 $$mS. S. Gubser and I. R. Klebanov,$$o[10]$$rhep-th/0212138 000000085 999C5 $$mM. Porrati,$$o[11]$$rhep-th/0112166$$sJ. High Energy Phys. 0204 (2002) 058 000000085 999C5 $$mK. G. Wilson and J. B. Kogut,$$o[12]$$sPhys. Rep. 12 (1974) 75 000000085 999C5 $$mI. R. Klebanov and E. Witten,$$o[13]$$rhep-th/9905104$$sNucl. Phys. B 556 (1999) 89 000000085 999C5 $$mW. Heidenreich,$$o[14]$$sJ. Math. Phys. 22 (1981) 1566 000000085 999C5 $$mD. Anselmi,$$o[15]$$rhep-th/0210123 000000001 001__ 1 000000001 005__ %(rec_1_rev)s 000000001 037__ $$aCERN-EX-0106015 000000001 100__ $$aPhotolab 000000001 245__ $$aALEPH experiment: Candidate of Higgs boson production 000000001 246_1 $$aExpérience ALEPH: Candidat de la production d'un boson Higgs 000000001 260__ $$c14 06 2000 000000001 340__ $$aFILM 000000001 520__ $$aCandidate for the associated production of the Higgs boson and Z boson. Both, the Higgs and Z boson decay into 2 jets each. The green and the yellow jets belong to the Higgs boson. They represent the fragmentation of a bottom andanti-bottom quark. The red and the blue jets stem from the decay of the Z boson into a quark anti-quark pair. Left: View of the event along the beam axis. Bottom right: Zoom around the interaction point at the centre showing detailsof the fragmentation of the bottom and anti-bottom quarks. As expected for b quarks, in each jet the decay of a long-lived B meson is visible. Top right: "World map" showing the spatial distribution of the jets in the event. 000000001 65017 $$2SzGeCERN$$aExperiments and Tracks 000000001 6531_ $$aLEP 000000001 8560_ $$fneil.calder@cern.ch 000000001 8564_ $$s1585244$$u%(siteurl)s/record/1/files/0106015_01.jpg 000000001 8564_ $$s20954$$u%(siteurl)s/record/1/files/0106015_01.gif?subformat=icon$$xicon 000000001 909C0 $$o0003717PHOPHO 000000001 909C0 $$y2000 000000001 909C0 $$b81 000000001 909C1 $$c2001-06-14$$l50$$m2001-08-27$$oCM 000000001 909CP $$pBldg. 2 000000001 909CP $$rCalder, N 000000001 909CS $$sn$$w200231 000000001 980__ $$aPICTURE 000000107 001__ 107 000000107 003__ SzGeCERN 000000107 005__ %(rec_107_rev)s 000000107 035__ $$9SPIRES$$a4066995 000000107 037__ $$aCERN-EP-99-060 000000107 041__ $$aeng 000000107 084__ $$2CERN Library$$aEP-1999-060 000000107 088__ $$9SCAN-9910048 000000107 088__ $$aCERN-L3-175 000000107 110__ $$aCERN. Geneva 000000107 245__ $$aLimits on Higgs boson masses from combining the data of the four LEP experiments at $\sqrt{s} \leq 183 GeV$ 000000107 260__ $$c1999 000000107 269__ $$aGeneva$$bCERN$$c26 Apr 1999 000000107 300__ $$a18 p 000000107 490__ $$aALEPH Papers 000000107 500__ $$aPreprint not submitted to publication 000000107 65017 $$2SzGeCERN$$aParticle Physics - Experiment 000000107 690C_ $$aCERN 000000107 690C_ $$aPREPRINT 000000107 693__ $$aCERN LEP$$eALEPH 000000107 693__ $$aCERN LEP$$eDELPHI 000000107 693__ $$aCERN LEP$$eL3 000000107 693__ $$aCERN LEP$$eOPAL 000000107 695__ $$9MEDLINE$$asearches Higgs bosons 000000107 697C_ $$aLexiHiggs 000000107 710__ $$5EP 000000107 710__ $$gALEPH Collaboration 000000107 710__ $$gDELPHI Collaboration 000000107 710__ $$gL3 Collaboration 000000107 710__ $$gLEP Working Group for Higgs Boson Searches 000000107 710__ $$gOPAL Collaboration 000000107 901__ $$uCERN 000000107 916__ $$sh$$w199941 000000107 960__ $$a11 000000107 963__ $$aPUBLIC 000000107 970__ $$a000330309CER 000000107 980__ $$aARTICLE """ % {'siteurl': CFG_SITE_URL, 'rec_1_rev': get_fieldvalues(1, '005__')[0], 'rec_85_rev': get_fieldvalues(85, '005__')[0], 'rec_107_rev': get_fieldvalues(107, '005__')[0]}) def test_search_engine_python_api_ranked_by_citation_asc(self): """websearch - search engine Python API for citation ranking asc""" self.assertEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 75, 76, 80, 82, 83, 85, 86, 87, 88, 89, 90, 92, 93, 96, 97, 98, 99, 100, 101, 102, 103, 104, 107, 108, 109, 113, 127, 128, 18, 74, 79, 91, 94, 77, 78, 95, 84, 81], perform_request_search(p='', rm='citation', so='a')) def test_search_engine_python_api_ranked_by_citation_desc(self): """websearch - search engine Python API for citation ranking desc""" self.assertEqual(list(reversed( [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 75, 76, 80, 82, 83, 85, 86, 87, 88, 89, 90, 92, 93, 96, 97, 98, 99, 100, 101, 102, 103, 104, 107, 108, 109, 113, 127, 128, 18, 74, 79, 91, 94, 77, 78, 95, 84, 81])), perform_request_search(p='', rm='citation', so='d')) def test_search_engine_python_api_textmarc_field_filtered(self): """websearch - search engine Python API for Text MARC output, field-filtered""" req = make_fake_request() perform_request_search(req=req, p='higgs', of='tm', ot=['100', '700']) out = req.test_output_buffer.getvalue() self.assertEqual(out, """\ 000000001 100__ $$aPhotolab 000000085 100__ $$aGirardello, L$$uINFN$$uUniversita di Milano-Bicocca 000000085 700__ $$aPorrati, Massimo 000000085 700__ $$aZaffaroni, A """) def test_search_engine_python_api_for_intersect_results_with_one_collrec(self): """websearch - search engine Python API for intersect results with one collrec""" self.assertEqual({'Books & Reports': intbitset([19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34])}, intersect_results_with_collrecs(None, intbitset(range(0,110)), ['Books & Reports'], 'id', 0, 'en', False)) def test_search_engine_python_api_for_intersect_results_with_several_collrecs(self): """websearch - search engine Python API for intersect results with several collrecs""" self.assertEqual({'Books': intbitset([21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34]), 'Reports': intbitset([19, 20]), 'Theses': intbitset([35, 36, 37, 38, 39, 40, 41, 42, 105])}, intersect_results_with_collrecs(None, intbitset(range(0,110)), ['Books', 'Theses', 'Reports'], 'id', 0, 'en', False)) def test_search_engine_python_api_textmarc_field_filtered_hidden_guest(self): """websearch - search engine Python API for Text MARC output, field-filtered, hidden field, no guest access""" req = make_fake_request() perform_request_search(req=req, p='higgs', of='tm', ot=['100', '595']) out = req.test_output_buffer.getvalue() self.assertEqual(out, """\ 000000001 100__ $$aPhotolab 000000085 100__ $$aGirardello, L$$uINFN$$uUniversita di Milano-Bicocca """) def test_search_engine_python_api_xmlmarc_full(self): """websearch - search engine Python API for XMLMARC output, full""" req = make_fake_request(admin_user=False) perform_request_search(req=req, p='higgs', of='xm', so='d') out = req.test_output_buffer.getvalue() # print out self.assertXmlEqual(out, """ 85 SzGeCERN %(rec_85_rev)s 2356302CERCER SLAC 5423422 hep-th/0212181 eng Girardello, L INFN Universita di Milano-Bicocca 3-D Interacting CFTs and Generalized Higgs Phenomenon in Higher Spin Theories on AdS 2003 16 Dec 2002 8 p We study a duality, recently conjectured by Klebanov and Polyakov, between higher-spin theories on AdS_4 and O(N) vector models in 3-d. These theories are free in the UV and interacting in the IR. At the UV fixed point, the O(N) model has an infinite number of higher-spin conserved currents. In the IR, these currents are no longer conserved for spin s>2. In this paper, we show that the dual interpretation of this fact is that all fields of spin s>2 in AdS_4 become massive by a Higgs mechanism, that leaves the spin-2 field massless. We identify the Higgs field and show how it relates to the RG flow connecting the two CFTs, which is induced by a double trace deformation. SzGeCERN Particle Physics - Theory ARTICLE LANL EDS High Energy Physics - Theory Porrati, Massimo Zaffaroni, A 112828 %(siteurl)s/record/85/files/0212181.ps.gz 151257 %(siteurl)s/record/85/files/0212181.pdf 289-293 Phys. Lett. B 561 2003 alberto.zaffaroni@mib.infn.it n 200251 13 20060823 0007 CER01 20021217 PUBLIC 002356302CER ARTICLE [1] D. Francia and A. Sagnotti, Phys. Lett. B 543 (2002) 303 hep-th/0207002 [1] P. Haggi-Mani and B. Sundborg, J. High Energy Phys. 0004 (2000) 031 hep-th/0002189 [1] B. Sundborg, Nucl. Phys. B, Proc. Suppl. 102 (2001) 113 hep-th/0103247 [1] E. Sezgin and P. Sundell, J. High Energy Phys. 0109 (2001) 036 hep-th/0105001 [1] A. Mikhailov, hep-th/0201019 [1] E. Sezgin and P. Sundell, Nucl. Phys. B 644 (2002) 303 hep-th/0205131 [1] E. Sezgin and P. Sundell, J. High Energy Phys. 0207 (2002) 055 hep-th/0205132 [1] J. Engquist, E. Sezgin and P. Sundell, Class. Quantum Gravity 19 (2002) 6175 hep-th/0207101 [1] M. A. Vasiliev, Int. J. Mod. Phys. D 5 (1996) 763 hep-th/9611024 [1] D. Anselmi, Nucl. Phys. B 541 (1999) 323 hep-th/9808004 [1] D. Anselmi, Class. Quantum Gravity 17 (2000) 1383 hep-th/9906167 [2] E. S. Fradkin and M. A. Vasiliev, Nucl. Phys. B 291 (1987) 141 [2] E. S. Fradkin and M. A. Vasiliev, Phys. Lett. B 189 (1987) 89 [3] I. R. Klebanov and A. M. Polyakov, Phys. Lett. B 550 (2002) 213 hep-th/0210114 [4] M. A. Vasiliev, hep-th/9910096 [5] T. Leonhardt, A. Meziane and W. Ruhl, hep-th/0211092 [6] O. Aharony, M. Berkooz and E. Silverstein, J. High Energy Phys. 0108 (2001) 006 hep-th/0105309 [7] E. Witten, hep-th/0112258 [8] M. Berkooz, A. Sever and A. Shomer J. High Energy Phys. 0205 (2002) 034 hep-th/0112264 [9] S. S. Gubser and I. Mitra, hep-th/0210093 [10] S. S. Gubser and I. R. Klebanov, hep-th/0212138 [11] M. Porrati, J. High Energy Phys. 0204 (2002) 058 hep-th/0112166 [12] K. G. Wilson and J. B. Kogut, Phys. Rep. 12 (1974) 75 [13] I. R. Klebanov and E. Witten, Nucl. Phys. B 556 (1999) 89 hep-th/9905104 [14] W. Heidenreich, J. Math. Phys. 22 (1981) 1566 [15] D. Anselmi, hep-th/0210123 1 %(rec_1_rev)s CERN-EX-0106015 Photolab ALEPH experiment: Candidate of Higgs boson production Expérience ALEPH: Candidat de la production d'un boson Higgs 14 06 2000 FILM Candidate for the associated production of the Higgs boson and Z boson. Both, the Higgs and Z boson decay into 2 jets each. The green and the yellow jets belong to the Higgs boson. They represent the fragmentation of a bottom andanti-bottom quark. The red and the blue jets stem from the decay of the Z boson into a quark anti-quark pair. Left: View of the event along the beam axis. Bottom right: Zoom around the interaction point at the centre showing detailsof the fragmentation of the bottom and anti-bottom quarks. As expected for b quarks, in each jet the decay of a long-lived B meson is visible. Top right: "World map" showing the spatial distribution of the jets in the event. SzGeCERN Experiments and Tracks LEP neil.calder@cern.ch 1585244 %(siteurl)s/record/1/files/0106015_01.jpg 20954 %(siteurl)s/record/1/files/0106015_01.gif?subformat=icon icon 0003717PHOPHO 2000 81 2001-06-14 50 2001-08-27 CM Bldg. 2 Calder, N n 200231 PICTURE 107 SzGeCERN %(rec_107_rev)s SPIRES 4066995 CERN-EP-99-060 eng CERN Library EP-1999-060 SCAN-9910048 CERN-L3-175 CERN. Geneva Limits on Higgs boson masses from combining the data of the four LEP experiments at $\sqrt{s} \leq 183 GeV$ 1999 Geneva CERN 26 Apr 1999 18 p ALEPH Papers Preprint not submitted to publication SzGeCERN Particle Physics - Experiment CERN PREPRINT CERN LEP ALEPH CERN LEP DELPHI CERN LEP L3 CERN LEP OPAL MEDLINE searches Higgs bosons LexiHiggs EP ALEPH Collaboration DELPHI Collaboration L3 Collaboration LEP Working Group for Higgs Boson Searches OPAL Collaboration CERN h 199941 11 PUBLIC 000330309CER ARTICLE """ % {'siteurl': CFG_SITE_URL, 'rec_1_rev': get_fieldvalues(1, '005__')[0], 'rec_85_rev': get_fieldvalues(85, '005__')[0], 'rec_107_rev': get_fieldvalues(107, '005__')[0]}) def test_search_engine_python_api_xmlmarc_field_filtered(self): """websearch - search engine Python API for XMLMARC output, field-filtered""" # we are testing example from /help/hacking/search-engine-api req = make_fake_request() perform_request_search(req=req, p='higgs', of='xm', ot=['100', '700'], so='d') out = req.test_output_buffer.getvalue() self.assertXmlEqual(out, """ 85 Girardello, L INFN Universita di Milano-Bicocca Porrati, Massimo Zaffaroni, A 1 Photolab 107 """) def test_search_engine_python_api_xmlmarc_field_filtered_hidden_guest(self): """websearch - search engine Python API for XMLMARC output, field-filtered, hidden field, no guest access""" # we are testing example from /help/hacking/search-engine-api req = make_fake_request() perform_request_search(req=req, p='higgs', of='xm', ot=['100', '595'], so='d') out = req.test_output_buffer.getvalue() self.assertXmlEqual(out, """ 85 Girardello, L INFN Universita di Milano-Bicocca 1 Photolab 107 """) def test_search_engine_python_api_long_author_with_quotes(self): """websearch - search engine Python API for p=author:"Abbot, R B"'""" \ """this test was written along with a bug report, needs fixing.""" self.assertEqual([16], perform_request_search(p='author:"Abbott, R B"')) def test_search_engine_python_api_search_refersto_year_2000(self): """websearch - search engine Python API for failed query""" self.assertEqual([92], perform_request_search(p='refersto:year:2000')) class WebSearchSearchEngineWebAPITest(InvenioTestCase): """Check typical search engine Web API calls on the demo data.""" def test_search_engine_web_api_for_failed_query(self): """websearch - search engine Web API for failed query""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=aoeuidhtns&of=id', expected_text="[]")) def test_search_engine_web_api_for_failed_query_format_intbitset(self): """websearch - search engine Web API for failed query, output format intbitset""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=aoeuidhtns&of=intbitset', expected_text=intbitset().fastdump())) def test_search_engine_web_api_for_successful_query(self): """websearch - search engine Web API for successful query""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=ellis&of=id&rg=0', expected_text="[47, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8]")) def test_search_engine_web_api_no_paging_parameter(self): """websearch - search engine Web API for successful query, ignore paging parameters""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=ellis&of=id&rg=0', expected_text="[47, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8]")) def test_search_engine_web_api_jrec_parameter(self): """websearch - search engine Web API for successful query, ignore paging parameters""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=ellis&of=id&rg=0&jrec=3', expected_text="[16, 15, 14, 13, 12, 11, 10, 9, 8]")) def test_search_engine_web_api_paging_parameters(self): """websearch - search engine Web API for successful query, ignore paging parameters""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=ellis&of=id&rg=5&jrec=3', expected_text="[16, 15, 14, 13, 12]")) def test_search_engine_web_api_respect_sorting_parameter(self): """websearch - search engine Web API for successful query, respect sorting parameters""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=klebanov&of=id', expected_text="[85, 84]")) self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=klebanov&of=id', username="admin", expected_text="[85, 84, 77]")) self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=klebanov&of=id&sf=909C4v', expected_text="[84, 85]")) self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=klebanov&of=id&sf=909C4v', username="admin", expected_text="[84, 85, 77]")) self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=klebanov&of=intbitset&sf=909C4v', username="admin", expected_text=intbitset([77, 84, 85]).fastdump())) def test_search_engine_web_api_respect_ranking_parameter(self): """websearch - search engine Web API for successful query, respect ranking parameters""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=klebanov&of=id', expected_text="[85, 84]")) self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=klebanov&of=id', username="admin", expected_text="[85, 84, 77]")) self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=klebanov&of=id&rm=citation', expected_text="[84, 85]")) self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=klebanov&of=id&rm=citation', username="admin", expected_text="[84, 77, 85]")) self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=klebanov&of=intbitset&rm=citation', username="admin", expected_text=intbitset([77, 84, 85]).fastdump())) def test_search_engine_web_api_for_existing_record(self): """websearch - search engine Web API for existing record""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?recid=8&of=id', expected_text="[8]")) def test_search_engine_web_api_for_nonexisting_record(self): """websearch - search engine Web API for non-existing record""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?recid=12345678&of=id', expected_text="[]")) def test_search_engine_web_api_for_nonexisting_collection(self): """websearch - search engine Web API for non-existing collection""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?c=Foo&of=id', expected_text="[]")) def test_search_engine_web_api_for_range_of_records(self): """websearch - search engine Web API for range of records""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?recid=1&recidb=10&of=id', expected_text="[1, 2, 3, 4, 5, 6, 7, 8, 9]")) def test_search_engine_web_api_ranked_by_citation(self): """websearch - search engine Web API for citation ranking""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=recid%3A81&rm=citation&of=id', expected_text="[82, 83, 87, 89]")) def test_search_engine_web_api_textmarc_full(self): """websearch - search engine Web API for Text MARC output, full""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=higgs&of=tm', expected_text="""\ 000000085 001__ 85 000000085 003__ SzGeCERN 000000085 005__ %(rec_85_rev)s 000000085 035__ $$a2356302CERCER 000000085 035__ $$9SLAC$$a5423422 000000085 037__ $$ahep-th/0212181 000000085 041__ $$aeng 000000085 100__ $$aGirardello, L$$uINFN$$uUniversita di Milano-Bicocca 000000085 245__ $$a3-D Interacting CFTs and Generalized Higgs Phenomenon in Higher Spin Theories on AdS 000000085 260__ $$c2003 000000085 269__ $$c16 Dec 2002 000000085 300__ $$a8 p 000000085 520__ $$aWe study a duality, recently conjectured by Klebanov and Polyakov, between higher-spin theories on AdS_4 and O(N) vector models in 3-d. These theories are free in the UV and interacting in the IR. At the UV fixed point, the O(N) model has an infinite number of higher-spin conserved currents. In the IR, these currents are no longer conserved for spin s>2. In this paper, we show that the dual interpretation of this fact is that all fields of spin s>2 in AdS_4 become massive by a Higgs mechanism, that leaves the spin-2 field massless. We identify the Higgs field and show how it relates to the RG flow connecting the two CFTs, which is induced by a double trace deformation. 000000085 65017 $$2SzGeCERN$$aParticle Physics - Theory 000000085 690C_ $$aARTICLE 000000085 695__ $$9LANL EDS$$aHigh Energy Physics - Theory 000000085 700__ $$aPorrati, Massimo 000000085 700__ $$aZaffaroni, A 000000085 8564_ $$s112828$$u%(siteurl)s/record/85/files/0212181.ps.gz 000000085 8564_ $$s151257$$u%(siteurl)s/record/85/files/0212181.pdf 000000085 859__ $$falberto.zaffaroni@mib.infn.it 000000085 909C4 $$c289-293$$pPhys. Lett. B$$v561$$y2003 000000085 916__ $$sn$$w200251 000000085 960__ $$a13 000000085 961__ $$c20060823$$h0007$$lCER01$$x20021217 000000085 963__ $$aPUBLIC 000000085 970__ $$a002356302CER 000000085 980__ $$aARTICLE 000000085 999C5 $$mD. Francia and A. Sagnotti,$$o[1]$$rhep-th/0207002$$sPhys. Lett. B 543 (2002) 303 000000085 999C5 $$mP. Haggi-Mani and B. Sundborg,$$o[1]$$rhep-th/0002189$$sJ. High Energy Phys. 0004 (2000) 031 000000085 999C5 $$mB. Sundborg,$$o[1]$$rhep-th/0103247$$sNucl. Phys. B, Proc. Suppl. 102 (2001) 113 000000085 999C5 $$mE. Sezgin and P. Sundell,$$o[1]$$rhep-th/0105001$$sJ. High Energy Phys. 0109 (2001) 036 000000085 999C5 $$mA. Mikhailov,$$o[1]$$rhep-th/0201019 000000085 999C5 $$mE. Sezgin and P. Sundell,$$o[1]$$rhep-th/0205131$$sNucl. Phys. B 644 (2002) 303 000000085 999C5 $$mE. Sezgin and P. Sundell,$$o[1]$$rhep-th/0205132$$sJ. High Energy Phys. 0207 (2002) 055 000000085 999C5 $$mJ. Engquist, E. Sezgin and P. Sundell,$$o[1]$$rhep-th/0207101$$sClass. Quantum Gravity 19 (2002) 6175 000000085 999C5 $$mM. A. Vasiliev,$$o[1]$$rhep-th/9611024$$sInt. J. Mod. Phys. D 5 (1996) 763 000000085 999C5 $$mD. Anselmi,$$o[1]$$rhep-th/9808004$$sNucl. Phys. B 541 (1999) 323 000000085 999C5 $$mD. Anselmi,$$o[1]$$rhep-th/9906167$$sClass. Quantum Gravity 17 (2000) 1383 000000085 999C5 $$mE. S. Fradkin and M. A. Vasiliev,$$o[2]$$sNucl. Phys. B 291 (1987) 141 000000085 999C5 $$mE. S. Fradkin and M. A. Vasiliev,$$o[2]$$sPhys. Lett. B 189 (1987) 89 000000085 999C5 $$mI. R. Klebanov and A. M. Polyakov,$$o[3]$$rhep-th/0210114$$sPhys. Lett. B 550 (2002) 213 000000085 999C5 $$mM. A. Vasiliev,$$o[4]$$rhep-th/9910096 000000085 999C5 $$mT. Leonhardt, A. Meziane and W. Ruhl,$$o[5]$$rhep-th/0211092 000000085 999C5 $$mO. Aharony, M. Berkooz and E. Silverstein,$$o[6]$$rhep-th/0105309$$sJ. High Energy Phys. 0108 (2001) 006 000000085 999C5 $$mE. Witten,$$o[7]$$rhep-th/0112258 000000085 999C5 $$mM. Berkooz, A. Sever and A. Shomer$$o[8]$$rhep-th/0112264$$sJ. High Energy Phys. 0205 (2002) 034 000000085 999C5 $$mS. S. Gubser and I. Mitra,$$o[9]$$rhep-th/0210093 000000085 999C5 $$mS. S. Gubser and I. R. Klebanov,$$o[10]$$rhep-th/0212138 000000085 999C5 $$mM. Porrati,$$o[11]$$rhep-th/0112166$$sJ. High Energy Phys. 0204 (2002) 058 000000085 999C5 $$mK. G. Wilson and J. B. Kogut,$$o[12]$$sPhys. Rep. 12 (1974) 75 000000085 999C5 $$mI. R. Klebanov and E. Witten,$$o[13]$$rhep-th/9905104$$sNucl. Phys. B 556 (1999) 89 000000085 999C5 $$mW. Heidenreich,$$o[14]$$sJ. Math. Phys. 22 (1981) 1566 000000085 999C5 $$mD. Anselmi,$$o[15]$$rhep-th/0210123 000000001 001__ 1 000000001 005__ %(rec_1_rev)s 000000001 037__ $$aCERN-EX-0106015 000000001 100__ $$aPhotolab 000000001 245__ $$aALEPH experiment: Candidate of Higgs boson production 000000001 246_1 $$aExpérience ALEPH: Candidat de la production d'un boson Higgs 000000001 260__ $$c14 06 2000 000000001 340__ $$aFILM 000000001 520__ $$aCandidate for the associated production of the Higgs boson and Z boson. Both, the Higgs and Z boson decay into 2 jets each. The green and the yellow jets belong to the Higgs boson. They represent the fragmentation of a bottom andanti-bottom quark. The red and the blue jets stem from the decay of the Z boson into a quark anti-quark pair. Left: View of the event along the beam axis. Bottom right: Zoom around the interaction point at the centre showing detailsof the fragmentation of the bottom and anti-bottom quarks. As expected for b quarks, in each jet the decay of a long-lived B meson is visible. Top right: "World map" showing the spatial distribution of the jets in the event. 000000001 65017 $$2SzGeCERN$$aExperiments and Tracks 000000001 6531_ $$aLEP 000000001 8560_ $$fneil.calder@cern.ch 000000001 8564_ $$s1585244$$u%(siteurl)s/record/1/files/0106015_01.jpg 000000001 8564_ $$s20954$$u%(siteurl)s/record/1/files/0106015_01.gif?subformat=icon$$xicon 000000001 909C0 $$o0003717PHOPHO 000000001 909C0 $$y2000 000000001 909C0 $$b81 000000001 909C1 $$c2001-06-14$$l50$$m2001-08-27$$oCM 000000001 909CP $$pBldg. 2 000000001 909CP $$rCalder, N 000000001 909CS $$sn$$w200231 000000001 980__ $$aPICTURE 000000107 001__ 107 000000107 003__ SzGeCERN 000000107 005__ %(rec_107_rev)s 000000107 035__ $$9SPIRES$$a4066995 000000107 037__ $$aCERN-EP-99-060 000000107 041__ $$aeng 000000107 084__ $$2CERN Library$$aEP-1999-060 000000107 088__ $$9SCAN-9910048 000000107 088__ $$aCERN-L3-175 000000107 110__ $$aCERN. Geneva 000000107 245__ $$aLimits on Higgs boson masses from combining the data of the four LEP experiments at $\sqrt{s} \leq 183 GeV$ 000000107 260__ $$c1999 000000107 269__ $$aGeneva$$bCERN$$c26 Apr 1999 000000107 300__ $$a18 p 000000107 490__ $$aALEPH Papers 000000107 500__ $$aPreprint not submitted to publication 000000107 65017 $$2SzGeCERN$$aParticle Physics - Experiment 000000107 690C_ $$aCERN 000000107 690C_ $$aPREPRINT 000000107 693__ $$aCERN LEP$$eALEPH 000000107 693__ $$aCERN LEP$$eDELPHI 000000107 693__ $$aCERN LEP$$eL3 000000107 693__ $$aCERN LEP$$eOPAL 000000107 695__ $$9MEDLINE$$asearches Higgs bosons 000000107 697C_ $$aLexiHiggs 000000107 710__ $$5EP 000000107 710__ $$gALEPH Collaboration 000000107 710__ $$gDELPHI Collaboration 000000107 710__ $$gL3 Collaboration 000000107 710__ $$gLEP Working Group for Higgs Boson Searches 000000107 710__ $$gOPAL Collaboration 000000107 901__ $$uCERN 000000107 916__ $$sh$$w199941 000000107 960__ $$a11 000000107 963__ $$aPUBLIC 000000107 970__ $$a000330309CER 000000107 980__ $$aARTICLE """ % {'siteurl': CFG_SITE_URL, 'rec_1_rev': get_fieldvalues(1, '005__')[0], 'rec_85_rev': get_fieldvalues(85, '005__')[0], 'rec_107_rev': get_fieldvalues(107, '005__')[0]})) def test_search_engine_web_api_textmarc_field_filtered(self): """websearch - search engine Web API for Text MARC output, field-filtered""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=higgs&of=tm&ot=100,700', expected_text="""\ 000000085 100__ $$aGirardello, L$$uINFN$$uUniversita di Milano-Bicocca 000000085 700__ $$aPorrati, Massimo 000000085 700__ $$aZaffaroni, A 000000001 100__ $$aPhotolab """)) def test_search_engine_web_api_textmarc_field_filtered_hidden_guest(self): """websearch - search engine Web API for Text MARC output, field-filtered, hidden field, no guest access""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=higgs&of=tm&ot=100,595', expected_text="""\ 000000085 100__ $$aGirardello, L$$uINFN$$uUniversita di Milano-Bicocca 000000001 100__ $$aPhotolab """)) def test_search_engine_web_api_textmarc_field_filtered_hidden_admin(self): """websearch - search engine Web API for Text MARC output, field-filtered, hidden field, admin access""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=higgs&of=tm&ot=100,595', username='admin', expected_text="""\ 000000085 100__ $$aGirardello, L$$uINFN$$uUniversita di Milano-Bicocca 000000085 595__ $$aLANL EDS 000000085 595__ $$aSIS LANLPUBL2004 000000085 595__ $$aSIS:2004 PR/LKR added 000000001 100__ $$aPhotolab 000000001 595__ $$aPress 000000107 595__ $$aNo authors 000000107 595__ $$aCERN-EP 000000107 595__ $$aOA 000000107 595__ $$aSIS:200740 PR/LKR not found (from SLAC, INSPEC) """)) def test_search_engine_web_api_textmarc_subfield_values(self): """websearch - search engine Web API for Text MARC output, subfield values""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=higgs&of=tm&ot=700__a', expected_text="""\ Porrati, Massimo Zaffaroni, A """)) def test_search_engine_web_api_xmlmarc_full(self): """websearch - search engine Web API for XMLMARC output, full""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=higgs&of=xm', expected_text="""\ 85 SzGeCERN %(rec_85_rev)s 2356302CERCER SLAC 5423422 hep-th/0212181 eng Girardello, L INFN Universita di Milano-Bicocca 3-D Interacting CFTs and Generalized Higgs Phenomenon in Higher Spin Theories on AdS 2003 16 Dec 2002 8 p We study a duality, recently conjectured by Klebanov and Polyakov, between higher-spin theories on AdS_4 and O(N) vector models in 3-d. These theories are free in the UV and interacting in the IR. At the UV fixed point, the O(N) model has an infinite number of higher-spin conserved currents. In the IR, these currents are no longer conserved for spin s>2. In this paper, we show that the dual interpretation of this fact is that all fields of spin s>2 in AdS_4 become massive by a Higgs mechanism, that leaves the spin-2 field massless. We identify the Higgs field and show how it relates to the RG flow connecting the two CFTs, which is induced by a double trace deformation. SzGeCERN Particle Physics - Theory ARTICLE LANL EDS High Energy Physics - Theory Porrati, Massimo Zaffaroni, A 112828 %(siteurl)s/record/85/files/0212181.ps.gz 151257 %(siteurl)s/record/85/files/0212181.pdf 289-293 Phys. Lett. B 561 2003 alberto.zaffaroni@mib.infn.it n 200251 13 20060823 0007 CER01 20021217 PUBLIC 002356302CER ARTICLE [1] D. Francia and A. Sagnotti, Phys. Lett. B 543 (2002) 303 hep-th/0207002 [1] P. Haggi-Mani and B. Sundborg, J. High Energy Phys. 0004 (2000) 031 hep-th/0002189 [1] B. Sundborg, Nucl. Phys. B, Proc. Suppl. 102 (2001) 113 hep-th/0103247 [1] E. Sezgin and P. Sundell, J. High Energy Phys. 0109 (2001) 036 hep-th/0105001 [1] A. Mikhailov, hep-th/0201019 [1] E. Sezgin and P. Sundell, Nucl. Phys. B 644 (2002) 303 hep-th/0205131 [1] E. Sezgin and P. Sundell, J. High Energy Phys. 0207 (2002) 055 hep-th/0205132 [1] J. Engquist, E. Sezgin and P. Sundell, Class. Quantum Gravity 19 (2002) 6175 hep-th/0207101 [1] M. A. Vasiliev, Int. J. Mod. Phys. D 5 (1996) 763 hep-th/9611024 [1] D. Anselmi, Nucl. Phys. B 541 (1999) 323 hep-th/9808004 [1] D. Anselmi, Class. Quantum Gravity 17 (2000) 1383 hep-th/9906167 [2] E. S. Fradkin and M. A. Vasiliev, Nucl. Phys. B 291 (1987) 141 [2] E. S. Fradkin and M. A. Vasiliev, Phys. Lett. B 189 (1987) 89 [3] I. R. Klebanov and A. M. Polyakov, Phys. Lett. B 550 (2002) 213 hep-th/0210114 [4] M. A. Vasiliev, hep-th/9910096 [5] T. Leonhardt, A. Meziane and W. Ruhl, hep-th/0211092 [6] O. Aharony, M. Berkooz and E. Silverstein, J. High Energy Phys. 0108 (2001) 006 hep-th/0105309 [7] E. Witten, hep-th/0112258 [8] M. Berkooz, A. Sever and A. Shomer J. High Energy Phys. 0205 (2002) 034 hep-th/0112264 [9] S. S. Gubser and I. Mitra, hep-th/0210093 [10] S. S. Gubser and I. R. Klebanov, hep-th/0212138 [11] M. Porrati, J. High Energy Phys. 0204 (2002) 058 hep-th/0112166 [12] K. G. Wilson and J. B. Kogut, Phys. Rep. 12 (1974) 75 [13] I. R. Klebanov and E. Witten, Nucl. Phys. B 556 (1999) 89 hep-th/9905104 [14] W. Heidenreich, J. Math. Phys. 22 (1981) 1566 [15] D. Anselmi, hep-th/0210123 1 %(rec_1_rev)s CERN-EX-0106015 Photolab ALEPH experiment: Candidate of Higgs boson production Expérience ALEPH: Candidat de la production d'un boson Higgs 14 06 2000 FILM Candidate for the associated production of the Higgs boson and Z boson. Both, the Higgs and Z boson decay into 2 jets each. The green and the yellow jets belong to the Higgs boson. They represent the fragmentation of a bottom andanti-bottom quark. The red and the blue jets stem from the decay of the Z boson into a quark anti-quark pair. Left: View of the event along the beam axis. Bottom right: Zoom around the interaction point at the centre showing detailsof the fragmentation of the bottom and anti-bottom quarks. As expected for b quarks, in each jet the decay of a long-lived B meson is visible. Top right: "World map" showing the spatial distribution of the jets in the event. SzGeCERN Experiments and Tracks LEP neil.calder@cern.ch 1585244 %(siteurl)s/record/1/files/0106015_01.jpg 20954 %(siteurl)s/record/1/files/0106015_01.gif?subformat=icon icon 0003717PHOPHO 2000 81 2001-06-14 50 2001-08-27 CM Bldg. 2 Calder, N n 200231 PICTURE 107 SzGeCERN %(rec_107_rev)s SPIRES 4066995 CERN-EP-99-060 eng CERN Library EP-1999-060 SCAN-9910048 CERN-L3-175 CERN. Geneva Limits on Higgs boson masses from combining the data of the four LEP experiments at $\sqrt{s} \leq 183 GeV$ 1999 Geneva CERN 26 Apr 1999 18 p ALEPH Papers Preprint not submitted to publication SzGeCERN Particle Physics - Experiment CERN PREPRINT CERN LEP ALEPH CERN LEP DELPHI CERN LEP L3 CERN LEP OPAL MEDLINE searches Higgs bosons LexiHiggs EP ALEPH Collaboration DELPHI Collaboration L3 Collaboration LEP Working Group for Higgs Boson Searches OPAL Collaboration CERN h 199941 11 PUBLIC 000330309CER ARTICLE """ % {'siteurl': CFG_SITE_URL, 'rec_1_rev': get_fieldvalues(1, '005__')[0], 'rec_85_rev': get_fieldvalues(85, '005__')[0], 'rec_107_rev': get_fieldvalues(107, '005__')[0]})) def test_search_engine_web_api_xmlmarc_field_filtered(self): """websearch - search engine Web API for XMLMARC output, field-filtered""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=higgs&of=xm&ot=100,700', expected_text="""\ 85 Girardello, L INFN Universita di Milano-Bicocca Porrati, Massimo Zaffaroni, A 1 Photolab 107 """)) def test_search_engine_web_api_xmlmarc_field_filtered_hidden_guest(self): """websearch - search engine Web API for XMLMARC output, field-filtered, hidden field, no guest access""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=higgs&of=xm&ot=100,595', expected_text="""\ 85 Girardello, L INFN Universita di Milano-Bicocca 1 Photolab 107 """)) def test_search_engine_web_api_xmlmarc_field_filtered_hidden_admin(self): """websearch - search engine Web API for XMLMARC output, field-filtered, hidden field, admin access""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=higgs&of=xm&ot=100,595', username='admin', expected_text="""\ 85 Girardello, L INFN Universita di Milano-Bicocca LANL EDS SIS LANLPUBL2004 SIS:2004 PR/LKR added 1 Photolab Press 107 No authors CERN-EP OA SIS:200740 PR/LKR not found (from SLAC, INSPEC) """)) class WebSearchSearchEngineJSONAPITest(InvenioTestCase): """Check typical search engine JSON API calls on the demo data.""" def test_search_engine_json_api_for_failed_query(self): """websearch - search engine JSON API for failed query""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=aoeuidhtns&of=recjson', expected_text="")) def test_search_engine_json_api_for_ellis_query(self): """websearch - search engine JSON API for Ellis""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=ellis&of=recjson&ot=recid', expected_text='[{"recid": 47},{"recid": 18},{"recid": 17},{"recid": 16},{"recid": 15},{"recid": 14},{"recid": 13},{"recid": 12},{"recid": 11},{"recid": 10}]')) def test_search_engine_json_api_for_ellis_query_paginated(self): """websearch - search engine JSON API for Ellis, output fields and pagination""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=ellis&of=recjson&ot=recid,title&jrec=4&rg=2', expected_text='[{"recid": 16, "title": {"title": "Cosmological perturbations in Kaluza-Klein models"}},{"recid": 15, "title": {"title": "Cosmic equation of state, Gravitational Lensing Statistics and Merging of Galaxies"}}]')) class WebSearchRecordWebAPITest(InvenioTestCase): """Check typical /record Web API calls on the demo data.""" def test_record_web_api_textmarc_full(self): """websearch - /record Web API for TextMARC output, full""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/record/85?of=tm', expected_text="""\ 000000085 001__ 85 000000085 003__ SzGeCERN 000000085 005__ %(rec_85_rev)s 000000085 035__ $$a2356302CERCER 000000085 035__ $$9SLAC$$a5423422 000000085 037__ $$ahep-th/0212181 000000085 041__ $$aeng 000000085 100__ $$aGirardello, L$$uINFN$$uUniversita di Milano-Bicocca 000000085 245__ $$a3-D Interacting CFTs and Generalized Higgs Phenomenon in Higher Spin Theories on AdS 000000085 260__ $$c2003 000000085 269__ $$c16 Dec 2002 000000085 300__ $$a8 p 000000085 520__ $$aWe study a duality, recently conjectured by Klebanov and Polyakov, between higher-spin theories on AdS_4 and O(N) vector models in 3-d. These theories are free in the UV and interacting in the IR. At the UV fixed point, the O(N) model has an infinite number of higher-spin conserved currents. In the IR, these currents are no longer conserved for spin s>2. In this paper, we show that the dual interpretation of this fact is that all fields of spin s>2 in AdS_4 become massive by a Higgs mechanism, that leaves the spin-2 field massless. We identify the Higgs field and show how it relates to the RG flow connecting the two CFTs, which is induced by a double trace deformation. 000000085 65017 $$2SzGeCERN$$aParticle Physics - Theory 000000085 690C_ $$aARTICLE 000000085 695__ $$9LANL EDS$$aHigh Energy Physics - Theory 000000085 700__ $$aPorrati, Massimo 000000085 700__ $$aZaffaroni, A 000000085 8564_ $$s112828$$u%(siteurl)s/record/85/files/0212181.ps.gz 000000085 8564_ $$s151257$$u%(siteurl)s/record/85/files/0212181.pdf 000000085 859__ $$falberto.zaffaroni@mib.infn.it 000000085 909C4 $$c289-293$$pPhys. Lett. B$$v561$$y2003 000000085 916__ $$sn$$w200251 000000085 960__ $$a13 000000085 961__ $$c20060823$$h0007$$lCER01$$x20021217 000000085 963__ $$aPUBLIC 000000085 970__ $$a002356302CER 000000085 980__ $$aARTICLE 000000085 999C5 $$mD. Francia and A. Sagnotti,$$o[1]$$rhep-th/0207002$$sPhys. Lett. B 543 (2002) 303 000000085 999C5 $$mP. Haggi-Mani and B. Sundborg,$$o[1]$$rhep-th/0002189$$sJ. High Energy Phys. 0004 (2000) 031 000000085 999C5 $$mB. Sundborg,$$o[1]$$rhep-th/0103247$$sNucl. Phys. B, Proc. Suppl. 102 (2001) 113 000000085 999C5 $$mE. Sezgin and P. Sundell,$$o[1]$$rhep-th/0105001$$sJ. High Energy Phys. 0109 (2001) 036 000000085 999C5 $$mA. Mikhailov,$$o[1]$$rhep-th/0201019 000000085 999C5 $$mE. Sezgin and P. Sundell,$$o[1]$$rhep-th/0205131$$sNucl. Phys. B 644 (2002) 303 000000085 999C5 $$mE. Sezgin and P. Sundell,$$o[1]$$rhep-th/0205132$$sJ. High Energy Phys. 0207 (2002) 055 000000085 999C5 $$mJ. Engquist, E. Sezgin and P. Sundell,$$o[1]$$rhep-th/0207101$$sClass. Quantum Gravity 19 (2002) 6175 000000085 999C5 $$mM. A. Vasiliev,$$o[1]$$rhep-th/9611024$$sInt. J. Mod. Phys. D 5 (1996) 763 000000085 999C5 $$mD. Anselmi,$$o[1]$$rhep-th/9808004$$sNucl. Phys. B 541 (1999) 323 000000085 999C5 $$mD. Anselmi,$$o[1]$$rhep-th/9906167$$sClass. Quantum Gravity 17 (2000) 1383 000000085 999C5 $$mE. S. Fradkin and M. A. Vasiliev,$$o[2]$$sNucl. Phys. B 291 (1987) 141 000000085 999C5 $$mE. S. Fradkin and M. A. Vasiliev,$$o[2]$$sPhys. Lett. B 189 (1987) 89 000000085 999C5 $$mI. R. Klebanov and A. M. Polyakov,$$o[3]$$rhep-th/0210114$$sPhys. Lett. B 550 (2002) 213 000000085 999C5 $$mM. A. Vasiliev,$$o[4]$$rhep-th/9910096 000000085 999C5 $$mT. Leonhardt, A. Meziane and W. Ruhl,$$o[5]$$rhep-th/0211092 000000085 999C5 $$mO. Aharony, M. Berkooz and E. Silverstein,$$o[6]$$rhep-th/0105309$$sJ. High Energy Phys. 0108 (2001) 006 000000085 999C5 $$mE. Witten,$$o[7]$$rhep-th/0112258 000000085 999C5 $$mM. Berkooz, A. Sever and A. Shomer$$o[8]$$rhep-th/0112264$$sJ. High Energy Phys. 0205 (2002) 034 000000085 999C5 $$mS. S. Gubser and I. Mitra,$$o[9]$$rhep-th/0210093 000000085 999C5 $$mS. S. Gubser and I. R. Klebanov,$$o[10]$$rhep-th/0212138 000000085 999C5 $$mM. Porrati,$$o[11]$$rhep-th/0112166$$sJ. High Energy Phys. 0204 (2002) 058 000000085 999C5 $$mK. G. Wilson and J. B. Kogut,$$o[12]$$sPhys. Rep. 12 (1974) 75 000000085 999C5 $$mI. R. Klebanov and E. Witten,$$o[13]$$rhep-th/9905104$$sNucl. Phys. B 556 (1999) 89 000000085 999C5 $$mW. Heidenreich,$$o[14]$$sJ. Math. Phys. 22 (1981) 1566 000000085 999C5 $$mD. Anselmi,$$o[15]$$rhep-th/0210123 """ % {'siteurl': CFG_SITE_URL, 'rec_85_rev': get_fieldvalues(85, '005__')[0]})) def test_record_web_api_xmlmarc_full(self): """websearch - /record Web API for XMLMARC output, full""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/record/85?of=xm', expected_text="""\ 85 SzGeCERN %(rec_85_rev)s 2356302CERCER SLAC 5423422 hep-th/0212181 eng Girardello, L INFN Universita di Milano-Bicocca 3-D Interacting CFTs and Generalized Higgs Phenomenon in Higher Spin Theories on AdS 2003 16 Dec 2002 8 p We study a duality, recently conjectured by Klebanov and Polyakov, between higher-spin theories on AdS_4 and O(N) vector models in 3-d. These theories are free in the UV and interacting in the IR. At the UV fixed point, the O(N) model has an infinite number of higher-spin conserved currents. In the IR, these currents are no longer conserved for spin s>2. In this paper, we show that the dual interpretation of this fact is that all fields of spin s>2 in AdS_4 become massive by a Higgs mechanism, that leaves the spin-2 field massless. We identify the Higgs field and show how it relates to the RG flow connecting the two CFTs, which is induced by a double trace deformation. SzGeCERN Particle Physics - Theory ARTICLE LANL EDS High Energy Physics - Theory Porrati, Massimo Zaffaroni, A 112828 %(siteurl)s/record/85/files/0212181.ps.gz 151257 %(siteurl)s/record/85/files/0212181.pdf 289-293 Phys. Lett. B 561 2003 alberto.zaffaroni@mib.infn.it n 200251 13 20060823 0007 CER01 20021217 PUBLIC 002356302CER ARTICLE [1] D. Francia and A. Sagnotti, Phys. Lett. B 543 (2002) 303 hep-th/0207002 [1] P. Haggi-Mani and B. Sundborg, J. High Energy Phys. 0004 (2000) 031 hep-th/0002189 [1] B. Sundborg, Nucl. Phys. B, Proc. Suppl. 102 (2001) 113 hep-th/0103247 [1] E. Sezgin and P. Sundell, J. High Energy Phys. 0109 (2001) 036 hep-th/0105001 [1] A. Mikhailov, hep-th/0201019 [1] E. Sezgin and P. Sundell, Nucl. Phys. B 644 (2002) 303 hep-th/0205131 [1] E. Sezgin and P. Sundell, J. High Energy Phys. 0207 (2002) 055 hep-th/0205132 [1] J. Engquist, E. Sezgin and P. Sundell, Class. Quantum Gravity 19 (2002) 6175 hep-th/0207101 [1] M. A. Vasiliev, Int. J. Mod. Phys. D 5 (1996) 763 hep-th/9611024 [1] D. Anselmi, Nucl. Phys. B 541 (1999) 323 hep-th/9808004 [1] D. Anselmi, Class. Quantum Gravity 17 (2000) 1383 hep-th/9906167 [2] E. S. Fradkin and M. A. Vasiliev, Nucl. Phys. B 291 (1987) 141 [2] E. S. Fradkin and M. A. Vasiliev, Phys. Lett. B 189 (1987) 89 [3] I. R. Klebanov and A. M. Polyakov, Phys. Lett. B 550 (2002) 213 hep-th/0210114 [4] M. A. Vasiliev, hep-th/9910096 [5] T. Leonhardt, A. Meziane and W. Ruhl, hep-th/0211092 [6] O. Aharony, M. Berkooz and E. Silverstein, J. High Energy Phys. 0108 (2001) 006 hep-th/0105309 [7] E. Witten, hep-th/0112258 [8] M. Berkooz, A. Sever and A. Shomer J. High Energy Phys. 0205 (2002) 034 hep-th/0112264 [9] S. S. Gubser and I. Mitra, hep-th/0210093 [10] S. S. Gubser and I. R. Klebanov, hep-th/0212138 [11] M. Porrati, J. High Energy Phys. 0204 (2002) 058 hep-th/0112166 [12] K. G. Wilson and J. B. Kogut, Phys. Rep. 12 (1974) 75 [13] I. R. Klebanov and E. Witten, Nucl. Phys. B 556 (1999) 89 hep-th/9905104 [14] W. Heidenreich, J. Math. Phys. 22 (1981) 1566 [15] D. Anselmi, hep-th/0210123 """ % {'siteurl': CFG_SITE_URL, 'rec_85_rev': get_fieldvalues(85, '005__')[0]})) def test_record_web_api_textmarc_field_filtered(self): """websearch - /record Web API for TextMARC output, field-filtered""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/record/85?of=tm&ot=100,700', expected_text="""\ 000000085 100__ $$aGirardello, L$$uINFN$$uUniversita di Milano-Bicocca 000000085 700__ $$aPorrati, Massimo 000000085 700__ $$aZaffaroni, A """)) def test_record_web_api_textmarc_field_filtered_hidden_guest(self): """websearch - /record Web API for TextMARC output, field-filtered, hidden field, no guest access""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/record/85?of=tm&ot=100,595', expected_text="""\ 000000085 100__ $$aGirardello, L$$uINFN$$uUniversita di Milano-Bicocca """)) def test_record_web_api_textmarc_field_filtered_hidden_admin(self): """websearch - /record Web API for TextMARC output, field-filtered, hidden field, admin access""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/record/85?of=tm&ot=100,595', username='admin', expected_text="""\ 000000085 100__ $$aGirardello, L$$uINFN$$uUniversita di Milano-Bicocca 000000085 595__ $$aLANL EDS 000000085 595__ $$aSIS LANLPUBL2004 000000085 595__ $$aSIS:2004 PR/LKR added """)) def test_record_web_api_xmlmarc_field_filtered(self): """websearch - /record Web API for XMLMARC output, field-filtered""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/record/85?of=xm&ot=100,700', expected_text="""\ 85 Girardello, L INFN Universita di Milano-Bicocca Porrati, Massimo Zaffaroni, A """)) def test_record_web_api_xmlmarc_field_filtered_hidden_guest(self): """websearch - /record Web API for XMLMARC output, field-filtered, hidden field, no guest access""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/record/85?of=xm&ot=100,595', expected_text="""\ 85 Girardello, L INFN Universita di Milano-Bicocca """)) def test_record_web_api_xmlmarc_field_filtered_hidden_admin(self): """websearch - /record Web API for XMLMARC output, field-filtered, hidden field, admin access""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/record/85?of=xm&ot=100,595', username='admin', expected_text="""\ 85 Girardello, L INFN Universita di Milano-Bicocca LANL EDS SIS LANLPUBL2004 SIS:2004 PR/LKR added """)) def test_record_web_api_textmarc_subfield_values(self): """websearch - /record Web API for TextMARC output, subfield values""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/record/85?of=tm&ot=700__a', expected_text="""\ Porrati, Massimo Zaffaroni, A """)) class WebSearchRecordJSONAPITest(InvenioTestCase): """Check typical /record JSON API calls on the demo data.""" def test_record_json_api_for_failed_field(self): """websearch - search engine JSON API for failed field""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/record/81?of=recjson&ot=aoeuidhtns', expected_text='[{"aoeuidhtns": null}]')) def test_record_json_api_for_field(self): """websearch - search engine JSON API for existing field""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/record/81?of=recjson&ot=authors', expected_text='[{"authors": [{"affiliation": "Stanford University", "first_name": "A", "last_name": "Adams", "full_name": "Adams, A"}, {"first_name": "J", "last_name": "McGreevy", "full_name": "McGreevy, J"}, {"first_name": "E", "last_name": "Silverstein", "full_name": "Silverstein, E"}]}]')) def test_record_json_api_for_field_subfield(self): """websearch - search engine JSON API for existing field.subfield""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/record/81?of=recjson&ot=authors.last_name', expected_text='[{"authors": {"last_name": ["Adams", "McGreevy", "Silverstein"]}}]')) def test_record_json_api_for_derived_field(self): """websearch - search engine JSON API for derived field""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/record/81?of=recjson&ot=number_of_authors', expected_text='[{"number_of_authors": 3}]')) def test_record_json_api_for_virtual_field(self): """websearch - search engine JSON API for virtual field""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/record/81?of=recjson&ot=recid,number_of_citations', expected_text='[{"recid": 81, "number_of_citations": 4}]')) class WebSearchRestrictedCollectionTest(InvenioTestCase): """Test of the restricted collections behaviour.""" def test_restricted_collection_interface_page(self): """websearch - restricted collection interface page body""" # there should be no Latest additions box for restricted collections self.assertNotEqual([], test_web_page_content(CFG_SITE_URL + '/collection/Theses', expected_text="Latest additions")) def test_restricted_search_as_anonymous_guest(self): """websearch - restricted collection not searchable by anonymous guest""" browser = Browser() browser.open(CFG_SITE_URL + '/search?c=Theses') response = browser.response().read() if response.find("If you think you have right to access it, please authenticate yourself.") > -1: pass else: self.fail("Oops, searching restricted collection without password should have redirected to login dialog.") return def test_restricted_search_as_authorized_person(self): """websearch - restricted collection searchable by authorized person""" browser = Browser() browser.open(CFG_SITE_URL + '/search?c=Theses') browser.select_form(nr=0) browser['p_un'] = 'jekyll' browser['p_pw'] = 'j123ekyll' browser.submit() if browser.response().read().find("records found") > -1: pass else: self.fail("Oops, Dr. Jekyll should be able to search Theses collection.") def test_restricted_search_as_unauthorized_person(self): """websearch - restricted collection not searchable by unauthorized person""" browser = Browser() browser.open(CFG_SITE_URL + '/search?c=Theses') browser.select_form(nr=0) browser['p_un'] = 'hyde' browser['p_pw'] = 'h123yde' browser.submit() # Mr. Hyde should not be able to connect: if browser.response().read().find("Authorization failure") <= -1: # if we got here, things are broken: self.fail("Oops, Mr.Hyde should not be able to search Theses collection.") def test_restricted_detailed_record_page_as_anonymous_guest(self): """websearch - restricted detailed record page not accessible to guests""" browser = Browser() browser.open(CFG_SITE_URL + '/%s/35' % CFG_SITE_RECORD) if browser.response().read().find("You can use your nickname or your email address to login.") > -1: pass else: self.fail("Oops, searching restricted collection without password should have redirected to login dialog.") return def test_restricted_detailed_record_page_as_authorized_person(self): """websearch - restricted detailed record page accessible to authorized person""" browser = Browser() browser.open(CFG_SITE_URL + '/youraccount/login') browser.select_form(nr=0) browser['p_un'] = 'jekyll' browser['p_pw'] = 'j123ekyll' browser.submit() browser.open(CFG_SITE_URL + '/%s/35' % CFG_SITE_RECORD) # Dr. Jekyll should be able to connect # (add the pw to the whole CFG_SITE_URL because we shall be # redirected to '/reordrestricted/'): if browser.response().read().find("A High-performance Video Browsing System") > -1: pass else: self.fail("Oops, Dr. Jekyll should be able to access restricted detailed record page.") def test_restricted_detailed_record_page_as_unauthorized_person(self): """websearch - restricted detailed record page not accessible to unauthorized person""" browser = Browser() browser.open(CFG_SITE_URL + '/youraccount/login') browser.select_form(nr=0) browser['p_un'] = 'hyde' browser['p_pw'] = 'h123yde' browser.submit() browser.open(CFG_SITE_URL + '/%s/35' % CFG_SITE_RECORD) # Mr. Hyde should not be able to connect: if browser.response().read().find('You are not authorized') <= -1: # if we got here, things are broken: self.fail("Oops, Mr.Hyde should not be able to access restricted detailed record page.") def test_collection_restricted_p(self): """websearch - collection_restricted_p""" self.failUnless(collection_restricted_p('Theses'), True) self.failIf(collection_restricted_p('Books & Reports')) def test_get_permitted_restricted_collections(self): """websearch - get_permitted_restricted_collections""" from invenio.webuser import get_uid_from_email, collect_user_info self.assertEqual(get_permitted_restricted_collections(collect_user_info(get_uid_from_email('jekyll@cds.cern.ch'))), ['Theses', 'Drafts']) self.assertEqual(get_permitted_restricted_collections(collect_user_info(get_uid_from_email('hyde@cds.cern.ch'))), []) self.assertEqual(get_permitted_restricted_collections(collect_user_info(get_uid_from_email('balthasar.montague@cds.cern.ch'))), ['ALEPH Theses', 'ALEPH Internal Notes', 'Atlantis Times Drafts']) self.assertEqual(get_permitted_restricted_collections(collect_user_info(get_uid_from_email('dorian.gray@cds.cern.ch'))), ['ISOLDE Internal Notes']) def test_restricted_record_has_restriction_flag(self): """websearch - restricted record displays a restriction flag""" browser = Browser() browser.open(CFG_SITE_URL + '/%s/42/files/' % CFG_SITE_RECORD) browser.select_form(nr=0) browser['p_un'] = 'jekyll' browser['p_pw'] = 'j123ekyll' browser.submit() if browser.response().read().find("Restricted") > -1: pass else: self.fail("Oops, a 'Restricted' flag should appear on restricted records.") browser.open(CFG_SITE_URL + '/%s/42/files/comments' % CFG_SITE_RECORD) if browser.response().read().find("Restricted") > -1: pass else: self.fail("Oops, a 'Restricted' flag should appear on restricted records.") # Flag also appear on records that exist both in a public and # restricted collection: error_messages = test_web_page_content(CFG_SITE_URL + '/%s/109' % CFG_SITE_RECORD, username='admin', password='', expected_text=['Restricted']) if error_messages: self.fail("Oops, a 'Restricted' flag should appear on restricted records.") class WebSearchRestrictedCollectionHandlingTest(InvenioTestCase): """ Check how the restricted or restricted and "hidden" collection handling works: (i)user has or not rights to access to specific records or collections, (ii)public and restricted results are displayed in the right position in the collection tree, (iii)display the right warning depending on the case. Changes in the collection tree used for testing (are showed the records used for testing as well): Articles & Preprints Books & Reports _____________|________________ ____________|_____________ | | | | | | | Articles Drafts(r) Notes Preprints Books Theses(r) Reports 69 77 109 10 105 77 98 98 108 105 CERN Experiments _________________________|___________________________ | | ALEPH ISOLDE _________________|_________________ ____________|_____________ | | | | | ALEPH ALEPH ALEPH ISOLDE ISOLDE Papers Internal Notes(r) Theses(r) Papers Internal Notes(r&h) 10 109 105 69 110 108 106 Authorized users: jekyll -> Drafts, Theses balthasar -> ALEPH Internal Notes, ALEPH Theses dorian -> ISOLDE Internal Notes """ def test_show_public_colls_in_warning_as_unauthorizad_user(self): """websearch - show public daugther collections in warning to unauthorized user""" error_messages = test_web_page_content(CFG_SITE_URL + '/search?ln=en&cc=Articles+%26+Preprints&sc=1&p=recid:20', username='hyde', password='h123yde', expected_text=['No match found in collection Articles, Preprints, Notes.']) if error_messages: self.fail(merge_error_messages(error_messages)) def test_show_public_and_restricted_colls_in_warning_as_authorized_user(self): """websearch - show public and restricted daugther collections in warning to authorized user""" error_messages = test_web_page_content(CFG_SITE_URL + '/search?ln=en&cc=Articles+%26+Preprints&sc=1&p=recid:20', username='jekyll', password='j123ekyll', expected_text=['No match found in collection Articles, Preprints, Notes, Drafts.']) if error_messages: self.fail(merge_error_messages(error_messages)) def test_restricted_record_in_different_colls_as_unauthorized_user(self): """websearch - record belongs to different restricted collections with different rights, user not has rights""" error_messages = test_web_page_content(CFG_SITE_URL + '/search?p=105&f=recid', username='hyde', password='h123yde', expected_text=['No public collection matched your query.'], unexpected_text=['records found']) if error_messages: self.fail(merge_error_messages(error_messages)) def test_restricted_record_in_different_colls_as_authorized_user_of_one_coll(self): """websearch - record belongs to different restricted collections with different rights, balthasar has rights to one of them""" from invenio.config import CFG_WEBSEARCH_VIEWRESTRCOLL_POLICY policy = CFG_WEBSEARCH_VIEWRESTRCOLL_POLICY.strip().upper() if policy == 'ANY': error_messages = test_web_page_content(CFG_SITE_URL + '/search?&sc=1&p=recid:105&c=Articles+%26+Preprints&c=Books+%26+Reports&c=Multimedia+%26+Arts', username='balthasar', password='b123althasar', expected_text=['[CERN-THESIS-99-074]'], unexpected_text=['No public collection matched your query.']) else: error_messages = test_web_page_content(CFG_SITE_URL + '/search?&sc=1&p=recid:105&c=Articles+%26+Preprints&c=Books+%26+Reports&c=Multimedia+%26+Arts', username='balthasar', password='b123althasar', expected_text=['No public collection matched your query.'], unexpected_text=['[CERN-THESIS-99-074]']) if error_messages: self.fail(merge_error_messages(error_messages)) def test_restricted_record_in_different_colls_as_authorized_user_of_two_colls(self): """websearch - record belongs to different restricted collections with different rights, jekyll has rights to two of them""" error_messages = test_web_page_content(CFG_SITE_URL + '/search?&sc=1&p=recid:105&c=Articles+%26+Preprints&c=Books+%26+Reports&c=Multimedia+%26+Arts', username='jekyll', password='j123ekyll', expected_text=['Articles & Preprints', 'Books & Reports']) if error_messages: self.fail(merge_error_messages(error_messages)) def test_restricted_record_in_different_colls_as_authorized_user_of_all_colls(self): """websearch - record belongs to different restricted collections with different rights, admin has rights to all of them""" error_messages = test_web_page_content(CFG_SITE_URL + '/search?&sc=1&p=recid:105&c=Articles+%26+Preprints&c=Books+%26+Reports&c=Multimedia+%26+Arts', username='admin', expected_text=['Articles & Preprints', 'Books & Reports', 'ALEPH Theses']) if error_messages: self.fail(merge_error_messages(error_messages)) def test_search_restricted_record_from_not_dad_coll(self): """websearch - record belongs to different restricted collections with different rights, search from a not dad collection""" error_messages = test_web_page_content(CFG_SITE_URL + '/search?ln=en&cc=Multimedia+%26+Arts&sc=1&p=recid%3A105&f=&action_search=Search&c=Pictures&c=Poetry&c=Atlantis+Times', username='admin', expected_text='No match found in collection', expected_link_label='1 hits') if error_messages: self.fail(merge_error_messages(error_messages)) def test_public_and_restricted_record_as_unauthorized_user(self): """websearch - record belongs to different public and restricted collections, user not has rights""" error_messages = test_web_page_content(CFG_SITE_URL + '/search?&sc=1&p=geometry&c=Articles+%26+Preprints&c=Books+%26+Reports&c=Multimedia+%26+Arts&of=id&so=a', username='guest', expected_text='[86, 80]', unexpected_text='[40, 80, 86]') if error_messages: self.fail(merge_error_messages(error_messages)) def test_public_and_restricted_record_as_authorized_user(self): """websearch - record belongs to different public and restricted collections, admin has rights""" error_messages = test_web_page_content(CFG_SITE_URL + '/search?&sc=1&p=geometry&c=Articles+%26+Preprints&c=Books+%26+Reports&c=Multimedia+%26+Arts&of=id&so=a', username='admin', password='', expected_text='[86, 40, 80]') if error_messages: self.fail(merge_error_messages(error_messages)) def test_public_and_restricted_record_of_focus_as_unauthorized_user(self): """websearch - record belongs to both a public and a restricted collection of "focus on", user not has rights""" error_messages = test_web_page_content(CFG_SITE_URL + '/search?ln=en&cc=Articles+%26+Preprints&sc=1&p=109&f=recid', username='hyde', password='h123yde', expected_text=['No public collection matched your query'], unexpected_text=['LEP Center-of-Mass Energies in Presence of Opposite']) if error_messages: self.fail(merge_error_messages(error_messages)) def test_public_and_restricted_record_of_focus_as_authorized_user(self): """websearch - record belongs to both a public and a restricted collection of "focus on", user has rights""" error_messages = test_web_page_content(CFG_SITE_URL + '/search?&sc=1&p=109&f=recid&c=Articles+%26+Preprints&c=Books+%26+Reports&c=Multimedia+%26+Arts', username='balthasar', password='b123althasar', expected_text=['Articles & Preprints', 'ALEPH Internal Notes', 'LEP Center-of-Mass Energies in Presence of Opposite']) if error_messages: self.fail(merge_error_messages(error_messages)) def test_search_public_and_restricted_record_from_not_dad_coll_as_authorized_user(self): """websearch - record belongs to both a public and a restricted collection, search from a not dad collection, admin has rights""" error_messages = test_web_page_content(CFG_SITE_URL + '/search?ln=en&cc=Books+%26+Reports&sc=1&p=recid%3A98&f=&action_search=Search&c=Books&c=Reports', username='admin', password='', expected_text='No match found in collection Books, Theses, Reports', expected_link_label='1 hits') if error_messages: self.fail(merge_error_messages(error_messages)) def test_search_public_and_restricted_record_from_not_dad_coll_as_unauthorized_user(self): """websearch - record belongs to both a public and a restricted collection, search from a not dad collection, hyde not has rights""" error_messages = test_web_page_content(CFG_SITE_URL + '/search?ln=en&cc=Books+%26+Reports&sc=1&p=recid%3A98&f=&action_search=Search&c=Books&c=Reports', username='hyde', password='h123yde', expected_text='No public collection matched your query', unexpected_text='No match found in collection') if error_messages: self.fail(merge_error_messages(error_messages)) def test_restricted_record_of_focus_as_authorized_user(self): """websearch - record belongs to a restricted collection of "focus on", balthasar has rights""" error_messages = test_web_page_content(CFG_SITE_URL + '/search?&sc=1&p=106&f=recid&c=Articles+%26+Preprints&c=Books+%26+Reports&c=Multimedia+%26+Arts&of=id', username='balthasar', password='b123althasar', expected_text='[106]', unexpected_text='[]') if error_messages: self.fail(merge_error_messages(error_messages)) def test_display_dad_coll_of_restricted_coll_as_unauthorized_user(self): """websearch - unauthorized user displays a collection that contains a restricted collection""" error_messages = test_web_page_content(CFG_SITE_URL + '/search?ln=en&cc=Articles+%26+Preprints&sc=1&p=&f=&action_search=Search&c=Articles&c=Drafts&c=Preprints', username='guest', expected_text=['This collection is restricted.']) if error_messages: self.fail(merge_error_messages(error_messages)) def test_display_dad_coll_of_restricted_coll_as_authorized_user(self): """websearch - authorized user displays a collection that contains a restricted collection""" error_messages = test_web_page_content(CFG_SITE_URL + '/search?ln=en&cc=Articles+%26+Preprints&sc=1&p=&f=&action_search=Search&c=Articles&c=Drafts&c=Notes&c=Preprints', username='jekyll', password='j123ekyll', expected_text=['Articles', 'Drafts', 'Notes', 'Preprints'], unexpected_text=['This collection is restricted.']) if error_messages: self.fail(merge_error_messages(error_messages)) def test_search_restricted_record_from_coll_of_focus_as_unauthorized_user(self): """websearch - search for a record that belongs to a restricted collection from a collection of "focus on" , jekyll not has rights""" error_messages = test_web_page_content(CFG_SITE_URL + '/search?ln=en&cc=CERN+Divisions&sc=1&p=recid%3A106&f=&action_search=Search&c=Experimental+Physics+(EP)&c=Theoretical+Physics+(TH)', username='jekyll', password='j123ekyll', expected_text=['No public collection matched your query.']) if error_messages: self.fail(merge_error_messages(error_messages)) def test_search_restricted_record_from_coll_of_focus_as_authorized_user(self): """websearch - search for a record that belongs to a restricted collection from a collection of "focus on" , admin has rights""" error_messages = test_web_page_content(CFG_SITE_URL + '/search?ln=en&cc=CERN+Divisions&sc=1&p=recid%3A106&f=&action_search=Search&c=Experimental+Physics+(EP)&c=Theoretical+Physics+(TH)', username='admin', password='', expected_text='No match found in collection Experimental Physics (EP), Theoretical Physics (TH).', expected_link_label='1 hits') if error_messages: self.fail(merge_error_messages(error_messages)) def test_search_restricted_record_from_not_direct_dad_coll_and_display_in_right_position_in_tree(self): """websearch - search for a restricted record from not direct dad collection and display it on its right position in the tree""" error_messages = test_web_page_content(CFG_SITE_URL + '/search?ln=en&sc=1&p=recid%3A40&f=&action_search=Search&c=Articles+%26+Preprints&c=Books+%26+Reports&c=Multimedia+%26+Arts', username='admin', password='', expected_text=['Books & Reports','[LBL-22304]']) if error_messages: self.fail(merge_error_messages(error_messages)) def test_search_restricted_record_from_direct_dad_coll_and_display_in_right_position_in_tree(self): """websearch - search for a restricted record from the direct dad collection and display it on its right position in the tree""" error_messages = test_web_page_content(CFG_SITE_URL + '/search?ln=en&cc=Books+%26+Reports&sc=1&p=recid%3A40&f=&action_search=Search&c=Books&c=Reports', username='admin', password='', expected_text=['Theses', '[LBL-22304]']) if error_messages: self.fail(merge_error_messages(error_messages)) def test_restricted_and_hidden_record_as_unauthorized_user(self): """websearch - search for a "hidden" record, user not has rights""" error_messages = test_web_page_content(CFG_SITE_URL + '/search?ln=en&sc=1&p=recid%3A110&f=&action_search=Search&c=Articles+%26+Preprints&c=Books+%26+Reports&c=Multimedia+%26+Arts', username='guest', expected_text=['If you were looking for a non-public document'], unexpected_text=['If you were looking for a hidden document']) if error_messages: self.fail(merge_error_messages(error_messages)) def test_restricted_and_hidden_record_as_authorized_user(self): """websearch - search for a "hidden" record, admin has rights""" error_messages = test_web_page_content(CFG_SITE_URL + '/search?ln=en&sc=1&p=recid%3A110&f=&action_search=Search&c=Articles+%26+Preprints&c=Books+%26+Reports&c=Multimedia+%26+Arts', username='admin', password='', expected_text=['If you were looking for a hidden document, please type the correct URL for this record.']) if error_messages: self.fail(merge_error_messages(error_messages)) def test_enter_url_of_restricted_and_hidden_coll_as_unauthorized_user(self): """websearch - unauthorized user types the concret URL of a "hidden" collection""" error_messages = test_web_page_content(CFG_SITE_URL + '/search?ln=en&cc=ISOLDE+Internal+Notes&sc=1&p=&f=&action_search=Search', username='guest', expected_text=['This collection is restricted.']) if error_messages: self.fail(merge_error_messages(error_messages)) def test_enter_url_of_restricted_and_hidden_coll_as_authorized_user(self): """websearch - authorized user types the concret URL of a "hidden" collection""" error_messages = test_web_page_content(CFG_SITE_URL + '/search?ln=en&cc=ISOLDE+Internal+Notes&sc=1&p=&f=&action_search=Search', username='dorian', password='d123orian', expected_text=['ISOLDE Internal Notes', '[CERN-PS-PA-Note-93-04]'], unexpected_text=['This collection is restricted.']) if error_messages: self.fail(merge_error_messages(error_messages)) def test_search_for_pattern_from_the_top_as_unauthorized_user(self): """websearch - unauthorized user searches for a pattern from the top""" error_messages = test_web_page_content(CFG_SITE_URL + '/search?ln=en&sc=1&p=of&f=&action_search=Search&c=Articles+%26+Preprints&c=Books+%26+Reports&c=Multimedia+%26+Arts', username='guest', expected_text=['Articles & Preprints', '61', 'records found', 'Books & Reports', '2', 'records found', 'Multimedia & Arts', '14', 'records found']) if error_messages: self.fail(merge_error_messages(error_messages)) def test_search_for_pattern_from_the_top_as_authorized_user(self): """websearch - authorized user searches for a pattern from the top""" error_messages = test_web_page_content(CFG_SITE_URL + '/search?ln=en&sc=1&p=of&f=&action_search=Search&c=Articles+%26+Preprints&c=Books+%26+Reports&c=Multimedia+%26+Arts', username='admin', password='', expected_text=['Articles & Preprints', '61', 'records found', 'Books & Reports', '6', 'records found', 'Multimedia & Arts', '14', 'records found', 'ALEPH Theses', '1', 'records found', 'ALEPH Internal Notes', '1', 'records found']) if error_messages: self.fail(merge_error_messages(error_messages)) def test_search_for_pattern_from_an_specific_coll_as_unauthorized_user(self): """websearch - unauthorized user searches for a pattern from one specific collection""" error_messages = test_web_page_content(CFG_SITE_URL + '/search?ln=en&cc=Books+%26+Reports&sc=1&p=of&f=&action_search=Search&c=Books&c=Reports', username='guest', expected_text=['Books', '1', 'records found', 'Reports', '1', 'records found']) if error_messages: self.fail(merge_error_messages(error_messages)) def test_search_for_pattern_from_an_specific_coll_as_authorized_user(self): """websearch - authorized user searches for a pattern from one specific collection""" error_messages = test_web_page_content(CFG_SITE_URL + '/search?ln=en&cc=Books+%26+Reports&sc=1&p=of&f=&action_search=Search&c=Books&c=Reports', username='admin', password='', expected_text=['Books', '1', 'records found', 'Reports', '1', 'records found', 'Theses', '4', 'records found']) if error_messages: self.fail(merge_error_messages(error_messages)) class WebSearchRestrictedPicturesTest(InvenioTestCase): """ Check whether restricted pictures on the demo site can be accessed well by people who have rights to access them. """ def test_restricted_pictures_guest(self): """websearch - restricted pictures not available to guest""" error_messages = test_web_page_content(CFG_SITE_URL + '/%s/1/files/0106015_01.jpg' % CFG_SITE_RECORD, expected_text=['This file is restricted. If you think you have right to access it, please authenticate yourself.']) if error_messages: self.fail(merge_error_messages(error_messages)) def test_restricted_pictures_romeo(self): """websearch - restricted pictures available to Romeo""" error_messages = test_web_page_content(CFG_SITE_URL + '/%s/1/files/0106015_01.jpg' % CFG_SITE_RECORD, username='romeo', password='r123omeo', expected_text=[], unexpected_text=['This file is restricted', 'You are not authorized']) if error_messages: self.fail(merge_error_messages(error_messages)) def test_restricted_pictures_hyde(self): """websearch - restricted pictures not available to Mr. Hyde""" error_messages = test_web_page_content(CFG_SITE_URL + '/%s/1/files/0106015_01.jpg' % CFG_SITE_RECORD, username='hyde', password='h123yde', expected_text=['This file is restricted', 'You are not authorized']) if error_messages: self.failUnless("HTTP Error 401: Unauthorized" in merge_error_messages(error_messages)) class WebSearchRestrictedWebJournalFilesTest(InvenioTestCase): """ Check whether files attached to a WebJournal article are well accessible when the article is published """ def test_restricted_files_guest(self): """websearch - files of unreleased articles are not available to guest""" # Record is not public... self.assertEqual(record_public_p(112), False) # ... and guest cannot access attached files error_messages = test_web_page_content(CFG_SITE_URL + '/%s/112/files/journal_galapagos_archipelago.jpg' % CFG_SITE_RECORD, expected_text=['This file is restricted. If you think you have right to access it, please authenticate yourself.']) if error_messages: self.fail(merge_error_messages(error_messages)) def test_restricted_files_editor(self): """websearch - files of unreleased articles are available to editor""" # Record is not public... self.assertEqual(record_public_p(112), False) # ... but editor can access attached files error_messages = test_web_page_content(CFG_SITE_URL + '/%s/112/files/journal_galapagos_archipelago.jpg' % CFG_SITE_RECORD, username='balthasar', password='b123althasar', expected_text=[], unexpected_text=['This file is restricted', 'You are not authorized']) if error_messages: self.fail(merge_error_messages(error_messages)) def test_public_files_guest(self): """websearch - files of released articles are available to guest""" # Record is not public... self.assertEqual(record_public_p(111), False) # ... but user can access attached files, as article is released error_messages = test_web_page_content(CFG_SITE_URL + '/%s/111/files/journal_scissor_beak.jpg' % CFG_SITE_RECORD, expected_text=[], unexpected_text=['This file is restricted', 'You are not authorized']) if error_messages: self.fail(merge_error_messages(error_messages)) def test_really_restricted_files_guest(self): """websearch - restricted files of released articles are not available to guest""" # Record is not public... self.assertEqual(record_public_p(111), False) # ... and user cannot access restricted attachements, even if # article is released error_messages = test_web_page_content(CFG_SITE_URL + '/%s/111/files/restricted-journal_scissor_beak.jpg' % CFG_SITE_RECORD, expected_text=['This file is restricted. If you think you have right to access it, please authenticate yourself.']) if error_messages: self.fail(merge_error_messages(error_messages)) def test_restricted_picture_has_restriction_flag(self): """websearch - restricted files displays a restriction flag""" error_messages = test_web_page_content(CFG_SITE_URL + '/%s/1/files/' % CFG_SITE_RECORD, expected_text="Restricted") if error_messages: self.fail(merge_error_messages(error_messages)) class WebSearchRSSFeedServiceTest(InvenioTestCase): """Test of the RSS feed service.""" def test_rss_feed_service(self): """websearch - RSS feed service""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/rss', expected_text=' -1: self.fail("Oops, when split by collection is off, " "results overview should not be present.") if body.find('') == -1: self.fail("Oops, when split by collection is off, " "Atlantis collection should be found.") if body.find('') > -1: self.fail("Oops, when split by collection is off, " "Multimedia & Arts should not be found.") try: browser.find_link(url='#15') self.fail("Oops, when split by collection is off, " "a link to Multimedia & Arts should not be found.") except LinkNotFoundError: pass def test_results_overview_split_on(self): """websearch - results overview box when split by collection is on""" browser = Browser() browser.open(CFG_SITE_URL + '/search?p=of&sc=1') body = browser.response().read() if body.find("Results overview") == -1: self.fail("Oops, when split by collection is on, " "results overview should be present.") if body.find('') > -1: self.fail("Oops, when split by collection is on, " "Atlantis collection should not be found.") if body.find('') == -1: self.fail("Oops, when split by collection is on, " "Multimedia & Arts should be found.") try: browser.find_link(url='#15') except LinkNotFoundError: self.fail("Oops, when split by collection is on, " "a link to Multimedia & Arts should be found.") class WebSearchResultsNumberingTest(InvenioTestCase): """Test the numbering of the search results.""" def test_results_numbering(self): """websearch - results number after the 1st page""" rg = 10 jrec = 11 browser = Browser() browser.open("%s/search?rg=%i&jrec=%i" % (CFG_SITE_URL, rg, jrec)) body = browser.response().read() self.assertEqual( range(jrec, jrec+rg), map(int, re.findall(r"\s*(\d+)\.\s*", body, re.I+re.M)) ) class WebSearchSortResultsTest(InvenioTestCase): """Test of the search results page's sorting capability.""" def test_sort_results_default(self): """websearch - search results sorting, default method""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=of&f=title&rg=3', expected_text="CMS animation of the high-energy collisions")) def test_sort_results_ascending(self): """websearch - search results sorting, ascending field""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=of&f=title&rg=2&sf=reportnumber&so=a', expected_text="[astro-ph/0104076]")) def test_sort_results_descending(self): """websearch - search results sorting, descending field""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=of&f=title&rg=1&sf=reportnumber&so=d', expected_text=" [TESLA-FEL-99-07]")) def test_sort_results_sort_pattern(self): """websearch - search results sorting, preferential sort pattern""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=of&f=title&rg=1&sf=reportnumber&so=d&sp=cern', expected_text="[CERN-TH-2002-069]")) class WebSearchSearchResultsXML(InvenioTestCase): """Test search results in various output""" def test_search_results_xm_output_split_on(self): """ websearch - check document element of search results in xm output (split by collection on)""" browser = Browser() browser.open(CFG_SITE_URL + '/search?sc=1&of=xm') body = browser.response().read() num_doc_element = body.count("") if num_doc_element == 0: self.fail("Oops, no document element " "found in search results.") elif num_doc_element > 1: self.fail("Oops, multiple document elements " "found in search results.") num_doc_element = body.count("") if num_doc_element == 0: self.fail("Oops, no document element " "found in search results.") elif num_doc_element > 1: self.fail("Oops, multiple document elements " "found in search results.") def test_search_results_xm_output_split_off(self): """ websearch - check document element of search results in xm output (split by collection off)""" browser = Browser() browser.open(CFG_SITE_URL + '/search?sc=0&of=xm') body = browser.response().read() num_doc_element = body.count("") if num_doc_element == 0: self.fail("Oops, no document element " "found in search results.") elif num_doc_element > 1: self.fail("Oops, multiple document elements " "found in search results.") num_doc_element = body.count("") if num_doc_element == 0: self.fail("Oops, no document element " "found in search results.") elif num_doc_element > 1: self.fail("Oops, multiple document elements " "found in search results.") def test_search_results_xd_output_split_on(self): """ websearch - check document element of search results in xd output (split by collection on)""" browser = Browser() browser.open(CFG_SITE_URL + '/search?sc=1&of=xd') body = browser.response().read() num_doc_element = body.count("" "found in search results.") elif num_doc_element > 1: self.fail("Oops, multiple document elements " "found in search results.") num_doc_element = body.count("") if num_doc_element == 0: self.fail("Oops, no document element " "found in search results.") elif num_doc_element > 1: self.fail("Oops, multiple document elements " "found in search results.") def test_search_results_xd_output_split_off(self): """ websearch - check document element of search results in xd output (split by collection off)""" browser = Browser() browser.open(CFG_SITE_URL + '/search?sc=0&of=xd') body = browser.response().read() num_doc_element = body.count("") if num_doc_element == 0: self.fail("Oops, no document element " "found in search results.") elif num_doc_element > 1: self.fail("Oops, multiple document elements " "found in search results.") num_doc_element = body.count("") if num_doc_element == 0: self.fail("Oops, no document element " "found in search results.") elif num_doc_element > 1: self.fail("Oops, multiple document elements " "found in search results.") class WebSearchUnicodeQueryTest(InvenioTestCase): """Test of the search results for queries containing Unicode characters.""" def test_unicode_word_query(self): """websearch - Unicode word query""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?of=id&p=title%3A%CE%99%CE%B8%CE%AC%CE%BA%CE%B7', expected_text="[76]")) def test_unicode_word_query_not_found_term(self): """websearch - Unicode word query, not found term""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=title%3A%CE%99%CE%B8', expected_text="ιθάκη")) def test_unicode_exact_phrase_query(self): """websearch - Unicode exact phrase query""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?of=id&p=title%3A%22%CE%99%CE%B8%CE%AC%CE%BA%CE%B7%22', expected_text="[76]")) def test_unicode_partial_phrase_query(self): """websearch - Unicode partial phrase query""" # no hit here for example title partial phrase query due to # removed difference between double-quoted and single-quoted # search: self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?of=id&p=title%3A%27%CE%B7%27', expected_text="[]")) def test_unicode_regexp_query(self): """websearch - Unicode regexp query""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?of=id&p=title%3A%2F%CE%B7%2F', expected_text="[76]")) class WebSearchMARCQueryTest(InvenioTestCase): """Test of the search results for queries containing physical MARC tags.""" def test_single_marc_tag_exact_phrase_query(self): """websearch - single MARC tag, exact phrase query (100__a)""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?of=id&p=100__a%3A%22Ellis%2C+J%22&so=a', expected_text="[9, 14, 18]")) def test_single_marc_tag_partial_phrase_query(self): """websearch - single MARC tag, partial phrase query (245__b)""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?of=id&p=245__b%3A%27and%27', expected_text="[28]")) def test_many_marc_tags_partial_phrase_query(self): """websearch - many MARC tags, partial phrase query (245)""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?of=id&p=245%3A%27and%27&rg=100&so=a', expected_text="[91, 108, 1, 8, 9, 14, 15, 20, 22, 24, 28, 33, 47, 48, 49, 51, 53, 64, 69, 71, 79, 82, 83, 85, 96]")) def test_single_marc_tag_regexp_query(self): """websearch - single MARC tag, regexp query""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?of=id&p=245%3A%2Fand%2F&rg=100&so=a', expected_text="[91, 108, 1, 8, 9, 14, 15, 20, 22, 24, 28, 33, 47, 48, 49, 51, 53, 64, 69, 71, 79, 82, 83, 85, 96]")) class WebSearchExtSysnoQueryTest(InvenioTestCase): """Test of queries using external system numbers.""" def test_existing_sysno_html_output(self): """websearch - external sysno query, existing sysno, HTML output""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?sysno=000289446CER', expected_text="The wall of the cave")) def test_existing_sysno_id_output(self): """websearch - external sysno query, existing sysno, ID output""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?sysno=000289446CER&of=id', expected_text="[95]")) def test_nonexisting_sysno_html_output(self): """websearch - external sysno query, non-existing sysno, HTML output""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?sysno=000289446CERRRR', expected_text="Requested record does not seem to exist.")) def test_nonexisting_sysno_id_output(self): """websearch - external sysno query, non-existing sysno, ID output""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?sysno=000289446CERRRR&of=id', expected_text="[]")) class WebSearchResultsRecordGroupingTest(InvenioTestCase): """Test search results page record grouping (rg).""" def test_search_results_rg_guest(self): """websearch - search results, records in groups of, guest""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?rg=17', expected_text="1 - 17")) def test_search_results_rg_nonguest(self): """websearch - search results, records in groups of, non-guest""" # This test used to fail due to saved user preference fetching # not overridden by URL rg argument. self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?rg=17', username='admin', expected_text="1 - 17")) class WebSearchSpecialTermsQueryTest(InvenioTestCase): """Test of the search results for queries containing special terms.""" def test_special_terms_u1(self): """websearch - query for special terms, U(1)""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?of=id&p=U%281%29', expected_text="[88, 80, 79, 57]")) def test_special_terms_u1_and_sl(self): """websearch - query for special terms, U(1) SL(2,Z)""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?of=id&p=U%281%29+SL%282%2CZ%29', expected_text="[88]")) def test_special_terms_u1_and_sl_or(self): """websearch - query for special terms, U(1) OR SL(2,Z)""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?of=id&p=U%281%29+OR+SL%282%2CZ%29', expected_text="[88, 80, 79, 57]")) @nottest def FIXME_TICKET_453_test_special_terms_u1_and_sl_or_parens(self): """websearch - query for special terms, (U(1) OR SL(2,Z))""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?of=id&p=%28U%281%29+OR+SL%282%2CZ%29%29', expected_text="[57, 79, 80, 88]")) def test_special_terms_u1_and_sl_in_quotes(self): """websearch - query for special terms, ('SL(2,Z)' OR 'U(1)')""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + "/search?of=id&p=%28%27SL%282%2CZ%29%27+OR+%27U%281%29%27%29", expected_text="[96, 88, 80, 79, 57]")) class WebSearchJournalQueryTest(InvenioTestCase): """Test of the search results for journal pubinfo queries.""" def test_query_journal_title_only(self): """websearch - journal publication info query, title only""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?of=id&f=journal&p=Phys.+Lett.+B&so=a', expected_text="[78, 85, 87]")) self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?of=id&f=journal&p=Phys.+Lett.+B&so=a', username='admin', expected_text="[77, 78, 85, 87]")) def test_query_journal_full_pubinfo(self): """websearch - journal publication info query, full reference""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?of=id&f=journal&p=Phys.+Lett.+B+531+%282002%29+301', expected_text="[78]")) class WebSearchStemmedIndexQueryTest(InvenioTestCase): """Test of the search results for queries using stemmed indexes.""" def test_query_stemmed_lowercase(self): """websearch - stemmed index query, lowercase""" # note that dasse/Dasse is stemmed into dass/Dass, as expected self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?of=id&p=dasse', expected_text="[26, 25]")) def test_query_stemmed_uppercase(self): """websearch - stemmed index query, uppercase""" # ... but note also that DASSE is stemmed into DASSE(!); so # the test would fail if the search engine would not lower the # query term. (Something that is not necessary for # non-stemmed indexes.) self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?of=id&p=DASSE', expected_text="[26, 25]")) class WebSearchSummarizerTest(InvenioTestCase): """Test of the search results summarizer functions.""" def test_most_popular_field_values_singletag(self): """websearch - most popular field values, simple tag""" from invenio.search_engine import get_most_popular_field_values self.assertEqual([('PREPRINT', 37), ('ARTICLE', 28), ('BOOK', 14), ('THESIS', 8), ('PICTURE', 7), ('DRAFT', 2), ('POETRY', 2), ('REPORT', 2), ('ALEPHPAPER', 1), ('ATLANTISTIMESNEWS', 1), ('ISOLDEPAPER', 1)], get_most_popular_field_values(range(0,100), '980__a')) def test_most_popular_field_values_singletag_multiexclusion(self): """websearch - most popular field values, simple tag, multiple exclusions""" from invenio.search_engine import get_most_popular_field_values self.assertEqual([('PREPRINT', 37), ('ARTICLE', 28), ('BOOK', 14), ('DRAFT', 2), ('REPORT', 2), ('ALEPHPAPER', 1), ('ATLANTISTIMESNEWS', 1), ('ISOLDEPAPER', 1)], get_most_popular_field_values(range(0,100), '980__a', ('THESIS', 'PICTURE', 'POETRY'))) def test_most_popular_field_values_multitag(self): """websearch - most popular field values, multiple tags""" from invenio.search_engine import get_most_popular_field_values self.assertEqual([('Ellis, J', 3), ('Enqvist, K', 1), ('Ibanez, L E', 1), ('Nanopoulos, D V', 1), ('Ross, G G', 1)], get_most_popular_field_values((9, 14, 18), ('100__a', '700__a'))) def test_most_popular_field_values_multitag_singleexclusion(self): """websearch - most popular field values, multiple tags, single exclusion""" from invenio.search_engine import get_most_popular_field_values self.assertEqual([('Enqvist, K', 1), ('Ibanez, L E', 1), ('Nanopoulos, D V', 1), ('Ross, G G', 1)], get_most_popular_field_values((9, 14, 18), ('100__a', '700__a'), ('Ellis, J'))) def test_most_popular_field_values_multitag_countrepetitive(self): """websearch - most popular field values, multiple tags, counting repetitive occurrences""" from invenio.search_engine import get_most_popular_field_values self.assertEqual([('THESIS', 2), ('REPORT', 1)], get_most_popular_field_values((41,), ('690C_a', '980__a'), count_repetitive_values=True)) self.assertEqual([('REPORT', 1), ('THESIS', 1)], get_most_popular_field_values((41,), ('690C_a', '980__a'), count_repetitive_values=False)) def test_ellis_citation_summary(self): """websearch - query ellis, citation summary output format""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=ellis&of=hcs', expected_text="Less known papers (1-9)", expected_link_target=CFG_BASE_URL+"/search?p=ellis%20AND%20cited%3A1-%3E9", expected_link_label='1')) def test_ellis_not_quark_citation_summary_advanced(self): """websearch - ellis and not quark, citation summary format advanced""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?ln=en&as=1&m1=a&p1=ellis&f1=author&op1=n&m2=a&p2=quark&f2=&op2=a&m3=a&p3=&f3=&action_search=Search&sf=&so=a&rm=&rg=10&sc=1&of=hcs', expected_text="Less known papers (1-9)", expected_link_target=CFG_BASE_URL+'/search?p=author%3Aellis%20and%20not%20quark%20AND%20cited%3A1-%3E9', expected_link_label='1')) def test_ellis_not_quark_citation_summary_regular(self): """websearch - ellis and not quark, citation summary format advanced""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?ln=en&p=author%3Aellis+and+not+quark&f=&action_search=Search&sf=&so=d&rm=&rg=10&sc=0&of=hcs', expected_text="Less known papers (1-9)", expected_link_target=CFG_BASE_URL+'/search?p=author%3Aellis%20and%20not%20quark%20AND%20cited%3A1-%3E9', expected_link_label='1')) class WebSearchRecordCollectionGuessTest(InvenioTestCase): """Primary collection guessing tests.""" def test_guess_primary_collection_of_a_record(self): """websearch - guess_primary_collection_of_a_record""" self.assertEqual(guess_primary_collection_of_a_record(96), 'Articles') def test_guess_collection_of_a_record(self): """websearch - guess_collection_of_a_record""" self.assertEqual(guess_collection_of_a_record(96), 'Articles') self.assertEqual(guess_collection_of_a_record(96, '%s/collection/Theoretical Physics (TH)?ln=en' % CFG_SITE_URL), 'Articles') self.assertEqual(guess_collection_of_a_record(12, '%s/collection/Theoretical Physics (TH)?ln=en' % CFG_SITE_URL), 'Theoretical Physics (TH)') self.assertEqual(guess_collection_of_a_record(12, '%s/collection/Theoretical%%20Physics%%20%%28TH%%29?ln=en' % CFG_SITE_URL), 'Theoretical Physics (TH)') class WebSearchGetFieldValuesTest(InvenioTestCase): """Testing get_fieldvalues() function.""" def test_get_fieldvalues_001(self): """websearch - get_fieldvalues() for bibxxx-agnostic tags""" self.assertEqual(get_fieldvalues(10, '001___'), ['10']) def test_get_fieldvalues_980(self): """websearch - get_fieldvalues() for bibxxx-powered tags""" self.assertEqual(get_fieldvalues(18, '700__a'), ['Enqvist, K', 'Nanopoulos, D V']) self.assertEqual(get_fieldvalues(18, '909C1u'), ['CERN']) def test_get_fieldvalues_wildcard(self): """websearch - get_fieldvalues() for tag wildcards""" self.assertEqual(get_fieldvalues(18, '%'), []) self.assertEqual(get_fieldvalues(18, '7%'), []) self.assertEqual(get_fieldvalues(18, '700%'), ['Enqvist, K', 'Nanopoulos, D V']) self.assertEqual(get_fieldvalues(18, '909C0%'), ['1985', '13','TH']) def test_get_fieldvalues_recIDs(self): """websearch - get_fieldvalues() for list of recIDs""" self.assertEqual(get_fieldvalues([], '001___'), []) self.assertEqual(get_fieldvalues([], '700__a'), []) self.assertEqual(get_fieldvalues([10, 13], '001___'), ['10', '13']) self.assertEqual(get_fieldvalues([18, 13], '700__a'), ['Dawson, S', 'Ellis, R K', 'Enqvist, K', 'Nanopoulos, D V']) def test_get_fieldvalues_repetitive(self): """websearch - get_fieldvalues() for repetitive values""" self.assertEqual(get_fieldvalues([17, 18], '909C1u'), ['CERN', 'CERN']) self.assertEqual(get_fieldvalues([17, 18], '909C1u', repetitive_values=True), ['CERN', 'CERN']) self.assertEqual(get_fieldvalues([17, 18], '909C1u', repetitive_values=False), ['CERN']) class WebSearchAddToBasketTest(InvenioTestCase): """Test of the add-to-basket presence depending on user rights.""" def test_add_to_basket_guest(self): """websearch - add-to-basket facility allowed for guests""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=recid%3A10', expected_text='Add to basket')) self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=recid%3A10', expected_text='')) def test_add_to_basket_jekyll(self): """websearch - add-to-basket facility allowed for Dr. Jekyll""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=recid%3A10', expected_text='Add to basket', username='jekyll', password='j123ekyll')) self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=recid%3A10', expected_text='', username='jekyll', password='j123ekyll')) def test_add_to_basket_hyde(self): """websearch - add-to-basket facility denied to Mr. Hyde""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=recid%3A10', unexpected_text='Add to basket', username='hyde', password='h123yde')) self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=recid%3A10', unexpected_text='', username='hyde', password='h123yde')) class WebSearchAlertTeaserTest(InvenioTestCase): """Test of the alert teaser presence depending on user rights.""" def test_alert_teaser_guest(self): """websearch - alert teaser allowed for guests""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=ellis', expected_link_label='email alert')) self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=ellis', expected_text='RSS feed')) def test_alert_teaser_jekyll(self): """websearch - alert teaser allowed for Dr. Jekyll""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=ellis', expected_text='email alert', username='jekyll', password='j123ekyll')) self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=ellis', expected_text='RSS feed', username='jekyll', password='j123ekyll')) def test_alert_teaser_hyde(self): """websearch - alert teaser allowed for Mr. Hyde""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=ellis', expected_text='email alert', username='hyde', password='h123yde')) self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=ellis', expected_text='RSS feed', username='hyde', password='h123yde')) class WebSearchSpanQueryTest(InvenioTestCase): """Test of span queries.""" def test_span_in_word_index(self): """websearch - span query in a word index""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=year%3A1992-%3E1996&of=id&ap=0', expected_text='[71, 69, 66, 17]')) def test_span_in_phrase_index(self): """websearch - span query in a phrase index""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=year%3A%221992%22-%3E%221996%22&of=id&ap=0', expected_text='[71, 69, 66, 17]')) def test_span_in_bibxxx(self): """websearch - span query in MARC tables""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=909C0y%3A%221992%22-%3E%221996%22&of=id&ap=0', expected_text='[71, 69, 66, 17]')) def test_span_with_spaces(self): """websearch - no span query when a space is around""" # useful for reaction search self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=title%3A%27mu%20--%3E%20e%27&of=id&ap=0', expected_text='[67]')) self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=245%3A%27mu%20--%3E%20e%27&of=id&ap=0', expected_text='[67]')) def test_span_in_author(self): """websearch - span query in special author index""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=author%3A%22Ellis,%20K%22-%3E%22Ellis,%20RZ%22&of=id&ap=0', expected_text='[47, 18, 17, 14, 13, 12, 11, 9, 8]')) class WebSearchReferstoCitedbyTest(InvenioTestCase): """Test of refersto/citedby search operators.""" def test_refersto_recid(self): 'websearch - refersto:recid:84' self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=refersto%3Arecid%3A84&of=id&ap=0&so=a', expected_text='[91, 85, 88]')) def test_refersto_repno(self): 'websearch - refersto:reportnumber:hep-th/0205061' self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=refersto%3Areportnumber%3Ahep-th/0205061&of=id&ap=0', expected_text='[91]')) def test_refersto_author_word(self): 'websearch - refersto:author:klebanov' self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=refersto%3Aauthor%3Aklebanov&of=id&ap=0&so=a', expected_text='[86, 91, 85, 88]')) def test_refersto_author_phrase(self): 'websearch - refersto:author:"Klebanov, I"' self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=refersto%3Aauthor%3A%22Klebanov,%20I%22&of=id&ap=0&so=a', expected_text='[86, 91, 85, 88]')) def test_citedby_recid(self): 'websearch - citedby:recid:92' self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=citedby%3Arecid%3A92&of=id&ap=0&so=a', expected_text='[91, 74]')) def test_citedby_repno(self): 'websearch - citedby:reportnumber:hep-th/0205061' self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=citedby%3Areportnumber%3Ahep-th/0205061&of=id&ap=0', expected_text='[78]')) def test_citedby_author_word(self): 'websearch - citedby:author:klebanov' self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=citedby%3Aauthor%3Aklebanov&of=id&ap=0', expected_text='[95]')) def test_citedby_author_phrase(self): 'websearch - citedby:author:"Klebanov, I"' self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=citedby%3Aauthor%3A%22Klebanov,%20I%22&of=id&ap=0', expected_text='[95]')) def test_refersto_bad_query(self): 'websearch - refersto:title:' self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=refersto%3Atitle%3A', expected_text='There are no records referring to title:.')) def test_citedby_bad_query(self): 'websearch - citedby:title:' self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=citedby%3Atitle%3A', expected_text='There are no records cited by title:.')) class WebSearchSPIRESSyntaxTest(InvenioTestCase): """Test of SPIRES syntax issues""" if CFG_WEBSEARCH_SPIRES_SYNTAX > 0: def test_and_not_parens(self): 'websearch - find a ellis, j and not a enqvist' self.assertEqual([], test_web_page_content(CFG_SITE_URL +'/search?p=find+a+ellis%2C+j+and+not+a+enqvist&of=id&ap=0&so=a', expected_text='[9, 12, 14, 47]')) if DATEUTIL_AVAILABLE: def test_dadd_search(self): - 'websearch - find da > today - 3650' - # XXX: assumes we've reinstalled our site in the last 10 years - # should return every document in the system + 'websearch - find da > today - 36500' + # finds all records that are declared with date added (see tag 005) in the past 100 years self.assertEqual([], - test_web_page_content(CFG_SITE_URL +'/search?ln=en&p=find+da+%3E+today+-+3650&f=&of=id&so=a&rg=0', - expected_text='[90, 92, 91, 97, 89, 107, 108, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 78, 79, 80, 81, 82, 83, 84, 85, 87, 88, 93, 94, 95, 96, 99, 100, 101, 102, 103, 104, 113, 127, 128]')) + test_web_page_content(CFG_SITE_URL +'/search?ln=en&p=find+da+%3E+today+-+36500&f=&of=id&so=a&rg=0', + expected_text='[86, 90, 92, 91, 97, 89, 107, 108, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 78, 79, 80, 81, 82, 83, 84, 85, 87, 88, 93, 94, 95, 96, 99, 100, 101, 102, 103, 104, 113, 127, 128]')) class WebSearchDateQueryTest(InvenioTestCase): """Test various date queries.""" def setUp(self): """Establish variables we plan to re-use""" self.empty = intbitset() def test_search_unit_hits_for_datecreated_previous_millenia(self): """websearch - search_unit with datecreated returns >0 hits for docs in the last 1000 years""" self.assertNotEqual(self.empty, search_unit('1000-01-01->9999-12-31', 'datecreated')) def test_search_unit_hits_for_datemodified_previous_millenia(self): """websearch - search_unit with datemodified returns >0 hits for docs in the last 1000 years""" self.assertNotEqual(self.empty, search_unit('1000-01-01->9999-12-31', 'datemodified')) def test_search_unit_in_bibrec_for_datecreated_previous_millenia(self): """websearch - search_unit_in_bibrec with creationdate gets >0 hits for past 1000 years""" self.assertNotEqual(self.empty, search_unit_in_bibrec("1000-01-01", "9999-12-31", 'creationdate')) def test_search_unit_in_bibrec_for_datecreated_next_millenia(self): """websearch - search_unit_in_bibrec with creationdate gets 0 hits for after year 3000""" self.assertEqual(self.empty, search_unit_in_bibrec("3000-01-01", "9999-12-31", 'creationdate')) class WebSearchSynonymQueryTest(InvenioTestCase): """Test of queries using synonyms.""" def test_journal_phrvd(self): """websearch - search-time synonym search, journal title""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=PHRVD&f=journal&of=id', expected_text="[72, 66]")) def test_journal_phrvd_54_1996_4234(self): """websearch - search-time synonym search, journal article""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=PHRVD%2054%20%281996%29%204234&f=journal&of=id', expected_text="[66]")) def test_journal_beta_decay_title(self): """websearch - index-time synonym search, beta decay in title""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=beta+decay&f=title&of=id', expected_text="[59]")) self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=%CE%B2+decay&f=title&of=id', expected_text="[59]")) def test_journal_beta_decay_global(self): """websearch - index-time synonym search, beta decay in any field""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=beta+decay&of=id', expected_text="[59, 52]")) self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=%CE%B2+decay&of=id', expected_text="[59]")) def test_journal_beta_title(self): """websearch - index-time synonym search, beta in title""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=beta&f=title&of=id', expected_text="[59]")) self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=%CE%B2&f=title&of=id', expected_text="[59]")) def test_journal_beta_global(self): """websearch - index-time synonym search, beta in any field""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=beta&of=id', expected_text="[59, 52]")) self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=%CE%B2&of=id', expected_text="[59]")) class WebSearchWashCollectionsTest(InvenioTestCase): """Test if the collection argument is washed correctly""" def test_wash_coll_when_coll_restricted(self): """websearch - washing of restricted daughter collections""" self.assertEqual( sorted(wash_colls(cc='', c=['Books & Reports', 'Theses'])[1]), ['Books & Reports', 'Theses']) self.assertEqual( sorted(wash_colls(cc='', c=['Books & Reports', 'Theses'])[2]), ['Books & Reports', 'Theses']) class WebSearchAuthorCountQueryTest(InvenioTestCase): """Test of queries using authorcount fields.""" def test_journal_authorcount_word(self): """websearch - author count, word query""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=4&f=authorcount&of=id&so=a', expected_text="[92, 51, 54, 59, 66, 96]")) def test_journal_authorcount_phrase(self): """websearch - author count, phrase query""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=%224%22&f=authorcount&of=id&so=a', expected_text="[92, 51, 54, 59, 66, 96]")) def test_journal_authorcount_span(self): """websearch - author count, span query""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=authorcount%3A9-%3E16&of=id&so=a', expected_text="[69, 71, 127]")) def test_journal_authorcount_plus(self): """websearch - author count, plus query""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=50%2B&f=authorcount&of=id&so=a', expected_text="[10, 17]")) class WebSearchItemCountQueryTest(InvenioTestCase): """Test of queries using itemcount field/index""" def test_itemcount_plus(self): """websearch - item count, search for more than one item, using 'plus'""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=2%2B&f=itemcount&of=id&so=a', expected_text="[31, 32, 34]")) def test_itemcount_span(self): """websearch - item count, search for more than one item, using 'span'""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=2->10&f=itemcount&of=id&so=a', expected_text="[31, 32, 34]")) def test_itemcount_phrase(self): """websearch - item count, search for records with exactly two items, phrase""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=%222%22&f=itemcount&of=id&so=a', expected_text="[31, 34]")) def test_itemcount_records_with_two_items(self): """websearch - item count, search for records with exactly two items""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=2&f=itemcount&of=id&so=a', expected_text="[31, 34]")) class WebSearchFiletypeQueryTest(InvenioTestCase): """Test of queries using filetype fields.""" def test_mpg_filetype(self): """websearch - file type, query for tif extension""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?ln=en&p=mpg&f=filetype&of=id', expected_text="[113]")) def test_tif_filetype_and_word_study(self): """websearch - file type, query for tif extension and word 'study'""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?ln=en&p=study+filetype%3Atif&of=id', expected_text="[71]")) def test_pdf_filetype_and_phrase(self): """websearch - file type, query for pdf extension and phrase 'parameter test'""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?ln=en&p=filetype%3Apdf+parameter+test&of=id&so=a', expected_text="[50, 93]")) class WebSearchFilenameQueryTest(InvenioTestCase): """Test of queries using filename fields.""" def test_search_for_main_file_name(self): """websearch - file name, query for name without extension""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?ln=en&p=0402130&f=filename&of=id', expected_text="[89]")) def test_search_for_file_name_with_extension(self): """websearch - file name, query for name with extension""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?ln=en&p=0210075.ps.gz&f=filename&of=id', expected_text="[83]")) def test_search_for_file_name_with_part_of_extension(self): """websearch - file name, query for name and part of extension""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?ln=en&p=filename:0212138.ps&of=id&so=a', expected_text="[84]")) def test_search_for_file_name_with_wildcard(self): """websearch - file name, query with wildcard""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?ln=en&p=filename:convert*&of=id&so=a', expected_text="[97, 66, 71]")) def test_search_for_file_name_with_span(self): """websearch - file name, query with span""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?ln=en&p=filename:6->7&of=id&so=a', expected_text="[3, 6]")) def make_fake_request(admin_user=True): environ = {'wsgi.errors': cStringIO.StringIO(), 'QUERY_STRING': '', 'PATH_INFO': ''} if admin_user: user_info = {'uid': 1, 'guest': '0', 'email': '', 'nickname': ''} else: user_info = {'uid': 2, 'guest': '1', 'email': '', 'nickname': ''} user_info['precached_permitted_restricted_collections'] = get_permitted_restricted_collections(user_info) buf = cStringIO.StringIO() def start_response(status, response_headers, exc_info=None): return buf.write req = SimulatedModPythonRequest(environ, start_response) req._user_info = user_info req.test_output_buffer = buf return req class WebSearchPerformRequestSearchRefactoringTest(InvenioTestCase): """Tests the perform request search API after refactoring.""" def _run_test(self, test_args, expected_results): params = {} params.update(map(lambda y: (y[0], ',' in y[1] and ', ' not in y[1] and y[1].split(',') or y[1]), map(lambda x: x.split('=', 1), test_args.split(';')))) if isinstance(expected_results, str): req = make_fake_request() params['req'] = req recs = perform_request_search(**params) if isinstance(expected_results, str): recs = req.test_output_buffer.getvalue() # this is just used to generate the results from the seearch engine before refactoring #if recs != expected_results: # print test_args # print params # print recs self.assertEqual(recs, expected_results, "Error, we expect: %s, and we received: %s" % (expected_results, recs)) def test_queries(self): """websearch - testing p_r_s standard arguments and their combinations""" self._run_test('p=ellis;f=author;action=Search', [8, 9, 10, 11, 12, 13, 14, 16, 17, 18, 47]) self._run_test('p=ellis;f=author;sf=title;action=Search', [8, 16, 14, 9, 11, 17, 18, 12, 10, 47, 13]) self._run_test('p=ellis;f=author;sf=title;wl=5;action=Search', [8, 16, 14, 9, 11, 17, 18, 12, 10, 47, 13]) self._run_test('p=ellis;f=author;sf=title;wl=5;so=a', [8, 16, 14, 9, 11, 17, 18, 12, 10, 47, 13]) self._run_test('p=ellis;f=author;sf=title;wl=5;so=d', [13, 47, 10, 12, 18, 17, 11, 9, 14, 16, 8]) self._run_test('p=ell*;sf=title;wl=5', [8, 15, 16, 14, 9, 11, 17, 18, 12, 10, 47, 13]) self._run_test('p=ell*;sf=title;wl=1', [10]) self._run_test('p=ell*;sf=title;wl=100', [8, 15, 16, 14, 9, 11, 17, 18, 12, 10, 47, 13]) self._run_test('p=muon OR kaon;f=author;sf=title;wl=5;action=Search', []) self._run_test('p=muon OR kaon;sf=title;wl=5;action=Search', [67, 12]) self._run_test('p=muon OR kaon;sf=title;wl=5;c=Articles,Preprints', [67, 12]) self._run_test('p=muon OR kaon;sf=title;wl=5;c=Articles', [67]) self._run_test('p=muon OR kaon;sf=title;wl=5;c=Preprints', [12]) self._run_test('p=el*;rm=citation;so=a', [2, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 23, 30, 32, 34, 47, 48, 51, 52, 54, 56, 58, 59, 92, 97, 100, 103, 109, 127, 128, 18, 74, 91, 94, 81]) self._run_test('p=el*;rm=citation;so=d', list(reversed([2, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 23, 30, 32, 34, 47, 48, 51, 52, 54, 56, 58, 59, 92, 97, 100, 103, 109, 127, 128, 18, 74, 91, 94, 81]))) if not get_external_word_similarity_ranker(): self._run_test('p=el*;rm=wrd', [2, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 23, 30, 32, 34, 47, 48, 51, 52, 54, 56, 58, 59, 74, 81, 91, 92, 94, 97, 100, 103, 109, 127, 128]) self._run_test('p=el*;sf=title', [100, 32, 8, 15, 16, 81, 97, 34, 23, 127, 58, 2, 14, 9, 128, 11, 30, 109, 52, 48, 94, 17, 56, 18, 91, 59, 12, 92, 74, 54, 103, 10, 51, 47, 13]) self._run_test('p=boson;rm=citation', [1, 47, 50, 107, 108, 77, 95]) if not get_external_word_similarity_ranker(): self._run_test('p=boson;rm=wrd', [47, 50, 77, 95, 108, 1, 107]) self._run_test('p1=ellis;f1=author;m1=a;op1=a;p2=john;f2=author;m2=a', [9, 12, 14, 18]) self._run_test('p1=ellis;f1=author;m1=o;op1=a;p2=john;f2=author;m2=o', [9, 12, 14, 18]) self._run_test('p1=ellis;f1=author;m1=e;op1=a;p2=john;f2=author;m2=e', []) self._run_test('p1=ellis;f1=author;m1=a;op1=o;p2=john;f2=author;m2=a', [8, 9, 10, 11, 12, 13, 14, 16, 17, 18, 47]) self._run_test('p1=ellis;f1=author;m1=o;op1=o;p2=john;f2=author;m2=o', [8, 9, 10, 11, 12, 13, 14, 16, 17, 18, 47]) self._run_test('p1=ellis;f1=author;m1=e;op1=o;p2=john;f2=author;m2=e', []) self._run_test('p1=ellis;f1=author;m1=a;op1=n;p2=john;f2=author;m2=a', [8, 10, 11, 13, 16, 17, 47]) self._run_test('p1=ellis;f1=author;m1=o;op1=n;p2=john;f2=author;m2=o', [8, 10, 11, 13, 16, 17, 47]) self._run_test('p1=ellis;f1=author;m1=e;op1=n;p2=john;f2=author;m2=e', []) self._run_test('p=Ellis, J;ap=1', [9, 10, 11, 12, 14, 17, 18, 47]) self._run_test('p=Ellis, J;ap=0', [9, 10, 11, 12, 14, 17, 18, 47]) self._run_test('p=recid:148x', []) self._run_test('p=recid:148x;of=xm;rg=200', "\n\n\n") class WebSearchDOIQueryTest(InvenioTestCase): """Tests queries using doi field.""" def test_span_doi_search(self): """websearch - doi, span query 1->9""" errors = test_web_page_content(CFG_SITE_URL + '/search?ln=en&p=doi%3A1->9&of=id', expected_text="[128, 127, 96]") self.assertEqual(True, errors == []) def test_doi_wildcard(self): """websearch - doi, query for '10.1063%'""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?ln=en&p=doi%3A10.1063%25&of=id', expected_text="[127]")) def test_doi_negative_search(self): """websearch - doi, query for 'VDB:88636' """ self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?ln=en&p=VDB%3A88636&f=doi&of=id', expected_text="[]")) class WebSearchGetRecordTests(InvenioTestCase): def setUp(self): self.recid = run_sql("INSERT INTO bibrec(creation_date, modification_date) VALUES(NOW(), NOW())") def tearDown(self): run_sql("DELETE FROM bibrec WHERE id=%s", (self.recid,)) def test_get_record(self): """bibformat - test print_record and get_record of empty record""" from invenio.search_engine import print_record, get_record self.assertEqual(print_record(self.recid, 'xm'), ' \n %s\n \n\n ' % self.recid) self.assertEqual(get_record(self.recid), {'001': [([], ' ', ' ', str(self.recid), 1)]}) class WebSearchExactTitleIndexTest(InvenioTestCase): """Checks if exact title index works correctly """ def test_exacttitle_query_solves_problems(self): """websearch - check exacttitle query solves problems""" error_messages = [] error_messages.extend(test_web_page_content(CFG_SITE_URL + "/search?ln=en&p=exacttitle%3A'solves+problems'&f=&action_search=Search", expected_text = "Non-compact supergravity solves problems")) if error_messages: self.fail(merge_error_messages(error_messages)) def test_exacttitle_query_solve_problems(self): """websearch - check exacttitle query solve problems""" error_messages = [] error_messages.extend(test_web_page_content(CFG_SITE_URL + "/search?ln=en&p=exacttitle%3A'solve+problems'&f=&action_search=Search", expected_text = ['Search term', 'solve problems', 'did not match'])) if error_messages: self.fail(merge_error_messages(error_messages)) def test_exacttitle_query_photon_beam(self): """websearch - check exacttitle search photon beam""" error_messages = [] error_messages.extend(test_web_page_content(CFG_SITE_URL + "/search?ln=en&p=exacttitle%3A'photon+beam'&f=&action_search=Search", expected_text = "Development of photon beam diagnostics")) if error_messages: self.fail(merge_error_messages(error_messages)) def test_exacttitle_query_photons_beam(self): """websearch - check exacttitle search photons beam""" error_messages = [] error_messages.extend(test_web_page_content(CFG_SITE_URL + "/search?ln=en&p=exacttitle%3A'photons+beam'&f=&action_search=Search", expected_text = ['Search term', 'photons beam', 'did not match'])) if error_messages: self.fail(merge_error_messages(error_messages)) class WebSearchCustomCollectionBoxesName(InvenioTestCase): """Test if the custom collection box labels are correctly displayed""" def test_custom_latest_additions_box_name(self): """websearch - test custom name for 'Latest additions' box in 'Videos' collection""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/collection/Videos?ln=en', expected_text='Latest videos:')) self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/collection/Videos?ln=fr', expected_text='Dernières vidéos:')) # There is currently no translation for that box in Afrikaans: # we must fall back to CFG_SITE_LANG self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/collection/Videos?ln=af', expected_text='Latest videos:')) def test_custom_narrow_by_box_name(self): """websearch - test custom name for 'Narrow by' box in 'CERN Divisions' collection""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/collection/CERN%20Divisions?ln=en', expected_text='Browse by division:')) self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/collection/CERN%20Divisions?ln=fr', expected_text='Naviguer par division:')) # There is currently no translation for that box in Afrikaans: # we must fall back to CFG_SITE_LANG self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/collection/CERN%20Divisions?ln=af', expected_text='Browse by division:')) class WebSearchDetailedRecordTabsTest(InvenioTestCase): def test_detailed_record(self): """websearch - check detailed record main tab""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/record/81', expected_text='Decapitating Tadpoles', unexpected_text='The server encountered an error')) def test_detailed_record_references_tab(self): """websearch - check detailed record references tab""" expected_refs = [ 'References (37)', 'W. Fischler and L. Susskind, "Dilaton Tadpoles, String Condensates And Scale In-variance,"', 'A. Adams, O. Aharony, J. McGreevy, E. Silverstein,..., work in progress', ] self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/record/81/references', expected_text=expected_refs)) def test_detailed_record_citations_tab(self): """websearch - check detailed record citations tab""" expected_cites = [ 'Filtering Gravity: Modification at Large Distances?', ] self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/record/81/citations', expected_text=expected_cites, unexpected_text='The server encountered an error')) def test_detailed_record_keywords_tab(self): """websearch - check detailed record keywords tab""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/record/81/keywords', expected_text='Keywords', unexpected_text='The server encountered an error')) def test_detailed_record_comments_tab(self): """websearch - check detailed record comments tab""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/record/81/comments', expected_text='Comments', unexpected_text='The server encountered an error')) def test_detailed_record_usage_tab(self): """websearch - check detailed record usage tab""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/record/81/usage', expected_text='Usage statistics', unexpected_text='The server encountered an error')) def test_detailed_record_files_tab(self): """websearch - check detailed record files tab""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/record/81/files', expected_text='Files', unexpected_text='The server encountered an error')) def test_detailed_record_plots_tab(self): """websearch - check detailed record plots tab""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/record/81/linkbacks', expected_text='Plots', unexpected_text='The server encountered an error')) def test_detailed_record_linkback_tab(self): """websearch - check detailed record linkback tab""" self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/record/81/linkbacks', expected_text='Linkbacks', unexpected_text='The server encountered an error')) class WebSearchResolveDOITest(InvenioTestCase): """Checks that we can resolve DOIs """ def test_resolve_existing_doi(self): """websearch - check resolution of a DOI for an existing record""" error_messages = [] error_messages.extend(test_web_page_content(CFG_SITE_URL + "/doi/10.4028/www.scientific.net/MSF.638-642.1098", expected_text = ['Influence of processing parameters on the manufacturing of anode-supported solid oxide fuel cells by different wet chemical routes'], unexpected_text = ['404 Not Found', 'could not be resolved'])) error_messages.extend(test_web_page_content(CFG_SITE_URL + "/doi/10.1063/1.2737136", expected_text = ['Epitaxially stabilized growth of orthorhombic LuScO3 thin films'], unexpected_text = ['404 Not Found', 'could not be resolved'])) if error_messages: self.fail(merge_error_messages(error_messages)) def test_resolve_non_existing_doi(self): """websearch - check resolution of a non-existing DOI""" error_messages = [] error_messages.extend(test_web_page_content(CFG_SITE_URL + "/doi/foobar", expected_text = ['could not be resolved', 'foobar'], unexpected_text = ['404 Not Found'])) if error_messages: self.fail(merge_error_messages(error_messages)) def test_resolve_non_doi(self): """websearch - check resolution of a non-DOI value living in 0247_a (without 0247__2:DOI)""" error_messages = [] error_messages.extend(test_web_page_content(CFG_SITE_URL + "/doi/0255-5476", expected_text = ['could not be resolved', '0255-5476'], unexpected_text = ['404 Not Found'])) if error_messages: self.fail(merge_error_messages(error_messages)) class WebSearchPatternLimitTest(InvenioTestCase): """Checks for pattern-limit style of queries.""" def test_search_pattern_limit(self): """websearch - search pattern limit style of queries""" # query Ellis without any limit: self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=ellis&of=id', expected_text="[47, 18, 17, 16, 15, 14, 13, 12, 11, 10]")) # query Ellis with a limit on reportnumber: self.assertEqual([], test_web_page_content(CFG_SITE_URL + '/search?p=ellis&reportnumber=CERN-PPE-92-085&of=id', expected_text="[17]")) TEST_SUITE = make_test_suite(WebSearchWebPagesAvailabilityTest, WebSearchTestSearch, WebSearchTestBrowse, WebSearchTestOpenURL, WebSearchTestCollections, WebSearchTestRecord, WebSearchTestLegacyURLs, WebSearchNearestTermsTest, WebSearchBooleanQueryTest, WebSearchAuthorQueryTest, WebSearchSearchEnginePythonAPITest, WebSearchSearchEngineWebAPITest, WebSearchSearchEngineJSONAPITest, WebSearchRecordWebAPITest, WebSearchRecordJSONAPITest, WebSearchRestrictedCollectionTest, WebSearchRestrictedCollectionHandlingTest, WebSearchRestrictedPicturesTest, WebSearchRestrictedWebJournalFilesTest, WebSearchRSSFeedServiceTest, WebSearchXSSVulnerabilityTest, WebSearchResultsOverview, WebSearchSortResultsTest, WebSearchSearchResultsXML, WebSearchUnicodeQueryTest, WebSearchMARCQueryTest, WebSearchExtSysnoQueryTest, WebSearchResultsRecordGroupingTest, WebSearchSpecialTermsQueryTest, WebSearchJournalQueryTest, WebSearchStemmedIndexQueryTest, WebSearchSummarizerTest, WebSearchRecordCollectionGuessTest, WebSearchGetFieldValuesTest, WebSearchAddToBasketTest, WebSearchAlertTeaserTest, WebSearchSpanQueryTest, WebSearchReferstoCitedbyTest, WebSearchSPIRESSyntaxTest, WebSearchDateQueryTest, WebSearchTestWildcardLimit, WebSearchSynonymQueryTest, WebSearchWashCollectionsTest, WebSearchAuthorCountQueryTest, WebSearchFiletypeQueryTest, WebSearchFilenameQueryTest, WebSearchDOIQueryTest, WebSearchPerformRequestSearchRefactoringTest, WebSearchGetRecordTests, WebSearchExactTitleIndexTest, WebSearchCJKTokenizedSearchTest, WebSearchItemCountQueryTest, WebSearchCustomCollectionBoxesName, WebSearchDetailedRecordTabsTest, WebSearchResolveDOITest, WebSearchPatternLimitTest) if __name__ == "__main__": run_test_suite(TEST_SUITE, warn_user=True) diff --git a/modules/websession/lib/websession_regression_tests.py b/modules/websession/lib/websession_regression_tests.py index 862ef73da..b612cfa90 100644 --- a/modules/websession/lib/websession_regression_tests.py +++ b/modules/websession/lib/websession_regression_tests.py @@ -1,135 +1,135 @@ # -*- coding: utf-8 -*- # # This file is part of Invenio. # Copyright (C) 2006, 2007, 2008, 2010, 2011, 2014, 2016 CERN. # # Invenio is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of the # License, or (at your option) any later version. # # Invenio 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Invenio; if not, write to the Free Software Foundation, Inc., # 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. # pylint: disable=E1102 """WebSession Regression Test Suite.""" __revision__ = \ "$Id$" from invenio.testutils import InvenioTestCase from mechanize import Browser from invenio.config import CFG_SITE_SECURE_URL, CFG_SITE_ADMIN_EMAIL, \ CFG_MISCUTIL_SMTP_PORT from invenio.testutils import make_test_suite, run_test_suite, \ test_web_page_content, merge_error_messages from invenio.dbquery import run_sql class WebSessionWebPagesAvailabilityTest(InvenioTestCase): """Check WebSession web pages whether they are up or not.""" def test_your_account_pages_availability(self): """websession - availability of Your Account pages""" baseurl = CFG_SITE_SECURE_URL + '/youraccount/' # not testing 'change' endpoint here, since it is accepting # only POST requests _exports = ['', 'edit', 'lost', 'display', 'send_email', 'youradminactivities', 'delete', 'logout', 'login', 'register'] error_messages = [] for url in [baseurl + page for page in _exports]: error_messages.extend(test_web_page_content(url)) if error_messages: self.fail(merge_error_messages(error_messages)) return def test_your_groups_pages_availability(self): """websession - availability of Your Groups pages""" baseurl = CFG_SITE_SECURE_URL + '/yourgroups/' _exports = ['', 'display', 'create', 'join', 'leave', 'edit', 'members'] error_messages = [] for url in [baseurl + page for page in _exports]: error_messages.extend(test_web_page_content(url)) if error_messages: self.fail(merge_error_messages(error_messages)) return if CFG_MISCUTIL_SMTP_PORT: class WebSessionLostYourPasswordTest(InvenioTestCase): """Test Lost Your Passwords functionality.""" def test_lost_your_password_for_internal_accounts(self): """websession - sending lost password for internal admin account""" try_with_account = CFG_SITE_ADMIN_EMAIL # click on "send lost password" for CFG_SITE_ADMIN_EMAIL internal account browser = Browser() browser.open(CFG_SITE_SECURE_URL + "/youraccount/lost") browser.select_form(nr=0) browser['p_email'] = try_with_account try: browser.submit() except Exception, e: # Restore the admin password (send_email set it to random number) run_sql("UPDATE user SET password=AES_ENCRYPT(email, '')" "WHERE id=1") self.fail("Obtained %s: probably the email server is not installed " "correctly." % e) # verify the response: expected_response = "Okay, a password reset link has been emailed to " + \ try_with_account lost_password_response_body = browser.response().read() try: lost_password_response_body.index(expected_response) except ValueError: # Restore the admin password (send_email set it to random number) run_sql("UPDATE user SET password=AES_ENCRYPT(email, '')" "WHERE id=1") else: # SMTP server is not available. let's skip this test - class WebSessionLostYourPasswordTest(unittest.TestCase): + class WebSessionLostYourPasswordTest(InvenioTestCase): pass class WebSessionExternalLoginTest(InvenioTestCase): """Test external login functionality.""" def test_no_external_login(self): """websession - openid, oauth1 or oauth2 external login option in log in page""" base_url = CFG_SITE_SECURE_URL + '/youraccount' login_url = base_url + '/login' browser = Browser() response = browser.open(login_url) #Check all the links and see if any of them is of class openid (external login button) for link in browser.links(): for value in link.attrs: if (value[0] == 'class'): if value[1] == 'openid_url': self.fail("Openid external login in login page: %s" % link.attrs) return TEST_SUITE = make_test_suite(WebSessionWebPagesAvailabilityTest, WebSessionLostYourPasswordTest, WebSessionExternalLoginTest) if __name__ == "__main__": run_test_suite(TEST_SUITE, warn_user=True) diff --git a/scripts/create-instance.sh b/scripts/create-instance.sh index d52334771..c37730084 100755 --- a/scripts/create-instance.sh +++ b/scripts/create-instance.sh @@ -1,264 +1,281 @@ #!/usr/bin/env bash # # This file is part of Invenio. # Copyright (C) 2016 CERN. # # Invenio is free software; you can redistribute it # and/or modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of the # License, or (at your option) any later version. # # Invenio 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Invenio; if not, write to the # Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, # MA 02111-1307, USA. # # In applying this license, CERN does not # waive the privileges and immunities granted to it by virtue of its status # as an Intergovernmental Organization or submit itself to any jurisdiction. # quit on errors: set -o errexit # check environment variables: if [ "${INVENIO_MYSQL_HOST}" = "" ]; then echo "[ERROR] Please set environment variable INVENIO_MYSQL_HOST before runnning this script." echo "[ERROR] Example: export INVENIO_MYSQL_HOST=192.168.50.11" exit 1 fi if [ "${INVENIO_MYSQL_DBNAME}" = "" ]; then echo "[ERROR] Please set environment variable INVENIO_MYSQL_DBNAME before runnning this script." echo "[ERROR] Example: INVENIO_MYSQL_DBNAME=invenio1" exit 1 fi if [ "${INVENIO_MYSQL_DBUSER}" = "" ]; then echo "[ERROR] Please set environment variable INVENIO_MYSQL_DBUSER before runnning this script." echo "[ERROR] Example: INVENIO_MYSQL_DBUSER=invenio1" exit 1 fi if [ "${INVENIO_MYSQL_DBPASS}" = "" ]; then echo "[ERROR] Please set environment variable INVENIO_MYSQL_DBPASS before runnning this script." echo "[ERROR] Example: INVENIO_MYSQL_DBPASS=dbpass123" exit 1 fi if [ "${INVENIO_WEB_HOST}" = "" ]; then echo "[ERROR] Please set environment variable INVENIO_WEB_HOST before runnning this script." echo "[ERROR] Example: export INVENIO_WEB_HOST=192.168.50.10" exit 1 fi if [ "${INVENIO_WEB_DSTDIR}" = "" ]; then echo "[ERROR] Please set environment variable INVENIO_WEB_DSTDIR before runnning this script." echo "[ERROR] Example: export INVENIO_WEB_DSTDIR=/opt/invenio" exit 1 fi if [ "${INVENIO_WEB_USER}" = "" ]; then echo "[ERROR] Please set environment variable INVENIO_WEB_USER before runnning this script." echo "[ERROR] Example: export INVENIO_WEB_USER=www-data" exit 1 fi # check optional environment variables: INVENIO_WEB_SMTP_PORT=${INVENIO_WEB_SMTP_PORT:=25} # quit on unbound symbols: set -o nounset # runs inside virtual environment? VIRTUAL_ENV=${VIRTUAL_ENV:=} # runs as root or needs sudo? if [[ "$EUID" -ne 0 ]]; then sudo='sudo' else sudo='' fi -create_apache_vhost_ubuntu_precise () { +create_apache_vhost_ubuntu12 () { sudo DEBIAN_FRONTEND=noninteractive apt-get install -y ssl-cert sudo mkdir -p /etc/apache2/ssl if [ ! -e /etc/apache2/ssl/apache.pem ]; then sudo DEBIAN_FRONTEND=noninteractive /usr/sbin/make-ssl-cert \ /usr/share/ssl-cert/ssleay.cnf /etc/apache2/ssl/apache.pem fi if [ ! -L /etc/apache2/sites-available/invenio.conf ]; then sudo ln -fs "${INVENIO_WEB_DSTDIR}/etc/apache/invenio-apache-vhost.conf" \ /etc/apache2/sites-available/invenio.conf fi if [ ! -e "${INVENIO_WEB_DSTDIR}/etc/apache/invenio-apache-vhost.conf" ]; then # create them empty for the time being so that apache would start sudo mkdir -p "${INVENIO_WEB_DSTDIR}/etc/apache/" sudo touch "${INVENIO_WEB_DSTDIR}/etc/apache/invenio-apache-vhost.conf" sudo chown -R "${INVENIO_WEB_USER}.${INVENIO_WEB_USER}" "${INVENIO_WEB_DSTDIR}" fi if [ ! -L /etc/apache2/sites-available/invenio-ssl.conf ]; then sudo ln -fs "${INVENIO_WEB_DSTDIR}/etc/apache/invenio-apache-vhost-ssl.conf" \ /etc/apache2/sites-available/invenio-ssl.conf fi if [ ! -e "${INVENIO_WEB_DSTDIR}/etc/apache/invenio-apache-vhost-ssl.conf" ]; then # create them empty for the time being so that apache would start sudo mkdir -p "${INVENIO_WEB_DSTDIR}/etc/apache/" sudo touch "${INVENIO_WEB_DSTDIR}/etc/apache/invenio-apache-vhost-ssl.conf" sudo chown -R "${INVENIO_WEB_USER}.${INVENIO_WEB_USER}" "${INVENIO_WEB_DSTDIR}" fi if [ -e /etc/apache2/sites-available/default-ssl ]; then sudo /usr/sbin/a2dissite "*default*" fi sudo /usr/sbin/a2ensite "invenio*" sudo /usr/sbin/a2enmod ssl sudo /usr/sbin/a2enmod version || echo "[WARNING] Ignoring 'a2enmod version' command; hoping IfVersion is built-in." sudo /usr/sbin/a2enmod xsendfile - sudo /etc/init.d/apache2 restart + sudo /usr/sbin/service apache2 restart +} + +create_apache_vhost_ubuntu14 () { + create_apache_vhost_ubuntu12 } create_apache_vhost_centos6 () { if ! grep -q "Include ${INVENIO_WEB_DSTDIR}/etc/apache/invenio-apache-vhost.conf" /etc/httpd/conf/httpd.conf; then echo "Include ${INVENIO_WEB_DSTDIR}/etc/apache/invenio-apache-vhost.conf" | sudo tee -a /etc/httpd/conf/httpd.conf fi if ! grep -q "Include ${INVENIO_WEB_DSTDIR}/etc/apache/invenio-apache-vhost-ssl.conf" /etc/httpd/conf/httpd.conf; then echo "Include ${INVENIO_WEB_DSTDIR}/etc/apache/invenio-apache-vhost-ssl.conf" | sudo tee -a /etc/httpd/conf/httpd.conf fi if ! grep -q "TraceEnable off" /etc/httpd/conf/httpd.conf; then echo "TraceEnable off" | sudo tee -a /etc/httpd/conf/httpd.conf fi if ! grep -q "SSLProtocol all -SSLv2" /etc/httpd/conf/httpd.conf; then echo "SSLProtocol all -SSLv2" | sudo tee -a /etc/httpd/conf/httpd.conf fi sudo sed -i 's,^Alias /error/,#Alias /error/,g' /etc/httpd/conf/httpd.conf } create_symlinks () { $sudo mkdir -p "${INVENIO_WEB_DSTDIR}" $sudo chown "${INVENIO_WEB_USER}.${INVENIO_WEB_USER}" "${INVENIO_WEB_DSTDIR}" $sudo -u "${INVENIO_WEB_USER}" mkdir -p "${INVENIO_WEB_DSTDIR}/lib/python/invenio" for pythonversion in python2.4 python2.6 python2.7; do for libversion in lib lib64 local/lib local/lib64; do for packageversion in site-packages dist-packages; do if [ -d "/usr/$libversion/$pythonversion/$packageversion/" ] && [ ! -L "/usr/$libversion/$pythonversion/$packageversion/invenio" ]; then $sudo ln -s "${INVENIO_WEB_DSTDIR}/lib/python/invenio" "/usr/$libversion/$pythonversion/$packageversion/invenio" fi done done done } install_sources () { cd "${INVENIO_SRCDIR}" rm -rf autom4te.cache/ aclocal automake -a autoconf ./configure --prefix="${INVENIO_WEB_DSTDIR}" make clean -s make -s sudo -u "${INVENIO_WEB_USER}" make -s install sudo -u "${INVENIO_WEB_USER}" make -s install-jquery-plugins sudo -u "${INVENIO_WEB_USER}" make -s install-mathjax-plugin sudo -u "${INVENIO_WEB_USER}" make -s install-ckeditor-plugin sudo -u "${INVENIO_WEB_USER}" make -s install-pdfa-helper-files sudo -u "${INVENIO_WEB_USER}" make -s install-mediaelement } create_openoffice_tmp_space () { sudo mkdir -p "${INVENIO_WEB_DSTDIR}/var/tmp/ooffice-tmp-files" sudo chown -R nobody "${INVENIO_WEB_DSTDIR}/var/tmp/ooffice-tmp-files" sudo chmod -R 755 "${INVENIO_WEB_DSTDIR}/var/tmp/ooffice-tmp-files" } configure_instance () { # create invenio-local.conf echo "[Invenio] CFG_SITE_URL = http://${INVENIO_WEB_HOST} CFG_SITE_SECURE_URL = https://${INVENIO_WEB_HOST} CFG_DATABASE_HOST = ${INVENIO_MYSQL_HOST} CFG_DATABASE_NAME = ${INVENIO_MYSQL_DBNAME} CFG_DATABASE_USER = ${INVENIO_MYSQL_DBUSER} CFG_DATABASE_PASS = ${INVENIO_MYSQL_DBPASS} CFG_SITE_ADMIN_EMAIL = ${INVENIO_ADMIN_EMAIL} CFG_SITE_SUPPORT_EMAIL = ${INVENIO_ADMIN_EMAIL} CFG_WEBALERT_ALERT_ENGINE_EMAIL = ${INVENIO_ADMIN_EMAIL} CFG_WEBCOMMENT_ALERT_ENGINE_EMAIL = ${INVENIO_ADMIN_EMAIL} CFG_WEBCOMMENT_DEFAULT_MODERATOR = ${INVENIO_ADMIN_EMAIL} CFG_BIBAUTHORID_AUTHOR_TICKET_ADMIN_EMAIL = ${INVENIO_ADMIN_EMAIL} CFG_BIBCATALOG_SYSTEM_EMAIL_ADDRESS = ${INVENIO_ADMIN_EMAIL} CFG_BIBSCHED_PROCESS_USER = ${INVENIO_WEB_USER} CFG_MISCUTIL_SMTP_PORT = ${INVENIO_WEB_SMTP_PORT} " | \ sudo -u "${INVENIO_WEB_USER}" tee "${INVENIO_WEB_DSTDIR}/etc/invenio-local.conf" # update instance with this information: sudo -u "${INVENIO_WEB_USER}" "${INVENIO_WEB_DSTDIR}/bin/inveniocfg" --update-all } create_tables () { sudo -u "${INVENIO_WEB_USER}" "${INVENIO_WEB_DSTDIR}/bin/inveniocfg" --create-tables --yes-i-know } create_apache_configuration () { sudo -u "${INVENIO_WEB_USER}" VIRTUAL_ENV="${VIRTUAL_ENV}" "${INVENIO_WEB_DSTDIR}/bin/inveniocfg" --create-apache-conf } -restart_apache_ubuntu_precise () { - $sudo /etc/init.d/apache2 restart +restart_apache_ubuntu12 () { + $sudo /usr/sbin/service apache2 restart +} + +restart_apache_ubuntu14 () { + restart_apache_ubuntu12 } restart_apache_centos6 () { - $sudo /etc/init.d/httpd restart + $sudo /sbin/service httpd restart } main () { # detect OS distribution and release version: if hash lsb_release 2> /dev/null; then os_distribution=$(lsb_release -i | cut -f 2) os_release=$(lsb_release -r | cut -f 2 | grep -oE '[0-9]+\.' | cut -d. -f1 | head -1) elif [ -e /etc/redhat-release ]; then os_distribution=$(cut -d ' ' -f 1 /etc/redhat-release) os_release=$(grep -oE '[0-9]+\.' /etc/redhat-release | cut -d. -f1 | head -1) else os_distribution="UNDETECTED" os_release="UNDETECTED" fi # call appropriate provisioning functions: if [ "$os_distribution" = "Ubuntu" ]; then if [ "$os_release" = "12" ]; then - create_apache_vhost_ubuntu_precise + create_apache_vhost_ubuntu12 + create_symlinks + install_sources + create_openoffice_tmp_space + configure_instance + create_tables + create_apache_configuration + restart_apache_ubuntu12 + elif [ "$os_release" = "14" ]; then + create_apache_vhost_ubuntu14 create_symlinks install_sources create_openoffice_tmp_space configure_instance create_tables create_apache_configuration - restart_apache_ubuntu_precise + restart_apache_ubuntu14 else echo "[ERROR] Sorry, unsupported release ${os_release}." exit 1 fi elif [ "$os_distribution" = "CentOS" ]; then if [ "$os_release" = "6" ]; then create_apache_vhost_centos6 create_symlinks install_sources create_openoffice_tmp_space configure_instance create_tables create_apache_configuration restart_apache_centos6 exit 1 else echo "[ERROR] Sorry, unsupported release ${os_release}." exit 1 fi else echo "[ERROR] Sorry, unsupported distribution ${os_distribution}." exit 1 fi } main diff --git a/scripts/drop-instance.sh b/scripts/drop-instance.sh index 8f0a81369..6b971a766 100755 --- a/scripts/drop-instance.sh +++ b/scripts/drop-instance.sh @@ -1,185 +1,204 @@ #!/usr/bin/env bash # # This file is part of Invenio. # Copyright (C) 2015, 2016 CERN. # # Invenio is free software; you can redistribute it # and/or modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of the # License, or (at your option) any later version. # # Invenio 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Invenio; if not, write to the # Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, # MA 02111-1307, USA. # # In applying this license, CERN does not # waive the privileges and immunities granted to it by virtue of its status # as an Intergovernmental Organization or submit itself to any jurisdiction. # quit on errors: set -o errexit # check environment variables: if [ "${INVENIO_MYSQL_HOST}" = "" ]; then echo "[ERROR] Please set environment variable INVENIO_MYSQL_HOST before runnning this script." echo "[ERROR] Example: export INVENIO_MYSQL_HOST=192.168.50.11" exit 1 fi if [ "${INVENIO_MYSQL_DBNAME}" = "" ]; then echo "[ERROR] Please set environment variable INVENIO_MYSQL_DBNAME before runnning this script." echo "[ERROR] Example: INVENIO_MYSQL_DBNAME=invenio1" exit 1 fi if [ "${INVENIO_MYSQL_DBUSER}" = "" ]; then echo "[ERROR] Please set environment variable INVENIO_MYSQL_DBUSER before runnning this script." echo "[ERROR] Example: INVENIO_MYSQL_DBUSER=invenio1" exit 1 fi if [ "${INVENIO_MYSQL_DBPASS}" = "" ]; then echo "[ERROR] Please set environment variable INVENIO_MYSQL_DBPASS before runnning this script." echo "[ERROR] Example: INVENIO_MYSQL_DBPASS=dbpass123" exit 1 fi if [ "${INVENIO_WEB_HOST}" = "" ]; then echo "[ERROR] Please set environment variable INVENIO_WEB_HOST before runnning this script." echo "[ERROR] Example: export INVENIO_WEB_HOST=192.168.50.10" exit 1 fi if [ "${INVENIO_WEB_DSTDIR}" = "" ]; then echo "[ERROR] Please set environment variable INVENIO_WEB_DSTDIR before runnning this script." echo "[ERROR] Example: export INVENIO_WEB_DSTDIR=/opt/invenio" exit 1 fi if [ "${INVENIO_WEB_USER}" = "" ]; then echo "[ERROR] Please set environment variable INVENIO_WEB_USER before runnning this script." echo "[ERROR] Example: export INVENIO_WEB_USER=www-data" exit 1 fi # quit on unbound symbols: set -o nounset # runs as root or needs sudo? if [[ "$EUID" -ne 0 ]]; then sudo='sudo' else sudo='' fi -start_apache_ubuntu_precise () { - $sudo /etc/init.d/apache2 start +start_apache_ubuntu12 () { + $sudo /usr/sbin/service apache2 start } -stop_apache_ubuntu_precise () { - $sudo /etc/init.d/apache2 stop +stop_apache_ubuntu12 () { + $sudo /usr/sbin/service apache2 stop +} + +start_apache_ubuntu14 () { + start_apache_ubuntu12 +} + +stop_apache_ubuntu14 () { + stop_apache_ubuntu12 } start_apache_centos6 () { - $sudo /etc/init.d/httpd start + $sudo /sbin/service httpd start } stop_apache_centos6 () { - $sudo /etc/init.d/httpd stop + $sudo /sbin/service httpd stop } -drop_apache_vhost_ubuntu_precise () { - stop_apache_ubuntu_precise +drop_apache_vhost_ubuntu12 () { + stop_apache_ubuntu12 if [ -e /etc/apache2/sites-available/default-ssl ]; then $sudo /usr/sbin/a2ensite "*default*" fi if [ -L /etc/apache2/sites-enabled/invenio.conf ]; then $sudo /usr/sbin/a2dissite "invenio*" fi - start_apache_ubuntu_precise + start_apache_ubuntu12 +} + +drop_apache_vhost_ubuntu14 () { + drop_apache_vhost_ubuntu12 } drop_apache_vhost_centos6 () { stop_apache_centos6 if grep -q "Include ${INVENIO_WEB_DSTDIR}/etc/apache/invenio-apache-vhost.conf" /etc/httpd/conf/httpd.conf; then sudo sed -i "s,^Include ${INVENIO_WEB_DSTDIR}/etc/apache/invenio-apache-vhost.conf,#Include ${INVENIO_WEB_DSTDIR}/etc/apache/invenio-apache-vhost.conf,g" /etc/httpd/conf/httpd.conf fi if grep -q "Include ${INVENIO_WEB_DSTDIR}/etc/apache/invenio-apache-vhost-ssl.conf" /etc/httpd/conf/httpd.conf; then sudo sed -i "s,^Include ${INVENIO_WEB_DSTDIR}/etc/apache/invenio-apache-vhost-ssl.conf,#Include ${INVENIO_WEB_DSTDIR}/etc/apache/invenio-apache-vhost-ssl.conf,g" /etc/httpd/conf/httpd.conf fi sudo sed -i 's,^#Alias /error/,Alias /error/,g' /etc/httpd/conf/httpd.conf start_apache_centos6 } drop_symlinks () { for pythonversion in python2.4 python2.6 python2.7; do for libversion in lib lib64 local/lib local/lib64; do for packageversion in site-packages dist-packages; do if [ -d /usr/$libversion/$pythonversion/$packageversion/ ] && [ ! -L /usr/$libversion/$pythonversion/$packageversion/invenio ]; then $sudo rm /usr/$libversion/$pythonversion/$packageversion/invenio fi done done done } drop_instance_folder () { $sudo rm -rf "${INVENIO_WEB_DSTDIR}/var/tmp/ooffice-tmp-files" # shellcheck disable=SC2086 $sudo -u "${INVENIO_WEB_USER}" rm -rf ${INVENIO_WEB_DSTDIR}/* } drop_instance_tables () { if [ -e "${INVENIO_WEB_DSTDIR}/bin/inveniocfg" ]; then $sudo -u "${INVENIO_WEB_USER}" "${INVENIO_WEB_DSTDIR}/bin/inveniocfg" --drop-tables --yes-i-know fi } main () { # detect OS distribution and release version: if hash lsb_release 2> /dev/null; then os_distribution=$(lsb_release -i | cut -f 2) os_release=$(lsb_release -r | cut -f 2 | grep -oE '[0-9]+\.' | cut -d. -f1 | head -1) elif [ -e /etc/redhat-release ]; then os_distribution=$(cut -d ' ' -f 1 /etc/redhat-release) os_release=$(grep -oE '[0-9]+\.' /etc/redhat-release | cut -d. -f1 | head -1) else os_distribution="UNDETECTED" os_release="UNDETECTED" fi # call appropriate provisioning functions: if [ "$os_distribution" = "Ubuntu" ]; then if [ "$os_release" = "12" ]; then - stop_apache_ubuntu_precise + stop_apache_ubuntu12 + drop_instance_tables + start_apache_ubuntu12 + drop_apache_vhost_ubuntu12 + drop_instance_folder + drop_symlinks + elif [ "$os_release" = "14" ]; then + stop_apache_ubuntu14 drop_instance_tables - start_apache_ubuntu_precise - drop_apache_vhost_ubuntu_precise + start_apache_ubuntu14 + drop_apache_vhost_ubuntu14 drop_instance_folder drop_symlinks else echo "[ERROR] Sorry, unsupported release ${os_release}." exit 1 fi elif [ "$os_distribution" = "CentOS" ]; then if [ "$os_release" = "6" ]; then stop_apache_centos6 drop_instance_tables start_apache_centos6 drop_apache_vhost_centos6 drop_instance_folder drop_symlinks else echo "[ERROR] Sorry, unsupported release ${os_release}." exit 1 fi else echo "[ERROR] Sorry, unsupported distribution ${os_distribution}." exit 1 fi } main diff --git a/scripts/populate-instance.sh b/scripts/populate-instance.sh index 0ad36b368..50c2ba4b6 100755 --- a/scripts/populate-instance.sh +++ b/scripts/populate-instance.sh @@ -1,125 +1,139 @@ #!/usr/bin/env bash # # This file is part of Invenio. # Copyright (C) 2016 CERN. # # Invenio is free software; you can redistribute it # and/or modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of the # License, or (at your option) any later version. # # Invenio 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Invenio; if not, write to the # Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, # MA 02111-1307, USA. # # In applying this license, CERN does not # waive the privileges and immunities granted to it by virtue of its status # as an Intergovernmental Organization or submit itself to any jurisdiction. # quit on errors: set -o errexit # check environment variables: if [ "${INVENIO_WEB_DSTDIR}" = "" ]; then echo "[ERROR] Please set environment variable INVENIO_WEB_DSTDIR before runnning this script." echo "[ERROR] Example: export INVENIO_WEB_DSTDIR=/opt/invenio" exit 1 fi if [ "${INVENIO_WEB_USER}" = "" ]; then echo "[ERROR] Please set environment variable INVENIO_WEB_USER before runnning this script." echo "[ERROR] Example: export INVENIO_WEB_USER=www-data" exit 1 fi # quit on unbound symbols: set -o nounset # runs inside virtual environment? VIRTUAL_ENV=${VIRTUAL_ENV:=} # runs as root or needs sudo? if [[ "$EUID" -ne 0 ]]; then sudo='sudo' else sudo='' fi create_demo_site () { $sudo -u "${INVENIO_WEB_USER}" "${INVENIO_WEB_DSTDIR}/bin/inveniocfg" --create-demo-site --yes-i-know } load_demo_records () { $sudo -u "${INVENIO_WEB_USER}" "${INVENIO_WEB_DSTDIR}/bin/inveniocfg" --load-demo-records --yes-i-know } apache_wsgi_restart () { $sudo -u "${INVENIO_WEB_USER}" touch "${INVENIO_WEB_DSTDIR}/var/www-wsgi/invenio.wsgi" } -start_apache_ubuntu_precise () { - $sudo /etc/init.d/apache2 start +start_apache_ubuntu12 () { + $sudo /usr/sbin/service apache2 start } -stop_apache_ubuntu_precise () { - $sudo /etc/init.d/apache2 stop +stop_apache_ubuntu12 () { + $sudo /usr/sbin/service apache2 stop +} + +start_apache_ubuntu14 () { + start_apache_ubuntu12 +} + +stop_apache_ubuntu14 () { + stop_apache_ubuntu12 } start_apache_centos6 () { - $sudo /etc/init.d/httpd start + $sudo /sbin/service httpd start } stop_apache_centos6 () { - $sudo /etc/init.d/httpd stop + $sudo /sbin/service httpd stop } main () { # detect OS distribution and release version: if hash lsb_release 2> /dev/null; then os_distribution=$(lsb_release -i | cut -f 2) os_release=$(lsb_release -r | cut -f 2 | grep -oE '[0-9]+\.' | cut -d. -f1 | head -1) elif [ -e /etc/redhat-release ]; then os_distribution=$(cut -d ' ' -f 1 /etc/redhat-release) os_release=$(grep -oE '[0-9]+\.' /etc/redhat-release | cut -d. -f1 | head -1) else os_distribution="UNDETECTED" os_release="UNDETECTED" fi # call appropriate provisioning functions: if [ "$os_distribution" = "Ubuntu" ]; then if [ "$os_release" = "12" ]; then - stop_apache_ubuntu_precise + stop_apache_ubuntu12 + create_demo_site + start_apache_ubuntu12 + load_demo_records + apache_wsgi_restart + elif [ "$os_release" = "14" ]; then + stop_apache_ubuntu14 create_demo_site - start_apache_ubuntu_precise + start_apache_ubuntu14 load_demo_records apache_wsgi_restart else echo "[ERROR] Sorry, unsupported release ${os_release}." exit 1 fi elif [ "$os_distribution" = "CentOS" ]; then if [ "$os_release" = "6" ]; then stop_apache_centos6 create_demo_site start_apache_centos6 load_demo_records apache_wsgi_restart else echo "[ERROR] Sorry, unsupported release ${os_release}." exit 1 fi else echo "[ERROR] Sorry, unsupported distribution ${os_distribution}." exit 1 fi } main diff --git a/scripts/provision-mysql.sh b/scripts/provision-mysql.sh index d21d8ea19..51454ae12 100755 --- a/scripts/provision-mysql.sh +++ b/scripts/provision-mysql.sh @@ -1,163 +1,169 @@ #!/usr/bin/env bash # # This file is part of Invenio. # Copyright (C) 2015, 2016 CERN. # # Invenio is free software; you can redistribute it # and/or modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of the # License, or (at your option) any later version. # # Invenio 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Invenio; if not, write to the # Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, # MA 02111-1307, USA. # # In applying this license, CERN does not # waive the privileges and immunities granted to it by virtue of its status # as an Intergovernmental Organization or submit itself to any jurisdiction. # quit on errors: set -o errexit # check environment variables: if [ "${INVENIO_MYSQL_HOST}" = "" ]; then echo "[ERROR] Please set environment variable INVENIO_MYSQL_HOST before runnning this script." echo "[ERROR] Example: export INVENIO_MYSQL_HOST=192.168.50.11" exit 1 fi if [ "${INVENIO_MYSQL_DBNAME}" = "" ]; then echo "[ERROR] Please set environment variable INVENIO_MYSQL_DBNAME before runnning this script." echo "[ERROR] Example: INVENIO_MYSQL_DBNAME=invenio1" exit 1 fi if [ "${INVENIO_MYSQL_DBUSER}" = "" ]; then echo "[ERROR] Please set environment variable INVENIO_MYSQL_DBUSER before runnning this script." echo "[ERROR] Example: INVENIO_MYSQL_DBUSER=invenio1" exit 1 fi if [ "${INVENIO_MYSQL_DBPASS}" = "" ]; then echo "[ERROR] Please set environment variable INVENIO_MYSQL_DBPASS before runnning this script." echo "[ERROR] Example: INVENIO_MYSQL_DBPASS=dbpass123" exit 1 fi if [ "${INVENIO_WEB_HOST}" = "" ]; then echo "[ERROR] Please set environment variable INVENIO_WEB_HOST before runnning this script." echo "[ERROR] Example: export INVENIO_WEB_HOST=192.168.50.10" exit 1 fi # quit on unbound symbols: set -o nounset -provision_mysql_ubuntu_precise () { +provision_mysql_ubuntu12 () { # update list of available packages sudo DEBIAN_FRONTEND=noninteractive apt-get update # install MySQL server: sudo DEBIAN_FRONTEND=noninteractive apt-get -y install \ mysql-server # allow network connections: if ! grep -q "${INVENIO_MYSQL_HOST}" /etc/mysql/my.cnf; then sudo sed -i "s/127.0.0.1/${INVENIO_MYSQL_HOST}/" /etc/mysql/my.cnf fi # restart MySQL server: sudo /usr/sbin/service mysql restart } +provision_mysql_ubuntu14 () { + provision_mysql_ubuntu12 +} + provision_mysql_centos6 () { # update list of available packages sudo yum update -y # install MySQL server: sudo yum install -y \ mysql-server # open firewall ports: if [ -e /sbin/iptables ]; then thisinputchain="INPUT" if sudo /sbin/iptables -nL | grep -q 'Chain RH-Firewall-1-INPUT'; then thisinputchain="RH-Firewall-1-INPUT" fi if ! sudo /sbin/iptables -nL | grep -q dpt:3306; then sudo /sbin/iptables -I $thisinputchain -p tcp -m tcp --dport 3306 -j ACCEPT sudo /sbin/iptables -I OUTPUT -p tcp -m tcp --dport 3306 -j ACCEPT fi if ! sudo /sbin/iptables -nL | grep -q dpt:3306; then sudo /sbin/iptables -I $thisinputchain -p tcp -m tcp --dport 3306 -j ACCEPT sudo /sbin/iptables -I OUTPUT -p tcp -m tcp --dport 3306 -j ACCEPT fi fi # save new firewall rules to survive reboot: - sudo /etc/init.d/iptables save + sudo /sbin/service iptables save # enable MySQL upon reboot: sudo /sbin/chkconfig mysqld on # restart MySQL server: - sudo /etc/init.d/mysqld restart + sudo /sbin/service mysqld restart } setup_db () { # create database if it does not exist: echo "CREATE DATABASE IF NOT EXISTS ${INVENIO_MYSQL_DBNAME} DEFAULT CHARACTER SET utf8;" | \ mysql -u root -B # grant privileges to the user on this database: echo "GRANT ALL PRIVILEGES ON ${INVENIO_MYSQL_DBNAME}.* TO ${INVENIO_MYSQL_DBUSER}@${INVENIO_WEB_HOST} IDENTIFIED BY '${INVENIO_MYSQL_DBPASS}';" | \ mysql -u root -B } main () { # detect OS distribution and release version: if hash lsb_release 2> /dev/null; then os_distribution=$(lsb_release -i | cut -f 2) os_release=$(lsb_release -r | cut -f 2 | grep -oE '[0-9]+\.' | cut -d. -f1 | head -1) elif [ -e /etc/redhat-release ]; then os_distribution=$(cut -d ' ' -f 1 /etc/redhat-release) os_release=$(grep -oE '[0-9]+\.' /etc/redhat-release | cut -d. -f1 | head -1) else os_distribution="UNDETECTED" os_release="UNDETECTED" fi # call appropriate provisioning functions: if [ "$os_distribution" = "Ubuntu" ]; then if [ "$os_release" = "12" ]; then - provision_mysql_ubuntu_precise + provision_mysql_ubuntu12 + elif [ "$os_release" = "14" ]; then + provision_mysql_ubuntu14 else echo "[ERROR] Sorry, unsupported release ${os_release}." exit 1 fi elif [ "$os_distribution" = "CentOS" ]; then if [ "$os_release" = "6" ]; then provision_mysql_centos6 else echo "[ERROR] Sorry, unsupported release ${os_release}." exit 1 fi else echo "[ERROR] Sorry, unsupported distribution ${os_distribution}." exit 1 fi # finish with common setups: setup_db } main diff --git a/scripts/provision-web.sh b/scripts/provision-web.sh index 0e68760e5..c48a67541 100755 --- a/scripts/provision-web.sh +++ b/scripts/provision-web.sh @@ -1,251 +1,347 @@ #!/usr/bin/env bash # # This file is part of Invenio. # Copyright (C) 2015, 2016 CERN. # # Invenio is free software; you can redistribute it # and/or modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of the # License, or (at your option) any later version. # # Invenio 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Invenio; if not, write to the # Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, # MA 02111-1307, USA. # # In applying this license, CERN does not # waive the privileges and immunities granted to it by virtue of its status # as an Intergovernmental Organization or submit itself to any jurisdiction. # quit on errors: set -o errexit # check environment variables: if [ "${INVENIO_SRCDIR}" = "" ]; then echo "[ERROR] Please set environment variable INVENIO_SRCDIR before runnning this script." echo "[ERROR] Example: export INVENIO_SRCDIR=/vagrant" exit 1 fi # quit on unbound symbols: set -o nounset # runs inside virtual environment? VIRTUAL_ENV=${VIRTUAL_ENV:=} # runs as root or needs sudo? if [[ "$EUID" -ne 0 ]]; then sudo='sudo' else sudo='' fi # unattended installation: export DEBIAN_FRONTEND=noninteractive -provision_web_ubuntu_precise () { +provision_web_ubuntu12 () { # update list of available packages $sudo DEBIAN_FRONTEND=noninteractive apt-get update # install useful system packages $sudo DEBIAN_FRONTEND=noninteractive apt-get install -y \ apache2-mpm-worker \ automake \ clisp \ curl \ cython \ gettext \ giflib-tools \ git \ - gnuplot poppler-utils \ + gnuplot \ html2text \ ipython \ libapache2-mod-wsgi \ libapache2-mod-xsendfile \ libffi-dev \ libfreetype6-dev \ libjpeg-dev \ libmsgpack-dev \ libmysqlclient-dev \ libpng-dev \ libssl-dev \ libtiff-dev \ libxml2-dev \ libxslt-dev \ make \ + mlocate \ mysql-client \ netpbm \ openOffice.org \ pdftk \ pep8 \ + poppler-utils \ postfix \ pstotext \ pylint \ python-dev \ python-gnuplot \ + python-h5py \ python-libxml2 \ python-libxslt1 \ python-nose \ python-nosexcover \ python-pip \ python-uno \ redis-server \ rlwrap \ sbcl \ screen \ texlive \ unzip \ vim + # make sure Apache is started: + sudo /usr/sbin/service apache2 restart + + # make sure Redis is started: + sudo /usr/sbin/service redis-server restart + + # update list of files e.g. useful for Apache version detection: + sudo updatedb + + # grant Apache user the nobody user rights for OpenOffice integration: + echo "www-data ALL=(nobody) NOPASSWD: ALL" | $sudo tee /etc/sudoers.d/www-data + $sudo chmod o-r /etc/sudoers.d/www-data + +} + +provision_web_ubuntu14 () { + + # update list of available packages + $sudo DEBIAN_FRONTEND=noninteractive apt-get update + + # install useful system packages + $sudo DEBIAN_FRONTEND=noninteractive apt-get install -y \ + apache2-mpm-worker \ + automake \ + clisp \ + curl \ + cython \ + gettext \ + giflib-tools \ + git \ + gnuplot \ + html2text \ + ipython \ + libapache2-mod-wsgi \ + libapache2-mod-xsendfile \ + libffi-dev \ + libfreetype6-dev \ + libjpeg-dev \ + libmsgpack-dev \ + libmysqlclient-dev \ + libpng-dev \ + libssl-dev \ + libtiff-dev \ + libxml2-dev \ + libxslt-dev \ + make \ + mlocate \ + mysql-client \ + netpbm \ + libreoffice \ + pdftk \ + pep8 \ + poppler-utils \ + postfix \ + pstotext \ + pylint \ + python-dev \ + python-gnuplot \ + python-h5py \ + python-libxml2 \ + python-libxslt1 \ + python-nose \ + python-nosexcover \ + python-pip \ + libreoffice-script-provider-python \ + redis-server \ + rlwrap \ + sbcl \ + screen \ + texlive \ + unzip \ + vim + + # make sure Apache is started: + sudo /usr/sbin/service apache2 restart + + # make sure Redis is started: + sudo /usr/sbin/service redis-server restart + + # update list of files e.g. useful for Apache version detection: + sudo updatedb + # grant Apache user the nobody user rights for OpenOffice integration: echo "www-data ALL=(nobody) NOPASSWD: ALL" | $sudo tee /etc/sudoers.d/www-data $sudo chmod o-r /etc/sudoers.d/www-data } provision_web_centos6 () { # update list of available packages $sudo yum update -y # add EPEL external repository: $sudo yum install -y epel-release # install useful system tools: $sudo yum install -y \ automake \ curl \ cython \ file \ freetype-devel \ gcc \ gcc-c++ \ gettext \ gettext-devel \ git \ gnuplot-py \ + h5py \ hdf5-devel \ ipython \ libffi-devel \ libpng-devel \ libreoffice \ libreoffice-headless \ libreoffice-pyuno \ libxml2-devel \ libxml2-python \ libxslt-devel \ libxslt-python \ + mlocate \ mod_ssl \ mod_wsgi \ mysql-devel \ poppler-utils \ python-devel \ python-pip \ redis \ rlwrap \ screen \ sendmail \ sudo \ texlive \ unzip \ vim \ w3m \ wget # open firewall ports: if [ -e /sbin/iptables ]; then thisinputchain="INPUT" if sudo /sbin/iptables -nL | grep -q 'Chain RH-Firewall-1-INPUT'; then thisinputchain="RH-Firewall-1-INPUT" fi if ! sudo /sbin/iptables -nL | grep -q dpt:http; then sudo /sbin/iptables -I $thisinputchain -p tcp -m tcp --dport 80 -j ACCEPT sudo /sbin/iptables -I OUTPUT -p tcp -m tcp --dport 80 -j ACCEPT fi if ! sudo /sbin/iptables -nL | grep -q dpt:https; then sudo /sbin/iptables -I $thisinputchain -p tcp -m tcp --dport 443 -j ACCEPT sudo /sbin/iptables -I OUTPUT -p tcp -m tcp --dport 443 -j ACCEPT fi fi # save new firewall rules to survive reboot: - sudo /etc/init.d/iptables save + sudo /sbin/service iptables save # enable Apache upon reboot: sudo /sbin/chkconfig httpd on - # start Redis: - sudo /etc/init.d/redis start - # enable Redis upon reboot: sudo /sbin/chkconfig redis on + # make sure Apache is started: + sudo /sbin/service httpd restart + + # make sure Redis is started: + sudo /sbin/service redis restart + + # update list of files e.g. useful for Apache version detection: + sudo updatedb + # grant Apache user the nobody user rights for OpenOffice integration: echo "apache ALL=(nobody) NOPASSWD: ALL" | $sudo tee /etc/sudoers.d/apache $sudo chmod o-r /etc/sudoers.d/apache } provision_web_pypi () { # install Python packages from PyPI olddir=$(pwd) cd "${INVENIO_SRCDIR}" for reqfile in requirements*.txt; do if [ -e "$reqfile" ]; then if [ "$VIRTUAL_ENV" != "" ]; then pip install -r "$reqfile" else sudo pip install -r "$reqfile" fi fi done cd "${olddir}" } main () { # detect OS distribution and release version: if hash lsb_release 2> /dev/null; then os_distribution=$(lsb_release -i | cut -f 2) os_release=$(lsb_release -r | cut -f 2 | grep -oE '[0-9]+\.' | cut -d. -f1 | head -1) elif [ -e /etc/redhat-release ]; then os_distribution=$(cut -d ' ' -f 1 /etc/redhat-release) os_release=$(grep -oE '[0-9]+\.' /etc/redhat-release | cut -d. -f1 | head -1) else os_distribution="UNDETECTED" os_release="UNDETECTED" fi # call appropriate provisioning functions: if [ "$os_distribution" = "Ubuntu" ]; then if [ "$os_release" = "12" ]; then - provision_web_ubuntu_precise + provision_web_ubuntu12 + provision_web_pypi + elif [ "$os_release" = "14" ]; then + provision_web_ubuntu14 provision_web_pypi else echo "[ERROR] Sorry, unsupported release ${os_release}." exit 1 fi elif [ "$os_distribution" = "CentOS" ]; then if [ "$os_release" = "6" ]; then provision_web_centos6 provision_web_pypi else echo "[ERROR] Sorry, unsupported release ${os_release}." exit 1 fi else echo "[ERROR] Sorry, unsupported distribution ${os_distribution}." exit 1 fi } main