Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test code for memory growing problem #1

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions pyros_httpbin/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,10 @@ catkin_pip_package(pyros_httpbin)
#######

if (CATKIN_ENABLE_TESTING)
catkin_add_pytests(tests/test_httpbin.py)
# catkin_add_pytests(tests/test_httpbin.py)
# Removing. somehow rostest cannot run the httpbin node. Rostest is too buggy we should drop it.
#find_package(rostest REQUIRED)
#add_rostest(tests/test_httpbin.test)
catkin_add_nosetests(tests/test_httpbin.py)
endif()

#####
Expand All @@ -83,5 +83,8 @@ endif()
install(
PROGRAMS
nodes/httpbin.py
nodes/leaktest.py
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)

install(DIRECTORY launch DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION})
33 changes: 33 additions & 0 deletions pyros_httpbin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,36 @@ In particular we need to find out how to mix and match:
- library to easily build ros-web client (and zmp-web ?)
- test for a ros-web client using httpbin
- gopher software application (for yujinrobot)

---
## test

mkdir build

cd build & cmake ../ & make & source devel/setup.bash & make test

or

py.test ../tests/test_httpbin.py -vv


## test for memory leak

source devel/setup.bash & cd ../scripts & ./leaktest.sh

or

roslaunch pyros_httpbin leaktest.launch --screen

## Troubleshooting

easy_install netaddr, when occur no module netaddr

git clone https://github.com/pyros-dev/pyros-setup.git & cd pyros-setup & python setup.py install, when occur no module pyros_setup

cd pyros_schemas-examples/build & source devel/setup.bash, when occur path error

## Docker

docker run -it --rm --name yujin-d3-devel-memory_leak_test --network=host zaxrok/yujin-d3:devel-memory_leak_test bash

4 changes: 4 additions & 0 deletions pyros_httpbin/launch/leaktest.launch
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<launch>
<node name="memory_leak_test" pkg="pyros_httpbin" type="leaktest.py">
</node>
</launch>
161 changes: 161 additions & 0 deletions pyros_httpbin/nodes/fixed_leaktest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
#!/usr/bin/env python
#
# License: Yujin
#
##############################################################################
# Documentation
##############################################################################
"""
Simple utility to start a gopher scheduler ROS node from the command line.
"""
##############################################################################
# Imports
##############################################################################
import os
import psutil
import sys
import argparse
import json
import requests
sys.path.insert(0, '/home/bcc/Tutorial/playbooks/gopher_docker/gopher_webclients/install/lib/python2.7/dist-packages')
try:
import rocon_console.console as console
import pyros_schemas
import pyros_httpbin

import rospy
from pyros_httpbin.srv import HttpbinPostJson, HttpbinPostJsonRequest, HttpbinPostJsonResponse
from pyros_httpbin.msg import HttpRequestHeaders, HttpbinPostArgs, HttpbinPostBody, HttpbinPostBody2
import pyros_msgs.opt_as_array # This will duck punch the standard message type initialization code.

except ImportError:
# Because we need to access Ros message types here (from ROS env or from virtualenv, or from somewhere else)
import pyros_setup
# We rely on default configuration in the environment to point us ot the proper distro and workspace
pyros_setup.configurable_import().configure().activate()

import rocon_console.console as console
import pyros_schemas
import pyros_httpbin

import rospy
from pyros_httpbin.srv import HttpbinPostJson, HttpbinPostJsonRequest, HttpbinPostJsonResponse
from pyros_httpbin.msg import HttpRequestHeaders, HttpbinPostArgs, HttpbinPostBody, HttpbinPostBody2
import pyros_msgs.opt_as_array # This will duck punch the standard message type initialization code.


# patching messages types with optional fields
pyros_msgs.opt_as_array.duck_punch(HttpRequestHeaders, [
'User_Agent',
'Accept',
'Accept_Encoding',
'Accept_Language',
'Host',
'Referer',
'Upgrade_Insecure_Requests',
])

