1# -*- coding: utf-8 -*-
2# MinIO Python Library for Amazon S3 Compatible Cloud Storage,
3# (C) 2015, 2016 MinIO, Inc.
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#     http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17import mock
18
19from nose.tools import eq_, timed
20from unittest import TestCase
21
22from minio import Minio
23from minio.api import _DEFAULT_USER_AGENT
24
25from .minio_mocks import MockResponse, MockConnection
26
27class ListObjectsTest(TestCase):
28    @mock.patch('urllib3.PoolManager')
29    def test_empty_list_objects_works(self, mock_connection):
30        mock_data = '''<?xml version="1.0"?>
31<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
32  <Name>bucket</Name>
33  <Prefix/>
34  <Marker/>
35  <IsTruncated>false</IsTruncated>
36  <MaxKeys>1000</MaxKeys>
37  <Delimiter/>
38</ListBucketResult>
39        '''
40        mock_server = MockConnection()
41        mock_connection.return_value = mock_server
42        mock_server.mock_add_request(MockResponse('GET',
43                                                  'https://localhost:9000/bucket/?max-keys=1000&prefix=',
44                                                  {'User-Agent': _DEFAULT_USER_AGENT}, 200, content=mock_data))
45        client = Minio('localhost:9000')
46        bucket_iter = client.list_objects('bucket', recursive=True)
47        buckets = []
48        for bucket in bucket_iter:
49            buckets.append(bucket)
50        eq_(0, len(buckets))
51
52    @timed(1)
53    @mock.patch('urllib3.PoolManager')
54    def test_list_objects_works(self, mock_connection):
55        mock_data = '''<?xml version="1.0"?>
56<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
57  <Name>bucket</Name>
58  <Prefix/>
59  <Marker/>
60  <MaxKeys>1000</MaxKeys>
61  <Delimiter/>
62  <IsTruncated>false</IsTruncated>
63  <Contents>
64    <Key>key1</Key>
65    <LastModified>2015-05-05T02:21:15.716Z</LastModified>
66    <ETag>5eb63bbbe01eeed093cb22bb8f5acdc3</ETag>
67    <Size>11</Size>
68    <StorageClass>STANDARD</StorageClass>
69    <Owner>
70      <ID>minio</ID>
71      <DisplayName>minio</DisplayName>
72    </Owner>
73  </Contents>
74  <Contents>
75    <Key>key2</Key>
76    <LastModified>2015-05-05T20:36:17.498Z</LastModified>
77    <ETag>2a60eaffa7a82804bdc682ce1df6c2d4</ETag>
78    <Size>1661</Size>
79    <StorageClass>STANDARD</StorageClass>
80    <Owner>
81      <ID>minio</ID>
82      <DisplayName>minio</DisplayName>
83    </Owner>
84  </Contents>
85</ListBucketResult>
86        '''
87        mock_server = MockConnection()
88        mock_connection.return_value = mock_server
89        mock_server.mock_add_request(MockResponse('GET',
90                                                  'https://localhost:9000/bucket/?delimiter=%2F&max-keys=1000&prefix=',
91                                                  {'User-Agent': _DEFAULT_USER_AGENT}, 200, content=mock_data))
92        client = Minio('localhost:9000')
93        bucket_iter = client.list_objects('bucket')
94        buckets = []
95        for bucket in bucket_iter:
96            # cause an xml exception and fail if we try retrieving again
97            mock_server.mock_add_request(MockResponse('GET',
98                                                      'https://localhost:9000/bucket/?delimiter=%2F&max-keys=1000&prefix=',
99                                                      {'User-Agent': _DEFAULT_USER_AGENT}, 200, content=''))
100            buckets.append(bucket)
101
102        eq_(2, len(buckets))
103
104    @timed(1)
105    @mock.patch('urllib3.PoolManager')
106    def test_list_objects_works_well(self, mock_connection):
107        mock_data1 = '''<?xml version="1.0"?>
108<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
109  <Name>bucket</Name>
110  <Prefix/>
111  <Marker />
112  <NextMarker>marker</NextMarker>
113  <MaxKeys>1000</MaxKeys>
114  <Delimiter/>
115  <IsTruncated>true</IsTruncated>
116  <Contents>
117    <Key>key1</Key>
118    <LastModified>2015-05-05T02:21:15.716Z</LastModified>
119    <ETag>5eb63bbbe01eeed093cb22bb8f5acdc3</ETag>
120    <Size>11</Size>
121    <StorageClass>STANDARD</StorageClass>
122    <Owner>
123      <ID>minio</ID>
124      <DisplayName>minio</DisplayName>
125    </Owner>
126  </Contents>
127  <Contents>
128    <Key>key2</Key>
129    <LastModified>2015-05-05T20:36:17.498Z</LastModified>
130    <ETag>2a60eaffa7a82804bdc682ce1df6c2d4</ETag>
131    <Size>1661</Size>
132    <StorageClass>STANDARD</StorageClass>
133    <Owner>
134      <ID>minio</ID>
135      <DisplayName>minio</DisplayName>
136    </Owner>
137  </Contents>
138</ListBucketResult>
139        '''
140        mock_data2 = '''<?xml version="1.0"?>
141<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
142  <Name>bucket</Name>
143  <Prefix/>
144  <Marker/>
145  <MaxKeys>1000</MaxKeys>
146  <Delimiter/>
147  <IsTruncated>false</IsTruncated>
148  <Contents>
149    <Key>key3</Key>
150    <LastModified>2015-05-05T02:21:15.716Z</LastModified>
151    <ETag>5eb63bbbe01eeed093cb22bb8f5acdc3</ETag>
152    <Size>11</Size>
153    <StorageClass>STANDARD</StorageClass>
154    <Owner>
155      <ID>minio</ID>
156      <DisplayName>minio</DisplayName>
157    </Owner>
158  </Contents>
159  <Contents>
160    <Key>key4</Key>
161    <LastModified>2015-05-05T20:36:17.498Z</LastModified>
162    <ETag>2a60eaffa7a82804bdc682ce1df6c2d4</ETag>
163    <Size>1661</Size>
164    <StorageClass>STANDARD</StorageClass>
165    <Owner>
166      <ID>minio</ID>
167      <DisplayName>minio</DisplayName>
168    </Owner>
169  </Contents>
170</ListBucketResult>
171        '''
172        mock_server = MockConnection()
173        mock_connection.return_value = mock_server
174        mock_server.mock_add_request(MockResponse('GET',
175                                                  'https://localhost:9000/bucket/?max-keys=1000&prefix=',
176                                                  {'User-Agent': _DEFAULT_USER_AGENT}, 200, content=mock_data1))
177        client = Minio('localhost:9000')
178        bucket_iter = client.list_objects('bucket', recursive=True)
179        buckets = []
180        for bucket in bucket_iter:
181            url = 'https://localhost:9000/bucket/?marker=marker&max-keys=1000&prefix='
182            mock_server.mock_add_request(MockResponse('GET', url,
183                                                      {'User-Agent': _DEFAULT_USER_AGENT}, 200,
184                                                      content=mock_data2))
185            buckets.append(bucket)
186
187        eq_(4, len(buckets))
188