diff --git a/lib/client/gnt_cluster.py b/lib/client/gnt_cluster.py
index cf9536ef03dd5365fa2a2723b2939434c4d0515e..ee45ca8dbdbdd3a8d9aa2c08c54971c861021d76 100644
--- a/lib/client/gnt_cluster.py
+++ b/lib/client/gnt_cluster.py
@@ -1397,7 +1397,9 @@ def _EpoOff(opts, node_list, inst_map):
     return constants.EXIT_FAILURE
 
 
-def Epo(opts, args):
+def Epo(opts, args, cl=None, _on_fn=_EpoOn, _off_fn=_EpoOff,
+        _confirm_fn=ConfirmOperation,
+        _stdout_fn=ToStdout, _stderr_fn=ToStderr):
   """EPO operations.
 
   @param opts: the command line options selected by the user
@@ -1408,25 +1410,24 @@ def Epo(opts, args):
 
   """
   if opts.groups and opts.show_all:
-    ToStderr("Only one of --groups or --all are allowed")
+    _stderr_fn("Only one of --groups or --all are allowed")
     return constants.EXIT_FAILURE
   elif args and opts.show_all:
-    ToStderr("Arguments in combination with --all are not allowed")
+    _stderr_fn("Arguments in combination with --all are not allowed")
     return constants.EXIT_FAILURE
 
-  client = GetClient()
+  if cl is None:
+    cl = GetClient()
 
   if opts.groups:
-    node_query_list = itertools.chain(*client.QueryGroups(names=args,
-                                                          fields=["node_list"],
-                                                          use_locking=False))
+    node_query_list = \
+      itertools.chain(*cl.QueryGroups(args, ["node_list"], False))
   else:
     node_query_list = args
 
-  result = client.QueryNodes(names=node_query_list,
-                             fields=["name", "master", "pinst_list",
-                                     "sinst_list", "powered", "offline"],
-                             use_locking=False)
+  result = cl.QueryNodes(node_query_list, ["name", "master", "pinst_list",
+                                           "sinst_list", "powered", "offline"],
+                         False)
 
   all_nodes = map(compat.fst, result)
   node_list = []
@@ -1447,25 +1448,26 @@ def Epo(opts, args):
       # already operating on the master at this point :)
       continue
     elif master and not opts.show_all:
-      ToStderr("%s is the master node, please do a master-failover to another"
-               " node not affected by the EPO or use --all if you intend to"
-               " shutdown the whole cluster", node)
+      _stderr_fn("%s is the master node, please do a master-failover to another"
+                 " node not affected by the EPO or use --all if you intend to"
+                 " shutdown the whole cluster", node)
       return constants.EXIT_FAILURE
     elif powered is None:
-      ToStdout("Node %s does not support out-of-band handling, it can not be"
-               " handled in a fully automated manner", node)
+      _stdout_fn("Node %s does not support out-of-band handling, it can not be"
+                 " handled in a fully automated manner", node)
     elif powered == opts.on:
-      ToStdout("Node %s is already in desired power state, skipping", node)
+      _stdout_fn("Node %s is already in desired power state, skipping", node)
     elif not offline or (offline and powered):
       node_list.append(node)
 
-  if not opts.force and not ConfirmOperation(all_nodes, "nodes", "epo"):
+  if not (opts.force or _confirm_fn(all_nodes, "nodes", "epo")):
     return constants.EXIT_FAILURE
 
   if opts.on:
-    return _EpoOn(opts, all_nodes, node_list, inst_map)
+    return _on_fn(opts, all_nodes, node_list, inst_map)
   else:
