Unittest for backup.py with coverage >= 90%

More Unittest needs to be implemented in Freezer.
The total coverage have to be at least 90%.
This commit is for freezer.backup unittest.

setup.py and tests directory re organized
according pytest best practices.

Change-Id: I61aa1b58d9501b81fda37dd785add27ba86d01c9
LAUNCHPAD: https://blueprints.launchpad.net/freezer/+spec/test-backup.py
This commit is contained in:
Fausto Marzi 2014-11-16 16:11:50 +00:00
parent bde16cbeb1
commit ce996d5bac
10 changed files with 3476 additions and 33 deletions

30
.coveragerc Normal file
View File

@ -0,0 +1,30 @@
# .coveragerc to control coverage.py
[run]
branch = True
[report]
# Regexes for lines to exclude from consideration
exclude_lines =
# Have to re-enable the standard pragma
pragma: no cover
# Don't complain about missing debug-only code:
def __repr__
if self\.debug
# Don't complain if tests don't hit defensive assertion code:
raise AssertionError
raise NotImplementedError
# Don't complain if non-runnable code isn't run:
if 0:
if __name__ == .__main__.:
ignore_errors = True
[paths]
source =
freezer/
[html]
directory = term

View File

@ -31,6 +31,7 @@ Requirements
- python-keystoneclient
- pymongo
- python-mysqldb
- libmysqlclient-dev
- At least 128 MB of memory reserved for Freezer
Installation & Env Setup
@ -52,7 +53,7 @@ MongoDB backup::
MySQL backup::
$ sudo apt-get install -y python-mysqldb
$ sudo apt-get install -y python-mysqldb libmysqlclient-dev
Freezer installation from Python package repo::

View File

@ -1,11 +0,0 @@
#!/usr/bin/env python
from freezer.arguments import backup_arguments
import pytest
import argparse
def test_backup_arguments():
backup_args, arg_parser = backup_arguments()
assert backup_args.tar_path is not False
assert backup_args.mode is ('fs' or 'mysql' or 'mongo')

View File

@ -1,16 +0,0 @@
#!/usr/bin/env python
from freezer.backup import (
backup_mode_mysql, backup_mode_fs, backup_mode_mongo)
from freezer.arguments import backup_arguments
import time
import os
def test_backup_mode_mysql():
# THE WHOLE TEST NEED TO BE CHANGED USING MOCK!!
# Return backup options and arguments
backup_args = backup_arguments()

3034
runtests.py Normal file

File diff suppressed because it is too large Load Diff

View File

