1# Copyright (c) 2012 Amazon.com, Inc. or its affiliates. All Rights Reserved 2# 3# Permission is hereby granted, free of charge, to any person obtaining a 4# copy of this software and associated documentation files (the 5# "Software"), to deal in the Software without restriction, including 6# without limitation the rights to use, copy, modify, merge, publish, dis- 7# tribute, sublicense, and/or sell copies of the Software, and to permit 8# persons to whom the Software is furnished to do so, subject to the fol- 9# lowing conditions: 10# 11# The above copyright notice and this permission notice shall be included 12# in all copies or substantial portions of the Software. 13# 14# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- 16# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 17# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 18# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20# IN THE SOFTWARE. 21# 22from tests.unit import AWSMockServiceTestCase 23 24from boto.s3.connection import S3Connection 25from boto.s3.bucket import Bucket 26from boto.s3.lifecycle import Rule, Lifecycle, Transition 27 28 29class TestS3LifeCycle(AWSMockServiceTestCase): 30 connection_class = S3Connection 31 32 def default_body(self): 33 return """ 34 <LifecycleConfiguration> 35 <Rule> 36 <ID>rule-1</ID> 37 <Prefix>prefix/foo</Prefix> 38 <Status>Enabled</Status> 39 <Transition> 40 <Days>30</Days> 41 <StorageClass>GLACIER</StorageClass> 42 </Transition> 43 <Expiration> 44 <Days>365</Days> 45 </Expiration> 46 </Rule> 47 <Rule> 48 <ID>rule-2</ID> 49 <Prefix>prefix/bar</Prefix> 50 <Status>Disabled</Status> 51 <Transition> 52 <Date>2012-12-31T00:00:000Z</Date> 53 <StorageClass>STANDARD_IA</StorageClass> 54 </Transition> 55 <Expiration> 56 <Date>2012-12-31T00:00:000Z</Date> 57 </Expiration> 58 </Rule> 59 <Rule> 60 <ID>multiple-transitions</ID> 61 <Prefix></Prefix> 62 <Status>Enabled</Status> 63 <Transition> 64 <Days>30</Days> 65 <StorageClass>STANDARD_IA</StorageClass> 66 </Transition> 67 <Transition> 68 <Days>90</Days> 69 <StorageClass>GLACIER</StorageClass> 70 </Transition> 71 </Rule> 72 </LifecycleConfiguration> 73 """ 74 75 def _get_bucket_lifecycle_config(self): 76 self.set_http_response(status_code=200) 77 bucket = Bucket(self.service_connection, 'mybucket') 78 return bucket.get_lifecycle_config() 79 80 def test_lifecycle_response_contains_all_rules(self): 81 self.assertEqual(len(self._get_bucket_lifecycle_config()), 3) 82 83 def test_parse_lifecycle_id(self): 84 rule = self._get_bucket_lifecycle_config()[0] 85 self.assertEqual(rule.id, 'rule-1') 86 87 def test_parse_lifecycle_prefix(self): 88 rule = self._get_bucket_lifecycle_config()[0] 89 self.assertEqual(rule.prefix, 'prefix/foo') 90 91 def test_parse_lifecycle_no_prefix(self): 92 rule = self._get_bucket_lifecycle_config()[2] 93 self.assertEquals(rule.prefix, '') 94 95 def test_parse_lifecycle_enabled(self): 96 rule = self._get_bucket_lifecycle_config()[0] 97 self.assertEqual(rule.status, 'Enabled') 98 99 def test_parse_lifecycle_disabled(self): 100 rule = self._get_bucket_lifecycle_config()[1] 101 self.assertEqual(rule.status, 'Disabled') 102 103 def test_parse_expiration_days(self): 104 rule = self._get_bucket_lifecycle_config()[0] 105 self.assertEqual(rule.expiration.days, 365) 106 107 def test_parse_expiration_date(self): 108 rule = self._get_bucket_lifecycle_config()[1] 109 self.assertEqual(rule.expiration.date, '2012-12-31T00:00:000Z') 110 111 def test_parse_expiration_not_required(self): 112 rule = self._get_bucket_lifecycle_config()[2] 113 self.assertIsNone(rule.expiration) 114 115 def test_parse_transition_days(self): 116 transition = self._get_bucket_lifecycle_config()[0].transition[0] 117 self.assertEquals(transition.days, 30) 118 self.assertIsNone(transition.date) 119 120 def test_parse_transition_days_deprecated(self): 121 transition = self._get_bucket_lifecycle_config()[0].transition 122 self.assertEquals(transition.days, 30) 123 self.assertIsNone(transition.date) 124 125 def test_parse_transition_date(self): 126 transition = self._get_bucket_lifecycle_config()[1].transition[0] 127 self.assertEquals(transition.date, '2012-12-31T00:00:000Z') 128 self.assertIsNone(transition.days) 129 130 def test_parse_transition_date_deprecated(self): 131 transition = self._get_bucket_lifecycle_config()[1].transition 132 self.assertEquals(transition.date, '2012-12-31T00:00:000Z') 133 self.assertIsNone(transition.days) 134 135 def test_parse_storage_class_standard_ia(self): 136 transition = self._get_bucket_lifecycle_config()[1].transition[0] 137 self.assertEqual(transition.storage_class, 'STANDARD_IA') 138 139 def test_parse_storage_class_glacier(self): 140 transition = self._get_bucket_lifecycle_config()[0].transition[0] 141 self.assertEqual(transition.storage_class, 'GLACIER') 142 143 def test_parse_storage_class_deprecated(self): 144 transition = self._get_bucket_lifecycle_config()[1].transition 145 self.assertEqual(transition.storage_class, 'STANDARD_IA') 146 147 def test_parse_multiple_lifecycle_rules(self): 148 transition = self._get_bucket_lifecycle_config()[2].transition 149 self.assertEqual(len(transition), 2) 150 151 def test_expiration_with_no_transition(self): 152 lifecycle = Lifecycle() 153 lifecycle.add_rule('myid', 'prefix', 'Enabled', 30) 154 xml = lifecycle.to_xml() 155 self.assertIn('<Expiration><Days>30</Days></Expiration>', xml) 156 157 def test_expiration_is_optional(self): 158 t = Transition(days=30, storage_class='GLACIER') 159 r = Rule('myid', 'prefix', 'Enabled', expiration=None, 160 transition=t) 161 xml = r.to_xml() 162 self.assertIn( 163 '<Transition><StorageClass>GLACIER</StorageClass><Days>30</Days>', 164 xml) 165 166 def test_transition_is_optional(self): 167 r = Rule('myid', 'prefix', 'Enabled') 168 xml = r.to_xml() 169 self.assertEqual( 170 '<Rule><ID>myid</ID><Prefix>prefix</Prefix><Status>Enabled</Status></Rule>', 171 xml) 172 173 def test_expiration_and_transition(self): 174 t = Transition(date='2012-11-30T00:00:000Z', storage_class='GLACIER') 175 r = Rule('myid', 'prefix', 'Enabled', expiration=30, transition=t) 176 xml = r.to_xml() 177 self.assertIn( 178 '<Transition><StorageClass>GLACIER</StorageClass>' 179 '<Date>2012-11-30T00:00:000Z</Date>', xml) 180 self.assertIn('<Expiration><Days>30</Days></Expiration>', xml) 181