text:
from etcd import Client as EtcdClient
from etcd import EtcdKeyNotFound, EtcdResult, EtcdException
import json
import unittest

from mock import ANY
from netaddr import IPNetwork, IPAddress
from nose.tools import *
from mock import patch, Mock, call

from pycalico.datastore import (DatastoreClient,
                                                  CALICO_V_PATH)
from pycalico.datastore_errors import DataStoreError, ProfileNotInEndpoint, ProfileAlreadyInEndpoint, \
    MultipleEndpointsMatch
from pycalico.datastore_datatypes import Rules, BGPPeer, IPPool, \
    Endpoint, Profile, Rule

TEST_HOST = "TEST_HOST"
TEST_ORCH_ID = "docker"
TEST_PROFILE = "TEST"
TEST_CONT_ID = "1234"
TEST_ENDPOINT_ID = "1234567890ab"
TEST_ENDPOINT_ID2 = "90abcdef1234"
TEST_HOST_PATH = CALICO_V_PATH + "/host/TEST_HOST"
IPV4_POOLS_PATH = CALICO_V_PATH + "/ipam/v4/pool/"
IPV6_POOLS_PATH = CALICO_V_PATH + "/ipam/v6/pool/"
TEST_PROFILE_PATH = CALICO_V_PATH + "/policy/profile/TEST/"
ALL_PROFILES_PATH = CALICO_V_PATH + "/policy/profile/"
ALL_ENDPOINTS_PATH = CALICO_V_PATH + "/host/"
ALL_HOSTS_PATH = CALICO_V_PATH + "/host/"
TEST_ORCHESTRATORS_PATH = CALICO_V_PATH + "/host/TEST_HOST/"
TEST_WORKLOADS_PATH = CALICO_V_PATH + "/host/TEST_HOST/workload/docker/"
TEST_ENDPOINT_PATH = CALICO_V_PATH + "/host/TEST_HOST/workload/docker/1234/" \
                                     "endpoint/1234567890ab"
TEST_CONT_ENDPOINTS_PATH = CALICO_V_PATH + "/host/TEST_HOST/workload/docker/" \
                                          "1234/"
TEST_CONT_PATH = CALICO_V_PATH + "/host/TEST_HOST/workload/docker/1234/"
CONFIG_PATH = CALICO_V_PATH + "/config/"

BGP_V_PATH = "/calico/bgp/v1"
BGP_GLOBAL_PATH = BGP_V_PATH + "/global"
TEST_BGP_HOST_PATH = BGP_V_PATH + "/host/TEST_HOST"
BGP_PEERS_PATH = BGP_GLOBAL_PATH + "/peer_v4/"
TEST_NODE_BGP_PEERS_PATH = TEST_BGP_HOST_PATH + "/peer_v4/"
BGP_NODE_DEF_AS_PATH = BGP_GLOBAL_PATH + "/as_num"
BGP_NODE_MESH_PATH = BGP_GLOBAL_PATH + "/node_mesh"
TEST_HOST_IPV4_PATH = TEST_HOST_PATH + "/bird_ip"
TEST_BGP_HOST_IPV4_PATH = TEST_BGP_HOST_PATH + "/ip_addr_v4"
TEST_BGP_HOST_IPV6_PATH = TEST_BGP_HOST_PATH + "/ip_addr_v6"
TEST_BGP_HOST_AS_PATH = TEST_BGP_HOST_PATH + "/as_num"

# 4 endpoints, with 2 TEST profile and 2 UNIT profile.
EP_56 = Endpoint(TEST_HOST, "docker", TEST_CONT_ID, "567890abcdef",
                 "active", "AA-22-BB-44-CC-66")
EP_56.profile_ids = ["TEST"]
EP_78 = Endpoint(TEST_HOST, "docker", TEST_CONT_ID, "7890abcdef12",
                 "active", "11-AA-33-BB-55-CC")
EP_78.profile_ids = ["TEST"]
EP_90 = Endpoint(TEST_HOST, "docker", TEST_CONT_ID, "90abcdef1234",
                 "active", "1A-2B-3C-4D-5E-6E")
EP_90.profile_ids = ["UNIT"]
EP_12 = Endpoint(TEST_HOST, "docker", TEST_CONT_ID, TEST_ENDPOINT_ID,
                 "active", "11-22-33-44-55-66")
EP_12.profile_ids = ["UNIT"]

# A complicated set of Rules JSON for testing serialization / deserialization.
RULES_JSON = """
{
  "id": "PROF_GROUP1",
  "inbound_rules": [
    {
      "action": "allow",
      "src_tag": "PROF_GROUP1"
    },
    {
      "action": "allow",
      "src_net": "192.168.77.0/24"
    },
    {
      "action": "allow",
      "src_net": "192.168.0.0"
    },
    {
      "protocol": "udp",
      "src_tag": "SRC_TAG",
      "src_ports": [10, 20, 30],
      "src_net": "192.168.77.0/30",
      "dst_tag": "DST_TAG",
      "dst_ports": [20, 30, 40],
      "dst_net": "1.2.3.4",
      "icmp_type": 30,
      "action": "deny"
    }
  ],
  "outbound_rules": [
    {
      "action": "allow"
    }
  ]
}"""

class TestRule(unittest.TestCase):

    def test_create(self):
        """
        Test creating a rule from constructor.
        """
        rule1 = Rule(action="allow",
                     src_tag="TEST",
                     src_ports=[300, 400])
        assert_dict_equal({"action": "allow",
                           "src_tag": "TEST",
                           "src_ports": [300, 400]}, rule1)

    def test_to_json(self):
        """
        Test to_json() method.
        """
        rule1 = Rule(action="deny",
                     dst_net=IPNetwork("192.168.13.0/24"))
        json_str = rule1.to_json()
        expected = json.dumps({"action": "deny",
                               "dst_net": "192.168.13.0/24"})
        assert_equal(json_str, expected)

        rule2 = Rule(action="deny",
                     src_net="192.168.13.0/24")
        json_str = rule2.to_json()
        expected = json.dumps({"action": "deny",
                               "src_net": "192.168.13.0/24"})
        assert_equal(json_str, expected)

    @raises(KeyError)
    def test_wrong_keys(self):
        """
        Test that instantiating a Rule with mistyped keys fails.
        """
        _ = Rule(action="deny", dst_nets="192.168.13.0/24")

    @raises(ValueError)
    def test_wrong_value(self):
        """
        Test that instantiating a Rule with action not allow|deny will fail.
        """
        _ = Rule(action="accept")

    def test_pprint(self):
        """
        Test pprint() method for human readable representation.
        """
        rule1 = Rule(action="allow",
                     src_tag="TEST",
                     src_ports=[300, 400, "100:200"])
        assert_equal("allow from ports 300,400,100:200 tag TEST",
                     rule1.pprint())

        rule2 = Rule(action="allow",
                     dst_tag="TEST",
                     dst_ports=[300, 400],
                     protocol="udp")
        assert_equal("allow udp to ports 300,400 tag TEST",
                     rule2.pprint())

        rule3 = Rule(action="deny",
                     src_net=IPNetwork("fd80::4:0/112"),
                     dst_ports=[80],
                     dst_net=IPNetwork("fd80::23:0/112"))
        assert_equal(
            "deny from cidr fd80::4:0/112 to ports 80 cidr fd80::23:0/112",
            rule3.pprint())

        rule4 = Rule(action="allow",
                     protocol="icmp",
                     icmp_code=100,
                     icmp_type=8,
                     src_net=IPNetwork("10/8"))
        assert_equal("allow icmp type 8 code 100 from cidr 10.0.0.0/8",
                     rule4.pprint())

class TestRules(unittest.TestCase):

    def test_rules(self):
        """
        Create a detailed set of rules, convert from and to json and compare
        the results.
        """
        # Convert a JSON blob into a Rules object.
        rules = Rules.from_json(RULES_JSON)

        # Convert the Rules object to JSON and then back again.
        new_json = rules.to_json()
        new_rules = Rules.from_json(new_json)

        # Compare the two rules objects.
        assert_equal(rules.id, new_rules.id)
        assert_equal(rules.inbound_rules,
                     new_rules.inbound_rules)
        assert_equal(rules.outbound_rules,
                     new_rules.outbound_rules)

        # Check the values of one of the inbound Rule objects.
        assert_equal(len(rules.inbound_rules), 4)
        inbound_rule = rules.inbound_rules[3]
        assert_equal(inbound_rule["protocol"], "udp")
        assert_equal(inbound_rule["src_tag"], "SRC_TAG")
        assert_equal(inbound_rule["src_ports"], [10, 20,30])
        assert_equal(inbound_rule["src_net"], IPNetwork("192.168.77.0/30"))
        assert_equal(inbound_rule["dst_tag"], "DST_TAG")
        assert_equal(inbound_rule["dst_net"], IPNetwork("1.2.3.4"))
        assert_equal(inbound_rule["icmp_type"], 30)
        assert_equal(inbound_rule["action"], "deny")

class TestEndpoint(unittest.TestCase):

    def test_to_json(self):
        """
        Test to_json() method.
        """
        endpoint1 = Endpoint(TEST_HOST, "docker", TEST_CONT_ID,
                             "aabbccddeeff112233",
                             "active", "11-22-33-44-55-66")
        assert_equal(endpoint1.endpoint_id, "aabbccddeeff112233")
        assert_equal(endpoint1.state, "active")
        assert_equal(endpoint1.mac, "11-22-33-44-55-66")
        assert_equal(endpoint1.profile_ids, [])  # Defaulted
        expected = {"state": "active",
                    "name": "caliaabbccddeef",
                    "mac": "11-22-33-44-55-66",
                    "profile_ids": [],
                    "ipv4_nets": [],
                    "ipv6_nets": [],
                    "ipv4_gateway": None,
                    "ipv6_gateway": None}
        assert_dict_equal(json.loads(endpoint1.to_json()), expected)

    def test_from_json(self):
        """
        Test from_json() class method
          - Directly from JSON
          - From to_json() method of existing Endpoint.
        """
        expected = {"state": "active",
                    "name": "caliaabbccddeef",
                    "mac": "11-22-33-44-55-66",
                    "profile_id": "TEST23",
                    "ipv4_nets": ["192.168.3.2/32", "10.3.4.23/32"],
                    "ipv6_nets": ["fd20::4:2:1/128"],
                    "ipv4_gateway": "10.3.4.2",
                    "ipv6_gateway": "2001:2:4a::1"}
        endpoint = Endpoint.from_json(TEST_ENDPOINT_PATH, json.dumps(expected))
        assert_equal(endpoint.state, "active")
        assert_equal(endpoint.endpoint_id, TEST_ENDPOINT_ID)
        assert_equal(endpoint.mac, "11-22-33-44-55-66")
        assert_equal(endpoint.profile_ids, ["TEST23"])
        assert_equal(endpoint.ipv4_gateway, IPAddress("10.3.4.2"))
        assert_equal(endpoint.ipv6_gateway, IPAddress("2001:2:4a::1"))
        assert_set_equal(endpoint.ipv4_nets, {IPNetwork("192.168.3.2/32"),
                                              IPNetwork("10.3.4.23/32")})
        assert_set_equal(endpoint.ipv6_nets, {IPNetwork("fd20::4:2:1/128")})

        endpoint2 = Endpoint.from_json(TEST_ENDPOINT_PATH, endpoint.to_json())
        assert_equal(endpoint.state, endpoint2.state)
        assert_equal(endpoint.endpoint_id, endpoint2.endpoint_id)
        assert_equal(endpoint.mac, endpoint2.mac)
        assert_equal(endpoint.profile_ids, endpoint2.profile_ids)
        assert_equal(endpoint.ipv4_gateway, endpoint2.ipv4_gateway)
        assert_equal(endpoint.ipv6_gateway, endpoint2.ipv6_gateway)
        assert_set_equal(endpoint.ipv4_nets, endpoint2.ipv4_nets)
        assert_set_equal(endpoint.ipv6_nets, endpoint2.ipv6_nets)

    def test_operators(self):
        """
        Test Endpoint operators __eq__, __ne__ and copy.
        """
        endpoint1 = Endpoint(TEST_HOST, "docker", TEST_CONT_ID,
                             "aabbccddeeff112233",
                             "active", "11-22-33-44-55-66")
        endpoint2 = Endpoint(TEST_HOST, "docker", TEST_CONT_ID,
                             "aabbccddeeff112233",
                             "inactive", "11-22-33-44-55-66")
        endpoint3 = endpoint1.copy()

        assert_equal(endpoint1, endpoint3)
        assert_not_equal(endpoint1, endpoint2)
        assert_not_equal(endpoint1, 1)
        assert_false(endpoint1 == "this is not an endpoint")

    def test_matches(self):
        """
        Test Endpoint.matches() with various match conditions.
        """
        endpoint1 = Endpoint(TEST_HOST, "docker", TEST_CONT_ID,
                             "aabbccddeeff112233",
                             "active", "11-22-33-44-55-66")
        assert_true(endpoint1.matches(hostname=TEST_HOST,
                                      orchestrator_id="docker",
                                      workload_id=TEST_CONT_ID,
                                      endpoint_id="aabbccddeeff112233"))
        assert_false(endpoint1.matches(hostname="INVALID",
                                       orchestrator_id="docker",
                                       workload_id=TEST_CONT_ID,
                                       endpoint_id="aabbccddeeff112233"))
        assert_false(endpoint1.matches(hostname=TEST_HOST,
                                       orchestrator_id="INVALID",
                                       workload_id=TEST_CONT_ID,
                                       endpoint_id="aabbccddeeff112233"))
        assert_false(endpoint1.matches(hostname=TEST_HOST,
                                       orchestrator_id="docker",
                                       workload_id="INVALID",
                                       endpoint_id="aabbccddeeff112233"))
        assert_false(endpoint1.matches(hostname=TEST_HOST,
                                       orchestrator_id="docker",
                                       workload_id=TEST_CONT_ID,
                                       endpoint_id="INVALID"))

    def test_repr(self):
        """
        Test __repr__ returns the correct string value.
        """
        jsondata = {"state": "active",
                    "name": "caliaabbccddeef",
                    "mac": "11-22-33-44-55-66",
                    "profile_id": "TEST23",
                    "ipv4_nets": ["192.168.3.2/32", "10.3.4.23/32"],
                    "ipv6_nets": ["fd20::4:2:1/128"],
                    "ipv4_gateway": "10.3.4.2",
                    "ipv6_gateway": "2001:2:4a::1"}
        endpoint = Endpoint.from_json(TEST_ENDPOINT_PATH, json.dumps(jsondata))

        # Not the best test since this repeats the underlying implementation,
        # but checks that it isn't changed unexpectedly.
        assert_equal(endpoint.__repr__(),
                     "Endpoint(%s)" % endpoint.to_json())

