Exception not raised assertRaises()? - python

I am giving a wrong input and I want an exception to be raised. Somehow this is not happening. This is my unit test code:
def test_invalid_bag_json_conversion_1(self):
file_name = "../test/test_files/wrong_bag.bag"
ru = RosbagUploader(file_name, self.json_output, "", "", "", "")
status = ru.start()
self.assertRaises(Exception, RosbagUploader, file_name, self.json_output, "", "", "", "")
self.assertEquals(ReturnCodes.FAIL, status)
and my code that I am testing:
class RosbagUploader(object):
"""
#brief Uploads deserialized input Rosbag file to ElasticSearch or
stores it locally
"""
def __init__(self, _rosbag_filepath, _json_filename, _es_addr, _es_index,
_es_type, _buffer_size):
self.overall_status = ReturnCodes.SUCCESS
self._rosbag_filepath = _rosbag_filepath
self._json_filename = _json_filename
self._buffer_size = _buffer_size if _buffer_size > 0 else 5000
self._es_type = _es_type
self._es_addr = _es_addr
self._es_index = _es_index
self._es_buff = []
try:
self._rosbag = rosbag.Bag(_rosbag_filepath, "r")
if self._es_addr:
self._es = Elasticsearch() if _es_addr == "" else \
Elasticsearch([_es_addr])
self._total_num_record = self._rosbag.get_message_count()
except:
print("[ERROR] {}".format(sys.exc_info()))
self.overall_status = ReturnCodes.FAIL
It shows the output that the exception is raised as below:
[ERROR] (<class 'rosbag.bag.ROSBagException'>, ROSBagException(), <traceback object at 0x7fdcb463e8c0>)
EException AttributeError: "'RosbagUploader' object has no attribute '_rosbag'" in <bound method RosbagUploader.__del__ of <rosbag_deserializer_core.RosbagUploader object at 0x7fdcb4899ad0>> ignored
Which is what it should do. But why doesnt it raise the exception?

You are essentially ignoring the exception since you are not re-raising after the print statement:
try:
[...]
except:
print("[ERROR] {}".format(sys.exc_info()))
self.overall_status = ReturnCodes.FAIL
You need to re-raise for callers to receive the exception:
try:
[...]
except:
print("[ERROR] {}".format(sys.exc_info()))
self.overall_status = ReturnCodes.FAIL
raise

Do you have a __del__ destruction method? Seems to be failing there.

Related

(Pymongo) AttributeError: 'InsertManyResult' object has no attribute 'inserted_count'

I follow the manual https://api.mongodb.com/python/3.4.0/api/pymongo/results.html
and similar problem AttributeError: 'dict' object has no attribute 'is_active' (PyMongo And Flask) (not fit mine issue)
after successfully .insert_many or .insert_one,
the .inserted_count not working
function main part I stock
if one_or_many_bool == True:
x = mycol.insert_many(insert_values_json)
else:
x = mycol.insert_one(insert_values_json)
return x
print(x)
print(x.inserted_count, "documents insert.")
output:
<pymongo.results.InsertManyResult object at 0x0000017D1D256950>
Traceback (most recent call last):
File "C:\Users\chuan\OneDrive\Desktop\10.17_connect_mongoD_練習\fake02.py", line 54, in <module>
print(x.inserted_count, "documents inserted.")
AttributeError: 'InsertManyResult' object has no attribute 'inserted_count'
the whole code(incase someone want to take a look):
import pymongo
import datetime
import json
from bson.objectid import ObjectId
from bson import json_util
def init_db(ip, db, coll):
try:
myclient = pymongo.MongoClient('mongodb://' + ip + '/')
mydb = myclient[db]
mycol = mydb[coll]
except Exception as e:
msg_fail_reason = "error in init_db function"
return msg_fail_reason
return mydb, mycol
# ins_data = insert_db_data
# one_or_many_bool: input 1 means True; input 0 is False
def ins_data(one_or_many_bool, insert_values_json ):
try:
if one_or_many_bool:
x = mycol.insert_many(insert_values_json)
else:
x = mycol.insert_one(insert_values_json)
return x
except Exception as e:
msg_fail_reason = "error in ins_data function"
return msg_fail_reason
msg_fail_reason = "no error occur"
ip_input = input("Enter the ip: ")
exist_DB_name = input("Enter exist DB name: ")
exist_coll_name = input("Enter exist collection name: ")
mydb, mycol = init_db(ip_input, exist_DB_name, exist_coll_name)
update_one_or_many = input("U are update one or many values? (ex:1 for many , 0 for one): ")
newvalues_str = input("Enter new values: ")
one_or_many_bool = bool(int(update_one_or_many))
insert_values_json =json.loads(newvalues_str)
x = ins_data(one_or_many_bool, insert_values_json )
print(x)
print(x.inserted_count, "documents insert.")
number_of_insert_data = int(x.inserted_count)
modified_data_list = []
for modified_data in mycol.find().sort("_id", -1).limit(number_of_insert_data):
# print(modified_data)
modified_data_list.append(modified_data)
def parse_json(data):
return json.loads(json_util.dumps(data))
# if someone want data in json
modified_data_json = parse_json(modified_data_list)
# 1 means success
return_status_str = { "ok" : 1 , "msg" : msg_fail_reason , "count" : number_of_insert_data}
print(return_status_str)
print(type(return_status_str))
As the PyMongo doc described, InsertManyResult doesn't has the inserted_count attrbute. You can use len(result.inserted_ids) instead.

