A computer engineer poking at your cerebral cortex.

Unittest for linux sys admin in python

I always like to program in python so I can program in classes and then simply call the shell. Both os.system(“”) & commands.getoutput(“”) has been replace but for now I leave this for backwards compatibility. See More Reading at the bottom of post for os.system(“”) replacement. I will add a new user to a linux machine with command:

useradd -m -s /bin/bash topDog

Python code to add user:

#!/usr/bin/env python
 
import os
import sys
 
def runCommand(command):
  status = os.system(command)
  if status <> 0:
    print "Command has Failed: " + command
    sys.exit()
  else:
    print "Successful command: " + command
 
def addUser(user):
  runCommand("useradd -m -s /bin/bash " + user)
 
addUser("topDog")

output:

Successful command: useradd -m -s /bin/bash topDog

Now for the unit test. Many times you just see unit test example that will call a class, call this method, make sure variable x matches x. I don’t do this here for system admin tasks. I add tests based on changes on the linux operating system level. For example my test will include: test /etc/passwd file for entry of topDog, test /etc/group file for entry of topDog, make sure /home/topDog directory exists, and I even go one step further to make sure this user has the right shell. I hate when I log into an account and it isn’t bash. Tab completion is our friend!

#!/usr/bin/env python
 
import unittest
import commands
import os
 
class default(unittest.TestCase):
 
  def test_passwdFile(self):
    command = "grep 'topDog' /etc/passwd | wc -l "
    self.assertEqual("1", commands.getoutput(command))
 
  def test_groupFile(self):
    command = "grep 'topDog' /etc/group  | wc -l "
    self.assertEqual("1", commands.getoutput(command))
 
  def test_directory(self):
    self.assertEqual(True, os.path.isdir('/home/topDog/'))
 
  def test_shell(self):
    command = "grep 'topDog' /etc/passwd | grep 'bash' | wc -l "
    self.assertEqual("1", commands.getoutput(command))
 
if __name__ == '__main__':
    unittest.main()

output:

./testAddUser.py 
....
----------------------------------------------------------------------
Ran 4 tests in 0.004s
 
OK

Here is another example to test a specific line in a file with head instead of grepping for the whole phrase or text.

#!/usr/bin/env python
 
import unittest
import commands
import os
import sys
 
class default(unittest.TestCase):
 
  def test_line(self):
    command = "head -n 5 /home/ubuntu/test.xml | grep myDatabaseServer | wc -l "
    self.assertEqual("1", commands.getoutput(command))
 
if __name__ == '__main__':
    unittest.main()

More reading:
python unittest
python os module
python subprocess module