Thursday, December 3, 2009

Use one keyboard and mouse on multiple cross platform computers



synergy: [noun] a mutually advantageous conjunction of distinct elements

Synergy lets you easily share a single mouse and keyboard between multiple computers with different operating systems, each with its own display, without special hardware. Redirecting the mouse and keyboard is as simple as moving the mouse off the edge of your screen. Synergy also merges the clipboards of all the systems into one, allowing cut-and-paste between systems.

I have this old computer that as use as a backup and multimedia server. I have hooked it to an overhead projector and a decent sound system, now you know what I am up to over the weekends. For all this time ssh and Remote Desktop Viewer have served me very faithully. But I started wondering is this it, can I use my mouse and keyboard on both machines but on different displays, and lo and behold, ladies and gentlemen I present to you Synergy.
So lets get to it.

Scenario

There is a Dell (Inspiron 1520) aka WorkStation, running Ubuntu 9.10 also the Synergy server and as a second machine, home built server aka Storage running Ubuntu 8.04LTS.
WorkStation: Side [left] | Hostname [feruzi.trilabs.co.tz] | IP Address [192.168.3.10]
Storage: Side [right] | Hostname [storage.trilabs.co.tz] | IP Address [192.168.3.9]

Installing from the Command Line

Start the terminal (you can also use Synaptic Package Manager) and run the following command on both machines.
$ sudo aptitude update && sudo aptitude install synergy
PLEASE NOTE: For MS Windows and MacOS users visit the site for more information.

Configuring the Synergy server

In your home directory create a file called
synergy.conf
and in in it is where the configureation for my set up.
section: screens
 feruzi.trilabs.co.tz:       
 storage.trilabs.co.tz:
end
section: aliases
 feruzi.trilabs.co.tz:
    192.168.3.10
 storage.trilabs.co.tz:
    192.168.3.9
end
section: links
 feruzi.trilabs.co.tz:
    right = storage.trilabs.co.tz
 storage.trilabs.co.tz:
    left = feruzi.trilabs.co.tz
end
section: options
 screenSaverSync = false 
end

section: screens

Screen section is a list of screen names, one name per line, each followed by a colon. Names are arbitrary strings but they must be unique. The hostname of each computer is recommended, and that is what I have used.

section: aliases

aliases section is a list of screen names just like in the screens section except each screen is followed by a list of aliases, one per line, not followed by a colon. An alias is a screen name and must be unique. During screen name lookup each alias is equivalent to the screen name it aliases. Because my DNS was not setup properly I assigned it to my IP address.

section: links

links section is a list of screen names just like in the screens section except each screen is followed by a list of links, one per line. Each link has the form {left|right|up|down}[] = name[]. A link indicates which screen is adjacent in the given direction. So on the right of feruzi.trilabs.co.tz there is storage.trilabs.co.tz and on the left of storage.trilabs.co.tz there is feruzi.trilabs.co.tz.
PLEASE NOTE: There is more you can do here, again visit the site for more information.

section: options

options section is a list of lines of the form name = value. These set the global options. There is a lot of other options you can set, visit the site for more information.

Starting up Synergy server and clients


To start up the server, on feruzi.trilabs.co.tz run the following command,
$ synergys -f --config synergy.conf
the output should be something like this, depending on your setting and operating systems.
INFO: synergys.cpp,1042: Synergy server 1.3.1 on Linux 2.6.31-15-generic #50-Ubuntu SMP Tue Nov 10 14:54:29 UTC 2009 i686
DEBUG: synergys.cpp,1051: opening configuration "synergy.conf"
DEBUG: synergys.cpp,1062: configuration read successfully
DEBUG: CXWindowsScreen.cpp,847: XOpenDisplay(":0.0")
DEBUG: CXWindowsScreenSaver.cpp,339: xscreensaver window: 0x00000000
DEBUG: CXWindowsScreen.cpp,117: screen shape: 0,0 1280x800 
DEBUG: CXWindowsScreen.cpp,118: window is 0x04800004
DEBUG: CScreen.cpp,38: opened display
DEBUG: CXWindowsScreen.cpp,679: registered hotkey ScrollLock (id=ef14 mask=0000) as id=1
NOTE: synergys.cpp,500: started server
INFO: CServer.cpp,1141: screen "feruzi" shape changed