class TestBGPPeer(unittest.TestCase):
    def test_operator(self):
        """
        Test BGPPeer equality operator.
        """
        peer1 = BGPPeer("1.2.3.4", "22222")
        peer2 = BGPPeer(IPAddress("1.2.3.4"), 22222)
        peer3 = BGPPeer("1.2.3.5", 22222)
        peer4 = BGPPeer("1.2.3.4", 22226)
        assert_equal(peer1, peer2)
        assert_false(peer1 == peer3)
        assert_false(peer1 == peer4)
        assert_false(peer1 == "This is not a BGPPeer")

class TestIPPool(unittest.TestCase):
    def test_eq(self):
        """
        Test IPPool equality operator.
        """
        ippool1 = IPPool("1.2.3.4/24", ipip=True, masquerade=True)
        ippool2 = IPPool(IPNetwork("1.2.3.8/24"), ipip=True, masquerade=True)
        ippool3 = IPPool("1.2.3.4/24", ipip=True)
        ippool4 = IPPool("1.2.3.4/24", masquerade=True)
        ippool5 = IPPool("1.2.3.4/24")
        assert_equal(ippool1, ippool2)
        assert_false(ippool1 == ippool3)
        assert_false(ippool1 == ippool4)
        assert_false(ippool1 == ippool5)
        assert_false(ippool1 == "This is not an IPPool")

    def test_contains(self):
        """
        Test IPPool "__contains__"operator.
        """
        assert_true(IPAddress("1.2.3.4") in IPPool("1.2.3.0/24"))
        assert_true("1.2.3.4" in IPPool("1.2.3.0/24"))

    def test_str(self):
        """
        Test __str__ returns just the CIDR.
        """
        assert_equals("1.2.3.0/24",
                      str(IPPool("1.2.3.4/24", ipip=True, masquerade=True)))