Cannot get the python test to assert an Exception was thrown

Code:
class ContributionHandler:
def __init__(self):
MetricsConfigurator.setup_metrics("ContributionMutationResolverLambda")
self.entity_linkage_authority_client_factory = EntityLinkageAuthorityClientFactory()
self.entity_linkage_authority_client = self.entity_linkage_authority_client_factory.get_client()
#retry(delay=0.5, tries=2)
def create_contribution(self, input_event):
"""
Calls Entity Linkage Authority to create a contribution between PEs
:return: the contribution created
"""
from_pe = input_event[constants.FROM_PE]
to_pe = input_event[constants.TO_PE]
logging.info(f"Creating contribution from PE: {from_pe} to PE: {to_pe}")
try:
response = self.__create_contribution_call(input_event)
return response
except Exception as e:
logging.info(f"Error creating the contribution from PE: {from_pe} to PE: {to_pe}")
raise e
#retry(delay=0.5, tries=2)
#metric_time
#metric_count
#metric_errors(verbose=True)
def __create_contribution_call(self, input_event):
"""
Separate retryable private function for api call with the client.
"""
relationship_contribution_info = RelationshipContributionInfo(input_event[constants.FROM_PE],
input_event[constants.TO_PE], input_event[constants.RELATIONSHIP_TYPE],
input_event[constants.INTENT], input_event[constants.IS_NEGATIVE])
audit_info = AuditInfo(input_event[constants.AUDIT_INFO][constants.CREATED_BY],
input_event[constants.AUDIT_INFO][constants.CREATED_AT])
try:
return self.entity_linkage_authority_client.create_relationship\
(CreateRelationshipRequest(relationship_contribution_info, audit_info))
except Exception as e:
logging.info("Recreating the client as Credentials expired1")
if isinstance(e, ClientError) and e.response['Error']['Code'] == 'ExpiredToken':
logging.info("Recreating the client as Credentials expired2")
self.entity_linkage_authority_client_factory = EntityLinkageAuthorityClientFactory()
self.entity_linkage_authority_client = self.entity_linkage_authority_client_factory.get_client()
raise e
Test case:
#mock.patch(METRICS_IMPORT_PATH + '.setup_metrics')
#mock.patch(ENTITY_LINKAGE_AUTHORITY_CLIENT_FACTORY_IMPORT_PATH + '.get_client')
#mock.patch(ENTITY_LINKAGE_AUTHORITY_CLIENT_FACTORY_IMPORT_PATH + '.__init__')
def test_create_contribution_handler_token_expiry(mock_client_factory_init, mock_get_client, mock_metrics):
mock_metrics.return_value = None
mock_client_factory_init.return_value = None
error_response = {"Error": {"Code": "ExpiredToken"}}
mock_get_client.return_value.create_relationship(mock.ANY).raiseError.side_effect = ClientError(error_response, "Expired Token")
contribution_handler = ContributionHandler()
with pytest.raises(ClientError) :
contribution_handler.create_contribution(CONTRIBUTION_INPUT)
# make sure we retried 3 times
# assert 3 == mock_client_factory_init.call_count
Output:
Test case is failing with following output:
[CPython36:setup:stdout] with pytest.raises(ClientError) :
[CPython36:setup:stdout] > contribution_handler.create_contribution(CONTRIBUTION_INPUT)
[CPython36:setup:stdout] E Failed: DID NOT RAISE

AttributeError: instance has no attribute error in Linux only

