From d29168fa3fe656ba4f2322226e4ae511c89dfed2 Mon Sep 17 00:00:00 2001
From: Anthony Young <sleepsonthefloor@gmail.com>
Date: Thu, 26 Jan 2012 16:13:09 -0800
Subject: [PATCH] Add limit and marker to user_list and tenant_list

 * This will ultimately enable seeing more than 10 users/tenants at a
   time in horizon :)

Change-Id: I54ab6305746a16fda8e57c9c67c48ea2d6b906c6
---
 keystoneclient/v2_0/tenants.py | 17 ++++++++++--
 keystoneclient/v2_0/users.py   | 19 +++++++++++---
 tests/v2_0/test_tenants.py     | 48 ++++++++++++++++++++++++++++++++++
 tests/v2_0/test_users.py       | 48 ++++++++++++++++++++++++++++++++++
 4 files changed, 127 insertions(+), 5 deletions(-)

diff --git a/keystoneclient/v2_0/tenants.py b/keystoneclient/v2_0/tenants.py
index fa0c05cd6..9b0c9f2bc 100644
--- a/keystoneclient/v2_0/tenants.py
+++ b/keystoneclient/v2_0/tenants.py
@@ -14,6 +14,8 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import urllib
+
 from keystoneclient import base
 
 
@@ -48,12 +50,23 @@ class TenantManager(base.ManagerWithFind):
 
         return self._create('/tenants', params, "tenant")
 
-    def list(self):
+    def list(self, limit=None, marker=None):
         """
         Get a list of tenants.
         :rtype: list of :class:`Tenant`
         """
-        return self._list("/tenants", "tenants")
+
+        params = {}
+        if limit:
+            params['limit'] = limit
+        if marker:
+            params['marker'] = marker
+
+        query = ""
+        if params:
+            query = "?" + urllib.urlencode(params)
+
+        return self._list("/tenants%s" % query, "tenants")
 
     def update(self, tenant_id, tenant_name=None, description=None,
                enabled=None):
diff --git a/keystoneclient/v2_0/users.py b/keystoneclient/v2_0/users.py
index 60451535c..ec97d941b 100644
--- a/keystoneclient/v2_0/users.py
+++ b/keystoneclient/v2_0/users.py
@@ -14,6 +14,8 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import urllib
+
 from keystoneclient import base
 
 
