- 1.0.1, update README
- 1.0.0, first release
give your feedback by following ways
-
visit https://github.com/dvdface/vstc (preferred)
-
send email to [email protected]
pip install vstc
1.x version, only support call locally. AKA, you can share a physical STC port between many test runers in the same PC.
It will support RPC in 2.x version so that you can share a physical STC port between many PCs.
VSTC means Virtual Spirent TestCenter.
It takes Spirent TestCenter and Switch as a Virutal Spirent TestCenter.
In general, you connect chassis, reserve port, create device under port, then create raw/bound streamblock, start traffic.
With VSTC, it takes a STC port and Vlan ID as a virtual STC port so that the
traffics generated by a same STC port can be redirect to target port by switch with VLAN ID.
Aka, one STC port can be used as multiple virutal ports by this way. so, you can save your money to buy Spirent TestCenter
Of course, you can use VSTC library without vid, so VSTC is just a ordinary STC.
The relationship between classes is Just like Spirent TestCenter GUI.
Chassis class provides ability to reserve port, create multicast groups.
Port class provides ability to create devices, streamblocks.
MCGroup represents Multicast Group, you can add IGMP type device into it.
StreamBlock represents streamblock under Port.
Device represents Device under Port.
Under the hook, VSTC uses stc:: / sth:: api provided by Spirent TestCenter.
VSTC uses STCObject to wrap object handle in stc::/sth::, so you can access / set object's attributes by PortObject['attribute'] syntax.
In STCObject, it provides properties by which you can access attributes more easily.
Name Stmts Miss Cover
----------------------------------------
vstc\__init__.py 9 0 100%
vstc\testcenter.py 821 116 86%
vstc\util.py 70 6 91%
----------------------------------------
TOTAL 900 122 86%
-
Chassis class
# connect testcenter with ip 10.182.32.138 , without reserving any port # creating chassis class will auto connect chassis chassis = Chassis('10.182.32.138') # disconnect chassis chassis.disconnect() # apply changes ( it will apply automatically) chassis.apply() # connect testcenter and reserve port chassis = Chassis('10.182.32.138', [{ 'location' : '//10.182.32.138/1/1', 'vid': None}, { 'location' : '//10.182.32.138/1/2', 'vid': None}]) # connect testcenter, reserve port and specify a default vlan with specified vid # when you create a device under the port, it will insert a vlan layer with vid 100 for you # when you create a streamblock, it will insert a vlan layer with vid 100 for you too chassis = Chassis('10.182.32.138', [{ 'location' : '//10.182.32.138/1/1', 'vid': 100}]) # save xml file chassis.save('test_configuration.xml') # get chassis serial number chassis.serial # get chassis ip chassis.ip
-
Port class
# access reserved ports # access all reserved ports # it wil return List[Port] chassis.ports # access the first reserved ports port = chassis.ports[0] # start capture port.start_capture() # stop capture port.stop_capture() # save capture port.save_capture('demo.pcap') # change DataPathMode # normal: send / receive data to other port port.mode = PortMode.normal # loopback: send data to self port.mode = PortMode.local_loopback # get port location # //10.182.32.138/1/1 port.location # get port vid port.vid # get port ownership state # OwnershipState.RESERVED、AVAILABLE、DISCONNECTED port.ownership # get port owner host port.owner_host == socket.gethostname() # get port onwer user port.owner_user
-
MCGroup class
# access multicast groups under chassis # it will return List[MCGroup] chassis.mcgroups # create a multicast group under chassis with name 'ipv4group', and group ip '224.0.0.1' mcgroup = chassis.create_mcgroup('ipv4group', ip='224.0.0.1') # remove mcgroup from chassis chassis.remove_mcgroup(mcgroup) # get / set group name mcgroup.name mcgroup.name = 'demo name' # get / set group ip mcgroup.ip mcgroup.ip = '225.0.0.1' # add IGMP device into MCGroup # 1.get a reserved port under chassis port = chassis.ports[0] # 2. create igmp device under port igmpDevice = port.create_device(DeviceType.igmp) # 3. add igmp device into a mcgroup mcgroup.add(igmpDevice) # 4. remove igmp device from mcgroup mcgroup.remove(igmpDevice) # get devices in the mcgroup # it will return List[IGMPDevice] mcgroup.devices
-
Device class
# create traffic only device dev = port.create_device(DeviceType.host) # set device mac, ip, mask, gateway, gateway mac dev.mac = '00:10:94:00:01:01' dev.ip = '192.168.1.1' dev.mask = 24 dev.gateway = '192.168.1.254' dev.gwmac = '00:10:94:00:11:11' # get stats for device dev.stats # create dhcp devices dhcpv4server = port.create_device(DeviceType.dhcpv4_server, ip_address='192.168.10.1', ipaddress_pool='192.168.10.2') dhcpv4client = port.create_device(DeviceType.dhcpv4_client) # create igmp devices igmp = port.create_device(DeviceType.igmp) # create pppox devices pppoxserver = port.create_device(DeviceType.pppox_server) pppoxclient = port.create_device(DeviceType.pppox_client) # set pppox auth mode, username, password and so on pppoxserver.auth = PPPoXAuthMode.auto pppoxserver.username = 'test' pppoxserver.password = 'testpassword'
-
Streamblock class
# raw streamblock streamblock = port.create_streamblock(StreamType.raw) # bound streamblock client = port.create_device(DeviceType.dhcpv4_client) server = port.create_device(DeviceType.dhcpv4_server, ip_address='192.168.1.254', ipaddress_pool='192.168.1.1') streamblock = port.create_streamblock(StreamType.bound, src_handle=client.handle, dst_handle=server.handle) # start / stop streamblock streamblock.start() wait_for_true(lambda : streamblock.state == StreamState.running) streamblock.stop() # get / set streamblock speed streamblock.speed streamblock.speed = '10mbps' streamblock.speed = '10pps' streamblock.speed = '10%' # get / set frame length streamblock.length_mode streamblock.min_length streamblock.max_length streamblock.length_step streamblock.length_mode = LengthMode.incr streamblock.min_length = 100 streamblock.max_length = 1500 streamblock.length_step = 64 # get / set fill type and fill constant streamblock.fill_type streamblock.fill_const streamblock.fill_type = FillType.constant streamblock.fill_const = 0x1234
class NewDevice(Device):
def _create_device(self, **kwargs) -> STCObject:
# create device here by using stc:: or sth:: api
dev_ret = SpirentAPI.instance.sth_emulation_device_config(mode='create', port_handle=self.port.handle, **kwargs)
# wrap device object hanlde with STCObject
return STCObject(dev_ret.handle)