I am getting the AttributeError: PortalTesting instance has no attribute 'reporting_screenshot' error in Linux only. When I run this code on Windows, its working as expected.
#!/usr/bin/env python
class PortalTesting:
def __init__(self):
self.start_time = time.time()
self.status = OrderedDict()
self.screenshots_folder = ''
self.new_folder_name = ''
self.tday = datetime.today().strftime('%Y%m%d-%H%M')
self.dt = date.today() - timedelta(2)
self.start_date = self.dt.strftime('%m-%d-%Y')
# self.reporting_screenshot = ''
# self.transcript = ''
def login(self):
try:
URL = ''
driver.get(URL)
# ------------------- Transcript ------------------- #
def transcript(self):
try:
tr_e1 = driver.find_element_by_id('Transcript_ID')
hover1 = ActionChains(driver).move_to_element(tr_e1)
hover1.click().perform()
....
....
self.transcript_screenshot = self.path + self.tday + "_Transcripts.png"
driver.get_screenshot_as_file(self.transcript_screenshot)
self.status['Transcript'] = ["Pass", self.transcript_screenshot]
# THIS IS WHERE I GET ERROR
except:
self.status['Transcript'] = ["Fail", self.transcript_screenshot]
# ------------------- Reporting ------------------- #
def reporting(self):
try:
# Reports tab
rpt_e1 = driver.find_element_by_id('report_menu_id')
hover1 = ActionChains(driver).move_to_element(rpt_e1)
hover1.click().perform()
.....
.....
WebDriverWait(driver, 60).until(EC.element_to_be_clickable((By.ID, 'PortalChartContainer'))).click()
self.reporting_screenshot = self.tday + "_Reports.png"
driver.get_screenshot_as_file(self.path + self.reporting_screenshot)
print("Reporting check complete.")
self.status['Reporting'] = ["Pass", self.reporting_screenshot]
# THIS IS WHERE I GET ERROR
except:
self.status['Reporting'] = ["Fail", self.reporting_screenshot]
pt = PortalTesting()
pt.login()
pt.reporting()
pt.transcript()
pt.admin()
pt.print_status()
What I am doing here is, login to URL. Run reports/ transcript. If success, add Pass and screenshot to self.status dictionary. If fails, add Fail and screenshot to self.status dictionary.
Above code works fine on Windows but, gives error when I copy paste same code on Linux.
If I add self.transcript = '' and self.reporting_screenshot = '' in __init__, I get TypeError: 'str' object is not callable
Traceback Error:
Traceback (most recent call last):
File "DC1PortalTesting.py", line 477, in <module>
pt.reporting()
File "DC1PortalTesting.py", line 375, in reporting
self.status['Reporting'] = ["Fail", self.reporting_screenshot]
AttributeError: PortalTesting instance has no attribute 'reporting_screenshot'
I would really appreciate your help.
#merlyn is right: the first error arise because of you try/except statement in the definition of reporting(). If any error pops up before self.reporting_screenshot = self.tday + "_Reports.png", then the attribute does not exist, and the except clause will raise this error.
Two suggestions here:
self.reporting_screenshot should be create at first in the definition of reporting(), because all its components already exist at this point.
def reporting(self):
self.reporting_screenshot = self.tday + "_Reports.png"
try:
# Reports tab
rpt_e1 = driver.find_element_by_id('report_menu_id')
hover1 = ActionChains(driver).move_to_element(rpt_e1)
hover1.click().perform()
.....
.....
WebDriverWait(driver, 60).until(EC.element_to_be_clickable((By.ID, 'PortalChartContainer'))).click()
# Removed line here
driver.get_screenshot_as_file(self.path + self.reporting_screenshot)
print("Reporting check complete.")
self.status['Reporting'] = ["Pass", self.reporting_screenshot]
...
Catch the error in your except statement, for debugging purpose.
...
# THIS IS WHERE I GET ERROR
except Exception as e: # catches any exception
# print(e) # uncomment for debugging, or make it smarter with a switch
self.status['Reporting'] = ["Fail", self.reporting_screenshot]
Regarding the other error: #merlyn also provided an explanation in his comment.
Regarding why your code fails on Linux: I assume it is working on Windows so you never tested the except clause there, right?

AttributeError: 'dict' object has no attribute 'decode'

I am trying to run a service even when API link is down but I keep getting the following error:
AttributeError: 'dict' object has no attribute 'decode'.
How can I solve this problem? Thank you
*#app.route('/test_api')
def test_api():
ipno = "192.168.0.120"
port = "8060"
url_time = 'https://{}:{}/time/'.format(ipno, port)
url_member = 'https://{}:{}/member/'.format(ipno, port)
url_state = 'https://{}:{}/state/'.format(ipno, port)
try:
r_time = _session.get(url_time).content
r_member = _session.get(url_member).content
r_state = _session.get(url_state).content
except requests.exceptions.ConnectionError:
r_uptime = {
"uptime": "OFF"
}.decode(utf-8)
r_member ={
"groupCount": "OFF",
}.decode(utf-8)
r_state={ "state": "OFF"
}.decode(utf-8)
return render_template('test_api.html', time = json.loads(r_time), member=json.loads(r_member), state=json.loads(r_state))*
Your code seems to have lots of errors.
First, you are using different names for same variable: r_time and r_uptime
Second, you are using different types for r_xxx values: strings in try and dict in except clause. I think, following code will better suite your needs:
import json.decoder
...
try:
r_uptime = json.loads(_session.get(url_time).content)
r_member = json.loads(_session.get(url_member).content)
r_state = json.loads(_session.get(url_state).content)
except (json.decoder.JSONDecodeError, requests.exceptions.ConnectionError) as ex:
r_uptime = {"uptime": "OFF"}
r_member = {"groupCount": "OFF"}
r_state = {"state": "OFF"}
return render_template('test_api.html', time = r_uptime, member=r_member, state=r_state)

