View · Index

Weblog

Showing 621 - 630 of 695 Postings (summary)

Installing OpenACS on Redhat

Created by OpenACS community, last modified by Gustaf Neumann 20 Aug 2013, at 01:32 PM

Redhat publishes 2 versions of their OS, Fedora (FC) and Redhat Enterprise...

The quicksheet versions:

You should know what you're doing when you use them.

Should you decide to Install OpenACS from source using general en:openacs-system-install instructions, refer to these notes for changes.

Some of these notes below are probably outdated by now, but might still give some useful hints for certain installations.

Notes for Installing Postgresql en:postgresql-install

If you install PostgreSQL 7.3.2 from the Red Hat 9 RPM, you can skip a few steps. These shell commands add some links for compatibility with the directories from a source-based install; start the service; create a new group for web service users, and modify the postgres user's environment (more information):

[root root]# ln -s /usr/lib/pgsql/ /var/lib/pgsql/lib
[root root]# ln -s /var/lib/pgsql /usr/local/pgsql
[root root]# ln -s /etc/init.d/postgresql /etc/init.d/postgres
[root root]# ln -s /usr/bin /usr/local/pgsql/bin
[root root]# service postgresql start
Initializing database:
                                                           [  OK  ]
Starting postgresql service:                               [  OK  ]
[root root]# echo "export LD_LIBRARY_PATH=/usr/local/pgsql/lib" >> ~postgres/.bash_profile
[root root]# echo "export PATH=$PATH:/usr/local/pgsql/bin" >> ~postgres/.bash_profile
[root root]# groupadd web
[root root]# su - postgres
-bash-2.05b$

ln -s /usr/lib/pgsql/ /var/lib/pgsql/lib
ln -s /var/lib/pgsql /usr/local/pgsql
ln -s /usr/bin /usr/local/pgsql/bin
service postgresql start
echo "export LD_LIBRARY_PATH=/usr/local/pgsql/lib" >> ~postgres/.bash_profile
echo "export PATH=$PATH:/usr/local/pgsql/bin" >> ~postgres/.bash_profile
groupadd web
su - postgres

... and then skip to the section in en:postgresql-install that deals with installing plpgsql.

Set PostgreSQL to start on boot

Red Hat RPM:

The init script is already installed; just turn it on for the appropriate run levels.

[root root]# chkconfig --level 345 postgresql on
[root root]# 

Red Hat from source:

[root src]# cp /var/tmp/openacs-5.2.0d1/packages/acs-core-docs/www/files/postgresql.txt /etc/init.d/postgresql
[root src]# chown root.root /etc/rc.d/init.d/postgresql
[root src]# chmod 755 /etc/rc.d/init.d/postgresql
[root src]# 
cp /var/tmp/openacs-5.2.0d1/packages/acs-core-docs/www/files/postgresql.txt /etc/init.d/postgresql
chown root.root /etc/rc.d/init.d/postgresql
chmod 755 /etc/rc.d/init.d/postgresql

Test the script.

[root root]# service postgresql stop
Stopping PostgreSQL: ok
[root root]# 

If PostgreSQL successfully stopped, then use the following command to make sure that the script is run appropriately at boot and shutdown. And turn it back on because we'll use it later.

[root root]# chkconfig --add postgresql
[root root]# chkconfig --level 345 postgresql on
[root root]# chkconfig --list postgresql
postgresql      0:off   1:off   2:on    3:on    4:on    5:on    6:off
[root root]# service postgresql start
Starting PostgreSQL: ok
[root root]#
chkconfig --add postgresql
chkconfig --level 345 postgresql on
chkconfig --list postgresql
service postgresql start

Red Hat defaults to starting services on 3-5. So, on Red Hat, PostgreSQL won't start on runlevel 2 unless you alter the above commands a little. This usually isn't a problem as Red Hat defaults to runlevel 3)

Learning Content Tool

Created by Alvaro Rodriguez, last modified by josue ruiz 21 Dec 2012, at 12:22 AM

Learning-Content Tool

Description


User specs
The Learning-Content Package is a simple content creation tool based on xowiki. This package lets you easily create, edit and organize content for a course, taking advantage of xowiki's easy inline edition and revision history.  The package provides a generic template generated automatically with the pages and the categories.
During the edition of the pages there is an interface that allows the addition of terms and definitions to a glossary, linking the words from the content. It comes with an interface that allows linking of certain resources from the course, such as linking evaluations, assessments and forums to the content pages.
There is a new admin section for the content which includes a page to manage the categories in the content tree, an option to show/hide a specific title for the course on every page, user tracking by page or user, and one-click automatic copy of the content to other classes/communities.

