# Test-run custom operator

```{raw} html
<div class="mo-api-page-show-toc" aria-hidden="true"></div>
```

Execute a custom operator test using the given input and return the test record. Only enabled Python code type operators can be piloted.

```text
POST https://moi.matrixorigin.cn/newmoi/workflow/v2/custom-operators/$OPERATOR_ID/test-run
```

## Preparation before calling

First [query custom operator details](get-custom-operator.md) and confirm that the operator to be tested is enabled and is a Python code type. Prepare the personal access token, target workspace ID, and custom operator ID that have access to the target workspace.


## Request body

::::{div} mo-api-split
:::{div} mo-api-split-main

```{raw} html
<dl class="mo-api-fields">
  <div class="mo-api-field"><dt><code>input</code><span class="mo-api-field__type">object</span></dt><dd>Test input; an empty object is used when omitted.</dd></div>
  <div class="mo-api-field"><dt><code>wait_timeout_seconds</code><span class="mo-api-field__type">integer</span></dt><dd>Number of seconds to wait for test results.</dd></div>
</dl>
```

:::
:::{div} mo-api-split-aside

```{raw} html
<p class="mo-api-example-label">Request example</p>
```

```bash
curl -X POST "https://moi.matrixorigin.cn/newmoi/workflow/v2/custom-operators/$OPERATOR_ID/test-run" \
  -H "X-API-Key: $AI_STUDIO_API_KEY" \
  -H "X-Workspace-ID: $WORKSPACE_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "input": {
      "text": "MatrixOne"
    },
    "wait_timeout_seconds": 30
  }'
```

:::
::::

## Successful response

The response returns the test record. Check test status, output, and error messages to confirm that the operator is functioning as expected.


The response fields are as follows.

::::{div} mo-api-split
:::{div} mo-api-split-main

