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:
parent
bde16cbeb1
commit
ce996d5bac
|
@ -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
|
|
@ -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::
|
||||
|
||||
|
|
|
@ -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')
|
|
@ -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()
|
||||
|
File diff suppressed because it is too large
Load Diff
18
setup.py
18
setup.py
|
@ -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=[
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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
|
Loading…
Reference in New Issue