class TestDatastoreClient(unittest.TestCase):

    @patch("pycalico.datastore.os.getenv", autospec=True)
    @patch("pycalico.datastore.etcd.Client", autospec=True)
    def setUp(self, m_etcd_client, m_getenv):
        m_getenv.return_value = "127.0.0.2:4002"
        self.etcd_client = Mock(spec=EtcdClient)
        m_etcd_client.return_value = self.etcd_client
        self.datastore = DatastoreClient()
        m_etcd_client.assert_called_once_with(host="127.0.0.2", port=4002)

    def test_ensure_global_config(self):
        """
        Test ensure_global_config when it doesn't already exist.
        """
        int_prefix_path = CONFIG_PATH + "InterfacePrefix"
        self.etcd_client.read.side_effect = EtcdKeyNotFound

        # We only write the interface prefix if there is no entry in the
        # etcd database.  Note it is not sufficient to just check for the
        # existence of the config directory to determine whether we write
        # the interface prefix since the config directory may contain other
        # global configuration.
        self.datastore.ensure_global_config()
        expected_reads = [call(int_prefix_path),
                          call(BGP_NODE_DEF_AS_PATH),
                          call(BGP_NODE_MESH_PATH)]
        self.etcd_client.read.assert_has_calls(expected_reads)
        expected_writes = [call(int_prefix_path, "cali"),
                           call(BGP_NODE_DEF_AS_PATH, 64511),
                           call(BGP_NODE_MESH_PATH, json.dumps({"enabled": True})),
                           call(CALICO_V_PATH + "/Ready", "true")]
        self.etcd_client.write.assert_has_calls(expected_writes)

    def test_ensure_global_config_exists(self):
        """
        Test ensure_global_config() when it already exists.
        """
        self.datastore.ensure_global_config()
        expected_reads = [call(CONFIG_PATH + "InterfacePrefix"),
                          call(BGP_NODE_DEF_AS_PATH),
                          call(BGP_NODE_MESH_PATH)]
        self.etcd_client.read.assert_has_calls(expected_reads)

    def test_ensure_global_config_exists_etcd_exc(self):
        """
        Test ensure_global_config() when etcd raises an EtcdException.
        """
        self.etcd_client.read.side_effect = EtcdException
        self.assertRaises(DataStoreError, self.datastore.ensure_global_config)
        self.etcd_client.read.assert_called_once_with(
                                               CONFIG_PATH + "InterfacePrefix")

    def test_get_profile(self):
        """
        Test getting a named profile that exists.
        Test getting a named profile that doesn't exist raises a KeyError.
        """

        def mock_read(path):
            result = Mock(spec=EtcdResult)
            if path == TEST_PROFILE_PATH:
                return result
            elif path == TEST_PROFILE_PATH + "tags":
                result.value = '["TAG1", "TAG2", "TAG3"]'
                return result
            elif path == TEST_PROFILE_PATH + "rules":
                result.value = """
{
  "id": "TEST",
  "inbound_rules": [
    {"action": "allow", "src_net": "192.168.1.0/24", "src_ports": [200,2001]}
  ],
  "outbound_rules": [
    {"action": "allow", "src_tag": "TEST", "src_ports": [200,2001]}
  ]
}
"""
                return result
            else:
                raise EtcdKeyNotFound()
        self.etcd_client.read.side_effect = mock_read

        profile = self.datastore.get_profile("TEST")
        assert_equal(profile.name, "TEST")
        assert_set_equal({"TAG1", "TAG2", "TAG3"}, profile.tags)
        assert_equal(Rule(action="allow",
                          src_net=IPNetwork("192.168.1.0/24"),
                          src_ports=[200, 2001]),
                     profile.rules.inbound_rules[0])
        assert_equal(Rule(action="allow",
                          src_tag="TEST",
                          src_ports=[200, 2001]),
                     profile.rules.outbound_rules[0])

        assert_raises(KeyError, self.datastore.get_profile, "TEST2")

    def test_get_profile_no_tags_or_rules(self):
        """
        Test getting a named profile that exists, but has no tags or rules.
        """

        def mock_read(path):
            result = Mock(spec=EtcdResult)
            if path == TEST_PROFILE_PATH:
                return result
            else:
                raise EtcdKeyNotFound()
        self.etcd_client.read.side_effect = mock_read

        profile = self.datastore.get_profile("TEST")
        assert_equal(profile.name, "TEST")
        assert_set_equal(set(), profile.tags)
        assert_equal([], profile.rules.inbound_rules)
        assert_equal([], profile.rules.outbound_rules)

    @raises(KeyError)
    def test_remove_profile_doesnt_exist(self):
        """
        Remove profile when it doesn't exist.  Check it throws a KeyError.
        :return: None
        """
        self.etcd_client.delete.side_effect = EtcdKeyNotFound
        self.datastore.remove_profile(TEST_PROFILE)

    def test_profile_update_tags(self):
        """
        Test updating tags on an existing profile.
        :return:
        """

        profile = Profile("TEST")
        profile.tags = {"TAG4", "TAG5"}
        profile.rules = Rules(id="TEST",
                              inbound_rules=[
                                  Rule(action="allow", dst_ports=[12]),
                                  Rule(action="allow", protocol="udp"),
                                  Rule(action="deny")
                              ],
                              outbound_rules=[
                                  Rule(action="allow", src_ports=[23]),
                                  Rule(action="deny")
                              ])

        self.datastore.profile_update_tags(profile)
        self.etcd_client.write.assert_called_once_with(
            TEST_PROFILE_PATH + "tags",
            '["TAG4", "TAG5"]')

    def test_profile_update_rules(self):
        """
        Test updating rules on an existing profile.
        :return:
        """

        profile = Profile("TEST")
        profile.tags = {"TAG4", "TAG5"}
        profile.rules = Rules(id="TEST",
                              inbound_rules=[
                                  Rule(action="allow", dst_ports=[12]),
                                  Rule(action="allow", protocol="udp"),
                                  Rule(action="deny")
                              ],
                              outbound_rules=[
                                  Rule(action="allow", src_ports=[23]),
                                  Rule(action="deny")
                              ])

        self.datastore.profile_update_rules(profile)
        self.etcd_client.write.assert_called_once_with(
            TEST_PROFILE_PATH + "rules",
            profile.rules.to_json())

    @patch("pycalico.datastore.DatastoreClient.get_endpoint", autospec=True)
    @patch("pycalico.datastore.DatastoreClient.update_endpoint", autospec=True)
    def test_append_profiles_to_endpoint(self, m_update, m_get):
        """
        Test append_profiles_to_endpoint() to check profile_ids are updated.
        :return: None.
        """
        endpoint1 = Endpoint(TEST_HOST, "docker", TEST_CONT_ID,
                             "aabbccddeeff112233",
                             "active", "11-22-33-44-55-66")
        endpoint1.profile_ids = ["PROF1", "PROFA", "PROF2", "PROFB"]
        m_get.return_value = endpoint1

        endpoint2 = endpoint1.copy()
        endpoint2.profile_ids = ["PROF1", "PROFA", "PROF2", "PROFB",
                                 "PROFZ", "PROF5"]

        def update_endpoint(_ds, ep):
            assert_list_equal(ep.profile_ids,
                              ["PROF1", "PROFA", "PROF2",
                               "PROFB", "PROFZ", "PROF5"])
            assert_equal(endpoint1, endpoint2)
        m_update.side_effect = update_endpoint

        self.datastore.append_profiles_to_endpoint(["PROFZ", "PROF5"])
        assert_true(m_update.called)

    @patch("pycalico.datastore.DatastoreClient.get_endpoint", autospec=True)
    @patch("pycalico.datastore.DatastoreClient.update_endpoint", autospec=True)
    def test_append_profiles_to_endpoint_duplicate(self, m_update, m_get):
        """
        Test append_profiles_to_endpoint() with a duplicate profile.

        No update should occur.
        :return: None.
        """
        endpoint1 = Endpoint(TEST_HOST, "docker", TEST_CONT_ID,
                             "aabbccddeeff112233",
                             "active", "11-22-33-44-55-66")
        endpoint1.profile_ids = ["PROF1", "PROFA", "PROF2", "PROFB"]
        m_get.return_value = endpoint1

        self.assertRaises(ProfileAlreadyInEndpoint,
                          self.datastore.append_profiles_to_endpoint,
                          ["PROFZ", "PROFA"])
        assert_false(m_update.called)

    @patch("pycalico.datastore.DatastoreClient.get_endpoint", autospec=True)
    @patch("pycalico.datastore.DatastoreClient.update_endpoint", autospec=True)
    def test_set_profiles_on_endpoint(self, m_update, m_get):
        """
        Test set_profiles_on_endpoint() to check profile_ids are updated.
        :return: None.
        """
        endpoint1 = Endpoint(TEST_HOST, "docker", TEST_CONT_ID,
                             "aabbccddeeff112233",
                             "active", "11-22-33-44-55-66")
        endpoint1.profile_ids = ["PROF1", "PROFA", "PROF2", "PROFB"]
        m_get.return_value = endpoint1

        endpoint2 = endpoint1.copy()
        endpoint2.profile_ids = ["PROFZ", "PROF5"]

        def update_endpoint(ds, ep):
            assert_list_equal(ep.profile_ids,
                              ["PROFZ", "PROF5"])
            assert_equal(endpoint1, endpoint2)
        m_update.side_effect = update_endpoint

        self.datastore.set_profiles_on_endpoint(["PROFZ", "PROF5"])
        assert_true(m_update.called)

    @patch("pycalico.datastore.DatastoreClient.get_endpoint", autospec=True)
    @patch("pycalico.datastore.DatastoreClient.update_endpoint", autospec=True)
    def test_remove_profiles_from_endpoint(self, m_update, m_get):
        """
        Test remove_profiles_from_endpoint() to check profile_ids are updated.
        :return: None.
        """
        endpoint1 = Endpoint(TEST_HOST, "docker", TEST_CONT_ID,
                             "aabbccddeeff112233",
                             "active", "11-22-33-44-55-66")
        endpoint1.profile_ids = ["PROF1", "PROFA", "PROF2", "PROFB"]
        m_get.return_value = endpoint1

        endpoint2 = endpoint1.copy()
        endpoint2.profile_ids = ["PROFA", "PROFB"]

        def update_endpoint(_ds, ep):
            assert_list_equal(ep.profile_ids,
                              ["PROFA", "PROFB"])
            assert_equal(endpoint1, endpoint2)
        m_update.side_effect = update_endpoint

        self.datastore.remove_profiles_from_endpoint(["PROF1", "PROF2"])
        assert_true(m_update.called)

    @patch("pycalico.datastore.DatastoreClient.get_endpoint", autospec=True)
    @patch("pycalico.datastore.DatastoreClient.update_endpoint", autospec=True)
    def test_remove_profiles_to_endpoint_missing(self, m_update, m_get):
        """
        Test remove_profiles_from_endpoint() with an invalid profile.

        No update should occur.
        :return: None.
        """
        endpoint1 = Endpoint(TEST_HOST, "docker", TEST_CONT_ID,
                             "aabbccddeeff112233",
                             "active", "11-22-33-44-55-66")
        endpoint1.profile_ids = ["PROF1", "PROFA", "PROF2", "PROFB"]
        m_get.return_value = endpoint1

        self.assertRaises(ProfileNotInEndpoint,
                          self.datastore.remove_profiles_from_endpoint,
                          ["PROF1", "PROFZ"])
        assert_false(m_update.called)

    def test_create_host_exists(self):
        """
        Test create_host() when the .../workload key already exists.
        :return: None
        """
        def mock_read_success(path):
            result = Mock(spec=EtcdResult)
            if path == TEST_HOST_PATH + "/workload":
                return result
            else:
                assert False

        self.etcd_client.read.side_effect = mock_read_success

        ipv4 = "192.168.2.4"
        ipv6 = "fd80::4"
        bgp_as = 65531
        self.datastore.create_host(TEST_HOST, ipv4, ipv6, bgp_as)
        expected_writes = [call(TEST_HOST_IPV4_PATH, ipv4),
                           call(TEST_BGP_HOST_IPV4_PATH, ipv4),
                           call(TEST_BGP_HOST_IPV6_PATH, ipv6),
                           call(TEST_BGP_HOST_AS_PATH, bgp_as),
                           call(TEST_HOST_PATH +
                                "/config/DefaultEndpointToHostAction",
                                "RETURN"),
                           call(TEST_HOST_PATH + "/config/marker",
                                "created")]
        self.etcd_client.write.assert_has_calls(expected_writes,
                                                any_order=True)
        assert_equal(self.etcd_client.write.call_count, 6)

    def test_create_host_mainline(self):
        """
        Test create_host() when none of the keys exists (specifically,
        .../workload is checked and doesn't exist).
        :return: None
        """
        def mock_read(path):
            if path == CALICO_V_PATH + "/host/TEST_HOST/workload":
                raise EtcdKeyNotFound()
            else:
                assert False

        self.etcd_client.read.side_effect = mock_read
        self.etcd_client.delete.side_effect = EtcdKeyNotFound()

        ipv4 = "192.168.2.4"
        ipv6 = "fd80::4"
        bgp_as = None
        self.datastore.create_host(TEST_HOST, ipv4, ipv6, bgp_as)
        expected_writes = [call(TEST_HOST_IPV4_PATH, ipv4),
                           call(TEST_BGP_HOST_IPV4_PATH, ipv4),
                           call(TEST_BGP_HOST_IPV6_PATH, ipv6),
                           call(TEST_HOST_PATH +
                                "/config/DefaultEndpointToHostAction",
                                "RETURN"),
                           call(TEST_HOST_PATH + "/config/marker",
                                "created"),
                           call(TEST_HOST_PATH + "/workload",
                                None, dir=True)]
        self.etcd_client.write.assert_has_calls(expected_writes,
                                                any_order=True)
        assert_equal(self.etcd_client.write.call_count, 6)

    def test_remove_host_mainline(self):
        """
        Test remove_host() when the key exists.
        :return:
        """
        self.datastore.remove_host(TEST_HOST)
        expected_deletes = [call(TEST_BGP_HOST_PATH + "/",
                                 dir=True,
                                 recursive=True),
                            call(TEST_HOST_PATH + "/",
                                 dir=True,
                                 recursive=True)]
        self.etcd_client.delete.assert_has_calls(expected_deletes)

    def test_remove_host_doesnt_exist(self):
        """
        Remove host when it doesn't exist.  Check it doesn't throw an
        exception.
        :return: None
        """
        self.etcd_client.delete.side_effect = EtcdKeyNotFound
        self.datastore.remove_host(TEST_HOST)

    def test_get_ip_pools(self):
        """
        Test getting IP pools from the datastore when there are some pools.
        :return: None
        """
        self.etcd_client.read.side_effect = mock_read_2_pools
        pools = self.datastore.get_ip_pools(4)
        assert_list_equal([IPPool("192.168.3.0/24"), IPPool("192.168.5.0/24")],
                          pools)

    def test_get_ip_pools_no_key(self):
        """
        Test getting IP pools from the datastore when the key doesn't exist.
        :return: None
        """
        def mock_read(path, recursive=False):
            assert_equal(path, IPV4_POOLS_PATH)
            assert_true(recursive)
            raise EtcdKeyNotFound()

        self.etcd_client.read.side_effect = mock_read
        pools = self.datastore.get_ip_pools(4)
        assert_list_equal([], pools)

    def test_get_ip_pools_no_pools(self):
        """
        Test getting IP pools from the datastore when the key is there but has
        no children.
        :return: None
        """
        self.etcd_client.read.side_effect = mock_read_no_pools
        pools = self.datastore.get_ip_pools(4)
        assert_list_equal([], pools)

    def test_get_ip_pool_config(self):
        """
        Test get_ip_pool_config where valid data is returned..
        """
        def mock_read(path):
            assert path == IPV4_POOLS_PATH + "1.2.0.0-16"
            result = Mock(spec=EtcdResult)
            result.key = path
            result.value = "{\"cidr\": \"1.2.0.0/16\"," \
                            "\"ipip\": \"tunl0\"," \
                            "\"masquerade\": true}"
            return result

        self.etcd_client.read.side_effect = mock_read
        config = self.datastore.get_ip_pool_config(4,
                                                   IPNetwork("1.2.3.4/16"))
        assert_equal(config,
                     IPPool("1.2.0.0/16", ipip=True, masquerade=True))

    def test_get_ip_pool_config_doesnt_exist(self):
        """
        Test get_ip_pool_config where the pool does not exist.
        """
        self.etcd_client.read.side_effect = EtcdKeyNotFound
        self.assertRaises(KeyError,
                          self.datastore.get_ip_pool_config,
                          4, IPNetwork("1.2.3.4/1"))

    def test_add_ip_pool(self):
        """
        Test adding an IP pool when the directory exists, but pool doesn't.
        :return: None
        """
        pool = IPPool("192.168.100.5/24", ipip=True, masquerade=True)
        self.datastore.add_ip_pool(4, pool)
        self.etcd_client.write.assert_called_once_with(IPV4_POOLS_PATH + "192.168.100.0-24",
                                                       ANY)
        raw_data = self.etcd_client.write.call_args[0][1]
        data = json.loads(raw_data)
        self.assertEqual(data, {'cidr': '192.168.100.0/24',
                                "ipip": "tunl0",
                                'masquerade': True})
        self.assertEqual(pool, IPPool.from_json(raw_data))

        self.etcd_client.write.reset_mock()
        pool = IPPool("192.168.100.5/24")
        self.datastore.add_ip_pool(4, pool)
        self.etcd_client.write.assert_called_once_with(IPV4_POOLS_PATH + "192.168.100.0-24",
                                                       ANY)
        raw_data = self.etcd_client.write.call_args[0][1]
        data = json.loads(raw_data)
        self.assertEqual(data, {'cidr': '192.168.100.0/24'})
        self.assertEqual(pool, IPPool.from_json(raw_data))

    def test_del_ip_pool_exists(self):
        """
        Test remove_ip_pool() when the pool does exist.
        :return: None
        """
        cidr = IPNetwork("192.168.3.1/24")
        self.datastore.remove_ip_pool(4, cidr)
        self.etcd_client.delete.assert_called_once_with(IPV4_POOLS_PATH + "192.168.3.0-24")

    def test_del_ip_pool_doesnt_exist(self):
        """
        Test remove_ip_pool() when the pool does not exist.
        :return: None
        """
        self.etcd_client.delete.side_effect = EtcdKeyNotFound
        cidr = IPNetwork("192.168.100.1/24")
        self.assertRaises(KeyError,
                          self.datastore.remove_ip_pool, 4, cidr)

    def test_profile_exists_true(self):
        """
        Test profile_exists() when it does.
        """
        def mock_read(path):
            assert_equal(path, TEST_PROFILE_PATH)
            return Mock(spec=EtcdResult)

        self.etcd_client.read.side_effect = mock_read
        assert_true(self.datastore.profile_exists("TEST"))

    def test_profile_exists_false(self):
        """
        Test profile_exists() when it doesn't exist.
        """
        def mock_read(path):
            assert_equal(path, TEST_PROFILE_PATH)
            raise EtcdKeyNotFound()

        self.etcd_client.read.side_effect = mock_read
        assert_false(self.datastore.profile_exists("TEST"))

    def test_create_profile(self):
        """
        Test create_profile()
        """
        self.datastore.create_profile("TEST")
        rules = Rules(id="TEST",
                      inbound_rules=[Rule(action="allow",
                                          src_tag="TEST")],
                      outbound_rules=[Rule(action="allow")])
        expected_calls = [call(TEST_PROFILE_PATH + "tags", '["TEST"]'),
                          call(TEST_PROFILE_PATH + "rules", rules.to_json())]
        self.etcd_client.write.assert_has_calls(expected_calls, any_order=True)

    def test_delete_profile(self):
        """
        Test deleting a policy profile.
        """
        self.datastore.remove_profile("TEST")
        self.etcd_client.delete.assert_called_once_with(TEST_PROFILE_PATH,
                                                        recursive=True,
                                                        dir=True)

    def test_get_profile_names_2(self):
        """
        Test get_profile_names() when there are two profiles.
        """
        self.etcd_client.read.side_effect = mock_read_2_profiles
        profiles = self.datastore.get_profile_names()
        assert_set_equal(profiles, {"UNIT", "TEST"})

    def test_get_profile_names_no_key(self):
        """
        Test get_profile_names() when the key hasn't been set up.  Should
        return empty set and not raise a KeyError.
        """
        self.etcd_client.read.side_effect = mock_read_profiles_key_error
        profiles = self.datastore.get_profile_names()
        assert_set_equal(profiles, set())

    def test_get_profile_names_no_profiles(self):
        """
        Test get_profile_names() when there are no profiles.
        """
        self.etcd_client.read.side_effect = mock_read_no_profiles
        profiles = self.datastore.get_profile_names()
        assert_set_equal(profiles, set())

    def test_get_profile_members(self):
        """
        Test get_profile_members() when there are endpoints.
        """
        self.maxDiff = 1000
        self.etcd_client.read.side_effect = mock_read_4_endpoints
        members = self.datastore.get_profile_members("TEST")
        assert_list_equal(members, [EP_56, EP_78])

        members = self.datastore.get_profile_members("UNIT")
        assert_list_equal(members, [EP_90, EP_12])

        members = self.datastore.get_profile_members("UNIT_TEST")
        assert_list_equal(members, [])

    def test_get_profile_members_no_key(self):
        """
        Test get_profile_members() when the endpoints path has not been
        set up.
        """
        self.etcd_client.read.side_effect = mock_read_endpoints_key_error
        members = self.datastore.get_profile_members("UNIT_TEST")
        assert_list_equal(members, [])

    def test_get_endpoint_exists(self):
        """
        Test get_endpoint() for an endpoint that exists.
        """
        ep = Endpoint(TEST_HOST, TEST_ORCH_ID, TEST_CONT_ID, TEST_ENDPOINT_ID,
                      "active", "11-22-33-44-55-66")
        self.etcd_client.read.side_effect = mock_read_for_endpoint(ep)
        ep2 = self.datastore.get_endpoint(hostname=TEST_HOST,
                                          orchestrator_id=TEST_ORCH_ID,
                                          workload_id=TEST_CONT_ID,
                                          endpoint_id=TEST_ENDPOINT_ID)
        assert_equal(ep.to_json(), ep2.to_json())
        assert_equal(ep.endpoint_id, ep2.endpoint_id)

    def test_get_endpoint_doesnt_exist(self):
        """
        Test get_endpoint() for an endpoint that doesn't exist.
        """
        def mock_read(path, recursive=None):
            assert_true(recursive)
            assert_equal(path, TEST_ENDPOINT_PATH)
            raise EtcdKeyNotFound()
        self.etcd_client.read.side_effect = mock_read
        assert_raises(KeyError,
                      self.datastore.get_endpoint,
                      hostname=TEST_HOST, orchestrator_id=TEST_ORCH_ID,
                      workload_id=TEST_CONT_ID, endpoint_id=TEST_ENDPOINT_ID)

    def test_get_endpoints_multiple(self):
        """
        Test get_endpoints() with more than a single result.
        """

        self.etcd_client.read.side_effect = \
            get_mock_read_2_ep_for_cont(ALL_ENDPOINTS_PATH, True)
        self.assertRaises(MultipleEndpointsMatch, self.datastore.get_endpoint)

    def test_set_endpoint(self):
        """
        Test set_endpoint().
        """
        EP_12._original_json = ""
        self.datastore.set_endpoint(EP_12)
        self.etcd_client.write.assert_called_once_with(TEST_ENDPOINT_PATH,
                                                       EP_12.to_json())
        assert_equal(EP_12._original_json, EP_12.to_json())

    def test_remove_endpoint(self):
        """
        Test remove_endpoint().
        """
        self.datastore.remove_endpoint(EP_12)
        self.etcd_client.delete.assert_called_once_with(TEST_ENDPOINT_PATH,
                                                        recursive=True,
                                                        dir=True)

    def test_update_endpoint(self):
        """
        Test update_endpoint().
        """
        ep = EP_12.copy()
        original_json = ep.to_json()
        ep._original_json = original_json
        ep.profile_ids = ["a", "different", "set", "of", "ids"]
        assert_not_equal(ep._original_json, ep.to_json())

        self.datastore.update_endpoint(ep)
        self.etcd_client.write.assert_called_once_with(TEST_ENDPOINT_PATH,
                                                     ep.to_json(),
                                                     prevValue=original_json)
        assert_not_equal(ep._original_json, original_json)
        assert_equals(ep._original_json, ep.to_json())

    def test_get_endpoints_exists(self):
        """
        Test get_endpoints() passing in various numbers of parameters, with
        matching return results.
        """

        self.etcd_client.read.side_effect = \
            get_mock_read_2_ep_for_cont(ALL_ENDPOINTS_PATH, True)
        eps = self.datastore.get_endpoints()
        assert_equal(len(eps), 2)
        assert_equal(eps[0].to_json(), EP_12.to_json())
        assert_equal(eps[0].endpoint_id, EP_12.endpoint_id)
        assert_equal(eps[1].to_json(), EP_78.to_json())
        assert_equal(eps[1].endpoint_id, EP_78.endpoint_id)

        self.etcd_client.read.side_effect = \
            get_mock_read_2_ep_for_cont(TEST_ORCHESTRATORS_PATH, True)
        eps = self.datastore.get_endpoints(hostname=TEST_HOST)
        assert_equal(len(eps), 2)
        assert_equal(eps[0].to_json(), EP_12.to_json())
        assert_equal(eps[0].endpoint_id, EP_12.endpoint_id)
        assert_equal(eps[1].to_json(), EP_78.to_json())
        assert_equal(eps[1].endpoint_id, EP_78.endpoint_id)

        self.etcd_client.read.side_effect = \
            get_mock_read_2_ep_for_cont(TEST_WORKLOADS_PATH, True)
        eps = self.datastore.get_endpoints(hostname=TEST_HOST,
                                           orchestrator_id=TEST_ORCH_ID)
        assert_equal(len(eps), 2)
        assert_equal(eps[0].to_json(), EP_12.to_json())
        assert_equal(eps[0].endpoint_id, EP_12.endpoint_id)
        assert_equal(eps[1].to_json(), EP_78.to_json())
        assert_equal(eps[1].endpoint_id, EP_78.endpoint_id)

        self.etcd_client.read.side_effect = \
            get_mock_read_2_ep_for_cont(TEST_CONT_ENDPOINTS_PATH, True)
        eps = self.datastore.get_endpoints(hostname=TEST_HOST,
                                           orchestrator_id=TEST_ORCH_ID,
                                           workload_id=TEST_CONT_ID)
        assert_equal(len(eps), 2)
        assert_equal(eps[0].to_json(), EP_12.to_json())
        assert_equal(eps[0].endpoint_id, EP_12.endpoint_id)
        assert_equal(eps[1].to_json(), EP_78.to_json())
        assert_equal(eps[1].endpoint_id, EP_78.endpoint_id)

    def test_get_endpoints_no_matches(self):
        """
        Test get_endpoints() with etcd data returned, but non-matching data.
        """
        self.etcd_client.read.side_effect = \
              get_mock_read_2_ep_for_cont(TEST_WORKLOADS_PATH, True)
        eps = self.datastore.get_endpoints(hostname=TEST_HOST,
                                           orchestrator_id=TEST_ORCH_ID,
                                           endpoint_id="NOTVALID")
        assert_equal(len(eps), 0)

    def test_get_endpoints_doesnt_exist(self):
        """
        Test get_endpoints() for a container that doesn't exist.
        """
        def mock_read(path, recursive=None):
            assert_true(recursive)
            assert_equal(path, TEST_CONT_ENDPOINTS_PATH)
            raise EtcdKeyNotFound()
        self.etcd_client.read.side_effect = mock_read
        eps = self.datastore.get_endpoints(hostname=TEST_HOST,
                                           orchestrator_id=TEST_ORCH_ID,
                                           workload_id=TEST_CONT_ID)
        assert_equal(eps, [])

    def test_get_default_next_hops(self):
        """
        Test get_default_next_hops when both are present.
        """
        def mock_read(path):
            result = Mock(spec=EtcdResult)
            if path == TEST_BGP_HOST_IPV4_PATH:
                result.value = "192.168.24.1"
                return result
            if path == TEST_BGP_HOST_IPV6_PATH:
                result.value = "fd30:4500::1"
                return result
            assert False
        self.etcd_client.read.side_effect = mock_read
        next_hops = self.datastore.get_default_next_hops(TEST_HOST)
        assert_dict_equal(next_hops, {4: IPAddress("192.168.24.1"),
                                      6: IPAddress("fd30:4500::1")})

    def test_get_default_next_hops_missing(self):
        """
        Test get_default_next_hops when both are missing.
        """
        def mock_read(path):
            result = Mock(spec=EtcdResult)
            if path == TEST_BGP_HOST_IPV4_PATH:
                result.value = ""
                return result
            if path == TEST_BGP_HOST_IPV6_PATH:
                result.value = ""
                return result
            assert False
        self.etcd_client.read.side_effect = mock_read
        next_hops = self.datastore.get_default_next_hops(TEST_HOST)
        assert_dict_equal(next_hops, {})

    @raises(KeyError)
    def test_get_default_next_hops_missing_config(self):
        """
        Test get_default_next_hops raises a KeyError when the BIRD
        configuration is missing from etcd.
        """
        self.etcd_client.read.side_effect = EtcdKeyNotFound
        next_hops = self.datastore.get_default_next_hops(TEST_HOST)

    def test_remove_all_data(self):
        """
        Test remove_all_data() when /calico does exist.
        """
        self.datastore.remove_all_data()
        self.etcd_client.delete.assert_called_once_with("/calico",
                                                        recursive=True,
                                                        dir=True)

    def test_remove_all_data_key_error(self):
        """
        Test remove_all_data() when delete() throws a KeyError.
        """
        self.etcd_client.delete.side_effect = EtcdKeyNotFound
        self.datastore.remove_all_data()  # should not throw exception.

    def test_remove_workload(self):
        """
        Test remove_workload()
        """
        self.datastore.remove_workload(TEST_HOST, TEST_ORCH_ID, TEST_CONT_ID)
        self.etcd_client.delete.assert_called_once_with(TEST_CONT_PATH,
                                                        recursive=True,
                                                        dir=True)

    @raises(KeyError)
    def test_remove_workload_missing(self):
        """
        Test remove_workload() raises a KeyError if the container does not
        exist.
        """
        self.etcd_client.delete.side_effect = EtcdKeyNotFound
        self.datastore.remove_workload(TEST_HOST, TEST_ORCH_ID, TEST_CONT_ID)

    def test_get_bgp_peers(self):
        """
        Test getting IP peers from the datastore when there are some peers.
        :return: None
        """
        self.etcd_client.read.side_effect = mock_read_2_peers
        peers = self.datastore.get_bgp_peers(4)
        assert_equal(peers, [BGPPeer("192.168.3.1", 32245),
                             BGPPeer("192.168.5.1", 32245)])

    def test_get_bgp_peers_no_key(self):
        """
        Test getting IP peers from the datastore when the key doesn't exist.
        :return: None
        """
        def mock_read(path):
            assert_equal(path, BGP_PEERS_PATH)
            raise EtcdKeyNotFound()

        self.etcd_client.read.side_effect = mock_read
        peers = self.datastore.get_bgp_peers(4)
        assert_list_equal([], peers)

    def test_get_bgp_peers_no_peers(self):
        """
        Test getting BGP peers from the datastore when the key is there but has
        no children.
        :return: None
        """
        self.etcd_client.read.side_effect = mock_read_no_bgppeers
        peers = self.datastore.get_bgp_peers(4)
        assert_list_equal([], peers)

    def test_add_bgp_peer(self):
        """
        Test adding an IP peer when the directory exists, but peer doesn't.
        :return: None
        """
        data = {"write": False}
        def mock_write(key, value):
            assert_equal(key, BGP_PEERS_PATH + "192.168.100.5")
            value = json.loads(value)
            assert_dict_equal(value,
                              {"as_num": 32245, "ip": "192.168.100.5"})
            data["write"] = True

        self.etcd_client.write.side_effect = mock_write
        peer = BGPPeer("192.168.100.5", 32245)
        self.datastore.add_bgp_peer(4, peer)
        assert_true(data["write"])

    def test_remove_bgp_peer_exists(self):
        """
        Test remove_bgp_peer() when the peer does exist.
        :return: None
        """
        self.etcd_client.delete = Mock()
        peer = IPAddress("192.168.3.1")
        self.datastore.remove_bgp_peer(4, peer)
        # 192.168.3.1 has a key ...v4/0 in the ordered list.
        self.etcd_client.delete.assert_called_once_with(
                                                BGP_PEERS_PATH + "192.168.3.1")

    def test_remove_bgp_peer_doesnt_exist(self):
        """
        Test remove_bgp_peer() when the peer does not exist.
        :return: None
        """
        self.etcd_client.delete.side_effect = EtcdKeyNotFound()
        peer = IPAddress("192.168.100.1")
        assert_raises(KeyError, self.datastore.remove_bgp_peer, 4, peer)

    def test_get_node_bgp_peer(self):
        """
        Test getting IP peers from the datastore when there are some peers.
        :return: None
        """
        self.etcd_client.read.side_effect = mock_read_2_node_peers
        peers = self.datastore.get_bgp_peers(4, hostname="TEST_HOST")
        assert_equal(peers, [BGPPeer("192.169.3.1", 32245),
                             BGPPeer("192.169.5.1", 32245)])

    def test_get_node_bgp_peer_no_key(self):
        """
        Test getting IP peers from the datastore when the key doesn't exist.
        :return: None
        """
        self.etcd_client.read.side_effect = mock_read_2_node_peers
        peers = self.datastore.get_bgp_peers(4, hostname="BLAH")
        assert_list_equal([], peers)

    def test_get_node_bgp_peer_no_peers(self):
        """
        Test getting BGP peers from the datastore when the key is there but has
        no children.
        :return: None
        """
        self.etcd_client.read.side_effect = mock_read_no_node_bgppeers
        peers = self.datastore.get_bgp_peers(4, hostname="TEST_HOST")
        assert_list_equal([], peers)

    def test_add_node_bgp_peer(self):
        """
        Test adding an IP peer when the directory exists, but peer doesn't.
        :return: None
        """
        data = {"write": False}
        def mock_write(key, value):
            assert_equal(key, TEST_NODE_BGP_PEERS_PATH + "192.169.100.5")
            value = json.loads(value)
            assert_dict_equal(value,
                              {"as_num": 32245, "ip": "192.169.100.5"})
            data["write"] = True

        self.etcd_client.write.side_effect = mock_write

        peer = BGPPeer(IPAddress("192.169.100.5"), 32245)
        self.datastore.add_bgp_peer(4, peer, hostname="TEST_HOST")
        assert_true(data["write"])

    def test_remove_node_bgp_peer_exists(self):
        """
        Test remove_node_bgp_peer() when the peer does exist.
        :return: None
        """
        self.etcd_client.delete = Mock()
        peer = IPAddress("192.168.3.1")
        self.datastore.remove_bgp_peer(4, peer, "TEST_HOST")
        # 192.168.3.1 has a key ...v4/0 in the ordered list.
        self.etcd_client.delete.assert_called_once_with(
                                      TEST_NODE_BGP_PEERS_PATH + "192.168.3.1")

    def test_remove_node_bgp_peer_doesnt_exist(self):
        """
        Test remove_node_bgp_peer() when the peer does not exist.
        :return: None
        """
        self.etcd_client.delete.side_effect = EtcdKeyNotFound()
        peer = IPAddress("192.168.100.1")
        assert_raises(KeyError, self.datastore.remove_bgp_peer,
                      4, peer, hostname="BLAH")

    def test_set_bgp_node_mesh(self):
        """
        Test set_bgp_node_mesh() stores the correct JSON when disabled and
        enabled.
        :return: None.
        """
        self.datastore.set_bgp_node_mesh(True)
        self.datastore.set_bgp_node_mesh(False)
        self.etcd_client.write.assert_has_calls([
                       call(BGP_NODE_MESH_PATH, json.dumps({"enabled": True})),
                       call(BGP_NODE_MESH_PATH, json.dumps({"enabled": False}))
                     ])

    def test_get_bgp_node_mesh(self):
        """
        Test get_bgp_node_mesh() returns the correct value based on the
        stored JSON.
        :return: None.
        """
        def mock_read(path):
            assert_equal(path, BGP_NODE_MESH_PATH)
            result = Mock(spec=EtcdResult)
            result.value = "{\"enabled\": true}"
            return result
        self.etcd_client.read = mock_read

        assert_true(self.datastore.get_bgp_node_mesh())

    def test_get_bgp_node_mesh_no_config(self):
        """
        Test get_bgp_node_mesh() returns the correct value when there is no
        mesh config.
        :return: None.
        """
        self.etcd_client.read.side_effect = EtcdKeyNotFound()
        assert_true(self.datastore.get_bgp_node_mesh())

    def test_set_default_node_as(self):
        """
        Test set_default_node_as() stores the correct value.
        :return: None.
        """
        self.datastore.set_default_node_as(12345)
        self.etcd_client.write.assert_called_once_with(BGP_NODE_DEF_AS_PATH,
                                                       12345)

    def test_get_default_node_as(self):
        """
        Test get_default_node_as() returns the correct value based on the
        stored value.
        :return: None.
        """
        def mock_read(path):
            assert_equal(path, BGP_NODE_DEF_AS_PATH)
            result = Mock(spec=EtcdResult)
            result.value = 24245
            return result
        self.etcd_client.read = mock_read

        assert_equal(self.datastore.get_default_node_as(), 24245)

    def test_get_default_node_as_no_config(self):
        """
        Test get_default_node_as() returns the correct value when there is no
        default AS config.
        :return: None.
        """
        self.etcd_client.read.side_effect = EtcdKeyNotFound()
        assert_equal(self.datastore.get_default_node_as(), 64511)

    def test_get_host_bgp_ips(self):
        """
        Check etcd for the configured IPv4 and IPv6 addresses for the specified
        host BGP binding. If it hasn't been configured yet, raise an
        EtcdKeyNotFound.

        :param hostname: The hostname.
        :return: A tuple containing the IPv4 and IPv6 address.
        """
        def mock_read(path):
            if path == TEST_BGP_HOST_IPV4_PATH:
                result = Mock(spec=EtcdResult)
                result.value = "1.2.3.4"
                return result
            if path == TEST_BGP_HOST_IPV6_PATH:
                result = Mock(spec=EtcdResult)
                result.value = "aa:bb::ee"
                return result
            raise AssertionError("Unexpected path %s" % path)
        self.etcd_client.read = mock_read

        assert_equal(self.datastore.get_host_bgp_ips(TEST_HOST),
                     ("1.2.3.4", "aa:bb::ee"))

    def test_get_host_bgp_ips_not_found(self):
        """
        Check etcd for the configured IPv4 and IPv6 addresses for the specified
        host BGP binding. If it hasn't been configured yet, raise an
        EtcdKeyNotFound.

        :param hostname: The hostname.
        :return: A tuple containing the IPv4 and IPv6 address.
        """
        self.etcd_client.read.side_effect = EtcdKeyNotFound

        assert_raises(KeyError, self.datastore.get_host_bgp_ips, TEST_HOST)