pyros_msgs.opt_as_array.duck_punch(HttpbinPostArgs, ['argopt'])
pyros_msgs.opt_as_array.duck_punch(HttpbinPostJson._request_class, ['headers'])
pyros_msgs.opt_as_array.duck_punch(HttpbinPostArgs, ['argopt'])
pyros_msgs.opt_as_array.duck_punch(HttpbinPostBody, ['testoptitem'])
pyros_msgs.opt_as_array.duck_punch(HttpbinPostBody2, ['subtestoptstring', 'subtestoptint', 'subtestoptfloat'])
##############################################################################
# Helpers
##############################################################################

class StatusCodeException(Exception):
pass

class TestPyrosSchemas(object):

def __init__(self):
rospy.Service('/test/pyros_schemas', HttpbinPostJson, self.test_pyros_schemas2)
rospy.wait_for_service('/test/pyros_schemas', timeout=10)
self.test_service_proxy = rospy.ServiceProxy('/test/pyros_schemas', HttpbinPostJson)

@pyros_schemas.with_service_schemas(HttpbinPostJson)
def test_pyros_schemas2(self, data, data_dict, errors):
print (" => {0}".format(data_dict)) # to help with debugging
h = data_dict.get('headers', {})
h.update({"Content-type": "application/json"})
p = data_dict.get('params')
d = data_dict.get('json')
response = requests.post('http://httpbin.org/post', headers=h, params=p, data=json.dumps(d))

if response.status_code == requests.status_codes.codes.OK: # TODO : easy way to check all "OK" codes
print (" <= {0}".format(response.json()))
return response.json()
else:
raise StatusCodeException(response.status_code)

def test_pyros_schemas(self, req):
resp = HttpbinPostJsonResponse()
return resp

def spin(self):
count = 0
pid = os.getpid()
process = psutil.Process(pid)
while not rospy.core.is_shutdown():
ros_data = pyros_httpbin.msg.HttpbinPostBody(
testitem=pyros_httpbin.msg.HttpbinPostBody2(
subteststring='teststr',
# subtestoptstring='', optional, lets not care about it
subteststringarray=['str1', 'str2', 'str3'],
subtestint=42,
# subtestoptint=21, #optional, lets not care about it
subtestintarray=[4, 2, 1],
subtestfloat=42.,
# subtestoptfloat=21., #optional, lets not care about it
subtestfloatarray=[4., 2., 1.],
),
# testoptitem optional lets not care about it
testitemarray=[
pyros_httpbin.msg.HttpbinPostBody2(
subteststring='teststr1',
# subtestoptstring='', optional, lets not care about it
subteststringarray=['str1', 'str2', 'str3'],
subtestint=42,
# subtestoptint=21, #optional, lets not care about it
subtestintarray=[4, 2, 1],
subtestfloat=42.,
# subtestoptfloat=21., #optional, lets not care about it
subtestfloatarray=[4., 2., 1.],
),
pyros_httpbin.msg.HttpbinPostBody2(
subteststring='teststr2',
# subtestoptstring='', optional, lets not care about it
subteststringarray=['str1', 'str2', 'str3'],
subtestint=42,
# subtestoptint=21, #optional, lets not care about it
subtestintarray=[4, 2, 1],
subtestfloat=42.,
# subtestoptfloat=21., #optional, lets not care about it
subtestfloatarray=[4., 2., 1.],
),
]
)
req = pyros_httpbin.srv.HttpbinPostJson._request_class(
params=pyros_httpbin.msg.HttpbinPostArgs(
arg='testarg',
# argopt='', # optional, let not care about it
arglist=['arg1', 'arg2']
# httpbin removes the list if only one arg here, but we do expect list in response.
# TODO : fix this...
),
# headers=pyros_httpbin.msg.HttpRequestHeaders(), # optional, let not care about it
json=ros_data
)
resp = self.test_service_proxy(req)
rospy.loginfo("COUNT: {0}".format(count))
rospy.loginfo("RESP: {0}".format(resp))
count += 1
mem = process.get_memory_info()[0]
rospy.loginfo("Memory usage(%s):%d" % (pid, mem))
rospy.sleep(0.01)

if __name__ == '__main__':
rospy.init_node('test_pyros_schemas', log_level=rospy.INFO)
_node = TestPyrosSchemas()
_node.spin()
Loading