Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 29 additions & 84 deletions docs/en/guides/Plugin-test.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Plugin test framework is designed for verifying the plugins' function and compatible status. As there are dozens of plugins and
hundreds of versions need to be verified, it is impossible to do manually.
The test framework uses container based tech stack, requires a set of real services with agent installed, then the test mock
OAP backend is running to check the segments and register data sent from agents.
OAP backend is running to check the segments data sent from agents.

Every plugin maintained in the main repo requires corresponding test cases, also matching the versions in the supported list doc.

Expand Down Expand Up @@ -90,7 +90,7 @@ The following files are required in every test case.
File Name | Descriptions
---|---
`configuration.yml` | Declare the basic case inform, including, case name, entrance endpoints, mode, dependencies.
`expectedData.yaml` | Describe the expected Segment(s), including two major parts, (1) Register metadata (2) Segments
`expectedData.yaml` | Describe the expected segmentItems.
`support-version.list` | List the target versions for this case
`startup.sh` |`JVM-container` only, don't need this when use`Tomcat-container`

Expand All @@ -101,8 +101,8 @@ File Name | Descriptions
| Field | description
| --- | ---
| type | Image type, options, `jvm` or `tomcat`. Required.
| entryService | The entrance endpoint(URL) for test case access. Required.
| healthCheck | The health check endpoint(URL) for test case access. Required.
| entryService | The entrance endpoint(URL) for test case access. Required. (HTTP Method: GET)
| healthCheck | The health check endpoint(URL) for test case access. Required. (HTTP Method: HEAD)
| startScript | Path of start up script. Required in `type: jvm` only.
| framework | Case name.
| runningMode | Running mode whether with the optional plugin, options, `default`(default), `with_optional`, `with_bootstrap`
Expand Down Expand Up @@ -210,33 +210,11 @@ as the version number, it will be changed in the test for every version.
| `null` | Null or empty String |
| `eq` | Equal(default) |


**Register verify description format**
```yml
registryItems:
services:
- { SERVICE_NAME: SERVICE_ID(int) }
...
instances:
- { SERVICE_CODE: INSTANCE_COUNT(int) }
...
operationNames:
...
```


| Field | Description
| --- | ---
| services | The registered service codes. Normally, not 0 should be enough.
| instances | The number of service instances exists in this test case.
| operationNames | Since 7.1.0, there is no operation name register. Ignore this.


**Segment verify description format**
```yml
segments:
segmentItems:
-
serviceName: SERVICE_CODE(string)
serviceName: SERVICE_NAME(string)
segmentSize: SEGMENT_SIZE(int)
segments:
- segmentId: SEGMENT_ID(string)
Expand All @@ -247,7 +225,7 @@ segments:

| Field | Description
| --- | ---
| serviceName | Service code.
| serviceName | Service Name.
| segmentSize | The number of segments is expected.
| segmentId | trace ID.
| spans | segment span list. Follow the next section to see how to describe every span.
Expand All @@ -258,15 +236,13 @@ segments:

```yml
operationName: OPERATION_NAME(string)
operationId: SPAN_ID(int)
parentSpanId: PARENT_SPAN_ID(int)
spanId: SPAN_ID(int)
startTime: START_TIME(int)
endTime: END_TIME(int)
isError: IS_ERROR(string: true, false)
spanLayer: SPAN_LAYER(string: DB, RPC_FRAMEWORK, HTTP, MQ, CACHE)
spanType: SPAN_TYPE(string: Exit, Entry, Local )
componentName: COMPONENT_NAME(string)
spanType: SPAN_TYPE(string: Exit, Entry, Local)
componentId: COMPONENT_ID(int)
tags:
- {key: TAG_KEY(string), value: TAG_VALUE(string)}
Expand All @@ -275,51 +251,47 @@ segments:
- {key: LOG_KEY(string), value: LOG_VALUE(string)}
...
peer: PEER(string)
peerId: PEER_ID(int)
refs:
- {
parentSpanId: PARENT_SPAN_ID(int),
traceId: TRACE_ID(string),
parentTraceSegmentId: PARENT_TRACE_SEGMENT_ID(string),
entryServiceInstanceId: ENTRY_SERVICE_INSTANCE_ID(int)
parentServiceInstanceId: PARENT_SERVICE_INSTANCE_ID(int),
networkAddress: NETWORK_ADDRESS(string),
networkAddressId: NETWORK_ADDRESS_ID(int),
parentSpanId: PARENT_SPAN_ID(int),
parentService: PARENT_SERVICE(string),
parentServiceInstance: PARENT_SERVICE_INSTANCE(string),
parentEndpoint: PARENT_ENDPOINT_NAME(string),
parentEndpointId: PARENT_ENDPOINT_ID(int),
entryEndpoint: ENTRY_ENDPOINT_NAME(string),
entryServiceInstanceId: ENTRY_ENDPOINT_ID(int),
networkAddress: NETWORK_ADDRESS(string),
refType: REF_TYPE(string: CrossProcess, CrossThread)
}
...
```

| Field | Description
|--- |---
| operationName | Span Operation Name
| operationId | Should be 0 for now
| operationName | Span Operation Name.
| parentSpanId | Parent span id. **Notice**: The parent span id of the first span should be -1.
| spanId | Span Id. **Notice**, start from 0.
| startTime | Span start time. It is impossible to get the accurate time, not 0 should be enough.
| endTime | Span finish time. It is impossible to get the accurate time, not 0 should be enough.
| isError | Span status, true or false.
| componentName | Component name, should be null in most cases, use component id instead.
| componentId | Component id for your plugin.
| tags | Span tag list. **Notice**, Keep in the same order as the plugin coded.
| logs | Span log list. **Notice**, Keep in the same order as the plugin coded.
| SpanLayer | Options, DB, RPC_FRAMEWORK, HTTP, MQ, CACHE
| SpanType | Span type, options, Exit, Entry or Local
| SpanLayer | Options, DB, RPC_FRAMEWORK, HTTP, MQ, CACHE.
| SpanType | Span type, options, Exit, Entry or Local.
| peer | Remote network address, IP + port mostly. For exit span, this should be required.
| peerId | Not 0 for now.


The verify description for SegmentRef,
The verify description for SegmentRef

| Field | Description
|---- |----
| traceId |
| parentTraceSegmentId | Parent SegmentId, pointing to the segment id in the parent segment.
| parentSpanId | Parent SpanID, pointing to the span id in the parent segment.
| entryServiceInstanceId/parentServiceInstanceId | Not 0 should be enough
| networkAddress/networkAddressId | The peer value of parent exit span. `networkAddressId` should be 0, as the mock tool doesn't do register for real.
| parentEndpoint/parentEndpointId | The endpoint of parent/downstream service. Usually set `parentEndpoint` as literal string name, unless there is no parent endpoint, set `parentEndpointId` as -1.
| entryEndpoint/entryServiceInstanceId | The endpoint of first service in the distributed chain. Usually set `entryEndpoint` as literal string name, unless there is no endpoint at the entry service, set `entryServiceInstanceId` as -1.
| parentService | The service of parent/downstream service name.
| parentServiceInstance | The instance of parent/downstream service instance name.
| parentEndpoint | The endpoint of parent/downstream service.
| networkAddress | The peer value of parent exit span.
| refType | Ref type, options, CrossProcess or CrossThread.

### startup.sh

Expand Down Expand Up @@ -407,7 +379,7 @@ and don't include the segments of heartbeat service in the expected segment data

### The example Process of Writing Expected Data

Expected data file, `expectedData.yaml`, includes `RegistryItems` and `SegmentIntems`.
Expected data file, `expectedData.yaml`, include `SegmentItems`.

We are using the HttpClient plugin to show how to write the expected data.

Expand Down Expand Up @@ -437,32 +409,14 @@ There are two key points of testing
| | |
+ + +
```

