Multisite Testbed

From TNG_Wiki
Jump to: navigation, search

Summary

Here is a great test system for TNG mod developers using Windows.

  • It hosts any number of TNG sites, each with its own version, configuration and database, and all accessible in a single browser session.
  • It allows creation of new sites with updated versions of TNG in just a few steps
  • It runs the latest version of PHP, but allows switching to earlier versions for testing older TNG installations.
  • It uses a single backup utility (MySQLDumper) to back up and restore any selected database in its entirety, not just TNG tables, and to synchronize with your live site by restoring a backup of the live site database.
  • all components are free, mostly open source and available for download from the Internet.

Using the diagram below, mod developers should be able to download and assemble the components without a lot of additional instruction. Everyone has their favorite WAMPS package. I can tell you that in the past five years using UniServer, I have not had any problems. It works out of the box. It requires no special setup or Windows operating system installation. If a script works on UniServer, it works on my live site and vice-versa. All you do is unzip the package, place the UniServer folder on your drive, rename it localhost or anything else you like, use Windows to go into the folder and click on UniController.exe to start it. That's it. Add your content to the www folder and use a browser to navigate to localhost.

Server Diagram


Download the Uniform Server

MySQLDumper completely solves the problem of timing out when backing up a large database by breaking it up into smaller chunks. It also backs up the entire database, not just the TNG tables. Put a copy on your live site to back up the database, and another copy on the test site to restore the database for a mirror site.

Download MySQLDumper

If you write articles for TNGWiki this is a great resource for writing your drafts and testing the visuals.

Download MediaWiki

Screen Shots

UniServer Controller

Controller: Start and Stop Apache and MySQL
Select PHP Version

You will need to download each additional version of PHP you want from the UniServer site. It is just a folder that you drop into localhost\core\. No other installation is required, although you can edit the PHP.ini files for specific behavior, like setting the time zones, etc. There are two versions of the file: php_development.ini and php_production.ini. They can be set up differently and you can choose which one to use with the UniServer control panel.

Site Index

Site Index

Download the Directory Program]

Browser Bookmarks

Browser Bookmarks

Add New Test Site

When TNG comes out with an upgrade, you can keep your current test site(s) and add the new one.

  1. make a copy of the most recent test site folder and rename it, for example, from t1012_Copy to t1013
  2. use phpMyAdmin to make a copy of the most recent site's database and name it to serve the new site, for example, _tng1013
  3. in the new site folder change config.php to use the new database and point to the correct $tngdomain, $rootpath, etc.
  4. update subroot.php if necessary
  5. download the TNG upgrade and apply it to the new test site.

Version Control With Mod Batch Files

While version control software is available, it would normally be serious overkill when compared to using simple batch files to manage TNG mods.

Mod Batch File

Batch files can be created on the local Windows machine to copy mod files/folders to an archive with both the mod version number and an edit version number, sometimes called a build number. It can also distro the mod to other selected test sites and zip up a package for upload to the TNGWiki. Here is one possible setup for an Archive in which the batch file collects all the required files/folders from the mods directory.

Each time the batch file is run it creates a new package with the current date-time so you can go back to earlier edits of the same mod-version, or if you are satisfied with the current one, you can delete the earlier copies. Your upload path to the TNGWiki might look like this:

D:\Archives\mod2\v10.1.1.13\A15.09.27.140912\mod2_v10.1.1.13.zip
Sample Archive Structure

In order for the batch file to create zipped folders you will have to download a copy of 7za.exe (7Zip command line program) and put it into your Windows/System32 folder.

Download the 7za.exe command line utility]

Creating a Batch File

For the sake of discussion, we will create a batch file to handle a mod named mod2. It has a cfg file and a supporting subfolder from which it copies files to the TNG root and elsewhere on the site when installed by Mod Manager.

As a rule developers must test, modify and re-test mod files in their deployed locations. When everything seems to be working correctly, they must copy any that were modified back into the mods/mod-folder and create a distribution package. It's easy to make mistakes here, so we'll create a batch file to automate it. We will:

  • place configuration parameters near the top to make adapting it to other mods easier
  • show an options menu
  • generate a date-time stamp
  • use a list of test sites
  • copy deployed files back into the mods folder to prevent updates from being lost
  • copy files/folders to an archive
  • zip up the mod for upload to the TNGWiki
  • copy the files/folders to other test sites for validation
  • display status for each operation

