Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
/*
* 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.skywalking.oap.server.storage.plugin.jdbc.common.dao;

import org.apache.skywalking.oap.server.core.browser.manual.errorlog.BrowserErrorLogRecord;
import org.apache.skywalking.oap.server.core.browser.source.BrowserErrorCategory;
import org.apache.skywalking.oap.server.core.query.input.Duration;
import org.apache.skywalking.oap.server.core.query.enumeration.Step;
import org.apache.skywalking.oap.server.library.client.jdbc.hikaricp.JDBCClient;
import org.apache.skywalking.oap.server.storage.plugin.jdbc.common.JDBCTableInstaller;
import org.apache.skywalking.oap.server.storage.plugin.jdbc.common.SQLAndParameters;
import org.apache.skywalking.oap.server.storage.plugin.jdbc.common.TableHelper;
import org.joda.time.DateTime;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.junit.jupiter.MockitoSettings;
import org.mockito.quality.Strictness;

import static org.assertj.core.api.Assertions.assertThat;

@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.LENIENT)
class JDBCBrowserLogQueryDAOTest {

private static final String TABLE = BrowserErrorLogRecord.INDEX_NAME;

@Mock
private JDBCClient jdbcClient;
@Mock
private TableHelper tableHelper;

private JDBCBrowserLogQueryDAO dao;

@BeforeEach
void setUp() {
dao = new JDBCBrowserLogQueryDAO(jdbcClient, tableHelper);
}

@Test
void buildSQL_shouldAlwaysContainTableColumnCondition() {
final SQLAndParameters result = dao.buildSQL(null, null, null, null, null, 10, 0, TABLE);

assertThat(result.sql()).contains(JDBCTableInstaller.TABLE_COLUMN + " = ?");
assertThat(result.parameters()).contains(BrowserErrorLogRecord.INDEX_NAME);
}

@Test
void buildSQL_withNoOptionalConditions_shouldProduceMinimalSQL() {
final SQLAndParameters result = dao.buildSQL(null, null, null, null, null, 10, 0, TABLE);

assertThat(result.sql()).doesNotContain(BrowserErrorLogRecord.SERVICE_ID);
assertThat(result.sql()).doesNotContain(BrowserErrorLogRecord.SERVICE_VERSION_ID);
assertThat(result.sql()).doesNotContain(BrowserErrorLogRecord.PAGE_PATH_ID);
assertThat(result.sql()).doesNotContain(BrowserErrorLogRecord.ERROR_CATEGORY);
assertThat(result.sql()).doesNotContain(BrowserErrorLogRecord.TIME_BUCKET);
}

@Test
void buildSQL_withServiceId_shouldIncludeServiceCondition() {
final SQLAndParameters result = dao.buildSQL("service-1", null, null, null, null, 10, 0, TABLE);

assertThat(result.sql()).contains(BrowserErrorLogRecord.SERVICE_ID + " = ?");
assertThat(result.parameters()).contains("service-1");
}

@Test
void buildSQL_withServiceVersionId_shouldIncludeVersionCondition() {
final SQLAndParameters result = dao.buildSQL(null, "version-1", null, null, null, 10, 0, TABLE);

assertThat(result.sql()).contains(BrowserErrorLogRecord.SERVICE_VERSION_ID + " = ?");
assertThat(result.parameters()).contains("version-1");
}

@Test
void buildSQL_withPagePathId_shouldIncludePagePathCondition() {
final SQLAndParameters result = dao.buildSQL(null, null, "path-1", null, null, 10, 0, TABLE);

assertThat(result.sql()).contains(BrowserErrorLogRecord.PAGE_PATH_ID + " = ?");
assertThat(result.parameters()).contains("path-1");
}

@Test
void buildSQL_withCategory_shouldIncludeCategoryCondition() {
final SQLAndParameters result = dao.buildSQL(
null, null, null, BrowserErrorCategory.AJAX, null, 10, 0, TABLE);

assertThat(result.sql()).contains(BrowserErrorLogRecord.ERROR_CATEGORY + " = ?");
assertThat(result.parameters()).contains(BrowserErrorCategory.AJAX.getValue());
}

@Test
void buildSQL_withDuration_shouldIncludeTimeBucketRange() {
final Duration duration = new Duration();
duration.setStart(new DateTime(2023, 1, 1, 0, 0).toString("yyyy-MM-dd HHmm"));
duration.setEnd(new DateTime(2023, 1, 2, 0, 0).toString("yyyy-MM-dd HHmm"));
duration.setStep(Step.MINUTE);

final SQLAndParameters result = dao.buildSQL(null, null, null, null, duration, 10, 0, TABLE);

assertThat(result.sql()).contains(BrowserErrorLogRecord.TIME_BUCKET + " >= ?");
assertThat(result.sql()).contains(BrowserErrorLogRecord.TIME_BUCKET + " <= ?");
}

@Test
void buildSQL_limitAndOffset_shouldBeApplied() {
final SQLAndParameters result = dao.buildSQL(null, null, null, null, null, 20, 5, TABLE);

assertThat(result.sql()).contains("limit 25");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
/*
* 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.skywalking.oap.server.storage.plugin.jdbc.common.dao;

import io.vavr.Tuple2;
import org.apache.skywalking.oap.server.core.analysis.record.Event;
import org.apache.skywalking.oap.server.core.query.type.event.EventQueryCondition;
import org.apache.skywalking.oap.server.core.query.type.event.EventType;
import org.apache.skywalking.oap.server.core.query.type.event.Source;
import org.apache.skywalking.oap.server.library.client.jdbc.hikaricp.JDBCClient;
import org.apache.skywalking.oap.server.storage.plugin.jdbc.common.JDBCTableInstaller;
import org.apache.skywalking.oap.server.storage.plugin.jdbc.common.TableHelper;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.junit.jupiter.MockitoSettings;
import org.mockito.quality.Strictness;

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static org.assertj.core.api.Assertions.assertThat;

@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.LENIENT)
class JDBCEventQueryDAOTest {

@Mock
private JDBCClient jdbcClient;
@Mock
private TableHelper tableHelper;

private JDBCEventQueryDAO dao;

@BeforeEach
void setUp() {
dao = new JDBCEventQueryDAO(jdbcClient, tableHelper);
}

@Test
void buildQuery_shouldAlwaysContainTableColumnCondition() {
final EventQueryCondition condition = new EventQueryCondition();

final Tuple2<Stream<String>, Stream<Object>> result = dao.buildQuery(condition);
final List<String> conditions = result._1().collect(Collectors.toList());

assertThat(conditions).contains(JDBCTableInstaller.TABLE_COLUMN + " = ?");
}

@Test
void buildQuery_withNoOptionalConditions_shouldProduceOnlyTableColumnCondition() {
final EventQueryCondition condition = new EventQueryCondition();

final Tuple2<Stream<String>, Stream<Object>> result = dao.buildQuery(condition);
final List<String> conditions = result._1().collect(Collectors.toList());
final List<Object> parameters = result._2().collect(Collectors.toList());

assertThat(conditions).hasSize(1);
assertThat(conditions.get(0)).isEqualTo(JDBCTableInstaller.TABLE_COLUMN + " = ?");
assertThat(parameters).containsExactly(Event.INDEX_NAME);
}

@Test
void buildQuery_withUuid_shouldIncludeUuidCondition() {
final EventQueryCondition condition = new EventQueryCondition();
condition.setUuid("test-uuid");

final Tuple2<Stream<String>, Stream<Object>> result = dao.buildQuery(condition);
final List<String> conditions = result._1().collect(Collectors.toList());
final List<Object> parameters = result._2().collect(Collectors.toList());

assertThat(conditions).contains(Event.UUID + "=?");
assertThat(parameters).contains("test-uuid");
}

@Test
void buildQuery_withSource_shouldIncludeServiceConditions() {
final EventQueryCondition condition = new EventQueryCondition();
final Source source = new Source();
source.setService("order-service");
source.setServiceInstance("instance-1");
source.setEndpoint("/orders");
condition.setSource(source);

final Tuple2<Stream<String>, Stream<Object>> result = dao.buildQuery(condition);
final List<String> conditions = result._1().collect(Collectors.toList());
final List<Object> parameters = result._2().collect(Collectors.toList());

assertThat(conditions).contains(Event.SERVICE + "=?");
assertThat(conditions).contains(Event.SERVICE_INSTANCE + "=?");
assertThat(conditions).contains(Event.ENDPOINT + "=?");
assertThat(parameters).contains("order-service", "instance-1", "/orders");
}

@Test
void buildQuery_withEventType_shouldIncludeTypeCondition() {
final EventQueryCondition condition = new EventQueryCondition();
condition.setType(EventType.Normal);

final Tuple2<Stream<String>, Stream<Object>> result = dao.buildQuery(condition);
final List<String> conditions = result._1().collect(Collectors.toList());
final List<Object> parameters = result._2().collect(Collectors.toList());

assertThat(conditions).contains(Event.TYPE + "=?");
assertThat(parameters).contains(EventType.Normal.name());
}

@Test
void buildQuery_withTableColumnConditionOnlyOnce() {
final EventQueryCondition condition = new EventQueryCondition();
condition.setUuid("uuid-1");

final Tuple2<Stream<String>, Stream<Object>> result = dao.buildQuery(condition);
final List<String> conditions = result._1().collect(Collectors.toList());

final long tableColumnCount = conditions.stream()
.filter(c -> c.equals(JDBCTableInstaller.TABLE_COLUMN + " = ?"))
.count();
assertThat(tableColumnCount).as("TABLE_COLUMN condition should appear exactly once").isEqualTo(1);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*
* 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.skywalking.oap.server.storage.plugin.jdbc.common.dao;

import org.apache.skywalking.oap.server.core.profiling.trace.ProfileThreadSnapshotRecord;
import org.apache.skywalking.oap.server.library.client.jdbc.hikaricp.JDBCClient;
import org.apache.skywalking.oap.server.storage.plugin.jdbc.common.JDBCTableInstaller;
import org.apache.skywalking.oap.server.storage.plugin.jdbc.common.TableHelper;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.junit.jupiter.MockitoSettings;
import org.mockito.quality.Strictness;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicReference;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doAnswer;

@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.LENIENT)
class JDBCProfileThreadSnapshotQueryDAOTest {

private static final String TABLE = ProfileThreadSnapshotRecord.INDEX_NAME;

@Mock
private JDBCClient jdbcClient;
@Mock
private TableHelper tableHelper;

private JDBCProfileThreadSnapshotQueryDAO dao;

@BeforeEach
void setUp() {
dao = new JDBCProfileThreadSnapshotQueryDAO(jdbcClient, tableHelper);
}

@Test
void querySegments_shouldContainTableColumnCondition() throws SQLException {
final AtomicReference<String> capturedSql = new AtomicReference<>();
doAnswer(invocation -> {
capturedSql.set(invocation.getArgument(0));
return new ArrayList<>();
}).when(jdbcClient).executeQuery(anyString(), any(), any(Object[].class));

dao.querySegments("task-1", TABLE);

assertThat(capturedSql.get()).contains(JDBCTableInstaller.TABLE_COLUMN + " = ?");
}

@Test
void querySegments_shouldFilterByTaskId() throws SQLException {
final AtomicReference<String> capturedSql = new AtomicReference<>();
doAnswer(invocation -> {
capturedSql.set(invocation.getArgument(0));
return new ArrayList<>();
}).when(jdbcClient).executeQuery(anyString(), any(), any(Object[].class));

dao.querySegments("task-abc", TABLE);

assertThat(capturedSql.get()).contains(ProfileThreadSnapshotRecord.TASK_ID + " = ?");
}

@Test
void querySegments_shouldFilterBySequenceZero() throws SQLException {
final AtomicReference<String> capturedSql = new AtomicReference<>();
doAnswer(invocation -> {
capturedSql.set(invocation.getArgument(0));
return new ArrayList<>();
}).when(jdbcClient).executeQuery(anyString(), any(), any(Object[].class));

dao.querySegments("task-1", TABLE);

assertThat(capturedSql.get()).contains(ProfileThreadSnapshotRecord.SEQUENCE + " = 0");
}
}
Loading