Test and debug a generic progress bar for tests
authorStavros Sachtouris <saxtouri@admin.grnet.gr>
Tue, 5 Feb 2013 15:33:35 +0000 (17:33 +0200)
committerStavros Sachtouris <saxtouri@admin.grnet.gr>
Tue, 5 Feb 2013 15:33:35 +0000 (17:33 +0200)
in client

kamaki/cli/utils.py
kamaki/clients/cyclades.py
kamaki/clients/tests/__init__.py
kamaki/clients/tests/cyclades.py

index 01ded66..4c7b76d 100644 (file)
@@ -33,6 +33,8 @@
 
 from sys import stdout, stdin
 from re import compile as regex_compile
 
 from sys import stdout, stdin
 from re import compile as regex_compile
+from time import sleep
+
 from kamaki.cli.errors import raiseCLIError
 
 try:
 from kamaki.cli.errors import raiseCLIError
 
 try:
@@ -393,14 +395,16 @@ def ask_user(msg, true_resp=['Y', 'y']):
     return user_response[0] in true_resp + ['\n']
 
 
     return user_response[0] in true_resp + ['\n']
 
 
-def spiner():
+def spiner(size=None):
     spins = ('/', '-', '\\', '|')
     spins = ('/', '-', '\\', '|')
-    i = 0
     stdout.write(' ')
     stdout.write(' ')
-    while True:
+    size = size or -1
+    i = 0
+    while size - i:
         stdout.write('\b%s' % spins[i % len(spins)])
         stdout.flush()
         i += 1
         stdout.write('\b%s' % spins[i % len(spins)])
         stdout.flush()
         i += 1
+        sleep(0.1)
         yield
 
 if __name__ == '__main__':
         yield
 
 if __name__ == '__main__':
index 21befb0..80179c1 100644 (file)
 # interpreted as representing official policies, either expressed
 # or implied, of GRNET S.A.
 
 # interpreted as representing official policies, either expressed
 # or implied, of GRNET S.A.
 
+from time import sleep
+
 from kamaki.clients.cyclades_rest_api import CycladesClientApi
 from kamaki.clients import ClientError
 from kamaki.clients.cyclades_rest_api import CycladesClientApi
 from kamaki.clients import ClientError
-from time import sleep
+from sys import stdout
 
 
 class CycladesClient(CycladesClientApi):
 
 
 class CycladesClient(CycladesClientApi):
@@ -277,9 +279,15 @@ class CycladesClient(CycladesClientApi):
                     for i in range(int(old_wait), int(total_wait)):
                         wait_gen.next()
                     old_wait = total_wait
                     for i in range(int(old_wait), int(total_wait)):
                         wait_gen.next()
                     old_wait = total_wait
+                else:
+                    stdout.write('.')
+                    stdout.flush()
             else:
                 if wait_cb:
                     wait_gen.next()
             else:
                 if wait_cb:
                     wait_gen.next()
+                else:
+                    stdout.write('.')
+                    stdout.flush()
                 total_wait += delay
             sleep(delay)
             r = self.get_server_details(server_id)
                 total_wait += delay
             sleep(delay)
             r = self.get_server_details(server_id)
index 1c4c8aa..4984e2e 100644 (file)
 from unittest import TestCase, TestSuite, makeSuite, TextTestRunner
 from argparse import ArgumentParser
 from sys import stdout
 from unittest import TestCase, TestSuite, makeSuite, TextTestRunner
 from argparse import ArgumentParser
 from sys import stdout
-from traceback import extract_stack, print_stack
 from progress.bar import ShadyBar
 
 from kamaki.cli.config import Config
 from progress.bar import ShadyBar
 
 from kamaki.cli.config import Config
+from kamaki.cli.utils import spiner
 
 
 def _add_value(foo, value):
 
 
 def _add_value(foo, value):
@@ -48,6 +48,7 @@ def _add_value(foo, value):
 
 class Generic(TestCase):
 
 
 class Generic(TestCase):
 
+    _waits = []
     _cnf = None
     _grp = None
     _fetched = {}
     _cnf = None
     _grp = None
     _fetched = {}
@@ -56,6 +57,9 @@ class Generic(TestCase):
         super(Generic, self).__init__(specific)
         self._cnf = Config(config_file)
         self._grp = group
         super(Generic, self).__init__(specific)
         self._cnf = Config(config_file)
         self._grp = group