def mock_read_2_peers(path):
    """
    EtcdClient mock side effect for read with 2 IPv4 peers.
    """
    result = Mock(spec=EtcdResult)
    assert_equal(path, BGP_PEERS_PATH)
    children = []
    for ip in ["192.168.3.1", "192.168.5.1"]:
        node = Mock(spec=EtcdResult)
        node.value = "{\"ip\": \"%s\", \"as_num\": 32245}" % ip
        node.key = BGP_PEERS_PATH + str(ip)
        children.append(node)
    result.children = iter(children)
    return result

def mock_read_2_node_peers(path):
    """
    EtcdClient mock side effect for read with 2 IPv4 peers.  Assumes host is
    "TEST_HOST" otherwise raises EtcdKeyNotFound.
    """
    result = Mock(spec=EtcdResult)
    if path != TEST_NODE_BGP_PEERS_PATH:
        raise EtcdKeyNotFound()
    children = []
    for ip in ["192.169.3.1", "192.169.5.1"]:
        node = Mock(spec=EtcdResult)
        node.value = "{\"ip\": \"%s\", \"as_num\": 32245}" % ip
        node.key = TEST_NODE_BGP_PEERS_PATH + str(ip)
        children.append(node)
    result.children = iter(children)
    return result

def mock_read_2_pools(path, recursive=False):
    """
    EtcdClient mock side effect for read with 2 IPv4 pools.
    """
    result = Mock(spec=EtcdResult)
    assert_equal(path, IPV4_POOLS_PATH)
    assert_true(recursive)
    children = []
    for net in ["192.168.3.0/24", "192.168.5.0/24"]:
        node = Mock(spec=EtcdResult)
        node.value = "{\"cidr\": \"%s\"}" % net
        node.key = IPV4_POOLS_PATH + net.replace("/", "-")
        children.append(node)
    result.leaves = iter(children)
    return result

