From 81b1a1fa6483b51964aac17c8750b856a6c44d6b Mon Sep 17 00:00:00 2001 From: nitin kumar Date: Thu, 22 Sep 2016 16:59:05 +0530 Subject: [PATCH 1/9] First commit for nssu & issu spport --- lib/jnpr/junos/utils/sw.py | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/lib/jnpr/junos/utils/sw.py b/lib/jnpr/junos/utils/sw.py index af20f4155..4703b518f 100644 --- a/lib/jnpr/junos/utils/sw.py +++ b/lib/jnpr/junos/utils/sw.py @@ -169,7 +169,12 @@ def pkgadd(self, remote_package, **kvargs): args = dict(no_validate=True, package_name=remote_package) args.update(kvargs) - rsp = self.rpc.request_package_add(**args) + if kvargs.get('issu', False): + rsp = self.rpc.request_package_in_service_upgrade(**args) + elif kvargs.get('nssu', False): + rsp = self.rpc.request_package_nonstop_upgrade(**args) + else: + rsp = self.rpc.request_package_add(**args) got = rsp.getparent() rc = int(got.findtext('package-result').strip()) @@ -384,7 +389,23 @@ def myprogress(dev, report): :param bool force_host: (Optional) Force the addition of host software package or bundle (ignore warnings) on the QFX5100 device. + + :param bool issu: + (Optional) When ``True`` allows unified in-service software upgrade + (ISSU) feature enables you to upgrade between two different Junos OS + releases with no disruption on the control plane and with minimal + disruption of traffic. + + :param bool nssu: + (Optional) When ``True`` allows nonstop software upgrade (NSSU) + enables you to upgrade the software running on a Juniper Networks + EX Series Virtual Chassis or a Juniper Networks EX Series Ethernet + Switch with redundant Routing Engines with a single command and minimal + disruption to network traffic. """ + if kwargs.get('issu', False) and kwargs.get('nssu', False): + raise TypeError('install function can either take issu or nssu') + def _progress(report): if progress is True: self.progress(self._dev, report) From e23e3326905cfe3ff2695e85cdc2126b58b64c71 Mon Sep 17 00:00:00 2001 From: nitin kumar Date: Fri, 23 Sep 2016 14:03:26 +0530 Subject: [PATCH 2/9] code changes for pkgadd, validation function to support issu, nssu --- lib/jnpr/junos/utils/sw.py | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/lib/jnpr/junos/utils/sw.py b/lib/jnpr/junos/utils/sw.py index 4703b518f..dc4c246ff 100644 --- a/lib/jnpr/junos/utils/sw.py +++ b/lib/jnpr/junos/utils/sw.py @@ -170,8 +170,10 @@ def pkgadd(self, remote_package, **kvargs): args.update(kvargs) if kvargs.get('issu', False): + kvargs.pop('issu') # Removing issu=True from kwargs rsp = self.rpc.request_package_in_service_upgrade(**args) elif kvargs.get('nssu', False): + kvargs.pop('nssu') # Removing nssu=True from kwargs rsp = self.rpc.request_package_nonstop_upgrade(**args) else: rsp = self.rpc.request_package_add(**args) @@ -195,8 +197,15 @@ def validate(self, remote_package, **kwargs): * ``True`` if validation passes * error (str) otherwise """ - rsp = self.rpc.request_package_validate( - package_name=remote_package, **kwargs).getparent() + if kwargs.get('nssu', False): + kwargs.pop('nssu') # Removing nssu=True from kwargs + if kwargs.get('issu', False): + kwargs.pop('issu') # Removing issu=True from kwargs + rsp = self.rpc.check_in_service_upgrade( + package_name=remote_package, **kwargs).getparent() + else: + rsp = self.rpc.request_package_validate( + package_name=remote_package, **kwargs).getparent() errcode = int(rsp.findtext('package-result')) return True if 0 == errcode else rsp.findtext('output').strip() @@ -402,9 +411,13 @@ def myprogress(dev, report): EX Series Virtual Chassis or a Juniper Networks EX Series Ethernet Switch with redundant Routing Engines with a single command and minimal disruption to network traffic. + + :returns: + * ``True`` when the installation is successful + * ``False`` otherwise """ if kwargs.get('issu', False) and kwargs.get('nssu', False): - raise TypeError('install function can either take issu or nssu') + raise TypeError('install function can either take issu or nssu not both') def _progress(report): if progress is True: @@ -452,8 +465,11 @@ def _progress(report): "validating software against current config," " please be patient ...") v_ok = self.validate(remote_package, dev_timeout=timeout) + if v_ok is not True: - return v_ok # will be the string of output + # will be the string of output + _progress("software validation message: %s"%v_ok) + return False if self._multi_RE is False: # simple case of device with only one RE From fc445c56cfbe08f0dd51d8c2ce77de7da74a4750 Mon Sep 17 00:00:00 2001 From: nitin kumar Date: Tue, 27 Sep 2016 13:50:57 +0530 Subject: [PATCH 3/9] final code for issu upgrade --- lib/jnpr/junos/utils/sw.py | 98 ++++++++++++++++++++++++++------------ 1 file changed, 68 insertions(+), 30 deletions(-) diff --git a/lib/jnpr/junos/utils/sw.py b/lib/jnpr/junos/utils/sw.py index dc4c246ff..4b17257ec 100644 --- a/lib/jnpr/junos/utils/sw.py +++ b/lib/jnpr/junos/utils/sw.py @@ -62,6 +62,7 @@ def __init__(self, dev): self._multi_RE is True and dev.facts.get('vc_capable') is True and dev.facts.get('vc_mode') != 'Disabled') self._mixed_VC = bool(dev.facts.get('vc_mode') == 'Mixed') + self.log = lambda report : None # ----------------------------------------------------------------------- # CLASS METHODS @@ -169,45 +170,72 @@ def pkgadd(self, remote_package, **kvargs): args = dict(no_validate=True, package_name=remote_package) args.update(kvargs) - if kvargs.get('issu', False): - kvargs.pop('issu') # Removing issu=True from kwargs - rsp = self.rpc.request_package_in_service_upgrade(**args) - elif kvargs.get('nssu', False): - kvargs.pop('nssu') # Removing nssu=True from kwargs - rsp = self.rpc.request_package_nonstop_upgrade(**args) - else: - rsp = self.rpc.request_package_add(**args) + rsp = self.rpc.request_package_add(**args) + return self._parse_pkgadd_response(rsp) + + + # ------------------------------------------------------------------------- + # pkgaddNSSU - used to perform NSSU upgrade + # ------------------------------------------------------------------------- + + def pkgaddNSSU(self, remote_package, **kvargs): + """ + Issue the 'request system software nonstop-upgrade' command on the package. + + :param str remote_package: + The file-path to the install package on the remote (Junos) device. + """ + + rsp = self.rpc.request_package_nonstop_upgrade( + package_name=remote_package, **kvargs) + return self._parse_pkgadd_response(rsp) + + # ------------------------------------------------------------------------- + # pkgaddISSU - used to perform ISSU upgrade + # ------------------------------------------------------------------------- + def pkgaddISSU(self, remote_package, **kvargs): + """ + Issue the 'request system software nonstop-upgrade' command on the package. + + :param str remote_package: + The file-path to the install package on the remote (Junos) device. + """ + + rsp = self.rpc.request_package_in_service_upgrade( + package_name=remote_package, **kvargs) + return self._parse_pkgadd_response(rsp) + + def _parse_pkgadd_response(self, rsp): got = rsp.getparent() rc = int(got.findtext('package-result').strip()) - - # return True if rc == 0 else got.findtext('output').strip() - return True if rc == 0 else False + if rc != 0: + self.log("software pkgadd message: %s" % got.findtext('output')) + return rc == 0 # ------------------------------------------------------------------------- # validate - perform 'request' operation to validate the package # ------------------------------------------------------------------------- - def validate(self, remote_package, **kwargs): + def validate(self, remote_package, issu=False, **kwargs): """ Issues the 'request' operation to validate the package against the config. :returns: - * ``True`` if validation passes - * error (str) otherwise + * ``True`` if validation passes. i.e return code (rc) value is 0 + * * ``False`` otherwise """ - if kwargs.get('nssu', False): - kwargs.pop('nssu') # Removing nssu=True from kwargs - if kwargs.get('issu', False): - kwargs.pop('issu') # Removing issu=True from kwargs + if issu: rsp = self.rpc.check_in_service_upgrade( package_name=remote_package, **kwargs).getparent() else: rsp = self.rpc.request_package_validate( package_name=remote_package, **kwargs).getparent() - errcode = int(rsp.findtext('package-result')) - return True if 0 == errcode else rsp.findtext('output').strip() + rc = int(rsp.findtext('package-result')) + if rc != 0: + self.log("software validation message: %s" % rsp.findtext('output')) + return 0 == rc def remote_checksum(self, remote_package, timeout=300): """ @@ -312,8 +340,8 @@ def _progress(report): # ------------------------------------------------------------------------- def install(self, package=None, pkg_set=None, remote_path='/var/tmp', progress=None, - validate=False, checksum=None, cleanfs=True, no_copy=False, - timeout=1800, **kwargs): + validate=False, checksum=None, cleanfs=True, no_copy=False, issu=False, + nssu=False, timeout=1800, **kwargs): """ Performs the complete installation of the **package** that includes the following steps: @@ -416,8 +444,9 @@ def myprogress(dev, report): * ``True`` when the installation is successful * ``False`` otherwise """ - if kwargs.get('issu', False) and kwargs.get('nssu', False): - raise TypeError('install function can either take issu or nssu not both') + if issu is True and nssu is True: + raise TypeError( + 'install function can either take issu or nssu not both') def _progress(report): if progress is True: @@ -425,6 +454,8 @@ def _progress(report): elif callable(progress): progress(self._dev, report) + self.log = _progress + # --------------------------------------------------------------------- # perform a 'safe-copy' of the image to the remote device # --------------------------------------------------------------------- @@ -464,14 +495,21 @@ def _progress(report): _progress( "validating software against current config," " please be patient ...") - v_ok = self.validate(remote_package, dev_timeout=timeout) + v_ok = self.validate(remote_package, issu, dev_timeout=timeout, + **kwargs) if v_ok is not True: - # will be the string of output - _progress("software validation message: %s"%v_ok) - return False - - if self._multi_RE is False: + return v_ok + + if issu is True: + _progress("ISSU: installing software ... please be patient ...") + return self.pkgaddISSU(remote_package, + dev_timeout=timeout, **kwargs) + elif nssu is True: + _progress("NSSU: installing software ... please be patient ...") + return self.pkgaddNSSU(remote_package, + dev_timeout=timeout, **kwargs) + elif self._multi_RE is False: # simple case of device with only one RE _progress("installing software ... please be patient ...") add_ok = self.pkgadd( From 01f0cbf63b093933d278f719de0645ce16e5259e Mon Sep 17 00:00:00 2001 From: nitin kumar Date: Tue, 27 Sep 2016 14:16:42 +0530 Subject: [PATCH 4/9] UT for issu features --- lib/jnpr/junos/utils/sw.py | 1 - tests/unit/utils/test_sw.py | 43 ++++++++++++++++++++++++++++++++++++- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/lib/jnpr/junos/utils/sw.py b/lib/jnpr/junos/utils/sw.py index 4b17257ec..117860871 100644 --- a/lib/jnpr/junos/utils/sw.py +++ b/lib/jnpr/junos/utils/sw.py @@ -160,7 +160,6 @@ def pkgadd(self, remote_package, **kvargs): be passed within **kvargs**, following the RPC syntax methodology (dash-2-underscore,etc.) - .. todo:: Add way to notify user why installation failed. .. warning:: Refer to the restrictions listed in :meth:`install`. """ diff --git a/tests/unit/utils/test_sw.py b/tests/unit/utils/test_sw.py index 0f26fd292..f001f2d42 100644 --- a/tests/unit/utils/test_sw.py +++ b/tests/unit/utils/test_sw.py @@ -111,7 +111,6 @@ def test_sw_progress(self): @patch('paramiko.SSHClient') @patch('scp.SCPClient.put') def test_sw_put(self, mock_scp_put, mock_scp): - # mock_scp_put.side_effect = self.mock_put package = 'test.tgz' self.sw.put(package) self.assertTrue( @@ -119,6 +118,17 @@ def test_sw_put(self, mock_scp_put, mock_scp): 'test.tgz', '/var/tmp') in mock_scp_put.mock_calls) + @patch('jnpr.junos.utils.sw.FTP') + def test_sw_put_ftp(self, mock_ftp_put): + dev = Device(host='1.1.1.1', user='rick', password='password123', + mode='telnet', port=23, gather_facts=False) + sw = SW(dev) + sw.put(package='test.tgz') + self.assertTrue( + call( + 'test.tgz', + '/var/tmp') in mock_ftp_put.mock_calls) + @patch('jnpr.junos.utils.scp.SCP.__exit__') @patch('jnpr.junos.utils.scp.SCP.__init__') @patch('jnpr.junos.utils.scp.SCP.__enter__') @@ -138,6 +148,37 @@ def test_sw_pkgadd(self, mock_execute): package = 'test.tgz' self.assertTrue(self.sw.pkgadd(package)) + @patch('jnpr.junos.Device.execute') + def test_sw_install_issu(self, mock_execute): + mock_execute.side_effect = self._mock_manager + package = 'test.tgz' + self.assertTrue(self.sw.install(package, issu=True, no_copy=True)) + + @patch('jnpr.junos.Device.execute') + def test_sw_install_nssu(self, mock_execute): + mock_execute.side_effect = self._mock_manager + package = 'test.tgz' + self.assertTrue(self.sw.install(package, nssu=True, no_copy=True)) + + @patch('jnpr.junos.Device.execute') + def test_sw_install_issu_nssu_both_error(self, mock_execute): + mock_execute.side_effect = self._mock_manager + package = 'test.tgz' + self.assertRaises(TypeError, self.sw.install, package, + nssu=True, issu=True) + + @patch('jnpr.junos.Device.execute') + def test_sw_pkgaddISSU(self, mock_execute): + mock_execute.side_effect = self._mock_manager + package = 'test.tgz' + self.assertTrue(self.sw.pkgaddISSU(package)) + + @patch('jnpr.junos.Device.execute') + def test_sw_pkgaddNSSU(self, mock_execute): + mock_execute.side_effect = self._mock_manager + package = 'test.tgz' + self.assertTrue(self.sw.pkgaddNSSU(package)) + @patch('jnpr.junos.Device.execute') def test_sw_pkgadd_pkg_set(self, mock_execute): mock_execute.side_effect = self._mock_manager From 42c9e561fd07c218807fa1e744bf09421f31e0ef Mon Sep 17 00:00:00 2001 From: nitin kumar Date: Tue, 27 Sep 2016 14:29:27 +0530 Subject: [PATCH 5/9] rpc-reply file for issu and nssu upgrade --- .../request-package-in-service-upgrade.xml | 26 +++++++++++++++++++ .../request-package-nonstop-upgrade.xml | 26 +++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 tests/unit/utils/rpc-reply/request-package-in-service-upgrade.xml create mode 100644 tests/unit/utils/rpc-reply/request-package-nonstop-upgrade.xml diff --git a/tests/unit/utils/rpc-reply/request-package-in-service-upgrade.xml b/tests/unit/utils/rpc-reply/request-package-in-service-upgrade.xml new file mode 100644 index 000000000..aa3a9a050 --- /dev/null +++ b/tests/unit/utils/rpc-reply/request-package-in-service-upgrade.xml @@ -0,0 +1,26 @@ + + + + + + + hup + + + + Verified junos-install-mx-x86-64-16.1-20160925.0 signed by PackageDevelopmentEc_2016 + Verified manifest signed by PackageDevelopmentEc_2016 + Checking PIC combinations + Verified fips-mode signed by PackageDevelopmentEc_2016 + Verified jail-runtime signed by PackageDevelopmentEc_2016 + Verified jdocs signed by PackageDevelopmentEc_2016 + Verified jpfe-X960 signed by PackageDevelopmentEc_2016 + Verified jpfe-common signed by PackageDevelopmentEc_2016 + Verified jpfe-wrlinux signed by PackageDevelopmentEc_2016 + Verified jsd signed by PackageDevelopmentEc_2016 + Verified vrr-mx signed by PackageDevelopmentEc_2016 + + + 0 + + diff --git a/tests/unit/utils/rpc-reply/request-package-nonstop-upgrade.xml b/tests/unit/utils/rpc-reply/request-package-nonstop-upgrade.xml new file mode 100644 index 000000000..aa3a9a050 --- /dev/null +++ b/tests/unit/utils/rpc-reply/request-package-nonstop-upgrade.xml @@ -0,0 +1,26 @@ + + + + + + + hup + + + + Verified junos-install-mx-x86-64-16.1-20160925.0 signed by PackageDevelopmentEc_2016 + Verified manifest signed by PackageDevelopmentEc_2016 + Checking PIC combinations + Verified fips-mode signed by PackageDevelopmentEc_2016 + Verified jail-runtime signed by PackageDevelopmentEc_2016 + Verified jdocs signed by PackageDevelopmentEc_2016 + Verified jpfe-X960 signed by PackageDevelopmentEc_2016 + Verified jpfe-common signed by PackageDevelopmentEc_2016 + Verified jpfe-wrlinux signed by PackageDevelopmentEc_2016 + Verified jsd signed by PackageDevelopmentEc_2016 + Verified vrr-mx signed by PackageDevelopmentEc_2016 + + + 0 + + From e56e59affcec43ab40a366e0c5f3f78942bb9f87 Mon Sep 17 00:00:00 2001 From: nitin kumar Date: Tue, 27 Sep 2016 16:25:09 +0530 Subject: [PATCH 6/9] SW class UT for ISSU --- .../rpc-reply/check-in-service-upgrade.xml | 26 ++++++++++++++++ tests/unit/utils/test_sw.py | 31 +++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 tests/unit/utils/rpc-reply/check-in-service-upgrade.xml diff --git a/tests/unit/utils/rpc-reply/check-in-service-upgrade.xml b/tests/unit/utils/rpc-reply/check-in-service-upgrade.xml new file mode 100644 index 000000000..aa3a9a050 --- /dev/null +++ b/tests/unit/utils/rpc-reply/check-in-service-upgrade.xml @@ -0,0 +1,26 @@ + + + + + + + hup + + + + Verified junos-install-mx-x86-64-16.1-20160925.0 signed by PackageDevelopmentEc_2016 + Verified manifest signed by PackageDevelopmentEc_2016 + Checking PIC combinations + Verified fips-mode signed by PackageDevelopmentEc_2016 + Verified jail-runtime signed by PackageDevelopmentEc_2016 + Verified jdocs signed by PackageDevelopmentEc_2016 + Verified jpfe-X960 signed by PackageDevelopmentEc_2016 + Verified jpfe-common signed by PackageDevelopmentEc_2016 + Verified jpfe-wrlinux signed by PackageDevelopmentEc_2016 + Verified jsd signed by PackageDevelopmentEc_2016 + Verified vrr-mx signed by PackageDevelopmentEc_2016 + + + 0 + + diff --git a/tests/unit/utils/test_sw.py b/tests/unit/utils/test_sw.py index f001f2d42..4f4175602 100644 --- a/tests/unit/utils/test_sw.py +++ b/tests/unit/utils/test_sw.py @@ -108,6 +108,20 @@ def test_sw_progress(self): with self.capture(SW.progress, self.dev, 'running') as output: self.assertEqual('1.1.1.1: running\n', output) + def test_sw_progress(self): + with self.capture(SW.progress, self.dev, 'running') as output: + self.assertEqual('1.1.1.1: running\n', output) + + @patch('jnpr.junos.Device.execute') + @patch('paramiko.SSHClient') + @patch('scp.SCPClient.put') + def test_sw_progress_true(self, scp_put, mock_paramiko, mock_execute): + mock_execute.side_effect = self._mock_manager + with self.capture(SW.progress, self.dev, 'testing') as output: + self.sw.install('test.tgz', progress=True, checksum=345, + cleanfs=False) + self.assertEqual('1.1.1.1: testing\n', output) + @patch('paramiko.SSHClient') @patch('scp.SCPClient.put') def test_sw_put(self, mock_scp_put, mock_scp): @@ -195,6 +209,23 @@ def test_sw_validate(self, mock_execute): package = 'package.tgz' self.assertTrue(self.sw.validate(package)) + @patch('jnpr.junos.Device.execute') + def test_sw_validate_issu(self, mock_execute): + mock_execute.side_effect = self._mock_manager + package = 'package.tgz' + self.assertTrue(self.sw.validate(package, issu=True)) + + @patch('jnpr.junos.Device.execute') + def test_sw_validate_issu(self, mock_execute): + rpc_reply = """mgd: commit complete + Validation succeeded + + 1 + """ + mock_execute.side_effect = etree.fromstring(rpc_reply) + package = 'package.tgz' + self.assertFalse(self.sw.validate(package, issu=True)) + @patch('jnpr.junos.Device.execute') def test_sw_remote_checksum_not_found(self, mock_execute): xml = ''' From 5a4e796c837df0c746e3a8e787ba89f63d365c0d Mon Sep 17 00:00:00 2001 From: nitin kumar Date: Wed, 28 Sep 2016 16:09:10 +0530 Subject: [PATCH 7/9] removed **kwargs from sw.validate call --- lib/jnpr/junos/utils/sw.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/jnpr/junos/utils/sw.py b/lib/jnpr/junos/utils/sw.py index 117860871..96b09aa0d 100644 --- a/lib/jnpr/junos/utils/sw.py +++ b/lib/jnpr/junos/utils/sw.py @@ -494,8 +494,7 @@ def _progress(report): _progress( "validating software against current config," " please be patient ...") - v_ok = self.validate(remote_package, issu, dev_timeout=timeout, - **kwargs) + v_ok = self.validate(remote_package, issu, dev_timeout=timeout) if v_ok is not True: return v_ok From 332ea147554315a4384655d9fa5a33177371e16a Mon Sep 17 00:00:00 2001 From: nitin kumar Date: Fri, 7 Oct 2016 15:21:57 +0530 Subject: [PATCH 8/9] address review comment from stacy --- lib/jnpr/junos/utils/sw.py | 13 +++++++++---- tests/unit/utils/test_sw.py | 18 +++++++++++++++--- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/lib/jnpr/junos/utils/sw.py b/lib/jnpr/junos/utils/sw.py index 96b09aa0d..9d73cdb63 100644 --- a/lib/jnpr/junos/utils/sw.py +++ b/lib/jnpr/junos/utils/sw.py @@ -208,8 +208,9 @@ def pkgaddISSU(self, remote_package, **kvargs): def _parse_pkgadd_response(self, rsp): got = rsp.getparent() rc = int(got.findtext('package-result').strip()) - if rc != 0: - self.log("software pkgadd message: %s" % got.findtext('output')) + output_msg = '\n'.join([i.text for i in got.findall('output')]) + self.log("software pkgadd package-result: %s\nOutput: %s" % ( + rc, output_msg)) return rc == 0 # ------------------------------------------------------------------------- @@ -232,8 +233,9 @@ def validate(self, remote_package, issu=False, **kwargs): rsp = self.rpc.request_package_validate( package_name=remote_package, **kwargs).getparent() rc = int(rsp.findtext('package-result')) - if rc != 0: - self.log("software validation message: %s" % rsp.findtext('output')) + output_msg = '\n'.join([i.text for i in rsp.findall('output')]) + self.log("software validate package-result: %s\nOutput: %s" % ( + rc, output_msg)) return 0 == rc def remote_checksum(self, remote_package, timeout=300): @@ -446,6 +448,9 @@ def myprogress(dev, report): if issu is True and nssu is True: raise TypeError( 'install function can either take issu or nssu not both') + elif (issu is True or nssu is True) and self._multi_RE is not True: + raise TypeError( + 'ISSU/NSSU requires Multi RE setup') def _progress(report): if progress is True: diff --git a/tests/unit/utils/test_sw.py b/tests/unit/utils/test_sw.py index 4f4175602..8c630d8e0 100644 --- a/tests/unit/utils/test_sw.py +++ b/tests/unit/utils/test_sw.py @@ -35,6 +35,8 @@ '2RE': False, 'serialnumber': 'aaf5fe5f9b88', 'fqdn': 'firefly', 'virtual': True, 'switch_style': 'NONE', 'version': '12.1X46-D15.3', 'HOME': '/cf/var/home/rick', 'srx_cluster': False, + 'version_RE0': '16.1-20160925.0', + 'version_RE1': '16.1-20160925.0', 'model': 'FIREFLY-PERIMETER', 'RE0': {'status': 'Testing', 'last_reboot_reason': 'Router rebooted after a ' @@ -77,7 +79,7 @@ def test_sw_hashfile(self): def test_sw_constructor_multi_re(self, mock_execute): mock_execute.side_effect = self._mock_manager self.sw = SW(self.dev) - self.assertFalse(self.sw._multi_RE) + self.assertTrue(self.sw._multi_RE) @patch('jnpr.junos.Device.execute') def test_sw_constructor_multi_vc(self, mock_execute): @@ -181,6 +183,14 @@ def test_sw_install_issu_nssu_both_error(self, mock_execute): self.assertRaises(TypeError, self.sw.install, package, nssu=True, issu=True) + @patch('jnpr.junos.Device.execute') + def test_sw_install_issu_single_re_error(self, mock_execute): + mock_execute.side_effect = self._mock_manager + package = 'test.tgz' + self.sw._multi_RE = False + self.assertRaises(TypeError, self.sw.install, package, + nssu=True, issu=True) + @patch('jnpr.junos.Device.execute') def test_sw_pkgaddISSU(self, mock_execute): mock_execute.side_effect = self._mock_manager @@ -330,11 +340,11 @@ def test_sw_install_mixed_vc(self, mock_pkgadd): @patch('jnpr.junos.utils.sw.SW.pkgadd') def test_sw_install_multi_vc_mode_disabled(self, mock_pkgadd): mock_pkgadd.return_value = True - self.dev._facts = { + self.dev._facts = {'2RE': True, 'domain': None, 'RE1': { 'status': 'OK', 'model': 'RE-EX8208', 'mastership_state': 'backup'}, 'ifd_style': 'SWITCH', - 'version_RE1': '12.3R7.7', 'version_RE0': '12.3', '2RE': True, + 'version_RE1': '12.3R7.7', 'version_RE0': '12.3', 'serialnumber': 'XXXXXX', 'fqdn': 'XXXXXX', 'RE0': {'status': 'OK', 'model': 'RE-EX8208', 'mastership_state': 'master'}, 'switch_style': 'VLAN', @@ -405,6 +415,7 @@ def test_sw_install_mixed_vc_TypeError(self, mock_pkgadd): def test_sw_install_kwargs_force_host(self, mock_execute): self.sw.install('file', no_copy=True, force_host=True) rpc = [ + '/var/tmp/file', '/var/tmp/file', '/var/tmp/file', '/var/tmp/file', @@ -470,6 +481,7 @@ def test_sw_reboot_multi_re_vc(self, mock_execute): def test_sw_reboot_mixed_vc(self, mock_execute): mock_execute.side_effect = self._mock_manager self.sw._mixed_VC = True + self.sw._multi_VC = True self.sw.reboot() self.assertTrue('all-members' in (etree.tostring(mock_execute.call_args[0][0]).decode('utf-8'))) From ce7678373f1e61a922eb49f898e00a0d9941c40f Mon Sep 17 00:00:00 2001 From: nitin kumar Date: Thu, 13 Oct 2016 11:12:39 +0530 Subject: [PATCH 9/9] test case for python 3.x --- tests/unit/utils/test_sw.py | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/tests/unit/utils/test_sw.py b/tests/unit/utils/test_sw.py index 8c630d8e0..3a77affa1 100644 --- a/tests/unit/utils/test_sw.py +++ b/tests/unit/utils/test_sw.py @@ -416,15 +416,30 @@ def test_sw_install_kwargs_force_host(self, mock_execute): self.sw.install('file', no_copy=True, force_host=True) rpc = [ '/var/tmp/file', + '/var/tmp/file', + '/var/tmp/file', + '/var/tmp/file', + '/var/tmp/file', + '/var/tmp/file', + '/var/tmp/file', + '/var/tmp/file', + '/var/tmp/file', + '/var/tmp/file', + '/var/tmp/file', + '/var/tmp/file', + '/var/tmp/file', + '/var/tmp/file', + '/var/tmp/file', + '/var/tmp/file', + '/var/tmp/file', '/var/tmp/file', '/var/tmp/file', '/var/tmp/file', '/var/tmp/file', '/var/tmp/file', '/var/tmp/file'] - self.assertTrue( - (etree.tostring( - mock_execute.call_args[0][0])).decode('utf-8)') in rpc) + self.assertTrue(etree.tostring( + mock_execute.call_args[0][0]).decode('utf-8') in rpc) @patch('jnpr.junos.Device.execute') def test_sw_rollback(self, mock_execute):