056d7a582056ac1d4e9ff94cc3f4549e8933cf12
[tests.git] / qaapi / qa / QAAPI.py
1 import sys, os
2 import traceback
3 import qa.modules
4 from qa.Config import Config
5 from qa.logger import log       
6
7 class QAAPI:
8    
9     modules_path = os.path.realpath(qa.modules.__path__[0])
10     methods = []
11                 
12         
13     def __init__(self, globals, config = None, logging=None, verbose=None):
14         if config is None: self.config = Config()
15         else: self.config = Config(config)
16
17         module_files = self.module_files(self.modules_path)
18         callables = set()
19         # determine what is callable
20         for file in module_files:
21             callables.update(self.callables(file))
22                 
23         # Add methods to self and global environemt     
24         for method in callables:            
25             if logging: method = log(method, method.mod_name)
26             elif hasattr(self.config, 'log') and self.config.log:
27                 method = log(method, method.mod_name)
28            
29             class Dummy: pass
30             paths = method.mod_name.split(".")
31             
32             if len(paths) > 1:
33                 first = paths.pop(0)
34
35                 if not hasattr(self, first):
36                     obj = Dummy()
37                     setattr(self, first, obj)
38                     # Also add to global environment if specified
39                     if globals is not None:
40                         globals[first] = obj
41
42                 obj = getattr(self, first)
43
44                 for path in paths:
45                     if not hasattr(obj, path):
46                         if path == paths[-1]:
47                             setattr(obj, path, method)
48                             globals[method.mod_name]=obj  
49                         else:
50                             setattr(obj, path, Dummy())
51                     obj = getattr(obj, path)
52             else:
53                 if globals is not None:
54                     globals[method.mod_name] = method           
55
56     def module_files(self, module_dir):
57         """
58         Build a list of files   
59         """     
60         
61         # Load files from modules direcotry
62         real_files = lambda name: not name.startswith('__init__') \
63                                   and  name.endswith('.py')
64         remove_ext = lambda name: name.split(".py")[0]
65         iterator = os.walk(module_dir)
66         (root, basenames, files) = iterator.next()
67         module_base = ""
68         module_files = []
69         module_files.extend([method_base+file for file in map(remove_ext, filter(real_files, files))])
70
71         # recurse through directory             
72         for (root, dirs, files) in iterator:
73             parts = root.split(os.sep)
74             for basename in basenames:
75                 if basename in parts:
76                     module_base = ".".join(parts[parts.index(basename):])+"."
77             files = filter(real_files, files)
78             files = map(remove_ext, files)
79             module_files.extend([module_base+file for file in  files])
80
81         return module_files 
82
83     def callables(self, module_file):
84         """
85         Return a new instance of the specified method. 
86         """      
87         
88         # Get new instance of method
89         parts = module_file.split(".")
90         # add every part except for the last to name (filename)
91         module_dir =  "qa.modules."
92         module_basename = ".".join(parts[:-1])
93         module_path = module_dir + module_file
94         try:
95             module = __import__(module_path, globals(), locals(), module_path)
96             callables = []
97
98             for attribute in dir(module):
99                 attr = getattr(module, attribute)
100                 if callable(attr) and hasattr(attr, 'status'):
101                     setattr(attr, 'mod_name', module_basename+"."+attribute)
102                     callables.append(attr(self.config))
103             return callables 
104         except ImportError, AttributeError:
105             raise  
106          
107