diff --git a/adapters-api/src/main/java/io/nosqlbench/adapters/api/util/TagFilter.java b/nb-api/src/main/java/io/nosqlbench/adapters/api/util/TagFilter.java similarity index 96% rename from adapters-api/src/main/java/io/nosqlbench/adapters/api/util/TagFilter.java rename to nb-api/src/main/java/io/nosqlbench/adapters/api/util/TagFilter.java index 60fd57d64..17dfebf41 100644 --- a/adapters-api/src/main/java/io/nosqlbench/adapters/api/util/TagFilter.java +++ b/nb-api/src/main/java/io/nosqlbench/adapters/api/util/TagFilter.java @@ -17,11 +17,9 @@ package io.nosqlbench.adapters.api.util; import io.nosqlbench.api.engine.util.Tagged; +import io.nosqlbench.api.labels.NBLabeledElement; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.function.BiFunction; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -107,6 +105,12 @@ public class TagFilter { .collect(Collectors.toList()); } + public List filterLabeled(Collection labeled) { + return labeled.stream() + .filter(l -> this.matches(l.getLabels().asMap()).matched()) + .collect(Collectors.toList()); + } + public List filterLog(List tagged) { return tagged.stream() .map(this::matchesTaggedResult) @@ -156,6 +160,11 @@ public class TagFilter { } } +// TODO: Implement Me! +// public TagFilter(Map filterSpec) { +// +// } + private static String unquote(String filterSpec) { for (String s : new String[]{"'", "\""}) { if (filterSpec.indexOf(s) == 0 && filterSpec.indexOf(s, 1) == filterSpec.length() - 1) { diff --git a/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBBaseMetric.java b/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBBaseMetric.java new file mode 100644 index 000000000..bedfbee8a --- /dev/null +++ b/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBBaseMetric.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2023 nosqlbench + * + * 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.nosqlbench.api.engine.metrics.instruments; + +import io.nosqlbench.api.labels.NBLabels; + +public class NBBaseMetric implements NBMetric { + private final NBLabels labels; + + public NBBaseMetric(String... labels) { + this.labels = NBLabels.forKV((Object[]) labels); + } + @Override + public NBLabels getLabels() { + return this.labels; + } + + +} diff --git a/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBMetric.java b/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBMetric.java new file mode 100644 index 000000000..861bfe435 --- /dev/null +++ b/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBMetric.java @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2023 nosqlbench + * + * 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.nosqlbench.api.engine.metrics.instruments; + +import com.codahale.metrics.Metric; +import io.nosqlbench.api.labels.NBLabeledElement; + +public interface NBMetric extends Metric, NBLabeledElement { +} diff --git a/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBMetricCounter.java b/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBMetricCounter.java index 5e4013702..19457a8dc 100644 --- a/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBMetricCounter.java +++ b/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBMetricCounter.java @@ -17,9 +17,10 @@ package io.nosqlbench.api.engine.metrics.instruments; import com.codahale.metrics.Counter; +import io.nosqlbench.api.labels.NBLabeledElement; import io.nosqlbench.api.labels.NBLabels; -public class NBMetricCounter extends Counter implements NBLabeledMetric { +public class NBMetricCounter extends Counter implements NBMetric { private final NBLabels labels; diff --git a/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBMetricGauge.java b/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBMetricGauge.java index e9e018e0c..bff4072a9 100644 --- a/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBMetricGauge.java +++ b/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBMetricGauge.java @@ -18,6 +18,6 @@ package io.nosqlbench.api.engine.metrics.instruments; import com.codahale.metrics.Gauge; -public interface NBMetricGauge extends Gauge, NBLabeledMetric { +public interface NBMetricGauge extends Gauge, NBMetric { } diff --git a/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBMetricGaugeWrapper.java b/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBMetricGaugeWrapper.java index c3f4ef650..56bce54ed 100644 --- a/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBMetricGaugeWrapper.java +++ b/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBMetricGaugeWrapper.java @@ -19,7 +19,7 @@ package io.nosqlbench.api.engine.metrics.instruments; import com.codahale.metrics.Gauge; import io.nosqlbench.api.labels.NBLabels; -public class NBMetricGaugeWrapper implements NBMetricGauge { +public class NBMetricGaugeWrapper implements NBMetricGauge, NBMetric { private final Gauge gauge; private final NBLabels labels; diff --git a/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBMetricHistogram.java b/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBMetricHistogram.java index f495de6d9..9652dbe72 100644 --- a/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBMetricHistogram.java +++ b/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBMetricHistogram.java @@ -24,7 +24,7 @@ import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; -public class NBMetricHistogram extends Histogram implements DeltaSnapshotter, HdrDeltaHistogramAttachment, HistogramAttachment, NBLabeledMetric { +public class NBMetricHistogram extends Histogram implements DeltaSnapshotter, HdrDeltaHistogramAttachment, HistogramAttachment, NBMetric { private final DeltaHdrHistogramReservoir hdrDeltaReservoir; private final NBLabels labels; diff --git a/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBMetricMeter.java b/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBMetricMeter.java index 3a3afb47c..cf0c8f50b 100644 --- a/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBMetricMeter.java +++ b/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBMetricMeter.java @@ -19,7 +19,7 @@ package io.nosqlbench.api.engine.metrics.instruments; import com.codahale.metrics.Meter; import io.nosqlbench.api.labels.NBLabels; -public class NBMetricMeter extends Meter implements NBLabeledMetric { +public class NBMetricMeter extends Meter implements NBMetric { private final NBLabels labels; diff --git a/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBMetricTimer.java b/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBMetricTimer.java index bbcd16fe2..9d1ed137c 100644 --- a/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBMetricTimer.java +++ b/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBMetricTimer.java @@ -25,7 +25,7 @@ import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.TimeUnit; -public class NBMetricTimer extends Timer implements DeltaSnapshotter, HdrDeltaHistogramAttachment, TimerAttachment, NBLabeledMetric { +public class NBMetricTimer extends Timer implements DeltaSnapshotter, HdrDeltaHistogramAttachment, TimerAttachment, NBMetric { private final DeltaHdrHistogramReservoir deltaHdrHistogramReservoir; private long cacheExpiry; private List mirrors; diff --git a/nb-api/src/main/java/io/nosqlbench/api/labels/MapLabels.java b/nb-api/src/main/java/io/nosqlbench/api/labels/MapLabels.java index 557f9a5c8..f38d91e4c 100644 --- a/nb-api/src/main/java/io/nosqlbench/api/labels/MapLabels.java +++ b/nb-api/src/main/java/io/nosqlbench/api/labels/MapLabels.java @@ -123,9 +123,11 @@ public class MapLabels implements NBLabels { @Override public String linearizeAsMetrics() { StringBuilder sb = new StringBuilder("{"); - this.labels.forEach((k,v) -> { - sb.append(k).append(":\"").append(v).append("\","); - }); + ArrayList keys = new ArrayList<>(this.labels.keySet()); + Collections.sort(keys); + for (String key : keys) { + sb.append(key).append("=\"").append(labels.get(key)).append("\","); + } sb.setLength(sb.length()-",".length()); sb.append("}"); return sb.toString(); diff --git a/nb-api/src/main/java/io/nosqlbench/api/labels/NBLabels.java b/nb-api/src/main/java/io/nosqlbench/api/labels/NBLabels.java index ebc6f714d..cf318e6a2 100644 --- a/nb-api/src/main/java/io/nosqlbench/api/labels/NBLabels.java +++ b/nb-api/src/main/java/io/nosqlbench/api/labels/NBLabels.java @@ -170,10 +170,10 @@ public interface NBLabels { */ Map asMap(); - String linearizeAsMetrics(); - /** - * @return a new set of labels which includes only those which are not using per-instance semantics. + * Return a String representation of the metric's labels as you would see it in an openmetrics filter, + * like
{@code {__name__="metric_family_name",k="20"}}
+ * @return a String */ - + String linearizeAsMetrics(); } diff --git a/nb-api/src/main/java/io/nosqlbench/components/NBBaseComponent.java b/nb-api/src/main/java/io/nosqlbench/components/NBBaseComponent.java index a147ff437..932118bbc 100644 --- a/nb-api/src/main/java/io/nosqlbench/components/NBBaseComponent.java +++ b/nb-api/src/main/java/io/nosqlbench/components/NBBaseComponent.java @@ -16,11 +16,15 @@ package io.nosqlbench.components; +import io.nosqlbench.api.engine.metrics.instruments.NBMetric; import io.nosqlbench.api.labels.NBLabels; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; -public class NBBaseComponent implements NBComponent { +public class NBBaseComponent extends NBBaseComponentMetrics implements NBComponent { private final NBComponent parent; private final List children = new ArrayList<>(); private final NBLabels labels; @@ -57,4 +61,25 @@ public class NBBaseComponent implements NBComponent { return (this.parent==null) ? labels : this.parent.getLabels().and(labels); } + @Override + public NBMetric lookupMetricInTree(String name) { + Iterator tree = NBComponentTraversal.traverseBreadth(this); + while (tree.hasNext()) { + NBComponent c = tree.next(); + NBMetric metric = c.lookupMetric(name); + if (metric!=null) return metric; + } + return null; + } + + @Override + public List findMetricsInTree(String pattern) { + Iterator tree = NBComponentTraversal.traverseBreadth(this); + List found = new ArrayList<>(); + while (tree.hasNext()) { + NBComponent c = tree.next(); + found.addAll(c.findMetrics(pattern)); + } + return found; + } } diff --git a/nb-api/src/main/java/io/nosqlbench/components/NBBaseComponentMetrics.java b/nb-api/src/main/java/io/nosqlbench/components/NBBaseComponentMetrics.java new file mode 100644 index 000000000..d1d11a10c --- /dev/null +++ b/nb-api/src/main/java/io/nosqlbench/components/NBBaseComponentMetrics.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2023 nosqlbench + * + * 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.nosqlbench.components; + +import io.nosqlbench.adapters.api.util.TagFilter; +import io.nosqlbench.api.engine.metrics.instruments.NBMetric; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +public class NBBaseComponentMetrics implements NBComponentMetrics { + private final Lock lock = new ReentrantLock(false); + private final Map metrics = new HashMap<>(); + @Override + public String addMetric(NBMetric metric) { + try { + lock.lock(); + String openMetricsName = metric.getLabels().linearizeAsMetrics(); + if (metrics.containsKey(openMetricsName)) { + throw new RuntimeException("Can't add the same metric by label set to the same live component:" + openMetricsName); + } + metrics.put(openMetricsName,metric); + return metric.getLabels().linearizeAsMetrics(); + } finally { + lock.unlock(); + } + } + @Override + public NBMetric lookupMetric(String name) { + return metrics.get(name); + } + + @Override + public List findMetrics(String pattern) { + TagFilter filter = new TagFilter(pattern); + return filter.filterLabeled(metrics.values()); + } +} diff --git a/nb-api/src/main/java/io/nosqlbench/components/NBComponent.java b/nb-api/src/main/java/io/nosqlbench/components/NBComponent.java index 65f895b84..9a0061157 100644 --- a/nb-api/src/main/java/io/nosqlbench/components/NBComponent.java +++ b/nb-api/src/main/java/io/nosqlbench/components/NBComponent.java @@ -33,7 +33,7 @@ import java.util.List; * * This interface will start as a tagging interface, but will eventually include aspects of above by extension. */ -public interface NBComponent extends NBLabeledElement { +public interface NBComponent extends NBLabeledElement, NBComponentMetrics, NBMetricsQuery { NBComponent getParent(); diff --git a/nb-api/src/main/java/io/nosqlbench/components/NBComponentMetrics.java b/nb-api/src/main/java/io/nosqlbench/components/NBComponentMetrics.java new file mode 100644 index 000000000..0b1d23e0a --- /dev/null +++ b/nb-api/src/main/java/io/nosqlbench/components/NBComponentMetrics.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2023 nosqlbench + * + * 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.nosqlbench.components; + +import io.nosqlbench.api.engine.metrics.instruments.NBMetric; + +import java.util.List; +import java.util.Optional; + +public interface NBComponentMetrics { + String addMetric(NBMetric metric); + + /** + * If you have the serialized open metrics name of a metric, you can ask for it + * this way and get a direct result. + * @param name The name of a metric in {@code {a:"b",...}} form + * @return the metric or null if it dosen't exist + */ + NBMetric lookupMetric(String name); + + default Optional lookupMetricOptionally(String name) { + return Optional.ofNullable(lookupMetric(name)); + } + + List findMetrics(String pattern); + + default NBMetric findOneMetric(String pattern) { + List found = findMetrics(pattern); + if (found.size()!=1) { + throw new RuntimeException("Found " + found.size() + " metrics with pattern '" + pattern + "', expected exactly 1"); + } + return found.get(0); + } + + +} diff --git a/nb-api/src/main/java/io/nosqlbench/components/NBMetricsQuery.java b/nb-api/src/main/java/io/nosqlbench/components/NBMetricsQuery.java new file mode 100644 index 000000000..20267aa03 --- /dev/null +++ b/nb-api/src/main/java/io/nosqlbench/components/NBMetricsQuery.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2023 nosqlbench + * + * 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.nosqlbench.components; + +import io.nosqlbench.api.engine.metrics.instruments.NBMetric; + +import java.util.List; +import java.util.Optional; + +public interface NBMetricsQuery { + /** + * If you have the serialized open metrics name of a metric, you can ask for it + * this way and get a direct result. + * @param name The name of a metric in {@code {a:"b",...}} form + * @return the metric or null if it dosen't exist + */ + NBMetric lookupMetricInTree(String name); + + default Optional lookupMetricOptionallyInTree(String name) { + return Optional.ofNullable(lookupMetricInTree(name)); + } + + List findMetricsInTree(String pattern); + + default NBMetric findOneMetricInTree(String pattern) { + List found = findMetricsInTree(pattern); + if (found.size()!=1) { + throw new RuntimeException("Found " + found.size() + " metrics with pattern '" + pattern + "', expected exactly 1"); + } + return found.get(0); + } + +} diff --git a/nb-api/src/main/java/io/nosqlbench/components/package-info.java b/nb-api/src/main/java/io/nosqlbench/components/package-info.java new file mode 100644 index 000000000..48edda892 --- /dev/null +++ b/nb-api/src/main/java/io/nosqlbench/components/package-info.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2023 nosqlbench + * + * 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. + */ + +/** + *

The component types in this package create a basic structural and lifecycle + * pattern that NoSQLBench runtimes should build upon. This allows leverage of + * the base component types to achieve: + *

    + *
  • consistent runtime behavior between modules
  • + *
  • modular composition of runtime modules in different configurations
  • + *
  • a uniform configuration interface across all components
  • + *
  • exposition of foundational runtime structure to users
  • + *
  • consistent layering of components and their lifetimes at different runtime scopes
  • + *
  • a naming and metadata based view which allows for components to be managed in a tangible way
  • + *
  • a consistent manifest and registry interface for attached elements, like metrics
  • + *
+ *

+ *
+ * + *

Components Defined

+ *

There can be different layers or types of components, but there is only one component hierarchy in each + * NoSQLBench process. Basically the Session is a component. The Scenario is a component. Each activity within a + * scenario is a component. Whether something is meaningful as a component depends on whether the management facilities + * provided by the component API make using, interacting with, or understanding that element better for users. However + * there is a limit to how fine-grained the component hierarchy should be allowed to get. This is because maintaining + * the component structure at runtime incurs a cost, and most feature of the component types are related to assemblage + * of fixtures in the runtime which are configured and initialized before steady state processing begins. For example, + * it makes sense to wire an activity as component, but not an operation, since an operation is ephemeral and + * short-lived. Apart from these trade-offs, make a layer a component layer if it makes sense for the user and/or the + * developer, as consolidating the logic into the component layer is beneficial to both.

+ * + *

Adoption Strategy

+ *

Consolidating existing logic to use the component types will be an incremental process. The base contract type + * {@link io.nosqlbench.components.NBComponent} establishes the contract for any conforming types. As contract facets + * are added to this type, common logic can be implemented on the base implementation types where possible, allowing + * for the elision of duplicitous code from prior functionality.

+ *

+ *

+ *


+ * + *

Component System Design

+ *

All key types in the NBComponent system must have names starting with NBComponent.

+ * + *

Components are structured hierarchically. All components exist within the scope of their parent, with the only + * exception being the root component, which has no parent. Components always know their parent from construction time. + * After a component is constructed, it is informed of children components being added and removed via + * {@link io.nosqlbench.components.NBComponent#attach} and {@link io.nosqlbench.components.NBComponent#detach} + * methods.

+ * + *

Component logic should interact with other components using the component interfaces and types. No contextual + * typing or casting should be allowed within the component layer methods. Components only understand components by + * design, and breaking this abstraction is counter-productive at best.

+ * + *

Utility classes which understand how to interact with components should be used where possible when the + * capabilities they provide are well-themed and cohesive. A Corollary to this is that each interface added to the core + * component type should be solely informational about the structure and properties of the component hierarchy when + * possible. This will help organize usage patterns around themed utilities and keep the surface area of the core types + * to a minimum.

+ * + * TODO: labeling consistency + */ +package io.nosqlbench.components; diff --git a/adapters-api/src/test/java/io/nosqlbench/adapters/api/util/TagFilterTest.java b/nb-api/src/test/java/io/nosqlbench/adapters/api/util/TagFilterTest.java similarity index 90% rename from adapters-api/src/test/java/io/nosqlbench/adapters/api/util/TagFilterTest.java rename to nb-api/src/test/java/io/nosqlbench/adapters/api/util/TagFilterTest.java index 2943ba8c4..9431909f6 100644 --- a/adapters-api/src/test/java/io/nosqlbench/adapters/api/util/TagFilterTest.java +++ b/nb-api/src/test/java/io/nosqlbench/adapters/api/util/TagFilterTest.java @@ -168,4 +168,18 @@ public class TagFilterTest { TagFilter tf2 = new TagFilter("any(car:truck,block:moon)"); assertThat(tf2.matches(itemtags).matched()).isFalse(); } + + @Test + public void testNoneCondition() { + Map itemtags = Map.of("block", "main", "truck", "car"); + TagFilter tf = new TagFilter(""); + assertThat(tf.matches(itemtags).matched()).isTrue(); + TagFilter tf4 = new TagFilter("none(unseen)"); + assertThat(tf4.matches(itemtags).matched()).isTrue(); + TagFilter tf2 = new TagFilter("none(truck)"); + assertThat(tf2.matches(itemtags).matched()).isFalse(); + TagFilter tf3 = new TagFilter("none(truck:car)"); + assertThat(tf3.matches(itemtags).matched()).isFalse(); + } + } diff --git a/nb-api/src/test/java/io/nosqlbench/api/labels/MapLabelsTest.java b/nb-api/src/test/java/io/nosqlbench/api/labels/MapLabelsTest.java index ab62f33d8..134f443a2 100644 --- a/nb-api/src/test/java/io/nosqlbench/api/labels/MapLabelsTest.java +++ b/nb-api/src/test/java/io/nosqlbench/api/labels/MapLabelsTest.java @@ -16,7 +16,6 @@ package io.nosqlbench.api.labels; -import io.nosqlbench.api.labels.MapLabels; import org.junit.jupiter.api.Test; import java.util.Map; @@ -38,6 +37,4 @@ public class MapLabelsTest { public void testInvalidCharacters() { assertThatThrownBy(() -> new MapLabels(Map.of("a-b","c-d"))).isOfAnyClassIn(RuntimeException.class); } - - } diff --git a/nb-api/src/test/java/io/nosqlbench/components/NBBaseComponentMetricsTest.java b/nb-api/src/test/java/io/nosqlbench/components/NBBaseComponentMetricsTest.java new file mode 100644 index 000000000..11bb21678 --- /dev/null +++ b/nb-api/src/test/java/io/nosqlbench/components/NBBaseComponentMetricsTest.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2023 nosqlbench + * + * 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.nosqlbench.components; + +import io.nosqlbench.api.engine.metrics.instruments.NBBaseMetric; +import io.nosqlbench.api.engine.metrics.instruments.NBMetric; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +class NBBaseComponentMetricsTest { + + @Test + void testBasicAddAndLookup() { + NBBaseComponentMetrics cm = new NBBaseComponentMetrics(); + NBMetric m1 = new NBBaseMetric("k","20"); + String m1Handle = cm.addMetric(m1); + NBMetric m2 = new NBBaseMetric("k","27","l","62"); + String m2Handle = cm.addMetric(m2); + + assertThat(cm.lookupMetric(m1Handle)).isEqualTo(m1); + assertThat(cm.lookupMetric(m2Handle)).isEqualTo(m2); + } + @Test + void find() { + NBBaseComponentMetrics cm = new NBBaseComponentMetrics(); + NBMetric m1 = new NBBaseMetric("k","20"); + String m1Handle = cm.addMetric(m1); + NBMetric m2 = new NBBaseMetric("k","27","l","62"); + String m2Handle = cm.addMetric(m2); + + assertThat(cm.findMetrics("k=27")).isEqualTo(List.of(m2)); + assertThat(cm.findMetrics("k=20")).isNotEqualTo(List.of(m2)); + } +} diff --git a/nb-api/src/test/java/io/nosqlbench/components/NBComponentLifecycleTest.java b/nb-api/src/test/java/io/nosqlbench/components/NBComponentLifecycleTest.java index 31c39f7c9..e1a5823e6 100644 --- a/nb-api/src/test/java/io/nosqlbench/components/NBComponentLifecycleTest.java +++ b/nb-api/src/test/java/io/nosqlbench/components/NBComponentLifecycleTest.java @@ -19,8 +19,6 @@ package io.nosqlbench.components; import io.nosqlbench.api.config.standard.TestComponent; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; - class NBComponentLifecycleTest { @Test @@ -36,7 +34,7 @@ class NBComponentLifecycleTest { System.out.println("node2 active"); } - System.out.print("node1 inactive"); + System.out.print("all inactive"); } diff --git a/nb-api/src/test/java/io/nosqlbench/components/NBComponentViewsTest.java b/nb-api/src/test/java/io/nosqlbench/components/NBComponentViewsTest.java index 359639e60..2b8f56ea6 100644 --- a/nb-api/src/test/java/io/nosqlbench/components/NBComponentViewsTest.java +++ b/nb-api/src/test/java/io/nosqlbench/components/NBComponentViewsTest.java @@ -19,19 +19,27 @@ package io.nosqlbench.components; import io.nosqlbench.api.config.standard.TestComponent; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; - class NBComponentViewsTest { @Test public void testBasicTreeView() { - var root = new TestComponent("a", "b") - .attach(new TestComponent("c", "d") - .attach(new TestComponent("U", "V")) - .attach(new TestComponent("Y","Z"))) - .attach(new TestComponent("e", "f")); - System.out.println(NBComponentViews.treeView(root)); + var root1 = new TestComponent("a", "b"); + var cd = new TestComponent(root1, "c", "d"); + var UV = new TestComponent(cd, "U", "V"); + var YZ = new TestComponent(cd, "Y", "Z"); + var ef = new TestComponent(root1, "e", "f"); - System.out.println(NBComponentViews.treeView(root, c -> String.valueOf(c.hashCode()))); + var root2 = new TestComponent("a", "b"); + + root2.attach(new TestComponent(root2, "c", "d") + .attach(new TestComponent("U", "V")) + .attach(new TestComponent("Y", "Z"))) + .attach(new TestComponent("e", "f")); + + System.out.println("root1:\n" + NBComponentViews.treeView(root1)); + System.out.println("root1:\n" + NBComponentViews.treeView(root1, c -> String.valueOf(c.hashCode()))); + + System.out.println("root2:\n" + NBComponentViews.treeView(root2)); + System.out.println("root2:\n" + NBComponentViews.treeView(root2, c -> String.valueOf(c.hashCode()))); } } diff --git a/nb-api/src/test/java/io/nosqlbench/components/NBMetricsQueryTest.java b/nb-api/src/test/java/io/nosqlbench/components/NBMetricsQueryTest.java new file mode 100644 index 000000000..3fd8baac3 --- /dev/null +++ b/nb-api/src/test/java/io/nosqlbench/components/NBMetricsQueryTest.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2023 nosqlbench + * + * 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.nosqlbench.components; + +import io.nosqlbench.api.config.standard.TestComponent; +import io.nosqlbench.api.engine.metrics.instruments.NBBaseMetric; +import io.nosqlbench.api.engine.metrics.instruments.NBMetric; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class NBMetricsQueryTest { + private final static TestComponent root = new TestComponent("root","root","type","rootelement"); + private final static TestComponent root_c2 = new TestComponent(root,"c2","c2"); + private final static TestComponent root_c3 = new TestComponent(root,"c3","c3"); + private final static NBMetric m1 = new NBBaseMetric("m1","m1"); + private final String m1Handle = root.addMetric(m1); + private final static NBMetric m2 = new NBBaseMetric("m2","m2"); + private final String m2Handle = root_c2.addMetric(m2); + private final static NBMetric m3 = new NBBaseMetric("m3","m3"); + private final String m3Handle = root_c3.addMetric(m3); + + @Test + public void testFindInTree() { + NBMetric expectedM3 = root.findOneMetricInTree("m3:m3"); + assertThat(expectedM3).isEqualTo(m3); + assertThatThrownBy(() -> root.findOneMetricInTree("m3:m4")).isOfAnyClassIn(RuntimeException.class); + } + + @Test + public void testFindOneInTree() { + List metricsInTree = root.findMetricsInTree(""); + assertThat(metricsInTree).containsExactly(m1, m2, m3); + List m3Only = root.findMetricsInTree("m3:m3"); + assertThat(m3Only).containsExactly(m3); + } +}