Coding conventions: Difference between revisions
No edit summary |
How to run tests. |
||
| Line 133: | Line 133: | ||
{{stub}} | {{stub}} | ||
== Running Tests == | |||
The test driver is installed on all CS department machines. A configuration file is used to launch tests and mail results to subscribers. You can subscribe to a test summary or receive notices when select tests fail. The default configuration file is: <tt>$G/common/build/valid/test.platform.cfg</tt> | |||
If you want to perform a private test run and suppress mail notifications run: | |||
<pre> | |||
> /systest/bin/vrl_test -noemail | |||
</pre> | |||
To run a set of select tests and specify alternative mail notifications (usually to yourself) you can run using a custom configuration file. Make a private copy of the default configuration file and modify it. The comments in the default configuration file describe the format. Then run using the new configuration: | |||
<pre> | |||
> /systest/bin/vrl_test -config <My work area>/<Custom configuration>.cfg | |||
</pre> | |||
Here is an example of a small custom configuration file. | |||
<pre> | |||
######################### test.platform.fast.cfg ############################# | |||
# | |||
Developer: you@cs.brown.edu | |||
Summary: none | |||
nag none linux common/build/valid/test.project.py common/include/nag | |||
libnr none linux common/build/valid/test.project.py common/gg/libnr | |||
libgg none linux common/build/valid/test.project.py common/gg/libgg | |||
libds none linux common/build/valid/test.project.py common/gg/libds | |||
libggpp none linux common/build/valid/test.project.py common/gg/libggpp | |||
libnum none linux common/build/valid/test.project.py common/gg/libnum | |||
libcff2 none linux common/build/valid/test.project.py common/gg/libcff2 | |||
libmri none linux common/build/valid/test.project.py common/mri/libmri | |||
# | |||
####################### end test.platform.fast.cfg ########################## | |||
</pre> | |||
[[Category:HOWTO]][[Category:$G HOWTO]][[Category:Software Development]] | [[Category:HOWTO]][[Category:$G HOWTO]][[Category:Software Development]] | ||
Revision as of 18:09, 29 April 2009
Just about everyone in the VRL ends up re-using code and programs that someone else wrote previously, and undoubtedly the code that they write will be used by someone else in the future. Therefore the golden rule applies well to software development in our lab: do unto others as you would have them do unto you. This page records best practices for getting started developing software in an environment where code lives on through many generations of researchers.
The primary things to keep in mind are that:
- Future users of your code need read and write permission; and
- Future users of your code can't read your mind, so it must be organized and well-documented.
File Permissions
On Linux, there are three basic permissions that may be modified for a file: r, w, and x, which stand for read, write, and execute. For a given file, the permissions may be different for three different classes of users, u, g, and o, which stand for the user who owns the file, other members of the owner's group, and other users. Therefore there are a total of nine permission bits on each file. Each three-bit rwx code may be represented in binary as a number between 0 and 7:
| # | r | w | x | Permission |
|---|---|---|---|---|
| 0 | 0 | 0 | 0 | No access |
| 1 | 0 | 0 | 1 | Execute only |
| 2 | 0 | 1 | 0 | Write only |
| 3 | 0 | 1 | 1 | Write and execute |
| 4 | 1 | 0 | 0 | Read only |
| 5 | 1 | 0 | 1 | Read and execute |
| 6 | 1 | 1 | 0 | Read and write |
| 7 | 1 | 1 | 1 | Read, write, and execute |
The entire set of permissions for a file or directory may therefore be compactly represented by a three-digit octal number. For example, 754 means that the owner may read, write, and execute the file, other members of the owner's group may read and execute it, and all others may only read.
Default permissions for new files
When a new file is created, it starts off having permissions 666 (read and write allowed for all users). For directories, the execute permission means that the user can access the directory, and so the initial permissions on a new directory are 777 (read, write, and access allowed for all users).
These initial permissions are modified by what's called the "umask" or "file mode creation mask". This is a nine-bit binary mask that is XOR'd with the initial permissions. By default, the umask is 022, and therefore a new file will come out with permissions 644 = 666 ^ 022 (read and write for the owner, read only for all others).
Every member of our research group is a member of the graphics group on the CS department network. In order to facilitate code sharing and collaboration, we need to make sure that read and write permissions are set not just for the owner of a file, but for all members of the graphics group, too. This is easily accopmlished by setting the umask to 002 instead: 666 ^ 002 = 664 (read and write for the owner and members of the owner's group, read only for all others).
The umask command either views or sets the current value of the umask. The config file ~/.environment is run every time you open a shell, and the default one created by the CS department for new users sets the umask to 022. To set the umask to 002 at the beginning of every shell session, just edit your ~/.environment file. Look for the line
umask 022
and change it to
umask 002
To make your change take effect immediately, execute the following command in all your open shells:
source ~/.environment
If that gives you an error, try the following instead:
. ~/.environment
You can check that it worked by running umask; the result should be 002. From now on, any files you create from the command line will be writeable by the group.
Commands you should know for dealing with permissions
Type man <command> at the command line to get information about any of the following:
- umask --- view or set the umask
- chmod --- change the permissions for a file or directory
- chown --- change the owner of a file or directory (only allowed if you are the owner)
Development Environment
The graphics group has developed a system over many years that allows easy development of a large, shared base of software. We give the whole thing the nickname $G ("dollar gee"), named after the environment variable that represents the root of the source tree.
There is a single "master" copy in $G of all the shared source code our group has created, and it is modified and backed up through a source control system called CVS (Concurrent Versioning System). You must have CVS set up properly in order to develop with our shared codebase.
Source control works by allowing an individual user to make structured copies of the master versions of files (this process is called "checking out" the files). The user then modifies his or her personal copies of the files, and then "checks in" the changes once they're certain that the code compiles and runs properly. The location where a user modifies a personal copy of shared code is called a "sandbox", because it is in some sense walled off from the master copy: destructive changes to the code in the sandbox do not affect the master copy, provided the user doesn't check them in.
Setting up CVS
Add the following to your ~/.environment file:
setenvvar CVSROOT /map/gfx0/cvsroot/
Setting up $G
Check which shell you use by running the following command in a terminal:
echo $SHELL
If the result is csh or tcsh, you're using the C shell. If it's bash, you're using the Bourne Again shell (don't ask). As before, once you've changed the appropriate config file, reload it by either running the source command or the . command.
... in csh
Open up the file ~/.cshrc in a text editor. Somewhere in the middle of the file you should see:
sourcefile $HOME/.environment
Just below that line, add the following code:
#
# Set $G
#
foreach d (/cygdrive/c/gfx /cygdrive/d/gfx /map/gfx0 /share/gfx)
if (-r $d/tools/gfxtools-startup-csh) then
source $d/tools/gfxtools-startup-csh
break
endif
end
... in bash
Open up the file ~/.bash_profile in a text editor and add the following code at the end:
#
# Set $G
#
for d in /cygdrive/c/gfx /cygdrive/d/gfx /map/gfx0 /share/gfx
do
if [ -r $d/tools/gfxtools-startup-bash ]
then
source $d/tools/gfxtools-startup-bash
break
fi
done
Setting up a development sandbox
We have a standard location for users' sandboxes: /map/gfx0/users. To create your own sandbox, do the following (the ">" just indicates the beginning of each command):
> cd /map/gfx0/users > mkdir -p $USER > cd $USER > $G/bin/gfxtree-init .
Note the period at the end of the last command! The last command will take a long time to finish but should not encounter any errors. Once you're done, you'll have a copy of all the shared source code used in the group.
While Brad's new version of $G is under construction, you also have to execute the following command afterward:
> cvs co common project
Development Best Practices
Running Tests
The test driver is installed on all CS department machines. A configuration file is used to launch tests and mail results to subscribers. You can subscribe to a test summary or receive notices when select tests fail. The default configuration file is: $G/common/build/valid/test.platform.cfg
If you want to perform a private test run and suppress mail notifications run:
> /systest/bin/vrl_test -noemail
To run a set of select tests and specify alternative mail notifications (usually to yourself) you can run using a custom configuration file. Make a private copy of the default configuration file and modify it. The comments in the default configuration file describe the format. Then run using the new configuration:
> /systest/bin/vrl_test -config <My work area>/<Custom configuration>.cfg
Here is an example of a small custom configuration file.
######################### test.platform.fast.cfg ############################# # Developer: you@cs.brown.edu Summary: none nag none linux common/build/valid/test.project.py common/include/nag libnr none linux common/build/valid/test.project.py common/gg/libnr libgg none linux common/build/valid/test.project.py common/gg/libgg libds none linux common/build/valid/test.project.py common/gg/libds libggpp none linux common/build/valid/test.project.py common/gg/libggpp libnum none linux common/build/valid/test.project.py common/gg/libnum libcff2 none linux common/build/valid/test.project.py common/gg/libcff2 libmri none linux common/build/valid/test.project.py common/mri/libmri # ####################### end test.platform.fast.cfg ##########################