You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by li...@apache.org on 2020/03/20 07:55:58 UTC
[servicecomb-java-chassis] 03/04: [SCB-1796] add ut
This is an automated email from the ASF dual-hosted git repository.
liubao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-java-chassis.git
commit 8fd8241c51b33004bac19667d43f45166c822707
Author: heyile <25...@qq.com>
AuthorDate: Tue Mar 17 21:47:11 2020 +0800
[SCB-1796] add ut
---
.../servicecomb/foundation/log/core/README.md | 5 +-
.../log/core/element/impl/HttpMethodItem.java | 2 +-
.../core/element/impl/InvocationContextItem.java | 4 +-
.../log/core/element/impl/QueryStringItem.java | 2 +-
.../log/core/element/impl/RemoteHostItem.java | 8 +-
.../log/core/element/impl/RequestHeaderItem.java | 6 +-
.../log/core/element/impl/RequestProtocolItem.java | 6 +-
.../log/core/element/impl/ResponseSizeItem.java | 4 +-
.../log/core/element/impl/TraceIdItem.java | 13 +-
.../log/core/element/impl/UrlPathItem.java | 2 +-
.../core/element/impl/UrlPathWithQueryItem.java | 8 +-
.../parser/impl/VertxRestLogPatternParser.java | 4 +-
.../foundation/log/core/LogConfigTest.java | 44 +++
.../foundation/log/core/LogGeneratorTest.java | 96 ++++++
.../log/core/element/impl/CookieItemTest.java | 177 ++++++++++
.../element/impl/DatetimeConfigurableItemTest.java | 215 ++++++++++++
.../element/impl/DurationMillisecondItemTest.java | 71 ++++
.../core/element/impl/DurationSecondItemTest.java | 101 ++++++
.../element/impl/FirstLineOfRequestItemTest.java | 110 +++++++
.../log/core/element/impl/HttpMethodItemTest.java | 134 ++++++++
.../log/core/element/impl/HttpStatusItemTest.java | 102 ++++++
.../element/impl/InvocationContextItemTest.java | 151 +++++++++
.../log/core/element/impl/LocalHostItemTest.java | 120 +++++++
.../log/core/element/impl/LocalPortItemTest.java | 90 +++++
.../log/core/element/impl/PlainTextItemTest.java} | 43 ++-
.../log/core/element/impl/QueryStringItemTest.java | 157 +++++++++
.../log/core/element/impl/RemoteHostItemTest.java | 162 +++++++++
.../core/element/impl/RequestHeaderItemTest.java | 141 ++++++++
.../core/element/impl/RequestProtocolItemTest.java | 124 +++++++
.../core/element/impl/ResponseHeaderItemTest.java | 156 +++++++++
.../core/element/impl/ResponseSizeItemTest.java | 87 +++++
.../log/core/element/impl/TraceIdItemTest.java | 160 +++++++++
.../log/core/element/impl/TransportItemTest.java | 109 +++++++
.../log/core/element/impl/UrlPathItemTest.java | 156 +++++++++
.../element/impl/UrlPathWithQueryItemTest.java | 125 +++++++
.../element/impl/UserDefinedAccessLogItem.java} | 29 +-
.../impl/UserDefinedAccessLogItemLowPriority.java} | 26 +-
.../TestCompositeExtendedAccessLogItemMeta.java | 39 +++
.../impl/TestSingleExtendedAccessLogItemMeta.java | 27 ++
.../impl/VertxRestAccessLogPatternParserTest.java | 362 +++++++++++++++++++++
...foundation.log.core.parser.VertxRestLogItemMeta | 19 ++
41 files changed, 3321 insertions(+), 76 deletions(-)
diff --git a/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/README.md b/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/README.md
index 0826dbe..b9e72c2 100644
--- a/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/README.md
+++ b/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/README.md
@@ -5,9 +5,12 @@
To enable access log printing, you can config access log in microservice.yaml like below:
```yaml
servicecomb:
+ outlog:
+ enabled: true
+ pattern: "%h %SCB-transport - - %t %r %s %D"
accesslog:
enabled: true
- pattern: "%h - - %t %r %s %B"
+ pattern: "%h - - %t %r %s %B %D"
```
***Access Log Configurations in microservice.yaml***
diff --git a/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/element/impl/HttpMethodItem.java b/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/element/impl/HttpMethodItem.java
index 5303b7a..521d770 100644
--- a/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/element/impl/HttpMethodItem.java
+++ b/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/element/impl/HttpMethodItem.java
@@ -49,7 +49,7 @@ public class HttpMethodItem implements LogItem<RoutingContext> {
@Override
public void appendFormattedItem(InvocationFinishEvent finishEvent, StringBuilder builder) {
OperationMeta operationMeta = finishEvent.getInvocation().getOperationMeta();
- if (!StringUtils.isEmpty(operationMeta.getHttpMethod())) {
+ if (operationMeta != null && !StringUtils.isEmpty(operationMeta.getHttpMethod())) {
builder.append(operationMeta.getHttpMethod());
return;
}
diff --git a/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/element/impl/InvocationContextItem.java b/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/element/impl/InvocationContextItem.java
index 76c8150..483faff 100644
--- a/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/element/impl/InvocationContextItem.java
+++ b/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/element/impl/InvocationContextItem.java
@@ -50,7 +50,9 @@ public class InvocationContextItem implements LogItem<RoutingContext> {
@Override
public void appendFormattedItem(InvocationFinishEvent finishEvent, StringBuilder builder) {
- if (StringUtils.isEmpty(finishEvent.getInvocation().getContext().get(varName))) {
+ Invocation invocation = finishEvent.getInvocation();
+ if (null == invocation || invocation.getContext() == null
+ || StringUtils.isEmpty(finishEvent.getInvocation().getContext().get(varName))) {
builder.append(NOT_FOUND);
return;
}
diff --git a/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/element/impl/QueryStringItem.java b/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/element/impl/QueryStringItem.java
index efb35dd..b20ea8a 100644
--- a/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/element/impl/QueryStringItem.java
+++ b/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/element/impl/QueryStringItem.java
@@ -34,7 +34,7 @@ public class QueryStringItem implements LogItem<RoutingContext> {
@Override
public void appendFormattedItem(ServerAccessLogEvent accessLogEvent, StringBuilder builder) {
HttpServerRequest request = accessLogEvent.getRoutingContext().request();
- if (null == request || null == request.query()) {
+ if (null == request || StringUtils.isEmpty(request.query())) {
builder.append(EMPTY_RESULT);
return;
}
diff --git a/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/element/impl/RemoteHostItem.java b/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/element/impl/RemoteHostItem.java
index 0334009..a53152b 100644
--- a/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/element/impl/RemoteHostItem.java
+++ b/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/element/impl/RemoteHostItem.java
@@ -17,7 +17,7 @@
package org.apache.servicecomb.foundation.log.core.element.impl;
-
+import org.apache.commons.lang3.StringUtils;
import org.apache.servicecomb.core.Endpoint;
import org.apache.servicecomb.core.event.InvocationFinishEvent;
import org.apache.servicecomb.core.event.ServerAccessLogEvent;
@@ -34,7 +34,8 @@ public class RemoteHostItem implements LogItem<RoutingContext> {
@Override
public void appendFormattedItem(ServerAccessLogEvent accessLogEvent, StringBuilder builder) {
HttpServerRequest request = accessLogEvent.getRoutingContext().request();
- if (null == request || null == request.remoteAddress()) {
+ if (null == request || null == request.remoteAddress()
+ || StringUtils.isEmpty(request.remoteAddress().host())) {
builder.append(EMPTY_RESULT);
return;
}
@@ -44,7 +45,8 @@ public class RemoteHostItem implements LogItem<RoutingContext> {
@Override
public void appendFormattedItem(InvocationFinishEvent clientLogEvent, StringBuilder builder) {
Endpoint endpoint = clientLogEvent.getInvocation().getEndpoint();
- if (null == endpoint || null == endpoint.getAddress()) {
+ if (null == endpoint || null == endpoint.getAddress()
+ || StringUtils.isEmpty(((URIEndpointObject) endpoint.getAddress()).getHostOrIp())) {
builder.append(EMPTY_RESULT);
return;
}
diff --git a/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/element/impl/RequestHeaderItem.java b/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/element/impl/RequestHeaderItem.java
index 3ceb1ab..305493e 100644
--- a/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/element/impl/RequestHeaderItem.java
+++ b/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/element/impl/RequestHeaderItem.java
@@ -50,10 +50,10 @@ public class RequestHeaderItem implements LogItem<RoutingContext> {
@Override
public void appendFormattedItem(InvocationFinishEvent clientLogEvent, StringBuilder builder) {
RestClientRequestImpl restRequestImpl = (RestClientRequestImpl) clientLogEvent.getInvocation().getHandlerContext()
- .get(RestConst.INVOCATION_HANDLER_REQUESTCLIENT);
+ .get(RestConst.INVOCATION_HANDLER_REQUESTCLIENT);
if (null == restRequestImpl || null == restRequestImpl.getRequest()
- || null == restRequestImpl.getRequest().headers()
- || StringUtils.isEmpty(restRequestImpl.getRequest().headers().get(varName))) {
+ || null == restRequestImpl.getRequest().headers()
+ || StringUtils.isEmpty(restRequestImpl.getRequest().headers().get(varName))) {
builder.append(RESULT_NOT_FOUND);
return;
}
diff --git a/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/element/impl/RequestProtocolItem.java b/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/element/impl/RequestProtocolItem.java
index f0ecd8e..22d9216 100644
--- a/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/element/impl/RequestProtocolItem.java
+++ b/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/element/impl/RequestProtocolItem.java
@@ -45,7 +45,11 @@ public class RequestProtocolItem implements LogItem<RoutingContext> {
@Override
public void appendFormattedItem(InvocationFinishEvent finishEvent, StringBuilder builder) {
Endpoint endpoint = finishEvent.getInvocation().getEndpoint();
- builder.append(((URIEndpointObject) endpoint.getAddress()).isSslEnabled() ? "https" : "http");
+ if (endpoint == null || endpoint.getAddress() == null) {
+ builder.append(EMPTY_RESULT);
+ return;
+ }
+ builder.append(((URIEndpointObject) endpoint.getAddress()).isSslEnabled() ? "HTTPS" : "HTTP");
}
private String getStringVersion(HttpVersion version) {
diff --git a/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/element/impl/ResponseSizeItem.java b/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/element/impl/ResponseSizeItem.java
index c9bff18..1e00309 100644
--- a/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/element/impl/ResponseSizeItem.java
+++ b/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/element/impl/ResponseSizeItem.java
@@ -44,7 +44,9 @@ public class ResponseSizeItem implements LogItem<RoutingContext> {
@Override
public void appendFormattedItem(InvocationFinishEvent finishEvent, StringBuilder builder) {
- //client do not know how to calculate is write..
+ /**
+ * client do not know how to calculate is right, maybe Object#toString().length
+ */
builder.append(zeroBytes);
}
diff --git a/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/element/impl/TraceIdItem.java b/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/element/impl/TraceIdItem.java
index 5c35e92..e1b2761 100644
--- a/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/element/impl/TraceIdItem.java
+++ b/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/element/impl/TraceIdItem.java
@@ -17,10 +17,11 @@
package org.apache.servicecomb.foundation.log.core.element.impl;
+import org.apache.commons.lang3.StringUtils;
import org.apache.servicecomb.core.Const;
+import org.apache.servicecomb.core.Invocation;
import org.apache.servicecomb.core.event.InvocationFinishEvent;
import org.apache.servicecomb.core.event.ServerAccessLogEvent;
-import org.springframework.util.StringUtils;
public class TraceIdItem extends InvocationContextItem {
@@ -36,13 +37,17 @@ public class TraceIdItem extends InvocationContextItem {
if (StringUtils.isEmpty(traceId)) {
traceId = accessLogEvent.getRoutingContext().request().getHeader(TRACE_ID);
}
-
builder.append(StringUtils.isEmpty(traceId) ? InvocationContextItem.NOT_FOUND : traceId);
}
@Override
public void appendFormattedItem(InvocationFinishEvent finishEvent, StringBuilder builder) {
- String traceId = finishEvent.getInvocation().getContext().get(TRACE_ID);
- builder.append(StringUtils.isEmpty(traceId) ? InvocationContextItem.NOT_FOUND : traceId);
+ Invocation invocation = finishEvent.getInvocation();
+ if (invocation == null || invocation.getContext() == null
+ || StringUtils.isEmpty(invocation.getContext().get(TRACE_ID))) {
+ builder.append(InvocationContextItem.NOT_FOUND);
+ return;
+ }
+ builder.append(invocation.getContext().get(TRACE_ID));
}
}
diff --git a/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/element/impl/UrlPathItem.java b/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/element/impl/UrlPathItem.java
index a44d72d..bf6b45a 100644
--- a/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/element/impl/UrlPathItem.java
+++ b/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/element/impl/UrlPathItem.java
@@ -48,7 +48,7 @@ public class UrlPathItem implements LogItem<RoutingContext> {
public void appendFormattedItem(InvocationFinishEvent finishEvent, StringBuilder builder) {
OperationMeta operationMeta = finishEvent.getInvocation().getOperationMeta();
SchemaMeta schemaMeta = finishEvent.getInvocation().getSchemaMeta();
- if (operationMeta != null && schemaMeta != null) {
+ if (operationMeta != null && schemaMeta != null && schemaMeta.getSwagger() != null) {
builder.append(schemaMeta.getSwagger().getBasePath()).append(operationMeta.getOperationPath());
return;
}
diff --git a/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/element/impl/UrlPathWithQueryItem.java b/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/element/impl/UrlPathWithQueryItem.java
index febc7f6..8465677 100644
--- a/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/element/impl/UrlPathWithQueryItem.java
+++ b/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/element/impl/UrlPathWithQueryItem.java
@@ -19,6 +19,7 @@ package org.apache.servicecomb.foundation.log.core.element.impl;
import static org.apache.servicecomb.common.rest.RestConst.REST_CLIENT_REQUEST_PATH;
+import org.apache.servicecomb.core.Invocation;
import org.apache.servicecomb.core.event.InvocationFinishEvent;
import org.apache.servicecomb.core.event.ServerAccessLogEvent;
import org.apache.servicecomb.foundation.log.core.element.LogItem;
@@ -43,11 +44,12 @@ public class UrlPathWithQueryItem implements LogItem<RoutingContext> {
@Override
public void appendFormattedItem(InvocationFinishEvent finishEvent, StringBuilder builder) {
- Object path = finishEvent.getInvocation().getLocalContext(REST_CLIENT_REQUEST_PATH);
- if (null == path || StringUtils.isEmpty(path.toString())) {
+ Invocation invocation = finishEvent.getInvocation();
+ if (null == invocation || null == invocation.getLocalContext(REST_CLIENT_REQUEST_PATH)
+ || StringUtils.isEmpty(invocation.getLocalContext(REST_CLIENT_REQUEST_PATH).toString())) {
builder.append(EMPTY_RESULT);
return;
}
- builder.append(path.toString());
+ builder.append(invocation.getLocalContext(REST_CLIENT_REQUEST_PATH).toString());
}
}
diff --git a/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/parser/impl/VertxRestLogPatternParser.java b/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/parser/impl/VertxRestLogPatternParser.java
index 40e7438..c077d76 100644
--- a/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/parser/impl/VertxRestLogPatternParser.java
+++ b/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/parser/impl/VertxRestLogPatternParser.java
@@ -63,7 +63,7 @@ public class VertxRestLogPatternParser implements LogPatternParser<RoutingContex
private List<VertxRestLogItemMeta> metaList = new ArrayList<>();
public VertxRestLogPatternParser() {
- List<VertxRestLogItemMeta> loadedMeta = loadVertxRestAccessLogItemMeta();
+ List<VertxRestLogItemMeta> loadedMeta = loadVertxRestLogItemMeta();
if (null == loadedMeta || loadedMeta.isEmpty()) {
LOGGER.error("cannot load AccessLogItemMeta!");
throw new IllegalStateException("cannot load AccessLogItemMeta!");
@@ -78,7 +78,7 @@ public class VertxRestLogPatternParser implements LogPatternParser<RoutingContex
sortAccessLogItemMeta(this.metaList);
}
- private List<VertxRestLogItemMeta> loadVertxRestAccessLogItemMeta() {
+ private List<VertxRestLogItemMeta> loadVertxRestLogItemMeta() {
return SPIServiceUtils.getOrLoadSortedService(VertxRestLogItemMeta.class);
}
diff --git a/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/LogConfigTest.java b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/LogConfigTest.java
new file mode 100644
index 0000000..431a800
--- /dev/null
+++ b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/LogConfigTest.java
@@ -0,0 +1,44 @@
+/*
+ * 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.servicecomb.foundation.log.core;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+import org.apache.servicecomb.foundation.log.LogConfig;
+import org.junit.Test;
+
+public class LogConfigTest {
+
+ @Test
+ public void getAccessLogEnabled() {
+ boolean serverEnabled = LogConfig.INSTANCE.isServerLogEnabled();
+ boolean clientEnabled = LogConfig.INSTANCE.isClientLogEnabled();
+ assertFalse(serverEnabled);
+ assertFalse(clientEnabled);
+ }
+
+ @Test
+ public void getAccesslogPattern() {
+ String clientLogPattern = LogConfig.INSTANCE.getClientLogPattern();
+ String serverLogPattern = LogConfig.INSTANCE.getServerLogPattern();
+
+ assertEquals("%h - - %t %r %s %B %D", serverLogPattern);
+ assertEquals("%h %SCB-transport - - %t %r %s %D", clientLogPattern);
+ }
+}
diff --git a/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/LogGeneratorTest.java b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/LogGeneratorTest.java
new file mode 100644
index 0000000..5682f2b
--- /dev/null
+++ b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/LogGeneratorTest.java
@@ -0,0 +1,96 @@
+/*
+ * 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.servicecomb.foundation.log.core;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.when;
+
+import java.text.SimpleDateFormat;
+import java.util.TimeZone;
+
+import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.core.definition.OperationMeta;
+import org.apache.servicecomb.core.event.InvocationFinishEvent;
+import org.apache.servicecomb.core.event.ServerAccessLogEvent;
+import org.apache.servicecomb.core.invocation.InvocationStageTrace;
+import org.apache.servicecomb.foundation.log.core.element.LogItem;
+import org.apache.servicecomb.foundation.log.core.element.impl.DatetimeConfigurableItem;
+import org.apache.servicecomb.foundation.log.core.element.impl.HttpMethodItem;
+import org.apache.servicecomb.foundation.log.core.element.impl.PlainTextItem;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import io.vertx.core.http.HttpMethod;
+import io.vertx.core.http.HttpServerRequest;
+import io.vertx.ext.web.RoutingContext;
+import mockit.Deencapsulation;
+
+public class LogGeneratorTest {
+
+ private static final LogGenerator LOG_GENERATOR = new LogGenerator("%m - %t");
+
+ @Test
+ public void testConstructor() {
+ LogItem<RoutingContext>[] elements = Deencapsulation.getField(LOG_GENERATOR, "logItems");
+ assertEquals(3, elements.length);
+ assertEquals(HttpMethodItem.class, elements[0].getClass());
+ assertEquals(PlainTextItem.class, elements[1].getClass());
+ assertEquals(DatetimeConfigurableItem.class, elements[2].getClass());
+ }
+
+ @Test
+ public void testServerLog() {
+ RoutingContext context = Mockito.mock(RoutingContext.class);
+ HttpServerRequest request = Mockito.mock(HttpServerRequest.class);
+ long startMillisecond = 1416863450581L;
+ ServerAccessLogEvent serverAccessLogEvent = new ServerAccessLogEvent();
+ serverAccessLogEvent.setMilliStartTime(startMillisecond).setRoutingContext(context);
+ SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DatetimeConfigurableItem.DEFAULT_DATETIME_PATTERN,
+ DatetimeConfigurableItem.DEFAULT_LOCALE);
+ simpleDateFormat.setTimeZone(TimeZone.getDefault());
+
+ when(context.request()).thenReturn(request);
+ when(request.method()).thenReturn(HttpMethod.DELETE);
+
+ String log = LOG_GENERATOR.generateServerLog(serverAccessLogEvent);
+ Assert.assertEquals("DELETE" + " - " + simpleDateFormat.format(startMillisecond), log);
+ }
+
+ @Test
+ public void testClientLog() {
+ Invocation invocation = Mockito.mock(Invocation.class);
+ InvocationStageTrace stageTrace = Mockito.mock(InvocationStageTrace.class);
+ OperationMeta operationMeta = Mockito.mock(OperationMeta.class);
+ long startMillisecond = 1416863450581L;
+ when(stageTrace.getStartSend()).thenReturn(0L);
+ when(stageTrace.getStart()).thenReturn(0L);
+ when(stageTrace.getFinish()).thenReturn(0L);
+ when(stageTrace.getStartCurrentTime()).thenReturn(startMillisecond);
+ when(invocation.getOperationMeta()).thenReturn(operationMeta);
+ when(invocation.getInvocationStageTrace()).thenReturn(stageTrace);
+
+ InvocationFinishEvent finishEvent = new InvocationFinishEvent(invocation, null);
+ SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DatetimeConfigurableItem.DEFAULT_DATETIME_PATTERN,
+ DatetimeConfigurableItem.DEFAULT_LOCALE);
+ simpleDateFormat.setTimeZone(TimeZone.getDefault());
+ when(operationMeta.getHttpMethod()).thenReturn(HttpMethod.DELETE.toString());
+ String log = LOG_GENERATOR.generateClientLog(finishEvent);
+ Assert.assertEquals("DELETE" + " - " + simpleDateFormat.format(startMillisecond), log);
+ }
+}
diff --git a/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/CookieItemTest.java b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/CookieItemTest.java
new file mode 100644
index 0000000..f31f711
--- /dev/null
+++ b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/CookieItemTest.java
@@ -0,0 +1,177 @@
+/*
+ * 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.servicecomb.foundation.log.core.element.impl;
+
+import static org.mockito.Mockito.when;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.servicecomb.common.rest.RestConst;
+import org.apache.servicecomb.common.rest.codec.param.RestClientRequestImpl;
+import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.core.event.InvocationFinishEvent;
+import org.apache.servicecomb.core.event.ServerAccessLogEvent;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import io.vertx.core.http.Cookie;
+import io.vertx.ext.web.RoutingContext;
+import io.vertx.ext.web.impl.CookieImpl;
+
+public class CookieItemTest {
+
+ public static final String COOKIE_NAME = "cookieName";
+
+ public static final String COOKIE_VALUE = "cookieVALUE";
+
+ private static final CookieItem ELEMENT = new CookieItem(COOKIE_NAME);
+
+ private StringBuilder strBuilder;
+
+ private InvocationFinishEvent finishEvent;
+
+ private ServerAccessLogEvent accessLogEvent;
+
+ private RoutingContext mockContext;
+
+ private Invocation invocation;
+
+ private RestClientRequestImpl restClientRequest;
+
+ @Before
+ public void initStrBuilder() {
+ mockContext = Mockito.mock(RoutingContext.class);
+ finishEvent = Mockito.mock(InvocationFinishEvent.class);
+ invocation = Mockito.mock(Invocation.class);
+ restClientRequest = Mockito.mock(RestClientRequestImpl.class);
+
+ accessLogEvent = new ServerAccessLogEvent();
+ strBuilder = new StringBuilder();
+ }
+
+ @Test
+ public void serverFormattedElement() {
+ HashMap<String, Cookie> cookieSet = new HashMap<>();
+ CookieImpl cookie = new CookieImpl(COOKIE_NAME, COOKIE_VALUE);
+
+ cookieSet.put(cookie.getName(), cookie);
+ when(mockContext.cookieCount()).thenReturn(1);
+ when(mockContext.cookieMap()).thenReturn(cookieSet);
+ accessLogEvent.setRoutingContext(mockContext);
+
+ ELEMENT.appendFormattedItem(accessLogEvent, strBuilder);
+ Assert.assertEquals(COOKIE_VALUE, strBuilder.toString());
+ }
+
+ @Test
+ public void clientFormattedElement() {
+ Map<String, Object> handlerMap = new HashMap<>();
+ handlerMap.put(RestConst.INVOCATION_HANDLER_REQUESTCLIENT, restClientRequest);
+
+ Map<String, String> cookieMap = new HashMap<>();
+ cookieMap.put(COOKIE_NAME, COOKIE_VALUE);
+
+ when(finishEvent.getInvocation()).thenReturn(invocation);
+ when(invocation.getHandlerContext()).thenReturn(handlerMap);
+ when(restClientRequest.getCookieMap()).thenReturn(cookieMap);
+
+ ELEMENT.appendFormattedItem(finishEvent, strBuilder);
+ Assert.assertEquals(COOKIE_VALUE, strBuilder.toString());
+ }
+
+ @Test
+ public void serverFormattedElementOnCookieCountIsZero() {
+ HashMap<String, Cookie> cookieSet = new HashMap<>();
+ Mockito.when(mockContext.cookieCount()).thenReturn(0);
+ Mockito.when(mockContext.cookieMap()).thenReturn(cookieSet);
+ accessLogEvent.setRoutingContext(mockContext);
+
+ ELEMENT.appendFormattedItem(accessLogEvent, strBuilder);
+ Assert.assertEquals("-", strBuilder.toString());
+ }
+
+ @Test
+ public void clientFormattedElementOnCookieCountIsZero() {
+ Map<String, Object> handlerMap = new HashMap<>();
+ handlerMap.put(RestConst.INVOCATION_HANDLER_REQUESTCLIENT, restClientRequest);
+ Map<String, String> cookieMap = new HashMap<>();
+
+ when(finishEvent.getInvocation()).thenReturn(invocation);
+ when(invocation.getHandlerContext()).thenReturn(handlerMap);
+ when(restClientRequest.getCookieMap()).thenReturn(cookieMap);
+
+ ELEMENT.appendFormattedItem(finishEvent, strBuilder);
+ Assert.assertEquals("-", strBuilder.toString());
+ }
+
+
+ @Test
+ public void serverFormattedElementOnCookieSetIsNull() {
+ Mockito.when(mockContext.cookieCount()).thenReturn(1);
+ Mockito.when(mockContext.cookieMap()).thenReturn(null);
+ accessLogEvent.setRoutingContext(mockContext);
+
+ ELEMENT.appendFormattedItem(accessLogEvent, strBuilder);
+ Assert.assertEquals("-", strBuilder.toString());
+ }
+
+ @Test
+ public void clientFormattedElementOnCookieSetIsNull() {
+ Map<String, Object> handlerMap = new HashMap<>();
+ handlerMap.put(RestConst.INVOCATION_HANDLER_REQUESTCLIENT, restClientRequest);
+
+ when(finishEvent.getInvocation()).thenReturn(invocation);
+ when(invocation.getHandlerContext()).thenReturn(handlerMap);
+ when(restClientRequest.getCookieMap()).thenReturn(null);
+
+ ELEMENT.appendFormattedItem(finishEvent, strBuilder);
+ Assert.assertEquals("-", strBuilder.toString());
+ }
+
+
+ @Test
+ public void serverFormattedElementOnNotFound() {
+ HashMap<String, Cookie> cookieSet = new HashMap<>();
+ CookieImpl cookie = new CookieImpl("anotherCookieName", COOKIE_VALUE);
+ cookieSet.put(cookie.getName(), cookie);
+ Mockito.when(mockContext.cookieCount()).thenReturn(1);
+ Mockito.when(mockContext.cookieMap()).thenReturn(cookieSet);
+ accessLogEvent.setRoutingContext(mockContext);
+
+ ELEMENT.appendFormattedItem(accessLogEvent, strBuilder);
+ Assert.assertEquals("-", strBuilder.toString());
+ }
+
+ @Test
+ public void clientFormattedElementOnNotFound() {
+ Map<String, Object> handlerMap = new HashMap<>();
+ handlerMap.put(RestConst.INVOCATION_HANDLER_REQUESTCLIENT, restClientRequest);
+
+ Map<String, String> cookieMap = new HashMap<>();
+ cookieMap.put("anotherCookieValue", COOKIE_VALUE);
+ when(finishEvent.getInvocation()).thenReturn(invocation);
+ when(invocation.getHandlerContext()).thenReturn(handlerMap);
+ when(restClientRequest.getCookieMap()).thenReturn(cookieMap);
+
+ ELEMENT.appendFormattedItem(finishEvent, strBuilder);
+ Assert.assertEquals("-", strBuilder.toString());
+ }
+}
diff --git a/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/DatetimeConfigurableItemTest.java b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/DatetimeConfigurableItemTest.java
new file mode 100644
index 0000000..22bbffc
--- /dev/null
+++ b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/DatetimeConfigurableItemTest.java
@@ -0,0 +1,215 @@
+/*
+ * 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.servicecomb.foundation.log.core.element.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.when;
+
+import java.text.SimpleDateFormat;
+import java.util.Locale;
+import java.util.TimeZone;
+
+import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.core.event.InvocationFinishEvent;
+import org.apache.servicecomb.core.event.ServerAccessLogEvent;
+import org.apache.servicecomb.core.invocation.InvocationStageTrace;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+public class DatetimeConfigurableItemTest {
+
+ private static final long START_MILLISECOND = 1416863450581L;
+
+ private StringBuilder strBuilder;
+
+ private InvocationFinishEvent finishEvent;
+
+ private ServerAccessLogEvent accessLogEvent;
+
+ private Invocation invocation;
+
+ private InvocationStageTrace invocationStageTrace;
+
+ @Before
+ public void initStrBuilder() {
+ finishEvent = Mockito.mock(InvocationFinishEvent.class);
+ invocation = Mockito.mock(Invocation.class);
+ invocationStageTrace = Mockito.mock(InvocationStageTrace.class);
+
+ when(finishEvent.getInvocation()).thenReturn(invocation);
+ when(invocation.getInvocationStageTrace()).thenReturn(invocationStageTrace);
+ when(invocationStageTrace.getStartSend()).thenReturn(0L);
+ when(invocationStageTrace.getStart()).thenReturn(0L);
+ when(invocationStageTrace.getStartCurrentTime()).thenReturn(START_MILLISECOND);
+
+ accessLogEvent = new ServerAccessLogEvent();
+ accessLogEvent.setMilliStartTime(START_MILLISECOND);
+ strBuilder = new StringBuilder();
+ }
+
+ @Test
+ public void serverFormattedElement() {
+ DatetimeConfigurableItem element = new DatetimeConfigurableItem(
+ "EEE, yyyy MMM dd HH:mm:ss zzz|GMT-08|zh-CN");
+ element.appendFormattedItem(accessLogEvent, strBuilder);
+ assertEquals("星期一, 2014 十一月 24 13:10:50 GMT-08:00", strBuilder.toString());
+ }
+
+ @Test
+ public void clientFormattedElement() {
+ DatetimeConfigurableItem element = new DatetimeConfigurableItem(
+ "EEE, yyyy MMM dd HH:mm:ss zzz|GMT-08|zh-CN");
+ element.appendFormattedItem(finishEvent, strBuilder);
+ assertEquals("星期一, 2014 十一月 24 13:10:50 GMT-08:00", strBuilder.toString());
+ }
+
+ @Test
+ public void serverFormattedElementOnNoPattern() {
+ DatetimeConfigurableItem element = new DatetimeConfigurableItem(
+ "|GMT+08|zh-CN");
+
+ element.appendFormattedItem(accessLogEvent, strBuilder);
+ assertEquals("星期二, 25 十一月 2014 05:10:50 GMT+08:00", strBuilder.toString());
+ }
+
+ @Test
+ public void clientFormattedElementOnNoPattern() {
+ DatetimeConfigurableItem element = new DatetimeConfigurableItem(
+ "|GMT+08|zh-CN");
+
+ element.appendFormattedItem(finishEvent, strBuilder);
+ assertEquals("星期二, 25 十一月 2014 05:10:50 GMT+08:00", strBuilder.toString());
+ }
+
+ @Test
+ public void getFormattedElementOnNoTimezone() {
+ DatetimeConfigurableItem element = new DatetimeConfigurableItem(
+ "yyyy/MM/dd zzz||zh-CN");
+ SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd zzz", Locale.forLanguageTag("zh-CN"));
+ simpleDateFormat.setTimeZone(TimeZone.getDefault());
+
+ element.appendFormattedItem(accessLogEvent, strBuilder);
+ assertEquals(simpleDateFormat.format(START_MILLISECOND), strBuilder.toString());
+ }
+
+ @Test
+ public void clientFormattedElementOnNoTimezone() {
+ DatetimeConfigurableItem element = new DatetimeConfigurableItem(
+ "yyyy/MM/dd zzz||zh-CN");
+ SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd zzz", Locale.forLanguageTag("zh-CN"));
+ simpleDateFormat.setTimeZone(TimeZone.getDefault());
+
+ element.appendFormattedItem(finishEvent, strBuilder);
+ assertEquals(simpleDateFormat.format(START_MILLISECOND), strBuilder.toString());
+ }
+
+ @Test
+ public void serverFormattedElementOnNoLocale() {
+ DatetimeConfigurableItem element = new DatetimeConfigurableItem(
+ "EEE, dd MMM yyyy HH:mm:ss zzz|GMT+08|");
+
+ element.appendFormattedItem(accessLogEvent, strBuilder);
+ assertEquals("Tue, 25 Nov 2014 05:10:50 GMT+08:00", strBuilder.toString());
+ }
+
+ @Test
+ public void clientFormattedElementOnNoLocale() {
+ DatetimeConfigurableItem element = new DatetimeConfigurableItem(
+ "EEE, dd MMM yyyy HH:mm:ss zzz|GMT+08|");
+
+ element.appendFormattedItem(finishEvent, strBuilder);
+ assertEquals("Tue, 25 Nov 2014 05:10:50 GMT+08:00", strBuilder.toString());
+ }
+
+ @Test
+ public void serverFormattedElementOnNoConfig() {
+ DatetimeConfigurableItem element = new DatetimeConfigurableItem(
+ "||");
+ SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DatetimeConfigurableItem.DEFAULT_DATETIME_PATTERN,
+ Locale.US);
+ simpleDateFormat.setTimeZone(TimeZone.getDefault());
+
+ element.appendFormattedItem(accessLogEvent, strBuilder);
+ assertEquals(simpleDateFormat.format(START_MILLISECOND), strBuilder.toString());
+ }
+
+ @Test
+ public void clientFormattedElementOnNoConfig() {
+ DatetimeConfigurableItem element = new DatetimeConfigurableItem(
+ "||");
+ SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DatetimeConfigurableItem.DEFAULT_DATETIME_PATTERN,
+ Locale.US);
+ simpleDateFormat.setTimeZone(TimeZone.getDefault());
+
+ element.appendFormattedItem(finishEvent, strBuilder);
+ assertEquals(simpleDateFormat.format(START_MILLISECOND), strBuilder.toString());
+ }
+
+ @Test
+ public void serverConstructorWithNoArg() {
+ DatetimeConfigurableItem element = new DatetimeConfigurableItem();
+ SimpleDateFormat simpleDateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US);
+ simpleDateFormat.setTimeZone(TimeZone.getDefault());
+
+ element.appendFormattedItem(accessLogEvent, strBuilder);
+ assertEquals("EEE, dd MMM yyyy HH:mm:ss zzz", element.getPattern());
+ assertEquals(Locale.US, element.getLocale());
+ assertEquals(TimeZone.getDefault(), element.getTimezone());
+ assertEquals(simpleDateFormat.format(START_MILLISECOND), strBuilder.toString());
+ }
+
+ @Test
+ public void clientConstructorWithNoArg() {
+ DatetimeConfigurableItem element = new DatetimeConfigurableItem();
+ SimpleDateFormat simpleDateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US);
+ simpleDateFormat.setTimeZone(TimeZone.getDefault());
+
+ element.appendFormattedItem(finishEvent, strBuilder);
+ assertEquals("EEE, dd MMM yyyy HH:mm:ss zzz", element.getPattern());
+ assertEquals(Locale.US, element.getLocale());
+ assertEquals(TimeZone.getDefault(), element.getTimezone());
+ assertEquals(simpleDateFormat.format(START_MILLISECOND), strBuilder.toString());
+ }
+
+ @Test
+ public void serverConstructorWithNoSeparator() {
+ DatetimeConfigurableItem element = new DatetimeConfigurableItem("yyyy/MM/dd HH:mm:ss zzz");
+ SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss zzz", Locale.US);
+ simpleDateFormat.setTimeZone(TimeZone.getDefault());
+
+ element.appendFormattedItem(accessLogEvent, strBuilder);
+ assertEquals("yyyy/MM/dd HH:mm:ss zzz", element.getPattern());
+ assertEquals(Locale.US, element.getLocale());
+ assertEquals(TimeZone.getDefault(), element.getTimezone());
+ assertEquals(simpleDateFormat.format(START_MILLISECOND), strBuilder.toString());
+ }
+
+ @Test
+ public void clientConstructorWithNoSeparator() {
+ DatetimeConfigurableItem element = new DatetimeConfigurableItem("yyyy/MM/dd HH:mm:ss zzz");
+ SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss zzz", Locale.US);
+ simpleDateFormat.setTimeZone(TimeZone.getDefault());
+
+ element.appendFormattedItem(finishEvent, strBuilder);
+ assertEquals("yyyy/MM/dd HH:mm:ss zzz", element.getPattern());
+ assertEquals(Locale.US, element.getLocale());
+ assertEquals(TimeZone.getDefault(), element.getTimezone());
+ assertEquals(simpleDateFormat.format(START_MILLISECOND), strBuilder.toString());
+ }
+}
diff --git a/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/DurationMillisecondItemTest.java b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/DurationMillisecondItemTest.java
new file mode 100644
index 0000000..231aae8
--- /dev/null
+++ b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/DurationMillisecondItemTest.java
@@ -0,0 +1,71 @@
+/*
+ * 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.servicecomb.foundation.log.core.element.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.when;
+
+import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.core.event.InvocationFinishEvent;
+import org.apache.servicecomb.core.event.ServerAccessLogEvent;
+import org.apache.servicecomb.core.invocation.InvocationStageTrace;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+public class DurationMillisecondItemTest {
+
+ public static final DurationMillisecondItem ELEMENT = new DurationMillisecondItem();
+
+ private StringBuilder strBuilder;
+
+ private InvocationFinishEvent finishEvent;
+
+ private ServerAccessLogEvent accessLogEvent;
+
+ private Invocation invocation;
+
+ private InvocationStageTrace invocationStageTrace;
+
+ @Before
+ public void initStrBuilder() {
+ finishEvent = Mockito.mock(InvocationFinishEvent.class);
+ invocation = Mockito.mock(Invocation.class);
+ invocationStageTrace = Mockito.mock(InvocationStageTrace.class);
+
+ when(finishEvent.getInvocation()).thenReturn(invocation);
+ when(invocation.getInvocationStageTrace()).thenReturn(invocationStageTrace);
+ when(invocationStageTrace.getStartSend()).thenReturn(0L);
+ when(invocationStageTrace.getFinish()).thenReturn(1000_000L);
+
+ accessLogEvent = new ServerAccessLogEvent();
+ accessLogEvent.setMilliStartTime(1L);
+ accessLogEvent.setMilliEndTime(2L);
+ strBuilder = new StringBuilder();
+ }
+
+ @Test
+ public void testAppendFormattedElement() {
+ ELEMENT.appendFormattedItem(accessLogEvent, strBuilder);
+ assertEquals("1", strBuilder.toString());
+
+ strBuilder = new StringBuilder();
+ ELEMENT.appendFormattedItem(finishEvent, strBuilder);
+ assertEquals("1", strBuilder.toString());
+ }
+}
diff --git a/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/DurationSecondItemTest.java b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/DurationSecondItemTest.java
new file mode 100644
index 0000000..2e983eb
--- /dev/null
+++ b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/DurationSecondItemTest.java
@@ -0,0 +1,101 @@
+/*
+ * 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.servicecomb.foundation.log.core.element.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.when;
+
+import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.core.event.InvocationFinishEvent;
+import org.apache.servicecomb.core.event.ServerAccessLogEvent;
+import org.apache.servicecomb.core.invocation.InvocationStageTrace;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+public class DurationSecondItemTest {
+
+ public static final DurationSecondItem ELEMENT = new DurationSecondItem();
+
+ private StringBuilder strBuilder;
+
+ private InvocationFinishEvent finishEvent;
+
+ private ServerAccessLogEvent accessLogEvent;
+
+ private Invocation invocation;
+
+ private InvocationStageTrace invocationStageTrace;
+
+ @Before
+ public void initStrBuilder() {
+ finishEvent = Mockito.mock(InvocationFinishEvent.class);
+ invocation = Mockito.mock(Invocation.class);
+ invocationStageTrace = Mockito.mock(InvocationStageTrace.class);
+
+ when(finishEvent.getInvocation()).thenReturn(invocation);
+ when(invocation.getInvocationStageTrace()).thenReturn(invocationStageTrace);
+ when(invocationStageTrace.getStartSend()).thenReturn(1000_000L);
+
+ accessLogEvent = new ServerAccessLogEvent();
+ accessLogEvent.setMilliStartTime(1L);
+ strBuilder = new StringBuilder();
+ }
+
+ @Test
+ public void serverFormattedElementOn999ms() {
+ accessLogEvent.setMilliEndTime(1000L);
+ ELEMENT.appendFormattedItem(accessLogEvent, strBuilder);
+ assertEquals("0", strBuilder.toString());
+ }
+
+ @Test
+ public void clientFormattedElementOn999ms() {
+ when(invocationStageTrace.getFinish()).thenReturn(1000_000_000L);
+ ELEMENT.appendFormattedItem(finishEvent, strBuilder);
+ assertEquals("0", strBuilder.toString());
+ }
+
+ @Test
+ public void serverFormattedElementOn1000ms() {
+ accessLogEvent.setMilliEndTime(1001L);
+ ELEMENT.appendFormattedItem(accessLogEvent, strBuilder);
+ assertEquals("1", strBuilder.toString());
+ }
+
+ @Test
+ public void clientFormattedElementOn1000ms() {
+ when(invocationStageTrace.getFinish()).thenReturn(1001_000_000L);
+ ELEMENT.appendFormattedItem(finishEvent, strBuilder);
+ assertEquals("1", strBuilder.toString());
+ }
+
+ @Test
+ public void serverFormattedElementOn1001ms() {
+ accessLogEvent.setMilliEndTime(1002L);
+ ELEMENT.appendFormattedItem(accessLogEvent, strBuilder);
+ assertEquals("1", strBuilder.toString());
+ }
+
+ @Test
+ public void clientFormattedElementOn1001ms() {
+ when(invocationStageTrace.getFinish()).thenReturn(1002_000_000L);
+ ELEMENT.appendFormattedItem(finishEvent, strBuilder);
+ assertEquals("1", strBuilder.toString());
+ }
+}
diff --git a/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/FirstLineOfRequestItemTest.java b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/FirstLineOfRequestItemTest.java
new file mode 100644
index 0000000..bf971ac
--- /dev/null
+++ b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/FirstLineOfRequestItemTest.java
@@ -0,0 +1,110 @@
+/*
+ * 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.servicecomb.foundation.log.core.element.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.when;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.servicecomb.common.rest.RestConst;
+import org.apache.servicecomb.common.rest.codec.param.RestClientRequestImpl;
+import org.apache.servicecomb.core.Endpoint;
+import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.core.event.InvocationFinishEvent;
+import org.apache.servicecomb.core.event.ServerAccessLogEvent;
+import org.apache.servicecomb.foundation.common.net.URIEndpointObject;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import io.vertx.core.http.HttpClientRequest;
+import io.vertx.core.http.HttpMethod;
+import io.vertx.core.http.HttpServerRequest;
+import io.vertx.core.http.HttpVersion;
+import io.vertx.ext.web.RoutingContext;
+
+public class FirstLineOfRequestItemTest {
+
+ public static final FirstLineOfRequestItem ELEMENT = new FirstLineOfRequestItem();
+
+ private StringBuilder strBuilder;
+
+ private InvocationFinishEvent finishEvent;
+
+ private ServerAccessLogEvent accessLogEvent;
+
+ private RoutingContext mockContext;
+
+ private Invocation invocation;
+
+ private RestClientRequestImpl restClientRequest;
+
+ private HttpClientRequest clientRequest;
+
+ private Endpoint endpoint;
+
+ private URIEndpointObject urlEndpoint;
+
+ @Before
+ public void initStrBuilder() {
+ mockContext = Mockito.mock(RoutingContext.class);
+ finishEvent = Mockito.mock(InvocationFinishEvent.class);
+ invocation = Mockito.mock(Invocation.class);
+ restClientRequest = Mockito.mock(RestClientRequestImpl.class);
+ clientRequest = Mockito.mock(HttpClientRequest.class);
+ endpoint = Mockito.mock(Endpoint.class);
+ urlEndpoint = Mockito.mock(URIEndpointObject.class);
+ Map<String, Object> handlerMap = new HashMap<>();
+ handlerMap.put(RestConst.INVOCATION_HANDLER_REQUESTCLIENT, restClientRequest);
+ when(finishEvent.getInvocation()).thenReturn(invocation);
+ when(invocation.getHandlerContext()).thenReturn(handlerMap);
+ when(restClientRequest.getRequest()).thenReturn(clientRequest);
+ when(invocation.getEndpoint()).thenReturn(endpoint);
+ when(endpoint.getAddress()).thenReturn(urlEndpoint);
+ accessLogEvent = new ServerAccessLogEvent();
+ accessLogEvent.setRoutingContext(mockContext);
+ strBuilder = new StringBuilder();
+ }
+
+ @Test
+ public void serverFormattedElement() {
+ HttpServerRequest request = Mockito.mock(HttpServerRequest.class);
+ String uri = "/test/uri";
+
+ when(mockContext.request()).thenReturn(request);
+ when(request.method()).thenReturn(HttpMethod.DELETE);
+ when(request.path()).thenReturn(uri);
+ when(request.version()).thenReturn(HttpVersion.HTTP_1_1);
+
+ ELEMENT.appendFormattedItem(accessLogEvent, strBuilder);
+ assertEquals("\"DELETE " + uri + " HTTP/1.1\"", strBuilder.toString());
+ }
+
+ @Test
+ public void clientFormattedElement() {
+ String uri = "/test/uri";
+ when(urlEndpoint.isSslEnabled()).thenReturn(false);
+ when(clientRequest.method()).thenReturn(HttpMethod.DELETE);
+ when(clientRequest.path()).thenReturn(uri);
+
+ ELEMENT.appendFormattedItem(finishEvent, strBuilder);
+ assertEquals("\"DELETE " + uri + " HTTP\"", strBuilder.toString());
+ }
+}
diff --git a/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/HttpMethodItemTest.java b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/HttpMethodItemTest.java
new file mode 100644
index 0000000..012a965
--- /dev/null
+++ b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/HttpMethodItemTest.java
@@ -0,0 +1,134 @@
+/*
+ * 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.servicecomb.foundation.log.core.element.impl;
+
+import static org.mockito.Mockito.when;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.servicecomb.common.rest.RestConst;
+import org.apache.servicecomb.common.rest.codec.param.RestClientRequestImpl;
+import org.apache.servicecomb.core.Endpoint;
+import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.core.event.InvocationFinishEvent;
+import org.apache.servicecomb.core.event.ServerAccessLogEvent;
+import org.apache.servicecomb.foundation.common.net.URIEndpointObject;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import io.vertx.core.http.HttpClientRequest;
+import io.vertx.core.http.HttpMethod;
+import io.vertx.core.http.HttpServerRequest;
+import io.vertx.ext.web.RoutingContext;
+
+public class HttpMethodItemTest {
+ private static final HttpMethodItem ITEM = new HttpMethodItem();
+
+ private StringBuilder strBuilder;
+
+ private InvocationFinishEvent finishEvent;
+
+ private ServerAccessLogEvent accessLogEvent;
+
+ private RoutingContext routingContext;
+
+ private Invocation invocation;
+
+ private RestClientRequestImpl restClientRequest;
+
+ private HttpClientRequest clientRequest;
+
+ private Endpoint endpoint;
+
+ private URIEndpointObject urlEndpoint;
+
+ @Before
+ public void initStrBuilder() {
+ routingContext = Mockito.mock(RoutingContext.class);
+ finishEvent = Mockito.mock(InvocationFinishEvent.class);
+ invocation = Mockito.mock(Invocation.class);
+ restClientRequest = Mockito.mock(RestClientRequestImpl.class);
+ clientRequest = Mockito.mock(HttpClientRequest.class);
+ endpoint = Mockito.mock(Endpoint.class);
+ urlEndpoint = Mockito.mock(URIEndpointObject.class);
+ Map<String, Object> handlerMap = new HashMap<>();
+ handlerMap.put(RestConst.INVOCATION_HANDLER_REQUESTCLIENT, restClientRequest);
+ when(finishEvent.getInvocation()).thenReturn(invocation);
+ when(invocation.getHandlerContext()).thenReturn(handlerMap);
+ when(invocation.getEndpoint()).thenReturn(endpoint);
+ when(endpoint.getAddress()).thenReturn(urlEndpoint);
+ accessLogEvent = new ServerAccessLogEvent();
+ accessLogEvent.setRoutingContext(routingContext);
+ strBuilder = new StringBuilder();
+ }
+
+ @Test
+ public void serverFormattedElement() {
+ HttpServerRequest request = Mockito.mock(HttpServerRequest.class);
+ Mockito.when(routingContext.request()).thenReturn(request);
+ Mockito.when(request.method()).thenReturn(HttpMethod.DELETE);
+ accessLogEvent.setRoutingContext(routingContext);
+ ITEM.appendFormattedItem(accessLogEvent, strBuilder);
+ Assert.assertEquals("DELETE", strBuilder.toString());
+ }
+
+ @Test
+ public void clientFormattedElement() {
+ when(restClientRequest.getRequest()).thenReturn(clientRequest);
+ when(clientRequest.method()).thenReturn(HttpMethod.DELETE);
+ ITEM.appendFormattedItem(finishEvent, strBuilder);
+ Assert.assertEquals("DELETE", strBuilder.toString());
+ }
+
+ @Test
+ public void serverFormattedElementOnRequestIsNull() {
+ accessLogEvent.setRoutingContext(routingContext);
+ Mockito.when(routingContext.request()).thenReturn(null);
+ ITEM.appendFormattedItem(accessLogEvent, strBuilder);
+ Assert.assertEquals("-", strBuilder.toString());
+ }
+
+ @Test
+ public void clientFormattedElementOnRequestIsNull() {
+ when(restClientRequest.getRequest()).thenReturn(null);
+ ITEM.appendFormattedItem(finishEvent, strBuilder);
+ Assert.assertEquals("-", strBuilder.toString());
+ }
+
+
+ @Test
+ public void serverFormattedElementOnMethodIsNull() {
+ HttpServerRequest request = Mockito.mock(HttpServerRequest.class);
+ accessLogEvent.setRoutingContext(routingContext);
+
+ Mockito.when(routingContext.request()).thenReturn(request);
+ Mockito.when(request.method()).thenReturn(null);
+ ITEM.appendFormattedItem(accessLogEvent, strBuilder);
+ Assert.assertEquals("-", strBuilder.toString());
+ }
+
+ @Test
+ public void clientFormattedElementOnMethodIsNull() {
+ when(clientRequest.method()).thenReturn(null);
+ ITEM.appendFormattedItem(finishEvent, strBuilder);
+ Assert.assertEquals("-", strBuilder.toString());
+ }
+}
diff --git a/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/HttpStatusItemTest.java b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/HttpStatusItemTest.java
new file mode 100644
index 0000000..6a43b88
--- /dev/null
+++ b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/HttpStatusItemTest.java
@@ -0,0 +1,102 @@
+/*
+ * 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.servicecomb.foundation.log.core.element.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.when;
+
+import org.apache.servicecomb.core.event.InvocationFinishEvent;
+import org.apache.servicecomb.core.event.ServerAccessLogEvent;
+import org.apache.servicecomb.swagger.invocation.Response;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import io.vertx.core.http.HttpServerResponse;
+import io.vertx.ext.web.RoutingContext;
+
+public class HttpStatusItemTest {
+
+ private static final HttpStatusItem STATUS_ELEMENT = new HttpStatusItem();
+
+ private StringBuilder strBuilder;
+
+ private InvocationFinishEvent finishEvent;
+
+ private ServerAccessLogEvent accessLogEvent;
+
+ private RoutingContext routingContext;
+
+ private Response response;
+
+ private HttpServerResponse serverResponse;
+
+ @Before
+ public void initStrBuilder() {
+ routingContext = Mockito.mock(RoutingContext.class);
+ finishEvent = Mockito.mock(InvocationFinishEvent.class);
+ response = Mockito.mock(Response.class);
+ serverResponse = Mockito.mock(HttpServerResponse.class);
+
+ accessLogEvent = new ServerAccessLogEvent();
+ accessLogEvent.setRoutingContext(routingContext);
+ strBuilder = new StringBuilder();
+ }
+
+ @Test
+ public void serverFormattedElement() {
+ int statusCode = 200;
+ when(routingContext.response()).thenReturn(serverResponse);
+ when(serverResponse.getStatusCode()).thenReturn(statusCode);
+
+ STATUS_ELEMENT.appendFormattedItem(accessLogEvent, strBuilder);
+ assertEquals("200", strBuilder.toString());
+ }
+
+ @Test
+ public void clientFormattedElement() {
+ int statusCode = 200;
+ when(finishEvent.getResponse()).thenReturn(response);
+ when(response.getStatusCode()).thenReturn(statusCode);
+
+ STATUS_ELEMENT.appendFormattedItem(finishEvent, strBuilder);
+ assertEquals("200", strBuilder.toString());
+ }
+
+ @Test
+ public void serverFormattedElementOnResponseIsNull() {
+ Mockito.when(routingContext.response()).thenReturn(null);
+ STATUS_ELEMENT.appendFormattedItem(accessLogEvent, strBuilder);
+ assertEquals("-", strBuilder.toString());
+
+ Mockito.when(routingContext.response()).thenReturn(serverResponse);
+ Mockito.when(serverResponse.closed()).thenReturn(true);
+ Mockito.when(serverResponse.ended()).thenReturn(false);
+
+ strBuilder = new StringBuilder();
+ STATUS_ELEMENT.appendFormattedItem(accessLogEvent, strBuilder);
+ assertEquals("-", strBuilder.toString());
+ }
+
+ @Test
+ public void clientFormattedElementOnResponseIsNull() {
+ when(finishEvent.getResponse()).thenReturn(null);
+ STATUS_ELEMENT.appendFormattedItem(finishEvent, strBuilder);
+ assertEquals("-", strBuilder.toString());
+ }
+}
diff --git a/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/InvocationContextItemTest.java b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/InvocationContextItemTest.java
new file mode 100644
index 0000000..48952d4
--- /dev/null
+++ b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/InvocationContextItemTest.java
@@ -0,0 +1,151 @@
+/*
+ * 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.servicecomb.foundation.log.core.element.impl;
+
+import static org.mockito.Mockito.when;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.servicecomb.common.rest.RestConst;
+import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.core.event.InvocationFinishEvent;
+import org.apache.servicecomb.core.event.ServerAccessLogEvent;
+import org.hamcrest.Matchers;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import io.vertx.ext.web.RoutingContext;
+
+public class InvocationContextItemTest {
+
+ public static final String INVOCATION_CONTEXT_KEY = "testKey";
+
+ public static final String INVOCATION_CONTEXT_VALUE = "testValue";
+
+ private static InvocationContextItem ITEM = new InvocationContextItem(INVOCATION_CONTEXT_KEY);
+
+ private StringBuilder strBuilder;
+
+ private InvocationFinishEvent finishEvent;
+
+ private ServerAccessLogEvent accessLogEvent;
+
+ private RoutingContext routingContext;
+
+ private Invocation invocation;
+
+ @Before
+ public void initStrBuilder() {
+ accessLogEvent = new ServerAccessLogEvent();
+ routingContext = Mockito.mock(RoutingContext.class);
+ finishEvent = Mockito.mock(InvocationFinishEvent.class);
+ invocation = Mockito.mock(Invocation.class);
+
+ accessLogEvent.setRoutingContext(routingContext);
+ strBuilder = new StringBuilder();
+ }
+
+ @Test
+ public void serverGetFormattedItem() {
+ Map<String, Object> routingContextData = new HashMap<>();
+ when(routingContext.data()).thenReturn(routingContextData);
+ routingContextData.put(RestConst.REST_INVOCATION_CONTEXT, invocation);
+ when(invocation.getContext(INVOCATION_CONTEXT_KEY)).thenReturn(INVOCATION_CONTEXT_VALUE);
+
+ ITEM.appendFormattedItem(accessLogEvent, strBuilder);
+ Assert.assertThat(strBuilder.toString(), Matchers.is(INVOCATION_CONTEXT_VALUE));
+ }
+
+ @Test
+ public void clientGetFormattedItem() {
+ Map<String, String> context = new HashMap<>();
+ when(finishEvent.getInvocation()).thenReturn(invocation);
+ when(invocation.getContext()).thenReturn(context);
+ context.put(INVOCATION_CONTEXT_KEY, INVOCATION_CONTEXT_VALUE);
+
+ ITEM.appendFormattedItem(finishEvent, strBuilder);
+ Assert.assertThat(strBuilder.toString(), Matchers.is(INVOCATION_CONTEXT_VALUE));
+ }
+
+ @Test
+ public void serverGetFormattedItemOnInvocationContextValueNotFound() {
+ Map<String, Object> routingContextData = new HashMap<>();
+ Invocation invocation = Mockito.mock(Invocation.class);
+ when(routingContext.data()).thenReturn(routingContextData);
+ routingContextData.put(RestConst.REST_INVOCATION_CONTEXT, invocation);
+ when(invocation.getContext(INVOCATION_CONTEXT_KEY)).thenReturn(null);
+
+ ITEM.appendFormattedItem(accessLogEvent, strBuilder);
+ Assert.assertThat(strBuilder.toString(), Matchers.is(InvocationContextItem.NOT_FOUND));
+ }
+
+ @Test
+ public void clientGetFormattedItemOnInvocationContextValueNotFound() {
+ Map<String, String> context = new HashMap<>();
+ when(finishEvent.getInvocation()).thenReturn(invocation);
+ when(invocation.getContext()).thenReturn(context);
+ context.put(INVOCATION_CONTEXT_KEY, null);
+
+ ITEM.appendFormattedItem(finishEvent, strBuilder);
+ Assert.assertThat(strBuilder.toString(), Matchers.is(InvocationContextItem.NOT_FOUND));
+ }
+
+ @Test
+ public void serverGetFormattedItemOnInvocationNotFound() {
+ Map<String, Object> routingContextData = new HashMap<>();
+ when(routingContext.data()).thenReturn(routingContextData);
+
+ ITEM.appendFormattedItem(accessLogEvent, strBuilder);
+ Assert.assertThat(strBuilder.toString(), Matchers.is(InvocationContextItem.NOT_FOUND));
+ }
+
+ @Test
+ public void clientGetFormattedItemOnInvocationContextNotFound() {
+ Map<String, String> context = new HashMap<>();
+ when(finishEvent.getInvocation()).thenReturn(invocation);
+ when(invocation.getContext()).thenReturn(context);
+
+ ITEM.appendFormattedItem(finishEvent, strBuilder);
+ Assert.assertThat(strBuilder.toString(), Matchers.is(InvocationContextItem.NOT_FOUND));
+ }
+
+ @Test
+ public void testGetFormattedItemOnRoutingContextDataNotFound() {
+ when(routingContext.data()).thenReturn(null);
+ ITEM.appendFormattedItem(accessLogEvent, strBuilder);
+ Assert.assertThat(strBuilder.toString(), Matchers.is(InvocationContextItem.NOT_FOUND));
+ }
+
+ @Test
+ public void clientGetFormattedItemOnRoutingContextDataNotFound() {
+ when(finishEvent.getInvocation()).thenReturn(invocation);
+ when(invocation.getContext()).thenReturn(null);
+ ITEM.appendFormattedItem(finishEvent, strBuilder);
+ Assert.assertThat(strBuilder.toString(), Matchers.is(InvocationContextItem.NOT_FOUND));
+ }
+
+ @Test
+ public void clientGetFormattedItemOnInvocationNotFound() {
+ when(finishEvent.getInvocation()).thenReturn(null);
+ ITEM.appendFormattedItem(finishEvent, strBuilder);
+ Assert.assertThat(strBuilder.toString(), Matchers.is(InvocationContextItem.NOT_FOUND));
+ }
+}
\ No newline at end of file
diff --git a/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/LocalHostItemTest.java b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/LocalHostItemTest.java
new file mode 100644
index 0000000..18d5471
--- /dev/null
+++ b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/LocalHostItemTest.java
@@ -0,0 +1,120 @@
+/*
+ * 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.servicecomb.foundation.log.core.element.impl;
+
+import static org.junit.Assert.assertEquals;
+
+import org.apache.servicecomb.core.event.InvocationFinishEvent;
+import org.apache.servicecomb.core.event.ServerAccessLogEvent;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import io.vertx.core.http.HttpServerRequest;
+import io.vertx.core.net.SocketAddress;
+import io.vertx.ext.web.RoutingContext;
+
+public class LocalHostItemTest {
+ public static final LocalHostItem ELEMENT = new LocalHostItem();
+
+ private StringBuilder strBuilder;
+
+ private InvocationFinishEvent finishEvent;
+
+ private ServerAccessLogEvent accessLogEvent;
+
+ private RoutingContext routingContext;
+
+ private HttpServerRequest serverRequest;
+
+ private SocketAddress socketAddress;
+
+ @Before
+ public void initStrBuilder() {
+ accessLogEvent = new ServerAccessLogEvent();
+ routingContext = Mockito.mock(RoutingContext.class);
+ finishEvent = Mockito.mock(InvocationFinishEvent.class);
+ serverRequest = Mockito.mock(HttpServerRequest.class);
+ socketAddress = Mockito.mock(SocketAddress.class);
+
+ accessLogEvent.setRoutingContext(routingContext);
+ strBuilder = new StringBuilder();
+ }
+
+ @Test
+ public void clientFormattedItem() {
+ ELEMENT.appendFormattedItem(finishEvent, strBuilder);
+ Assert.assertEquals("-", strBuilder.toString());
+ }
+
+ @Test
+ public void serverFormattedItem() {
+ String localAddress = "192.168.0.1";
+ accessLogEvent.setLocalAddress(localAddress);
+ ELEMENT.appendFormattedItem(accessLogEvent, strBuilder);
+ Assert.assertEquals(localAddress, strBuilder.toString());
+ }
+
+ @Test
+ public void getLocalAddress() {
+ String localHost = "testHost";
+ Mockito.when(routingContext.request()).thenReturn(serverRequest);
+ Mockito.when(serverRequest.localAddress()).thenReturn(socketAddress);
+ Mockito.when(socketAddress.host()).thenReturn(localHost);
+
+ String result = LocalHostItem.getLocalAddress(routingContext);
+ assertEquals(localHost, result);
+ }
+
+ @Test
+ public void getLocalAddressOnRequestIsNull() {
+ Mockito.when(routingContext.request()).thenReturn(null);
+ String result = LocalHostItem.getLocalAddress(routingContext);
+ assertEquals("-", result);
+ }
+
+ @Test
+ public void getLocalAddressOnLocalAddressIsNull() {
+ Mockito.when(routingContext.request()).thenReturn(serverRequest);
+ Mockito.when(serverRequest.localAddress()).thenReturn(null);
+ String result = LocalHostItem.getLocalAddress(routingContext);
+ assertEquals("-", result);
+ }
+
+ @Test
+ public void getLocalAddressOnHostIsNull() {
+ Mockito.when(routingContext.request()).thenReturn(serverRequest);
+ Mockito.when(serverRequest.localAddress()).thenReturn(socketAddress);
+ Mockito.when(socketAddress.host()).thenReturn(null);
+
+ String result = LocalHostItem.getLocalAddress(routingContext);
+ assertEquals("-", result);
+ }
+
+ @Test
+ public void getLocalAddressIsEmpty() {
+ String localHost = "";
+ Mockito.when(routingContext.request()).thenReturn(serverRequest);
+ Mockito.when(serverRequest.localAddress()).thenReturn(socketAddress);
+ Mockito.when(socketAddress.host()).thenReturn(localHost);
+
+ String result = LocalHostItem.getLocalAddress(routingContext);
+ assertEquals("-", result);
+ }
+}
diff --git a/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/LocalPortItemTest.java b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/LocalPortItemTest.java
new file mode 100644
index 0000000..e27359b
--- /dev/null
+++ b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/LocalPortItemTest.java
@@ -0,0 +1,90 @@
+/*
+ * 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.servicecomb.foundation.log.core.element.impl;
+
+import static org.junit.Assert.assertEquals;
+
+import org.apache.servicecomb.core.event.InvocationFinishEvent;
+import org.apache.servicecomb.core.event.ServerAccessLogEvent;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import io.vertx.core.http.HttpServerRequest;
+import io.vertx.core.net.SocketAddress;
+import io.vertx.ext.web.RoutingContext;
+
+public class LocalPortItemTest {
+ public static final LocalPortItem ELEMENT = new LocalPortItem();
+
+ private StringBuilder strBuilder;
+
+ private InvocationFinishEvent finishEvent;
+
+ private ServerAccessLogEvent accessLogEvent;
+
+ private RoutingContext routingContext;
+
+ private HttpServerRequest serverRequest;
+
+ private SocketAddress socketAddress;
+
+ @Before
+ public void initStrBuilder() {
+ accessLogEvent = new ServerAccessLogEvent();
+ routingContext = Mockito.mock(RoutingContext.class);
+ finishEvent = Mockito.mock(InvocationFinishEvent.class);
+ serverRequest = Mockito.mock(HttpServerRequest.class);
+ socketAddress = Mockito.mock(SocketAddress.class);
+
+ accessLogEvent.setRoutingContext(routingContext);
+ strBuilder = new StringBuilder();
+ }
+
+ @Test
+ public void serverFormattedElement() {
+ Mockito.when(routingContext.request()).thenReturn(serverRequest);
+ Mockito.when(serverRequest.localAddress()).thenReturn(socketAddress);
+ Mockito.when(socketAddress.port()).thenReturn(8080);
+
+ ELEMENT.appendFormattedItem(accessLogEvent, strBuilder);
+ assertEquals("8080", strBuilder.toString());
+ }
+
+ @Test
+ public void clientFormattedElement() {
+ ELEMENT.appendFormattedItem(finishEvent, strBuilder);
+ assertEquals("-", strBuilder.toString());
+ }
+
+ @Test
+ public void getFormattedElementOnRequestIsNull() {
+ Mockito.when(routingContext.request()).thenReturn(null);
+ ELEMENT.appendFormattedItem(accessLogEvent, strBuilder);
+ assertEquals("-", strBuilder.toString());
+ }
+
+ @Test
+ public void getFormattedElementOnLocalAddressIsNull() {
+ Mockito.when(routingContext.request()).thenReturn(serverRequest);
+ Mockito.when(serverRequest.localAddress()).thenReturn(null);
+
+ ELEMENT.appendFormattedItem(accessLogEvent, strBuilder);
+ assertEquals("-", strBuilder.toString());
+ }
+}
diff --git a/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/element/impl/TraceIdItem.java b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/PlainTextItemTest.java
similarity index 52%
copy from foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/element/impl/TraceIdItem.java
copy to foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/PlainTextItemTest.java
index 5c35e92..2fcb201 100644
--- a/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/element/impl/TraceIdItem.java
+++ b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/PlainTextItemTest.java
@@ -17,32 +17,39 @@
package org.apache.servicecomb.foundation.log.core.element.impl;
-import org.apache.servicecomb.core.Const;
+import static org.junit.Assert.assertEquals;
+
import org.apache.servicecomb.core.event.InvocationFinishEvent;
import org.apache.servicecomb.core.event.ServerAccessLogEvent;
-import org.springframework.util.StringUtils;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
-public class TraceIdItem extends InvocationContextItem {
+public class PlainTextItemTest {
+ private InvocationFinishEvent finishEvent;
- public static final String TRACE_ID = Const.TRACE_ID_NAME;
+ private ServerAccessLogEvent accessLogEvent;
- public TraceIdItem() {
- super(TRACE_ID);
- }
+ private StringBuilder strBuilder;
- @Override
- public void appendFormattedItem(ServerAccessLogEvent accessLogEvent, StringBuilder builder) {
- String traceId = getValueFromInvocationContext(accessLogEvent);
- if (StringUtils.isEmpty(traceId)) {
- traceId = accessLogEvent.getRoutingContext().request().getHeader(TRACE_ID);
- }
+ @Before
+ public void initStrBuilder() {
+ accessLogEvent = new ServerAccessLogEvent();
+ finishEvent = Mockito.mock(InvocationFinishEvent.class);
+ strBuilder = new StringBuilder();
+ }
- builder.append(StringUtils.isEmpty(traceId) ? InvocationContextItem.NOT_FOUND : traceId);
+ @Test
+ public void serverFormattedElement() {
+ PlainTextItem element = new PlainTextItem("contentTest");
+ element.appendFormattedItem(accessLogEvent, strBuilder);
+ assertEquals("contentTest", strBuilder.toString());
}
- @Override
- public void appendFormattedItem(InvocationFinishEvent finishEvent, StringBuilder builder) {
- String traceId = finishEvent.getInvocation().getContext().get(TRACE_ID);
- builder.append(StringUtils.isEmpty(traceId) ? InvocationContextItem.NOT_FOUND : traceId);
+ @Test
+ public void clientFormattedElement() {
+ PlainTextItem element = new PlainTextItem("contentTest");
+ element.appendFormattedItem(finishEvent, strBuilder);
+ assertEquals("contentTest", strBuilder.toString());
}
}
diff --git a/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/QueryStringItemTest.java b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/QueryStringItemTest.java
new file mode 100644
index 0000000..5aa8f1f
--- /dev/null
+++ b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/QueryStringItemTest.java
@@ -0,0 +1,157 @@
+/*
+ * 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.servicecomb.foundation.log.core.element.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.when;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.servicecomb.common.rest.RestConst;
+import org.apache.servicecomb.common.rest.codec.param.RestClientRequestImpl;
+import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.core.event.InvocationFinishEvent;
+import org.apache.servicecomb.core.event.ServerAccessLogEvent;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import io.vertx.core.http.HttpClientRequest;
+import io.vertx.core.http.HttpServerRequest;
+import io.vertx.ext.web.RoutingContext;
+
+public class QueryStringItemTest {
+ private static final QueryStringItem ITEM = new QueryStringItem();
+
+ private StringBuilder strBuilder;
+
+ private InvocationFinishEvent finishEvent;
+
+ private ServerAccessLogEvent accessLogEvent;
+
+ private RoutingContext routingContext;
+
+ private Invocation invocation;
+
+ private RestClientRequestImpl restClientRequest;
+
+ private HttpServerRequest serverRequest;
+
+ private HttpClientRequest clientRequest;
+
+ @Before
+ public void initStrBuilder() {
+ routingContext = Mockito.mock(RoutingContext.class);
+ finishEvent = Mockito.mock(InvocationFinishEvent.class);
+ invocation = Mockito.mock(Invocation.class);
+ serverRequest = Mockito.mock(HttpServerRequest.class);
+ restClientRequest = Mockito.mock(RestClientRequestImpl.class);
+ clientRequest = Mockito.mock(HttpClientRequest.class);
+
+ accessLogEvent = new ServerAccessLogEvent();
+ accessLogEvent.setRoutingContext(routingContext);
+ strBuilder = new StringBuilder();
+ }
+
+ @Test
+ public void serverFormattedElement() {
+ String query = "?status=up";
+ when(routingContext.request()).thenReturn(serverRequest);
+ when(serverRequest.query()).thenReturn(query);
+ ITEM.appendFormattedItem(accessLogEvent, strBuilder);
+ assertEquals(query, strBuilder.toString());
+ }
+
+ @Test
+ public void clientFormattedElement() {
+ String query = "?status=up";
+ Map<String, Object> handlerContext = new HashMap<>();
+ handlerContext.put(RestConst.INVOCATION_HANDLER_REQUESTCLIENT, restClientRequest);
+ when(finishEvent.getInvocation()).thenReturn(invocation);
+ when(invocation.getHandlerContext()).thenReturn(handlerContext);
+ when(restClientRequest.getRequest()).thenReturn(clientRequest);
+ when(clientRequest.query()).thenReturn(query);
+
+ ITEM.appendFormattedItem(finishEvent, strBuilder);
+ assertEquals(query, strBuilder.toString());
+ }
+
+ @Test
+ public void serverFormattedElementOnRequestIsNull() {
+ when(routingContext.request()).thenReturn(null);
+ ITEM.appendFormattedItem(accessLogEvent, strBuilder);
+ assertEquals("-", strBuilder.toString());
+ }
+
+ @Test
+ public void clientFormattedElementOnRequestIsNull() {
+ Map<String, Object> handlerContext = new HashMap<>();
+ handlerContext.put(RestConst.INVOCATION_HANDLER_REQUESTCLIENT, restClientRequest);
+ when(finishEvent.getInvocation()).thenReturn(invocation);
+ when(invocation.getHandlerContext()).thenReturn(handlerContext);
+ when(restClientRequest.getRequest()).thenReturn(null);
+
+ ITEM.appendFormattedItem(finishEvent, strBuilder);
+ assertEquals("-", strBuilder.toString());
+ }
+
+ @Test
+ public void serverFormattedElementOnQueryIsNull() {
+ when(routingContext.request()).thenReturn(serverRequest);
+ when(serverRequest.query()).thenReturn(null);
+ ITEM.appendFormattedItem(accessLogEvent, strBuilder);
+ assertEquals("-", strBuilder.toString());
+ }
+
+ @Test
+ public void clientFormattedElementOnQueryIsNull() {
+ Map<String, Object> handlerContext = new HashMap<>();
+ handlerContext.put(RestConst.INVOCATION_HANDLER_REQUESTCLIENT, restClientRequest);
+ when(finishEvent.getInvocation()).thenReturn(invocation);
+ when(invocation.getHandlerContext()).thenReturn(handlerContext);
+ when(restClientRequest.getRequest()).thenReturn(clientRequest);
+ when(clientRequest.query()).thenReturn(null);
+
+ ITEM.appendFormattedItem(finishEvent, strBuilder);
+ assertEquals("-", strBuilder.toString());
+ }
+
+ @Test
+ public void serverFormattedElementOnQueryIsEmpty() {
+ String query = "";
+ when(routingContext.request()).thenReturn(serverRequest);
+ when(serverRequest.query()).thenReturn(query);
+ ITEM.appendFormattedItem(accessLogEvent, strBuilder);
+ assertEquals("-", strBuilder.toString());
+ }
+
+ @Test
+ public void clientFormattedElementOnQueryIsEmpty() {
+ String query = "";
+ Map<String, Object> handlerContext = new HashMap<>();
+ handlerContext.put(RestConst.INVOCATION_HANDLER_REQUESTCLIENT, restClientRequest);
+ when(finishEvent.getInvocation()).thenReturn(invocation);
+ when(invocation.getHandlerContext()).thenReturn(handlerContext);
+ when(restClientRequest.getRequest()).thenReturn(clientRequest);
+ when(clientRequest.query()).thenReturn(query);
+
+ ITEM.appendFormattedItem(finishEvent, strBuilder);
+ assertEquals("-", strBuilder.toString());
+ }
+}
diff --git a/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/RemoteHostItemTest.java b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/RemoteHostItemTest.java
new file mode 100644
index 0000000..24967d9
--- /dev/null
+++ b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/RemoteHostItemTest.java
@@ -0,0 +1,162 @@
+/*
+ * 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.servicecomb.foundation.log.core.element.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import org.apache.servicecomb.core.Endpoint;
+import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.core.event.InvocationFinishEvent;
+import org.apache.servicecomb.core.event.ServerAccessLogEvent;
+import org.apache.servicecomb.foundation.common.net.URIEndpointObject;
+import org.junit.Before;
+import org.junit.Test;
+
+import io.vertx.core.http.HttpServerRequest;
+import io.vertx.core.net.SocketAddress;
+import io.vertx.ext.web.RoutingContext;
+
+public class RemoteHostItemTest {
+ public static final RemoteHostItem ELEMENT = new RemoteHostItem();
+
+ private StringBuilder strBuilder;
+
+ private InvocationFinishEvent finishEvent;
+
+ private ServerAccessLogEvent accessLogEvent;
+
+ private RoutingContext routingContext;
+
+ private Invocation invocation;
+
+ private HttpServerRequest serverRequest;
+
+ private Endpoint endpoint;
+
+ private URIEndpointObject uriEndpointObject;
+
+ private SocketAddress socketAddress;
+
+ @Before
+ public void initStrBuilder() {
+ routingContext = mock(RoutingContext.class);
+ finishEvent = mock(InvocationFinishEvent.class);
+ invocation = mock(Invocation.class);
+ serverRequest = mock(HttpServerRequest.class);
+ endpoint = mock(Endpoint.class);
+ uriEndpointObject = mock(URIEndpointObject.class);
+ socketAddress = mock(SocketAddress.class);
+ accessLogEvent = new ServerAccessLogEvent();
+ accessLogEvent.setRoutingContext(routingContext);
+ strBuilder = new StringBuilder();
+ }
+
+ @Test
+ public void serverFormattedElement() {
+ String remoteHost = "remoteHost";
+ when(routingContext.request()).thenReturn(serverRequest);
+ when(serverRequest.remoteAddress()).thenReturn(socketAddress);
+ when(socketAddress.host()).thenReturn(remoteHost);
+
+ ELEMENT.appendFormattedItem(accessLogEvent, strBuilder);
+ assertEquals(remoteHost, strBuilder.toString());
+ }
+
+ @Test
+ public void clientFormattedElement() {
+ String remoteHost = "remoteHost";
+ when(finishEvent.getInvocation()).thenReturn(invocation);
+ when(invocation.getEndpoint()).thenReturn(endpoint);
+ when(endpoint.getAddress()).thenReturn(uriEndpointObject);
+ when(uriEndpointObject.getHostOrIp()).thenReturn(remoteHost);
+ ELEMENT.appendFormattedItem(finishEvent, strBuilder);
+ assertEquals(remoteHost, strBuilder.toString());
+ }
+
+ @Test
+ public void serverFormattedElementOnRequestIsNull() {
+ when(routingContext.request()).thenReturn(null);
+ ELEMENT.appendFormattedItem(accessLogEvent, strBuilder);
+ assertEquals("-", strBuilder.toString());
+ }
+
+ @Test
+ public void clientFormattedElementOnRequestIsNull() {
+ when(finishEvent.getInvocation()).thenReturn(invocation);
+ when(invocation.getEndpoint()).thenReturn(null);
+ ELEMENT.appendFormattedItem(finishEvent, strBuilder);
+ assertEquals("-", strBuilder.toString());
+ }
+
+ @Test
+ public void serverFormattedElementOnRemoteAddressIsNull() {
+ when(routingContext.request()).thenReturn(serverRequest);
+ when(serverRequest.remoteAddress()).thenReturn(null);
+ ELEMENT.appendFormattedItem(accessLogEvent, strBuilder);
+ assertEquals("-", strBuilder.toString());
+ }
+
+ @Test
+ public void clientFormattedElementOnRemoteAddressIsNull() {
+ when(finishEvent.getInvocation()).thenReturn(invocation);
+ when(invocation.getEndpoint()).thenReturn(endpoint);
+ when(endpoint.getAddress()).thenReturn(null);
+ ELEMENT.appendFormattedItem(finishEvent, strBuilder);
+ assertEquals("-", strBuilder.toString());
+ }
+
+ @Test
+ public void serverFormattedElementOnHostIsNull() {
+ when(routingContext.request()).thenReturn(serverRequest);
+ when(serverRequest.remoteAddress()).thenReturn(socketAddress);
+ when(socketAddress.host()).thenReturn(null);
+ ELEMENT.appendFormattedItem(accessLogEvent, strBuilder);
+ assertEquals("-", strBuilder.toString());
+ }
+
+ @Test
+ public void clientFormattedElementOnHostIsNull() {
+ when(finishEvent.getInvocation()).thenReturn(invocation);
+ when(invocation.getEndpoint()).thenReturn(endpoint);
+ when(endpoint.getAddress()).thenReturn(uriEndpointObject);
+ when(uriEndpointObject.getHostOrIp()).thenReturn(null);
+ ELEMENT.appendFormattedItem(finishEvent, strBuilder);
+ assertEquals("-", strBuilder.toString());
+ }
+
+ @Test
+ public void serverFormattedElementOnHostIsEmpty() {
+ when(routingContext.request()).thenReturn(serverRequest);
+ when(serverRequest.remoteAddress()).thenReturn(socketAddress);
+ when(socketAddress.host()).thenReturn("");
+ ELEMENT.appendFormattedItem(accessLogEvent, strBuilder);
+ assertEquals("-", strBuilder.toString());
+ }
+
+ @Test
+ public void clientFormattedElementOnHostIsEmpty() {
+ when(finishEvent.getInvocation()).thenReturn(invocation);
+ when(invocation.getEndpoint()).thenReturn(endpoint);
+ when(endpoint.getAddress()).thenReturn(uriEndpointObject);
+ when(uriEndpointObject.getHostOrIp()).thenReturn("");
+ ELEMENT.appendFormattedItem(finishEvent, strBuilder);
+ assertEquals("-", strBuilder.toString());
+ }
+}
diff --git a/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/RequestHeaderItemTest.java b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/RequestHeaderItemTest.java
new file mode 100644
index 0000000..3d84b9b
--- /dev/null
+++ b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/RequestHeaderItemTest.java
@@ -0,0 +1,141 @@
+/*
+ * 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.servicecomb.foundation.log.core.element.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.when;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.servicecomb.common.rest.RestConst;
+import org.apache.servicecomb.common.rest.codec.param.RestClientRequestImpl;
+import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.core.event.InvocationFinishEvent;
+import org.apache.servicecomb.core.event.ServerAccessLogEvent;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import io.vertx.core.MultiMap;
+import io.vertx.core.http.HttpClientRequest;
+import io.vertx.core.http.HttpServerRequest;
+import io.vertx.core.http.impl.headers.VertxHttpHeaders;
+import io.vertx.ext.web.RoutingContext;
+
+public class RequestHeaderItemTest {
+ private static final String VAR_NAME = "varName";
+
+ private static final RequestHeaderItem ELEMENT = new RequestHeaderItem(VAR_NAME);
+
+ private StringBuilder strBuilder;
+
+ private InvocationFinishEvent finishEvent;
+
+ private ServerAccessLogEvent accessLogEvent;
+
+ private RoutingContext routingContext;
+
+ private Invocation invocation;
+
+ private RestClientRequestImpl restClientRequest;
+
+ private HttpServerRequest serverRequest;
+
+ private HttpClientRequest clientRequest;
+
+ private MultiMap headers;
+
+ @Before
+ public void initStrBuilder() {
+ routingContext = Mockito.mock(RoutingContext.class);
+ finishEvent = Mockito.mock(InvocationFinishEvent.class);
+ invocation = Mockito.mock(Invocation.class);
+ serverRequest = Mockito.mock(HttpServerRequest.class);
+ restClientRequest = Mockito.mock(RestClientRequestImpl.class);
+ clientRequest = Mockito.mock(HttpClientRequest.class);
+ headers = Mockito.mock(MultiMap.class);
+
+ accessLogEvent = new ServerAccessLogEvent();
+ accessLogEvent.setRoutingContext(routingContext);
+ strBuilder = new StringBuilder();
+ }
+
+ @Test
+ public void serverFormattedElement() {
+ VertxHttpHeaders headers = new VertxHttpHeaders();
+ String testValue = "testValue";
+ headers.add(VAR_NAME, testValue);
+ when(routingContext.request()).thenReturn(serverRequest);
+ when(serverRequest.headers()).thenReturn(headers);
+
+ ELEMENT.appendFormattedItem(accessLogEvent, strBuilder);
+ assertEquals(testValue, strBuilder.toString());
+ assertEquals(ELEMENT.getVarName(), VAR_NAME);
+ }
+
+ @Test
+ public void clientFormattedElement() {
+ Map<String, Object> handlerContext = new HashMap<>();
+ String testValue = "testValue";
+
+ handlerContext.put(RestConst.INVOCATION_HANDLER_REQUESTCLIENT, restClientRequest);
+ when(finishEvent.getInvocation()).thenReturn(invocation);
+ when(invocation.getHandlerContext()).thenReturn(handlerContext);
+ when(restClientRequest.getRequest()).thenReturn(clientRequest);
+ when(clientRequest.headers()).thenReturn(headers);
+ when(headers.get(VAR_NAME)).thenReturn(testValue);
+
+ ELEMENT.appendFormattedItem(finishEvent, strBuilder);
+ assertEquals(testValue, strBuilder.toString());
+ }
+
+ @Test
+ public void serverFormattedElementIfHeaderIsNull() {
+ when(routingContext.request()).thenReturn(serverRequest);
+ when(serverRequest.headers()).thenReturn(null);
+
+ ELEMENT.appendFormattedItem(accessLogEvent, strBuilder);
+ assertEquals("-", strBuilder.toString());
+ }
+
+ @Test
+ public void clientFormattedElementIfHeaderIsNull() {
+ Map<String, Object> handlerContext = new HashMap<>();
+ handlerContext.put(RestConst.INVOCATION_HANDLER_REQUESTCLIENT, restClientRequest);
+ when(finishEvent.getInvocation()).thenReturn(invocation);
+ when(invocation.getHandlerContext()).thenReturn(handlerContext);
+ when(restClientRequest.getRequest()).thenReturn(clientRequest);
+ when(clientRequest.headers()).thenReturn(null);
+
+ ELEMENT.appendFormattedItem(finishEvent, strBuilder);
+ assertEquals("-", strBuilder.toString());
+ }
+
+ @Test
+ public void serverFormattedElementIfNotFound() {
+ VertxHttpHeaders headers = new VertxHttpHeaders();
+ String testValue = "testValue";
+ headers.add("anotherKey", testValue);
+ when(routingContext.request()).thenReturn(serverRequest);
+ when(serverRequest.headers()).thenReturn(headers);
+
+ ELEMENT.appendFormattedItem(accessLogEvent, strBuilder);
+ assertEquals("-", strBuilder.toString());
+ }
+}
diff --git a/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/RequestProtocolItemTest.java b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/RequestProtocolItemTest.java
new file mode 100644
index 0000000..d85151b
--- /dev/null
+++ b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/RequestProtocolItemTest.java
@@ -0,0 +1,124 @@
+/*
+ * 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.servicecomb.foundation.log.core.element.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.when;
+
+import org.apache.servicecomb.core.Endpoint;
+import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.core.event.InvocationFinishEvent;
+import org.apache.servicecomb.core.event.ServerAccessLogEvent;
+import org.apache.servicecomb.foundation.common.net.URIEndpointObject;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import io.vertx.core.http.HttpServerRequest;
+import io.vertx.core.http.HttpVersion;
+import io.vertx.ext.web.RoutingContext;
+
+public class RequestProtocolItemTest {
+ private static final RequestProtocolItem ITEM = new RequestProtocolItem();
+
+ private StringBuilder strBuilder;
+
+ private InvocationFinishEvent finishEvent;
+
+ private ServerAccessLogEvent accessLogEvent;
+
+ private RoutingContext routingContext;
+
+ private Invocation invocation;
+
+ private HttpServerRequest serverRequest;
+
+ private Endpoint endpoint;
+
+ private URIEndpointObject urlEndpoint;
+
+ @Before
+ public void initStrBuilder() {
+ routingContext = Mockito.mock(RoutingContext.class);
+ finishEvent = Mockito.mock(InvocationFinishEvent.class);
+ invocation = Mockito.mock(Invocation.class);
+ serverRequest = Mockito.mock(HttpServerRequest.class);
+ urlEndpoint = Mockito.mock(URIEndpointObject.class);
+ endpoint = Mockito.mock(Endpoint.class);
+
+ accessLogEvent = new ServerAccessLogEvent();
+ accessLogEvent.setRoutingContext(routingContext);
+ strBuilder = new StringBuilder();
+ }
+
+ @Test
+ public void serverFormattedElement() {
+ when(routingContext.request()).thenReturn(serverRequest);
+ when(serverRequest.version()).thenReturn(HttpVersion.HTTP_1_1);
+
+ ITEM.appendFormattedItem(accessLogEvent, strBuilder);
+ assertEquals("HTTP/1.1", strBuilder.toString());
+
+ strBuilder = new StringBuilder();
+ when(serverRequest.version()).thenReturn(HttpVersion.HTTP_1_0);
+ ITEM.appendFormattedItem(accessLogEvent, strBuilder);
+ assertEquals("HTTP/1.0", strBuilder.toString());
+
+ strBuilder = new StringBuilder();
+ when(serverRequest.version()).thenReturn(HttpVersion.HTTP_2);
+ ITEM.appendFormattedItem(accessLogEvent, strBuilder);
+ assertEquals("HTTP/2.0", strBuilder.toString());
+ }
+
+ @Test
+ public void clientFormattedElementOnRequestIsNull() {
+ when(finishEvent.getInvocation()).thenReturn(invocation);
+ when(invocation.getEndpoint()).thenReturn(endpoint);
+ when(endpoint.getAddress()).thenReturn(urlEndpoint);
+ when(urlEndpoint.isSslEnabled()).thenReturn(true);
+ ITEM.appendFormattedItem(finishEvent, strBuilder);
+ assertEquals("HTTPS", strBuilder.toString());
+
+ strBuilder = new StringBuilder();
+ when(finishEvent.getInvocation()).thenReturn(invocation);
+ when(invocation.getEndpoint()).thenReturn(endpoint);
+ when(endpoint.getAddress()).thenReturn(urlEndpoint);
+ when(urlEndpoint.isSslEnabled()).thenReturn(false);
+ ITEM.appendFormattedItem(finishEvent, strBuilder);
+ assertEquals("HTTP", strBuilder.toString());
+ }
+
+ @Test
+ public void serverFormattedElementOnVersionIsNull() {
+ when(routingContext.request()).thenReturn(serverRequest);
+ when(serverRequest.version()).thenReturn(null);
+
+ ITEM.appendFormattedItem(accessLogEvent, strBuilder);
+ assertEquals("-", strBuilder.toString());
+ }
+
+ @Test
+ public void clientFormattedElementOnVersionIsNull() {
+ when(finishEvent.getInvocation()).thenReturn(invocation);
+ when(invocation.getEndpoint()).thenReturn(endpoint);
+ when(endpoint.getAddress()).thenReturn(null);
+
+ ITEM.appendFormattedItem(finishEvent, strBuilder);
+ assertEquals("-", strBuilder.toString());
+ }
+}
diff --git a/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/ResponseHeaderItemTest.java b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/ResponseHeaderItemTest.java
new file mode 100644
index 0000000..dad7e31
--- /dev/null
+++ b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/ResponseHeaderItemTest.java
@@ -0,0 +1,156 @@
+/*
+ * 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.servicecomb.foundation.log.core.element.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.when;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.servicecomb.core.event.InvocationFinishEvent;
+import org.apache.servicecomb.core.event.ServerAccessLogEvent;
+import org.apache.servicecomb.swagger.invocation.Response;
+import org.apache.servicecomb.swagger.invocation.response.Headers;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import io.vertx.core.http.HttpServerResponse;
+import io.vertx.core.http.impl.headers.VertxHttpHeaders;
+import io.vertx.ext.web.RoutingContext;
+
+public class ResponseHeaderItemTest {
+
+ private static final String VAR_NAME = "varName";
+
+ private static final ResponseHeaderItem ELEMENT = new ResponseHeaderItem(VAR_NAME);
+
+ private StringBuilder strBuilder;
+
+ private InvocationFinishEvent finishEvent;
+
+ private ServerAccessLogEvent accessLogEvent;
+
+ private RoutingContext routingContext;
+
+ private HttpServerResponse serverResponse;
+
+ private Response response;
+
+ @Before
+ public void initStrBuilder() {
+ routingContext = Mockito.mock(RoutingContext.class);
+ finishEvent = Mockito.mock(InvocationFinishEvent.class);
+ serverResponse = Mockito.mock(HttpServerResponse.class);
+ response = Mockito.mock(Response.class);
+
+ accessLogEvent = new ServerAccessLogEvent();
+ accessLogEvent.setRoutingContext(routingContext);
+ strBuilder = new StringBuilder();
+ }
+
+ @Test
+ public void serverFormattedElement() {
+ VertxHttpHeaders headers = new VertxHttpHeaders();
+ String headerValue = "headerValue";
+ headers.add(VAR_NAME, headerValue);
+ when(routingContext.response()).thenReturn(serverResponse);
+ when(serverResponse.headers()).thenReturn(headers);
+
+ ELEMENT.appendFormattedItem(accessLogEvent, strBuilder);
+ assertEquals(headerValue, strBuilder.toString());
+ assertEquals(ELEMENT.getVarName(), VAR_NAME);
+ }
+
+ @Test
+ public void clientFormattedElement() {
+ String headerValue = "headerValue";
+ Headers headers = new Headers();
+ Map<String, List<Object>> headerMap = new HashMap<>();
+ headerMap.put(VAR_NAME, Arrays.asList(headerValue));
+
+ headers.setHeaderMap(headerMap);
+ when(finishEvent.getResponse()).thenReturn(response);
+ when(response.getHeaders()).thenReturn(headers);
+
+ ELEMENT.appendFormattedItem(finishEvent, strBuilder);
+ assertEquals(headerValue, strBuilder.toString());
+ assertEquals(ELEMENT.getVarName(), VAR_NAME);
+ }
+
+ @Test
+ public void serverFormattedElementOnHeadersIsNull() {
+ when(routingContext.response()).thenReturn(serverResponse);
+ when(serverResponse.headers()).thenReturn(null);
+
+ ELEMENT.appendFormattedItem(accessLogEvent, strBuilder);
+ assertEquals("-", strBuilder.toString());
+ }
+
+ @Test
+ public void clientFormattedElementOnHeadersIsNull() {
+ when(finishEvent.getResponse()).thenReturn(response);
+ when(response.getHeaders()).thenReturn(null);
+
+ ELEMENT.appendFormattedItem(finishEvent, strBuilder);
+ assertEquals("-", strBuilder.toString());
+ }
+
+ @Test
+ public void serverFormattedElementOnResponseIsNull() {
+ when(routingContext.response()).thenReturn(null);
+ ELEMENT.appendFormattedItem(accessLogEvent, strBuilder);
+ assertEquals("-", strBuilder.toString());
+ }
+
+ @Test
+ public void clientFormattedElementOnResponseIsNull() {
+ when(finishEvent.getResponse()).thenReturn(null);
+ ELEMENT.appendFormattedItem(finishEvent, strBuilder);
+ assertEquals("-", strBuilder.toString());
+ }
+
+ @Test
+ public void serverFormattedElementOnNotFound() {
+ VertxHttpHeaders headers = new VertxHttpHeaders();
+ String headerValue = "headerValue";
+ headers.add("anotherHeader", headerValue);
+ when(routingContext.response()).thenReturn(serverResponse);
+ when(serverResponse.headers()).thenReturn(headers);
+
+ ELEMENT.appendFormattedItem(accessLogEvent, strBuilder);
+ assertEquals("-", strBuilder.toString());
+ }
+
+ @Test
+ public void clientFormattedElementOnNotFound() {
+ String headerValue = "headerValue";
+ Headers headers = new Headers();
+ Map<String, List<Object>> headerMap = new HashMap<>();
+ headerMap.put("anotherHeader", Arrays.asList(headerValue));
+ headers.setHeaderMap(headerMap);
+ when(finishEvent.getResponse()).thenReturn(response);
+ when(response.getHeaders()).thenReturn(headers);
+
+ ELEMENT.appendFormattedItem(finishEvent, strBuilder);
+ assertEquals("-", strBuilder.toString());
+ }
+}
diff --git a/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/ResponseSizeItemTest.java b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/ResponseSizeItemTest.java
new file mode 100644
index 0000000..0db4f27
--- /dev/null
+++ b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/ResponseSizeItemTest.java
@@ -0,0 +1,87 @@
+/*
+ * 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.servicecomb.foundation.log.core.element.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.when;
+
+import org.apache.servicecomb.core.event.InvocationFinishEvent;
+import org.apache.servicecomb.core.event.ServerAccessLogEvent;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import io.vertx.core.http.HttpServerResponse;
+import io.vertx.ext.web.RoutingContext;
+
+public class ResponseSizeItemTest {
+ private static final ResponseSizeItem ELEMENT = new ResponseSizeItem("0");
+
+ private StringBuilder strBuilder;
+
+ private InvocationFinishEvent finishEvent;
+
+ private ServerAccessLogEvent accessLogEvent;
+
+ private RoutingContext routingContext;
+
+ private HttpServerResponse serverResponse;
+
+ @Before
+ public void initStrBuilder() {
+ routingContext = Mockito.mock(RoutingContext.class);
+ finishEvent = Mockito.mock(InvocationFinishEvent.class);
+ serverResponse = Mockito.mock(HttpServerResponse.class);
+
+ accessLogEvent = new ServerAccessLogEvent();
+ accessLogEvent.setRoutingContext(routingContext);
+ strBuilder = new StringBuilder();
+ }
+
+ @Test
+ public void serverFormattedElement() {
+ long bytesWritten = 16L;
+ when(routingContext.response()).thenReturn(serverResponse);
+ when(serverResponse.bytesWritten()).thenReturn(bytesWritten);
+
+ ELEMENT.appendFormattedItem(accessLogEvent, strBuilder);
+ assertEquals(String.valueOf(bytesWritten), strBuilder.toString());
+ }
+
+ @Test
+ public void clientFormattedElement() {
+ ELEMENT.appendFormattedItem(finishEvent, strBuilder);
+ assertEquals("0", strBuilder.toString());
+ }
+
+ @Test
+ public void getFormattedElementOnResponseIsNull() {
+ when(routingContext.response()).thenReturn(null);
+ ELEMENT.appendFormattedItem(accessLogEvent, strBuilder);
+ assertEquals("0", strBuilder.toString());
+ }
+
+ @Test
+ public void getFormattedElementOnBytesWrittenIsZero() {
+ long bytesWritten = 0L;
+ when(routingContext.response()).thenReturn(serverResponse);
+ when(serverResponse.bytesWritten()).thenReturn(bytesWritten);
+ ELEMENT.appendFormattedItem(accessLogEvent, strBuilder);
+ assertEquals("0", strBuilder.toString());
+ }
+}
diff --git a/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/TraceIdItemTest.java b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/TraceIdItemTest.java
new file mode 100644
index 0000000..779561d
--- /dev/null
+++ b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/TraceIdItemTest.java
@@ -0,0 +1,160 @@
+/*
+ * 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.servicecomb.foundation.log.core.element.impl;
+
+import static org.hamcrest.core.Is.is;
+import static org.mockito.Mockito.when;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.servicecomb.common.rest.RestConst;
+import org.apache.servicecomb.core.Const;
+import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.core.event.InvocationFinishEvent;
+import org.apache.servicecomb.core.event.ServerAccessLogEvent;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import io.vertx.core.http.HttpServerRequest;
+import io.vertx.ext.web.RoutingContext;
+
+public class TraceIdItemTest {
+ private static final TraceIdItem ELEMENT = new TraceIdItem();
+
+ private StringBuilder strBuilder;
+
+ private InvocationFinishEvent finishEvent;
+
+ private ServerAccessLogEvent accessLogEvent;
+
+ private RoutingContext routingContext;
+
+ private HttpServerRequest serverRequest;
+
+ private Invocation invocation;
+
+ private Map<String, String> clientContext = new HashMap<>();
+
+ @Before
+ public void initStrBuilder() {
+ accessLogEvent = new ServerAccessLogEvent();
+ routingContext = Mockito.mock(RoutingContext.class);
+ finishEvent = Mockito.mock(InvocationFinishEvent.class);
+ invocation = Mockito.mock(Invocation.class);
+ serverRequest = Mockito.mock(HttpServerRequest.class);
+
+ accessLogEvent.setRoutingContext(routingContext);
+ strBuilder = new StringBuilder();
+ clientContext.clear();
+ }
+
+ @Test
+ public void serverGetFormattedElementFromInvocationContext() {
+ Map<String, Object> data = new HashMap<>();
+ String traceIdTest = "traceIdTest";
+ when(invocation.getContext(Const.TRACE_ID_NAME)).thenReturn(traceIdTest);
+ when(routingContext.data()).thenReturn(data);
+ data.put(RestConst.REST_INVOCATION_CONTEXT, invocation);
+
+ ELEMENT.appendFormattedItem(accessLogEvent, strBuilder);
+ Assert.assertThat(strBuilder.toString(), is(traceIdTest));
+ }
+
+ @Test
+ public void clientGetFormattedElementFromInvocationContext() {
+ String traceIdTest = "traceIdTest";
+ clientContext.put(Const.TRACE_ID_NAME, traceIdTest);
+ when(finishEvent.getInvocation()).thenReturn(invocation);
+ when(invocation.getContext()).thenReturn(clientContext);
+
+ ELEMENT.appendFormattedItem(finishEvent, strBuilder);
+ Assert.assertThat(strBuilder.toString(), is(traceIdTest));
+ }
+
+ @Test
+ public void serverGetFormattedElementFromRequestHeader() {
+ Map<String, Object> data = new HashMap<>();
+ String traceIdTest = "traceIdTest";
+ when(invocation.getContext(Const.TRACE_ID_NAME)).thenReturn(null);
+ when(routingContext.data()).thenReturn(data);
+ data.put(RestConst.REST_INVOCATION_CONTEXT, invocation);
+
+ when(serverRequest.getHeader(Const.TRACE_ID_NAME)).thenReturn(traceIdTest);
+ when(routingContext.request()).thenReturn(serverRequest);
+ ELEMENT.appendFormattedItem(accessLogEvent, strBuilder);
+ Assert.assertThat(strBuilder.toString(), is(traceIdTest));
+ }
+
+ @Test
+ public void serverGetFormattedElementOnTraceIdNotFound() {
+ Map<String, Object> data = new HashMap<>();
+ when(invocation.getContext(Const.TRACE_ID_NAME)).thenReturn("");
+ when(routingContext.data()).thenReturn(data);
+ data.put(RestConst.REST_INVOCATION_CONTEXT, invocation);
+
+ when(serverRequest.getHeader(Const.TRACE_ID_NAME)).thenReturn(null);
+ when(routingContext.request()).thenReturn(serverRequest);
+ ELEMENT.appendFormattedItem(accessLogEvent, strBuilder);
+ Assert.assertThat(strBuilder.toString(), is("-"));
+
+ strBuilder = new StringBuilder();
+ when(invocation.getContext(Const.TRACE_ID_NAME)).thenReturn(null);
+ ELEMENT.appendFormattedItem(accessLogEvent, strBuilder);
+ Assert.assertThat(strBuilder.toString(), is("-"));
+ }
+
+ @Test
+ public void clientGetFormattedElementOnTraceIdNotFound() {
+ clientContext.put(Const.TRACE_ID_NAME, null);
+ when(finishEvent.getInvocation()).thenReturn(invocation);
+ when(invocation.getContext()).thenReturn(clientContext);
+
+ ELEMENT.appendFormattedItem(finishEvent, strBuilder);
+ Assert.assertThat(strBuilder.toString(), is("-"));
+ }
+
+ @Test
+ public void serverGetFormattedElementOnInvocationContextIsNull() {
+ when(routingContext.data()).thenReturn(null);
+ when(routingContext.request()).thenReturn(serverRequest);
+ when(serverRequest.getHeader(Const.TRACE_ID_NAME)).thenReturn(null);
+ ELEMENT.appendFormattedItem(accessLogEvent, strBuilder);
+ Assert.assertThat(strBuilder.toString(), is("-"));
+ }
+
+ @Test
+ public void clientGetFormattedElementOnInvocationContextIsNull() {
+ when(finishEvent.getInvocation()).thenReturn(invocation);
+ when(invocation.getContext()).thenReturn(null);
+
+ ELEMENT.appendFormattedItem(finishEvent, strBuilder);
+ Assert.assertThat(strBuilder.toString(), is("-"));
+ }
+
+ @Test
+ public void serverGetFormattedElementOnDataIsNull() {
+ when(serverRequest.getHeader(Const.TRACE_ID_NAME)).thenReturn(null);
+ when(routingContext.request()).thenReturn(serverRequest);
+ when(routingContext.data()).thenReturn(null);
+ ELEMENT.appendFormattedItem(accessLogEvent, strBuilder);
+ Assert.assertThat(strBuilder.toString(), is("-"));
+ }
+}
diff --git a/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/TransportItemTest.java b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/TransportItemTest.java
new file mode 100644
index 0000000..e3da5f4
--- /dev/null
+++ b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/TransportItemTest.java
@@ -0,0 +1,109 @@
+/*
+ * 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.servicecomb.foundation.log.core.element.impl;
+
+import static org.mockito.Mockito.when;
+
+import org.apache.servicecomb.core.Endpoint;
+import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.core.event.InvocationFinishEvent;
+import org.apache.servicecomb.core.event.ServerAccessLogEvent;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+public class TransportItemTest {
+ private static final TransportItem ITEM = new TransportItem();
+
+ private StringBuilder strBuilder;
+
+ private InvocationFinishEvent finishEvent;
+
+ private ServerAccessLogEvent accessLogEvent;
+
+ private Invocation invocation;
+
+ private Endpoint endpoint;
+
+ @Before
+ public void initStrBuilder() {
+ finishEvent = Mockito.mock(InvocationFinishEvent.class);
+ invocation = Mockito.mock(Invocation.class);
+ endpoint = Mockito.mock(Endpoint.class);
+ accessLogEvent = new ServerAccessLogEvent();
+ strBuilder = new StringBuilder();
+ }
+
+ @Test
+ public void clientFormattedElement() {
+ when(finishEvent.getInvocation()).thenReturn(invocation);
+ when(invocation.getConfigTransportName()).thenReturn("rest");
+ ITEM.appendFormattedItem(finishEvent, strBuilder);
+ Assert.assertEquals("rest", strBuilder.toString());
+
+ strBuilder = new StringBuilder();
+ when(finishEvent.getInvocation()).thenReturn(invocation);
+ when(invocation.getEndpoint()).thenReturn(endpoint);
+ when(endpoint.getEndpoint()).thenReturn("rest:xxx:30100");
+ ITEM.appendFormattedItem(finishEvent, strBuilder);
+ Assert.assertEquals("rest", strBuilder.toString());
+ }
+
+ @Test
+ public void serverFormattedElement() {
+ ITEM.appendFormattedItem(accessLogEvent, strBuilder);
+ Assert.assertEquals("-", strBuilder.toString());
+ }
+
+ @Test
+ public void clientConfigTransportNameIsNull() {
+ when(finishEvent.getInvocation()).thenReturn(invocation);
+ when(invocation.getConfigTransportName()).thenReturn(null);
+
+ strBuilder = new StringBuilder();
+ when(finishEvent.getInvocation()).thenReturn(invocation);
+ when(invocation.getEndpoint()).thenReturn(endpoint);
+ when(endpoint.getEndpoint()).thenReturn("rest:xxx:30100");
+ ITEM.appendFormattedItem(finishEvent, strBuilder);
+ Assert.assertEquals("rest", strBuilder.toString());
+ }
+
+ @Test
+ public void clientConfigTransportNameIsEmpty() {
+ when(finishEvent.getInvocation()).thenReturn(invocation);
+ when(invocation.getConfigTransportName()).thenReturn("");
+ strBuilder = new StringBuilder();
+ when(finishEvent.getInvocation()).thenReturn(invocation);
+ when(invocation.getEndpoint()).thenReturn(endpoint);
+ when(endpoint.getEndpoint()).thenReturn("rest:xxx:30100");
+ ITEM.appendFormattedItem(finishEvent, strBuilder);
+ Assert.assertEquals("rest", strBuilder.toString());
+ }
+
+ @Test
+ public void clientALLIsEmpty() {
+ when(finishEvent.getInvocation()).thenReturn(invocation);
+ when(invocation.getConfigTransportName()).thenReturn(null);
+ strBuilder = new StringBuilder();
+ when(finishEvent.getInvocation()).thenReturn(invocation);
+ when(invocation.getEndpoint()).thenReturn(null);
+ ITEM.appendFormattedItem(finishEvent, strBuilder);
+ Assert.assertEquals("-", strBuilder.toString());
+ }
+}
diff --git a/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/UrlPathItemTest.java b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/UrlPathItemTest.java
new file mode 100644
index 0000000..00183fe
--- /dev/null
+++ b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/UrlPathItemTest.java
@@ -0,0 +1,156 @@
+/*
+ * 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.servicecomb.foundation.log.core.element.impl;
+
+import static org.mockito.Mockito.when;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.servicecomb.common.rest.RestConst;
+import org.apache.servicecomb.common.rest.codec.param.RestClientRequestImpl;
+import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.core.definition.OperationMeta;
+import org.apache.servicecomb.core.definition.SchemaMeta;
+import org.apache.servicecomb.core.event.InvocationFinishEvent;
+import org.apache.servicecomb.core.event.ServerAccessLogEvent;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import io.swagger.models.Swagger;
+import io.vertx.core.http.HttpClientRequest;
+import io.vertx.core.http.HttpServerRequest;
+import io.vertx.ext.web.RoutingContext;
+
+public class UrlPathItemTest {
+ private static final UrlPathItem ITEM = new UrlPathItem();
+
+ private StringBuilder strBuilder;
+
+ private InvocationFinishEvent finishEvent;
+
+ private ServerAccessLogEvent accessLogEvent;
+
+ private RoutingContext routingContext;
+
+ private Invocation invocation;
+
+ private HttpServerRequest serverRequest;
+
+ private OperationMeta operationMeta;
+
+ private SchemaMeta schemaMeta;
+
+ private Swagger swagger;
+
+ private RestClientRequestImpl restClientRequest;
+
+ private HttpClientRequest clientRequest;
+
+ @Before
+ public void initStrBuilder() {
+ accessLogEvent = new ServerAccessLogEvent();
+ routingContext = Mockito.mock(RoutingContext.class);
+ finishEvent = Mockito.mock(InvocationFinishEvent.class);
+ invocation = Mockito.mock(Invocation.class);
+ serverRequest = Mockito.mock(HttpServerRequest.class);
+ operationMeta = Mockito.mock(OperationMeta.class);
+ schemaMeta = Mockito.mock(SchemaMeta.class);
+ swagger = Mockito.mock(Swagger.class);
+ restClientRequest = Mockito.mock(RestClientRequestImpl.class);
+ clientRequest = Mockito.mock(HttpClientRequest.class);
+
+ accessLogEvent.setRoutingContext(routingContext);
+ strBuilder = new StringBuilder();
+ }
+
+ @Test
+ public void clientFormattedElement() {
+ String uri = "/base/test";
+ when(finishEvent.getInvocation()).thenReturn(invocation);
+ when(invocation.getOperationMeta()).thenReturn(operationMeta);
+ when(invocation.getSchemaMeta()).thenReturn(schemaMeta);
+ when(schemaMeta.getSwagger()).thenReturn(swagger);
+ when(swagger.getBasePath()).thenReturn("/base");
+ when(operationMeta.getOperationPath()).thenReturn("/test");
+
+ ITEM.appendFormattedItem(finishEvent, strBuilder);
+ Assert.assertEquals(uri, strBuilder.toString());
+
+ strBuilder = new StringBuilder();
+ Map<String, Object> handlerContext = new HashMap<>();
+ handlerContext.put(RestConst.INVOCATION_HANDLER_REQUESTCLIENT, restClientRequest);
+ when(invocation.getOperationMeta()).thenReturn(null);
+ when(invocation.getSchemaMeta()).thenReturn(null);
+ when(finishEvent.getInvocation()).thenReturn(invocation);
+ when(invocation.getHandlerContext()).thenReturn(handlerContext);
+ when(restClientRequest.getRequest()).thenReturn(clientRequest);
+ when(clientRequest.path()).thenReturn(uri);
+ ITEM.appendFormattedItem(finishEvent, strBuilder);
+ Assert.assertEquals(uri, strBuilder.toString());
+ }
+
+ @Test
+ public void serverFormattedElement() {
+ String uri = "/test";
+ when(routingContext.request()).thenReturn(serverRequest);
+ when(serverRequest.path()).thenReturn(uri);
+ ITEM.appendFormattedItem(accessLogEvent, strBuilder);
+ Assert.assertEquals(uri, strBuilder.toString());
+ }
+
+ @Test
+ public void serverFormattedElementOnRequestIsNull() {
+ when(routingContext.request()).thenReturn(null);
+ ITEM.appendFormattedItem(accessLogEvent, strBuilder);
+ Assert.assertEquals("-", strBuilder.toString());
+ }
+
+ @Test
+ public void clientFormattedElementOnRequestIsNull() {
+ Map<String, Object> handlerContext = new HashMap<>();
+ handlerContext.put(RestConst.INVOCATION_HANDLER_REQUESTCLIENT, restClientRequest);
+ when(finishEvent.getInvocation()).thenReturn(invocation);
+ when(invocation.getHandlerContext()).thenReturn(handlerContext);
+ when(restClientRequest.getRequest()).thenReturn(null);
+ ITEM.appendFormattedItem(finishEvent, strBuilder);
+ Assert.assertEquals("-", strBuilder.toString());
+ }
+
+ @Test
+ public void serverFormattedElementOnMethodIsNull() {
+ when(routingContext.request()).thenReturn(serverRequest);
+ when(serverRequest.path()).thenReturn(null);
+ ITEM.appendFormattedItem(accessLogEvent, strBuilder);
+ Assert.assertEquals("-", strBuilder.toString());
+ }
+
+ @Test
+ public void clientFormattedElementOnMethodIsNull() {
+ Map<String, Object> handlerContext = new HashMap<>();
+ handlerContext.put(RestConst.INVOCATION_HANDLER_REQUESTCLIENT, restClientRequest);
+ when(finishEvent.getInvocation()).thenReturn(invocation);
+ when(invocation.getHandlerContext()).thenReturn(handlerContext);
+ when(restClientRequest.getRequest()).thenReturn(clientRequest);
+ when(clientRequest.path()).thenReturn(null);
+ ITEM.appendFormattedItem(finishEvent, strBuilder);
+ Assert.assertEquals("-", strBuilder.toString());
+ }
+}
diff --git a/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/UrlPathWithQueryItemTest.java b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/UrlPathWithQueryItemTest.java
new file mode 100644
index 0000000..b17fbb6
--- /dev/null
+++ b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/UrlPathWithQueryItemTest.java
@@ -0,0 +1,125 @@
+/*
+ * 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.servicecomb.foundation.log.core.element.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.when;
+
+import org.apache.servicecomb.common.rest.RestConst;
+import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.core.event.InvocationFinishEvent;
+import org.apache.servicecomb.core.event.ServerAccessLogEvent;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import io.vertx.core.http.HttpServerRequest;
+import io.vertx.ext.web.RoutingContext;
+
+public class UrlPathWithQueryItemTest {
+
+ public static final UrlPathWithQueryItem ELEMENT = new UrlPathWithQueryItem();
+
+ private StringBuilder strBuilder;
+
+ private InvocationFinishEvent finishEvent;
+
+ private ServerAccessLogEvent accessLogEvent;
+
+ private RoutingContext routingContext;
+
+ private Invocation invocation;
+
+ private HttpServerRequest serverRequest;
+
+ @Before
+ public void initStrBuilder() {
+ accessLogEvent = new ServerAccessLogEvent();
+ routingContext = Mockito.mock(RoutingContext.class);
+ finishEvent = Mockito.mock(InvocationFinishEvent.class);
+ invocation = Mockito.mock(Invocation.class);
+ serverRequest = Mockito.mock(HttpServerRequest.class);
+
+ accessLogEvent.setRoutingContext(routingContext);
+ strBuilder = new StringBuilder();
+ }
+
+ @Test
+ public void serverFormattedElement() {
+ String uri = "uriTest";
+ when(routingContext.request()).thenReturn(serverRequest);
+ when(serverRequest.uri()).thenReturn(uri);
+ ELEMENT.appendFormattedItem(accessLogEvent, strBuilder);
+ assertEquals(uri, strBuilder.toString());
+ }
+
+ @Test
+ public void clientFormattedElement() {
+ String uri = "uriTest";
+ when(finishEvent.getInvocation()).thenReturn(invocation);
+ when(invocation.getLocalContext(RestConst.REST_CLIENT_REQUEST_PATH)).thenReturn(uri);
+ ELEMENT.appendFormattedItem(finishEvent, strBuilder);
+ assertEquals(uri, strBuilder.toString());
+ }
+
+ @Test
+ public void serverFormattedElementOnRequestIsNull() {
+ when(routingContext.request()).thenReturn(null);
+ ELEMENT.appendFormattedItem(accessLogEvent, strBuilder);
+ assertEquals("-", strBuilder.toString());
+ }
+
+ @Test
+ public void clientFormattedElementOnRequestIsNull() {
+ when(finishEvent.getInvocation()).thenReturn(null);
+ ELEMENT.appendFormattedItem(finishEvent, strBuilder);
+ assertEquals("-", strBuilder.toString());
+ }
+
+ @Test
+ public void serverFormattedElementOnUriIsNull() {
+ when(routingContext.request()).thenReturn(serverRequest);
+ when(serverRequest.uri()).thenReturn(null);
+ ELEMENT.appendFormattedItem(accessLogEvent, strBuilder);
+ assertEquals("-", strBuilder.toString());
+ }
+
+ @Test
+ public void clientFormattedElementOnUriIsNull() {
+ when(finishEvent.getInvocation()).thenReturn(invocation);
+ when(invocation.getLocalContext(RestConst.REST_CLIENT_REQUEST_PATH)).thenReturn(null);
+ ELEMENT.appendFormattedItem(finishEvent, strBuilder);
+ assertEquals("-", strBuilder.toString());
+ }
+
+ @Test
+ public void serverFormattedElementOnUriIsEmpty() {
+ when(routingContext.request()).thenReturn(serverRequest);
+ when(serverRequest.uri()).thenReturn("");
+ ELEMENT.appendFormattedItem(accessLogEvent, strBuilder);
+ assertEquals("-", strBuilder.toString());
+ }
+
+ @Test
+ public void clientFormattedElementOnUriIsEmpty() {
+ when(finishEvent.getInvocation()).thenReturn(invocation);
+ when(invocation.getLocalContext(RestConst.REST_CLIENT_REQUEST_PATH)).thenReturn("");
+ ELEMENT.appendFormattedItem(finishEvent, strBuilder);
+ assertEquals("-", strBuilder.toString());
+ }
+}
diff --git a/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/element/impl/RemoteHostItem.java b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/UserDefinedAccessLogItem.java
similarity index 62%
copy from foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/element/impl/RemoteHostItem.java
copy to foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/UserDefinedAccessLogItem.java
index 0334009..da948c0 100644
--- a/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/element/impl/RemoteHostItem.java
+++ b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/UserDefinedAccessLogItem.java
@@ -18,36 +18,31 @@
package org.apache.servicecomb.foundation.log.core.element.impl;
-import org.apache.servicecomb.core.Endpoint;
import org.apache.servicecomb.core.event.InvocationFinishEvent;
import org.apache.servicecomb.core.event.ServerAccessLogEvent;
-import org.apache.servicecomb.foundation.common.net.URIEndpointObject;
import org.apache.servicecomb.foundation.log.core.element.LogItem;
-import io.vertx.core.http.HttpServerRequest;
import io.vertx.ext.web.RoutingContext;
-public class RemoteHostItem implements LogItem<RoutingContext> {
+/**
+ * For access log extension test
+ */
+public class UserDefinedAccessLogItem implements LogItem<RoutingContext> {
+ private String config;
- public static final String EMPTY_RESULT = "-";
+ public UserDefinedAccessLogItem(String config) {
+ this.config = config;
+ }
@Override
public void appendFormattedItem(ServerAccessLogEvent accessLogEvent, StringBuilder builder) {
- HttpServerRequest request = accessLogEvent.getRoutingContext().request();
- if (null == request || null == request.remoteAddress()) {
- builder.append(EMPTY_RESULT);
- return;
- }
- builder.append(request.remoteAddress().host());
+ builder.append("user-defined-")
+ .append(config);
}
@Override
public void appendFormattedItem(InvocationFinishEvent clientLogEvent, StringBuilder builder) {
- Endpoint endpoint = clientLogEvent.getInvocation().getEndpoint();
- if (null == endpoint || null == endpoint.getAddress()) {
- builder.append(EMPTY_RESULT);
- return;
- }
- builder.append(((URIEndpointObject) endpoint.getAddress()).getHostOrIp());
+ builder.append("user-defined-")
+ .append(config);
}
}
diff --git a/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/element/impl/RemoteHostItem.java b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/UserDefinedAccessLogItemLowPriority.java
similarity index 62%
copy from foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/element/impl/RemoteHostItem.java
copy to foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/UserDefinedAccessLogItemLowPriority.java
index 0334009..8104129 100644
--- a/foundations/foundation-log/src/main/java/org/apache/servicecomb/foundation/log/core/element/impl/RemoteHostItem.java
+++ b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/element/impl/UserDefinedAccessLogItemLowPriority.java
@@ -17,37 +17,25 @@
package org.apache.servicecomb.foundation.log.core.element.impl;
-
-import org.apache.servicecomb.core.Endpoint;
import org.apache.servicecomb.core.event.InvocationFinishEvent;
import org.apache.servicecomb.core.event.ServerAccessLogEvent;
-import org.apache.servicecomb.foundation.common.net.URIEndpointObject;
import org.apache.servicecomb.foundation.log.core.element.LogItem;
-import io.vertx.core.http.HttpServerRequest;
import io.vertx.ext.web.RoutingContext;
-public class RemoteHostItem implements LogItem<RoutingContext> {
-
- public static final String EMPTY_RESULT = "-";
+/**
+ * For access log extension test, will be overridden by {@link RemoteHostItem}("%h"),
+ * and takes no effect.
+ */
+public class UserDefinedAccessLogItemLowPriority implements LogItem<RoutingContext> {
@Override
public void appendFormattedItem(ServerAccessLogEvent accessLogEvent, StringBuilder builder) {
- HttpServerRequest request = accessLogEvent.getRoutingContext().request();
- if (null == request || null == request.remoteAddress()) {
- builder.append(EMPTY_RESULT);
- return;
- }
- builder.append(request.remoteAddress().host());
+ builder.append("OverriddenItem");
}
@Override
public void appendFormattedItem(InvocationFinishEvent clientLogEvent, StringBuilder builder) {
- Endpoint endpoint = clientLogEvent.getInvocation().getEndpoint();
- if (null == endpoint || null == endpoint.getAddress()) {
- builder.append(EMPTY_RESULT);
- return;
- }
- builder.append(((URIEndpointObject) endpoint.getAddress()).getHostOrIp());
+ builder.append("OverriddenItem");
}
}
diff --git a/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/parser/impl/TestCompositeExtendedAccessLogItemMeta.java b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/parser/impl/TestCompositeExtendedAccessLogItemMeta.java
new file mode 100644
index 0000000..a14913b
--- /dev/null
+++ b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/parser/impl/TestCompositeExtendedAccessLogItemMeta.java
@@ -0,0 +1,39 @@
+/*
+ * 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.servicecomb.foundation.log.core.parser.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.servicecomb.foundation.log.core.element.impl.UserDefinedAccessLogItem;
+import org.apache.servicecomb.foundation.log.core.parser.CompositeVertxRestLogItemMeta;
+import org.apache.servicecomb.foundation.log.core.parser.VertxRestLogItemMeta;
+
+
+public class TestCompositeExtendedAccessLogItemMeta extends CompositeVertxRestLogItemMeta {
+ private static final List<VertxRestLogItemMeta> META_LIST = new ArrayList<>();
+
+ static {
+ META_LIST.add(new VertxRestLogItemMeta("%{", "}user-defined", UserDefinedAccessLogItem::new));
+ }
+
+ @Override
+ public List<VertxRestLogItemMeta> getAccessLogItemMetas() {
+ return META_LIST;
+ }
+}
diff --git a/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/parser/impl/TestSingleExtendedAccessLogItemMeta.java b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/parser/impl/TestSingleExtendedAccessLogItemMeta.java
new file mode 100644
index 0000000..46926a3
--- /dev/null
+++ b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/parser/impl/TestSingleExtendedAccessLogItemMeta.java
@@ -0,0 +1,27 @@
+/*
+ * 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.servicecomb.foundation.log.core.parser.impl;
+
+import org.apache.servicecomb.foundation.log.core.element.impl.UserDefinedAccessLogItemLowPriority;
+import org.apache.servicecomb.foundation.log.core.parser.VertxRestLogItemMeta;
+
+public class TestSingleExtendedAccessLogItemMeta extends VertxRestLogItemMeta {
+ public TestSingleExtendedAccessLogItemMeta() {
+ super("%h", null, config -> new UserDefinedAccessLogItemLowPriority(), 1);
+ }
+}
diff --git a/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/parser/impl/VertxRestAccessLogPatternParserTest.java b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/parser/impl/VertxRestAccessLogPatternParserTest.java
new file mode 100644
index 0000000..66dfeed
--- /dev/null
+++ b/foundations/foundation-log/src/test/java/org/apache/servicecomb/foundation/log/core/parser/impl/VertxRestAccessLogPatternParserTest.java
@@ -0,0 +1,362 @@
+/*
+ * 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.servicecomb.foundation.log.core.parser.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Locale;
+import java.util.TimeZone;
+
+import org.apache.servicecomb.core.event.ServerAccessLogEvent;
+import org.apache.servicecomb.foundation.log.core.element.LogItem;
+import org.apache.servicecomb.foundation.log.core.element.impl.CookieItem;
+import org.apache.servicecomb.foundation.log.core.element.impl.DatetimeConfigurableItem;
+import org.apache.servicecomb.foundation.log.core.element.impl.DurationMillisecondItem;
+import org.apache.servicecomb.foundation.log.core.element.impl.DurationSecondItem;
+import org.apache.servicecomb.foundation.log.core.element.impl.FirstLineOfRequestItem;
+import org.apache.servicecomb.foundation.log.core.element.impl.HttpMethodItem;
+import org.apache.servicecomb.foundation.log.core.element.impl.HttpStatusItem;
+import org.apache.servicecomb.foundation.log.core.element.impl.InvocationContextItem;
+import org.apache.servicecomb.foundation.log.core.element.impl.LocalHostItem;
+import org.apache.servicecomb.foundation.log.core.element.impl.LocalPortItem;
+import org.apache.servicecomb.foundation.log.core.element.impl.QueryStringItem;
+import org.apache.servicecomb.foundation.log.core.element.impl.RemoteHostItem;
+import org.apache.servicecomb.foundation.log.core.element.impl.RequestHeaderItem;
+import org.apache.servicecomb.foundation.log.core.element.impl.RequestProtocolItem;
+import org.apache.servicecomb.foundation.log.core.element.impl.ResponseHeaderItem;
+import org.apache.servicecomb.foundation.log.core.element.impl.ResponseSizeItem;
+import org.apache.servicecomb.foundation.log.core.element.impl.TraceIdItem;
+import org.apache.servicecomb.foundation.log.core.element.impl.TransportItem;
+import org.apache.servicecomb.foundation.log.core.element.impl.UrlPathItem;
+import org.apache.servicecomb.foundation.log.core.element.impl.UrlPathWithQueryItem;
+import org.apache.servicecomb.foundation.log.core.parser.CompositeVertxRestLogItemMeta;
+import org.apache.servicecomb.foundation.log.core.parser.VertxRestLogItemMeta;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import io.vertx.ext.web.RoutingContext;
+import mockit.Deencapsulation;
+import mockit.Mock;
+import mockit.MockUp;
+
+public class VertxRestAccessLogPatternParserTest {
+ private static final String ROW_PATTERN = "[cs-method] %m %s%T%D%h%v%p%B%b%r%U%q"
+ + "cs-uri-stemcs-uri-querycs-uri%H%t%{yyyy MM dd HH:mm:ss zzz}t"
+ + "%{yyyy MM dd HH:mm:ss|GMT+0|en-US}t"
+ + "%{incoming-header}i"
+ + "%{outgoing-header}o"
+ + "%{cookie}C"
+ + "%SCB-traceId"
+ + "%{ctx}SCB-ctx"
+ + "%SCB-transport";
+
+ private static VertxRestLogPatternParser logPatternParser = new VertxRestLogPatternParser();
+
+ private ServerAccessLogEvent accessLogEvent;
+
+ private RoutingContext routingContext;
+
+
+ @Before
+ public void initStrBuilder() {
+ routingContext = Mockito.mock(RoutingContext.class);
+ accessLogEvent = new ServerAccessLogEvent();
+ accessLogEvent.setRoutingContext(routingContext);
+ }
+
+ @Test
+ public void testParsePatternFullTest() {
+ List<LogItem<RoutingContext>> result = logPatternParser.parsePattern(ROW_PATTERN);
+ assertEquals(29, result.size());
+ StringBuilder builder = new StringBuilder();
+ result.get(0).appendFormattedItem(accessLogEvent, builder);
+ assertEquals("[", builder.toString());
+ assertEquals(HttpMethodItem.class, result.get(1).getClass());
+ builder = new StringBuilder();
+ result.get(2).appendFormattedItem(accessLogEvent, builder);
+ assertEquals("] ", builder.toString());
+ assertEquals(HttpMethodItem.class, result.get(3).getClass());
+ builder = new StringBuilder();
+ result.get(4).appendFormattedItem(accessLogEvent, builder);
+ assertEquals(" ", builder.toString());
+ assertEquals(HttpStatusItem.class, result.get(5).getClass());
+ assertEquals(DurationSecondItem.class, result.get(6).getClass());
+ assertEquals(DurationMillisecondItem.class, result.get(7).getClass());
+ assertEquals(RemoteHostItem.class, result.get(8).getClass());
+ assertEquals(LocalHostItem.class, result.get(9).getClass());
+ assertEquals(LocalPortItem.class, result.get(10).getClass());
+ assertEquals(ResponseSizeItem.class, result.get(11).getClass());
+ assertEquals("0", ((ResponseSizeItem) result.get(11)).getZeroBytes());
+ assertEquals(ResponseSizeItem.class, result.get(12).getClass());
+ assertEquals("-", ((ResponseSizeItem) result.get(12)).getZeroBytes());
+ assertEquals(FirstLineOfRequestItem.class, result.get(13).getClass());
+ assertEquals(UrlPathItem.class, result.get(14).getClass());
+ assertEquals(QueryStringItem.class, result.get(15).getClass());
+ assertEquals(UrlPathItem.class, result.get(16).getClass());
+ assertEquals(QueryStringItem.class, result.get(17).getClass());
+ assertEquals(UrlPathWithQueryItem.class, result.get(18).getClass());
+ assertEquals(RequestProtocolItem.class, result.get(19).getClass());
+ assertEquals(DatetimeConfigurableItem.class, result.get(20).getClass());
+ assertEquals(DatetimeConfigurableItem.DEFAULT_DATETIME_PATTERN,
+ ((DatetimeConfigurableItem) result.get(20)).getPattern());
+ assertEquals(DatetimeConfigurableItem.DEFAULT_LOCALE, ((DatetimeConfigurableItem) result.get(20)).getLocale());
+ assertEquals(TimeZone.getDefault(), ((DatetimeConfigurableItem) result.get(20)).getTimezone());
+ assertEquals("yyyy MM dd HH:mm:ss zzz", ((DatetimeConfigurableItem) result.get(21)).getPattern());
+ assertEquals(DatetimeConfigurableItem.DEFAULT_LOCALE, ((DatetimeConfigurableItem) result.get(21)).getLocale());
+ assertEquals(TimeZone.getDefault(), ((DatetimeConfigurableItem) result.get(21)).getTimezone());
+ assertEquals("yyyy MM dd HH:mm:ss", ((DatetimeConfigurableItem) result.get(22)).getPattern());
+ assertEquals(Locale.forLanguageTag("en-US"), ((DatetimeConfigurableItem) result.get(22)).getLocale());
+ assertEquals(TimeZone.getTimeZone("GMT+0"), ((DatetimeConfigurableItem) result.get(22)).getTimezone());
+ assertEquals(RequestHeaderItem.class, result.get(23).getClass());
+ assertEquals("incoming-header", ((RequestHeaderItem) result.get(23)).getVarName());
+ assertEquals(ResponseHeaderItem.class, result.get(24).getClass());
+ assertEquals("outgoing-header", ((ResponseHeaderItem) result.get(24)).getVarName());
+ assertEquals(CookieItem.class, result.get(25).getClass());
+ assertEquals("cookie", ((CookieItem) result.get(25)).getVarName());
+ assertEquals(TraceIdItem.class, result.get(26).getClass());
+ assertEquals(InvocationContextItem.class, result.get(27).getClass());
+ assertEquals("ctx", ((InvocationContextItem) result.get(27)).getVarName());
+ assertEquals(TransportItem.class, result.get(28).getClass());
+ }
+
+ @Test
+ public void testParsePattern() {
+ String pattern = " %m cs-uri-stem %{response-header}o ";
+ List<LogItem<RoutingContext>> result = logPatternParser.parsePattern(pattern);
+ assertEquals(7, result.size());
+ StringBuilder stringBuilder = new StringBuilder();
+ result.get(0).appendFormattedItem(accessLogEvent, stringBuilder);
+ assertEquals(" ", stringBuilder.toString());
+ assertEquals(HttpMethodItem.class, result.get(1).getClass());
+ stringBuilder = new StringBuilder();
+ result.get(2).appendFormattedItem(accessLogEvent, stringBuilder);
+ assertEquals(" ", stringBuilder.toString());
+ assertEquals(UrlPathItem.class, result.get(3).getClass());
+ stringBuilder = new StringBuilder();
+ result.get(4).appendFormattedItem(accessLogEvent, stringBuilder);
+ assertEquals(" ", stringBuilder.toString());
+ assertEquals(ResponseHeaderItem.class, result.get(5).getClass());
+ assertEquals("response-header", ((ResponseHeaderItem) result.get(5)).getVarName());
+ stringBuilder = new StringBuilder();
+ result.get(6).appendFormattedItem(accessLogEvent, stringBuilder);
+ assertEquals(" ", stringBuilder.toString());
+ }
+
+ @Test
+ public void testParsePatternWithNoBlank() {
+ String pattern = "%mcs-uri-stem%{response-header}o";
+ List<LogItem<RoutingContext>> result = logPatternParser.parsePattern(pattern);
+ assertEquals(3, result.size());
+
+ assertEquals(HttpMethodItem.class, result.get(0).getClass());
+ assertEquals(UrlPathItem.class, result.get(1).getClass());
+ assertEquals(ResponseHeaderItem.class, result.get(2).getClass());
+ assertEquals("response-header", ((ResponseHeaderItem) result.get(2)).getVarName());
+ }
+
+ @Test
+ public void testParsePatternComplex() {
+ String pattern = "%m cs-uri-stem %{response-header}o abc cs-uri-query %s%{request} header}i plain cs-uri";
+ List<LogItem<RoutingContext>> result = logPatternParser.parsePattern(pattern);
+ assertEquals(12, result.size());
+
+ assertEquals(HttpMethodItem.class, result.get(0).getClass());
+ StringBuilder stringBuilder = new StringBuilder();
+ result.get(1).appendFormattedItem(accessLogEvent, stringBuilder);
+ assertEquals(" ", stringBuilder.toString());
+ assertEquals(UrlPathItem.class, result.get(2).getClass());
+ stringBuilder = new StringBuilder();
+ result.get(3).appendFormattedItem(accessLogEvent, stringBuilder);
+ assertEquals(" ", stringBuilder.toString());
+ assertEquals(ResponseHeaderItem.class, result.get(4).getClass());
+ assertEquals("response-header", ((ResponseHeaderItem) result.get(4)).getVarName());
+ stringBuilder = new StringBuilder();
+ result.get(5).appendFormattedItem(accessLogEvent, stringBuilder);
+ assertEquals(" abc ", stringBuilder.toString());
+ assertEquals(QueryStringItem.class, result.get(6).getClass());
+ stringBuilder = new StringBuilder();
+ result.get(7).appendFormattedItem(accessLogEvent, stringBuilder);
+ assertEquals(" ", stringBuilder.toString());
+ assertEquals(HttpStatusItem.class, result.get(8).getClass());
+ assertEquals(RequestHeaderItem.class, result.get(9).getClass());
+ assertEquals("request} header", ((RequestHeaderItem) result.get(9)).getVarName());
+ stringBuilder = new StringBuilder();
+ result.get(10).appendFormattedItem(accessLogEvent, stringBuilder);
+ assertEquals(" plain ", stringBuilder.toString());
+ assertEquals(UrlPathWithQueryItem.class, result.get(11).getClass());
+ }
+
+ Comparator<VertxRestLogItemMeta> comparator = VertxRestLogPatternParser.accessLogItemMetaComparator;
+
+ /**
+ * one factor test
+ */
+ @Test
+ public void testCompareMetaSimple() {
+ Assert.assertTrue(
+ comparator.compare(
+ new VertxRestLogItemMeta(null, null, null, 0),
+ new VertxRestLogItemMeta(null, null, null, 1)
+ ) < 0
+ );
+ Assert.assertTrue(
+ comparator.compare(
+ new VertxRestLogItemMeta(null, "}abc", null, 0),
+ new VertxRestLogItemMeta(null, null, null, 0)
+ ) < 0
+ );
+ Assert.assertTrue(
+ comparator.compare(
+ new VertxRestLogItemMeta(null, "}abc", null, 0),
+ new VertxRestLogItemMeta(null, "}de", null, 0)
+ ) < 0
+ );
+ Assert.assertTrue(
+ comparator.compare(
+ new VertxRestLogItemMeta(null, "}abc", null, 0),
+ new VertxRestLogItemMeta(null, "}ab", null, 0)
+ ) < 0
+ );
+ Assert.assertTrue(
+ comparator.compare(
+ new VertxRestLogItemMeta("%abc", null, null, 0),
+ new VertxRestLogItemMeta("%de", null, null, 0)
+ ) < 0
+ );
+ Assert.assertTrue(
+ comparator.compare(
+ new VertxRestLogItemMeta("%abc", null, null, 0),
+ new VertxRestLogItemMeta("%ab", null, null, 0)
+ ) < 0
+ );
+ Assert.assertEquals(0, comparator.compare(
+ new VertxRestLogItemMeta("%abc", null, null, 0),
+ new VertxRestLogItemMeta("%abc", null, null, 0)
+ ));
+ }
+
+ /**
+ * multiple factors test
+ */
+ @Test
+ public void testCompareMetaComplex() {
+ Assert.assertTrue(
+ comparator.compare(
+ new VertxRestLogItemMeta("%bcd", "}ab", null, 0),
+ new VertxRestLogItemMeta("%abc", "}abc", null, 0)
+ ) > 0
+ );
+ Assert.assertTrue(
+ comparator.compare(
+ new VertxRestLogItemMeta("%abc", null, null, 0),
+ new VertxRestLogItemMeta("%bcd", "}ab", null, 0)
+ ) > 0
+ );
+ Assert.assertTrue(
+ comparator.compare(
+ new VertxRestLogItemMeta("%bcd", "}abc", null, 0),
+ new VertxRestLogItemMeta("%abc", "}abc", null, 0)
+ ) > 0
+ );
+ Assert.assertTrue(
+ comparator.compare(
+ new VertxRestLogItemMeta("%abc", "}abc", null, 1),
+ new VertxRestLogItemMeta("%ab", "}ab", null, 0)
+ ) > 0
+ );
+ }
+
+ @Test
+ public void testComparePlaceholderString() {
+ Assert.assertTrue(
+ VertxRestLogPatternParser.comparePlaceholderString("abc", "bbc") < 0
+ );
+ Assert.assertTrue(
+ VertxRestLogPatternParser.comparePlaceholderString("abc", "ab") < 0
+ );
+ Assert.assertEquals(0, VertxRestLogPatternParser.comparePlaceholderString("abc", "abc"));
+ Assert.assertTrue(
+ VertxRestLogPatternParser.comparePlaceholderString("bbc", "abc") > 0
+ );
+ Assert.assertTrue(
+ VertxRestLogPatternParser.comparePlaceholderString("ab", "abc") > 0
+ );
+ }
+
+ @Test
+ public void testExtendedVertxRestAccessLogItemCreator() {
+ final List<VertxRestLogItemMeta> metaList0 = new ArrayList<>();
+ metaList0.add(new VertxRestLogItemMeta("%{", "}abc", null));
+ metaList0.add(new VertxRestLogItemMeta("%{", "}a", null));
+ metaList0.add(new VertxRestLogItemMeta("%_", null, null, -1));
+
+ final List<VertxRestLogItemMeta> metaList1 = new ArrayList<>();
+ metaList0.add(new VertxRestLogItemMeta("%a", "}abc", null));
+ metaList0.add(new VertxRestLogItemMeta("%0", "}abc", null, 1));
+ metaList0.add(new VertxRestLogItemMeta("%m", null, null));
+
+ new MockUp<VertxRestLogPatternParser>() {
+ @Mock
+ List<VertxRestLogItemMeta> loadVertxRestLogItemMeta() {
+ List<VertxRestLogItemMeta> metaList = new ArrayList<>(1);
+ CompositeVertxRestLogItemMeta compositeMeta0 = new CompositeVertxRestLogItemMeta() {
+ @Override
+ public List<VertxRestLogItemMeta> getAccessLogItemMetas() {
+ return metaList0;
+ }
+ };
+ CompositeVertxRestLogItemMeta compositeMeta1 = new CompositeVertxRestLogItemMeta() {
+ @Override
+ public List<VertxRestLogItemMeta> getAccessLogItemMetas() {
+ return metaList1;
+ }
+ };
+ metaList.add(compositeMeta0);
+ metaList.add(compositeMeta1);
+ metaList.add(new VertxRestLogItemMeta("%{", null, null));
+ return metaList;
+ }
+ };
+
+ VertxRestLogPatternParser parser = new VertxRestLogPatternParser();
+
+ List<VertxRestLogItemMeta> accessLogItemMetaList =
+ Deencapsulation.getField(parser, "metaList");
+
+ assertEquals(7, accessLogItemMetaList.size());
+ assertEquals("%_", accessLogItemMetaList.get(0).getPrefix());
+ assertEquals("%a", accessLogItemMetaList.get(1).getPrefix());
+ assertEquals("}abc", accessLogItemMetaList.get(1).getSuffix());
+ assertEquals("%{", accessLogItemMetaList.get(2).getPrefix());
+ assertEquals("}abc", accessLogItemMetaList.get(2).getSuffix());
+ assertEquals("%{", accessLogItemMetaList.get(3).getPrefix());
+ assertEquals("}a", accessLogItemMetaList.get(3).getSuffix());
+ assertEquals("%m", accessLogItemMetaList.get(4).getPrefix());
+ assertNull(accessLogItemMetaList.get(4).getSuffix());
+ assertEquals("%{", accessLogItemMetaList.get(5).getPrefix());
+ assertNull(accessLogItemMetaList.get(5).getSuffix());
+ assertEquals("%0", accessLogItemMetaList.get(6).getPrefix());
+ assertEquals("}abc", accessLogItemMetaList.get(6).getSuffix());
+ }
+}
diff --git a/foundations/foundation-log/src/test/resources/META-INF/services/org.apache.servicecomb.foundation.log.core.parser.VertxRestLogItemMeta b/foundations/foundation-log/src/test/resources/META-INF/services/org.apache.servicecomb.foundation.log.core.parser.VertxRestLogItemMeta
new file mode 100644
index 0000000..1ef1185
--- /dev/null
+++ b/foundations/foundation-log/src/test/resources/META-INF/services/org.apache.servicecomb.foundation.log.core.parser.VertxRestLogItemMeta
@@ -0,0 +1,19 @@
+#
+# 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.
+#
+
+org.apache.servicecomb.foundation.log.core.parser.impl.TestCompositeExtendedAccessLogItemMeta
+org.apache.servicecomb.foundation.log.core.parser.impl.TestSingleExtendedAccessLogItemMeta
\ No newline at end of file