@ -9,16 +9,22 @@ import os
here = os.path.abspath(os.path.dirname(__file__))
class PyTest(TestCommand):
user_options = [('pytest-args=', 'a', "Arguments to pass to py.test")]
def initialize_options(self):
TestCommand.initialize_options(self)
self.pytest_args = []
def finalize_options(self):
TestCommand.finalize_options(self)
self.test_args = []
self.test_suite = True
def run_tests(self):
#import here, cause outside the eggs aren't loaded
import pytest
errcode = pytest.main(self.test_args)
sys.exit(errcode)
errno = pytest.main(self.pytest_args)
sys.exit(errno)
def read(*filenames, **kwargs):
encoding = kwargs.get('encoding', 'utf-8')
@ -40,12 +46,14 @@ setup(
maintainer='Fausto Marzi, Ryszard Chojnacki, Emil Dimitrov',
maintainer_email='fausto.marzi@hp.com, ryszard@hp.com, edimitrov@hp.com',
tests_require=['pytest'],
description='''OpenStack incremental backup and restore automation tool for file system, MongoDB, MySQL. LVM snapshot and encryption support''',
description=('OpenStack incremental backup and restore automation tool '
'for file system, MongoDB, MySQL. LVM snapshot and '
'encryption support'),
long_description=open('README.rst').read(),
keywords="OpenStack Swift backup restore mongodb mysql lvm snapshot",
packages=find_packages(),
platforms='Linux, *BSD, OSX',
test_suite='freezer.test.test_freezer',
#test_suite='freezer.test.test_freezer',
cmdclass={'test': PyTest},
scripts=['bin/freezerc'],
classifiers=[

269
tests/commons.py Normal file
View File

@ -0,0 +1,269 @@
#!/usr/bin/env python
from freezer.backup import backup_mode_mysql, backup_mode_fs, backup_mode_mongo
import freezer
import swiftclient
import multiprocessing
import subprocess
import time
import os
import MySQLdb
import pymongo
import re
import __builtin__
os.environ['OS_REGION_NAME'] = 'testregion'
os.environ['OS_TENANT_ID'] = '0123456789'
os.environ['OS_PASSWORD'] = 'testpassword'
os.environ['OS_AUTH_URL'] = 'testauthurl'
os.environ['OS_USERNAME'] = 'testusername'
os.environ['OS_TENANT_NAME'] = 'testtenantename'
class FakeOpen:
def __init__(self):
return None
def open(self, opt1=True, op2=True):
fd_open = os.open('/tmp/pytest-testopen', os.O_RDWR|os.O_CREAT|os.O_TRUNC)
os.write(fd_open, '/dev/mapper/testgroup-testsnapname\n')
py_fd = os.fdopen(fd_open)
return py_fd
class FakeBackup:
def __init__(self):
return None
def backup_mode_fs(opt1=True, opt2=True, opt3=True, opt4=True):
return True
class FakeMultiProcessing:
def __init__(self, duplex=True, maxsize=True):
return None
class Queue:
def __init__(self, duplex=True):
return None
def put(self, opt1=dict()):
return True
def get(self, opt1=dict()):
return True
def __call__(self, duplex=True):
return []
class Pipe:
def __init__(self, duplex=True):
return None
def send_bytes(self, opt1=True):
return True
def recv_bytes(self, opt1=True):
return True
def send(self, opt1=True):
return True
def recv(self, opt1=True):
return True
def poll(self):
return True
def close(self):
return True
def __call__(self, duplex=True):
return [self, self]
class Process:
def __init__(self, target=True, args=True):
return None
def start(self):
return True
def stop(self):
return True
def daemon(self):
return True
def join(self):
return True
@classmethod
def util(cls):
return True
class FakeSubProcess:
def __init__(self):
return None
class Popen:
def __init__(self, opt1=True, stdin=True, stdout=True,
stderr=True, shell=True, executable=True):
return None
def communicate(self):
return 'successfully removed', ''
class Lvm:
def __init__(self):
return None
def lvm_snap_remove(self, opt1=True):
return True
def lvm_eval(self, opt1=True):
return False
class FakeSwiftClient:
def __init__(self):
return None
class client:
def __init__(self):
return None
class Connection:
def __init__(self, key=True, os_options=True, auth_version=True, user=True, authurl=True, tenant_name=True, retries=True):
return None
def put_object(self, opt1=True, opt2=True, opt3=True, opt4=True, opt5=True, headers=True, content_length=True, content_type=True):
return True
class FakeRe:
def __init__(self):
return None
class search:
def __init__(self, opt1=True, opt2=True, opt3=True):
self.opt1 = opt1
self.opt2 = opt2
self.opt3 = opt3
return None
def group(self, opt1=True, opt2=True):
self.opt1 = opt1
self.opt2 = opt2
return 'testgroup'
class BackupOpt1:
def __init__(self):
fakeclient = FakeSwiftClient()
fakeconnector = fakeclient.client()
fakeswclient = fakeconnector.Connection()
self.mysql_conf_file = '/dev/null'
self.lvm_auto_snap = '/dev/null'
self.lvm_volgroup = 'testgroup'
self.lvm_srcvol = 'testvol'
self.lvm_dirmount= 'testdir'
self.lvm_snapsize = '1G'
self.lvm_snapname = 'testsnapname'
self.lvcreate_path = 'true'
self.lvremove_path = 'true'
self.mode = 'mysql'
self.bash_path = 'true'
self.file_path = 'true'
self.mount_path = 'true'
self.umount_path = 'true'
self.backup_name = 'test-backup-name'
self.hostname = 'test-hostname'
self.curr_backup_level = '0'
self.src_file = '/tmp'
self.tar_path= 'true'
self.dereference_symlink = 'true'
self.no_incremental = 'true'
self.exclude = 'true'
self.encrypt_pass_file = 'true'
self.openssl_path = 'true'
self.always_backup_level = '0'
self.max_backup_level = '0'
self.remove_older_than = '0'
self.max_seg_size = '0'
self.time_stamp = '0'
self.container_segments = 'test-container-segements'
self.container = 'test-container'
self.restart_always_backup = '0'
self.workdir = '/tmp'
self.upload = 'true'
self.sw_connector = fakeswclient
class FakeMySQLdb:
def __init__(self):
return None
class connect:
def __init__(self, host=True, user=True, passwd=True):
self.host = host
self.user = user
self.passwd = passwd
return None
class cursor:
def __init__(self):
return None
def execute(self, string):
return True
def close(self):
return True
def commit(self):
return True
def close(self):
return True
class FakeMongoDB:
def __init__(self, opt1=True):
return None
def __call__(self, opt1=True):
return self
class admin:
def __init__(self):
return None
@classmethod
def command(cls, opt1=True):
return {'me': 'testnode', 'primary': 'testnode'}
class Os:
def __init__(self):
return None
def expanduser(self, directory=True):
return True
def makedirs(self, directory=True):
return True
def isdir(self, directory=True):
return True
def exists(self, directory=True):
return True

128
tests/test_backup.py Normal file
View File

@ -0,0 +1,128 @@
#!/usr/bin/env python
from freezer.backup import backup_mode_mysql, backup_mode_fs, backup_mode_mongo
import freezer
import swiftclient
import multiprocessing
import subprocess
import time
import os
import MySQLdb
import pymongo
import re
from commons import *
import __builtin__
class TestBackUP:
def test_backup_mode_mysql(self, monkeypatch):
test_meta = dict()
backup_opt = BackupOpt1()
fakemysql = FakeMySQLdb()
expanduser = Os()
fakere = FakeRe()
fakeswiftclient = FakeSwiftClient()
fakelvm = Lvm()
fakesubprocess = FakeSubProcess()
fakesubprocesspopen = fakesubprocess.Popen()
fakeopen = FakeOpen()
fakemultiprocessing = FakeMultiProcessing()
fakemultiprocessingqueue = fakemultiprocessing.Queue()
fakemultiprocessingpipe = fakemultiprocessing.Pipe()
fakemultiprocessinginit = fakemultiprocessing.__init__()
monkeypatch.setattr(
multiprocessing, 'Queue', fakemultiprocessingqueue)
monkeypatch.setattr(
multiprocessing, 'Pipe', fakemultiprocessingpipe)
monkeypatch.setattr(
multiprocessing, 'Process', fakemultiprocessing.Process)
monkeypatch.setattr(
multiprocessing, '__init__', fakemultiprocessinginit)
monkeypatch.setattr(__builtin__, 'open', fakeopen.open)
monkeypatch.setattr(
subprocess.Popen, 'communicate', fakesubprocesspopen.communicate)
monkeypatch.setattr(
freezer.lvm, 'lvm_snap_remove', fakelvm.lvm_snap_remove)
monkeypatch.setattr(freezer.lvm, 'lvm_eval', fakelvm.lvm_eval)
monkeypatch.setattr(re, 'search', fakere.search)
monkeypatch.setattr(MySQLdb, 'connect', fakemysql.connect)
monkeypatch.setattr(os.path, 'expanduser', expanduser.expanduser)
monkeypatch.setattr(os.path, 'isdir', expanduser.isdir)
monkeypatch.setattr(os, 'makedirs', expanduser.makedirs)
monkeypatch.setattr(os.path, 'exists', expanduser.exists)
monkeypatch.setattr(swiftclient, 'client', fakeswiftclient.client)
assert backup_mode_mysql(
backup_opt, int(time.time()), test_meta) is None
def test_backup_mode_fs(self, monkeypatch):
# Class and other settings initialization
test_meta = dict()
backup_opt = BackupOpt1()
backup_opt.mode = 'fs'
expanduser = Os()
fakere = FakeRe()
fakeswiftclient = FakeSwiftClient()
fakelvm = Lvm()
fakemultiprocessing = FakeMultiProcessing()
fakemultiprocessingqueue = fakemultiprocessing.Queue()
fakemultiprocessingpipe = fakemultiprocessing.Pipe()
fakemultiprocessinginit = fakemultiprocessing.__init__()
# Monkey patch
monkeypatch.setattr(
multiprocessing, 'Queue', fakemultiprocessingqueue)
monkeypatch.setattr(multiprocessing, 'Pipe', fakemultiprocessingpipe)
monkeypatch.setattr(
multiprocessing, 'Process', fakemultiprocessing.Process)
monkeypatch.setattr(
multiprocessing, '__init__', fakemultiprocessinginit)
monkeypatch.setattr(freezer.lvm, 'lvm_eval', fakelvm.lvm_eval)
monkeypatch.setattr(swiftclient, 'client', fakeswiftclient.client)
monkeypatch.setattr(re, 'search', fakere.search)
monkeypatch.setattr(os.path, 'exists', expanduser.exists)
assert backup_mode_fs(
backup_opt, int(time.time()), test_meta) is None
def test_backup_mode_mongo(self, monkeypatch):
# Class and other settings initialization
test_meta = dict()
backup_opt = BackupOpt1()
fakemongo = FakeMongoDB()
backup_opt.mode = 'mongo'
fakeos = Os()
fakere = FakeRe()
fakeswiftclient = FakeSwiftClient()
fakeopen = FakeOpen()
fakelvm = Lvm()
fakemultiprocessing = FakeMultiProcessing()
fakemultiprocessingqueue = fakemultiprocessing.Queue()
fakemultiprocessingpipe = fakemultiprocessing.Pipe()
fakemultiprocessinginit = fakemultiprocessing.__init__()
monkeypatch.setattr(
multiprocessing, 'Queue', fakemultiprocessingqueue)
monkeypatch.setattr(
multiprocessing, 'Pipe', fakemultiprocessingpipe)
monkeypatch.setattr(
multiprocessing, 'Process', fakemultiprocessing.Process)
monkeypatch.setattr(
multiprocessing, '__init__', fakemultiprocessinginit)
monkeypatch.setattr(freezer.lvm, 'lvm_eval', fakelvm.lvm_eval)
monkeypatch.setattr(pymongo, 'MongoClient', fakemongo)
monkeypatch.setattr(os.path, 'exists', fakeos.exists)
monkeypatch.setattr(re, 'search', fakere.search)
monkeypatch.setattr(swiftclient, 'client', fakeswiftclient.client)
monkeypatch.setattr(__builtin__, 'open', fakeopen.open)
assert backup_mode_mongo(
backup_opt, int(time.time()), test_meta) is None