def mock_read_no_pools(path, recursive=False):
    """
    EtcdClient mock side effect for read with no IPv4 pools.
    """
    result = Mock(spec=EtcdResult)
    assert path == IPV4_POOLS_PATH
    assert_true(recursive)
    result.leaves = []
    return result

def mock_read_no_bgppeers(path):
    """
    EtcdClient mock side effect for read with no IPv4 BGP Peers
    """
    result = Mock(spec=EtcdResult)
    assert path == BGP_PEERS_PATH

    # Bug in etcd seems to return the parent when enumerating children if there
    # are no children.  We handle this in the datastore.
    node = Mock(spec=EtcdResult)
    node.value = None
    node.key = BGP_PEERS_PATH
    result.children = iter([node])
    return result

def mock_read_no_node_bgppeers(path):
    """
    EtcdClient mock side effect for read with no IPv4 BGP Peers
    """
    result = Mock(spec=EtcdResult)
    assert path == TEST_NODE_BGP_PEERS_PATH

    # Bug in etcd seems to return the parent when enumerating children if there
    # are no children.  We handle this in the datastore.
    node = Mock(spec=EtcdResult)
    node.value = None
    node.key = TEST_NODE_BGP_PEERS_PATH
    result.children = iter([node])
    return result

def mock_read_2_profiles(path):
    assert path == ALL_PROFILES_PATH
    nodes = [CALICO_V_PATH + "/policy/profile/TEST",
             CALICO_V_PATH + "/policy/profile/UNIT"]
    children = []
    for node in nodes:
        result = Mock(spec=EtcdResult)
        result.key = node
        children.append(result)
    results = Mock(spec=EtcdResult)
    results.children = iter(children)
    return results

def mock_read_no_profiles(path):
    assert path == ALL_PROFILES_PATH
    results = Mock(spec=EtcdResult)
    results.children = iter([])
    return results

def mock_read_profiles_key_error(path):
    assert path == ALL_PROFILES_PATH
    raise EtcdKeyNotFound()

def mock_read_4_endpoints(path, recursive):
    assert path == ALL_ENDPOINTS_PATH
    assert recursive
    leaves = []

    specs = [
        (CALICO_V_PATH + "/host/TEST_HOST/config/marker", "created"),
        (CALICO_V_PATH + "/host/TEST_HOST/workload/docker/1234/endpoint/567890abcdef",
         EP_56.to_json()),
        (CALICO_V_PATH + "/host/TEST_HOST/workload/docker/5678/endpoint/90abcdef1234",
         EP_90.to_json()),
        (CALICO_V_PATH + "/host/TEST_HOST2/config/marker", "created"),
        (CALICO_V_PATH + "/host/TEST_HOST2/workload/docker/1234/endpoint/7890abcdef12",
         EP_78.to_json()),
        (CALICO_V_PATH + "/host/TEST_HOST2/workload/docker/5678/endpoint/1234567890ab",
         EP_12.to_json())]
    for spec in specs:
        leaf = Mock(spec=EtcdResult)
        leaf.key = spec[0]
        leaf.value = spec[1]
        leaves.append(leaf)

    result = Mock(spec=EtcdResult)
    result.leaves = iter(leaves)
    return result

def mock_read_endpoints_key_error(path, recursive):
    assert path == ALL_ENDPOINTS_PATH
    assert recursive
    raise EtcdKeyNotFound()

def mock_read_for_endpoint(ep):
    def mock_read_get_endpoint(path, recursive=None):
        assert recursive
        assert path == TEST_ENDPOINT_PATH
        leaf = Mock(spec=EtcdResult)
        leaf.key = TEST_ENDPOINT_PATH
        leaf.value = ep.to_json()
        result = Mock(spec=EtcdResult)
        result.leaves = iter([leaf])
        return result
    return mock_read_get_endpoint

def get_mock_read_2_ep_for_cont(expected_path, expected_recursive):
    def mock_read(path, recursive=None):
        assert_equal(recursive, expected_recursive)
        assert_equal(path, expected_path)
        leaves = []

        specs = [
            (CALICO_V_PATH + "/host/TEST_HOST/workload/docker/1234/endpoint/1234567890ab",
             EP_12.to_json()),
            (CALICO_V_PATH + "/host/TEST_HOST/workload/docker/1234/endpoint/7890abcdef12",
             EP_78.to_json())
        ]
        for spec in specs:
            leaf = Mock(spec=EtcdResult)
            leaf.key = spec[0]
            leaf.value = spec[1]
            leaves.append(leaf)

        result = Mock(spec=EtcdResult)
        result.leaves = iter(leaves)
        return result
    return mock_read

def mock_read_0_ep_for_cont(path):
    assert path == TEST_CONT_ENDPOINTS_PATH
    leaves = []
    result = Mock(spec=EtcdResult)
    result.leaves = iter(leaves)
    return result


text:
/**
 * Removes a given node from the DOM.
 *
 * @param node the node to remove
 */
export default function remove(
  node: Node | null
): Node | null {
  if (node && node.parentNode) {
    node.parentNode.removeChild(node);
    return node;
  }
  return null;
}

