OLD | NEW |
(Empty) | |
| 1 # -*- coding: utf-8 -*- |
| 2 # Copyright 2013 Google Inc. All Rights Reserved. |
| 3 # |
| 4 # Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 # you may not use this file except in compliance with the License. |
| 6 # You may obtain a copy of the License at |
| 7 # |
| 8 # http://www.apache.org/licenses/LICENSE-2.0 |
| 9 # |
| 10 # Unless required by applicable law or agreed to in writing, software |
| 11 # distributed under the License is distributed on an "AS IS" BASIS, |
| 12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 # See the License for the specific language governing permissions and |
| 14 # limitations under the License. |
| 15 """Integration tests for the setacl and setdefacl commands.""" |
| 16 |
| 17 import gslib.tests.testcase as testcase |
| 18 import re |
| 19 from gslib.util import Retry |
| 20 from gslib.tests.util import ObjectToURI as suri |
| 21 |
| 22 PUBLIC_READ_ACL_TEXT = '<Scope type="AllUsers"/><Permission>READ</Permission>' |
| 23 |
| 24 |
| 25 class TestSetAcl(testcase.GsUtilIntegrationTestCase): |
| 26 """Integration tests for setacl command.""" |
| 27 |
| 28 def test_set_invalid_acl_object(self): |
| 29 """Ensures that invalid XML content returns a MalformedACLError.""" |
| 30 obj_uri = suri(self.CreateObject(contents='foo')) |
| 31 inpath = self.CreateTempFile(contents='badXml') |
| 32 stderr = self.RunGsUtil(['setacl', inpath, obj_uri], return_stderr=True, |
| 33 expected_status=1) |
| 34 |
| 35 self.assertIn('MalformedACLError', stderr) |
| 36 |
| 37 def test_set_invalid_acl_bucket(self): |
| 38 """Ensures that invalid XML content returns a MalformedACLError.""" |
| 39 bucket_uri = suri(self.CreateBucket()) |
| 40 inpath = self.CreateTempFile(contents='badXml') |
| 41 stderr = self.RunGsUtil(['setacl', inpath, bucket_uri], return_stderr=True, |
| 42 expected_status=1) |
| 43 |
| 44 self.assertIn('MalformedACLError', stderr) |
| 45 |
| 46 def test_set_valid_acl_object(self): |
| 47 """Ensures that valid canned and XML ACLs work with get/set.""" |
| 48 obj_uri = suri(self.CreateObject(contents='foo')) |
| 49 acl_string = self.RunGsUtil(['getacl', obj_uri], return_stdout=True) |
| 50 inpath = self.CreateTempFile(contents=acl_string) |
| 51 self.RunGsUtil(['setacl', 'public-read', obj_uri]) |
| 52 acl_string2 = self.RunGsUtil(['getacl', obj_uri], return_stdout=True) |
| 53 self.RunGsUtil(['setacl', inpath, obj_uri]) |
| 54 acl_string3 = self.RunGsUtil(['getacl', obj_uri], return_stdout=True) |
| 55 |
| 56 self.assertNotEqual(acl_string, acl_string2) |
| 57 self.assertEqual(acl_string, acl_string3) |
| 58 |
| 59 def test_set_valid_permission_whitespace_object(self): |
| 60 """Ensures that whitespace is allowed in <Permission> elements.""" |
| 61 obj_uri = suri(self.CreateObject(contents='foo')) |
| 62 acl_string = self.RunGsUtil(['getacl', obj_uri], return_stdout=True) |
| 63 acl_string = re.sub(r'<Permission>', r'<Permission> \n', acl_string) |
| 64 acl_string = re.sub(r'</Permission>', r'\n </Permission>', acl_string) |
| 65 inpath = self.CreateTempFile(contents=acl_string) |
| 66 self.RunGsUtil(['setacl', inpath, obj_uri]) |
| 67 |
| 68 def test_set_valid_acl_bucket(self): |
| 69 """Ensures that valid canned and XML ACLs work with get/set.""" |
| 70 bucket_uri = suri(self.CreateBucket()) |
| 71 acl_string = self.RunGsUtil(['getacl', bucket_uri], return_stdout=True) |
| 72 inpath = self.CreateTempFile(contents=acl_string) |
| 73 self.RunGsUtil(['setacl', 'public-read', bucket_uri]) |
| 74 acl_string2 = self.RunGsUtil(['getacl', bucket_uri], return_stdout=True) |
| 75 self.RunGsUtil(['setacl', inpath, bucket_uri]) |
| 76 acl_string3 = self.RunGsUtil(['getacl', bucket_uri], return_stdout=True) |
| 77 |
| 78 self.assertNotEqual(acl_string, acl_string2) |
| 79 self.assertEqual(acl_string, acl_string3) |
| 80 |
| 81 def test_invalid_canned_acl_object(self): |
| 82 """Ensures that an invalid canned ACL returns a CommandException.""" |
| 83 obj_uri = suri(self.CreateObject(contents='foo')) |
| 84 stderr = self.RunGsUtil(['setacl', 'not-a-canned-acl', |
| 85 obj_uri], return_stderr=True, expected_status=1) |
| 86 self.assertIn('CommandException', stderr) |
| 87 self.assertIn('Invalid canned ACL', stderr) |
| 88 |
| 89 def test_set_valid_def_acl_bucket(self): |
| 90 """Ensures that valid default canned and XML ACLs works with get/set.""" |
| 91 bucket_uri = self.CreateBucket() |
| 92 |
| 93 # Default ACL is project private. |
| 94 obj_uri1 = suri(self.CreateObject(bucket_uri=bucket_uri, contents='foo')) |
| 95 acl_string = self.RunGsUtil(['getacl', obj_uri1], return_stdout=True) |
| 96 |
| 97 # Change it to authenticated-read. |
| 98 self.RunGsUtil(['setdefacl', 'authenticated-read', suri(bucket_uri)]) |
| 99 obj_uri2 = suri(self.CreateObject(bucket_uri=bucket_uri, contents='foo2')) |
| 100 acl_string2 = self.RunGsUtil(['getacl', obj_uri2], return_stdout=True) |
| 101 |
| 102 # Now change it back to the default via XML. |
| 103 inpath = self.CreateTempFile(contents=acl_string) |
| 104 self.RunGsUtil(['setdefacl', inpath, suri(bucket_uri)]) |
| 105 obj_uri3 = suri(self.CreateObject(bucket_uri=bucket_uri, contents='foo3')) |
| 106 acl_string3 = self.RunGsUtil(['getacl', obj_uri3], return_stdout=True) |
| 107 |
| 108 self.assertNotEqual(acl_string, acl_string2) |
| 109 self.assertIn('AllAuthenticatedUsers', acl_string2) |
| 110 self.assertEqual(acl_string, acl_string3) |
| 111 |
| 112 def test_setacl_version_specific_uri(self): |
| 113 bucket_uri = self.CreateVersionedBucket() |
| 114 # Create initial object version. |
| 115 uri = self.CreateObject(bucket_uri=bucket_uri, contents='data') |
| 116 # Create a second object version. |
| 117 inpath = self.CreateTempFile(contents='def') |
| 118 self.RunGsUtil(['cp', inpath, uri.uri]) |
| 119 |
| 120 # Find out the two object version IDs. |
| 121 # Use @Retry as hedge against bucket listing eventual consistency. |
| 122 @Retry(AssertionError, tries=3, delay=1, backoff=1) |
| 123 def _GetVersions(): |
| 124 stdout = self.RunGsUtil(['ls', '-a', uri.uri], return_stdout=True) |
| 125 lines = stdout.split('\n') |
| 126 # There should be 3 lines, counting final \n. |
| 127 self.assertEqual(len(lines), 3) |
| 128 return lines[0], lines[1] |
| 129 |
| 130 v0_uri_str, v1_uri_str = _GetVersions() |
| 131 |
| 132 # Check that neither version currently has public-read permission |
| 133 # (default ACL is project-private). |
| 134 orig_acls = [] |
| 135 for uri_str in (v0_uri_str, v1_uri_str): |
| 136 acl = self.RunGsUtil(['getacl', uri_str], return_stdout=True) |
| 137 self.assertNotIn(PUBLIC_READ_ACL_TEXT, self._strip_xml_whitespace(acl)) |
| 138 orig_acls.append(acl) |
| 139 |
| 140 # Set the ACL for the older version of the object to public-read. |
| 141 self.RunGsUtil(['setacl', 'public-read', v0_uri_str]) |
| 142 # Check that the older version's ACL is public-read, but newer version |
| 143 # is not. |
| 144 acl = self.RunGsUtil(['getacl', v0_uri_str], return_stdout=True) |
| 145 self.assertIn(PUBLIC_READ_ACL_TEXT, self._strip_xml_whitespace(acl)) |
| 146 acl = self.RunGsUtil(['getacl', v1_uri_str], return_stdout=True) |
| 147 self.assertNotIn(PUBLIC_READ_ACL_TEXT, self._strip_xml_whitespace(acl)) |
| 148 |
| 149 # Check that reading the ACL with the version-less URI returns the |
| 150 # original ACL (since the version-less URI means the current version). |
| 151 acl = self.RunGsUtil(['getacl', uri.uri], return_stdout=True) |
| 152 self.assertEqual(acl, orig_acls[0]) |
| 153 |
| 154 def _strip_xml_whitespace(self, xml): |
| 155 s = re.sub('>\s*', '>', xml.replace('\n', '')) |
| 156 return re.sub('\s*<', '<', s) |
OLD | NEW |