From 3c7b5185ca1eb89a00c54a57bb9ef028bcb290bb Mon Sep 17 00:00:00 2001
From: TerryHowe <terrylhowe@gmail.com>
Date: Tue, 14 Apr 2015 11:03:22 -0600
Subject: [PATCH] Handle the pagination for image list

Handle the paginatiion for image list.  We were sorting the
data here, so nothing lost for the generator.

Change-Id: I2d7d4b3d5c9f650953f309c971ac53b64f6f7f77
---
 openstackclient/image/v1/image.py            | 12 +++++++++-
 openstackclient/image/v2/image.py            | 12 +++++++++-
 openstackclient/tests/image/v1/test_image.py | 20 +++++++++++------
 openstackclient/tests/image/v2/test_image.py | 23 +++++++++++++++-----
 4 files changed, 52 insertions(+), 15 deletions(-)

diff --git a/openstackclient/image/v1/image.py b/openstackclient/image/v1/image.py
index 127a7735ec..7f5f5af967 100644
--- a/openstackclient/image/v1/image.py
+++ b/openstackclient/image/v1/image.py
@@ -405,7 +405,17 @@ class ListImage(lister.Lister):
             columns = ("ID", "Name")
             column_headers = columns
 
-        data = image_client.api.image_list(**kwargs)
+        # List of image data received
+        data = []
+        # No pages received yet, so start the page marker at None.
+        marker = None
+        while True:
+            page = image_client.api.image_list(marker=marker, **kwargs)
+            if not page:
+                break
+            data.extend(page)
+            # Set the marker to the id of the last item we received
+            marker = page[-1]['id']
 
         if parsed_args.property:
             # NOTE(dtroyer): coerce to a list to subscript it in py3
diff --git a/openstackclient/image/v2/image.py b/openstackclient/image/v2/image.py
index afc99e8578..eb82c9102c 100644
--- a/openstackclient/image/v2/image.py
+++ b/openstackclient/image/v2/image.py
@@ -156,7 +156,17 @@ class ListImage(lister.Lister):
             columns = ("ID", "Name")
             column_headers = columns
 
-        data = image_client.api.image_list(**kwargs)
+        # List of image data received
+        data = []
+        # No pages received yet, so start the page marker at None.
+        marker = None
+        while True:
+            page = image_client.api.image_list(marker=marker, **kwargs)
+            if not page:
+                break
+            data.extend(page)
+            # Set the marker to the id of the last item we received
+            marker = page[-1]['id']
 
         if parsed_args.property:
             # NOTE(dtroyer): coerce to a list to subscript it in py3
diff --git a/openstackclient/tests/image/v1/test_image.py b/openstackclient/tests/image/v1/test_image.py
index 2776e7448d..2136f109de 100644
--- a/openstackclient/tests/image/v1/test_image.py
+++ b/openstackclient/tests/image/v1/test_image.py
@@ -306,8 +306,8 @@ class TestImageList(TestImage):
         super(TestImageList, self).setUp()
 
         self.api_mock = mock.Mock()
