Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[report]
omit =
*__init__*
8 changes: 4 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@ python:
- "2.7"

install:
- 'if [ ${TRAVIS_BRANCH} = "master" ]; then
pip install --extra-index-url https://testpypi.python.org/pypi -r src/requirements.txt;
else
- 'if [ ${TRAVIS_BRANCH} \!= "master" ] && [ -f dev_requirements.txt ]; then
pip install --extra-index-url https://testpypi.python.org/pypi -r dev_requirements.txt;
else
pip install -r src/requirements.txt;
fi'
- pip install -r test_requirements.txt
- pip install coveralls

script:
- nosetests --with-coverage --cover-package=src --where=tests
- nosetests --with-coverage --cover-package=src tests

after_success:
- coveralls
76 changes: 44 additions & 32 deletions datamodel/datamodel.xml
Original file line number Diff line number Diff line change
@@ -1,48 +1,60 @@
<?xml version="1.0" encoding="utf-8"?>
<DataModelInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.qualisystems.com/ResourceManagement/DataModelSchema.xsd">
<DataModelInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://schemas.qualisystems.com/ResourceManagement/DataModelSchema.xsd">

<Attributes>
<AttributeInfo Name="Client Install Path" Type="String" DefaultValue="" IsReadOnly="false"
Description="The path in which the traffic client is installed on the Execution Server. For example 'C:/Program Files (x86)/Ixia/IxOS/6.90-EA'.">
<Rules>
<Rule Name="Configuration" />
</Rules>
</AttributeInfo>
<AttributeInfo Name="Controller Address" Type="String" DefaultValue="" IsReadOnly="false"
Description="The IP address of the traffic server. Relevant only in case an external server is configured.">
<Rules>
<Rule Name="Configuration" />
</Rules>
</AttributeInfo>
<AttributeInfo Name="Controller TCP Port" Type="String" DefaultValue="" IsReadOnly="false"
Description="The TCP port of the traffic server. Relevant only in case an external server is configured. Default TCP port should be used if kept empty.">
<Rules>
<Rule Name="Configuration" />
</Rules>
</AttributeInfo>
<Attributes>
<AttributeInfo Name="Client Install Path" Type="String" DefaultValue="" IsReadOnly="false"
Description="The path in which the traffic client is installed on the Execution Server. For example 'C:/Program Files (x86)/Ixia/IxOS/6.90-EA'.">
<Rules>
<Rule Name="Configuration"/>
</Rules>
</AttributeInfo>
<AttributeInfo Name="Controller Address" Type="String" DefaultValue="" IsReadOnly="false"
Description="The IP address of the traffic server. Relevant only in case an external server is configured.">
<Rules>
<Rule Name="Configuration"/>
</Rules>
</AttributeInfo>
<AttributeInfo Name="Controller TCP Port" Type="String" DefaultValue="" IsReadOnly="false"
Description="The TCP port of the traffic server. Relevant only in case an external server is configured. Default TCP port should be used if kept empty.">
<Rules>
<Rule Name="Configuration"/>
</Rules>
</AttributeInfo>
<AttributeInfo Name="Password" Type="Password" DefaultValue="" IsReadOnly="false"
Description="">
Description="">
<Rules>
<Rule Name="Configuration"/>
</Rules>
</AttributeInfo>
<AttributeInfo Name="User" Type="String" DefaultValue="" IsReadOnly="false"
Description="">
Description="">
<Rules>
<Rule Name="Configuration"/>
</Rules>
</AttributeInfo>
<AttributeInfo Name="Test Files Location" Type="String" DefaultValue="" IsReadOnly="false"
Description="Location for test related files">
<Rules>
<Rule Name="Configuration"/>
</Rules>
</AttributeInfo>
</Attributes>
</Attributes>

<ResourceFamilies>
<ResourceFamily Description="" IsService="true" Name="Traffic Generator Controller" ServiceType="Regular">
<Models />
<Categories />
</ResourceFamily>
</ResourceFamilies>
<ResourceFamilies>
<ResourceFamily Description="" IsService="true" Name="Traffic Generator Controller" ServiceType="Regular">
<AttachedAttributes>
<AttachedAttribute Name="Test Files Location" IsOverridable="true" IsLocal="true" UserInput="true">
<AllowedValues/>
</AttachedAttribute>
</AttachedAttributes>
<Models/>
<Categories/>
</ResourceFamily>
</ResourceFamilies>

