コード例 #1
0
class Abstract(share.AbstractTest):
    endpoint_alpha = model.NetworkEndpoint(share.make_datapath_id(1), 4)
    endpoint_beta = model.NetworkEndpoint(share.make_datapath_id(2), 6)
    endpoint_gamma = model.NetworkEndpoint(share.make_datapath_id(3), 8)

    isl_alpha_beta = model.InterSwitchLink(
        model.IslPathNode(endpoint_alpha.dpid, endpoint_alpha.port),
        model.IslPathNode(endpoint_beta.dpid, endpoint_beta.port))
    isl_beta_alpha = isl_alpha_beta.reversed()

    def setUp(self):
        super(Abstract, self).setUp()

        for isl in (self.isl_alpha_beta, self.isl_beta_alpha):
            isl_info = share.isl_info_payload(isl)
            command = share.command(isl_info)
            self.assertTrue(messageclasses.MessageItem(command).handle())

    def take_response(self, **kwargs):
        return self.take_kafka_response(config.KAFKA_NORTHBOUND_TOPIC,
                                        **kwargs)

    def _ensure_props_match(self, link_props, props):
        with self.open_neo4j_session() as tx:
            persistent = link_props_utils.read(tx, link_props)
            self.assertEqual(props, persistent.props)

    def _put(self, subject):
        request = share.link_props_request(subject)
        payload = share.link_props_put_payload(request)
        self.feed_service(share.command(payload))
        return payload
コード例 #2
0
ファイル: test_isl.py プロジェクト: jangwonpark74/open-kilda
    def test_multi_isl_port_down(self):
        sw_alpha = share.make_datapath_id(1)
        sw_beta = share.make_datapath_id(2)
        sw_gamma = share.make_datapath_id(3)

        isl_alpha_beta = model.InterSwitchLink(
            model.IslPathNode(sw_alpha, 2),
            model.IslPathNode(sw_beta, 2), None)
        isl_beta_alpha = isl_alpha_beta.reversed()
        isl_beta_gamma = model.InterSwitchLink(
            model.IslPathNode(sw_beta, 2),
            model.IslPathNode(sw_gamma, 3), None)
        isl_gamma_beta = isl_beta_gamma.reversed()

        for dpid in sw_alpha, sw_beta, sw_gamma:
            self.assertTrue(make_switch_add(dpid))

        self.assertTrue(share.feed_isl_discovery(isl_alpha_beta))
        self.assertTrue(share.feed_isl_discovery(isl_beta_alpha))
        self.assertTrue(share.feed_isl_discovery(isl_beta_gamma))
        self.assertTrue(share.feed_isl_discovery(isl_gamma_beta))

        self.assertTrue(make_port_down(isl_alpha_beta.dest))
        self.ensure_isl_props(
            neo4j_connect, isl_alpha_beta, ISL_STATUS_PROPS_HALF_UP)
        self.ensure_isl_props(
            neo4j_connect, isl_beta_alpha, ISL_STATUS_PROPS_DOWN)
        self.ensure_isl_props(
            neo4j_connect, isl_beta_gamma, ISL_STATUS_PROPS_DOWN)
        self.ensure_isl_props(
            neo4j_connect, isl_gamma_beta, ISL_STATUS_PROPS_HALF_UP)
コード例 #3
0
ファイル: isl_utils.py プロジェクト: phantomii/open-kilda
def switch_unplug(tx, dpid, mtime=True):
    logging.info("Deactivate all ISL to/from %s", dpid)

    involved = list(fetch_by_datapath(tx, dpid))
    _lock_affected_switches(tx, involved, dpid)

    for db_link in involved:
        source = model.IslPathNode(db_link['src_switch'], db_link['src_port'])
        dest = model.IslPathNode(db_link['dst_switch'], db_link['dst_port'])
        isl = model.InterSwitchLink(source, dest, db_link['actual'])
        logging.debug("Found ISL: %s", isl)

        set_active_field(tx, db.neo_id(db_link), 'inactive')
        update_status(tx, isl, mtime=mtime)
