diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5521061b59d3286875a4ec16fb88c96182b2150c..95b0a116a7bdc85e8dd5864706dc8ea0b79a2063 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -4,8 +4,40 @@ include: stages: - static_code_analysis + - functional_test + - functional_api_test variables: DEBUG: 'TRUE' SOURCE_FOLDER: "src" +run_functional_test: + stage: functional_test + image: iopsys/code-analysis-dev:latest + allow_failure: true + script: + - "./gitlab-ci/install-dependencies.sh" + - "./gitlab-ci/setup.sh" + - "./gitlab-ci/functional-test.sh" + + artifacts: + when: always + paths: + - functional-test-memory-report.xml + - timestamp.log + +run_functional_api_test: + stage: functional_api_test + image: iopsys/code-analysis-dev:latest + allow_failure: true + script: + - "./gitlab-ci/install-dependencies.sh" + - "./gitlab-ci/setup.sh" + - "./gitlab-ci/functional-api-test.sh" + + artifacts: + when: always + paths: + - api-test-memory-report.xml + - api-result.log + - timestamp.log diff --git a/docs/api/topology.md b/docs/api/topology.md new file mode 100644 index 0000000000000000000000000000000000000000..e9aa40fbecd80ac5679740eb165c376dea691601 --- /dev/null +++ b/docs/api/topology.md @@ -0,0 +1,1692 @@ +# topology Schema + +``` +https://www.iopsys.eu/usp.raw.json +``` + +| Custom Properties | Additional Properties | +| ----------------- | --------------------- | +| Forbidden | Forbidden | + +# topology + +| List of Methods | +| ----------------------- | +| [changelog](#changelog) | Method | topology (this schema) | +| [dump](#dump) | Method | topology (this schema) | +| [nodes](#nodes) | Method | topology (this schema) | +| [refresh](#refresh) | Method | topology (this schema) | +| [status](#status) | Method | topology (this schema) | + +## changelog + +### This object represents log entries for changes in the 1905 Network Topology. + +`changelog` + +- type: `Method` + +### changelog Type + +`object` with following properties: + +| Property | Type | Required | +| -------- | ------ | ------------ | +| `output` | object | **Required** | + +#### output + +`output` + +- is **required** +- type: `object` + +##### output Type + +`object` with following properties: + +| Property | Type | Required | +| --------------- | ------- | -------- | +| `changelog` | array | Optional | +| `num_changelog` | integer | Optional | + +#### changelog + +`changelog` + +- is optional +- type: `object[]` + +##### changelog Type + +Array type: `object[]` + +All items must be of the type: `object` with following properties: + +| Property | Type | Required | +| -------------------- | ------- | -------- | +| `event_type` | string | Optional | +| `is1905_neighbor` | boolean | Optional | +| `neighbor` | string | Optional | +| `reporter` | string | Optional | +| `reporter_interface` | string | Optional | +| `timestamp` | integer | Optional | + +#### event_type + +`event_type` + +- is optional +- type: reference + +##### event_type Type + +`string` + +All instances must conform to this regular expression (test examples [here](https://regexr.com/?expression=add%7Cdel)): + +```regex +add|del +``` + +#### is1905_neighbor + +`is1905_neighbor` + +- is optional +- type: `boolean` + +##### is1905_neighbor Type + +`boolean` + +#### neighbor + +mac address in string format + +`neighbor` + +- is optional +- type: reference + +##### neighbor Type + +`string` + +- minimum length: 17 characters +- maximum length: 17 characters All instances must conform to this regular expression (test examples + [here](<https://regexr.com/?expression=(%5B0-9a-fA-F%5D%7B2%7D%3A)%7B5%7D%5B0-9a-fA-F%5D%7B2%7D>)): + +```regex +([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2} +``` + +#### reporter + +mac address in string format + +`reporter` + +- is optional +- type: reference + +##### reporter Type + +`string` + +- minimum length: 17 characters +- maximum length: 17 characters All instances must conform to this regular expression (test examples + [here](<https://regexr.com/?expression=(%5B0-9a-fA-F%5D%7B2%7D%3A)%7B5%7D%5B0-9a-fA-F%5D%7B2%7D>)): + +```regex +([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2} +``` + +#### reporter_interface + +mac address in string format + +`reporter_interface` + +- is optional +- type: reference + +##### reporter_interface Type + +`string` + +- minimum length: 17 characters +- maximum length: 17 characters All instances must conform to this regular expression (test examples + [here](<https://regexr.com/?expression=(%5B0-9a-fA-F%5D%7B2%7D%3A)%7B5%7D%5B0-9a-fA-F%5D%7B2%7D>)): + +```regex +([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2} +``` + +#### timestamp + +Time the node was changed + +`timestamp` + +- is optional +- type: reference + +##### timestamp Type + +`integer` + +- minimum value: `0` +- maximum value: `65535` + +#### num_changelog + +`num_changelog` + +- is optional +- type: `integer` + +##### num_changelog Type + +`integer` + +- minimum value: `1` +- maximum value: `255` + +### Output Example + +```json +{ + "num_changelog": 236, + "changelog": [ + { + "reporter": "d5:Ff:68:5c:fb:9a", + "reporter_interface": "CC:Ec:2f:f3:76:DE", + "neighbor": "b5:4F:8b:f2:6d:f2", + "is1905_neighbor": false, + "event_type": "add", + "timestamp": 16618 + } + ] +} +``` + +## dump + +### Topology info of AL nodes and there parameters + +`dump` + +- type: `Method` + +### dump Type + +`object` with following properties: + +| Property | Type | Required | +| -------- | ------ | -------- | +| `output` | object | Optional | + +#### output + +`output` + +- is optional +- type: `object` + +##### output Type + +`object` with following properties: + +| Property | Type | Required | +| -------- | ------ | -------- | +| `nodes` | array | Optional | +| `self` | object | Optional | + +#### nodes + +`nodes` + +- is optional +- type: `object[]` + +##### nodes Type + +Array type: `object[]` + +All items must be of the type: `object` with following properties: + +| Property | Type | Required | +| ----------------------- | ------- | -------- | +| `1905_nbr_localintf` | string | Optional | +| `bridge_tuple` | array | Optional | +| `bridging_tuple_num` | integer | Optional | +| `control_url` | string | Optional | +| `friendly_name` | string | Optional | +| `ieee1905_macaddr` | string | Optional | +| `interfaces` | array | Optional | +| `ipv4_itfr_num` | integer | Optional | +| `ipv4_params` | array | Optional | +| `ipv6_itfr_num` | integer | Optional | +| `l2_neighbor` | array | Optional | +| `l2_neighbor_num` | integer | Optional | +| `local_interface_nbr` | integer | Optional | +| `manufacturer_model` | string | Optional | +| `manufacturer_name` | string | Optional | +| `neighbors` | array | Optional | +| `non1905_nbr_localintf` | string | Optional | +| `non1905_neighbors` | array | Optional | +| `num_neighbors` | integer | Optional | +| `num_non1905_neighbors` | integer | Optional | +| `registrar_freq_band` | string | Optional | +| `version` | string | Optional | + +#### 1905_nbr_localintf + +mac address in string format + +`1905_nbr_localintf` + +- is optional +- type: reference + +##### 1905_nbr_localintf Type + +`string` + +- minimum length: 17 characters +- maximum length: 17 characters All instances must conform to this regular expression (test examples + [here](<https://regexr.com/?expression=(%5B0-9a-fA-F%5D%7B2%7D%3A)%7B5%7D%5B0-9a-fA-F%5D%7B2%7D>)): + +```regex +([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2} +``` + +#### bridge_tuple + +`bridge_tuple` + +- is optional +- type: `object[]` + +##### bridge_tuple Type + +Array type: `object[]` + +All items must be of the type: `object` with following properties: + +| Property | Type | Required | +| -------- | ----- | -------- | +| `br_mac` | array | Optional | + +#### br_mac + +`br_mac` + +- is optional +- type: reference + +##### br_mac Type + +Array type: reference + +All items must be of the type: `string` + +- minimum length: 17 characters +- maximum length: 17 characters All instances must conform to this regular expression (test examples + [here](<https://regexr.com/?expression=(%5B0-9a-fA-F%5D%7B2%7D%3A)%7B5%7D%5B0-9a-fA-F%5D%7B2%7D>)): + +```regex +([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2} +``` + +mac address in string format + +#### bridging_tuple_num + +`bridging_tuple_num` + +- is optional +- type: `integer` + +##### bridging_tuple_num Type + +`integer` + +- minimum value: `0` + +#### control_url + +`control_url` + +- is optional +- type: `string` + +##### control_url Type + +`string` + +All instances must conform to this regular expression (test examples +[here](<https://regexr.com/?expression=%5Ehttp%3A%5C%2F(%5B0-255%5D%5C.)%7B3%7D%5B0-255%5D>)): + +```regex +^http:\/([0-255]\.){3}[0-255] +``` + +#### friendly_name + +`friendly_name` + +- is optional +- type: `string` + +##### friendly_name Type + +`string` + +#### ieee1905_macaddr + +mac address in string format + +`ieee1905_macaddr` + +- is optional +- type: reference + +##### ieee1905_macaddr Type + +`string` + +- minimum length: 17 characters +- maximum length: 17 characters All instances must conform to this regular expression (test examples + [here](<https://regexr.com/?expression=(%5B0-9a-fA-F%5D%7B2%7D%3A)%7B5%7D%5B0-9a-fA-F%5D%7B2%7D>)): + +```regex +([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2} +``` + +#### interfaces + +`interfaces` + +- is optional +- type: `object[]` + +##### interfaces Type + +Array type: `object[]` + +All items must be of the type: `object` with following properties: + +| Property | Type | Required | +| -------------------- | ------- | -------- | +| `ap_channel_band` | integer | Optional | +| `freq_index1` | integer | Optional | +| `freq_index2` | integer | Optional | +| `interface_id` | string | Optional | +| `media_type` | string | Optional | +| `network_membership` | string | Optional | +| `role` | string | Optional | + +#### ap_channel_band + +`ap_channel_band` + +- is optional +- type: `integer` + +##### ap_channel_band Type + +`integer` + +- minimum value: `0` + +#### freq_index1 + +`freq_index1` + +- is optional +- type: `integer` + +##### freq_index1 Type + +`integer` + +- minimum value: `0` + +#### freq_index2 + +`freq_index2` + +- is optional +- type: `integer` + +##### freq_index2 Type + +`integer` + +- minimum value: `0` + +#### interface_id + +mac address in string format + +`interface_id` + +- is optional +- type: reference + +##### interface_id Type + +`string` + +- minimum length: 17 characters +- maximum length: 17 characters All instances must conform to this regular expression (test examples + [here](<https://regexr.com/?expression=(%5B0-9a-fA-F%5D%7B2%7D%3A)%7B5%7D%5B0-9a-fA-F%5D%7B2%7D>)): + +```regex +([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2} +``` + +#### media_type + +Linux network interface type + +`media_type` + +- is optional +- type: reference + +##### media_type Type + +`string` + +All instances must conform to this regular expression (test examples +[here](<https://regexr.com/?expression=%5EIEEE%20802%5C.(3u%7C3ab%7C11b%7C11g%7C11a%7C11n%202.4%7C11n%205.0%7C11ac%7C11ad%7C11af)>)): + +```regex +^IEEE 802\.(3u|3ab|11b|11g|11a|11n 2.4|11n 5.0|11ac|11ad|11af) +``` + +#### network_membership + +mac address in string format + +`network_membership` + +- is optional +- type: reference + +##### network_membership Type + +`string` + +- minimum length: 17 characters +- maximum length: 17 characters All instances must conform to this regular expression (test examples + [here](<https://regexr.com/?expression=(%5B0-9a-fA-F%5D%7B2%7D%3A)%7B5%7D%5B0-9a-fA-F%5D%7B2%7D>)): + +```regex +([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2} +``` + +#### role + +`role` + +- is optional +- type: `string` + +##### role Type + +`string` + +#### ipv4_itfr_num + +`ipv4_itfr_num` + +- is optional +- type: `integer` + +##### ipv4_itfr_num Type + +`integer` + +- minimum value: `0` + +#### ipv4_params + +`ipv4_params` + +- is optional +- type: `object[]` + +##### ipv4_params Type + +Array type: `object[]` + +All items must be of the type: `object` with following properties: + +| Property | Type | Required | +| ---------------- | ------ | -------- | +| `dhcp_addr` | string | Optional | +| `ipv4_addr_type` | string | Optional | +| `ipv4_address` | string | Optional | +| `mac_address` | string | Optional | + +#### dhcp_addr + +IPv4 Address + +`dhcp_addr` + +- is optional +- type: reference + +##### dhcp_addr Type + +`string` + +All instances must conform to this regular expression (test examples +[here](<https://regexr.com/?expression=(%5B0-255%5D%5C.)%7B3%7D%5B0-255%5D>)): + +```regex +([0-255]\.){3}[0-255] +``` + +#### ipv4_addr_type + +`ipv4_addr_type` + +- is optional +- type: `string` + +##### ipv4_addr_type Type + +`string` + +#### ipv4_address + +IPv4 Address + +`ipv4_address` + +- is optional +- type: reference + +##### ipv4_address Type + +`string` + +All instances must conform to this regular expression (test examples +[here](<https://regexr.com/?expression=(%5B0-255%5D%5C.)%7B3%7D%5B0-255%5D>)): + +```regex +([0-255]\.){3}[0-255] +``` + +#### mac_address + +mac address in string format + +`mac_address` + +- is optional +- type: reference + +##### mac_address Type + +`string` + +- minimum length: 17 characters +- maximum length: 17 characters All instances must conform to this regular expression (test examples + [here](<https://regexr.com/?expression=(%5B0-9a-fA-F%5D%7B2%7D%3A)%7B5%7D%5B0-9a-fA-F%5D%7B2%7D>)): + +```regex +([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2} +``` + +#### ipv6_itfr_num + +`ipv6_itfr_num` + +- is optional +- type: `integer` + +##### ipv6_itfr_num Type + +`integer` + +- minimum value: `0` + +#### l2_neighbor + +`l2_neighbor` + +- is optional +- type: `object[]` + +##### l2_neighbor Type + +Array type: `object[]` + +All items must be of the type: `object` with following properties: + +| Property | Type | Required | +| --------------- | ------ | -------- | +| `local_intf_id` | string | Optional | +| `local_nbr_id` | string | Optional | + +#### local_intf_id + +mac address in string format + +`local_intf_id` + +- is optional +- type: reference + +##### local_intf_id Type + +`string` + +- minimum length: 17 characters +- maximum length: 17 characters All instances must conform to this regular expression (test examples + [here](<https://regexr.com/?expression=(%5B0-9a-fA-F%5D%7B2%7D%3A)%7B5%7D%5B0-9a-fA-F%5D%7B2%7D>)): + +```regex +([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2} +``` + +#### local_nbr_id + +mac address in string format + +`local_nbr_id` + +- is optional +- type: reference + +##### local_nbr_id Type + +`string` + +- minimum length: 17 characters +- maximum length: 17 characters All instances must conform to this regular expression (test examples + [here](<https://regexr.com/?expression=(%5B0-9a-fA-F%5D%7B2%7D%3A)%7B5%7D%5B0-9a-fA-F%5D%7B2%7D>)): + +```regex +([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2} +``` + +#### l2_neighbor_num + +`l2_neighbor_num` + +- is optional +- type: `integer` + +##### l2_neighbor_num Type + +`integer` + +- minimum value: `0` + +#### local_interface_nbr + +`local_interface_nbr` + +- is optional +- type: `integer` + +##### local_interface_nbr Type + +`integer` + +- minimum value: `0` + +#### manufacturer_model + +`manufacturer_model` + +- is optional +- type: `string` + +##### manufacturer_model Type + +`string` + +#### manufacturer_name + +`manufacturer_name` + +- is optional +- type: `string` + +##### manufacturer_name Type + +`string` + +#### neighbors + +`neighbors` + +- is optional +- type: `object[]` + +##### neighbors Type + +Array type: `object[]` + +All items must be of the type: `object` with following properties: + +| Property | Type | Required | +| -------------- | ------ | -------- | +| `link_metrics` | array | Optional | +| `nbr_mac_id` | string | Optional | + +#### link_metrics + +`link_metrics` + +- is optional +- type: `object[]` + +##### link_metrics Type + +Array type: `object[]` + +All items must be of the type: `object` with following properties: + +| Property | Type | Required | +| --------------------- | ------- | -------- | +| `ieee_bridge` | boolean | Optional | +| `link_availability` | integer | Optional | +| `mac_thrput_capacity` | integer | Optional | +| `nbr_intf_macid` | string | Optional | +| `phy_rate` | integer | Optional | +| `rssi` | integer | Optional | +| `rx_packet_error` | integer | Optional | +| `rx_packet_ok` | integer | Optional | +| `tx_packet_error` | integer | Optional | +| `tx_packet_ok` | integer | Optional | + +#### ieee_bridge + +`ieee_bridge` + +- is optional +- type: `boolean` + +##### ieee_bridge Type + +`boolean` + +#### link_availability + +`link_availability` + +- is optional +- type: `integer` + +##### link_availability Type + +`integer` + +- minimum value: `0` +- maximum value: `100` + +#### mac_thrput_capacity + +`mac_thrput_capacity` + +- is optional +- type: `integer` + +##### mac_thrput_capacity Type + +`integer` + +- minimum value: `0` + +#### nbr_intf_macid + +mac address in string format + +`nbr_intf_macid` + +- is optional +- type: reference + +##### nbr_intf_macid Type + +`string` + +- minimum length: 17 characters +- maximum length: 17 characters All instances must conform to this regular expression (test examples + [here](<https://regexr.com/?expression=(%5B0-9a-fA-F%5D%7B2%7D%3A)%7B5%7D%5B0-9a-fA-F%5D%7B2%7D>)): + +```regex +([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2} +``` + +#### phy_rate + +`phy_rate` + +- is optional +- type: `integer` + +##### phy_rate Type + +`integer` + +- minimum value: `0` + +#### rssi + +`rssi` + +- is optional +- type: `integer` + +##### rssi Type + +`integer` + +- minimum value: `0` + +#### rx_packet_error + +`rx_packet_error` + +- is optional +- type: `integer` + +##### rx_packet_error Type + +`integer` + +- minimum value: `0` + +#### rx_packet_ok + +`rx_packet_ok` + +- is optional +- type: `integer` + +##### rx_packet_ok Type + +`integer` + +- minimum value: `0` + +#### tx_packet_error + +`tx_packet_error` + +- is optional +- type: `integer` + +##### tx_packet_error Type + +`integer` + +- minimum value: `0` + +#### tx_packet_ok + +`tx_packet_ok` + +- is optional +- type: `integer` + +##### tx_packet_ok Type + +`integer` + +- minimum value: `0` + +#### nbr_mac_id + +mac address in string format + +`nbr_mac_id` + +- is optional +- type: reference + +##### nbr_mac_id Type + +`string` + +- minimum length: 17 characters +- maximum length: 17 characters All instances must conform to this regular expression (test examples + [here](<https://regexr.com/?expression=(%5B0-9a-fA-F%5D%7B2%7D%3A)%7B5%7D%5B0-9a-fA-F%5D%7B2%7D>)): + +```regex +([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2} +``` + +#### non1905_nbr_localintf + +mac address in string format + +`non1905_nbr_localintf` + +- is optional +- type: reference + +##### non1905_nbr_localintf Type + +`string` + +- minimum length: 17 characters +- maximum length: 17 characters All instances must conform to this regular expression (test examples + [here](<https://regexr.com/?expression=(%5B0-9a-fA-F%5D%7B2%7D%3A)%7B5%7D%5B0-9a-fA-F%5D%7B2%7D>)): + +```regex +([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2} +``` + +#### non1905_neighbors + +`non1905_neighbors` + +- is optional +- type: reference + +##### non1905_neighbors Type + +Array type: reference + +All items must be of the type: `string` + +- minimum length: 17 characters +- maximum length: 17 characters All instances must conform to this regular expression (test examples + [here](<https://regexr.com/?expression=(%5B0-9a-fA-F%5D%7B2%7D%3A)%7B5%7D%5B0-9a-fA-F%5D%7B2%7D>)): + +```regex +([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2} +``` + +mac address in string format + +#### num_neighbors + +`num_neighbors` + +- is optional +- type: `integer` + +##### num_neighbors Type + +`integer` + +- minimum value: `0` + +#### num_non1905_neighbors + +`num_non1905_neighbors` + +- is optional +- type: `integer` + +##### num_non1905_neighbors Type + +`integer` + +- minimum value: `0` + +#### registrar_freq_band + +mac address in string format + +`registrar_freq_band` + +- is optional +- type: reference + +##### registrar_freq_band Type + +`string` + +- minimum length: 17 characters +- maximum length: 17 characters All instances must conform to this regular expression (test examples + [here](<https://regexr.com/?expression=(%5B0-9a-fA-F%5D%7B2%7D%3A)%7B5%7D%5B0-9a-fA-F%5D%7B2%7D>)): + +```regex +([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2} +``` + +#### version + +`version` + +- is optional +- type: `string` + +##### version Type + +`string` + +All instances must conform to this regular expression (test examples +[here](<https://regexr.com/?expression=(1905%5C.1a%7C1905)>)): + +```regex +(1905\.1a|1905) +``` + +#### self + +`self` + +- is optional +- type: `object` + +##### self Type + +`object` with following properties: + +| Property | Type | Required | +| ----------------------- | ------- | -------- | +| `ieee1905_macaddr` | string | Optional | +| `neighbors` | array | Optional | +| `non1905_neighbors` | array | Optional | +| `num_neighbors` | integer | Optional | +| `num_non1905_neighbors` | integer | Optional | + +#### ieee1905_macaddr + +mac address in string format + +`ieee1905_macaddr` + +- is optional +- type: reference + +##### ieee1905_macaddr Type + +`string` + +- minimum length: 17 characters +- maximum length: 17 characters All instances must conform to this regular expression (test examples + [here](<https://regexr.com/?expression=(%5B0-9a-fA-F%5D%7B2%7D%3A)%7B5%7D%5B0-9a-fA-F%5D%7B2%7D>)): + +```regex +([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2} +``` + +#### neighbors + +`neighbors` + +- is optional +- type: `object[]` + +##### neighbors Type + +Array type: `object[]` + +All items must be of the type: `object` with following properties: + +| Property | Type | Required | +| ------------ | ------ | -------- | +| `nbr_mac_id` | string | Optional | + +#### nbr_mac_id + +mac address in string format + +`nbr_mac_id` + +- is optional +- type: reference + +##### nbr_mac_id Type + +`string` + +- minimum length: 17 characters +- maximum length: 17 characters All instances must conform to this regular expression (test examples + [here](<https://regexr.com/?expression=(%5B0-9a-fA-F%5D%7B2%7D%3A)%7B5%7D%5B0-9a-fA-F%5D%7B2%7D>)): + +```regex +([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2} +``` + +#### non1905_neighbors + +`non1905_neighbors` + +- is optional +- type: reference + +##### non1905_neighbors Type + +Array type: reference + +All items must be of the type: `string` + +- minimum length: 17 characters +- maximum length: 17 characters All instances must conform to this regular expression (test examples + [here](<https://regexr.com/?expression=(%5B0-9a-fA-F%5D%7B2%7D%3A)%7B5%7D%5B0-9a-fA-F%5D%7B2%7D>)): + +```regex +([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2} +``` + +mac address in string format + +#### num_neighbors + +`num_neighbors` + +- is optional +- type: `integer` + +##### num_neighbors Type + +`integer` + +- minimum value: `0` + +#### num_non1905_neighbors + +`num_non1905_neighbors` + +- is optional +- type: `integer` + +##### num_non1905_neighbors Type + +`integer` + +- minimum value: `0` + +### Output Example + +```json +{ + "self": { + "ieee1905_macaddr": "E2:aE:30:3A:De:b9", + "num_neighbors": 18387137, + "neighbors": [ + { "nbr_mac_id": "71:F6:d3:38:BD:A0" }, + { "nbr_mac_id": "Ca:ef:e8:E9:d5:2e" }, + { "nbr_mac_id": "dF:b2:99:e2:6c:52" } + ], + "num_non1905_neighbors": 9369078, + "non1905_neighbors": ["31:2b:15:8b:86:cc", "f0:4E:28:E0:Fb:eA", "4C:DF:6E:8D:5B:29"] + }, + "nodes": [ + { + "ieee1905_macaddr": "DA:dE:fb:fB:81:DA", + "num_neighbors": 85875137, + "neighbors": [ + { + "nbr_mac_id": "9c:BE:Cc:aE:3E:8C", + "link_metrics": [ + { + "nbr_intf_macid": "87:7b:5D:bD:Ab:Be", + "ieee_bridge": true, + "tx_packet_error": 67051184, + "tx_packet_ok": 86624513, + "mac_thrput_capacity": 20426377, + "link_availability": 0, + "phy_rate": 53859676, + "rx_packet_error": 63130145, + "rx_packet_ok": 19040358, + "rssi": 35282557 + }, + { + "nbr_intf_macid": "43:9a:64:6f:aA:aa", + "ieee_bridge": true, + "tx_packet_error": 13593344, + "tx_packet_ok": 11801570, + "mac_thrput_capacity": 85910385, + "link_availability": 67, + "phy_rate": 2176470, + "rx_packet_error": 54960195, + "rx_packet_ok": 78897682, + "rssi": 34003344 + } + ] + }, + { + "nbr_mac_id": "ac:F5:64:aF:eA:Ea", + "link_metrics": [ + { + "nbr_intf_macid": "C1:CE:85:4f:75:8C", + "ieee_bridge": true, + "tx_packet_error": 61090328, + "tx_packet_ok": 21947155, + "mac_thrput_capacity": 59957558, + "link_availability": 6, + "phy_rate": 34074792, + "rx_packet_error": 34199878, + "rx_packet_ok": 72913887, + "rssi": 95990520 + } + ] + }, + { + "nbr_mac_id": "13:0d:6b:dE:Ef:BA", + "link_metrics": [ + { + "nbr_intf_macid": "08:4F:1c:c9:35:9d", + "ieee_bridge": false, + "tx_packet_error": 8676733, + "tx_packet_ok": 41945894, + "mac_thrput_capacity": 93087924, + "link_availability": 41, + "phy_rate": 56642915, + "rx_packet_error": 66783426, + "rx_packet_ok": 50078385, + "rssi": 84370224 + }, + { + "nbr_intf_macid": "6D:Fa:a6:be:a1:79", + "ieee_bridge": false, + "tx_packet_error": 32744513, + "tx_packet_ok": 45283698, + "mac_thrput_capacity": 14490457, + "link_availability": 23, + "phy_rate": 32518402, + "rx_packet_error": 20140868, + "rx_packet_ok": 38500445, + "rssi": 19221008 + }, + { + "nbr_intf_macid": "44:bE:9f:6f:fc:4C", + "ieee_bridge": false, + "tx_packet_error": 28786808, + "tx_packet_ok": 53574651, + "mac_thrput_capacity": 62953812, + "link_availability": 49, + "phy_rate": 23209366, + "rx_packet_error": 43407016, + "rx_packet_ok": 83227301, + "rssi": 73001461 + } + ] + }, + { + "nbr_mac_id": "e7:a7:EB:a2:56:0e", + "link_metrics": [ + { + "nbr_intf_macid": "9f:78:b9:1F:aA:16", + "ieee_bridge": false, + "tx_packet_error": 27831347, + "tx_packet_ok": 69759987, + "mac_thrput_capacity": 33993343, + "link_availability": 73, + "phy_rate": 2699981, + "rx_packet_error": 67692075, + "rx_packet_ok": 18205065, + "rssi": 48620621 + }, + { + "nbr_intf_macid": "C3:E9:Be:aE:E5:CB", + "ieee_bridge": true, + "tx_packet_error": 58858275, + "tx_packet_ok": 44945375, + "mac_thrput_capacity": 16538719, + "link_availability": 92, + "phy_rate": 11801220, + "rx_packet_error": 18349318, + "rx_packet_ok": 35366956, + "rssi": 4286776 + } + ] + } + ], + "num_non1905_neighbors": 33928039, + "non1905_neighbors": ["B3:19:1A:b2:CC:6E", "dd:Cc:b9:3c:db:C6", "DE:98:b1:0D:0c:7a", "c2:80:3e:Be:Bc:Fa"], + "registrar_freq_band": "1B:F7:bb:5A:57:37", + "non1905_nbr_localintf": "9C:a7:a7:f3:6D:91", + "1905_nbr_localintf": "32:58:72:3F:a0:FD", + "local_interface_nbr": 98177152, + "l2_neighbor_num": 29315467, + "bridging_tuple_num": 84138762, + "version": "1905", + "friendly_name": "incididunt est nostrud", + "manufacturer_name": "Ut eiusmod", + "manufacturer_model": "eiusmod nisi aute id", + "control_url": "http:/1.0.0.1", + "ipv4_itfr_num": 40437, + "ipv6_itfr_num": 36932042, + "interfaces": [ + { + "interface_id": "Fb:c8:24:59:86:52", + "media_type": "IEEE 802.11g", + "network_membership": "BE:4F:76:bb:EE:93", + "role": "voluptate in cillum qui", + "ap_channel_band": 96366223, + "freq_index1": 89577010, + "freq_index2": 66181794 + }, + { + "interface_id": "A2:75:8e:ea:b5:88", + "media_type": "IEEE 802.11b", + "network_membership": "FF:48:dF:1a:e4:95", + "role": "culpa", + "ap_channel_band": 38406494, + "freq_index1": 5919201, + "freq_index2": 77051282 + }, + { + "interface_id": "47:e1:B0:40:3b:96", + "media_type": "IEEE 802.11af", + "network_membership": "84:b9:8F:fd:B2:23", + "role": "sit", + "ap_channel_band": 17570727, + "freq_index1": 82136359, + "freq_index2": 9189596 + }, + { + "interface_id": "63:Cd:0c:fF:6A:EA", + "media_type": "IEEE 802.11b", + "network_membership": "b7:cf:51:Df:eE:1d", + "role": "minim", + "ap_channel_band": 49487476, + "freq_index1": 38232161, + "freq_index2": 52949003 + } + ], + "l2_neighbor": [{ "local_intf_id": "F0:d7:ab:da:0c:2E", "local_nbr_id": "83:1C:36:7b:c8:23" }], + "bridge_tuple": [ + { "br_mac": ["CF:87:4b:4D:12:8B", "2e:AD:E5:aB:ec:e8"] }, + { + "br_mac": [ + "0b:54:e7:81:eB:2E", + "E1:8f:a3:50:c3:23", + "9b:05:bD:fC:61:5D", + "b7:F6:7C:35:18:38", + "0a:Cd:eb:01:8B:ff" + ] + } + ], + "ipv4_params": [ + { + "mac_address": "12:03:DA:Fd:a0:Dc", + "ipv4_addr_type": "dolor esse nisi pariatur Ut", + "ipv4_address": "5.0.0.2", + "dhcp_addr": "2.0.2.0" + }, + { + "mac_address": "60:A0:CE:39:Ad:0E", + "ipv4_addr_type": "irure amet quis deserunt", + "ipv4_address": "1.5.0.5", + "dhcp_addr": "2.0.0.5" + }, + { + "mac_address": "eF:Dc:52:4B:E4:bd", + "ipv4_addr_type": "amet cupidatat dolor in dolor", + "ipv4_address": "1.5.0.0", + "dhcp_addr": "0.2.2.1" + }, + { + "mac_address": "bd:E9:b8:Bd:dC:8d", + "ipv4_addr_type": "volup", + "ipv4_address": "1.2.5.1", + "dhcp_addr": "5.1.0.1" + }, + { + "mac_address": "eD:f9:90:C0:0e:e2", + "ipv4_addr_type": "Lorem pariatur reprehenderit", + "ipv4_address": "5.5.1.5", + "dhcp_addr": "1.1.5.2" + } + ] + } + ] +} +``` + +## nodes + +### Give the mac id of self and the neighbor nodes + +`nodes` + +- type: `Method` + +### nodes Type + +`object` with following properties: + +| Property | Type | Required | +| -------- | ------ | ------------ | +| `output` | object | **Required** | + +#### output + +`output` + +- is **required** +- type: `object` + +##### output Type + +`object` with following properties: + +| Property | Type | Required | +| ------------------ | ------ | -------- | +| `ieee1905_macaddr` | string | Optional | +| `neighbors` | array | Optional | + +#### ieee1905_macaddr + +mac address in string format + +`ieee1905_macaddr` + +- is optional +- type: reference + +##### ieee1905_macaddr Type + +`string` + +- minimum length: 17 characters +- maximum length: 17 characters All instances must conform to this regular expression (test examples + [here](<https://regexr.com/?expression=(%5B0-9a-fA-F%5D%7B2%7D%3A)%7B5%7D%5B0-9a-fA-F%5D%7B2%7D>)): + +```regex +([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2} +``` + +#### neighbors + +`neighbors` + +- is optional +- type: reference + +##### neighbors Type + +Array type: reference + +All items must be of the type: `string` + +- minimum length: 17 characters +- maximum length: 17 characters All instances must conform to this regular expression (test examples + [here](<https://regexr.com/?expression=(%5B0-9a-fA-F%5D%7B2%7D%3A)%7B5%7D%5B0-9a-fA-F%5D%7B2%7D>)): + +```regex +([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2} +``` + +mac address in string format + +### Output Example + +```json +{ + "ieee1905_macaddr": "af:AE:D7:de:6C:cF", + "neighbors": ["da:ec:4c:CB:BE:74", "FB:Fc:13:df:3C:24", "c6:6C:3b:4b:cE:2c", "46:Ec:0F:72:DD:62"] +} +``` + +## refresh + +### Remake the topology tree + +`refresh` + +- type: `Method` + +### refresh Type + +`object` with following properties: + +| Property | Type | Required | +| -------- | ---- | -------- | +| `output` | | Optional | + +#### output + +`output` + +- is optional +- type: complex + +##### output Type + +Unknown type ``. + +```json +{ + "definitions": { + "mac_t": { + "description": "mac address in string format", + "type": "string", + "minLength": 17, + "maxLength": 17, + "pattern": "([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}" + }, + "boolean_t": { + "type": "string", + "pattern": "(0|1)" + }, + "event_type_t": { + "type": "string", + "description": "events of node addition or deletion", + "pattern": "Add|Delete" + }, + "interface_type_t": { + "description": "Linux network interface type", + "type": "string", + "pattern": "^IEEE 802\\.(3u|3ab|11b|11g|11a|11n 2.4|11n 5.0|11ac|11ad|11af)" + }, + "ipv4_t": { + "description": "IPv4 Address", + "type": "string", + "pattern": "([0-255]\\.){3}[0-255]" + }, + "status_t": { + "type": "string", + "pattern": "Incomplete|Available" + }, + "event_t": { + "type": "string", + "pattern": "add|del" + }, + "timestamp_t": { + "description": "Time the node was changed", + "type": "integer", + "minimum": 0, + "maximum": 65535 + } + }, + "out": "{\"definitions\":{\"mac_t\":{\"description\":\"mac address in string format\",\"type\":\"string\",\"minLength\":17,\"maxLength\":17,\"pattern\":\"([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}\"},\"boolean_t\":{\"type\":\"string\",\"pattern\":\"(0|1)\"},\"event_type_t\":{\"type\":\"string\",\"description\":\"events of node addition or deletion\",\"pattern\":\"Add|Delete\"},\"interface_type_t\":{\"description\":\"Linux network interface type\",\"type\":\"string\",\"pattern\":\"^IEEE 802\\\\.(3u|3ab|11b|11g|11a|11n 2.4|11n 5.0|11ac|11ad|11af)\"},\"ipv4_t\":{\"description\":\"IPv4 Address\",\"type\":\"string\",\"pattern\":\"([0-255]\\\\.){3}[0-255]\"},\"status_t\":{\"type\":\"string\",\"pattern\":\"Incomplete|Available\"},\"event_t\":{\"type\":\"string\",\"pattern\":\"add|del\"},\"timestamp_t\":{\"description\":\"Time the node was changed\",\"type\":\"integer\",\"minimum\":0,\"maximum\":65535}}}", + "simpletype": "complex" +} +``` + +### Output Example + +```json +{ + "definitions": { + "mac_t": { + "description": "mac address in string format", + "type": "string", + "minLength": 17, + "maxLength": 17, + "pattern": "([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}" + }, + "boolean_t": { "type": "string", "pattern": "(0|1)" }, + "event_type_t": { + "type": "string", + "description": "events of node addition or deletion", + "pattern": "Add|Delete" + }, + "interface_type_t": { + "description": "Linux network interface type", + "type": "string", + "pattern": "^IEEE 802\\.(3u|3ab|11b|11g|11a|11n 2.4|11n 5.0|11ac|11ad|11af)" + }, + "ipv4_t": { "description": "IPv4 Address", "type": "string", "pattern": "([0-255]\\.){3}[0-255]" }, + "status_t": { "type": "string", "pattern": "Incomplete|Available" }, + "event_t": { "type": "string", "pattern": "add|del" }, + "timestamp_t": { "description": "Time the node was changed", "type": "integer", "minimum": 0, "maximum": 65535 } + } +} +``` + +## status + +### Indicates the transient phase of the discovery of the network topology + +`status` + +- type: `Method` + +### status Type + +`object` with following properties: + +| Property | Type | Required | +| -------- | ------ | -------- | +| `output` | object | Optional | + +#### output + +`output` + +- is optional +- type: `object` + +##### output Type + +`object` with following properties: + +| Property | Type | Required | +| -------- | ------ | -------- | +| `status` | string | Optional | + +#### status + +`status` + +- is optional +- type: reference + +##### status Type + +`string` + +All instances must conform to this regular expression (test examples +[here](https://regexr.com/?expression=Incomplete%7CAvailable)): + +```regex +Incomplete|Available +``` + +### Output Example + +```json +{ "status": "Incomplete" } +``` diff --git a/docs/api/uci.topology.md b/docs/api/uci.topology.md new file mode 100644 index 0000000000000000000000000000000000000000..396c17bfe3583ff03cb3f5d52f8b7bbb7c9ce20a --- /dev/null +++ b/docs/api/uci.topology.md @@ -0,0 +1 @@ +<tbody><tr><td colspan="2"><div style="font-weight: bold">topology</div><table style="width:100%"><tbody><tr><td><div style="font-weight: bold; font-size: 14px">section</div></td><td><div style="font-weight: bold; font-size: 14px">description</div></td><td><div style="font-weight: bold; font-size: 14px">multi</div></td><td><div style="font-weight: bold; font-size: 14px">options</div></td></tr><tr><td class="td_row_even"><div class="td_row_even">topology</div></td><td class="td_row_even"><div class="td_row_even">ieee1905 topology Stack</div></td><td class="td_row_even"><div class="td_row_even">false</div></td><td class="td_row_even"><table style="width:100%"><tbody><tr><td><div style="font-weight: bold; font-size: 14px">name</div></td><td><div style="font-weight: bold; font-size: 14px">type</div></td><td><div style="font-weight: bold; font-size: 14px">required</div></td><td><div style="font-weight: bold; font-size: 14px">default</div></td><td><div style="font-weight: bold; font-size: 14px">description</div></td></tr><tr><td class="td_row_even"><div class="td_row_even">enabled</div></td><td class="td_row_even"><div class="td_row_even">boolean</div></td><td class="td_row_even"><div class="td_row_even">yes</div></td><td class="td_row_even"><div class="td_row_even">true</div></td><td class="td_row_even"><div class="td_row_even">Enable topology daemon</div></td></tr><tr><td class="td_row_odd"><div class="td_row_odd">depth</div></td><td class="td_row_odd"><div class="td_row_odd">integer</div></td><td class="td_row_odd"><div class="td_row_odd">yes</div></td><td class="td_row_odd"><div class="td_row_odd">16</div></td><td class="td_row_odd"><div class="td_row_odd">Hash node depth</div></td></tr><tr><td class="td_row_even"><div class="td_row_even">interval</div></td><td class="td_row_even"><div class="td_row_even">integer</div></td><td class="td_row_even"><div class="td_row_even">yes</div></td><td class="td_row_even"><div class="td_row_even">120</div></td><td class="td_row_even"><div class="td_row_even">Topology refresh interval in seconds</div></td></tr><tr><td class="td_row_odd"><div class="td_row_odd">maxlog</div></td><td class="td_row_odd"><div class="td_row_odd">integer</div></td><td class="td_row_odd"><div class="td_row_odd">yes</div></td><td class="td_row_odd"><div class="td_row_odd">32</div></td><td class="td_row_odd"><div class="td_row_odd">The maximum number of logs in the changelog</div></td></tr></tbody></table></td></tr></tbody></table></td></tr></tbody> \ No newline at end of file diff --git a/gitlab-ci/functional-api-test.sh b/gitlab-ci/functional-api-test.sh new file mode 100755 index 0000000000000000000000000000000000000000..6c51b99c40721ddb356954b944d3e1e23f4bff53 --- /dev/null +++ b/gitlab-ci/functional-api-test.sh @@ -0,0 +1,40 @@ +#!/bin/bash + +echo "$0 preparation script" +pwd + +export LIB_DIR=${PWD}/lib + +cd ${PWD}/src +echo "Cleaning ..." +make clean + +echo "Running tests now pwd ${LIB_DIR}" +make +ret=$? + +# installing dependent library +cp topologyd /usr/sbin/ + +supervisorctl status all +supervisorctl update +supervisorctl restart all +sleep 3 +supervisorctl restart topologyd +sleep 1 +supervisorctl status all + +cd /builds/iopsys/map-topology +# run API validation +ubus-api-validator -d ./test/api/json/ > ./api-result.log +ret=$? + +supervisorctl stop all +supervisorctl status + +cp ./memory-report.xml ./api-test-memory-report.xml +tap-junit --input ./api-result.log --output report +date +%s > timestamp.log + +echo "$0 exit status ${ret}" +exit ${ret} diff --git a/gitlab-ci/functional-test.sh b/gitlab-ci/functional-test.sh new file mode 100755 index 0000000000000000000000000000000000000000..54ecbf8b55281c17e09d96911e8112ec98aa804f --- /dev/null +++ b/gitlab-ci/functional-test.sh @@ -0,0 +1,38 @@ +i#!/bin/bash + +echo "$0 preparation script" +pwd + +export LIB_DIR=${PWD}/lib + +cd ${PWD}/src +echo "Cleaning ..." +make clean + +echo "Running tests now pwd ${LIB_DIR}" +make +ret=$? + +# installing dependent library +cp topologyd /usr/sbin/ + +supervisorctl status all +supervisorctl update +supervisorctl restart all +sleep 3 +supervisorctl restart topologyd +sleep 1 +supervisorctl status all +cd /builds/iopsys/map-topology/ +./gitlab-ci/replay_packets.sh +./gitlab-ci/verify.sh +ret=$? + +supervisorctl stop all +supervisorctl status + +cp memory-report.xml functional-test-memory-report.xml +date +%s > timestamp.log + +echo "$0 exit status ${ret}" +exit ${ret} diff --git a/gitlab-ci/install-dependencies.sh b/gitlab-ci/install-dependencies.sh new file mode 100755 index 0000000000000000000000000000000000000000..c1ba5b4fbf58f349ea96118476983c16cc024eb3 --- /dev/null +++ b/gitlab-ci/install-dependencies.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +echo "install dependencies" + +pwd + +function exec_cmd() +{ + echo "executing $@" + $@ >/dev/null 2>&1 + + if [ $? -ne 0 ]; then + echo "Failed to execute $@" + exit 1 + fi +} + +mkdir -p /opt/dev/ +# install packages +exec_cmd apt update + +# install ieee1905 +cd /opt/dev +export CFLAGS="${CFLAGS} -g -Wall -g -O0" +rm -fr ieee1905 +exec_cmd git clone -b devel https://dev.iopsys.eu/iopsys/ieee1905.git +cd ieee1905 +exec_cmd ./gitlab-ci/install-dependencies.sh +#exec_cmd sed -i \'s/cp \./#cp \./g\' ./gitlab-ci/setup.sh +exec_cmd ./gitlab-ci/setup.sh +exec_cmd make "CONFIG_IEEE1905_ALME_OVER_UBUS=y" +exec_cmd make install +ls +mkdir -p /usr/include/ieee1905 +exec_cmd cp -a include/plugin.h /usr/include/ieee1905 +exec_cmd cp -a libieee1905/include/1905_cmdus.h /usr/include/ieee1905 +exec_cmd cp -a libieee1905/include/1905_tlvs.h /usr/include/ieee1905 +exec_cmd cp -a ieee1905d /usr/sbin/ + +cd /builds/iopsys/map-topology +exec_cmd ./gitlab-ci/setup.sh diff --git a/gitlab-ci/iopsys-supervisord.conf b/gitlab-ci/iopsys-supervisord.conf new file mode 100644 index 0000000000000000000000000000000000000000..cbf1d1eede44c1815c99b8eb508a15095918403e --- /dev/null +++ b/gitlab-ci/iopsys-supervisord.conf @@ -0,0 +1,12 @@ +[program:ubusd] +command=/bin/bash -c "/usr/sbin/ubusd" + +[program:rpcd] +command=/bin/bash -c "/usr/sbin/rpcd" + +[program:ieee1905d] +command=/bin/bash -c "/usr/sbin/ieee1905d" + +[program:topologyd] +command=/bin/bash -c "/usr/bin/valgrind --xml=yes --xml-file=memory-report.xml --leak-check=full --show-reachable=yes --show-leak-kinds=all --errors-for-leak-kinds=all --error-exitcode=1 --track-origins=yes /builds/iopsys/map-topology/src/topologyd" + diff --git a/gitlab-ci/replay_packets.sh b/gitlab-ci/replay_packets.sh new file mode 100755 index 0000000000000000000000000000000000000000..64c9c6b2f5a26a43da4a7603ff3a5fb41dc1b786 --- /dev/null +++ b/gitlab-ci/replay_packets.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +pwd +PCAP_PATH="./test/pcap/" + +function replay() +{ + echo "Replaying ${1}.pcap" + tcpreplay -q --intf1=eth0 ${PCAP_PATH}/${1}.pcap >/dev/null +} + +replay topology_discover +replay autoconfig_search +replay topology_query +replay topology_discover +replay topology_query +replay topology_response +replay topology_discover +replay higher_layer_query +replay link_metric_query +replay higher_layer_response +replay link_metric_response + diff --git a/gitlab-ci/setup.sh b/gitlab-ci/setup.sh new file mode 100755 index 0000000000000000000000000000000000000000..637255620b8f1427fb920929279723106e4eb1db --- /dev/null +++ b/gitlab-ci/setup.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +echo "preparation script" + +cp -rf ./test/files/etc/* /etc/ +cp -r ./test/files/lib/* /lib/ +cp -r ./test/files/tmp/* /tmp/ +cp -r ./test/files/usr/* /usr/ +cp -r ./schemas/ubus/* /usr/share/rpcd/schemas +cp ./gitlab-ci/iopsys-supervisord.conf /etc/supervisor/conf.d/ + +ls /etc/supervisor/conf.d/ + diff --git a/gitlab-ci/verify.sh b/gitlab-ci/verify.sh new file mode 100755 index 0000000000000000000000000000000000000000..e725e57413c33d06e401e39af9bd86b1f49606c9 --- /dev/null +++ b/gitlab-ci/verify.sh @@ -0,0 +1,68 @@ +#!/bin/bash +OUT_PATH=./test/output + +# output metrics used for validation in this file is aligned with pcap(s) +# used to simulate neighbor + +function verify_file() +{ + diff -q ${OUT_PATH}/${1} ${2} >/dev/null 2>&1 + + if [ "$?" -eq 0 ]; then + echo "PASS" + else + echo "Output differs" + cat ${2} + exit 1 + fi +} + +function verify_output() +{ + grep -wq "${1}" /tmp/t.log + if [ "$?" -eq 0 ]; then + echo "PASS" + else + echo "Output differs" + cat /tmp/t.log + exit 1 + fi +} + +function verify_node() +{ + echo "Verify the added node " + ubus call topology nodes >/tmp/t.log + + verify_output "00:22:07:6f:70:e2" +} + +function verify_changelog() +{ + echo "Verify the changelog information" + ubus call topology changelog >/tmp/t.log + + verify_output "00:22:07:6f:70:e2" +} + +function verify_dump() +{ + echo "Verify the topology dump" + ubus call topology dump >/tmp/t.log + + verify_output "00:22:07:6f:70:e2" +} + +function verify_status() +{ + echo "Verify the topology status" + ubus call topology status >/tmp/t.log + + verify_output "\"status\":\ \"available\"" +} + +## Call tests here +verify_node +verify_changelog +verify_dump +verify_status diff --git a/schemas/ubus/topology.json b/schemas/ubus/topology.json new file mode 100644 index 0000000000000000000000000000000000000000..e80b7350b941eff7e0b25477b8e0c530bc35c107 --- /dev/null +++ b/schemas/ubus/topology.json @@ -0,0 +1,401 @@ +{ + "definitions": { + "mac_t": { + "description": "mac address in string format", + "type": "string", + "minLength": 17, + "maxLength": 17, + "pattern": "([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}" + }, + "boolean_t": { + "type": "string", + "pattern": "(0|1)" + }, + "event_type_t": { + "type": "string", + "description" : "events of node addition or deletion", + "pattern": "Add|Delete" + }, + "interface_type_t": { + "description": "Linux network interface type", + "type": "string", + "pattern": "^IEEE 802\\.(3u|3ab|11b|11g|11a|11n 2.4|11n 5.0|11ac|11ad|11af)" + }, + "ipv4_t": { + "description": "IPv4 Address", + "type": "string", + "pattern": "([0-255]\\.){3}[0-255]" + }, + "status_t": { + "type": "string", + "pattern": "Incomplete|Available" + }, + "event_t": { + "type": "string", + "pattern": "add|del" + }, + "timestamp_t": { + "description": "Time the node was changed", + "type": "integer", + "minimum": 0, + "maximum": 65535 + } + }, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://www.iopsys.eu/usp.raw.json", + "type": "object", + "title": "topology", + "object": "topology", + "additionalProperties": false, + "regex": true, + "properties": { + "dump": { + "title": "Topology info of AL nodes and there parameters", + "description": "", + "type": "object", + "properties": { + "output": { + "type": "object", + "properties": { + "self": { + "type": "object", + "properties": { + "ieee1905_macaddr": { + "$ref": "#/definitions/mac_t" + }, + "num_neighbors": { + "type": "integer", + "minimum": 0 + }, + "neighbors": { + "type": "array", + "items": { + "type": "object", + "properties": { + "nbr_mac_id": { + "$ref": "#/definitions/mac_t" + } + } + } + }, + "num_non1905_neighbors": { + "type": "integer", + "minimum": 0 + }, + "non1905_neighbors": { + "type": "array", + "items": { + "$ref": "#/definitions/mac_t" + } + } + } + }, + "nodes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "ieee1905_macaddr": { + "$ref": "#/definitions/mac_t" + }, + "num_neighbors": { + "type": "integer", + "minimum": 0 + }, + "neighbors": { + "type": "array", + "items": { + "type": "object", + "properties": { + "nbr_mac_id": { + "$ref": "#/definitions/mac_t" + }, + "link_metrics": { + "type": "array", + "items": { + "type": "object", + "properties": { + "nbr_intf_macid": { + "$ref": "#/definitions/mac_t" + }, + "ieee_bridge": { + "type": "boolean" + }, + "tx_packet_error": { + "type": "integer", + "minimum": 0 + }, + "tx_packet_ok": { + "type": "integer", + "minimum": 0 + }, + "mac_thrput_capacity": { + "type": "integer", + "minimum": 0 + }, + "link_availability": { + "type": "integer", + "minimum": 0, + "maximum": 100 + }, + "phy_rate": { + "type": "integer", + "minimum": 0 + }, + "rx_packet_error": { + "type": "integer", + "minimum": 0 + }, + "rx_packet_ok": { + "type": "integer", + "minimum": 0 + }, + "rssi": { + "type": "integer", + "minimum": 0 + } + } + } + } + } + } + }, + "num_non1905_neighbors": { + "type": "integer", + "minimum": 0 + }, + "non1905_neighbors": { + "type": "array", + "items": { + "$ref": "#/definitions/mac_t" + } + }, + "registrar_freq_band": { + "$ref": "#/definitions/mac_t" + }, + "non1905_nbr_localintf": { + "$ref": "#/definitions/mac_t" + }, + "1905_nbr_localintf": { + "$ref": "#/definitions/mac_t" + }, + "local_interface_nbr": { + "type": "integer", + "minimum": 0 + }, + "l2_neighbor_num": { + "type": "integer", + "minimum": 0 + }, + "bridging_tuple_num": { + "type": "integer", + "minimum": 0 + }, + "version": { + "type": "string", + "pattern": "(1905\\.1a|1905)" + }, + "friendly_name": { + "type": "string" + }, + "manufacturer_name": { + "type": "string" + }, + "manufacturer_model": { + "type": "string" + }, + "control_url": { + "type": "string", + "pattern": "^http:\\/([0-255]\\.){3}[0-255]" + }, + "ipv4_itfr_num": { + "type": "integer", + "minimum": 0 + }, + "ipv6_itfr_num": { + "type": "integer", + "minimum": 0 + }, + "interfaces": { + "type": "array", + "items": { + "type": "object", + "properties": { + "interface_id": { + "$ref": "#/definitions/mac_t" + }, + "media_type": { + "$ref": "#/definitions/interface_type_t" + }, + "network_membership": { + "$ref": "#/definitions/mac_t" + }, + "role": { + "type": "string" + }, + "ap_channel_band": { + "type": "integer", + "minimum": 0 + }, + "freq_index1": { + "type": "integer", + "minimum": 0 + }, + "freq_index2": { + "type": "integer", + "minimum": 0 + } + } + } + }, + "l2_neighbor": { + "type": "array", + "items": { + "type": "object", + "properties": { + "local_intf_id": { + "$ref": "#/definitions/mac_t" + }, + "local_nbr_id": { + "$ref": "#/definitions/mac_t" + } + } + } + }, + "bridge_tuple": { + "type": "array", + "items": { + "type": "object", + "properties": { + "br_mac": { + "type": "array", + "items": { + "$ref": "#/definitions/mac_t" + } + } + } + } + }, + "ipv4_params": { + "type": "array", + "items": { + "type": "object", + "properties": { + "mac_address": { + "$ref": "#/definitions/mac_t" + }, + "ipv4_addr_type": { + "type": "string" + }, + "ipv4_address": { + "$ref": "#/definitions/ipv4_t" + }, + "dhcp_addr": { + "$ref": "#/definitions/ipv4_t" + } + } + } + } + } + } + } + } + } + } + }, + "status": { + "title": "Indicates the transient phase of the discovery of the network topology", + "description": "", + "type": "object", + "properties": { + "output": { + "type": "object", + "properties": { + "status": { + "$ref": "#/definitions/status_t" + } + } + } + } + }, + "changelog": { + "title": "This object represents log entries for changes in the 1905 Network Topology.", + "description": "", + "type": "object", + "required": [ + "output" + ], + "properties": { + "output": { + "type": "object", + "properties": { + "num_changelog": { + "type": "integer", + "minimum": 1, + "maximum": 255 + }, + "changelog": { + "type": "array", + "items": { + "type": "object", + "properties": { + "reporter": { + "$ref": "#/definitions/mac_t" + }, + "reporter_interface": { + "$ref": "#/definitions/mac_t" + }, + "neighbor": { + "$ref": "#/definitions/mac_t" + }, + "is1905_neighbor": { + "type": "boolean" + }, + "event_type": { + "$ref": "#/definitions/event_t" + }, + "timestamp": { + "$ref": "#/definitions/timestamp_t" + } + } + } + } + } + } + } + }, + "nodes": { + "title": "Give the mac id of self and the neighbor nodes", + "description": "", + "type": "object", + "required": [ + "output" + ], + "properties": { + "output": { + "type": "object", + "properties": { + "ieee1905_macaddr": { + "$ref": "#/definitions/mac_t" + }, + "neighbors": { + "type": "array", + "items": { + "$ref": "#/definitions/mac_t" + } + } + } + } + } + }, + "refresh": { + "title": "Remake the topology tree", + "description": "", + "type": "object", + "properties": { + "output": { + } + } + } + } +} diff --git a/schemas/uci/topology.json b/schemas/uci/topology.json new file mode 100644 index 0000000000000000000000000000000000000000..66345c68ed1c305b70177dedf4b8753fa7ae7ce6 --- /dev/null +++ b/schemas/uci/topology.json @@ -0,0 +1,39 @@ +{ + "topology": [ + { + "section": "topology", + "description": "ieee1905 topology Stack", + "multi": false, + "options": [ + { + "name": "enabled", + "type": "boolean", + "required": "yes", + "default": "true", + "description": "Enable topology daemon" + }, + { + "name": "depth", + "type": "integer", + "required": "yes", + "default": "8", + "description": "Hash node depth" + }, + { + "name": "interval", + "type": "integer", + "required": "yes", + "default": "60", + "description": "Topology refresh interval in seconds" + }, + { + "name": "maxlog", + "type": "integer", + "required": "yes", + "default": "32", + "description": "The maximum number of logs in the changelog" + } + ] + } + ] +} diff --git a/test/api/json/topology.validation.json b/test/api/json/topology.validation.json new file mode 100644 index 0000000000000000000000000000000000000000..4fd968f55808e67244ebcb005a6c84741948626c --- /dev/null +++ b/test/api/json/topology.validation.json @@ -0,0 +1,26 @@ +{ + "object": "topology", + "methods": [ + { + "method": "nodes", + "rc": 0 + }, + { + "method": "dump", + "rc": 0 + }, + { + "method": "status", + "rc": 0 + }, + { + "method": "changelog", + "rc": 0 + }, + { + "method": "hello", + "rc": 3 + } + ] +} + diff --git a/test/files/etc/config/ieee1905 b/test/files/etc/config/ieee1905 new file mode 100644 index 0000000000000000000000000000000000000000..94b5ab94111dd8d01d91cc005167dba8f7acf2dc --- /dev/null +++ b/test/files/etc/config/ieee1905 @@ -0,0 +1,17 @@ +config ieee1905 'ieee1905' + option enabled '1' + option debug true + option debug_level 3 + option macaddress '02:42:ac:11:00:02' + option registrar 0 + option cmdu_event 1 + option map_plugin 0 + +config security 'security' + list method 'PBC' + +config al-iface + option enabled 1 + option ifname 'eth0' + option media 'eth' + diff --git a/test/files/etc/config/topology b/test/files/etc/config/topology new file mode 100644 index 0000000000000000000000000000000000000000..1a10aa5db05cdf9a441ece9a0c953e97a98708f5 --- /dev/null +++ b/test/files/etc/config/topology @@ -0,0 +1,6 @@ + +config topology 'topology' + option enabled '1' + option depth '8' + option interval '60' + option maxlog '32' diff --git a/test/files/lib/db/config/device b/test/files/lib/db/config/device new file mode 100644 index 0000000000000000000000000000000000000000..4f217072b33803c1c7686bc450072c4853788a08 --- /dev/null +++ b/test/files/lib/db/config/device @@ -0,0 +1,12 @@ +config deviceinfo 'deviceinfo' + option Manufacturer 'iopsys' + option ProductClass 'FirstClass' + option SerialNumber '000000001' + option SoftwareVersion 'IOPSYS-CODE-ANALYSIS' + option HardwareVersion '1.0' + option DeviceCategory 'Gateway' + option ModelName 'ModelName' + option Description 'Iopsys code analysis test simulator' + option ManufacturerOUI 'XXX' + option BaseMACAddress 'feeddeadbeef' + option FriendlyName 'docker1905' diff --git a/test/files/tmp/network.status b/test/files/tmp/network.status new file mode 100644 index 0000000000000000000000000000000000000000..9583767d31483391ca83fcfb26b75b72a7004068 --- /dev/null +++ b/test/files/tmp/network.status @@ -0,0 +1,65 @@ +{ + "eth0": { + "external": false, + "present": true, + "type": "Network device", + "up": true, + "carrier": false, + "link-advertising": [ + "100baseT-F", + "1000baseT-F" + ], + "link-partner-advertising": [ + + ], + "link-supported": [ + "100baseT-F", + "1000baseT-F" + ], + "speed": "0H", + "autoneg": true, + "mtu": 1998, + "mtu6": 1500, + "macaddr": "02:42:ac:11:00:02", + "txqueuelen": 1000, + "ipv6": true, + "promisc": false, + "rpfilter": 0, + "acceptlocal": false, + "igmpversion": 0, + "mldversion": 0, + "neigh4reachabletime": 30000, + "neigh6reachabletime": 30000, + "neigh4gcstaletime": 60, + "neigh6gcstaletime": 60, + "neigh4locktime": 100, + "dadtransmits": 1, + "multicast": true, + "sendredirects": true, + "statistics": { + "collisions": 0, + "rx_frame_errors": 0, + "tx_compressed": 0, + "multicast": 0, + "rx_length_errors": 0, + "tx_dropped": 0, + "rx_bytes": 0, + "rx_missed_errors": 0, + "tx_errors": 0, + "rx_compressed": 0, + "rx_over_errors": 0, + "tx_fifo_errors": 0, + "rx_crc_errors": 0, + "rx_packets": 0, + "tx_heartbeat_errors": 0, + "rx_dropped": 0, + "tx_aborted_errors": 0, + "tx_packets": 0, + "rx_errors": 0, + "tx_bytes": 0, + "tx_window_errors": 0, + "rx_fifo_errors": 0, + "tx_carrier_errors": 0 + } + } +} diff --git a/test/files/usr/libexec/rpcd/network.device b/test/files/usr/libexec/rpcd/network.device new file mode 100755 index 0000000000000000000000000000000000000000..4bee55526fd059952c42081edf9ed303acc837d3 --- /dev/null +++ b/test/files/usr/libexec/rpcd/network.device @@ -0,0 +1,17 @@ +#!/bin/sh + +. /usr/share/libubox/jshn.sh + +case "$1" in + list) + echo '{ "status" : {} }' + ;; + call) + case "$2" in + status) + cat /tmp/network.status 2>/dev/null + ;; + esac + ;; +esac + diff --git a/test/output/changelog.data b/test/output/changelog.data new file mode 100644 index 0000000000000000000000000000000000000000..da498f2d9425a82401c32ed792a24ba4c7634055 --- /dev/null +++ b/test/output/changelog.data @@ -0,0 +1,13 @@ +{ + "num_changelog": 1, + "changelog": [ + { + "reporter": "00:22:07:6f:70:e2", + "reporter_interface": "00:22:07:6f:70:e2", + "neighbor": "00:22:07:6f:70:e2", + "is1905_neighbor": "IEEE1905", + "event_type": "add", + "timestamp": "2020-09-23T08:50:53" + } + ] +} diff --git a/test/output/dump.data b/test/output/dump.data new file mode 100644 index 0000000000000000000000000000000000000000..203ef68b7b6f675a2988a10ece9e92ca4eae06c1 --- /dev/null +++ b/test/output/dump.data @@ -0,0 +1,105 @@ +{ + "self": { + "ieee1905_macaddr": "02:42:ac:11:00:02", + "num_neighbors": 0, + "neighbors": [ + + ], + "num_non1905_neighbors": 1, + "non1905_neighbors": [ + "02:42:a7:0a:70:fe" + ] + }, + "nodes": [ + { + "ieee1905_macaddr": "00:22:07:6f:70:e2", + "num_neighbors": 1, + "neighbors": [ + { + "nbr_mac_id": "02:42:ac:11:00:02", + "link_metrics": [ + { + "nbr_intf_macid": "00:22:07:76:5c:54", + "ieee_bridge": 0, + "tx_packet_error": 0, + "tx_packet_ok": 69, + "mac_thrput_capacity": 0, + "link_availability": 100, + "phy_rate": 0, + "rx_packet_error": 0, + "rx_packet_ok": 207, + "rssi": 0 + } + ] + } + ], + "num_non1905_neighbors": 0, + "non1905_neighbors": [ + + ], + "registrar_freq_band": "", + "1905_nbr_localintf": "00:22:07:6f:70:e2", + "local_interface_nbr": 3, + "interfaces": [ + { + "interface_id": "00:22:07:6f:70:e3", + "media_type": "IEEE 802.11ac", + "network_membership": "00:00:00:00:00:00", + "role": "AP", + "ap_channel_band": 2, + "freq_index1": 52, + "freq_index2": 0 + }, + { + "interface_id": "00:22:07:6f:70:e4", + "media_type": "IEEE 802.11n 2.4", + "network_membership": "00:00:00:00:00:00", + "role": "AP", + "ap_channel_band": 0, + "freq_index1": 1, + "freq_index2": 0 + }, + { + "interface_id": "00:22:07:6f:70:e2", + "media_type": "IEEE 802.3ab" + } + ], + "l2_neighbor_num": 1, + "l2_neighbor": [ + { + "local_intf_id": "00:22:07:6f:70:e2", + "local_nbr_id": "00:22:07:76:5c:54", + "behind_mac_id": "" + } + ], + "bridging_tuple_num": 1, + "bridge_tuple": [ + { + "br_mac": [ + "00:22:07:6f:70:e3", + "00:22:07:6f:70:e4", + "00:22:07:6f:70:e2" + ] + } + ], + "version": "1905.1a", + "friendly_name": "iopsysWrt", + "manufacturer_name": "IOPSYS", + "manufacturer_model": "EG400R0", + "control_url": "http:\/\/192.168.1.1", + "ipv4_itfr_num": 1, + "ipv4_params": [ + { + "mac_address": "00:22:07:6f:70:e2", + "ipv4_addr_type": "IPV4_DHCP", + "ipv4_address": "192.168.1.2", + "dhcp_addr": "127.1.1.1" + } + ], + "ipv6_itfr_num": 0, + "ipv6_params": [ + + ] + } + ] +} diff --git a/test/output/nodes.data b/test/output/nodes.data new file mode 100644 index 0000000000000000000000000000000000000000..818e4a2802a8d59906784a86dda0f9e1c68c8ab4 --- /dev/null +++ b/test/output/nodes.data @@ -0,0 +1,6 @@ +{ + "ieee1905_macaddr": "02:42:ac:11:00:02", + "neighbors": [ + "00:22:07:6f:70:e2" + ] +} diff --git a/test/pcap/autoconfig_search.pcap b/test/pcap/autoconfig_search.pcap new file mode 100644 index 0000000000000000000000000000000000000000..75860be32bf78444ad310d5a07bade10e85c0cb5 Binary files /dev/null and b/test/pcap/autoconfig_search.pcap differ diff --git a/test/pcap/higher_layer_query.pcap b/test/pcap/higher_layer_query.pcap new file mode 100644 index 0000000000000000000000000000000000000000..c0a7c8d4294824ba83f221861d87313f7e037ad5 Binary files /dev/null and b/test/pcap/higher_layer_query.pcap differ diff --git a/test/pcap/higher_layer_response.pcap b/test/pcap/higher_layer_response.pcap new file mode 100644 index 0000000000000000000000000000000000000000..66984f46eff45569ba3bb363e2e26cff446527f9 Binary files /dev/null and b/test/pcap/higher_layer_response.pcap differ diff --git a/test/pcap/link_metric_query.pcap b/test/pcap/link_metric_query.pcap new file mode 100644 index 0000000000000000000000000000000000000000..1d7a8172409c4192ea2e3891b5f16a0a4723c6d5 Binary files /dev/null and b/test/pcap/link_metric_query.pcap differ diff --git a/test/pcap/link_metric_response.pcap b/test/pcap/link_metric_response.pcap new file mode 100644 index 0000000000000000000000000000000000000000..293eaad8dbdfb4ec7307243011f482dcf0f913e0 Binary files /dev/null and b/test/pcap/link_metric_response.pcap differ diff --git a/test/pcap/topology_discover.pcap b/test/pcap/topology_discover.pcap new file mode 100644 index 0000000000000000000000000000000000000000..11c0aee2d19bb090e9b22968467bc752cd6ba502 Binary files /dev/null and b/test/pcap/topology_discover.pcap differ diff --git a/test/pcap/topology_query.pcap b/test/pcap/topology_query.pcap new file mode 100644 index 0000000000000000000000000000000000000000..b12274161b472b68b627dacd62dfa121fac51f33 Binary files /dev/null and b/test/pcap/topology_query.pcap differ diff --git a/test/pcap/topology_response.pcap b/test/pcap/topology_response.pcap new file mode 100644 index 0000000000000000000000000000000000000000..ed00e206c0d0ecdc7a2dbe95e9bf5e744cba00ea Binary files /dev/null and b/test/pcap/topology_response.pcap differ