Development History


2007

The Content package was first developed by Byron Linares (Galileo University) as a portlet using xowiki as the main package, adding all the files and modifications needed in xowiki. The automatic template included was specific for the Galileo's theme.

Works on:
postgresql 8.2.x
xowiki 0.47
xotcl 0.47

Required:
ltree module for postgresql

2008-2009
The package was improved by Alvaro Rodriguez and Viaro Networks team to make it a real package as an extension of xowiki, it was updated to work with the latest version of xotcl-core, xowiki from the oacs-5-4 branch. It was completely ported to Oracle and it no longer requires the ltree module for postgresql.

How to Install


Works on:
Postgresql 8.2.x +
Oracle 9i +

Requires:
xowiki 0.106.1
xotcl-core 0.100
views 0.1d3
ajaxhelper 0.87d (needs upgrade to YUI 2.5.2+)

Installation process:
  1. Get the following packages from branch oacs-5-4: dotlrn-all, xowiki, xotcl-core, views
  2. Get the following packages from HEAD: learning-content, learning-content-portlet, dotlrn-learning-content, ajaxhelper
  3. Move to the content package folder and run the script.sh, this will patch all the files from other packages to integrate them with content new features
    1. To run the script:
      • /$path_to_content_patch/$  sh script.sh
  4. Install dotlrn, then install xowiki, xotcl-core, learn-content, learn-content-portlet, dotlrn-learn-content, ajaxhelper and views
  5. Restart the server
  6. Activate the applet in a course

Release Notes


Name: Content
Version: 0.1d  (October 2007)
Developed by: Byron Linares (Galileo University)
  • Provides a simple interface to create web pages and easily include and manipulate web assets such as flash, videos, images, etc.
  • Provides a web template, easy to manage, similar to a PPT template but with built in navigation (sequential navigation, tab based organization, sub tabs supported and per unit / module navigation).
  • Folder, subfolders, pages ordering.
  • Free of "standards" approaches, so professors with basic word knowledge can use it.
  • Auto scroll (focus navigation on the content area).
  • It provides portlets for .LRN

Name: Learn Content (Renamed because Content was a very generic name)
Version: 1.0b (January 2009)
Developed by: Alvaro Rodriguez (Viaro Networks)
  • The package is an OO extension of xowiki, leaves xowiki package unmodified
  • Glossary tool, a plugin for xinha to add words to the glossary during the content edition, an admin page to manage all words and definitions, dynamic popup with the word definition inside the content
  • Integration with other dotlrn resources, a new interface to link resources from the course to the content pages, this allows the content tool to be the reference of a course like SCORM
  • User tracking, reports about all the content pages and all the users views, visits by page and visits by user
  • Header for the content, show/hide a specific title for the course on top of each page of the content
  • An admin section of the content for teachers, the xowiki's inherited admin section is only for swa
  • Automatic copy of the content to other classes/communities inside dotlrn
  • Split up the automatic template in sections to be easily changed (by developers/designers)

Technical specs


The Learn-Content Package is an OO extension of xowiki. The package generic template was split into sections so that it can be easily modified (by a developer/designer).  A new plug-in for the Xinha richtext editor allows it to interact with the new glossary feature. To use this plug-in a parameter in the Xinha configuration must be set (which is automatically added in content).

Every page instantiated along with the package (index, glossary admin, templates, etc) is now in the prototypes section of content. If a site-wide administrator deletes a page it will be loaded again when requested. There is a new admin section that is independent of xowiki's admin section, this section is in a different directory so that different permissions can be set.

Calls to content callbacks have been added to other packages in the add forms to be able to link the resources from those packages to the content pages. The callbacks extend the form of a new object to receive the page_id to be linked to, and inserts the objects into the page once it has been created in the submit section of the form.

A new proc was created that automatically copies content to other classes/comunities using the export and import options of xowiki, complete with all the categories, the mapped objects, and the activities linked to the content.

Each callback is defined and implemented in the learn-content-callback-procs, in the following way:
ad_proc -public -callback "callback_name" -impl content
if a package needs a different implementation of a callback it should be done in the package callbacks procs in the following way:
ad_proc -public -callback "callback_name" -impl $package_key
This callbacks are used inside the page that has the form for creating/editing new in the following way:
callback -catch -impl content "callback_name" -params...

