/** * Copyright 2015-2016 The OpenZipkin Authors * * Licensed 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 zipkin.collector.zookeeper; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestName; import zipkin.Span; import zipkin.collector.Collector; import zipkin.internal.CallbackCaptor; import zipkin.storage.InMemoryStorage; import static java.util.Arrays.asList; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.withinPercentage; import static zipkin.TestObjects.LOTS_OF_SPANS; public class ZooKeeperCollectorSamplerTest { @Rule public ZooKeeperRule zookeeper = new ZooKeeperRule(); @Rule public TestName testName = new TestName(); Collector collector; InMemoryStorage storage = new InMemoryStorage(); ZooKeeperCollectorSampler sampler; @Before public void clear() throws Exception { if (sampler != null) { sampler.close(); } sampler = new ZooKeeperCollectorSampler.Builder() .basePath(basePath()) .updateFrequency(2) // 1 is least, but larger in case the build is slow and 1 causes flakes .build(zookeeper.client); collector = Collector.builder(getClass()) .sampler(sampler) .storage(storage).build(); } @Test public void sampleRateReadFromZookeeper() throws Exception { // Simulates an existing sample rate, set from connectString zookeeper.create(basePath() + "/sampleRate", "0.9"); accept(LOTS_OF_SPANS); assertThat(storage.acceptedSpanCount()) .isCloseTo((int) (LOTS_OF_SPANS.length * 0.9), withinPercentage(3)); } @Test public void exportsStoreRateToZookeeperOnInterval() throws Exception { accept(LOTS_OF_SPANS); // Until the update interval, we'll see a store rate of zero assertThat(sampler.storeRate.get()).isZero(); // Await until update interval passes (2 seconds + fudge) Thread.sleep(2100); // let the update interval pass // since update frequency is every 2 seconds, the rate exported to ZK will be the amount * 30 assertThat(sampler.storeRate.get()) .isEqualTo(LOTS_OF_SPANS.length * 30); assertThat(storeRateFromZooKeeper(sampler.groupMember)) .isEqualTo(sampler.storeRate.get()); } /** Blocks until the callback completes to allow read-your-writes consistency during tests. */ void accept(Span... spans) { CallbackCaptor<Void> captor = new CallbackCaptor<>(); collector.accept(asList(spans), captor); captor.get(); // block on result } int storeRateFromZooKeeper(String id) throws Exception { byte[] data = zookeeper.client.getData().forPath(basePath() + "/storeRates/" + id); return data.length == 0 ? 0 : Integer.parseInt(new String(data)); } private String basePath() { return "/" + testName.getMethodName(); } }