redpajama_set_name: RedPajamaGithub


text:
class TokensWithBudget2 : public CalcMethod {

public:

    // Constructor / destructor
    TokensWithBudget2(size_t budget);
    ~TokensWithBudget2();

    // Initialization
    virtual void Init();

    // Compute primes up to a limit
    virtual void ComputePrimes(U64 limit);

    // The name of this method
    virtual const char* Name() const {
        return "TokensWithBudget2";
    }

protected:

    struct Token {
        U64 prime;
        size_t sievePos;
    };

    struct TokenWithPlace {
        Token* t;
        U64 place;
        TokenWithPlace(Token* t_ = NULL, U64 p_ = 0) : t(t_), place(p_) {}
    };

    size_t budget;
    Sieve sieve;
    size_t sievePos;
    U64 curr;
    Token** list[2];

    // These should only change when the main thread is blocking and its known that its
    // not accessing any of them
    U32 whichList;
    U64 listBase;
    U64 listSize;

    // For sending tokens to the overflow thread
    LockFreeQueue<TokenWithPlace> queue;

    // For setup of overflow thread
    pthread_t overflowThread;
    bool threadStarted;
    U32 threadResult;

    // For coordination between main thread and overflow thread
    volatile bool threadJoining;
    volatile bool fillingSecondary;
    volatile bool nextList;

    // A pair of files used for storing / loading overflow tokens
    std::vector<FILE*> overflowFile;
    size_t overflowBaseIdx;

    // Place the given token (with the given value) at it's next location
    void PlaceToken(Token* t, U64 place);

    // Interface for the overflow thread
    // Static method to call the virtual run method
    static void* OverflowThreadCB(void* arg);
    U32 OverflowThread();

    // Add a token to be put into overflow
    void AddOverflowToken(Token* t, U64 place);

    // Waits until it's safe to switch lists and then switches
    // Called in the main thread and blocks on the overflow thread resetting "nextList"
    void NextList();

    // Place a token in the secondary list
    void PlaceSecondaryToken(Token* t, U64 place);

    // Method used by overflow thread to write a token to a particular overflow file
    void WriteToOverflowFile(U64 listIdx, Token* t, U64 place);
};


text:
@interface NSObject (OFObjectHelpers)

- (BOOL) isPresent;

@end


text:
/**
 * This package contains built-in implementations of the {@link org.easybatch.core.api.RecordWriter} interface.
 */
package org.easybatch.core.writer;


text:
#include <iostream>
#include <utility>
#include <vector>
using namespace std;

/*
 * Approach: we first find the position of the rook on the board and then we move up, down, left, and right.
 * While moving in those directions, we only stop moving if we reach a spot that is off the board, we capture a pawn,
 * or we encounter a friendly bishop.
 *
 * Time complexity: O(number of rows * number of columns) --> O(8 * 8) --> O(64)
 * Space complexity: O(1)
 */

bool isOnBoard(int rows, int columns, int row, int column)
{
    return (row >= 0 && row < rows) && (column >= 0 && column < columns);
}

int numRookCaptures(vector<vector<char>>& board)
{
    int captures=0;

    if(board.empty())
    {
        return captures;
    }

    pair<int, int> rookPosition(-1, -1);

    int rows=8;

    int columns=8;

    bool done=false;

    for(int row=0;row<rows;++row)
    {
        for(int column=0;column<columns;++column)
        {
            if(board[row][column]=='R')
            {
                rookPosition.first=row;

                rookPosition.second=column;

                done=true;
            }
        }

        if(done)
        {
            break;
        }
    }

    pair<int, int> current=rookPosition;

    while(isOnBoard(rows, columns, current.first, current.second))
    {
        if(board[current.first][current.second]=='p')
        {
            captures++;

            break;
        }
        else if(board[current.first][current.second]=='B')
        {
            break;
        }

        current.first--;
    }

    current=rookPosition;

    while(isOnBoard(rows, columns, current.first, current.second))
    {
        if(board[current.first][current.second]=='p')
        {
            captures++;

            break;
        }
        else if(board[current.first][current.second]=='B')
        {
            break;
        }

        current.first++;
    }

    current=rookPosition;

    while(isOnBoard(rows, columns, current.first, current.second))
    {
        if(board[current.first][current.second]=='p')
        {
            captures++;

            break;
        }
        else if(board[current.first][current.second]=='B')
        {
            break;
        }

        current.second--;
    }

    current=rookPosition;

    while(isOnBoard(rows, columns, current.first, current.second))
    {
        if(board[current.first][current.second]=='p')
        {
            captures++;

            break;
        }
        else if(board[current.first][current.second]=='B')
        {
            break;
        }

        current.second++;
    }

    return captures;
}