To add a new package to the activities available in content, the callbacks should be added to the file(s) where the objects are created, i.e. forum-new, task-add-edit, etc.
  1. A new parameter called page_instance_id needs to be added to the ad_page_contract
  2. The following callback should be added in a place where the form can be extended
    • callback -catch -impl content learning_content::extend_form -name $form_name -page_instance_id $page_instance_id
  3. The following callback should be added in the submit section of the form after the object has been created
    • callback -catch -impl content learning_content::insert_object -name $object_name -item_id $page_instance_id -activity_id $object_id
  4. The activity should be added to the activity-new and get-activities pages in the learning-content package, check out the existing activities sections to figure out the right way to include

The script added to the package to patch the rest of the packages was generated with diff between the packages from clean oacs-5-4 and modified oacs-5-4:
diff -crNB ~/oacs-5-4/packages/$package_name ~/custom-oacs-5-4/packages/$package_name


This work was done in collaboration with Innova - UNED.

Openacs git repo on Github

Created by Jim Lynch, last modified by Jim Lynch 13 Jul 2012, at 12:35 AM

description/intro paragraph (this might as well be inline)

(all the rest are menu items, which probably open into submenu which has content)

getting started with git for openacs

git for openacs users

git for openacs coders and contributors

openacs release management using git

managing the repos

Install OpenACS on Mac OS X 10.5 / 10.6 (Snow Leopard) Using Macports

Created by Malte Sussdorff, last modified by Gustaf Neumann 03 Nov 2011, at 02:26 PM

I worked off the work of Dave Bauer and used Macports.

Unfortunately, the default configuration of Mac OS X does not allow suitable amounts of shared memory to be created to run the database server. 

Therefore you should edit your /etc/sysctl.conf

On a MacBook Pro with 2GB of RAM, the author's sysctl.conf contains:

kern.sysv.shmmax=1610612736

kern.sysv.shmall=393216

kern.sysv.shmmin=1

kern.sysv.shmmni=32

kern.sysv.shmseg=8

kern.maxprocperuid=512

kern.maxproc=2048

Download and install MacPorts from http://www.macports.org/install.php and get the latest version (1.7.1 as of 2009-04-18)

Install PostgreSQL 8.4

sudo port -k install postgresql84
cd `port work postgresql84`/postgresql-8.4.7/contrib/ltree
make all
sudo make install
sudo port install postgresql84-server
This installs expat, gperf, libiconv, ncursesw, ncurses, gettext, m4, bison, zlib, libxml2, libxslt1, openssl, readline, postgresql82. The macports install then says
To create a database instance, after install do
sudo mkdir -p /opt/local/var/db/postgresql84/defaultdb
sudo chown postgres:postgres /opt/local/var/db/postgresql84/defaultdb
sudo su postgres -c '/opt/local/lib/postgresql84/bin/initdb -D /opt/local/var/db/postgresql84/defaultdb'

Then after initdb postgres says to start postgresql. Before that edit the config file to make it compatible with ACS

sudo emacs -nw /opt/local/var/db/postgresql84/defaultdb/postgresql.conf
Once you have emacs open, change the following config items:
autovacuum = on
add_missing_from = on
default_with_oids = on
regex_flavor = extended

Now start the PostgreSQL Server 

sudo su postgres -c  '/opt/local/lib/postgresql84/bin/postgres -D /opt/local/var/db/postgresql84/defaultdb' &

Install plpgsql as a language

/opt/local/lib/postgresql84/bin/createlang plpgsql template1 -U postgres

Last but not least, put postgresql under launchctl so you can start and stop it: 

sudo launchctl load -w /Library/LaunchDaemons/org.macports.postgresql84-server.plist 

To start it from then on just call

sudo launchctl start org.macports.postgresql84-server

To stop it:

sudo launchctl stop org.macports.postgresql84-server

Install AOLserver 4.5

sudo port install tcl +threads +headers

This will install Tcl with threads enabled, which is needed for AOLserver.

sudo port install aolserver
Now we have AOLserver installed into /opt/local/aolserver. You now need to configure the server to your needs. You might want to create another user (e.g. aolserver) to run the server. First get all the files:
    cd /usr/local/src
    mkdir aolserver 
    cd aolserver 
    TCLLIB=1.13
    XOTCL=1.6.7
    # Path for the AOLserver installation 
    NS=/opt/local/aolserver
    cvs -z3 -d:pserver:anonymous@aolserver.cvs.sourceforge.net:/cvsroot/aolserver co nssha1 
    cvs -z3 -d:pserver:anonymous@aolserver.cvs.sourceforge.net:/cvsroot/aolserver co nspostgres
    echo "Getting TDOM ..." 
    git clone git://github.com/tDOM/tdom.git
    echo "Getting TCL modules ..." 
    curl -L -O http://downloads.sourceforge.net/tcllib/tcllib-${TCLLIB}.tar.bz2 
    curl -L -O http://downloads.sourceforge.net/tcl/thread2.6.5.tar.gz 
    curl -L -O http://media.wu-wien.ac.at/download/xotcl-${XOTCL}.tar.gz