When building and testing a batch file, always comment out the executable commands with REM (remark) to check menus and program flow. Once you have that right, uncomment one command at a time for testing.

REM ROBOCOPY %css% %modpack%\css %%a > nul

Backslashes are required by the DOS environment.

Getting Started: mod2.bat

:: Mod2
:: Archive mod2, distro it to other test sites and create a zipfile
@echo off
SETLOCAL

Each batch file should start with comments describing its purpose followed by two commands:

  • @echo off keeps Windows from echoing each command to the screen
  • SETLOCAL allows you to set variables locally so they will be removed from the Windows environment when the batch file is finished running.

Setting Parameters

Parameters are values assigned to variables that will be used in the processing. Our test site is localhost/t1012, the mod name is mod2, it is in the /mods folder, it is version v10.1.1.13 and it has a supporting folder with files to be copied by Mod Manager to the TNG site.

SET root=D:\localhost\www\t1012
SET mods=%root%\mods
SET modname=mod2
SET version=v10.1.1.13

:: mod2 includes a subfolder of supporting scripts/images
SET supported=1
SET modpack=%mods%\%modname%_%version%

Variables and their values are set using the SET keyword. The last line is an example of using variables where actual values are substituted for %mods%, %modname% and %version%. When testing for equality (==) both the variable and the test value must be enclosed in double quotes.

IF "%supported%"=="0" goto Done

Batchfile keywords like ECHO, SET, IF and GOTO are case insensitive, but are often upper cased for better readability.

Lists

Batchfiles are capable of processing from a list. A list can contain zero or more elements. If the list is empty (SET example=) it will not be processed. Creating a list is straightforward: just separate the items with a space. To create a list named example:

SET example=item1 item2 item3 item4

Items can also be written as a vertical list for readability provided the rules (see below) are strictly followed.

The following lists will be part of our batchfile.

:: list test site mod folders
SET sitelist=^
 D:\localhost\www\t0812\mods^
 D:\localhost\www\t0813\mods^
 D:\localhost\www\t0900\mods^
 D:\localhost\www\t0910\mods^
 D:\localhost\www\t0922\mods^
 D:\localhost\www\t1000\mods^
 D:\localhost\www\t1001\mods^
 D:\localhost\www\t1002\mods^
 D:\localhost\www\t1003\mods^
 D:\localhost\www\t1010\mods^
 D:\localhost\www\t1011\mods^
 D:\localhost\www\t1012\mods

The carets (^) in the above list signify continuation. When using it as above, the caret must be followed by a space -- thus the blank space at the beginning of the following line. If the space is missing the batch file will fail.

:: list of files to be copied from TNG root back to support folder
SET rootlist=^
 mod2data.php^
 mod2fetch.php^
 mod2_mysql.php^
 mod2_mysqli.php^
 mod2_upgrade.php

:: files to be copied from /css back to support folder/css
SET css=%root%\css
SET csslist=mod2.css

:: files to be copied from /js back to support folder/js
SET js=%root%\js
SET jslist=mod2.js mod2_ajax.js

:: files to be copied from /languages/Language back to support folder/Language
SET languages=%root%\languages
SET langlist=English English-UTF8 German German-UTF8
SET langfiles=mod2_text.php

Note that the batchfile does not delete or "uninstall" any deployed files.

More Parameters

We need to create a date-time stamp to use as an edit (build) number in our destination paths

:: create timestamp for archived folders
SET HOUR=%time:~0,2%
SET dtStamp9=A%date:~-2%.%date:~4,2%.%date:~7,2%.0%time:~1,1%%time:~3,2%%time:~6,2%
SET dtStamp24=A%date:~-2%.%date:~4,2%.%date:~7,2%.%time:~0,2%%time:~3,2%%time:~6,2%
if "%HOUR:~0,1%" == " " (SET dtStamp=%dtStamp9%) else (SET dtStamp=%dtStamp24%)