And the cliet, in this case on storage.trilabs.co.tz, ssh into the client machine and run the following command and we are ready to rumble.
$ synergyc -f --name storage 192.168.3.10
the output should be something like this, depending on your setting and operating systems.
INFO: synergyc.cpp,716: Synergy client 1.3.1 on Linux 2.6.27-15-generic #1 SMP Tue Oct 20 06:52:09 UTC 2009 i686
DEBUG: CXWindowsScreen.cpp,841: XOpenDisplay(":0.0")
DEBUG: CXWindowsScreenSaver.cpp,339: xscreensaver window: 0x00000000
DEBUG: CXWindowsScreen.cpp,111: screen shape: 0,0 1400x1050 
DEBUG: CXWindowsScreen.cpp,112: window is 0x03000004
DEBUG: CScreen.cpp,38: opened display
NOTE: synergyc.cpp,330: started client
DEBUG: CXWindowsClipboard.cpp,313: open clipboard 0
DEBUG: CXWindowsClipboard.cpp,266: empty clipboard 0
DEBUG: CXWindowsClipboard.cpp,289: grabbed clipboard 0
DEBUG: CXWindowsClipboard.cpp,348: close clipboard 0
DEBUG: CXWindowsClipboard.cpp,313: open clipboard 1
DEBUG: CXWindowsClipboard.cpp,266: empty clipboard 1
DEBUG: CXWindowsClipboard.cpp,289: grabbed clipboard 1
DEBUG: CXWindowsClipboard.cpp,348: close clipboard 1
NOTE: synergyc.cpp,247: connected to server

And that is it. Have fun, questions and comments are welcome.

Saturday, November 28, 2009

Google's Go - a systems programming language



November 10, Google release it's  new systems programming language called Go.  According to the website http://golang.org Go has the following outstanding features:-

  • simple in term of programming syntax, less typing
  • fast  compilers produce fast code fast. Typical Go builds take a fraction of a second yet the resulting programs run nearly as quickly as comparable C or C++ code.
  • safe in type safe and memory safe. Go has pointers but no pointer arithmetic. For random access, use slices, which know their limits.
  • concurrent is a core part of the language. Go promotes writing systems and servers as sets of lightweight communicating processes, called goroutines, with strong support from the language. Run thousands of goroutines if you want—and say good-bye to stack overflows.
  • fun to work with. Go has fast builds, clean syntax, garbage collection, methods for any type, and run-time reflection. It feels like a dynamic language but has the speed and safety of a static language. It's a joy to use
  • open source, Go is realised under the BSD licence.

After watching a video on Google TechTalk by one of the archtechts of the language, I thought of giving a try. I have installed it on my Ubuntu, with no difficulty at all, and have done a few example. I have not done anything worth showing, but during the course I will blog more about it.

Visit their site,http://golang.org, and see if you can make use of this language.

Introduction to TDD with PHPUnit


What is TDD?

Test Drive Development [TDD] is an approach to development which combines test-first development where you write a test before you write just enough production code to fulfill that test and refactoring. So basically you first decide the functions or sections of your code you want to test. Then write test for these functions for different scenarios with expected values. Then write the implement the functions while checking if they meet the different scenarios you captured in the tests, if not refactoring is done till all tests have passed.

Why use TDD?

  • by focusing on the different test cases first, developer(s) focuses on the functionality more than the implementation
  • it allows the developer to focus on a small section of the implementations at a time till its working as expected
  • can lead to more modularized, flexible, and extensible code
  • no more code is written than necessary to pass a failing test case, automated tests tend to cover every code path
  • while it is true that more code is required with TDD than without TDD because of the unit test code, total code implementation time is typically shorter

TDD Example with PHP

There are many ways in which one can implement a TDD. In this example, we will create a simple calculator with the four basic operations that is (add, subtract, multiply and divide).
But after looking around and looking back to my exprience, it looks like there is one way that most developers agree on:-
  1. design your class/API
  2. create a test suite
  3. run the test, and in this case all tests should fail
  4. implement the class
  5. run the test, an this time some test will pass and some will fail
  6. fix failures or errors
  7. repeat 5 and 6 till all tests have passed

Download Source Code

Designing the class/API

This basically mean designing the skeleton of the class, so the class body with its functions signatures without the actually implementation
/* === calculator.php === */
class Calculator{
/**
* Constructor
* NOTE: if you are using function __constructor() can also be used for older version of PHP
* @return unknown_type
*/
function Calculator(){

}

/**
* add two numbers (a + b)
* @param $a an integer
* @param $b an integer
* @return a + b or null otherwise
*/
function add($a, $b){

}

/**
* subtact b from a numbers (a - b)
* @param $a an integer
* @param $b an integer
* @return a - b or null otherwise
*/
function subtract($a, $b){

}

/**
* multipy a and b numbers (a x b)
* @param $a an integer
* @param $b an integer
* @return a x b or null otherwise
*/
function  multiply($a, $b){

}

/**
* divide a by b numbers (a / b)
* @param $a an integer
* @param $b an integer
* @return a / b or null otherwise
*/
function  multiply($a, $b){

}
}

Creating the test class

To test a function there is two (or more depending on the test used) things that are  needed, value returned by the function and the values expected. Then using a once of the many assert functions to establish if the test has passed or not. Look at the comments on the code.