Pickleing error: connot pickle Request object

I know That it is not possible to pickle a pyramid request object, but I cant seem to find where I am sending the Request object.
Consider the following:
#task
def do_consignment_task(store, agent):
print "GOTHERE IN TASK"
s = sqlahelper.get_session()
consign = store.gen_consignment()
ca = Agents.by_id(store.consignment_agents_id)
consign.consignment_agents_id = ca.id
consign.consignment_teamleader_id = ca.ou[0].lead_agents_id
consign.consignment_timestamp = func.now()
consign.created_by_agent_id = agent.id
consign.complete_stamp = func.now()
consign.sims = store.sims
consign.status = "SUCCESS"
print "GOT BEFORE LOOP "
for sim in store.sims:
if sim in consign.sims:
continue
else:
consign.sims.append(sim)
s.add(consign)
transaction.savepoint()
print "GOT AFTER SAVEPOINT"
for sim in consign.sims:
is_reconsign = sim.consignment_agent or sim.consignment_teamlead
if is_reconsign:
if not sim.consignment_history:
sim.consignment_history = []
sim.consignment_history.append(dict(
stamp=sim.consignment_timestamp,
consignment_agent_id=sim.consignment_agents_id,
consignment_teamleader_id=sim.consignment_teamleader_id,
by_agent_id=agent.id
))
s.query(
Sims
).filter(
Sims.iccid == sim.iccid
).update(
{
"consignment_agents_id": consign.consignment_agents_id,
"consignment_history": sim.consignment_history,
"consignment_teamleader_id": ca.ou[0].lead_agents_id,
"consignment_timestamp": func.now(),
"modify_stamp": func.now(),
"consignments_id": consign.id
},
synchronize_session=False
)
print "GOT BEFORE COMMIT"
transaction.savepoint()
print "THIS IS THE ID ID ID ID ID ID : ", consign.id
I call this function like:
if self.store.finalise:
try:
store = self.store
agent = self.agent
do_consignment_task.delay(store, agent)
transaction.commit()
self.check_and_purge()
return "Consignmnet is being processed"
except Exception, exc:
self.check_and_purge()
self.log.exception(exc)
exc_error = "CONSIGNERR:", exc.message
raise USSDFailure(exc_error)
else:
self.store.status = "CANCELLED"
if "fullconfirm" in self.session:
del self.session["fullconfirm"]
self.check_and_purge()
return "CONSIGNMENT Cancelled"
When I run this code I get the following error:
EncodeError: Can't pickle <class 'pyramid.util.Request'>: attribute lookup pyramid.util.Request failed
I am not sending self or request objects - at least not that I can see.
How can solve this problem? Am I sending a request object, because I can not see one?
The traceback can be seen here
EDIT:
okay So I have tried to change the data I send to the function - I am not passing a sqlalchemy object and I am making a copy of the store object, that changes my code to:
#task
def do_consignment_task(agent_id, **store):
print "GOTHERE IN TASK"
s = sqlahelper.get_session()
cObj = USSDConsignmentsObject()
consign = cObj.gen_consignment()
ca = Agents.by_id(store.consignment_agents_id)
consign.consignment_agents_id = ca.id
consign.consignment_teamleader_id = ca.ou[0].lead_agents_id
consign.consignment_timestamp = func.now()
consign.created_by_agent_id = agent_id
# etc
and:
if self.store.finalise:
try:
# del self.service
store = self.store.__dict__.copy()
agent_id = self.agent.id
print store
print agent_id
# print help(store)
do_consignment_task.delay(agent_id, **store)
transaction.commit()
#etc
This however still gives me the same error :|
Try not to serialise a Pyramid request object. When you interact with a celery task you should think of it as an independent process.
Provide it all the information it needs to do it's work. Be aware that you need to serialise that information.
So self.store possibly contains attribute references that may be unrealistic to serialise.
Perhaps create a method on the store object that returns a clean dictionary object.
def serialize(self):
data = {}
data["element1"] = self.element1
data["element2"] = self.element2
data["element3"] = self.element3
return data
Then when you want to call the delay method make sure to use store.serialize() instead of store or the dict.

Categories