diff --git a/tests/tests-api.py b/tests/tests-api.py index 517eecf..3a04114 100755 --- a/tests/tests-api.py +++ b/tests/tests-api.py @@ -11,7 +11,6 @@ import oftest.message as message import oftest.action as action import re - # ------ Start: Mandatory portion on each test case file ------ #@var basic_port_map Local copy of the configuration map from OF port @@ -73,9 +72,7 @@ def runTest(self): self.assertTrue(success, "%s: Not success" %(self.__class__.__name__)) self.logger.info("Ping: Received: %s" % data) self.assertTrue(data.has_key(exp_data_fv), "%s: Received unexpected message" %(self.__class__.__name__)) - self.assertTrue(data.has_key(exp_data_db), "%s: Received unexpected message" %(self.__class__.__name__)) - - + self.assertTrue(data.has_key(exp_data_db), "%s: Received unexpected message" %(self.__class__.__name__)) class ListFlowSpace(Ping): """ @@ -138,6 +135,11 @@ def runTest(self): (success, data) = testutils.setRule(self, self.sv, rule) self.assertTrue(success, "%s: Not success" %(self.__class__.__name__)) + #Attempt to remove a dummy flowspace. Should return FlowEntryNotFound Exception. + rule = ["remove-flowspace", "DummyFlowName"] + (success, data) = testutils.setRule(self, self.sv,rule) + self.assertFalse(success, "%s: Was success but should not be" %(self.__class__.__name__)) + class CreateSlice(Ping): """ @@ -171,7 +173,7 @@ def runTest(self): # Try to create a slice with a same name and different configuration. # Should be failed slice_random_email = "ctl2@bar.com" - rule = ["add-lice", slice_name, slice_pswd, slice_port, slice_random_email, {}] + rule = ["add-slice", slice_name, slice_pswd, slice_port, slice_random_email, {}] (success, data) = testutils.setRule(self, self.sv, rule) self.assertFalse(success, "%s: Shouldn't be created" %(self.__class__.__name__)) @@ -186,7 +188,6 @@ def runTest(self): self.assertTrue(success, "%s: The slice should be created" %(self.__class__.__name__)) - class DeleteSlice(Ping): """ Delete_slice @@ -198,6 +199,11 @@ def runTest(self): rule = ["remove-slice", testutils.EXIST_SLICE0_IN_CONF_FILE] (success, data) = testutils.setRule(self, self.sv, rule) self.assertTrue(success, "%s: DeleteSlice: Not success" %(self.__class__.__name__)) + + #Attempt to delete a dummy slice name. Should return InvalidSliceName Exception + rule = ["remove-slice", "DummySliceName"] + (success, data) = testutils.setRule(self, self.sv, rule) + self.assertFalse(success, "%s: DeleteSlice: Success but should not be" %(self.__class__.__name__)) remaining_fs = testutils.NUM_FLOWSPACE_IN_CONF_FILE-testutils.NUM_FLOWSPACE_EXIST_SLICE0 # Check number of flow space @@ -274,3 +280,94 @@ def runTest(self): self.logger.debug("GetSliceInfo: Raw received: " + str(data)) self.assertEqual(data['admin-contact'], new_email, "%s: Received unexpected contact_email" %(self.__class__.__name__)) self.assertTrue(re.search(str(new_port), data['controller-url']), "%s: Received unexpected controller_port" %(self.__class__.__name__)) + +class addFlowSpace(Ping): + def runTest(self): + #Add flowspace + flowspace_name = "dummyFlowName" + flowspace_dpid = "1" + flowspace_priority = 100 + flowspace_match = {"in_port" : 1, "dl_src" : "00:00:00:00:00:02"} + flowspace_slice = [{"slice-name" : "controller0", "permission" : 7}] + + rule = ["add-flowspace" , flowspace_name, flowspace_dpid, flowspace_priority, flowspace_match, flowspace_slice, {}] + (success, data) = testutils.setRule(self, self.sv, rule) + self.assertTrue(success, "%s: AddFlowSpace: Not success" %(self.__class__.__name__)) + self.logger.info("Raw received " + str(data)) + + #Attempt to add corrupt flowspace. Should return MissingRequiredField Exception. + rule = ["add-flowspace", flowspace_name, flowspace_dpid, flowspace_priority, flowspace_match, {}] + (success, data) = testutils.setRule(self, self.sv, rule) + self.assertFalse(success, "%s: AddFlowSpace: Was success, but shouldn't be" %(self.__class__.__name__)) + self.logger.info("Raw received " + str(data)) + + #Attempt to add corrupt flowspace. Should return SliceNotFound Exception. + flowspace_slice = [{"slice-name" : "FAKESLICE", "permission" : 7}] + rule = ["add-flowspace", flowspace_name, flowspace_dpid, flowspace_priority, flowspace_match, flowspace_slice, {}] + (success, data) = testutils.setRule(self, self.sv, rule) + self.assertFalse(success, "%s: AddFlowSpace: Was success, but shouldn't be" %(self.__class__.__name__)) + self.logger.info("Raw received: " + str(data)) + + #Check if flowspace added. + rule = ["list-flowspace", {}] + (success, data) = testutils.setRule(self, self.sv, rule) + self.assertTrue(success, "%s: Not success" %(self.__class__.__name__)) + num_flow = len(data) + self.logger.info("ListFlowSpace: Expected: %s" %(testutils.NUM_FLOWSPACE_IN_CONF_FILE + 1)) + self.logger.info("ListFlowSpace: Received: %s" % num_flow) + self.logger.debug("ListFlowSpace: Raw received: %s" % data) + self.assertEqual(num_flow, testutils.NUM_FLOWSPACE_IN_CONF_FILE + 1, "%s: Received wrong number of flow space" %(self.__class__.__name__)) + + #Send packet across flowspace. + pkt = testutils.simplePacket(dl_src="00:00:00:00:00:02") + in_port = 1 + msg = testutils.genPacketIn(in_port=in_port, pkt=pkt) + + snd_list = ["switch", 0, msg] + exp_list = [["controller", 0, msg]] + res = testutils.ofmsgSndCmp(self, snd_list, exp_list, xid_ignore=True) + self.assertTrue(res, "%s: Received unexpected message" %(self.__class__.__name__)) + +class listFVHealth(Ping): + def runTest(self): + rule = ["list-fv-health"] + (success, data) = testutils.setRule(self, self.sv, rule) + self.assertTrue(success, "%s: Not success." %(self.__class__.__name__)) + +class listDatapathStats(Ping): + def runTest(self): + rule = ["list-datapath-stats", testutils.SRC_MAC_FOR_CTL1_0] + (success, data) = testutils.setRule(self, self.sv, rule) + self.assertTrue(success, "%s: Not success." %(self.__class__.__name__)) + + #Test whether any packets dropped from this dpid. Should be {} or no packets dropped. + self.assertEqual(data['drop']['Total'], {}, "%s: Dropped some packets" %(self.__class__.__name__)) + self.logger.debug("Received: " + str(data)) + + #Attempt to list stats for random DPID. Should return DPIDNotFound Exception. + randomDPID = "12:34:56:78:90" + rule = ["list-datapath-stats", randomDPID] + (success, data) = testutils.setRule(self, self.sv, rule) + self.assertFalse(success, "%s: Was success but should not be" %(self.__class__.__name__)) + +class listSliceStats(Ping): + def runTest(self): + rule = ["list-slice-stats", testutils.EXIST_SLICE0_IN_CONF_FILE] + (success, data) = testutils.setRule(self, self.sv, rule) + self.assertTrue(success, "%s: Not success." %(self.__class__.__name__)) + +class listSliceHealth(Ping): + def runTest(self): + rule = ["list-slice-health", testutils.EXIST_SLICE0_IN_CONF_FILE] + (success, data) = testutils.setRule(self, self.sv, rule) + self.assertTrue(success, "%s: Not success." %(self.__class__.__name__)) + self.assertEqual(data['is-connected'], True, "%s: Slice not connected" %(self.__class__.__name__)) + self.logger.debug("Received: " + str(data)) + +class updateSlicePasswd(Ping): + def runTest(self): + new_passwd = "hello123" + slice_user = "controller0" + rule = ["update-slice-password", slice_user, new_passwd] + (success, data) = testutils.setRule(self, self.sv, rule) + self.assertTrue(success, "%s: UpdateSlicePasswd: Not success" %(self.__class__.__name__)) diff --git a/tests/tests-config.py b/tests/tests-config.py new file mode 100644 index 0000000..95f18e2 --- /dev/null +++ b/tests/tests-config.py @@ -0,0 +1,129 @@ +""" +Tests for the configuration commands using fvconfig. +""" +import sys +import logging +import templatetest +import testutils +import oftest.cstruct as ofp +import oftest.message as message +import oftest.parse as parse +import oftest.action as action +import oftest.error as error +import socket +import time +import json +import subprocess +import threading +from pprint import pprint + + +# ------ Start: Mandatory portion on each test case file ------ + +#@var basic_port_map Local copy of the configuration map from OF port +# numbers to OS interfaces +basic_port_map = None +#@var basic_logger Local logger object +basic_logger = None +#@var basic_timeout Local copy of global timeout value +basic_timeout = None +#@var basic_config Local copy of global configuration data +basic_config = None + +test_prio = {} + +def test_set_init(config): + """ + Set up function for basic test classes + @param config The configuration dictionary; see fvt + """ + global basic_port_map + global basic_fv_cmd + global basic_logger + global basic_timeout + global basic_config + + basic_fv_cmd = config["fv_cmd"] + basic_logger = logging.getLogger("actions") + basic_logger.info("Initializing test set") + basic_timeout = config["timeout"] + basic_port_map = config["port_map"] + basic_config = config + +# ------ End: Mandatory portion on each test case file ------ + +#Command class for calling the command.run which takes in a timeout period. +#After the timeout period(usually reached when exceptions thrown), +#the thread is stopped so that the test can continue on +class Command(object): + def __init__(self, cmd): + self.cmd = cmd + self.process = None + + def run(self, timeout): + def target(): + self.process = subprocess.Popen(self.cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True) + (out, err) = self.process.communicate() + basic_logger.debug("Received output: " + out) + + #Start thread with target as the command to be run. + thread = threading.Thread(target=target) + thread.start() + + #Wait for however long timeout is. + thread.join(timeout) + if (thread.is_alive()): + basic_logger.debug("Terminating thread.") + self.process.terminate() + thread._Thread__stop() + #Takes too long, so return success value = False + return False + #Command finished successfully, so success value = True + else: + return True + +class generateConfig(templatetest.TemplateTest): + def setUp(self): + templatetest.TemplateTest.setUp(self) + self.logger = basic_logger + return + + def runTest(self): + cmd = " generate " + config_file = "newconfig.json" + host_name = " host" + host_passwd = " openflow" + of_port = " 16633" + api_port = " 6633" + output = "" + params = host_name +host_passwd + of_port + api_port + + #Generating newconfig.json + self.logger.info("Running fvconfig" + cmd + config_file + params) + command = Command("fvconfig" + cmd + config_file + params) + success = command.run(timeout=10) + self.assertTrue(success, "%s: Generate timeout" %(self.__class__.__name__)) + + with open('newconfig.json') as data_file: + data = json.load(data_file) + self.logger.debug("Data received: " + str(data)) + + #Loading newconfig.json + cmd = " load " + self.logger.info("Running fvconfig" + cmd + config_file) + command = Command("fvconfig" + cmd + config_file) + success = command.run(timeout=10) + self.assertTrue(success, "%s: Load timeout" %(self.__class__.__name__)) + + #Loading DUMMYCONFIG.json. Should return error. + config_file = "DUMMYCONFIG.json" + self.logger.info("Running fvconfig" + cmd + config_file) + command = Command("fvconfig" + cmd + config_file) + success = command.run(timeout=10) + self.assertFalse(success, "%s: Load error not caught." %(self.__class__.__name__)) + + #Delete newconfig.json generated from this test. + config_file = "newconfig.json" + command = Command("rm -f " + config_file) + success = command.run(timeout=10) + self.assertTrue(success, "%s: rm Timeout." %(self.__class__.__name__)) diff --git a/tests/tests-config.pyc b/tests/tests-config.pyc new file mode 100644 index 0000000..e5cce10 Binary files /dev/null and b/tests/tests-config.pyc differ