/* === calculatortest.php === */
require_once 'calculator.php';
require_once 'PHPUnit.php';

class CalculatorTest extends PHPUnit_TestCase{
 /**
  * Constructor
  * NOTE: if you are using function __constructor() can also be used for older version of PHP
  * @return unknown_type
  */
 var $calc;

 function CalculatorTest($name){
  $this->PHPUnit_TestCase($name);
 }

 /**
  * Used to set up and default values
  *
  * (non-PHPdoc)
  * @see PHPUnit/PHPUnit_TestCase#setUp()
  */
 function setUp(){
  // creating the Calculator object
  $this->calc = new Calculator();
 }

 /**
  * Used to destroy values that where set in the setUp()
  *
  * (non-PHPdoc)
  * @see PHPUnit/PHPUnit_TestCase#tearDown()
  */
 function tearDown(){
  // destroying the  calculator object 
  unset($this->calc);
 }

 /**
  * Testing add two numbers (a + b)
  */
 function testAdd(){
  $actual = $this->calc->add(2,3);
  $expected = 5;
  //checking if value returned value is what we expected
  $this->assertEquals($expected, $actual);
 }

 /**
  * Testing subtact b from a numbers (a - b)
  */
 function testSubtract(){
  $actual = $this->calc->subtract(5,2);
  $expected = 3;
  //checking if value returned value is what we expected
  $this->assertEquals($expected, $actual);
 }

 /**
  * Testing multipy a and b numbers (a x b)
  */
 function  testMultiply(){
  $actual = $this->calc->multiply(5,2);
  $expected = 10;
  //checking if value returned value is what we expected
  $this->assertEquals($expected, $actual);
 }

 /**
  * Testing divide a by b numbers where b=0
  */
 function  testDivideByZero(){
  $actual = $this->calc->divide(3,0);
  $expected = NULL;
  //checking if value returned value is what we expected
  $this->assertEquals($expected, $actual);
 }

 /**
  * Testing divide a by b numbers (a / b)
  */
 function  testDivide(){
  $actual = $this->calc->divide(10,2);
  $expected = 5;
  //checking if value returned value is what we expected
  $this->assertEquals($expected, $actual);
 }
}

Write the Testing

Now we need to write the code to actual run the code
/* ==== test.php ==== */

require_once 'calculatortest.php';
require_once 'PHPUnit.php';

/* the value passed duing the instantiating must be the name of the test class */
$suite  = new PHPUnit_TestSuite("CalculatorTest");
/*rin the test*/
$result = PHPUnit::run($suite);
/*dispay the result */
echo $result->toString();

Running the test

Start up your terminal and run the test.php with php or if run it through your apache and view the result on the browser
eferuzi@feruzi /v/w/phpunit> php5 test.php
TestCase CalculatorTest->testDivideByZero() passed
TestCase CalculatorTest->testAdd() failed: expected 5, actual  in /var/www/phpunit/calculatortest.php:56
TestCase CalculatorTest->testSubtract() failed: expected 3, actual  in /var/www/phpunit/calculatortest.php:66
TestCase CalculatorTest->testMultiply() failed: expected 10, actual  in /var/www/phpunit/calculatortest.php:76
TestCase CalculatorTest->testDivide() failed: expected 5, actual  in /var/www/phpunit/calculatortest.php:96
As you can see we have one passing because the functions are not returning anything at the moment and that test checks if NULL is returned.

Implementations of the Calculator

So now we add implementation into the functions in the Calculator class

/* === calculatortest.php === */


require_once 'calculator.php';
require_once 'PHPUnit.php';

class CalculatorTest extends PHPUnit_TestCase{
 /**
  * Constructor
  * NOTE: if you are using function __constructor() can also be used for older version of PHP
  * @return unknown_type
  */
 var $calc;

 function CalculatorTest($name){
  $this->PHPUnit_TestCase($name);
 }

 /**
  * Used to set up and default values
  *
  * (non-PHPdoc)
  * @see PHPUnit/PHPUnit_TestCase#setUp()
  */
 function setUp(){
  // creating the Calculator object
  $this->calc = new Calculator();
 }

 /**
  * Used to destroy values that where set in the setUp()
  *
  * (non-PHPdoc)
  * @see PHPUnit/PHPUnit_TestCase#tearDown()
  */
 function tearDown(){
  // destroying the  calculator object
  unset($this->calc);
 }

 /**
  * Testing add two numbers (a + b)
  */
 function testAdd(){
  $actual = $this->calc->add(2,3);
  $expected = 5;
  //checking if value returned value is what we expected
  $this->assertEquals($expected, $actual);
 }

 /**
  * Testing the add method with wrong or none numerical input
  */
 function testAddInvalidValues(){
  $actual = $this->calc->add('ugali',3);
  //checking if value returned value is what we expected
  $this->assertNull($actual);
 }


