Using private DBus connection in PyDbus mocks - python

There is a service (in the second listing the DBus "coordinates" are given)
running in a Linux environment, and at the same time
I in the tests a custom private DBus is being run as in the following
fixture:
def run_custom_daemon():
cmd = [
"dbus-daemon",
"--system",
"--nofork",
"--address=unix:path=<some_path>.sock"
]
proc = subprocess.Popen(cmd,stdout=subprocess.PIPE,shell=False)
os.environ['CUSTOM_DBUS_SYSTEM_BUS_ADDRESS'] = "<some_path>.sock"
time.sleep(0.5)
yield proc
proc.kill()
Now, my component uses the service com.foo.bar.Baz and in the C++-code
I connect to it using the
sdbus-c++ as e.g.
m_prx = stdbus::createProxy(...)
Now, if I run the tests as it is it appears that because the "official"
DBus is somehow "shielded" by the tests, I am getting a ServiceNotKnown
error. However, if I mock the service using a code below,
I get "the name already has owner"-type of error.
The question is, probably, how to tell the mock to use
the above "privately" set-up DBus?
from pydbus import SystemBus
from gi.repository import GLib
class MockSrv:
dbus = """
<node name="/com/foo/bar/Baz">
<interface name="com.foo.bar.Baz">
<method name="Buzz">
<arg type="s" direction="out"/>
</method>
</interface>
</node>
"""
mloop = GLib.MainLoop()
mbus = SystemBus()
srv = MockSrv()
mbus.publish("com.foo.bar.Baz",
("/com/foo/bar/Baz", srv)
)
mloop.run()

If I'm understanding you correctly, you want to use Python to mock a DBus service, which you then connect to using C++ for testing.
The best way that I've found to do this is to create a local session bus(using something like dbus-run-session) to run the applications. This will setup the environment variables correctly to open a new SESSION bus, and then exit at the end.

Related

How can I launch an Android app on a device through Python?

I have consulted several topics on the subject, but I didn't see any related to launching an app on a device directly using a ppadb command.
I managed to do this code:
import ppadb
import subprocess
from ppadb.client import Client as AdbClient
# Create the connect functiun
def connect():
client = AdbClient(host='localhost', port=5037)
devices = client.devices()
for device in devices:
print (device.serial)
if len(devices) == 0:
print('no device connected')
quit()
phone = devices[0]
print (f'connected to {phone.serial}')
return phone, client
if __name__ == '__main__':
phone, client = connect()
import time
time.sleep(5)
# How to print each app on the emulator
list = phone.list_packages()
for truc in list:
print(truc)
# Launch the desired app through phone.shell using the package name
phone.shell(????????????????)
From there, I have access to each app package (com.package.name). I would like to launch it through a phone.shell() command but I can't access the correct syntax.
I can execute a tap or a keyevent and it's perfectly working, but I want to be sure my code won't be disturbed by any change in position.
From How to start an application using Android ADB tools, the shell command to launch an app is
am start -n com.package.name/com.package.name.ActivityName
Hence you would call
phone.shell("am start -n com.package.name/com.package.name.ActivityName")
A given package may have multiple activities. To find out what they are, you can use dumpsys package as follows:
def parse_activities(package, connection, retval):
out = ""
while True:
data = connection.read(1024)
if not data: break
out += data.decode('utf-8')
retval.clear()
retval += [l.split()[-1] for l in out.splitlines() if package in l and "Activity" in l]
connection.close()
activities = []
phone.shell("dumpsys package", handler=lambda c: parse_activities("com.package.name", c, activities))
print(activities)
Here is the correct and easiest answer:
phone.shell('monkey -p com.package.name 1')
This method will launch the app without needing to have acces to the ActivityName
Using AndroidViewClient/cluebra, you can launch the MAIN Activity of a package as follows:
#! /usr/bin/env python3
# -*- coding: utf-8 -*-
from com.dtmilano.android.viewclient import ViewClient
ViewClient.connectToDeviceOrExit()[0].startActivity(package='com.example.package')
This connects to the device (waiting if necessary) and then invokes startActivity() just using the package name.
startActivity() can also receive a component which is used when you know the package and the activity.