コード例 #4
0
    def test_port_down_without_isl(self):
        sw_alpha = share.make_datapath_id(1)
        sw_beta = share.make_datapath_id(2)
        isl_alpha_beta = model.InterSwitchLink(model.IslPathNode(sw_alpha, 2),
                                               model.IslPathNode(sw_beta, 2),
                                               None)
        isl_beta_alpha = isl_alpha_beta.reversed()

        self.assertTrue(make_switch_add(sw_alpha))
        self.assertTrue(make_port_down(isl_alpha_beta.source))

        self.assertRaises(exc.DBRecordNotFound, isl_utils.fetch, neo4j_connect,
                          isl_alpha_beta)
        self.assertRaises(exc.DBRecordNotFound, isl_utils.fetch, neo4j_connect,
                          isl_beta_alpha)
コード例 #5
0
    def isl_discovery_failed(self):
        """
        :return: Ideally, this should return true IFF discovery is deleted or deactivated.
        """
        path = self.payload['path']
        switch_id = path[0]['switch_id']
        port = int(path[0]['port_no'])

        effective_policy = config.get("isl_failover_policy", "effective_policy")
        logger.info('Isl failure: %s_%d -- apply policy %s: timestamp=%s',
                    switch_id, port, effective_policy, self.timestamp)

        is_moved = self.payload['state'] == 'MOVED'
        try:
            with graph.begin() as tx:
                updated = isl_utils.disable_by_endpoint(
                        tx, model.IslPathNode(switch_id, port), is_moved)
                updated.sort(key=lambda x: (x.source, x.dest))
                for isl in updated:
                    # we can get multiple records for one port
                    # but will use lifecycle data from first one
                    life_cycle = isl_utils.get_life_cycle_fields(tx, isl)
                    self.update_payload_lifecycle(life_cycle)
                    break

        except exc.DBRecordNotFound:
            logger.error('There is no ISL on %s_%s', switch_id, port)
コード例 #6
0
    def test_time_update_on_isl_discovery(self):
        sw_alpha = share.make_datapath_id(1)
        sw_beta = share.make_datapath_id(2)
        isl_alpha_beta = model.InterSwitchLink(model.IslPathNode(sw_alpha, 2),
                                               model.IslPathNode(sw_beta, 2),
                                               None)

        self.assertTrue(make_switch_add(sw_alpha))
        self.assertTrue(make_switch_add(sw_beta))

        update_point_a = model.TimeProperty.now(milliseconds_precission=True)

        message = share.command(share.isl_info_payload(isl_alpha_beta))
        message['timestamp'] = update_point_a.as_java_timestamp()
        self.feed_service(message)

        recovered = model.TimeProperty.new_from_java_timestamp(
            message['timestamp'])
        self.assertEquals(update_point_a.value, recovered.value)

        with neo4j_connect.begin() as tx:
            isl = isl_utils.fetch(tx, isl_alpha_beta)
            neo4j_connect.pull(isl)

            db_ctime = model.TimeProperty.new_from_db(isl['time_create'])
            self.assertEqual(update_point_a.value, db_ctime.value)

            db_mtime = model.TimeProperty.new_from_db(isl['time_modify'])
            self.assertEqual(update_point_a.value, db_mtime.value)

        # one more update
        update_point_b = model.TimeProperty.now(milliseconds_precission=True)
        self.assertNotEqual(update_point_a.value, update_point_b.value)

        message['timestamp'] = update_point_b.as_java_timestamp()
        self.feed_service(message)
        with neo4j_connect.begin() as tx:
            isl = isl_utils.fetch(tx, isl_alpha_beta)
            neo4j_connect.pull(isl)

            db_ctime = model.TimeProperty.new_from_db(isl['time_create'])
            self.assertEqual(update_point_a.value, db_ctime.value)

            db_mtime = model.TimeProperty.new_from_db(isl['time_modify'])
            self.assertEqual(update_point_b.value, db_mtime.value)
コード例 #7
0
ファイル: test_isl.py プロジェクト: jangwonpark74/open-kilda
    def test_isl_without_life_cycle_fields(self):
        sw_alpha = share.make_datapath_id(1)
        sw_beta = share.make_datapath_id(2)
        isl_alpha_beta = model.InterSwitchLink(
                model.IslPathNode(sw_alpha, 2),
                model.IslPathNode(sw_beta, 2), None)

        self.assertTrue(make_switch_add(sw_alpha))
        self.assertTrue(make_switch_add(sw_beta))

        self.assertTrue(share.feed_isl_discovery(isl_alpha_beta))

        with neo4j_connect.begin() as tx:
            neo4j_connect.pull(isl_utils.fetch(tx, isl_alpha_beta))
            isl_utils.set_props(
                    tx, isl_alpha_beta,
                    {'time_create': None, 'time_modify': None})

        self.assertTrue(share.feed_isl_discovery(isl_alpha_beta))
