def test_get_nonexistent_interface_raises(self):
        self.switch.in_transaction = False
        self.netconf_mock.should_receive("get_config").with_args(
            source="running",
            filter=is_xml(
                """
                    <filter>
                      <configuration>
                          <interfaces>
                            <interface>
                              <name>ge-0/0/INEXISTENT</name>
                            </interface>
                          </interfaces>
                        <vlans />
                      </configuration>
                    </filter>
                """
            ),
        ).and_return(
            a_configuration(
                """
                    <interfaces/>
                    <vlans/>
                """
            )
        )
        self.netconf_mock.should_receive("rpc").with_args(
            is_xml(
                """
                    <get-interface-information>
                      <terse/>
                    </get-interface-information>
                """
            )
        ).and_return(
            an_rpc_response(
                textwrap.dedent(
                    """
                    <interface-information style="terse">
                      <physical-interface>
                        <name>
                    ge-0/0/1
                    </name>
                        <admin-status>
                    down
                    </admin-status>
                        <oper-status>
                    down
                    </oper-status>
                      </physical-interface>
                    </interface-information>
                """
                )
            )
        )

        with self.assertRaises(UnknownInterface) as expect:
            self.switch.get_interface("ge-0/0/INEXISTENT")

        assert_that(str(expect.exception), equal_to("Unknown interface ge-0/0/INEXISTENT"))
    def test_get_nonexistent_interface_raises(self):
        self.switch.in_transaction = False
        self.netconf_mock.should_receive("get_config").with_args(
            source="running",
            filter=is_xml("""
                    <filter>
                      <configuration>
                          <interfaces>
                            <interface>
                              <name>ge-0/0/INEXISTENT</name>
                            </interface>
                          </interfaces>
                        <vlans />
                      </configuration>
                    </filter>
                """)).and_return(
                a_configuration("""
                    <interfaces/>
                    <vlans/>
                """))
        self.netconf_mock.should_receive("rpc").with_args(
            is_xml("""
                    <get-interface-information>
                      <terse/>
                    </get-interface-information>
                """)).and_return(
                an_rpc_response(
                    textwrap.dedent("""
                    <interface-information style="terse">
                      <physical-interface>
                        <name>
                    ge-0/0/1
                    </name>
                        <admin-status>
                    down
                    </admin-status>
                        <oper-status>
                    down
                    </oper-status>
                      </physical-interface>
                    </interface-information>
                """)))

        with self.assertRaises(UnknownInterface) as expect:
            self.switch.get_interface('ge-0/0/INEXISTENT')

        assert_that(str(expect.exception),
                    equal_to("Unknown interface ge-0/0/INEXISTENT"))
    def test_get_interfaces(self):
        self.switch.in_transaction = False

        self.netconf_mock.should_receive("rpc").with_args(
            is_xml("""
                    <get-interface-information>
                      <terse/>
                    </get-interface-information>
                """)).and_return(
                an_rpc_response(
                    textwrap.dedent("""
                    <interface-information style="terse">
                      <physical-interface>
                        <name>
                    ge-0/0/1
                    </name>
                        <admin-status>
                    up
                    </admin-status>
                        <oper-status>
                    down
                    </oper-status>
                        <logical-interface>
                          <name>
                    ge-0/0/1.0
                    </name>
                          <admin-status>
                    up
                    </admin-status>
                          <oper-status>
                    down
                    </oper-status>
                          <filter-information>
                          </filter-information>
                          <address-family>
                            <address-family-name>
                    eth-switch
                    </address-family-name>
                          </address-family>
                        </logical-interface>
                      </physical-interface>
                      <physical-interface>
                        <name>
                    ge-0/0/2
                    </name>
                        <admin-status>
                    down
                    </admin-status>
                        <oper-status>
                    down
                    </oper-status>
                        <logical-interface>
                          <name>
                    ge-0/0/2.0
                    </name>
                          <admin-status>
                    up
                    </admin-status>
                          <oper-status>
                    down
                    </oper-status>
                          <filter-information>
                          </filter-information>
                          <address-family>
                            <address-family-name>
                    eth-switch
                    </address-family-name>
                          </address-family>
                        </logical-interface>
                      </physical-interface>
                      <physical-interface>
                        <name>
                    ge-0/0/3
                    </name>
                        <admin-status>
                    up
                    </admin-status>
                        <oper-status>
                    down
                    </oper-status>
                        <logical-interface>
                          <name>
                    ge-0/0/3.0
                    </name>
                          <admin-status>
                    up
                    </admin-status>
                          <oper-status>
                    down
                    </oper-status>
                          <filter-information>
                          </filter-information>
                          <address-family>
                            <address-family-name>
                    eth-switch
                    </address-family-name>
                          </address-family>
                        </logical-interface>
                      </physical-interface>
                      <physical-interface>
                        <name>
                    ge-0/0/4
                    </name>
                        <admin-status>
                    up
                    </admin-status>
                        <oper-status>
                    down
                    </oper-status>
                        <logical-interface>
                          <name>
                    ge-0/0/4.0
                    </name>
                          <admin-status>
                    up
                    </admin-status>
                          <oper-status>
                    down
                    </oper-status>
                          <filter-information>
                          </filter-information>
                          <address-family>
                            <address-family-name>
                    eth-switch
                    </address-family-name>
                          </address-family>
                        </logical-interface>
                      </physical-interface>
                      <physical-interface>
                        <name>
                    ge-0/0/5
                    </name>
                        <admin-status>
                    up
                    </admin-status>
                        <oper-status>
                    down
                    </oper-status>
                      </physical-interface>
                    </interface-information>
                """)))

        self.netconf_mock.should_receive("get_config").with_args(
            source="running",
            filter=is_xml("""
            <filter>
              <configuration>
                <interfaces />
                <vlans />
              </configuration>
            </filter>
        """)).and_return(
                a_configuration("""
            <interfaces>
              <interface>
                <name>ge-0/0/1</name>
                <unit>
                  <name>0</name>
                  <family>
                    <ethernet-switching>
                    </ethernet-switching>
                  </family>
                </unit>
              </interface>
              <interface>
                <name>ge-0/0/2</name>
                <disable />
                <description>Howdy</description>
                <unit>
                  <name>0</name>
                  <family>
                    <ethernet-switching>
                      <vlan>
                        <members>1000</members>
                      </vlan>
                    </ethernet-switching>
                  </family>
                </unit>
              </interface>
              <interface>
                <name>ge-0/0/3</name>
                <native-vlan-id>2000</native-vlan-id>
                <unit>
                  <name>0</name>
                  <family>
                    <ethernet-switching>
                      <interface-mode>trunk</interface-mode>
                      <vlan>
                        <members>999-1001</members>
                        <members>1000</members>
                      </vlan>
                    </ethernet-switching>
                  </family>
                </unit>
              </interface>
              <interface>
                <name>ge-0/0/4</name>
                <ether-options>
                  <no-auto-negotiation/>
                </ether-options>
                <unit>
                  <name>0</name>
                  <family>
                    <ethernet-switching>
                      <interface-mode>trunk</interface-mode>
                    </ethernet-switching>
                  </family>
                </unit>
              </interface>
              <interface>
                <name>ge-0/0/5</name>
                <ether-options>
                  <auto-negotiation/>
                  <ieee-802.3ad>
                    <bundle>ae10</bundle>
                  </ieee-802.3ad>
                </ether-options>
              </interface>
              <interface>
                <name>vlan</name>
                <unit>
                  <name>40</name>
                </unit>
              </interface>
              <interface>
                <name>ae10</name>
                <aggregated-ether-options>
                  <lacp>
                    <active/>
                    <periodic>slow</periodic>
                  </lacp>
                </aggregated-ether-options>
                <unit>
                  <name>0</name>
                  <family>
                    <ethernet-switching />
                  </family>
                </unit>
              </interface>
            </interfaces>
            <vlans/>
        """))

        if1, if2, if3, if4, if5 = self.switch.get_interfaces()

        assert_that(if1.name, equal_to("ge-0/0/1"))
        assert_that(if1.shutdown, equal_to(False))
        assert_that(if1.port_mode, equal_to(ACCESS))
        assert_that(if1.access_vlan, equal_to(None))
        assert_that(if1.trunk_native_vlan, equal_to(None))
        assert_that(if1.trunk_vlans, equal_to([]))
        assert_that(if1.auto_negotiation, equal_to(None))

        assert_that(if2.name, equal_to("ge-0/0/2"))
        assert_that(if2.shutdown, equal_to(True))
        assert_that(if2.port_mode, equal_to(ACCESS))
        assert_that(if2.access_vlan, equal_to(1000))
        assert_that(if2.trunk_native_vlan, equal_to(None))
        assert_that(if2.trunk_vlans, equal_to([]))

        assert_that(if3.name, equal_to("ge-0/0/3"))
        assert_that(if3.port_mode, equal_to(TRUNK))
        assert_that(if3.access_vlan, equal_to(None))
        assert_that(if3.trunk_native_vlan, equal_to(2000))
        assert_that(if3.trunk_vlans, equal_to([999, 1000, 1001]))

        assert_that(if4.name, equal_to("ge-0/0/4"))
        assert_that(if4.trunk_native_vlan, equal_to(None))
        assert_that(if4.trunk_vlans, equal_to([]))
        assert_that(if4.auto_negotiation, equal_to(False))

        assert_that(if5.name, equal_to("ge-0/0/5"))
        assert_that(if5.port_mode, equal_to(BOND_MEMBER))
        assert_that(if5.bond_master, equal_to(10))
        assert_that(if5.auto_negotiation, equal_to(True))
    def test_get_interfaces(self):
        self.switch.in_transaction = False

        self.netconf_mock.should_receive("rpc").with_args(
            is_xml(
                """
                    <get-interface-information>
                      <terse/>
                    </get-interface-information>
                """
            )
        ).and_return(
            an_rpc_response(
                textwrap.dedent(
                    """
                    <interface-information style="terse">
                      <physical-interface>
                        <name>
                    ge-0/0/1
                    </name>
                        <admin-status>
                    up
                    </admin-status>
                        <oper-status>
                    down
                    </oper-status>
                        <logical-interface>
                          <name>
                    ge-0/0/1.0
                    </name>
                          <admin-status>
                    up
                    </admin-status>
                          <oper-status>
                    down
                    </oper-status>
                          <filter-information>
                          </filter-information>
                          <address-family>
                            <address-family-name>
                    eth-switch
                    </address-family-name>
                          </address-family>
                        </logical-interface>
                      </physical-interface>
                      <physical-interface>
                        <name>
                    ge-0/0/2
                    </name>
                        <admin-status>
                    down
                    </admin-status>
                        <oper-status>
                    down
                    </oper-status>
                        <logical-interface>
                          <name>
                    ge-0/0/2.0
                    </name>
                          <admin-status>
                    up
                    </admin-status>
                          <oper-status>
                    down
                    </oper-status>
                          <filter-information>
                          </filter-information>
                          <address-family>
                            <address-family-name>
                    eth-switch
                    </address-family-name>
                          </address-family>
                        </logical-interface>
                      </physical-interface>
                      <physical-interface>
                        <name>
                    ge-0/0/3
                    </name>
                        <admin-status>
                    up
                    </admin-status>
                        <oper-status>
                    down
                    </oper-status>
                        <logical-interface>
                          <name>
                    ge-0/0/3.0
                    </name>
                          <admin-status>
                    up
                    </admin-status>
                          <oper-status>
                    down
                    </oper-status>
                          <filter-information>
                          </filter-information>
                          <address-family>
                            <address-family-name>
                    eth-switch
                    </address-family-name>
                          </address-family>
                        </logical-interface>
                      </physical-interface>
                      <physical-interface>
                        <name>
                    ge-0/0/4
                    </name>
                        <admin-status>
                    up
                    </admin-status>
                        <oper-status>
                    down
                    </oper-status>
                        <logical-interface>
                          <name>
                    ge-0/0/4.0
                    </name>
                          <admin-status>
                    up
                    </admin-status>
                          <oper-status>
                    down
                    </oper-status>
                          <filter-information>
                          </filter-information>
                          <address-family>
                            <address-family-name>
                    eth-switch
                    </address-family-name>
                          </address-family>
                        </logical-interface>
                      </physical-interface>
                      <physical-interface>
                        <name>
                    ge-0/0/5
                    </name>
                        <admin-status>
                    up
                    </admin-status>
                        <oper-status>
                    down
                    </oper-status>
                      </physical-interface>
                    </interface-information>
                """
                )
            )
        )

        self.netconf_mock.should_receive("get_config").with_args(
            source="running",
            filter=is_xml(
                """
            <filter>
              <configuration>
                <interfaces />
                <vlans />
              </configuration>
            </filter>
        """
            ),
        ).and_return(
            a_configuration(
                """
            <interfaces>
              <interface>
                <name>ge-0/0/1</name>
                <unit>
                  <name>0</name>
                  <family>
                    <ethernet-switching>
                    </ethernet-switching>
                  </family>
                </unit>
              </interface>
              <interface>
                <name>ge-0/0/2</name>
                <disable />
                <description>Howdy</description>
                <unit>
                  <name>0</name>
                  <family>
                    <ethernet-switching>
                      <vlan>
                        <members>1000</members>
                      </vlan>
                    </ethernet-switching>
                  </family>
                </unit>
              </interface>
              <interface>
                <name>ge-0/0/3</name>
                <native-vlan-id>2000</native-vlan-id>
                <unit>
                  <name>0</name>
                  <family>
                    <ethernet-switching>
                      <interface-mode>trunk</interface-mode>
                      <vlan>
                        <members>999-1001</members>
                        <members>1000</members>
                      </vlan>
                    </ethernet-switching>
                  </family>
                </unit>
              </interface>
              <interface>
                <name>ge-0/0/4</name>
                <ether-options>
                  <no-auto-negotiation/>
                </ether-options>
                <unit>
                  <name>0</name>
                  <family>
                    <ethernet-switching>
                      <interface-mode>trunk</interface-mode>
                    </ethernet-switching>
                  </family>
                </unit>
              </interface>
              <interface>
                <name>ge-0/0/5</name>
                <ether-options>
                  <auto-negotiation/>
                  <ieee-802.3ad>
                    <bundle>ae10</bundle>
                  </ieee-802.3ad>
                </ether-options>
              </interface>
              <interface>
                <name>vlan</name>
                <unit>
                  <name>40</name>
                </unit>
              </interface>
              <interface>
                <name>ae10</name>
                <aggregated-ether-options>
                  <lacp>
                    <active/>
                    <periodic>slow</periodic>
                  </lacp>
                </aggregated-ether-options>
                <unit>
                  <name>0</name>
                  <family>
                    <ethernet-switching />
                  </family>
                </unit>
              </interface>
            </interfaces>
            <vlans/>
        """
            )
        )

        if1, if2, if3, if4, if5 = self.switch.get_interfaces()

        assert_that(if1.name, equal_to("ge-0/0/1"))
        assert_that(if1.shutdown, equal_to(False))
        assert_that(if1.port_mode, equal_to(ACCESS))
        assert_that(if1.access_vlan, equal_to(None))
        assert_that(if1.trunk_native_vlan, equal_to(None))
        assert_that(if1.trunk_vlans, equal_to([]))
        assert_that(if1.auto_negotiation, equal_to(None))

        assert_that(if2.name, equal_to("ge-0/0/2"))
        assert_that(if2.shutdown, equal_to(True))
        assert_that(if2.port_mode, equal_to(ACCESS))
        assert_that(if2.access_vlan, equal_to(1000))
        assert_that(if2.trunk_native_vlan, equal_to(None))
        assert_that(if2.trunk_vlans, equal_to([]))

        assert_that(if3.name, equal_to("ge-0/0/3"))
        assert_that(if3.port_mode, equal_to(TRUNK))
        assert_that(if3.access_vlan, equal_to(None))
        assert_that(if3.trunk_native_vlan, equal_to(2000))
        assert_that(if3.trunk_vlans, equal_to([999, 1000, 1001]))

        assert_that(if4.name, equal_to("ge-0/0/4"))
        assert_that(if4.trunk_native_vlan, equal_to(None))
        assert_that(if4.trunk_vlans, equal_to([]))
        assert_that(if4.auto_negotiation, equal_to(False))

        assert_that(if5.name, equal_to("ge-0/0/5"))
        assert_that(if5.port_mode, equal_to(BOND_MEMBER))
        assert_that(if5.bond_master, equal_to(10))
        assert_that(if5.auto_negotiation, equal_to(True))