From 21e82603cb9b2d60e3ddfbbd70392da3be376da1 Mon Sep 17 00:00:00 2001 From: steve Date: Mon, 12 Dec 2016 10:06:04 -0600 Subject: [PATCH] Testcases and refactor for MVP --- src/monitor.py | 159 ++++++++++++++++++++++++++++++++++++++ src/monitor.pyc | Bin 0 -> 7580 bytes test/TestServerMonitor.py | 19 +++++ 3 files changed, 178 insertions(+) create mode 100755 src/monitor.py create mode 100644 src/monitor.pyc create mode 100644 test/TestServerMonitor.py diff --git a/src/monitor.py b/src/monitor.py new file mode 100755 index 0000000..5ecbe61 --- /dev/null +++ b/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 \ No newline at end of file diff --git a/src/monitor.pyc b/src/monitor.pyc new file mode 100644 index 0000000000000000000000000000000000000000..098be59d949dd8af2327fadc14f089dd1cbf46b9 GIT binary patch literal 7580 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 literal 0 HcmV?d00001 diff --git a/test/TestServerMonitor.py b/test/TestServerMonitor.py new file mode 100644 index 0000000..89174ec --- /dev/null +++ b/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() \ No newline at end of file