Jupyter Notebook Custom Service

I want to write a new service for Jupyter Notebook. But I'm having trouble figuring out how to get it to run. I've created a service similar to the default services found here https://github.com/jupyter/notebook/tree/master/notebook/services.
I'm attempting to run it in a Docker container built from jupyter/base-notebook. I've added c.NotebookApp.extra_services = ['TestHandler'] to the Notebook config and I've copied my service to /opt/conda/lib/python3.6/site-packages/notebook/services/test.py.
When I start the Notebook server I get an error saying ModuleNotFoundError: No module named 'TestHandler' so obviously my service is not being loaded correctly. Unfortunately I can't find any documentation on how to load a service in Jupyter Notebook.
This is my test.py service:
import json
from tornado import web
from ...base.handlers import APIHandler
class TestHandler(APIHandler):
#web.authenticated
def get(self):
res = { "foo": "bar" }
self.finish(json.dumps(res))
default_handlers = [
(r"/api/test", TestHandler),
]
That config value expects a list of importable modules which have a default_handlers attribute. You can therefore either use a full path:
# assuming your `test.py` lives in a top level package `mypackage`
c.NotebookApp.extra_services = ['mypackage.test']
Alteratively you can directly construct a module:
import sys
from types import ModuleType
name = 'some_long_ass_name_that_doesnt_conflict'
sys.modules[name] = ModuleType(name) # make the import machinery find it
sys.modules[name].default_handlers = [...]
c.NotebookApp.extra_services = [name]

ansible: local test new module with Error:Module unable to decode valid JSON on stdin. Unable to figure out what parameters were passed

I'm new to Python. This is my first Ansible module in order to delete the SimpleDB domain from ChaosMonkey deletion.
When tested in my local venv with my Mac OS X, it keeps saying
Module unable to decode valid JSON on stdin. Unable to figure out
what parameters were passed.
Here is the code:
#!/usr/bin/python
# Delete SimpleDB Domain
from ansible.module_utils.basic import *
import boto3
def delete_sdb_domain():
fields = dict(
sdb_domain_name=dict(required=True, type='str')
)
module = AnsibleModule(argument_spec=fields)
client = boto3.client('sdb')
response = client.delete_domain(DomainName='module.params['sdb_domain_name']')
module.exit_json(changed = False, meta = response)
def main():
delete_sdb_domain()
if __name__ == '__main__':
main()
And I'm trying to pass in parameters from this file: /tmp/args.json.
and run the following command to make the local test:
$ python ./delete_sdb_domain.py /tmp/args.json
please note I'm using venv test environment on my Mac.
If you find any syntax error in my module, please also point it out.
This is not how you should test your modules.
AnsibleModule expects to have specific JSON as stdin data.
So the closest thing you can try is:
python ./delete_sdb_domain.py < /tmp/args.json
But I bet you have your json file in wrong format (no ANSIBLE_MODULE_ARGS, etc.).
To debug your modules you can use test-module script from Ansible hacking pack:
./hacking/test-module -m delete_sdb_domain.py -a "sdb_domain_name=zzz"

Python 3 Windows Service starts only in debug mode