コード例 #8
0
class Abstract(share.AbstractTest):
    endpoint_alpha = model.NetworkEndpoint(share.make_datapath_id(1), 4)
    endpoint_beta = model.NetworkEndpoint(share.make_datapath_id(2), 6)
    endpoint_gamma = model.NetworkEndpoint(share.make_datapath_id(3), 8)

    isl_alpha_beta = model.InterSwitchLink(
        model.IslPathNode(endpoint_alpha.dpid, endpoint_alpha.port),
        model.IslPathNode(endpoint_beta.dpid, endpoint_beta.port))
    isl_beta_alpha = isl_alpha_beta.reversed()

    def setUp(self):
        super(Abstract, self).setUp()

        for isl in (self.isl_alpha_beta, self.isl_beta_alpha):
            isl_info = share.isl_info_payload(isl)
            command = share.command(isl_info)
            self.assertTrue(messageclasses.MessageItem(command).handle())

    def _put(self, subject):
        request = share.link_props_request(subject)
        payload = share.link_props_put_payload(request)
        self.feed_service(share.command(payload))
        return payload

    def _get_kafka_response(self,
                            offset=0,
                            expect_class=message_utils.MT_INFO):
        kafka_backlog = share.env.kafka_producer_stub.backlog

        self.assertTrue(offset < len(kafka_backlog))

        kafka_record = kafka_backlog[offset]
        self.assertEqual(config.KAFKA_NORTHBOUND_TOPIC, kafka_record.topic)

        message = json.loads(kafka_record.payload)
        self.assertEqual(expect_class, message['clazz'])

        return message['payload']
コード例 #9
0
    def port_down(self):
        switch_id = self.payload['switch_id']
        port_id = int(self.payload['port_no'])

        logger.info('Port %s_%d deletion request: timestamp=%s',
                    switch_id, port_id, self.timestamp)

        try:
            with graph.begin() as tx:
                for isl in isl_utils.disable_by_endpoint(
                        tx, model.IslPathNode(switch_id, port_id)):
                    # TODO(crimi): should be policy / toggle based
                    isl_utils.increase_cost(
                        tx, isl,
                        config.ISL_COST_WHEN_PORT_DOWN,
                        config.ISL_COST_WHEN_PORT_DOWN)
                    isl_utils.increase_cost(
                        tx, isl.reversed(),
                        config.ISL_COST_WHEN_PORT_DOWN,
                        config.ISL_COST_WHEN_PORT_DOWN)
        except exc.DBRecordNotFound:
            logger.info("There is no ISL on %s_%s", switch_id, port_id)
