commit
						1d69e88d0c
					
				@ -0,0 +1,155 @@
 | 
				
			|||||||
 | 
					"""
 | 
				
			||||||
 | 
					    This program is designed to inspect an application environment
 | 
				
			||||||
 | 
					    This program should only be run on unix friendly systems
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					from __future__  import division
 | 
				
			||||||
 | 
					import os
 | 
				
			||||||
 | 
					import subprocess
 | 
				
			||||||
 | 
					from sets import Set
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Analysis:
 | 
				
			||||||
 | 
						def __init__(self):
 | 
				
			||||||
 | 
							self.logs = []
 | 
				
			||||||
 | 
							pass
 | 
				
			||||||
 | 
						def post(self,object):
 | 
				
			||||||
 | 
							self.logs.append(object)
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
						This class is designed to analyze environment variables. Environment variables can either be folders, files or simple values
 | 
				
			||||||
 | 
						The class returns a quantifiable assessment of the environment variables (expected 100%)
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					class Env(Analysis):
 | 
				
			||||||
 | 
						def __init__(self,values):
 | 
				
			||||||
 | 
							Analysis.__init__(self)
 | 
				
			||||||
 | 
							self.values = values
 | 
				
			||||||
 | 
						"""
 | 
				
			||||||
 | 
							This function evaluate the validity of an environment variable by returning a 1 or 0 (computable)
 | 
				
			||||||
 | 
							The function will use propositional logic (https://en.wikipedia.org/wiki/Propositional_calculus)
 | 
				
			||||||
 | 
						"""
 | 
				
			||||||
 | 
						def evaluate(self,id):
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							if id in os.environ :
 | 
				
			||||||
 | 
								#
 | 
				
			||||||
 | 
								# We can inspect to make sure the environment variable is not a path or filename.
 | 
				
			||||||
 | 
								# Using propositional logic we proceed as follows:
 | 
				
			||||||
 | 
								# 	- (p) We determine if the value is an folder or file name (using regex)
 | 
				
			||||||
 | 
								# 	- (q) In case of a file or folder we check for existance
 | 
				
			||||||
 | 
								# The final result is a conjuction of p and q
 | 
				
			||||||
 | 
								#
 | 
				
			||||||
 | 
								value = os.environ[id]
 | 
				
			||||||
 | 
								expressions = [os.sep,'(\\.\w+)$']
 | 
				
			||||||
 | 
								p = sum([ re.search(xchar,value) is not None for xchar in expressions])
 | 
				
			||||||
 | 
								q = os.path.exists(value)
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								return int(p and q)
 | 
				
			||||||
 | 
							else:
 | 
				
			||||||
 | 
								return 0
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						def composite (self):
 | 
				
			||||||
 | 
							r = [ self.evaluate(id) for id in values] ;		
 | 
				
			||||||
 | 
							N = len(r)
 | 
				
			||||||
 | 
							n = sum(r)
 | 
				
			||||||
 | 
							return n/N
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Sandbox(Analysis):
 | 
				
			||||||
 | 
						def __init__(self,conf):
 | 
				
			||||||
 | 
							Analysis.__init__(self)
 | 
				
			||||||
 | 
							self.sandbox_path = conf['path']
 | 
				
			||||||
 | 
							self.requirements_path = conf['requirements']
 | 
				
			||||||
 | 
						def get_requirements (self):
 | 
				
			||||||
 | 
							f = open(self.requirements_path)
 | 
				
			||||||
 | 
							return [ name.replace('-',' ').replace('_',' ') for name in f.read().split('\n') name != '']
 | 
				
			||||||
 | 
						"""
 | 
				
			||||||
 | 
							This function will return the modules installed in the sandbox (virtual environment)
 | 
				
			||||||
 | 
						"""
 | 
				
			||||||
 | 
						def get_sandbox_requirements(self):
 | 
				
			||||||
 | 
							cmd = ['freeze']
 | 
				
			||||||
 | 
							xchar = ''.join([os.sep]*2)
 | 
				
			||||||
 | 
							pip_vm = ''.join([self.sandbox_path,os.sep,'bin',os.sep,'pip']).replace(xchar,os.sep)
 | 
				
			||||||
 | 
							cmd = [pip_vm]+cmd
 | 
				
			||||||
 | 
							r = subprocess.check_output(cmd).split('\n')
 | 
				
			||||||
 | 
							return [row.replace('-',' ').replace('_',' ') for row in r if row.strip() != '']	
 | 
				
			||||||
 | 
						def evaluate(self):
 | 
				
			||||||
 | 
							pass
 | 
				
			||||||
 | 
						"""
 | 
				
			||||||
 | 
							This function returns the ratio of existing modules relative to the ones expected
 | 
				
			||||||
 | 
						"""
 | 
				
			||||||
 | 
						def composite(self):
 | 
				
			||||||
 | 
							required_modules= self.get_requirements()
 | 
				
			||||||
 | 
							sandbox_modules	= self.get_sandbox_requirements()
 | 
				
			||||||
 | 
							N = len(requirements)
 | 
				
			||||||
 | 
							n = len(Set(required_modules) - Set(sandbox_modules))
 | 
				
			||||||
 | 
							return n/N
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
						This class performs the analysis of a list of processes and determines
 | 
				
			||||||
 | 
						The class provides a quantifiable measure of how many processes it found over all
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					class Processes(Analysis):
 | 
				
			||||||
 | 
						def __init__(self,names):
 | 
				
			||||||
 | 
							Analysis.__init__(self)
 | 
				
			||||||
 | 
							self.names = names
 | 
				
			||||||
 | 
						def evaluate(self,name):
 | 
				
			||||||
 | 
							cmd  = "".join(['ps aux |grep -E "^ {0,}',name,'" |wc -l'])
 | 
				
			||||||
 | 
							handler = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE)
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							return int(handler.communicate()[0].replace('\n','')) > 0
 | 
				
			||||||
 | 
						def composite(self):
 | 
				
			||||||
 | 
							r = [ self.evaluate(name) for name in self.names]
 | 
				
			||||||
 | 
							N = len(r)
 | 
				
			||||||
 | 
							n = sum(r)
 | 
				
			||||||
 | 
							return n/N
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
						This class returns an application's both memory and cpu usage
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					class DetailProcess(Analysis):
 | 
				
			||||||
 | 
						def __init__(self,name):
 | 
				
			||||||
 | 
							self.name = name;
 | 
				
			||||||
 | 
						def evaluate(self,name) :
 | 
				
			||||||
 | 
							cmd	= "ps -eo pmem,pcpu,vsize,comm|grep :app$"
 | 
				
			||||||
 | 
							handler = subprocess.Popen(cmd.replace(":app",name),shell=True,stdout=subprocess.PIPE)
 | 
				
			||||||
 | 
							ostream = handler.communicate()[0].split(' ')
 | 
				
			||||||
 | 
							return [float(value) for value in ostream if value.strip() not in ['',name]]
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
						def composite(self):
 | 
				
			||||||
 | 
							value = self.evaluate(self.name)
 | 
				
			||||||
 | 
							#row= {"memory_usage":value[0],"cpu_usage":value[1]}
 | 
				
			||||||
 | 
							return row
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
						This class will require
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					class QueueServer(Analysis):
 | 
				
			||||||
 | 
						def __init__(self,conf):
 | 
				
			||||||
 | 
							Analysis.__init__(self)
 | 
				
			||||||
 | 
							pass
 | 
				
			||||||
 | 
						def is_running(self):
 | 
				
			||||||
 | 
							p = Process(['rabbitmq-server'])
 | 
				
			||||||
 | 
							return p.composite()
 | 
				
			||||||
 | 
						def has_virtualhost(self,name):
 | 
				
			||||||
 | 
							return 0
 | 
				
			||||||
 | 
						def has_user(self,uid):
 | 
				
			||||||
 | 
							return 0
 | 
				
			||||||
 | 
						def composite(self):
 | 
				
			||||||
 | 
							if self.is_running() :
 | 
				
			||||||
 | 
								pass
 | 
				
			||||||
 | 
							else:
 | 
				
			||||||
 | 
								return [0,0,0]
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
						Normalization will be required for the data produced by this class
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					class DatabaseServer(Analysis):
 | 
				
			||||||
 | 
						def __init__(self,conf):
 | 
				
			||||||
 | 
							Analysis.__init__(self)
 | 
				
			||||||
 | 
							pass
 | 
				
			||||||
 | 
						def has_table(self,name):
 | 
				
			||||||
 | 
							pass
 | 
				
			||||||
 | 
						def has_fields(self,table,fields):
 | 
				
			||||||
 | 
							pass
 | 
				
			||||||
 | 
						def has_data(self,table):
 | 
				
			||||||
 | 
							pass
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
						This function will return the number of test-cases of the last build.
 | 
				
			||||||
 | 
						The use of the returned number will have to be normalized if used in a dataset.
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					class TestCaseCount(Analysis):
 | 
				
			||||||
 | 
						pass
 | 
				
			||||||
					Loading…
					
					
				
		Reference in new issue