Skip to content

Commit

Permalink
remove builders, add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ajbalogh committed Nov 11, 2024
1 parent 475e2e7 commit 59ab581
Show file tree
Hide file tree
Showing 10 changed files with 146 additions and 240 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ build: ## compile all .proto files and generate artifacts
--python_out=$(GENERATED_DIR) \
--pyi_out=$(GENERATED_DIR) \
--grpc_python_out=$(GENERATED_DIR) \
et_def.proto infra.proto bind.proto
et_def.proto infra.proto bind.proto service.proto
python3 -m pip uninstall -y keysight-chakra
python3 setup.py bdist_wheel
python3 -m pip install --no-cache .
Expand Down
16 changes: 1 addition & 15 deletions protos/bind.proto
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ syntax = "proto3";
package bind;

import "google/protobuf/any.proto";
import "infra.proto";

message Data {
// Use this field to provide descriptive information about the message
Expand Down Expand Up @@ -53,7 +52,7 @@ message Binding {
oneof infrastructure_path {
// the binding is global to the infrastructure and the value provided here
// is for informational purposes only
string global = 1;
string infrastructure = 1;

// binding is specific to an Infrastructure.inventory.device.name
// example: dgx
Expand Down Expand Up @@ -102,16 +101,3 @@ message Bindings {
// A list of user defined information for specific endpoints
repeated Binding bindings = 1;
}

message ValidationRequest {
infra.Infrastructure infrastructure = 1;
repeated Binding bindings = 2;
}

message ValidationResponse {
repeated Binding invalid_bindings = 1;
}

service BindService {
rpc Validate(ValidationRequest) returns (ValidationResponse);
}
50 changes: 16 additions & 34 deletions protos/infra.proto
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,10 @@ message Switch {
// Component describes a number of components that share a specific type
message Component {
// the name of the component
string name = 1;
optional string name = 1;

// the number of this type of component
uint32 count = 2;
optional uint32 count = 2;

// the type of component
oneof type {
Expand Down Expand Up @@ -115,7 +115,7 @@ message Bandwidth {
// Link describes a link between Components
message Link {
// name of the link
string name = 1;
optional string name = 1;

// type of link
LinkType type = 2;
Expand All @@ -128,21 +128,18 @@ message Link {
// between those components
message Device {
// the name of the device
string name = 1;
optional string name = 1;

// collection of unique components in the device
repeated Component components = 3;
map<string, Component> components = 3;

// collection of unique links in the device
repeated Link links = 4;
map<string, Link> links = 4;

// a list of connections that describe how Components are connected to each
// other in a single Device
//
// format: The following pieces of information each separated by a "."
// An * indicates all possible indexes for a component will be mapped
// In the case where an * is used for both indexes then the mapping will be
// a one-to-one mapping.
//
// - name = Component.name
// - index < Component.count
Expand All @@ -153,6 +150,7 @@ message Device {
// examples:
// nic.0.pcie.cpu.0
// npu.0.pcie.nvswitch.0
// asic.0.mii.nic.0
//
repeated string connections = 5;
}
Expand All @@ -162,15 +160,15 @@ message DeviceInstances {
// it should be used to categorize the devices
// for example it can be Dgx1Host, ZionexHost, RackSwitch, PodSwitch,
// SpineSwitch etc.
string name = 1;
optional string name = 1;

// the name of an actual device that exists in the
// Infrastructure.inventory.devices field
// this allows for a Device to be reused.
string device = 2;
optional string device = 2;

// the number of instances of the device in the infrastructure under this name
uint32 count = 3;
optional uint32 count = 3;
}

// The Inventory message is a collection of unique devices and links present
Expand All @@ -179,15 +177,15 @@ message DeviceInstances {
// DeviceInstance, DeviceLink, ConnectionLink messages
message Inventory {
// A collection of all unique types of devices in the infrastructure
// Uniquess is determined by the Device.name field.
// This list is not an instance list, for eg, you define one DGX1 or ZionEx
// device and use the DeviceInstances message to scale up the number of those
// devices.
// Uniqueness is determined by the Device.name field.
// This list is not an instance list instead use the DeviceInstances message
// to create an instance of a Device and to scale it to the count present
// in your infrastructure.
map<string, Device> devices = 1;

// A collection of all unique types of links in the infrastructure.
// These links can be reused multiple times when creating ComponentConnection
// and DeviceConnection messages.
// These links can be reused multiple times when creating connections
// between devices.
map<string, Link> links = 2;
}

Expand All @@ -207,9 +205,6 @@ message Infrastructure {
repeated DeviceInstances device_instances = 2;

// format: The following pieces of information each separated by a "."
// An * indicates all possible indexes for a component will be mapped
// In the case where an * is used for both indexes then the mapping will be
// a one-to-one mapping.
//
// - name = DeviceInstance.name
// - index < DeviceInstance.count
Expand All @@ -223,19 +218,6 @@ message Infrastructure {
//
// examples:
// host.0.nic.0.100gpbs.racksw.0.nic.0
// host.0.nic.0-8.100gpbs.racksw.0.nic.8-15
//
repeated string connections = 3;
}

message ValidationRequest {
infra.Infrastructure infrastructure = 1;
}

message ValidationResponse {
repeated string invalid_connections = 1;
}

service InfraService {
rpc Validate(ValidationRequest) returns (ValidationResponse);
}
33 changes: 33 additions & 0 deletions protos/service.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// service.proto
//
// Service and rpcs for infrastructure and bindings

syntax = "proto3";

package service;

import "infra.proto";
import "bind.proto";

message ValidationRequest {
infra.Infrastructure infrastructure = 1;
bind.Bindings bindingas = 2;
}

message ValidationError {
oneof type {
string optional = 1;
string oneof = 2;
string map = 3;
string repeated = 4;
string connection = 5;
}
}

message ValidationResponse {
repeated ValidationError errors = 1;
}

service Service {
rpc Validate(ValidationRequest) returns (ValidationResponse);
}
25 changes: 0 additions & 25 deletions src/infra_service.py

This file was deleted.

50 changes: 50 additions & 0 deletions src/service.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
if __package__ is None or __package__ == "":
from generated.service_pb2 import ValidationRequest, ValidationError, ValidationResponse
else:
from .generated.service_pb2 import ValidationRequest, ValidationError, ValidationResponse


class Service:
@staticmethod
def Validate(request: ValidationRequest):
"""Validate every connection in the Infrastructure.
Every Device in Infrastructure.inventory.devices has connections which
must have a valid number of pieces separated by a ".".
Every connection in Infrastructure.connections must be composed of
a valid number of pieces separated by a "." and the pieces must exist
in the Infrastructure.inventory.devices and Infrastructure.inventory.links.
The format of a Device connection is the following:
"component_name.component_index.link_name.component_name.component_index"
"""
errors = []
for device_key, device in request.infrastructure.inventory.devices.items():
if device.HasField("name") is False:
errors.append(ValidationError(optional=f"Device name field has not been set"))
if device_key != device.name:
errors.append(
ValidationError(
map=f"Device key '{device_key}' does not match Device.name '{device.name}'"
)
)
for link_key, link in device.links.items():
if link_key != link.name:
errors.append(
ValidationError(
map=f"Device '{device.name}' link key '{link_key}' does not match Link.name '{link.name}'"
)
)
if link.bandwidth.WhichOneof("type") is None:
errors.append(ValidationError(oneof="Device.links.bandwidth type must be set"))
for connection in device.connections:
try:
src, src_idx, link, dst, dst_idx = connection.split(".")
except ValueError:
errors.append(
ValidationError(
connection=f"Component connection in device '{device.name}' is incorrectly formatted"
)
)
return ValidationResponse(errors=errors)
10 changes: 9 additions & 1 deletion src/tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@
import pytest
import os
import sys

sys.path.extend(
[
os.path.join(os.path.dirname(__file__), ".."),
os.path.join(os.path.dirname(__file__), "../generated"),
]
)
83 changes: 0 additions & 83 deletions src/tests/test_device.py

This file was deleted.

Loading

0 comments on commit 59ab581

Please sign in to comment.