diff --git a/qa/ganeti-qa.py b/qa/ganeti-qa.py
index f99b58cffc3c6d114663742d26369af6b051ed22..6d1309ac66d1a1baf4f9338645461a223e0abd3f 100755
--- a/qa/ganeti-qa.py
+++ b/qa/ganeti-qa.py
@@ -31,6 +31,7 @@ import qa_cluster
 import qa_config
 import qa_daemon
 import qa_env
+import qa_group
 import qa_instance
 import qa_node
 import qa_os
@@ -221,6 +222,14 @@ def RunCommonNodeTests():
   RunTestIf("node-storage", qa_node.TestNodeStorage)
 
 
+def RunGroupListTests():
+  """Run tests for listing node groups.
+
+  """
+  RunTestIf("group-list", qa_group.TestGroupListDefaultFields)
+  RunTestIf("group-list", qa_group.TestGroupListAllFields)
+
+
 def RunExportImportTests(instance, pnode, snode):
   """Tries to export and import the instance.
 
@@ -348,6 +357,7 @@ def main():
   RunTestIf("tags", qa_tags.TestClusterTags)
 
   RunCommonNodeTests()
+  RunGroupListTests()
 
   pnode = qa_config.AcquireNode(exclude=qa_config.GetMasterNode())
   try:
@@ -374,6 +384,7 @@ def main():
     if qa_config.TestEnabled('instance-add-plain-disk'):
       instance = RunTest(qa_instance.TestInstanceAddWithPlainDisk, pnode)
       RunCommonInstanceTests(instance)
+      RunGroupListTests()
       RunExportImportTests(instance, pnode, None)
       RunDaemonTests(instance, pnode)
       RunTest(qa_instance.TestInstanceRemove, instance)
@@ -391,6 +402,7 @@ def main():
           instance = RunTest(func, pnode, snode)
           RunTestIf("cluster-verify", qa_cluster.TestClusterVerify)
           RunCommonInstanceTests(instance)
+          RunGroupListTests()
           if qa_config.TestEnabled('instance-convert-disk'):
             RunTest(qa_instance.TestInstanceShutdown, instance)
             RunTest(qa_instance.TestInstanceConvertDisk, instance, snode)
diff --git a/qa/qa-sample.json b/qa/qa-sample.json
index 57fd3539f1655461535aeeb32ae4788a61a90c34..b1a9e4b1fc157d8b16c0926557a6d3dae52116e9 100644
--- a/qa/qa-sample.json
+++ b/qa/qa-sample.json
@@ -53,6 +53,8 @@
     "cluster-reserved-lvs": true,
     "cluster-modify": true,
 
+    "group-list": true,
+
     "node-info": true,
     "node-volumes": true,
     "node-readd": true,
diff --git a/qa/qa_group.py b/qa/qa_group.py
new file mode 100644
index 0000000000000000000000000000000000000000..9671b02ac62771f182519de0e9ad999588134de9
--- /dev/null
+++ b/qa/qa_group.py
@@ -0,0 +1,33 @@
+#
+#
+
+# Copyright (C) 2010 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.
+
+
+from qa_utils import AssertCommand
+
+
+def TestGroupListDefaultFields():
+  """gnt-group list"""
+  AssertCommand(["gnt-group", "list"])
+
+
+def TestGroupListAllFields():
+  """gnt-group list -o FIELDS"""
+  AssertCommand(["gnt-group", "list", "-o",
+                 "name,uuid,node_cnt,node_list,pinst_cnt,pinst_list"])
diff --git a/qa/qa_rapi.py b/qa/qa_rapi.py
index a1b371ef30024f6199c917495c8278aec61bc659..0af50e14a33654d46137fce068704ef659ca8cfc 100644
--- a/qa/qa_rapi.py
+++ b/qa/qa_rapi.py
@@ -94,6 +94,11 @@ NODE_FIELDS = ("name", "dtotal", "dfree",
                "mtotal", "mnode", "mfree",
                "pinst_cnt", "sinst_cnt", "tags")
 
+GROUP_FIELDS = frozenset([
+  "name", "uuid",
+  "node_cnt", "node_list",
+  ])
+
 JOB_FIELDS = frozenset([
   "id", "ops", "status", "summary",
   "opstatus", "opresult", "oplog",
@@ -167,12 +172,26 @@ def TestEmptyCluster():
       for entry in NODE_FIELDS:
         AssertIn(entry, node)
 
+  def _VerifyGroups(data):
+    default_group = {
+      "name": "default",
+      "uri": "/2/groups/default",
+      }
+    AssertIn(default_group, data)
+
+  def _VerifyGroupsBulk(data):
+    for group in data:
+      for field in GROUP_FIELDS:
+        AssertIn(field, group)
+
   _DoTests([
     ("/", None, 'GET', None),
     ("/2/info", _VerifyInfo, 'GET', None),
     ("/2/tags", None, 'GET', None),
     ("/2/nodes", _VerifyNodes, 'GET', None),
     ("/2/nodes?bulk=1", _VerifyNodesBulk, 'GET', None),
+    ("/2/groups", _VerifyGroups, 'GET', None),
+    ("/2/groups?bulk=1", _VerifyGroupsBulk, 'GET', None),
     ("/2/instances", [], 'GET', None),
     ("/2/instances?bulk=1", [], 'GET', None),
     ("/2/os", None, 'GET', None),