From ea7693c1c3b9234660381f8b475e7f06242f07c3 Mon Sep 17 00:00:00 2001
From: Helga Velroyen <helgav@google.com>
Date: Tue, 15 Jan 2013 15:34:55 +0100
Subject: [PATCH] Network QA

This adds a script for the QA of 'gnt-network'. So far it
covers adding/removing and connecting/disconnecting networks.

Signed-off-by: Helga Velroyen <helgav@google.com>
Reviewed-by: Michael Hanselmann <hansmi@google.com>
---
 qa/ganeti-qa.py   | 10 ++++++
 qa/qa-sample.json | 10 ++++++
 qa/qa_network.py  | 81 +++++++++++++++++++++++++++++++++++++++++++++++
 qa/qa_utils.py    | 33 ++++++++++++++++---
 4 files changed, 129 insertions(+), 5 deletions(-)
 create mode 100644 qa/qa_network.py

diff --git a/qa/ganeti-qa.py b/qa/ganeti-qa.py
index 26c2407ac..987517eb8 100755
--- a/qa/ganeti-qa.py
+++ b/qa/ganeti-qa.py
@@ -37,6 +37,7 @@ import qa_env
 import qa_error
 import qa_group
 import qa_instance
+import qa_network
 import qa_node
 import qa_os
 import qa_job
@@ -324,6 +325,14 @@ def RunGroupListTests():
   RunTestIf("group-list", qa_group.TestGroupListFields)
 
 
+def RunNetworkTests():
+  """Run tests for network management.
+
+  """
+  RunTestIf("network", qa_network.TestNetworkAddRemove)
+  RunTestIf("network", qa_network.TestNetworkConnect)
+
+
 def RunGroupRwTests():
   """Run tests for adding/removing/renaming groups.
 
@@ -478,6 +487,7 @@ def RunQa():
   RunCommonNodeTests()
   RunGroupListTests()
   RunGroupRwTests()
+  RunNetworkTests()
 
   # The master shouldn't be readded or put offline; "delay" needs a non-master
   # node to test
diff --git a/qa/qa-sample.json b/qa/qa-sample.json
index 15be20e6a..40a3c2336 100644
--- a/qa/qa-sample.json
+++ b/qa/qa-sample.json
@@ -84,6 +84,14 @@
     ]
   },
 
+  "networks": {
+    "inexistent-networks": [
+      "network1",
+      "network2",
+      "network3"
+    ]
+  },
+
   "tests": {
     "# Whether tests are enabled or disabled by default": null,
     "default": true,
@@ -118,6 +126,8 @@
     "group-list": true,
     "group-rwops": true,
 
+    "network": false,
+
     "node-list": true,
     "node-info": true,
     "node-volumes": true,
diff --git a/qa/qa_network.py b/qa/qa_network.py
new file mode 100644
index 000000000..5648fd60c
--- /dev/null
+++ b/qa/qa_network.py
@@ -0,0 +1,81 @@
+#
+#
+
+# Copyright (C) 2013 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
+# 02110-1301, USA.
+
+
+"""QA tests for networks.
+
+"""
+
+import qa_config
+import qa_utils
+
+from qa_utils import AssertCommand
+
+
+def GetNonexistentNetworks(count):
+  """Gets network names which shouldn't exist on the cluster.
+
+  @param count: Number of networks to get
+  @rtype: integer
+
+  """
+  return qa_utils.GetNonexistentEntityNames(count, "networks", "network")
+
+
+def TestNetworkAddRemove():
+  """gnt-network add/remove"""
+  (network1, network2) = GetNonexistentNetworks(2)
+
+  # Add some networks of different sizes.
+  # Note: Using RFC5737 addresses.
+  AssertCommand(["gnt-network", "add", "--network", "192.0.2.0/30", network1])
+  AssertCommand(["gnt-network", "add", "--network", "198.51.100.0/24",
+                 network2])
+  # Try to add a network with an existing name.
+  AssertCommand(["gnt-network", "add", "--network", "203.0.133.0/24", network2],
+                fail=True)
+
+  AssertCommand(["gnt-network", "remove", network1])
+  AssertCommand(["gnt-network", "remove", network2])
+
+
+def TestNetworkConnect():
+  """gnt-network connect/disconnect"""
+  (group1, ) = qa_utils.GetNonexistentGroups(1)
+  (network1, ) = GetNonexistentNetworks(1)
+
+  default_mode = "bridged"
+  default_link = "xen-br0"
+  nicparams = qa_config.get("default-nicparams")
+  if nicparams:
+    mode = nicparams.get("mode", default_mode)
+    link = nicparams.get("link", default_link)
+  else:
+    mode = default_mode
+    link = default_link
+
+  AssertCommand(["gnt-group", "add", group1])
+  AssertCommand(["gnt-network", "add", "--network", "192.0.2.0/24", network1])
+
+  AssertCommand(["gnt-network", "connect", network1, mode, link, group1])
+  AssertCommand(["gnt-network", "disconnect", network1, group1])
+
+  AssertCommand(["gnt-group", "remove", group1])
+  AssertCommand(["gnt-network", "remove", network1])
diff --git a/qa/qa_utils.py b/qa/qa_utils.py
index 45baea6b4..6c8fa760f 100644
--- a/qa/qa_utils.py
+++ b/qa/qa_utils.py
@@ -653,17 +653,40 @@ def GetNonexistentGroups(count):
   """Gets group names which shouldn't exist on the cluster.
 
   @param count: Number of groups to get
-  @rtype: list
+  @rtype: integer
 
   """
-  groups = qa_config.get("groups", {})
+  return GetNonexistentEntityNames(count, "groups", "group")
 
-  default = ["group1", "group2", "group3"]
+
+def GetNonexistentEntityNames(count, name_config, name_prefix):
+  """Gets entity names which shouldn't exist on the cluster.
+
+  The actualy names can refer to arbitrary entities (for example
+  groups, networks).
+
+  @param count: Number of names to get
+  @rtype: integer
+  @param name_config: name of the leaf in the config containing
+    this entity's configuration, including a 'inexistent-'
+    element
+  @rtype: string
+  @param name_prefix: prefix of the entity's names, used to compose
+    the default values; for example for groups, the prefix is
+    'group' and the generated names are then group1, group2, ...
+  @rtype: string
+
+  """
+  entities = qa_config.get(name_config, {})
+
+  default = [name_prefix + str(i) for i in range(count)]
   assert count <= len(default)
 
-  candidates = groups.get("inexistent-groups", default)[:count]
+  name_config_inexistent = "inexistent-" + name_config
+  candidates = entities.get(name_config_inexistent, default)[:count]
 
   if len(candidates) < count:
-    raise Exception("At least %s non-existent groups are needed" % count)
+    raise Exception("At least %s non-existent %s are needed" %
+                    (count, name_config))
 
   return candidates
-- 
GitLab