コード例 #10
0
ファイル: test_isl.py プロジェクト: jangwonpark74/open-kilda
    def test_isl_replug(self):
        sw_alpha = share.make_datapath_id(1)
        sw_beta = share.make_datapath_id(2)
        sw_gamma = share.make_datapath_id(3)
        sw_delta = share.make_datapath_id(4)

        isl_alpha_beta = model.InterSwitchLink(
                model.IslPathNode(sw_alpha, 2),
                model.IslPathNode(sw_beta, 2), None)
        isl_beta_alpha = isl_alpha_beta.reversed()
        isl_beta_gamma = model.InterSwitchLink(
                model.IslPathNode(sw_beta, 2),
                model.IslPathNode(sw_gamma, 3), None)
        isl_gamma_beta = isl_beta_gamma.reversed()
        isl_gamma_delta = model.InterSwitchLink(
                model.IslPathNode(sw_gamma, 3),
                model.IslPathNode(sw_delta, 3), None)
        isl_delta_gamma = isl_gamma_delta.reversed()

        for dpid in sw_alpha, sw_beta, sw_gamma, sw_delta:
            self.assertTrue(make_switch_add(dpid))

        self.assertTrue(share.feed_isl_discovery(isl_alpha_beta))
        self.assertTrue(share.feed_isl_discovery(isl_beta_alpha))
        self.assertTrue(share.feed_isl_discovery(isl_gamma_delta))
        self.assertTrue(share.feed_isl_discovery(isl_delta_gamma))

        self.ensure_isl_props(
                neo4j_connect, isl_alpha_beta, ISL_STATUS_PROPS_UP)
        self.ensure_isl_props(
                neo4j_connect, isl_beta_alpha, ISL_STATUS_PROPS_UP)
        self.ensure_isl_props(
                neo4j_connect, isl_gamma_delta, ISL_STATUS_PROPS_UP)
        self.ensure_isl_props(
                neo4j_connect, isl_delta_gamma, ISL_STATUS_PROPS_UP)

        self.assertRaises(
                exc.DBRecordNotFound, isl_utils.fetch,
                neo4j_connect, isl_beta_gamma)
        self.assertRaises(
                exc.DBRecordNotFound, isl_utils.fetch,
                neo4j_connect, isl_gamma_beta)

        # replug
        self.assertTrue(
                share.feed_isl_discovery(isl_beta_gamma))
        # alpha <-> beta is down
        self.ensure_isl_props(
                neo4j_connect, isl_alpha_beta, ISL_STATUS_PROPS_HALF_UP)
        self.ensure_isl_props(
                neo4j_connect, isl_beta_alpha, ISL_STATUS_PROPS_DOWN)
        # gamma -> delta is down
        self.ensure_isl_props(
                neo4j_connect, isl_gamma_delta, ISL_STATUS_PROPS_DOWN)
        self.ensure_isl_props(
                neo4j_connect, isl_delta_gamma, ISL_STATUS_PROPS_HALF_UP)
        # beta <-> gamma is half up
        self.ensure_isl_props(
                neo4j_connect, isl_beta_gamma, ISL_STATUS_PROPS_HALF_UP)
        self.ensure_isl_props(
                neo4j_connect, isl_gamma_beta, ISL_STATUS_PROPS_DOWN)

        self.assertTrue(
                share.feed_isl_discovery(isl_gamma_beta))
        # alpha <-> beta is down
        self.ensure_isl_props(
                neo4j_connect, isl_alpha_beta, ISL_STATUS_PROPS_HALF_UP)
        self.ensure_isl_props(
                neo4j_connect, isl_beta_alpha, ISL_STATUS_PROPS_DOWN)
        # gamma -> delta is down
        self.ensure_isl_props(
                neo4j_connect, isl_gamma_delta, ISL_STATUS_PROPS_DOWN)
        self.ensure_isl_props(
                neo4j_connect, isl_delta_gamma, ISL_STATUS_PROPS_HALF_UP)
        # beta <-> gamma is up
        self.ensure_isl_props(
                neo4j_connect, isl_beta_gamma, ISL_STATUS_PROPS_UP)
        self.ensure_isl_props(
                neo4j_connect, isl_gamma_beta, ISL_STATUS_PROPS_UP)
