Hi Damian,<br><br><br>
> In reading the following code I suspect that this could be clearer if<br>it accepted a single argument that was the dict of 'argument => return value'.<br><br>All set -- mock_fn() now takes a dictionary rather than two lists as an argument.  The docstring suggestions have also been implemented.<br>

<br>> Why do you fall through to the target function? Unit tests need to be<br>
os independent, so if falling though to an os will break on some<br>
platforms then we'll need to find an alternative.<br><br>We do this in order to accommodate a call of open() that is being made somewhere within the call of test_get_connections().  We had no easy way of seeing what exactly was making this call, but it was giving us a large backtrace and error if we did not provide a way for the original open funciton to be called.<br>

<br>We will run this code under windows tomorrow when we have access to a windows machine.<br><br>All of these changes are in Megan's Github at: <a href="https://github.com/meganchang/Stem/blob/proc-tests/test/unit/util/proc.py">https://github.com/meganchang/Stem/blob/proc-tests/test/unit/util/proc.py</a><br>

<br>Per your suggestion to use itertools.product(), we tried this but ran into a problem.  Our subsets() function returns a list of lists, where each sub-list contains tuples that bind input values to return values -- we want these to be persistent throughout.  itertools doesn't seem to be able to take a single list of tuples and create all possible combinations of these tuples (from each individual tuple in its own list to all four given tuples in a single list).  It is challenging to explain, but let us know if you think it is still a better option when you have a chance to look over the code again.<br>

<br>As for Onionoo, we had a brief discussion about it today, and we are definitely considering it.  We will take a closer look at it tomorrow and give a more definite answer then.<br><br>Have a good evening,<br>Erik & Megan<br>

<br><br><div class="gmail_quote">On Tue, Jun 26, 2012 at 4:25 PM, Damian Johnson <span dir="ltr"><<a href="mailto:atagar@torproject.org" target="_blank">atagar@torproject.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

Hi Erik, hi Megan.<br>
<div class="im"><br>
> Megan and I have finished a first run at writing unit tests for the proc utilities in stem.<br>
<br>
</div>Looks great! I only got down to 'test_get_memory_usage()' before<br>
needing to run to catch the bus but the tests that I've seen so far<br>
look good. The mocking though confused me for a bit.<br>
<br>
> +def mock_fn(exp_args, return_vals, target=None):<br>
> +  """<br>
> +  Provides a lambda function that may be used to mock another function.<br>
<br>
In reading the following code I suspect that this could be clearer if<br>
it accepted a single argument that was the dict of 'argument => return<br>
value'.<br>
<br>
> +  :param list of tuples exp_args: expected input value(s) to be used for comparison<br>
<br>
The ReStructuredTest format for param entries are...<br>
:param [type ]arg_name:<br>
<br>
So to properly compile this should be...<br>
:param list exp_args:<br>
<br>
Usually I say what the list contains in the following description.<br>
<br>
> +  :param function target: target function to be called if mocking doesn't cover this input<br>
<br>
Why do you fall through to the target function? Unit tests need to be<br>
os independent, so if falling though to an os will break on some<br>
platforms then we'll need to find an alternative.<br>
<br>
Speaking of os independence, if it isn't too hard would you mind<br>
running this on a warty platform like Windows? If you don't have a<br>
Windows system laying around then don't worry about it.<br>
<br>
Don't worry if the expand_path unit test breaks - that's something<br>
Beck is currently fixing.<br>
<br>
> +  :precondition: len(exp_args) = len(return_vals)<br>
<br>
I checked the sphinx index [1] and python domain [2] for<br>
"precondition" and didn't find it. Are you sure that directive exists?<br>
If not then we can simply provide it in the above function<br>
description.<br>
<br>
> +                                                 return_vals[i]    a=exp_args[i]<br>
> +  :returns:  function _mocker such that: f(*a) = target(*a)        a != exp_args[i] and target != N<br>
> +                                                 raise TargetError a != exp_args[i] and target = No<br>
<br>
Nice, though to make this render the way that you want in sphinx it<br>
should be changed to...<br>
<br>
:returns:  function _mocker such that...<br>
  * return_vals[i]    a = exp_args[i]<br>
  * target(*a)        a != exp_args[i] and target != N<br>
  * raise TargetError a != exp_args[i] and target = No<br>
<br>
> +  Used with the builtin zip function to create all possible combinations<br>
> +  of two lists. Called in test_get_stats().<br>
<br>
That sounds a lot like itertools.product().<br>
<br>
>>> import itertools<br>
>>> list(itertools.product([1, 2, 3], ['a', 'b', 'c']))<br>
[(1, 'a'), (1, 'b'), (1, 'c'), (2, 'a'), (2, 'b'), (2, 'c'), (3, 'a'),<br>
(3, 'b'), (3, 'c')]<br>
<div class="im"><br>
> Looking further into the future, we discussed our next project with Stem with Professor Danner today, and agreed that the "Export Tor Desciptors" project would be ideal.<br>
<br>
</div>Ok. Little more context on that project in case you're not on tor-dev@...<br>
<a href="https://lists.torproject.org/pipermail/tor-dev/2012-June/003634.html" target="_blank">https://lists.torproject.org/pipermail/tor-dev/2012-June/003634.html</a><br>
<br>
I was gonna suggest a python port of Onionoo [3][4], which is the<br>
service that supports Atlas [5]. Karsten would be able to help mentor<br>
that, and it would involve filling in the missing bits of descriptor<br>
parsing that we'll need for it (such as network status entries).<br>
However, that would be far more ambitious and might be a bit too<br>
large. Up to you.<br>
<br>
Cheers! -Damian<br>
<br>
[1] <a href="http://sphinx.pocoo.org/genindex.html" target="_blank">http://sphinx.pocoo.org/genindex.html</a><br>
[2] <a href="http://sphinx.pocoo.org/domains.html#directive-py:class" target="_blank">http://sphinx.pocoo.org/domains.html#directive-py:class</a><br>
[3] <a href="https://www.torproject.org/projects/onionoo.html" target="_blank">https://www.torproject.org/projects/onionoo.html</a><br>
[4] <a href="https://gitweb.torproject.org/onionoo.git/blob/HEAD:/DESIGN" target="_blank">https://gitweb.torproject.org/onionoo.git/blob/HEAD:/DESIGN</a><br>
[5] <a href="https://atlas.torproject.org/" target="_blank">https://atlas.torproject.org/</a><br>
</blockquote></div><br>