Monkeyrunner doesn't support signal.SIGALRM - timeout

Monkeyrunner hangs from time to time.
I am using the following code from the web. (Sorry, I forget the source.)
This code is used to detect the "Monkeyrunner hang issue" and reconnect.
class Timeout():
"""Timeout class using ALARM signal."""
class Timeout(Exception):
pass
def __init__(self, sec):
self.sec = sec
def __enter__(self):
signal.signal(signal.SIGALRM, self.raise_timeout)
signal.alarm(self.sec)
def __exit__(self, *args):
signal.alarm(0) # disable alarm
def raise_timeout(self, *args):
raise Timeout.Timeout()
def snapshot():
while (True):
try:
with Timeout(2):
return(mdevice().takeSnapshot())
except Timeout.Timeout:
print "========================= snapshot timeout ==============="
mdevice(1)
However, the following error is reported:
File ".\lib\monkeySetting.py", line 30, in __enter__
signal.signal(signal.SIGALRM, self.raise_timeout)
AttributeError: 'module' object has no attribute 'SIGALRM'
How can this be solved?
Or is there another way to solve the "Monkeyrunner hang issue"?

First of all, SIGALRM is not implemented on Windows:
On Windows, signal() can only be called with SIGABRT, SIGFPE, SIGILL,
SIGINT, SIGSEGV, or SIGTERM. A ValueError will be raised in any other
case.
On the other hand, you should try AndroidViewClient/culebra, and I hope you solve the hang problem and don't need SIGALRM at all.

Related

Service __len__ not found Unexpected error, recovered safely

python3.8
My code:
from googleads import adwords
def execute_request():
adwords_client = adwords.AdWordsClient.LoadFromStorage(path="google_general/googleads.yaml")
campaign_service = adwords_client.GetService('CampaignService', version='v201809')
pass
context["dict_list"] = execute_request()
Traceback:
Traceback (most recent call last):
File "/home/michael/pycharm-community-2019.3.2/plugins/python-ce/helpers/pydev/_pydevd_bundle/pydevd_xml.py", line 282, in frame_vars_to_xml
xml += var_to_xml(v, str(k), evaluate_full_value=eval_full_val)
File "/home/michael/pycharm-community-2019.3.2/plugins/python-ce/helpers/pydev/_pydevd_bundle/pydevd_xml.py", line 369, in var_to_xml
elif hasattr(v, "__len__") and not is_string(v):
File "/home/michael/PycharmProjects/ads3/venv/lib/python3.8/site-packages/googleads/common.py", line 694, in __getattr__
raise googleads.errors.GoogleAdsValueError('Service %s not found' % attr)
googleads.errors.GoogleAdsValueError: Service __len__ not found
Unexpected error, recovered safely.
googleads.yaml about logging
logging:
version: 1
disable_existing_loggers: False
formatters:
default_fmt:
format: ext://googleads.util.LOGGER_FORMAT
handlers:
default_handler:
class: logging.StreamHandler
formatter: default_fmt
level: DEBUG
loggers:
# Configure root logger
"":
handlers: [default_handler]
level: DEBUG
I've just started studying the API.
Namely, I'm trying to execute my first request (https://developers.google.com/adwords/api/docs/guides/first-api-call#make_your_first_api_call)
Could you help me with this problem? At least how to localize it more precisely.
This seems to be a problem which results from the way the PyCharm debugger inspects live objects during debugging.
Specifically, it checks if a given object has the __len__ attribute/method in the code of var_to_xml, most likely to determine an appropriate representation of the object for the debugger interface (which seems to require constructing an XML representation).
googleads service objects such as your campaign_service, however, use some magic to be able to call the defined SOAP methods on them without requiring to hard-code all of them. The code looks like this:
def __getattr__(self, attr):
"""Support service.method() syntax."""
if self._WsdlHasMethod(attr):
if attr not in self._method_proxies:
self._method_proxies[attr] = self._CreateMethod(attr)
return self._method_proxies[attr]
else:
raise googleads.errors.GoogleAdsValueError('Service %s not found' % attr)
This means that the debugger's check for a potential __len__ attribute is intercepted, and because the CampaignService does not have a SOAP operation called __len__, an exception is raised.
You can validate this by running your snippet in the regular way (i.e. not debugging it) and checking if that works.
An actual fix would seem to either require that PyCharm's debugger changes the way it inspects objects (not calling hasattr(v, "__len__")) or that googleads modifies the way it implements __getattr__, for example by actually implementing a __len__ method that just raises AttributeError.