:: set destination paths for the file and zip archives
SET archive=D:\Archives\%modname%\%version%\%dtStamp%\%modname%
SET zipsrc=%archive%
SET ziparc=D:\Archives\%folder%\%version%\%dtStamp%\%modname%_%version%.zip

Options Menu

User Instructions

Provide last minute reminders

cls
echo.
echo %modname% %version%
echo.
echo PLEASE READ THIS CHECKLIST FIRST!!!
echo.
echo * TEST on all versions of TNG and PHP
echo * UPDATE version NUMBER AND DATE in version.php
echo * TURN OFF debug mode in all scripts
echo * RESTORE mod2_config.php to default values
echo * REMOVE log and error files
echo.

The Menu

:menu
echo.
echo Options (defaults to all)
echo ===========================
echo.
if "%supported%"=="0" goto L1
echo R) Recover deployed files
:L1
echo A) Archive master copy
echo D) Deploy to test sites only
echo E) Exit without processing
echo.
SET /p job=Select:
echo.
IF "%supported%"=="0" goto L2
IF "%job%"=="r" echo Recover & goto Recover
IF "%job%"=="R" echo Recover & goto Recover
:L2
IF "%job%"=="a" echo Archive & goto Archive
IF "%job%"=="A" echo Archive & goto Archive
IF "%job%"=="d" echo Distro & goto Distro
IF "%job%"=="D" echo Distro & goto Distro
IF "%job%"=="e" goto Done
IF "%job%"=="E" goto Done
IF "%job%"=="" echo Process All & goto Recover
GOTO menu

If a mod does not include a support folder, the Recover (deployed files) option is not offered. Batch files use a leading single colon to designate a label, a point to which processing will jump using the GOTO keyword, skipping over any code in between. On this menu, if the user enters a "d", processing will skip Recover and Archive and go straight to Distro to copy the mod to the listed test sites.

Recover Deployed Files

This section only executes if the mod has a support folder. It uses the deployment lists defined earlier to recover files back to the support folder. ROBOCOPY syntax can be found online. It is primarily a DOS folder copy utility, but it will copy individual files if you ask nicely. If the source file is the same as the destination file, it will not be copied.

:Recover
if "%supported%"=="0" goto Archive
::=========================================================
:: Recover deployed mod files back to master mod support
::    folder per the deployed file lists (R)
::=========================================================
echo.
echo RECOVERING EDITS TO DEPLOYED FILES ...
echo.
IF "%supported"=="0" goto EndRecover

(FOR %%a in (%rootlist%) do (
   echo %root%\%%a
   echo %modpack%\%%a
   ROBOCOPY %root% %modpack% %%a > nul
   CALL :ERRORCHECK
))

(FOR %%a in (%csslist%) do (
   echo %css%\%%a
   echo %modpack%\css\%%a
   ROBOCOPY %css% %modpack%\css %%a > nul
   CALL :ERRORCHECK
))

(FOR %%a in (%jslist%) do (
   echo %js%\%%a
   echo %modpack%\js\%%a
   ROBOCOPY %js% %modpack%\js %%a > nul
   CALL :ERRORCHECK
))

(FOR %%a in (%langlist%) do (
   echo %languages%\%%a
   echo %modpack%\%%a
   ROBOCOPY %languages%\%%a %modpack%\%%a %langfiles% > nul
   CALL :ERRORCHECK
))
:EndRecover

IF "%job%"=="r" goto Done
IF "%job%"=="R" goto Done

Archive the Mod

:Archive
::=========================================================
:: Save config file to stamped versions folder (A)
::=========================================================
echo.
echo ARCHIVING MOD CFG FILE ...
echo.
echo %mods%\%modname%_%version%.cfg
echo %archive%\%modname%_%version%.cfg
ROBOCOPY %mods% %archive% %modname%_%version%.cfg > nul
CALL :ERRORCHECK
:: if there is no mod support folder then we're finished
IF "%supported%"=="0" goto EndArchive

Archive Mod Support Folder