<DriverDescriptors>
<DriverDescriptor Name="BreakingPointControllerDriver" DriverType="PythonDriver" />
</DriverDescriptors>
<DriverDescriptors>
<DriverDescriptor Name="BreakingPointControllerDriver" DriverType="PythonDriver"/>
</DriverDescriptors>

</DataModelInfo>
4 changes: 2 additions & 2 deletions src/bp_controller/actions/test_configuration_actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ def import_pcap(self, pcap_file_path):
def export_test(self, test_name):
self._logger.debug('Exporting test {0}'.format(test_name))
uri = '/api/v1/bps/export/bpt/testname/' + test_name
data = self._rest_service.request_get(uri)
result = data
data = self._rest_service.request_get_files(uri)
result = data.content
return result

def reserve_port(self, slot, port_list):
Expand Down
10 changes: 10 additions & 0 deletions src/bp_controller/flows/bp_download_test_file_flow.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from bp_controller.actions.test_configuration_actions import TestConfigurationActions
from cloudshell.tg.breaking_point.flows.bp_flow import BPFlow


class BPDownloadTestFileFlow(BPFlow):
def download_test_file(self, test_name):
with self._session_context_manager as rest_service:
configuration_actions = TestConfigurationActions(rest_service, self._logger)
test_file_content = configuration_actions.export_test(test_name)
return test_file_content
45 changes: 45 additions & 0 deletions src/bp_controller/runners/bp_test_runner.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import csv
import json
import os

from bp_controller.flows.bp_download_test_file_flow import BPDownloadTestFileFlow
from bp_controller.helpers.port_reservation_helper import PortReservationHelper
import re

Expand Down Expand Up @@ -34,6 +37,7 @@ def __init__(self, context, logger, api):
self.__test_statistics_flow = None
self.__test_results_flow = None
self.__test_configuration_file_flow = None
self.__download_test_file_flow = None
self.__reservation_details = None
self.__port_reservation_helper = None

Expand Down Expand Up @@ -104,6 +108,13 @@ def _test_configuration_file_flow(self):
self.logger)
return self.__test_configuration_file_flow

@property
def _download_test_file_flow(self):
if not self.__download_test_file_flow:
self.__download_test_file_flow = BPDownloadTestFileFlow(self._session_context_manager,
self.logger)
return self.__download_test_file_flow

@property
def _cs_reservation_details(self):
"""
Expand Down Expand Up @@ -151,12 +162,29 @@ def _port_reservation_helper(self):
self.logger)
return self.__port_reservation_helper

def _get_existing_path(self, file_path):
"""
Looking for existing path
:return:
:rtype: basestring
"""
search_order = [os.path.join(self.context.resource.attributes.get('Test Files Location') or '', file_path),
file_path]
for path in search_order:
if os.path.exists(path):
return path
raise BPRunnerException(self.__class__.__name__,
'File {} does not exists or "Test Files Location" attribute was not specified'.format(
file_path))

def load_configuration(self, file_path):
"""
Upload configuration file and reserve ports
:param file_path:
:return:
"""
file_path = self._get_existing_path(file_path)

self._test_name = self._test_configuration_file_flow.load_configuration(file_path)
test_model = ElementTree.parse(file_path).getroot().find('testmodel')
network_name = test_model.get('network')
Expand Down Expand Up @@ -247,6 +275,23 @@ def get_results(self):
file_stream=pdf_result)
return "Please check attachments for results"

def get_test_file(self, test_name):
test_files_location = self.context.resource.attributes.get('Test Files Location')
if not test_files_location:
raise BPRunnerException(self.__class__.__name__, "Test Files Location attribute is not defined")
if not os.path.exists(test_files_location) or os.access(test_files_location, os.W_OK) is not True:
raise BPRunnerException(self.__class__.__name__,
'The location of the test files "{}" does not exist or is not writable'.format(
test_files_location))
reservation_files = os.path.join(test_files_location, self.context.reservation.reservation_id)
if not os.path.exists(reservation_files):
os.makedirs(reservation_files)
test_file_path = os.path.join(reservation_files, test_name + '.bpt', )
test_file_content = self._download_test_file_flow.download_test_file(test_name)
with open(test_file_path, 'w') as f:
f.write(test_file_content)
return test_file_path

def close(self):
"""
Destroy
Expand Down
10 changes: 10 additions & 0 deletions src/driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,16 @@ def get_results(self, context):
with self._runners_pool.actual_runner(context) as runner:
return runner.get_results()