Now install nssha1

 
    cd nssha1
    sudo make install NSHOME=${NS} 
    cd ..

Now go for nspostgres

 
    cd nspostgres/

    # Edit the Makefile so it reads (adding the "-lnsdb")
    MODLIBS = -L$(PGLIB) -lpq -lnsdb
    
    sudo make install AOLSERVER=/opt/local/aolserver/ PGCONFIG=/opt/local/lib/postgresql84/bin/pg_config POSTGRES=/opt/local PGINC=/opt/local/include/postgresql84/ PGLIB=/opt/local/lib/postgresql84/ ACS=1
    cd ..

tDOM

 
    cd tDOM-0.8.2/unix
    ../configure    --mandir=/usr/local/share/man    --libdir=/opt/local/aolserver/lib    --with-tcl=/opt/local/lib   --with-aolserver=/opt/local/aolserver
    sudo make install 
    cd ../..

Thread

 
    tar xvfz thread2.6.5.tar.gz 
    cd thread2.6.5/unix 
    ../configure    --mandir=/usr/local/share/man    --libdir=/Library/Tcl    --with-tcl=/System/Library/Frameworks/Tcl.framework    --with-tclinclude=/System/Library/Frameworks/Tcl.framework/Headers    --with-aolserver=/opt/local/aolserver 
    sudo make install
    cd ../..

XOTcl

The private header files of Tcl are missing, therefore I got the source and recompiled Tcl:

  curl -L -O http://downloads.sourceforge.net/tcl/tcl8.5.9-src.tar.gz
  tar xfz tcl8.5.9-src.tar.gz
  cd tcl8.5.9/unix
  ./configure --enable-threads --prefix=/opt/local --disable-corefoundation 
  sudo make install
  cd ../..

  tar xvfz xotcl-1.6.7.tar.gz 
  cd xotcl-1.6.7
  NS=/opt/local/aolserver/ 
  ./configure --enable-threads --enable-symbols --prefix=${NS} --exec-prefix=${NS} --with-tcl=/opt/local/lib
  sudo make install-aol
  cd .. 

Now we finish off with tcllib

 
  tar xvfj tcllib-1.13.tar.bz2 
  cd tcllib-1.13
  ./configure --prefix=/opt/local/aolserver/ 
  sudo make install
Type in terminal before starting nsd
  ulimit -n 256
I would recommend to install the server in ~/Sites/yourserver if you don't intend to run multiple different servers with access rights on your machine. Checkout the OpenACS code and Edit ~/Sites/yourserver/etc/config.tcl and make the following changes
# Change the server root
set serverroot                "~/Sites/${server}"

# Make sure that OpenACS finds PostgreSQL. Add two lines to the $database if statement

if { $database eq "oracle" } {
    set db_password           "mysitepassword"
} else {
    set db_host               localhost
    set db_port               ""
    set db_user               $server
    ns_section "ns/db/driver/postgres"
    ns_param   pgbin              /opt/local/lib/postgresql84/bin/
}

# Change the AOLserver location
set homedir                   /opt/local/aolserver

Now you can start up your server. First try ist with /opt/local/aolserver/bin/nsd -t ~/Sites/yourserver/etc/config.tcl. If this works you might want to create a launchctl entry as you did above for postgresql

Edit /Library/LaunchDaemons/org.openacs.YOURSERVER.plist and enter the following

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>Label</key>
        <string>org.openacs.YOURSERVER</string>
        <key>OnDemand</key>
        <false/>
        <key>ProgramArguments</key>
        <array>
            <string>/Users/youruser/Sites/yourserver/etc/daemontools/run</string>
        </array>
        <key>ServiceDescription</key>
        <string>OpenACS Service</string>
        <key>UserName</key>
        <string>youruser</string>
        <key>GroupName</key>
        <string>staff</string>
    </dict>
</plist>

Now put yourserver under launchctl so you can start and stop it: 

sudo launchctl load -w /Library/LaunchDaemons/org.openacs.yourserver.plist 

To start it from then on just call

sudo launchctl start org.openacs.yourserver

To stop it:

sudo launchctl stop org.openacs.yourserver 

It is a good idea to schedule regular backups for your server(s). To do this create a shell script, e.g. backup.sh which executes your backups and then create a launchdaemon plist to run your backups nightly

Edit /Library/LaunchDaemons/org.openacs.backup.plist and enter the following

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>Label</key>
        <string>org.openacs.backup</string>
        <key>ProgramArguments</key>
        <array>
        <string>/Users/youruser/Sites/backup.sh</string>
        </array>
        <key>LowPriorityIO</key>
                <true/>
                <key>Nice</key>
                <integer>1</integer>
                <key>StartCalendarInterval</key>
                <dict>
                        <key>Hour</key>
                        <integer>3</integer>
                        <key>Minute</key>
                        <integer>15</integer>
                </dict>
    </dict>
</plist>

If you intend to run AOLserver on a continous basis remember that it is a great idea to make sure it responds properly. To do this you can run a keepalive service.

Edit /Library/LaunchDaemons/org.openacs.keepalive.plist and enter the following

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>Label</key>
        <string>org.openacs.keepalive.plist</string>
        <key>ProgramArguments</key>
        <array>
            <string>/Users/youruser/Sites/keepalive.sh</string>
	    <string>yourserver</string>
            <string>yourport</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
        <key>StartInterval</key>
        <integer>180</integer>
</dict>
</plist>

Your keepalive.sh could look like this

#!/bin/bash 
GREP=/usr/bin/grep
HEAD="/usr/bin/head -1"

INSTANCE="$1";
PORT="$2"

[ -z "$1" ] && exit
[ -z "$2" ] && exit

MAIL_ADDR=""
WGET_FILE=/tmp/.output-keepalive-${INSTANCE}
URL_TEST="http://127.0.0.1:${PORT}/SYSTEM/dbtest"
[ -f ${WGET_FILE} ] && rm -f ${WGET_FILE}  

_restartwebserver ()
{

/bin/launchctl start org.openacs.$INSTANCE
sleep 3
/bin/launchctl start org.openacs.$INSTANCE
}

_sendmail ()
{
echo "${1}" |mailx -s AolWebserver ${MAIL_ADDR}
}

while [ 1 -eq 1 ];
do
        [ -f ${WGET_FILE} ] && /bin/rm -f ${WGET_FILE}
        /usr/bin/curl -s -o $WGET_FILE --connect-timeout 3 --retry 3 "${URL_TEST}"

        if [ -f ${WGET_FILE} ] 
                then
                FIRST_LINE=`${HEAD} ${WGET_FILE} | ${GREP} -i "success"`
                [ -z "${FIRST_LINE}" ] && _restartwebserver && _sendmail "I just restarted the $INSTANCE webserver on `uname -n`" && echo "`date +'%D-%H:%M'` :: FAILURE" || echo "`date +'%D-%H:%M'` :: success $INSTANCE" >>/Users/malte/Sites/keepalive.log 
                else
                _restartwebserver && _sendmail "I just restarted the $INSTANCE webserver on `uname -n`"
#               _restartwebserver
                echo "`date +'%D-%H:%M'` :: FAILURE"
        fi
done

If you intend to run AOLserver on a continous basis remember that it is a great idea to restart your server once per night, otherwise the memory footprint will grow and grow and grow.

Edit /Library/LaunchDaemons/org.openacs.restart.plist and enter the following

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>Label</key>
        <string>org.openacs.restart</string>
        <key>OnDemand</key>
        <false/>
        <key>ProgramArguments</key>
        <array>
            <string>/Users/youruser/Sites/restart.sh</string>
        </array>
         <key>LowPriorityIO</key>
        <true/>
                <key>Nice</key>
                <integer>1</integer>
                <key>StartCalendarInterval</key>
                <dict>
                        <key>Hour</key>
                        <integer>4</integer>
                        <key>Minute</key>
                        <integer>15</integer>
                </dict>
</dict>
</plist>

Now put scripts under launchctl so they will run in the night: 

sudo launchctl load -w /Library/LaunchDaemons/org.openacs.backup.plist

sudo launchctl load -w /Library/LaunchDaemons/org.openacs.restart.plist

sudo launchctl load -w /Library/LaunchDaemons/org.openacs.keepalive.plist

Your restart.sh could look like this

  #!/bin/bash
  echo "cognovis"
  sudo launchctl stop org.openacs.yourserver
  sleep 10
  sudo launchctl start org.openacs.yourserver 

Commit graph

Created by Jeff Davis, last modified by Jeff Davis 04 Nov 2010, at 03:22 PM

