Просмотр исходного кода

Testcases and refactor for MVP

steve 8 лет назад
Родитель
Сommit
21e82603cb
3 измененных файлов с 178 добавлено и 0 удалено
  1. 159 0
      src/monitor.py
  2. BIN
      src/monitor.pyc
  3. 19 0
      test/TestServerMonitor.py

+ 159 - 0
src/monitor.py

@@ -0,0 +1,159 @@
+"""
+    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
+import re
+
+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 self.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') if 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,names):
+		self.names = names;
+	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]] +[name]
+		
+	def composite(self):
+		#value = self.evaluate(self.name)
+		#row= {"memory_usage":value[0],"cpu_usage":value[1]}
+		#return row
+		ma = [self.evaluate(name) for name in self.names]
+		
+		return [{"memory_usage":row[0],"cpu_usage":row[1],"memory_available":row[2]/1000,"label":row[3]} for row in ma]
+"""
+	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

BIN
src/monitor.pyc


+ 19 - 0
test/TestServerMonitor.py

@@ -0,0 +1,19 @@
+from __future__ import division
+import unittest
+from monitor import Env, DetailProcess
+
+class TestMonitorServer(unittest.TestCase):
+	
+	def test_Environment(self):
+		"""
+			This test case is designed to test the existance of a resource set as an environment variable. This applies to files, folders (not values)
+		"""
+		p = Env(['PATH','HOME','SHELL'])
+		value = p.composite()
+		self.assertTrue(value > 0 and value == 2/3)
+		self.assertTrue(p.evaluate('PATH') == 0)
+	def test_RunningProcess(self):
+		p = DetailProcess(['rabbitmq-server','python'])
+		print p.composite()
+if __name__ == '__main__' :
+	unittest.main()