-        self.api_mock.image_list.return_value = [
-            copy.deepcopy(image_fakes.IMAGE),
+        self.api_mock.image_list.side_effect = [
+            [copy.deepcopy(image_fakes.IMAGE)], [],
         ]
         self.app.client_manager.image.api = self.api_mock
 
@@ -327,6 +327,7 @@ class TestImageList(TestImage):
         columns, data = self.cmd.take_action(parsed_args)
         self.api_mock.image_list.assert_called_with(
             detailed=False,
+            marker=image_fakes.image_id,
         )
 
         collist = ('ID', 'Name')
@@ -354,6 +355,7 @@ class TestImageList(TestImage):
         self.api_mock.image_list.assert_called_with(
             detailed=False,
             public=True,
+            marker=image_fakes.image_id,
         )
 
         collist = ('ID', 'Name')
@@ -381,6 +383,7 @@ class TestImageList(TestImage):
         self.api_mock.image_list.assert_called_with(
             detailed=False,
             private=True,
+            marker=image_fakes.image_id,
         )
 
         collist = ('ID', 'Name')
@@ -405,6 +408,7 @@ class TestImageList(TestImage):
         columns, data = self.cmd.take_action(parsed_args)
         self.api_mock.image_list.assert_called_with(
             detailed=True,
+            marker=image_fakes.image_id,
         )
 
         collist = (
@@ -437,8 +441,8 @@ class TestImageList(TestImage):
 
     @mock.patch('openstackclient.api.utils.simple_filter')
     def test_image_list_property_option(self, sf_mock):
-        sf_mock.return_value = [
-            copy.deepcopy(image_fakes.IMAGE),
+        sf_mock.side_effect = [
+            [copy.deepcopy(image_fakes.IMAGE)], [],
         ]
 
         arglist = [
@@ -453,6 +457,7 @@ class TestImageList(TestImage):
         columns, data = self.cmd.take_action(parsed_args)
         self.api_mock.image_list.assert_called_with(
             detailed=True,
+            marker=image_fakes.image_id,
         )
         sf_mock.assert_called_with(
             [image_fakes.IMAGE],
@@ -472,8 +477,8 @@ class TestImageList(TestImage):
 
     @mock.patch('openstackclient.common.utils.sort_items')
     def test_image_list_sort_option(self, si_mock):
-        si_mock.return_value = [
-            copy.deepcopy(image_fakes.IMAGE)
+        si_mock.side_effect = [
+            [copy.deepcopy(image_fakes.IMAGE)], [],
         ]
 
         arglist = ['--sort', 'name:asc']
@@ -483,7 +488,8 @@ class TestImageList(TestImage):
         # DisplayCommandBase.take_action() returns two tuples
         columns, data = self.cmd.take_action(parsed_args)
         self.api_mock.image_list.assert_called_with(
-            detailed=False
+            detailed=False,
+            marker=image_fakes.image_id,
         )
         si_mock.assert_called_with(
             [image_fakes.IMAGE],
diff --git a/openstackclient/tests/image/v2/test_image.py b/openstackclient/tests/image/v2/test_image.py
index 6a28b1ec2d..7eb23769ec 100644
--- a/openstackclient/tests/image/v2/test_image.py
+++ b/openstackclient/tests/image/v2/test_image.py
@@ -70,8 +70,8 @@ class TestImageList(TestImage):
         super(TestImageList, self).setUp()
 
         self.api_mock = mock.Mock()
-        self.api_mock.image_list.return_value = [
-            copy.deepcopy(image_fakes.IMAGE),
+        self.api_mock.image_list.side_effect = [
+            [copy.deepcopy(image_fakes.IMAGE)], [],
         ]
         self.app.client_manager.image.api = self.api_mock
 
@@ -90,7 +90,9 @@ class TestImageList(TestImage):
 
         # DisplayCommandBase.take_action() returns two tuples
         columns, data = self.cmd.take_action(parsed_args)
-        self.api_mock.image_list.assert_called_with()
+        self.api_mock.image_list.assert_called_with(
+            marker=image_fakes.image_id,
+        )
 
         collist = ('ID', 'Name')
 
@@ -117,6 +119,7 @@ class TestImageList(TestImage):
         columns, data = self.cmd.take_action(parsed_args)
         self.api_mock.image_list.assert_called_with(
             public=True,
+            marker=image_fakes.image_id,
         )
 
         collist = ('ID', 'Name')
@@ -144,6 +147,7 @@ class TestImageList(TestImage):
         columns, data = self.cmd.take_action(parsed_args)
         self.api_mock.image_list.assert_called_with(
             private=True,
+            marker=image_fakes.image_id,
         )
 
         collist = ('ID', 'Name')
@@ -171,6 +175,7 @@ class TestImageList(TestImage):
         columns, data = self.cmd.take_action(parsed_args)
         self.api_mock.image_list.assert_called_with(
             shared=True,
+            marker=image_fakes.image_id,
         )
 
         collist = ('ID', 'Name')
@@ -193,7 +198,9 @@ class TestImageList(TestImage):
 
         # DisplayCommandBase.take_action() returns two tuples
         columns, data = self.cmd.take_action(parsed_args)
-        self.api_mock.image_list.assert_called_with()
+        self.api_mock.image_list.assert_called_with(
+            marker=image_fakes.image_id,
+        )
 
         collist = (
             'ID',
@@ -239,7 +246,9 @@ class TestImageList(TestImage):
 
         # DisplayCommandBase.take_action() returns two tuples
         columns, data = self.cmd.take_action(parsed_args)
-        self.api_mock.image_list.assert_called_with()
+        self.api_mock.image_list.assert_called_with(
+            marker=image_fakes.image_id,
+        )
         sf_mock.assert_called_with(
             [image_fakes.IMAGE],
             attr='a',
@@ -268,7 +277,9 @@ class TestImageList(TestImage):
 
         # DisplayCommandBase.take_action() returns two tuples
         columns, data = self.cmd.take_action(parsed_args)
-        self.api_mock.image_list.assert_called_with()
+        self.api_mock.image_list.assert_called_with(
+            marker=image_fakes.image_id,
+        )
         si_mock.assert_called_with(
             [image_fakes.IMAGE],
             'name:asc'