From 782696aec17791e2097e2e8df472a7a167fdd743 Mon Sep 17 00:00:00 2001 From: Kezhu Wang Date: Wed, 11 Sep 2024 21:03:23 +0800 Subject: [PATCH] CURATOR-714: Assert that namespace paths are created using CuratorFramework's ACLProvider (#505) CURATOR-221 reported that namespace paths are created with no ACL. Though, I belive that it should be fixed by CURATOR-222. It should still be a good to write tests to assert that. --- .../curator/framework/imps/TestCreate.java | 131 ++++++++++++++++++ 1 file changed, 131 insertions(+) diff --git a/curator-framework/src/test/java/org/apache/curator/framework/imps/TestCreate.java b/curator-framework/src/test/java/org/apache/curator/framework/imps/TestCreate.java index a83192754..fc866a89b 100644 --- a/curator-framework/src/test/java/org/apache/curator/framework/imps/TestCreate.java +++ b/curator-framework/src/test/java/org/apache/curator/framework/imps/TestCreate.java @@ -182,6 +182,75 @@ public void processResult(CuratorFramework client, CuratorEvent event) throws Ex } } + @Test + public void testCreateWithParentsWithAclApplyToParentsInNamespace() throws Exception { + CuratorFramework client = createClient(new DefaultACLProvider()); + try { + client.start(); + + // given: a namespace + CuratorFramework bar = client.usingNamespace("bar"); + + // when: create a path with custom ACL and applyToParents option open in that namespace + List acl = + Collections.singletonList(new ACL(ZooDefs.Perms.CREATE | ZooDefs.Perms.READ, ANYONE_ID_UNSAFE)); + bar.create().creatingParentsIfNeeded().withACL(acl, true).forPath("/foo/boo"); + + // then: the created path has custom ACL + List actual_bar_foo_boo = client.getACL().forPath("/bar/foo/boo"); + assertEquals(actual_bar_foo_boo, acl); + + // then: the parent path has custom ACL + List actual_bar_foo = client.getACL().forPath("/bar/foo"); + assertEquals(actual_bar_foo, acl); + + // then: but the namespace path inherits ACL from CuratorFramework + List actual_bar = client.getACL().forPath("/bar"); + assertEquals(actual_bar, ZooDefs.Ids.OPEN_ACL_UNSAFE); + } finally { + CloseableUtils.closeQuietly(client); + } + } + + @Test + public void testCreateWithParentsWithAclApplyToParentsInNamespaceBackground() throws Exception { + CuratorFramework client = createClient(new DefaultACLProvider()); + try { + client.start(); + + final CountDownLatch latch = new CountDownLatch(1); + BackgroundCallback callback = (client1, event) -> latch.countDown(); + + List acl = + Collections.singletonList(new ACL(ZooDefs.Perms.CREATE | ZooDefs.Perms.READ, ANYONE_ID_UNSAFE)); + + // given: a namespace + CuratorFramework bar = client.usingNamespace("bar"); + + // when: create a path with custom ACL and applyToParents option open in that namespace in background + bar.create() + .creatingParentsIfNeeded() + .withACL(acl, true) + .inBackground(callback) + .forPath("/foo/boo"); + assertTrue(latch.await(2000, TimeUnit.MILLISECONDS), "Callback not invoked"); + + // then: the created path has custom ACL + List actual_bar_foo_boo = client.getACL().forPath("/bar/foo/boo"); + assertEquals(actual_bar_foo_boo, acl); + + // then: the parent path has custom ACL + List actual_bar_foo = client.getACL().forPath("/bar/foo"); + assertEquals(actual_bar_foo, acl); + + // then: but the namespace path inherits ACL from CuratorFramework + List actual_bar = client.getACL().forPath("/bar"); + assertEquals(actual_bar, ZooDefs.Ids.OPEN_ACL_UNSAFE); + } finally { + CloseableUtils.closeQuietly(client); + } + } + /** * Tests that if no ACL list provided to the create builder, then the ACL list is created based on the client's ACLProvider. */ @@ -235,6 +304,68 @@ public void processResult(CuratorFramework client, CuratorEvent event) throws Ex } } + /** + * Tests that if no ACL list provided to the create builder, then the ACL list is created based on the client's ACLProvider. + */ + @Test + public void testCreateWithParentsWithoutAclInNamespace() throws Exception { + CuratorFramework client = createClient(testACLProvider); + try { + client.start(); + + // given: a namespace + CuratorFramework bar = client.usingNamespace("bar"); + + // when: create a path in that namespace + bar.create().creatingParentsIfNeeded().forPath("/foo/boo"); + + // then: all created paths inherit ACLs from CuratorFramework + List actual_bar_foo_boo = client.getACL().forPath("/bar/foo/boo"); + assertEquals(actual_bar_foo_boo, ZooDefs.Ids.OPEN_ACL_UNSAFE); + List actual_bar_foo = client.getACL().forPath("/bar/foo"); + assertEquals(actual_bar_foo, READ_CREATE_WRITE); + + // then: also the namespace path inherits ACL from CuratorFramework + List actual_bar = client.getACL().forPath("/bar"); + assertEquals(actual_bar, READ_CREATE); + } finally { + CloseableUtils.closeQuietly(client); + } + } + + /** + * Tests that if no ACL list provided to the create builder, then the ACL list is created based on the client's ACLProvider. + */ + @Test + public void testCreateWithParentsWithoutAclInNamespaceBackground() throws Exception { + CuratorFramework client = createClient(testACLProvider); + try { + client.start(); + + final CountDownLatch latch = new CountDownLatch(1); + BackgroundCallback callback = (client1, event) -> latch.countDown(); + + // given: a namespace + CuratorFramework bar = client.usingNamespace("bar"); + + // when: create a path in that namespace in background + bar.create().creatingParentsIfNeeded().inBackground(callback).forPath("/foo/boo"); + assertTrue(latch.await(2000, TimeUnit.MILLISECONDS), "Callback not invoked"); + + // then: all created paths inherit ACLs from CuratorFramework + List actual_bar_foo_boo = client.getACL().forPath("/bar/foo/boo"); + assertEquals(actual_bar_foo_boo, ZooDefs.Ids.OPEN_ACL_UNSAFE); + List actual_bar_foo = client.getACL().forPath("/bar/foo"); + assertEquals(actual_bar_foo, READ_CREATE_WRITE); + + // then: also the namespace path inherits ACL from CuratorFramework + List actual_bar = client.getACL().forPath("/bar"); + assertEquals(actual_bar, READ_CREATE); + } finally { + CloseableUtils.closeQuietly(client); + } + } + private void check( CuratorFramework client, CreateBuilderMain builder, String path, byte[] data, boolean expectedSuccess) throws Exception {