Debugging DLXS Perl Code
From DLXS Documentation
(9 intermediate revisions not shown.) | |||
Line 1: | Line 1: | ||
+ | [[DLXS Wiki|Main Page]] > [[Programming Issues]] > Debugging DLXS Perl Code | ||
+ | |||
<p>Much code debugging can be accomplished in whatever development environment you may be using. At DLPS we generally use XEmacs, along with its Comint mode for the Perl debugger. However, it is often helpful to investigate a program's behavior within the browser environment as well. There are occasional debugging statements in the code that will print values of specific variables or even dump entire objects in HTML. These are controlled by adding a parameter to any URL. Simply add a " | <p>Much code debugging can be accomplished in whatever development environment you may be using. At DLPS we generally use XEmacs, along with its Comint mode for the Perl debugger. However, it is often helpful to investigate a program's behavior within the browser environment as well. There are occasional debugging statements in the code that will print values of specific variables or even dump entire objects in HTML. These are controlled by adding a parameter to any URL. Simply add a " | ||
<tt> | <tt> | ||
Line 16: | Line 18: | ||
<p>These values pertain to the debugging output produced by modules in Lib i.e. DLXSROOT/lib | <p>These values pertain to the debugging output produced by modules in Lib i.e. DLXSROOT/lib | ||
and as such they are common to all of the class middleware.</p> | and as such they are common to all of the class middleware.</p> | ||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
+ | ;<b>tpl</b> | ||
+ | :show the path where files subject to fallback resolution (.xml, .xsl, .css, .js) are found. | ||
+ | |||
+ | ;<b>xml</b> | ||
+ | :emit the raw xml from the middleware not subjected to XSLT transformation to HTML. | ||
+ | |||
+ | ;<b>xslt</b> | ||
+ | :emit the virtual stylesheet constructed by the middleware. | ||
+ | |||
+ | ;<b>xsltwrite</b> | ||
+ | :writes the virtual stylesheet constructed by the middleware and the xml file to $DLXSROOT/web/cache as<b> temp.xsl</b> and<b> temp.xml</b> (or REMOTE_USER.temp.xml REMOTE_USER.temp.xsl if the REMOTE_USER environment variable is set). | ||
- | + | ;<b>auth</b> | |
- | <b>auth</b> | + | :Prints the contents of the <tt>AUTHZD_COLL</tt> and <tt>PUBLIC_COLL</tt> environment variables. |
- | + | ||
- | Prints the contents of the <tt>AUTHZD_COLL</tt> and <tt>PUBLIC_COLL</tt> environment variables. | + | |
- | + | ;<b>cache</b> | |
- | <b>cache</b> | + | :Prints information regarding the process of caching information in the session and when profiling time spent in certain parts of the code. See the debug variable <b>time</b> below. |
- | + | ||
- | + | ||
- | when profiling time spent in certain parts of the code. See the debug | + | |
- | variable <b>time</b> below. | + | |
- | + | ;<b>collsinfo</b> | |
- | <b>collsinfo</b> | + | :Prints a variety of information about the Collection Information (<tt>CollsInfo</tt>) object primarily related to the contents of the object, also whether the object has been "reused" (e.g., from the cache) or created fresh from the database. |
- | + | ||
- | Prints a variety of information about the Collection Information (<tt>CollsInfo</tt>) object primarily related to the contents of the object, also whether the object has been "reused" (e.g., from the cache) or created fresh from the database. | + | |
<ul> | <ul> | ||
<li>Dumps the contents of the CollsInfo object as a list of table rows, one per collection.</li> | <li>Dumps the contents of the CollsInfo object as a list of table rows, one per collection.</li> | ||
Line 50: | Line 45: | ||
<li>Prints warnings about collections that are authorized according to the auth variables but that do not appear in the database and vice versa.</li> | <li>Prints warnings about collections that are authorized according to the auth variables but that do not appear in the database and vice versa.</li> | ||
<li>Reports the successful addition of a Class (Text, Bib, Image) object supporting each collection in the CollsInfo object that is marked as requested by the user.</li> | <li>Reports the successful addition of a Class (Text, Bib, Image) object supporting each collection in the CollsInfo object that is marked as requested by the user.</li> | ||
- | |||
<li>Reports the Group Information object (<tt>GroupsInfo</tt>) in the same way as the <tt>CollsInfo</tt> object. Additionally, prints a warning if a database group is deleted from the object if none of the group's collections are authorized.</li> | <li>Reports the Group Information object (<tt>GroupsInfo</tt>) in the same way as the <tt>CollsInfo</tt> object. Additionally, prints a warning if a database group is deleted from the object if none of the group's collections are authorized.</li> | ||
<li>Reports the creation of a object for each collection to be supported.</li> | <li>Reports the creation of a object for each collection to be supported.</li> | ||
</ul> | </ul> | ||
- | |||
- | + | ;<b>reauth</b> | |
- | <b>reauth</b> | + | :Prints out the contents of the link generated to redirect the user to your site's authorization system. |
- | + | ||
- | + | ||
- | + | ;<b>results</b> | |
- | <b>results</b> | + | :Prints each query just before it is sent to XPAT for evaluation and prints a formatted representation of the raw results returned by XPAT. Prints the "clean" result after XPAT result markup tags have been removed, displaying the order in which the result came back from XPAT, its byte offset, the data and the size of the data. |
- | + | ||
- | + | ||
- | prints a formatted representation of the raw results returned by XPAT. Prints the "clean" result after XPAT result markup tags have been removed, displaying the order in which the result came back from XPAT, its byte offset, the data and the size of the data. | + | |
- | + | ;<b>resultset</b> | |
- | <b>resultset</b> | + | :Prints the type and label of each XPat Result Object as it is added to the given Result Set object (<tt>XPatResutlSet</tt>). |
- | + | ||
- | + | ||
- | to the given Result Set object (<tt>XPatResutlSet</tt>). | + | |
- | + | ||
- | + | ;<b>session</b> | |
- | <b>session</b> | + | :Prints the session id under which the current invocation of the cgi |
- | + | ||
- | + | ||
program is running and indicates whether this is a new session id or the id of | program is running and indicates whether this is a new session id or the id of | ||
- | a previous session retrieved from the session cache. | + | a previous session retrieved from the session cache. |
- | + | ||
- | + | ;<b>xpat</b> | |
- | <b>xpat</b> | + | :Prints a dump of the <tt>XPat</tt> object when it is first created. Prints the local or remote startup command string to be sent to the forked process running XPAT and each query string sent to XPAT for evaluation. |
- | + | ||
- | + | ;<b>cgi</b> | |
- | running XPAT and each query string sent to XPAT for evaluation. | + | :Prints a dump of the CGI object created from the URL that invoked the cgi program. It is a <tt>key=value</tt>list of the URL parameters. |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | <b>cgi</b> | + | |
- | + | ||
- | + | ||
- | the cgi program. It is a <tt>key=value</tt>list of the URL parameters. | + | |
- | + | ;<b>env</b> | |
- | <b>env</b> | + | :Prints a dump of the environment variables in effect when the cgi program runs. |
- | + | ||
- | + | ||
- | program runs. | + | |
- | + | ;<b>search</b> | |
- | + | :<ul> | |
- | <b>search</b> | + | <li>Prints the query and query type for each search query sent to XPAT for a variety of different search types.</li> |
- | + | <li>Prints status information when the Class CGI is unable to start up an XPAT process for a given collection. This normally fails silently so as not to interrupt a startup loop over multiple collections.</li> | |
- | + | ||
- | <ul> | + | |
- | <li>Prints the query and query type for each search query sent to | + | |
- | XPAT for a variety of different search types.</li> | + | |
- | <li>Prints status information when the Class CGI is unable to | + | |
- | start up an XPAT process for a given collection. This normally fails silently so | + | |
- | as not to interrupt a startup loop over multiple collections.</li> | + | |
</ul> | </ul> | ||
- | |||
- | + | ;<b>time</b> | |
- | <b>time</b> | + | :Prints a summary of the amount of time it takes the Class CGI to |
- | + | ||
- | + | ||
run. It displays the elapsed time to compile and run the entire program (which | run. It displays the elapsed time to compile and run the entire program (which | ||
includes time to communicate with a local or remote XPAT process, and so | includes time to communicate with a local or remote XPAT process, and so | ||
Line 126: | Line 85: | ||
communication overhead). It also displays the CPU time devoted solely to the | communication overhead). It also displays the CPU time devoted solely to the | ||
process running the Class CGI. The difference between these two numbers is a | process running the Class CGI. The difference between these two numbers is a | ||
- | rough indication of the overhead to which the CGI is subject. | + | rough indication of the overhead to which the CGI is subject. |
- | + | ;<b>version</b> | |
- | <b>version</b> | + | :Prints the value <tt>$LibVersion::VERSION</tt> that is the version of the separate Lib deliverable in use by the Class CGI. Prints the Release number of the middleware. Prints the Perl version number. Prints the main program version number. |
- | + | ||
- | + | ||
- | separate Lib deliverable in use by the Class CGI. Prints the Release number of the middleware. Prints the Perl version number. Prints the main program version number. | + | |
- | + | ;<b>db</b> | |
- | <b>db</b> | + | :Prints connect string used to access the database and the database user name the connect was issued under. For example, |
- | + | <pre> | |
- | </ | + | <tt>DSN=DBI:mysql:dlxs:mysql.umdl.umich.edu:, Username=dlxs</tt>. |
- | + | </pre> | |
+ | |||
<h1>Unique Text Class Debug Values</h1> | <h1>Unique Text Class Debug Values</h1> | ||
- | + | ||
- | + | ;<b>filter</b> | |
- | <b>filter</b> | + | :Prints the result of applying various filters to the results returned from a given query. Currently, the following filters' results are printed: |
- | + | ||
- | + | ||
- | returned from a given query. Currently, the following filters' results are | + | |
- | printed: | + | |
<ul> | <ul> | ||
<li> | <li> | ||
Line 156: | Line 109: | ||
<li> | <li> | ||
<tt>StripMainHeader</tt> | <tt>StripMainHeader</tt> | ||
- | |||
</li> | </li> | ||
<li> | <li> | ||
Line 162: | Line 114: | ||
</li> | </li> | ||
</ul> | </ul> | ||
- | + | ||
- | + | ;<b>links</b> | |
- | + | :Prints the contents of the 'search within' link generated by <tt>TextClass::_SearchWithinLinks</tt> | |
- | <b>links</b> | + | |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ;<b>qf</b> | |
- | <b>qf</b> | + | :Prints status when the QueryFactory object is created for a given collection object. If the collection implements the use of XPAT mapping of special characters (e.g. 'Y' for yogh in Middle English) the transformation of these characters in the CGI object is called out at this point. |
- | + | ||
- | + | ||
- | + | ;<b>target</b> | |
- | <b>target</b> | + | :Useful for tracing the construction of searches for the target of <PTR> type notes. Prints which mode of target region search was used, i.e. fabricated region search or explicitly coded list of regions. Prints the XPAT query for the target region and the parent region of the target region. Prints the overall restriction applied to limit the search to a particular main region. This debug output appears in the note popup window when the note is displayed. |
- | + | ||
- | + | ||
- | + | ;<b>sort</b> | |
- | <b>sort</b> | + | :Prints information regarding the process of sorting results and when profiling time spent in certain parts of the code. See the debug variable <b>time</b> below. |
- | + | ||
- | + | ||
- | when profiling time spent in certain parts of the code. See the debug | + | |
- | variable <b>time</b> below. | + | |
- | + | ;<b>pageviewer</b> | |
- | <b>pageviewer</b> | + | :Prints a variety of information related to page viewing (<tt>pageviewer-idx</tt>) including: |
- | + | ||
- | + | ||
<ul> | <ul> | ||
<li>A dump of the Page View object's (<tt>PageView</tt>) contents.</li> | <li>A dump of the Page View object's (<tt>PageView</tt>) contents.</li> | ||
- | <li>Entry trace information for the subroutines that serve the | + | <li>Entry trace information for the subroutines that serve the frames in the Pageviewer frameset.</li> |
- | frames in the Pageviewer frameset.</li> | + | <li>The contents of the URL that the Pageviewer CGI uses to redirect to the TextClass CGI for text-mode page viewing.</li> |
- | <li>The contents of the URL that the Pageviewer CGI uses to | + | |
- | redirect to the TextClass CGI for text-mode page viewing.</li> | + | |
</ul> | </ul> | ||
- | + | ;<b>ww</b> | |
- | + | :Prints a variety of information about the Wordwheel CGI and Wordwheel Object. The information printed for the CGI includes the environment and the contents of the CGI object created from the URL that invoked the wordwheel CGI. The information printed for the Wordwheel object (<tt>WW</tt>)consists of: | |
- | <b>ww</b> | + | |
- | + | ||
- | + | ||
- | Wordwheel Object. The information printed for the CGI includes the environment | + | |
- | and the contents of the CGI object created from the URL that invoked the | + | |
- | wordwheel CGI. The information printed for the Wordwheel object (<tt>WW</tt>)consists of: | + | |
<ul> | <ul> | ||
<li>Status information about failure to start XPAT (if failed)</li> | <li>Status information about failure to start XPAT (if failed)</li> | ||
- | |||
<li>A dump of the Wordwheel object contents.</li> | <li>A dump of the Wordwheel object contents.</li> | ||
<li>A dump of the table of words constructed by the <tt>GetCombinedTable</tt> object method.</li> | <li>A dump of the table of words constructed by the <tt>GetCombinedTable</tt> object method.</li> | ||
- | <li>A dump of the search results returned by the XPAT queries | + | <li>A dump of the search results returned by the XPAT queries usedto generate the wordwheel table.</li> |
- | + | ||
</ul> | </ul> | ||
- | |||
- | |||
- | |||
<h1>Unique Bib Class Debug Values</h1> | <h1>Unique Bib Class Debug Values</h1> | ||
- | + | ;<b>fisheye</b> | |
- | + | :A dump of the data computed for the construction of the fisheye navigation string. | |
- | <b>fisheye</b> | + | |
- | + | ||
- | + | ||
- | navigation string. | + | |
- | + | ||
<h1>Unique Image Class Debug Values</h1> | <h1>Unique Image Class Debug Values</h1> | ||
Line 234: | Line 153: | ||
<p>There are not many distinct values unique to Image Class for the <tt>debug</tt> URL parameter. Assigning any value to <tt>debug</tt> (e.g. <tt>1</tt>) will turn on debugging output globally within Image Class. Of course, the common distinct values mentioned earlier must be specified as documented to turn on their given debug function. </p> | <p>There are not many distinct values unique to Image Class for the <tt>debug</tt> URL parameter. Assigning any value to <tt>debug</tt> (e.g. <tt>1</tt>) will turn on debugging output globally within Image Class. Of course, the common distinct values mentioned earlier must be specified as documented to turn on their given debug function. </p> | ||
- | + | ;<b>hs</b> | |
- | + | :Prints the collection ID for each collection processes in the <tt>HandleSearch</tt> subroutine. | |
- | <b>hs</b> | + | |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
<h1>Environment Variables</h1> | <h1>Environment Variables</h1> | ||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | + | ;<b>DBI_TRACE</b> | |
- | + | :This will enable a dump of the interaction of the middleware with the Perl DBI (database interface) module. It must be set <i>before</i> Perl executes. Refer to the POD for <tt>DBI.pm</tt> in your Perl install tree (At the shell prompt type: <tt>perldoc DBI.pm</tt>). | |
- | <b> | + | |
- | < | + | |
- | < | + | |
- | + | ||
- | </ | + | ;<b>ASSERTION_EMAIL</b> |
- | + | :Setting this environment variable to an email address (e.g. <tt>umdl-errors@umich.edu</tt>) will cause the <tt>ASSERT</tt>subroutine to send a complete email summary of the data that caused an assertion failure. This is useful in monitoring the health of production code in the absence of user feedback. Set in the apache <b>httpd.conf</b> file for the virtual host using "SetEnv ASSERT" | |
- | + | ||
+ | |||
+ | ;<b>XPAT_LOGGING</b> | ||
+ | :Setting this environment variable to the name of a file will cause the <tt>XPat.pm</tt> module to log process ids and associated URL strings for each XPAT process forked to execute a query. At DLPS we couple this log file with a runaway process killer which kills XPAT processes that run for more than 1.5 minutes. The process killer sends email notification and with the additional logged data we can determine the URL that generated the runaway and resolve the problem. Set in the apache <b>httpd.conf</b> file for the virtual host using "SetEnv ASSERT" | ||
+ | |||
<h1>Support for Virtual Host-based Work Directories</h1> | <h1>Support for Virtual Host-based Work Directories</h1> | ||
- | <p>Related to the issue of | + | <p>Related to the issue of debugging is the issue off having multiple work directories for each developer. DLXS middleware supports this. There are ways of setting up "sandboxes" so that individuals can have their own environments for running and testing changes they are making, independently of others' work. For more information, see [[DLPS's Development Environment for DLXS Software]]. |
</p> | </p> | ||
+ | |||
+ | |||
+ | [[#top|Top]] |
Current revision
Main Page > Programming Issues > Debugging DLXS Perl Code
Much code debugging can be accomplished in whatever development environment you may be using. At DLPS we generally use XEmacs, along with its Comint mode for the Perl debugger. However, it is often helpful to investigate a program's behavior within the browser environment as well. There are occasional debugging statements in the code that will print values of specific variables or even dump entire objects in HTML. These are controlled by adding a parameter to any URL. Simply add a " ;debug=value " to a URL in your browser where value is any of the following described below.
Note that the value all turns on all debugging switches and produces a considerable quantity of output, especially in the case of searches.
Contents |
Debug Values Available in All Classes
These values pertain to the debugging output produced by modules in Lib i.e. DLXSROOT/lib and as such they are common to all of the class middleware.
- tpl
- show the path where files subject to fallback resolution (.xml, .xsl, .css, .js) are found.
- xml
- emit the raw xml from the middleware not subjected to XSLT transformation to HTML.
- xslt
- emit the virtual stylesheet constructed by the middleware.
- xsltwrite
- writes the virtual stylesheet constructed by the middleware and the xml file to $DLXSROOT/web/cache as temp.xsl and temp.xml (or REMOTE_USER.temp.xml REMOTE_USER.temp.xsl if the REMOTE_USER environment variable is set).
- auth
- Prints the contents of the AUTHZD_COLL and PUBLIC_COLL environment variables.
- cache
- Prints information regarding the process of caching information in the session and when profiling time spent in certain parts of the code. See the debug variable time below.
- collsinfo
- Prints a variety of information about the Collection Information (CollsInfo) object primarily related to the contents of the object, also whether the object has been "reused" (e.g., from the cache) or created fresh from the database.
- Dumps the contents of the CollsInfo object as a list of table rows, one per collection.
- Indicates whether a session-cached CollsInfo object is reused or a new one is created by reading the database.
- Prints the path to the database and the database table in use. Prints the database user name accessing the rows: a specific userid, dlxsadm or production.
- Prints warnings about collections that are authorized according to the auth variables but that do not appear in the database and vice versa.
- Reports the successful addition of a Class (Text, Bib, Image) object supporting each collection in the CollsInfo object that is marked as requested by the user.
- Reports the Group Information object (GroupsInfo) in the same way as the CollsInfo object. Additionally, prints a warning if a database group is deleted from the object if none of the group's collections are authorized.
- Reports the creation of a object for each collection to be supported.
- reauth
- Prints out the contents of the link generated to redirect the user to your site's authorization system.
- results
- Prints each query just before it is sent to XPAT for evaluation and prints a formatted representation of the raw results returned by XPAT. Prints the "clean" result after XPAT result markup tags have been removed, displaying the order in which the result came back from XPAT, its byte offset, the data and the size of the data.
- resultset
- Prints the type and label of each XPat Result Object as it is added to the given Result Set object (XPatResutlSet).
- session
- Prints the session id under which the current invocation of the cgi
program is running and indicates whether this is a new session id or the id of a previous session retrieved from the session cache.
- xpat
- Prints a dump of the XPat object when it is first created. Prints the local or remote startup command string to be sent to the forked process running XPAT and each query string sent to XPAT for evaluation.
- cgi
- Prints a dump of the CGI object created from the URL that invoked the cgi program. It is a key=valuelist of the URL parameters.
- env
- Prints a dump of the environment variables in effect when the cgi program runs.
- search
- time
- Prints a summary of the amount of time it takes the Class CGI to
run. It displays the elapsed time to compile and run the entire program (which includes time to communicate with a local or remote XPAT process, and so includes process startup, context switching, network latency, and inter-process communication overhead). It also displays the CPU time devoted solely to the process running the Class CGI. The difference between these two numbers is a rough indication of the overhead to which the CGI is subject.
- version
- Prints the value $LibVersion::VERSION that is the version of the separate Lib deliverable in use by the Class CGI. Prints the Release number of the middleware. Prints the Perl version number. Prints the main program version number.
- db
- Prints connect string used to access the database and the database user name the connect was issued under. For example,
<tt>DSN=DBI:mysql:dlxs:mysql.umdl.umich.edu:, Username=dlxs</tt>.
Unique Text Class Debug Values
- filter
- Prints the result of applying various filters to the results returned from a given query. Currently, the following filters' results are printed:
- FilterDivhead
- FilterMainHeader
- StripMainHeader
- _HeaderFilter
- links
- Prints the contents of the 'search within' link generated by TextClass::_SearchWithinLinks
- qf
- Prints status when the QueryFactory object is created for a given collection object. If the collection implements the use of XPAT mapping of special characters (e.g. 'Y' for yogh in Middle English) the transformation of these characters in the CGI object is called out at this point.
- target
- Useful for tracing the construction of searches for the target of <PTR> type notes. Prints which mode of target region search was used, i.e. fabricated region search or explicitly coded list of regions. Prints the XPAT query for the target region and the parent region of the target region. Prints the overall restriction applied to limit the search to a particular main region. This debug output appears in the note popup window when the note is displayed.
- sort
- Prints information regarding the process of sorting results and when profiling time spent in certain parts of the code. See the debug variable time below.
- pageviewer
- Prints a variety of information related to page viewing (pageviewer-idx) including:
- A dump of the Page View object's (PageView) contents.
- Entry trace information for the subroutines that serve the frames in the Pageviewer frameset.
- The contents of the URL that the Pageviewer CGI uses to redirect to the TextClass CGI for text-mode page viewing.
- ww
- Prints a variety of information about the Wordwheel CGI and Wordwheel Object. The information printed for the CGI includes the environment and the contents of the CGI object created from the URL that invoked the wordwheel CGI. The information printed for the Wordwheel object (WW)consists of:
- Status information about failure to start XPAT (if failed)
- A dump of the Wordwheel object contents.
- A dump of the table of words constructed by the GetCombinedTable object method.
- A dump of the search results returned by the XPAT queries usedto generate the wordwheel table.
Unique Bib Class Debug Values
- fisheye
- A dump of the data computed for the construction of the fisheye navigation string.
Unique Image Class Debug Values
There are not many distinct values unique to Image Class for the debug URL parameter. Assigning any value to debug (e.g. 1) will turn on debugging output globally within Image Class. Of course, the common distinct values mentioned earlier must be specified as documented to turn on their given debug function.
- hs
- Prints the collection ID for each collection processes in the HandleSearch subroutine.
Environment Variables
- DBI_TRACE
- This will enable a dump of the interaction of the middleware with the Perl DBI (database interface) module. It must be set before Perl executes. Refer to the POD for DBI.pm in your Perl install tree (At the shell prompt type: perldoc DBI.pm).
- ASSERTION_EMAIL
- Setting this environment variable to an email address (e.g. umdl-errors@umich.edu) will cause the ASSERTsubroutine to send a complete email summary of the data that caused an assertion failure. This is useful in monitoring the health of production code in the absence of user feedback. Set in the apache httpd.conf file for the virtual host using "SetEnv ASSERT"
- XPAT_LOGGING
- Setting this environment variable to the name of a file will cause the XPat.pm module to log process ids and associated URL strings for each XPAT process forked to execute a query. At DLPS we couple this log file with a runaway process killer which kills XPAT processes that run for more than 1.5 minutes. The process killer sends email notification and with the additional logged data we can determine the URL that generated the runaway and resolve the problem. Set in the apache httpd.conf file for the virtual host using "SetEnv ASSERT"
Support for Virtual Host-based Work Directories
Related to the issue of debugging is the issue off having multiple work directories for each developer. DLXS middleware supports this. There are ways of setting up "sandboxes" so that individuals can have their own environments for running and testing changes they are making, independently of others' work. For more information, see DLPS's Development Environment for DLXS Software.