rails 4 - active job - wrong number of arguments (0 for 1) even though im passing 1 argument

Here I call the job - passing in procedure:
ProcedureDayAfterJob.set(wait_until: reminder_for_jo).perform_later(procedure)
Here is the job itself - taking procedure as argument:
class ProcedureDayAfterJob < ActiveJob::Base
queue_as :mailers
def perform(procedure)
return if procedure.upcoming?
Admin::NotificationMailer.procedure_day_after(procedure).deliver_later
end
end
Here is method in mailer - taking procedure as argument:
def procedure_day_after(procedure)
#procedure = procedure
mail(
# hiding who im sending to
)
end
And here is the error I'm getting:
2017-12-15T19:25:57.365Z 9222 TID-oxvg7jsso ERROR: !!! ERROR HANDLER
THREW AN ERROR !!!
2017-12-15T19:25:57.365Z 9222 TID-oxvg7jsso ERROR: wrong number of
arguments (0 for 1)
2017-12-15T19:25:57.365Z 9222 TID-oxvg7jsso ERROR:
/Users/foreverlabs/foreverlabs/app/jobs/procedure_day_after_job.rb:4:in
`perform'
I'm passing in the argument to each method so can anybody figure out what's going on?
I have seen this happen due to a typo in the initializer for the Service/Class being called within the job.
It is usually misleading with the single line errors where the only helpful info is the line number and file it is erroring on. With that, and looking at your queue log, it shows it is coming from the 4th line which is inside the perform method itself, and where the code has been redacted.
Check the class you are calling on this line to see if "initialize" is misspelled somehow (I do it from time to time myself),because doing such would cause the constructor to disable, as well as cause the class to expect zero arguments.
I'm sure you have fixed this, but hopefully this will help someone else in the future.

How do you timeout a twisted test that uses pytest?

I'm working on converting some tests from using Nose and twisted, to using Pytest and twisted, as Nose is no longer in development. The easiest way to convert the tests is by editing the custom decorator that each test has. This decorator is on every test, and defines a timeout for the individual test.
I've tried using #pytest.mark.timeout, but the only method that's worked is the 'thread' method, but this stops the entire test run and won't continue on to the next test. Using the method 'signal' fails to stop the test, but I can see an error present in the junitxml file.
def inlineCallbacksTest ( timeout = None ):
def decorator ( method ):
#wraps ( method )
#pytest.mark.timeout(timeout = timeout, method = 'signal' )
#pytest.inlineCallbacks
def testMethod ( *args, **kwargs ):
return method(*args, **kwargs)
return testMethod
return decorator
The tests themselves use twisted to start up and send messages to the software. I don't need the tests to cancel any twisted processes or locks. I would just like pytest to mark the test as a failure after the timeout, and then move onto the next test.
Below is the error I see in the xml file when using signal method of timeout.
</system-out><system-err>
+++++++++++++++++++++++++++++++++++ Timeout ++++++++++++++++++++++++++++++++++++
~~~~~~~ Stack of PoolThread-twisted.internet.reactor-2 (139997693642496) ~~~~~~~
File "/usr/lib64/python2.7/threading.py", line 784, in __bootstrap
self.__bootstrap_inner()
File "/usr/lib64/python2.7/threading.py", line 811, in __bootstrap_inner
self.run()
File "/usr/lib64/python2.7/threading.py", line 764, in run
self.__target(*self.__args, **self.__kwargs)
File "/usr/lib64/python2.7/site-packages/twisted/python/threadpool.py", line 190, in _worker
o = self.q.get()
File "/usr/lib64/python2.7/Queue.py", line 168, in get
self.not_empty.wait()
File "/usr/lib64/python2.7/threading.py", line 339, in wait
waiter.acquire()
~~~~~~~ Stack of PoolThread-twisted.internet.reactor-1 (139997702035200) ~~~~~~~
File "/usr/lib64/python2.7/threading.py", line 784, in __bootstrap
self.__bootstrap_inner()
File "/usr/lib64/python2.7/threading.py", line 811, in __bootstrap_inner
self.run()
File "/usr/lib64/python2.7/threading.py", line 764, in run
self.__target(*self.__args, **self.__kwargs)
File "/usr/lib64/python2.7/site-packages/twisted/python/threadpool.py", line 190, in _worker
o = self.q.get()
File "/usr/lib64/python2.7/Queue.py", line 168, in get
self.not_empty.wait()
File "/usr/lib64/python2.7/threading.py", line 339, in wait
waiter.acquire()
+++++++++++++++++++++++++++++++++++ Timeout ++++++++++++++++++++++++++++++++++++
Unhandled Error
Traceback (most recent call last):
File "/usr/lib64/python2.7/site-
packages/twisted/internet/base.py", line 1169, in run
self.mainLoop()
--- <exception caught here> ---
File "/usr/lib64/python2.7/site-
packages/twisted/internet/base.py", line 1181, in mainLoop
self.doIteration(t)
File "/usr/lib64/python2.7/site-
packages/twisted/internet/epollreactor.py", line 362, in doPoll
l = self._poller.poll(timeout, len(self._selectables))
File "/usr/lib/python2.7/site-packages/pytest_timeout.py", line 110, in handler
timeout_sigalrm(item, timeout)
File "/usr/lib/python2.7/site-packages/pytest_timeout.py", line 243, in timeout_sigalrm
pytest.fail(&apos;Timeout >%ss&apos; % timeout)
File "/usr/lib/python2.7/site-packages/_pytest/outcomes.py", line 85, in fail
raise Failed(msg=msg, pytrace=pytrace)
builtins.Failed: Timeout >5.0s
</system-err>
I have looked around for a similar solution, and the closest I could find was this question. Any help or suggestions would be appreciated.
Coming back to this after 4+ years with an answer. The problem seems to be the exception from the test getting caught by the twisted reactor. I was able to resolve this by updating the version of twisted. Twisted versions since 16.5 have a new Deferred function call addTimeout (Docs). Using that, I was able to modify the original decorator to the following. Now whenever a test times out, it simply raises an exception and moves on to the next one. May not be the most elegant, but I hope this helps someone else out!
import twisted.internet.defer as defer
import pytest_twisted as pt
from functools import wraps
def inlineCallbacksTest ( timeout = None ):
def testDecorator ( testFunc ):
def timeoutError ( value, timeout ):
raise Exception ( "Test Timeout: {} secs have expired".format ( timeout ) )
#wraps ( testFunc )
def wrapper ( *args, **kwargs ):
testDefer = pt.inlineCallbacks ( testFunc )( *args, **kwargs )
testDefer.addTimeout ( timeout, reactor, timeoutError )
return testDefer
return wrapper
return testDecorator

Lua: How to call error without stack trace

I'm using Lua to parse scripts written in some language (let's call it L) and create Lua-code that can be run by e.g. LuaJIT. But to simplify debugging for the users, I want to map the run time errors given by Lua/LuaJIT to the correct line in the L-files. I do this by xpcalling the created Lua-code, translating the error message and stacktrace and then calling error with this message. Unfortunately this gives me two stack traces, one created by me and one tracing back to the function that called error. Is it possible to get rid of this stack trace, or is there some better way of doing this?
local status, err = xpcall(loadedCode, debug.traceback)
if not status then
error(createANewErrorMessageWithPrettyTraceback(err),0)
end
Output:
luajit: ./my/file.name:5: Some error message
stack traceback:
my pretty traceback
stack traceback:
[C]: in function 'error'
./my/file/calling/error.lua:44: in function <./my/file/calling/error.lua:26>
./my-main:16: in main chunk
[C]: at 0x00404180
I know that e.g. Moonscript does something similar to this, but as far as I can see they just write the new error message to stderr and then continues as normal, instead of stopping the program which is what I want to do.
There is a possibility of doing this and then calling error with no arguments, which will make the program fail (actually I think it's error that fails), but this feels like quite an ugly solution, so I'll rather keep the stupid second trace than doing that.
PS: I assume what the title asks actually doesn't work (as error only takes two arguments), so what I'm actually asking is more how something like this can be achieved. (Are there other functions that do similar things perhaps, or where I should look to figure out how to write that function myself.)
Edit: Is it perhaps possible to edit the function that error's using to get its traceback, as it is with debug.traceback?
I wanted to do something similar (only from Lua directly) and I ended up overwriting debug.traceback function itself to change the stack trace to suit my needs. My code is below; see if this method works for you as well:
local dtraceback = debug.traceback
debug.traceback = function (...)
if select('#', ...) >= 1 then
local err, lvl = ...
if err and type(err) ~= 'thread' then
local trace = dtraceback(err, (lvl or 2)+1)
if genv.print == iobase.print then -- no remote redirect
return trace
else
genv.print(trace) -- report the error remotely
return -- don't report locally to avoid double reporting
end
end
end
-- direct call to debug.traceback: return the original.
-- debug.traceback(nil, level) doesn't work in Lua 5.1
-- (http://lua-users.org/lists/lua-l/2011-06/msg00574.html), so
-- simply remove first frame from the stack trace
return (dtraceback(...):gsub("(stack traceback:\n)[^\n]*\n", "%1"))
end
You could simply display the modified traceback that you want and exit.
local function errh(err)
print(createANewErrorMessageWithPrettyTraceback(debug.traceback(err, 2)))
os.exit(-1) -- error code
end
local status, result = xpcall(loadedCode, errh)
-- The script will never reach this point if there is an error.
print(result)

GCE Python API: oauth2client.util:execute() takes at most 1 positional argument (2 given)

I'm trying to get started with the Python API for Google Compute Engine using their "hello world" tutorial on https://developers.google.com/compute/docs/api/python_guide#setup
Whenever making the call response = request.execute(auth_http) though, I get the following error signaling that I can't authenticate:
WARNING:oauth2client.util:execute() takes at most 1 positional argument (2 given)
I'm clearly only passing one positional argument (auth_http), and I've looked into oauth2client/util.py, apiclient/http.py, and oauth2client/client.py for answers, but nothing seems amiss. I found another stack overflow post that encountered the same issue, but it seems that in the constructor of the OAuth2WebServerFlow class in oauth2client/client.py, 'access_type' is set to 'offline' already (though to be honest I don't completely understand what's going on here in terms of setting up oauth2.0 flows).
Any suggestions would be much appreciated, and thanks in advance!
Looking at the code, the #util.positional(1) annotation is throwing the warning. Avoid it using named parameters.
Instead of:
response = request.execute(auth_http)
Do:
response = request.execute(http=auth_http)
https://code.google.com/p/google-api-python-client/source/browse/apiclient/http.py#637
I think documentation is wrong. Please use the following:
auth_http = credentials.authorize(http)
# Build the service
gce_service = build('compute', API_VERSION, http=auth_http)
project_url = '%s%s' % (GCE_URL, PROJECT_ID)
# List instances
request = gce_service.instances().list(project=PROJECT_ID, filter=None, zone=DEFAULT_ZONE)
response = request.execute()
You can do one of three things here:
1 Ignore the warnings and do nothing.
2 Suppress the warnings and set the flag to ignore:
import oauth2client
import gflags
gflags.FLAGS['positional_parameters_enforcement'].value = 'IGNORE'
3 Figure out where the positional parameter is being provided and fix it:
import oauth2client
import gflags
gflags.FLAGS['positional_parameters_enforcement'].value = 'EXCEPTION'
# Implement a try and catch around your code:
try:
pass
except TypeError, e:
# Print the stack so you can fix the problem, see python exception traceback docs.
print str(e)

Resources