Implement a battery of unit tests for SSSD

Introduction

An idea of implementing a battery of unit tests for SSSD(System Service Security Daemon) using cmocka unit test framework is proposed after having a thorough discussion with the SSSD upstream maintainer jhrozek (Jakub Hrozek, #sssd). Actually, it is not just writing better automated test codes but a total refinement of SSSD unit-tests using the cmocka unit testing framework in such a way that it will reduce complexity of unit testing code and making it efficient and provide a good mocking framework for better testing for other developers. Following are the details of the project and the proposed plan of action.

Abstract

Implementing unit tests for SSSD modules using cmocka unit testing framework with proper refactoring, minimum boilerplates and better test coverage. The tests would focus on both covering the new features but mostly on creating test for the core SSSD features, providing developers with better confidence when writing new code

Benefits to Fedora community

  • Contributing the set of unit tests to the SSSD would greatly improve its stability long-term and would help raise confidence when pushing new SSSD versions into Fedora or other distributions.
  • Making SSSD tests less complicated and mock-based unittesting framework would certainly result into an improved testing mechanism and error handling in SSSD.
  • Improvement in the test coverage will result in improvement of code quality of the SSSD.
  • Writing unit-test will help in deeper confidence in the correct behaviour of SSSD code and eventually result in easier resolution of many of the issuses related to SSSD

Project Details

The aim of the project is not just quality assurance of SSSD but to provide a proper implementation of a Unit testing framework rather than just a proof-of-concept. It has far greater goals. SSSD is an important part of the authentication picture for Fedora and other Linux distributions. Unfortunately the current version of SSSD lacks proper unit testing framework for exercising the code which are only reachable when SSSD is connected to the network. This project deals more about writing new tests based on the cmocka framweork and complete refinement of old written SSSD tests using the check framework. The idea here is to dig deeper into testing to provide and maintain long-term robustness and quality of SSSD. It is also important that the new cmocka based tests should be less complex and more efficient. It should have more automated behavior and minimum or no boilerplate code. It should also the coding style set by SSSD coding guidelines.

The other important feature of the framework should be that it should be sustainable long-term in order to support further SSSD improvements. In other words, the tests must be easy to modify when the core SSSD code changes to minimize the time needed to fix the unit tests after architectural changes are performed to the SSSD. This feature would allow the SSSD developers to be more confident of refactoring changes in the daemon itself.

Tools Required During Development

  • the Talloc and Tevent libraries
  • Cmocka library
  • Coverage tool : lcov
  • Vim (IDE)

 

The outline of my work plans

The initial stage of my work deals with becoming familiar with SSSD and learning concepts of cmocka unit-testing framework as mentioned in plan.

The general idea for the unit tests is to cover the two most important parts:

  • retrieving user information
  • authenticating users.

The following diagram gives a pictorial representation of the core components of SSSD and how they interact. Sssdsoc.png
Basically the whole project is divided into two phases, which mimick how the SSSD itself is structured:

  • Phase I : building provider tests
  • Phase II: building responder tests

Because of the large size of the SSSD project, the unit testing framework would focus on the core SSSD features that are enabled in most, if not all, SSSD deployments. In particular, the unit tests would cover only the NSS and PAM responders, while the back end (provider) tests would cover the LDAP users and group code.

Time-line for Milestones

The project is planned to be split across following weekly phases:

[Project Week 1]

Learning the tevent library and the asynchronous model

[Project Week 2]

Learning the tevent library and the async model. Might include some experimenting and reading the code.

[Project Week 3]

Reading the current NSS responder test and augmenting the “get user by name/ID tests”

[Project Week 4]

Adding a similar test for retrieving groups as added for users in the previous step.

[Project Week 5]

Adding another test for the initgroups operation.

[Project Week 6]

Studying the PAM responder code.

[Project Week 7]

Adding a unit test that would cover the PAM responder. Only login (PAM authentication phase) can be covered.

[Project Week 8]

Learning the backend and provider internals. The current DNS update tests might be a good start.

[Project Week 9]

Creating unit tests for retrieving LDAP users. These tests would not be big by themselves, but would include code to be reused by other LDAP tests later

[Project Week 10]

Creating unit tests for storing LDAP groups without nesting (RFC2307)

[Project Week 11]

Creating unit tests for storing LDAP groups with nesting (RFC2307bis)

[Project Week 12]

An extra week to polish the work before submission

Deliverables

Better and improved test codes of SSSD with following features:

  • Tests covering NSS and PAM responders
  • Contribute to the overall code quality by uncovering issues with the unit tests
  • Less complex test infrastructure
  • More efficient testing mechanism

Unit Tests For Mozbase

Introduction

An idea of unit testing mozbase is proposed after having a good discussion with jhammel, jmaher, ctalbert (members of ateam). Actually, it is not just writing better automated test codes but a total refinement of mozbase unit-tests including unittesting framework in such a way that it will reduce complexity of code and will be efficient. Following are the details of the project and the proposed plan of action.

Abstract

Implementing unit tests for mozbase modules using unittest framework with proper refactoring, minimum boilerplates and better test coverage. Doing sanity checking, resulting in efficient test codes.

Benefits to Mozilla community

  • Implementation of mozbase tests with less complicated tests and Unittesting framework would certainly result into an improved testing mechanism and error handling in mozbase.
  • Improvement in the test coverage will result in improvement of code quality of mozbase.
  • A detailed documentation on the work to help the contributers for further improvements on the work.
  • Writing unit-test will help in deep extensibilty to the behaviour of mozbase code and eventually results in solving many of the issuses related to mozbase-testing on bug tracker

Project Details

The aim of the project is not just quality assurance of mozbase but to provide a proper implementation of Unit testing framework rather than just a POC(proof of concept). It has far greater goals. Mozbase is so important that all of Mozilla’s test harnesses use mozbase to some degree, including Talos, mochitest, reftest, Autophone, and Eideticker. But the Current version of mozbase lacks proper unit tests and has poor test coverage. This project deals more about writing new efficient tests and complete refinement of old written mozbase tests using unit testing. The idea here is to dug deeper into testing to provide and maintain robustness and quality of mozbase. It is also important that the new tests should be less complex and more efficient. It should have more automated behaviour and minimum or no boilerplates. It should also pass pep8 and pyflakes testing.

One other feature of the framework should be that it should be sustainable and support further improvements. It means that if the tests need to be implemented further because of addition or enhancement of new feature(s) or tests need to be modified after a year or something, only slight change in the fixers should be enough and an automated process would be taking care of implementation of respective fixers to the tests. Since, it would be quite troublesome to implement all the tests again and again with each new modification or new release of mozbase dependencies, this feature is quite necessary from development perspective.

Tools Required During Development

  • Python Unittesting framework
  • Coverage
  • Pep8
  • Pyflakes
  • Vim (IDE)

The outline of my work plans

Modules of the mozbase which will be tested are :

  • moznetwork
  • mozprocess
  • mozcrash
  • mozdevice
  • mozfile
  • mozhttpd
  • mozinfo
  • mozinstall
  • mozlog
  • manifestdestiny
  • mozb2g
  • mozprofile
  • mozrunner

These modules further consists of different submodules that will be unit tested.

Schedule of Deliverables

The project is planned to be split across following weekly phases:

[Test Week 1] Adding unit tests for mozinfo and moznetwork.

[Test Week 2] Writing tests for mozfile and mozhttpd

[Test Week 3] Tests cover sub-modules of mozprofile.

[Test Week 4] Continuation of tests for sub-modules of mozprofile

[Test Week 5] Creating tests for sub-modulese of mozprocess

[Test Week 6] Continuation of tests for sub-modules of mozprocess

[Test Week 7] Adding tests for mozB2g, mozcrash and mozinstall.

[Test Week 8] Writing tests for mozdestiny.

[Test Week 9] Test for mozrunner sub-modules.

[Test Week 10] Adding tests for mozdevice sub-modules.

[Test Week 11] Continuation week for mozdevice

[Test Week 12] Final week for mozdevice and to polish the work before submission

Deliverables

  • Tests covering mozdevice, mozprocess and other core modules of mozbase.
  • Contribute to the overall code quality by uncovering issues with the unit tests
  • Less complex test infrastructure
  • More efficient testing mechanism

Pytest : An Automation Testing Tool

Py.test is an alternative to unit test suite which provides more pythonic way of writing our tests. The overhead for creating unit tests is reduced almost to zero!

Jobs of Automated testing tools :

  • It verifies the code changes work outs.
  • Provides help when test fails, providing necessary details where and why the test failed.
  • It makes writing tests easy and fun.

Some fundamental features of Pytest are :

  • It’s cross project testing tool.
  • Provides useful information when tests fail.
  • no boiler plate (repetitive code) test code.
  • deep extensibilty
  • distribute tests to multiple hosts

Installing Pytest

$ pip install -U pytest       # or
$ easy_install -U pytest

Writing tests using pytest

In the previous post I showed how unittest test is used for testing by a taking a simple example of a calculator application.I am using the same example here to guide you thorough the basics of using pytest. Following is the code for calculator application.

# calculator.py

class Calculator:
    def add(self, x, y):
        return x + y

    def sub(self, x, y):
        return x - y

    def mul(self, x, y):
        return x * y

    def div(self, x, y):
        assert(y != 0);
        return x / y

The pytest code for this application is :


  # test_pytest_calculator.py

  class TestCalculator:
      def test_add(self, setup):
          cal = setup
          res = cal.add(10, 2)
          assert 12 == res

      def test_sub(self, setup):
          cal = setup
          res = cal.sub(7, 4)
          assert 3 == res

      def test_mul(self, setup):
          cal = setup
          res = cal.mul(5, 25)
          assert 125 == res

      def test_div(self, setup):
          cal = setup
          res = cal.div(20, 4)
          assert 5 == res

# conftest.py

from calculator import Calculator

def pytest_funcarg__setup(request):
    cal = Calculator()
    return cal

Now go to the command prompt in terminal and type the following command to run the test_calculator module

$ py.test test_calculator.py

for more verbose output use -v attribute.

$ py.test -v test_calculator.py

I am stopping myself here as am bit running out of time now.I will be updating this post soon with more topics showing skipping, expected to fail tests, marking a test and using some advanced plugins like Pep8, Pyflakes, codecheckers.
Happy Testing! cheers 🙂

Welcome back!

Here is an assert introspection for py.test


def test_assert_introspection():
    ''' with Unittest.py '''
    assert x        # assertTrue()
    assert x == 1   # assertEqual(x, 1)
    assert x != 2   # assertNotEqual(x, 2)
    assert not x    # assertFalse(x)

Marking Test functions/methods

py.test.mark.skipif(expression)                                    # for skipping tests

py.test.mark.xfail(expression)                                      # for expected to fail tests

py.test.mark.Name                                                          # use your own custom marking

Here is an example showing skipping test methods and xfail test methods:


# test_pytest_calculator.py
import py

class TestCalculator:
    def test_add(self, setup):
        cal = setup
        res = cal.add(10, 2)
        assert 12 == res

    @py.test.mark.skipif('True')
    def test_sub(self, setup):
        cal = setup
        res = cal.sub(7, 4)
        assert 3 == res

    @py.test.mark.xfail
    def test_mul(self, setup):
        cal = setup
        res = cal.mul(5, 25)
        assert 150 == res

    def test_div(self, setup):
        cal = setup
        res = cal.div(20, 4)
        assert 5 == res

Testing small project

Let’s do testing of a small scanner application which reads a file and looks for the url(s) present in the file and stores them in a separate list.
Following is the code for scanner application.


import urllib

class Scanner:
    def __init__(self, config):
        self.config = config

    def extract_urls(self, path):
        urls = []
        for line in path.readlines():
            line = line.strip()
            for urlprefix in self.config.urlprefixes:
                if line.startswith(urlprefix):
                    urls.append(line)
        return urls

and the py.test module for this application is :


import py
from myscan.scanner import Scanner

class config:
    pass

def test_extract_url(tmpdir):
    path=tmpdir.join('foo.ini')
    path.write("Testing Scanner\nhttp://pytest.org\nhttps://google.com\n")
    print path.read()
    con = config()
    con.urlprefixes = ['http://', 'https://']
    Scan = Scanner(con)
    urls = Scan.extract_urls(path)
    assert len(urls) == 2
    assert urls == ['http://pytest.org', 'https://google.com']

Some Advanced Plugins

py.test provides some important plugins, some of them which are most widely used are:

  • figleaf : It checks the test code coverage
  • codecheckers (pyflakes, pep8) : checks standardization of code, indentation, spacing etc and tells which of the modules where imported and not used etc to make code better.

Installing figleaf plugin

$ easy_install pytest-figleaf                       # or

$ pip install pytest-figleaf

Using figleaf plugin

$ py.test –figleaf test_module.py

Installing codecheckers plugin

$ easy_install pytest-codecheckers         # or

$ pip install pytest-codecheckers

Now let’s wind up this basic tutorial.Hope you all have enjoyed and will find testing interesting and fun.Happy testing! cheers 🙂

Unittest – Unit Testing Framework (Python)

Unit testing : It refers to the kind of testing where the tester refers to a small software module at a time and testing it in an isolated fashion.

Unittest supports test automation, sharing of setup and shutdown code for tests, aggregation of tests into collections, and independence of the tests from the reporting framework module.This module provides classes that make it easy to support these qualities for a set of tests.

Test Fixture : A test fixture is setting up well known and fixed environment in which tests are run so that to get a particular/expected  outcome.

A test is generally done in four phases.

Four Phases of a test are :

  • set up – It is used for setting up test fixture.
  • Exercise – interact with system under test.
  • verify – determine whether the expected outcome has been obtained.
  • Tear down – for cleanup of test fixture so that it returns to original state.

Note : Unit testing is a kind of white box testing.

Here I am giving a brief introduction  to unitttesting (python) so that those who wants to get started with software testing will find it interesting and easier.

I have taken a simple example of  a calculator application and will try to test it through unit testing frame work provided by unittest module in python.

# calculator.py

class Calculator:
def add(self, x, y):
return x + y

def sub(self, x, y):
return x - y

def mul(self, x, y):
return x * y

def div(self, x, y):
assert (y != 0)
        return x / y

The following is the unittest code for testing this calculator application.


# test_calculator.py

import unittest
from calculator import Calculator

class TestCalculator(unittest.TestCase):
def setUp(self):
self.cal = Calculator()

def test_add(self):
res = self.cal.add(10, 2)
self.assertEqual(12, res)

def test_sub(self):
res = self.cal.sub(7, 4)
self.assertEqual(3, res)

def test_mul(self):
res = self.cal.mul(5, 25)
self.assertEqual(125, res)

def test_div(self):
res = self.cal.div(20, 4)
self.assertEqual(5, res)

if __name__ == '__main__':
unittest.main()

In unittest framework we have to create a subclass of unittest TestCase as I have create in the above code. Here TestCalculator is the subclass of unittest TestCase class. The important thing to note here is that the name of the testcase class start with the word Test(i.e should follow this pattern ‘ Test*’ ) and the test methods name follows the pattern ‘ test* ‘. The methods test_add, test_sub, test_mul, test_div is used for testing add(), sub() , mul(), div() methods of Calculator class.Then setUp() method is used to create test fixture for the tests.

Skipping tests and Expected failures:

unittest provides methods for skipping test methods as well as test class and to mark a test as expected failures when we know that the test is going to fail.Here is an example code showing test skipping and expected failures.

# test_calculator.py

import unittest
from calculator import Calculator

class TestCalculator(unittest.TestCase):
def setUp(self):
self.cal = Calculator()

def test_add(self):
res = self.cal.add(10, 2)
self.assertEqual(12, res)

@unittest.skip("Demonstrating method skippping")
def test_sub(self):
res = self.cal.sub(7, 4)
self.assertEqual(12, res)

    @unittest.skipIf(2 > 0, "Demonstrating method skipping using skipIf")
def test_mul(self):
res = self.cal.mul(5, 25)
self.assertEqual(125, res)

@unittest.expectedFailure
def test_div(self):
res = self.cal.div(20, 4)
self.assertEqual(5, res)

if __name__ == '__main__':
unittest.main()

Get CPU information in Linux

It’s quite easy to get CPU information in Linux.Just open terminal and give the following command:

$ cat /proc/cpuinfo

Note : Presence of lm(Long mode) in flags indicate that the CPU is 64 bit whereas its absence indicates that it’s a 32 bit processor.

You can also use uname -i command  to know whether its a 32 bit or a 64 bit processor.

$ uname -i

It will say “i686” for 32bit and “x86_64” for 64bit.

Mounting a Pendrive

Manually Mounting a Pendrive :

At first whenever you encounter a Problem with USB devices,first check the latest debug information generated from kernel just after you plugin your device and/or just after you encounter the problem by using cmd as
$dmesg

Now run
$lsub                                                                                                              //to see list of usb devices
then
$sudo fdisk -l                                                                                                    //to see all attached storage devices and their partition

$sudo mkdir /media/external                                                                                      //creating mount point

$sudo mount -t vfat /dev/sdb1 /media/external -o uid=1000,gid=1000,utf8,dmask=027,fmask=137                     //The options following the “-o” allow your user to have ownership of the drive, and the masks allow for extra security for file system permissions. If you don’t use those extra options you may not be able to read and write the drive with your regular username.
or otherwise if the device is formatted with NTFS, run:

sudo mount -t ntfs-3g /dev/sdb1 /media/external

Troubleshooting:
1.Use ‘dmesg’ cmd to get necessary details.

2.Check for User Priviledge:
Go to System->Administration->User and Groups, choose the user, click on “Properties”, then go to the “User Privileges” tab. You should have the “Access external storage devices automatically” option checked.

3.Check Preferences:
If your usb device doesn’t appear on your desktop, you should check that the automount action is enabled in the preferences:
Navigate to “System” > “Preferences” > “Removable Drives and Media”
Verify that all “Mount removable drives when…” are checked.

Resetting My SQL password

For resetting mysql root passwd follow the following steps:

Step 1: Stop mysql service

/etc/init.d/mysql stop

Step 2: Start to mysql server w/o password

mysqld_safe –skip-grant-tables &

Step 3: Now connect to mysql server using mysql client

mysql -u root

Step 4: Setup new mysql root user password

mysql> use mysql;
     mysql> update user set password=PASSWORD(“sctfmysql”) where User=’root’;
     mysql> flush privileges;
     mysql> quit

Step 4: Stop mysql Server

/etc/init.d/mysql stop

Step 5:Start mysql server and test it

/etc/init.d/mysql start

mysql -u root -p

Step 6:It’s done 😀

Resetting root password in Linux using Backtrack

backtrack

Steps for resetting password of root to ‘sctfroot’ using backtrack.

Step1: Boot the backtrack cd and log in as root.

Step2: find the partition in which the linux is installed using cmd
$fdisk-l                                        //we are already loged in as root hence its not required to use sudo cmd anywhere.

Step3: suppose linux is installed in partition /dev/sda6 then make a directory name sda6 in mnt directory and mount that partition to it using following cmd(s)
$mkdir /mnt/sda6                             //make sda6 in mnt directory  
$mount /dev/sda6 /mnt/sda6

Step4: cd /mnt/sda6                                  //entering in sda6

Step4: change the permission of passwd file to 755
$chmod 755 passwd                             //check comments in step2

Step5: open passwd file
$vi /etc/passwd

Step6: Find root and delete the whatever is there in between the first ‘:’ and second ‘:’ and save the file.It will make the root password less.
root:x:0:0:root:/root:/bin/bash                //before

root::0:0:root:/root:/bin/bash               //after 

Step7: Now remove backtrack and restart the computer and open in grub mode(recovery mode) and you will find the root prompting at cmd line without asking for password.Now use passwd cmd to change passwd of root to sctfroot.

$passwd root
and type password as ‘sctfroot’ when it is asked.

Note: You can prevent him from hacking your sytem by setting a Bios password(so that he can’t access your system without cracking your bios password 😀 ).

Using Mutex to implement atomicity

/***********************************************************************
* OBJECTIVE : Implement atomicity in case of threads
* FILE NAME : mutex.c
* DATE      : 10-09-2012
* AUTHOR    : Abhishek Kumar Singh
************************************************************************/

#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<unistd.h>
#include<pthread.h>

/* Gobal data */
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int counter = 0;

void *increment(void *);

int main()
{
    pthread_t thread1,thread2;
    int iret1,iret2;

    /* Create two threads that executes independently and parallely */
    iret1 = pthread_create(&thread1,NULL,increment,NULL);
    iret2 = pthread_create(&thread2,NULL,increment,NULL);

    if(iret1 != 0)
        fprintf(stderr,"thread1 can't created");
    if(iret2 != 0 )
        fprintf(stderr,"thread2 can't be created");

    /* Waiting for the threads to terminate */
    pthread_join(thread1,NULL);
    pthread_join(thread2,NULL);

    return EXIT_SUCCESS;
}

void *increment(void *ptr)
{
    /* Locking Resources for other threads */
    pthread_mutex_lock(&mutex);
    counter ++;
    printf("counter:%d\n",counter);
    pthread_mutex_unlock(&mutex);
    /* Unlocking Resources so that other threads can acess */
    return NULL;
}

Cracking passwords using Jhon The Reaper

Download and Install John the reaper using

$ sudo apt-get install john

Cracking Linux password

being root run the following command:

$ /usr/bin/unshadow /etc/shadow /etc/passwd>/tmp/crackpass.db

Now being normal user run the following command

$ john /tmp/crackpass.db

It will take some time depending on the strength of password to crack it.

cracking MD5 passwords

$ john <passwdfile> –format MD5