commits.png
NameContent TypeLast ModifiedBy UserSize (Bytes)
commits.pngimage/png2010-11-04 15:22:29+01Jeff Davis4670500

Commits

Created by Jeff Davis, last modified by Jeff Davis 04 Nov 2010, at 03:20 PM

Commit graph

Automated Installs - Using install.xml

Created by Ryan Gallimore, last modified by Ryan Gallimore 10 Apr 2010, at 07:29 PM

To automatically install packages with specific parameters and mount points, create an install.xml file in your /path/to/service/ directory, according to:

 Automated Install Thread

Testing with TCLWebtest

Created by OpenACS community, last modified by Ryan Gallimore 10 Apr 2010, at 06:49 PM

Testing with TCLWebtest

by Simon Carstensen and Joel Aufrecht

Tclwebtest is primarily for testing user interface and acceptance testing.

API testing is only part of testing your package - it doesn't test the code in our adp/tcl pairs. For this, we can use TCLWebtest (see sourceforge). TCLWebtest provides a library of functions (see command reference) that make it easy to call a page through HTTP, examine the results, and drive forms. TCLwebtest's functions overlap slightly with acs-automated-testing; see the example provided for one approach on integrating them.

TCLWebtest must be installed for to work. Since automated testing uses it, it should be part of every OpenACS installation. Note that TCLwebtest is installed automatically by Malte's install script.

Forum Posts:

Command Reference:

  • http://tclwebtest.sourceforge.net/doc/api_public.html 

Articles:

  • Automated Testing Best Practices see: https://openacs.org/doc/automated-testing-best-practices.html
  • testing packages for release en:Package_Testing_Process_

Tools:

  • Webtest-Recorder Firefox extension (TwtR) see http://www.km.co.at/km/twtr This module is a plugin for Firefox. It is used to generate/edit a tclwebtest script which can be used later for regression testing without the need of a browser. There is a certain overlap of the application range between selenium and TwtR. This plugin was developed by Åsmund Realfsen for regression/load testing of the assessment module.

Here are some guidelines on how to write automated tests with TCLWebtest. It is a joy to work with automated testing once you get the hang of it. We will use the "myfirstpackage" as an example.

Create the directory that will contain the test script and edit the script file. The directory location and file name are standards which are recognized by the automated testing package:

[$OPENACS_SERVICE_NAME www]$ mkdir /var/lib/aolserver/$OPENACS_SERVICE_NAME/packages/myfirstpackage/tcl/test
[$OPENACS_SERVICE_NAME www]$ cd /var/lib/aolserver/$OPENACS_SERVICE_NAME/packages/myfirstpackage/tcl/test

[$OPENACS_SERVICE_NAME test]$ emacs myfirstpackages-procs.tcl

Write the tests. This is obviously the big step :) The script should first call ad_library like any normal -procs.tcl file:

ad_library {
    ...
}

To create a test case you call aa_register_case test_case_name.. Once you've created the test case you start writing the needed logic. We'll use the tutorial package, "myfirstpackage," as an example. Let's say you just wrote an API for adding and deleting notes in the notes packages and wanted to test that. You'd probably want to write a test that first creates a note, then verifies that it was inserted, then perhaps deletes it again, and finally verifies that it is gone.

Naturally this means you'll be adding a lot of bogus data to the database, which you're not really interested in having there. To avoid this I usually do two things. I always put all my test code inside a call to aa_run_with_teardown which basically means that all the inserts, deletes, and updates will be rolled back once the test has been executed. A very useful feature. Instead of inserting bogus data like: set name "Simon", I tend to generate a random script in order avoid inserting a value that's already in the database:

set name [ad_generate_random_string]

Here's how the test case looks so far:

aa_register_case mfp_basic_test {
    My test
} {
    aa_run_with_teardown \
       -rollback \
       -test_code  {

       }
}

Now look at the actual test code. That's the code that goes inside -test_code {}. We want to implement test case API-001, "Given an object id from API-001, invoke mfp::note::get. Proc should return the specific word in the title."

      set name [ad_generate_random_string]
      set new_id [mfp::note::add -title $name]
      aa_true "Note add succeeded" [exists_and_not_null new_id]