コード例 #11
0
ファイル: test_isl.py プロジェクト: jangwonpark74/open-kilda
class TestIsl(share.AbstractTest):
    src_endpoint = model.IslPathNode(share.make_datapath_id(1), 2)
    dst_endpoint = model.IslPathNode(share.make_datapath_id(2), 4)

    def test_isl_status(self):
        src_endpoint, dst_endpoint = self.src_endpoint, self.dst_endpoint
        forward = model.InterSwitchLink(src_endpoint, dst_endpoint, None)
        reverse = forward.reversed()

        make_switch_add(src_endpoint.dpid)
        make_switch_add(dst_endpoint.dpid)

        status_down = {'actual': ISL_STATUS_INACTIVE, 'status': ISL_STATUS_INACTIVE}
        status_half_up = {'actual': ISL_STATUS_ACTIVE, 'status': ISL_STATUS_INACTIVE}
        status_up = {'actual': ISL_STATUS_ACTIVE, 'status': ISL_STATUS_ACTIVE}

        # 0 0
        self.assertTrue(share.feed_isl_discovery(forward))

        # 1 0
        self.ensure_isl_props(neo4j_connect, forward, status_half_up)
        self.ensure_isl_props(neo4j_connect, reverse, status_down)
        self.assertTrue(share.feed_isl_discovery(reverse))

        # 1 1
        self.ensure_isl_props(neo4j_connect, forward, status_up)
        self.ensure_isl_props(neo4j_connect, reverse, status_up)
        self.assertTrue(make_isl_failed(src_endpoint))

        # 0 1
        self.ensure_isl_props(neo4j_connect, forward, status_down)
        self.ensure_isl_props(neo4j_connect, reverse, status_half_up)
        self.assertTrue(share.feed_isl_discovery(forward))

        # 1 1
        self.ensure_isl_props(neo4j_connect, forward, status_up)
        self.ensure_isl_props(neo4j_connect, reverse, status_up)
        self.assertTrue(make_isl_failed(dst_endpoint))

        # 1 0
        self.ensure_isl_props(neo4j_connect, forward, status_half_up)
        self.ensure_isl_props(neo4j_connect, reverse, status_down)
        self.assertTrue(share.feed_isl_discovery(reverse))

        # 1 1
        self.ensure_isl_props(neo4j_connect, forward, status_up)
        self.ensure_isl_props(neo4j_connect, reverse, status_up)
        self.assertTrue(make_isl_failed(src_endpoint))

        # 0 1
        self.ensure_isl_props(neo4j_connect, forward, status_down)
        self.ensure_isl_props(neo4j_connect, reverse, status_half_up)
        self.assertTrue(make_isl_failed(dst_endpoint))

        # 0 0
        self.ensure_isl_props(neo4j_connect, forward, status_down)
        self.ensure_isl_props(neo4j_connect, reverse, status_down)

    @unittest.skip('ISL conflict resolution was disabled, because event topology is responsible for them now')
    def test_isl_replug(self):
        sw_alpha = share.make_datapath_id(1)
        sw_beta = share.make_datapath_id(2)
        sw_gamma = share.make_datapath_id(3)
        sw_delta = share.make_datapath_id(4)

        isl_alpha_beta = model.InterSwitchLink(
                model.IslPathNode(sw_alpha, 2),
                model.IslPathNode(sw_beta, 2), None)
        isl_beta_alpha = isl_alpha_beta.reversed()
        isl_beta_gamma = model.InterSwitchLink(
                model.IslPathNode(sw_beta, 2),
                model.IslPathNode(sw_gamma, 3), None)
        isl_gamma_beta = isl_beta_gamma.reversed()
        isl_gamma_delta = model.InterSwitchLink(
                model.IslPathNode(sw_gamma, 3),
                model.IslPathNode(sw_delta, 3), None)
        isl_delta_gamma = isl_gamma_delta.reversed()

        for dpid in sw_alpha, sw_beta, sw_gamma, sw_delta:
            self.assertTrue(make_switch_add(dpid))

        self.assertTrue(share.feed_isl_discovery(isl_alpha_beta))
        self.assertTrue(share.feed_isl_discovery(isl_beta_alpha))
        self.assertTrue(share.feed_isl_discovery(isl_gamma_delta))
        self.assertTrue(share.feed_isl_discovery(isl_delta_gamma))

        self.ensure_isl_props(
                neo4j_connect, isl_alpha_beta, ISL_STATUS_PROPS_UP)
        self.ensure_isl_props(
                neo4j_connect, isl_beta_alpha, ISL_STATUS_PROPS_UP)
        self.ensure_isl_props(
                neo4j_connect, isl_gamma_delta, ISL_STATUS_PROPS_UP)
        self.ensure_isl_props(
                neo4j_connect, isl_delta_gamma, ISL_STATUS_PROPS_UP)

        self.assertRaises(
                exc.DBRecordNotFound, isl_utils.fetch,
                neo4j_connect, isl_beta_gamma)
        self.assertRaises(
                exc.DBRecordNotFound, isl_utils.fetch,
                neo4j_connect, isl_gamma_beta)

        # replug
        self.assertTrue(
                share.feed_isl_discovery(isl_beta_gamma))
        # alpha <-> beta is down
        self.ensure_isl_props(
                neo4j_connect, isl_alpha_beta, ISL_STATUS_PROPS_HALF_UP)
        self.ensure_isl_props(
                neo4j_connect, isl_beta_alpha, ISL_STATUS_PROPS_DOWN)
        # gamma -> delta is down
        self.ensure_isl_props(
                neo4j_connect, isl_gamma_delta, ISL_STATUS_PROPS_DOWN)
        self.ensure_isl_props(
                neo4j_connect, isl_delta_gamma, ISL_STATUS_PROPS_HALF_UP)
        # beta <-> gamma is half up
        self.ensure_isl_props(
                neo4j_connect, isl_beta_gamma, ISL_STATUS_PROPS_HALF_UP)
        self.ensure_isl_props(
                neo4j_connect, isl_gamma_beta, ISL_STATUS_PROPS_DOWN)

        self.assertTrue(
                share.feed_isl_discovery(isl_gamma_beta))
        # alpha <-> beta is down
        self.ensure_isl_props(
                neo4j_connect, isl_alpha_beta, ISL_STATUS_PROPS_HALF_UP)
        self.ensure_isl_props(
                neo4j_connect, isl_beta_alpha, ISL_STATUS_PROPS_DOWN)
        # gamma -> delta is down
        self.ensure_isl_props(
                neo4j_connect, isl_gamma_delta, ISL_STATUS_PROPS_DOWN)
        self.ensure_isl_props(
                neo4j_connect, isl_delta_gamma, ISL_STATUS_PROPS_HALF_UP)
        # beta <-> gamma is up
        self.ensure_isl_props(
                neo4j_connect, isl_beta_gamma, ISL_STATUS_PROPS_UP)
        self.ensure_isl_props(
                neo4j_connect, isl_gamma_beta, ISL_STATUS_PROPS_UP)

    def test_isl_down_without_isl(self):
        sw_alpha = share.make_datapath_id(1)
        sw_beta = share.make_datapath_id(2)
        isl_alpha_beta = model.InterSwitchLink(
                model.IslPathNode(sw_alpha, 2),
                model.IslPathNode(sw_beta, 2), None)
        isl_beta_alpha = isl_alpha_beta.reversed()

        self.assertTrue(make_switch_add(sw_alpha))
        self.assertTrue(make_isl_failed(isl_alpha_beta.source))

        self.assertRaises(
                exc.DBRecordNotFound, isl_utils.fetch,
                neo4j_connect, isl_alpha_beta)
        self.assertRaises(
                exc.DBRecordNotFound, isl_utils.fetch,
                neo4j_connect, isl_beta_alpha)

    def test_port_down_without_isl(self):
        sw_alpha = share.make_datapath_id(1)
        sw_beta = share.make_datapath_id(2)
        isl_alpha_beta = model.InterSwitchLink(
                model.IslPathNode(sw_alpha, 2),
                model.IslPathNode(sw_beta, 2), None)
        isl_beta_alpha = isl_alpha_beta.reversed()

        self.assertTrue(make_switch_add(sw_alpha))
        self.assertTrue(make_port_down(isl_alpha_beta.source))

        self.assertRaises(
                exc.DBRecordNotFound, isl_utils.fetch,
                neo4j_connect, isl_alpha_beta)
        self.assertRaises(
                exc.DBRecordNotFound, isl_utils.fetch,
                neo4j_connect, isl_beta_alpha)

    def test_port_down_with_cost_as_string(self):
        sw_alpha = share.make_datapath_id(1)
        sw_beta = share.make_datapath_id(2)
        isl_alpha_beta = model.InterSwitchLink(
                model.NetworkEndpoint(sw_alpha, 2),
                model.NetworkEndpoint(sw_beta, 2), None)
        self.assertTrue(share.feed_isl_discovery(isl_alpha_beta))

        with neo4j_connect.begin() as tx:
            isl_utils.set_props(tx, isl_alpha_beta, {"cost": "10"})

        self.assertTrue(make_port_down(isl_alpha_beta.source))

    def test_multi_isl_port_down(self):
        sw_alpha = share.make_datapath_id(1)
        sw_beta = share.make_datapath_id(2)
        sw_gamma = share.make_datapath_id(3)

        isl_alpha_beta = model.InterSwitchLink(
            model.IslPathNode(sw_alpha, 2),
            model.IslPathNode(sw_beta, 2), None)
        isl_beta_alpha = isl_alpha_beta.reversed()
        isl_beta_gamma = model.InterSwitchLink(
            model.IslPathNode(sw_beta, 2),
            model.IslPathNode(sw_gamma, 3), None)
        isl_gamma_beta = isl_beta_gamma.reversed()

        for dpid in sw_alpha, sw_beta, sw_gamma:
            self.assertTrue(make_switch_add(dpid))

        self.assertTrue(share.feed_isl_discovery(isl_alpha_beta))
        self.assertTrue(share.feed_isl_discovery(isl_beta_alpha))
        self.assertTrue(share.feed_isl_discovery(isl_beta_gamma))
        self.assertTrue(share.feed_isl_discovery(isl_gamma_beta))

        self.assertTrue(make_port_down(isl_alpha_beta.dest))
        self.ensure_isl_props(
            neo4j_connect, isl_alpha_beta, ISL_STATUS_PROPS_HALF_UP)
        self.ensure_isl_props(
            neo4j_connect, isl_beta_alpha, ISL_STATUS_PROPS_DOWN)
        self.ensure_isl_props(
            neo4j_connect, isl_beta_gamma, ISL_STATUS_PROPS_DOWN)
        self.ensure_isl_props(
            neo4j_connect, isl_gamma_beta, ISL_STATUS_PROPS_HALF_UP)

    def test_cost_raise_on_port_down(self):
        self.setup_initial_data()
        self._cost_raise_on_port_down(10, 10010, 10010)
        self._cost_raise_on_port_down(10010, 10010, 10010)

        self._set_isl_cost('20')

        self._cost_raise_on_port_down(20, 10020, 10020)
        self._cost_raise_on_port_down(10020, 10020, 10020)

        self._set_isl_cost(0)

        self._cost_raise_on_port_down(0, 10000, 10000)
        self._cost_raise_on_port_down(10000, 10000, 10000)

    def test_cost_raise_on_port_down_without_link_props(self):
        self.setup_initial_data(make_link_props=False)
        self._cost_raise_on_port_down(None, 10000, 10000)

    def _cost_raise_on_port_down(self, initial, down, recover):
        src_endpoint, dst_endpoint = self.src_endpoint, self.dst_endpoint
        isl = model.InterSwitchLink(src_endpoint, dst_endpoint, None)

        self.ensure_isl_costs(
            (src_endpoint, initial),
            (dst_endpoint, initial))

        self.assertTrue(
            make_port_down(src_endpoint), 'Port DOWN command have failed')

        self.ensure_isl_costs(
            (src_endpoint, down),
            (dst_endpoint, down))

        self.assertTrue(
            share.feed_isl_discovery(isl),
            'ISL discovery command have failed')

        self.ensure_isl_costs(
            (src_endpoint, recover),
            (dst_endpoint, recover))

    def _set_isl_cost(self, value):
        with neo4j_connect.begin() as tx:
            isl = model.InterSwitchLink(
                self.src_endpoint, self.dst_endpoint, None)
            isl_utils.set_cost(tx, isl, value)
            isl_utils.set_cost(tx, isl.reversed(), value)

        with neo4j_connect.begin() as tx:
            props = {'cost': model.convert_integer(value)}
            self.ensure_isl_props(tx, isl, props)
            self.ensure_isl_props(tx, isl.reversed(), props)

    def test_no_cost_raise_on_isl_down(self):
        self.setup_initial_data()

        src_endpoint, dst_endpoint = self.src_endpoint, self.dst_endpoint
        isl = model.InterSwitchLink(src_endpoint, dst_endpoint, None)

        self.ensure_isl_costs(
                (src_endpoint, 10),
                (dst_endpoint, 10))

        self.assertTrue(
                make_isl_failed(src_endpoint), 'Port DOWN command have failed')

        self.ensure_isl_costs(
                (src_endpoint, 10),
                (dst_endpoint, 10))

        self.assertTrue(
                share.feed_isl_discovery(isl), 'ISL discovery command have failed')

        self.ensure_isl_costs(
                (src_endpoint, 10),
                (dst_endpoint, 10))

    def test_moved_isl_should_be_marked(self):
        self.setup_initial_data()
        src_endpoint, dst_endpoint = self.src_endpoint, self.dst_endpoint
        forward = model.InterSwitchLink(src_endpoint, dst_endpoint, None)

        make_isl_moved(forward)
        self.ensure_isl_props(neo4j_connect, forward, ISL_STATUS_PROPS_MOVED)

    def test_isl_without_life_cycle_fields(self):
        sw_alpha = share.make_datapath_id(1)
        sw_beta = share.make_datapath_id(2)
        isl_alpha_beta = model.InterSwitchLink(
                model.IslPathNode(sw_alpha, 2),
                model.IslPathNode(sw_beta, 2), None)

        self.assertTrue(make_switch_add(sw_alpha))
        self.assertTrue(make_switch_add(sw_beta))

        self.assertTrue(share.feed_isl_discovery(isl_alpha_beta))

        with neo4j_connect.begin() as tx:
            neo4j_connect.pull(isl_utils.fetch(tx, isl_alpha_beta))
            isl_utils.set_props(
                    tx, isl_alpha_beta,
                    {'time_create': None, 'time_modify': None})

        self.assertTrue(share.feed_isl_discovery(isl_alpha_beta))

    def test_time_update_on_isl_discovery(self):
        sw_alpha = share.make_datapath_id(1)
        sw_beta = share.make_datapath_id(2)
        isl_alpha_beta = model.InterSwitchLink(
                model.IslPathNode(sw_alpha, 2),
                model.IslPathNode(sw_beta, 2), None)

        self.assertTrue(make_switch_add(sw_alpha))
        self.assertTrue(make_switch_add(sw_beta))

        update_point_a = model.TimeProperty.now(milliseconds_precission=True)

        message = share.command(share.isl_info_payload(isl_alpha_beta))
        message['timestamp'] = update_point_a.as_java_timestamp()
        self.feed_service(message)

        recovered = model.TimeProperty.new_from_java_timestamp(message['timestamp'])
        self.assertEquals(update_point_a.value, recovered.value)

        with neo4j_connect.begin() as tx:
            isl = isl_utils.fetch(tx, isl_alpha_beta)
            neo4j_connect.pull(isl)

            db_ctime = model.TimeProperty.new_from_db(isl['time_create'])
            self.assertEqual(update_point_a.value, db_ctime.value)

            db_mtime = model.TimeProperty.new_from_db(isl['time_modify'])
            self.assertEqual(update_point_a.value, db_mtime.value)

        # one more update
        update_point_b = model.TimeProperty.now(milliseconds_precission=True)
        self.assertNotEqual(update_point_a.value, update_point_b.value)

        message['timestamp'] = update_point_b.as_java_timestamp()
        self.feed_service(message)
        with neo4j_connect.begin() as tx:
            isl = isl_utils.fetch(tx, isl_alpha_beta)
            neo4j_connect.pull(isl)

            db_ctime = model.TimeProperty.new_from_db(isl['time_create'])
            self.assertEqual(update_point_a.value, db_ctime.value)

            db_mtime = model.TimeProperty.new_from_db(isl['time_modify'])
            self.assertEqual(update_point_b.value, db_mtime.value)

    def ensure_isl_props(self, tx, isl, props):
        isl_record = isl_utils.fetch(tx, isl)
        neo4j_connect.pull(isl_record)
        for name in props:
            self.assertEqual(
                    props[name], isl_record[name],
                    "Invalid ISL's {!r} value ({!r})".format(name, isl_record))

    def ensure_isl_costs(self, *endpoint_cost_pairs):
        endpoints = []
        costs = []
        for pair in endpoint_cost_pairs:
            endpoints.append(pair[0])
            costs.append(pair[1])

        for isl, expect in zip(self.enumerate_isl(*endpoints), costs):
            self.assertEqual(
                    expect, isl['cost'],
                    'Bad "cost" value {!r} (expect {!r}) in isl {!r}'.format(
                            isl['cost'], expect, isl))

    def enumerate_isl(self, *endpoints):
        with neo4j_connect.begin() as tx:
            for node in endpoints:
                q = (
                    'MATCH (a:switch)-[self:isl]->(:switch)\n'
                    'WHERE a.name=$dpid\n'
                    'RETURN self')

                for data_set in tx.run(q, dpid=node.dpid):
                    node = data_set['self']
                    neo4j_connect.pull(node)
                    yield node

    def setup_initial_data(self, make_link_props=True):
        src_endpoint, dst_endpoint = self.src_endpoint, self.dst_endpoint

        make_switch_add(src_endpoint.dpid)
        make_switch_add(dst_endpoint.dpid)

        if make_link_props:
            with neo4j_connect.begin() as tx:
                payload = {'cost': 10}
                inject_db_link_props(tx, src_endpoint, dst_endpoint, payload)
                inject_db_link_props(tx, dst_endpoint, src_endpoint, payload)

        make_isl_pair(src_endpoint, dst_endpoint)