 /**
  * Testing subtact b from a numbers (a - b)
  */
 function testSubtract(){
  $actual = $this->calc->subtract(5,2);
  $expected = 3;
  //checking if value returned value is what we expected
  $this->assertEquals($expected, $actual);
 }

 /**
  * Testing multipy a and b numbers (a x b)
  */
 function  testMultiply(){
  $actual = $this->calc->multiply(5,2);
  $expected = 10;
  //checking if value returned value is what we expected
  $this->assertEquals($expected, $actual);
 }

 /**
  * Testing divide a by b numbers where b=0
  */
 function  testDivideByZero(){
  $actual = $this->calc->divide(3,0);
  $expected = NULL;
  //checking if value returned value is what we expected
  $this->assertEquals($expected, $actual);
 }

 /**
  * Testing divide a by b numbers (a / b)
  */
 function  testDivide(){
  $actual = $this->calc->divide(10,2);
  $expected = 5;
  //checking if value returned value is what we expected
  $this->assertEquals($expected, $actual);
 }

Re-run the test

Re-run the test again and this time you should see some more passes if not refactor your code till you get all passes.

eferuzi@feruzi /v/w/phpunit> php5 test.php
TestCase CalculatorTest->testAdd() passed
TestCase CalculatorTest->testAddInvalidValues() passed
TestCase CalculatorTest->testSubtract() passed
TestCase CalculatorTest->testMultiply() passed
TestCase CalculatorTest->testDivideByZero() passed
TestCase CalculatorTest->testDivide() passed

Download Source Code

More information:-

  • TDD:
    • http://en.wikipedia.org/wiki/Test-driven_development
    • http://www.extremeprogramming.org/rules.html
  • PHPUnit:
    • http://www.phpunit.de/
Do not hesitate to ask me questions.

Sunday, November 22, 2009

kiGM : A Terminology Tool




To explain kiGM one has to start with GlossMasterGlossMaster is the fabulous multi-lingual terminology tool developed for ANLoc, the African Network for Localization. kiGM is a very lightweght version GlossMaster with an aim of allowing user with low or no internet connection to work and sycn data with GlossMaster periodically.GlossMaster. kiGM has a verys small subset of the functionality that Glossmaster.

Please come in and help.


Monday, October 5, 2009

Backup with mysqldump with PHP

Have you ever wanted to create a script a script that will create a mysqldump of a database using PHP? Here is a good starting point. More can be done to extend this to make it more useful, things like emailing the dump, restoring the database on fly and so much more.

There is a minor difference between the script for a server running on MS Windows as compate to the Linux/UNIX

MS Windows: XAMMP or WAMP

/* variable declaration */
$db_user = "yourUsername";
$db_password = "yourPassword";
$db_database = "yourDatabaseName";
$db_server = "yourHostName"; //default: localhost
$backup_path = "C:\\path\\to\\backup\\folder\\";
//e.g $backup_path = "C:\\backups\\sqldumps\\";
$path_to_mysqldump = "C:\\path\\to\\mysql\\bin\\";
//e.g $path_to_mysqldump = "C:\\xampp\\mysql\\bin\\";
$filename = "backup".date("YmdHis").".sql"; //filename with a timestamp

/*construction the command to be run */
$command= "$path_to_mysqldump\\mysqldump.exe --add-drop-table --add-drop-database -h $db_server -u $db_user --password=$db_password $db_database > $filename ";

/* excution of the command */ 
exec($command, $dump, $status); 

/*checking the status of the command after runing */
if($status!=0){
echo "The execution was not successful. An empty file has been created";
}else{
echo "The execution was successful. Backup files is " . $backup_path.$filename ;
}

Linux/UNIX
* variable declaration */
$db_user = "yourUsername";
$db_password = "yourPassword";
$db_database = "yourDatabaseName";
$db_server = "yourHostName"; //default: localhost
$backup_path = "/path/to/backup/folder/"; //you must have permission to write in this folder
//e.g $backup_path = "/servers/backups/sqldumps/"; 
$filename = $backup_path."backup".date("YmdHis").".sql"; //filename with a timestamp

/*construction the command to be run */
$command= "mysqldump.exe --add-drop-table --add-drop-database -h $db_server -u $db_user --password=$db_password $db_database > $filename ";

/* excution of the command */ 
exec($command, $dump, $status); 

/*checking the status of the command after runing */
if($status!=0){
echo "The execution was not successful. An empty file has been created";
}else{
echo "The execution was successful. Backup files is " . $backup_path.$filename ;
}

Differences highlighted:
  • in windows it, unless you have added the mysql bin to the path, you must specify the full path to the mysqldump.exe, as in Linux it accessible with out the full path
  • also the \\ used in the path, as in Linux we use /
  • in Linux remember you mush have write asses to the folder you are