[PATCH 0/2] Objectstore and server tests

On way to complete the tests refactoring, I am sending 2 patches: one related to objectstore tests and other one about server tests. Aline Manera (2): Object store tests Server tests tests/test_mockmodel.py | 35 ------ tests/test_model.py | 71 ------------ tests/test_objectstore.py | 96 ++++++++++++++++ tests/test_rest.py | 176 ----------------------------- tests/test_server.py | 274 +++++++++++++++++++++++++++++++++++++++++++--- 5 files changed, 356 insertions(+), 296 deletions(-) create mode 100644 tests/test_objectstore.py -- 2.1.0

Create a specific file (test_objectstore.py) to handle all the Objectstore tests. Signed-off-by: Aline Manera <alinefm@linux.vnet.ibm.com> --- tests/test_model.py | 54 -------------------------- tests/test_objectstore.py | 96 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+), 54 deletions(-) create mode 100644 tests/test_objectstore.py diff --git a/tests/test_model.py b/tests/test_model.py index 63bd721..2a57507 100644 --- a/tests/test_model.py +++ b/tests/test_model.py @@ -706,60 +706,6 @@ class ModelTests(unittest.TestCase): for t in threads: t.join() - def test_object_store(self): - store = kimchi.objectstore.ObjectStore(self.tmp_store) - - with store as session: - # Test create - session.store('fǒǒ', 'těst1', {'α': 1}) - session.store('fǒǒ', 'těst2', {'β': 2}) - - # Test list - items = session.get_list('fǒǒ') - self.assertTrue(u'těst1' in items) - self.assertTrue(u'těst2' in items) - - # Test get - item = session.get('fǒǒ', 'těst1') - self.assertEquals(1, item[u'α']) - - # Test delete - session.delete('fǒǒ', 'těst2') - self.assertEquals(1, len(session.get_list('fǒǒ'))) - - # Test get non-existent item - - self.assertRaises(NotFoundError, session.get, - 'α', 'β') - - # Test delete non-existent item - self.assertRaises(NotFoundError, session.delete, - 'fǒǒ', 'těst2') - - # Test refresh existing item - session.store('fǒǒ', 'těst1', {'α': 2}) - item = session.get('fǒǒ', 'těst1') - self.assertEquals(2, item[u'α']) - - def test_object_store_threaded(self): - def worker(ident): - with store as session: - session.store('foo', ident, {}) - - store = kimchi.objectstore.ObjectStore(self.tmp_store) - - threads = [] - for i in xrange(50): - t = threading.Thread(target=worker, args=(i,)) - t.setDaemon(True) - t.start() - threads.append(t) - for t in threads: - t.join() - with store as session: - self.assertEquals(50, len(session.get_list('foo'))) - self.assertEquals(10, len(store._connections.keys())) - def test_get_interfaces(self): inst = model.Model('test:///default', objstore_loc=self.tmp_store) diff --git a/tests/test_objectstore.py b/tests/test_objectstore.py new file mode 100644 index 0000000..f62217e --- /dev/null +++ b/tests/test_objectstore.py @@ -0,0 +1,96 @@ +# -*- coding: utf-8 -*- +# +# Project Kimchi +# +# Copyright IBM, Corp. 2015 +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +import os +import tempfile +import threading +import unittest + +from kimchi.exception import NotFoundError +from kimchi import objectstore + +tmpfile = None + + +def setUpModule(): + global tmpfile + tmpfile = tempfile.mktemp() + + +def tearDownModule(): + os.unlink(tmpfile) + + +class ObjectStoreTests(unittest.TestCase): + def test_objectstore(self): + store = objectstore.ObjectStore(tmpfile) + + with store as session: + # Test create + session.store('fǒǒ', 'těst1', {'α': 1}) + session.store('fǒǒ', 'těst2', {'β': 2}) + + # Test list + items = session.get_list('fǒǒ') + self.assertTrue(u'těst1' in items) + self.assertTrue(u'těst2' in items) + + # Test get + item = session.get('fǒǒ', 'těst1') + self.assertEquals(1, item[u'α']) + + # Test delete + session.delete('fǒǒ', 'těst2') + self.assertEquals(1, len(session.get_list('fǒǒ'))) + + # Test get non-existent item + + self.assertRaises(NotFoundError, session.get, + 'α', 'β') + + # Test delete non-existent item + self.assertRaises(NotFoundError, session.delete, + 'fǒǒ', 'těst2') + + # Test refresh existing item + session.store('fǒǒ', 'těst1', {'α': 2}) + item = session.get('fǒǒ', 'těst1') + self.assertEquals(2, item[u'α']) + + def test_object_store_threaded(self): + def worker(ident): + with store as session: + session.store('foo', ident, {}) + + store = objectstore.ObjectStore(tmpfile) + + threads = [] + for i in xrange(50): + t = threading.Thread(target=worker, args=(i,)) + t.setDaemon(True) + t.start() + threads.append(t) + + for t in threads: + t.join() + + with store as session: + self.assertEquals(50, len(session.get_list('foo'))) + self.assertEquals(10, len(store._connections.keys())) -- 2.1.0

