Merge ~mpontillo/maas:fix-random-choice-no-choices into maas:master

Proposed by Mike Pontillo
Status: Merged
Approved by: Mike Pontillo
Approved revision: d12f855cac596173616f47bdd73a34bcf6679e57
Merge reported by: MAAS Lander
Merged at revision: not available
Proposed branch: ~mpontillo/maas:fix-random-choice-no-choices
Merge into: maas:master
Diff against target: 96 lines (+32/-9)
3 files modified
requirements.txt (+1/-1)
src/maasserver/rpc/regionservice.py (+11/-7)
src/maasserver/rpc/tests/test_regionservice.py (+20/-1)
Reviewer Review Type Date Requested Status
Blake Rouse (community) Approve
Review via email: mp+327708@code.launchpad.net

Commit message

Prevent RegionService from using empty lists.

LP: #1705254

To post a comment you must log in.
Revision history for this message
Blake Rouse (blake-rouse) wrote :

Looks good.

review: Approve
Revision history for this message
MAAS Lander (maas-lander) wrote :

LANDING
-b fix-random-choice-no-choices lp:~mpontillo/maas into -b master lp:~maas-committers/maas

STATUS: FAILED BUILD
LOG: http://maas-ci-jenkins.internal:8080/job/maas/job/branch-tester/120/console

d12f855... by Mike Pontillo

Fix incorrect assumptions.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/requirements.txt b/requirements.txt
index e08077a..160c720 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -13,7 +13,7 @@ petname==2.0
13pexpect==4.2.013pexpect==4.2.0
14psycopg2==2.6.214psycopg2==2.6.2
15pymongo==3.215pymongo==3.2
16pyopenssl==16.0.016pyopenssl==16.2.0
17pyparsing==2.0.717pyparsing==2.0.7
18pyvmomi==6.0.0.2016.618pyvmomi==6.0.0.2016.6
19requests==2.11.019requests==2.11.0
diff --git a/src/maasserver/rpc/regionservice.py b/src/maasserver/rpc/regionservice.py
index a5790e8..02d987d 100644
--- a/src/maasserver/rpc/regionservice.py
+++ b/src/maasserver/rpc/regionservice.py
@@ -992,21 +992,25 @@ class RegionService(service.Service, object):
992 def getAllClients(self):992 def getAllClients(self):
993 """Return a list with one connection per rack controller."""993 """Return a list with one connection per rack controller."""
994 return [994 return [
995 common.Client(random.choice(list(conns)))995 common.Client(random.choice(list(connections)))
996 for conns in self.connections.values()996 for connections in self.connections.values()
997 if len(connections) > 0
997 ]998 ]
998999
999 @asynchronous(timeout=FOREVER)1000 @asynchronous(timeout=FOREVER)
1000 def getRandomClient(self):1001 def getRandomClient(self):
1001 """Return a list of all connected :class:`common.Client`s."""1002 """Return a random connected :class:`common.Client`."""
1002 clients = list(self.connections.values())1003 connections = list(self.connections.values())
1003 if len(clients) == 0:1004 if len(connections) == 0:
1004 raise exceptions.NoConnectionsAvailable(1005 raise exceptions.NoConnectionsAvailable(
1005 "Unable to connect to any rack controller; no connections "1006 "Unable to connect to any rack controller; no connections "
1006 "available.")1007 "available.")
1007 else:1008 else:
1008 conns = list(random.choice(clients))1009 connection = random.choice(connections)
1009 return common.Client(random.choice(conns))1010 # The connection object is a set of RegionServer objects.
1011 # Make sure a sane set was returned.
1012 assert len(connection) > 0, "Connection set empty."
1013 return common.Client(random.choice(list(connection)))
10101014
10111015
1012def ignoreCancellation(failure):1016def ignoreCancellation(failure):
diff --git a/src/maasserver/rpc/tests/test_regionservice.py b/src/maasserver/rpc/tests/test_regionservice.py
index e845b30..972a3d7 100644
--- a/src/maasserver/rpc/tests/test_regionservice.py
+++ b/src/maasserver/rpc/tests/test_regionservice.py
@@ -80,7 +80,10 @@ from provisioningserver.rpc import (
80 common,80 common,
81 exceptions,81 exceptions,
82)82)
83from provisioningserver.rpc.exceptions import CannotRegisterRackController83from provisioningserver.rpc.exceptions import (
84 CannotRegisterRackController,
85 NoConnectionsAvailable,
86)
84from provisioningserver.rpc.interfaces import IConnection87from provisioningserver.rpc.interfaces import IConnection
85from provisioningserver.rpc.region import RegisterRackController88from provisioningserver.rpc.region import RegisterRackController
86from provisioningserver.rpc.testing import call_responder89from provisioningserver.rpc.testing import call_responder
@@ -91,6 +94,7 @@ from provisioningserver.utils.twisted import (
91 callInReactorWithTimeout,94 callInReactorWithTimeout,
92 DeferredValue,95 DeferredValue,
93)96)
97from testtools import ExpectedException
94from testtools.deferredruntest import assert_fails_with98from testtools.deferredruntest import assert_fails_with
95from testtools.matchers import (99from testtools.matchers import (
96 AfterPreprocessing,100 AfterPreprocessing,
@@ -875,6 +879,21 @@ class TestRegionService(MAASTestCase):
875 self.assertThat(service.getAllClients(), Equals([]))879 self.assertThat(service.getAllClients(), Equals([]))
876880
877 @wait_for_reactor881 @wait_for_reactor
882 def test_getAllClients_empty_connections(self):
883 service = RegionService(sentinel.advertiser)
884 service.connections.clear()
885 uuid1 = factory.make_UUID()
886 service.connections[uuid1] = set()
887 self.assertThat(service.getAllClients(), Equals([]))
888
889 @wait_for_reactor
890 def test_getRandomClient_empty_raises_NoConnectionsAvailable(self):
891 service = RegionService(sentinel.advertiser)
892 service.connections.clear()
893 with ExpectedException(NoConnectionsAvailable):
894 service.getRandomClient()
895
896 @wait_for_reactor
878 def test_getAllClients(self):897 def test_getAllClients(self):
879 service = RegionService(sentinel.advertiser)898 service = RegionService(sentinel.advertiser)
880 uuid1 = factory.make_UUID()899 uuid1 = factory.make_UUID()

Subscribers

People subscribed via source and target branches