def get_test_file(self, context, test_name):
"""
Download test file configuration and put to the folder defined in Test Files Location attribute
:param context:
:param test_name: Name of the test
:return:
"""
with self._runners_pool.actual_runner(context) as runner:
return runner.get_test_file(test_name)

def cleanup(self):
"""
Close runners
Expand Down
7 changes: 7 additions & 0 deletions src/drivermetadata.xml
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,12 @@
DisplayName="Output Type" DefaultValue="csv" Description="CSV or JSON"/>
</Parameters>
</Command>
<Command Name="get_test_file" DisplayName="Get Test File" Description="Download test file to the folder specified in the Test Files Location attribute">
<Parameters>
<Parameter Name="test_name" Type="String" Mandatory="True"
DisplayName="Test Name"
Description="Name of the Test"/>
</Parameters>
</Command>
</Layout>
</Driver>
25 changes: 23 additions & 2 deletions tests/bp_controller/runners/test_bp_test_runner.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import re

from mock import Mock, patch, PropertyMock
from mock import Mock, patch, PropertyMock, call
from unittest2 import TestCase

from bp_controller.runners.bp_test_runner import BPTestRunner
Expand Down Expand Up @@ -171,6 +171,8 @@ def test_port_reservation_helper(self, port_reservation_helper_class, logger_pro
@patch('bp_controller.runners.bp_test_runner.BPTestRunner._port_reservation_helper', new_callable=PropertyMock)
@patch('bp_controller.runners.bp_test_runner.ElementTree')
def test_load_configuration(self, element_tree_class, port_reservation_helper_prop, configuration_file_flow_prop):
file_path = Mock()
self._instance._get_existing_path = Mock(return_value=file_path)
port_reservation_helper = Mock()
configuration_file_flow = Mock()
port_reservation_helper_prop.return_value = port_reservation_helper
Expand All @@ -188,7 +190,6 @@ def test_load_configuration(self, element_tree_class, port_reservation_helper_pr
interface = Mock()
test_model.findall.return_value = [interface]
interface.get.return_value = '3'
file_path = Mock()
self._instance.load_configuration(file_path)
configuration_file_flow.load_configuration.assert_called_once_with(file_path)
self.assertIs(self._instance._test_name, test_name)
Expand Down Expand Up @@ -389,3 +390,23 @@ def test_get_results_flow(self, create_quali_api_instance, test_results_flow_pro
def test_close(self, port_reservation_helper_prop):
self._context.reservation.reservation_id = 'test'
port_reservation_helper_prop.unreserve_ports.assewrt_called_once_with()

@patch('bp_controller.runners.bp_test_runner.os')
def test_get_existing_path(self, os_instance):
path1 = Mock()
path2 = Mock()
os_instance.path.join.return_value = path2
os_instance.path.exists.side_effect = [False, True]
self.assertIs(self._instance._get_existing_path(path1), path1)
os_instance.path.join.assert_called_once_with(self._context.resource.attributes.get('Test Files Location'),
path1)
os_instance.path.exists.assert_has_calls([call(path2), call(path1)])

@patch('bp_controller.runners.bp_test_runner.os')
def test_get_existing_path_exception(self, os_instance):
path1 = Mock()
path2 = Mock()
os_instance.path.join.return_value = path2
os_instance.path.exists.side_effect = [False, False]
with self.assertRaisesRegex(BPRunnerException, 'does not exists'):
self._instance._get_existing_path(path1)
8 changes: 8 additions & 0 deletions tests/test_driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,14 @@ def test_get_results(self):
self._runners_pool.actual_runner.assert_called_once_with(self._context)
self._runner.get_results.assert_called_once_with()

def test_get_test_file(self):
result = Mock()
self._runner.get_test_file.return_value = result
test_name = Mock()
self.assertIs(self._instance.get_test_file(self._context, test_name), result)
self._runners_pool.actual_runner.assert_called_once_with(self._context)
self._runner.get_test_file.assert_called_once_with(test_name)

def test_cleanup(self):
self._instance.cleanup()
self._runners_pool.close_all_runners.assert_called_once_with()
Expand Down