To test our simple case, we must load the test file into the system (just as with the /tcl file in the basic tutorial, since the file didn't exist when the system started, the system doesn't know about it.) To make this file take effect, go to the APM and choose "Reload changed" for "MyFirstPackage". Since we'll be changing it frequently, select "watch this file" on the next page. This will cause the system to check this file every time any page is requested, which is bad for production systems but convenient for developing. We can also add some aa_register_case flags to make it easier to run the test. The -procs flag, which indicates which procs are tested by this test case, makes it easier to find procs in your package that aren't tested at all. The -cats flag, setting categories, makes it easier to control which tests to run. The smoke test setting means that this is a basic test case that can and should be run any time you are doing any test. (a definition of "smoke test")

Once the file is loaded, go to ACS Automated Testing and click on myfirstpackage. You should see your test case. Run it and examine the results.

Example

Now we can add the rest of the API tests, including a test with deliberately bad data. The complete test looks like:

ad_library {
    Test cases for my first package.
}

aa_register_case \
    -cats {smoke api} \
    -procs {mfp::note::add mfp::note::get mfp::note::delete} \
    mfp_basic_test \
    {
        A simple test that adds, retrieves, and deletes a record.
    } {
        aa_run_with_teardown \
            -rollback \
            -test_code  {
                set name [ad_generate_random_string]
                set new_id [mfp::note::add -title $name]
                aa_true "Note add succeeded" [exists_and_not_null new_id]
                
                mfp::note::get -item_id $new_id -array note_array
                aa_true "Note contains correct title" [string equal $note_array(title) $name]
                
                mfp::note::delete -item_id $new_id
                
                set get_again [catch {mfp::note::get -item_id $new_id -array note_array}]
                aa_false "After deleting a note, retrieving it fails" [expr $get_again == 0]
            }
    }

aa_register_case \
    -cats {api} \
    -procs {mfp::note::add mfp::note::get mfp::note::delete} \
    mfp_bad_data_test \
    {
        A simple test that adds, retrieves, and deletes a record, using some tricky data.
    } {
        aa_run_with_teardown \
            -rollback \
            -test_code  {
                set name {-Bad [BAD] \077 { $Bad}} 
                append name [ad_generate_random_string]
                set new_id [mfp::note::add -title $name]
                aa_true "Note add succeeded" [exists_and_not_null new_id]
                
                mfp::note::get -item_id $new_id -array note_array
                aa_true "Note contains correct title" [string equal $note_array(title) $name]
                aa_log "Title is $name"
                mfp::note::delete -item_id $new_id
                
                set get_again [catch {mfp::note::get -item_id $new_id -array note_array}]
                aa_false "After deleting a note, retrieving it fails" [expr $get_again == 0]
            }
    }


