class test_libHelperFunctions(unittest.TestCase): """ """ @classmethod def setUpClass(self): """ """ self.logger = CyLogger(debug_mode=True) self.logger.initializeLogs() self.logger.log(lp.DEBUG, "Test " + self.__name__ + " initialized...") @classmethod def tearDownClass(self): """ """ pass def test_FoundException(self): """ """ pass def test_get_os_vers(self): """ """ pass def test_get_os_minor_vers(self): """ """ pass
class test_ramdiskFactory(unittest.TestCase, GenericTestUtilities): """ """ @classmethod def setUpClass(self): """ Initializer """ unittest.SkipTest("Tests need to be written...") # Start timer in miliseconds self.test_start_time = datetime.now() self.logger = CyLogger() self.libcPath = None # initial initialization ##### # If we don't have a supported platform, skip this test. if not sys.platform.startswith("darwin") and \ not sys.platform.startswith("linux"): raise unittest.SkipTest("This is not valid on this OS") raise unittest.SkipTest("Not a supported tests....") def setUp(self): """ This method runs before each test run. @author: Roy Nielsen """ pass ############################################################################### ##### Method Tests ################################## def test_ramdiskFactoryFirstTest(self): """ """ pass ################################## def test_ramdiskFactorySecondTest(self): """ """ pass ############################################################################### ##### Functional Tests ############################################################################### ##### unittest Tear down @classmethod def tearDownClass(self): """ disconnect ramdisk """ self.logger = CyLogger() ##### # capture end time test_end_time = datetime.now() ##### # Calculate and log how long it took... test_time = (test_end_time - self.test_start_time) self.logger.log( lp.INFO, self.__module__ + " took " + str(test_time) + " time to complete...")
(opts, args) = parser.parse_args() log_level = "" if opts.debug: loglevel = 20 elif opts.verbose: loglevel = 30 else: loglevel = 40 logger = CyLogger(level=lp.DEBUG) logger.initializeLogs() logger.log(lp.DEBUG, "Logger initialized") os.environ['DEVELOPER_DIR'] = '/Applications/Xcode.app/Contents/Developer' keychainPass = False if opts.password: ##### # On the other end, each character was translated by 'ord' to a number, # and each number was separated by a colon. Change the password from # letters that have been converted to a number via the 'ord' function # back to the origional character passArray = opts.password.split(':') keychainPass = "" for orded in passArray: keychainPass = keychainPass + chr(int(orded))
class GenericTestUtilities(object): """ Generic class based Yutilities for ramdisk testing... @author: Roy Nielsen """ def __init__(self): """ Initialization Method... """ self.logger = CyLogger() self.getLibc() ################################################ ##### Helper Methods @classmethod def getLibc(self): """ """ ##### # For Mac try: libc = ctypes.CDLL("/usr/lib/libc.dylib") # libc = ctypes.CDLL("libc.dylib") except OSError: ##### # For Linux possible_paths = ["/lib/x86_64-linux-gnu/libc.so.6", "/lib/i386-linux-gnu/libc.so.6", "/usr/lib64/libc.so.6"] for path in possible_paths: if os.path.exists(path): libc = ctypes.CDLL(path) break try: if libc: libc.sync() except AttributeError: raise LibcNotAvailableError("............................Cannot Sync.") return libc ################################################ def findLinuxLibC(self): """ Find Linux Libc library... @author: Roy Nielsen """ possible_paths = ["/lib/x86_64-linux-gnu/libc.so.6", "/lib/i386-linux-gnu/libc.so.6"] for path in possible_paths: if os.path.exists(path): self.libcPath = path self.libc = ctypes.CDLL(self.libcPath) break ################################################ @classmethod def _pass(self): """ Filler if a library didn't load properly """ pass ################################################ def touch(self, fname="", message_level="normal"): """ Python implementation of the touch command.. @author: Roy Nielsen """ if re.match("^\s*$", str(fname)): self.logger.log(lp.WARNING, "Cannot touch a file without a filename....") else: try: os.utime(fname, None) except: try: open(fname, 'a').close() except Exception as err: self.logger.log(lp.WARNING, "Cannot open to touch: " + str(fname)) ################################################ def mkdirs(self, path=""): """ A function to do an equivalent of "mkdir -p" """ if not path: self.logger.log(lp.WARNING, "Bad path...") else: if not os.path.exists(str(path)): try: os.makedirs(str(path)) except OSError as err1: self.logger.log(lp.WARNING, "OSError exception attempting to create directory: " + str(path)) self.logger.log(lp.WARNING, "Exception: " + str(err1)) except Exception as err2: self.logger.log(lp.WARNING, "Unexpected Exception trying to makedirs: " + str(err2)) ################################################ def mkfile(self, file_path="", file_size=0, pattern="rand", block_size=512, mode=0o777): """ Create a file with "file_path" and "file_size". To be used in file creation benchmarking - filesystem vs ramdisk. @parameter: file_path - Full path to the file to create @parameter: file_size - Size of the file to create, in Mba @parameter: pattern - "rand": write a random pattern "0xXX": where XX is a hex value for a byte @parameter: block_size - size of blocks to write in bytes @parameter: mode - file mode, default 0o777 @returns: time in miliseconds the write took @author: Roy Nielsen """ total_time = 0 if file_path and file_size: self.libc.sync() file_size = file_size * 1024 * 1024 if os.path.isdir(file_path): tmpfile_path = os.path.join(file_path, "testfile") else: tmpfile_path = file_path self.logger.log(lp.DEBUG, "Writing to: " + tmpfile_path) try: # Get the number of blocks to create blocks = file_size/block_size # Start timer in miliseconds start_time = datetime.now() # do low level file access... tmpfile = os.open(tmpfile_path, os.O_WRONLY | os.O_CREAT, mode) # do file writes... for i in range(blocks): tmp_buffer = os.urandom(block_size) os.write(tmpfile, str(tmp_buffer)) os.fsync(tmpfile) self.libc.sync() os.close(tmpfile) self.libc.sync() os.unlink(tmpfile_path) self.libc.sync() # capture end time end_time = datetime.now() except Exception as err: self.logger.log(lp.WARNING, "Exception trying to write temp file for " + \ "benchmarking...") self.logger.log(lp.WARNING, "Exception thrown: " + str(err)) total_time = 0 else: total_time = end_time - start_time return total_time
(opts, args) = parser.parse_args() log_level = "" if opts.debug: loglevel = 20 elif opts.verbose: loglevel = 30 else: loglevel = 40 logger = CyLogger(level=lp.DEBUG) logger.initializeLogs() logger.log(lp.DEBUG, "Logger initialized") os.environ['DEVELOPER_DIR'] = '/Applications/Xcode.app/Contents/Developer' keychainPass = False if opts.password: ##### # On the other end, each character was translated by 'ord' to a number, # and each number was separated by a colon. Change the password from # letters that have been converted to a number via the 'ord' function # back to the origional character passArray = opts.password.split(':') keychainPass = "" for orded in passArray: keychainPass = keychainPass + chr(int(orded))
class MacBuilder(): def __init__(self, options=optparse.Values({"compileGui": False, "version": "0", "clean": False, "test": False, "debug":False, "sig":False}), ramdisk_size=1024): ''' Build .pkg and .dmg for stonix4mac @param ramdisk_size: int that defines ramdisk size in MB @param debug: to print debug messages ''' if isinstance(options.debug, bool) and options.debug: debug = 20 else: debug = 40 self.logger = CyLogger(level=debug) self.logger.initializeLogs() self.ramdisk_size = ramdisk_size self.libc = getLibc() if options.sig: self.codesignSignature = options.sig self.mbl = None # This script needs to be run from [stonixroot]/src/MacBuild; make sure # that is our current operating location cwd = os.getcwd() if not re.search("src/MacBuild$", cwd): print "This script needs to be run from src/MacBuild. Exiting..." exit(1) try: rmtree("/tmp/the_luggage") except OSError as e: if not e.errno == 2: raise if options.clean: self.clean() # If version was not included at command line, use hardcoded version # number if options.version == "0": self.APPVERSION = "0.9.5.0" else: self.APPVERSION = options.version self.compileGui = options.compileGui if not self.confParser(): raise ConfusingConfigurationError("Cannot determine the correct configuration...") self.RSYNC = "/usr/bin/rsync" print " " print " " print " ************************************************************" print " ************************************************************" print " ***** App Version: " + self.APPVERSION print " ************************************************************" print " ************************************************************" print " " print " " self.keyuser = raw_input("Keychain User: "******"Keychain Password: "******"HOME"] tmphome = mkdtemp(prefix=current_user + ".") os.environ["HOME"] = tmphome os.chmod(tmphome, 0755) # Create a ramdisk and mount it to the tmphome ramdisk = self.setupRamdisk(self.ramdisk_size, tmphome) os.mkdir("/tmp/the_luggage") luggage = self.setupRamdisk(self.ramdisk_size, "/tmp/the_luggage") print "Device for tmp ramdisk is: " + ramdisk # After creation of the ramdisk, all further calls need to be wrapped # in a try/except block so that the ramdisk will be detached before # exit try: # Copy src dir to /tmp/<username> so shutil doesn't freak about # long filenames. # ONLY seems to be a problem on Mavericks call([self.RSYNC, "-aqp", "--exclude=\".svn\"", "--exclude=\"*.tar.gz\"", "--exclude=\"*.dmg\"", self.STONIX_ROOT + "/src", tmphome]) # Compile .ui files to .py files if self.compileGui: self.compileStonix4MacAppUiFiles(tmphome + "/src/MacBuild/stonix4mac") # Change the versions in the program_arguments.py in both stonix # and stonix4mac self.setProgramArgumentsVersion(tmphome + "/src/stonix_resources/" + "localize.py") # Copy stonix source to scratch build directory self.prepStonixBuild(tmphome + "/src/MacBuild") # Compile the two apps... self.compileApp(self.STONIX, self.STONIXVERSION, self.STONIXICON, tmphome + "/src/MacBuild/" + self.STONIX) self.compileApp(self.STONIX4MAC, self.STONIX4MACVERSION, self.STONIX4MACICON, tmphome + "/src/MacBuild/" + self.STONIX4MAC) # Restore the HOME environment variable os.environ["HOME"] = directory # Copy and create all necessary resources to app resources dir. # This only gets called for stonix4mac self.buildStonix4MacAppResources(self.STONIX4MAC, tmphome + "/src/MacBuild", tmphome + "/src") # Create dmg and pkg with luggage self.buildStonix4MacAppPkg(self.STONIX4MAC, self.STONIX4MACVERSION, tmphome + "/src/MacBuild") # Copy back to pseudo-build directory call([self.RSYNC, "-aqp", tmphome + "/src", self.STONIX_ROOT]) os.chdir(self.STONIX_ROOT) self.mbl.chownR(current_user, "src") # chmod so it's readable by everyone, writable by the group self.mbl.chmodR(stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH | stat.S_IWGRP, "src", "append") # Return to the start dir os.chdir(self.STONIX_ROOT + "/src/MacBuild") except (KeyboardInterrupt, SystemExit): self.exit(ramdisk, luggage, 130) except Exception: self.exit(ramdisk, luggage, 1) # Eject the ramdisk self.detachRamdisk(ramdisk) self.detachRamdisk(luggage) print " " print " " print " Done building stonix4mac.app..." print " " print " " def setupRamdisk(self, size, mntpnt=""): ramdisk = RamDisk(str(size), mntpnt) if not ramdisk.success: print("Ramdisk setup failed...") raise Exception("Ramdisk setup failed...") return ramdisk.getDevice() def detachRamdisk(self, device): if detach(device): print("Successfully detached disk: " + str(device).strip()) return True else: print("Couldn't detach disk: " + str(device).strip()) raise Exception("Cannot eject disk: " + str(device).strip()) def exit(self, ramdisk, luggage, exitcode=0): os.chdir(self.STONIX_ROOT) self.detachRamdisk(ramdisk) self.detachRamdisk(luggage) print traceback.format_exc() exit(exitcode) def clean(self): ''' Clean all artifacts from previous builds. @author: Eric Ball ''' folders = (["dmgs", "stonix", "stonix4mac/dist", "stonix4mac/private"] + glob("stonix.*") + glob("dmgs.*")) files = (glob("*.pyc") + glob("stonix4mac/*.pyc") + glob("stonix4mac/*_ui.py") + glob("stonix4mac/*.spec")) for folder in folders: try: rmtree(folder) except OSError as e: if not e.errno == 2: raise for rmfile in files: os.remove(rmfile) exit(0) def compileStonix4MacAppUiFiles(self, stonix4macDir): ''' Compile the .ui files to .py files for stonix4mac.app. Works within the MacBuild/stonix4mac directory @author: Roy Nielsen, Eric Ball @param stonix4macDir: Path to the [stonixroot]/src/MacBuild/stonix4mac directory where this method should work ''' try: returnDir = os.getcwd() os.chdir(stonix4macDir) print "Starting compileStonix4MacAppUiFiles in " + os.getcwd() # to compile the .ui files to .py files: print "Compiling Qt ui files to python files for stonix4mac.app..." call([self.PYUIC, "admin_credentials.ui"], stdout=open("admin_credentials_ui.py", "w")) call([self.PYUIC, "stonix_wrapper.ui"], stdout=open("stonix_wrapper_ui.py", "w")) call([self.PYUIC, "general_warning.ui"], stdout=open("general_warning_ui.py", "w")) os.chdir(returnDir) except Exception: raise print "compileStonix4MacAppUiFiles Finished..." def setProgramArgumentsVersion(self, localizePath): ''' Change the STONIX version to the version specified within the build script @author: Roy Nielsen, Eric Ball @param localizePath: Path to the [stonixroot]/src/stonix_resources/ localize.py file that this method should modify ''' print "Changing versions in localize.py..." try: self.mbl.regexReplace(localizePath, r"^STONIXVERSION =.*$", r"STONIXVERSION = '" + self.APPVERSION + "'", backupname="../stonix_resources/localize.py.bak") except Exception: raise print "Finished changing versions in localize.py..." def prepStonixBuild(self, MacBuildDir): ''' Copy stonix source to app build directory @author: Roy Nielsen, Eric Ball @param MacBuildDir: Path to the [stonixroot]/src/MacBuild directory where this method should work ''' print "Starting prepStonixBuild..." try: returnDir = os.getcwd() os.chdir(MacBuildDir) # Make sure the "stonix" directory exists, so we can put # together and create the stonix.app if os.path.islink("stonix"): os.unlink("stonix") if not os.path.isdir("stonix"): os.mkdir("stonix") else: # Cannot use mkdtmp here because it will make the directory on # the root filesystem instead of the ramdisk, then it will try # to link across filesystems which won't work tmpdir = "stonix." + str(time()) os.rename("stonix", tmpdir) os.mkdir("stonix") copy2("../stonix.py", "stonix") call([self.RSYNC, "-ap", "--exclude=\".svn\"", "--exclude=\"*.tar.gz\"", "--exclude=\"*.dmg\"", "--exclude=\".git*\"", "../stonix_resources", "./stonix"]) os.chdir(returnDir) except Exception: raise print "prepStonixBuild Finished..." def compileApp(self, appName, appVersion, appIcon, appPath): ''' Compiles stonix4mac.app @author: Roy Nielsen, Eric Ball @param appName: Name of application as it should appear on OS X systems @param appVersion: Version of app being built @param appIcon: File name of icon for OS X app @param appPath: Path to [stonixroot]/src/MacBuild/[appName] ''' print "Started compileApp with " + appName + ", " + appVersion + \ ", " + appIcon try: returnDir = os.getcwd() os.chdir(appPath) self.logger.log(lp.DEBUG, "...") self.logger.log(lp.DEBUG, "...") self.logger.log(lp.DEBUG, "...") self.logger.log(lp.DEBUG, "\n\n\tPWD: " + appPath + " \n\n") myfiles = os.listdir('.') self.logger.log(lp.DEBUG, "\n\tDIRS: " + str(myfiles)) self.logger.log(lp.DEBUG, "...") self.logger.log(lp.DEBUG, "...") self.logger.log(lp.DEBUG, "...") if os.path.isdir("build"): rmtree("build") if os.path.isdir("dist"): rmtree("dist") self.logger.log(lp.DEBUG, "Hidden imports: " + str(self.hiddenimports)) hdnimports = self.hiddenimports + ['ctypes', '_ctypes', 'ctypes._endian', 'decimal', 'numbers'] # to compile a pyinstaller spec file for app creation: print "Creating a pyinstaller spec file for the project..." print self.mbl.pyinstMakespec([appName + ".py"], True, True, False, "../" + appIcon + ".icns", pathex=["stonix_resources/rules", "stonix_resources", "/usr/lib"] + self.PYPATHS, specpath=os.getcwd(), hiddenimports=hdnimports) ''' if appName == "stonix": fo = open(appName + ".spec", "r") spectext = fo.read() fo.close() spectext = spectext.replace("hiddenimports=[]", "hiddenimports=['ctypes', " + "'_ctypes', 'ctypes._endian', " + "'decimal', 'numbers']") fo = open(appName + ".spec", "w") fo.write(spectext) fo.close() ''' # to build: print "Building the app..." self.mbl.pyinstBuild(appName + ".spec", "private/tmp", appPath + "/dist", True, True) plist = appPath + "/dist/" + appName + ".app/Contents/Info.plist" # Change version string of the app print "Changing .app version string..." self.mbl.modplist(plist, "CFBundleShortVersionString", appVersion) # Change icon name in the app print "Changing .app icon..." self.mbl.modplist(plist, "CFBundleIconFile", appIcon + ".icns") # Copy icons to the resources directory copy2("../" + appIcon + ".icns", "./dist/" + appName + ".app/Contents/Resources") # Change mode of Info.plist to 0755 os.chmod(plist, 0755) os.chdir('dist') except Exception: raise print "compileApp with " + appName + ", " + appVersion + " Finished..." def buildStonix4MacAppResources(self, appName, appPath, appPathParent): ''' Copy and/or create all necessary files to the Resources directory of stonix4mac.app @author: Roy Nielsen, Eric Ball @param appName: Name of application as it should appear on OS X systems @param appPath: Path to [stonixroot]/src/MacBuild/[appName] ''' print "Started buildStonix4MacAppResources with \"" + appName + \ "\" in " + appPath + "..." try: returnDir = os.getcwd() os.chdir(appPath) # Copy source to app dir call([self.RSYNC, "-aqp", "--exclude=\".svn\"", "--exclude=\"*.tar.gz\"", "--exclude=\"*.dmg\"", "--exclude=\".git*\"", appPathParent + "/stonix_resources", appPath + "/stonix/dist/stonix.app/Contents/MacOS"]) # Copy stonix.app to the stonix4mac Resources directory call([self.RSYNC, "-aqp", "--exclude=\".svn\"", "--exclude=\"*.tar.gz\"", "--exclude=\"*.dmg\"", "--exclude=\".git*\"", appPath + "/stonix/dist/stonix.app", "./" + appName + "/dist/" + appName + ".app/Contents/Resources"]) # Copy the stonix.conf file copy2(appPath + "/../etc/stonix.conf", appPath + "/" + appName + "/dist/" + appName + ".app/Contents/Resources/stonix.conf") copy2(appPath + "/stonix/dist/stonix.app/Contents/MacOS/" + "stonix_resources/localize.py", appPath + "/" + appName + "/dist/" + appName + ".app/Contents/MacOS") ##### # Copy helper files to the resources directory call([self.RSYNC, "-aqp", appPath + '/' + appName + '/Resources/', appPath + "/" + appName + "/dist/" + appName + \ ".app/Contents/Resources"]) ##### # Need a disk checkpoint here to make sure all files are flushed # to disk, ie perform a filesystem sync. self.libc.sync() self.libc.sync() self.mbl.codeSign(self.keyuser, self.keypass, self.codesignSignature, self.codesignVerbose, self.codesignDeep, "./" + appName + "/dist/" + appName + ".app") self.mbl.codeSign(self.keyuser, self.keypass, self.codesignSignature, self.codesignVerbose, self.codesignDeep, "./" + appName + "/dist/" + appName + ".app/Contents/Resources/stonix.app") os.chdir(returnDir) except Exception: raise print "buildStonix4MacAppResources Finished..." def buildStonix4MacAppPkg(self, appName, appVersion, appPath): ''' Build installer package and wrap into a dmg @author: Roy Nielsen, Eric Ball @param appName: Name of application as it should appear on OS X systems @param appVersion: Version of app being built @param appPath: Path to [stonixroot]/src/MacBuild ''' print "Started buildStonix4MacAppPkg..." try: returnDir = os.getcwd() os.chdir(appPath + "/" + appName) print "Putting new version into Makefile..." self.mbl.regexReplace("Makefile", r"PACKAGE_VERSION=", "PACKAGE_VERSION=" + appVersion) if not os.path.isdir(appPath + "/dmgs"): os.mkdir(appPath + "/dmgs") else: # Cannot use mkdtmp here because it will make the directory on # the root filesystem instead of the ramdisk, then it will try # to link across filesystems which won't work tmpdir = appPath + "/dmgs." + str(time()) os.rename(appPath + "/dmgs", tmpdir) os.mkdir(appPath + "/dmgs") print "Creating a .dmg file with a .pkg file inside for " + \ "installation purposes..." #call(["make", "dmg", "PACKAGE_VERSION=" + appVersion, # "USE_PKGBUILD=1"]) call(["make", "pkg", "PACKAGE_VERSION=" + appVersion, "USE_PKGBUILD=1"]) print "Moving dmg and pkg to the dmgs directory." #dmgname = appName + "-" + appVersion + ".dmg" pkgname = appName + "-" + appVersion + ".pkg" #os.rename(dmgname, appPath + "/dmgs/" + dmgname) os.rename(pkgname, appPath + "/dmgs/" + pkgname) os.chdir(returnDir) except Exception: raise print "buildStonix4MacAppPkg... Finished" def configSectionMap(self, section): ''' Acquire values from the config file and store in a dictionary. @author: rsn ''' dict1 = {} options = self.parser.options(section) for option in options: try: dict1[option] = self.parser.get(section, option) if dict1[option] == -1: self.logger.log(lp.DEBUG, "skip: %s" % option) except: print("exception on %s!" % option) dict1[option] = None print dict1 return dict1 def confParser(self): """ Parse a config file to find potential conf file settings. @author: rsn """ success = False # This script should be run from [stonixroot]/src/MacBuild. We must os.chdir("../..") self.STONIX_ROOT = os.getcwd() os.chdir("src/MacBuild") macbuild_root = os.getcwd() myconf = os.path.join(macbuild_root, 'macbuild.conf') print myconf if os.path.isfile(myconf): self.parser = SafeConfigParser() candidates = [myconf, 'not_a_real_conf.conf'] found = self.parser.read(candidates) missing = set(candidates) - set(found) try: dict1 = {} for section in self.parser.sections(): dict1[section] = self.configSectionMap(section) print dict1 except: ##### # happens if there was a problem attempting to read the config # file, Initializing class variables. self.STONIX = "stonix" self.STONIXICON = "stonix_icon" self.STONIXVERSION = self.APPVERSION self.STONIX4MAC = "stonix4mac" self.STONIX4MACICON = "stonix_icon" self.STONIX4MACVERSION = self.APPVERSION #-- Internal libraries from macbuildlib import macbuildlib self.mbl = macbuildlib(self.logger) self.PYUIC = self.mbl.getpyuicpath() self.codesignVerbose = 'vvvv' self.codesignDeep = True else: ##### # Config file read, initializing class variables. self.STONIX = dict1['stonix']['app'] self.STONIXICON = dict1['stonix']['app_icon'] self.STONIXVERSION = dict1['stonix']['app_version'] self.STONIX4MAC = dict1['stonix']['wrapper'] self.STONIX4MACICON = dict1['stonix']['wrapper_icon'] self.STONIX4MACVERSION = dict1['stonix']['wrapper_version'] self.PYUIC = dict1['libpaths']['pyuic'] self.PYPATHS = dict1['libpaths']['pythonpath'].split(':') self.logger.log(lp.INFO, 'attempting to get codesigning information...') self.codesignVerbose = dict1['codesign']['verbose'] if re.match('^True$', dict1['codesign']['deep']): self.codesignDeep = True else: self.codesignDeep = False self.logger.log(lp.INFO, "Grabbed codesign info...") for path in self.PYPATHS: sys.path.append(path) #-- Internal libraries try: from macbuildlib import macbuildlib self.mbl = macbuildlib(self.logger, self.PYPATHS) except Exception, err: raise self.logger.log(lp.INFO, "... macbuildlib loaded ...") finally:
class test_run_commands(unittest.TestCase): """ """ @classmethod def setUpClass(self): """ """ ##### # Set up logging self.logger = CyLogger(debug_mode=True) self.logger.initializeLogs() self.rw = RunWith(self.logger) ##### # Start timer in miliseconds self.test_start_time = datetime.now() @classmethod def tearDownClass(self): """ """ pass def test_RunCommunicateWithBlankCommand(self): self.rw.__init__(self.logger) self.assertRaises(SetCommandTypeError, self.rw.setCommand, "") self.assertRaises(SetCommandTypeError, self.rw.setCommand, []) self.assertRaises(SetCommandTypeError, self.rw.setCommand, None) self.assertRaises(SetCommandTypeError, self.rw.setCommand, True) self.assertRaises(SetCommandTypeError, self.rw.setCommand, {}) def test_setCommand(self): self.rw.__init__(self.logger) command = ['/bin/ls', 1, '.'] self.assertRaises(SetCommandTypeError, self.rw.setCommand, [command]) def test_communicate(self): """ """ self.rw.__init__(self.logger) self.logger.log(lp.DEBUG, "=============== Starting test_communicate...") self.rw.setCommand('/bin/ls /var/spool', myshell=True) _, _, retval = self.rw.communicate(silent=False) self.assertEqual(retval, 0, "Valid [] command execution failed: " + '/bin/ls /var/spool --- retval: ' + str(retval)) self.rw.setCommand(['/bin/ls', '-l', '/usr/local']) _, _, retval = self.rw.communicate(silent=False) self.assertEqual(retval, 0, "Valid [] command execution failed: " + '/bin/ls /var/spool --- retval: ' + str(retval)) self.logger.log(lp.DEBUG, "=============== Ending test_communicate...") def test_wait(self): """ """ self.rw.__init__(self.logger) self.logger.log(lp.DEBUG, "=============== Starting test_wait...") self.rw.setCommand('/bin/ls /var/spool') try: _, _, retval = self.rw.communicate(silent=False) except Exception as err: self.logger.log(lp.ERROR, traceback.format_exc()) # raise err self.assertEqual(retval, 0, "Valid [] command execution failed: " + '/bin/ls /var/spool --- retval: ' + str(retval)) self.rw.setCommand(['/bin/ls', '-l', '/usr/local']) try: _, _, retval = self.rw.communicate(silent=False) except Exception as err: self.logger.log(lp.ERROR, traceback.format_exc()) # raise err self.assertEqual(retval, 0, "Valid [] command execution failed: " + '/bin/ls -l /usr/local --- retval: ' + str(retval)) ''' temporarily commented out may not work the same on python 3.10.x self.rw.setCommand(['/bin/ls', '/1', '/']) tracemalloc.start(25) try: _, _, retcode = self.rw.wait() except Exception as err: self.logger.log(lp.ERROR, traceback.format_exc()) retcode = 99999 # raise err self.logger.log(lp.WARNING, "retcode: " + str(retcode)) if sys.platform == 'darwin': self.assertEqual(retcode, 1, "Returncode Test failed...") else: self.assertEqual(retcode, 2, "Returncode Test failed...") ''' self.logger.log(lp.DEBUG, "=============== Completed test_wait...") @unittest.skip("temporary skip to determine if split stdout/stderr could be the problem...") def test_waitNpassThruStdout(self): """ """ self.rw.__init__(self.logger) self.logger.log(lp.DEBUG, "=============== Starting test_wait...") tracemalloc.start(25) self.rw.setCommand(['/bin/ls', '-l', '/usr/local']) try: _, _, retval = self.rw.waitNpassThruStdout() self.assertEqual(retval, 0, "Valid [] command execution failed: " + '/bin/ls /var/spool --- retval: ' + str(retval)) except Exception as err: self.logger.log(lp.ERROR, traceback.format_exc()) # raise err self.logger.log(lp.INFO, "...first subtest done...") self.rw.setCommand(['/bin/ls', '/1', '/']) try: _, _, retval = self.rw.waitNpassThruStdout() except Exception as err: self.logger.log(lp.ERROR, traceback.format_exc()) # raise err if sys.platform == 'darwin': self.assertEqual(retval, 1, "Returncode Test failed...") else: self.assertEqual(retval, 2, "Returncode Test failed...") self.logger.log(lp.DEBUG, "=============== Completed test_wait...") def test_timeout(self): """ """ self.rw.__init__(self.logger) tracemalloc.start(25) if os.path.exists("/sbin/ping"): ping = "/sbin/ping" elif os.path.exists('/bin/ping'): ping = "/bin/ping" self.rw.setCommand([ping, '-c', '12', '8.8.8.8']) try: startTime = time.time() self.rw.timeout(3) elapsed = (time.time() - startTime) except Exception as err: self.logger.log(lp.ERROR, traceback.format_exc()) # raise err finally: self.logger.log(lp.INFO, "elapsed time: " + str(elapsed)) self.assertTrue(elapsed < 4, "Elapsed time is greater than it should be...") def test_runAs(self): """ """ pass def test_liftDown(self): """ """ pass def test_runAsWithSudo(self): """ """ pass def test_runWithSudo(self): """ """ pass def test_getecho(self): """ """ pass def test_waitnoecho(self): """ """ pass def test_RunThread(self): """ """ pass def test_runMyThreadCommand(self): """ """ pass
class test_CheckApplicable(unittest.TestCase): """ """ ################################## @classmethod def setUpClass(self): """ """ ##### # Set up logging self.logger = CyLogger(debug_mode=True) self.logger.initializeLogs() self.rw = RunWith(self.logger) self.enviro = Environment() self.ca = CheckApplicable(self.enviro, LOGGER) ##### # Start timer in miliseconds self.testStartTime = datetime.now() ################################## @classmethod def tearDownClass(self): """ """ ##### # capture end time testEndTime = datetime.now() ##### # Calculate and log how long it took... test_time = (testEndTime - self.testStartTime) # print str(test_time) # global LOGGER self.logger.log(lp.INFO, self.__module__ + " took " + str(test_time) + " time so far...") ################################## def testCheckRedHatApplicable(self): """ """ self.ca.setOsFamily ################################## def testCheckLinuxApplicable(self): """ """ ################################## def testCheckDebianApplicable(self): """ """ ################################## def testCheckUbuntuApplicable(self): """ """ ################################## def testCheckCentOS6Applicable(self): """ """ ################################## def testCheckCentOS7Applicable(self): """ """ ################################## def testCheckMacOS1011Applicable(self): """ """ ################################## def testCheckMacOS1011to12Applicable(self): """ """ ################################## def testCheckMacOS1011to13Applicable(self): """
class test_libHelperExceptions(unittest.TestCase): """ """ @classmethod def setUpClass(self): """ Initializer """ unittest.SkipTest("Tests need to be written...") # Start timer in miliseconds self.test_start_time = datetime.now() self.logger = CyLogger() self.logger.initializeLogs() self.libcPath = None # initial initialization def setUp(self): """ This method runs before each test run. @author: Roy Nielsen """ self.libcPath = None # initial initialization ##### # setting up to call ctypes to do a filesystem sync if sys.platform.startswith("darwin"): ##### # For Mac self.libc = C.CDLL("/usr/lib/libc.dylib") elif sys.platform.startswith("linux"): ##### # For Linux self.findLinuxLibC() self.libc = C.CDLL(self.libcPath) else: self.libc = self._pass() ############################################################################### ##### Helper Classes def setMessageLevel(self, msg_lvl="normal"): """ Set the logging level to what is passed in. """ self.message_level = msg_lvl def findLinuxLibC(self): """ Find Linux Libc library... @author: Roy Nielsen """ possible_paths = [ "/lib/x86_64-linux-gnu/libc.so.6", "/lib/i386-linux-gnu/libc.so.6" ] for path in possible_paths: if os.path.exists(path): self.libcPath = path break def _pass(self): """ Filler if a library didn't load properly """ pass ############################################################################### ##### Method Tests ################################## def test_init(self): """ """ pass ################################## ############################################################################### ##### Functional Tests ################################## ############################################################################### ##### unittest Tear down @classmethod def tearDownClass(self): """ disconnect ramdisk """ # self.logger = CyLogger() ##### # capture end time test_end_time = datetime.now() ##### # Calculate and log how long it took... test_time = (test_end_time - self.test_start_time) self.logger.log(lp.INFO, self.__module__ + " took " + str(test_time) + \ " time to complete...")
action="store_true", dest="verbose", default=0, help="Print status messages") (opts, args) = parser.parse_args() if opts.verbose != 0: level = CyLogger(level=lp.INFO) elif opts.debug != 0: level = CyLogger(level=lp.DEBUG) else: level = lp.WARNING if (not isinstance(opts.device, str) and \ re.match("^[A-Za-z0-9/]+$", opts.device)) or not opts.device: print("Cannot detach a device with no name..") parser.print_help() else: device = opts.device logger = CyLogger(level=level) logger.initializeLogs() if detach(device): logger.log(lp.INFO, r"Successfully detached disk: " + str(device).strip()) else: logger.log(lp.ERROR, r"Couldn't detach disk: " + str(device).strip()) parser.print_help()
username = input("Username: "******"Password: "******"New Password: "******"Repeat New Password: "******"huh?" klock_success = "huh?" kpass_success = "huh?" if oneNewPass == twoNewPass: logger.log(lp.DEBUG, "One and two match, proceeding...") try: mu.setUserName(username) upass_success = mu.setUserPassword(username, oneNewPass, oldPass) except: raise Exception(traceback.format_exc()) print(str(upass_success)) mk.setUser(username) keychain = "/Users/" + username + "/Library/Keychains/login.keychain" try: klock_success = mk.lockKeychain(keychain) kpass_success = mk.deleteKeychain(keychain) kpass_success = mk.createKeychain(oneNewPass, keychain) except Exception: message = "Exception attempting to change the " + keychain + \ " password.. \n" + traceback.format_exc()
class RamDiskTemplate(object): """ """ def __init__(self, size=0, mountpoint=False, logger=False): """ """ ##### # Version/timestamp is # <YYYY><MM><DD>.<HH><MM><SS>.<microseconds> # in UTC time self.module_version = '20160224.032043.009191' if not isinstance(logger, CyLogger): self.logger = CyLogger() else: self.logger = logger self.logger.log(lp.INFO, "Logger: " + str(self.logger)) self.diskSize = size self.success = False self.myRamdiskDev = None if not mountpoint: self.getRandomizedMountpoint() else: self.mntPoint = mountpoint self.logger.log(lp.DEBUG, "disk size: " + str(self.diskSize)) self.logger.log(lp.DEBUG, "volume name: " + str(self.mntPoint)) ########################################################################### def getData(self): """ Getter for mount data, and if the mounting of a ramdisk was successful Does not print or log the data. @author: Roy Nielsen """ return (self.success, str(self.mntPoint), str(self.myRamdiskDev)) ########################################################################### def getNlogData(self): """ Getter for mount data, and if the mounting of a ramdisk was successful Also logs the data. @author: Roy Nielsen """ self.logger.log(lp.INFO, "Success: " + str(self.success)) self.logger.log(lp.INFO, "Mount point: " + str(self.mntPoint)) self.logger.log(lp.INFO, "Device: " + str(self.myRamdiskDev)) return (self.success, str(self.mntPoint), str(self.myRamdiskDev)) ########################################################################### def getNprintData(self): """ Getter for mount data, and if the mounting of a ramdisk was successful """ print("Success: " + str(self.success)) print("Mount point: " + str(self.mntPoint)) print("Device: " + str(self.myRamdiskDev)) return (self.success, str(self.mntPoint), str(self.myRamdiskDev)) ########################################################################### def getRandomizedMountpoint(self): """ Create a randomized (secure) mount point - per python's implementation of mkdtemp - a way to make an unguessable directory on the system @author: Roy Nielsen """ success = False self.mntPoint = "" try: self.mntPoint = mkdtemp() except Exception as err: self.logger.log(lp.WARNING, "Exception trying to create temporary directory") raise err else: success = True self.logger.log( lp.WARNING, "Success: " + str(success) + " in get_randomizedMountpoint: " + str(self.mntPoint)) self.logger.log( lp.WARNING, "Randomized mount point: \"" + str(self.mntPoint) + "\"") return success ########################################################################### def umount(self): """ Unmount the disk - same functionality as __eject on the mac Must be over-ridden to provide OS/Method specific functionality @author: Roy Nielsen """ success = False return success ########################################################################### def unmount(self): """ Unmount the disk - same functionality as __eject on the mac Must be over-ridden to provide OS/Method specific functionality @author: Roy Nielsen """ success = False return success ########################################################################### def __isMemoryAvailable(self): """ Check to make sure there is plenty of memory of the size passed in before creating the ramdisk @author: Roy Nielsen """ success = False return success ########################################################################### def _format(self): """ Format the ramdisk Must be over-ridden to provide OS/Method specific functionality @author: Roy Nielsen """ success = False return success ########################################################################### def getDevice(self): """ Getter for the device name the ramdisk is using Must be over-ridden to provide OS/Method specific functionality @author: Roy Nielsen """ return self.myRamdiskDev ########################################################################### def getMountPoint(self): """ Getter for the mount point name the ramdisk is using Must be over-ridden to provide OS/Method specific functionality @author: Roy Nielsen """ return self.mntPoint ########################################################################### def setDevice(self, device=None): """ Setter for the device so it can be ejected. Must be over-ridden to provide OS/Method specific functionality @author: Roy Nielsen """ self.myRamdiskDev = device ########################################################################### def getVersion(self): """ Getter for the version of the ramdisk Must be over-ridden to provide OS/Method specific functionality @author: Roy Nielsen """ return self.module_version
class SoftwareBuilder(): '''Class to manage the build process. Initially used with the Stonix project on the Mac platform, will be used for others as well. ''' def __init__(self, options=optparse.Values({"compileGui": False, "version": "0", "clean": False, "test": False, "debug":False, "sig":False, "hiddenImports":False, "keychain":''}), ramdisk_size=1600): ''' Initialization routine. @param: compileGui - bool to determine if the gui should be compiled or not @param: version - if passed in, the version to use for app and package creation. @param: clean - bool to determine whether or not to clean artifacts from previous builds @param: test - Don't run the driver - specifically for unit testing @param: debug - bool to determine whether or not to log in debug mode @param: sig - signature to use for application and package signing in the build process ''' if isinstance(options.debug, bool) and options.debug: debug = 20 else: debug = 40 # format log file name according to tracker artf55027 datestamp = datetime.datetime.now() stamp = datestamp.strftime("%Y-%m-%d_%H-%M-%S") log_name = "build-output_" + str(stamp) + ".log" # set macbuild logging path according to tracker artf55027 try: log_path = os.path.dirname(os.path.realpath(__file__)) except (IOError, OSError, AttributeError): log_path = os.getcwd() ##### # helper class initialization self.logger = CyLogger(level=debug) # initialize the logger object to log macbuild.py logs according to tracker artf55027 self.logger.initializeLogs(logdir=log_path, filename=log_name) self.rw = RunWith(self.logger) self.mu = ManageUser(self.logger) self.mk = ManageKeychain(self.logger) self.ramdisk_size = ramdisk_size self.libc = getLibc() ##### # Handle command line options self.mbl = None self.signature = options.sig self.includeHiddenImports = options.hiddenImports self.keychain = options.keychain self.noExit = options.noExit # This script needs to be run from [stonixroot]/src/MacBuild; make sure # that is our current operating location cwd = os.getcwd() if not re.search("src/MacBuild$", cwd): print("This script needs to be run from src/MacBuild. Exiting...") exit(1) try: rmtree("/tmp/the_luggage") except OSError as e: if not e.errno == 2: raise #if options.clean: # self.clean() if FISMACAT is not None and FISMACAT != '': self.FISMACAT = FISMACAT else: self.FISMACAT = "low" # If version was not included at command line, use hardcoded version # number if options.version == "0": self.APPVERSION = "0.9.5.1" else: self.APPVERSION = options.version self.compileGui = options.compileGui if not self._configParser(): raise ConfusingConfigurationError("Cannot determine the correct configuration...") self.RSYNC = "/usr/bin/rsync" print(" ") print(" ") print(" ************************************************************") print(" ************************************************************") print((" ***** App Version: " + self.APPVERSION)) print(" ************************************************************") print(" ************************************************************") print(" ") print(" ") if self.signature: count = 0 while count < 3: success = False self.keyuser = os.environ['SUDO_USER'] self.keypass = getpass.getpass("Keychain Password: "******"Sorry, Keychain password is not valid... Please try again.") count += 1 if not success: sys.exit(1) ##### # Get a translated password self.ordPass = self.getOrdPass(self.keypass) else: self.keyuser = getpass.getuser() self.keypass = False self.ordPass = False if not options.test: self.driver() #-------------------------------------------------------------------------- # Private support methods def _setupRamdisk(self, size, mntpnt=""): ramdisk = RamDisk(str(size), mntpnt) if not ramdisk.success: print("Ramdisk setup failed...") raise Exception("Ramdisk setup failed...") return ramdisk.getDevice() def _detachRamdisk(self, device): if detach(device): print("Successfully detached disk: " + str(device).strip()) return True else: print("Couldn't detach disk: " + str(device).strip()) raise Exception("Cannot eject disk: " + str(device).strip()) def _exit(self, ramdisk, luggage, exitcode=0): os.chdir(self.STONIX_ROOT) self._detachRamdisk(ramdisk) self._detachRamdisk(luggage) print((traceback.format_exc())) exit(exitcode) def _configSectionMap(self, section): '''Acquire values from the config file and store in a dictionary. @author: rsn :param section: ''' dict1 = {} options = self.parser.options(section) for option in options: try: dict1[option] = self.parser.get(section, option) if dict1[option] == -1: self.logger.log(lp.DEBUG, "skip: %s" % option) except: print("exception on %s!" % option) dict1[option] = None print(dict1) return dict1 def _configParser(self): '''Parse config file and instanciate/initialize class variables from config file data. ''' success = False # This script should be run from [stonixroot]/src/MacBuild. We must os.chdir("../..") self.STONIX_ROOT = os.getcwd() os.chdir("src/MacBuild") macbuild_root = os.getcwd() myconf = os.path.join(macbuild_root, 'build.conf') print(myconf) self.logger.log(lp.INFO, "... macbuildlib loaded ...") self.PYPATHS = [] try: if not os.path.isfile(myconf): raise ConfusingConfigurationError("Configuration File Does Not Exist...") self.parser = ConfigParser() candidates = [myconf, 'not_a_real_conf.conf'] found = self.parser.read(candidates) missing = set(candidates) - set(found) dict1 = {} for section in self.parser.sections(): dict1[section] = self._configSectionMap(section) print(dict1) except: self.STONIX = "stonix" self.STONIXICON = "stonix_icon" self.STONIXVERSION = self.APPVERSION self.STONIX4MAC = "stonix4mac" self.STONIX4MACICON = "stonix_icon" self.STONIX4MACVERSION = self.APPVERSION self.mbl = MacBuildLib(self.logger) self.PYUIC = self.mbl.getpyuicpath() self.codesignVerbose = 'vvvv' self.codesignDeep = True if self.signature: self.doCodesign = True else: self.doCodesign = False else: self.STONIX = dict1['stonix']['app'] self.STONIXICON = "stonix_icon" self.STONIXVERSION = dict1['stonix']['app_version'] self.STONIX4MAC = dict1['stonix']['wrapper'] self.STONIX4MACICON = "stonix_icon" self.STONIX4MACVERSION = dict1['stonix']['wrapper_version'] self.APPVERSION = self.STONIXVERSION self.PYUIC = dict1['libpaths']['pyuic'] self.PYPATHS = dict1['libpaths']['pythonpath'].split(':') if self.PYPATHS: self.mbl = MacBuildLib(self.logger, self.PYPATHS) else: self.mbl = MacBuildLib(self.logger) self.logger.log(lp.INFO, 'attempting to get codesigning information...') self.codesignVerbose = dict1['codesign']['verbose'] if re.match('^True$', dict1['codesign']['ask']) or self.signature: self.doCodesign = True else: self.doCodesign = False if re.match('^True$', dict1['codesign']['deep']): self.codesignDeep = True else: self.codesignDeep = False self.logger.log(lp.INFO, "Grabbed codesign info...") for path in self.PYPATHS: sys.path.append(path) #-- Internal libraries finally: success = True return success def getOrdPass(self, passwd=''): '''Get the password translated to a direct ascii pattern of: "[\d+:]\d+" for use when in the need of passing it via self.rw.liftDown() ##### # Prepare for transport of the password to the xcodebuild.py # builder. This is not encryption, this is just encoding, using # similar to UTF encoding of various languages. # The standard python 'ord' function, to allow for special # characters to be passed, that may be consumed by a shell in # the process of passing the password to the other python script. :param passwd: (Default value = '') :returns: s: translated password ''' i = 0 ordPass = "" for char in self.keypass: i += 1 if i == 1: ordPass += str(ord(char)) else: ordPass += ':' + str(ord(char)) self.logger.log(lp.INFO, str(ordPass)) return str(ordPass) #-------------------------------------------------------------------------- # Main controller/driver for the class def driver(self): '''The driver orchestrates the build process.''' # Check that user building stonix has uid 0 current_user, _ = self.mbl.checkBuildUser() ##### # The driver needs to be run inside a try/except block to make sure to # call the tearDown method in case of an exception before exit. try: self.setUp() ##### # Process Stonix self.preCompile(self.STONIX, self.tmphome + "/src/MacBuild/") # Compile the two apps... self.compile(self.STONIX, self.STONIXVERSION, self.STONIXICON, self.tmphome + "/src/MacBuild/" + self.STONIX) self.postCompile(self.STONIX, self.tmphome + "/src/MacBuild/") ##### # Process stonix4mac self.preCompile(self.STONIX4MAC, self.tmphome + "/src/MacBuild/") self.compile(self.STONIX4MAC, self.STONIX4MACVERSION, self.STONIX4MACICON, self.tmphome + "/src/MacBuild/" + \ self.STONIX4MAC) self.postCompile(self.STONIX4MAC, self.tmphome + "/src/MacBuild/") ##### # Create the installer self.makeInstaller(self.STONIX4MAC, self.STONIXVERSION, self.tmphome + \ "/src/MacBuild/") except (KeyboardInterrupt, SystemExit): print((traceback.format_exc())) except Exception: print((traceback.format_exc())) finally: self.tearDown() #-------------------------------------------------------------------------- # Interface support methods def setUp(self): '''Performing build setup for the whole process.''' success = False try: # Check that user building stonix has uid 0 current_user, _ = self.mbl.checkBuildUser() # Create temp home directory for building with pyinstaller self.buildHome = os.getcwd() self.directory = os.environ["HOME"] self.tmphome = mkdtemp(prefix=current_user + ".", dir="/tmp") os.environ["HOME"] = self.tmphome os.chmod(self.tmphome, 0o755) # Create a ramdisk and mount it to the tmphome self.ramdisk = self._setupRamdisk(self.ramdisk_size, self.tmphome) os.mkdir("/tmp/the_luggage") self.luggage = self._setupRamdisk(self.ramdisk_size, "/tmp/the_luggage") print(("Device for tmp ramdisk is: " + self.ramdisk)) print(".") print(".") print(".") rsync = [self.RSYNC, "-apv", "--exclude=\".svn\"", "--exclude=\"*.tar.gz\"", "--exclude=\"*.dmg\"", "../../src", self.tmphome] print((str(rsync))) print(".") print(".") print(".") output = Popen(rsync, stdout=PIPE, stderr=STDOUT).communicate()[0] print(("\t\trsync output: " + str(output))) print(".") print(".") print(".") except Exception as err: print((traceback.format_exc())) self.logger.log(lp.WARNING, "Problem setting up ramdisks, not likely to succeed...") raise err else: success = True return success def preCompile(self, appName, prepPath): ''' :param appName: :param prepPath: ''' success = False self.libc.sync() sleep(1) self.libc.sync() sleep(1) returnDir = os.getcwd() os.chdir(prepPath) self.libc.sync() sleep(1) self.libc.sync() sleep(1) try: if appName == 'stonix': ##### # Build an __init__.py for the rules directory with all of the # rules imported, so they get included in the python frozen # package # currentDirPathList = os.path.dirname(os.path.abspath(__file__)).split("/") rulesDir = self.tmphome + "/src/stonix_resources/rules" self.logger.log(lp.DEBUG, "---------------------+++===") self.logger.log(lp.DEBUG, "---------------------+++===") self.logger.log(lp.DEBUG, "---------------------+++===") self.logger.log(lp.DEBUG, "rulesDir: " + rulesDir) self.logger.log(lp.DEBUG, "---------------------+++===") self.logger.log(lp.DEBUG, "---------------------+++===") self.logger.log(lp.DEBUG, "---------------------+++===") if not self.mbl.writeInit(rulesDir): raise ValueError("No success Jim!") ##### # Acquire hidden imports to include in the pyinstaller # compiled binaries if self.includeHiddenImports: self.hiddenImports = self.mbl.getHiddenImports(self.tmphome + "/src/", "stonix_resources") else: self.hiddenImports = [] self.logger.log(lp.DEBUG, "Hidden imports: " + str(self.hiddenImports)) # Copy src dir to /tmp/<username> so shutil doesn't freak about # long filenames. # ONLY seems to be a problem on Mavericks ##### # Set the stonix version number correctly self.mbl.regexReplace(self.tmphome + "/src/stonix_resources/localize.py", r"^STONIXVERSION =.*$", r"STONIXVERSION = '" + self.APPVERSION + "'", backupname="../stonix_resources/localize.py.bak") ##### # Make sure the "stonix" directory exists, so we can put # together and create the stonix.app if os.path.islink(self.tmphome + "/src/MacBuild/stonix"): os.unlink(self.tmphome + "/src/MacBuild/stonix") elif os.path.isfile(self.tmphome + "/src/MacBuild/stonix"): ##### # Cannot use mkdtmp here because it will make the directory on # the root filesystem instead of the ramdisk, then it will try # to link across filesystems which won't work tmpdir = self.tmphome + "/src/MacBuild/stonix." + str(time()) os.rename(self.tmphome + "/src/MacBuild/stonix", tmpdir) os.mkdir(self.tmphome + "/src/MacBuild/stonix") elif not os.path.isdir(self.tmphome + "/src/MacBuild/stonix"): os.mkdir(self.tmphome + "/src/MacBuild/stonix") ##### # Set up stonix for a build copy2(self.tmphome + "/src/stonix.py", self.tmphome + "/src/MacBuild/stonix") ##### # Sync the stonix_resources directory, ready for the build. # TODO: Use run_commands utility in ramdisk/lib/ rsync = [self.RSYNC, "-ap", "--exclude=\".svn\"", "--exclude=\"*.tar.gz\"", "--exclude=\"*.dmg\"", "--exclude=\".git*\"", self.tmphome + "/src/stonix_resources", self.tmphome + "/src/MacBuild/stonix"] output = Popen(rsync, stdout=PIPE, stderr=STDOUT).communicate()[0] self.libc.sync() sleep(1) self.libc.sync() sleep(1) self.libc.sync() sleep(1) print((str(output))) elif appName == 'stonix4mac': ##### # Change the Info.plist with the new version string plist = self.tmphome + "/src/MacBuild/" + appName + "/" + appName + "/Info.plist" # Change version string of the app print("Changing .app version string...") self.mbl.modplist(plist, "CFBundleShortVersionString", self.APPVERSION) self.mbl.changeViewControllerTitle("stonix4mac " + str(self.APPVERSION)) ##### # Change the Application icon used in the xcode build pbxproj = self.tmphome + "/src/MacBuild/stonix4mac/stonix4mac.xcodeproj/project.pbxproj" self.mbl.regexReplace(pbxproj, r"ASSETCATALOG_COMPILER_APPICON_NAME =.*$", r"ASSETCATALOG_COMPILER_APPICON_NAME = stonix4macfisma" + self.FISMACAT + ";\n", backupname=pbxproj + ".bak") # Change the stonix image used the privilege escalation window sbpath = self.tmphome + "/src/MacBuild/stonix4mac/stonix4mac/Base.lproj/Main.storyboard" self.mbl.regexReplace(sbpath, r"stoniximage", r"stoniximage" + self.FISMACAT, backupname=sbpath + ".bak") os.chdir(returnDir) except: print((traceback.format_exc())) raise else: success = True return success def compile(self, appName, appVersion, appIcon, appPath): '''Perform compile - to create an 'app' for the applications directory :param appName: Name of application as it should appear on OS X systems :param appVersion: Version of app being built :param appIcon: File name of icon for OS X app :param appPath: Path to [stonixroot]/src/MacBuild/[appName] @author: Eric Ball, Roy Nielsen ''' print(("Started compileApp with " + appName + ", " + appVersion + \ ", " + appIcon)) try: returnDir = os.getcwd() os.chdir(appPath) ##### # Determine compile type - ie: xcodebuild vs pyinstaller if appName == "stonix4mac": self.logger.log(lp.DEBUG, ".") self.logger.log(lp.DEBUG, ".") self.logger.log(lp.DEBUG, ".") self.logger.log(lp.DEBUG, ".") self.logger.log(lp.DEBUG, "TMPHOME: " + str(self.tmphome)) self.logger.log(lp.DEBUG, ".") self.logger.log(lp.DEBUG, ".") self.logger.log(lp.DEBUG, ".") self.logger.log(lp.DEBUG, ".") if self.ordPass: ##### # Run the xcodebuild script to build stonix4mac with codesigning enabled cmd = [self.tmphome + '/src/MacBuild/xcodebuild.py', '--tmpenc', self.ordPass, '-u', self.keyuser, '-i', appName, '-d', '--psd', self.tmphome + "/src/Macbuild/stonix4mac", '--keychain', self.keychain] self.rw.setCommand(cmd) output, error, retcode = self.rw.liftDown(self.keyuser, os.getcwd()) # output, error, retcode = self.rw.waitNpassThruStdout() print("Output: " + output) print("Error: " + error) print("Return Code: " + str(retcode)) else: ##### # Run the xcodebuild script to build stonix4mac without codesigning enabled cmd = [self.tmphome + '/src/MacBuild/xcodebuild.py', '-i', appName, '-d', '--psd', self.tmphome + "/src/Macbuild/stonix4mac"] self.rw.setCommand(cmd) output, error, retcode = self.rw.liftDown(self.keyuser, os.getcwd(), silent=False) # output, error, retcode = self.rw.waitNpassThruStdout() print("Output: " + output) print("Error: " + error) print("Return Code: " + str(retcode)) elif appName == "stonix": ##### # Perform pyinstaller build if os.path.isdir(self.tmphome + "/src/MacBuild/stonix/build"): rmtree(self.tmphome + "/src/MacBuild/stonix/build") if os.path.isdir(self.tmphome + "/src/MacBuild/stonix/dist"): rmtree(self.tmphome + "/src/MacBuild/stonix/dist") self.logger.log(lp.DEBUG, "Hidden imports: " + str(self.hiddenImports)) # TODO: Reevaluate hidden imports hdnimports = self.hiddenImports + ['ctypes', '_ctypes', 'ctypes._endian', 'decimal', 'numbers'] # to compile a pyinstaller spec file for app creation: print("Creating a pyinstaller spec file for the project...") stonix_hooks_path = "./additional_hooks/runtime_hooks" # TODO: may need to create/maintain a stonix_resources pyinstaller hooks script stonix_runtime_hooks = stonix_hooks_path + '/stonix_resrouces.py' # Make a specifications file output = self.mbl.pyinstMakespec([appName + ".py"], True, False, False, "../" + appIcon + ".icns", pathex=["/usr/lib", "./stonix_resources/rules", "stonix_resources"] + self.PYPATHS, specpath=os.getcwd(), hiddenImports=hdnimports) print(output) # Build app using specifications file created by pyinstMakespec call print("Building the app...") self.mbl.pyinstBuild(appName + ".spec", "private/tmp", appPath + "/dist", True, True) except Exception: raise finally: os.chdir(returnDir) print(("compileApp with " + appName + ", " + appVersion + " Finished...")) def postCompile(self, appName, prepPath): '''Perform post-compile processing. @author: Eric Ball, Roy Nielsen :param appName: :param prepPath: ''' print("Started postCompile...") returnDir = os.getcwd() os.chdir(prepPath) try: if appName == 'stonix': self.logger.log(lp.DEBUG, "Starting stonix postCompile.") returnDir = os.getcwd() os.chdir(prepPath) plist = self.tmphome + "/src/MacBuild/stonix/dist/" + appName + ".app/Contents/Info.plist" # Change version string of the app print("Changing .app version string...") self.mbl.modplist(plist, "CFBundleShortVersionString", self.APPVERSION) # Change icon name in the app print("Changing .app icon...") self.mbl.modplist(plist, "CFBundleIconFile", self.STONIXICON + ".icns") # Change mode of Info.plist to 0o664 os.chmod(plist, 0o664) ##### # Copy the stonix_resources directory into the # stonix.app/Contents/MacOS directory rsync = [self.RSYNC, "-avp", "--exclude=\".svn\"", "--exclude=\"*.tar.gz\"", "--exclude=\"*.dmg\"", "--exclude=\".git*\"", self.tmphome + \ "/src/stonix_resources", self.tmphome + "/src/MacBuild/stonix/dist/" + \ appName + ".app/Contents/MacOS"] output = Popen(rsync, stdout=PIPE, stderr=STDOUT).communicate()[0] print(output) self.libc.sync() self.libc.sync() # Copy icon to the resources directory copy2(self.tmphome + "/src/MacBuild/stonix4macfisma" + self.FISMACAT + ".icns", self.tmphome + "/src/MacBuild/stonix/dist/" \ + appName + ".app/Contents/Resources/" + \ self.STONIXICON + ".icns") # Copy splashscreen to the resources directory copy2(self.tmphome + "/src/stonix_resources/gfx/stonix4macfisma" + \ self.FISMACAT + "splashscreen.png", self.tmphome + "/src/MacBuild/stonix/dist/" + \ appName + ".app/Contents/MacOS/stonix_resources/gfx/StonixSplash.png") self.libc.sync() self.libc.sync() ##### # Copy stonix.app to the stonix4mac directory rsync = [self.RSYNC, "-avp", "--exclude=\".svn\"", "--exclude=\"*.tar.gz\"", "--exclude=\"*.dmg\"", "--exclude=\".git*\"", self.tmphome + \ "/src/MacBuild/stonix/dist/stonix.app", "./stonix4mac"] output = Popen(rsync, stdout=PIPE, stderr=STDOUT).communicate()[0] print(output) self.libc.sync() ##### # Optional codesign self.libc.sync() self.libc.sync() if self.doCodesign and self.signature: # Sign stonix app self.signObject(self.tmphome + '/src/Macbuild/stonix4mac', self.tmphome + '/src/Macbuild/stonix4mac', 'stonix.app') elif appName == 'stonix4mac': self.logger.log(lp.DEBUG, "Starting stonix4mac postCompile.") os.chdir(self.tmphome + "/src/MacBuild/stonix4mac/build/Release") ##### # Optional codesign self.libc.sync() self.libc.sync() if self.doCodesign and self.signature: # Sign stonix4mac app self.signObject(self.tmphome + '/src/Macbuild/stonix4mac', self.tmphome + '/src/Macbuild/stonix4mac/build/Release', appName + '.app') os.chdir(returnDir) except Exception: raise print("buildStonix4MacAppResources Finished...") def signObject(self, workingDir, objectParentDir, objectName): '''Uses xcodebuild to sign a file or bundle. :param workingDir: The working directory that the process will take place :param objectParentDir: The directory that contains the object to be signed :param objectName: The name of the object to be signed @author: Brandon R. Gonzales ''' self.logger.log(lp.DEBUG, "\n##################################################") self.logger.log(lp.DEBUG, "##################################################") self.logger.log(lp.DEBUG, "Signing \'" + os.path.join(objectParentDir, objectName) + "\'!") self.logger.log(lp.DEBUG, "##################################################") self.logger.log(lp.DEBUG, "##################################################") os.chdir(workingDir) print(workingDir) ##### # Perform a codesigning on the stonix4mac application cmd = [self.tmphome + '/src/MacBuild/xcodebuild.py', '--psd', objectParentDir, '-c', '--tmpenc', self.ordPass, '-u', self.keyuser, '-i', objectName, '-d', '-v', self.codesignVerbose, '-s', '"' + self.signature + '"', '--keychain', self.keychain] self.logger.log(lp.DEBUG, '.') self.logger.log(lp.DEBUG, '.') self.logger.log(lp.DEBUG, "Working dir: " + workingDir) self.logger.log(lp.DEBUG, '.') self.logger.log(lp.DEBUG, '.') ##### # Run the xcodebuild script to codesign the mac installer package self.rw.setCommand(cmd) output, error, retcode = self.rw.liftDown(self.keyuser, workingDir) # output, error, retcode = self.rw.communicate() self.logger.log(lp.DEBUG, "Codesign returns: " + str(retcode)) for line in output.split('\n'): self.logger.log(lp.DEBUG, line) for line in error.split('\n'): self.logger.log(lp.DEBUG, line) self.libc.sync() sleep(1) self.libc.sync() sleep(3) def makeInstaller(self, appName, appVersion, appPath): '''Create an installer. As of Nov 2016, use luggage to create a <appName>.pkg :param appName: Name of application as it should appear on OS X systems :param appVersion: Version of app being built :param appPath: Path to [stonixroot]/src/MacBuild @authors: Eric Ball, Roy Nielsen ''' ##### # run make to create a pkg installer self.logger.log(lp.DEBUG, "Started buildStonix4MacAppPkg...") try: returnDir = os.getcwd() os.chdir(appPath + "/" + appName) ##### # Processing makefile to create a package self.logger.log(lp.DEBUG, "Putting new version into Makefile...") self.mbl.regexReplace("Makefile", r"PACKAGE_VERSION=", "PACKAGE_VERSION=" + self.APPVERSION) dmgsPath = self.tmphome + "/src/MacBuild/dmgs" if not os.path.isdir(dmgsPath) and os.path.exists(dmgsPath): # Cannot use mkdtmp here because it will make the directory on # the root filesystem instead of the ramdisk, then it will try # to link across filesystems which won't work tmpdir = self.tmphome + "/src/MacBuild/dmgs." + str(time()) os.rename(dmgsPath, tmpdir) os.mkdir(dmgsPath) if not os.path.exists(dmgsPath): os.mkdir(dmgsPath) print(("Creating a .dmg file with a .pkg file inside for " + \ "installation purposes...")) #call(["make", "dmg", "PACKAGE_VERSION=" + appVersion, # "USE_PKGBUILD=1"]) makepkg = ["/usr/bin/make", "pkg", "PACKAGE_VERSION=" + self.APPVERSION, "USE_PKGBUILD=1"] output = Popen(makepkg, stdout=PIPE, stderr=STDOUT).communicate()[0] for line in output.decode('utf-8').split('\n'): self.logger.log(lp.DEBUG, line) sleep(2) self.libc.sync() sleep(2) self.libc.sync() sleep(3) self.libc.sync() sleep(3) ##### # Perform a codesigning on the stonix4mac application if self.ordPass: if self.FISMACAT == "high": cmd = [self.tmphome + '/src/MacBuild/xcodebuild.py', '--psd', self.tmphome + '/src/MacBuild/stonix4mac', '--productsign', '--tmpenc', self.ordPass, '-u', self.keyuser, '-i', appName + '-red-' + str(self.STONIXVERSION) + '.pkg', '-n', appName + '-red.' + str(self.STONIXVERSION) + '.pkg', '-d', '-s', '"Developer ID Installer"', '--keychain', self.keychain] else: cmd = [self.tmphome + '/src/MacBuild/xcodebuild.py', '--psd', self.tmphome + '/src/MacBuild/stonix4mac', '--productsign', '--tmpenc', self.ordPass, '-u', self.keyuser, '-i', appName + '-' + str(self.STONIXVERSION) + '.pkg', '-n', appName + '.' + str(self.STONIXVERSION) + '.pkg', '-d', '-s', '"Developer ID Installer"', '--keychain', self.keychain] else: if self.FISMACAT == "high": cmd = [self.tmphome + '/src/MacBuild/xcodebuild.py', '--psd', self.tmphome + '/src/MacBuild/stonix4mac', '-u', self.keyuser, '-i', appName + '-red-' + str(self.STONIXVERSION) + '.pkg', '-n', appName + '-red.' + str(self.STONIXVERSION) + '.pkg', '-d'] else: cmd = [self.tmphome + '/src/MacBuild/xcodebuild.py', '--psd', self.tmphome + '/src/MacBuild/stonix4mac', '-u', self.keyuser, '-i', appName + '-' + str(self.STONIXVERSION) + '.pkg', '-n', appName + '.' + str(self.STONIXVERSION) + '.pkg', '-d'] self.logger.log(lp.DEBUG, '.') self.logger.log(lp.DEBUG, '.') self.logger.log(lp.DEBUG, "Working dir: " + os.getcwd()) self.logger.log(lp.DEBUG, '.') self.logger.log(lp.DEBUG, '.') ##### # Run the xcodebuild script to codesign the mac installer package self.rw.setCommand(cmd) # output, error, retcode = self.rw.communicate() buildDir = os.getcwd() print(buildDir) output, error, retcode = self.rw.liftDown(self.keyuser, buildDir) for line in output.split('\n'): self.logger.log(lp.DEBUG, line) for line in error.split('\n'): self.logger.log(lp.DEBUG, line) sleep(2) self.libc.sync() sleep(3) self.libc.sync() sleep(2) self.libc.sync() print("Moving dmg and pkg to the dmgs directory.") if self.FISMACAT == "high": pkgname = self.STONIX4MAC + "-red." + self.APPVERSION + ".pkg" else: pkgname = self.STONIX4MAC + "." + self.APPVERSION + ".pkg" self.product = self.tmphome + "/src/Macbuild/" + self.STONIX4MAC + "/" + pkgname self.logger.log(lp.DEBUG, "Copying: " + str(pkgname) + " to: " + dmgsPath + "/" + pkgname) copy2(self.product, dmgsPath) sleep(2) self.libc.sync() sleep(3) self.libc.sync() sleep(2) self.libc.sync() os.chdir(returnDir) except Exception: print((traceback.format_exc())) raise print("buildStonix4MacAppPkg... Finished") def backup(self): ''' ''' pass def tearDown(self): '''Disconnect ramdisk, unloading data to pre-build location.''' self.logger.log(lp.DEBUG, "===== Entering tearDown =====") self.mbl.chownR(self.keyuser, self.tmphome + "/src") # chmod so it's readable by everyone, writable by the group self.mbl.chmodR(stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH | stat.S_IWGRP, self.tmphome + "/src", "append") self.libc.sync() self.libc.sync() # Copy bopy back to pseudo-build directory productDest= self.buildHome + "/dmgs" if not os.path.isdir(productDest): os.makedirs(productDest) cmd = [self.RSYNC, "-avp", self.product, productDest] self.logger.log(lp.DEBUG, str(cmd)) output, error = Popen(cmd, stdout=PIPE, stderr=STDOUT).communicate() for line in output.decode('utf-8').split("\n"): self.logger.log(lp.DEBUG, str(line)) if error: for line in error.decode('utf-8').split("\n"): self.logger.log(lp.DEBUG, str(line)) self.libc.sync() self.libc.sync() cmd = [self.RSYNC, "-avp", self.tmphome + "/src/", self.buildHome + "/builtSrc"] self.logger.log(lp.DEBUG, str(cmd)) output, error = Popen(cmd, stdout=PIPE, stderr=STDOUT).communicate() for line in output.decode('utf-8').split("\n"): self.logger.log(lp.DEBUG, str(line)) if error: for line in error.decode('utf-8').split("\n"): self.logger.log(lp.DEBUG, str(line)) self.libc.sync() sleep(1) self.libc.sync() sleep(1) self.libc.sync() sleep(3) os.chdir(self.buildHome) if not self.noExit: self._exit(self.ramdisk, self.luggage, 0)
class BuildAndRunSuite(object): def __init__(self, logger): """ """ if logger: self.logger = logger else: self.logger = CyLogger() self.module_version = '20160224.032043.009191' self.prefix = [] ############################################## def setPrefix(self, prefix=[]): """ Setter for the prefix variable... """ if prefix and isinstance(prefix, list): self.prefix = prefix else: self.prefix = ["test_", "Test_"] ############################################## def get_all_tests(self, prefix=[]): """ Collect all available tests using the test prefix(s) @author: Roy Nielsen """ test_list = [] if not self.modules: allfiles = os.listdir(testdir) for check_file in allfiles: test_name = str(check_file).split(".")[0] pycfile = os.path.join("./tests/", test_name + ".pyc") if os.path.exists(pycfile): os.unlink(pycfile) for item in self.prefix: if re.match("^%s.+\.py$" % item, check_file): if re.match("^__init__.py$", check_file): continue print("Loading test: " + str(check_file)) test_list.append(os.path.join("./tests/", check_file)) print(str(test_list)) return test_list ############################################## def run_suite(self, modules=[]): """ Gather all the tests from this module in a test suite. @author: Roy Nielsen """ self.test_dir_name = testdir.split("/")[1] self.modules = modules ##### # Initialize the test suite self.test_suite = unittest.TestSuite() ##### # Generate the test list if self.modules and isinstance(self.modules, list): test_list = self.modules else: test_list = self.get_all_tests(prefix) ##### # Import each of the tests and add them to the suite for check_file in test_list: self.logger.log(lp.DEBUG, str(check_file)) test_name = str(check_file).split("/")[-1] test_name = str(test_name).split(".")[0] self.logger.log(lp.DEBUG, "test_name: " + str(test_name)) test_name_import_path = ".".join([self.test_dir_name, test_name]) self.logger.log( lp.DEBUG, "test_name_import_path: " + str(test_name_import_path)) try: ################################################ # Test class needs to be named the same as the # filename for this to work. # import the file named in "test_name" variable # Python 3.9 module_to_run = importlib.import_module(test_name_import_path) # Python 2.7 # module_to_run = __import__(test_name_import_path, # fromlist=test_name, level=-1) # Python 3.9 test_to_run = getattr(module_to_run, test_name) # Python 2.7 # getattr(x, 'foobar') is equivalent to x.foobar # test_to_run = getattr(module_to_run, test_name) # Add the test class to the test suite self.test_suite.addTest(unittest.makeSuite(test_to_run)) except AttributeError as err: self.logger.log(lp.ERROR, traceback.format_exc()) self.logger.log(lp.ERROR, "WTF homeslice!") ##### # calll the run_action to execute the test suite self.run_action() ############################################## def run_action(self): """ Run the Suite. """ runner = unittest.TextTestRunner() runner.run(self.test_suite)
modules = options.modules else: modules = None ##### # ... processing logging options... if options.verbose: level = 20 elif options.debug: level = 10 else: level = 30 logger = CyLogger(level=level) logger.initializeLogs(filename="ramdiskTestLog") logger.log(lp.DEBUG, "Modules: " + str(modules)) ##### # ... processing test prefixes if options.prefix: prefix = options.prefix else: prefix = ["test_", "Test_"] """ ##### # todo: Need to figure out a different way to do this that doesn't require interaction - # Perhaps a unittest needs to do this check as part of its tests rather than in the # test runner.... if os.geteuid != 0: print("\n\nNote - Some tests will fail if not run with superuser privilege.") print("\n")
class GenericRamdiskTest(unittest.TestCase, GenericTestUtilities): """ Holds helper methods. DO NOT create an init Inspiration for using classmethod: http://simeonfranklin.com/testing2.pdf @author: Roy Nielsen """ @classmethod def setUpClass(self): """ """ self.libc = getLibc() self.subdirs = ["two", "three" "one/four"] self.logger = CyLogger() self.logger.log(lp.CRITICAL, "Logger initialized............................") """ Set up a ramdisk and use that random location as a root to test the filesystem functionality of what is being tested. """ #Calculate size of ramdisk to make for this unit test. size_in_mb = 1800 ramdisk_size = size = size_in_mb self.mnt_pnt_requested = "testmntpnt" self.success = False self.mountPoint = "" self.ramdiskDev = False self.mnt_pnt_requested = False # get a ramdisk of appropriate size, with a secure random mountpoint self.my_ramdisk = RamDisk(str(ramdisk_size), self.mnt_pnt_requested, logger=self.logger) (self.success, self.mountPoint, self.ramdiskDev) = self.my_ramdisk.getData() self.logger.log(lp.WARNING, str(self.success) + " : " + str(self.mountPoint) + " : " + str(self.ramdiskDev)) self.mount = self.mountPoint self.logger.log(lp.INFO, "::::::::Ramdisk Mount Point: " + str(self.mountPoint)) self.logger.log(lp.INFO, "::::::::Ramdisk Device : " + str(self.ramdiskDev)) if not self.success: raise IOError("Cannot get a ramdisk for some reason. . .") ##### # Create a temp location on disk to run benchmark tests against self.fs_dir = tempfile.mkdtemp() # Start timer in miliseconds self.test_start_time = datetime.now() self.setUpInstanceSpecifics() @classmethod def setUpInstanceSpecifics(self): """ Call the child class setUpClass initializer, if possible.. Here to be over-ridden by a child class. @author: Roy Nielsen """ pass ################################################ ##### Helper Methods def _unloadRamdisk(self): """ """ if self.my_ramdisk.umount(): self.logger.log(lp.INFO, r"Successfully detached disk: " + \ str(self.my_ramdisk.mntPoint).strip()) else: self.logger.log(lp.WARNING, r"Couldn't detach disk: " + \ str(self.my_ramdisk.myRamdiskDev).strip() + \ " : mntpnt: " + str(self.my_ramdisk.mntPoint)) raise Exception(r"Cannot eject disk: " + \ str(self.my_ramdisk.myRamdiskDev).strip() + \ " : mntpnt: " + str(self.my_ramdisk.mntPoint)) ############################################################################### ##### Functional Tests ################################## def test_files_n_dirs(self): """ Should work when files exist in ramdisk. """ # Do file setup for this test for subdir in self.subdirs: dirpath = self.mountPoint + "/" + subdir self.logger.log(lp.DEBUG, "DIRPATH: : " + str(dirpath)) self.mkdirs(dirpath) self.touch(dirpath + "/" + "test") # Do the tests for subdir in self.subdirs: # CANNOT use os.path.join this way. os.path.join cannot deal with # absolute directories. May work with mounting ramdisk in local # relative directories. self.assertTrue(os.path.exists(self.mountPoint + "/" + subdir + "/" + "test"), "Problem with ramdisk...") ################################## def test_four_file_sizes(self): """ Test file creation of various sizes, ramdisk vs. filesystem """ ##### # Clean up the ramdisk self.my_ramdisk._format() ##### # 100Mb file size oneHundred = 100 ##### # 500Mb file size fiveHundred = 500 ##### # 800Mb file size eightHundred = 800 ##### # 1Gb file size oneGig = 1000 my_fs_array = [oneHundred, fiveHundred, eightHundred, oneGig] for file_size in my_fs_array: self.logger.log(lp.INFO, "testfile size: " + str(file_size)) ##### # Create filesystem file and capture the time it takes... fs_time = self.mkfile(os.path.join(self.fs_dir, "testfile"), file_size) self.logger.log(lp.INFO, "fs_time: " + str(fs_time)) ##### # get the time it takes to create the file in ramdisk... ram_time = self.mkfile(os.path.join(self.mountPoint, "testfile"), file_size) self.logger.log(lp.INFO, "ram_time: " + str(ram_time)) speed = fs_time - ram_time self.logger.log(lp.INFO, "ramdisk: " + str(speed) + " faster...") assert_message = "Problem with " + str(file_size) + "mb ramdisk..." self.logger.log(lp.DEBUG, assert_message) self.logger.log(lp.INFO, "Smaller file sizes will fail this test on systems with SSD's...") self.assertTrue((fs_time - ram_time).days > -1, assert_message) ################################## def test_many_small_files_creation(self): """ """ ##### # Clean up the ramdisk self.my_ramdisk._format() ##### # ramdisk_starttime = datetime.now() for i in range(1000): self.mkfile(os.path.join(self.mountPoint, "testfile" + str(i)), 1) ramdisk_endtime = datetime.now() rtime = ramdisk_endtime - ramdisk_starttime fs_starttime = datetime.now() for i in range(1000): self.mkfile(os.path.join(self.fs_dir, "testfile" + str(i)), 1) fsdisk_endtime = datetime.now() fstime = fsdisk_endtime - fs_starttime self.assertTrue((fstime - rtime).days > -1, "Problem with ramdisk...") ################################## @classmethod def tearDownInstanceSpecifics(self): """ Skeleton method in case a child class wants/needs to override it. @author: Roy Nielsen """ pass @classmethod def tearDownClass(self): """ """ self.tearDownInstanceSpecifics() try: umount(self.mount) self.logger.log(lp.INFO, r"Successfully detached disk: " + \ str(self.my_ramdisk.mntPoint).strip()) except Exception: message = r"Couldn't detach disk: " + \ str(self.my_ramdisk.myRamdiskDev).strip() + \ " : mntpnt: " + str(self.my_ramdisk.mntPoint) ex_message = message + "\n" + traceback.format_exc() raise Exception(ex_message) ##### # capture end time test_end_time = datetime.now() ##### # Calculate and log how long it took... test_time = (test_end_time - self.test_start_time) self.logger.log(lp.INFO, self.__module__ + " took " + str(test_time) + \ " time to complete...")