Repository URL to install this package:
|
Version:
3.3.14 ▾
|
tvault-contego
/
home
/
tvault
/
.virtenv
/
lib
/
python2.7
/
site-packages
/
pypowervm
/
tests
/
test_session.py
|
|---|
# Copyright 2014, 2017 IBM Corp.
#
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import copy
import gc
import mock
import os
import requests.models as req_mod
import requests.structures as req_struct
import subunit
import sys
import testtools
import pypowervm.adapter as adp
import pypowervm.exceptions as pvmex
import pypowervm.tests.lib as testlib
import pypowervm.tests.test_fixtures as fx
_logon_response_password = testlib.file2b("logon.xml")
_logon_response_file = testlib.file2b("logon_file.xml")
class TestSession(subunit.IsolatedTestCase, testtools.TestCase):
"""Test cases to test the Session classes and methods."""
@mock.patch('time.sleep')
@mock.patch('lxml.etree.fromstring', new=mock.Mock())
@mock.patch('pypowervm.adapter.Session._get_auth_tok_from_file',
new=mock.Mock())
def test_Session(self, mock_sleep):
"""Ensure Session can be instantiated, and test logon retries."""
# Passing in 0.0.0.0 will raise a ConnectionError or SSLError, but only
# if it gets past all the __init__ setup since _logon is the last
# statement.
self.assertRaises((pvmex.ConnectionError, pvmex.SSLError), adp.Session,
'0.0.0.0', 'uid', 'pwd')
mock_sleep.assert_not_called()
# Now set up a retry
self.assertRaises((pvmex.ConnectionError, pvmex.SSLError), adp.Session,
'0.0.0.0', 'uid', 'pwd', conn_tries=5)
# 5 tries = 4 sleeps
mock_sleep.assert_has_calls([mock.call(2)] * 4)
# Ensure 404 on the logon URI also retries
mock_sleep.reset_mock()
with mock.patch('requests.Session.request') as mock_rq:
mock_rq.side_effect = [mock.Mock(status_code=404),
mock.Mock(status_code=204)]
adp.Session(conn_tries=5)
# Only retried once, after the 404
mock_sleep.assert_called_once_with(2)
@mock.patch('pypowervm.adapter.Session._logon', new=mock.Mock())
@mock.patch('pypowervm.adapter._EventListener._get_events')
def test_session_init(self, mock_get_evts):
"""Ensure proper parameter handling in the Session initializer."""
mock_get_evts.return_value = {'general': 'init'}, [], []
logfx = self.useFixture(fx.LoggingFx())
# No params - local, file-based, http.
sess = adp.Session()
self.assertTrue(sess.use_file_auth)
self.assertIsNone(sess.password)
self.assertTrue(sess.username.startswith('pypowervm_'))
self.assertEqual('localhost', sess.host)
self.assertEqual('http', sess.protocol)
self.assertEqual(12080, sess.port)
self.assertEqual('http://localhost:12080', sess.dest)
self.assertEqual(1200, sess.timeout)
self.assertEqual('/etc/ssl/certs/', sess.certpath)
self.assertEqual('.crt', sess.certext)
# localhost + http is okay
self.assertEqual(0, logfx.patchers['warning'].mock.call_count)
# Verify unique session names
sess2 = adp.Session()
self.assertNotEqual(sess.username, sess2.username)
# Ensure proper protocol, port, and certpath defaulting when remote
sess = adp.Session(host='host', username='user', password='pass')
self.assertFalse(sess.use_file_auth)
self.assertIsNotNone(sess.password)
self.assertEqual('user', sess.username)
self.assertEqual('host', sess.host)
self.assertEqual('https', sess.protocol)
self.assertEqual(12443, sess.port)
self.assertEqual('https://host:12443', sess.dest)
self.assertEqual(1200, sess.timeout)
self.assertEqual('/etc/ssl/certs/', sess.certpath)
self.assertEqual('.crt', sess.certext)
# non-localhost + (implied) https is okay
self.assertEqual(0, logfx.patchers['warning'].mock.call_count)
@mock.patch('pypowervm.adapter.Session._logon', new=mock.Mock())
@mock.patch('pypowervm.adapter._EventListener._get_events')
@mock.patch('imp.load_source')
def test_session_ext_cfg(self, mock_load, mock_get_evts):
"""Test Session init with external config from env var."""
mock_get_evts.return_value = {'general': 'init'}, [], []
with mock.patch.dict(os.environ, {'PYPOWERVM_SESSION_CONFIG': 'path'}):
sess = adp.Session()
mock_load.assert_called_once_with('sesscfg', 'path')
mock_load.return_value.session_config.assert_called_once_with(sess)
@mock.patch('pypowervm.adapter.Session._logon')
def test_session_init_remote_http(self, mock_logon):
# Proper port defaulting and warning emitted when remote + http
with self.assertLogs(adp.__name__, 'WARNING'):
sess = adp.Session(host='host', protocol='http')
self.assertEqual(12080, sess.port)
@mock.patch.object(adp.Session, '_logon')
@mock.patch.object(adp.Session, '_logoff')
def test_session_clone(self, mock_logoff, mock_logon):
sess = adp.Session()
# Ensure the id that created the object is recorded.
self.assertTrue(hasattr(sess, '_init_by'))
# Create a shallow clone and ensure the _init_by does not match the id
sess_clone = copy.copy(sess)
self.assertTrue(hasattr(sess_clone, '_init_by'))
self.assertNotEqual(sess._init_by, id(sess_clone))
# Now test what happens when the clone is garbage collected.
self.assertFalse(mock_logoff.called)
sess_clone = None
gc.collect()
# The clone was not logged off
self.assertFalse(mock_logoff.called)
# Deep copy (properly) raises TypeError in py2 and py3 >= 3.6.
pyver = sys.version_info
if pyver.major == 2 or (pyver.major == 3 and pyver.minor >= 6):
# Ensure deep copies raise an exception.
self.assertRaises(TypeError, copy.deepcopy, sess)
else:
# Or if works, it is not logged off
sess_deepclone = copy.deepcopy(sess)
# Make pep8 happy, use the clone
self.assertIsNotNone(sess_deepclone)
sess_deepclone = None
gc.collect()
# The clone was not logged off
self.assertFalse(mock_logoff.called)
sess = None
gc.collect()
# The original session was logged off
self.assertTrue(mock_logoff.called)
@mock.patch('pypowervm.util.validate_certificate')
@mock.patch('requests.Session')
def test_logon(self, mock_session, mock_validate_cert):
"""Ensure a Session can be created and log on to PowerVM."""
# Init test data
host = '0.0.0.0'
user = 'user'
pwd = 'pwd'
auditmemento = 'audit'
# Create a Response object, that will serve as a mock return value
my_response = req_mod.Response()
my_response.status_code = 200
my_response.reason = 'OK'
dict_headers = {'content-length': '576',
'x-powered-by': 'Servlet/3.0',
'set-cookie': 'JSESSIONID=0000a41BnJsGTNQvBGERA3wR1nj:'
'759878cb-4f9a-4b05-a09a-3357abfea3b4; P'
'ath=/; Secure; HttpOnly, CCFWSESSION=E4'
'C0FFBE9130431DBF1864171ECC6A6E; Path=/;'
' Secure; HttpOnly',
'expires': 'Thu, 01 Dec 1994 16:00:00 GMT',
'x-transaction-id': 'XT10000073',
'cache-control': 'no-cache="set-cookie, set-cookie2"',
'date': 'Wed, 23 Jul 2014 21:51:10 GMT',
'content-type': 'application/vnd.ibm.powervm.web+xml; '
'type=LogonResponse'}
my_response.headers = req_struct.CaseInsensitiveDict(dict_headers)
my_response._content = _logon_response_password
# Mock out the method and class we are not currently testing
session = mock_session.return_value
session.request.return_value = my_response
# Run the actual test
result = adp.Session(host, user, pwd, auditmemento=auditmemento)
# Verify the result
self.assertTrue(result._logged_in)
self.assertEqual('PUIoR6x0kP6fQqA7qZ8sLZQJ8MLx9JHfLCYzT4oGFSE2WaGIhaFX'
'IyQYvbqdKNS8QagjBpPi9NP7YR_h61SOJ3krS_RvKAp-oCf2p8x8'
'uvQrrDv-dUzc17IT5DkR7_jv2qc8iUD7DJ6Rw53a17rY0p63KqPg'
'9oUGd6Bn3fNDLiEwaBR4WICftVxUFj-tfWMOyZZY2hWEtN2K8ScX'
'vyFMe-w3SleyRbGnlR34jb0A99s=', result._sessToken)
self.assertEqual(1, mock_validate_cert.call_count)
# No X-MC-Type header => 'HMC' is assumed.
self.assertEqual('HMC', result.mc_type)
# Now test file-based authentication and X-MC-Type
my_response._content = _logon_response_file
# Local/HMC is bad
self.assertRaises(pvmex.Error, adp.Session)
my_response.headers['X-MC-Type'] = 'PVM'
result = adp.Session()
# Verify the result.
self.assertTrue(result._logged_in)
# Token read from token_file, as indicated by logon_file.xml response.
self.assertEqual('file-based-auth-token', result._sessToken)
# validate_certificate should not have been called again
self.assertEqual(1, mock_validate_cert.call_count)
self.assertEqual('PVM', result.mc_type)