diff --git a/instrumentation/geode-1.4/javaagent/src/test/groovy/PutGetTest.groovy b/instrumentation/geode-1.4/javaagent/src/test/groovy/PutGetTest.groovy deleted file mode 100644 index 9b8b9967477a..000000000000 --- a/instrumentation/geode-1.4/javaagent/src/test/groovy/PutGetTest.groovy +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification -import io.opentelemetry.semconv.trace.attributes.SemanticAttributes -import org.apache.geode.DataSerializable -import org.apache.geode.cache.client.ClientCacheFactory -import org.apache.geode.cache.client.ClientRegionShortcut -import spock.lang.Shared -import spock.lang.Unroll - -import static io.opentelemetry.api.trace.SpanKind.CLIENT -import static io.opentelemetry.api.trace.SpanKind.INTERNAL - -@Unroll -class PutGetTest extends AgentInstrumentationSpecification { - @Shared - def cache = new ClientCacheFactory().create() - - @Shared - def regionFactory = cache.createClientRegionFactory(ClientRegionShortcut.LOCAL) - - @Shared - def region = regionFactory.create("test-region") - - def "test put and get"() { - when: - def cacheValue = runWithSpan("someTrace") { - region.clear() - region.put(key, value) - region.get(key) - } - - then: - cacheValue == value - assertGeodeTrace("get", null) - - where: - key | value - 'Hello' | 'World' - 'Humpty' | 'Dumpty' - '1' | 'One' - 'One' | '1' - } - - def "test put and remove"() { - when: - runWithSpan("someTrace") { - region.clear() - region.put(key, value) - region.remove(key) - } - - then: - region.size() == 0 - assertGeodeTrace("remove", null) - - where: - key | value - 'Hello' | 'World' - 'Humpty' | 'Dumpty' - '1' | 'One' - 'One' | '1' - } - - def "test query"() { - when: - def cacheValue = runWithSpan("someTrace") { - region.clear() - region.put(key, value) - region.query("SELECT * FROM /test-region") - } - - then: - cacheValue.asList().size() - assertGeodeTrace("query", "SELECT * FROM /test-region") - - where: - key | value - 'Hello' | 'World' - 'Humpty' | 'Dumpty' - '1' | 'One' - 'One' | '1' - } - - def "test existsValue"() { - when: - def exists = runWithSpan("someTrace") { - region.clear() - region.put(key, value) - region.existsValue("SELECT * FROM /test-region") - } - - then: - exists - assertGeodeTrace("existsValue", "SELECT * FROM /test-region") - - where: - key | value - 'Hello' | 'World' - 'Humpty' | 'Dumpty' - '1' | 'One' - 'One' | '1' - } - - def assertGeodeTrace(String verb, String query) { - assertTraces(1) { - trace(0, 4) { - span(0) { - name "someTrace" - kind INTERNAL - } - span(1) { - name "clear test-region" - kind CLIENT - attributes { - "$SemanticAttributes.DB_SYSTEM" "geode" - "$SemanticAttributes.DB_NAME" "test-region" - "$SemanticAttributes.DB_OPERATION" "clear" - } - } - span(2) { - name "put test-region" - kind CLIENT - attributes { - "$SemanticAttributes.DB_SYSTEM" "geode" - "$SemanticAttributes.DB_NAME" "test-region" - "$SemanticAttributes.DB_OPERATION" "put" - } - } - span(3) { - name "$verb test-region" - kind CLIENT - attributes { - "$SemanticAttributes.DB_SYSTEM" "geode" - "$SemanticAttributes.DB_NAME" "test-region" - "$SemanticAttributes.DB_OPERATION" verb - if (query != null) { - "$SemanticAttributes.DB_STATEMENT" query - } - } - } - } - } - return true - } - - def "should sanitize geode query"() { - given: - def value = new Card(cardNumber: '1234432156788765', expDate: '10/2020') - - region.clear() - region.put(1, value) - ignoreTracesAndClear(2) - - when: - def results = region.query("SELECT * FROM /test-region p WHERE p.expDate = '10/2020'") - - then: - results.toList() == [value] - - assertTraces(1) { - trace(0, 1) { - span(0) { - name "query test-region" - kind CLIENT - attributes { - "$SemanticAttributes.DB_SYSTEM" "geode" - "$SemanticAttributes.DB_NAME" "test-region" - "$SemanticAttributes.DB_OPERATION" "query" - "$SemanticAttributes.DB_STATEMENT" "SELECT * FROM /test-region p WHERE p.expDate = ?" - } - } - } - } - } - - static class Card implements DataSerializable { - String cardNumber - String expDate - - @Override - void toData(DataOutput dataOutput) throws IOException { - dataOutput.writeUTF(cardNumber) - dataOutput.writeUTF(expDate) - } - - @Override - void fromData(DataInput dataInput) throws IOException, ClassNotFoundException { - cardNumber = dataInput.readUTF() - expDate = dataInput.readUTF() - } - } -} diff --git a/instrumentation/geode-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/geode/PutGetTest.java b/instrumentation/geode-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/geode/PutGetTest.java new file mode 100644 index 000000000000..5ca235527cf4 --- /dev/null +++ b/instrumentation/geode-1.4/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/geode/PutGetTest.java @@ -0,0 +1,201 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.geode; + +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import io.opentelemetry.api.trace.SpanKind; +import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension; +import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; +import io.opentelemetry.semconv.trace.attributes.SemanticAttributes; +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; +import java.util.stream.Stream; +import org.apache.geode.DataSerializable; +import org.apache.geode.cache.Region; +import org.apache.geode.cache.client.ClientCache; +import org.apache.geode.cache.client.ClientCacheFactory; +import org.apache.geode.cache.client.ClientRegionFactory; +import org.apache.geode.cache.client.ClientRegionShortcut; +import org.apache.geode.cache.query.QueryException; +import org.apache.geode.cache.query.SelectResults; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class PutGetTest { + @RegisterExtension + private static final InstrumentationExtension testing = AgentInstrumentationExtension.create(); + + static ClientCache cache = new ClientCacheFactory().create(); + static ClientRegionFactory regionFactory = + cache.createClientRegionFactory(ClientRegionShortcut.LOCAL); + static Region region = regionFactory.create("test-region"); + + private static Stream provideParameters() { + return Stream.of( + Arguments.of("Hello", "World"), + Arguments.of("Humpty", "Dumpty"), + Arguments.of(Integer.valueOf(1), "One"), + Arguments.of("One", Integer.valueOf(1))); + } + + @ParameterizedTest + @MethodSource("provideParameters") + void testPutAndGet(Object key, Object value) { + Object cacheValue = + testing.runWithSpan( + "someTrace", + () -> { + region.clear(); + region.put(key, value); + return region.get(key); + }); + assertEquals(value, cacheValue); + assertGeodeTrace("get", null); + } + + @ParameterizedTest + @MethodSource("provideParameters") + void testPutAndRemove(Object key, Object value) { + testing.runWithSpan( + "someTrace", + () -> { + region.clear(); + region.put(key, value); + region.remove(key); + }); + assertEquals(0, region.size()); + assertGeodeTrace("remove", null); + } + + @ParameterizedTest + @MethodSource("provideParameters") + void testQuery(Object key, Object value) throws QueryException { + SelectResults cacheValue = + testing.runWithSpan( + "someTrace", + () -> { + region.clear(); + region.put(key, value); + return region.query("SELECT * FROM /test-region"); + }); + assertEquals(1, cacheValue.size()); + assertGeodeTrace("query", "SELECT * FROM /test-region"); + } + + @ParameterizedTest + @MethodSource("provideParameters") + void testExistsValue(Object key, Object value) throws QueryException { + boolean cacheValue = + testing.runWithSpan( + "someTrace", + () -> { + region.clear(); + region.put(key, value); + return region.existsValue("SELECT * FROM /test-region"); + }); + assertTrue(cacheValue); + assertGeodeTrace("existsValue", "SELECT * FROM /test-region"); + } + + @Test + void shouldSanitizeGeodeQuery() throws QueryException { + Card value = new Card("1234432156788765", "10/2020"); + SelectResults results = + testing.runWithSpan( + "someTrace", + () -> { + region.clear(); + region.put(1, value); + return region.query("SELECT * FROM /test-region p WHERE p.expDate = '10/2020'"); + }); + + assertEquals(value, results.asList().get(0)); + assertGeodeTrace("query", "SELECT * FROM /test-region p WHERE p.expDate = ?"); + } + + void assertGeodeTrace(String verb, String query) { + testing.waitAndAssertTraces( + trace -> + trace + .hasSize(4) + .hasSpansSatisfyingExactly( + span -> span.hasName("someTrace").hasKind(SpanKind.INTERNAL), + span -> + span.hasName("clear test-region") + .hasKind(SpanKind.CLIENT) + .hasAttributesSatisfyingExactly( + equalTo(SemanticAttributes.DB_SYSTEM, "geode"), + equalTo(SemanticAttributes.DB_NAME, "test-region"), + equalTo(SemanticAttributes.DB_OPERATION, "clear")), + span -> + span.hasName("put test-region") + .hasKind(SpanKind.CLIENT) + .hasAttributesSatisfyingExactly( + equalTo(SemanticAttributes.DB_SYSTEM, "geode"), + equalTo(SemanticAttributes.DB_NAME, "test-region"), + equalTo(SemanticAttributes.DB_OPERATION, "put")), + span -> + span.hasName(verb.concat(" test-region")) + .hasKind(SpanKind.CLIENT) + .hasAttributesSatisfying( + attributes -> { + assertThat(attributes) + .containsEntry(SemanticAttributes.DB_SYSTEM, "geode") + .containsEntry(SemanticAttributes.DB_NAME, "test-region") + .containsEntry(SemanticAttributes.DB_OPERATION, verb); + if (query != null) { + assertThat(attributes) + .containsEntry(SemanticAttributes.DB_STATEMENT, query); + } + }))); + } + + static class Card implements DataSerializable { + String cardNumber; + String expDate; + + public Card(String cardNumber, String expDate) { + this.cardNumber = cardNumber; + this.expDate = expDate; + } + + public String getCardNumber() { + return cardNumber; + } + + public void setCardNumber(String cardNumber) { + this.cardNumber = cardNumber; + } + + public String getExpDate() { + return expDate; + } + + public void setExpDate(String expDate) { + this.expDate = expDate; + } + + @Override + public void toData(DataOutput dataOutput) throws IOException { + dataOutput.writeUTF(cardNumber); + dataOutput.writeUTF(expDate); + } + + @Override + public void fromData(DataInput dataInput) throws IOException, ClassNotFoundException { + cardNumber = dataInput.readUTF(); + expDate = dataInput.readUTF(); + } + } +}