def test_bootstrap(self): file_utils.create_dir(lxc_dir, True) script_base_dir = os.path.realpath(os.path.join(__file__, "..", "..")) def __generate_bind_target__(lxc_spec): bind_target = os.path.join(lxc_dir, lxc_spec, "rootfs", "home/user/scripts/") return bind_target def __pre_target__(lxc_spec): ################################################################ # Copying scripts ############################################################### # - create a copy of scripts directory (in order to not mess up the sources) # - ?? simple sync with lxc doesn't seem to work (maybe due to different inode management) (simple rsync both before and after boot causes the dissappearence of file after some instants) -> mount-bind that directory # - shutil.copy2 should copy sufficient metadata # - only copy scripts subdirectory (as it should work independently from source root) # - exclude tests in order to avoid endless recursion with copies into source (specification of absolute exclusions doesn't work -> specify relatively), exclude *.pyc because it might causes errors # - always copy, not only at installations, in order update changes # - only os.path.realpath allows to resolve /path/to/file.ext/.. (os.path.join doesn't) script_copy_dir = os.path.join(lxc_dir, "scripts-copy") if not os.path.exists(script_copy_dir): os.makedirs(script_copy_dir) for root, dirnames, filenames in os.walk( script_base_dir, topdown=True, # necessary for in-place manipulation of dirnames ): dirnames[:] = [d for d in dirnames if d not in ["tests", "tmp"]] # also excludes subdirs for filename in filenames: if filename == "lxc-btrfs.img": continue if filename.endswith(".pyc"): continue script = os.path.join(root,filename) rel_to_base_dir = os.path.relpath(script, script_base_dir) target = os.path.join(script_copy_dir, rel_to_base_dir) target_parent = os.path.realpath(os.path.join(target, "..")) if not os.path.exists(target_parent): os.makedirs(target_parent) logger.debug("copying %s -> %s" % (script, target)) shutil.copy2(script, target) bind_target = __generate_bind_target__(lxc_spec) if not os.path.exists(bind_target): os.makedirs(bind_target) sp.check_call([mount, "-o", "rw,bind", script_copy_dir, bind_target]) # has to be unmounted before the original is restored below def __target__(child): child.sendline("sudo chown -R user:user /home/user/scripts") # chown at every start because script are copied at every run child.expect(__sudo_queries__(lxc_username)) child.sendline("user") child.expect("[#$][\\s]") # test success child.sendline("sudo python /home/user/scripts/bootstrap_prequisites.py") child.expect("Do you want to continue \\[Y/n\\]\\?") # apt (don't use --assume-yes or --yes in the script!) child.sendline("y") child.expect("[#$][\\s]") child.sendline("echo $?") child.expect("[0-9]+") child_output = child.after.strip() child.expect("[#$][\\s]") # after parsing the return of echo $? the prompt has to be expected self.assertTrue(0 == int(child_output)) child.sendline("sudo halt") child.expect(":") # sudo password for shutdown child.sendline("user") child.wait() def __post_target__(lxc_spec): bind_target = __generate_bind_target__(lxc_spec) sp.check_call([umount, bind_target]) # doesn't really make sense to ignore failure (just messes up the failure output) because removing a mounted directory fails certainly config_file_path = os.path.realpath(os.path.join(__file__, "..", "bootstrap_test.conf")) logger.debug("reading config file %s" % (config_file_path,)) config = ConfigParser.ConfigParser() config.read([config_file_path]) apt_proxy = config.get("lxc-apt", "apt.proxy") lxc_test.test(lxc_dir=lxc_dir, target=__target__, pre_target=__pre_target__, post_target=__post_target__, apt_proxy=apt_proxy)
def test_bootstrap(self): sudo_uid = int(os.getenv("SUDO_UID")) if sudo_uid != os.getuid(): logger.info("recognized sudo invokation, using invoking user's maven cache and uid for user space files and directories") postgresql_jdbc_url= "%s/%s" % (ftp_url, bootstrap.postgresql_jdbc_name) postgresql_deb_url= "%s/%s" % (ftp_url, bootstrap.postgresql_deb_name) geotools_url= "%s/%s" % (ftp_url, bootstrap.geotools_src_archive_name) postgis_url= "%s/%s" % (ftp_url, bootstrap.postgis_src_archive_name) jgrapht_url= "%s/%s" % (ftp_url, bootstrap.jgrapht_name) jfuzzy_url= "%s/%s" % (ftp_url, bootstrap.jfuzzy_name) maven_bin_archive_url= "%s/%s" % (ftp_url, bootstrap.maven_bin_archive_name) commons_src_archive_url = "%s/%s" % (ftp_url, bootstrap.commons_src_archive_name) # local unit test def __test__(q): try: os.setuid(sudo_uid) os.environ["JAVA_HOME"] = "/usr/java/latest" bootstrap_dir = tempfile.mkdtemp() postgres_datadir_path = bootstrap.postgres_datadir_path_default bootstrap.bootstrap(bootstrap_dir=bootstrap_dir, skip_build=False, postgres_datadir_path=postgres_datadir_path, force_overwrite_postgres_datadir=None, postgresql_jdbc_url=postgresql_jdbc_url, postgresql_deb_url=postgresql_deb_url, geotools_url=geotools_url, postgis_url=postgis_url, jgrapht_url=jgrapht_url, jfuzzy_url=jfuzzy_url, maven_bin_archive_url=maven_bin_archive_url, commons_src_archive_url=commons_src_archive_url) except Exception as ex: q.put(ex) q = multiprocessing.Queue() p = multiprocessing.Process(target=__test__, args=(q,)) p.start() p.join() if not q.empty(): raise q.get() # tests in LXCs def __generate_bind_target__(lxc_spec): bind_target = os.path.join(lxc_dir, lxc_spec, "rootfs", "home/user/scripts/") return bind_target def __pre_target__(lxc_spec): ################################################################ # Copying scripts ############################################################### # - create a copy of scripts directory (in order to not mess up the sources) # - ?? simple sync with lxc doesn't seem to work (maybe due to different inode management) (simple rsync both before and after boot causes the dissappearence of file after some instants) -> mount-bind that directory # - shutil.copy2 should copy sufficient metadata # - only copy scripts subdirectory (as it should work independently from source root) # - exclude tests in order to avoid endless recursion with copies into source (specification of absolute exclusions doesn't work -> specify relatively), exclude *.pyc because it might causes errors # - always copy, not only at installations, in order update changes # - only os.path.realpath allows to resolve /path/to/file.ext/.. (os.path.join doesn't) script_copy_dir = os.path.join(lxc_dir, "scripts-copy") if not os.path.exists(script_copy_dir): os.makedirs(script_copy_dir) script_base_dir = os.path.realpath(os.path.join(__file__, "..", "..")) for root, dirnames, filenames in os.walk( script_base_dir, topdown=True, # necessary for in-place manipulation of dirnames ): dirnames[:] = [d for d in dirnames if d not in ["tests", "tmp"]] # also excludes subdirs for filename in filenames: if filename == "lxc-btrfs.img": continue if filename.endswith(".pyc"): continue script = os.path.join(root,filename) rel_to_base_dir = os.path.relpath(script, script_base_dir) target = os.path.join(script_copy_dir, rel_to_base_dir) target_parent = os.path.realpath(os.path.join(target, "..")) if not os.path.exists(target_parent): os.makedirs(target_parent) logger.debug("copying %s -> %s" % (script, target)) shutil.copy2(script, target) bind_target = __generate_bind_target__(lxc_spec) if not os.path.exists(bind_target): os.makedirs(bind_target) sp.check_call([mount, "-o", "rw,bind", script_copy_dir, bind_target]) # has to be unmounted before the original is restored below def __target__(child): child.sendline("sudo chown -R user:user /home/user/scripts") # chown at every start because script are copied at every run child.expect(__sudo_queries__(lxc_username)) child.sendline("user") child.expect("[#$][\\s]") child.sendline("sudo apt-get install %s" % str.join(" ", common_programs)) child.expect("[#$][\\s]") # test unset JAVA_HOME child.sendline("unset JAVA_HOME") child.expect("[#$][\\s]") child.sendline("python /home/user/scripts/bootstrap.py") child.expect("[#$][\\s]") child_output = child.before.strip() self.assertTrue("JAVA_HOME is not set" in child_output) # @TODO: check that JAVA_HOME is not set by installation # test JAVA_HOME set to inexisting path child.sendline("export JAVA_HOME=/some/inexisting/path") child.sendline("python /home/user/scripts/bootstrap.py") child.expect("[#$][\\s]") child_output = child.after.strip() if not re.match(".*JAVA_HOME .* doesn't seem to point to a valid JDK.*", child_output) is None: self.fail("output should match 'JAVA_HOME .* doesn't seem to point to a valid JDK'") # test success child.sendline("export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-%s" % lxc_arch) child.expect("[#$][\\s]") child.sendline("sudo python /home/user/scripts/bootstrap_prequisites.py") # assume that bootstrap_prequisites.py just works; it is tested elsewhere child.expect("[#$][\\s]") child.sendline("python /home/user/scripts/bootstrap.py") child.expect("[#$][\\s]") child.sendline("echo $?") child.expect("[0-9]+") child_output = child.after.strip() child.expect("[#$][\\s]") # after parsing the return of echo $? the prompt has to be expected self.assertTrue(0 == int(child_output)) child.sendline("sudo halt") child.expect(":") # sudo password for shutdown child.sendline("user") child.wait() def __post_target__(lxc_spec): bind_target = __generate_bind_target__(lxc_spec) logger.debug("unmounting %s" % (bind_target,)) sp.check_call([umount, bind_target]) # doesn't really make sense to ignore failure (just messes up the failure output) because removing a mounted directory fails certainly config_file_path = os.path.realpath(os.path.join(__file__, "..", "bootstrap_test.conf")) logger.debug("reading config file %s" % (config_file_path,)) config = ConfigParser.ConfigParser() config.read([config_file_path]) mirror_debian = config.get("lxc", "mirror.debian") mirror_ubuntu = config.get("lxc", "mirror.ubuntu") lxc_test.test(lxc_dir=lxc_dir, target=__target__, pre_target=__pre_target__, post_target=__post_target__)
def test_bootstrap(self): sudo_uid = int(os.getenv("SUDO_UID")) if sudo_uid != os.getuid(): logger.info( "recognized sudo invokation, using invoking user's maven cache and uid for user space files and directories" ) postgresql_jdbc_url = "%s/%s" % (ftp_url, bootstrap.postgresql_jdbc_name) postgresql_deb_url = "%s/%s" % (ftp_url, bootstrap.postgresql_deb_name) geotools_url = "%s/%s" % (ftp_url, bootstrap.geotools_src_archive_name) postgis_url = "%s/%s" % (ftp_url, bootstrap.postgis_src_archive_name) jgrapht_url = "%s/%s" % (ftp_url, bootstrap.jgrapht_name) jfuzzy_url = "%s/%s" % (ftp_url, bootstrap.jfuzzy_name) maven_bin_archive_url = "%s/%s" % (ftp_url, bootstrap.maven_bin_archive_name) commons_src_archive_url = "%s/%s" % ( ftp_url, bootstrap.commons_src_archive_name) # local unit test def __test__(q): try: os.setuid(sudo_uid) os.environ["JAVA_HOME"] = "/usr/java/latest" bootstrap_dir = tempfile.mkdtemp() postgres_datadir_path = bootstrap.postgres_datadir_path_default bootstrap.bootstrap( bootstrap_dir=bootstrap_dir, skip_build=False, postgres_datadir_path=postgres_datadir_path, force_overwrite_postgres_datadir=None, postgresql_jdbc_url=postgresql_jdbc_url, postgresql_deb_url=postgresql_deb_url, geotools_url=geotools_url, postgis_url=postgis_url, jgrapht_url=jgrapht_url, jfuzzy_url=jfuzzy_url, maven_bin_archive_url=maven_bin_archive_url, commons_src_archive_url=commons_src_archive_url) except Exception as ex: q.put(ex) q = multiprocessing.Queue() p = multiprocessing.Process(target=__test__, args=(q, )) p.start() p.join() if not q.empty(): raise q.get() # tests in LXCs def __generate_bind_target__(lxc_spec): bind_target = os.path.join(lxc_dir, lxc_spec, "rootfs", "home/user/scripts/") return bind_target def __pre_target__(lxc_spec): ################################################################ # Copying scripts ############################################################### # - create a copy of scripts directory (in order to not mess up the sources) # - ?? simple sync with lxc doesn't seem to work (maybe due to different inode management) (simple rsync both before and after boot causes the dissappearence of file after some instants) -> mount-bind that directory # - shutil.copy2 should copy sufficient metadata # - only copy scripts subdirectory (as it should work independently from source root) # - exclude tests in order to avoid endless recursion with copies into source (specification of absolute exclusions doesn't work -> specify relatively), exclude *.pyc because it might causes errors # - always copy, not only at installations, in order update changes # - only os.path.realpath allows to resolve /path/to/file.ext/.. (os.path.join doesn't) script_copy_dir = os.path.join(lxc_dir, "scripts-copy") if not os.path.exists(script_copy_dir): os.makedirs(script_copy_dir) script_base_dir = os.path.realpath( os.path.join(__file__, "..", "..")) for root, dirnames, filenames in os.walk( script_base_dir, topdown= True, # necessary for in-place manipulation of dirnames ): dirnames[:] = [ d for d in dirnames if d not in ["tests", "tmp"] ] # also excludes subdirs for filename in filenames: if filename == "lxc-btrfs.img": continue if filename.endswith(".pyc"): continue script = os.path.join(root, filename) rel_to_base_dir = os.path.relpath(script, script_base_dir) target = os.path.join(script_copy_dir, rel_to_base_dir) target_parent = os.path.realpath(os.path.join( target, "..")) if not os.path.exists(target_parent): os.makedirs(target_parent) logger.debug("copying %s -> %s" % (script, target)) shutil.copy2(script, target) bind_target = __generate_bind_target__(lxc_spec) if not os.path.exists(bind_target): os.makedirs(bind_target) sp.check_call([ mount, "-o", "rw,bind", script_copy_dir, bind_target ]) # has to be unmounted before the original is restored below def __target__(child): child.sendline( "sudo chown -R user:user /home/user/scripts" ) # chown at every start because script are copied at every run child.expect(__sudo_queries__(lxc_username)) child.sendline("user") child.expect("[#$][\\s]") child.sendline("sudo apt-get install %s" % str.join(" ", common_programs)) child.expect("[#$][\\s]") # test unset JAVA_HOME child.sendline("unset JAVA_HOME") child.expect("[#$][\\s]") child.sendline("python /home/user/scripts/bootstrap.py") child.expect("[#$][\\s]") child_output = child.before.strip() self.assertTrue( "JAVA_HOME is not set" in child_output ) # @TODO: check that JAVA_HOME is not set by installation # test JAVA_HOME set to inexisting path child.sendline("export JAVA_HOME=/some/inexisting/path") child.sendline("python /home/user/scripts/bootstrap.py") child.expect("[#$][\\s]") child_output = child.after.strip() if not re.match( ".*JAVA_HOME .* doesn't seem to point to a valid JDK.*", child_output) is None: self.fail( "output should match 'JAVA_HOME .* doesn't seem to point to a valid JDK'" ) # test success child.sendline("export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-%s" % lxc_arch) child.expect("[#$][\\s]") child.sendline( "sudo python /home/user/scripts/bootstrap_prequisites.py" ) # assume that bootstrap_prequisites.py just works; it is tested elsewhere child.expect("[#$][\\s]") child.sendline("python /home/user/scripts/bootstrap.py") child.expect("[#$][\\s]") child.sendline("echo $?") child.expect("[0-9]+") child_output = child.after.strip() child.expect( "[#$][\\s]" ) # after parsing the return of echo $? the prompt has to be expected self.assertTrue(0 == int(child_output)) child.sendline("sudo halt") child.expect(":") # sudo password for shutdown child.sendline("user") child.wait() def __post_target__(lxc_spec): bind_target = __generate_bind_target__(lxc_spec) logger.debug("unmounting %s" % (bind_target, )) sp.check_call( [umount, bind_target] ) # doesn't really make sense to ignore failure (just messes up the failure output) because removing a mounted directory fails certainly config_file_path = os.path.realpath( os.path.join(__file__, "..", "bootstrap_test.conf")) logger.debug("reading config file %s" % (config_file_path, )) config = ConfigParser.ConfigParser() config.read([config_file_path]) mirror_debian = config.get("lxc", "mirror.debian") mirror_ubuntu = config.get("lxc", "mirror.ubuntu") lxc_test.test(lxc_dir=lxc_dir, target=__target__, pre_target=__pre_target__, post_target=__post_target__)