@@ -90,14 +92,25 @@ class UserManager(base.ManagerWithFind):
         """
         return self._delete("/users/%s" % base.getid(user))
 
-    def list(self, tenant_id=None):
+    def list(self, tenant_id=None, limit=None, marker=None):
         """
         Get a list of users (optionally limited to a tenant)
 
         :rtype: list of :class:`User`
         """
 
+        params = {}
+        if limit:
+            params['limit'] = int(limit)
+        if marker:
+            params['marker'] = int(marker)
+
+        query = ""
+        if params:
+            query = "?" + urllib.urlencode(params)
+
         if not tenant_id:
-            return self._list("/users", "users")
+            return self._list("/users%s" % query, "users")
         else:
-            return self._list("/tenants/%s/users" % tenant_id, "users")
+            return self._list("/tenants/%s/users%s" % (tenant_id, query),
+                              "users")
diff --git a/tests/v2_0/test_tenants.py b/tests/v2_0/test_tenants.py
index ea4f78b54..fb7a70b5b 100644
--- a/tests/v2_0/test_tenants.py
+++ b/tests/v2_0/test_tenants.py
@@ -116,6 +116,54 @@ class TenantTests(utils.TestCase):
         tenant_list = self.client.tenants.list()
         [self.assertTrue(isinstance(t, tenants.Tenant)) for t in tenant_list]
 
+    def test_list_limit(self):
+        resp = httplib2.Response({
+            "status": 200,
+            "body": json.dumps(self.TEST_TENANTS),
+            })
+
+        httplib2.Http.request(urlparse.urljoin(self.TEST_URL,
+                              'v2.0/tenants?limit=1&fresh=1234'),
+                              'GET',
+                              headers=self.TEST_REQUEST_HEADERS) \
+                              .AndReturn((resp, resp['body']))
+        self.mox.ReplayAll()
+
+        tenant_list = self.client.tenants.list(limit=1)
+        [self.assertTrue(isinstance(t, tenants.Tenant)) for t in tenant_list]
+
+    def test_list_marker(self):
+        resp = httplib2.Response({
+            "status": 200,
+            "body": json.dumps(self.TEST_TENANTS),
+            })
+
+        httplib2.Http.request(urlparse.urljoin(self.TEST_URL,
+                              'v2.0/tenants?marker=1&fresh=1234'),
+                              'GET',
+                              headers=self.TEST_REQUEST_HEADERS) \
+                              .AndReturn((resp, resp['body']))
+        self.mox.ReplayAll()
+
+        tenant_list = self.client.tenants.list(marker=1)
+        [self.assertTrue(isinstance(t, tenants.Tenant)) for t in tenant_list]
+
+    def test_list_limit_marker(self):
+        resp = httplib2.Response({
+            "status": 200,
+            "body": json.dumps(self.TEST_TENANTS),
+            })
+
+        httplib2.Http.request(urlparse.urljoin(self.TEST_URL,
+                              'v2.0/tenants?marker=1&limit=1&fresh=1234'),
+                              'GET',
+                              headers=self.TEST_REQUEST_HEADERS) \
+                              .AndReturn((resp, resp['body']))
+        self.mox.ReplayAll()
+
+        tenant_list = self.client.tenants.list(limit=1, marker=1)
+        [self.assertTrue(isinstance(t, tenants.Tenant)) for t in tenant_list]
+
     def test_update(self):
         req_body = {"tenant": {"id": 4,
                                "name": "tenantX",
diff --git a/tests/v2_0/test_users.py b/tests/v2_0/test_users.py
index dbff00870..7b9ab3b2e 100644
--- a/tests/v2_0/test_users.py
+++ b/tests/v2_0/test_users.py
@@ -114,6 +114,54 @@ class UserTests(utils.TestCase):
         user_list = self.client.users.list()
         [self.assertTrue(isinstance(u, users.User)) for u in user_list]
 
+    def test_list_limit(self):
+        resp = httplib2.Response({
+            "status": 200,
+            "body": json.dumps(self.TEST_USERS),
+            })
+
+        httplib2.Http.request(urlparse.urljoin(self.TEST_URL,
+                              'v2.0/users?limit=1&fresh=1234'),
+                              'GET',
+                              headers=self.TEST_REQUEST_HEADERS) \
+                              .AndReturn((resp, resp['body']))
+        self.mox.ReplayAll()
+
+        user_list = self.client.users.list(limit=1)
+        [self.assertTrue(isinstance(u, users.User)) for u in user_list]
+
+    def test_list_marker(self):
+        resp = httplib2.Response({
+            "status": 200,
+            "body": json.dumps(self.TEST_USERS),
+            })
+
+        httplib2.Http.request(urlparse.urljoin(self.TEST_URL,
+                              'v2.0/users?marker=1&fresh=1234'),
+                              'GET',
+                              headers=self.TEST_REQUEST_HEADERS) \
+                              .AndReturn((resp, resp['body']))
+        self.mox.ReplayAll()
+
+        user_list = self.client.users.list(marker=1)
+        [self.assertTrue(isinstance(u, users.User)) for u in user_list]
+
+    def test_list_limit_marker(self):
+        resp = httplib2.Response({
+            "status": 200,
+            "body": json.dumps(self.TEST_USERS),
+            })
+
+        httplib2.Http.request(urlparse.urljoin(self.TEST_URL,
+                              'v2.0/users?marker=1&limit=1&fresh=1234'),
+                              'GET',
+                              headers=self.TEST_REQUEST_HEADERS) \
+                              .AndReturn((resp, resp['body']))
+        self.mox.ReplayAll()
+
+        user_list = self.client.users.list(limit=1, marker=1)
+        [self.assertTrue(isinstance(u, users.User)) for u in user_list]
+
     def test_update(self):
         req_1 = {"user": {"password": "swordfish", "id": 2}}
         req_2 = {"user": {"id": 2, "email": "gabriel@example.com"}}