I first posted an answer in this post, but it didn't conform to the forum standards. I hope this time te answer fits the forum standards. This code should be more clear and easy to read.
In Python 3+ I have the following class that I use to build a Windows Service (it does nothing, just writes a log file):
#MyWindowsService.py
import win32serviceutil
import servicemanager
import win32service
import win32event
import sys
import logging
import win32api
class MyWindowsService(win32serviceutil.ServiceFramework):
_svc_name_ = 'ServiceName'
_svc_display_name_ = 'Service Display Name'
_svc_description_ = 'Service Full Description'
logging.basicConfig(
filename = 'c:\\Temp\\{}.log'.format(_svc_name_),
level = logging.DEBUG,
format = '%(levelname)-7.7s # %(asctime)s: %(message)s'
)
def __init__(self, *args):
self.log('Initializing service {}'.format(self._svc_name_))
win32serviceutil.ServiceFramework.__init__(self, *args)
self.stop_event = win32event.CreateEvent(None, 0, 0, None)
def SvcDoRun(self):
self.ReportServiceStatus(win32service.SERVICE_START_PENDING)
try:
self.log('START: Service start')
self.ReportServiceStatus(win32service.SERVICE_RUNNING)
self.start()
win32event.WaitForSingleObject(self.stop_event, win32event.INFINITE)
except Exception as e:
self.log('Exception: {}'.format(e))
self.SvcStop()
def SvcStop(self):
self.log('STOP: Service stopping...')
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
self.stop()
win32event.SetEvent(self.stop_event)
self.ReportServiceStatus(win32service.SERVICE_STOPPED)
def log(self, msg):
servicemanager.LogInfoMsg(str(msg)) #system log
logging.info(str(msg)) #text log
def start(self):
self.runflag = True
while self.runflag:
win32api.Sleep((2*1000), True)
self.log('Service alive')
def stop(self):
self.runflag = False
self.log('Stop received')
if __name__ == '__main__':
win32serviceutil.HandleCommandLine(MyWindowsService)
In the script I use a log file to check if it's working properly. I'm running python3.6 (also tried with python3.4) on Windows 7 and I'm experiencing the following problem. When I run python MyWindowsService.py install the prompt says that the service has been installed (but nothing is written in the log file). If I try to start the service, I get Service Error: 1 - More info NET HELPMSG 3547 which doesn't say much about the error. If I run python MyWindowsService.py debug, the program runs just fine (the log file is written), but still I don't have any control over the service: if I open another prompt and try to stop/start the service I still got the same results as stated above.
I also tryed to insert some debug code inside the init function, and when I run python MyWindowsService.py install it seems it doesn't get called. Is it possible?
I've checked for multiple solution and workarounds around the net, but I didn't find anything suitable. What am I missing?
As pointed out by eriksun in the comment to the first post, the problem came from the location of the python script, that was in a drive mapped with an UNC path - I'm working with a virtual machine. Moving the python script in the same drive as the python installation did the job.
To sum it up for future uses, if the service fails to start and you're pretty sure about your code, these are helpful actions to try and solve your issues:
use sc start ServiceName, sc query ServiceName and sc stop ServiceName to get info about the service.
check if your file is in a physical drive or in a UNC-mapped drive. If the latter try to run the script using the UNC path (for example python \\Server\share\python\your-folder\script.py) or move your script in the same drive as the python installation
make sure that "python36.dll", "vcruntime140.dll", and "pywintypes36.dll" are either symlink'd to the directory that has PythonService.exe; or symlink'd to the System32 directory; or that the directories with these DLLs are in the system (not user) Path
Check the system register with command reg query HKLM\System\CurrentControlSet\Services\your_service_name /s to get more information about the script
PLease, feel free to complete, change, modify the last so that it can be usefull for anyone that like me encounder this issue.
EDIT: One more thing... My project was thought to work actually with network folders (and UNC-mapped drive) and it failed when I tried to make it run as service. One very useful (day-saving) resource that I used to make it work is the SysinternalsSuite by Mark Russinovich that I found in this post. Hope this helps.

all python windows service can not start{error 1053}

