From 6de7c41dff317d4a28be278d82fe6a1c1767b6da Mon Sep 17 00:00:00 2001 From: Iustin Pop <iustin@google.com> Date: Tue, 18 Nov 2008 10:00:28 +0000 Subject: [PATCH] Add a FieldSet class for variable parameter sets This patch adds a _FieldSet class that can be used for the new variable parameter sets: e.g. the sda_size will change to disk/0.size (or similar) and we need to both check validity and extract the index of the parameter easily. The patch also sorts the unittest list in Makefile.am. Reviewed-by: ultrotter --- Makefile.am | 17 ++++++----- lib/cmdlib.py | 43 ++++++++++++++++++++++++++ test/ganeti.cmdlib_unittest.py | 55 ++++++++++++++++++++++++++++++++++ 3 files changed, 107 insertions(+), 8 deletions(-) create mode 100755 test/ganeti.cmdlib_unittest.py diff --git a/Makefile.am b/Makefile.am index 2e63c6dc0..0474980c8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -191,18 +191,19 @@ TEST_FILES = \ test/data/proc_drbd8.txt dist_TESTS = \ + test/ganeti.bdev_unittest.py \ + test/ganeti.cli_unittest.py \ + test/ganeti.cmdlib_unittest.py \ test/ganeti.config_unittest.py \ + test/ganeti.constants_unittest.py \ test/ganeti.hooks_unittest.py \ - test/ganeti.utils_unittest.py \ - test/ganeti.bdev_unittest.py \ - test/ganeti.ssh_unittest.py \ + test/ganeti.http_unittest.py \ test/ganeti.locking_unittest.py \ - test/ganeti.serializer_unittest.py \ - test/ganeti.workerpool_unittest.py \ test/ganeti.rapi.resources_unittest.py \ - test/ganeti.http_unittest.py \ - test/ganeti.constants_unittest.py \ - test/ganeti.cli_unittest.py + test/ganeti.serializer_unittest.py \ + test/ganeti.ssh_unittest.py \ + test/ganeti.utils_unittest.py \ + test/ganeti.workerpool_unittest.py nodist_TESTS = diff --git a/lib/cmdlib.py b/lib/cmdlib.py index 5f1517bcc..6fd79e897 100644 --- a/lib/cmdlib.py +++ b/lib/cmdlib.py @@ -32,6 +32,7 @@ import re import platform import logging import copy +import itertools from ganeti import ssh from ganeti import utils @@ -322,6 +323,48 @@ class NoHooksLU(LogicalUnit): HTYPE = None +class _FieldSet(object): + """A simple field set. + + Among the features are: + - checking if a string is among a list of static string or regex objects + - checking if a whole list of string matches + - returning the matching groups from a regex match + + Internally, all fields are held as regular expression objects. + + """ + def __init__(self, *items): + self.items = [re.compile("^%s$" % value) for value in items] + + def Extend(self, other_set): + """Extend the field set with the items from another one""" + self.items.extend(other_set.items) + + def Matches(self, field): + """Checks if a field matches the current set + + @type field: str + @param field: the string to match + @return: either False or a regular expression match object + + """ + for m in itertools.ifilter(None, (val.match(field) for val in self.items)): + return m + return False + + def NonMatching(self, items): + """Returns the list of fields not matching the current set + + @type items: list + @param items: the list of fields to check + @rtype: list + @return: list of non-matching fields + + """ + return [val for val in items if not self.Matches(val)] + + def _GetWantedNodes(lu, nodes): """Returns list of checked and expanded node names. diff --git a/test/ganeti.cmdlib_unittest.py b/test/ganeti.cmdlib_unittest.py new file mode 100755 index 000000000..1fcf43a62 --- /dev/null +++ b/test/ganeti.cmdlib_unittest.py @@ -0,0 +1,55 @@ +#!/usr/bin/python +# + +# Copyright (C) 2008 Google Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 0.0510-1301, USA. + + +"""Script for unittesting the cmdlib module""" + + +import os +import unittest +import time +import Queue + +from ganeti import cmdlib +from ganeti import errors + + +class FieldSetTestCase(unittest.TestCase): + """Test case for FieldSets""" + + def testSimpleMatch(self): + f = cmdlib._FieldSet("a", "b", "c", "def") + self.failUnless(f.Matches("a")) + self.failIf(f.Matches("d"), "Substring matched") + self.failIf(f.Matches("defghi"), "Prefix string matched") + self.failIf(f.NonMatching(["b", "c"])) + self.failIf(f.NonMatching(["a", "b", "c", "def"])) + self.failUnless(f.NonMatching(["a", "d"])) + + def testRegexMatch(self): + f = cmdlib._FieldSet("a", "b([0-9]+)", "c") + self.failUnless(f.Matches("b1")) + self.failUnless(f.Matches("b99")) + self.failIf(f.Matches("b/1")) + self.failIf(f.NonMatching(["b12", "c"])) + self.failUnless(f.NonMatching(["a", "1"])) + +if __name__ == '__main__': + unittest.main() -- GitLab