tman provides the check graph command to validate predefined graphs or a start_graph command for correctness. To see the usage details, use the following command:
$tmancheckgraph-hCheck whether the graph content of the predefined graph or start_graph command is correct. For more detailed usage, run 'graph -h'
Usage:tmancheckgraph [OPTIONS] --app <APP>Options:--app<APP> The absolute path of the app defined in the graph. By default, the predefined graph will be read from the first one in the list.
--predefined-graph-name<PREDEFINED_GRAPH_NAME>Specifyapredefinedgraphnametocheck,otherwise,allpredefinedgraphswillbechecked.--graph<GRAPH> Specify the JSON string of a 'start_graph' command to be checked. If not specified, the predefined graph in the first app will be checked.
-h,--helpPrinthelp
The check graph command is designed to handle graphs that may span multiple apps, so it does not require being run from the root directory of a specific app. Instead, it can be executed from any directory, with the --app parameter used to specify the folders of the apps involved in the graph.
Predefined Graph Definition Requirement: If a predefined graph name is specified, the definition will be extracted from the property.json file of the app specified by the first --app parameter.
Package Installation Requirement: Before running the check graph command, all extensions that the app depends on must be installed using the tman install command. This is necessary because the validation process requires information about each extension in the graph, such as APIs defined in their manifest.json files.
Unique App URI Requirement: In a multi-app graph, each app's property.json must define a unique _ten::uri. Additionally, the uri value cannot be set to "localhost".
Validation Rules
1. Presence of Nodes
The nodes array is required in any graph definition. If absent, an error will be thrown.
Checking graph[0]... ❌. Details:
No extension node is defined in graph.
All is done.
❌ Error: 1/1 graphs failed.
2. Uniqueness of Nodes
Each node in the nodes array represents a specific extension instance within a group of an app, created by a specified addon. Therefore, each extension instance should be uniquely represented by a single node. A node must be uniquely identified by the combination of app, extension_group, and name. Multiple entries for the same extension instance are not allowed.
Checking graph[0]... ❌. Details:
Duplicated extension was found in nodes[1], addon: basic_hello_world_1__test_extension, name: test_extension.
All is done.
❌ Error: 1/1 graphs failed.
3. Extensions used in connections should be defined in nodes
All extension instances referenced in the connections field, whether as a source or destination, must be explicitly defined in the nodes field. Any instance not defined in the nodes array will cause validation errors.
Example (Source extension not defined):
Imagine that the content of property.json of a TEN app is as follows.
Checking graph[0]... ❌. Details:
The extension declared in connections[0] is not defined in nodes, extension_group: producer, extension: some_extension.
All is done.
❌ Error: 1/1 graphs failed.
Example (Destination extension not defined):
Imagine that the content of property.json of a TEN app is as follows.
Checking graph[0]... ❌. Details:
The extension declared in connections[0].cmd[1] is not defined in nodes extension_group: some_group, extension: consumer.
All is done.
❌ Error: 1/1 graphs failed.
4. The addons declared in the nodes must be installed in the app
Example (The _ten::uri in property.json is not equal to the app field in nodes):
Imagine that the content of property.json of a TEN app is as follows.
Checking graph[0]... ❌. Details:
The following packages are declared in nodes but not installed: [("localhost", Extension, "default_extension_go")].
All is done.
❌ Error: 1/1 graphs failed.
The problem is all packages in the app will be stored in a map which key is the uri of the app, and each node in the graph is retrieved by the app field (which is localhost by default). The app in node (i.e., localhost) is mismatch with the uri of app (i.e., http://localhost:8001).
Example (the ten_packages does not exist as the tman install has not executed):
Imagine that the content of property.json of a TEN app is as follows.
Checking graph[0]... ❌. Details:
The following packages are declared in nodes but not installed: [("localhost", Extension, "default_extension_go")].
All is done.
❌ Error: 1/1 graphs failed.
5. In connections, messages sent from one extension should be defined in the same section
Example:
Imagine that all the packages have been installed.
Checking graph[0]... ❌. Details:
extension 'some_extension' is defined in connection[0] and connection[1], merge them into one section.
All is done.
❌ Error: 1/1 graphs failed.
6. In connections, the messages sent out from one extension should have a unique name in each type
Example:
Imagine that all the packages have been installed.
Checking graph[0]... ❌. Details:
- connection[0]:
- Merge the following cmd into one section:
'hello' is defined in flow[0] and flow[1].
All is done.
❌ Error: 1/1 graphs failed.
7. The messages declared in the connections should be compatible
The message declared in each message flow in the connections will be checked if the schema is compatible, according to the schema definition in the manifest.json of extensions. The rules of message compatible are as follows.
If the message schema is not found neither in the source extension nor the target extension, the message is compatible.
If the message schema is only found in one of the extensions, the message is incompatible.
The message is compatible only if the following conditions are met.
The property type is compatible.
If the property is an object, the fields both in the source and target schema must have a compatible type.
If the required keyword is defined in the target schema, there must be a required keyword in the source schema, which is the superset of the required in the target.
Example:
Imagine that all the packages have been installed.
The content of manifest.json in addon_a is as follows.
Checking graph[0]... ❌. Details:
- connections[0]:
- cmd[0]: Schema incompatible to [extension_group: some_group, extension: another_ext], { .foo: type is incompatible, source is [string], but target is [int8] }
All is done.
❌ Error: 1/1 graphs failed.
8. The app in node must be unambiguous
The app field in each node must met the following rules.
The app field must be equal to the _ten::uri of the corresponding TEN app.
Either all nodes should have app declared, or none should.
The app field can not be localhost.
The app field can not be an empty string.
Example (some of the nodes specified the app field):
❌ Error: Failed to parse graph string, nodes[1]: 'localhost' is not allowed in graph definition, and the graph seems to be a single-app graph, just remove the 'app' field
Example (The app field is localhost in a multi-app graph):
❌ Error: Failed to parse graph string, nodes[1]: 'localhost' is not allowed in graph definition, change the content of 'app' field to be consistent with '_ten::uri'