all python code service can install but cannot start
Error 1053: The service did not respond to the start or control request in a timely fashion".
since my service can install and start in my server.
i think my code has no problem.
but i still wonder is there a solution that i can solve this error in code
my service:
import win32serviceutil
import win32service
import win32event
import time
import traceback
import os
import ConfigParser
import time
import traceback
import os
import utils_func
from memcache_synchronizer import *
class MyService(win32serviceutil.ServiceFramework):
"""Windows Service."""
os.chdir(os.path.dirname(__file__))
conf_file_name = "memcache_sync_service.ini"
conf_parser = ConfigParser.SafeConfigParser()
conf_parser.read(conf_file_name)
_svc_name_, _svc_display_name_, _svc_description_ = utils_func.get_win_service(conf_parser)
def __init__(self, args):
if os.path.dirname(__file__):
os.chdir(os.path.dirname(__file__))
win32serviceutil.ServiceFramework.__init__(self, args)
# create an event that SvcDoRun can wait on and SvcStop can set.
self.stop_event = win32event.CreateEvent(None, 0, 0, None)
def SvcDoRun(self):
self.Run()
win32event.WaitForSingleObject(self.stop_event, win32event.INFINITE)
def SvcStop(self):
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.stop_event)
LoggerInstance.log("memcache_sync service is stopped")
self.ReportServiceStatus(win32service.SERVICE_STOPPED)
sys.exit()
def Run(self):
try:
LoggerInstance.log("\n******\n\memcache_sync_service is running, configuration: %s\n******" % (self.conf_file_name,))
if ((not self.conf_parser.has_section('Memcache')) or
(not self.conf_parser.has_option('Memcache', 'check_interval'))):
LoggerInstance.log('memcache_sync_service : no Memcache service parameters')
self.SvcStop()
# set configuration parameters from ini configuration
self.check_interval = self.conf_parser.getint('Memcache', 'check_interval')
ms = MemcacheSynchronizer()
while 1:
ms.Sync()
time.sleep(self.check_interval)
except:
LoggerInstance.log("Unhandled Exception \n\t%s" % (traceback.format_exc(),))
if __name__ == '__main__':
win32serviceutil.HandleCommandLine(MyService)
execute result of "sc query [name]" cmd:
SERVICE_NAME: NewsMonitoringMemcacheSynchronizer
TYPE : 10 WIN32_OWN_PROCESS
STATE : 1 STOPPED
(NOT_STOPPABLE,NOT_PAUSABLE,IGNORES_SHUTDOWN)
WIN32_EXIT_CODE : 0 (0x0)
SERVICE_EXIT_CODE : 0 (0x0)
CHECKPOINT : 0x0
WAIT_HINT : 0x0
update:
i can run this service with debug mode, cmd:
memcache_syn_service.py debug
Had the same problem using pypiwin32 (version: 220) and python (version: 3.6). I had to copy :
"\Python36-32\Lib\site-packages\pypiwin32_system32\pywintypes36.dll"
to
"\Python36-32\Lib\site-packages\win32"
for the service to start (was working in debug mode)
If:
python your_service.py debug works, whilst
python your_service.py install + start it as a service fails with error 1053,
this command may help python C:\Python27\Scripts\pywin32_postinstall.py.
all my python coded windows service cannot run on my computer.
but all of them can start at our dev-server which means my code is correct.
but i found a alternative solution, run in debug mode:
any_service.py debug
Make sure you run the application with a different user than the default Local System user. Replace it with the user you successfully be able to run the debug command with.
To replace the user go to the windows services (start > services.msc)
Right click on the service you created > properties > Log On
Uncheck the Local System Account and enter your own.
All of the known fixes have failed me, and this one worked:
In services window:
right-click your installed service;
Go to Log On tab;
Select "This Account" and enter your user ID and pass;
Restart PC.
Has to do with Windows Permissions I was explained...
Method won't work if there's no password set for Windows User.
In my case the problem was from python37.dll not being at C:\Python37-x64\Lib\site-packages\win32.
Just copy it there and it will solve the problem
I had similar problem with a python service and found out that it was missing DLLs since the 'System Path' (not the user path) was not complete. Check the path in your dev-server and whether it matches the one at your computer (System path if service is installed as a LocalSystem service). For me I was missing python dlls' path c:\python27 (windows).
I had this issue and solved it two times in the same way, simply adding the Environment Variables.
I opened Environment Variables, and in system variable PATH added
C:\Users\MyUser\AppData\Local\Programs\Python\PythonXXX
C:\Users\MyUser\AppData\Local\Programs\Python\PythonXXX\Scripts
(Obviously change User name and XXX with Python version)

Categories