+        self._waits.append(0.71828)
+        for i in range(10):
+            self._waits.append(self._waits[-1] * 2.71828)
 
     def __getitem__(self, key):
         key = self._key(key)
 
     def __getitem__(self, key):
         key = self._key(key)
@@ -83,20 +87,34 @@ class Generic(TestCase):
     def _safe_progress_bar(self, msg):
         """Try to get a progress bar, but do not raise errors"""
         try:
     def _safe_progress_bar(self, msg):
         """Try to get a progress bar, but do not raise errors"""
         try:
-            progress_bar = ShadyBar()
-            gen = progress_bar.get_generator(msg)
+            wait_bar = ShadyBar(msg)
+
+            def wait_gen(n):
+                for i in wait_bar.iter(range(int(n))):
+                    yield
+                yield
+            wait_cb = wait_gen
         except Exception:
         except Exception:
-            return (None, None)
-        return (progress_bar, gen)
+            stdout.write('%s:' % msg)
+            (wait_bar, wait_cb) = (None, spiner)
+        return (wait_bar, wait_cb)
 
     def _safe_progress_bar_finish(self, progress_bar):
         try:
             progress_bar.finish()
         except Exception:
 
     def _safe_progress_bar_finish(self, progress_bar):
         try:
             progress_bar.finish()
         except Exception:
-            pass
-
-    def do_with_progress_bar(self, action, msg, list, *args, **kwargs):
-        (action_bar, action_cb) = self._safe_progress_bar('')
+            print(' DONE')
+
+    def do_with_progress_bar(self, action, msg, items):
+        if not items:
+            print('%s: DONE' % msg)
+            return
+        (action_bar, action_cb) = self._safe_progress_bar(msg)
+        action_gen = action_cb(len(items))
+        for item in items:
+            action(item)
+            action_gen.next()
+        self._safe_progress_bar_finish(action_bar)
 
     def assert_dicts_are_deeply_equal(self, d1, d2):
         for k, v in d1.items():
 
     def assert_dicts_are_deeply_equal(self, d1, d2):
         for k, v in d1.items():
@@ -144,13 +162,11 @@ def main(argv):
             suiteFew.addTest(unittest.makeSuite(testPithos))
         else:
             suiteFew.addTest(testPithos('test_' + argv[1]))
             suiteFew.addTest(unittest.makeSuite(testPithos))
         else:
             suiteFew.addTest(testPithos('test_' + argv[1]))
-    if len(argv) == 0 or argv[0] == 'cyclades':
-        if len(argv) == 1:
-            #suiteFew.addTest(unittest.makeSuite(testCyclades))
-            suiteFew.addTest(testCyclades('test_000'))
-        else:
-            suiteFew.addTest(testCyclades('test_' + argv[1]))
     """
     """
+    if len(argv) == 0 or argv[0] == 'cyclades':
+        from kamaki.clients.tests.cyclades import Cyclades
+        test_method = 'test_%s' % (argv[1] if len(argv) > 1 else '000')
+        suiteFew.addTest(Cyclades(test_method))
     if len(argv) == 0 or argv[0] == 'image':
         from kamaki.clients.tests.image import Image
         test_method = 'test_%s' % (argv[1] if len(argv) > 1 else '000')
     if len(argv) == 0 or argv[0] == 'image':
         from kamaki.clients.tests.image import Image
         test_method = 'test_%s' % (argv[1] if len(argv) > 1 else '000')
index f938569..48a5d0e 100644 (file)
@@ -32,8 +32,9 @@
 # or implied, of GRNET S.A.
 
 import time
 # or implied, of GRNET S.A.
 
 import time
+from progress.bar import ShadyBar
 
 
-from kamaki.clients import tests
+from kamaki.clients import tests, ClientError
 from kamaki.clients.cyclades import CycladesClient
 
 
 from kamaki.clients.cyclades import CycladesClient
 
 
@@ -86,14 +87,15 @@ class Cyclades(tests.Generic):
 
     def tearDown(self):
         """Destoy servers used in testing"""
 
     def tearDown(self):
         """Destoy servers used in testing"""