-    return _EpoOff(opts, node_list, inst_map)
+    return _off_fn(opts, node_list, inst_map)
+
 
 commands = {
   "init": (
diff --git a/test/ganeti.client.gnt_cluster_unittest.py b/test/ganeti.client.gnt_cluster_unittest.py
index 737d438f8268dbe51e69679880550dd0ab41f1d9..1908f879a0bbeaaf72029b90a6cac613964361f5 100755
--- a/test/ganeti.client.gnt_cluster_unittest.py
+++ b/test/ganeti.client.gnt_cluster_unittest.py
@@ -22,15 +22,17 @@
 """Script for testing ganeti.client.gnt_cluster"""
 
 import unittest
+import optparse
 
 from ganeti.client import gnt_cluster
 from ganeti import utils
 from ganeti import compat
+from ganeti import constants
 
 import testutils
 
 
-class TestEpo(unittest.TestCase):
+class TestEpoUtilities(unittest.TestCase):
   def setUp(self):
     self.nodes2ip = dict(("node%s" % i, "192.0.2.%s" % i) for i in range(1, 10))
     self.nodes = set(self.nodes2ip.keys())
@@ -143,5 +145,118 @@ class TestEpo(unittest.TestCase):
     self.assertFalse(inst_map)
 
 
+class _ClientForEpo:
+  def __init__(self, groups, nodes):
+    self._groups = groups
+    self._nodes = nodes
+
+  def QueryGroups(self, names, fields, use_locking):
+    assert not use_locking
+    assert fields == ["node_list"]
+    return self._groups
+
+  def QueryNodes(self, names, fields, use_locking):
+    assert not use_locking
+    assert fields == ["name", "master", "pinst_list", "sinst_list", "powered",
+                      "offline"]
+    return self._nodes
+
+
+class TestEpo(unittest.TestCase):
+  _ON_EXITCODE = 253
+  _OFF_EXITCODE = 254
+
+  def _ConfirmForce(self, *args):
+    self.fail("Shouldn't need confirmation")
+
+  def _Confirm(self, exp_names, result, names, ltype, text):
+    self.assertEqual(names, exp_names)
+    self.assertFalse(result is NotImplemented)
+    return result
+
+  def _Off(self, exp_node_list, opts, node_list, inst_map):
+    self.assertEqual(node_list, exp_node_list)
+    self.assertFalse(inst_map)
+    return self._OFF_EXITCODE
+
+  def _Test(self, *args, **kwargs):
+    defaults = dict(cl=NotImplemented, _on_fn=NotImplemented,
+                    _off_fn=NotImplemented,
+                    _stdout_fn=lambda *args: None,
+                    _stderr_fn=lambda *args: None)
+    defaults.update(kwargs)
+    return gnt_cluster.Epo(*args, **defaults)
+
+  def testShowAllWithGroups(self):
+    opts = optparse.Values(dict(groups=True, show_all=True))
+    result = self._Test(opts, NotImplemented)
+    self.assertEqual(result, constants.EXIT_FAILURE)
+
+  def testShowAllWithArgs(self):
+    opts = optparse.Values(dict(groups=False, show_all=True))
+    result = self._Test(opts, ["a", "b", "c"])
+    self.assertEqual(result, constants.EXIT_FAILURE)
+
+  def testNoArgumentsNoParameters(self):
+    for (force, confirm_result) in [(True, NotImplemented), (False, False),
+                                    (False, True)]:
+      opts = optparse.Values(dict(groups=False, show_all=False, force=force,
+                                  on=False))
+      client = _ClientForEpo(NotImplemented, [
+        ("node1.example.com", False, [], [], True, False),
+        ])
+
+      if force:
+        confirm_fn = self._ConfirmForce
+      else:
+        confirm_fn = compat.partial(self._Confirm, ["node1.example.com"],
+                                    confirm_result)
+
+      off_fn = compat.partial(self._Off, ["node1.example.com"])
+
+      result = self._Test(opts, [], cl=client, _off_fn=off_fn,
+                          _confirm_fn=confirm_fn)
+      if force or confirm_result:
+        self.assertEqual(result, self._OFF_EXITCODE)
+      else:
+        self.assertEqual(result, constants.EXIT_FAILURE)
+
+  def testPowerOn(self):
+    for master in [False, True]:
+      opts = optparse.Values(dict(groups=False, show_all=True,
+                                  force=True, on=True))
+      client = _ClientForEpo(NotImplemented, [
+        ("node1.example.com", False, [], [], True, False),
+        ("node2.example.com", False, [], [], False, False),
+        ("node3.example.com", False, [], [], True, True),
+        ("node4.example.com", False, [], [], None, True),
+        ("node5.example.com", master, [], [], False, False),
+        ])
+
+      def _On(_, all_nodes, node_list, inst_map):
+        self.assertEqual(all_nodes,
+                         ["node%s.example.com" % i for i in range(1, 6)])
+        if master:
+          self.assertEqual(node_list, ["node2.example.com"])
+        else:
+          self.assertEqual(node_list, ["node2.example.com",
+                                       "node5.example.com"])
+        self.assertFalse(inst_map)
+        return self._ON_EXITCODE
+
+      result = self._Test(opts, [], cl=client, _on_fn=_On,
+                          _confirm_fn=self._ConfirmForce)
+      self.assertEqual(result, self._ON_EXITCODE)
+
+  def testMasterWithoutShowAll(self):
+    opts = optparse.Values(dict(groups=False, show_all=False,
+                                force=True, on=False))
+    client = _ClientForEpo(NotImplemented, [
+      ("node1.example.com", True, [], [], True, False),
+      ])
+    result = self._Test(opts, [], cl=client, _confirm_fn=self._ConfirmForce)
+    self.assertEqual(result, constants.EXIT_FAILURE)
+
+
 if __name__ == "__main__":
   testutils.GanetiTestProgram()