Move all the server related tests to the test_server.py file to make maintenance easier. Signed-off-by: Aline Manera <alinefm@linux.vnet.ibm.com> --- tests/test_mockmodel.py | 35 ------- tests/test_model.py | 17 --- tests/test_rest.py | 176 ------------------------------- tests/test_server.py | 274 +++++++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 260 insertions(+), 242 deletions(-) diff --git a/tests/test_mockmodel.py b/tests/test_mockmodel.py index 68a28d3..c7e733e 100644 --- a/tests/test_mockmodel.py +++ b/tests/test_mockmodel.py @@ -27,7 +27,6 @@ import unittest import kimchi.mockmodel from utils import get_free_port, patch_auth, request, run_server from utils import wait_task -from kimchi.control.base import Collection, Resource from kimchi.osinfo import get_template_default @@ -63,40 +62,6 @@ class MockModelTests(unittest.TestCase): def setUp(self): model.reset() - def test_collection(self): - c = Collection(model) - - # The base Collection is always empty - cherrypy.request.method = 'GET' - self.assertEquals('[]', c.index()) - - # POST and DELETE raise HTTP:405 by default - for method in ('POST', 'DELETE'): - cherrypy.request.method = method - try: - c.index() - except cherrypy.HTTPError, e: - self.assertEquals(405, e.code) - else: - self.fail("Expected exception not raised") - - def test_resource(self): - r = Resource(model) - - # Test the base Resource representation - cherrypy.request.method = 'GET' - self.assertEquals('{}', r.index()) - - # POST and DELETE raise HTTP:405 by default - for method in ('POST', 'DELETE'): - cherrypy.request.method = method - try: - r.index() - except cherrypy.HTTPError, e: - self.assertEquals(405, e.code) - else: - self.fail("Expected exception not raised") - def test_screenshot_refresh(self): # Create a VM req = json.dumps({'name': 'test', 'cdrom': fake_iso}) diff --git a/tests/test_model.py b/tests/test_model.py index 2a57507..c87ce50 100644 --- a/tests/test_model.py +++ b/tests/test_model.py @@ -26,7 +26,6 @@ import pwd import re import shutil import socket -import threading import time import urlparse import unittest @@ -690,22 +689,6 @@ class ModelTests(unittest.TestCase): self.assertEquals([], inst.vm_lookup(u'пeω-∨м')['users']) self.assertEquals([], inst.vm_lookup(u'пeω-∨м')['groups']) - def test_multithreaded_connection(self): - def worker(): - for i in xrange(100): - ret = inst.vms_get_list() - self.assertEquals('test', ret[0]) - - inst = model.Model('test:///default', self.tmp_store) - threads = [] - for i in xrange(100): - t = threading.Thread(target=worker) - t.setDaemon(True) - t.start() - threads.append(t) - for t in threads: - t.join() - def test_get_interfaces(self): inst = model.Model('test:///default', objstore_loc=self.tmp_store) diff --git a/tests/test_rest.py b/tests/test_rest.py index 4ecf3ce..7d9dacf 100644 --- a/tests/test_rest.py +++ b/tests/test_rest.py @@ -18,7 +18,6 @@ # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -import base64 import json import os import re @@ -94,70 +93,6 @@ class RestTests(unittest.TestCase): resp = self.request(*args) self.assertEquals(code, resp.status) - def assertValidJSON(self, txt): - try: - json.loads(txt) - except ValueError: - self.fail("Invalid JSON: %s" % txt) - - def test_404(self): - """ - A non-existent path should return HTTP:404 - """ - url_list = ['/doesnotexist', '/vms/blah'] - for url in url_list: - self.assertHTTPStatus(404, url) - - # Make sure it fails for bad HTML requests - # We must be authenticated first. Otherwise all requests will return - # HTTP:401. Since HTTP Simple Auth is not allowed for text/html, we - # need to use the login API and establish a session. - user, pw = kimchi.mockmodel.fake_user.items()[0] - req = json.dumps({'username': user, 'password': pw}) - resp = self.request('/login', req, 'POST') - self.assertEquals(200, resp.status) - cookie = resp.getheader('set-cookie') - - self.assertHTTPStatus(404, url, None, 'GET', - {'Accept': 'text/html', - 'Cookie': cookie}) - - # Verify it works for DELETE too - self.assertHTTPStatus(404, '/templates/blah', '', 'DELETE') - - def test_accepts(self): - """ - Verify the following expectations regarding the client Accept header: - If omitted, default to html - If 'application/json', serve the rest api - If 'text/html', serve the UI - If both of the above (in any order), serve the rest api - If neither of the above, HTTP:406 - """ - resp = self.request("/", headers={}) - location = resp.getheader('location') - self.assertTrue(location.endswith("login.html")) - resp = self.request("/login.html", headers={}) - self.assertTrue('<!doctype html>' in resp.read().lower()) - - resp = self.request("/", headers={'Accept': 'application/json'}) - self.assertValidJSON(resp.read()) - - resp = self.request("/", headers={'Accept': 'text/html'}) - location = resp.getheader('location') - self.assertTrue(location.endswith("login.html")) - - resp = self.request("/", headers={'Accept': - 'application/json, text/html'}) - self.assertValidJSON(resp.read()) - - resp = self.request("/", headers={'Accept': - 'text/html, application/json'}) - self.assertValidJSON(resp.read()) - - h = {'Accept': 'text/plain'} - self.assertHTTPStatus(406, "/", None, 'GET', h) - def test_host_devices(self): resp = self.request('/host/devices?_cap=scsi_host') nodedevs = json.loads(resp.read()) @@ -1077,92 +1012,6 @@ class RestTests(unittest.TestCase): resp = self.request('/peers').read() self.assertEquals([], json.loads(resp)) - def test_auth_unprotected(self): - hdrs = {'AUTHORIZATION': ''} - uris = ['/js/kimchi.min.js', - '/css/theme-default.min.css', - '/libs/jquery-1.10.0.min.js', - '/images/icon-vm.png', - '/login.html', - '/logout'] - for uri in uris: - resp = self.request(uri, None, 'HEAD', hdrs) - self.assertEquals(200, resp.status) - - user, pw = kimchi.mockmodel.fake_user.items()[0] - req = json.dumps({'username': user, 'password': pw}) - resp = self.request('/login', req, 'POST', hdrs) - self.assertEquals(200, resp.status) - - def test_auth_protected(self): - hdrs = {'AUTHORIZATION': ''} - uris = ['/vms', - '/vms/doesnotexist', - '/tasks'] - for uri in uris: - resp = self.request(uri, None, 'GET', hdrs) - self.assertEquals(401, resp.status) - - def test_auth_bad_creds(self): - # Test HTTPBA - hdrs = {'AUTHORIZATION': "Basic " + base64.b64encode("nouser:badpass")} - resp = self.request('/vms', None, 'GET', hdrs) - self.assertEquals(401, resp.status) - - # Test REST API - hdrs = {'AUTHORIZATION': ''} - req = json.dumps({'username': 'nouser', 'password': 'badpass'}) - resp = self.request('/login', req, 'POST', hdrs) - self.assertEquals(401, resp.status) - - def test_auth_browser_no_httpba(self): - # Kimchi detects REST requests from the browser by looking for a - # specific header - hdrs = {"X-Requested-With": "XMLHttpRequest"} - - # Try our request (Note that request() will add a valid HTTPBA header) - resp = self.request('/vms', None, 'GET', hdrs) - self.assertEquals(401, resp.status) - self.assertEquals(None, resp.getheader('WWW-Authenticate')) - - def test_auth_session(self): - hdrs = {'AUTHORIZATION': '', - 'Content-Type': 'application/json', - 'Accept': 'application/json'} - - # Test we are logged out - resp = self.request('/tasks', None, 'GET', hdrs) - self.assertEquals(401, resp.status) - - # Execute a login call - user, pw = kimchi.mockmodel.fake_user.items()[0] - req = json.dumps({'username': user, 'password': pw}) - resp = self.request('/login', req, 'POST', hdrs) - self.assertEquals(200, resp.status) - - user_info = json.loads(resp.read()) - self.assertEquals(sorted(user_info.keys()), - ['groups', 'roles', 'username']) - roles = user_info['roles'] - for tab, role in roles.iteritems(): - self.assertEquals(role, u'admin') - - cookie = resp.getheader('set-cookie') - hdrs['Cookie'] = cookie - - # Test we are logged in with the cookie - resp = self.request('/tasks', None, 'GET', hdrs) - self.assertEquals(200, resp.status) - - # Execute a logout call - resp = self.request('/logout', '{}', 'POST', hdrs) - self.assertEquals(200, resp.status) - del hdrs['Cookie'] - - # Test we are logged out - resp = self.request('/tasks', None, 'GET', hdrs) - self.assertEquals(401, resp.status) - def test_distros(self): resp = self.request('/config/distros').read() distros = json.loads(resp) @@ -1306,31 +1155,6 @@ class RestTests(unittest.TestCase): self.assertEquals(task_info['status'], 'finished') self.assertIn(u'All packages updated', task_info['message']) - def test_get_param(self): - req = json.dumps({'name': 'test', 'cdrom': fake_iso}) - self.request('/templates', req, 'POST') - - # Create a VM - req = json.dumps({'name': 'test-vm1', 'template': '/templates/test'}) - resp = self.request('/vms', req, 'POST') - self.assertEquals(201, resp.status) - req = json.dumps({'name': 'test-vm2', 'template': '/templates/test'}) - resp = self.request('/vms', req, 'POST') - self.assertEquals(201, resp.status) - - resp = request(host, ssl_port, '/vms') - self.assertEquals(200, resp.status) - res = json.loads(resp.read()) - self.assertEquals(3, len(res)) - - # FIXME: control/base.py also allows filter by regex so it is returning - # 2 vms when querying for 'test-vm1': 'test' and 'test-vm1' - resp = request(host, ssl_port, '/vms?name=test-vm1') - self.assertEquals(200, resp.status) - res = json.loads(resp.read()) - self.assertEquals(2, len(res)) - self.assertIn('test-vm1', [r['name'] for r in res]) - def test_repositories(self): def verify_repo(t, res): for field in ('repo_id', 'enabled', 'baseurl', 'config'): diff --git a/tests/test_server.py b/tests/test_server.py index bebc383..42bebbe 100644 --- a/tests/test_server.py +++ b/tests/test_server.py @@ -1,7 +1,7 @@ # # Project Kimchi # -# Copyright IBM, Corp. 2013-2014 +# Copyright IBM, Corp. 2013-2015 # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -17,29 +17,275 @@ # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +import base64 +import cherrypy +import json import os +import tempfile +import threading import unittest +from functools import partial import utils -import kimchi.mockmodel +from kimchi import mockmodel +from kimchi.control.base import Collection, Resource + +test_server = None +model = None +host = None +port = None +ssl_port = None +cherrypy_port = None +tmpfile = None + + +def setUpModule(): + global test_server, model, host, port, ssl_port, cherrypy_port, tmpfile + + utils.patch_auth() + tmpfile = tempfile.mktemp() + model = mockmodel.MockModel(tmpfile) + host = '127.0.0.1' + port = utils.get_free_port('http') + ssl_port = utils.get_free_port('https') + cherrypy_port = utils.get_free_port('cherrypy_port') + test_server = utils.run_server(host, port, ssl_port, test_mode=True, + cherrypy_port=cherrypy_port, model=model) + + +def tearDownModule(): + test_server.stop() + os.unlink(tmpfile) class ServerTests(unittest.TestCase): + def setUp(self): + self.request = partial(utils.request, host, ssl_port) + model.reset() + + def assertValidJSON(self, txt): + try: + json.loads(txt) + except ValueError: + self.fail("Invalid JSON: %s" % txt) + def test_server_start(self): """ Test that we can start a server and receive HTTP:200. """ - host = '127.0.0.1' - port = utils.get_free_port('http') - ssl_port = utils.get_free_port('https') - model = kimchi.mockmodel.MockModel('/tmp/obj-store-test') - s = utils.run_server(host, port, ssl_port, test_mode=True, model=model) - try: - resp = utils.request(host, ssl_port, '/') + resp = self.request('/') + self.assertEquals(200, resp.status) + + def test_multithreaded_connection(self): + def worker(): + for i in xrange(100): + ret = model.vms_get_list() + self.assertEquals('test', ret[0]) + + threads = [] + for i in xrange(100): + t = threading.Thread(target=worker) + t.setDaemon(True) + t.start() + threads.append(t) + for t in threads: + t.join() + + def test_collection(self): + c = Collection(model) + + # The base Collection is always empty + cherrypy.request.method = 'GET' + cherrypy.request.headers['Accept'] = 'application/json' + self.assertEquals('[]', c.index()) + + # POST and DELETE raise HTTP:405 by default + for method in ('POST', 'DELETE'): + cherrypy.request.method = method + try: + c.index() + except cherrypy.HTTPError, e: + self.assertEquals(405, e.code) + else: + self.fail("Expected exception not raised") + + def test_resource(self): + r = Resource(model) + + # Test the base Resource representation + cherrypy.request.method = 'GET' + cherrypy.request.headers['Accept'] = 'application/json' + self.assertEquals('{}', r.index()) + + # POST and DELETE raise HTTP:405 by default + for method in ('POST', 'DELETE'): + cherrypy.request.method = method + try: + r.index() + except cherrypy.HTTPError, e: + self.assertEquals(405, e.code) + else: + self.fail("Expected exception not raised") + + def test_404(self): + """ + A non-existent path should return HTTP:404 + """ + url_list = ['/doesnotexist', '/vms/blah'] + for url in url_list: + resp = self.request(url) + self.assertEquals(404, resp.status) + + # Verify it works for DELETE too + resp = self.request('/templates/blah', '', 'DELETE') + self.assertEquals(404, resp.status) + + def test_accepts(self): + """ + Verify the following expectations regarding the client Accept header: + If omitted, default to html + If 'application/json', serve the rest api + If 'text/html', serve the UI + If both of the above (in any order), serve the rest api + If neither of the above, HTTP:406 + """ + resp = self.request("/", headers={}) + location = resp.getheader('location') + self.assertTrue(location.endswith("login.html")) + resp = self.request("/login.html", headers={}) + self.assertTrue('<!doctype html>' in resp.read().lower()) + + resp = self.request("/", headers={'Accept': 'application/json'}) + self.assertValidJSON(resp.read()) + + resp = self.request("/", headers={'Accept': 'text/html'}) + location = resp.getheader('location') + self.assertTrue(location.endswith("login.html")) + + resp = self.request("/", headers={'Accept': + 'application/json, text/html'}) + self.assertValidJSON(resp.read()) + + resp = self.request("/", headers={'Accept': + 'text/html, application/json'}) + self.assertValidJSON(resp.read()) + + h = {'Accept': 'text/plain'} + resp = self.request('/', None, 'GET', h) + self.assertEquals(406, resp.status) + + def test_auth_unprotected(self): + hdrs = {'AUTHORIZATION': ''} + uris = ['/js/kimchi.min.js', + '/css/theme-default.min.css', + '/libs/jquery-1.10.0.min.js', + '/images/icon-vm.png', + '/login.html', + '/logout'] + + for uri in uris: + resp = self.request(uri, None, 'HEAD', hdrs) self.assertEquals(200, resp.status) - except: - raise - finally: - os.unlink('/tmp/obj-store-test') - s.stop() + + def test_auth_protected(self): + hdrs = {'AUTHORIZATION': ''} + uris = ['/vms', + '/vms/doesnotexist', + '/tasks'] + + for uri in uris: + resp = self.request(uri, None, 'GET', hdrs) + self.assertEquals(401, resp.status) + + def test_auth_bad_creds(self): + # Test HTTPBA + hdrs = {'AUTHORIZATION': "Basic " + base64.b64encode("nouser:badpass")} + resp = self.request('/vms', None, 'GET', hdrs) + self.assertEquals(401, resp.status) + + # Test REST API + hdrs = {'AUTHORIZATION': ''} + req = json.dumps({'username': 'nouser', 'password': 'badpass'}) + resp = self.request('/login', req, 'POST', hdrs) + self.assertEquals(401, resp.status) + + def test_auth_browser_no_httpba(self): + # Kimchi detects REST requests from the browser by looking for a + # specific header + hdrs = {"X-Requested-With": "XMLHttpRequest"} + + # Try our request (Note that request() will add a valid HTTPBA header) + resp = self.request('/vms', None, 'GET', hdrs) + self.assertEquals(401, resp.status) + self.assertEquals(None, resp.getheader('WWW-Authenticate')) + + def test_auth_session(self): + hdrs = {'AUTHORIZATION': '', + 'Content-Type': 'application/json', + 'Accept': 'application/json'} + + # Test we are logged out + resp = self.request('/tasks', None, 'GET', hdrs) + self.assertEquals(401, resp.status) + + # Execute a login call + user, pw = mockmodel.fake_user.items()[0] + req = json.dumps({'username': user, 'password': pw}) + resp = self.request('/login', req, 'POST', hdrs) + self.assertEquals(200, resp.status) + + user_info = json.loads(resp.read()) + self.assertEquals(sorted(user_info.keys()), + ['groups', 'roles', 'username']) + roles = user_info['roles'] + for tab, role in roles.iteritems(): + self.assertEquals(role, u'admin') + + cookie = resp.getheader('set-cookie') + hdrs['Cookie'] = cookie + + # Test we are logged in with the cookie + resp = self.request('/tasks', None, 'GET', hdrs) + self.assertEquals(200, resp.status) + + # Execute a logout call + resp = self.request('/logout', '{}', 'POST', hdrs) + self.assertEquals(200, resp.status) + del hdrs['Cookie'] + + # Test we are logged out + resp = self.request('/tasks', None, 'GET', hdrs) + self.assertEquals(401, resp.status) + + def test_get_param(self): + # Create a mock ISO file + mockiso = '/tmp/mock.iso' + open('/tmp/mock.iso', 'w').close() + + req = json.dumps({'name': 'test', 'cdrom': mockiso}) + self.request('/templates', req, 'POST') + + # Create a VM + req = json.dumps({'name': 'test-vm1', 'template': '/templates/test'}) + resp = self.request('/vms', req, 'POST') + self.assertEquals(201, resp.status) + req = json.dumps({'name': 'test-vm2', 'template': '/templates/test'}) + resp = self.request('/vms', req, 'POST') + self.assertEquals(201, resp.status) + + # Remove mock iso + os.unlink(mockiso) + + resp = self.request('/vms') + self.assertEquals(200, resp.status) + res = json.loads(resp.read()) + self.assertEquals(3, len(res)) + + # FIXME: control/base.py also allows filter by regex so it is returning + # 2 vms when querying for 'test-vm1': 'test' and 'test-vm1' + resp = self.request('/vms?name=test-vm1') + self.assertEquals(200, resp.status) + res = json.loads(resp.read()) + self.assertEquals(2, len(res)) + self.assertIn('test-vm1', [r['name'] for r in res]) -- 2.1.0

Reviewed-by: Crístian Deives <cristiandeives@gmail.com> On Fri, Apr 10, 2015 at 3:03 PM Aline Manera <alinefm@linux.vnet.ibm.com> wrote:
On way to complete the tests refactoring, I am sending 2 patches: one related to objectstore tests and other one about server tests.
Aline Manera (2): Object store tests Server tests
tests/test_mockmodel.py | 35 ------ tests/test_model.py | 71 ------------ tests/test_objectstore.py | 96 ++++++++++++++++ tests/test_rest.py | 176 ----------------------------- tests/test_server.py | 274 +++++++++++++++++++++++++++++++++++++++++++--- 5 files changed, 356 insertions(+), 296 deletions(-) create mode 100644 tests/test_objectstore.py
-- 2.1.0
_______________________________________________ Kimchi-devel mailing list Kimchi-devel@ovirt.org http://lists.ovirt.org/mailman/listinfo/kimchi-devel
participants (2)
-
Aline Manera
-
Crístian Viana