+ * 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.zookeeper.test; + +import static org.junit.Assert.assertEquals; +import org.apache.zookeeper.Quotas; +import org.junit.Test; + +public class QuotasTest { + + @Test + public void testStatPath() { + assertEquals("/zookeeper/quota/foo/zookeeper_stats", Quotas.statPath("/foo")); + assertEquals("/zookeeper/quota/bar/zookeeper_stats", Quotas.statPath("/bar")); + } + + @Test + public void testLimitPath() { + assertEquals("/zookeeper/quota/foo/zookeeper_limits", Quotas.limitPath("/foo")); + assertEquals("/zookeeper/quota/bar/zookeeper_limits", Quotas.limitPath("/bar")); + } + + @Test + public void testQuotaPathPath() { + assertEquals("/zookeeper/quota/bar", Quotas.quotaPath("/bar")); + assertEquals("/zookeeper/quota/foo", Quotas.quotaPath("/foo")); + } + + @Test + public void testTrimQuotaPath() { + assertEquals("/foo", Quotas.trimQuotaPath("/zookeeper/quota/foo")); + assertEquals("/bar", Quotas.trimQuotaPath("/zookeeper/quota/bar")); + } +} diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/StatsTrackTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/StatsTrackTest.java new file mode 100644 index 00000000000..978e629dae2 --- /dev/null +++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/StatsTrackTest.java @@ -0,0 +1,135 @@ +/** + * 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.zookeeper.test;
+
+import org.apache.zookeeper.StatsTrack;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class StatsTrackTest {
+
+ public static class OldStatsTrack {
+ private int count;
+ private long bytes;
+ private String countStr = "count";
+ private String byteStr = "bytes";
+
+ /**
+ * a default constructor for
+ * stats
+ */
+ public OldStatsTrack() {
+ this(null);
+ }
+ /**
+ * the stat string should be of the form count=int,bytes=long
+ * if stats is called with null the count and bytes are initialized
+ * to -1.
+ * @param stats the stat string to be intialized with
+ */
+ public OldStatsTrack(String stats) {
+ if (stats == null) {
+ stats = "count=-1,bytes=-1";
+ }
+ String[] split = stats.split(",");
+ if (split.length != 2) {
+ throw new IllegalArgumentException("invalid string " + stats);
+ }
+ count = Integer.parseInt(split[0].split("=")[1]);
+ bytes = Long.parseLong(split[1].split("=")[1]);
+ }
+
+
+ /**
+ * get the count of nodes allowed as part of quota
+ *
+ * @return the count as part of this string
+ */
+ public int getCount() {
+ return this.count;
+ }
+
+ /**
+ * set the count for this stat tracker.
+ *
+ * @param count
+ * the count to set with
+ */
+ public void setCount(int count) {
+ this.count = count;
+ }
+
+ /**
+ * get the count of bytes allowed as part of quota
+ *
+ * @return the bytes as part of this string
+ */
+ public long getBytes() {
+ return this.bytes;
+ }
+
+ /**
+ * set teh bytes for this stat tracker.
+ *
+ * @param bytes
+ * the bytes to set with
+ */
+ public void setBytes(long bytes) {
+ this.bytes = bytes;
+ }
+
+ @Override
+ /*
+ * returns the string that maps to this stat tracking.
+ */
+ public String toString() {
+ return countStr + "=" + count + "," + byteStr + "=" + bytes;
+ }
+ }
+
+ @Test
+ public void testBackwardCompatibility() {
+ StatsTrack quota = new StatsTrack();
+ quota.setCount(4);
+ quota.setCountHardLimit(4);
+ quota.setBytes(9L);
+ quota.setByteHardLimit(15L);
+ Assert.assertEquals("count=4,bytes=9=;byteHardLimit=15;countHardLimit=4", quota.toString());
+
+ OldStatsTrack ost = new OldStatsTrack(quota.toString());
+ Assert.assertTrue("bytes are set", ost.getBytes() == 9L);
+ Assert.assertTrue("num count is set", ost.getCount() == 4);
+ Assert.assertEquals("count=4,bytes=9", ost.toString());
+ }
+
+ @Test
+ public void testUpwardCompatibility() {
+ OldStatsTrack ost = new OldStatsTrack(null);
+ ost.setCount(2);
+ ost.setBytes(5);
+ Assert.assertEquals("count=2,bytes=5", ost.toString());
+
+ StatsTrack st = new StatsTrack(ost.toString());
+ Assert.assertEquals("count=2,bytes=5", st.toString());
+ Assert.assertEquals(5, st.getBytes());
+ Assert.assertEquals(2, st.getCount());
+ Assert.assertEquals(-1, st.getByteHardLimit());
+ Assert.assertEquals(-1, st.getCountHardLimit());
+ }
+}
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/ZooKeeperQuotaTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ZooKeeperQuotaTest.java
index 2eb2c6caabe..f8c724d2d81 100644
--- a/zookeeper-server/src/test/java/org/apache/zookeeper/test/ZooKeeperQuotaTest.java
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ZooKeeperQuotaTest.java
@@ -21,24 +21,44 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import java.io.IOException;
+import java.util.List;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.KeeperException.ByteQuotaExceededException;
+import org.apache.zookeeper.KeeperException.CountQuotaExceededException;
import org.apache.zookeeper.Quotas;
import org.apache.zookeeper.StatsTrack;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.cli.DelQuotaCommand;
+import org.apache.zookeeper.cli.ListQuotaCommand;
import org.apache.zookeeper.cli.MalformedPathException;
import org.apache.zookeeper.cli.SetQuotaCommand;
import org.apache.zookeeper.data.Stat;
import org.apache.zookeeper.server.ZooKeeperServer;
+import org.apache.zookeeper.test.StatsTrackTest.OldStatsTrack;
import org.junit.Test;
public class ZooKeeperQuotaTest extends ClientBase {
+ private ZooKeeper zk = null;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ zk = createClient();
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ super.tearDown();
+ zk.close();
+ }
@Test
public void testQuota() throws Exception {
- final ZooKeeper zk = createClient();
+
final String path = "/a/b/v";
// making sure setdata works on /
zk.setData("/", "some".getBytes(), -1);
@@ -49,18 +69,33 @@ public void testQuota() throws Exception {
zk.create("/a/b/v", "some".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
zk.create("/a/b/v/d", "some".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
- SetQuotaCommand.createQuota(zk, path, 5L, 10);
+
+ StatsTrack quota = new StatsTrack();
+ quota.setCount(4);
+ quota.setCountHardLimit(4);
+ quota.setBytes(9L);
+ quota.setByteHardLimit(15L);
+ SetQuotaCommand.createQuota(zk, path, quota);
// see if its set
- String absolutePath = Quotas.quotaZookeeper + path + "/" + Quotas.limitNode;
+ String absolutePath = Quotas.limitPath(path);
byte[] data = zk.getData(absolutePath, false, new Stat());
- StatsTrack st = new StatsTrack(new String(data));
- assertTrue("bytes are set", st.getBytes() == 5L);
- assertTrue("num count is set", st.getCount() == 10);
+ StatsTrack st = new StatsTrack(data);
+ assertTrue("bytes are set", st.getBytes() == 9L);
+ assertTrue("byte hard limit is set",
+ st.getByteHardLimit() == 15L);
+ assertTrue("num count is set", st.getCount() == 4);
+ assertTrue("count hard limit is set",
+ st.getCountHardLimit() == 4);
+
+ // check quota node readable by old servers
+ OldStatsTrack ost = new OldStatsTrack(new String(data));
+ assertTrue("bytes are set", ost.getBytes() == 9L);
+ assertTrue("num count is set", ost.getCount() == 4);
- String statPath = Quotas.quotaZookeeper + path + "/" + Quotas.statNode;
+ String statPath = Quotas.statPath(path);
byte[] qdata = zk.getData(statPath, false, new Stat());
- StatsTrack qst = new StatsTrack(new String(qdata));
+ StatsTrack qst = new StatsTrack(qdata);
assertTrue("bytes are set", qst.getBytes() == 8L);
assertTrue("count is set", qst.getCount() == 2);
@@ -76,7 +111,6 @@ public void testQuota() throws Exception {
@Test
public void testSetQuota() throws IOException, InterruptedException, KeeperException, MalformedPathException {
- final ZooKeeper zk = createClient();
String path = "/c1";
String nodeData = "foo";
@@ -84,18 +118,21 @@ public void testSetQuota() throws IOException, InterruptedException, KeeperExcep
int count = 10;
long bytes = 5L;
- SetQuotaCommand.createQuota(zk, path, bytes, count);
+ StatsTrack quota = new StatsTrack();
+ quota.setCount(count);
+ quota.setBytes(bytes);
+ SetQuotaCommand.createQuota(zk, path, quota);
//check the limit
- String absoluteLimitPath = Quotas.quotaZookeeper + path + "/" + Quotas.limitNode;
+ String absoluteLimitPath = Quotas.limitPath(path);
byte[] data = zk.getData(absoluteLimitPath, false, null);
- StatsTrack st = new StatsTrack(new String(data));
+ StatsTrack st = new StatsTrack(data);
assertEquals(bytes, st.getBytes());
assertEquals(count, st.getCount());
//check the stats
- String absoluteStatPath = Quotas.quotaZookeeper + path + "/" + Quotas.statNode;
+ String absoluteStatPath = Quotas.statPath(path);
data = zk.getData(absoluteStatPath, false, null);
- st = new StatsTrack(new String(data));
+ st = new StatsTrack(data);
assertEquals(nodeData.length(), st.getBytes());
assertEquals(1, st.getCount());
@@ -104,9 +141,9 @@ public void testSetQuota() throws IOException, InterruptedException, KeeperExcep
String nodeData2 = "bar";
zk.create(path2, nodeData2.getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
- absoluteStatPath = Quotas.quotaZookeeper + path + "/" + Quotas.statNode;
+ absoluteStatPath = Quotas.statPath(path);
data = zk.getData(absoluteStatPath, false, null);
- st = new StatsTrack(new String(data));
+ st = new StatsTrack(data);
//check the stats
assertEquals(nodeData.length() + nodeData2.length(), st.getBytes());
assertEquals(2, st.getCount());
@@ -114,7 +151,6 @@ public void testSetQuota() throws IOException, InterruptedException, KeeperExcep
@Test
public void testSetQuotaWhenSetQuotaOnParentOrChildPath() throws IOException, InterruptedException, KeeperException, MalformedPathException {
- final ZooKeeper zk = createClient();
zk.create("/c1", "some".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
zk.create("/c1/c2", "some".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
@@ -123,19 +159,344 @@ public void testSetQuotaWhenSetQuotaOnParentOrChildPath() throws IOException, In
zk.create("/c1/c2/c3/c4/c5", "some".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
//set the quota on the path:/c1/c2/c3
- SetQuotaCommand.createQuota(zk, "/c1/c2/c3", 5L, 10);
+ StatsTrack quota = new StatsTrack();
+ quota.setCount(5);
+ quota.setBytes(10);
+ SetQuotaCommand.createQuota(zk, "/c1/c2/c3", quota);
try {
- SetQuotaCommand.createQuota(zk, "/c1", 5L, 10);
+ SetQuotaCommand.createQuota(zk, "/c1", quota);
+ fail("should not set quota when child has a quota");
} catch (IllegalArgumentException e) {
assertEquals("/c1 has a child /c1/c2/c3 which has a quota", e.getMessage());
}
try {
- SetQuotaCommand.createQuota(zk, "/c1/c2/c3/c4/c5", 5L, 10);
+ SetQuotaCommand.createQuota(zk, "/c1/c2/c3/c4/c5", quota);
+ fail("should not set quota when parent has a quota");
} catch (IllegalArgumentException e) {
assertEquals("/c1/c2/c3/c4/c5 has a parent /c1/c2/c3 which has a quota", e.getMessage());
}
}
-}
+ @Test
+ public void testSetQuotaWhenExceedBytesSoftQuota() throws Exception {
+
+ final String path = "/c1";
+ zk.create(path, "data".getBytes(), Ids.OPEN_ACL_UNSAFE,
+ CreateMode.PERSISTENT);
+ StatsTrack st = new StatsTrack();
+ st.setBytes(5L);
+ SetQuotaCommand.createQuota(zk, path, st);
+
+ zk.setData(path, "12345".getBytes(), -1);
+
+ try {
+ zk.setData(path, "123456".getBytes(), -1);
+ } catch (Exception e) {
+ fail("should set data which exceeds the soft byte quota");
+ }
+ }
+
+ @Test
+ public void testSetQuotaWhenExceedBytesHardQuota() throws Exception {
+
+ final String path = "/c1";
+ zk.create(path, "12345".getBytes(), Ids.OPEN_ACL_UNSAFE,
+ CreateMode.PERSISTENT);
+ StatsTrack st = new StatsTrack();
+ st.setByteHardLimit(5L);
+ SetQuotaCommand.createQuota(zk, path, st);
+
+ try {
+ zk.setData(path, "123456".getBytes(), -1);
+ fail("should not set data which exceeds the hard byte quota");
+ } catch (ByteQuotaExceededException e) {
+ //expected
+ }
+ }
+
+ @Test
+ public void testSetQuotaWhenExceedBytesHardQuotaExtend() throws Exception {
+
+ String path = "/c0";
+ zk.create(path, "1".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+ int bytes = 100;
+ StatsTrack st = new StatsTrack();
+ st.setByteHardLimit(bytes);
+ SetQuotaCommand.createQuota(zk, path, st);
+ StringBuilder sb = new StringBuilder(path);
+ for (int i = 1; i <= bytes; i++) {
+ sb.append("/c" + i);
+ if (i == bytes) {
+ try {
+ zk.create(sb.toString(), "1".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+ fail("should not set quota when exceeds hard bytes quota");
+ } catch (ByteQuotaExceededException e) {
+ //expected
+ }
+ } else {
+ zk.create(sb.toString(), "1".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+ }
+ }
+ }
+
+ @Test
+ public void testSetQuotaWhenSetQuotaLessThanExistBytes() throws Exception {
+
+ String path = "/c0";
+ zk.create(path, "123456789".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+ int bytes = 5;
+ StatsTrack st = new StatsTrack();
+ st.setByteHardLimit(bytes);
+ SetQuotaCommand.createQuota(zk, path, st);
+ try {
+ zk.setData(path, "123456".getBytes(), -1);
+ fail("should not set quota when exceeds hard bytes quota");
+ } catch (ByteQuotaExceededException e) {
+ //expected
+ }
+ }
+
+ @Test
+ public void testSetQuotaWhenSetChildDataExceedBytesQuota() throws Exception {
+
+ final String path = "/test/quota";
+ zk.create("/test", null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+ zk.create("/test/quota", "01234".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+ zk.create("/test/quota/data", "56789".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+
+ StatsTrack quota = new StatsTrack();
+ quota.setByteHardLimit(10);
+ SetQuotaCommand.createQuota(zk, path, quota);
+ try {
+ zk.setData("/test/quota/data", "567891".getBytes(), -1);
+ fail("should not set data when exceed hard byte quota");
+ } catch (ByteQuotaExceededException e) {
+ //expected
+ }
+ }
+
+ @Test
+ public void testSetQuotaWhenCreateNodeExceedBytesQuota() throws Exception {
+
+ final String path = "/test/quota";
+ zk.create("/test", null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+ zk.create("/test/quota", "01234".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+
+ StatsTrack quota = new StatsTrack();
+ quota.setByteHardLimit(10);
+ SetQuotaCommand.createQuota(zk, path, quota);
+ try {
+ zk.create("/test/quota/data", "567891".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+ fail("should not set data when exceed hard byte quota");
+ } catch (ByteQuotaExceededException e) {
+ //expected
+ }
+ }
+
+ @Test
+ public void testSetQuotaWhenExceedCountSoftQuota() throws Exception {
+
+ final String path = "/c1";
+ zk.create(path, "data".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+ int count = 2;
+ StatsTrack st = new StatsTrack();
+ st.setCount(count);
+ SetQuotaCommand.createQuota(zk, path, st);
+ zk.create(path + "/c2", "data".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+
+ try {
+ zk.create(path + "/c2" + "/c3", "data".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+ } catch (CountQuotaExceededException e) {
+ fail("should set quota when exceeds soft count quota");
+ }
+ }
+
+ @Test
+ public void testSetQuotaWhenExceedCountHardQuota() throws Exception {
+
+ final String path = "/c1";
+ zk.create(path, "data".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+ int count = 2;
+ StatsTrack st = new StatsTrack();
+ st.setCountHardLimit(count);
+ SetQuotaCommand.createQuota(zk, path, st);
+ zk.create(path + "/c2", "data".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+
+ try {
+ zk.create(path + "/c2" + "/c3", "data".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+ fail("should not set quota when exceeds hard count quota");
+ } catch (CountQuotaExceededException e) {
+ //expected
+ }
+ }
+
+ @Test
+ public void testSetQuotaWhenExceedCountHardQuotaExtend() throws Exception {
+
+ String path = "/c0";
+ zk.create(path, "data".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+ int count = 100;
+ StatsTrack st = new StatsTrack();
+ st.setCountHardLimit(count);
+ SetQuotaCommand.createQuota(zk, path, st);
+ StringBuilder sb = new StringBuilder(path);
+ for (int i = 1; i <= count; i++) {
+ sb.append("/c" + i);
+ if (i == count) {
+ try {
+ zk.create(sb.toString() , "data".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+ fail("should not set quota when exceeds hard count quota");
+ } catch (CountQuotaExceededException e) {
+ //expected
+ }
+ } else {
+ zk.create(sb.toString(), "data".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+ }
+ }
+ }
+
+ @Test
+ public void testSetQuotaWhenSetQuotaLessThanExistCount() throws Exception {
+
+ String path = "/c0";
+ zk.create(path, "1".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+ zk.create(path + "/c1", "1".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+ zk.create(path + "/c2", "1".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+ int count = 2;
+ StatsTrack st = new StatsTrack();
+ st.setCountHardLimit(count);
+ SetQuotaCommand.createQuota(zk, path, st);
+ try {
+ zk.create(path + "/c3", "1".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+ fail("should not set quota when exceeds hard count quota");
+ } catch (CountQuotaExceededException e) {
+ //expected
+ }
+ }
+
+ @Test
+ public void testSetQuotaWhenExceedBothBytesAndCountHardQuota() throws Exception {
+
+ final String path = "/c1";
+ zk.create(path, "12345".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+ StatsTrack st = new StatsTrack();
+ st.setByteHardLimit(5L);
+ st.setCountHardLimit(1);
+ SetQuotaCommand.createQuota(zk, path, st);
+
+ try {
+ zk.create(path + "/c2", "1".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+ fail("should give priority to CountQuotaExceededException when both meets the count and bytes quota");
+ } catch (CountQuotaExceededException e) {
+ //expected
+ }
+ }
+
+ @Test
+ public void testDeleteBytesQuota() throws Exception {
+
+ final String path = "/c1";
+ zk.create(path, "12345".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+ StatsTrack st = new StatsTrack();
+ st.setByteHardLimit(5L);
+ SetQuotaCommand.createQuota(zk, path, st);
+
+ try {
+ zk.setData(path, "123456".getBytes(), -1);
+ fail("should not set data which exceeds the hard byte quota");
+ } catch (ByteQuotaExceededException e) {
+ //expected
+ }
+
+ //delete the Byte Hard Quota
+ st = new StatsTrack();
+ st.setByteHardLimit(1);
+ DelQuotaCommand.delQuota(zk, path, st);
+
+ zk.setData(path, "123456".getBytes(), -1);
+ }
+
+ @Test
+ public void testDeleteCountQuota() throws Exception {
+
+ final String path = "/c1";
+ zk.create(path, "data".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+ int count = 2;
+ StatsTrack st = new StatsTrack();
+ st.setCountHardLimit(count);
+ SetQuotaCommand.createQuota(zk, path, st);
+ zk.create(path + "/c2", "data".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+
+ try {
+ zk.create(path + "/c2" + "/c3", "data".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+ fail("should not set quota when exceeds hard count quota");
+ } catch (CountQuotaExceededException e) {
+ //expected
+ }
+
+ //delete the Count Hard Quota
+ st = new StatsTrack();
+ st.setCountHardLimit(1);
+ DelQuotaCommand.delQuota(zk, path, st);
+
+ zk.create(path + "/c2" + "/c3", "data".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+ }
+
+ @Test
+ public void testListQuota() throws Exception {
+
+ final String path = "/c1";
+ zk.create(path, "12345".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+ StatsTrack st = new StatsTrack();
+ long bytes = 5L;
+ int count = 10;
+ long byteHardLimit = 6L;
+ int countHardLimit = 12;
+ st.setBytes(bytes);
+ st.setCount(count);
+ st.setByteHardLimit(byteHardLimit);
+ st.setCountHardLimit(countHardLimit);
+ SetQuotaCommand.createQuota(zk, path, st);
+
+ List