```{raw} html
<dl class="mo-api-fields">
  <div class="mo-api-field"><dt><code>code</code><span class="mo-api-field__type">string</span></dt><dd>OK on success.</dd></div>
  <div class="mo-api-field"><dt><code>msg</code><span class="mo-api-field__type">string</span></dt><dd>OK on success.</dd></div>
  <div class="mo-api-field"><dt><code>data.test_run.operator_id</code><span class="mo-api-field__type">integer</span></dt><dd>Custom operator ID for this test.</dd></div>
  <div class="mo-api-field"><dt><code>data.test_run.node_id</code><span class="mo-api-field__type">string</span></dt><dd>The operator ID used in this test.</dd></div>
  <div class="mo-api-field"><dt><code>data.test_run.version</code><span class="mo-api-field__type">string</span></dt><dd>The operator version used in this test.</dd></div>
  <div class="mo-api-field"><dt><code>data.test_run.task_id</code><span class="mo-api-field__type">string</span></dt><dd>ID of this test task.</dd></div>
  <div class="mo-api-field"><dt><code>data.test_run.case_id</code><span class="mo-api-field__type">string</span></dt><dd>ID of this test record.</dd></div>
  <div class="mo-api-field"><dt><code>data.test_run.status</code><span class="mo-api-field__type">string</span></dt><dd>Test running status.</dd></div>
  <div class="mo-api-field"><dt><code>data.test_run.case_result</code><span class="mo-api-field__type">string</span></dt><dd>Test case result; returned if there is a value.</dd></div>
  <div class="mo-api-field"><dt><code>data.test_run.runtime_input</code><span class="mo-api-field__type">object</span></dt><dd>Actual input; returned if there is a value.</dd></div>
  <div class="mo-api-field"><dt><code>data.test_run.runtime_output</code><span class="mo-api-field__type">object</span></dt><dd>Actual output; returned if there is a value.</dd></div>
  <div class="mo-api-field"><dt><code>data.test_run.case_error</code><span class="mo-api-field__type">string</span></dt><dd>Test error message; returned when there is an error.</dd></div>
  <div class="mo-api-field"><dt><code>data.test_run.node_detail</code><span class="mo-api-field__type">object</span></dt><dd>Details of the execution node of the operator in this test; returned if there is a value.</dd></div>
  <div class="mo-api-field"><dt><code>data.test_run.node_detail.node.flow_id</code><span class="mo-api-field__type">string</span></dt><dd>The process to which the execution node belongs.</dd></div>
  <div class="mo-api-field"><dt><code>data.test_run.node_detail.node.name</code><span class="mo-api-field__type">string</span></dt><dd>Execution node name.</dd></div>
  <div class="mo-api-field"><dt><code>data.test_run.node_detail.node.node_key</code><span class="mo-api-field__type">string</span></dt><dd>Execution node ID.</dd></div>
  <div class="mo-api-field"><dt><code>data.test_run.node_detail.node.node_type</code><span class="mo-api-field__type">string</span></dt><dd>Execution node type.</dd></div>
  <div class="mo-api-field"><dt><code>data.test_run.node_detail.node.display_name</code><span class="mo-api-field__type">string</span></dt><dd>Execution node display name.</dd></div>
  <div class="mo-api-field"><dt><code>data.test_run.node_detail.node.workitem_id</code><span class="mo-api-field__type">string</span></dt><dd>Work item ID; returned if there is a value.</dd></div>
  <div class="mo-api-field"><dt><code>data.test_run.node_detail.node.node_execution_id</code><span class="mo-api-field__type">string</span></dt><dd>Node execution identifier; returned if there is a value.</dd></div>
  <div class="mo-api-field"><dt><code>data.test_run.node_detail.run.status</code><span class="mo-api-field__type">string</span></dt><dd>Node execution status.</dd></div>
  <div class="mo-api-field"><dt><code>data.test_run.node_detail.run.started_at</code><span class="mo-api-field__type">string</span></dt><dd>Start time; returned if there is a value.</dd></div>
  <div class="mo-api-field"><dt><code>data.test_run.node_detail.run.ended_at</code><span class="mo-api-field__type">string</span></dt><dd>End time; returned if there is a value.</dd></div>
  <div class="mo-api-field"><dt><code>data.test_run.node_detail.run.error</code><span class="mo-api-field__type">string</span></dt><dd>Execution error; returned if there is a value.</dd></div>
  <div class="mo-api-field"><dt><code>data.test_run.node_detail.run.duration_ms</code><span class="mo-api-field__type">integer</span></dt><dd>Node execution time, unit is milliseconds; returned if there is a value.</dd></div>
  <div class="mo-api-field"><dt><code>data.test_run.node_detail.run.runtime_input</code><span class="mo-api-field__type">object</span></dt><dd>The actual input of the node.</dd></div>
  <div class="mo-api-field"><dt><code>data.test_run.node_detail.run.runtime_output</code><span class="mo-api-field__type">object</span></dt><dd>The actual output of the node.</dd></div>
  <div class="mo-api-field"><dt><code>data.test_run.node_detail.run.config</code><span class="mo-api-field__type">object</span></dt><dd>Node configuration.</dd></div>
  <div class="mo-api-field"><dt><code>data.test_run.node_detail.run.runtime_vars</code><span class="mo-api-field__type">object</span></dt><dd>Node running variable; returned when there is a value.</dd></div>
  <div class="mo-api-field"><dt><code>data.test_run.node_detail.run.metrics</code><span class="mo-api-field__type">object</span></dt><dd>Node running indicator; returned if there is a value.</dd></div>
  <div class="mo-api-field"><dt><code>data.test_run.node_detail.run.developer_logs</code><span class="mo-api-field__type">object</span></dt><dd>Node development log; returned if there is a value.</dd></div>
  <div class="mo-api-field"><dt><code>data.test_run.developer_logs</code><span class="mo-api-field__type">object</span></dt><dd>Development log; returned when the service is provided.</dd></div>
  <div class="mo-api-field"><dt><code>data.test_run.wait_timeout_seconds</code><span class="mo-api-field__type">integer</span></dt><dd>The number of seconds to wait for the result of this test.</dd></div>
</dl>
```

:::
:::{div} mo-api-split-aside

```{raw} html
<p class="mo-api-example-label">Successful response example</p>
```

```json
{
  "code": "OK",
  "msg": "OK",
  "data": {
    "test_run": {
      "operator_id": 123,
      "node_id": "moi:custom.operator:workspace:text_counter",
      "version": "v1",
      "task_id": "task_01",
      "case_id": "case_01",
      "status": "succeeded",
      "runtime_input": {
        "text": "MatrixOne"
      },
      "runtime_output": {
        "count": 9
      }
    }
  }
}
```

:::
::::

## Error response

::::{div} mo-api-split
:::{div} mo-api-split-main

```{raw} html
<dl class="mo-api-fields">
  <div class="mo-api-field"><dt><code>code</code><span class="mo-api-field__type">string</span></dt><dd>Error code.</dd></div>
  <div class="mo-api-field"><dt><code>msg</code><span class="mo-api-field__type">string</span></dt><dd>Readable error message.</dd></div>
  <div class="mo-api-field"><dt><code>data</code><span class="mo-api-field__type">null</span></dt><dd>`null` in an error response.</dd></div>
</dl>
```

:::
:::{div} mo-api-split-aside

```{raw} html
<p class="mo-api-example-label">Error response example</p>
```

```json
{
  "code": "ErrParamInvalid",
  "msg": "请求参数无效",
  "data": null
}
```

:::
::::

## Follow-up operations

After completion [Query custom operator details](get-custom-operator.md) confirms the current status.
