diff --git a/.github/workflows/skywalking.yaml b/.github/workflows/skywalking.yaml index 599d547c4ab6..1bde7c328a28 100644 --- a/.github/workflows/skywalking.yaml +++ b/.github/workflows/skywalking.yaml @@ -826,7 +826,7 @@ jobs: KUBERNETES_VERSION: ${{ matrix.versions.kubernetes }} ALS_ANALYZER: ${{ matrix.analyzer }} with: - e2e-file: $GITHUB_WORKSPACE/test/e2e-v2/cases/istio/als/e2e.yaml + e2e-file: test/e2e-v2/cases/istio/als/e2e.yaml - if: ${{ failure() }} run: | df -h @@ -839,6 +839,67 @@ jobs: name: test-logs-${{ matrix.test.name }} path: "${{ env.SW_INFRA_E2E_LOG_DIR }}" + e2e-test-istio-ambient: + if: | + ( always() && ! cancelled() ) && + ((github.event_name == 'schedule' && github.repository == 'apache/skywalking') || needs.changes.outputs.oap == 'true') + name: E2E test + needs: [docker] + runs-on: ubuntu-24.04 + timeout-minutes: 60 + strategy: + fail-fast: false + matrix: + analyzer: [k8s-mesh, mx-mesh] + versions: + - istio: 1.23.0 + kubernetes: 28 + - istio: 1.24.0 + kubernetes: 28 + steps: + - uses: actions/checkout@v4 + with: + submodules: true + persist-credentials: false + - run: grep -v '^#' test/e2e-v2/script/env >> "$GITHUB_ENV" + - uses: apache/skywalking-cli/actions/setup@master + with: + version: ${{ env.SW_CTL_COMMIT }} + - uses: actions/download-artifact@v4 + name: Download docker images + with: + name: docker-images-11 + path: docker-images + - name: Load docker images + run: | + find docker-images -name "*.tar" -exec docker load -i {} \; + find docker-images -name "*.tar" -exec rm {} \; + - name: Login to ghcr + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: ${{ matrix.test.name }} + uses: apache/skywalking-infra-e2e@cf589b4a0b9f8e6f436f78e9cfd94a1ee5494180 + env: + ISTIO_VERSION: ${{ matrix.versions.istio }} + KUBERNETES_VERSION: ${{ matrix.versions.kubernetes }} + ALS_ANALYZER: ${{ matrix.analyzer }} + with: + e2e-file: test/e2e-v2/cases/istio/ambient-als/e2e.yaml + - if: ${{ failure() }} + run: | + df -h + du -sh . + docker images + - uses: actions/upload-artifact@v4 + if: ${{ failure() }} + name: Upload Logs + with: + name: test-istio-ambient-logs-${{ matrix.versions.istio }}-${{ matrix.versions.kubernetes }}-${{ matrix.analyzer }} + path: "${{ env.SW_INFRA_E2E_LOG_DIR }}" + e2e-test-java-versions: if: | ( always() && ! cancelled() ) && @@ -1004,6 +1065,7 @@ jobs: - slow-integration-test - e2e-test - e2e-test-istio + - e2e-test-istio-ambient - e2e-test-java-versions runs-on: ubuntu-latest timeout-minutes: 10 @@ -1023,6 +1085,7 @@ jobs: timeConsumingITResults=${{ needs.slow-integration-test.result }}; e2eResults=${{ needs.e2e-test.result }}; e2eIstioResults=${{ needs.e2e-test-istio.result }}; + e2eIstioAmbientResults=${{ needs.e2e-test-istio-ambient.result }}; e2eJavaVersionResults=${{ needs.e2e-test-java-versions.result }}; [[ ${depLicenseResults} == 'success' ]] || [[ ${execute} != 'true' && ${depLicenseResults} == 'skipped' ]] || exit -2; @@ -1030,6 +1093,7 @@ jobs: [[ ${integrationResults} == 'success' ]] || [[ ${execute} != 'true' && ${integrationResults} == 'skipped' ]] || exit -4; [[ ${e2eResults} == 'success' ]] || [[ ${execute} != 'true' && ${e2eResults} == 'skipped' ]] || exit -5; [[ ${e2eIstioResults} == 'success' ]] || [[ ${execute} != 'true' && ${e2eIstioResults} == 'skipped' ]] || exit -6; + [[ ${e2eIstioAmbientResults} == 'success' ]] || [[ ${execute} != 'true' && ${e2eIstioAmbientResults} == 'skipped' ]] || exit -6; [[ ${e2eJavaVersionResults} == 'success' ]] || [[ ${execute} != 'true' && ${e2eJavaVersionResults} == 'skipped' ]] || exit -7; [[ ${timeConsumingITResults} == 'success' ]] || [[ ${execute} != 'true' && ${timeConsumingITResults} == 'skipped' ]] || exit -8; diff --git a/apm-protocol/apm-network/src/main/proto b/apm-protocol/apm-network/src/main/proto index 07e601830118..157baf3e7a97 160000 --- a/apm-protocol/apm-network/src/main/proto +++ b/apm-protocol/apm-network/src/main/proto @@ -1 +1 @@ -Subproject commit 07e6018301187a6a9429e5c204c62df1e4db7a6b +Subproject commit 157baf3e7a9710d3041e9caec39eecab7e0c5a82 diff --git a/docs/en/changes/changes.md b/docs/en/changes/changes.md index b167a8d4e648..920a7a99e13a 100644 --- a/docs/en/changes/changes.md +++ b/docs/en/changes/changes.md @@ -19,6 +19,7 @@ * Support analysis waypoint metrics in Envoy ALS receiver. * Add Ztunnel component in the topology. * [Break Change] Change `compomentId` to `componentIds` in the K8SServiceRelation Scope. +* Adapt the mesh metrics if detect the ambient mesh in the eBPF access log receiver. #### UI diff --git a/oap-server/server-receiver-plugin/skywalking-ebpf-receiver-plugin/pom.xml b/oap-server/server-receiver-plugin/skywalking-ebpf-receiver-plugin/pom.xml index 2863e5907d9d..4329ffaebff8 100644 --- a/oap-server/server-receiver-plugin/skywalking-ebpf-receiver-plugin/pom.xml +++ b/oap-server/server-receiver-plugin/skywalking-ebpf-receiver-plugin/pom.xml @@ -33,10 +33,15 @@ skywalking-sharing-server-plugin ${project.version} + + org.apache.skywalking + skywalking-mesh-receiver-plugin + ${project.version} + org.apache.skywalking agent-analyzer ${project.version} - \ No newline at end of file + diff --git a/oap-server/server-receiver-plugin/skywalking-ebpf-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/ebpf/provider/handler/AccessLogServiceHandler.java b/oap-server/server-receiver-plugin/skywalking-ebpf-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/ebpf/provider/handler/AccessLogServiceHandler.java index 9c469b176cac..118eadaed38d 100644 --- a/oap-server/server-receiver-plugin/skywalking-ebpf-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/ebpf/provider/handler/AccessLogServiceHandler.java +++ b/oap-server/server-receiver-plugin/skywalking-ebpf-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/ebpf/provider/handler/AccessLogServiceHandler.java @@ -23,6 +23,7 @@ import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; +import org.apache.skywalking.aop.server.receiver.mesh.TelemetryDataDispatcher; import org.apache.skywalking.apm.network.common.v3.DetectPoint; import org.apache.skywalking.apm.network.ebpf.accesslog.v3.AccessLogConnection; import org.apache.skywalking.apm.network.ebpf.accesslog.v3.AccessLogConnectionTLSMode; @@ -46,7 +47,15 @@ import org.apache.skywalking.apm.network.ebpf.accesslog.v3.IPAddress; import org.apache.skywalking.apm.network.ebpf.accesslog.v3.KubernetesProcessAddress; import org.apache.skywalking.apm.network.ebpf.accesslog.v3.ZTunnelAttachmentEnvironment; +import org.apache.skywalking.apm.network.ebpf.accesslog.v3.ZTunnelAttachmentEnvironmentDetectBy; import org.apache.skywalking.apm.network.ebpf.accesslog.v3.ZTunnelAttachmentSecurityPolicy; +import org.apache.skywalking.apm.network.servicemesh.v3.HTTPServiceMeshMetric; +import org.apache.skywalking.apm.network.servicemesh.v3.HTTPServiceMeshMetrics; +import org.apache.skywalking.apm.network.servicemesh.v3.Protocol; +import org.apache.skywalking.apm.network.servicemesh.v3.ServiceMeshMetrics; +import org.apache.skywalking.apm.network.servicemesh.v3.TCPServiceMeshMetric; +import org.apache.skywalking.apm.network.servicemesh.v3.TCPServiceMeshMetrics; +import org.apache.skywalking.library.elasticsearch.response.NodeInfo; import org.apache.skywalking.library.kubernetes.ObjectID; import org.apache.skywalking.oap.meter.analyzer.k8s.K8sInfoRegistry; import org.apache.skywalking.oap.server.core.Const; @@ -60,6 +69,7 @@ import org.apache.skywalking.oap.server.core.source.K8SServiceInstance; import org.apache.skywalking.oap.server.core.source.K8SServiceInstanceRelation; import org.apache.skywalking.oap.server.core.source.K8SServiceRelation; +import org.apache.skywalking.oap.server.core.source.Service; import org.apache.skywalking.oap.server.core.source.SourceReceiver; import org.apache.skywalking.oap.server.library.module.ModuleManager; import org.apache.skywalking.oap.server.library.util.StringUtil; @@ -74,6 +84,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; @@ -100,6 +111,7 @@ public AccessLogServiceHandler(ModuleManager moduleManager) { this.sourceReceiver = moduleManager.find(CoreModule.NAME).provider().getService(SourceReceiver.class); this.namingControl = moduleManager.find(CoreModule.NAME).provider().getService(NamingControl.class); + TelemetryDataDispatcher.init(moduleManager); MetricsCreator metricsCreator = moduleManager.find(TelemetryModule.NAME) .provider() .getService(MetricsCreator.class); @@ -150,6 +162,8 @@ public void onNext(EBPFAccessLogMessage logMessage) { return; } + prepareForDispatch(node, connection, logMessage); + for (AccessLogKernelLog accessLogKernelLog : logMessage.getKernelLogsList()) { inCounter.inc(); dispatchKernelLog(node, connection, accessLogKernelLog); @@ -178,6 +192,119 @@ public void onCompleted() { }; } + protected void prepareForDispatch(NodeInfo node, ConnectionInfo connection, EBPFAccessLogMessage logMessage) { + // if the connection is communicated with ztunnel, then needs to generate mesh metrics + if (connection.getOriginalConnection().hasAttachment() && connection.getOriginalConnection().getAttachment().hasZTunnel()) { + prepareDispatchForZtunnelMesh(node, connection, logMessage); + } + } + + protected void prepareDispatchForZtunnelMesh(NodeInfo node, ConnectionInfo connection, EBPFAccessLogMessage logMessage) { + final K8SServiceRelation serviceRelation = connection.toServiceRelation(); + buildBaseServiceFromRelation(serviceRelation, Layer.MESH) + .forEach(sourceReceiver::receive); + // adapt to the mesh metrics + String tlsMode = Const.TLS_MODE.NON_TLS; + if (AccessLogConnectionTLSMode.TLS.equals(connection.getTlsMode())) { + tlsMode = Const.TLS_MODE.TLS; + } + if (ZTunnelAttachmentSecurityPolicy.MTLS.equals(connection.getOriginalConnection().getAttachment().getZTunnel().getSecurityPolicy())) { + tlsMode = Const.TLS_MODE.M_TLS; + } + + if (logMessage.hasProtocolLog()) { + final AccessLogProtocolLogs protocolLog = logMessage.getProtocolLog(); + final ServiceMeshMetrics.Builder serviceMeshMetrics = ServiceMeshMetrics.newBuilder(); + switch (protocolLog.getProtocolCase()) { + case HTTP: + serviceMeshMetrics.setHttpMetrics(HTTPServiceMeshMetrics.newBuilder() + .addMetrics(generateHTTPServiceMeshMetrics(node, connection, protocolLog.getHttp(), tlsMode))); + break; + } + TelemetryDataDispatcher.process(serviceMeshMetrics.build()); + } + + final ServiceMeshMetrics.Builder serviceMeshMetrics = ServiceMeshMetrics.newBuilder(); + final TCPServiceMeshMetrics.Builder builder = TCPServiceMeshMetrics.newBuilder(); + for (AccessLogKernelLog accessLogKernelLog : logMessage.getKernelLogsList()) { + Optional.ofNullable(generateTCPServiceMeshMetrics(node, connection, accessLogKernelLog, tlsMode)) + .ifPresent(builder::addMetrics); + } + serviceMeshMetrics.setTcpMetrics(builder.build()); + TelemetryDataDispatcher.process(serviceMeshMetrics.build()); + } + + protected HTTPServiceMeshMetric generateHTTPServiceMeshMetrics(NodeInfo node, ConnectionInfo connection, + AccessLogHTTPProtocol http, String tlsMode) { + KubernetesProcessAddress source, dest; + if (DetectPoint.client.equals(connection.getRole())) { + source = connection.getLocal(); + dest = connection.getRemote(); + } else { + source = connection.getRemote(); + dest = connection.getLocal(); + } + final long startTime = node.parseTimestamp(http.getStartTime()); + final long endTime = node.parseTimestamp(http.getEndTime()); + return HTTPServiceMeshMetric.newBuilder() + .setStartTime(startTime) + .setEndTime(endTime) + .setSourceServiceName(buildServiceNameByAddress(node, source)) + .setSourceServiceInstance(buildServiceInstanceName(source)) + .setDestServiceName(buildServiceNameByAddress(node, dest)) + .setDestServiceInstance(buildServiceInstanceName(dest)) + .setEndpoint(buildHTTPProtocolEndpointName(connection, http)) + .setLatency((int) (endTime - startTime)) + .setResponseCode(http.getResponse().getStatusCode()) + .setStatus(http.getResponse().getStatusCode() < 500) + .setProtocol(Protocol.HTTP) + .setDetectPoint(connection.getRole()) + .setTlsMode(tlsMode).build(); + } + + protected TCPServiceMeshMetric generateTCPServiceMeshMetrics(NodeInfo node, ConnectionInfo connection, + AccessLogKernelLog kernelLog, String tlsMode) { + long receivedBytes = 0, sentBytes = 0; + long startTime = 0, endTime = 0; + switch (kernelLog.getOperationCase()) { + case CONNECT: + case ACCEPT: + case CLOSE: + return null; + case WRITE: + final AccessLogKernelWriteOperation write = kernelLog.getWrite(); + sentBytes = write.getL4Metrics().getTotalPackageSize(); + startTime = node.parseTimestamp(write.getStartTime()); + endTime = node.parseTimestamp(write.getEndTime()); + break; + case READ: + final AccessLogKernelReadOperation read = kernelLog.getRead(); + receivedBytes = read.getL2Metrics().getTotalPackageSize(); + startTime = node.parseTimestamp(read.getStartTime()); + endTime = node.parseTimestamp(read.getEndTime()); + break; + } + KubernetesProcessAddress source, dest; + if (DetectPoint.client.equals(connection.getRole())) { + source = connection.getLocal(); + dest = connection.getRemote(); + } else { + source = connection.getRemote(); + dest = connection.getLocal(); + } + return TCPServiceMeshMetric.newBuilder() + .setStartTime(startTime) + .setEndTime(endTime) + .setSourceServiceName(buildServiceNameByAddress(node, source)) + .setSourceServiceInstance(buildServiceInstanceName(source)) + .setDestServiceName(buildServiceNameByAddress(node, dest)) + .setDestServiceInstance(buildServiceInstanceName(dest)) + .setDetectPoint(connection.getRole()) + .setTlsMode(tlsMode) + .setReceivedBytes(receivedBytes) + .setSentBytes(sentBytes).build(); + } + protected List buildKernelLogMetrics(NodeInfo node, ConnectionInfo connection, AccessLogKernelLog kernelLog) { return Arrays.asList(connection.toService(), connection.toServiceInstance(), connection.toServiceRelation(), connection.toServiceInstanceRelation()); @@ -395,6 +522,11 @@ public long parseMinuteTimeBucket(EBPFTimestamp timestamp) { return TimeBucket.getMinuteTimeBucket(seconds * 1000); } + public long parseTimestamp(EBPFTimestamp timestamp) { + return TimeUnit.SECONDS.toMillis(bootTime.getSeconds() + + TimeUnit.NANOSECONDS.toSeconds(timestamp.getOffset().getOffset())); + } + public boolean shouldExcludeNamespace(String namespace) { return excludeNamespaces.contains(namespace); } @@ -422,17 +554,19 @@ protected String buildServiceInstanceName(KubernetesProcessAddress address) { } protected String buildProtocolEndpointName(ConnectionInfo connectionInfo, AccessLogProtocolLogs protocol) { - final String serviceName = connectionInfo.buildLocalServiceName(); switch (protocol.getProtocolCase()) { case HTTP: - final AccessLogHTTPProtocol http = protocol.getHttp(); - return namingControl.formatEndpointName(serviceName, - StringUtils.upperCase(http.getRequest().getMethod().name()) + ":" + http.getRequest().getPath()); + return buildHTTPProtocolEndpointName(connectionInfo, protocol.getHttp()); default: return null; } } + protected String buildHTTPProtocolEndpointName(ConnectionInfo connectionInfo, AccessLogHTTPProtocol http) { + return namingControl.formatEndpointName(connectionInfo.buildLocalServiceName(), + StringUtils.upperCase(http.getRequest().getMethod().name()) + ":" + http.getRequest().getPath()); + } + protected void recordIgnoreSameService(String sourceService) { final DropDataReason dropDataReason = dropReasons.computeIfAbsent(sourceService, key -> DropDataReason.buildWhenSameService(sourceService)); @@ -491,11 +625,13 @@ protected void printDropReasons() { protected KubernetesProcessAddress buildKubernetesAddressByIP(NodeInfo nodeInfo, AccessLogConnection connection, boolean isLocal, IPAddress ipAddress) { String host = ipAddress.getHost(); - // if the resolving address is not local, and have attached ztunnel info, then using the ztunnel mapped host - if (!isLocal && connection.hasAttachment() && connection.getAttachment().hasZTunnel()) { + // if the resolving address is not local, have attached ztunnel info, + // and must is detected by outbound, then using the ztunnel mapped host + if (!isLocal && connection.hasAttachment() && connection.getAttachment().hasZTunnel() && + ZTunnelAttachmentEnvironmentDetectBy.ZTUNNEL_OUTBOUND_FUNC.equals(connection.getAttachment().getZTunnel().getBy())) { final ZTunnelAttachmentEnvironment ztunnel = connection.getAttachment().getZTunnel(); host = ztunnel.getRealDestinationIp(); - log.debug("detected the ztunnel connection, so update the remote IP address as: {}, detect by: {}", host, + log.debug("detected the ztunnel outbound connection, so update the remote IP address as: {}, detect by: {}", host, ztunnel.getBy()); } final ObjectID service = K8sInfoRegistry.getInstance().findServiceByIP(host); @@ -535,9 +671,11 @@ protected KubernetesProcessAddress buildRemoteAddress(NodeInfo nodeInfo, ObjectI protected List buildConnectionComponentId(ConnectionInfo connectionInfo) { final AccessLogConnection originalConnection = connectionInfo.getOriginalConnection(); - if (originalConnection.hasAttachment() && originalConnection.getAttachment().hasZTunnel() && - ZTunnelAttachmentSecurityPolicy.MTLS.equals(originalConnection.getAttachment().getZTunnel().getSecurityPolicy())) { - return Arrays.asList(142, 162); // mTLS, ztunnel + if (originalConnection.hasAttachment() && originalConnection.getAttachment().hasZTunnel()) { + if (ZTunnelAttachmentSecurityPolicy.MTLS.equals(originalConnection.getAttachment().getZTunnel().getSecurityPolicy())) { + return Arrays.asList(142, 162); // mTLS, ztunnel + } + return Arrays.asList(162); // ztunnel } return Arrays.asList(buildProtocolComponentID(connectionInfo)); } @@ -725,6 +863,10 @@ public org.apache.skywalking.oap.server.core.source.DetectPoint parseToSourceRol } } + public AccessLogConnection getOriginal() { + return originalConnection; + } + public String toString() { return String.format("local: %s, remote: %s, role: %s, tlsMode: %s, protocolType: %s, valid: %b", buildConnectionAddressString(originalConnection.getLocal()), @@ -766,4 +908,21 @@ public void increaseCount() { protected long convertNsToMs(long latency) { return TimeUnit.NANOSECONDS.toMillis(latency); } + + protected List buildBaseServiceFromRelation(K8SServiceRelation relation, Layer layer) { + if (relation == null) { + return Collections.emptyList(); + } + Service localService = new Service(); + localService.setLayer(layer); + localService.setName(relation.getSourceServiceName()); + localService.setTimeBucket(TimeBucket.getMinuteTimeBucket(System.currentTimeMillis())); + Service remoteService = new Service(); + remoteService.setLayer(layer); + remoteService.setName(relation.getDestServiceName()); + remoteService.setTimeBucket(TimeBucket.getMinuteTimeBucket(System.currentTimeMillis())); + log.debug("generate the {} layer service local service: {}, remote service: {}", + layer, relation.getSourceServiceName(), relation.getDestServiceName()); + return Arrays.asList(localService, remoteService); + } } diff --git a/oap-server/server-starter/src/main/resources/component-libraries.yml b/oap-server/server-starter/src/main/resources/component-libraries.yml index d6174eaeb85c..25c1aba053c3 100644 --- a/oap-server/server-starter/src/main/resources/component-libraries.yml +++ b/oap-server/server-starter/src/main/resources/component-libraries.yml @@ -538,6 +538,7 @@ ThreadPerTask-executor: ztunnel: id: 162 languages: ebpf, mesh + priority: 10 # .NET/.NET Core components # [3000, 4000) for C#/.NET only diff --git a/test/e2e-v2/cases/cilium/traffic-gen.yaml b/test/e2e-v2/cases/cilium/traffic-gen.yaml index 590ff4d98fa9..6f946ae52e93 100644 --- a/test/e2e-v2/cases/cilium/traffic-gen.yaml +++ b/test/e2e-v2/cases/cilium/traffic-gen.yaml @@ -39,7 +39,7 @@ spec: - | while true; do curl -s -o /dev/null -w "%{http_code}\n" http://productpage:9080/productpage - sleep 1 + sleep 5 done resources: requests: diff --git a/test/e2e-v2/cases/istio/ambient-als/e2e.yaml b/test/e2e-v2/cases/istio/ambient-als/e2e.yaml new file mode 100644 index 000000000000..8017f29b44e4 --- /dev/null +++ b/test/e2e-v2/cases/istio/ambient-als/e2e.yaml @@ -0,0 +1,222 @@ +# 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. + +# This file is used to show how to write configuration files and can be used to test. + +setup: + env: kind + file: ../kind.k${KUBERNETES_VERSION}.yaml + init-system-environment: ../../../script/env + kind: + import-images: + - skywalking/ui:latest + - skywalking/oap:latest + expose-ports: + - namespace: istio-system + resource: service/skywalking-ui + port: 80 + steps: + - name: set PATH + command: export PATH=/tmp/skywalking-infra-e2e/bin:$PATH + - name: install yq + command: bash test/e2e-v2/script/prepare/setup-e2e-shell/install.sh yq + - name: install swctl + command: bash test/e2e-v2/script/prepare/setup-e2e-shell/install.sh swctl + - name: install kubectl + command: bash test/e2e-v2/script/prepare/setup-e2e-shell/install.sh kubectl + - name: install istio + command: | + bash test/e2e-v2/script/prepare/setup-e2e-shell/install.sh istioctl + istioctl install -y --set profile=ambient --skip-confirmation --set meshConfig.accessLogFile=/dev/stdout \ + --set meshConfig.defaultConfig.envoyAccessLogService.address=skywalking-oap.istio-system:11800 \ + --set meshConfig.enableEnvoyAccessLogService=true + kubectl get crd gateways.gateway.networking.k8s.io &> /dev/null || \ + kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.3.0-rc.1/standard-install.yaml + kubectl label namespace default istio.io/dataplane-mode=ambient + - name: install waypoint + command: istioctl waypoint apply --name simple-http-waypoint && sleep 10 + wait: + - namespace: default + resource: deployments/simple-http-waypoint + for: condition=available + - name: Install helm + command: bash test/e2e-v2/script/prepare/setup-e2e-shell/install.sh helm + - name: Install SkyWalking + command: | + helm -n istio-system install skywalking \ + oci://ghcr.io/apache/skywalking-helm/skywalking-helm \ + --version "0.0.0-${SW_KUBERNETES_COMMIT_SHA}" \ + --set fullnameOverride=skywalking \ + --set elasticsearch.replicas=1 \ + --set elasticsearch.minimumMasterNodes=1 \ + --set oap.env.SW_ENVOY_METRIC_ALS_HTTP_ANALYSIS=$ALS_ANALYZER \ + --set oap.env.SW_ENVOY_METRIC_ALS_TCP_ANALYSIS=$ALS_ANALYZER \ + --set oap.env.K8S_SERVICE_NAME_RULE='e2e::${service.metadata.name}' \ + --set oap.envoy.als.enabled=true \ + --set oap.replicas=1 \ + --set ui.image.repository=skywalking/ui \ + --set ui.image.tag=latest \ + --set oap.image.tag=latest \ + --set oap.image.repository=skywalking/oap \ + --set oap.storageType=elasticsearch \ + -f test/e2e-v2/cases/istio/values.yaml + wait: + - namespace: istio-system + resource: deployments/skywalking-oap + for: condition=available + - name: Deploy demo services + command: | + kubectl apply -f https://raw.githubusercontent.com/istio/istio/$ISTIO_VERSION/samples/bookinfo/platform/kube/bookinfo.yaml + kubectl apply -f https://raw.githubusercontent.com/istio/istio/$ISTIO_VERSION/samples/bookinfo/networking/bookinfo-gateway.yaml + # Enable TCP services + kubectl apply -f https://raw.githubusercontent.com/istio/istio/$ISTIO_VERSION/samples/bookinfo/platform/kube/bookinfo-ratings-v2.yaml + kubectl apply -f https://raw.githubusercontent.com/istio/istio/$ISTIO_VERSION/samples/bookinfo/platform/kube/bookinfo-db.yaml + kubectl apply -f https://raw.githubusercontent.com/istio/istio/$ISTIO_VERSION/samples/bookinfo/networking/destination-rule-all.yaml + kubectl apply -f https://raw.githubusercontent.com/istio/istio/$ISTIO_VERSION/samples/bookinfo/networking/virtual-service-ratings-db.yaml + wait: + - namespace: default + resource: pod + for: condition=Ready + - name: Add reviews service as waypoint transform + command: kubectl label service -n default details istio.io/use-waypoint=simple-http-waypoint --overwrite + - name: Install SkyWalking Rover + command: | + envsubst < test/e2e-v2/cases/profiling/ebpf/access_log/rover.yaml | kubectl apply -f - + wait: + - namespace: default + resource: pod + for: condition=Ready + - name: Status of istio mesh + command: istioctl zc all && sleep 15 # sleep for waiting the rover ready to monitoring all services + - name: Generate traffic + path: traffic-gen.yaml + wait: + - namespace: default + resource: pod + for: condition=Ready + timeout: 25m + +verify: + retry: + count: 20 + interval: 15s + cases: + # service list + - query: swctl --display yaml --base-url=http://${service_skywalking_ui_host}:${service_skywalking_ui_80}/graphql service ls + expected: expected/service.yml + # service instance list + - query: swctl --display yaml --base-url=http://${service_skywalking_ui_host}:${service_skywalking_ui_80}/graphql instance list --service-name=productpage.default + expected: expected/service-instance.yml + - query: swctl --display yaml --base-url=http://${service_skywalking_ui_host}:${service_skywalking_ui_80}/graphql instance list --service-name=reviews.default + expected: expected/service-instance.yml + # service endpoint + - query: swctl --display yaml --base-url=http://${service_skywalking_ui_host}:${service_skywalking_ui_80}/graphql endpoint list --service-name=productpage.default + expected: expected/service-endpoint-productpage.yml + - query: swctl --display yaml --base-url=http://${service_skywalking_ui_host}:${service_skywalking_ui_80}/graphql endpoint list --service-name=reviews.default + expected: expected/service-endpoint-reviews.yml + + # mesh service metrics: productpage.default + - query: swctl --display yaml --base-url=http://${service_skywalking_ui_host}:${service_skywalking_ui_80}/graphql metrics exec --expression=service_sla --service-name=productpage.default + expected: expected/metrics-has-value.yml + - query: swctl --display yaml --base-url=http://${service_skywalking_ui_host}:${service_skywalking_ui_80}/graphql metrics exec --expression=service_cpm --service-name=productpage.default + expected: expected/metrics-has-value.yml + - query: swctl --display yaml --base-url=http://${service_skywalking_ui_host}:${service_skywalking_ui_80}/graphql metrics exec --expression=service_resp_time --service-name=productpage.default + expected: expected/metrics-has-value.yml + - query: swctl --display yaml --base-url=http://${service_skywalking_ui_host}:${service_skywalking_ui_80}/graphql metrics exec --expression=service_apdex --service-name=productpage.default + expected: expected/metrics-has-value.yml + # service metrics: reviews.default + - query: swctl --display yaml --base-url=http://${service_skywalking_ui_host}:${service_skywalking_ui_80}/graphql metrics exec --expression=service_sla --service-name=reviews.default + expected: expected/metrics-has-value.yml + - query: swctl --display yaml --base-url=http://${service_skywalking_ui_host}:${service_skywalking_ui_80}/graphql metrics exec --expression=service_cpm --service-name=reviews.default + expected: expected/metrics-has-value.yml + - query: swctl --display yaml --base-url=http://${service_skywalking_ui_host}:${service_skywalking_ui_80}/graphql metrics exec --expression=service_resp_time --service-name=reviews.default + expected: expected/metrics-has-value.yml + - query: swctl --display yaml --base-url=http://${service_skywalking_ui_host}:${service_skywalking_ui_80}/graphql metrics exec --expression=service_apdex --service-name=reviews.default + expected: expected/metrics-has-value.yml + # service instance metrics: productpage.default + - query: | + swctl --display yaml --base-url=http://${service_skywalking_ui_host}:${service_skywalking_ui_80}/graphql metrics exec --expression=service_instance_resp_time --service-name=productpage.default --instance-name=$( \ + swctl --display yaml --base-url=http://${service_skywalking_ui_host}:${service_skywalking_ui_80}/graphql instance list --service-name=productpage.default | yq e '.[0].name' - + ) + expected: expected/metrics-has-value.yml + - query: | + swctl --display yaml --base-url=http://${service_skywalking_ui_host}:${service_skywalking_ui_80}/graphql metrics exec --expression=service_instance_cpm --service-name=productpage.default --instance-name=$( \ + swctl --display yaml --base-url=http://${service_skywalking_ui_host}:${service_skywalking_ui_80}/graphql instance list --service-name=productpage.default | yq e '.[0].name' - + ) + expected: expected/metrics-has-value.yml + - query: | + swctl --display yaml --base-url=http://${service_skywalking_ui_host}:${service_skywalking_ui_80}/graphql metrics exec --expression=service_instance_sla --service-name=productpage.default --instance-name=$( \ + swctl --display yaml --base-url=http://${service_skywalking_ui_host}:${service_skywalking_ui_80}/graphql instance list --service-name=productpage.default | yq e '.[0].name' - + ) + expected: expected/metrics-has-value.yml + # service instance metrics: reviews.default + - query: | + swctl --display yaml --base-url=http://${service_skywalking_ui_host}:${service_skywalking_ui_80}/graphql metrics exec --expression=service_instance_resp_time --service-name=reviews.default --instance-name=$( \ + swctl --display yaml --base-url=http://${service_skywalking_ui_host}:${service_skywalking_ui_80}/graphql instance list --service-name=reviews.default | yq e '.[0].name' - + ) + expected: expected/metrics-has-value.yml + - query: | + swctl --display yaml --base-url=http://${service_skywalking_ui_host}:${service_skywalking_ui_80}/graphql metrics exec --expression=service_instance_cpm --service-name=reviews.default --instance-name=$( \ + swctl --display yaml --base-url=http://${service_skywalking_ui_host}:${service_skywalking_ui_80}/graphql instance list --service-name=reviews.default | yq e '.[0].name' - + ) + expected: expected/metrics-has-value.yml + - query: | + swctl --display yaml --base-url=http://${service_skywalking_ui_host}:${service_skywalking_ui_80}/graphql metrics exec --expression=service_instance_sla --service-name=reviews.default --instance-name=$( \ + swctl --display yaml --base-url=http://${service_skywalking_ui_host}:${service_skywalking_ui_80}/graphql instance list --service-name=reviews.default | yq e '.[0].name' - + ) + expected: expected/metrics-has-value.yml + + # service endpoint metrics: productpage.default GET:/productpage + - query: swctl --display yaml --base-url=http://${service_skywalking_ui_host}:${service_skywalking_ui_80}/graphql metrics exec --expression=endpoint_cpm --endpoint-name=GET:/productpage --service-name=productpage.default + expected: expected/metrics-has-value.yml + - query: swctl --display yaml --base-url=http://${service_skywalking_ui_host}:${service_skywalking_ui_80}/graphql metrics exec --expression=endpoint_resp_time --endpoint-name=GET:/productpage --service-name=productpage.default + expected: expected/metrics-has-value.yml + - query: swctl --display yaml --base-url=http://${service_skywalking_ui_host}:${service_skywalking_ui_80}/graphql metrics exec --expression=endpoint_sla --endpoint-name=GET:/productpage --service-name=productpage.default + expected: expected/metrics-has-value.yml + # service endpoint metrics: reviews.default GET:/reviews/0 + - query: swctl --display yaml --base-url=http://${service_skywalking_ui_host}:${service_skywalking_ui_80}/graphql metrics exec --expression=endpoint_cpm --endpoint-name=GET:/reviews/0 --service-name=reviews.default + expected: expected/metrics-has-value.yml + - query: swctl --display yaml --base-url=http://${service_skywalking_ui_host}:${service_skywalking_ui_80}/graphql metrics exec --expression=endpoint_resp_time --endpoint-name=GET:/reviews/0 --service-name=reviews.default + expected: expected/metrics-has-value.yml + - query: swctl --display yaml --base-url=http://${service_skywalking_ui_host}:${service_skywalking_ui_80}/graphql metrics exec --expression=endpoint_sla --endpoint-name=GET:/reviews/0 --service-name=reviews.default + expected: expected/metrics-has-value.yml + + # dependency service + - query: swctl --display yaml --base-url=http://${service_skywalking_ui_host}:${service_skywalking_ui_80}/graphql dependency global --layer=MESH + expected: expected/dependency-global-mesh.yml + - query: swctl --display yaml --base-url=http://${service_skywalking_ui_host}:${service_skywalking_ui_80}/graphql dependency instance --service-name=productpage.default --dest-service-name=reviews.default + expected: expected/dependency-services-instance-productpage.yml + + # service relation metrics + - query: swctl --display yaml --base-url=http://${service_skywalking_ui_host}:${service_skywalking_ui_80}/graphql metrics exec --expression=service_relation_client_cpm --service-name=productpage.default --dest-service-name=reviews.default + expected: expected/metrics-has-value.yml + - query: swctl --display yaml --base-url=http://${service_skywalking_ui_host}:${service_skywalking_ui_80}/graphql metrics exec --expression=service_relation_server_cpm --service-name=productpage.default --dest-service-name=reviews.default + expected: expected/metrics-has-value.yml + # service instance relation metrics, productpage.default -> reviews.default + - query: | + swctl --display yaml --base-url=http://${service_skywalking_ui_host}:${service_skywalking_ui_80}/graphql metrics exec --expression=service_instance_relation_client_cpm \ + --service-name=productpage.default --instance-name=$( \ + swctl --display yaml --base-url=http://${service_skywalking_ui_host}:${service_skywalking_ui_80}/graphql instance list --service-name=productpage.default | yq e '.[0].name' - ) \ + --dest-service-name=reviews.default --dest-instance-name=$( \ + swctl --display yaml --base-url=http://${service_skywalking_ui_host}:${service_skywalking_ui_80}/graphql instance list --service-name=reviews.default | yq e '.[0].name' - ) + expected: expected/metrics-has-value.yml + - query: | + swctl --display yaml --base-url=http://${service_skywalking_ui_host}:${service_skywalking_ui_80}/graphql metrics exec --expression=service_instance_relation_server_cpm \ + --service-name=productpage.default --instance-name=$( \ + swctl --display yaml --base-url=http://${service_skywalking_ui_host}:${service_skywalking_ui_80}/graphql instance list --service-name=productpage.default | yq e '.[0].name' - ) \ + --dest-service-name=reviews.default --dest-instance-name=$( \ + swctl --display yaml --base-url=http://${service_skywalking_ui_host}:${service_skywalking_ui_80}/graphql instance list --service-name=reviews.default | yq e '.[0].name' - ) + + expected: expected/metrics-has-value.yml diff --git a/test/e2e-v2/cases/istio/ambient-als/expected/dependency-global-mesh.yml b/test/e2e-v2/cases/istio/ambient-als/expected/dependency-global-mesh.yml new file mode 100644 index 000000000000..438172c4b3a6 --- /dev/null +++ b/test/e2e-v2/cases/istio/ambient-als/expected/dependency-global-mesh.yml @@ -0,0 +1,104 @@ +# 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. + +debuggingtrace: null +nodes: +{{- contains .nodes }} +- id: {{ b64enc "reviews.default"}}.1 + name: reviews.default + type: http + isreal: true + layers: + {{- contains .layers }} + - MESH + - K8S_SERVICE + {{- end }} +- id: {{ b64enc "simple-http-waypoint.default"}}.1 + name: simple-http-waypoint.default + type: tls + isreal: true + layers: + {{- contains .layers }} + - MESH + - K8S_SERVICE + {{- end }} +- id: {{ b64enc "productpage.default"}}.1 + name: productpage.default + type: http + isreal: true + layers: + {{- contains .layers }} + - MESH + - K8S_SERVICE + {{- end }} +- id: {{ b64enc "details.default" }}.1 + name: details.default + type: http + isreal: true + layers: + {{- contains .layers }} + - MESH + - K8S_SERVICE + {{- end }} +{{- end }} +calls: +{{- contains .calls }} +- source: {{ b64enc "productpage.default"}}.1 + sourcecomponents: + {{- contains .sourcecomponents }} + - tcp + - http + {{- end }} + target: {{ b64enc "simple-http-waypoint.default"}}.1 + targetcomponents: + {{- contains .targetcomponents }} + - ztunnel + {{- end }} + id: {{ b64enc "productpage.default"}}.1-{{ b64enc "simple-http-waypoint.default"}}.1 + detectpoints: + - CLIENT + - SERVER +- source: {{ b64enc "simple-http-waypoint.default"}}.1 + sourcecomponents: + {{- contains .sourcecomponents }} + - tls + {{- end }} + target: {{ b64enc "details.default"}}.1 + targetcomponents: + {{- contains .targetcomponents }} + - ztunnel + {{- end }} + id: {{ b64enc "simple-http-waypoint.default" }}.1-{{ b64enc "details.default"}}.1 + detectpoints: + - CLIENT + - SERVER +- source: {{ b64enc "productpage.default" }}.1 + sourcecomponents: + {{- contains .sourcecomponents }} + - ztunnel + - tcp + - http + {{- end }} + target: {{ b64enc "reviews.default"}}.1 + targetcomponents: + {{- contains .targetcomponents }} + - ztunnel + - http + {{- end }} + id: {{ b64enc "productpage.default" }}.1-{{ b64enc "reviews.default"}}.1 + detectpoints: + - CLIENT + - SERVER +{{- end }} diff --git a/test/e2e-v2/cases/istio/ambient-als/expected/dependency-services-instance-productpage.yml b/test/e2e-v2/cases/istio/ambient-als/expected/dependency-services-instance-productpage.yml new file mode 100644 index 000000000000..180cfc64e1b7 --- /dev/null +++ b/test/e2e-v2/cases/istio/ambient-als/expected/dependency-services-instance-productpage.yml @@ -0,0 +1,42 @@ +# 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. + +debuggingtrace: null +nodes: +{{- contains .nodes }} +- id: {{ notEmpty .id }} + name: {{ notEmpty .name }} + serviceid: {{ b64enc "reviews.default" }}.1 + servicename: reviews.default + type: "" + isreal: true +- id: {{ notEmpty .id }} + name: {{ notEmpty .name }} + serviceid: {{ b64enc "productpage.default" }}.1 + servicename: productpage.default + type: "" + isreal: true +{{- end }} +calls: +{{- contains .calls }} +- source: {{ notEmpty .source }} + sourcecomponents: [] + target: {{ notEmpty .target }} + targetcomponents: [] + id: {{ notEmpty .source }}-{{ notEmpty .target }} + detectpoints: + - CLIENT + - SERVER +{{- end }} diff --git a/test/e2e-v2/cases/istio/ambient-als/expected/metrics-has-value.yml b/test/e2e-v2/cases/istio/ambient-als/expected/metrics-has-value.yml new file mode 100644 index 000000000000..d5e6476d7a53 --- /dev/null +++ b/test/e2e-v2/cases/istio/ambient-als/expected/metrics-has-value.yml @@ -0,0 +1,34 @@ +# 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. + +debuggingtrace: null +type: TIME_SERIES_VALUES +results: + {{- contains .results }} + - metric: + labels: [] + values: + {{- contains .values }} + - id: "{{ notEmpty .id }}" + value: {{ .value }} + owner: null + traceid: null + - id: "{{ notEmpty .id }}" + value: null + owner: null + traceid: null + {{- end}} + {{- end}} +error: null diff --git a/test/e2e-v2/cases/istio/ambient-als/expected/service-endpoint-productpage.yml b/test/e2e-v2/cases/istio/ambient-als/expected/service-endpoint-productpage.yml new file mode 100644 index 000000000000..f5788fe089aa --- /dev/null +++ b/test/e2e-v2/cases/istio/ambient-als/expected/service-endpoint-productpage.yml @@ -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. + +{{- contains . }} +- id: {{ b64enc "productpage.default" }}.1_{{ b64enc "GET:/productpage" }} + name: GET:/productpage +{{- end }} diff --git a/test/e2e-v2/cases/istio/ambient-als/expected/service-endpoint-reviews.yml b/test/e2e-v2/cases/istio/ambient-als/expected/service-endpoint-reviews.yml new file mode 100644 index 000000000000..1fffece05b82 --- /dev/null +++ b/test/e2e-v2/cases/istio/ambient-als/expected/service-endpoint-reviews.yml @@ -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. + +{{- contains . }} +- id: {{ b64enc "reviews.default" }}.1_{{ b64enc "GET:/reviews/0" }} + name: GET:/reviews/0 +{{- end }} diff --git a/test/e2e-v2/cases/istio/ambient-als/expected/service-instance.yml b/test/e2e-v2/cases/istio/ambient-als/expected/service-instance.yml new file mode 100644 index 000000000000..658cdbd553b0 --- /dev/null +++ b/test/e2e-v2/cases/istio/ambient-als/expected/service-instance.yml @@ -0,0 +1,22 @@ +# 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. + +{{- contains . }} +- id: {{ notEmpty .id }} + name: {{ notEmpty .name }} + attributes: [] + language: UNKNOWN + instanceuuid: {{ notEmpty .instanceuuid }} +{{- end }} diff --git a/test/e2e-v2/cases/istio/ambient-als/expected/service.yml b/test/e2e-v2/cases/istio/ambient-als/expected/service.yml new file mode 100644 index 000000000000..f98b6e7778d0 --- /dev/null +++ b/test/e2e-v2/cases/istio/ambient-als/expected/service.yml @@ -0,0 +1,64 @@ +# 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. + +{{- contains . }} +- id: {{ b64enc "details.default" }}.1 + name: details.default + group: "" + shortname: details.default + layers: + - MESH + - K8S_SERVICE + normal: true +- id: {{ b64enc "e2e::simple-http-waypoint" }}.1 + name: e2e::simple-http-waypoint + group: "e2e" + shortname: simple-http-waypoint + layers: + - MESH + normal: true +- id: {{ b64enc "reviews.default" }}.1 + name: reviews.default + group: "" + shortname: reviews.default + layers: + - MESH + - K8S_SERVICE + normal: true +- id: {{ b64enc "ratings.default" }}.1 + name: ratings.default + group: "" + shortname: ratings.default + layers: + - MESH + - K8S_SERVICE + normal: true +- id: {{ b64enc "productpage.default" }}.1 + name: productpage.default + group: "" + shortname: productpage.default + layers: + - MESH + - K8S_SERVICE + normal: true +- id: {{ b64enc "mongodb.default" }}.1 + name: mongodb.default + group: "" + shortname: mongodb.default + layers: + - MESH + - K8S_SERVICE + normal: true +{{- end }} diff --git a/test/e2e-v2/cases/istio/ambient-als/traffic-gen.yaml b/test/e2e-v2/cases/istio/ambient-als/traffic-gen.yaml new file mode 100644 index 000000000000..65e2ac62d2cb --- /dev/null +++ b/test/e2e-v2/cases/istio/ambient-als/traffic-gen.yaml @@ -0,0 +1,47 @@ +# 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. + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: trafficgenerator + labels: + app: trafficgenerator +spec: + replicas: 1 + selector: + matchLabels: + app: trafficgenerator + template: + metadata: + annotations: + sidecar.istio.io/inject: "false" + labels: + app: trafficgenerator + spec: + containers: + - name: trafficgenerator + image: alpine/curl:8.9.1 + command: ["/bin/sh", "-c", "--"] + args: + - | + while true; do + curl -s -o /dev/null -w "%{http_code}\n" http://productpage.default:9080/productpage + sleep 5 + done + resources: + requests: + cpu: 0.1 + diff --git a/test/e2e-v2/cases/istio/kind.k25.yaml b/test/e2e-v2/cases/istio/kind.k25.yaml index fe248b66f6c1..c3271a47ede6 100644 --- a/test/e2e-v2/cases/istio/kind.k25.yaml +++ b/test/e2e-v2/cases/istio/kind.k25.yaml @@ -18,3 +18,6 @@ apiVersion: kind.x-k8s.io/v1alpha4 nodes: - role: control-plane image: kindest/node:v1.25.11@sha256:227fa11ce74ea76a0474eeefb84cb75d8dad1b08638371ecf0e86259b35be0c8 + extraMounts: + - hostPath: / + containerPath: /host diff --git a/test/e2e-v2/cases/istio/kind.k28.yaml b/test/e2e-v2/cases/istio/kind.k28.yaml index 6bb82dfce82e..f2f618b841ae 100644 --- a/test/e2e-v2/cases/istio/kind.k28.yaml +++ b/test/e2e-v2/cases/istio/kind.k28.yaml @@ -18,3 +18,6 @@ apiVersion: kind.x-k8s.io/v1alpha4 nodes: - role: control-plane image: kindest/node:v1.28.15@sha256:a7c05c7ae043a0b8c818f5a06188bc2c4098f6cb59ca7d1856df00375d839251 + extraMounts: + - hostPath: / + containerPath: /host diff --git a/test/e2e-v2/cases/istio/values.yaml b/test/e2e-v2/cases/istio/values.yaml index 27426bbd75f0..115282057d31 100644 --- a/test/e2e-v2/cases/istio/values.yaml +++ b/test/e2e-v2/cases/istio/values.yaml @@ -18,6 +18,25 @@ oap: metadata-service-mapping.yaml: | serviceName: e2e::${LABELS."service.istio.io/canonical-name",SERVICE} serviceInstanceName: ${NAME} + log4j2.xml: | + + + + + + + + + + + + + + + + + + elasticsearch: esConfig: diff --git a/test/e2e-v2/cases/php/e2e.yaml b/test/e2e-v2/cases/php/e2e.yaml index bed6bfeddfd8..dd8ced3960a3 100644 --- a/test/e2e-v2/cases/php/e2e.yaml +++ b/test/e2e-v2/cases/php/e2e.yaml @@ -38,8 +38,8 @@ trigger: verify: # verify with retry strategy retry: - count: 20 - interval: 10s + count: 30 + interval: 15s cases: # layer list - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql layer ls diff --git a/test/e2e-v2/cases/profiling/ebpf/access_log/traffic-gen.yaml b/test/e2e-v2/cases/profiling/ebpf/access_log/traffic-gen.yaml index a1d08fef93f1..addefc63d74e 100644 --- a/test/e2e-v2/cases/profiling/ebpf/access_log/traffic-gen.yaml +++ b/test/e2e-v2/cases/profiling/ebpf/access_log/traffic-gen.yaml @@ -39,7 +39,7 @@ spec: - | while true; do curl -s -o /dev/null -w "%{http_code}\n" http://productpage:9080/productpage - sleep 1 + sleep 5 done resources: requests: diff --git a/test/e2e-v2/cases/profiling/ebpf/continuous/postgres/e2e.yaml b/test/e2e-v2/cases/profiling/ebpf/continuous/postgres/e2e.yaml new file mode 100644 index 000000000000..6be954ee94ee --- /dev/null +++ b/test/e2e-v2/cases/profiling/ebpf/continuous/postgres/e2e.yaml @@ -0,0 +1,85 @@ +# 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. + +# This file is used to show how to write configuration files and can be used to test. + +setup: + env: kind + file: ../../kind.yaml + init-system-environment: ../../../../../script/env + kind: + import-images: + - skywalking/ui:latest + - skywalking/oap:latest + - test/continuous:test + expose-ports: + - namespace: istio-system + resource: service/skywalking-ui + port: 80 + steps: + - name: set PATH + command: export PATH=/tmp/skywalking-infra-e2e/bin:$PATH + - name: install yq + command: bash test/e2e-v2/script/prepare/setup-e2e-shell/install.sh yq + - name: install swctl + command: bash test/e2e-v2/script/prepare/setup-e2e-shell/install.sh swctl + - name: install kubectl + command: bash test/e2e-v2/script/prepare/setup-e2e-shell/install.sh kubectl + - name: Install helm + command: bash test/e2e-v2/script/prepare/setup-e2e-shell/install.sh helm + - name: Install kubectl + command: bash test/e2e-v2/script/prepare/setup-e2e-shell/install.sh kubectl + - name: Install SkyWalking + command: | + kubectl create namespace istio-system + helm -n istio-system install skywalking \ + oci://ghcr.io/apache/skywalking-helm/skywalking-helm \ + --version "0.0.0-${SW_KUBERNETES_COMMIT_SHA}" \ + --set fullnameOverride=skywalking \ + --set elasticsearch.enabled=false \ + --set banyandb.enabled=true \ + --set banyandb.image.tag=${SW_BANYANDB_COMMIT} \ + --set banyandb.image.repository=ghcr.io/apache/skywalking-banyandb \ + --set oap.replicas=1 \ + --set ui.image.repository=skywalking/ui \ + --set ui.image.tag=latest \ + --set oap.image.tag=latest \ + --set oap.image.repository=skywalking/oap \ + --set oap.storageType=banyandb \ + -f test/e2e-v2/cases/profiling/ebpf/kubernetes-values.yaml + wait: + - namespace: istio-system + resource: deployments/skywalking-oap + for: condition=available + - name: Deploy services + command: | + export IMAGE_NAME=test/continuous:test + export HAS_SERVICE_EXP=".Pod.HasContainer \\\"test-continuous\\\"" + export SERVICE_NAME_EXP="sqrt" + envsubst < test/e2e-v2/cases/profiling/ebpf/continuous/service.yaml | kubectl apply -f - + envsubst < test/e2e-v2/cases/profiling/ebpf/rover.yaml | kubectl apply -f - + wait: + - namespace: default + resource: pod + for: condition=Ready + timeout: 25m + +verify: + retry: + count: 20 + interval: 10s + cases: + - includes: + - ../profiling-cases.yaml \ No newline at end of file diff --git a/test/e2e-v2/cases/storage/banyandb/stages/e2e.yaml b/test/e2e-v2/cases/storage/banyandb/stages/e2e.yaml index 70d9466e447c..d02da95cc7cd 100644 --- a/test/e2e-v2/cases/storage/banyandb/stages/e2e.yaml +++ b/test/e2e-v2/cases/storage/banyandb/stages/e2e.yaml @@ -66,6 +66,6 @@ verify: - query: | swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql trace ls --trace-id=$( \ swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql trace ls --tags http.method=get --start="-96h" --end="-48h" --cold=true \ - | yq e '.traces | select(.[].endpointnames[0]=="/dubbox-case/case/dubbox-rest/404-test") | .[0].traceids[0]' - + | yq e '.traces | select(.[].endpointnames[0]=="/dubbox-case/case/dubbox-rest/404-test") | .[2].traceids[0]' - ) --start="-96h" --end="-48h" --cold=true expected: ../../expected/cold/trace-detail.yml diff --git a/test/e2e-v2/script/env b/test/e2e-v2/script/env index ef63dca6e4a5..09ad865c6c89 100644 --- a/test/e2e-v2/script/env +++ b/test/e2e-v2/script/env @@ -22,7 +22,7 @@ SW_AGENT_PYTHON_COMMIT=c76a6ec51a478ac91abb20ec8f22a99b8d4d6a58 SW_AGENT_CLIENT_JS_COMMIT=af0565a67d382b683c1dbd94c379b7080db61449 SW_AGENT_CLIENT_JS_TEST_COMMIT=4f1eb1dcdbde3ec4a38534bf01dded4ab5d2f016 SW_KUBERNETES_COMMIT_SHA=6fe5e6f0d3b7686c6be0457733e825ee68cb9b35 -SW_ROVER_COMMIT=738b1a42fe4941e0b4e6f5816403437cf572708f +SW_ROVER_COMMIT=79292fe07f17f98f486e0c4471213e1961fb2d1d SW_BANYANDB_COMMIT=c4b4384f3083f44ca6067257f5fa59030427ad6b SW_AGENT_PHP_COMMIT=3192c553002707d344bd6774cfab5bc61f67a1d3 SW_PREDICTOR_COMMIT=54a0197654a3781a6f73ce35146c712af297c994