#### RegistryItems

HttpClient test case is running in Tomcat container, only one instance exists, so
1. instance number is 1
1. applicationId is not 0
1. Because we have two servlet mapping paths, so two operation names. No health check operation name here.

```yml
registryItems:
services:
- {httpclient-case: nq 0}
instances:
- {httpclient-case: 1}
operationNames:
- httpclient-case: [/httpclient-case/case/httpclient,/httpclient-case/case/context-propagate]
```

#### segmentItems

By following the flow of HttpClient case, there should be two segments created.
1. Segment represents the CaseServlet access. Let's name it as `SegmentA`.
1. Segment represents the ContextPropagateServlet access. Let's name it as `SegmentB`.

```yml
segments:
segmentItems:
- serviceName: httpclient-case
segmentSize: ge 2 # Could have more than one health check segments, because, the dependency is not standby.
```
Expand All @@ -476,39 +430,33 @@ SegmentA span list should like following
- segmentId: not null
spans:
- operationName: /httpclient-case/case/context-propagate
operationId: eq 0
parentSpanId: 0
spanId: 1
startTime: nq 0
endTime: nq 0
isError: false
spanLayer: Http
spanType: Exit
componentName: null
componentId: eq 2
tags:
- {key: url, value: 'http://127.0.0.1:8080/httpclient-case/case/context-propagate'}
- {key: http.method, value: GET}
logs: []
peer: null
peerId: eq 0
peer: 127.0.0.1:8080
- operationName: /httpclient-case/case/httpclient
operationId: eq 0
parentSpanId: -1
spanId: 0
startTime: nq 0
endTime: nq 0
spanLayer: Http
isError: false
spanType: Entry
componentName: null
componentId: 1
tags:
- {key: url, value: 'http://localhost:{SERVER_OUTPUT_PORT}/httpclient-case/case/httpclient'}
- {key: http.method, value: GET}
logs: []
peer: null
peerId: eq 0
```

SegmentB should only have one Tomcat entry span, but includes the Ref pointing to SegmentA.
Expand All @@ -519,7 +467,6 @@ SegmentB span list should like following
spans:
-
operationName: /httpclient-case/case/context-propagate
operationId: eq 0
parentSpanId: -1
spanId: 0
tags:
Expand All @@ -531,12 +478,10 @@ SegmentB span list should like following
spanLayer: Http
isError: false
spanType: Entry
componentName: null
componentId: 1
peer: null
peerId: eq 0
refs:
- {parentSpanId: 1, parentTraceSegmentId: "${httpclient-case[0]}", entryServiceName: "/httpclient-case/case/httpclient", networkAddress: "127.0.0.1:8080",parentServiceName: "/httpclient-case/case/httpclient",entryApplicationInstanceId: nq 0 }
- {parentEndpoint: /httpclient-case/case/httpclient, networkAddress: 'localhost:8080', refType: CrossProcess, parentSpanId: 1, parentTraceSegmentId: not null, parentServiceInstance: not null, parentService: not null, traceId: not null}
```

## Local Test and Pull Request To The Upstream
Expand Down