::=========================================================
:: Save mod support folder to archive (A)
::=========================================================
echo.
echo ARCHIVING MOD SUPPORT FOLDER ...
echo.
echo %modpack%
echo %archive%
ROBOCOPY %modpack% %archive% /S > nul
CALL :ERRORCHECK

:EndArchive

Create Zip Archive

::========================================================================
:: ZIP UP THE ARCHIVED PACKAGE
::========================================================================
7za a -tzip %ziparc% %zipsrc%
IF "%job%"=="a" goto Done
IF "%job%"=="A" goto Done

Copy Mod to Other Test Sites

:Distro
::=========================================================
:: Deploy master to other test sites per the site list (D)
::=========================================================
echo.
echo DEPLOYING MOD CFG TO SELECTED TEST SITES ...
echo.
(FOR %%a in (%sitelist%) do (
   echo %mods%\%modname%_%version%.cfg
   echo %%a\%modname%_%version%.cfg
   ROBOCOPY %mods% %%a %modname%_%version%.cfg > nul
   CALL :ERRORCHECK
))
IF "%supported%"=="0" goto Done

echo.
echo DEPLOYING MOD SUPPORT FOLDER TO SELECTED TEST SITES ...
echo.
(FOR %%a in (%sitelist%) do (
   echo.
   echo %modpack%
   echo %%a\%modname%_%version%
   ROBOCOPY %modpack% %%a\%modname%_%version% /S > nul
   CALL :ERRORCHECK
   echo.
))

goto Done

Error Checking

::=========================================================
:: ErrorCheck Function
::=========================================================
:ERRORCHECK
if %ERRORLEVEL% EQU 16 ECHO ***FATAL ERROR*** & goto done
if %ERRORLEVEL% EQU 15 ECHO OKCOPY + FAIL + MISMATCHES + XTRA & goto done
if %ERRORLEVEL% EQU 14 ECHO FAIL + MISMATCHES + XTRA & goto done
if %ERRORLEVEL% EQU 13 ECHO OKCOPY + FAIL + MISMATCHES & goto done
if %ERRORLEVEL% EQU 12 ECHO FAIL + MISMATCHES& goto done
if %ERRORLEVEL% EQU 11 ECHO OKCOPY + FAIL + XTRA & goto done
if %ERRORLEVEL% EQU 10 ECHO FAIL + XTRA & goto done
if %ERRORLEVEL% EQU 9 ECHO OKCOPY + FAIL & goto done
if %ERRORLEVEL% EQU 8 ECHO FAIL & goto done
if %ERRORLEVEL% EQU 7 ECHO OKCOPY + MISMATCHES + XTRA & goto done
if %ERRORLEVEL% EQU 6 ECHO MISMATCHES + XTRA & goto done
if %ERRORLEVEL% EQU 5 ECHO OKCOPY + MISMATCHES & goto done
if %ERRORLEVEL% EQU 4 ECHO MISMATCHES & goto done
if %ERRORLEVEL% EQU 3 ECHO OKCOPY + XTRA & goto done
if %ERRORLEVEL% EQU 2 ECHO XTRA & goto done
if %ERRORLEVEL% EQU 1 ECHO Copied!
if %ERRORLEVEL% EQU 0 ECHO Not copied -- files were the same!
echo.
GOTO :EOF

:Done
echo Done!
pause

Show Session

Create a simple PHP file to display the contents of the current session. Name the file show_session.php, place it in the www folder and invoke it with a browser bookmark -- localhost/show_session.php.

session_start();
foreach ($_SESSION as $key => $val) {
   echo "$key = $val";
   echo "<br />";
}

Clear Session

Create a simple PHP file to clear the contents of the current session. With the Multisite setup, there is only one common session open, no matter which test site you are exploring. Older versions of TNG create different session variables than newer versions. Normally that would not be a problem, but for debugging mods, you will sometimes want a clean, version-specific session, so use this as a bookmarked URL (localhost/clear_session.php) to clear the session before calling up the home page to test your mod.

session_start();
  foreach( $_SESSION as $key => $value ) {
    unset( $_SESSION[$key] );
  }
  echo "Done!";