| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.apache.hadoop.registry.client.impl; |
| |
| import org.apache.curator.framework.api.CuratorEvent; |
| import org.apache.hadoop.conf.Configuration; |
| import org.apache.hadoop.fs.FileAlreadyExistsException; |
| import org.apache.hadoop.fs.PathIsNotEmptyDirectoryException; |
| import org.apache.hadoop.fs.PathNotFoundException; |
| import org.apache.hadoop.service.ServiceOperations; |
| import org.apache.hadoop.registry.AbstractZKRegistryTest; |
| import org.apache.hadoop.registry.client.impl.zk.CuratorService; |
| import org.apache.hadoop.registry.client.impl.zk.RegistrySecurity; |
| import org.apache.zookeeper.CreateMode; |
| import org.apache.zookeeper.data.ACL; |
| import org.junit.After; |
| import org.junit.Before; |
| import org.junit.Test; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import java.io.IOException; |
| import java.util.List; |
| |
| /** |
| * Test the curator service |
| */ |
| public class TestCuratorService extends AbstractZKRegistryTest { |
| private static final Logger LOG = |
| LoggerFactory.getLogger(TestCuratorService.class); |
| |
| |
| protected CuratorService curatorService; |
| |
| public static final String MISSING = "/missing"; |
| private List<ACL> rootACL; |
| |
| @Before |
| public void startCurator() throws IOException { |
| createCuratorService(); |
| } |
| |
| @After |
| public void stopCurator() { |
| ServiceOperations.stop(curatorService); |
| } |
| |
| /** |
| * Create an instance |
| */ |
| protected void createCuratorService() throws IOException { |
| curatorService = new CuratorService("curatorService"); |
| curatorService.init(createRegistryConfiguration()); |
| curatorService.start(); |
| rootACL = RegistrySecurity.WorldReadWriteACL; |
| curatorService.maybeCreate("", CreateMode.PERSISTENT, rootACL, true); |
| } |
| |
| @Test |
| public void testLs() throws Throwable { |
| curatorService.zkList("/"); |
| } |
| |
| @Test(expected = PathNotFoundException.class) |
| public void testLsNotFound() throws Throwable { |
| List<String> ls = curatorService.zkList(MISSING); |
| } |
| |
| @Test |
| public void testExists() throws Throwable { |
| assertTrue(curatorService.zkPathExists("/")); |
| } |
| |
| @Test |
| public void testExistsMissing() throws Throwable { |
| assertFalse(curatorService.zkPathExists(MISSING)); |
| } |
| |
| @Test |
| public void testVerifyExists() throws Throwable { |
| pathMustExist("/"); |
| } |
| |
| @Test(expected = PathNotFoundException.class) |
| public void testVerifyExistsMissing() throws Throwable { |
| pathMustExist("/file-not-found"); |
| } |
| |
| @Test |
| public void testMkdirs() throws Throwable { |
| mkPath("/p1", CreateMode.PERSISTENT); |
| pathMustExist("/p1"); |
| mkPath("/p1/p2", CreateMode.EPHEMERAL); |
| pathMustExist("/p1/p2"); |
| } |
| |
| private void mkPath(String path, CreateMode mode) throws IOException { |
| curatorService.zkMkPath(path, mode, false, |
| RegistrySecurity.WorldReadWriteACL); |
| } |
| |
| public void pathMustExist(String path) throws IOException { |
| curatorService.zkPathMustExist(path); |
| } |
| |
| @Test(expected = PathNotFoundException.class) |
| public void testMkdirChild() throws Throwable { |
| mkPath("/testMkdirChild/child", CreateMode.PERSISTENT); |
| } |
| |
| @Test |
| public void testMaybeCreate() throws Throwable { |
| assertTrue(curatorService.maybeCreate("/p3", CreateMode.PERSISTENT, |
| RegistrySecurity.WorldReadWriteACL, false)); |
| assertFalse(curatorService.maybeCreate("/p3", CreateMode.PERSISTENT, |
| RegistrySecurity.WorldReadWriteACL, false)); |
| } |
| |
| @Test |
| public void testRM() throws Throwable { |
| mkPath("/rm", CreateMode.PERSISTENT); |
| curatorService.zkDelete("/rm", false, null); |
| verifyNotExists("/rm"); |
| curatorService.zkDelete("/rm", false, null); |
| } |
| |
| @Test |
| public void testRMNonRf() throws Throwable { |
| mkPath("/rm", CreateMode.PERSISTENT); |
| mkPath("/rm/child", CreateMode.PERSISTENT); |
| try { |
| curatorService.zkDelete("/rm", false, null); |
| fail("expected a failure"); |
| } catch (PathIsNotEmptyDirectoryException expected) { |
| |
| } |
| } |
| |
| @Test |
| public void testRMRf() throws Throwable { |
| mkPath("/rm", CreateMode.PERSISTENT); |
| mkPath("/rm/child", CreateMode.PERSISTENT); |
| curatorService.zkDelete("/rm", true, null); |
| verifyNotExists("/rm"); |
| curatorService.zkDelete("/rm", true, null); |
| } |
| |
| |
| @Test |
| public void testBackgroundDelete() throws Throwable { |
| mkPath("/rm", CreateMode.PERSISTENT); |
| mkPath("/rm/child", CreateMode.PERSISTENT); |
| CuratorEventCatcher events = new CuratorEventCatcher(); |
| curatorService.zkDelete("/rm", true, events); |
| CuratorEvent taken = events.take(); |
| LOG.info("took {}", taken); |
| assertEquals(1, events.getCount()); |
| } |
| |
| @Test |
| public void testCreate() throws Throwable { |
| |
| curatorService.zkCreate("/testcreate", |
| CreateMode.PERSISTENT, getTestBuffer(), |
| rootACL |
| ); |
| pathMustExist("/testcreate"); |
| } |
| |
| @Test |
| public void testCreateTwice() throws Throwable { |
| byte[] buffer = getTestBuffer(); |
| curatorService.zkCreate("/testcreatetwice", |
| CreateMode.PERSISTENT, buffer, |
| rootACL); |
| try { |
| curatorService.zkCreate("/testcreatetwice", |
| CreateMode.PERSISTENT, buffer, |
| rootACL); |
| fail(); |
| } catch (FileAlreadyExistsException e) { |
| |
| } |
| } |
| |
| @Test |
| public void testCreateUpdate() throws Throwable { |
| byte[] buffer = getTestBuffer(); |
| curatorService.zkCreate("/testcreateupdate", |
| CreateMode.PERSISTENT, buffer, |
| rootACL |
| ); |
| curatorService.zkUpdate("/testcreateupdate", buffer); |
| } |
| |
| @Test(expected = PathNotFoundException.class) |
| public void testUpdateMissing() throws Throwable { |
| curatorService.zkUpdate("/testupdatemissing", getTestBuffer()); |
| } |
| |
| @Test |
| public void testUpdateDirectory() throws Throwable { |
| mkPath("/testupdatedirectory", CreateMode.PERSISTENT); |
| curatorService.zkUpdate("/testupdatedirectory", getTestBuffer()); |
| } |
| |
| @Test |
| public void testUpdateDirectorywithChild() throws Throwable { |
| mkPath("/testupdatedirectorywithchild", CreateMode.PERSISTENT); |
| mkPath("/testupdatedirectorywithchild/child", CreateMode.PERSISTENT); |
| curatorService.zkUpdate("/testupdatedirectorywithchild", getTestBuffer()); |
| } |
| |
| @Test |
| public void testUseZKServiceForBinding() throws Throwable { |
| CuratorService cs2 = new CuratorService("curator", zookeeper); |
| cs2.init(new Configuration()); |
| cs2.start(); |
| } |
| |
| protected byte[] getTestBuffer() { |
| byte[] buffer = new byte[1]; |
| buffer[0] = '0'; |
| return buffer; |
| } |
| |
| |
| public void verifyNotExists(String path) throws IOException { |
| if (curatorService.zkPathExists(path)) { |
| fail("Path should not exist: " + path); |
| } |
| } |
| } |