text:
[![Build Status](https://dev.azure.com/vscode/VSCode/_apis/build/status/VS%20Code?branchName=master)](https://aka.ms/vscode-builds)
[![Feature Requests](https://img.shields.io/github/issues/Microsoft/vscode/feature-request.svg)](https://github.com/Microsoft/vscode/issues?q=is%3Aopen+is%3Aissue+label%3Afeature-request+sort%3Areactions-%2B1-desc)
[![Bugs](https://img.shields.io/github/issues/Microsoft/vscode/bug.svg)](https://github.com/Microsoft/vscode/issues?utf8=✓&q=is%3Aissue+is%3Aopen+label%3Abug)
[![Gitter](https://img.shields.io/badge/chat-on%20gitter-yellow.svg)](https://gitter.im/Microsoft/vscode)

## The Repository

This repository ("`Code - OSS`") is where we (Microsoft) develop the [Visual Studio Code](https://code.visualstudio.com) product. Not only do we work on code and issues here, we also publish our [roadmap](https://github.com/microsoft/vscode/wiki/Roadmap), [monthly iteration plans](https://github.com/microsoft/vscode/wiki/Iteration-Plans), and our [endgame plans](https://github.com/microsoft/vscode/wiki/Running-the-Endgame). This source code is available to everyone under the standard [MIT license](https://github.com/microsoft/vscode/blob/master/LICENSE.txt).

## Visual Studio Code

[Visual Studio Code](https://code.visualstudio.com) is a distribution of the `Code - OSS` repository with Microsoft specific customizations released under a traditional [Microsoft product license](https://code.visualstudio.com/License/).

[Visual Studio Code](https://code.visualstudio.com) combines the simplicity of a code editor with what developers need for their core edit-build-debug cycle. It provides comprehensive code editing, navigation, and understanding support along with lightweight debugging, a rich extensibility model, and lightweight integration with existing tools.

Visual Studio Code is updated monthly with new features and bug fixes. You can download it for Windows, macOS, and Linux on [Visual Studio Code's website](https://code.visualstudio.com/Download). To get the latest releases every day, install the [Insiders build](https://code.visualstudio.com/insiders).

## Contributing

There are many ways in which you can participate in the project, for example:

* [Submit bugs and feature requests](https://github.com/microsoft/vscode/issues), and help us verify as they are checked in
* Review [source code changes](https://github.com/microsoft/vscode/pulls)
* Review the [documentation](https://github.com/microsoft/vscode-docs) and make pull requests for anything from typos to new content

If you are interested in fixing issues and contributing directly to the code base,
please see the document [How to Contribute](https://github.com/Microsoft/vscode/wiki/How-to-Contribute), which covers the following:

* [How to build and run from source](https://github.com/Microsoft/vscode/wiki/How-to-Contribute#build-and-run)
* [The development workflow, including debugging and running tests](https://github.com/Microsoft/vscode/wiki/How-to-Contribute#debugging)
* [Coding guidelines](https://github.com/Microsoft/vscode/wiki/Coding-Guidelines)
* [Submitting pull requests](https://github.com/Microsoft/vscode/wiki/How-to-Contribute#pull-requests)
* [Finding an issue to work on](https://github.com/microsoft/vscode/wiki/How-to-Contribute#where-to-contribute)
* [Contributing to translations](https://aka.ms/vscodeloc)

## Feedback

* Ask a question on [Stack Overflow](https://stackoverflow.com/questions/tagged/vscode)
* [Request a new feature](CONTRIBUTING.md)
* Upvote [popular feature requests](https://github.com/Microsoft/vscode/issues?q=is%3Aopen+is%3Aissue+label%3Afeature-request+sort%3Areactions-%2B1-desc)
* [File an issue](https://github.com/Microsoft/vscode/issues)
* Follow [@code](https://twitter.com/code) and let us know what you think!

## Related Projects

Many of the core components and extensions to VS Code live in their own repositories on GitHub. For example, the [node debug adapter](https://github.com/microsoft/vscode-node-debug) and the [mono debug adapter](https://github.com/microsoft/vscode-mono-debug) have their own repositories. For a complete list, please visit the [Related Projects](https://github.com/Microsoft/vscode/wiki/Related-Projects) page on our [wiki](https://github.com/Microsoft/vscode/wiki).

## Bundled Extensions

VS Code includes a set of built-in extensions located in the [extensions](extensions) folder, including grammars and snippets for many languages. Extensions that provide rich language support (code completion, Go to Definition) for a language have the suffix `language-features`. For example, the `json` extension provides coloring for `JSON` and the `json-language-features` provides rich language support for `JSON`.

## Development Container

This repository includes a Visual Studio Code Remote - Containers / Codespaces development container.

- For [Remote - Containers](https://aka.ms/vscode-remote/download/containers), use the **Remote-Containers: Open Repository in Container...** command which creates a Docker volume for better disk I/O on macOS and Windows.
- For Codespaces, install the [Visual Studio Codespaces](https://aka.ms/vscs-ext-vscode) extension in VS Code, and use the **Codespaces: Create New Codespace** command.

Docker / the Codespace should have at least **4 Cores and 6 GB of RAM (8 GB recommended)** to run full build. See the [development container README](.devcontainer/README.md) for more information.

## Code of Conduct

This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.

## License

Copyright (c) Microsoft Corporation. All rights reserved.

Licensed under the [MIT](LICENSE.txt) license.


text:
var locomotive = require('locomotive')
  , Controller = locomotive.Controller;

var pagesController = new Controller();

pagesController.main = function() {
  if(!this.checkKey()) return;
  this.render();
}

module.exports = pagesController;


text:
typedef struct sVoiture * Voiture;

Voiture initVoiture(void);

void detruireVoiture(Voiture voiture);

Position deplacementVoiture(Voiture voiture);

Voiture ajouterVoitureAcceleration(Voiture voiture,Acceleration	acceleration);

void setPositionVoiture(Voiture voiture, Position position);

void resetVitesseVoiture(Voiture voiture);

Position getPositionVoiture(Voiture voiture);

void afficherVoiture(Voiture voiture);

void afficherVoitureRecursif(Voiture voiture);

#endif


text:
package tonius.neiintegration.mods.minefactoryreloaded;

import java.awt.Point;
import java.awt.Rectangle;
import java.text.NumberFormat;
import java.util.List;

import net.minecraft.item.ItemStack;
import net.minecraft.util.WeightedRandom.Item;
import net.minecraftforge.fluids.FluidRegistry;
import net.minecraftforge.fluids.FluidStack;
import powercrystals.minefactoryreloaded.MFRRegistry;
import powercrystals.minefactoryreloaded.MineFactoryReloadedCore;
import powercrystals.minefactoryreloaded.tile.machine.TileEntitySludgeBoiler;
import tonius.neiintegration.PositionedFluidTank;
import tonius.neiintegration.RecipeHandlerBase;
import tonius.neiintegration.Utils;
import codechicken.lib.gui.GuiDraw;
import codechicken.nei.PositionedStack;
import codechicken.nei.recipe.GuiRecipe;
import cofh.lib.util.WeightedRandomItemStack;

public class RecipeHandlerSludgeBoiler extends RecipeHandlerBase {

    private static List<Item> drops;
    private static int totalWeight;
    private static int sludgePerOperation;
    private static int energyPerOperation;

    @Override
    public void prepare() {
        drops = MFRRegistry.getSludgeDrops();
        for (Item drop : drops) {
            totalWeight += drop.itemWeight;
        }

        TileEntitySludgeBoiler dummy = new TileEntitySludgeBoiler();
        sludgePerOperation = dummy.getWorkMax() * 10;
        energyPerOperation = dummy.getActivationEnergy() * dummy.getWorkMax();
        dummy = null;
    }

    public class CachedSludgeBoilerRecipe extends CachedBaseRecipe {

        public PositionedFluidTank sludgeInput;
        public PositionedStack output;
        public float chance;

        public CachedSludgeBoilerRecipe(ItemStack output, int weight) {
            this.sludgeInput = new PositionedFluidTank(FluidRegistry.getFluidStack("sludge", sludgePerOperation), 4000, new Rectangle(111, 2, 16, 60), RecipeHandlerSludgeBoiler.this.getGuiTexture(), new Point(176, 0));
            this.output = new PositionedStack(output, 48, 24);
            this.chance = (float) weight / (float) totalWeight;
        }

        @Override
        public PositionedStack getResult() {
            return this.output;
        }

        @Override
        public PositionedFluidTank getFluidTank() {
            return this.sludgeInput;
        }

    }

    @Override
    public String getRecipeName() {
        return Utils.translate("tile.mfr.machine.sludgeboiler.name", false);
    }

    @Override
    public String getRecipeID() {
        return "minefactoryreloaded.sludgeboiler";
    }

    @Override
    public String getGuiTexture() {
        return MineFactoryReloadedCore.guiFolder + "sludgeboiler.png";
    }

    @Override
    public void loadTransferRects() {
        this.addTransferRect(76, 25, 22, 15);
    }

    @Override
    public void drawBackground(int recipe) {
        this.changeToGuiTexture();
        GuiDraw.drawTexturedModalRect(0, 0, 11, 13, 160, 65);
        this.changeToOverlayTexture();
        GuiDraw.drawTexturedModalRect(76, 25, 0, 15, 22, 15);
    }

    @Override
    public void drawExtras(int recipe) {
        this.drawProgressBar(129, 0, 176, 58, 8, 62, 1.0F, 3);
        this.drawProgressBar(139, 0, 185, 58, 8, 62, 40, 3);

        CachedSludgeBoilerRecipe crecipe = (CachedSludgeBoilerRecipe) this.arecipes.get(recipe);
        NumberFormat percentFormat = NumberFormat.getPercentInstance();
        percentFormat.setMaximumFractionDigits(2);
        GuiDraw.drawStringC(percentFormat.format(crecipe.chance), 57, 44, 0x808080, false);
    }

    @Override
    public List<String> provideTooltip(GuiRecipe guiRecipe, List<String> currenttip, CachedBaseRecipe crecipe, Point relMouse) {
        super.provideTooltip(guiRecipe, currenttip, crecipe, relMouse);
        if (new Rectangle(129, 2, 8, 60).contains(relMouse)) {
            currenttip.add(energyPerOperation + " RF");
        }
        return currenttip;
    }

    @Override
    public void loadAllRecipes() {
        for (Item drop : drops) {
            if (drop instanceof WeightedRandomItemStack) {
                this.arecipes.add(new CachedSludgeBoilerRecipe(((WeightedRandomItemStack) drop).getStack(), drop.itemWeight));
            }
        }
    }

    @Override
    public void loadCraftingRecipes(ItemStack result) {
        for (Item drop : drops) {
            if (drop instanceof WeightedRandomItemStack) {
                if (Utils.areStacksSameTypeCraftingSafe(((WeightedRandomItemStack) drop).getStack(), result)) {
                    this.arecipes.add(new CachedSludgeBoilerRecipe(result, drop.itemWeight));
                }
            }
        }
    }

    @Override
    public void loadUsageRecipes(FluidStack ingredient) {
        if (ingredient.getFluid().getName().equals("sludge")) {
            this.loadAllRecipes();
        }
    }

}


text:
// Copyright (c) Microsoft.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.

using System.Collections.Immutable;

namespace Microsoft.CodeAnalysis.Semantics
{
    /// <summary>
    /// Represents an argument value that has been omitted in an invocation.
    /// </summary>
    /// <remarks>
    /// This interface is reserved for implementation by its associated APIs. We reserve the right to
    /// change it in the future.
    /// </remarks>
    public interface IOmittedArgumentExpression : IOperation
    {
    }
}


text:
#include "ServerFixture.hh"
#include "gazebo/physics/physics.hh"
#include "gazebo/physics/Gripper.hh"
#include "gazebo/physics/World.hh"
#include "gazebo/physics/Model.hh"
#include "gazebo/physics/Joint.hh"

class GripperTest : public ServerFixture
{
};

/////////////////////////////////////////////////
// \brief Test to make sure the gripper forms a joint when grasping an object
TEST_F(GripperTest, Close)
{
  Load("worlds/gripper.world");
  physics::WorldPtr world = physics::get_world("default");
  ASSERT_TRUE(world);

  physics::ModelPtr model = world->GetModel("simple_gripper");
  ASSERT_TRUE(model);

  physics::JointPtr leftJoint = model->GetJoint("palm_left_finger");
  ASSERT_TRUE(leftJoint);

  physics::JointPtr rightJoint = model->GetJoint("palm_right_finger");
  ASSERT_TRUE(rightJoint);

  physics::GripperPtr gripper = model->GetGripper(0);
  ASSERT_TRUE(gripper);

  // The gripper should not be attached to anything
  EXPECT_FALSE(gripper->IsAttached());

  // Close the gripper.
  leftJoint->SetForce(0, -0.5);
  rightJoint->SetForce(0, 0.5);

  transport::PublisherPtr jointPub = this->node->Advertise<msgs::JointCmd>(
        "~/simple_gripper/joint_cmd");

  msgs::JointCmd msg;
  msg.set_name("simple_gripper::palm_right_finger");
  msg.set_force(0.6);
  jointPub->Publish(msg);

  msg.set_name("simple_gripper::palm_left_finger");
  msg.set_force(-0.6);
  jointPub->Publish(msg);

  int i = 0;
  while (!gripper->IsAttached() && i < 100)
  {
    common::Time::MSleep(500);
    ++i;
  }
  EXPECT_LT(i, 100);

  // The gripper should be attached.
  EXPECT_TRUE(gripper->IsAttached());
}

/////////////////////////////////////////////////
// \brief Test grasp can close and open
TEST_F(GripperTest, CloseOpen)
{
  Load("worlds/gripper.world");
  physics::WorldPtr world = physics::get_world("default");
  ASSERT_TRUE(world);

  physics::ModelPtr model = world->GetModel("simple_gripper");
  ASSERT_TRUE(model);

  physics::JointPtr leftJoint = model->GetJoint("palm_left_finger");
  ASSERT_TRUE(leftJoint);

  physics::JointPtr rightJoint = model->GetJoint("palm_right_finger");
  ASSERT_TRUE(rightJoint);

  physics::GripperPtr gripper = model->GetGripper(0);
  ASSERT_TRUE(gripper);

  // The gripper should not be attached to anything
  EXPECT_FALSE(gripper->IsAttached());

  // Close the gripper.
  leftJoint->SetForce(0, -0.5);
  rightJoint->SetForce(0, 0.5);

  transport::PublisherPtr jointPub = this->node->Advertise<msgs::JointCmd>(
        "~/simple_gripper/joint_cmd");

  msgs::JointCmd msg;
  msg.set_name("simple_gripper::palm_right_finger");
  msg.set_force(0.6);
  jointPub->Publish(msg);

  msg.set_name("simple_gripper::palm_left_finger");
  msg.set_force(-0.6);
  jointPub->Publish(msg);

  int i = 0;
  while (!gripper->IsAttached() && i < 100)
  {
    common::Time::MSleep(500);
    ++i;
  }
  EXPECT_LT(i, 100);

  // The gripper should be attached.
  EXPECT_TRUE(gripper->IsAttached());

  // Open the gripper.
  msg.set_name("simple_gripper::palm_right_finger");
  msg.set_force(-0.6);
  jointPub->Publish(msg);

  msg.set_name("simple_gripper::palm_left_finger");
  msg.set_force(0.6);
  jointPub->Publish(msg);

  i = 0;
  while (gripper->IsAttached() && i < 100)
  {
    common::Time::MSleep(500);
    ++i;
  }
  EXPECT_LT(i, 100);

  // The gripper should release the box.
  EXPECT_FALSE(gripper->IsAttached());
}

/////////////////////////////////////////////////
int main(int argc, char **argv)
{
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}


text:
import * as passport from 'passport'
import * as Facebook from 'passport-facebook'

import {userService} from '~/server/service/user'
import {UserInstance} from '~/server/db/models/user'
const Mock = require('~/server/service/authentication/mock')
const {mockAuthentication} = require('~/server/config/index.js')

export interface IPassportConfig {
  clientID: string
  clientSecret: string
  callbackURL: string
}

const signInCallback = (
  profile: Facebook.Profile,
  done: (_e: any, user?: Facebook.Profile) => void
) => {
  const facebookId = profile.id
  userService
    .signIn(facebookId)
    .then((_u: UserInstance) => done(null, profile))
    .catch((e: any) => done(JSON.stringify(e)))
}

const setupFacebookStrategy = (options: IPassportConfig) => {
  const fbStrategy = new Facebook.Strategy(options, (_t, _rt, profile, done) => {
    signInCallback(profile, done)
  })
  passport.use(fbStrategy)
}

const setupMockStrategy = (options: IPassportConfig) => {
  const mockStrategy = new Mock.Strategy(options, signInCallback)
  passport.use(mockStrategy)
}

export const setupStrategy = (options: IPassportConfig) => {
  if (mockAuthentication) {
    setupMockStrategy(options)
  } else {
    setupFacebookStrategy(options)
  }

  /**
   * Determines which data of the user object should be stored in the session.
   * The result of the serializeUser method is attached to the session as
   * req.session.passport.user.
   **/
  passport.serializeUser((user, done) => {
    done(null, user)
  })

  /**
   * The first argument of deserializeUser corresponds to the key of the user
   * object that was given to the done function. So your whole object is
   * retrieved with help of that key. That key here is the user id (key can
   * be any key of the user object i.e. name, email etc). In deserializeUser
   * that key is matched with the in memory array / database or any data resource.
   **/
  passport.deserializeUser((user, done) => {
    done(null, user)
  })
}


text:
#ifndef _NETINET_CC_CUBIC_H_
#define _NETINET_CC_CUBIC_H_

/* Number of bits of precision for fixed point math calcs. */
#define	CUBIC_SHIFT		8

#define	CUBIC_SHIFT_4		32

/* 0.5 << CUBIC_SHIFT. */
#define	RENO_BETA		128

/* ~0.8 << CUBIC_SHIFT. */
#define	CUBIC_BETA		204

/* ~0.2 << CUBIC_SHIFT. */
#define	ONE_SUB_CUBIC_BETA	51

/* 3 * ONE_SUB_CUBIC_BETA. */
#define	THREE_X_PT2		153

/* (2 << CUBIC_SHIFT) - ONE_SUB_CUBIC_BETA. */
#define	TWO_SUB_PT2		461

/* ~0.4 << CUBIC_SHIFT. */
#define	CUBIC_C_FACTOR		102

/* CUBIC fast convergence factor: ~0.9 << CUBIC_SHIFT. */
#define	CUBIC_FC_FACTOR		230

/* Don't trust s_rtt until this many rtt samples have been taken. */
#define	CUBIC_MIN_RTT_SAMPLES	8

/* Userland only bits. */
#ifndef _KERNEL

extern int hz;

/*
 * Implementation based on the formulae found in the CUBIC Internet Draft
 * "draft-rhee-tcpm-cubic-02".
 *
 * Note BETA used in cc_cubic is equal to (1-beta) in the I-D
 */

static __inline float
theoretical_cubic_k(double wmax_pkts)
{
	double C;

	C = 0.4;

	return (pow((wmax_pkts * 0.2) / C, (1.0 / 3.0)) * pow(2, CUBIC_SHIFT));
}

static __inline unsigned long
theoretical_cubic_cwnd(int ticks_since_cong, unsigned long wmax, uint32_t smss)
{
	double C, wmax_pkts;

	C = 0.4;
	wmax_pkts = wmax / (double)smss;

	return (smss * (wmax_pkts +
	    (C * pow(ticks_since_cong / (double)hz -
	    theoretical_cubic_k(wmax_pkts) / pow(2, CUBIC_SHIFT), 3.0))));
}

static __inline unsigned long
theoretical_reno_cwnd(int ticks_since_cong, int rtt_ticks, unsigned long wmax,
    uint32_t smss)
{

	return ((wmax * 0.5) + ((ticks_since_cong / (float)rtt_ticks) * smss));
}

static __inline unsigned long
theoretical_tf_cwnd(int ticks_since_cong, int rtt_ticks, unsigned long wmax,
    uint32_t smss)
{

	return ((wmax * 0.8) + ((3 * 0.2) / (2 - 0.2) *
	    (ticks_since_cong / (float)rtt_ticks) * smss));
}

#endif /* !_KERNEL */

/*
 * Compute the CUBIC K value used in the cwnd calculation, using an
 * implementation of eqn 2 in the I-D. The method used
 * here is adapted from Apple Computer Technical Report #KT-32.
 */
static __inline int64_t
cubic_k(unsigned long wmax_pkts)
{
	int64_t s, K;
	uint16_t p;

	K = s = 0;
	p = 0;

	/* (wmax * beta)/C with CUBIC_SHIFT worth of precision. */
	s = ((wmax_pkts * ONE_SUB_CUBIC_BETA) << CUBIC_SHIFT) / CUBIC_C_FACTOR;

	/* Rebase s to be between 1 and 1/8 with a shift of CUBIC_SHIFT. */
	while (s >= 256) {
		s >>= 3;
		p++;
	}

	/*
	 * Some magic constants taken from the Apple TR with appropriate
	 * shifts: 275 == 1.072302 << CUBIC_SHIFT, 98 == 0.3812513 <<
	 * CUBIC_SHIFT, 120 == 0.46946116 << CUBIC_SHIFT.
	 */
	K = (((s * 275) >> CUBIC_SHIFT) + 98) -
	    (((s * s * 120) >> CUBIC_SHIFT) >> CUBIC_SHIFT);

	/* Multiply by 2^p to undo the rebasing of s from above. */
	return (K <<= p);
}

/*
 * Compute the new cwnd value using an implementation of eqn 1 from the I-D.
 * Thanks to Kip Macy for help debugging this function.
 *
 * XXXLAS: Characterise bounds for overflow.
 */
static __inline unsigned long
cubic_cwnd(int ticks_since_cong, unsigned long wmax, uint32_t smss, int64_t K)
{
	int64_t cwnd;

	/* K is in fixed point form with CUBIC_SHIFT worth of precision. */

	/* t - K, with CUBIC_SHIFT worth of precision. */
	cwnd = ((int64_t)(ticks_since_cong << CUBIC_SHIFT) - (K * hz)) / hz;

	/* (t - K)^3, with CUBIC_SHIFT^3 worth of precision. */
	cwnd *= (cwnd * cwnd);

	/*
	 * C(t - K)^3 + wmax
	 * The down shift by CUBIC_SHIFT_4 is because cwnd has 4 lots of
	 * CUBIC_SHIFT included in the value. 3 from the cubing of cwnd above,
	 * and an extra from multiplying through by CUBIC_C_FACTOR.
	 */
	cwnd = ((cwnd * CUBIC_C_FACTOR * smss) >> CUBIC_SHIFT_4) + wmax;

	return ((unsigned long)cwnd);
}

/*
 * Compute an approximation of the NewReno cwnd some number of ticks after a
 * congestion event. RTT should be the average RTT estimate for the path
 * measured over the previous congestion epoch and wmax is the value of cwnd at
 * the last congestion event. The "TCP friendly" concept in the CUBIC I-D is
 * rather tricky to understand and it turns out this function is not required.
 * It is left here for reference.
 */
static __inline unsigned long
reno_cwnd(int ticks_since_cong, int rtt_ticks, unsigned long wmax,
    uint32_t smss)
{

	/*
	 * For NewReno, beta = 0.5, therefore: W_tcp(t) = wmax*0.5 + t/RTT
	 * W_tcp(t) deals with cwnd/wmax in pkts, so because our cwnd is in
	 * bytes, we have to multiply by smss.
	 */
	return (((wmax * RENO_BETA) + (((ticks_since_cong * smss)
	    << CUBIC_SHIFT) / rtt_ticks)) >> CUBIC_SHIFT);
}

/*
 * Compute an approximation of the "TCP friendly" cwnd some number of ticks
 * after a congestion event that is designed to yield the same average cwnd as
 * NewReno while using CUBIC's beta of 0.8. RTT should be the average RTT
 * estimate for the path measured over the previous congestion epoch and wmax is
 * the value of cwnd at the last congestion event.
 */
static __inline unsigned long
tf_cwnd(int ticks_since_cong, int rtt_ticks, unsigned long wmax,
    uint32_t smss)
{

	/* Equation 4 of I-D. */
	return (((wmax * CUBIC_BETA) + (((THREE_X_PT2 * ticks_since_cong *
	    smss) << CUBIC_SHIFT) / TWO_SUB_PT2 / rtt_ticks)) >> CUBIC_SHIFT);
}

#endif /* _NETINET_CC_CUBIC_H_ */


text:
import uuid

import prettytable

from keystoneclient import exceptions

# Decorator for cli-args
def arg(*args, **kwargs):
    def _decorator(func):
        # Because of the sematics of decorator composition if we just append
        # to the options list positional options will appear to be backwards.
        func.__dict__.setdefault('arguments', []).insert(0, (args, kwargs))
        return func
    return _decorator

def pretty_choice_list(l):
    return ', '.join("'%s'" % i for i in l)

def print_list(objs, fields, formatters={}):
    pt = prettytable.PrettyTable([f for f in fields], caching=False)
    pt.aligns = ['l' for f in fields]

    for o in objs:
        row = []
        for field in fields:
            if field in formatters:
                row.append(formatters[field](o))
            else:
                field_name = field.lower().replace(' ', '_')
                data = getattr(o, field_name, '')
                if data is None:
                    data = ''
                row.append(data)
        pt.add_row(row)

    print pt.get_string(sortby=fields[0])

def print_dict(d):
    pt = prettytable.PrettyTable(['Property', 'Value'], caching=False)
    pt.aligns = ['l', 'l']
    for (prop, value) in d.iteritems():
        if value is None:
            value = ''
        pt.add_row([prop, value])
    print pt.get_string(sortby='Property')

def find_resource(manager, name_or_id):
    """Helper for the _find_* methods."""
    # first try to get entity as integer id
    try:
        if isinstance(name_or_id, int) or name_or_id.isdigit():
            return manager.get(int(name_or_id))
    except exceptions.NotFound:
        pass

    # now try to get entity as uuid
    try:
        uuid.UUID(str(name_or_id))
        return manager.get(name_or_id)
    except (ValueError, exceptions.NotFound):
        pass

    # finally try to find entity by name
    try:
        return manager.find(name=name_or_id)
    except exceptions.NotFound:
        msg = ("No %s with a name or ID of '%s' exists." %
               (manager.resource_class.__name__.lower(), name_or_id))
        raise exceptions.CommandError(msg)

def unauthenticated(f):
    """ Adds 'unauthenticated' attribute to decorated function.

    Usage:
        @unauthenticated
        def mymethod(f):
            ...
    """
    f.unauthenticated = True
    return f

def isunauthenticated(f):
    """
    Checks to see if the function is marked as not requiring authentication
    with the @unauthenticated decorator. Returns True if decorator is
    set to True, False otherwise.
    """
    return getattr(f, 'unauthenticated', False)

def string_to_bool(arg):
    if isinstance(arg, bool):
        return arg

    return arg.strip().lower() in ('t', 'true', 'yes', '1')


text:
/////// Module
////{| "itemName": "Shapes", "kind": "module", "parentName": "" |}module Shapes {
////
////    // Class
////    {| "itemName": "Point", "kind": "class", "parentName": "Shapes" |}export class Point {
////        // Instance member
////        {| "itemName": "originality", "kind": "property", "parentName": "Point", "matchKind": "prefix"|}private originality = 0.0;
////
////        {| "itemName": "distanceFromOrig", "kind": "property", "parentName": "Point", "matchKind": "prefix"|}private distanceFromOrig = 0.0;
////
////        // Getter
////        {| "itemName": "distanceFarFarAway", "kind": "getter", "parentName": "Point", "matchKind": "prefix" |}get distanceFarFarAway(): number { return 0; }
////    }
////}
////
////// Local variables
////{| "itemName": "pointsSquareBox", "kind": "var", "parentName": "", "matchKind": "prefix"  |}var pointsSquareBox = new Shapes.Point();

//// Testing for exact matching of navigationItems
// var searchValue = "origin distance points shape";

test.markers().forEach((marker) => {
    if (marker.data) {
        var itemName = marker.data.itemName;
        verify.navigationItemsListContains(itemName, marker.data.kind, itemName.substr(0, itemName.length - 1), marker.data.matchKind, marker.fileName, marker.data.parentName);
    }
});


text:
using System;

namespace System.Xml.Linq
{
	[Flags]
	internal enum SaveOptions
	{
		None = 0,
		DisableFormatting = 1,
#if NET_4_0
		OmitDuplicateNamespaces = 2
#endif
	}
}


text:
"""add datetime to forum models

Revision ID: f3927c7ad77e
Revises: e32bf2e2b443
Create Date: 2016-11-24 01:44:05.894107

"""
from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = 'f3927c7ad77e'
down_revision = 'e32bf2e2b443'
branch_labels = None
depends_on = None

def upgrade():
    ### commands auto generated by Alembic - please adjust! ###
    op.add_column('forum_replies', sa.Column('create_datetime', sa.DateTime()))
    op.add_column('forum_topics', sa.Column('create_datetime', sa.DateTime()))
    ### end Alembic commands ###

def downgrade():
    ### commands auto generated by Alembic - please adjust! ###
    op.drop_column('forum_topics', 'create_datetime')
    op.drop_column('forum_replies', 'create_datetime')
    ### end Alembic commands ###


text:
<?php echo @$title; ?>

			<form action="" method="POST" role="form" class="form-horizontal" data-provide="validation">

Group Name

						<input type="text" name="name" placeholder="name" class="form-control" value="<?php echo set_value('name', $detail['name']); ?>" required>
						<?php echo form_error('name'); ?>

Group Description

						<input type="text" name="description" placeholder="description" class="form-control" value="<?php echo set_value('description', $detail['description']); ?>" required>
						<?php echo form_error('description'); ?>

Status

						<select name="status" class="show-tick form-control" data-provide="selectpicker_bak" style="width: 100%" required>

              <option value="0" <?php if ($detail['status']==0) { echo "selected=''"; }  ?> >Aktif</option>
              <option value="1" <?php if ($detail['status']==1) { echo "selected=''"; }  ?> >Non Aktif</option>

            </select>
						<?php echo form_error('status'); ?>

						<a href="<?php echo site_url('role/lists'); ?>" class="btn btn-secondary">Cancel
						<button class="btn btn-primary" type="submit">Save</button>

			</form>


text:
<title>strchr - Untitled</title>
<meta http-equiv="Content-Type" content="text/html">
<meta name="description" content="Untitled">
<meta name="generator" content="makeinfo 4.11">
<link title="Top" rel="start" href="index.html#Top">
<link rel="up" href="Strings.html#Strings" title="Strings">
<link rel="prev" href="strcat.html#strcat" title="strcat">
<link rel="next" href="strcmp.html#strcmp" title="strcmp">
<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
<meta http-equiv="Content-Style-Type" content="text/css">

Next: strcmp,
Previous: strcat,
Up: Strings

5.19 strchr—search for character in string

Synopsis

     #include <string.h>
     char * strchr(const char *<var>string</var>, int <var>c</var>);

Description

This function finds the first occurence of <var>c</var> (converted to
a char) in the string pointed to by <var>string</var> (including the
terminating null character).

Returns

Returns a pointer to the located character, or a null pointer
if <var>c</var> does not occur in <var>string</var>.

Portability

strchr is ANSI C.

strchr requires no supporting OS subroutines.


text:
---
layout: default
---

{{ page.title }}

<time datetime="{{ page.date | date_to_xmlschema }}" itemprop="datePublished">{{ page.date | date: "%d.%m.%Y" }}</time>{% if page.author %} • {{ page.author }}{% endif %}

    {{ content }}

  {% if page.comments_enabled == 1 %}

    Please enable JavaScript to view the comments powered by Disqus.
  {% endif %}


text:
package io.syndesis.qe.pages.integrations.editor.add.connection.actions.jms;

import static com.codeborne.selenide.Condition.visible;

import org.openqa.selenium.By;

import io.syndesis.qe.pages.integrations.editor.add.connection.actions.fragments.FieldFiller;
import lombok.extern.slf4j.Slf4j;

/**
 * Created by sveres on 12/19/17.
 */
@Slf4j
public class JmsPublish extends FieldFiller {

    private static final class Element {
        public static final By TITLE = By.cssSelector("div[innertext='Publish Messages']");
    }

    private static final class Input {
        public static final By DESTINATION_NAME = By.id("destinationName");
        public static final By PERSISTENT = By.id("persistent");
    }

    private static final class Select {
        public static final By DESTINATION_TYPE = By.id("destinationType");
    }

    @Override
    public boolean validate() {
        return this.getRootElement().find(Element.TITLE).is(visible);
    }

    @Override
    public Class getInputClass() {
        return JmsPublish.Input.class;
    }

    @Override
    public Class getSelectClass() {
        return JmsPublish.Select.class;
    }
}