def test_zz_apparmor(self): '''Test apparmor''' if self.lsb_release['Release'] < 12.10: self._skipped("No profile in 12.04 and under") self.aa_unload_at_teardown = True # Currently while we have a profile, it is shipped disabled by default. # Verify that. rc, report = testlib.check_apparmor(self.aa_abs_profile, 12.10, is_running=False) expected = 1 result = 'Got exit code %d, expected %d\n' % (rc, expected) self.assertEquals(rc, expected, result + report) # Verify it is syntactically correct rc, report = testlib.cmd(['apparmor_parser', '-p', self.aa_abs_profile]) expected = 0 result = 'Got exit code %d, expected %d\n' % (rc, expected) self.assertEquals(rc, expected, result + report) # Verify it loads ok rc, report = testlib.cmd(['aa-enforce', self.aa_abs_profile]) expected = 0 result = 'Got exit code %d, expected %d\n' % (rc, expected) self.assertEquals(rc, expected, result + report) self._stop() self._start() rc, report = testlib.check_apparmor(self.aa_abs_profile, 12.10, is_running=True) expected = 1 result = 'Got exit code %d, expected %d\n' % (rc, expected) self.assertEquals(rc, expected, result + report)
def _start(self): '''Start process''' # check if there is a /etc/init/initscript.conf if os.path.exists("/etc/init/%s.conf" % self.initscript): rc, report = testlib.cmd(['start', self.initscript]) else: rc, report = testlib.cmd(["/etc/init.d/%s" % self.initscript, 'start']) expected = 0 result = 'Got exit code %d, expected %d\n' % (rc, expected) self.assertEquals(expected, rc, result + report) time.sleep(2)
def _stop(self): '''Stop httpd''' #print self.initscript,"stop" rc, report = testlib.cmd([self.initscript, 'stop']) expected = 0 result = 'Got exit code %d, expected %d\n' % (rc, expected) self.assertEquals(expected, rc, result + report)
def _disable_site(self, sitename): rc, report = testlib.cmd(['a2dissite', sitename]) expected = 0 result = 'Got exit code %d, expected %d\n' % (rc, expected) self.assertEquals(expected, rc, result + report) self._restart() time.sleep(2)
def test_CVE_2011_3205(self): '''Test parsing lines > 4096 in length (CVE-2011-3205)''' longline = "ABCDEF" * 4096 testlib.config_replace(self.gophermap, """Welcome to Pygopherd! You can place your documents in /var/gopher for future use. You can remove the gophermap file there to get rid of this message, or you can edit it to use other things. (You'll need to do at least one of these two things in order to get your own data to show up!) %s Some links to get you started: 1Pygopherd Home /devel/gopher/pygopherd gopher.quux.org 70 1Quux.Org Mega Server / gopher.quux.org 70 1The Gopher Project /Software/Gopher gopher.quux.org 70 1Traditional UMN Home Gopher / gopher.tc.umn.edu 70 Welcome to the world of Gopher and enjoy! """ %(longline), append=False) rc, report = testlib.cmd(['squidclient', '-h', '127.0.0.1', '-p', '3128', '-r', "gopher://127.0.0.1"]) expected = 0 result = 'Got exit code %d, expected %d\n' % (rc, expected) self.assertEquals(expected, rc, result + report)
def _stop(self): '''Stop process''' # check if process is running if os.path.exists("/etc/init/%s.conf" % self.initscript): rc, pidof = testlib.cmd(['pidof', '-x', self.initscript]) if pidof: rc, report = testlib.cmd(['stop', self.initscript]) else: # no need to stop it, it's stopped rc, report = (0, '') else: rc, report = testlib.cmd([self.initscript, 'stop']) expected = 0 result = 'Got exit code %d, expected %d\n' % (rc, expected) self.assertEquals(expected, rc, result + report)
def _start(self): '''Start httpd''' #print self.initscript,"start" rc, report = testlib.cmd([self.initscript, 'start']) expected = 0 result = 'Got exit code %d, expected %d\n' % (rc, expected) self.assertEquals(expected, rc, result + report) time.sleep(2)
def _test_url_proxy(self, url="http://localhost/", content="", proxy="localhost:3128"): '''Test the given url''' rc, report = testlib.cmd(['elinks', '-verbose', '2', '-no-home', '1', '-eval', 'set protocol.ftp.proxy.host = "%s"' %(proxy), '-eval', 'set protocol.http.proxy.host = "%s"' %(proxy), '-eval', 'set protocol.https.proxy.host = "%s"' %(proxy), '-dump', url]) expected = 0 result = 'Got exit code %d, expected %d\n' % (rc, expected) self.assertEquals(expected, rc, result + report) if content != "": self._word_find(report, content)
def _get_page(self, url="http://localhost/"): '''Get contents of given url''' rc, report = testlib.cmd(['elinks', '-verbose', '2', '-no-home', '1', '-dump', url]) expected = 0 result = 'Got exit code %d, expected %d\n' % (rc, expected) self.assertEquals(expected, rc, result + report) return report
def test_squidclient(self): '''Test squidclient''' urls = ['http://www.ubuntu.com/', 'https://wiki.ubuntu.com/', \ 'ftp://anonymous@localhost:21', 'gopher://127.0.0.1'] for url in urls: rc, report = testlib.cmd(['squidclient', '-h', '127.0.0.1', '-p', '3128', '-r', url]) expected = 0 result = 'Got exit code %d, expected %d\n' % (rc, expected) self.assertEquals(expected, rc, result + report)
def __disable_mod(self, mod): if not os.path.exists(os.path.join("/etc/apache2/mods-available", mod + \ ".load")): return if not os.path.exists("/usr/sbin/a2dismod"): return rc, report = testlib.cmd(['a2dismod', mod]) expected = 0 result = 'Got exit code %d, expected %d\n' % (rc, expected) self.assertEquals(expected, rc, result + report)
def test_21_security_CVE_2011_1720(self): '''CVE-2011-1720 fixed''' # http://www.postfix.org/CVE-2011-1720.html # setup sasl and connect self.s.quit() self._setup_sasl("CRAM-MD5", "DIGEST-MD5") # verify sasl support rc, report = testlib.cmd(['postconf', 'smtpd_sasl_auth_enable']) expected = 0 result = 'Got exit code %d, expected %d\n' % (rc, expected) self.assertEquals(expected, rc, result + report) self.assertTrue('yes' in report, "Could not find 'yes' in report:\n%s" % report) if self.lsb_release['Release'] > 6.06: rc, report = testlib.cmd(['postconf', 'smtpd_sasl_type']) expected = 0 result = 'Got exit code %d, expected %d\n' % (rc, expected) self.assertEquals(expected, rc, result + report) self.assertTrue('cyrus' in report, "Could not find 'cyrus' in report:\n%s" % report) # ehlo reply = self._check_auth("CRAM-MD5") self.assertTrue('DIGEST-MD5' in reply, reply) code, msg = self.s.docmd("AUTH", "CRAM-MD5") reply = '%d %s' % (code, msg) self.assertEquals(code, 334, reply) code, msg = self.s.docmd("*") reply = '%d %s' % (code, msg) self.assertEquals(code, 501, reply) error = False try: code, msg = self.s.docmd("AUTH", "DIGEST-MD5") except: error = True self.assertFalse(error, "server disconnected") reply = '%d %s' % (code, msg) self.assertEquals(code, 334, reply)
def _enable_site(self, sitename): rc, report = testlib.cmd(['a2ensite', sitename]) expected = 0 result = 'Got exit code %d, expected %d\n' % (rc, expected) self.assertEquals(expected, rc, result + report) # for some reason, force-reload doesn't work # if self.lsb_release['Release'] >= 8.04: # self._reload() #else: self._restart() time.sleep(2)
def _setup_sasl(self, mech, other_mech="", force_sasldb=False): '''Setup sasl for mech''' conf_file = '/etc/postfix/main.cf' for field in ['smtpd_sasl_type','smtpd_sasl_local_domain','smtpd_tls_auth_only']: testlib.config_comment(conf_file,field) testlib.config_set(conf_file,'smtpd_sasl_path','smtpd') testlib.config_set(conf_file,'smtpd_sasl_auth_enable','yes') #testlib.config_set(conf_file,'broken_sasl_auth_clients','yes') testlib.config_set(conf_file,'smtpd_sasl_authenticated_header','yes') testlib.config_set(conf_file,'smtpd_tls_loglevel','2') # setup smtpd.conf and the sasl users contents = '' self.assertTrue(mech in ['LOGIN', 'PLAIN', 'CRAM-MD5', 'DIGEST-MD5'], "Invalid mech: %s" % mech) if not force_sasldb and (mech == "PLAIN" or mech == "LOGIN"): conf_file = '/etc/default/saslauthd' testlib.config_set(conf_file, 'START', 'yes', spaces=False) contents = ''' pwcheck_method: saslauthd allowanonymouslogin: 0 allowplaintext: 1 mech_list: %s %s ''' % (mech, other_mech) # attach SASL to postfix chroot subprocess.call(['mkdir','-p','/var/spool/postfix/var/run/saslauthd']) subprocess.call(['rm','-rf','/var/run/saslauthd']) subprocess.call(['ln','-s','/var/spool/postfix/var/run/saslauthd','/var/run/saslauthd']) subprocess.call(['/etc/init.d/saslauthd', 'stop'], stdout=subprocess.PIPE) assert subprocess.call(['/etc/init.d/saslauthd', 'start'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) == 0 # Force crackful perms so chroot'd postfix can talk to saslauthd subprocess.call(['chmod','o+x','/var/spool/postfix/var/run/saslauthd']) else: plaintext = "1" if mech == "LOGIN" or mech == "PLAIN": plaintext = "0" contents = ''' pwcheck_method: auxprop allowanonymouslogin: 0 allowplaintext: %s mech_list: %s %s ''' % (plaintext, mech, other_mech) # Add user to sasldb2 testlib.config_replace("/etc/sasldb2", '', append=False) rc, report = testlib.cmd(['postconf', '-h', 'myhostname']) expected = 0 result = 'Got exit code %d, expected %d\n' % (rc, expected) self.assertEquals(expected, rc, result + report) child = pexpect.spawn('saslpasswd2 -c -u %s %s' % (report.strip(), self.user.login)) time.sleep(0.2) child.expect(r'(?i)password', timeout=5) time.sleep(0.2) child.sendline(self.user.password) time.sleep(0.2) child.expect(r'.*(for verification)', timeout=5) time.sleep(0.2) child.sendline(self.user.password) time.sleep(0.2) rc = child.expect('\n', timeout=5) time.sleep(0.2) self.assertEquals(rc, expected, "passwd returned %d" %(rc)) child.kill(0) os.chmod("/etc/sasldb2", 0640) rc, report = testlib.cmd(['chgrp', 'postfix', '/etc/sasldb2']) expected = 0 result = 'Got exit code %d, expected %d\n' % (rc, expected) self.assertEquals(expected, rc, result + report) # Force crackful perms so chroot'd postfix can talk to saslauthd subprocess.call(['mv', '-f', '/etc/sasldb2', '/var/spool/postfix/etc']) subprocess.call(['ln', '-s', '/var/spool/postfix/etc/sasldb2', '/etc/sasldb2']) conf_file = '/etc/postfix/sasl/smtpd.conf' testlib.config_replace(conf_file, contents, append=False) # Restart server self._restart_server()
def _flush_firewall(self): '''Flush firewall''' if os.path.exists('/lib/ufw/ufw-init'): testlib.cmd(['/lib/ufw/ufw-init', 'flush-all']) else: # based on '/lib/ufw/ufw-init flush-all' for exe in ['iptables', 'ip6tables']: testlib.cmd([exe, '-F']) testlib.cmd([exe, '-X']) testlib.cmd([exe, '-P', 'INPUT', 'ACCEPT']) testlib.cmd([exe, '-P', 'OUTPUT', 'ACCEPT']) testlib.cmd([exe, '-P', 'FORWARD', 'ACCEPT']) # Mangle table rc, report = testlib.cmd([exe, '-L', '-t', 'mangle']) if rc != 0: continue for mangle_chain in [ 'INPUT', 'OUTPUT', 'FORWARD', 'PREROUTING', 'POSTROUTING' ]: testlib.cmd([exe, '-t', 'mangle', '-F', mangle_chain]) testlib.cmd( [exe, '-t', 'mangle', '-P', mangle_chain, 'ACCEPT']) # Nat table rc, report = testlib.cmd([exe, '-L', '-t', 'nat']) for nat_chain in ['OUTPUT', 'PREROUTING', 'POSTROUTING']: testlib.cmd([exe, '-t', 'nat', '-F', mangle_chain]) testlib.cmd( [exe, '-t', 'nat', '-P', mangle_chain, 'ACCEPT'])
def _run_test(self, test, runas, search_terms, python="python"): '''Run specific testsuite test''' build_dir = testlib.prepare_source('ufw', \ self.builder, \ self.cached_src, \ os.path.join(self.tmpdir, \ os.path.basename(self.cached_src)), \ self.patch_system) os.chdir(build_dir) user_args = [] if runas == 'non-root': user_args = ['sudo', '-u', self.builder.login] test_args = [] if test == "non-root": test_args = ['./run_tests.sh', '-s', '-i', python] elif test == "root": test_args = ['./run_tests.sh', '-s', '-i', python, 'root'] elif test == 'syntax-check': rc, report = testlib.cmd(['grep', test, './Makefile']) if rc == 0: test_args = ['make', test] elif test == 'man-check': rc, report = testlib.cmd(['grep', test, './Makefile']) if rc == 0: test_args = ['make', test] if len(test_args) == 0: return self._skipped("Skipped: TODO") print "" print " make clean" rc, report = testlib.cmd(user_args + ['make', 'clean']) print " %s (may take a while)" % (" ".join(test_args)) rc, report = testlib.cmd(user_args + test_args) expected = 0 result = 'Got exit code %d, expected %d\n' % (rc, expected) self.assertEquals(expected, rc, result + report) # Useful to see if failure #print report for search in search_terms: self.assertTrue(search in report, "Could not find '%s' in:\n%s" % (search, report)) self.assertFalse('FAIL' in report, "Found 'FAIL' in:\n%s" % (report)) # Newer versions of ufw added capabilities tests. Lets make sure the # test chain is not present if test == "root": for exe in ['iptables', 'ip6tables']: rc, report = testlib.cmd([exe, '-L', '-n']) expected = 0 result = 'Got exit code %d, expected %d\n' % (rc, expected) self.assertEquals(expected, rc, result + report) search = 'caps-test' self.assertFalse(search in report, "Found '%s' in:\n%s" % (search, report)) return report
all_tests = [ 'about', 'desktop', 'files', 'images', 'pages', 'plugins', 'java', 'ssl', 'private' ] if options.include_skipped: testlib_browser.include_skipped = True if options.tabs: testlib_browser.tabs = True testlib_browser.exes = ['firefox'] if options.exe: testlib_browser.exes = [] for e in options.exe: rc, output = testlib.cmd(['which', e]) expected = 0 if rc == expected: # konqueror tests don't work well unless kdeinit4 is running if e.startswith("konqueror") or e.startswith("rekonq"): if not testlib.is_kdeinit_running(): continue testlib_browser.exes.append(e) else: print >> sys.stderr, ("Skipping '%s': not found" % (e)) for e in testlib_browser.exes: if e.startswith("firefox") and "apparmor" not in all_tests: all_tests.append("apparmor") testlib_browser.use_existing = False
def _reload(self): '''Reload httpd''' rc, report = testlib.cmd([self.initscript, 'force-reload']) expected = 0 result = 'Got exit code %d, expected %d\n' % (rc, expected) self.assertEquals(expected, rc, result + report)
def test_zz_cve_2010_3879_2(self): '''Test CVE-2010-3879 - Part 2''' # Doesn't compile on natty+ if self.lsb_release['Release'] >= 11.04: return self._skipped("PoC doesn't compile on natty and newer") # # Running the original exploit twice in a row has uncovered a # second issue, where having crap leftover in the mtab causes # fuse to misbehave # test_iso = 'util-linux/test.iso' test_file = 'testfile.txt' mountpoint = "/mountpoint" if os.path.exists(mountpoint): testlib.recursive_rm(mountpoint) os.mkdir(mountpoint, 0777) # mount the iso file rc, report = testlib.cmd(['mount', '-o', 'loop', test_iso, mountpoint]) expected = 0 result = 'Got exit code %d, expected %d\n' % (rc, expected) self.assertEquals(expected, rc, result + report) # See if we can see the file inside result = "Couldn't find testfile %s in mounted directory" % test_file self.assertTrue(os.path.exists('%s/%s' % (mountpoint, test_file)), result) # Compile required binaries and move to user's dir sourceA = os.path.join(self.tmpdir, "DirModifyInotify.c") binaryA = os.path.join(self.userY.home, "DirModifyInotify") sourceB = os.path.join(self.tmpdir, "FuseMinimal.c") binaryB = os.path.join(self.userY.home, "FuseMinimal") script = os.path.join(self.userY.home, "Test.sh") shutil.copy('./fuse/DirModifyInotify.c', sourceA) shutil.copy('./fuse/FuseMinimal.c', sourceB) testlib.create_fill( script, ''' #!/bin/bash mkdir -p tmp%s (cd tmp%s; sleep 1; ../../FuseMinimal .) & (./DirModifyInotify --Watch tmp%s --Watch /etc/mtab --WatchCount 8 --MovePath tmp --LinkTarget /) & sleep 3 fusermount -u -z %s/ killall DirModifyInotify killall FuseMinimal return 0 ''' % (mountpoint, mountpoint, mountpoint, mountpoint)) os.chmod(script, 0755) rc, report = testlib.cmd(['gcc', '-o', binaryA, sourceA]) expected = 0 result = 'Got exit code %d, expected %d\n' % (rc, expected) self.assertEquals(expected, rc, result + report) rc, report = testlib.cmd([ 'gcc', '-D_FILE_OFFSET_BITS=64', '-lfuse', '-Wall', '-o', binaryB, sourceB ]) expected = 0 result = 'Got exit code %d, expected %d\n' % (rc, expected) self.assertEquals(expected, rc, result + report) expected = 0 [rc, out] = self.user_run_cmd(self.userY, [script]) self.assertEquals( expected, rc, "CVE-2010-3879 script failed! RC:'%s', Output:'%s'" % (rc, out)) # Clean up exploit self.fuse_unmount(os.path.join(self.userY.home, "tmp-moved/mountpoint")) testlib.recursive_rm(os.path.join(self.userY.home, "tmp-moved")) # This should be a symlink to /, so don't do a recursive_rm! os.unlink(os.path.join(self.userY.home, "tmp")) # Run it a second time expected = 0 [rc, out] = self.user_run_cmd(self.userY, [script]) self.assertEquals( expected, rc, "CVE-2010-3879 script failed! RC:'%s', Output:'%s'" % (rc, out)) result = 'Mount went missing! Vulnerable to CVE-2010-3879, part 2!\n' self.assertTrue(os.path.exists('%s/%s' % (mountpoint, test_file)), result) # unmount it rc, report = testlib.cmd(['umount', mountpoint]) expected = 0 result = 'Got exit code %d, expected %d\n' % (rc, expected) self.assertEquals(expected, rc, result + report) # Make sure we can't see the file anymore result = "Found testfile %s in mounted directory" % test_file self.assertFalse(os.path.exists('%s/%s' % (mountpoint, test_file)), result) os.chdir(self.current_dir) testlib.recursive_rm(mountpoint)
def test_puppet_spec_tests(self): '''Testsuite rake spec (takes a while)''' if self.lsb_release['Release'] >= 11.04: (totalmem, totalswap) = testlib.get_memory() if totalmem < 1000000: print "\nWARNING: Need 1GB of RAM or higher on Natty+ or tests may fail!" ex_failures = [] if self.lsb_release['Release'] == 10.04: #ex_failures.append("Errno::EISDIR in 'Puppet::Indirector::FileContent::FileServer when finding files should find plugin file content in the environment specified in the request'") ex_failures.append( "Net::HTTPError in 'Puppet::Indirector::REST when using webrick when finding a model instance over REST when a matching model instance can be found should use a supported format'" ) ex_failures.append( "Net::HTTPError in 'Puppet::Indirector::REST when using mongrel when finding a model instance over REST when a matching model instance can be found should use a supported format'" ) ex_failures.append( "Puppet::ParseError in 'Puppet::Parser::Compiler should be able to determine the configuration version from a local version control repository'" ) ex_failures.append( "'Puppet::Type::File when writing files should fail if no backup can be performed' FAILED" ) ex_failures.append( "'puppetmasterd should create a PID file' FAILED") ex_failures.append( "Puppet::SSLCertificates::Support::MissingCertificate in 'puppetmasterd should be serving status information over xmlrpc'" ) elif self.lsb_release['Release'] == 11.10: ex_failures.append( "Puppet::Interface::Action with action-level options it should behave like things that declare options should support option documentation" ) ex_failures.append( "Puppet::Application::Inspect when executing when archiving to a bucket when auditing files should not send unreadable files" ) ex_failures.append( "Puppet::Interface it should behave like things that declare options should support option documentation" ) ex_failures.append( "Puppet::Parser::Compiler should be able to determine the configuration version from a local version control repository" ) elif self.lsb_release['Release'] == 12.04: # Holy failures, Batman! Good thing this is an LTS! ex_failures.append( "Puppet::Type::File#asuser should return the desired owner if they can write to the parent directory" ) ex_failures.append( "Puppet::Type::File#asuser should return nil if the desired owner can't write to the parent directory" ) ex_failures.append( "Puppet::Type::File#asuser should return the desired owner if they can write to the parent directory" ) ex_failures.append( "Puppet::Type::File#asuser should return nil if the desired owner can't write to the parent directory" ) # CVE-2013-4969 regression fix has broken test cases ex_failures.append( "Puppet::Type::File#write when resource mode is not supplied and content is supplied should default to 0644 mode" ) ex_failures.append( "Puppet::Type::File#write when resource mode is not supplied and no content is supplied should use puppet's default umask of 022" ) ex_failures.append( "Puppet::Application::Device when running for each device should cleanup the vardir setting after the run" ) ex_failures.append( "Puppet::Application::Device when running for each device should cleanup the confdir setting after the run" ) ex_failures.append( "Puppet::Application::Device when running for each device should cleanup the certname setting after the run" ) ex_failures.append( "Puppet::Application::Inspect when executing when archiving to a bucket when auditing files should not send unreadable files" ) ex_failures.append( "Puppet::Indirector::SslFile should fail if no store directory or file location has been set" ) ex_failures.append( "Puppet::Parser::Compiler should be able to determine the configuration version from a local version control repository" ) # Big heap of fail: (not sure why it's running a windows test...) self.testsuite_disabled.append( "spec/integration/util/windows/security_spec.rb") # This test should be removed, as the file it's testing got removed in 2.7.11-1ubuntu2.5 self.testsuite_disabled.append( "spec/unit/util/instrumentation/listeners/process_name_spec.rb" ) elif self.lsb_release['Release'] == 12.10 or self.lsb_release[ 'Release'] == 13.04: # Quantal and Raring ex_failures.append( "Puppet::Type::File#asuser should return the desired owner if they can write to the parent directory" ) ex_failures.append( "Puppet::Type::File#asuser should return nil if the desired owner can't write to the parent directory" ) ex_failures.append( "Puppet::Type::File#asuser should return the desired owner if they can write to the parent directory" ) ex_failures.append( "Puppet::Type::File#asuser should return nil if the desired owner can't write to the parent directory" ) # CVE-2013-4969 regression fix has broken test cases ex_failures.append( "Puppet::Type::File#write when resource mode is not supplied and content is supplied should default to 0644 mode" ) ex_failures.append( "Puppet::Type::File#write when resource mode is not supplied and no content is supplied should use puppet's default umask of 022" ) ex_failures.append( "Puppet::Application::Inspect when executing when archiving to a bucket when auditing files should not send unreadable files" ) ex_failures.append( "Puppet::Node::Facts::InventoryActiveRecord#search should return node names that match 'equal' constraints" ) ex_failures.append( "Puppet::Node::Facts::InventoryActiveRecord#search should return node names that match 'not equal' constraints" ) ex_failures.append( "Puppet::Indirector::SslFile should fail if no store directory or file location has been set" ) ex_failures.append( "Puppet::Parser::Compiler should be able to determine the configuration version from a local version control repository" ) ex_failures.append( "Puppet::Network::RestAuthConfig should warn when matching against IP addresses" ) # Big heap of fail: (not sure why it's running a windows test...) self.testsuite_disabled.append( "spec/integration/util/windows/security_spec.rb") elif self.lsb_release['Release'] >= 13.10: # Saucy and higher ex_failures.append( "Puppet::Network::Server when using webrick before listening should not be reachable at the specified address and port" ) ex_failures.append( "Puppet::Network::Server when using webrick when listening should be reachable on the specified address and port" ) ex_failures.append( "Puppet::Network::Server when using webrick when listening should use any specified bind address" ) ex_failures.append( "Puppet::Network::Server when using webrick when listening should not allow multiple servers to listen on the same address and port" ) ex_failures.append( "Puppet::Network::Server when using webrick after unlistening should not be reachable on the port and address assigned" ) ex_failures.append( "Puppet::Parser::Compiler using classic parser behaves like the compiler should be able to determine the configuration version from a local version control repository" ) ex_failures.append( "Puppet::Parser::Compiler using future parser behaves like the compiler should be able to determine the configuration version from a local version control repository" ) ex_failures.append( "Puppet::SSL::CertificateAuthority should create a CA host") ex_failures.append( "Puppet::SSL::CertificateAuthority should be able to generate a certificate" ) ex_failures.append( "Puppet::SSL::CertificateAuthority should be able to generate a new host certificate" ) ex_failures.append( "Puppet::SSL::CertificateAuthority should be able to revoke a host certificate" ) ex_failures.append( "Puppet::SSL::CertificateAuthority should have a CRL") ex_failures.append( "Puppet::SSL::CertificateAuthority should be able to read in a previously created CRL" ) ex_failures.append( "Puppet::SSL::CertificateAuthority when signing certificates should be able to sign certificates" ) ex_failures.append( "Puppet::SSL::CertificateAuthority when signing certificates should save the signed certificate" ) ex_failures.append( "Puppet::SSL::CertificateAuthority when signing certificates should be able to sign multiple certificates" ) ex_failures.append( "Puppet::SSL::CertificateAuthority when signing certificates should save the signed certificate to the :signeddir" ) ex_failures.append( "Puppet::SSL::CertificateAuthority when signing certificates should save valid certificates" ) ex_failures.append( "Puppet::SSL::CertificateAuthority when signing certificates should verify proof of possession when signing certificates" ) ex_failures.append( "Puppet::SSL::CertificateRequest should be able to save CSRs") ex_failures.append( "Puppet::SSL::CertificateRequest should be able to find saved certificate requests via the Indirector" ) ex_failures.append( "Puppet::SSL::CertificateRequest should save the completely CSR when saving" ) ex_failures.append( "Puppet::SSL::CertificateRevocationList should be able to read in written out CRLs with no revoked certificates" ) ex_failures.append( "Puppet::SSL::Host should be considered a CA host if its name is equal to 'ca'" ) ex_failures.append( "Puppet::SSL::Host should pass the verification of its own SSL store" ) ex_failures.append( "Puppet::SSL::Host when managing its key should be able to generate and save a key" ) ex_failures.append( "Puppet::SSL::Host when managing its key should save the key such that the Indirector can find it" ) ex_failures.append( "Puppet::SSL::Host when managing its key should save the private key into the :privatekeydir" ) ex_failures.append( "Puppet::SSL::Host when managing its certificate request should be able to generate and save a certificate request" ) ex_failures.append( "Puppet::SSL::Host when managing its certificate request should save the certificate request such that the Indirector can find it" ) ex_failures.append( "Puppet::SSL::Host when managing its certificate request should save the private certificate request into the :privatekeydir" ) ex_failures.append( "Puppet::SSL::Host when the CA host should never store its key in the :privatekeydir" ) ex_failures.append( "Puppet::Application::Inspect when executing when archiving to a bucket when auditing files should not send unreadable files" ) ex_failures.append( "Puppet::Application::Master when running the main command should give the server to the daemon" ) ex_failures.append( "Puppet::Application::Master when running the main command should generate a SSL cert for localhost" ) ex_failures.append( "Puppet::Application::Master when running the main command should make sure to *only* hit the CA for data" ) ex_failures.append( "Puppet::Application::Master when running the main command should daemonize if needed" ) ex_failures.append( "Puppet::Application::Master when running the main command should start the service" ) ex_failures.append( "Puppet::Reports::Rrdgraph should not error on 0.25.x report format" ) ex_failures.append( "Puppet::Reports::Rrdgraph should not error on 2.6.x report format" ) # Big heap of fail: (not sure why it's running a windows test...) self.testsuite_disabled.append( "spec/integration/util/windows/security_spec.rb") # This fails miserably, need to figure out why self.testsuite_disabled.append("spec/integration/faces/ca_spec.rb") if self.lsb_release['Release'] == 11.10 or self.lsb_release[ 'Release'] == 12.04: print "INFO: installing rspec from gem since we need 2.6.0 to run 'rake spec' with puppet 2.7" # rspec 2.7 doesn't work with ruby1.8 on 11.10 rc, report = testlib.cmd( ['gem', 'install', 'rspec', '-v', '2.6.0']) expected = 0 self.assertEquals(rc, expected, "get install rspec failed:\n" + report) if self.lsb_release['Release'] == 12.10 or self.lsb_release[ 'Release'] == 13.04: print "INFO: installing mocha from gem since we need an older version in quantal+" # mocha 0.10.x doesn't work with puppet 2.7 rc, report = testlib.cmd( ['gem1.8', 'install', 'mocha', '-v', '0.9.12']) expected = 0 self.assertEquals(rc, expected, "get install mocha failed:\n" + report) if self.lsb_release['Release'] >= 13.10: print "INFO: installing rgen from gem since it's not packaged" # rgen is needed to run test suite on 13.10+ rc, report = testlib.cmd(['gem', 'install', 'rgen', '-v', '0.6.6']) expected = 0 self.assertEquals(rc, expected, "get install rgen failed:\n" + report) non_deterministic_tests = [] if self.lsb_release['Release'] == 10.04: non_deterministic_tests.append( "'Puppet::Type::Mount::ProviderParsed Puppet::Type::Mount::ProviderParsed when modifying the filesystem tab should write the mount to disk when :flush is called' FAILED" ) if self.lsb_release['Release'] == 12.04: # New failure with July 2012 security update: non_deterministic_tests.append( "Puppet::Network::RestAuthConfig should warn when matching against IP addresses" ) if self.lsb_release['Release'] == 12.10: non_deterministic_tests.append( "Puppet::Indirector::REST when making http requests should provide a suggestive error message when certificate verify failed" ) if self.lsb_release['Release'] >= 12.10: # These three only fail on i386 for some reason non_deterministic_tests.append( "Puppet::Type::Exec::ProviderPosix#run should execute the command if the command given includes arguments or subcommands" ) non_deterministic_tests.append( "Puppet::Type::Exec::ProviderPosix#run should warn if you're overriding something in environment" ) non_deterministic_tests.append( "Puppet::Type::Exec::ProviderPosix#run when the command is a relative path should execute the command if it finds it in the path and is executable" ) for i in self.testsuite_disabled: d = os.path.dirname(os.path.join(self.tmpdir, i)) if not os.path.exists(d): testlib.cmd(['mkdir', '-p', d]) shutil.move(os.path.join(self.testsuite, i), os.path.join(self.tmpdir, i)) if self.lsb_release['Release'] >= 12.10: # Disable the gem check since we want to use the system rspec f = os.path.join(self.testsuite, "spec/spec_helper.rb") self.testsuite_edits.append(f) testlib.config_replace(f, "", append=True) subprocess.call(['sed', '-i', "s/^gem 'rspec'/#gem 'rspec'/", f]) self._run_rake_tests('spec', ex_failures, None, non_deterministic_tests)
def __enable_mod(self, mod): rc, report = testlib.cmd(['a2enmod', mod]) expected = 0 result = 'Got exit code %d, expected %d\n' % (rc, expected) self.assertEquals(expected, rc, result + report)
def test_gfs_tool(self): '''Test gfs_tool/gfs2_tool''' self._create_fs(use_lvm=True) print "" if self.type == "gfs" or self.lsb_release['Release'] < 8.10: print " counters" rc, report = testlib.cmd( ['%s_tool' % self.type, 'counters', self.mnt]) expected = 0 result = 'Got exit code %d, expected %d\n' % (rc, expected) self.assertEquals(expected, rc, result + report) for i in ['locks', 'locks held']: result = "Could not find '%s'\n" % (i) self.assertTrue(i in report, result + report) # gfs2_tool df blows up on Intrepid if self.type == "gfs" or self.lsb_release['Release'] != 8.10: print " df" rc, report = testlib.cmd(['%s_tool' % self.type, 'df', self.mnt]) for i in ['Block size', 'Journals', 'Resource Groups']: result = "Could not find '%s'\n" % (i) self.assertTrue(i in report, result + report) if self.type == "gfs": print " getsb" rc, report = testlib.cmd( ['%s_tool' % self.type, 'getsb', self.mnt]) expected = 0 result = 'Got exit code %d, expected %d\n' % (rc, expected) self.assertEquals(expected, rc, result + report) for i in ['mh_magic', 'mh_type']: result = "Could not find '%s'\n" % (i) self.assertTrue(i in report, result + report) print " jindex" rc, report = testlib.cmd( ['%s_tool' % self.type, 'jindex', self.mnt]) expected = 0 result = 'Got exit code %d, expected %d\n' % (rc, expected) self.assertEquals(expected, rc, result + report) for i in ['ji_addr', 'ji_reserved']: result = "Could not find '%s'\n" % (i) self.assertTrue(i in report, result + report) print " rindex" rc, report = testlib.cmd( ['%s_tool' % self.type, 'rindex', self.mnt]) expected = 0 result = 'Got exit code %d, expected %d\n' % (rc, expected) self.assertEquals(expected, rc, result + report) for i in ['ri_addr', 'ri_reserved']: result = "Could not find '%s'\n" % (i) self.assertTrue(i in report, result + report) rc, report = testlib.cmd(['%s_tool' % self.type, 'gettune', self.mnt]) expected = 0 result = 'Got exit code %d, expected %d\n' % (rc, expected) self.assertEquals(expected, rc, result + report) for i in ['quota', 'statfs']: result = "Could not find '%s'\n" % (i) self.assertTrue(i in report, result + report) print " list" rc, report = testlib.cmd(['%s_tool' % self.type, 'list']) expected = 0 result = 'Got exit code %d, expected %d\n' % (rc, expected) self.assertEquals(expected, rc, result + report) search = 'dm-' result = "Could not find '%s'\n" % (i) self.assertTrue(search in report, result + report) print " lockdump" rc, report = testlib.cmd(['%s_tool' % self.type, 'lockdump', self.mnt]) expected = 0 result = 'Got exit code %d, expected %d\n' % (rc, expected) self.assertEquals(expected, rc, result + report) search_terms = ['s:SH', 's:UN', 's:EX'] if self.type == "gfs" or self.lsb_release['Release'] < 8.10: search_terms = ['gl_flags', 'gh_flags', 'Glock', 'Holder'] for i in search_terms: result = "Could not find '%s'\n" % (i) self.assertTrue(i in report, result + report)
def _setup_sasl(self, mech, other_mech="", force_sasldb=False): '''Setup sasl for mech''' conf_file = '/etc/postfix/main.cf' for field in [ 'smtpd_sasl_type', 'smtpd_sasl_local_domain', 'smtpd_tls_auth_only' ]: testlib.config_comment(conf_file, field) testlib.config_set(conf_file, 'smtpd_sasl_path', 'smtpd') testlib.config_set(conf_file, 'smtpd_sasl_auth_enable', 'yes') #testlib.config_set(conf_file,'broken_sasl_auth_clients','yes') testlib.config_set(conf_file, 'smtpd_sasl_authenticated_header', 'yes') testlib.config_set(conf_file, 'smtpd_tls_loglevel', '2') # setup smtpd.conf and the sasl users contents = '' self.assertTrue(mech in ['LOGIN', 'PLAIN', 'CRAM-MD5', 'DIGEST-MD5'], "Invalid mech: %s" % mech) if not force_sasldb and (mech == "PLAIN" or mech == "LOGIN"): conf_file = '/etc/default/saslauthd' testlib.config_set(conf_file, 'START', 'yes', spaces=False) contents = ''' pwcheck_method: saslauthd allowanonymouslogin: 0 allowplaintext: 1 mech_list: %s %s ''' % (mech, other_mech) # attach SASL to postfix chroot subprocess.call( ['mkdir', '-p', '/var/spool/postfix/var/run/saslauthd']) subprocess.call(['rm', '-rf', '/var/run/saslauthd']) subprocess.call([ 'ln', '-s', '/var/spool/postfix/var/run/saslauthd', '/var/run/saslauthd' ]) subprocess.call(['/usr/sbin/service', 'saslauthd', 'stop'], stdout=subprocess.PIPE) assert subprocess.call(['/usr/sbin/service', 'saslauthd', 'start'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) == 0 # Force crackful perms so chroot'd postfix can talk to saslauthd subprocess.call( ['chmod', 'o+x', '/var/spool/postfix/var/run/saslauthd']) else: plaintext = "1" if mech == "LOGIN" or mech == "PLAIN": plaintext = "0" contents = ''' pwcheck_method: auxprop allowanonymouslogin: 0 allowplaintext: %s mech_list: %s %s ''' % (plaintext, mech, other_mech) # Add user to sasldb2 testlib.config_replace("/etc/sasldb2", '', append=False) rc, report = testlib.cmd(['postconf', '-h', 'myhostname']) expected = 0 result = 'Got exit code %d, expected %d\n' % (rc, expected) self.assertEqual(expected, rc, result + report) child = pexpect.spawn('saslpasswd2 -c -u %s %s' % (report.strip(), self.user.login)) time.sleep(0.2) child.expect(r'(?i)password', timeout=5) time.sleep(0.2) child.sendline(self.user.password) time.sleep(0.2) child.expect(r'.*(for verification)', timeout=5) time.sleep(0.2) child.sendline(self.user.password) time.sleep(0.2) rc = child.expect('\n', timeout=5) time.sleep(0.2) self.assertEqual(rc, expected, "passwd returned %d" % (rc)) child.kill(0) os.chmod("/etc/sasldb2", 0o640) rc, report = testlib.cmd(['chgrp', 'postfix', '/etc/sasldb2']) expected = 0 result = 'Got exit code %d, expected %d\n' % (rc, expected) self.assertEqual(expected, rc, result + report) # Force crackful perms so chroot'd postfix can talk to saslauthd subprocess.call( ['mv', '-f', '/etc/sasldb2', '/var/spool/postfix/etc']) subprocess.call( ['ln', '-s', '/var/spool/postfix/etc/sasldb2', '/etc/sasldb2']) conf_file = '/etc/postfix/sasl/smtpd.conf' testlib.config_replace(conf_file, contents, append=False) # Restart server self._restart_server()
def _run_mkfontdir(self): '''Runs mkfontdir on the temp directory''' (rc, report) = testlib.cmd(["/usr/bin/mkfontdir", self.tempdir]) expected = 0 result = 'Got exit code %d, expected %d\n' % (rc, expected) self.assertEquals(expected, rc, result + report)
def test_small_sized_reply(self): '''Test for CVE-2007-6341 fix''' badserver = subprocess.Popen([ 'perl', '-e', r''' # Beyond Security(c) # Vulnerability found by beSTORM - DNS Server module use strict; use IO::Socket; my($sock, $oldmsg, $newmsg, $hisaddr, $hishost, $MAXLEN, $PORTNO); $MAXLEN = 1024; $PORTNO = 5351; $sock = IO::Socket::INET->new(LocalPort => $PORTNO, Proto => 'udp') or die "socket: $@"; my $oldmsg = "\x5a\x40\x81\x80\x00\x01\x00\x01\x00\x01\x00\x01\x07\x63\x72\x61". "\x63\x6b\x6d\x65\x0a\x6d\x61\x73\x74\x65\x72\x63\x61\x72\x64\x03". "\x63\x6f\x6d\x00\x00\x01\x00\x01\x03\x77\x77\x77\x0e\x62\x65\x79". "\x6f\x6e\x64\x73\x65\x63\x75\x72\x69\x74\x79\x03\x63\x6f\x6d\x00". "\x00\x01\x00\x01\x00\x00\x00\x01\x00\x04\xc0\xa8\x01\x02\x0e\x62". "\x65\x79\x6f\x6e\x64\x73\x65\x63\x75\x72\x69\x74\x79\x03\x63\x6f". "\x6d\x00\x00\x02\x00\x01\x00\x00\x00\x01\x00\x1b\x02\x6e\x73\x03". "\x77\x77\x77\x0e\x62\x65\x79\x6f\x6e\x64\x73\x65\x63\x75\x72\x69". "\x74\x79\x03\x63\x6f\x6d\x00\x02\x6e\x73\x0e\x62\x65\x79\x6f\x6e". "\x64\x73\x65\x63\x75\x72\x69\x74\x79\x03\x63\x6f\x6d\x00\x00\x01". "\x00\x01\x00\x00\x00\x01\x00\x01\x41"; $sock->recv($newmsg, $MAXLEN); my($port, $ipaddr) = sockaddr_in($sock->peername); $hishost = gethostbyaddr($ipaddr, AF_INET); $sock->send($oldmsg); print "Sent reply to $hishost\n"; ''' ], stdout=subprocess.PIPE, stderr=subprocess.PIPE) rc, out = testlib.cmd([ 'perl', '-e', ''' use strict; use warnings; use Net::DNS; my $res = Net::DNS::Resolver->new; $res->nameservers('127.0.0.1'); $res->port(5351); $res->udp_timeout(2); my $query = $res->search("%s"); if ($query) { foreach my $rr ($query->answer) { next unless $rr->type eq "%s"; print $rr->address, "\n"; } } else { die "query failed: ", $res->errorstring, "\n"; } ''' ]) self.assertNotEqual(rc, 0, out) self.assertTrue('timed out' in out, out) out, err = badserver.communicate() self.assertTrue("Sent reply to " in out, out)
def test_puppet_unit_tests(self): '''Testsuite rake unit (takes a while)''' # Seems there is no unit tests anymore on saucy+ if self.lsb_release['Release'] >= 13.10: return self._skipped("No unit tests in 13.10 and later") if self.lsb_release['Release'] >= 11.10: (totalmem, totalswap) = testlib.get_memory() if totalmem < 1000000: print "\nWARNING: Need 1GB of RAM or higher on Oneiric+ or tests may fail!" ex_failures = [] if self.lsb_release['Release'] == 10.04: ex_failures.append( "test_uppercase_files_are_renamed_and_read(TestCertSupport)") ex_failures.append("test_file_rc(TestDebianServiceProvider)") ex_failures.append("test_sysv_rc(TestDebianServiceProvider)") ex_failures.append("test_autorequire_user(TestExec)") ex_failures.append("test_wxrubylayouts_gem(TestPackageProvider)") ex_failures.append("test_execution(TestPuppetModule)") ex_failures.append("test_existence(TestPuppetModule)") elif self.lsb_release['Release'] == 11.10: ex_failures.append("test_autorequire_user(TestExec)") ex_failures.append("test_nofollowlinks(TestFile)") ex_failures.append("test_duplicateIDs(TestGroupProvider)") ex_failures.append("test_mkgroup(TestGroupProvider)") ex_failures.append("test_wxrubylayouts_gem(TestPackageProvider)") ex_failures.append("test_alluserproperties(TestUserProvider)") ex_failures.append("test_infocollection(TestUserProvider)") ex_failures.append("test_simpleuser(TestUserProvider)") elif self.lsb_release['Release'] == 12.04: ex_failures.append("test_autorequire_user(TestExec)") ex_failures.append("test_nofollowlinks(TestFile)") ex_failures.append("test_duplicateIDs(TestGroupProvider)") ex_failures.append("test_mkgroup(TestGroupProvider)") ex_failures.append("test_wxrubylayouts_gem(TestPackageProvider)") ex_failures.append("test_30_stale_lock(TestPuppetUtilPidlock)") ex_failures.append("test_alluserproperties(TestUserProvider)") ex_failures.append("test_infocollection(TestUserProvider)") ex_failures.append("test_simpleuser(TestUserProvider)") else: # Quantal and higher ex_failures.append("test_autorequire_user(TestExec)") ex_failures.append("test_nofollowlinks(TestFile)") ex_failures.append("test_duplicateIDs(TestGroupProvider)") ex_failures.append("test_mkgroup(TestGroupProvider)") ex_failures.append("test_wxrubylayouts_gem(TestPackageProvider)") ex_failures.append("test_alluserproperties(TestUserProvider)") ex_failures.append("test_infocollection(TestUserProvider)") ex_failures.append("test_simpleuser(TestUserProvider)") # Disabling this test also requires updating test/ral/type/filesources.rb, so # do it here if self.lsb_release['Release'] >= 11.04 and self.lsb_release[ 'Release'] < 13.10: self.testsuite_disabled.append("test/network/handler/runner.rb") # Need to include puppet/network/http_pool since we lost runner.rb f = os.path.join(self.testsuite, "test/ral/type/filesources.rb") self.testsuite_edits.append(f) testlib.config_replace(f, "", append=True) subprocess.call([ 'sed', '-i', "s#^require 'mocha'#require 'mocha'\\nrequire 'puppet/network/http_pool'#", f ]) non_deterministic_tests = [] if self.lsb_release['Release'] == 10.04: non_deterministic_tests.append( "test_parse_line(TestCronParsedProvider)") non_deterministic_tests.append( "test_wxrubylayouts_gem(TestPackageProvider)") non_deterministic_tests.append( "'Puppet::Type::File when writing files should fail if no backup can be performed' FAILED" ) ex_errors = [] ex_errors.append("RuntimeError: Global resource removal is deprecated") ex_errors.append( "Puppet::Util::Settings::FileSetting::SettingError: Internal error: The :group setting for must be 'service', not 'daemon'" ) ex_errors.append( "Puppet::Util::Settings::FileSetting::SettingError: Internal error: The :group setting for must be 'service', not 'daemon'" ) if self.lsb_release['Release'] == 11.10: ex_errors.append( "MissingSourceFile: no such file to load -- sqlite3") ex_errors.append( "MissingSourceFile: no such file to load -- sqlite3") if self.lsb_release['Release'] >= 11.10: ex_errors.append("NoMethodError: undefined method `system?' for #") non_deterministic_errors = [] # This now fails on natty too with the july 2012 security update. # It used to only fail on Oneiric+ if self.lsb_release['Release'] >= 11.04: non_deterministic_errors.append( "Errno::ENOENT: No such file or directory - /tmp/puppettesting" ) test_type = 'unit' if self.lsb_release['Release'] > 99.10: test_type = 'test' # this should (maybe?) be used in 2.7.3 and higher for i in self.testsuite_disabled: d = os.path.dirname(os.path.join(self.tmpdir, i)) if not os.path.exists(d): testlib.cmd(['mkdir', '-p', d]) shutil.move(os.path.join(self.testsuite, i), os.path.join(self.tmpdir, i)) self._run_rake_tests(test_type, ex_failures, ex_errors, non_deterministic_tests, non_deterministic_errors)
def setUp(self): '''Set up prior to each test_* function''' self.plugindir = "/etc/puppet/plugins" self.classesdir = "/etc/puppet/manifests/classes" self.site_pp = "/etc/puppet/manifests/site.pp" self.fileserver_conf = "/etc/puppet/fileserver.conf" self.debian_version = "/etc/debian_version" self.hosts_file = "/etc/hosts" self.puppet_default = "/etc/default/puppet" self.testsuite = "/usr/share/puppet-testsuite" self.testsuite_disabled = [] self.testsuite_edits = [] self.tmpdir = tempfile.mkdtemp(prefix='testlib', dir='/tmp') # Create missing directories if not os.path.exists(self.plugindir): os.mkdir(self.plugindir) if not os.path.exists(self.classesdir): os.mkdir(self.classesdir) # Set up configuration file testlib.config_replace(self.fileserver_conf, '''# [files] path /etc/puppet/files allow * [plugins] path /etc/puppet/plugins allow * ''', append=False) # On Quantal+, we need to use mocha from gem since the one in # the archive is too new. Rename a few directories. There's # probably a better way of doing this. if self.lsb_release['Release'] == 12.10 or self.lsb_release[ 'Release'] == 13.04: rc, report = testlib.cmd([ 'mv', '/usr/lib/ruby/vendor_ruby/mocha', '/usr/lib/ruby/vendor_ruby/mocha-disabled' ]) expected = 0 self.assertEquals(rc, expected, "directory rename failed:\n" + report) rc, report = testlib.cmd([ 'mv', '/usr/lib/ruby/vendor_ruby/mocha.rb', '/usr/lib/ruby/vendor_ruby/mocha.rb-disabled' ]) expected = 0 self.assertEquals(rc, expected, "directory rename failed:\n" + report) # Enable the client service on lucid+ testlib.config_replace(self.puppet_default, "", True) subprocess.call( ['sed', '-i', 's/^START=no/START=yes/', self.puppet_default]) # Add puppet host to host file testlib.config_replace(self.hosts_file, "127.0.0.1 puppet", True) self.serverdaemon = testlib.TestDaemon("/etc/init.d/puppetmaster") self.clientdaemon = testlib.TestDaemon("/etc/init.d/puppet") self._restart()
def _get_my_ip(self): '''Attempt to get local ip address''' # Yes, this is awful. rc, report = testlib.cmd(["/sbin/ifconfig"]) return report.split("\n")[1].split()[1][5:]
def setUp(self): '''Set up prior to each test_* function''' self.cluster_conf = "/etc/cluster/cluster.conf" self.hosts_file = "/etc/hosts" self.ip = None self.cluster_name = "testlib_cluster" self.tmpdir = "" self.domain_name = "testlib.domain" # these are listed in boot start order self.scripts = [ 'openais', 'cman', 'clvm', 'gfs2-tools', 'gfs-tools', 'rgmanager' ] if self.lsb_release['Release'] >= 8.10: self.scripts = [ 'corosync', 'openais', 'cman', 'clvm', 'gfs2-tools', 'gfs-tools', 'rgmanager' ] if self.lsb_release['Release'] < 8.04: self.scripts = [ 'ccs', 'cman', 'gulm', 'fence', 'clvm', 'gfs-tools', 'rgmanager' ] # daemons to check to make sure they are running self.daemons = [ 'clurgmgrd', 'clvmd', 'dlm_controld', 'fenced', 'aisexec', 'ccsd' ] if self.lsb_release['Release'] >= 8.10: self.daemons.remove('aisexec') self.daemons.append('corosync') if self.lsb_release['Release'] < 8.04: self.daemons.remove('aisexec') self.daemons.remove('dlm_controld') if not os.path.exists(os.path.dirname(self.cluster_conf)): os.mkdir(os.path.dirname(self.cluster_conf)) rc, report = testlib.cmd(['hostname']) expected = 0 result = 'Got exit code %d, expected %d\n' % (rc, expected) self.assertEquals(expected, rc, result + report) self.hostname = report.strip() self.fqdn = "%s.%s" % (self.hostname, self.domain_name) self.ip = self._get_ip() stanza = "%s %s" % (self.ip, self.fqdn) hosts_contents = open(self.hosts_file).read() if self.lsb_release['Release'] < 8.04: for line in hosts_contents.splitlines(): if stanza in line or line.startswith('#'): continue result = "Found one of %s, %s or %s in %s. Please remove these entries" % ( self.ip, self.fqdn, self.hostname, self.hosts_file) self.assertFalse( self.ip in line or self.fqdn in line or self.hostname in line, result) # update /etc/hosts, permanently (for good reboots) if stanza not in hosts_contents: testlib.config_replace(self.hosts_file, "%s\n" % stanza, True) cluster_version = "5" name = self.fqdn if self.lsb_release['Release'] < 8.04: cluster_version = "2" name = self.hostname self.cluster_contents = '''<?xml version="1.0" ?> <cluster config_version="%s" name="%s"> <fence_daemon post_fail_delay="0" post_join_delay="3"/> <clusternodes> <clusternode name="%s" nodeid="1" votes="1"> <fence> <method name="1"> <device name="testlib-fence" nodename="%s"/> </method> </fence> </clusternode> </clusternodes> <cman/> <fencedevices> <fencedevice agent="fence_manual" name="testlib-fence"/> </fencedevices> <rm> <failoverdomains/> <resources/> </rm> </cluster> ''' % (cluster_version, self.cluster_name, name, name)
def _run_rake_tests(self, test_type, ex_failures, ex_errors=None, non_deterministic_tests=None, non_deterministic_errors=None): '''Helper for rake tests''' ts_dir = "/usr/share/puppet-testsuite" ts_dir_test = "/usr/share/puppet-testsuite/test" valid_test_types = ['spec'] if self.lsb_release['Release'] > 99.10: valid_test_types.append( 'test') # this should (maybe?) be used in 2.7.3 and higher else: valid_test_types.append('unit') self.assertTrue(test_type in valid_test_types, "Invalid test type '%s'" % test_type) nd_tests = 0 if non_deterministic_tests != None: nd_tests = len(non_deterministic_tests) nd_errors = 0 if non_deterministic_errors != None: nd_errors = len(non_deterministic_errors) os.chdir(ts_dir) # Quantal and Raring now use ruby1.9 by default, make sure we use ruby1.8 if self.lsb_release['Release'] == 12.10 or self.lsb_release[ 'Release'] == 13.04: if test_type == 'unit': # Work around "rake" hardcoded in main testsuite Rakefile os.chdir(ts_dir_test) rc, report = testlib.cmd(['ruby1.8', '/usr/bin/rake']) else: rc, report = testlib.cmd( ['ruby1.8', '/usr/bin/rake', test_type]) else: rc, report = testlib.cmd(['rake', test_type]) # skip rc check as these all fail. Instead, parse the rake output. Idea # here is that we check if we have no more failures. Then check if we # have all our expected failures. This could be made more intelligent, # but this at least guarantees we won't miss anything (even though it # does require updating the script of one of the expected failures # starts to work) pat = re.compile(r'^[0-9]+ .*, [0-9]+ failure') line = '' for line in report.splitlines(): if pat.search(line) != None: break print "\nDEBUG: %s" % line num_failures = 0 for part in line.split(', '): if "failure" in part: num_failures = int(part.split()[0]) total_failures = len(ex_failures) + nd_tests self.assertTrue( num_failures <= total_failures, "Found more than the '%d' expected failures (%d)\n" % (total_failures, num_failures) + report) for f in ex_failures: result = "Could not find '%s' in report" % (f) self.assertTrue(f in report, result + report) # unit tests also have errors if ex_errors == None: return num_errors = int(line.split(', ')[3].split()[0]) total_errors = len(ex_errors) + nd_errors self.assertTrue( num_errors <= total_errors, "Found more than the '%d' expected errors (%d)\n" % (total_errors, num_errors) + report) for f in ex_errors: result = "Could not find '%s' in report" % (f) self.assertTrue(f in report, result + report) if non_deterministic_tests == None: return for n in non_deterministic_tests: result = "INFO: found '%s' in report (test marked as non-deterministic)" % ( n) if n in report: print result if non_deterministic_errors == None: return for n in non_deterministic_errors: result = "INFO: found '%s' in report (error marked as non-deterministic)" % ( n) if n in report: print result
def test_aaa_status(self): '''Test status (apache2ctl)''' rc, report = testlib.cmd(['apache2ctl', 'status']) expected = 0 result = 'Got exit code %d, expected %d\n' % (rc, expected) self.assertEquals(expected, rc, result + report)