aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build.gradle3
-rw-r--r--buildscripts/import-control.xml1
-rw-r--r--metrics/src/main/java/io/opencensus/metrics/Metrics.java78
-rw-r--r--metrics/src/main/java/io/opencensus/metrics/MetricsComponent.java57
-rw-r--r--metrics/src/main/java/io/opencensus/metrics/export/ExportComponent.java60
-rw-r--r--metrics/src/main/java/io/opencensus/metrics/export/MetricProducer.java38
-rw-r--r--metrics/src/main/java/io/opencensus/metrics/export/MetricProducerManager.java88
-rw-r--r--metrics/src/test/java/io/opencensus/metrics/MetricsComponentTest.java34
-rw-r--r--metrics/src/test/java/io/opencensus/metrics/MetricsTest.java65
-rw-r--r--metrics/src/test/java/io/opencensus/metrics/export/ExportComponentTest.java33
-rw-r--r--metrics/src/test/java/io/opencensus/metrics/export/MetricProducerManagerTest.java112
11 files changed, 568 insertions, 1 deletions
diff --git a/build.gradle b/build.gradle
index f7551cad..4fec8e69 100644
--- a/build.gradle
+++ b/build.gradle
@@ -377,7 +377,8 @@ subprojects {
'opencensus-impl-core',
'opencensus-impl-lite',
'opencensus-impl',
- // TODO(songya): add the Export (or Metrics + SpanData) artifact once we agree on its name
+ // TODO(songya): add the Export (or Metrics + SpanData) artifact once we agree on its name.
+ // TODO(bdrutu): Fix dependencies on the api internal subpackage for the metrics artifact.
'opencensus-testing']
}
diff --git a/buildscripts/import-control.xml b/buildscripts/import-control.xml
index 46e4d0ef..607f626c 100644
--- a/buildscripts/import-control.xml
+++ b/buildscripts/import-control.xml
@@ -39,6 +39,7 @@ General guidelines on imports:
<allow pkg="io.opencensus.tags"/>
</subpackage>
<subpackage name="metrics">
+ <allow pkg="io.opencensus.internal"/>
<allow pkg="io.opencensus.common"/>
<allow pkg="io.opencensus.metrics"/>
<allow pkg="io.opencensus.stats"/>
diff --git a/metrics/src/main/java/io/opencensus/metrics/Metrics.java b/metrics/src/main/java/io/opencensus/metrics/Metrics.java
new file mode 100644
index 00000000..e36bc4e1
--- /dev/null
+++ b/metrics/src/main/java/io/opencensus/metrics/Metrics.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2018, OpenCensus 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 io.opencensus.metrics;
+
+import io.opencensus.common.ExperimentalApi;
+import io.opencensus.internal.DefaultVisibilityForTesting;
+import io.opencensus.internal.Provider;
+import io.opencensus.metrics.export.ExportComponent;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.annotation.Nullable;
+
+@ExperimentalApi
+public final class Metrics {
+ private static final Logger logger = Logger.getLogger(Metrics.class.getName());
+ private static final MetricsComponent metricsComponent =
+ loadMetricsComponent(MetricsComponent.class.getClassLoader());
+
+ /**
+ * Returns the global {@link ExportComponent}.
+ *
+ * @return the global {@code ExportComponent}.
+ * @since 0.16
+ */
+ public static ExportComponent getExportComponent() {
+ return metricsComponent.getExportComponent();
+ }
+
+ // Any provider that may be used for MetricsComponent can be added here.
+ @DefaultVisibilityForTesting
+ static MetricsComponent loadMetricsComponent(@Nullable ClassLoader classLoader) {
+ try {
+ // Call Class.forName with literal string name of the class to help shading tools.
+ return Provider.createInstance(
+ Class.forName(
+ "io.opencensus.impl.metrics.MetricsComponentImpl", /*initialize=*/ true, classLoader),
+ MetricsComponent.class);
+ } catch (ClassNotFoundException e) {
+ logger.log(
+ Level.FINE,
+ "Couldn't load full implementation for MetricsComponent, now trying to load lite "
+ + "implementation.",
+ e);
+ }
+ try {
+ // Call Class.forName with literal string name of the class to help shading tools.
+ return Provider.createInstance(
+ Class.forName(
+ "io.opencensus.impllite.metrics.MetricsComponentImplLite",
+ /*initialize=*/ true,
+ classLoader),
+ MetricsComponent.class);
+ } catch (ClassNotFoundException e) {
+ logger.log(
+ Level.FINE,
+ "Couldn't load lite implementation for MetricsComponent, now using default "
+ + "implementation for MetricsComponent.",
+ e);
+ }
+ return MetricsComponent.newNoopMetricsComponent();
+ }
+
+ private Metrics() {}
+}
diff --git a/metrics/src/main/java/io/opencensus/metrics/MetricsComponent.java b/metrics/src/main/java/io/opencensus/metrics/MetricsComponent.java
new file mode 100644
index 00000000..df6d4aec
--- /dev/null
+++ b/metrics/src/main/java/io/opencensus/metrics/MetricsComponent.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2018, OpenCensus 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 io.opencensus.metrics;
+
+import io.opencensus.common.ExperimentalApi;
+import io.opencensus.metrics.export.ExportComponent;
+
+/**
+ * Class that holds the implementation instance for {@link ExportComponent}.
+ *
+ * @since 0.16
+ */
+@ExperimentalApi
+public abstract class MetricsComponent {
+
+ /**
+ * Returns the {@link ExportComponent} with the provided implementation. If no implementation is
+ * provided then no-op implementations will be used.
+ *
+ * @return the {@link ExportComponent} implementation.
+ * @since 0.16
+ */
+ public abstract ExportComponent getExportComponent();
+
+ /**
+ * Returns an instance that contains no-op implementations for all the instances.
+ *
+ * @return an instance that contains no-op implementations for all the instances.
+ */
+ static MetricsComponent newNoopMetricsComponent() {
+ return new NoopMetricsComponent();
+ }
+
+ private static final class NoopMetricsComponent extends MetricsComponent {
+ private static final ExportComponent EXPORT_COMPONENT =
+ ExportComponent.newNoopExportComponent();
+
+ @Override
+ public ExportComponent getExportComponent() {
+ return EXPORT_COMPONENT;
+ }
+ }
+}
diff --git a/metrics/src/main/java/io/opencensus/metrics/export/ExportComponent.java b/metrics/src/main/java/io/opencensus/metrics/export/ExportComponent.java
new file mode 100644
index 00000000..f1511543
--- /dev/null
+++ b/metrics/src/main/java/io/opencensus/metrics/export/ExportComponent.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2018, OpenCensus 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 io.opencensus.metrics.export;
+
+import io.opencensus.common.ExperimentalApi;
+
+/**
+ * Class that holds the implementation instance for {@link MetricProducerManager}.
+ *
+ * <p>Unless otherwise noted all methods (on component) results are cacheable.
+ *
+ * @since 0.16
+ */
+@ExperimentalApi
+public abstract class ExportComponent {
+ /**
+ * Returns the no-op implementation of the {@code ExportComponent}.
+ *
+ * @return the no-op implementation of the {@code ExportComponent}.
+ * @since 0.16
+ */
+ public static ExportComponent newNoopExportComponent() {
+ return new NoopExportComponent();
+ }
+
+ /**
+ * Returns the global {@link MetricProducerManager} which can be used to register handlers to
+ * export all the recorded metrics.
+ *
+ * @return the implementation of the {@code MetricExporter} or no-op if no implementation linked
+ * in the binary.
+ * @since 0.16
+ */
+ public abstract MetricProducerManager getMetricProducerManager();
+
+ private static final class NoopExportComponent extends ExportComponent {
+
+ private static final MetricProducerManager METRIC_PRODUCER_MANAGER =
+ new MetricProducerManager();
+
+ @Override
+ public MetricProducerManager getMetricProducerManager() {
+ return METRIC_PRODUCER_MANAGER;
+ }
+ }
+}
diff --git a/metrics/src/main/java/io/opencensus/metrics/export/MetricProducer.java b/metrics/src/main/java/io/opencensus/metrics/export/MetricProducer.java
new file mode 100644
index 00000000..a6658ac1
--- /dev/null
+++ b/metrics/src/main/java/io/opencensus/metrics/export/MetricProducer.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2018, OpenCensus 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 io.opencensus.metrics.export;
+
+import io.opencensus.common.ExperimentalApi;
+import io.opencensus.metrics.Metric;
+import java.util.Collection;
+
+/**
+ * A {@link Metric} producer that can be registered for exporting using {@link
+ * MetricProducerManager}.
+ *
+ * <p>All implementation MUST be thread-safe.
+ */
+@ExperimentalApi
+public abstract class MetricProducer {
+
+ /**
+ * Returns a collection of produced {@link Metric}s to be exported.
+ *
+ * @return a collection of produced {@link Metric}s to be exported.
+ */
+ public abstract Collection<Metric> getMetrics();
+}
diff --git a/metrics/src/main/java/io/opencensus/metrics/export/MetricProducerManager.java b/metrics/src/main/java/io/opencensus/metrics/export/MetricProducerManager.java
new file mode 100644
index 00000000..ae744635
--- /dev/null
+++ b/metrics/src/main/java/io/opencensus/metrics/export/MetricProducerManager.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2018, OpenCensus 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 io.opencensus.metrics.export;
+
+import io.opencensus.common.ExperimentalApi;
+import io.opencensus.internal.Utils;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.Set;
+import javax.annotation.concurrent.ThreadSafe;
+
+/**
+ * Keeps a set of {@link MetricProducer} that is used by exporters to determine the metrics that
+ * need to be exported.
+ *
+ * @since 0.16
+ */
+@ExperimentalApi
+@ThreadSafe
+public final class MetricProducerManager {
+ private volatile Set<MetricProducer> metricProducers =
+ Collections.unmodifiableSet(new LinkedHashSet<MetricProducer>());
+
+ /**
+ * Adds the {@link MetricProducer} to the manager if it is not already present.
+ *
+ * @param metricProducer the {@code MetricProducer} to be added to the manager.
+ * @since 0.16
+ */
+ public synchronized void add(MetricProducer metricProducer) {
+ Utils.checkNotNull(metricProducer, "metricProducer");
+ // Updating the set of MetricProducers happens under a lock to avoid multiple add or remove
+ // operations to happen in the same time.
+ Set<MetricProducer> newMetricProducers = new LinkedHashSet<MetricProducer>(metricProducers);
+ if (!newMetricProducers.add(metricProducer)) {
+ // The element already present, no need to update the current set of MetricProducers.
+ return;
+ }
+ metricProducers = Collections.unmodifiableSet(newMetricProducers);
+ }
+
+ /**
+ * Removes the {@link MetricProducer} to the manager if it is present.
+ *
+ * @param metricProducer the {@code MetricProducer} to be removed from the manager.
+ */
+ public synchronized void remove(MetricProducer metricProducer) {
+ Utils.checkNotNull(metricProducer, "metricProducer");
+ // Updating the set of MetricProducers happens under a lock to avoid multiple add or remove
+ // operations to happen in the same time.
+ Set<MetricProducer> newMetricProducers = new LinkedHashSet<MetricProducer>(metricProducers);
+ if (!newMetricProducers.remove(metricProducer)) {
+ // The element not present, no need to update the current set of MetricProducers.
+ return;
+ }
+ metricProducers = Collections.unmodifiableSet(newMetricProducers);
+ }
+
+ /**
+ * Returns all registered {@link MetricProducer}s that should be exported.
+ *
+ * <p>This method should be used by any metrics exporter that automatically exports data for
+ * {@code MetricProducer} registered with the {@code MetricProducerManager}.
+ *
+ * @return all registered {@code MetricProducer}s that should be exported.
+ */
+ public Set<MetricProducer> getAllMetricProducer() {
+ return metricProducers;
+ }
+
+ // Package protected to allow us to possibly change this to an abstract class in the future. This
+ // ensures that nobody can create an instance of this class except ExportComponent.
+ MetricProducerManager() {}
+}
diff --git a/metrics/src/test/java/io/opencensus/metrics/MetricsComponentTest.java b/metrics/src/test/java/io/opencensus/metrics/MetricsComponentTest.java
new file mode 100644
index 00000000..0a3ceb14
--- /dev/null
+++ b/metrics/src/test/java/io/opencensus/metrics/MetricsComponentTest.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2018, OpenCensus 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 io.opencensus.metrics;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import io.opencensus.metrics.export.ExportComponent;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Unit tests for {@link MetricsComponent}. */
+@RunWith(JUnit4.class)
+public class MetricsComponentTest {
+ @Test
+ public void defaultExportComponent() {
+ assertThat(MetricsComponent.newNoopMetricsComponent().getExportComponent())
+ .isInstanceOf(ExportComponent.newNoopExportComponent().getClass());
+ }
+}
diff --git a/metrics/src/test/java/io/opencensus/metrics/MetricsTest.java b/metrics/src/test/java/io/opencensus/metrics/MetricsTest.java
new file mode 100644
index 00000000..9a56f257
--- /dev/null
+++ b/metrics/src/test/java/io/opencensus/metrics/MetricsTest.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2018, OpenCensus 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 io.opencensus.metrics;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import io.opencensus.metrics.export.ExportComponent;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Unit tests for {@link Metrics}. */
+@RunWith(JUnit4.class)
+public class MetricsTest {
+ @Rule public ExpectedException thrown = ExpectedException.none();
+
+ @Test
+ public void loadMetricsComponent_UsesProvidedClassLoader() {
+ final RuntimeException toThrow = new RuntimeException("UseClassLoader");
+ thrown.expect(RuntimeException.class);
+ thrown.expectMessage("UseClassLoader");
+ Metrics.loadMetricsComponent(
+ new ClassLoader() {
+ @Override
+ public Class<?> loadClass(String name) {
+ throw toThrow;
+ }
+ });
+ }
+
+ @Test
+ public void loadMetricsComponent_IgnoresMissingClasses() {
+ ClassLoader classLoader =
+ new ClassLoader() {
+ @Override
+ public Class<?> loadClass(String name) throws ClassNotFoundException {
+ throw new ClassNotFoundException();
+ }
+ };
+ assertThat(Metrics.loadMetricsComponent(classLoader).getClass().getName())
+ .isEqualTo("io.opencensus.metrics.MetricsComponent$NoopMetricsComponent");
+ }
+
+ @Test
+ public void defaultExportComponent() {
+ assertThat(Metrics.getExportComponent())
+ .isInstanceOf(ExportComponent.newNoopExportComponent().getClass());
+ }
+}
diff --git a/metrics/src/test/java/io/opencensus/metrics/export/ExportComponentTest.java b/metrics/src/test/java/io/opencensus/metrics/export/ExportComponentTest.java
new file mode 100644
index 00000000..15c6e883
--- /dev/null
+++ b/metrics/src/test/java/io/opencensus/metrics/export/ExportComponentTest.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2018, OpenCensus 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 io.opencensus.metrics.export;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Unit tests for {@link ExportComponent}. */
+@RunWith(JUnit4.class)
+public class ExportComponentTest {
+ @Test
+ public void defaultMetricExporter() {
+ assertThat(ExportComponent.newNoopExportComponent().getMetricProducerManager())
+ .isInstanceOf(MetricProducerManager.class);
+ }
+}
diff --git a/metrics/src/test/java/io/opencensus/metrics/export/MetricProducerManagerTest.java b/metrics/src/test/java/io/opencensus/metrics/export/MetricProducerManagerTest.java
new file mode 100644
index 00000000..2d4e7c9c
--- /dev/null
+++ b/metrics/src/test/java/io/opencensus/metrics/export/MetricProducerManagerTest.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2018, OpenCensus 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 io.opencensus.metrics.export;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import java.util.Set;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/** Unit tests for {@link MetricProducerManager}. */
+@RunWith(JUnit4.class)
+public class MetricProducerManagerTest {
+ private final MetricProducerManager metricProducerManager = new MetricProducerManager();
+ @Mock private MetricProducer metricProducer;
+ @Mock private MetricProducer metricProducerOther;
+
+ @Rule public final ExpectedException thrown = ExpectedException.none();
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ }
+
+ @Test
+ public void add_DisallowsNull() {
+ thrown.expect(NullPointerException.class);
+ metricProducerManager.add(null);
+ }
+
+ @Test
+ public void add() {
+ metricProducerManager.add(metricProducer);
+ assertThat(metricProducerManager.getAllMetricProducer()).containsExactly(metricProducer);
+ }
+
+ @Test
+ public void add_DuplicateElement() {
+ metricProducerManager.add(metricProducer);
+ Set<MetricProducer> metricProducerSet = metricProducerManager.getAllMetricProducer();
+ assertThat(metricProducerSet).containsExactly(metricProducer);
+ metricProducerManager.add(metricProducer);
+ // Returns the same object.
+ assertThat(metricProducerManager.getAllMetricProducer()).isSameAs(metricProducerSet);
+ }
+
+ @Test
+ public void add_MultipleElements() {
+ metricProducerManager.add(metricProducer);
+ Set<MetricProducer> metricProducerSet = metricProducerManager.getAllMetricProducer();
+ assertThat(metricProducerSet).containsExactly(metricProducer);
+ metricProducerManager.add(metricProducerOther);
+ // Returns the same object.
+ assertThat(metricProducerManager.getAllMetricProducer())
+ .containsExactly(metricProducer, metricProducerOther);
+ }
+
+ @Test
+ public void addAndRemove() {
+ metricProducerManager.add(metricProducer);
+ assertThat(metricProducerManager.getAllMetricProducer()).containsExactly(metricProducer);
+ metricProducerManager.remove(metricProducer);
+ assertThat(metricProducerManager.getAllMetricProducer()).isEmpty();
+ }
+
+ @Test
+ public void remove_DisallowsNull() {
+ thrown.expect(NullPointerException.class);
+ metricProducerManager.remove(null);
+ }
+
+ @Test
+ public void remove_FromEmpty() {
+ metricProducerManager.remove(metricProducer);
+ assertThat(metricProducerManager.getAllMetricProducer()).isEmpty();
+ }
+
+ @Test
+ public void remove_NotPresent() {
+ metricProducerManager.add(metricProducer);
+ Set<MetricProducer> metricProducerSet = metricProducerManager.getAllMetricProducer();
+ assertThat(metricProducerSet).containsExactly(metricProducer);
+ metricProducerManager.remove(metricProducerOther);
+ // Returns the same object.
+ assertThat(metricProducerManager.getAllMetricProducer()).isSameAs(metricProducerSet);
+ }
+
+ @Test
+ public void getAllMetricProducer_empty() {
+ assertThat(metricProducerManager.getAllMetricProducer()).isEmpty();
+ }
+}