Revision 256eb94b

b/lib/utils.py
42 42
import resource
43 43
import logging
44 44
import signal
45
import string
45 46

  
46 47
from cStringIO import StringIO
47 48

  
......
489 490
  return pid
490 491

  
491 492

  
492
def MatchNameComponent(key, name_list):
493
def MatchNameComponent(key, name_list, case_sensitive=True):
493 494
  """Try to match a name against a list.
494 495

  
495 496
  This function will try to match a name like test1 against a list
......
504 505
  @param key: the name to be searched
505 506
  @type name_list: list
506 507
  @param name_list: the list of strings against which to search the key
508
  @type case_sensitive: boolean
509
  @param case_sensitive: whether to provide a case-sensitive match
507 510

  
508 511
  @rtype: None or str
509 512
  @return: None if there is no match I{or} if there are multiple matches,
......
512 515
  """
513 516
  if key in name_list:
514 517
    return key
515
  mo = re.compile("^%s(\..*)?$" % re.escape(key))
516
  names_filtered = [name for name in name_list if mo.match(name) is not None]
517
  if len(names_filtered) != 1:
518
    return None
519
  return names_filtered[0]
518

  
519
  re_flags = 0
520
  if not case_sensitive:
521
    re_flags |= re.IGNORECASE
522
    key = string.upper(key)
523
  mo = re.compile("^%s(\..*)?$" % re.escape(key), re_flags)
524
  names_filtered = []
525
  string_matches = []
526
  for name in name_list:
527
    if mo.match(name) is not None:
528
      names_filtered.append(name)
529
      if not case_sensitive and key == string.upper(name):
530
        string_matches.append(name)
531

  
532
  if len(string_matches) == 1:
533
    return string_matches[0]
534
  if len(names_filtered) == 1:
535
    return names_filtered[0]
536
  return None
520 537

  
521 538

  
522 539
class HostInfo:
b/test/ganeti.utils_unittest.py
336 336
    self.failUnlessEqual(MatchNameComponent(key1, mlist), None)
337 337
    self.failUnlessEqual(MatchNameComponent(key2, mlist), key2)
338 338

  
339
  def testCaseInsensitivePartialMatch(self):
340
    """Test for the case_insensitive keyword"""
341
    mlist = ["test1.example.com", "test2.example.net"]
342
    self.assertEqual(MatchNameComponent("test2", mlist, case_sensitive=False),
343
                     "test2.example.net")
344
    self.assertEqual(MatchNameComponent("Test2", mlist, case_sensitive=False),
345
                     "test2.example.net")
346
    self.assertEqual(MatchNameComponent("teSt2", mlist, case_sensitive=False),
347
                     "test2.example.net")
348
    self.assertEqual(MatchNameComponent("TeSt2", mlist, case_sensitive=False),
349
                     "test2.example.net")
350

  
351

  
352
  def testCaseInsensitiveFullMatch(self):
353
    mlist = ["ts1.ex", "ts1.ex.org", "ts2.ex", "Ts2.ex"]
354
    # Between the two ts1 a full string match non-case insensitive should work
355
    self.assertEqual(MatchNameComponent("Ts1", mlist, case_sensitive=False),
356
                     None)
357
    self.assertEqual(MatchNameComponent("Ts1.ex", mlist, case_sensitive=False),
358
                     "ts1.ex")
359
    self.assertEqual(MatchNameComponent("ts1.ex", mlist, case_sensitive=False),
360
                     "ts1.ex")
361
    # Between the two ts2 only case differs, so only case-match works
362
    self.assertEqual(MatchNameComponent("ts2.ex", mlist, case_sensitive=False),
363
                     "ts2.ex")
364
    self.assertEqual(MatchNameComponent("Ts2.ex", mlist, case_sensitive=False),
365
                     "Ts2.ex")
366
    self.assertEqual(MatchNameComponent("TS2.ex", mlist, case_sensitive=False),
367
                     None)
368

  
339 369

  
340 370
class TestFormatUnit(unittest.TestCase):
341 371
  """Test case for the FormatUnit function"""

Also available in: Unified diff