Report: High Availability and Distributed Storage miniconf at LCA 2012
by Tim Serong
Hi All,
Apologies for the mass email, but it seemed most appropriate to post a
followup to all the lists I originally sent the LCA 2012 HA miniconf CFP
to. I would humbly suggest that any miniconf-related replies be sent
either direct to myself, or to ha-wg(a)lists.linux-foundation.org.
Comments on the HA BOF mentioned below should probably go to either
pacemaker(a)oss.clusterlabs.org or linux-ha(a)lists.linux-ha.org.
==========
The High Availability and Distributed Storage miniconf[1] at LCA 2012
went very well. Probably 60+ in attendance (so about 1/8th of the
conference attendees, given 7 other concurrent miniconfs), with maybe a
few less later in the day. First half was more linux-ha type stuff,
second half more database-y, with a bit of CTDB and Samba foo in the
middle. Sadly we didn't actually get much in the way of distributed
storage talks -- oddly enough, there was a conspicuous absence of
Gluster and Ceph talks in the main conf track as well. We hope to have
better luck next year (I plan to propose this miniconf again).
The talks were almost all 25 minute slots, as follows:
Storage Replication in High-Performance High-Availability Environments
http://www.youtube.com/watch?v=l910kiEuHOM
by Florian Haas; discussion of using drbd with flashcache to
provide failover while still keeping the cache hot.
Building a Non-Shared Storage HA Cluster with Pacemaker & PostgreSQL 9.1
http://www.youtube.com/watch?v=ON4QGfDkqwg
by Keisuke Mori; enhanced pgsql RA to work with PostgreSQL
streaming replication.
Extend Pacemaker to Support Geographically Distributed Clustering
http://www.youtube.com/watch?v=S3DB_DSVI_A
by Tim Serong on behalf of Jiaju Zhang; an introduction to
Booth (what it is, how to configure it).
HiPBX - HiAv VoIP with Open Source Software and 5000 Lines of Bash
http://www.youtube.com/watch?v=CpMifzcYSdU
by Rob Thomas; showing how he built an HA VoIP system with live
demo (which almost worked) and a rickroll. Very entertaining.
Squashing SPOFs with Common Sense, Velcro, and a Hammer
http://www.youtube.com/watch?v=6mQ65Flmri8
also by Rob Thomas; somewhat more generic (label everything,
do proper cable management etc.), but still also entertaining.
CTDB Overview
http://www.youtube.com/watch?v=L7-QSbEEjS0
by Ronnie Sahlberg; CTDB's approach to clustering - run
everything everywhere instead of classic active/passive, and
know what state is safe to drop/lose if a node dies.
High Availability Login Services with Samba4 Active Directory
http://www.youtube.com/watch?v=-EeqYbEwJU8
by Kai Blin; Brief overview of using Samba4 for AD auth - Kai
has a whole bunch of little embedded systems in his house
running this, which is kind of cute.
HA Lessons Learned from Darth Vader
http://www.youtube.com/watch?v=tnBz8212X5M
by Ronnie Sahlberg; essentially saying the Empire got it wrong
with the Death Star (big SPOF), but did better on Hoth with its
redundant army of AT-ATs.
MySQL for the Developer in a Post-Oracle World
http://www.youtube.com/watch?v=oJ9HnFgC48s
by Adam Donnison; various forking etc. of MySQL, both project
forking and different companies providing dev, consulting etc.
MySQL and Postgres Cloud Offerings
http://www.youtube.com/watch?v=UFTp0zA4Mx8
by Stewart Smith & Selena Deckelmann; basically there aren't
many sensible DB cloud offerings and/or they don't work and/or
they don't scale (I might be exaggerating, but probably not
much).
Scaling Data: Postgres, The Stack and the Future of Replication
http://www.youtube.com/watch?v=Pdgzy7KoGWU
by Selena Deckelmann; some general postgres discussion, live
demo of setting up binary replication, new stuff in 9.2.
Swift 101
http://www.youtube.com/watch?v=mX25RtDvf8E
by Monty Taylor; introduction to Swift in OpenStack - it's not
a RAID, it's not distributed storage, it's not (etc.), it's an
object store! Good for backups (large, write once, read never)
and web content (small, write once, read many).
MySQL Web Infra Scaling and Keeping it Online, Cheaply
http://www.youtube.com/watch?v=A4K-ZDDBRHI
by Arjen Lentz; the approaches his company takes when "fixing"
client systems so that they're resilient to failure (mysql
tuning, split web/db servers, backups, monitoring, master/slave
systems etc.)
We also had two lightning talks which apparently weren't recorded. One
was Avi Miller from Oracle announcing that they're supporting DRBD 8.3
in UEK2 (which is currently in beta). The other was from Florian Haas
ranting about crappy HA stack usability (e.g.: inscrutable command line
options and incomprehensible error messages). It was fun.
On Thursday, I co-presented the tutorial "High Availability Sprint: from
the brink of disaster to the Zen of Pacemaker" with Florian Haas. We
ran through basic concepts of drbd, corosync, pacemaker etc. then did a
walkthrough of setting up drbd+corosync+pacemaker+mysql on two VMs (VM
images were provided in advance, so participants could follow along).
This was well received, with people coming out of it actually
understanding what the hell we were talking about. Probably 30-40
attendees. The video is at http://www.youtube.com/watch?v=3GoT36cK6os
After that we had an HA birds of a feather session for a couple of
hours, maybe 15-20 people. Party this was answering questions and
random discussion, but also us (myself, Florian, Andrew Beekhof) seeking
feedback about pain points with the HA stack. Comments include:
- Documentation is still too hard to find.
- crm shell lacks some facilities for automation with e.g.: puppet.
Someone wanted to be able to query the current value of a monitor op
on a resource. Querying the whole primitive and grepping is too
coarse.
- The whole stack is too complicated(?) and/or some concern about
maintenance of documentation going forwards.
- Corosync 2.0 drops support for plugins, and requires libqb.
- Someone wants resource-agents manpage generation foo to go to a
devel package, so people shipping their own RAs can utilize that.
- A "frequently encountered errors and solutions" help page somewhere
would be of major benefit. We could probably crowdsource this to some
extent. We're still evaluating where this could be hosted best, but
currently the Clusterlabs wiki seems like the most suitable candidate.
- The need to deprecate resource agents came up again ("should I use
ocf:heartbeat:drbd or ocf:linbit:drbd?"), highlighting the need for
the overdue OCF spec update.
- Some part of Red Hat's decision to use their own (new, in development)
shell for Pacemaker in RHEL 7(?) is because they want that shell to
do whole cluster setup, including corosync etc. which is a different
scope than the crm shell.
Thanks for reading, hope it was interesting.
Regards,
Tim
[1]
http://lca2012.linux.org.au/wiki/index.php/Miniconfs/HighAvailabilityAndD...
--
Tim Serong
Senior Clustering Engineer
SUSE
tserong(a)suse.com
12 years, 3 months
D-Bus to QMF bridge
by Zane Bitter
Hi Radek,
I have one question about the D-Bus to QMF bridge: at the moment it
looks like there is one bridge object exported and that method calls
have to specify the object explicitly. Have you considered a model where
there are more, finer-grained objects? The ideal would be if we could
export every D-Bus object as a QMF object, but it may be that there are
just too many objects for this to be practical. My concern is that we
could end up missing out on a lot of the introspection capabilities that
QMF provides.
(I'm including the list in case anybody else has any input. The code
under discussion can be found here:
https://github.com/rnovacek/matahari/tree/dbus-bridge)
cheers,
Zane.
12 years, 3 months
[PATCH] Shell: Make method calls more robust
by Zane Bitter
An asynchronous method call may return a result before the actual method
call has returned the sequence number, so use a lock to ensure this is
handled correctly. Also, correctly ignore results that don't match an
expected sequence number - e.g. if they come from a previous call that has
already timed out.
Signed-off-by: Zane Bitter <zbitter(a)redhat.com>
---
src/python/matahari/core.py | 14 +++++++++-----
1 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/src/python/matahari/core.py b/src/python/matahari/core.py
index e79b24a..bcb1597 100644
--- a/src/python/matahari/core.py
+++ b/src/python/matahari/core.py
@@ -177,16 +177,20 @@ class Manager(object):
results = [None] * len(objs)
seqs = []
event = threading.Event()
+ seqlock = threading.Lock()
def recv_response(seq, response):
- i = seqs.index(seq)
- results[i] = response
- if None not in results:
- event.set()
+ with seqlock:
+ i = seqs.index(seq)
+ if i >= 0:
+ results[i] = response
+ if None not in results:
+ event.set()
self._async.handle_method_responses(recv_response)
for o in objs:
m = getattr(o, method)
- seqs.append(m(*args, _async=True, **kwargs))
+ with seqlock:
+ seqs.append(m(*args, _async=True, **kwargs))
event.wait(TIMEOUT)
return tuple(results)
12 years, 3 months
[PATCH] Shell: Add command line options
by Zane Bitter
Allow the user to specify the broker hostname and port, and make exception
debugging a selectable option.
Signed-off-by: Zane Bitter <zbitter(a)redhat.com>
---
src/python/matahari/api.py | 2 +
src/python/matahari/shell/__init__.py | 37 +++++++++++++++++---
.../matahari/shell/interpreter/interpreter.py | 10 +----
src/python/mhsh | 26 ++++++++++++--
4 files changed, 58 insertions(+), 17 deletions(-)
diff --git a/src/python/matahari/api.py b/src/python/matahari/api.py
index d48ab35..6583103 100644
--- a/src/python/matahari/api.py
+++ b/src/python/matahari/api.py
@@ -20,7 +20,7 @@ import core
class BrokerConnection(object):
def __init__(self, host='localhost', port=49000, ssl=False):
self.host = host
- self.port = 49000
+ self.port = port
self.ssl = ssl
class Proxy(object):
diff --git a/src/python/matahari/shell/__init__.py b/src/python/matahari/shell/__init__.py
index 2cf3855..a72c559 100644
--- a/src/python/matahari/shell/__init__.py
+++ b/src/python/matahari/shell/__init__.py
@@ -15,15 +15,42 @@
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
import matahari.api
import mode
import interpreter
+
class MatahariShell(object):
- def __init__(self, prompt='mhsh'):
- self.state = matahari.api.Matahari()
+ """A Matahari Shell object, with its own API state."""
+
+ def __init__(self, connection=None, debug=False):
+ """
+ Initialise with optional connection parameters.
+ Specify debug=True to print all exceptions.
+ """
+ args = []
+ if connection is not None:
+ args.append(connection)
+ self.state = matahari.api.Matahari(*args)
initial_mode = mode.RootMode(self.state)
- self.interpreter = interpreter.Interpreter(prompt, initial_mode, debug=True)
+ self.interpreter = interpreter.Interpreter('mhsh', initial_mode,
+ debug=debug)
+
+ def __call__(self, *args):
+ """
+ Run the shell, either in interactive mode or executing the specified
+ scripts.
+ """
+ def getscript(arg):
+ if arg == '-':
+ import sys
+ return sys.stdin
+ return file(arg)
- def __call__(self):
- self.interpreter.cmdloop()
+ if args:
+ for arg in args:
+ with getscript(arg) as script:
+ self.interpreter.runscript(script)
+ else:
+ self.interpreter.cmdloop()
diff --git a/src/python/matahari/shell/interpreter/interpreter.py b/src/python/matahari/shell/interpreter/interpreter.py
index f641237..a8722c7 100644
--- a/src/python/matahari/shell/interpreter/interpreter.py
+++ b/src/python/matahari/shell/interpreter/interpreter.py
@@ -22,6 +22,7 @@ The commands supported by the interpreter are supplied by the current mode,
which can be changed by passing a new mode to the set_mode() method.
"""
+import sys
import cmd
import mode
@@ -85,7 +86,7 @@ class Interpreter(cmd.Cmd):
if self.debug:
import traceback
- self.stdout.write(traceback.format_exc())
+ sys.stderr.write(traceback.format_exc())
def cmdloop(self, *args, **kwargs):
while True:
@@ -133,10 +134,3 @@ class Interpreter(cmd.Cmd):
return (filter(lambda n: n != 'do_EOF', cmd.Cmd.get_names(self)) +
['%s_%s' % (p, c) for p in ['do', 'complete', 'help']
for c in self.mode])
-
-
-if __name__ == '__main__':
- mode = mode.Mode()
- shell = Interpreter('mhsh', mode)
- shell.cmdloop()
-
diff --git a/src/python/mhsh b/src/python/mhsh
index ff26b30..9e2f216 100755
--- a/src/python/mhsh
+++ b/src/python/mhsh
@@ -1,10 +1,30 @@
#!/usr/bin/env python
-import matahari.shell
+import matahari.shell, matahari.api
+
+
+def getoptions():
+ from optparse import OptionParser
+
+ parser = OptionParser('usage: %prog [-d] [-b BROKER] [-p PORT] [SCRIPT]')
+ parser.add_option('-d', '--debug', dest='debug', action='store_true',
+ default=False, help='Enable debugging output')
+ parser.add_option('-b', '--broker', dest='broker', action='store',
+ default='localhost', type='string',
+ help='Specify the broker to connect to')
+ parser.add_option('-p', '--port', dest='port', action='store',
+ default=49000, type='int',
+ help='Specify the broker port to connect to')
+ return parser.parse_args()
def main():
- shell = matahari.shell.MatahariShell()
- shell()
+ options, args = getoptions()
+ connection = matahari.api.BrokerConnection(options.broker, options.port)
+
+ shell = matahari.shell.MatahariShell(connection, debug=options.debug)
+
+ shell(*args)
+
if __name__ == '__main__':
main()
12 years, 3 months
[matahari] DBus tests and various fixes (#9)
by Radek Novacek
I've finally finished DBus tests. I've found some issues and fix them too.
You can merge this Pull Request by running:
git pull https://github.com/rnovacek/matahari tests
Or you can view, comment on it, or merge it online at:
https://github.com/matahari/matahari/pull/9
-- Commit Summary --
* tests: Move test initialization to superclass
* Unify results of dbus and qmf agents
* tests: Optional tests of DBus agents
* DBus: show warning when property is not handled
* service: Fix arguments for status method on DBus
* service: Remove DBus methods that are no longer in the schema
-- File Changes --
M src/host/host-dbus.c (10)
M src/network/network-dbus.c (12)
M src/service/service-dbus.c (50)
M src/sysconfig/sysconfig-dbus.c (28)
M src/tests/matahariTest.py (178)
M src/tests/test_host_api.py (281)
M src/tests/test_network_api.py (265)
M src/tests/test_network_api_minimal.py (52)
M src/tests/test_resource_api.py (48)
M src/tests/test_service_api.py (276)
M src/tests/test_service_api_minimal.py (53)
M src/tests/test_sysconfig_api.py (285)
-- Patch Links --
https://github.com/matahari/matahari/pull/9.patch
https://github.com/matahari/matahari/pull/9.diff
---
Reply to this email directly or view it on GitHub:
https://github.com/matahari/matahari/pull/9
12 years, 3 months
[PATCH] tests: tweaked some error messaging
by dajo@redhat.com
From: Dave Johnson <dajo(a)redhat.com>
Signed-off-by: Dave Johnson <dajo(a)redhat.com>
---
src/tests/test_host_api.py | 36 ++++++++++++++++++------------------
1 files changed, 18 insertions(+), 18 deletions(-)
diff --git a/src/tests/test_host_api.py b/src/tests/test_host_api.py
index 2b6215d..0fde65b 100644
--- a/src/tests/test_host_api.py
+++ b/src/tests/test_host_api.py
@@ -107,7 +107,7 @@ class HostApiTests(unittest.TestCase):
uname = cmd.getoutput("uname -a")
if "s390x" in uname:
- self.assertEquals(value, int(cmd.getoutput("cat /proc/cpuinfo | grep processors | awk '{ print $4 }'")), "cpu count not matching")
+ self.assertEquals(value, int(cmd.getoutput("cat /proc/cpuinfo | grep processors | awk '{ print $4 }'")), "cpu count not matching")
else:
self.assertEquals(value, int(cmd.getoutput("cat /proc/cpuinfo | grep processor | wc -l")), "cpu count not matching")
@@ -122,21 +122,21 @@ class HostApiTests(unittest.TestCase):
else:
core_count = cmd.getoutput("cat /proc/cpuinfo | grep \"core id\" | uniq | wc -l").strip()
- if value != core_count:
- sys.stderr.write("cpu_cores: '%s', expected '%s'\n" %
- (value, core_count))
- self.assertEquals(value, core_count, "cpu core count not matching")
+ self.assertEquals(value, core_count, "cpu core count ("+value+") not matching expected ("+core_count+")")
def test_cpu_model_property(self):
value = connection.props.get('cpu_model')
uname = cmd.getoutput("uname -a")
- if "s390x" in uname:
- self.assertEquals(value, cmd.getoutput("cat /proc/cpuinfo | grep 'processor 0' | awk -F, '{ print $3 }' | awk -F= '{ print $2 }'").strip(), "cpu model not matching")
+ if "s390x" in uname:
+ expected = cmd.getoutput("cat /proc/cpuinfo | grep 'processor 0' | awk -F, '{ print $3 }' | awk -F= '{ print $2 }'").strip()
+ self.assertEquals(value, expected, "cpu model ("+value+") not matching expected ("+expected+")")
elif "ppc64" in uname:
- self.assertTrue(value in cmd.getoutput("cat /proc/cpuinfo | grep cpu | head -1"), "cpu model not matching")
- else:
- self.assertEquals(value, cmd.getoutput("cat /proc/cpuinfo | grep 'model name' | head -1 | awk -F: {'print $2'}").strip(), "cpu model not matching")
+ expected = cmd.getoutput("cat /proc/cpuinfo | grep cpu | head -1")
+ self.assertTrue(value in expected, "cpu model ("+value+") not found in ("+expected+")")
+ else:
+ expected = cmd.getoutput("cat /proc/cpuinfo | grep 'model name' | head -1 | awk -F: {'print $2'}").strip()
+ self.assertEquals(value, expected, "cpu model ("+value+") not matching expected ("+expected+")")
def test_cpu_flags_property(self):
value = connection.props.get('cpu_flags')
@@ -181,7 +181,7 @@ class HostApiTests(unittest.TestCase):
def test_get_uuid_Reboot_lifetime(self):
result = host.get_uuid('Reboot')
- self.assertNotEqual(result.get('uuid'),'not-available', "not-available text not found on parm 'lifetime'")
+ self.assertNotEqual(result.get('uuid'),' not-available', "Reboot lifetime returned 'not-available' ")
def test_get_uuid_unset_Custom_lifetime(self):
cmd.getoutput("rm -rf /etc/custom-machine-id")
@@ -191,15 +191,15 @@ class HostApiTests(unittest.TestCase):
connection = HostTestsSetup()
host = connection.host
result = host.get_uuid('Custom')
- self.assertEqual(result.get('uuid'),'not-available', "not-available text not found on parm 'lifetime'")
+ self.assertEqual(result.get('uuid'), 'not-available', "unset Custom liftetime not returning 'not-available' ("+result.get('uuid')+")")
def test_get_uuid_unknown_lifetime(self):
result = host.get_uuid('lifetime')
- self.assertEqual(result.get('uuid'),'invalid-lifetime', "invalid-lifetime text not found on parm 'lifetime'")
+ self.assertEqual(result.get('uuid'), 'invalid-lifetime', "parm 'lifetime' not returning 'invalid-lifetime' ("+result.get('uuid')+")")
def test_get_uuid_empty_string(self):
result = host.get_uuid('')
- self.assertEqual("invalid-lifetime", result.get('uuid'), "empty string UUID not the same as 'filesystem' UUID")
+ self.assertEqual(result.get('uuid'), 'invalid-lifetime', "empty string not returning 'invalid-lifetime' ("+result.get('uuid')+")")
def test_get_uuid_zero_parameters(self):
try:
@@ -214,17 +214,17 @@ class HostApiTests(unittest.TestCase):
test_uuid = testUtil.getRandomKey(20)
host.set_uuid('Custom', test_uuid)
result = host.get_uuid('Custom')
- self.assertEqual(result.get('uuid'), test_uuid, "uuid value not matching expected("+result.get('uuid')+")")
+ self.assertEqual(result.get('uuid'), test_uuid, "uuid value ("+result.get('uuid')+") not matching expected("+test_uuid+")")
connection.reQuery()
- self.assertEqual(connection.props.get('custom_uuid'), test_uuid, "property not matching set value")
+ self.assertEqual(connection.props.get('custom_uuid'), test_uuid, "uuid value ("+connection.props.get('uuid')+") not matching expected("+test_uuid+")")
def test_set_uuid_new_Custom_lifetime(self):
test_uuid = testUtil.getRandomKey(20)
host.set_uuid('Custom', test_uuid)
result = host.get_uuid('Custom')
- self.assertEqual(result.get('uuid'), test_uuid, "uuid value not matching expected("+result.get('uuid')+")")
+ self.assertEqual(result.get('uuid'), test_uuid, "uuid value ("+result.get('uuid')+") not matching expected("+test_uuid+")")
connection.reQuery()
- self.assertEqual(connection.props.get('custom_uuid'), test_uuid, "property not matching set value")
+ self.assertEqual(connection.props.get('custom_uuid'), test_uuid, "uuid value ("+connection.props.get('uuid')+") not matching expected("+test_uuid+")")
def test_set_uuid_Hardware_lifetime_fails(self):
result = host.set_uuid('Hardware', testUtil.getRandomKey(20) )
--
1.7.4.4
12 years, 3 months
[PATCH] tests: few tweaks, mainly around s390x/ppc64 support
by dajo@redhat.com
From: Dave Johnson <dajo(a)redhat.com>
Signed-off-by: Dave Johnson <dajo(a)redhat.com>
---
src/tests/test_host_api.py | 43 +++++++++++++++++++++++++++++++------------
1 files changed, 31 insertions(+), 12 deletions(-)
diff --git a/src/tests/test_host_api.py b/src/tests/test_host_api.py
index 0ea3efc..2b6215d 100644
--- a/src/tests/test_host_api.py
+++ b/src/tests/test_host_api.py
@@ -86,12 +86,11 @@ class HostApiTests(unittest.TestCase):
def test_wordsize_property(self):
value = connection.props.get('wordsize')
+ uname = cmd.getoutput("uname -a")
word_size = 0
- if cmd.getoutput("uname -a | awk '{print $12}'") == "i686":
+ if "i386" in uname or "i686" in uname:
word_size = 32
- elif cmd.getoutput("uname -a | awk '{print $12}'") == "i386":
- word_size = 32
- elif cmd.getoutput("uname -a | awk '{print $12}'") == "x86_64":
+ elif "x86_64" in uname or "s390x" in uname or "ppc64" in uname:
word_size = 64
self.assertEquals(value, word_size, "wordsize not matching")
@@ -105,14 +104,24 @@ class HostApiTests(unittest.TestCase):
def test_cpu_count_property(self):
value = connection.props.get('cpu_count')
- self.assertEquals(value, int(cmd.getoutput("cat /proc/cpuinfo | grep processor | wc -l")), "cpu count not matching")
+ uname = cmd.getoutput("uname -a")
+
+ if "s390x" in uname:
+ self.assertEquals(value, int(cmd.getoutput("cat /proc/cpuinfo | grep processors | awk '{ print $4 }'")), "cpu count not matching")
+ else:
+ self.assertEquals(value, int(cmd.getoutput("cat /proc/cpuinfo | grep processor | wc -l")), "cpu count not matching")
def test_cpu_cores_property(self):
# XXX Core count is still busted in F15, sigar needs to be updated
if os.path.exists("/etc/fedora-release") and open("/etc/fedora-release", "r").read().strip() == "Fedora release 15 (Lovelock)":
return
value = str(connection.props.get('cpu_cores'))
- core_count = cmd.getoutput("cat /proc/cpuinfo | grep \"core id\" | uniq | wc -l").strip()
+
+ if "s390x" in cmd.getoutput("uname -a"):
+ core_count = cmd.getoutput("cat /proc/cpuinfo | grep processors | awk '{ print $4 }'").strip()
+ else:
+ core_count = cmd.getoutput("cat /proc/cpuinfo | grep \"core id\" | uniq | wc -l").strip()
+
if value != core_count:
sys.stderr.write("cpu_cores: '%s', expected '%s'\n" %
(value, core_count))
@@ -120,12 +129,24 @@ class HostApiTests(unittest.TestCase):
def test_cpu_model_property(self):
value = connection.props.get('cpu_model')
- cmdline = cmd.getoutput("cat /proc/cpuinfo | grep 'model name' | head -1 | awk -F: {'print $2'}")
- self.assertTrue(value in cmdline, "cpu model not matching")
+ uname = cmd.getoutput("uname -a")
+
+ if "s390x" in uname:
+ self.assertEquals(value, cmd.getoutput("cat /proc/cpuinfo | grep 'processor 0' | awk -F, '{ print $3 }' | awk -F= '{ print $2 }'").strip(), "cpu model not matching")
+ elif "ppc64" in uname:
+ self.assertTrue(value in cmd.getoutput("cat /proc/cpuinfo | grep cpu | head -1"), "cpu model not matching")
+ else:
+ self.assertEquals(value, cmd.getoutput("cat /proc/cpuinfo | grep 'model name' | head -1 | awk -F: {'print $2'}").strip(), "cpu model not matching")
def test_cpu_flags_property(self):
value = connection.props.get('cpu_flags')
- self.assertEquals(value, cmd.getoutput("cat /proc/cpuinfo | grep 'flags' | head -1 | awk -F: {'print $2'}").strip(), "cpu flags not matching")
+ uname = cmd.getoutput("uname -a")
+ if "s390x" in uname:
+ self.assertEquals(value.strip(), cmd.getoutput("cat /proc/cpuinfo | grep 'features' | head -1 | awk -F: {'print $2'}").strip(), "cpu flags not matching")
+ elif "ppc64" in uname:
+ self.assertTrue(value in cmd.getoutput("cat /proc/cpuinfo | grep cpu | head -1"), "cpu flags not matching")
+ else:
+ self.assertEquals(value, cmd.getoutput("cat /proc/cpuinfo | grep 'flags' | head -1 | awk -F: {'print $2'}").strip(), "cpu flags not matching")
def test_update_interval_property(self):
value = connection.props.get('update_interval')
@@ -178,9 +199,7 @@ class HostApiTests(unittest.TestCase):
def test_get_uuid_empty_string(self):
result = host.get_uuid('')
- result2 = host.get_uuid('filesystem')
- self.assertEqual(result.get('uuid'), result2.get('uuid'),
- "empty string UUID not the same as 'filesystem' UUID")
+ self.assertEqual("invalid-lifetime", result.get('uuid'), "empty string UUID not the same as 'filesystem' UUID")
def test_get_uuid_zero_parameters(self):
try:
--
1.7.4.4
12 years, 3 months
[PATCH] tests: added augeas attr to filter out on downstream tests
by dajo@redhat.com
From: Dave Johnson <dajo(a)redhat.com>
Signed-off-by: Dave Johnson <dajo(a)redhat.com>
---
src/tests/test_sysconfig_api.py | 10 ++++++++++
1 files changed, 10 insertions(+), 0 deletions(-)
diff --git a/src/tests/test_sysconfig_api.py b/src/tests/test_sysconfig_api.py
index 13879bb..6e320ae 100644
--- a/src/tests/test_sysconfig_api.py
+++ b/src/tests/test_sysconfig_api.py
@@ -39,6 +39,8 @@ import threading
import SimpleHTTPServer
import SocketServer
import errno
+from nose.plugins.attrib import attr
+
# The docs for SocketServer show an allow_reuse_address option, but I
# can't seem to make it work, so screw it, randomize the port.
@@ -224,21 +226,25 @@ class TestSysconfigApi(unittest.TestCase):
# TODO: need to handle upstream vs rhel difference
# TEST - Augeas
+ @attr('augeas')
def test_run_uri_good_url_augeas(self):
results = wrapper('uri', testAugeasFileUrl, 0, 'augeas', testUtil.getRandomKey(5)).get('status')
tokens = results.split('\n')
self.assertEqual(tokens[0], 'OK', "result: %s != OK" % tokens[0])
self.assertTrue(tokens[1].startswith("%s = " % augeasQuery))
+ @attr('augeas')
def test_run_uri_http_url_not_found_augeas(self):
self.assertRaises(QmfAgentException, wrapper, 'uri', testAugeasFileUrl + "_bad", 0, 'augeas', testUtil.getRandomKey(5))
+ @attr('augeas')
def test_run_uri_good_file_augeas(self):
results = wrapper('uri', 'file://'+testAugeasFileWithPath, 0, 'augeas', testUtil.getRandomKey(5)).get('status')
tokens = results.split('\n')
self.assertEqual(tokens[0], 'OK', "result: %s != OK" % tokens[0])
self.assertTrue(tokens[1].startswith("%s = " % augeasQuery))
+ @attr('augeas')
def test_run_uri_file_url_not_found(self):
self.assertRaises(QmfAgentException, wrapper, 'uri', 'file://'+testAugeasFile, 0, 'augeas', testUtil.getRandomKey(5))
@@ -273,12 +279,14 @@ class TestSysconfigApi(unittest.TestCase):
self.assertTrue( 0 == checkFile(testPuppetFileWithPath, origFilePerms, origFileOwner, origFileGroup), "file properties not expected")
# TEST - Augeas
+ @attr('augeas')
def test_run_string_good_augeas(self):
results = wrapper('string', augeasFileContents, 0, 'augeas', testUtil.getRandomKey(5)).get('status')
tokens = results.split('\n')
self.assertEqual(tokens[0], 'OK', "result: %s != OK" % tokens[0])
self.assertTrue(tokens[1].startswith("%s = " % augeasQuery))
+ @attr('augeas')
def test_run_string_bad_augeas(self):
result = wrapper('string', 'bad augeas query', 0, 'augeas', testUtil.getRandomKey(5)).get('status')
tokens = result.split('\n')
@@ -286,10 +294,12 @@ class TestSysconfigApi(unittest.TestCase):
# TEST - query()
# ================================================================
+ @attr('augeas')
def test_query_good_augeas(self):
result = sysconfig.query(augeasQuery, 0, 'augeas').get('data')
self.assertNotEqual(result, 'unknown', "result: %s == unknown" % result)
+ @attr('augeas')
def test_query_bad_augeas(self):
result = sysconfig.query('bad augeas query', 0, 'augeas').get('data')
self.assertEqual(result, 'unknown', "result: %s != unknown" % result)
--
1.7.4.4
12 years, 3 months