aa_register_case \
    -cats {web smoke} \
    -libraries tclwebtest \
    mfp_web_basic_test \
    {
        A simple tclwebtest test case for the tutorial demo package.
        
        @author Peter Marklund
    } {
        # we need to get a user_id here so that it's available throughout
        # this proc
        set user_id [db_nextval acs_object_id_seq]

        set note_title [ad_generate_random_string]

        # NOTE: Never use the aa_run_with_teardown with the rollback switch
        # when running Tclwebtest tests since this will put the test code in
        # a transaction and changes won't be visible across HTTP requests.
        
        aa_run_with_teardown -test_code {
            
            #-------------------------------------------------------------
            # Login
            #-------------------------------------------------------------
            
            # Make a site-wide admin user for this test
            # We use an admin to avoid permission issues
            array set user_info [twt::user::create -admin -user_id $user_id]
            
            # Login the user
            twt::user::login $user_info(email) $user_info(password)
            
            #-------------------------------------------------------------
            # New Note
            #-------------------------------------------------------------
            
            # Request note-edit page
            set package_uri [apm_package_url_from_key myfirstpackage]
            set edit_uri "${package_uri}note-edit"
            aa_log "[twt::server_url]$edit_uri"
            twt::do_request "[twt::server_url]$edit_uri"
            
            # Submit a new note

            tclwebtest::form find ~n note
            tclwebtest::field find ~n title
            tclwebtest::field fill $note_title
            tclwebtest::form submit
            
            #-------------------------------------------------------------
            # Retrieve note
            #-------------------------------------------------------------
            
            # Request index page and verify that note is in listing
            tclwebtest::do_request $package_uri                 
            aa_true "New note with title \"$note_title\" is found in index page" \
                [string match "*${note_title}*" [tclwebtest::response body]]
            
            #-------------------------------------------------------------
            # Delete Note
            #-------------------------------------------------------------
            # Delete all notes

            # Three options to delete the note
            # 1) go directly to the database to get the id
            # 2) require an API function that takes name and returns ID
            # 3) screen-scrape for the ID
            # all options are problematic.  We'll do #1 in this example:

            set note_id [db_string get_note_id_from_name " 
                select item_id 
                  from cr_items 
                 where name = :note_title  
                   and content_type = 'mfp_note'
            " -default 0]

            aa_log "Deleting note with id $note_id"

            set delete_uri "${package_uri}note-delete?item_id=${note_id}"
            twt::do_request $delete_uri
            
            # Request index page and verify that note is in listing
            tclwebtest::do_request $package_uri                 
            aa_true "Note with title \"$note_title\" is not found in index page after deletion." \
                ![string match "*${note_title}*" [tclwebtest::response body]]
            
        } -teardown_code {
            
            twt::user::delete -user_id $user_id
        }
    }


.LRN Meetings

Created by Alvaro Rodriguez, last modified by Alvaro Rodriguez 10 Mar 2010, at 04:41 AM

Next Meeting: 2010-03-10 18:00 CET/CEST Convert to your local time

Agenda

  • .LRN 2.6 Release

Previous Meetings


2008

Community Metrics in OpenACS

Created by Michael Steigman, last modified by Michael Steigman 09 Dec 2009, at 06:09 PM

What can we provide now?


* WIKI

new pages this week
average: new pages per month
page edits this week
average: page edits per month
average: editors per page

* FORUMS

new threads this week
posts this week
average: new threads per month
average: posts per month
average: forum notification subscriptions per month
ratio: posts per thread (monthly?)

example queries:

hub=# select to_char(r.publish_date, 'YYYY-MM') as month, count(*) from cr_items i join cr_revisions r on (i.item_id = r.item_id) where parent_id = '2239905' group by month order by month desc;
  month  | count
---------+-------
 2009-10 |   123
 2009-09 |   394
 2009-08 |   410
 2009-07 |   671
 2009-06 |   158
 2009-05 |     4
 2009-03 |     8
 2009-01 |     4
 2008-12 |    56
(9 rows)

hub=# select to_char(o.creation_date, 'YYYY-MM') as month, count(*) from cr_items i join acs_objects o on (i.item_id = o.object_id) where parent_id = '2239905' group by month order by month desc;
  month  | count
---------+-------
 2009-10 |     2
 2009-09 |    31
 2009-08 |    38
 2009-07 |    71
 2009-06 |    39
 2009-05 |     2
 2009-03 |     4
 2009-01 |     1
 2008-12 |    12
(9 rows)

hub=# select max(count) from (select count(distinct creation_user) as count from cr_items i join cr_revisions r on (i.item_id = r.item_id) join acs_object\
s o on (o.context_id = r.item_id) where parent_id = '2239905' group by i.item_id) a;
 max
-----
   7
(1 row)

hub=# select avg(count) from (select count(distinct creation_user) as count from cr_items i join cr_revisions r on (i.item_id = r.item_id) join acs_object\
s o on (o.context_id = r.item_id) where parent_id = '2239905' group by i.item_id) a;
        avg
--------------------
 1.4900000000000000
(1 row)

hub=# select count(distinct creation_user), i.item_id from cr_items i join cr_revisions r on (i.item_id = r.item_id) join acs_objects o on (o.context_id =\
 r.item_id) where parent_id = '2239905' group by i.item_id;
 count | item_id
-------+---------
     2 | 2239907
     1 | 2240099
     1 | 2240101
     2 | 2240276
     1 | 2240751
     1 | 2240763
     1 | 2240769
     7 | 2240772
     1 | 2248445
     1 | 2249069
     1 | 2249119
     1 | 2249149
...
     2 | 2714595
     1 | 2716420
     1 | 2721530
     1 | 2722191
     2 | 2724344
     1 | 2731842
     1 | 2752093
(200 rows)

What could we provide in the future?


average: # new/departed group members per day/month/year
average: visit length of group members
2 day answer rate for new threads
average: uploads/downloads per month
average: first answer time for threads
ratio: page view per post (lurk)
etc.

Next Page
previous January 2026
Sun Mon Tue Wed Thu Fri Sat
28 29 30 31 1 2 3
4 (1) 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 (2) 30 31

Popular tags

17 , 5.10 , 5.10.0 , 5.10.1 , 5.9.0 , 5.9.1 , ad_form , ADP , ajax , aolserver , asynchronous , Azure , bgdelivery , bootstrap , bugtracker , CentOS , COMET , compatibility , conference , CSP , CSRF , cvs , debian , docker , docker-compose , emacs , engineering-standards , exec , fedora , FreeBSD
No registered users in community xowiki
in last 30 minutes
Contributors

OpenACS.org