-        print
-        for netid in self.networks.keys():
-            self._delete_network(netid)
-        if 0 >= len(self.servers):
-            return
-        print('-> Found %s servers to delete' % len(self.servers))
-        for server in self.servers.values():
-            self._delete_server(server['id'])
+        self.do_with_progress_bar(
+            self._delete_network,
+            'Delete %s networks' % len(self.networks),
+            self.networks.keys())
+        server_list = [server['id'] for server in self.servers.values()]
+        self.do_with_progress_bar(
+            self._delete_server,
+            'Delete %s servers %s' % (len(server_list), server_list),
+            server_list)
 
     def _create_server(self, servername, flavorid, imageid, personality=None):
         server = self.client.create_server(servername,
 
     def _create_server(self, servername, flavorid, imageid, personality=None):
         server = self.client.create_server(servername,
@@ -111,8 +113,8 @@ class Cyclades(tests.Generic):
                 return
         except:
             return
                 return
         except:
             return
-        self.client.delete_server(servid)
         self._wait_for_status(servid, current_state)
         self._wait_for_status(servid, current_state)
+        self.client.delete_server(servid)
 
     def _create_network(self, netname, **kwargs):
         net = self.client.create_network(netname, **kwargs)
 
     def _create_network(self, netname, **kwargs):
         net = self.client.create_network(netname, **kwargs)
@@ -120,16 +122,91 @@ class Cyclades(tests.Generic):
         return net
 
     def _delete_network(self, netid):
         return net
 
     def _delete_network(self, netid):
-        sys.stdout.write('\tDelete network %s ' % netid)
+        print('Disconnect nics of network %s' % netid)
         self.client.disconnect_network_nics(netid)
         self.client.disconnect_network_nics(netid)
-        wait = 3
-        while True:
+
+        def netwait(self, wait):
             try:
                 self.client.delete_network(netid)
             try:
                 self.client.delete_network(netid)
-                print('\n\tSUCCESFULL COMMIT delete network %s' % netid)
-                break
-            except ClientError as err:
-                self.assertEqual(err.status, 421)
+            except ClientError:
                 time.sleep(wait)
                 time.sleep(wait)
-                wait += 3
-                sys.stdout.write('.')
+        self.do_with_progress_bar(
+            netwait,
+            'Delete network %s' % netid,
+            self._waits[:5])
+
+    def _wait_for_network(self, netid, status):
+
+        def netwait(self, wait):
+            r = self.client.get_network_details(netid)
+            if r['status'] == status:
+                return
+            time.sleep(wait)
+        self.do_with_progress_bar(
+            netwait,
+            'Wait network %s to reach status %s' % (netid, status),
+            self._waits[:5])
+
+    def _wait_for_nic(self, netid, servid, in_creation=True):
+        self._wait_for_network(netid, 'ACTIVE')
+
+        def nicwait(self, wait):
+            nics = self.client.list_server_nics(servid)
+            for net in nics:
+                found_nic = net['network_id'] == netid
+                if (in_creation and found_nic)\
+                or not (in_creation or found_nic):
+                    return
+            time.sleep(wait)
+        self.do_with_progress_bar(
+            nicwait,
+            'Wait nic-%s-%s to %sconnect' % (
+                netid,
+                servid,
+                '' if in_creation else 'dis'),
+            self._waits[:5])
+
+    def _has_status(self, servid, status):
+        r = self.client.get_server_details(servid)
+        return r['status'] == status
+
+    def _wait_for_status(self, servid, status):
+        (wait_bar, wait_cb) = self._safe_progress_bar(
+            'Server %s in %s' % (servid, status))
+        self.client.wait_server(servid, status, wait_cb=wait_cb)
+        self._safe_progress_bar_finish(wait_bar)
+
+    def test_list_servers(self):
+        """Test list servers"""
+        self.server1 = self._create_server(
+            self.servname1,
+            self.flavorid,
+            self.img)
+        return
+        self.server2 = self._create_server(
+            self.servname2,
+            self.flavorid + 2,
+            self.img)
+        self._test_list_servers()
+
+    def _test_list_servers(self):
+        servers = self.client.list_servers()
+        dservers = self.client.list_servers(detail=True)
+
+        """detailed and simple are same size"""
+        self.assertEqual(len(dservers), len(servers))
+        for i in range(len(servers)):
+            for field in ('created',
+            'flavorRef',
+            'hostId',
+            'imageRef',
+            'progress',
+            'status',
+            'updated'):
+                self.assertFalse(field in servers[i])
+                self.assertTrue(field in dservers[i])
+
+        """detailed and simple contain same names"""
+        names = sorted(map(lambda x: x["name"], servers))
+        dnames = sorted(map(lambda x: x["name"], dservers))
+        self.assertEqual(names, dnames)